]> git.sur5r.net Git - openldap/commitdiff
Merge latest devel codes into releng 2 branch.
authorKurt Zeilenga <kurt@openldap.org>
Tue, 13 Jun 2000 19:56:15 +0000 (19:56 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Tue, 13 Jun 2000 19:56:15 +0000 (19:56 +0000)
Remove back-perl, back-sql, back-tcl from branch as they have yet
to be updated.
Additional changes are needed prior to release of alpha4.

722 files changed:
ANNOUNCEMENT
COPYRIGHT
INSTALL
LICENSE [new file with mode: 0644]
Makefile.in
README
acconfig.h
acinclude.m4
aclocal.m4
build/build.dsp [new file with mode: 0644]
build/build.mak [new file with mode: 0644]
build/dir.mk
build/info.mk
build/install-sh
build/lib-shared.mk
build/lib-static.mk
build/lib.mk
build/ltconfig [new file with mode: 0755]
build/ltmain.sh
build/main.dsw
build/man.mk
build/mkdep
build/mkdep.aix [new file with mode: 0755]
build/mkrelease
build/mkversion
build/mod.mk
build/openldap.m4
build/rules.mk
build/srv.mk
build/top.mk
build/version
clients/Makefile.in
clients/fax500/Makefile.in
clients/fax500/main.c
clients/finger/Makefile.in
clients/finger/main.c
clients/gopher/Makefile.in
clients/gopher/go500.c
clients/gopher/go500gw.c
clients/mail500/Makefile.in
clients/mail500/README
clients/mail500/mail500.m4 [new file with mode: 0644]
clients/mail500/main.c
clients/mail500/sendmail.cf
clients/maildap/Makefile.in [new file with mode: 0644]
clients/maildap/README [new file with mode: 0644]
clients/maildap/maildap.m4 [new file with mode: 0644]
clients/maildap/main.c [new file with mode: 0644]
clients/rcpt500/Makefile.in
clients/rcpt500/cmds.c
clients/rcpt500/main.c
clients/rcpt500/rcpt500.h
clients/tools/Makefile.in
clients/tools/ldapdelete.c
clients/tools/ldapdelete.dsp [new file with mode: 0644]
clients/tools/ldapmodify.c
clients/tools/ldapmodify.dsp [new file with mode: 0644]
clients/tools/ldapmodrdn.c
clients/tools/ldapmodrdn.dsp [new file with mode: 0644]
clients/tools/ldappasswd.c
clients/tools/ldappasswd.dsp [new file with mode: 0644]
clients/tools/ldapsearch.c
clients/tools/ldapsearch.dsp [new file with mode: 0644]
clients/ud/Makefile.in
clients/ud/auth.c
clients/ud/edit.c
clients/ud/find.c
clients/ud/globals.c
clients/ud/group.c
clients/ud/help.c
clients/ud/main.c
clients/ud/mod.c
clients/ud/print.c
clients/ud/string_to_key.c
clients/ud/ud.dsp [new file with mode: 0644]
clients/ud/ud.h
clients/ud/util.c
configure
configure.in
contrib/Makefile.in
contrib/README
contrib/gtk-tool/COPYRIGHT [new file with mode: 0644]
contrib/gtk-tool/ChangeLog [new file with mode: 0644]
contrib/gtk-tool/Gtk_LdapServer.cc [new file with mode: 0644]
contrib/gtk-tool/Gtk_LdapServer.h [new file with mode: 0644]
contrib/gtk-tool/Gtk_LdapTree.cc [new file with mode: 0644]
contrib/gtk-tool/Gtk_LdapTreeItem.cc [new file with mode: 0644]
contrib/gtk-tool/Gtk_LdapTreeItem.h [new file with mode: 0644]
contrib/gtk-tool/INSTALL [new file with mode: 0644]
contrib/gtk-tool/Makefile [new file with mode: 0644]
contrib/gtk-tool/My_Window.cc [new file with mode: 0644]
contrib/gtk-tool/My_Window.h [new file with mode: 0644]
contrib/gtk-tool/README [new file with mode: 0644]
contrib/gtk-tool/TODO [new file with mode: 0644]
contrib/gtk-tool/common.h [new file with mode: 0644]
contrib/gtk-tool/cpluscommon.h [new file with mode: 0644]
contrib/gtk-tool/gtk.h [new file with mode: 0644]
contrib/gtk-tool/icons/monitor.h [new file with mode: 0644]
contrib/gtk-tool/main.cc [new file with mode: 0644]
contrib/gtk-tool/utils.cc [new file with mode: 0644]
contrib/ldaptcl/Makefile.in
contrib/ldaptcl/configure.in
contrib/ldaptcl/ldap.n [new file with mode: 0644]
contrib/ldaptcl/neoXldap.c
contrib/ldaptcl/tkAppInit.c [new file with mode: 0644]
contrib/php3-tool/COPYRIGHT [new file with mode: 0644]
contrib/php3-tool/index.php3 [new file with mode: 0644]
contrib/saucer/Makefile.in
contrib/saucer/main.c
contrib/tweb/Makefile.openldap
contrib/tweb/README
contrib/tweb/dn.c
contrib/tweb/html.c
contrib/tweb/queries.c
contrib/tweb/tgeneral.h
contrib/tweb/tglobal.h
contrib/tweb/tweb.h
contrib/tweb/x500.c
contrib/web_ldap/Makefile.in
contrib/whois++/Makefile
contrib/whois++/whois++.c
doc/Makefile.in
doc/devel/asn-layman.txt [new file with mode: 0644]
doc/devel/guidelines [new file with mode: 0644]
doc/drafts/README
doc/drafts/draft-good-ldap-ldif-xx.txt
doc/drafts/draft-ietf-asid-ldapv3-attributes-03.txt [new file with mode: 0644]
doc/drafts/draft-ietf-ldapext-acl-model-xx.txt
doc/drafts/draft-ietf-ldapext-authmeth-xx.txt [deleted file]
doc/drafts/draft-ietf-ldapext-ldap-c-api-xx.txt
doc/drafts/draft-ietf-ldapext-ldapv3-vlv-xx.txt [new file with mode: 0644]
doc/drafts/draft-ietf-ldapext-locate-xx.txt [new file with mode: 0644]
doc/drafts/draft-ietf-ldapext-sorting-xx.txt [new file with mode: 0644]
doc/drafts/draft-ietf-ldup-framing-xx.txt [new file with mode: 0644]
doc/drafts/draft-ietf-ldup-infomod-xx.txt [new file with mode: 0644]
doc/drafts/draft-ietf-ldup-model-xx.txt [new file with mode: 0644]
doc/drafts/draft-ietf-ldup-protocol-xx.txt [new file with mode: 0644]
doc/drafts/draft-ietf-ldup-replica-req-xx.txt [new file with mode: 0644]
doc/drafts/draft-ietf-ldup-subentry-xx.txt
doc/drafts/draft-ietf-ldup-urp-xx.txt [new file with mode: 0644]
doc/drafts/draft-lachman-laser-ldap-mail-routing-xx.txt [new file with mode: 0644]
doc/drafts/draft-leach-uuids-guids-01.txt [new file with mode: 0644]
doc/drafts/draft-rharrison-ldap-extpartresp-xx.txt [new file with mode: 0644]
doc/drafts/draft-smith-ldap-c-api-ext-vlv-xx.txt [new file with mode: 0644]
doc/man/Makefile.in [new file with mode: 0644]
doc/man/man1/Makefile.in [new file with mode: 0644]
doc/man/man1/ldapdelete.1
doc/man/man1/ldapmodify.1
doc/man/man1/ldapmodrdn.1
doc/man/man1/ldappasswd.1 [new file with mode: 0644]
doc/man/man1/ldapsearch.1
doc/man/man1/ud.1
doc/man/man3/Makefile.in [new file with mode: 0644]
doc/man/man3/cldap_close.3
doc/man/man3/cldap_open.3
doc/man/man3/cldap_search_s.3
doc/man/man3/cldap_setretryinfo.3
doc/man/man3/lber-decode.3
doc/man/man3/lber-decode.3.links [new file with mode: 0644]
doc/man/man3/lber-encode.3
doc/man/man3/lber-encode.3.links [new file with mode: 0644]
doc/man/man3/ldap.3
doc/man/man3/ldap_abandon.3
doc/man/man3/ldap_add.3
doc/man/man3/ldap_bind.3
doc/man/man3/ldap_cache.3
doc/man/man3/ldap_charset.3
doc/man/man3/ldap_compare.3
doc/man/man3/ldap_delete.3
doc/man/man3/ldap_disptmpl.3
doc/man/man3/ldap_entry2text.3
doc/man/man3/ldap_error.3
doc/man/man3/ldap_first_attribute.3
doc/man/man3/ldap_first_entry.3
doc/man/man3/ldap_friendly.3
doc/man/man3/ldap_get_dn.3
doc/man/man3/ldap_get_values.3
doc/man/man3/ldap_getfilter.3
doc/man/man3/ldap_modify.3
doc/man/man3/ldap_modrdn.3
doc/man/man3/ldap_open.3
doc/man/man3/ldap_result.3
doc/man/man3/ldap_schema.3 [new file with mode: 0644]
doc/man/man3/ldap_schema.3.links [new file with mode: 0644]
doc/man/man3/ldap_search.3
doc/man/man3/ldap_searchprefs.3
doc/man/man3/ldap_sort.3
doc/man/man3/ldap_ufn.3
doc/man/man3/ldap_url.3
doc/man/man5/Makefile.in [new file with mode: 0644]
doc/man/man5/ldap.conf.5
doc/man/man5/ldapfilter.conf.5
doc/man/man5/ldapfriendly.5
doc/man/man5/ldapsearchprefs.conf.5
doc/man/man5/ldaptemplates.conf.5
doc/man/man5/ldif.5
doc/man/man5/slapd.conf.5
doc/man/man5/slapd.replog.5
doc/man/man5/ud.conf.5
doc/man/man8/Makefile.in [new file with mode: 0644]
doc/man/man8/centipede.8
doc/man/man8/chlog2replog.8
doc/man/man8/edb2ldif.8
doc/man/man8/go500.8
doc/man/man8/go500gw.8
doc/man/man8/in.xfingerd.8
doc/man/man8/ldif.8
doc/man/man8/mail500.8
doc/man/man8/rcpt500.8
doc/man/man8/slapadd.8
doc/man/man8/slapcat.8
doc/man/man8/slapd.8
doc/man/man8/slurpd.8
doc/rfc/rfc1488.txt [deleted file]
doc/rfc/rfc1558.txt [deleted file]
doc/rfc/rfc2119.txt [new file with mode: 0644]
doc/rfc/rfc2222.txt [new file with mode: 0644]
doc/rfc/rfc2649.txt [new file with mode: 0644]
doc/rfc/rfc2657.txt [new file with mode: 0644]
doc/rfc/rfc2696.txt [new file with mode: 0644]
doc/rfc/rfc2713.txt [new file with mode: 0644]
doc/rfc/rfc2714.txt [new file with mode: 0644]
doc/rfc/rfc2798.txt [new file with mode: 0644]
doc/rfc/rfc2829.txt [new file with mode: 0644]
doc/rfc/rfc2830.txt [new file with mode: 0644]
doc/rfc/rfc2831.txt [new file with mode: 0644]
include/Makefile.in
include/ac/alloca.h
include/ac/assert.h
include/ac/bytes.h
include/ac/crypt.h [new file with mode: 0644]
include/ac/ctype.h
include/ac/dirent.h
include/ac/errno.h
include/ac/krb.h
include/ac/krb5.h [new file with mode: 0644]
include/ac/param.h [new file with mode: 0644]
include/ac/regex.h
include/ac/setproctitle.h
include/ac/signal.h
include/ac/socket.h
include/ac/stdarg.h
include/ac/stdlib.h
include/ac/string.h
include/ac/sysexits.h
include/ac/syslog.h
include/ac/termios.h
include/ac/time.h
include/ac/unistd.h
include/ac/wait.h
include/avl.h
include/disptmpl.h
include/getopt-compat.h
include/lber.h
include/lber_pvt.h
include/lber_types.h.in
include/lber_types.nt
include/ldap.h
include/ldap_cdefs.h
include/ldap_config.h.in
include/ldap_config.nt
include/ldap_defaults.h
include/ldap_features.h.in
include/ldap_features.nt
include/ldap_int_thread.h [new file with mode: 0644]
include/ldap_log.h
include/ldap_pvt.h
include/ldap_pvt_thread.h
include/ldap_schema.h
include/ldbm.h
include/ldif.h
include/lutil.h
include/lutil_lockf.h
include/lutil_md5.h
include/lutil_sha1.h
include/portable.h.in
include/portable.nt
include/setup.dsp
include/setup.mak
include/srchpref.h
include/sysexits-compat.h
libraries/Makefile.in
libraries/libavl/Makefile.in
libraries/libavl/avl.c
libraries/libavl/libavl.dsp [new file with mode: 0644]
libraries/libavl/testavl.c
libraries/libavl/testavl.dsp [new file with mode: 0644]
libraries/liblber/Makefile.in
libraries/liblber/assert.c
libraries/liblber/bprint.c
libraries/liblber/decode.c
libraries/liblber/dtest.c
libraries/liblber/dtest.dsp [new file with mode: 0644]
libraries/liblber/encode.c
libraries/liblber/etest.c
libraries/liblber/etest.dsp [new file with mode: 0644]
libraries/liblber/idtest.c
libraries/liblber/io.c
libraries/liblber/lber-int.h
libraries/liblber/liblber.dsp [new file with mode: 0644]
libraries/liblber/memory.c
libraries/liblber/nt_err.c [new file with mode: 0644]
libraries/liblber/options.c
libraries/liblber/sockbuf.c
libraries/libldap/Makefile.in
libraries/libldap/abandon.c
libraries/libldap/add.c
libraries/libldap/addentry.c
libraries/libldap/apitest.c
libraries/libldap/apitest.dsp [new file with mode: 0644]
libraries/libldap/bind.c
libraries/libldap/cache.c
libraries/libldap/charray.c
libraries/libldap/charset.c [deleted file]
libraries/libldap/cldap.c
libraries/libldap/compare.c
libraries/libldap/controls.c
libraries/libldap/delete.c
libraries/libldap/digest.c [deleted file]
libraries/libldap/disptmpl.c
libraries/libldap/dn.c
libraries/libldap/dnssrv.c [new file with mode: 0644]
libraries/libldap/dsparse.c
libraries/libldap/error.c
libraries/libldap/extended.c
libraries/libldap/free.c
libraries/libldap/friendly.c
libraries/libldap/getattr.c
libraries/libldap/getdn.c
libraries/libldap/getdxbyname.c [deleted file]
libraries/libldap/getentry.c
libraries/libldap/getfilter.c
libraries/libldap/getvalues.c
libraries/libldap/init.c
libraries/libldap/kbind.c
libraries/libldap/ldap-int.h
libraries/libldap/libldap.dsp
libraries/libldap/ltest.dsp [new file with mode: 0644]
libraries/libldap/messages.c
libraries/libldap/modify.c
libraries/libldap/modrdn.c
libraries/libldap/open.c
libraries/libldap/options.c
libraries/libldap/os-ip.c
libraries/libldap/os-local.c [new file with mode: 0644]
libraries/libldap/print.c
libraries/libldap/references.c
libraries/libldap/request.c
libraries/libldap/result.c
libraries/libldap/sasl.c
libraries/libldap/sbind.c
libraries/libldap/schema.c
libraries/libldap/search.c
libraries/libldap/sort.c
libraries/libldap/sortctrl.c [new file with mode: 0644]
libraries/libldap/srchpref.c
libraries/libldap/string.c
libraries/libldap/test.c
libraries/libldap/tls.c
libraries/libldap/tmplout.c
libraries/libldap/tmpltest.c
libraries/libldap/ufn.c
libraries/libldap/unbind.c
libraries/libldap/url.c
libraries/libldap/utf-8.c [new file with mode: 0644]
libraries/libldap/util-int.c
libraries/libldap/vlvctrl.c [new file with mode: 0644]
libraries/libldap_r/Makefile.in
libraries/libldap_r/apitest_r.dsp [new file with mode: 0644]
libraries/libldap_r/libldap_r.dsp [new file with mode: 0644]
libraries/libldap_r/ltest_r.dsp [new file with mode: 0644]
libraries/libldap_r/rdwr.c
libraries/libldap_r/thr_cthreads.c
libraries/libldap_r/thr_lwp.c
libraries/libldap_r/thr_nt.c
libraries/libldap_r/thr_posix.c
libraries/libldap_r/thr_pth.c
libraries/libldap_r/thr_sleep.c [deleted file]
libraries/libldap_r/thr_stub.c
libraries/libldap_r/thr_thr.c
libraries/libldap_r/threads.c [new file with mode: 0644]
libraries/libldap_r/tpool.c [new file with mode: 0644]
libraries/libldbm/Makefile.in
libraries/libldbm/ldbm.c
libraries/libldbm/libldbm.dsp [new file with mode: 0644]
libraries/libldif/Makefile.in
libraries/libldif/fetch.c
libraries/libldif/libldif.dsp
libraries/libldif/line64.c
libraries/liblutil/Makefile.in
libraries/liblutil/authpasswd.c [new file with mode: 0644]
libraries/liblutil/base64.c
libraries/liblutil/debug.c
libraries/liblutil/detach.c
libraries/liblutil/entropy.c [new file with mode: 0644]
libraries/liblutil/getopt.c
libraries/liblutil/getpass.c
libraries/liblutil/liblutil.dsp
libraries/liblutil/lockf.c
libraries/liblutil/md5.c
libraries/liblutil/nt_err.c [deleted file]
libraries/liblutil/ntservice.c
libraries/liblutil/passwd.c
libraries/liblutil/passwd.dsp [new file with mode: 0644]
libraries/liblutil/passwd.dsw [new file with mode: 0644]
libraries/liblutil/ptest.c [new file with mode: 0644]
libraries/liblutil/sha1.c
libraries/liblutil/slapdmsg.bin [new file with mode: 0644]
libraries/liblutil/slapdmsg.h [new file with mode: 0644]
libraries/liblutil/slapdmsg.rc [new file with mode: 0644]
libraries/liblutil/sockpair.c
libraries/liblutil/utils.c
servers/Makefile.in
servers/slapd/Makefile.in
servers/slapd/abandon.c
servers/slapd/acl.c
servers/slapd/aclparse.c
servers/slapd/ad.c [new file with mode: 0644]
servers/slapd/add.c
servers/slapd/at.c [new file with mode: 0644]
servers/slapd/attr.c
servers/slapd/ava.c
servers/slapd/back-bdb2/Makefile.in [deleted file]
servers/slapd/back-bdb2/abandon.c [deleted file]
servers/slapd/back-bdb2/add.c [deleted file]
servers/slapd/back-bdb2/alias.c [deleted file]
servers/slapd/back-bdb2/attr.c [deleted file]
servers/slapd/back-bdb2/back-bdb2.h [deleted file]
servers/slapd/back-bdb2/bind.c [deleted file]
servers/slapd/back-bdb2/cache.c [deleted file]
servers/slapd/back-bdb2/close.c [deleted file]
servers/slapd/back-bdb2/compare.c [deleted file]
servers/slapd/back-bdb2/config.c [deleted file]
servers/slapd/back-bdb2/dbcache.c [deleted file]
servers/slapd/back-bdb2/delete.c [deleted file]
servers/slapd/back-bdb2/dn2id.c [deleted file]
servers/slapd/back-bdb2/entry.c [deleted file]
servers/slapd/back-bdb2/external.h [deleted file]
servers/slapd/back-bdb2/filterindex.c [deleted file]
servers/slapd/back-bdb2/group.c [deleted file]
servers/slapd/back-bdb2/id2children.c [deleted file]
servers/slapd/back-bdb2/id2entry.c [deleted file]
servers/slapd/back-bdb2/idl.c [deleted file]
servers/slapd/back-bdb2/index.c [deleted file]
servers/slapd/back-bdb2/init.c [deleted file]
servers/slapd/back-bdb2/kerberos.c [deleted file]
servers/slapd/back-bdb2/modify.c [deleted file]
servers/slapd/back-bdb2/modrdn.c [deleted file]
servers/slapd/back-bdb2/nextid.c [deleted file]
servers/slapd/back-bdb2/porter.c [deleted file]
servers/slapd/back-bdb2/proto-back-bdb2.h [deleted file]
servers/slapd/back-bdb2/search.c [deleted file]
servers/slapd/back-bdb2/startup.c [deleted file]
servers/slapd/back-bdb2/timing.c [deleted file]
servers/slapd/back-bdb2/tools.c [deleted file]
servers/slapd/back-bdb2/txn.c [deleted file]
servers/slapd/back-bdb2/txn.h [deleted file]
servers/slapd/back-bdb2/unbind.c [deleted file]
servers/slapd/back-dnssrv/Makefile.in [new file with mode: 0644]
servers/slapd/back-dnssrv/add.c [new file with mode: 0644]
servers/slapd/back-dnssrv/back-dnssrv.h [new file with mode: 0644]
servers/slapd/back-dnssrv/bind.c [new file with mode: 0644]
servers/slapd/back-dnssrv/compare.c [new file with mode: 0644]
servers/slapd/back-dnssrv/config.c [new file with mode: 0644]
servers/slapd/back-dnssrv/delete.c [new file with mode: 0644]
servers/slapd/back-dnssrv/external.h [new file with mode: 0644]
servers/slapd/back-dnssrv/init.c [new file with mode: 0644]
servers/slapd/back-dnssrv/modify.c [new file with mode: 0644]
servers/slapd/back-dnssrv/modrdn.c [new file with mode: 0644]
servers/slapd/back-dnssrv/request.c [new file with mode: 0644]
servers/slapd/back-dnssrv/search.c [new file with mode: 0644]
servers/slapd/back-ldap/Makefile.in
servers/slapd/back-ldap/add.c
servers/slapd/back-ldap/back-ldap.h
servers/slapd/back-ldap/bind.c
servers/slapd/back-ldap/compare.c
servers/slapd/back-ldap/config.c
servers/slapd/back-ldap/delete.c
servers/slapd/back-ldap/external.h
servers/slapd/back-ldap/group.c [new file with mode: 0644]
servers/slapd/back-ldap/init.c
servers/slapd/back-ldap/modify.c
servers/slapd/back-ldap/modrdn.c
servers/slapd/back-ldap/search.c
servers/slapd/back-ldap/unbind.c
servers/slapd/back-ldbm/Makefile.in
servers/slapd/back-ldbm/abandon.c
servers/slapd/back-ldbm/add.c
servers/slapd/back-ldbm/alias.c
servers/slapd/back-ldbm/attr.c
servers/slapd/back-ldbm/back-ldbm.h
servers/slapd/back-ldbm/backldbm.dsp
servers/slapd/back-ldbm/bind.c
servers/slapd/back-ldbm/cache.c
servers/slapd/back-ldbm/close.c
servers/slapd/back-ldbm/compare.c
servers/slapd/back-ldbm/config.c
servers/slapd/back-ldbm/dbcache.c
servers/slapd/back-ldbm/delete.c
servers/slapd/back-ldbm/dn2id.c
servers/slapd/back-ldbm/entry.c
servers/slapd/back-ldbm/extended.c [new file with mode: 0644]
servers/slapd/back-ldbm/external.h
servers/slapd/back-ldbm/filterindex.c
servers/slapd/back-ldbm/group.c
servers/slapd/back-ldbm/id2children.c
servers/slapd/back-ldbm/id2entry.c
servers/slapd/back-ldbm/idl.c
servers/slapd/back-ldbm/index.c
servers/slapd/back-ldbm/init.c
servers/slapd/back-ldbm/kerberos.c [deleted file]
servers/slapd/back-ldbm/key.c [new file with mode: 0644]
servers/slapd/back-ldbm/modify.c
servers/slapd/back-ldbm/modrdn.c
servers/slapd/back-ldbm/nextid.c
servers/slapd/back-ldbm/passwd.c [new file with mode: 0644]
servers/slapd/back-ldbm/proto-back-ldbm.h
servers/slapd/back-ldbm/sasl.c [new file with mode: 0644]
servers/slapd/back-ldbm/search.c
servers/slapd/back-ldbm/startup.c [deleted file]
servers/slapd/back-ldbm/tools.c
servers/slapd/back-ldbm/unbind.c
servers/slapd/back-passwd/Makefile.in
servers/slapd/back-passwd/external.h
servers/slapd/back-passwd/init.c
servers/slapd/back-passwd/search.c
servers/slapd/back-perl/Makefile.in [deleted file]
servers/slapd/back-perl/add.c [deleted file]
servers/slapd/back-perl/bind.c [deleted file]
servers/slapd/back-perl/close.c [deleted file]
servers/slapd/back-perl/compare.c [deleted file]
servers/slapd/back-perl/config.c [deleted file]
servers/slapd/back-perl/delete.c [deleted file]
servers/slapd/back-perl/external.h [deleted file]
servers/slapd/back-perl/init.c [deleted file]
servers/slapd/back-perl/modify.c [deleted file]
servers/slapd/back-perl/modrdn.c [deleted file]
servers/slapd/back-perl/perl_back.h [deleted file]
servers/slapd/back-perl/search.c [deleted file]
servers/slapd/back-perl/unbind.c [deleted file]
servers/slapd/back-shell/Makefile.in
servers/slapd/back-shell/abandon.c
servers/slapd/back-shell/add.c
servers/slapd/back-shell/bind.c
servers/slapd/back-shell/compare.c
servers/slapd/back-shell/config.c
servers/slapd/back-shell/delete.c
servers/slapd/back-shell/external.h
servers/slapd/back-shell/fork.c
servers/slapd/back-shell/init.c
servers/slapd/back-shell/modify.c
servers/slapd/back-shell/modrdn.c
servers/slapd/back-shell/result.c
servers/slapd/back-shell/search.c
servers/slapd/back-shell/searchexample.conf
servers/slapd/back-shell/searchexample.sh
servers/slapd/back-shell/shell.h
servers/slapd/back-shell/unbind.c
servers/slapd/back-tcl/Makefile.in [deleted file]
servers/slapd/back-tcl/external.h [deleted file]
servers/slapd/back-tcl/tcl_abandon.c [deleted file]
servers/slapd/back-tcl/tcl_add.c [deleted file]
servers/slapd/back-tcl/tcl_back.h [deleted file]
servers/slapd/back-tcl/tcl_bind.c [deleted file]
servers/slapd/back-tcl/tcl_close.c [deleted file]
servers/slapd/back-tcl/tcl_compare.c [deleted file]
servers/slapd/back-tcl/tcl_config.c [deleted file]
servers/slapd/back-tcl/tcl_delete.c [deleted file]
servers/slapd/back-tcl/tcl_init.c [deleted file]
servers/slapd/back-tcl/tcl_modify.c [deleted file]
servers/slapd/back-tcl/tcl_modrdn.c [deleted file]
servers/slapd/back-tcl/tcl_search.c [deleted file]
servers/slapd/back-tcl/tcl_unbind.c [deleted file]
servers/slapd/back-tcl/tcl_util.c [deleted file]
servers/slapd/backend.c
servers/slapd/bind.c
servers/slapd/ch_malloc.c
servers/slapd/charray.c
servers/slapd/compare.c
servers/slapd/config.c
servers/slapd/configinfo.c
servers/slapd/connection.c
servers/slapd/controls.c
servers/slapd/daemon.c
servers/slapd/delete.c
servers/slapd/dn.c
servers/slapd/entry.c
servers/slapd/extended.c
servers/slapd/filter.c
servers/slapd/filterentry.c
servers/slapd/index.c [new file with mode: 0644]
servers/slapd/init.c
servers/slapd/kerberos.c [new file with mode: 0644]
servers/slapd/libslapd.dsp
servers/slapd/lock.c
servers/slapd/main.c
servers/slapd/modify.c
servers/slapd/modrdn.c
servers/slapd/module.c
servers/slapd/monitor.c
servers/slapd/mr.c [new file with mode: 0644]
servers/slapd/nt_svc.c
servers/slapd/oc.c [new file with mode: 0644]
servers/slapd/operation.c
servers/slapd/passwd.c [new file with mode: 0644]
servers/slapd/phonetic.c
servers/slapd/proto-slap.h
servers/slapd/repl.c
servers/slapd/result.c
servers/slapd/root_dse.c
servers/slapd/sasl.c
servers/slapd/schema.c
servers/slapd/schema/core.schema
servers/slapd/schema/cosine.schema [new file with mode: 0644]
servers/slapd/schema/inetorgperson.schema [new file with mode: 0644]
servers/slapd/schema/internet_mail.at.conf [deleted file]
servers/slapd/schema/internet_mail.oc.conf [deleted file]
servers/slapd/schema/microsoft.ext.schema [new file with mode: 0644]
servers/slapd/schema/microsoft.schema [new file with mode: 0644]
servers/slapd/schema/microsoft.std.schema [new file with mode: 0644]
servers/slapd/schema/misc.schema
servers/slapd/schema/nadf.schema
servers/slapd/schema/nis.at.conf [deleted file]
servers/slapd/schema/nis.oc.conf [deleted file]
servers/slapd/schema/nis.schema
servers/slapd/schema/openldap.schema [new file with mode: 0644]
servers/slapd/schema/others_nis.at.conf [deleted file]
servers/slapd/schema/others_nis.oc.conf [deleted file]
servers/slapd/schema/pilot.schema
servers/slapd/schema_check.c [new file with mode: 0644]
servers/slapd/schema_init.c [new file with mode: 0644]
servers/slapd/schema_prep.c [new file with mode: 0644]
servers/slapd/schemaparse.c
servers/slapd/search.c
servers/slapd/shell-backends/Makefile.in
servers/slapd/shell-backends/passwd-shell.c
servers/slapd/shell-backends/pwd-Version.c [deleted file]
servers/slapd/shell-backends/shellutil.c
servers/slapd/slap.h
servers/slapd/slapd.at.conf [deleted file]
servers/slapd/slapd.conf
servers/slapd/slapd.dsp [new file with mode: 0644]
servers/slapd/slapd.oc.conf [deleted file]
servers/slapd/starttls.c [new file with mode: 0644]
servers/slapd/str2filter.c
servers/slapd/suffixalias.c
servers/slapd/syntax.c [new file with mode: 0644]
servers/slapd/tools/Makefile.in
servers/slapd/tools/ldbmtest.c
servers/slapd/tools/ldbmtest.dsp
servers/slapd/tools/ldif.c
servers/slapd/tools/ldif.dsp
servers/slapd/tools/mimic.c
servers/slapd/tools/slapadd.c
servers/slapd/tools/slapadd.dsp
servers/slapd/tools/slapcat.c
servers/slapd/tools/slapcat.dsp
servers/slapd/tools/slapcommon.c
servers/slapd/tools/slapcommon.h
servers/slapd/tools/slapindex.c
servers/slapd/tools/slapindex.dsp
servers/slapd/tools/slappasswd.c [new file with mode: 0644]
servers/slapd/unbind.c
servers/slapd/user.c
servers/slapd/value.c
servers/slurpd/Makefile.in
servers/slurpd/args.c
servers/slurpd/config.c
servers/slurpd/globals.c
servers/slurpd/globals.h
servers/slurpd/ldap_op.c
servers/slurpd/lock.c
servers/slurpd/main.c
servers/slurpd/replog.c
servers/slurpd/rq.c
servers/slurpd/sanity.c
servers/slurpd/slurp.h
servers/slurpd/st.c
tests/Makefile.in
tests/README
tests/data/acl.out.master
tests/data/do_add.1
tests/data/modify.out.master
tests/data/modrdn.out.master
tests/data/modrdn.out.master.0
tests/data/modrdn.out.master.1
tests/data/modrdn.out.master.2 [new file with mode: 0644]
tests/data/modrdn.out.master.3
tests/data/passwd.ldif [new file with mode: 0644]
tests/data/search.out.master
tests/data/slapd-acl.conf
tests/data/slapd-bdb2-acl.conf
tests/data/slapd-bdb2-pw.conf [new file with mode: 0644]
tests/data/slapd-bdb2-repl-slave.conf
tests/data/slapd-dnssrv.conf [new file with mode: 0644]
tests/data/slapd-master.conf
tests/data/slapd-passwd.conf
tests/data/slapd-pw.conf [new file with mode: 0644]
tests/data/slapd-ref-slave.conf
tests/data/slapd-repl-master.conf
tests/data/slapd-repl-slave.conf
tests/data/slapd.at.conf [deleted file]
tests/data/slapd.oc.conf [deleted file]
tests/data/test-ordered.ldif
tests/data/test.ldif
tests/progs/Makefile.in
tests/progs/slapd-addel.c
tests/progs/slapd-read.c
tests/progs/slapd-search.c
tests/progs/slapd-tester.c
tests/scripts/defines.sh
tests/scripts/passwd-search
tests/scripts/test001-slapadd
tests/scripts/test002-populate
tests/scripts/test003-search
tests/scripts/test004-modify
tests/scripts/test005-modrdn
tests/scripts/test006-acls
tests/scripts/test007-replication
tests/scripts/test008-concurrency
tests/scripts/test009-referral
tests/scripts/test010-passwd [new file with mode: 0755]

index 0075060e709f79413bb850bb0ad360109104b645..eed58ebbe12f0bf3427e1154a363baeb884378b0 100644 (file)
-                       A N N O U N C E M E N T
-
-                              LDAP 3.3
-
-    The University of Michigan is pleased to announce release 3.3 of
-    UM-LDAP, an implementation of the Lightweight Directory Access
-    Protocol. LDAP is a draft Internet standard directory service
-    protocol that runs over TCP/IP. It can be used to provide a
-    stand-alone directory service, or to provide lightweight access to
-    the X.500 directory.  LDAP is defined by RFC 1777 and RFC 1778.
-
-    This release includes the following components:
-
-       - slapd - a stand-alone LDAP directory server
-       - slurpd - a stand-alone LDAP replication server
-       - ldapd - an LDAP-to-X.500 gateway server
-       - centipede - an LDAP centroid generation and maintenance program
-       - libldap - an LDAP client library
-       - liblber - a lightweight BER/DER encoding/decoding library
-       - ldif tools - data conversion tools for use with slapd
-       - in.xfingerd - a finger-to-LDAP gateway server
-       - go500 - a gopher-to-LDAP gateway server for searching
-       - go500gw - a gopher-to-LDAP gateway server for searching and browsing
-       - rcpt500 - an email-to-LDAP query responder
-       - mail500 - an LDAP-capable mailer
-       - fax500 - an LDAP-capable mailer that supports remote printing
-       - LDAP tools - A collection of shell-based LDAP utility programs
-
-    In addition, there are some contributed components:
-
-       - web500 - an HTTP-to-LDAP gateway
-       - whois++d - a WHOIS++-to-LDAP gateway
-       - saucer - a simple command-line oriented client program
-
-CHANGES
-
-    Changes since release 3.2 of LDAP include
-
-       - slurpd has been rewritten as a single process threaded daemon
-       - ldaptools (ldapsearch, etc) now support the LDIF format
-       - support for LDAP URLs added to libldap
-       - improved support for LDAP referrals in libldap
-       - preliminary test scripts included
-       - support for additional platforms
-       - various bug fixes and build fixes
-
-    See the CHANGES file in the distribution for more details.
+       A N N O U N C E M E N T
+
+       OpenLDAP 2.0-Alpha
+
+       The OpenLDAP Project is pleased to announce the availability
+       of OpenLDAP 2.0-Alpha, a suite of the Lightweight Weight
+       Directory Protocol servers, clients, utilities, and development tools.
+
+       This alpha release is for REFERENCE PURPOSES ONLY.
+       This alpha release is NOT for GENERAL USE.
+       This alpha release is NOT feature complete nor well tested.
+
+       This release contains the following major enhancements:
+
+               * LDAPv3 support
+                       + RFC2251-2256
+                       + named referrals
+                       + DNS SRV location
+               * SASL support
+               * TLS/SSL support
+               * IPv6 support
+               * LDAP over IPC support
+               * Updated C API 
+               * Enhanced Standalone LDAP Server:
+                       + Updated Access Control System
+                       + Thread Pooling
+                       + DNS SRV referral backend
+                       + LDAP backend
+                       + Better tools
+
+       This release includes the following major components:
+
+               * slapd - a stand-alone LDAP directory server
+               * slurpd - a stand-alone LDAP replication server
+               * -lldap - an LDAP client library
+               * -llber - a lightweight BER/DER encoding/decoding library
+               * LDIF tools - data conversion tools for use with slapd
+               * LDAP gateways - finger, gopher, email to LDAP gateways
+               * LDAP mailer - sendmail-compatibile mail delivery agents
+               * LDAP tools - A collection of command line LDAP utility programs
+
+       In addition, there are some contributed components:
+
+               * ldapTCL - the NeoSoft TCL LDAP SDK 
+               * gtk-tool - a demonstration ldap interface written gtk
+               * php3-tool - a demonstration ldap interface written php3 
+               * saucer - a simple command-line oriented client program
+               * whois++d - a WHOIS++-to-LDAP gateway
+
+
+ACKNOWLEDGEMENTS
+
+       OpenLDAP is developed by a team of volunteers whose use
+       the Internet to coordinate their activities.   The project is
+       managed by the OpenLDAP Foundation.
+
+       OpenLDAP LDAP implementation is derived from University of
+       Michigan LDAP release 3.3.
+
 
 AVAILABILITY
 
-    This software is freely available to anyone for any lawful purpose,
-    subject to the U-M copyright notice and disclaimer.  The software is
-    available for anonymous ftp from the following location:
+       This software is available under the OpenLDAP Public License,
+       an unrestrictive, "free," OSS-approved open source license.
+       For download information is available at:
+
+               http://www.OpenLDAP.org/software/download/
 
-       ftp://terminator.rs.itd.umich.edu/ldap/ldap-3.3.tar.Z
 
 SUPPORT
 
-    The software is provided as is without any express or implied
-    warranty, but there is a bug reporting mail address which is
-    responded to on a best-effort basis:
+       OpenLDAP software is user supported
+
+               http://www.openldap.org/support/
+
+       The project maintains a FAQ which you may find useful:
+
+               http://www.openldap.org/faq/
 
-       ldap-support@umich.edu
+       In addition, there are also a number of discussion lists
+       related OpenLDAP.  A list of mailing lists is available at:
 
-    In addition, there is a discussion list for issues relating to this
-    implementation of ldap:
+               http://www.OpenLDAP.org/lists/
 
-       ldap@umich.edu                  -- discussion list
-       ldap-request@umich.edu          -- to join the list
+       To report bugs, please use project's Issue Tracking System:
 
-    Comments or questions about the LDAP protocol in general should be
-    sent to the IETF ASID discussion group:
+               http://www.openldap.org/its/
 
-       ietf-asid@umich.edu             -- discussion list
-       ietf-asid-request@umich.edu     -- to join the list
+       The OpenLDAP home page containing lots of interesting information
+       and online documentation is available at this URL:
 
-    An LDAP home page containing lots of interesting information and
-    online documentation is available at this URL:
+               http://www.OpenLDAP.org/
 
-        http://www.umich.edu/~rsug/ldap/
 
 SUPPORTED PLATFORMS
 
-    This release has been ported to many UNIX platforms, including
-    SunOS 4.1.x, Solaris 2.x, Ultrix 4.3, HP-UX 9.05, AIX 3.2.5,
-    SCO, FreeBSD, NetBSD, LINUX, IRIX, Digital Unix (OSF/1), and
-    NeXTSTEP 3.2.  This release has also been ported to VMS.
+       This release has been ported to many UNIX (and UNIX-like) platforms
+       including FreeBSD, Linux, NetBSD, OpenBSD and most commericial
+       UNIX systems.  The release has also been ported (in part or in whole)
+       to other platforms including BeOS, MacOS, and MS Windows NT/2000.
 
-    The client libraries and some clients have also been ported to
-    MacOS 7.x, MSDOS (some TCP stacks), and MS Windows 3.1/95/NT.
index 5450dd0d1d1307fee1eb6d3a6f1bcb5f6bc08537..305fc2609f351d4c717ed156657123c95a4bc882 100644 (file)
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -1,4 +1,4 @@
-Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+Copyright 1998-2000 The OpenLDAP Foundation
 All rights reserved.
 
 Redistribution and use in source and binary forms are permitted only
diff --git a/INSTALL b/INSTALL
index 8f3685d0857610aeeb8a3b74c2e49ee2f53b732b..77fe82016acb5f9ca5974c695192cb793faf4bf2 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -4,8 +4,7 @@ Making and Installing the OpenLDAP Distribution
 ** It is recommended that you read or at least skim through ALL of the
 ** instructions in this file before attempting to build the software.
 **
-** A Quick Start Guide, which may be used in conjunction with this
-** document, is available at:
+** The OpenLDAP Quick Start Guide is available at:
 **    http://www.openldap.org/faq/index.cgi?file=172
 **
 ** The OpenLDAP Installation FAQ is available at:
@@ -91,8 +90,7 @@ these steps:
  7. install the binaries and man pages.  You may need to be superuser to
     do this (depending on where you are installing things):
 
-       % su
-       # make install
+       % su root -c make install
 
     That's it!
 
@@ -157,8 +155,9 @@ The configure script will also use your environmental
 variables for determining compiler/linker options.   This can
 be used to manual specify features and compilation options.
 
-NOTE: If you change environment setting, be sure to remove
-       any config.cache before running ./configure.
+WARNING: Executable built in your environment may not run
+       in your user's environments.  The portability of
+       executables between environments is your responsibility.
 
 Supported Environmental Variables
        CC                      C compiler              (cc, egcc)
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..123dfc3
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,51 @@
+The OpenLDAP Public License
+  Version 2.2.1, 1 March 2000
+
+Redistribution and use of this software and associated documentation
+("Software"), with or without modification, are permitted provided
+that the following conditions are met:
+
+1. Redistributions of source code must retain copyright statements
+and notices.  Redistributions must also contain a copy of this
+document.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the
+distribution.
+
+3. The name "OpenLDAP" must not be used to endorse or promote
+products derived from this Software without prior written permission
+of the OpenLDAP Foundation.
+
+4. Products derived from this Software may not be called "OpenLDAP"
+nor may "OpenLDAP" appear in their names without prior written
+permission of the OpenLDAP Foundation.
+
+5. Due credit should be given to the OpenLDAP Project
+(http://www.openldap.org/).
+
+6. The OpenLDAP Foundation may revise this license from time to
+time.  Each revision is distinguished by a version number.  You
+may use the Software under terms of this license revision or under
+the terms of any subsequent revision of the license.
+
+THIS SOFTWARE IS PROVIDED BY THE OPENLDAP FOUNDATION AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+THE OPENLDAP FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+
+OpenLDAP is a trademark of the OpenLDAP Foundation.
+
+Copyright 1999-2000 The OpenLDAP Foundation, Redwood City,
+California, USA.  All Rights Reserved.  Permission to copy and
+distributed verbatim copies of this document is granted.
+
index a4c7025afa95cbc69d63d06fea304d5a35b547d9..3a33861dd693eb0a5a00027849945b6194b32219 100644 (file)
@@ -1,7 +1,7 @@
 # $OpenLDAP$
 # Master Makefile for OpenLDAP
 ##
-## Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+## Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
 ## All rights reserved.
 ##
 ## Redistribution and use in source and binary forms are permitted only
@@ -28,3 +28,6 @@ veryclean-local: FORCE
        $(RM) config.cache config.status libtool stamp-h stamp-h.in
 
 distclean: veryclean FORCE
+
+test: FORCE
+       cd tests; make test
diff --git a/README b/README
index 6c4371cca39e9abec3acc7767f90599bad93589b..dcbf546807f1c0b53bbce0cea11857ad999aaf6c 100644 (file)
--- a/README
+++ b/README
@@ -1,16 +1,21 @@
-OpenLDAP Release 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.
+OpenLDAP 2.0 Alpha README
+       This is an alpha release of OpenLDAP 2.0.  It is provided
+       for reference purposes only.  It is not for general use.
+
+       The OpenLDAP Developer's FAQ is available at:
+               http://www.openldap.org/faq/index.cgi?file=4
+
+       Developer's and early testers should provide feedback regarding
+       this release to the openldap-devel@openldap.org mailing list.
+       As this release is not intended for general use, no general
+       use questions will be answered.   Developer's wishing to
+       contribute changes should work with latest devel codes, this
+       snapshot is for reference purposes only.
 
        For a more detailed description of how to make an install the
        distribution, see the INSTALL file in this directory.  Additional
-       installation information, such as per platform hints can be found
-       in the doc/install directory.
-
-       For more information:
-               http://www.OpenLDAP.org/software/
+       installation information can be found on the OpenLDAP website:
+               http://www.openldap.org/
 
 
 REQUIRED SOFTWARE
@@ -26,7 +31,7 @@ REQUIRED SOFTWARE
 
        SLURPD:
                LTHREAD compatible thread package
-                       (POSIX pthreads, MIT pthreads, Mach Cthreads or Sun LWP)
+                       (POSIX threads, Mach Cthreads, Sun LWP, or GNU Pth)
 
        CLIENTS/CONTRIB ware:
                Depends on package.  See per package README.
@@ -52,21 +57,21 @@ DOCUMENTATION
        etc..  It is located at:
                http://www.OpenLDAP.org/
 
+       The OpenLDAP Quick Start Guide is available at:
+               http://www.openldap.org/faq/index.cgi?file=172
+
        The OpenLDAP Software FAQ is available at:
                http://www.openldap.org/faq/index.cgi?file=2
 
 
-FEEDBACK / PROBLEM REPORTS / DISCUSSIONS
-       We would appreciate any feedback you can provide.  If you have
-       problems, report them using our Issue Tracking System:
-
-               http://www.OpenLDAP.com/its/
-
-       or by sending e-mail to:
-
-               OpenLDAP-its@OpenLDAP.org
-
-       Additional mailing lists are available.  Please see:
-
-               http://www.OpenLDAP.com/lists/
+SUPPORT / FEEDBACK / PROBLEM REPORTS / DISCUSSIONS
+       OpenLDAP is user supported.  If you have problems, please
+       review the OpenLDAP FAQ <http://www.openldap.org/faq/> and
+       archives of the OpenLDAP-software and OpenLDAP-bugs mailing
+       lists <http://www.openldap.org/lists/>.
 
+       Issues, such as bug reports, should be reported using our
+       our Issue Tracking System <http://www.OpenLDAP.com/its/> or
+       by sending mail to OpenLDAP-its@OpenLDAP.org.  Do not use
+       this system for general or software equiries.  Please direct
+       these to the appropriate mailing list.
index 9c89097b37d696485674aa432e138f6c2f9f923f..cd6ad29d45142e73ec0227b093a89593539bda09 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 #define _LDAP_PORTABLE_H
 
 /* end of preamble */
+
+#if !defined(SLAPD_SCHEMA_COMPAT) && !defined(SLAPD_SCHEMA_NOT_COMPAT)
+       /* define SLAPD_SCHEMA_COMPAT if you want old schema codes */
+#define SLAPD_SCHEMA_NOT_COMPAT 1
+#endif
+
 @TOP@
 
 /* define this if needed to get reentrant functions */
@@ -47,7 +53,7 @@
 /*
        LDAP_API_FEATURE_X_OPENLDAP_REENTRANT
        LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE
-       LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
+       LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
        LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
 */
 
        LBER_TAG_T
 */
 
+/* define to character address type */
+#undef caddr_t
+
+/* define to signed size type */
+#undef ssize_t
+
 \f
 /* Leave that blank line there!!  Autoheader needs it. */
 
 @BOTTOM@
+
 /* begin of postamble */
 
+#ifdef _WIN32
+       /* don't suck in all of the win32 api */
+#      define WIN32_LEAN_AND_MEAN 1
+#endif
+
 #ifndef __NEED_PROTOTYPES
 /* force LDAP_P to always include prototypes */
 #define __NEED_PROTOTYPES 1
index 35f9931fee7a87f9e0b27cb8891a4c7eef918445..5590d0fc99d8c1b331f0775c3c06182e32c50c90 100644 (file)
@@ -1,8 +1,9 @@
 dnl $OpenLDAP$
 dnl
-dnl Copyright 1998-1999 The OpenLDAP Foundation,  All Rights Reserved.
+dnl Copyright 1998-2000 The OpenLDAP Foundation,  All Rights Reserved.
 dnl COPYING RESTRICTIONS APPLY, See COPYRIGHT file
 dnl
 dnl OpenLDAP Autoconf Macros
 dnl
+divert(-1)
 builtin(include, build/openldap.m4)dnl
index 008ce7166446e15c08bfb87ed06218803d313516..9e714628bc9ce06c5b95af3efafc91231c016918 100644 (file)
@@ -12,11 +12,12 @@ dnl PARTICULAR PURPOSE.
 
 dnl $OpenLDAP$
 dnl
-dnl Copyright 1998-1999 The OpenLDAP Foundation,  All Rights Reserved.
+dnl Copyright 1998-2000 The OpenLDAP Foundation,  All Rights Reserved.
 dnl COPYING RESTRICTIONS APPLY, See COPYRIGHT file
 dnl
 dnl OpenLDAP Autoconf Macros
 dnl
+divert(-1)
 builtin(include, build/openldap.m4)dnl
 
 # Do all the work for Automake.  This macro actually does too much --
@@ -147,7 +148,7 @@ LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
 LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
 DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
 ${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
-$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $lt_target \
 || AC_MSG_ERROR([libtool configure failed])
 
 # Reload cache, that may have been modified by ltconfig
@@ -179,6 +180,11 @@ AC_REQUIRE([AC_PROG_NM])dnl
 AC_REQUIRE([AC_PROG_LN_S])dnl
 dnl
 
+case "$target" in
+NONE) lt_target="$host" ;;
+*) lt_target="$target" ;;
+esac
+
 # Check for any special flags to pass to ltconfig.
 libtool_flags="--cache-file=$cache_file"
 test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
@@ -197,7 +203,7 @@ test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
 
 # Some flags need to be propagated to the compiler or linker for good
 # libtool support.
-case "$host" in
+case "$lt_target" in
 *-*-irix6*)
   # Find out which ABI we are using.
   echo '[#]line __oline__ "configure"' > conftest.$ac_ext
@@ -413,7 +419,6 @@ else
   AC_MSG_RESULT(no)
 fi
 test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
-AC_SUBST(LD)
 AC_PROG_LD_GNU
 ])
 
@@ -459,14 +464,13 @@ else
 fi])
 NM="$ac_cv_path_NM"
 AC_MSG_RESULT([$NM])
-AC_SUBST(NM)
 ])
 
 # AC_CHECK_LIBM - check for math library
 AC_DEFUN(AC_CHECK_LIBM,
 [AC_REQUIRE([AC_CANONICAL_HOST])dnl
 LIBM=
-case "$host" in
+case "$lt_target" in
 *-*-beos* | *-*-cygwin*)
   # These system don't have libm
   ;;
diff --git a/build/build.dsp b/build/build.dsp
new file mode 100644 (file)
index 0000000..3103133
--- /dev/null
@@ -0,0 +1,172 @@
+# Microsoft Developer Studio Project File - Name="build" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) External Target" 0x0106
+
+CFG=build - Win32 DLL Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "build.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "build.mak" CFG="build - Win32 DLL Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "build - Win32 Release" (based on "Win32 (x86) External Target")
+!MESSAGE "build - Win32 Debug" (based on "Win32 (x86) External Target")
+!MESSAGE "build - Win32 Single Debug" (based on "Win32 (x86) External Target")
+!MESSAGE "build - Win32 Single Release" (based on\
+ "Win32 (x86) External Target")
+!MESSAGE "build - Win32 DLL Debug" (based on "Win32 (x86) External Target")
+!MESSAGE "build - Win32 DLL Release" (based on "Win32 (x86) External Target")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+
+!IF  "$(CFG)" == "build - Win32 Release"
+
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Cmd_Line "NMAKE /f build.mak"
+# PROP BASE Rebuild_Opt "/a"
+# PROP BASE Target_File "build.exe"
+# PROP BASE Bsc_Name "build.bsc"
+# PROP BASE Target_Dir ""
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Cmd_Line "NMAKE /f build.mak"
+# PROP Rebuild_Opt "/a"
+# PROP Target_File "build.txt"
+# PROP Bsc_Name "build.bsc"
+# PROP Target_Dir ""
+
+!ELSEIF  "$(CFG)" == "build - Win32 Debug"
+
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Cmd_Line "NMAKE /f build.mak"
+# PROP BASE Rebuild_Opt "/a"
+# PROP BASE Target_File "build.exe"
+# PROP BASE Bsc_Name "build.bsc"
+# PROP BASE Target_Dir ""
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Cmd_Line ""
+# PROP Rebuild_Opt ""
+# PROP Bsc_Name ""
+# PROP Target_Dir ""
+
+!ELSEIF  "$(CFG)" == "build - Win32 Single Debug"
+
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "build___"
+# PROP BASE Intermediate_Dir "build___"
+# PROP BASE Cmd_Line ""
+# PROP BASE Rebuild_Opt ""
+# PROP BASE Bsc_Name ""
+# PROP BASE Target_Dir ""
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "build___"
+# PROP Intermediate_Dir "build___"
+# PROP Cmd_Line ""
+# PROP Rebuild_Opt ""
+# PROP Bsc_Name ""
+# PROP Target_Dir ""
+
+!ELSEIF  "$(CFG)" == "build - Win32 Single Release"
+
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "build__0"
+# PROP BASE Intermediate_Dir "build__0"
+# PROP BASE Cmd_Line "NMAKE /f build.mak"
+# PROP BASE Rebuild_Opt "/a"
+# PROP BASE Target_File "build.exe"
+# PROP BASE Bsc_Name "build.bsc"
+# PROP BASE Target_Dir ""
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "build__0"
+# PROP Intermediate_Dir "build__0"
+# PROP Cmd_Line "NMAKE /f build.mak"
+# PROP Rebuild_Opt "/a"
+# PROP Target_File "build.exe"
+# PROP Bsc_Name "build.bsc"
+# PROP Target_Dir ""
+
+!ELSEIF  "$(CFG)" == "build - Win32 DLL Debug"
+
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "build__1"
+# PROP BASE Intermediate_Dir "build__1"
+# PROP BASE Cmd_Line ""
+# PROP BASE Rebuild_Opt ""
+# PROP BASE Bsc_Name ""
+# PROP BASE Target_Dir ""
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "build__1"
+# PROP Intermediate_Dir "build__1"
+# PROP Cmd_Line ""
+# PROP Rebuild_Opt ""
+# PROP Bsc_Name ""
+# PROP Target_Dir ""
+
+!ELSEIF  "$(CFG)" == "build - Win32 DLL Release"
+
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "build__2"
+# PROP BASE Intermediate_Dir "build__2"
+# PROP BASE Cmd_Line "NMAKE /f build.mak"
+# PROP BASE Rebuild_Opt "/a"
+# PROP BASE Target_File "build.exe"
+# PROP BASE Bsc_Name "build.bsc"
+# PROP BASE Target_Dir ""
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "build__2"
+# PROP Intermediate_Dir "build__2"
+# PROP Cmd_Line "NMAKE /f build.mak"
+# PROP Rebuild_Opt "/a"
+# PROP Target_File "build.exe"
+# PROP Bsc_Name "build.bsc"
+# PROP Target_Dir ""
+
+!ENDIF 
+
+# Begin Target
+
+# Name "build - Win32 Release"
+# Name "build - Win32 Debug"
+# Name "build - Win32 Single Debug"
+# Name "build - Win32 Single Release"
+# Name "build - Win32 DLL Debug"
+# Name "build - Win32 DLL Release"
+
+!IF  "$(CFG)" == "build - Win32 Release"
+
+!ELSEIF  "$(CFG)" == "build - Win32 Debug"
+
+!ELSEIF  "$(CFG)" == "build - Win32 Single Debug"
+
+!ELSEIF  "$(CFG)" == "build - Win32 Single Release"
+
+!ELSEIF  "$(CFG)" == "build - Win32 DLL Debug"
+
+!ELSEIF  "$(CFG)" == "build - Win32 DLL Release"
+
+!ENDIF 
+
+# Begin Source File
+
+SOURCE=.\build.mak
+# End Source File
+# End Target
+# End Project
diff --git a/build/build.mak b/build/build.mak
new file mode 100644 (file)
index 0000000..7071624
--- /dev/null
@@ -0,0 +1,10 @@
+# $OpenLDAP$
+#
+# Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+# COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+#
+
+all: build.txt
+
+build.txt: version
+       copy version build.txt
index 7f163fdc0d8aa50f87958088f8ee9075e031ab81..efda69262e90552b7dffd2a1c4525bcebcf4ed24 100644 (file)
@@ -1,5 +1,5 @@
 # $OpenLDAP$
-## Copyright 1998,1999 The OpenLDAP Foundation
+## Copyright 1998-2000 The OpenLDAP Foundation
 ## COPYING RESTRICTIONS APPLY.  See COPYRIGHT File in top level directory
 ## of this package for details.
 ##---------------------------------------------------------------------------
@@ -13,6 +13,7 @@ all-common: FORCE
        @for i in $(SUBDIRS) $(ALLDIRS); do             \
                echo "  Entering subdirectory $$i";             \
                ( cd $$i; $(MAKE) $(MFLAGS) all );              \
+               if test $$? != 0 ; then exit 1; fi ;    \
                echo " ";                                                               \
        done
 
@@ -21,6 +22,7 @@ install-common: FORCE
        @for i in $(SUBDIRS) $(INSTALLDIRS); do         \
                echo "  Entering subdirectory $$i";             \
                ( cd $$i; $(MAKE) $(MFLAGS) install );  \
+               if test $$? != 0 ; then exit 1; fi ;    \
                echo " ";                                                               \
        done
 
@@ -29,6 +31,7 @@ clean-common: FORCE
        @for i in $(SUBDIRS) $(CLEANDIRS); do           \
                echo "  Entering subdirectory $$i";             \
                ( cd $$i; $(MAKE) $(MFLAGS) clean );    \
+               if test $$? != 0 ; then exit 1; fi ;    \
                echo " ";                                                               \
        done
 
@@ -37,6 +40,7 @@ veryclean-common: FORCE
        @for i in $(SUBDIRS) $(CLEANDIRS); do           \
                echo "  Entering subdirectory $$i";             \
                ( cd $$i; $(MAKE) $(MFLAGS) veryclean );        \
+               if test $$? != 0 ; then exit 1; fi ;    \
                echo " ";                                                               \
        done
 
@@ -45,6 +49,7 @@ depend-common: FORCE
        @for i in $(SUBDIRS) $(DEPENDDIRS); do          \
                echo "  Entering subdirectory $$i";             \
                ( cd $$i; $(MAKE) $(MFLAGS) depend );   \
+               if test $$? != 0 ; then exit 1; fi ;    \
                echo " ";                                                               \
        done
 
index df9d94ddb405a3a58f563c7c9c815db77e7d62e6..d6091ffb3cccc59f1dd72f90331b26a670f1c2fa 100644 (file)
@@ -1,5 +1,5 @@
 # $OpenLDAP$
-## Copyright 1998,1999 The OpenLDAP Foundation
+## Copyright 1998-2000 The OpenLDAP Foundation
 ## COPYING RESTRICTIONS APPLY.  See COPYRIGHT File in top level directory
 ## of this package for details.
 ##---------------------------------------------------------------------------
index c7348ecd251ec76dd178069fcab5f9567837e7b5..e91ee1db75a3d7a772d727012831548f3bf9f862 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # $OpenLDAP$
-## Copyright 1998,1999 The OpenLDAP Foundation
+## Copyright 1998-2000 The OpenLDAP Foundation
 ## COPYING RESTRICTIONS APPLY.  See COPYRIGHT File in top level directory
 ## of this package for details.
 #
index 776972ac6d86bb4686769e883ec8f22f73ba0ec8..3952bcf3c9a753437cb2e85a0655fae1979c5c6d 100644 (file)
@@ -1,5 +1,5 @@
 # $OpenLDAP$
-## Copyright 1998,1999 The OpenLDAP Foundation
+## Copyright 1998-2000 The OpenLDAP Foundation
 ## COPYING RESTRICTIONS APPLY.  See COPYRIGHT File in top level directory
 ## of this package for details.
 ##---------------------------------------------------------------------------
@@ -7,7 +7,16 @@
 ## Makefile Template for Shared Libraries
 ##
 
-COMPILE = $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c
+NT_LTFLAGS = --only-$(LINKAGE)
+LTFLAGS = $(@PLAT@_LTFLAGS) 
+
+NT_DYN_LT_NO_UNDEF = -no-undefined
+LT_NO_UNDEF = $(@PLAT@_@LIB_LINKAGE@_LT_NO_UNDEF)
+
+COMPILE = $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) $(CFLAGS) $(EXTRA_DEFS) -c
+LTLIBLINK = $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) \
+               $(LTVERSION) $(LT_NO_UNDEF)
+
 MKDEPFLAG = -l
 
 .SUFFIXES: .c .o .lo
@@ -15,11 +24,29 @@ MKDEPFLAG = -l
 .c.lo:
        $(COMPILE) $<
 
+
+# DYN_EXT (@DYN_EXT@) describes the extension assoicated with a
+# dynamic library, e.g. so, dll
+
+DYN_EXT=@DYN_EXT@
+
 $(LIBRARY):  version.lo
-       $(LTLIBLINK) -rpath $(libdir) -o $@ $(OBJS) version.lo
-       $(RM) ../$@;    \
-       (d=`$(PWD)` ; $(LN_S) `$(BASENAME) $$d`/$@ ../$@)
-       $(RM) ../`$(BASENAME) $@ .la`.a;        \
-       (d=`$(PWD)`; t=`$(BASENAME) $@ .la`.a; $(LN_S) `$(BASENAME) $$d`/.libs/$$t ../$$t)
+       $(LTLIBLINK) -rpath $(libdir) -o $@ $(OBJS) version.lo $(EXTRA_LIBS)
+       $(RM) ../$@
+       d=`$(PWD)`; d=`$(BASENAME) $$d`; cd ..; $(LN_S) $$d/$@ $@; \
+       t=`$(BASENAME) $@ .la`.a; $(RM) $$t; $(LN_S) $$d/.libs/$$t $$t
+       @# If we want our binaries to link dynamically with libldap{,_r} liblber
+       @# We also symlink the .so, so we can run the tests without installing
+       if test "$(LINK_BINS_DYNAMIC)" = "yes"; then \
+               d=`$(PWD)`; d=`$(BASENAME) $$d`; b=`$(BASENAME) $@ .la`; \
+                cd .libs; t=`echo $$b*.$(DYN_EXT)`; (cd ../.. ; $(RM) $$t; \
+                $(LN_S) $$d/.libs/$$t $$t); \
+               if test "$(DYN_EXT)" != dll; then \
+                   t=`echo $$b.$(DYN_EXT).?`; cd ../.. ; \
+                   $(RM) $$t; \
+                   $(LN_S) $$d/.libs/$$t $$t; \
+               fi \
+       fi
 
 Makefile: $(top_srcdir)/build/lib-shared.mk
+
index ad0d14669c0f2f15adac528fb32383d0c5f335a7..272408b98e7f239bfed0ea98be384baf2d41defb 100644 (file)
@@ -1,5 +1,5 @@
 # $OpenLDAP$
-## Copyright 1998,1999 The OpenLDAP Foundation
+## Copyright 1998-2000 The OpenLDAP Foundation
 ## COPYING RESTRICTIONS APPLY.  See COPYRIGHT File in top level directory
 ## of this package for details.
 ##---------------------------------------------------------------------------
@@ -11,6 +11,6 @@ $(LIBRARY): version.o
        $(AR) ru $@ $(OBJS) version.o
        @$(RANLIB) $@;  \
        $(RM) ../$@;    \
-       (d=`$(PWD)` ; $(LN_S) `$(BASENAME) $$d`/$@ ../$@)
+       (d=`$(PWD)` ; cd .. ; $(LN_S) `$(BASENAME) $$d`/$@ $@)
 
 Makefile: $(top_srcdir)/build/lib-static.mk
index 9bf542d340c7e15963696c2882bb3b887716c4d5..b647665842f9e09c1d4d612b14201a652e256cfa 100644 (file)
@@ -1,5 +1,5 @@
 # $OpenLDAP$
-## Copyright 1998,1999 The OpenLDAP Foundation
+## Copyright 1998-2000 The OpenLDAP Foundation
 ## COPYING RESTRICTIONS APPLY.  See COPYRIGHT File in top level directory
 ## of this package for details.
 ##---------------------------------------------------------------------------
@@ -24,7 +24,8 @@ lint5: lint5-local FORCE
 clean-common:  FORCE
        $(RM) $(LIBRARY) ../$(LIBRARY) $(XLIBRARY) \
                $(PROGRAMS) $(XPROGRAMS) $(XSRCS) $(XXSRCS) \
-               *.o *.lo a.out core version.c .libs/*
+               *.o *.lo a.out *.exe core version.c .libs/* \
+               ../`$(BASENAME) $(LIBRARY) .la`{.a,.so*,*.dll}
 
 depend-common: FORCE
        $(MKDEP) $(DEFS) $(DEFINES) $(SRCS) $(XXSRCS)
diff --git a/build/ltconfig b/build/ltconfig
new file mode 100755 (executable)
index 0000000..c09e494
--- /dev/null
@@ -0,0 +1,3069 @@
+#! /bin/sh
+
+# ltconfig - Create a system-specific libtool.
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# 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
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# 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.
+#
+# 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.
+
+# A lot of this script is taken from autoconf-2.10.
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+echo=echo
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell.
+  exec "$SHELL" "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit 0
+fi
+
+# Find the correct PATH separator.  Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != "Xset"; then
+  UNAME=${UNAME-`uname 2>/dev/null`}
+  case X$UNAME in
+    *-DOS) PATH_SEPARATOR=';' ;;
+    *)     PATH_SEPARATOR=':' ;;
+  esac
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi
+
+if test "X${echo_test_string+set}" != "Xset"; then
+  # 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`" &&
+       (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then
+      break
+    fi
+  done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" != 'X\t' ||
+   test "X`($echo "$echo_test_string") 2>/dev/null`" != X"$echo_test_string"; then
+  # The Solaris, AIX, and Digital Unix default echo programs unquote
+  # backslashes.  This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  #
+  # So, first we look for a working echo in the user's PATH.
+
+  IFS="${IFS=  }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+  for dir in $PATH /usr/ucb; do
+    if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+       test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+       test "X`($dir/echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+      echo="$dir/echo"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  if test "X$echo" = Xecho; then
+    # We didn't find a better echo, so look for alternatives.
+    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+       test "X`(print -r "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+      # This shell has a builtin print -r that does the trick.
+      echo='print -r'
+    elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+        test "X$CONFIG_SHELL" != X/bin/ksh; then
+      # If we have ksh, try running ltconfig again with it.
+      ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}"
+      export ORIGINAL_CONFIG_SHELL
+      CONFIG_SHELL=/bin/ksh
+      export CONFIG_SHELL
+      exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"}
+    else
+      # Try using printf.
+      echo='printf "%s\n"'
+      if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+        test "X`($echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+       # Cool, printf works
+       :
+      elif test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+          test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+       CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL"
+       export CONFIG_SHELL
+       SHELL="$CONFIG_SHELL"
+       export SHELL
+       echo="$CONFIG_SHELL $0 --fallback-echo"
+      elif test "X`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+          test "X`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+       echo="$CONFIG_SHELL $0 --fallback-echo"
+      else
+       # maybe with a smaller string...
+       prev=:
+
+       for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+         if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then
+           break
+         fi
+         prev="$cmd"
+       done
+
+       if test "$prev" != 'sed 50q "$0"'; then
+         echo_test_string=`eval $prev`
+         export echo_test_string
+         exec "${ORIGINAL_CONFIG_SHELL}" "$0" ${1+"$@"}
+       else
+         # Oops.  We lost completely, so just stick with echo.
+         echo=echo
+       fi
+      fi
+    fi
+  fi
+fi
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# The name of this program.
+progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'`
+
+# Constants:
+PROGRAM=ltconfig
+PACKAGE=libtool
+VERSION=1.3.3
+TIMESTAMP=" (1.385.2.181 1999/07/02 15:49:11)"
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.c 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.c $LIBS 1>&5'
+rm="rm -f"
+
+help="Try \`$progname --help' for more information."
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+enable_shared=yes
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+enable_static=yes
+enable_fast_install=yes
+enable_dlopen=unknown
+enable_win32_dll=no
+ltmain=
+silent=
+srcdir=
+ac_config_guess=
+ac_config_sub=
+host=
+nonopt=
+ofile="$default_ofile"
+verify_host=yes
+with_gcc=no
+with_gnu_ld=no
+need_locks=yes
+ac_ext=c
+objext=o
+libext=a
+exeext=
+cache_file=
+
+old_AR="$AR"
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+old_CPPFLAGS="$CPPFLAGS"
+old_LDFLAGS="$LDFLAGS"
+old_LD="$LD"
+old_LN_S="$LN_S"
+old_LIBS="$LIBS"
+old_NM="$NM"
+old_RANLIB="$RANLIB"
+old_DLLTOOL="$DLLTOOL"
+old_OBJDUMP="$OBJDUMP"
+old_AS="$AS"
+
+# Parse the command line options.
+args=
+prev=
+for option
+do
+  case "$option" in
+  -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    eval "$prev=\$option"
+    prev=
+    continue
+  fi
+
+  case "$option" in
+  --help) cat <<EOM
+Usage: $progname [OPTION]... [HOST [LTMAIN]]
+
+Generate a system-specific libtool script.
+
+    --debug                enable verbose shell tracing
+    --disable-shared       do not build shared libraries
+    --disable-static       do not build static libraries
+    --disable-fast-install do not optimize for fast installation
+    --enable-dlopen        enable dlopen support
+    --enable-win32-dll     enable building dlls on win32 hosts
+    --help                 display this help and exit
+    --no-verify            do not verify that HOST is a valid host type
+-o, --output=FILE          specify the output file [default=$default_ofile]
+    --quiet                same as \`--silent'
+    --silent               do not print informational messages
+    --srcdir=DIR           find \`config.guess' in DIR
+    --version              output version information and exit
+    --with-gcc             assume that the GNU C compiler will be used
+    --with-gnu-ld          assume that the C compiler uses the GNU linker
+    --disable-lock         disable file locking
+    --cache-file=FILE      configure cache file
+
+LTMAIN is the \`ltmain.sh' shell script fragment or \`ltmain.c' program
+that provides basic libtool functionality.
+
+HOST is the canonical host system name [default=guessed].
+EOM
+  exit 0
+  ;;
+
+  --debug)
+    echo "$progname: enabling shell trace mode"
+    set -x
+    ;;
+
+  --disable-shared) enable_shared=no ;;
+
+  --disable-static) enable_static=no ;;
+
+  --disable-fast-install) enable_fast_install=no ;;
+
+  --enable-dlopen) enable_dlopen=yes ;;
+
+  --enable-win32-dll) enable_win32_dll=yes ;;
+
+  --quiet | --silent) silent=yes ;;
+
+  --srcdir) prev=srcdir ;;
+  --srcdir=*) srcdir="$optarg" ;;
+
+  --no-verify) verify_host=no ;;
+
+  --output | -o) prev=ofile ;;
+  --output=*) ofile="$optarg" ;;
+
+  --version) echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"; exit 0 ;;
+
+  --with-gcc) with_gcc=yes ;;
+  --with-gnu-ld) with_gnu_ld=yes ;;
+
+  --disable-lock) need_locks=no ;;
+
+  --cache-file=*) cache_file="$optarg" ;;
+
+  -*)
+    echo "$progname: unrecognized option \`$option'" 1>&2
+    echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    if test -z "$ltmain"; then
+      ltmain="$option"
+    elif test -z "$host"; then
+# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1
+#      if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then
+#        echo "$progname: warning \`$option' is not a valid host type" 1>&2
+#      fi
+      host="$option"
+    else
+      echo "$progname: too many arguments" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+done
+
+if test -z "$ltmain"; then
+  echo "$progname: you must specify a LTMAIN file" 1>&2
+  echo "$help" 1>&2
+  exit 1
+fi
+
+if test ! -f "$ltmain"; then
+  echo "$progname: \`$ltmain' does not exist" 1>&2
+  echo "$help" 1>&2
+  exit 1
+fi
+
+# Quote any args containing shell metacharacters.
+ltconfig_args=
+for arg
+do
+  case "$arg" in
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ltconfig_args="$ltconfig_args '$arg'" ;;
+  *) ltconfig_args="$ltconfig_args $arg" ;;
+  esac
+done
+
+# A relevant subset of AC_INIT.
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 5 compiler messages saved in config.log
+# 6 checking for... messages and results
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>>./config.log
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+
+if test -n "$cache_file" && test -r "$cache_file"; then
+  echo "loading cache $cache_file within ltconfig"
+  . $cache_file
+fi
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='       '
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+if test -z "$srcdir"; then
+  # Assume the source directory is the same one as the path to LTMAIN.
+  srcdir=`$echo "X$ltmain" | $Xsed -e 's%/[^/]*$%%'`
+  test "$srcdir" = "$ltmain" && srcdir=.
+fi
+
+trap "$rm conftest*; exit 1" 1 2 15
+if test "$verify_host" = yes; then
+  # Check for config.guess and config.sub.
+  ac_aux_dir=
+  for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+    if test -f $ac_dir/config.guess; then
+      ac_aux_dir=$ac_dir
+      break
+    fi
+  done
+  if test -z "$ac_aux_dir"; then
+    echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+  ac_config_guess=$ac_aux_dir/config.guess
+  ac_config_sub=$ac_aux_dir/config.sub
+
+  # Make sure we can run config.sub.
+  if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then :
+  else
+    echo "$progname: cannot run $ac_config_sub" 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+
+  echo $ac_n "checking host system type""... $ac_c" 1>&6
+
+  host_alias=$host
+  case "$host_alias" in
+  "")
+    if host_alias=`$SHELL $ac_config_guess`; then :
+    else
+      echo "$progname: cannot guess host type; you must specify one" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+  host=`$SHELL $ac_config_sub $host_alias`
+  echo "$ac_t$host" 1>&6
+
+  # Make sure the host verified.
+  test -z "$host" && exit 1
+
+elif test -z "$host"; then
+  echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2
+  echo "$help" 1>&2
+  exit 1
+else
+  host_alias=$host
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case "$host_os" in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+case "$host_os" in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "${COLLECT_NAMES+set}" != set; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR cru $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+# Set a sane default for `AR'.
+test -z "$AR" && AR=ar
+
+# Set a sane default for `OBJDUMP'.
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+# If RANLIB is not set, then run the test.
+if test "${RANLIB+set}" != "set"; then
+  result=no
+
+  echo $ac_n "checking for ranlib... $ac_c" 1>&6
+  IFS="${IFS=  }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+  for dir in $PATH; do
+    test -z "$dir" && dir=.
+    if test -f $dir/ranlib || test -f $dir/ranlib$ac_exeext; then
+      RANLIB="ranlib"
+      result="ranlib"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  echo "$ac_t$result" 1>&6
+fi
+
+if test -n "$RANLIB"; then
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+  old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+fi
+
+# Set sane defaults for `DLLTOOL', `OBJDUMP', and `AS', used on cygwin.
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$AS" && AS=as
+
+# Check to see if we are using GCC.
+if test "$with_gcc" != yes || test -z "$CC"; then
+  # If CC is not set, then try to find GCC or a usable CC.
+  if test -z "$CC"; then
+    echo $ac_n "checking for gcc... $ac_c" 1>&6
+    IFS="${IFS=        }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for dir in $PATH; do
+      test -z "$dir" && dir=.
+      if test -f $dir/gcc || test -f $dir/gcc$ac_exeext; then
+       CC="gcc"
+       break
+      fi
+    done
+    IFS="$save_ifs"
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+  fi
+
+  # Not "gcc", so try "cc", rejecting "/usr/ucb/cc".
+  if test -z "$CC"; then
+    echo $ac_n "checking for cc... $ac_c" 1>&6
+    IFS="${IFS=        }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    cc_rejected=no
+    for dir in $PATH; do
+      test -z "$dir" && dir=.
+      if test -f $dir/cc || test -f $dir/cc$ac_exeext; then
+       if test "$dir/cc" = "/usr/ucb/cc"; then
+         cc_rejected=yes
+         continue
+       fi
+       CC="cc"
+       break
+      fi
+    done
+    IFS="$save_ifs"
+    if test $cc_rejected = yes; then
+      # We found a bogon in the path, so make sure we never use it.
+      set dummy $CC
+      shift
+      if test $# -gt 0; then
+       # We chose a different compiler from the bogus one.
+       # However, it has the same name, so the bogon will be chosen
+       # first if we set CC to just the name; use the full file name.
+       shift
+       set dummy "$dir/cc" "$@"
+       shift
+       CC="$@"
+      fi
+    fi
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+
+    if test -z "$CC"; then
+      echo "$progname: error: no acceptable cc found in \$PATH" 1>&2
+      exit 1
+    fi
+  fi
+
+  # Now see if the compiler is really GCC.
+  with_gcc=no
+  echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6
+  echo "$progname:581: checking whether we are using GNU C" >&5
+
+  $rm conftest.c
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+  if { ac_try='${CC-cc} -E conftest.c'; { (eval echo $progname:589: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+    with_gcc=yes
+  fi
+  $rm conftest.c
+  echo "$ac_t$with_gcc" 1>&6
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+echo $ac_n "checking for object suffix... $ac_c" 1>&6
+$rm conftest*
+echo 'int i = 1;' > conftest.c
+echo "$progname:603: checking for object suffix" >& 5
+if { (eval echo $progname:604: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then
+  # Append any warnings to the config.log.
+  cat conftest.err 1>&5
+
+  for ac_file in conftest.*; do
+    case $ac_file in
+    *.c) ;;
+    *) objext=`echo $ac_file | sed -e s/conftest.//` ;;
+    esac
+  done
+else
+  cat conftest.err 1>&5
+  echo "$progname: failed program was:" >&5
+  cat conftest.c >&5
+fi
+$rm conftest*
+echo "$ac_t$objext" 1>&6
+
+echo $ac_n "checking for executable suffix... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_exeext="no"
+  $rm conftest*
+  echo 'main () { return 0; }' > conftest.c
+  echo "$progname:629: checking for executable suffix" >& 5
+  if { (eval echo $progname:630: \"$ac_link\") 1>&5; (eval $ac_link) 2>conftest.err; }; then
+    # Append any warnings to the config.log.
+    cat conftest.err 1>&5
+
+    for ac_file in conftest.*; do
+      case $ac_file in
+      *.c | *.err | *.$objext ) ;;
+      *) ac_cv_exeext=.`echo $ac_file | sed -e s/conftest.//` ;;
+      esac
+    done
+  else
+    cat conftest.err 1>&5
+    echo "$progname: failed program was:" >&5
+    cat conftest.c >&5
+  fi
+  $rm conftest*
+fi
+if test "X$ac_cv_exeext" = Xno; then
+  exeext=""
+else
+  exeext="$ac_cv_exeext"
+fi
+echo "$ac_t$ac_cv_exeext" 1>&6
+
+echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6
+pic_flag=
+special_shlib_compile_flags=
+wl=
+link_static_flag=
+no_builtin_flag=
+
+if test "$with_gcc" = yes; then
+  wl='-Wl,'
+  link_static_flag='-static'
+
+  case "$host_os" in
+  beos* | irix5* | irix6* | osf3* | osf4*)
+    # PIC is the default for these OSes.
+    ;;
+  aix*)
+    # Below there is a dirty hack to force normal static linking with -ldl
+    # The problem is because libdl dynamically linked with both libc and
+    # libC (AIX C++ library), which obviously doesn't included in libraries
+    # list by gcc. This cause undefined symbols with -static flags.
+    # This hack allows C programs to be linked with "-static -ldl", but
+    # we not sure about C++ programs.
+    link_static_flag="$link_static_flag ${wl}-lC"
+    ;;
+  cygwin* | mingw* | os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+  amigaos*)
+    # FIXME: we need at least 68020 code to build shared libraries, but
+    # adding the `-m68020' flag to GCC prevents building anything better,
+    # like `-m68040'.
+    pic_flag='-m68020 -resident32 -malways-restore-a4'
+    ;;
+  sysv4*MP*)
+    if test -d /usr/nec; then
+       pic_flag=-Kconform_pic
+    fi
+    ;;
+  *)
+    pic_flag='-fPIC'
+    ;;
+  esac
+else
+  # PORTME Check for PIC flags for the system compiler.
+  case "$host_os" in
+  aix3* | aix4*)
+    # All AIX code is PIC.
+    link_static_flag='-bnso -bI:/lib/syscalls.exp'
+    ;;
+
+  hpux9* | hpux10* | hpux11*)
+    # Is there a better link_static_flag that works with the bundled CC?
+    wl='-Wl,'
+    link_static_flag="${wl}-a ${wl}archive"
+    pic_flag='+Z'
+    ;;
+
+  irix5* | irix6*)
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    # PIC (with -KPIC) is the default.
+    ;;
+
+  cygwin* | mingw* | os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+
+  osf3* | osf4*)
+    # All OSF/1 code is PIC.
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    ;;
+
+  sco3.2v5*)
+    pic_flag='-Kpic'
+    link_static_flag='-dn'
+    special_shlib_compile_flags='-belf'
+    ;;
+
+  solaris*)
+    pic_flag='-KPIC'
+    link_static_flag='-Bstatic'
+    wl='-Wl,'
+    ;;
+
+  sunos4*)
+    pic_flag='-PIC'
+    link_static_flag='-Bstatic'
+    wl='-Qoption ld '
+    ;;
+
+  sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+    pic_flag='-KPIC'
+    link_static_flag='-Bstatic'
+    wl='-Wl,'
+    ;;
+
+  uts4*)
+    pic_flag='-pic'
+    link_static_flag='-Bstatic'
+    ;;
+  sysv4*MP*)
+    if test -d /usr/nec ;then
+      pic_flag='-Kconform_pic'
+      link_static_flag='-Bstatic'
+    fi
+    ;;
+  *)
+    can_build_shared=no
+    ;;
+  esac
+fi
+
+if test -n "$pic_flag"; then
+  echo "$ac_t$pic_flag" 1>&6
+
+  # Check to make sure the pic_flag actually works.
+  echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $pic_flag -DPIC"
+  echo "$progname:776: checking if $compiler PIC flag $pic_flag works" >&5
+  if { (eval echo $progname:777: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then
+    # Append any warnings to the config.log.
+    cat conftest.err 1>&5
+    
+    case "$host_os" in
+    hpux9* | hpux10* | hpux11*)
+      # On HP-UX, both CC and GCC only warn that PIC is supported... then they
+      # create non-PIC objects.  So, if there were any warnings, we assume that
+      # PIC is not supported.
+      if test -s conftest.err; then
+       echo "$ac_t"no 1>&6
+       can_build_shared=no
+       pic_flag=
+      else
+       echo "$ac_t"yes 1>&6
+       pic_flag=" $pic_flag"
+      fi
+      ;;
+    *)
+      echo "$ac_t"yes 1>&6
+      pic_flag=" $pic_flag"
+      ;;
+    esac
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    can_build_shared=no
+    pic_flag=
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+else
+  echo "$ac_t"none 1>&6
+fi
+
+# Check to see if options -o and -c are simultaneously supported by compiler
+echo $ac_n "checking if $compiler supports -c -o file.o... $ac_c" 1>&6
+$rm -r conftest 2>/dev/null
+mkdir conftest
+cd conftest
+$rm conftest*
+echo "int some_variable = 0;" > conftest.c
+mkdir out
+# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
+# that will create temporary files in the current directory regardless of
+# the output directory.  Thus, making CWD read-only will cause this test
+# to fail, enabling locking or at least warning the user not to do parallel
+# builds.
+chmod -w .
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -o out/conftest2.o"
+echo "$progname:829: checking if $compiler supports -c -o file.o" >&5
+if { (eval echo $progname:830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.o; then
+
+  # The compiler can only warn and ignore the option if not recognized
+  # So say no if there are warnings
+    if test -s out/conftest.err; then
+      echo "$ac_t"no 1>&6
+      compiler_c_o=no
+    else
+      echo "$ac_t"yes 1>&6
+      compiler_c_o=yes
+    fi
+else
+  # Append any errors to the config.log.
+  cat out/conftest.err 1>&5
+  compiler_c_o=no
+  echo "$ac_t"no 1>&6
+fi
+CFLAGS="$save_CFLAGS"
+chmod u+w .
+$rm conftest* out/*
+rmdir out
+cd ..
+rmdir conftest
+$rm -r conftest 2>/dev/null
+
+if test x"$compiler_c_o" = x"yes"; then
+  # Check to see if we can write to a .lo
+  echo $ac_n "checking if $compiler supports -c -o file.lo... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -c -o conftest.lo"
+  echo "$progname:862: checking if $compiler supports -c -o file.lo" >&5
+if { (eval echo $progname:863: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.lo; 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
+       echo "$ac_t"no 1>&6
+       compiler_o_lo=no
+      else
+       echo "$ac_t"yes 1>&6
+       compiler_o_lo=yes
+      fi
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    compiler_o_lo=no
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+else
+  compiler_o_lo=no
+fi
+
+# Check to see if we can do hard links to lock some files if needed
+hard_links="nottested"
+if test "$compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&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 "$ac_t$hard_links" 1>&6
+  $rm conftest*
+  if test "$hard_links" = no; then
+    echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+if test "$with_gcc" = yes; then
+  # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
+  echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.c"
+  echo "$progname:914: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+  if { (eval echo $progname:915: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; 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
+       echo "$ac_t"no 1>&6
+       compiler_rtti_exceptions=no
+      else
+       echo "$ac_t"yes 1>&6
+       compiler_rtti_exceptions=yes
+      fi
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    compiler_rtti_exceptions=no
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+
+  if test "$compiler_rtti_exceptions" = "yes"; then
+    no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
+  else
+    no_builtin_flag=' -fno-builtin'
+  fi
+  
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$special_shlib_compile_flags"; then
+  echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2
+  if echo "$old_CC $old_CFLAGS " | egrep -e "[         ]$special_shlib_compile_flags[  ]" >/dev/null; then :
+  else
+    echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2
+    can_build_shared=no
+  fi
+fi
+
+echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6
+$rm conftest*
+echo 'main(){return(0);}' > conftest.c
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $link_static_flag"
+echo "$progname:958: checking if $compiler static flag $link_static_flag works" >&5
+if { (eval echo $progname:959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  echo "$ac_t$link_static_flag" 1>&6
+else
+  echo "$ac_t"none 1>&6
+  link_static_flag=
+fi
+LDFLAGS="$save_LDFLAGS"
+$rm conftest*
+
+if test -z "$LN_S"; then
+  # Check to see if we can use ln -s, or we need hard links.
+  echo $ac_n "checking whether ln -s works... $ac_c" 1>&6
+  $rm conftest.dat
+  if ln -s X conftest.dat 2>/dev/null; then
+    $rm conftest.dat
+    LN_S="ln -s"
+  else
+    LN_S=ln
+  fi
+  if test "$LN_S" = "ln -s"; then
+    echo "$ac_t"yes 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+fi
+
+# Make sure LD is an absolute path.
+if test -z "$LD"; then
+  ac_prog=ld
+  if test "$with_gcc" = yes; then
+    # Check if gcc -print-prog-name=ld gives a path.
+    echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6
+    echo "$progname:991: checking for ld used by GCC" >&5
+    ac_prog=`($CC -print-prog-name=ld) 2>&5`
+    case "$ac_prog" in
+    # Accept absolute paths.
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+    "")
+      # If it fails, then pretend we are not using GCC.
+      ac_prog=ld
+      ;;
+    *)
+      # If it is relative, then search for the first ld in PATH.
+      with_gnu_ld=unknown
+      ;;
+    esac
+  elif test "$with_gnu_ld" = yes; then
+    echo $ac_n "checking for GNU ld... $ac_c" 1>&6
+    echo "$progname:1015: checking for GNU ld" >&5
+  else
+    echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+    echo "$progname:1018: checking for non-GNU ld" >&5
+  fi
+
+  if test -z "$LD"; then
+    IFS="${IFS=        }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for ac_dir in $PATH; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+       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.
+       # Break only if it was the GNU/non-GNU ld that we prefer.
+       if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+         test "$with_gnu_ld" != no && break
+       else
+         test "$with_gnu_ld" != yes && break
+       fi
+      fi
+    done
+    IFS="$ac_save_ifs"
+  fi
+
+  if test -n "$LD"; then
+    echo "$ac_t$LD" 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+
+  if test -z "$LD"; then
+    echo "$progname: error: no acceptable ld found in \$PATH" 1>&2
+    exit 1
+  fi
+fi
+
+# Check to see if it really is or is not GNU ld.
+echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6
+# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+echo "$ac_t$with_gnu_ld" 1>&6
+
+# See if the linker supports building shared libraries.
+echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6
+
+allow_undefined_flag=
+no_undefined_flag=
+need_lib_prefix=unknown
+need_version=unknown
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+archive_cmds=
+archive_expsym_cmds=
+old_archive_from_new_cmds=
+export_dynamic_flag_spec=
+whole_archive_flag_spec=
+thread_safe_flag_spec=
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_default_flag=
+hardcode_shlibpath_var=unsupported
+runpath_var=
+link_export=
+link_export_all=
+always_export_symbols=no
+export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
+# include_expsyms should be a list of space-separated symbols to be *always*
+# included in the symbol list
+include_expsyms=
+# exclude_expsyms can be an egrep regular expression of symbols to exclude
+# it will be wrapped by ` (' and `)$', so one must not match beginning or
+# end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+# as well as any symbol that contains `d'.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+# platforms (ab)use it in PIC code, but their linkers get confused if
+# the symbol is explicitly referenced.  Since portable code cannot
+# rely on this symbol name, it's probably fine to never include it in
+# preloaded symbol tables.
+
+case "$host_os" in
+cygwin* | mingw*)
+  # FIXME: the MSVC++ port hasn't been tested in a loooong time
+  # When not using gcc, we currently assume that we are using
+  # Microsoft Visual C++.
+  if test "$with_gcc" != yes; then
+    with_gnu_ld=no
+  fi
+  ;;
+
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+  # If archive_cmds runs LD, not CC, wlarc should be empty
+  wlarc='${wl}'
+
+  # See if GNU ld supports shared libraries.
+  case "$host_os" in
+  aix3* | aix4*)
+    # On AIX, the GNU linker is very broken
+    ld_shlibs=no
+    cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+    ;;
+
+  amigaos*)
+    archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+
+    # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+    # that the semantics of dynamic libraries on AmigaOS, at least up
+    # to version 4, is to share data among multiple programs linked
+    # with the same dynamic library.  Since this doesn't match the
+    # behavior of shared libraries on other platforms, we can use
+    # them.
+    ld_shlibs=no
+    ;;
+
+  beos*)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      allow_undefined_flag=unsupported
+      # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+      # support --undefined.  This deserves some investigation.  FIXME
+      archive_cmds='$CC -nostart $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+
+  cygwin* | mingw*)
+    # hardcode_libdir_flag_spec is actually meaningless, as there is
+    # no search path for DLLs.
+    hardcode_libdir_flag_spec='-L$libdir'
+    allow_undefined_flag=unsupported
+    always_export_symbols=yes
+
+    # HACK - this is actually determined at configure time in newer versions
+    # of libtool
+    lt_cv_need_dllmain=yes
+    lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles"
+
+    # cygwin and mingw dlls have different entry points and sets of symbols
+    # to exclude.
+    # FIXME: what about values for MSVC?
+    dll_entry=__cygwin_dll_entry@12
+    case "$host_os" in
+    mingw*)
+      # mingw values
+      dll_entry=_DllMainCRTStartup@12
+      lt_cv_need_dllmain=no
+      lt_cv_cc_dll_switch=-mdll
+      ;;
+    esac
+
+    # mingw and cygwin differ, and it's simplest to just exclude the union
+    # of the two symbol sets.
+    dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12
+
+    # recent cygwin and mingw systems supply a stub DllMain which the user
+    # can override, but on older systems we have to supply one (in ltdll.c)
+    if test "x$lt_cv_need_dllmain" = "xyes"; then
+      ltdll_obj='$objdir/$soname-ltdll.'"$objext "
+      ltdll_cmds='test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~
+        test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~'
+    else
+      ltdll_obj=
+      ltdll_cmds=
+    fi
+
+    # Extract the symbol export list from an `--export-all' def file,
+    # then regenerate the def file from the symbol export list, so that
+    # the compiled dll only exports the symbol export list.
+    # Be careful not to strip the DATA tag left be newer dlltools.
+    export_symbols_cmds="$ltdll_cmds"'
+      $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $objdir/$soname-def '$ltdll_obj'$libobjs $convenience~
+      sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//" < $objdir/$soname-def > $export_symbols'
+
+    # If DATA tags from a recent dlltool are present, honour them!
+    archive_expsym_cmds='echo EXPORTS > $objdir/$soname-def~
+      _lt_hint=1;
+      cat $export_symbols | while read symbol; do
+        set dummy \$symbol;
+        case \$# in
+          2) echo "     \$2 @ \$_lt_hint ; " >> $objdir/$soname-def;;
+          *) echo "     \$2 @ \$_lt_hint \$3 ; " >> $objdir/$soname-def;;
+        esac;
+       _lt_hint=`expr 1 + \$_lt_hint`;
+      done~
+      '"$ltdll_cmds"'
+      $CC -Wl,--base-file,$objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $lib '$ltdll_obj'$libobjs $deplibs $linkopts~
+      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+      $CC -Wl,--base-file,$objdir/$soname-base $objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $lib '$ltdll_obj'$libobjs $deplibs $linkopts~
+      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+      $CC $objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $lib '$ltdll_obj'$libobjs $deplibs $linkopts'
+
+      old_archive_from_new_cmds='$DLLTOOL --as=$AS --dllname $soname --def $objdir/$soname-def --output-lib $objdir/$libname.a' 
+    ;;
+
+  netbsd*)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      archive_cmds='$LD -Bshareable $libobjs $deplibs $linkopts -o $lib'
+      # can we support soname and/or expsyms with a.out? -oliva
+    fi
+    ;;
+
+  solaris*)
+    if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
+      ld_shlibs=no
+      cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+    elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;      
+
+  sunos4*)
+    archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    wlarc=
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+  esac
+
+  if test "$ld_shlibs" = yes; then
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    case $host_os in
+    cygwin* | mingw*)
+      # dlltool doesn't understand --whole-archive et. al.
+      whole_archive_flag_spec=
+      ;;
+    *)
+      whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      ;;
+    esac
+  fi
+else
+  # PORTME fill in a description of your system's linker (not GNU ld)
+  case "$host_os" in
+  aix3*)
+    allow_undefined_flag=unsupported
+    always_export_symbols=yes
+    link_export=' -bE:$export_symbols'
+    archive_expsym_cmds='$LD -o $objdir/$soname $libobjs $deplibs $linkopts -bE:$export_symbols -T512 -H512 -bM:SRE~$AR cru $lib $objdir/$soname'
+    # Note: this linker hardcodes the directories in LIBPATH if there
+    # are no directories specified by -L.
+    hardcode_minus_L=yes
+    if test "$with_gcc" = yes && test -z "$link_static_flag"; then
+      # Neither direct hardcoding nor static linking is supported with a
+      # broken collect2.
+      hardcode_direct=unsupported
+    fi
+    ;;
+
+  aix4*)
+    hardcode_libdir_flag_spec='${wl}-b ${wl}libpath:$libdir:/usr/lib:/lib'
+    hardcode_libdir_separator=':'
+    if test "$with_gcc" = yes; then
+      collect2name=`${CC} -print-prog-name=collect2`
+      if test -f "$collect2name" && \
+        strings "$collect2name" | grep resolve_lib_name >/dev/null
+      then
+       # We have reworked collect2
+       hardcode_direct=yes
+      else
+       # We have old collect2
+       hardcode_direct=unsupported
+       # It fails to find uninstalled libraries when the uninstalled
+       # path is not listed in the libpath.  Setting hardcode_minus_L
+       # to unsupported forces relinking
+       hardcode_minus_L=yes
+       hardcode_libdir_flag_spec='-L$libdir'
+       hardcode_libdir_separator=
+      fi
+      shared_flag='-shared'
+    else
+      shared_flag='${wl}-bM:SRE'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_default_flag='${wl}-b nolibpath'
+    fi
+    allow_undefined_flag=' ${wl}-berok'
+    archive_expsym_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}'
+    link_export=' ${wl}-bE:$export_symbols'
+    link_export_all=' ${wl}-bexpall'
+    always_export_symbols=yes
+   ;;
+
+  amigaos*)
+    archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    # see comment about different semantics on the GNU ld section
+    ld_shlibs=no
+    ;;
+
+  cygwin* | mingw*)
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    # hardcode_libdir_flag_spec is actually meaningless, as there is
+    # no search path for DLLs.
+    hardcode_libdir_flag_spec=' '
+    allow_undefined_flag=unsupported
+    # Tell ltmain to make .lib files, not .a files.
+    libext=lib
+    # FIXME: Setting linknames here is a bad hack.
+    archive_cmds='$CC -o $lib $libobjs $linkopts `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+    # 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'
+    fix_srcfile_path='`cygpath -w $srcfile`'
+    ;;
+
+  freebsd1*)
+    ld_shlibs=no
+    ;;
+
+  # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+  # support.  Future versions do this automatically, but an explicit c++rt0.o
+  # does not break anything, and helps significantly (at the cost of a little
+  # extra space).
+  freebsd2.2*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts /usr/lib/c++rt0.o'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+  freebsd2*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+  freebsd*)
+    archive_cmds='$CC -shared -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  hpux9* | hpux10* | hpux11*)
+    case "$host_os" in
+    hpux9*) archive_cmds='$rm $objdir/$soname~$LD -b +b $install_libdir -o $objdir/$soname $libobjs $deplibs $linkopts~test $objdir/$soname = $lib || mv $objdir/$soname $lib' ;;
+    *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linkopts' ;;
+    esac
+    hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+    hardcode_libdir_separator=:
+    hardcode_direct=yes
+    hardcode_minus_L=yes # Not in the search PATH, but as the default
+                        # location of the library.
+    export_dynamic_flag_spec='${wl}-E'
+    ;;
+
+  irix5* | irix6*)
+    if test "$with_gcc" = yes; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+    else
+      archive_cmds='$LD -shared $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'  # a.out
+    else
+      archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linkopts'      # ELF
+    fi
+    hardcode_libdir_flag_spec='${wl}-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  openbsd*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  os2*)
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    allow_undefined_flag=unsupported
+    archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def~$echo DATA >> $objdir/$libname.def~$echo " SINGLE NONSHARED" >> $objdir/$libname.def~$echo EXPORTS >> $objdir/$libname.def~emxexp $libobjs >> $objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $linkopts $objdir/$libname.def'
+    old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def'
+    ;;
+
+  osf3* | osf4*)
+    if test "$with_gcc" = yes; then
+      allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+      archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+    else
+      allow_undefined_flag=' -expect_unresolved \*'
+      archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  sco3.2v5*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_shlibpath_var=no
+    runpath_var=LD_RUN_PATH
+    hardcode_runpath_var=yes
+    ;;
+
+  solaris*)
+    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 $linkopts'
+    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 $linkopts~$rm $lib.exp'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_shlibpath_var=no
+    case "$host_os" in
+    solaris2.[0-5] | solaris2.[0-5].*) ;;
+    *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+      whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+    esac
+    ;;
+
+  sunos4*)
+    archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    runpath_var='LD_RUN_PATH'
+    hardcode_shlibpath_var=no
+    hardcode_direct=no #Motorola manual says yes, but my tests say they lie 
+    ;;  
+
+  sysv4.3*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_shlibpath_var=no
+    export_dynamic_flag_spec='-Bexport'
+    ;;
+
+  uts4*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  dgux*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4*MP*)
+    if test -d /usr/nec ;then
+    # archive_cmds='$LD -G -z text -h $soname -o $lib$libobjs$deplibs'
+    archive_cmds='$LD -G -h $soname -o $lib$libobjs$deplibs'
+    hardcode_shlibpath_var=no
+    runpath_var=LD_RUN_PATH
+    hardcode_runpath_var=yes
+    ld_shlibs=yes
+    fi
+    ;;
+
+  *)
+    ld_shlibs=no
+    ;;
+  esac
+fi
+echo "$ac_t$ld_shlibs" 1>&6
+test "$ld_shlibs" = no && can_build_shared=no
+
+if test -z "$NM"; then
+  echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6
+  case "$NM" in
+  [\\/]* | [A-Za-z]:[\\/]*) ;; # Let the user override the test with a path.
+  *)
+    IFS="${IFS=        }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for ac_dir in $PATH /usr/ucb /usr/ccs/bin /bin; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f $ac_dir/nm || test -f $ac_dir/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
+       if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+         NM="$ac_dir/nm -B"
+         break
+       elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+         NM="$ac_dir/nm -p"
+         break
+       else
+         NM=${NM="$ac_dir/nm"} # keep the first match, but
+         continue # so that we can try to find one that supports BSD flags
+       fi
+      fi
+    done
+    IFS="$ac_save_ifs"
+    test -z "$NM" && NM=nm
+    ;;
+  esac
+  echo "$ac_t$NM" 1>&6
+fi
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*) # Its linker distinguishes data from code symbols
+  global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+  ;;
+irix*)
+  symcode='[BCDEGRST]'
+  ;;
+solaris*)
+  symcode='[BDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+  symcode='[ABCDGISTW]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Write the raw and C identifiers.
+  global_symbol_pipe="sed -n -e 's/^.*[        ]\($symcode\)[  ][      ]*\($ac_symprfx\)$sympat$/$symxfrm/p'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+  $rm conftest*
+  cat > conftest.c <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+  echo "$progname:1592: checking if global_symbol_pipe works" >&5
+  if { (eval echo $progname:1593: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { echo "$progname:1596: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then
+
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+       mv -f "$nlist"T "$nlist"
+      else
+       rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+       if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+         cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+         # Now generate the symbol file.
+         eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.c'
+
+         cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+         sed 's/^. \(.*\) \(.*\)$/  {"\2", (lt_ptr_t) \&\2},/' < "$nlist" >> conftest.c
+         cat <<\EOF >> conftest.c
+  {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+         # Now try linking the two files.
+         mv conftest.$objext conftstm.$objext
+         save_LIBS="$LIBS"
+         save_CFLAGS="$CFLAGS"
+         LIBS="conftstm.$objext"
+         CFLAGS="$CFLAGS$no_builtin_flag"
+         if { (eval echo $progname:1648: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+           pipe_works=yes
+         else
+           echo "$progname: failed program was:" >&5
+           cat conftest.c >&5
+         fi
+         LIBS="$save_LIBS"
+       else
+         echo "cannot find nm_test_func in $nlist" >&5
+       fi
+      else
+       echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.c >&5
+  fi
+  $rm conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    global_symbol_pipe=
+  fi
+done
+if test "$pipe_works" = yes; then
+  echo "${ac_t}ok" 1>&6
+else
+  echo "${ac_t}failed" 1>&6
+fi
+
+if test -z "$global_symbol_pipe"; then
+  global_symbol_to_cdecl=
+fi
+
+# Check hardcoding attributes.
+echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+   test -n "$runpath_var"; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$hardcode_shlibpath_var" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+echo "$ac_t$hardcode_action" 1>&6
+
+
+reload_flag=
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6
+# PORTME Some linkers may need a different reload flag.
+reload_flag='-r'
+echo "$ac_t$reload_flag" 1>&6
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+# PORTME Fill in your ld.so characteristics
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+file_magic_cmd=
+file_magic_test_file=
+deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [regex]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6
+case "$host_os" in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}.so$major'
+  lt_cv_dlopen_self=yes
+  need_lib_prefix=no
+  ;;
+
+aix4*)
+  version_type=linux
+  # AIX has no versioning support, so currently we can not hardcode correct
+  # soname into executable. Probably we can add versioning support to
+  # collect2, so additional links can be useful in future.
+  # We preserve .a as extension for shared libraries though AIX4.2
+  # and later linker supports .so
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.a'
+  shlibpath_var=LIBPATH
+  deplibs_check_method=pass_all
+  lt_cv_dlopen_self=yes
+  need_lib_prefix=no
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}.so'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  deplibs_check_method=pass_all
+  lt_cv_dlopen="load_add_on"
+  lt_cv_dlopen_libs=
+  lt_cv_dlopen_self=yes
+  ;;
+
+bsdi4*)
+  version_type=linux
+  library_names_spec='${libname}.so$major ${libname}.so'
+  soname_spec='${libname}.so'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/shlib/libc.so
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw*)
+  version_type=windows
+  need_version=no
+  need_lib_prefix=no
+  if test "$with_gcc" = yes; then
+    library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.a'
+  else
+    library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib'
+  fi
+  dynamic_linker='Win32 ld.exe'
+  deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  file_magic_cmd='${OBJDUMP} -f'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  lt_cv_dlopen="LoadLibrary"
+  lt_cv_dlopen_libs=
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+  
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case "$version_type" in
+    freebsd-elf*)
+      deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object'
+      file_magic_cmd=/usr/bin/file
+      file_magic_test_file=`echo /usr/lib/libc.so*`
+      library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      deplibs_check_method=unknown
+      library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix'
+      need_version=yes
+      ;;
+  esac
+  finish_cmds='PATH="\$PATH:/sbin" OBJFORMAT="'"$objformat"'" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  case "$host_os" in
+  freebsd2* | freebsd3.[01]*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  *) # from 3.2 on
+    shlibpath_overrides_runpath=no
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  dynamic_linker="$host_os dld.sl"
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  shlibpath_var=SHLIB_PATH
+  shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+  library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
+  soname_spec='${libname}${release}.sl$major'
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6*)
+  version_type=irix
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}.so.$major'
+  library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major ${libname}${release}.so $libname.so'
+  case "$host_os" in
+  irix5*)
+    libsuff= shlibsuff=
+    # this will be overridden with pass_all, but let us keep it just in case
+    deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+    ;;
+  *)
+    case "$LD" in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    # this will be overridden with pass_all, but let us keep it just in case
+    deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+  deplibs_check_method='pass_all'
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+
+  if test -f /lib/ld.so.1; then
+    dynamic_linker='GNU ld.so'
+  else
+    # Only the GNU ld.so supports shared libraries on MkLinux.
+    case "$host_cpu" in
+    powerpc*) dynamic_linker=no ;;
+    *) dynamic_linker='Linux ld.so' ;;
+    esac
+  fi
+  ;;
+
+netbsd*)
+  version_type=sunos
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
+    soname_spec='${libname}${release}.so$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+openbsd*)
+  version_type=sunos
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+    need_version=no
+  fi
+  library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+os2*)
+  libname_spec='$name'
+  need_lib_prefix=no
+  library_names_spec='$libname.dll $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4*)
+  version_type=osf
+  need_version=no
+  soname_spec='${libname}${release}.so'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  # this will be overridden with pass_all, but let us keep it just in case
+  deplibs_check_method='file_magic COFF format alpha shared library'
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/shlib/libc.so
+  deplibs_check_method='pass_all'
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}.so$major'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  deplibs_check_method="file_magic ELF [0-9][0-9]-bit [LM]SB dynamic lib"
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/lib/libc.so
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case "$host_vendor" in
+    ncr)
+      deplibs_check_method='pass_all'
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      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]'
+      file_magic_cmd=/usr/bin/file
+      file_magic_test_file=`echo /usr/lib/libc.so*`
+      ;;
+  esac
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+    soname_spec='$libname.so.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$ac_t$dynamic_linker" 1>&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+# Report the final consequences.
+echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6
+
+# Only try to build win32 dlls if AC_LIBTOOL_WIN32_DLL was used in
+# configure.in, otherwise build static only libraries.
+case "$host_os" in
+cygwin* | mingw* | os2*)
+  if test x$can_build_shared = xyes; then
+    test x$enable_win32_dll = xno && can_build_shared=no
+    echo "checking if package supports dlls... $can_build_shared" 1>&6
+  fi
+;;
+esac
+
+if test -n "$file_magic_test_file" && test -n "$file_magic_cmd"; then
+  case "$deplibs_check_method" in
+  "file_magic "*)
+    file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+    if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+       egrep "$file_magic_regex" > /dev/null; then
+      :
+    else
+      cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+    fi ;;
+  esac
+fi
+
+echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&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
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+
+aix4*)
+  test "$enable_shared" = yes && enable_static=no
+  ;;
+esac
+
+echo "$ac_t$enable_shared" 1>&6
+
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+
+echo "checking whether to build static libraries... $enable_static" 1>&6
+
+if test "$hardcode_action" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+echo $ac_n "checking for objdir... $ac_c" 1>&6
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$ac_t$objdir" 1>&6
+
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+if eval "test \"`echo '$''{'lt_cv_dlopen'+set}'`\" != set"; then
+  lt_cv_dlopen=no lt_cv_dlopen_libs=
+echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "$progname:2170: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2178 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* 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; }
+EOF
+if { (eval echo $progname:2188: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen""... $ac_c" 1>&6
+echo "$progname:2207: checking for dlopen" >&5
+if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2212 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char dlopen(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* 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() {
+
+/* 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
+dlopen();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_dlopen=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_dlopen=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dlopen"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6
+echo "$progname:2251: checking for dld_link in -ldld" >&5
+ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldld  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2259 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* 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; }
+EOF
+if { (eval echo $progname:2269: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load""... $ac_c" 1>&6
+echo "$progname:2288: checking for shl_load" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2293 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shl_load(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* 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() {
+
+/* 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
+shl_load();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2315: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_shl_load=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_shl_load=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="shl_load"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
+echo "$progname:2333: checking for shl_load in -ldld" >&5
+ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldld  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2341 "ltconfig"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* 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; }
+EOF
+if { (eval echo $progname:2352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+fi
+
+    
+fi
+
+  
+fi
+
+
+fi
+
+fi
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  fi
+
+  case "$lt_cv_dlopen" in
+  dlopen)
+for ac_hdr in dlfcn.h; do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "$progname:2395: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2400 "ltconfig"
+#include <$ac_hdr>
+int fnord = 0;
+EOF
+ac_try="$ac_compile conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo $progname:2405: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+    if test "x$ac_cv_header_dlfcn_h" = xyes; then
+      CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+    fi
+    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+  echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2433: checking whether a program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self+set}" = set; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    lt_cv_dlopen_self=cross
+  else
+    cat > conftest.c <<EOF
+#line 2441 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL   RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+#  define LTDL_GLOBAL  DL_GLOBAL
+# else
+#  define LTDL_GLOBAL  0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+#  define LTDL_LAZY_OR_NOW     RTLD_LAZY
+# else
+#  ifdef DL_LAZY
+#   define LTDL_LAZY_OR_NOW    DL_LAZY
+#  else
+#   ifdef RTLD_NOW
+#    define LTDL_LAZY_OR_NOW   RTLD_NOW
+#   else
+#    ifdef DL_NOW
+#     define LTDL_LAZY_OR_NOW  DL_NOW
+#    else
+#     define LTDL_LAZY_OR_NOW  0
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+    if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+              if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } 
+
+EOF
+if { (eval echo $progname:2487: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  lt_cv_dlopen_self=yes
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  lt_cv_dlopen_self=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self" 1>&6
+
+  if test "$lt_cv_dlopen_self" = yes; then
+    LDFLAGS="$LDFLAGS $link_static_flag"
+  echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2506: checking whether a statically linked program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    lt_cv_dlopen_self_static=cross
+  else
+    cat > conftest.c <<EOF
+#line 2514 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL   RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+#  define LTDL_GLOBAL  DL_GLOBAL
+# else
+#  define LTDL_GLOBAL  0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+#  define LTDL_LAZY_OR_NOW     RTLD_LAZY
+# else
+#  ifdef DL_LAZY
+#   define LTDL_LAZY_OR_NOW    DL_LAZY
+#  else
+#   ifdef RTLD_NOW
+#    define LTDL_LAZY_OR_NOW   RTLD_NOW
+#   else
+#    ifdef DL_NOW
+#     define LTDL_LAZY_OR_NOW  DL_NOW
+#    else
+#     define LTDL_LAZY_OR_NOW  0
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+    if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+    if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } 
+
+EOF
+if { (eval echo $progname:2560: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  lt_cv_dlopen_self_static=yes
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  lt_cv_dlopen_self_static=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6
+fi
+    ;;
+  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
+
+# Copy echo and quote the copy, instead of the original, because it is
+# used later.
+ltecho="$echo"
+if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+   ltecho="$CONFIG_SHELL \$0 --fallback-echo"
+fi
+LTSHELL="$SHELL"
+
+LTCONFIG_VERSION="$VERSION"
+
+# Only quote variables if we're using ltmain.sh.
+case "$ltmain" in
+*.sh)
+  # Now quote all the things that may contain metacharacters.
+  for var in ltecho old_CC old_CFLAGS old_CPPFLAGS \
+    old_LD old_LDFLAGS old_LIBS \
+    old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS \
+    AR CC LD LN_S NM LTSHELL LTCONFIG_VERSION \
+    reload_flag reload_cmds wl \
+    pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
+    thread_safe_flag_spec whole_archive_flag_spec libname_spec \
+    library_names_spec soname_spec \
+    RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+    old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds postuninstall_cmds \
+    file_magic_cmd export_symbols_cmds deplibs_check_method allow_undefined_flag no_undefined_flag \
+    finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
+    hardcode_libdir_flag_spec hardcode_libdir_separator  \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
+
+    case "$var" in
+    reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case "$ltecho" in
+  *'\$0 --fallback-echo"')
+    ltecho=`$echo "X$ltecho" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+  trap "$rm \"$ofile\"; exit 1" 1 2 15
+  echo "creating $ofile"
+  $rm "$ofile"
+  cat <<EOF > "$ofile"
+#! $SHELL
+
+# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# 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.
+#
+# 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.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "\${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi
+
+### BEGIN LIBTOOL CONFIG
+EOF
+  cfgfile="$ofile"
+  ;;
+
+*)
+  # Double-quote the variables that need it (for aesthetics).
+  for var in old_CC old_CFLAGS old_CPPFLAGS \
+    old_LD old_LDFLAGS old_LIBS \
+    old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS; do
+    eval "$var=\\\"\$var\\\""
+  done
+
+  # Just create a config file.
+  cfgfile="$ofile.cfg"
+  trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+  echo "creating $cfgfile"
+  $rm "$cfgfile"
+  cat <<EOF > "$cfgfile"
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+EOF
+  ;;
+esac
+
+cat <<EOF >> "$cfgfile"
+# Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# CC=$old_CC CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\
+# LD=$old_LD LDFLAGS=$old_LDFLAGS LIBS=$old_LIBS \\
+# NM=$old_NM RANLIB=$old_RANLIB LN_S=$old_LN_S \\
+# DLLTOOL=$old_DLLTOOL OBJDUMP=$old_OBJDUMP AS=$old_AS \\
+#   $0$ltconfig_args
+#
+# Compiler and other test output produced by $progname, useful for
+# debugging $progname, is in ./config.log if it exists.
+
+# The version of $progname that generated this script.
+LTCONFIG_VERSION=$LTCONFIG_VERSION
+
+# Shell to use when invoking shell scripts.
+SHELL=$LTSHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$ltecho
+
+# The archiver.
+AR=$AR
+
+# The default C compiler.
+CC=$CC
+
+# The linker used to build libraries.
+LD=$LD
+
+# Whether we need hard or soft links.
+LN_S=$LN_S
+
+# A BSD-compatible nm program.
+NM=$NM
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$reload_flag
+reload_cmds=$reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$wl
+
+# Object file suffix (normally "o").
+objext="$objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$pic_flag
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$compiler_c_o
+
+# Can we write directly to a .lo ?
+compiler_o_lo=$compiler_o_lo
+
+# Must we lock files when doing compilation ?
+need_locks=$need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$link_static_flag
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$RANLIB
+old_archive_cmds=$old_archive_cmds
+old_postinstall_cmds=$old_postinstall_cmds
+old_postuninstall_cmds=$old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$old_archive_from_new_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$archive_cmds
+archive_expsym_cmds=$archive_expsym_cmds
+postinstall_cmds=$postinstall_cmds
+postuninstall_cmds=$postuninstall_cmds
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$global_symbol_to_cdecl
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Flag to force default rpath, to bypass effect of -L
+hardcode_default_flag='$hardcode_default_flag'
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# Set to use export list when linking programs.
+link_export='$link_export'
+link_export_all='$link_export_all'
+
+# The commands to list exported symbols.
+export_symbols_cmds=$export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$include_expsyms
+
+EOF
+
+case "$ltmain" in
+*.sh)
+  echo '### END LIBTOOL CONFIG' >> "$ofile"
+  echo >> "$ofile"
+  case "$host_os" in
+  aix3*)
+    cat <<\EOF >> "$ofile"
+
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "${COLLECT_NAMES+set}" != set; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+EOF
+    ;;
+  esac
+
+  # Append the ltmain.sh script.
+  sed '$q' "$ltmain" >> "$ofile" || (rm -f "$ofile"; exit 1)
+
+  chmod +x "$ofile"
+  ;;
+
+*)
+  # Compile the libtool program.
+  echo "FIXME: would compile $ltmain"
+  ;;
+esac
+
+test -n "$cache_file" || exit 0
+
+# AC_CACHE_SAVE
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# 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.
+# 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.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
index f886d7e5c620ee8ed50963f7edbb62cc65b0bfc7..3ca937b978c3edb4defebfef58d6a8ee3323a96e 100755 (executable)
@@ -1086,7 +1086,7 @@ compiler."
       -l*)
        if test "$arg" = "-lc"; then
          case "$host" in
-         *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
+         *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos* | *-*-aix*)
            # These systems don't actually have c library (as such)
            continue
            ;;
@@ -1629,6 +1629,9 @@ compiler."
        $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
       fi
       install_libdir="$2"
+      if test -n "$hardcode_default_flag"; then
+       eval linkopts=\"$linkopts$hardcode_default_flag\"
+      fi
 
       oldlibs=
       if test -z "$rpath"; then
@@ -1803,7 +1806,7 @@ compiler."
 
        dependency_libs="$deplibs"
        case "$host" in
-       *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
+       *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos* | *-*-aix*)
          # these systems don't actually have a c library (as such)!
          ;;
        *)
@@ -2445,6 +2448,14 @@ EOF
       fi
       finalize_rpath="$rpath"
 
+      if test -z "$compile_rpath" -a -n "$hardcode_default_flag"; then
+       eval compile_rpath=\" $hardcode_default_flag\"
+      fi
+
+      if test -z "$finalize_rpath" -a -n "$hardcode_default_flag"; then
+       eval finalize_rpath=\" $hardcode_default_flag\"
+      fi
+
       output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
       if test "X$output_objdir" = "X$output"; then
        output_objdir="$objdir"
@@ -2538,6 +2549,32 @@ extern \"C\" {
            fi
          fi
 
+       # Prepare the list of exported symbols
+       if test -z "$export_symbols"; then
+         if test "$always_export_symbols" = yes -a -n "$link_export_all"; then
+           eval link_export=\"$link_export_all\"
+         elif test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+           $show "generating symbol list for \`$output'"
+           export_symbols="$output_objdir/$output.exp"
+           $run $rm $export_symbols
+           libobjs="$objs"
+           eval cmds=\"$export_symbols_cmds\"
+           IFS="${IFS=         }"; save_ifs="$IFS"; IFS='~'
+           for cmd in $cmds; do
+             IFS="$save_ifs"
+             $show "$cmd"
+             $run eval "$cmd" || exit $?
+           done
+           IFS="$save_ifs"
+           if test -n "$export_symbols_regex"; then
+             $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+             $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+             $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+             $run eval '$mv "${export_symbols}T" "$export_symbols"'
+           fi
+         fi
+       fi
+
          for arg in $dlprefiles; do
            $show "extracting global C symbols from \`$arg'"
            name=`echo "$arg" | sed -e 's%^.*/%%'`
@@ -2649,10 +2686,15 @@ static const void *lt_preloaded_setup() {
        finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
       fi
 
+      link_export_opt=
+      if test -n "$export_symbols" -o -n "$dlsyms"; then
+       eval link_export_opt=\"$link_export\"
+      fi
+
       if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then
        # Replace the output file specification.
        compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
-       link_command="$compile_command$compile_rpath"
+       link_command="$compile_command$compile_rpath$link_export_opt"
 
        # We have no uninstalled library dependencies, so finalize right now.
        $show "$link_command"
@@ -2739,6 +2781,8 @@ static const void *lt_preloaded_setup() {
       # Replace the output file specification.
       link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
       
+      link_command="$link_command$link_export_opt"
+
       # Delete the old output files.
       $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
 
@@ -2918,7 +2962,7 @@ else
       # Run the actual program with our arguments.
 "
        case $host in
-       *-*-cygwin* | *-*-mingw | *-*-os2*)
+       *-*-cygwin* | *-*-mingw* | *-*-os2*)
          # win32 systems need to use the prog path for dll
          # lookup to work
          $echo >> $output "\
@@ -3308,7 +3352,14 @@ libdir='$install_libdir'\
          $show "$install_prog $dir/$realname $destdir/$realname"
          $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $?
 
-         if test $# -gt 0; then
+         # Windows does not have any symlinks to DLLs, despite what
+         # library_names has been set to.
+         skip_syms=false
+         case $host in
+         *-*-cygwin* | *-*-mingw*) skip_syms=true ;;
+         esac
+
+         if test "$skip_syms" = "false" && test $# -gt 0; then
            # Delete the old symlinks, and create new ones.
            for linkname
            do
@@ -3338,7 +3389,7 @@ libdir='$install_libdir'\
        $run eval "$install_prog $instname $destdir/$name" || exit $?
 
        # Maybe install the static library, too.
-       test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+       test -n "$old_library" -a $build_old_libs = yes && staticlibs="$staticlibs $dir/$old_library"
        ;;
 
       *.lo)
index 0dee32c0c042c3de80ef75328e5040cee1619c55..bc84913c00d5c41b3d21ae6761f1d7a803ddc360 100644 (file)
@@ -87,9 +87,6 @@ Package=<4>
     Project_Dep_Name ldapsearch
     End Project Dependency
     Begin Project Dependency
-    Project_Dep_Name ldbmtest
-    End Project Dependency
-    Begin Project Dependency
     Project_Dep_Name ldif
     End Project Dependency
     Begin Project Dependency
@@ -128,6 +125,9 @@ Package=<4>
     Begin Project Dependency
     Project_Dep_Name ltest_r
     End Project Dependency
+    Begin Project Dependency
+    Project_Dep_Name passwd
+    End Project Dependency
 }}}
 
 ###############################################################################
@@ -273,7 +273,7 @@ Package=<4>
 
 ###############################################################################
 
-Project: "ldbmtest"=..\servers\slapd\tools\ldbmtest.dsp - Package Owner=<4>
+Project: "ldif"=..\servers\slapd\tools\ldif.dsp - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -281,35 +281,23 @@ Package=<5>
 
 Package=<4>
 {{{
-    Begin Project Dependency
-    Project_Dep_Name backldbm
-    End Project Dependency
     Begin Project Dependency
     Project_Dep_Name liblber
     End Project Dependency
     Begin Project Dependency
-    Project_Dep_Name libldap_r
+    Project_Dep_Name libldif
     End Project Dependency
     Begin Project Dependency
-    Project_Dep_Name libldbm
+    Project_Dep_Name libldap
     End Project Dependency
     Begin Project Dependency
     Project_Dep_Name liblutil
     End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name libslapd
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name libavl
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name libldif
-    End Project Dependency
 }}}
 
 ###############################################################################
 
-Project: "ldif"=..\servers\slapd\tools\ldif.dsp - Package Owner=<4>
+Project: "libavl"=..\libraries\libavl\libavl.dsp - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -318,22 +306,13 @@ Package=<5>
 Package=<4>
 {{{
     Begin Project Dependency
-    Project_Dep_Name liblber
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name libldif
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name libldap
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name liblutil
+    Project_Dep_Name setup
     End Project Dependency
 }}}
 
 ###############################################################################
 
-Project: "libavl"=..\libraries\libavl\libavl.dsp - Package Owner=<4>
+Project: "liblber"=..\libraries\liblber\liblber.dsp - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -341,11 +320,14 @@ Package=<5>
 
 Package=<4>
 {{{
+    Begin Project Dependency
+    Project_Dep_Name setup
+    End Project Dependency
 }}}
 
 ###############################################################################
 
-Project: "liblber"=..\libraries\liblber\liblber.dsp - Package Owner=<4>
+Project: "libldap"=..\libraries\libldap\libldap.dsp - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -353,11 +335,14 @@ Package=<5>
 
 Package=<4>
 {{{
+    Begin Project Dependency
+    Project_Dep_Name setup
+    End Project Dependency
 }}}
 
 ###############################################################################
 
-Project: "libldap"=..\libraries\libldap\libldap.dsp - Package Owner=<4>
+Project: "libldap_r"=..\libraries\libldap_r\libldap_r.dsp - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -365,11 +350,14 @@ Package=<5>
 
 Package=<4>
 {{{
+    Begin Project Dependency
+    Project_Dep_Name setup
+    End Project Dependency
 }}}
 
 ###############################################################################
 
-Project: "libldap_r"=..\libraries\libldap_r\libldap_r.dsp - Package Owner=<4>
+Project: "libldbm"=..\libraries\libldbm\libldbm.dsp - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -377,11 +365,14 @@ Package=<5>
 
 Package=<4>
 {{{
+    Begin Project Dependency
+    Project_Dep_Name setup
+    End Project Dependency
 }}}
 
 ###############################################################################
 
-Project: "libldbm"=..\libraries\libldbm\libldbm.dsp - Package Owner=<4>
+Project: "libldif"=..\libraries\libldif\libldif.dsp - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -389,11 +380,14 @@ Package=<5>
 
 Package=<4>
 {{{
+    Begin Project Dependency
+    Project_Dep_Name setup
+    End Project Dependency
 }}}
 
 ###############################################################################
 
-Project: "libldif"=..\libraries\libldif\libldif.dsp - Package Owner=<4>
+Project: "liblunicode"=..\libraries\liblunicode\liblunicode.dsp - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -401,6 +395,9 @@ Package=<5>
 
 Package=<4>
 {{{
+    Begin Project Dependency
+    Project_Dep_Name setup
+    End Project Dependency
 }}}
 
 ###############################################################################
@@ -413,6 +410,9 @@ Package=<5>
 
 Package=<4>
 {{{
+    Begin Project Dependency
+    Project_Dep_Name setup
+    End Project Dependency
 }}}
 
 ###############################################################################
@@ -425,6 +425,9 @@ Package=<5>
 
 Package=<4>
 {{{
+    Begin Project Dependency
+    Project_Dep_Name setup
+    End Project Dependency
 }}}
 
 ###############################################################################
@@ -471,6 +474,24 @@ Package=<4>
 
 ###############################################################################
 
+Project: "passwd"=..\libraries\liblutil\passwd.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name liblber
+    End Project Dependency
+    Begin Project Dependency
+    Project_Dep_Name liblutil
+    End Project Dependency
+}}}
+
+###############################################################################
+
 Project: "setup"=..\include\setup.dsp - Package Owner=<4>
 
 Package=<5>
index 91a96065cba6d12bcc144ef65532e0fc6d02d114..a63385d88ae944eded5c3275154c69328947bc5a 100644 (file)
@@ -1,5 +1,5 @@
 # $OpenLDAP$
-## Copyright 1998,1999 The OpenLDAP Foundation
+## Copyright 1998-2000 The OpenLDAP Foundation
 ## COPYING RESTRICTIONS APPLY.  See COPYRIGHT File in top level directory
 ## of this package for details.
 ##---------------------------------------------------------------------------
@@ -26,17 +26,17 @@ all-common:
        done
 
 install-common:
-       -$(MKDIR) $(MANDIR)
+       -$(MKDIR) $(DESTDIR)$(MANDIR)
        PAGES=`cd $(srcdir); echo *.$(MANSECT)`; \
        for page in $$PAGES; do \
                echo "installing $(MANDIR)/$$page"; \
-               $(RM) $(MANDIR)/$$page; \
-               $(INSTALL) $(INSTALLFLAGS) -m 644 $$page.$(TMP_SUFFIX) $(MANDIR)/$$page; \
+               $(RM) $(DESTDIR)$(MANDIR)/$$page; \
+               $(INSTALL) $(INSTALLFLAGS) -m 644 $$page.$(TMP_SUFFIX) $(DESTDIR)$(MANDIR)/$$page; \
                if test -f "$(srcdir)/$$page.links" ; then \
                        for link in `$(CAT) $(srcdir)/$$page.links`; do \
                                echo "installing $(MANDIR)/$$link as link to $$page"; \
-                               $(RM) $(MANDIR)/$$link ; \
-                               $(LN_S) $$page $(MANDIR)/$$link; \
+                               $(RM) $(DESTDIR)$(MANDIR)/$$link ; \
+                               $(LN_S) $$page $(DESTDIR)$(MANDIR)/$$link; \
                        done; \
                fi; \
        done
index 55ef1e4c5091e53339993ea1c07437f462268b62..d2e316865ee29d9373d15f787c4baf30b201fb46 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh -
 # $OpenLDAP$
-## Copyright 1998,1999 The OpenLDAP Foundation
+## Copyright 1998-2000 The OpenLDAP Foundation
 ## COPYING RESTRICTIONS APPLY.  See COPYRIGHT File in top level directory
 ## of this package for details.
 #
diff --git a/build/mkdep.aix b/build/mkdep.aix
new file mode 100755 (executable)
index 0000000..1339a1d
--- /dev/null
@@ -0,0 +1,4 @@
+#! /bin/sh
+cc_r -ME $* > /dev/null
+cat *.u
+rm *.u
index c694984f3c4b5de710d5cc2fa88bb796daa73802..90bf90552d32715e56a9f0d211831414fe99d5c6 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # $OpenLDAP$
-## Copyright 1998,1999 The OpenLDAP Foundation
+## Copyright 1998-2000 The OpenLDAP Foundation
 ## COPYING RESTRICTIONS APPLY.  See COPYRIGHT File in top level directory
 ## of this package for details.
 #
@@ -45,6 +45,7 @@ fi
 tar cf $RELNAME.tar $RELNAME
 gzip -9 -c $RELNAME.tar > $RELNAME.tgz
 md5 $RELNAME.tgz > $RELNAME.md5
+rm -f $RELNAME.tar
 
 ls -l $RELNAME.*
 cat $RELNAME/build/version
index d0ba1373a1c7aff4339fabe52fdf4b89d91130fe..d8c98914e2f6560b7965d3953beeec3523eaf13f 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # $OpenLDAP$
-## Copyright 1998,1999 The OpenLDAP Foundation
+## Copyright 1998-2000 The OpenLDAP Foundation
 ## COPYING RESTRICTIONS APPLY.  See COPYRIGHT File in top level directory
 ## of this package for details.
 #
@@ -47,7 +47,7 @@ WHOWHERE="$USER@`uname -n`:`pwd`"
 
 cat << __EOF__
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation
+ * Copyright 1998-2000 The OpenLDAP Foundation
  * COPYING RESTRICTIONS APPLY.  See COPYRIGHT File in top level directory
  * of this package for details.
  */
index 380e1dc78c4191a97c9c4938a54562beaaa5f55c..7433cf07898282f68ff25cec2897e44e13a7a181 100644 (file)
@@ -1,5 +1,5 @@
 # $OpenLDAP$
-## Copyright 1998,1999 The OpenLDAP Foundation
+## Copyright 1998-2000 The OpenLDAP Foundation
 ## COPYING RESTRICTIONS APPLY.  See COPYRIGHT File in top level directory
 ## of this package for details.
 ##---------------------------------------------------------------------------
@@ -9,8 +9,20 @@
 
 LIBRARY = $(LIBBASE).la
 LIBSTAT = lib$(LIBBASE).a
+
 LTFLAGS = --only-$(LINKAGE)
 
+COMPILE = $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) $(CFLAGS) $(MODDEFS) -c
+LTLIBLINK = $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) \
+               $(LTVERSION) $(LT_NO_UNDEF)
+
+MKDEPFLAG = -l
+
+.SUFFIXES: .c .o .lo
+
+.c.lo:
+       $(COMPILE) $<
+
 all-no lint-no 5lint-no depend-no install-no: FORCE
        @echo "run configure with $(BUILD_OPT) to make $(LIBBASE)"
 
@@ -20,8 +32,9 @@ version.c: $(OBJS)
        $(RM) $@
        $(MKVERSION) $(LIBBASE) > $@
 
-$(LIBRARY): version.lo
-       $(LTLIBLINK) -module -rpath $(moduledir) -o $@ $(OBJS) version.lo
+$(LIBRARY): $(MODDEPS) version.lo
+       $(LTLIBLINK) -module -rpath $(moduledir) -o $@ $(OBJS) version.lo \
+           $(MODLIBS)
 
 $(LIBSTAT): version.lo
        $(AR) ruv $@ `echo $(OBJS) | sed 's/\.lo/.o/g'` version.o
@@ -46,8 +59,8 @@ all-local-lib:
 all-yes: $(LIBSTAT) all-local-lib FORCE
 
 install-mod: $(LIBRARY)
-       @-$(MKDIR) $(moduledir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 $(LIBRARY) $(moduledir)
+       @-$(MKDIR) $(DESTDIR)$(moduledir)
+       $(LTINSTALL) $(INSTALLFLAGS) -m 755 $(LIBRARY) $(DESTDIR)$(moduledir)
 
 install-local-lib:
 install-yes: install-local-lib FORCE
@@ -71,12 +84,5 @@ depend-yes depend-mod: depend-local-lib FORCE
 veryclean-local-lib:
 veryclean-lib:         clean-lib veryclean-local-lib
 
-COMPILE = $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) $(CFLAGS) -c
-MKDEPFLAG = -l
-
-.SUFFIXES: .c .o .lo
-
-.c.lo:
-       $(COMPILE) $<
-
 Makefile: $(top_srcdir)/build/mod.mk
+
index 4ceadfe3e11165acdaf77673c8aaccd1fcbb4b8b..1ce490ff12a9098205349429ccba2387d4fe942c 100644 (file)
@@ -1,6 +1,6 @@
 dnl $OpenLDAP$
 dnl
-dnl Copyright 1998-1999 The OpenLDAP Foundation,  All Rights Reserved.
+dnl Copyright 1998-2000 The OpenLDAP Foundation,  All Rights Reserved.
 dnl COPYING RESTRICTIONS APPLY, See COPYRIGHT file
 dnl
 dnl OpenLDAP Autoconf Macros
@@ -56,6 +56,33 @@ dnl AC_VERBOSE(OpenLDAP --with-$1 $ol_with_$1)
 ])dnl
 dnl
 dnl ====================================================================
+dnl
+AC_DEFUN(AC_COMPILE_CHECK_SIZEOF,
+[changequote(<<, >>)dnl 
+dnl The name to #define. 
+define(<<AC_TYPE_NAME>>, translit(sizeof_$1, [a-z *], [A-Z_P]))dnl 
+dnl The cache variable name. 
+define(<<AC_CV_NAME>>, translit(ac_cv_sizeof_$1, [ *], [_p]))dnl 
+changequote([, ])dnl 
+AC_MSG_CHECKING(size of $1) 
+AC_CACHE_VAL(AC_CV_NAME, 
+[for ac_size in 4 8 1 2 16 $2 ; do # List sizes in rough order of prevalence. 
+  AC_TRY_COMPILE([#include "confdefs.h" 
+#include <sys/types.h> 
+$2 
+], [switch (0) case 0: case (sizeof ($1) == $ac_size):;], AC_CV_NAME=$ac_size) 
+  if test x$AC_CV_NAME != x ; then break; fi 
+done 
+]) 
+if test x$AC_CV_NAME = x ; then 
+  AC_MSG_ERROR([cannot determine a size for $1]) 
+fi 
+AC_MSG_RESULT($AC_CV_NAME) 
+AC_DEFINE_UNQUOTED(AC_TYPE_NAME, $AC_CV_NAME, [The number of bytes in type $1]) 
+undefine([AC_TYPE_NAME])dnl 
+undefine([AC_CV_NAME])dnl 
+])
+dnl ====================================================================
 dnl check if hard links are supported.
 dnl
 AC_DEFUN([OL_PROG_LN_H], [# test for ln hardlink support
@@ -211,141 +238,166 @@ fi
 ])
 dnl
 dnl ====================================================================
-dnl Check if db.h is Berkeley DB2
+dnl Berkeley DB macros
 dnl
-dnl defines ol_cv_header_db2 to 'yes' or 'no'
-dnl
-dnl uses:
-dnl            AC_CHECK_HEADERS(db.h)
-dnl
-AC_DEFUN([OL_HEADER_BERKELEY_DB2],
-[AC_CHECK_HEADERS(db.h)
-if test $ac_cv_header_db_h = yes ; then
-       AC_CACHE_CHECK([if db.h is DB2], [ol_cv_header_db2],[
-               AC_EGREP_CPP(__db_version_2,[
-#                      include <db.h>
-                       /* this check could be improved */
-#                      ifdef DB_VERSION_MAJOR
-#                              if DB_VERSION_MAJOR == 2
-                                       __db_version_2
-#                              endif
-#                      endif
-               ], ol_cv_header_db2=yes, ol_cv_header_db2=no)])
-else
-       ol_cv_header_db2=no
-fi
-])dnl
 dnl --------------------------------------------------------------------
-dnl Check if Berkeley DB2 library exists
-dnl Check for dbopen in standard libraries or -ldb
-dnl
-dnl defines ol_cv_lib_db2 to '-ldb' or 'no'
-dnl
-dnl uses:
-dnl            AC_CHECK_LIB(db,db_open)
-dnl
-AC_DEFUN([OL_LIB_BERKELEY_DB2],
-[AC_CACHE_CHECK([for DB2 library], [ol_cv_lib_db2],
-[      ol_LIBS="$LIBS"
-       AC_CHECK_LIB(db,db_open,[ol_cv_lib_db2=-ldb],[ol_cv_lib_db2=no])
+dnl Try to link
+AC_DEFUN([OL_BERKELEY_DB_TRY],
+[if test $ol_cv_lib_db = no ; then
+       AC_CACHE_CHECK([for Berkeley DB link (]ifelse($2,,default,$2)[)],[$1],
+[
+       ol_DB_LIB=ifelse($2,,,$2)
+       ol_LIBS=$LIBS
+       LIBS="$ol_DB_LIB $LIBS"
+
+       AC_TRY_LINK([
+#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
+],[
+#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
+],[$1=yes],[$1=no])
+
        LIBS="$ol_LIBS"
 ])
-])dnl
-dnl
-dnl --------------------------------------------------------------------
-dnl Check if Berkeley db2 exists
-dnl
-dnl defines ol_cv_berkeley_db2 to 'yes' or 'no'
-dnl 
-dnl uses:
-dnl            OL_LIB_BERKELEY_DB2
-dnl            OL_HEADER_BERKELEY_DB2
-dnl
-AC_DEFUN([OL_BERKELEY_DB2],
-[AC_REQUIRE([OL_LIB_BERKELEY_DB2])
- AC_REQUIRE([OL_HEADER_BERKELEY_DB2])
- AC_CACHE_CHECK([for Berkeley DB2], [ol_cv_berkeley_db2], [
-       if test "$ol_cv_lib_db2" = no -o "$ol_cv_header_db2" = no ; then
-               ol_cv_berkeley_db2=no
-       else
-               ol_cv_berkeley_db2=yes
-       fi
-])
- if test $ol_cv_berkeley_db2 = yes ; then
-       AC_DEFINE(HAVE_BERKELEY_DB2,1, [define if Berkeley DBv2 is available])
- fi
-])dnl
-dnl
-dnl ====================================================================
-dnl Check for db.h/db_185.h is Berkeley DB
-dnl
-dnl defines ol_cv_header_db to 'yes' or 'no'
-dnl
-dnl uses:
-dnl            OL_HEADER_BERKELEY_DB2
-dnl            AC_CHECK_HEADERS(db_185.h)
-dnl
-AC_DEFUN([OL_HEADER_BERKELEY_DB],
-[AC_REQUIRE([OL_HEADER_BERKELEY_DB2])
-AC_CHECK_HEADERS(db_185.h)
-if test "$ol_cv_header_db2" = yes ; then
-       dnl db.h is db2! 
 
-       ol_cv_header_db=$ac_cv_header_db_185_h
-else
-       ol_cv_header_db=$ac_cv_header_db_h
+       if test $$1 = yes ; then
+               ol_cv_lib_db=ifelse($2,,yes,$2)
+       fi
 fi
-])dnl
+])
 dnl
 dnl --------------------------------------------------------------------
-dnl Check if Berkeley DB library exists
-dnl Check for dbopen in standard libraries or -ldb
-dnl
-dnl defines ol_cv_lib_db to 'yes' or '-ldb' or 'no'
-dnl            'yes' implies dbopen is in $LIBS
-dnl
-dnl uses:
-dnl            AC_CHECK_FUNC(dbopen)
-dnl            AC_CHECK_LIB(db,dbopen)
+dnl Try to locate appropriate library
+AC_DEFUN([OL_BERKELEY_DB_LINK],
+[ol_cv_lib_db=no
+OL_BERKELEY_DB_TRY(ol_cv_db_none)
+OL_BERKELEY_DB_TRY(ol_cv_db_db,[-ldb])
+OL_BERKELEY_DB_TRY(ol_cv_db_db3,[-ldb3])
+OL_BERKELEY_DB_TRY(ol_cv_db_db2,[-ldb2])
+OL_BERKELEY_DB_TRY(ol_cv_db_db1,[-ldb1])
+])
 dnl
-AC_DEFUN([OL_LIB_BERKELEY_DB],
-[AC_CACHE_CHECK([for Berkeley DB library], [ol_cv_lib_db],
-[
-       AC_CHECK_HEADERS(db1/db.h)
+dnl --------------------------------------------------------------------
+dnl Check if Berkeley DB supports DB_THREAD
+AC_DEFUN([OL_BERKELEY_DB_THREAD],
+[AC_CACHE_CHECK([for Berkeley DB thread support], [ol_cv_berkeley_db_thread], [
        ol_LIBS="$LIBS"
-       AC_CHECK_FUNC(dbopen,[ol_cv_lib_db=yes], [
-               AC_CHECK_LIB(db1,dbopen,[ol_cv_lib_db=-ldb1],[
-                       AC_CHECK_LIB(db,dbopen,[ol_cv_lib_db=-ldb],
-                       [ol_cv_lib_db=no])
-               ])
-       ])
+       if test $ol_cv_lib_db != yes ; then
+               LIBS="$ol_cv_lib_db"
+       fi
+
+       AC_TRY_RUN([
+#ifdef HAVE_DB_185_H
+       choke me;
+#else
+#include <db.h>
+#endif
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+main()
+{
+       int rc;
+       u_int32_t flags = DB_CREATE | DB_THREAD;
+
+
+#if DB_VERSION_MAJOR > 2
+       DB_ENV *env = NULL;
+
+       rc = db_env_create( &env, 0 );
+
+       if( rc == 0 ) {
+               rc = env->open( env, NULL, NULL, flags, 0 );
+       }
+
+#else
+       DB_ENV env;
+       memset( &env, '\0', sizeof(env) );
+
+       rc = db_appinit( NULL, NULL, &env, flags );
+
+       if( rc == 0 ) {
+               db_appexit( &env );
+       }
+#endif
+
+       return rc;
+}],
+       [ol_cv_berkeley_db_thread=yes],
+       [ol_cv_berkeley_db_thread=no],
+       [ol_cv_berkeley_db_thread=cross])
+
        LIBS="$ol_LIBS"
-])
-])dnl
+
+       if test $ol_cv_berkeley_db_thread != no ; then
+               AC_DEFINE(HAVE_BERKELEY_DB_THREAD, 1,
+                       [define if Berkeley DB has DB_THREAD support])
+       fi
+])])dnl
 dnl
 dnl --------------------------------------------------------------------
-dnl Check if Berkeley DB exists
-dnl
-dnl defines ol_cv_berkeley_db to 'yes' or 'no'
-dnl 
-dnl uses:
-dnl            OL_LIB_BERKELEY_DB
-dnl            OL_HEADER_BERKELEY_DB
-dnl
+dnl Find any DB
 AC_DEFUN([OL_BERKELEY_DB],
-[AC_REQUIRE([OL_LIB_BERKELEY_DB])
- AC_REQUIRE([OL_HEADER_BERKELEY_DB])
- AC_CACHE_CHECK([for Berkeley DB], [ol_cv_berkeley_db], [
-       if test "$ol_cv_lib_db" = no -o "$ol_cv_header_db" = no ; then
-               ol_cv_berkeley_db=no
-       else
+[ol_cv_berkeley_db=no
+AC_CHECK_HEADERS(db.h)
+if test $ac_cv_header_db_h = yes; then
+       OL_BERKELEY_DB_LINK
+       if test "$ol_cv_lib_db" != no ; then
                ol_cv_berkeley_db=yes
+               OL_BERKELEY_DB_THREAD
        fi
+fi
+])
+dnl
+dnl --------------------------------------------------------------------
+dnl Find old Berkeley DB 1.85/1.86
+AC_DEFUN([OL_BERKELEY_COMPAT_DB],
+[ol_cv_berkeley_db=no
+AC_CHECK_HEADERS(db_185.h db.h)
+if test $ac_cv_header_db_185_h = yes -o $ac_cv_header_db_h = yes; then
+       AC_CACHE_CHECK([if Berkeley DB header compatibility], [ol_cv_header_db1],[
+               AC_EGREP_CPP(__db_version_1,[
+#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
+],     [ol_cv_header_db1=yes], [ol_cv_header_db1=no])])
+
+       if test ol_cv_header_db1=yes ; then
+               OL_BERKELEY_DB_LINK
+               if test "$ol_cv_lib_db" != no ; then
+                       ol_cv_berkeley_db=yes
+               fi
+       fi
+fi
 ])
- if test $ol_cv_berkeley_db = yes ; then
-       AC_DEFINE(HAVE_BERKELEY_DB,1, [define if Berkeley DB is available])
- fi
-])dnl
 dnl
 dnl ====================================================================
 dnl Check if GDBM library exists
@@ -507,7 +559,7 @@ AC_DEFUN([OL_POSIX_THREAD_VERSION],
 #              include <pthread.h>
                /* this check could be improved */
 #              ifdef PTHREAD_ONCE_INIT
-                       pthread_version_final
+                       pthread_version_final;
 #              endif
        ], ol_pthread_final=yes, ol_pthread_final=no)
 
@@ -515,7 +567,7 @@ AC_DEFUN([OL_POSIX_THREAD_VERSION],
 #              include <pthread.h>
                /* this check could be improved */
 #              ifdef pthread_once_init
-                       pthread_version_draft4
+                       pthread_version_draft4;
 #              endif
        ], ol_pthread_draft4=yes, ol_pthread_draft4=no)
 
@@ -547,14 +599,26 @@ AC_DEFUN([OL_PTHREAD_TEST_FUNCTION],[
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -620,7 +684,7 @@ AC_DEFUN([OL_HEADER_GNU_PTH_PTHREAD_H], [
                [AC_EGREP_CPP(__gnu_pth__,
                        [#include <pthread.h>
 #ifdef _POSIX_THREAD_IS_GNU_PTH
-       __gnu_pth__
+       __gnu_pth__;
 #endif
 ],
                        [ol_cv_header_gnu_pth_pthread_h=yes],
@@ -628,6 +692,19 @@ AC_DEFUN([OL_HEADER_GNU_PTH_PTHREAD_H], [
                ])
 ])dnl
 dnl ====================================================================
+dnl Check for NT Threads
+AC_DEFUN([OL_NT_THREADS], [
+       AC_CACHE_CHECK([for NT Threads], [ol_cv_nt_threads], [
+               AC_CHECK_FUNC(_beginthread,
+                       [ol_cv_nt_threads=yes],
+                       [ol_cv_nt_threads=no])
+       ])
+
+       if test $ol_cv_nt_threads = yes ; then
+               AC_DEFINE(HAVE_NT_THREADS,1,[if you have NT Threads])
+       fi
+])
+dnl ====================================================================
 dnl Check LinuxThreads Header
 dnl
 dnl defines ol_cv_header linux_threads to 'yes' or 'no'
@@ -740,7 +817,10 @@ AC_DEFUN([OL_SYS_ERRLIST],
        AC_TRY_COMPILE([
 #include <stdio.h>
 #include <sys/types.h>
-#include <errno.h> ],
+#include <errno.h>
+#ifdef WINNT
+#include <stdlib.h>
+#endif ],
        [char *c = (char *) *sys_errlist],
        [ol_cv_dcl_sys_errlist=yes
        ol_cv_have_sys_errlist=yes],
@@ -783,7 +863,7 @@ dnl
 dnl ====================================================================
 dnl Look for fetch(3)
 AC_DEFUN([OL_LIB_FETCH],
-[ol=$LIBS
+[ol_LIBS=$LIBS
 LIBS="-lfetch -lcom_err $LIBS"
 AC_CACHE_CHECK([fetch(3) library],ol_cv_lib_fetch,[
        AC_TRY_LINK([
@@ -865,13 +945,31 @@ AC_DEFUN(OL_FUNC_CTIME_R_NARGS,
  [AC_CACHE_CHECK(number of arguments of ctime_r, ol_cv_func_ctime_r_nargs,
    [AC_TRY_COMPILE([#include <time.h>],
                [time_t ti; char *buffer; ctime_r(&ti,buffer,32);],
-                       ol_cv_func_ctime_r_nargs=3,
-                       [AC_TRY_COMPILE([#include <time.h>],
-                               [time_t ti; char *buffer; ctime_r(&ti,buffer);],
-                                       ol_cv_func_ctime_r_nargs=2,
-                                       ol_cv_func_ctime_r_nargs=0)])])
+                       ol_cv_func_ctime_r_nargs3=yes,
+                       ol_cv_func_ctime_r_nargs3=no)
+
+       AC_TRY_COMPILE([#include <time.h>],
+               [time_t ti; char *buffer; ctime_r(&ti,buffer);],
+                       ol_cv_func_ctime_r_nargs2=yes,
+                       ol_cv_func_ctime_r_nargs2=no)
+
+       if test $ol_cv_func_ctime_r_nargs3 = yes -a \
+               $ol_cv_func_ctime_r_nargs2 = no ; then
+
+               ol_cv_func_ctime_r_nargs=3
+
+       elif test $ol_cv_func_ctime_r_nargs3 = no -a \
+               $ol_cv_func_ctime_r_nargs2 = yes ; then
+
+               ol_cv_func_ctime_r_nargs=2
+
+       else
+               ol_cv_func_ctime_r_nargs=0
+       fi
+  ])
+
   if test $ol_cv_func_ctime_r_nargs -gt 1 ; then
-    AC_DEFINE_UNQUOTED(CTIME_R_NARGS, $ol_cv_func_ctime_r_nargs,
+       AC_DEFINE_UNQUOTED(CTIME_R_NARGS, $ol_cv_func_ctime_r_nargs,
                [set to the number of arguments ctime_r() expects])
   fi
 ])dnl
@@ -902,19 +1000,36 @@ AC_DEFUN(OL_FUNC_GETHOSTBYNAME_R_NARGS,
                int bufsize=BUFSIZE;int h_errno;
                (void)gethostbyname_r("segovia.cs.purdue.edu", &hent,
                        buffer, bufsize, &h_errno);],
-               ol_cv_func_gethostbyname_r_nargs=5, 
-               [AC_TRY_COMPILE([#include <sys/types.h>
+               ol_cv_func_gethostbyname_r_nargs5=yes, 
+               ol_cv_func_gethostbyname_r_nargs5=no)
+
+       AC_TRY_COMPILE([#include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <netdb.h>
 #define BUFSIZE (sizeof(struct hostent)+10)],
-                       [struct hostent hent;struct hostent *rhent;
-                       char buffer[BUFSIZE];
-                       int bufsize=BUFSIZE;int h_errno;
-                       (void)gethostbyname_r("localhost", &hent, buffer, bufsize,
-                               &rhent, &h_errno);],
-                       ol_cv_func_gethostbyname_r_nargs=6,
-                       ol_cv_func_gethostbyname_r_nargs=0)])])
+               [struct hostent hent;struct hostent *rhent;
+               char buffer[BUFSIZE];
+               int bufsize=BUFSIZE;int h_errno;
+               (void)gethostbyname_r("localhost", &hent, buffer, bufsize,
+                       &rhent, &h_errno);],
+               ol_cv_func_gethostbyname_r_nargs6=yes,
+               ol_cv_func_gethostbyname_r_nargs6=no)
+
+       if test $ol_cv_func_gethostbyname_r_nargs5 = yes -a \
+               $ol_cv_func_gethostbyname_r_nargs6 = no ; then
+
+               ol_cv_func_gethostbyname_r_nargs=5
+
+       elif test $ol_cv_func_gethostbyname_r_nargs5 = no -a \
+               $ol_cv_func_gethostbyname_r_nargs6 = yes ; then
+
+               ol_cv_func_gethostbyname_r_nargs=6
+
+       else
+               ol_cv_func_gethostbyname_r_nargs=0
+       fi
+  ])
   if test $ol_cv_func_gethostbyname_r_nargs -gt 1 ; then
        AC_DEFINE_UNQUOTED(GETHOSTBYNAME_R_NARGS,
                $ol_cv_func_gethostbyname_r_nargs,
@@ -937,22 +1052,39 @@ AC_DEFUN(OL_FUNC_GETHOSTBYADDR_R_NARGS,
            int bufsize=BUFSIZE;int h_errno;
                (void)gethostbyaddr_r( (void *)&(add.s_addr),
                        alen, AF_INET, &hent, buffer, bufsize, &h_errno);],
-               ol_cv_func_gethostbyaddr_r_nargs=7,
-               [AC_TRY_COMPILE([#include <sys/types.h>
+               ol_cv_func_gethostbyaddr_r_nargs7=yes,
+               ol_cv_func_gethostbyaddr_r_nargs7=no)
+
+       AC_TRY_COMPILE([#include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <netdb.h>
 #define BUFSIZE (sizeof(struct hostent)+10)],
-                       [struct hostent hent;
-                       struct hostent *rhent; char buffer[BUFSIZE]; 
-                       struct in_addr add;
-                       size_t alen=sizeof(struct in_addr);
-                       int bufsize=BUFSIZE;int h_errno;
-                       (void)gethostbyaddr_r( (void *)&(add.s_addr),
-                               alen, AF_INET, &hent, buffer, bufsize, 
-                               &rhent, &h_errno);],
-                       ol_cv_func_gethostbyaddr_r_nargs=8,
-                       ol_cv_func_gethostbyaddr_r_nargs=0)])])
+               [struct hostent hent;
+               struct hostent *rhent; char buffer[BUFSIZE]; 
+               struct in_addr add;
+               size_t alen=sizeof(struct in_addr);
+               int bufsize=BUFSIZE;int h_errno;
+               (void)gethostbyaddr_r( (void *)&(add.s_addr),
+                       alen, AF_INET, &hent, buffer, bufsize, 
+                       &rhent, &h_errno);],
+               ol_cv_func_gethostbyaddr_r_nargs8=yes,
+               ol_cv_func_gethostbyaddr_r_nargs8=no)
+
+       if test $ol_cv_func_gethostbyaddr_r_nargs7 = yes -a \
+               $ol_cv_func_gethostbyaddr_r_nargs8 = no ; then
+
+               ol_cv_func_gethostbyaddr_r_nargs=7
+
+       elif test $ol_cv_func_gethostbyaddr_r_nargs7 = no -a \
+               $ol_cv_func_gethostbyaddr_r_nargs8 = yes ; then
+
+               ol_cv_func_gethostbyaddr_r_nargs=8
+
+       else
+               ol_cv_func_gethostbyaddr_r_nargs=0
+       fi
+  ])
   if test $ol_cv_func_gethostbyaddr_r_nargs -gt 1 ; then
     AC_DEFINE_UNQUOTED(GETHOSTBYADDR_R_NARGS,
                $ol_cv_func_gethostbyaddr_r_nargs,
index 4f795ff3533b8fefa33eaeeeac6fb6c8e1155b4a..0002cd0ac8153b6e3f0895118f4934d8dbbc2a17 100644 (file)
@@ -1,5 +1,5 @@
 # $OpenLDAP$
-## Copyright 1998,1999 The OpenLDAP Foundation
+## Copyright 1998-2000 The OpenLDAP Foundation
 ## COPYING RESTRICTIONS APPLY.  See COPYRIGHT File in top level directory
 ## of this package for details.
 ##---------------------------------------------------------------------------
@@ -10,7 +10,8 @@
 all-common: $(PROGRAMS) FORCE
 
 clean-common:  FORCE
-       $(RM) $(PROGRAMS) $(XPROGRAMS) $(XSRCS) *.o *.lo a.out core *.core .libs/*
+       $(RM) $(PROGRAMS) $(XPROGRAMS) $(XSRCS) *.o *.lo a.out core *.core \
+                   .libs/* *.exe
 
 depend-common: FORCE
        $(MKDEP) $(DEFS) $(DEFINES) $(SRCS)
index ee6d5daa2741cadefa7aa9049201e0897cd6ae81..cfc51b0954497569687331dddc7ee4f44122b48f 100644 (file)
@@ -1,5 +1,5 @@
 # $OpenLDAP$
-## Copyright 1998,1999 The OpenLDAP Foundation
+## Copyright 1998-2000 The OpenLDAP Foundation
 ## COPYING RESTRICTIONS APPLY.  See COPYRIGHT File in top level directory
 ## of this package for details.
 ##---------------------------------------------------------------------------
@@ -38,7 +38,7 @@ lint-yes: lint-local-srv FORCE
 
 clean-local-srv:
 clean-srv:     clean-local-srv FORCE
-       $(RM) $(PROGRAMS) $(XPROGRAMS) $(XSRCS) *.o a.out core .libs/*
+       $(RM) $(PROGRAMS) $(XPROGRAMS) $(XSRCS) *.o a.out core .libs/* *.exe
 
 depend-local-srv:
 depend-yes: depend-local-srv FORCE
index 9dc7dcdce0ebdcf1f33838127f3c1ee291ff2dbe..98cbf1aadb22212af057cb1f32b96647a4976141 100644 (file)
@@ -1,5 +1,5 @@
 # $OpenLDAP$
-## Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+## Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
 ## All rights reserved.
 ##
 ## Redistribution and use in source and binary forms are permitted only
@@ -22,18 +22,18 @@ prefix = @prefix@
 exec_prefix = @exec_prefix@
 ldap_subdir = @ldap_subdir@
 
-bindir = $(TMPROOT)@bindir@
-datadir = $(TMPROOT)@datadir@$(ldap_subdir)
-includedir = $(TMPROOT)@includedir@
-infodir = $(TMPROOT)@infodir@
-libdir = $(TMPROOT)@libdir@
-libexecdir = $(TMPROOT)@libexecdir@
-localstatedir = $(TMPROOT)@localstatedir@
-mandir = $(TMPROOT)@mandir@
-moduledir = $(TMPROOT)@libexecdir@$(ldap_subdir)
-sbindir = $(TMPROOT)@sbindir@
-sharedstatedir = $(TMPROOT)@sharedstatedir@
-sysconfdir = $(TMPROOT)@sysconfdir@$(ldap_subdir)
+bindir = @bindir@
+datadir = @datadir@$(ldap_subdir)
+includedir = @includedir@
+infodir = @infodir@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+moduledir = @libexecdir@$(ldap_subdir)
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@$(ldap_subdir)
 
 EXEEXT = @EXEEXT@
 OBJEXT = @OBJEXT@
@@ -54,9 +54,8 @@ MKDEP_CFLAGS = @OL_MKDEP_FLAGS@
 MKVERSION = $(top_srcdir)/build/mkversion -v "$(VERSION)"
 
 LIBTOOL = @LIBTOOL@
-LIBVERSION = 2:0:0
+LIBVERSION = 0:0:0
 LTVERSION = -version-info $(LIBVERSION)
-LTLIBLINK  = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LTVERSION)
 LTLINK  = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS)
 LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL) 
 
@@ -114,6 +113,7 @@ LDAP_LIBDEPEND = $(LDAP_LIBLDAP_DEPEND) $(LDAP_LIBLBER_DEPEND) \
 SLAPD_LIBDEPEND = $(LDAP_LIBDEPEND) $(LDAP_LIBAVL_DEPEND) \
        $(LDAP_LIBLDBM_DEPEND) $(LDAP_LIBLTHREAD_DEPEND)
 
+WRAP_LIBS = @WRAP_LIBS@
 # AutoConfig generated 
 AC_CC  = @CC@
 AC_CFLAGS = @CFLAGS@
@@ -121,18 +121,21 @@ AC_DEFS = @CPPFLAGS@ # @DEFS@
 AC_LDFLAGS = @LDFLAGS@
 AC_LIBS = @LIBS@
 
-KRB_LIBS = @KRB_LIBS@
+KRB4_LIBS = @KRB4_LIBS@
+KRB5_LIBS = @KRB5_LIBS@
+KRB_LIBS = @KRB4_LIBS@ @KRB5_LIBS@
 SASL_LIBS = @SASL_LIBS@
 TLS_LIBS = @TLS_LIBS@
-SECURITY_LIBS = @SASL_LIBS@ @KRB_LIBS@ @TLS_LIBS@
+AUTH_LIBS = @AUTH_LIBS@
+SECURITY_LIBS = $(SASL_LIBS) $(KRB_LIBS) $(TLS_LIBS) $(AUTH_LIBS)
 
 MODULES_CPPFLAGS = @SLAPD_MODULES_CPPFLAGS@
 MODULES_LDFLAGS = @SLAPD_MODULES_LDFLAGS@
 MODULES_LIBS = @MODULES_LIBS@
-PERL_CPPFLAGS = @SLAPD_PERL_CPPFLAGS@
-PERL_LDFLAGS = @SLAPD_PERL_LDFLAGS@
 TERMCAP_LIBS = @TERMCAP_LIBS@
+LINK_BINS_DYNAMIC = @LINK_BINS_DYNAMIC@
 
+QUIPU_LIBS = @QUIPU_LIBS@
 SLAPD_LIBS = @SLAPD_LIBS@
 SLURPD_LIBS = @SLURPD_LIBS@
 
@@ -177,3 +180,4 @@ Makefile: Makefile.in $(top_srcdir)/build/top.mk
 FORCE:
 
 ##---------------------------------------------------------------------------
+
index 6563d6fcc4836ad608e0516f225fdab1fb6362e9..05466500f65c30cfa0bd57a632060504c5078fc9 100644 (file)
@@ -1 +1 @@
-2.0-Engineeering
+2.0-alpha4
index 29f893128516fa4102d6e7c30f777c8de8d87152..5bc6b69eb71e805178cd0f0cad6b6d8ef2d1a701 100644 (file)
@@ -1,7 +1,7 @@
 # $OpenLDAP$
-## Copyright 1998 The OpenLDAP Foundation, All Rights Reserved.
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
 ## COPYING RESTRICTIONS APPLY, See COPYRIGHT file
 ##
 ## Clients Makefile.in for OpenLDAP
 
-SUBDIRS= tools ud finger gopher mail500 fax500 rcpt500
+SUBDIRS= tools ud finger gopher mail500 fax500 rcpt500 maildap
index 4520a63ef6c3cd5d7b014b270f1777e8b6732de6..eefd45123cae9c079bbf82db24b9c2c79be2e33f 100644 (file)
@@ -1,6 +1,8 @@
 # $OpenLDAP$
 
-PROGRAMS= rp500 fax500 xrpcomp.tmp
+UNIX_PRGS = rp500 fax500
+EXEPRGS = $(@PLAT@_PRGS)
+PROGRAMS = xrpcomp.tmp $(EXEPRGS)
 
 SRCS= main.c faxtotpc.c rp500.c
 XSRCS=fax5version.c rpversion.c
@@ -32,7 +34,12 @@ xrpcomp.tmp: xrpcomp
        $(SED) -e 's|%LIBEXECDIR%|$(libexecdir)|' $(srcdir)/xrpcomp > xrpcomp.tmp
 
 install-local: $(PROGRAMS) FORCE
-       -$(MKDIR) $(libexecdir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 rp500 $(libexecdir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 fax500 $(libexecdir)
-       $(INSTALL) $(INSTALLFLAGS) -m 755 xrpcomp.tmp $(libexecdir)/xrpcomp
+       -$(MKDIR) $(DESTDIR)$(libexecdir)
+       @(                                                              \
+           for prg in $(EXEPRGS); do                                   \
+               $(LTINSTALL) $(INSTALLFLAGS) -s -m 755 $$prg$(EXEEXT)   \
+                   $(DESTDIR)$(libexecdir);                            \
+           done                                                        \
+       )
+       $(INSTALL_SCRIPT) $(INSTALLFLAGS) xrpcomp.tmp   \
+               $(DESTDIR)$(libexecdir)/xrpcomp
index b94a1a62159c50e60dfdea8f7f559e2094a7f034..8362a7b520c26fdfbb9148178075ed4185d12c1e 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <ac/ctype.h>
 #include <ac/errno.h>
+#include <ac/param.h>
 #include <ac/signal.h>
 #include <ac/socket.h>
 #include <ac/string.h>
@@ -28,9 +29,6 @@
 #include <ac/unistd.h>
 #include <ac/wait.h>
 
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
 #ifdef HAVE_SYS_RESOURCE_H
 #include <sys/resource.h>
 #endif
@@ -191,7 +189,7 @@ main ( int argc, char **argv )
 
 #ifdef LOG_MAIL
        openlog( myname, OPENLOG_OPTIONS, LOG_MAIL );
-#else
+#elif LOG_DEBUG
        openlog( myname, OPENLOG_OPTIONS );
 #endif
 
@@ -832,7 +830,7 @@ add_member(
 
        timeout.tv_sec = FAX_TIMEOUT;
        timeout.tv_usec = 0;
-       if ( (rc = ldap_search_st( ld, dn, LDAP_SCOPE_BASE, "(objectclass=*)",
+       if ( (rc = ldap_search_st( ld, dn, LDAP_SCOPE_BASE, NULL,
            attrs, 0, &timeout, &res )) != LDAP_SUCCESS ) {
                if ( rc == LDAP_NO_SUCH_OBJECT ) {
                        add_error( err, nerr, E_BADMEMBER, dn, NULL );
@@ -1466,7 +1464,7 @@ get_attributes_mail_dn( LDAPMessage *e, char *attr1, char *attr2 )
 
                for ( i = 0; dnlist[i] != NULL; i++ ) {
                        if ( (rc = ldap_search_st( ld, dnlist[i],
-                           LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0,
+                           LDAP_SCOPE_BASE, NULL, attrs, 0,
                            &timeout, &res )) != LDAP_SUCCESS ) {
                                if ( rc != LDAP_NO_SUCH_OBJECT ) {
                                        unbind_and_exit( EX_TEMPFAIL );
index 613bda9e409e7440cc4b1f5ccce84418cce6b7b9..5a5d7fc3ea1bfcffec900e1b03f9f70eb4c4b5cf 100644 (file)
@@ -3,7 +3,9 @@
 SRCS=  main.c
 XSRCS= version.c
 OBJS=  main.o
-PROGRAMS= in.xfingerd
+
+UNIX_PRGS = in.xfingerd
+PROGRAMS = $(@PLAT@_PRGS)
 
 LDAP_INCDIR= ../../include
 LDAP_LIBDIR= ../../libraries
@@ -19,5 +21,11 @@ version.c: ${OBJS} ${LDAP_LIBDEPEND}
        $(MKVERSION) in.xfingerd > $@
 
 install-local: $(PROGRAMS) FORCE
-       -$(MKDIR) $(libexecdir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 in.xfingerd $(libexecdir)
+       -$(MKDIR) $(DESTDIR)$(libexecdir)
+       @(                                                              \
+           for prg in $(PROGRAMS); do                                  \
+               $(LTINSTALL) $(INSTALLFLAGS) -s -m 755 $$prg$(EXEEXT)   \
+                   $(DESTDIR)$(libexecdir);                            \
+           done                                                        \
+       )
+
index 5e84fe4916bc8cca28988d0cfacaf608a9bf21f5..5e8111633e0ee2037f8eb110dcf04dedcceba412 100644 (file)
@@ -130,14 +130,14 @@ main( int argc, char **argv )
        if ( dosyslog ) {
 #ifdef LOG_LOCAL4
                openlog( myname, OPENLOG_OPTIONS, LOG_LOCAL4 );
-#else
+#elif LOG_DEBUG
                openlog( myname, OPENLOG_OPTIONS );
 #endif
        }
 
        if ( dosyslog && !interactive ) {
-               hp = gethostbyaddr( (char *) &peername.sin_addr.s_addr,
-                                   sizeof(peername.sin_addr.s_addr), AF_INET );
+               hp = gethostbyaddr( (char *) &peername.sin_addr,
+                                   sizeof(peername.sin_addr), AF_INET );
                syslog( LOG_INFO, "connection from %s (%s)",
                        (hp == NULL) ? "unknown" : hp->h_name,
                        inet_ntoa( peername.sin_addr ) );
index a9d5e4ee949c4f889f3aac17290ae93f7167a745..27e2ba136a4bba9697b4b0b412b136399d85b16c 100644 (file)
@@ -2,9 +2,12 @@
 ##
 ## Makefile for gopher clients
 ##
-PROGRAMS= go500gw go500
+
+UNIX_PRGS= go500gw go500
+PROGRAMS = $(@PLAT@_PRGS)
 
 SRCS=  go500.c go500gw.c 
+
 XSRCS= gwversion.c goversion.c
 GOOBJS =  go500.o
 GWOBJS =  go500gw.o
@@ -30,8 +33,13 @@ gwversion.c: ${GWOBJS} $(LDAP_LIBDEPEND)
        $(MKVERSION) go500gw > $@
 
 install-local: $(PROGRAMS) go500gw.help FORCE
-       -$(MKDIR) $(libexecdir) $(datadir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 go500       $(libexecdir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 go500gw $(libexecdir)
-       -$(MV) $(datadir)/go500gw.help $(datadir)/go500gw.help-
-       $(INSTALL) $(INSTALLFLAGS) -m 644 $(srcdir)/go500gw.help $(datadir)
+       -$(MKDIR) $(DESTDIR)$(libexecdir) $(DESTDIR)$(datadir)
+       @(                                                              \
+           for prg in $(PROGRAMS); do                                  \
+               $(LTINSTALL) $(INSTALLFLAGS) -s -m 755 $$prg$(EXEEXT)   \
+                   $(DESTDIR)$(libexecdir);                            \
+           done                                                        \
+       )
+       -$(MV) $(DESTDIR)$(datadir)/go500gw.help $(DESTDIR)$(datadir)/go500gw.help-
+       $(INSTALL) $(INSTALLFLAGS) -m 644 $(srcdir)/go500gw.help $(DESTDIR)$(datadir)
+
index e8342fc4a61b5ca93fafaaa7610ac36af0895fcb..ca03ce0a98a9614739bc039449f15329ab71c4eb 100644 (file)
 #include <ac/unistd.h>
 #include <ac/wait.h>
 
+#include <ac/param.h>
 #include <ac/setproctitle.h>
 
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
 #ifdef HAVE_SYS_RESOURCE_H
 #include <sys/resource.h>
 #endif
@@ -184,7 +181,7 @@ main( int argc, char **argv )
        if ( dosyslog ) {
 #ifdef LOG_LOCAL3
                openlog( myname, OPENLOG_OPTIONS, LOG_LOCAL3 );
-#else
+#elif LOG_DEBUG
                openlog( myname, OPENLOG_OPTIONS );
 #endif
        }
@@ -203,8 +200,8 @@ main( int argc, char **argv )
                fromlen = sizeof(from);
                if ( getpeername( 0, (struct sockaddr *) &from, &fromlen )
                    == 0 ) {
-                       hp = gethostbyaddr( (char *) &(from.sin_addr.s_addr),
-                           sizeof(from.sin_addr.s_addr), AF_INET );
+                       hp = gethostbyaddr( (char *) &(from.sin_addr),
+                           sizeof(from.sin_addr), AF_INET );
                        Debug( LDAP_DEBUG_ARGS, "connection from %s (%s)\n",
                            (hp == NULL) ? "unknown" : hp->h_name,
                            inet_ntoa( from.sin_addr ), 0 );
@@ -247,8 +244,8 @@ main( int argc, char **argv )
                        exit( EXIT_FAILURE );
                }
 
-               hp = gethostbyaddr( (char *) &(from.sin_addr.s_addr),
-                   sizeof(from.sin_addr.s_addr), AF_INET );
+               hp = gethostbyaddr( (char *) &(from.sin_addr),
+                   sizeof(from.sin_addr), AF_INET );
 
                if ( dosyslog ) {
                        syslog( LOG_INFO, "TCP connection from %s (%s)",
index c1c5ab4a9ef47c556e3823f66d3ce195aedeb13f..dfda607001f42358689535db12433571c8e4991e 100644 (file)
 #include <ac/unistd.h>
 #include <ac/wait.h>
 
+#include <ac/param.h>
 #include <ac/setproctitle.h>
 
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
 #ifdef HAVE_SYS_RESOURCE_H
 #include <sys/resource.h>
 #endif
@@ -207,7 +204,7 @@ main (int  argc, char **argv )
        if ( dosyslog ) {
 #ifdef LOG_LOCAL3
                openlog( myname, OPENLOG_OPTIONS, LOG_LOCAL3 );
-#else
+#elif LOG_DEBUG
                openlog( myname, OPENLOG_OPTIONS );
 #endif
        }
@@ -226,8 +223,8 @@ main (int  argc, char **argv )
                fromlen = sizeof(from);
                if ( getpeername( 0, (struct sockaddr *) &from, &fromlen )
                    == 0 ) {
-                       hp = gethostbyaddr( (char *) &(from.sin_addr.s_addr),
-                           sizeof(from.sin_addr.s_addr), AF_INET );
+                       hp = gethostbyaddr( (char *) &(from.sin_addr),
+                           sizeof(from.sin_addr), AF_INET );
                        Debug( LDAP_DEBUG_ARGS, "connection from %s (%s)\n",
                            (hp == NULL) ? "unknown" : hp->h_name,
                            inet_ntoa( from.sin_addr ), 0 );
@@ -272,8 +269,8 @@ main (int  argc, char **argv )
                        exit( EXIT_FAILURE );
                }
 
-               hp = gethostbyaddr( (char *) &(from.sin_addr.s_addr),
-                   sizeof(from.sin_addr.s_addr), AF_INET );
+               hp = gethostbyaddr( (char *) &(from.sin_addr),
+                   sizeof(from.sin_addr), AF_INET );
 
                if ( dosyslog ) {
                        syslog( LOG_INFO, "TCP connection from %s (%s)",
@@ -556,7 +553,7 @@ isnonleaf( LDAP *ld, char **oclist, char *dn )
                timeout.tv_usec = 0;
                ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &sizelimit);
                if ( (rc = ldap_search_st( ld, dn, LDAP_SCOPE_ONELEVEL,
-                   "(objectClass=*)", attrs, 0, &timeout, &res ))
+                   NULL, attrs, 0, &timeout, &res ))
                    == LDAP_SUCCESS || rc == LDAP_SIZELIMIT_EXCEEDED ) {
                        sizelimit = LDAP_NO_LIMIT;
                        ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &sizelimit);
@@ -706,7 +703,7 @@ make_scope( LDAP *ld, char *dn )
 
        timeout.tv_sec = GO500GW_TIMEOUT;
        timeout.tv_usec = 0;
-       if ( ldap_search_st( ld, dn, LDAP_SCOPE_BASE, "objectClass=*",
+       if ( ldap_search_st( ld, dn, LDAP_SCOPE_BASE, NULL,
            attrs, 0, &timeout, &res ) != LDAP_SUCCESS ) {
                return( -1 );
        }
index 38b61fd40486f51b193e893b8a1d8737711def70..260fefcae942a18835dac2e4737d0169db83ed30 100644 (file)
@@ -1,6 +1,7 @@
 # $OpenLDAP$
 
-PROGRAMS= mail500
+UNIX_PRGS = mail500
+PROGRAMS = $(@PLAT@_PRGS)
 
 SRCS=  main.c
 XSRCS= version.c
@@ -20,5 +21,11 @@ version.c: ${OBJS} $(LDAP_LIBDEPEND)
        $(MKVERSION) mail500 > $@
 
 install-local: $(PROGRAMS) FORCE
-       -$(MKDIR) $(libexecdir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 mail500 $(libexecdir)
+       -$(MKDIR) $(DESTDIR)$(libexecdir)
+       @(                                                              \
+           for prg in $(PROGRAMS); do                                  \
+               $(LTINSTALL) $(INSTALLFLAGS) -s -m 755 $$prg$(EXEEXT)   \
+                   $(DESTDIR)$(libexecdir);                            \
+           done                                                        \
+       )
+
index 57e7dd1cf883e5ee509981a5b57179d31b809741..edd9b2e582b0ccc4c53cbfd29522c783cbf2f625 100644 (file)
@@ -38,6 +38,8 @@ R$+%$+<@umich.edu>                 $>10$1%$2<@>
 R$+!$+<@umich.edu>                 $>10$1!$2<@>
 
 See the sample sendmail.cf in this directory for more details.
+For sendmail 8.9 (and later) users can use MAILER(mail500) if
+mail500.m4 is placed within sendmail's cf/mailer directory.
 
 The mail500 mailer should be defined similar to this in the
 sendmail.cf file:
@@ -76,11 +78,11 @@ by changing the base array in main.c.  For example, the configuration
 we use at U-M is like this:
 
        Base    base[] =
-               { "ou=People, o=University of Michigan, c=US", 0
+               { "ou=People, dc=OpenLDAP, dc=org", 0
                        "uid=%s", "cn=%s", NULL,
-                 "ou=System Groups, ou=Groups, o=University of Michigan, c=US", 1
+                 "ou=System Groups, ou=Groups, dc=OpenLDAP, dc=org", 1
                        "(&(cn=%s)(associatedDomain=%h))", NULL, NULL,
-                 "ou=User Groups, ou=Groups, o=University of Michigan, c=US", 1
+                 "ou=User Groups, ou=Groups, dc=OpenLDAP, dc=org", 1
                        "(&(cn=%s)(associatedDomain=%h))", NULL, NULL,
                  NULL
                };
@@ -88,16 +90,16 @@ we use at U-M is like this:
 which means that in delivering mail to "name" mail500 would do the
 the following searches, stopping if it found anything at any step:
 
-       Search (18) [2]: c=US@o=University of Michigan@ou=People
+       Search (18) [2]: dc=org@dc=OpenLDAP@ou=People
        Search subtree (uid=name)
-       Search (18) [3]: c=US@o=University of Michigan@ou=People
+       Search (18) [3]: dc=org@dc=OpenLDAP@ou=People
        Search subtree (cn=name)
 
-       Search (18) [4]: c=US@o=University of Michigan@ou=Groups@ou=System Groups
-       Search subtree & ((cn=name)(associatedDomain=umich.edu))
+       Search (18) [4]: dc=org@dc=OpenLDAP@ou=Groups@ou=System Groups
+       Search subtree & ((cn=name)(associatedDomain=OpenLDAP.org))
 
-       Search (18) [5]: c=US@o=University of Michigan@ou=Groups@ou=User Groups
-       Search subtree & ((cn=name)(associatedDomain=umich.edu))
+       Search (18) [5]: dc=org@dc=OpenLDAP@ou=Groups@ou=User Groups
+       Search subtree & ((cn=name)(associatedDomain=OpenLDAP.org))
 
 Notice that when specifying a filter %s is replaced by the name,
 or user portion of the address while %h is replaced by whatever is
diff --git a/clients/mail500/mail500.m4 b/clients/mail500/mail500.m4
new file mode 100644 (file)
index 0000000..c5cb36b
--- /dev/null
@@ -0,0 +1,51 @@
+PUSHDIVERT(-1)
+## Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms are permitted only
+## as authorized by the OpenLDAP Public License.  A copy of this
+## license is available at http://www.OpenLDAP.org/license.html or
+## in file LICENSE in the top-level directory of the distribution.
+POPDIVERT
+
+dnl
+dnl mail500 mailer
+dnl
+dnl This file should be placed in the sendmail's cf/mailer directory.
+dnl To include this mailer in your .cf file, use the directive:
+dnl    MAILER(mail500)
+dnl
+
+ifdef(`MAIL500_HOST',
+       `define(`MAIL500_HOST_FLAG', `')',
+       `define(`MAIL500_HOST_FLAG', CONCAT(` -l ', CONCAT(MAIL500_HOST,` ')))')
+ifdef(`MAIL500_MAILER_PATH',,
+       `ifdef(`MAIL500_PATH',
+               `define(`MAIL500_MAILER_PATH', MAIL500_PATH)',
+               `define(`MAIL500_MAILER_PATH', /usr/local/libexec/mail500)')')
+ifdef(`MAIL500_MAILER_FLAGS',,
+       `define(`MAIL500_MAILER_FLAGS', `SmnXuh')')
+ifdef(`MAIL500_MAILER_ARGS',,
+       `define(`MAIL500_MAILER_ARGS',
+               CONCAT(`mail500',CONCAT(MAIL500_HOST_FLAG,`-f $f -h $h -m $n@$w $u')))')
+dnl
+
+MAILER_DEFINITIONS
+
+######################*****##############
+###   MAIL500 Mailer specification   ###
+##################*****##################
+
+VERSIONID(`$OpenLDAP$')
+
+Mmail500,      P=MAIL500_MAILER_PATH, F=CONCAT(`DFM', MAIL500_MAILER_FLAGS), S=11/31, R=20/40, T=DNS/RFC822/X-Unix,
+               ifdef(`MAIL500_MAILER_MAX', `M=500_MAILER_MAX, ')A=MAIL500_MAILER_ARGS
+
+LOCAL_CONFIG
+# Mail500 Domains
+#CQ foo.com
+
+PUSHDIVERT(3)
+# mail500 additions
+R$* < @ $=Q > $*       $#mail500 $@ $2 $: <$1>         domain handled by mail500
+POPDIVERT
index 064ed64c348b5b6b560741c715ba937801835062..3d0c538a24585ba2b184eb122f88f47cd59b9537 100644 (file)
@@ -10,7 +10,7 @@
  * software without specific prior written permission. This software
  * is provided ``as is'' without express or implied warranty.
  *
- * Copyright 1998,1999 The OpenLDAP Foundation
+ * Copyright 1998-2000 The OpenLDAP Foundation
  * COPYING RESTRICTIONS APPLY.  See COPYRIGHT File in top level directory
  * of this package for details.
  */
@@ -22,6 +22,7 @@
 #include <ac/stdlib.h>
 
 #include <ac/ctype.h>
+#include <ac/param.h>
 #include <ac/signal.h>
 #include <ac/string.h>
 #include <ac/sysexits.h>
 
 #include <sys/stat.h>
 
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
 #ifdef HAVE_SYS_RESOURCE_H
 #include <sys/resource.h>
 #endif
@@ -64,7 +61,7 @@
 
 LDAP   *ld;
 char   *vacationhost = NULL;
-char   *errorsfrom = MAIL500_BOUNCEFROM;
+char   *errorsfrom = NULL;
 char   *mailfrom = NULL;
 char   *host = NULL;
 char   *ldaphost = NULL;
@@ -98,92 +95,63 @@ typedef struct groupto {
        char    *g_dn;
        char    *g_errorsto;
        char    **g_members;
-       int     g_nmembers;
 } Group;
 
 typedef struct baseinfo {
-       char    *b_url;
-       int     b_m_entries;
+       char    *b_dn;          /* dn to start searching at */
        char    b_rdnpref;      /* give rdn's preference when searching? */
        int     b_search;       /* ORed with the type of thing the address */
                                /*  looks like (USER, GROUP_ERRORS, etc.)  */
                                /*  to see if this should be searched      */
+       char    *b_filter[3];   /* filter to apply - name substituted for %s */
+                               /* (up to three of them) */
 } Base;
 
-/*
- * We should limit the search to objectclass=mailRecipient or
- * objectclass=mailGroup.
- */
-
-/*
 Base   base[] = {
-       {"dc=StlInter, dc=Net",
-               0, 0xff,
-               {"mail=%s", "mailAlternateAddress=%s", NULL}},
+       {"ou=People, dc=OpenLDAP, dc=org",
+               0, USER,
+               {"uid=%s", "cn=%s", NULL}},
+       {"ou=System Groups, ou=Groups, dc=OpenLDAP, dc=org",
+               1, 0xff,
+               {"(&(cn=%s)(associatedDomain=%h))", NULL, NULL}},
+       {"ou=User Groups, ou=Groups, dc=OpenLDAP, dc=org",
+               1, 0xff,
+               {"(&(cn=%s)(associatedDomain=%h))", NULL, NULL}},
        {NULL}
 };
-*/
-
-Base   **base = NULL;
 
 char   *sendmailargs[] = { MAIL500_SENDMAIL, "-oMrLDAP", "-odi", "-oi", "-f", NULL, NULL };
 
-typedef struct attr_semantics {
-       char    *as_name;
-       int     as_m_valued;    /* Is multivalued? */
-       int     as_final;       /* If true, no further expansion is tried. */
-       int     as_syntax;      /* How to interpret values */
-       int     as_m_entries;   /* Can resolve to several entries? */
-       int     as_kind;        /* Recipient, sender, etc. */
-       char    *as_param;      /* Extra info for filters and things alike */
-} AttrSemantics;
-
-#define AS_SYNTAX_UNKNOWN      0       /* Unqualified mailbox name */
-#define AS_SYNTAX_NATIVE_MB    1       /* Unqualified mailbox name */
-#define AS_SYNTAX_RFC822       2       /* RFC822 mail address */
-#define AS_SYNTAX_HOST         3
-#define AS_SYNTAX_DN           4       /* A directory entry */
-#define AS_SYNTAX_RFC822_EXT   5
-#define AS_SYNTAX_URL          6       /* mailto: or ldap: URL */
-#define AS_SYNTAX_BOOL_FILTER  7       /* For joinable, filter in as_param */
-
-#define AS_KIND_UNKNOWN                0
-#define AS_KIND_RECIPIENT      1
-#define AS_KIND_ERRORS         2       /* For ErrorsTo and similar */
-#define AS_KIND_REQUEST                3
-#define AS_KIND_OWNER          4
-#define AS_KIND_FORWARD_TO_HOST        5       /* Expand at some other host */
-#define AS_KIND_ALLOWED_SENDER 6       /* Can send to group */
-#define AS_KIND_MODERATOR      7
-
-AttrSemantics **attr_semantics = NULL;
-
-typedef struct subst {
-       char    sub_char;
-       char    *sub_value;
-} Subst;
-
-char   **groupclasses = NULL;
-char   **def_attr = NULL;
-
-static void load_config( char *filespec );
-static void split_address( char *address, char **localpart, char **domainpart);
-static int entry_engine( LDAPMessage *e, char *dn, char *address, char ***to, int *nto, Group **togroups, int *ngroups, Error **err, int *nerr, int type );
+static char    *attrs[] = { "objectClass", "title", "postaladdress",
+                       "telephoneNumber", "mail", "description", "owner",
+                       "errorsTo", "rfc822ErrorsTo", "requestsTo",
+                       "rfc822RequestsTo", "joinable", "cn", "member",
+                       "moderator", "onVacation", "uid",
+                       "suppressNoEmailError", NULL };
+
 static void do_address( char *name, char ***to, int *nto, Group **togroups, int *ngroups, Error **err, int *nerr, int type );
+static int  do_group( LDAPMessage *e, char *dn, char ***to, int *nto, Group **togroups, int *ngroups, Error **err, int *nerr );
+static void do_group_members( LDAPMessage *e, char *dn, char ***to, int *nto, Group **togroups, int *ngroups, Error **err, int *nerr );
 static void send_message( char **to );
 static void send_errors( Error *err, int nerr );
 static void do_noemail( FILE *fp, Error *err, int namelen );
 static void do_ambiguous( FILE *fp, Error *err, int namelen );
-static int count_values( char **list );
 static void add_to( char ***list, int *nlist, char **new );
-static void add_single_to( char ***list, char *new );
 static int  isgroup( LDAPMessage *e );
 static void add_error( Error **err, int *nerr, int code, char *addr, LDAPMessage *msg );
-static void unbind_and_exit( int rc ) LDAP_GCCATTR((noreturn));
+static void add_group( char *dn, Group **list, int *nlist );
+static void unbind_and_exit( int rc );
+static int  group_loop( char *dn );
 static void send_group( Group *group, int ngroup );
-
+static int  has_attributes( LDAPMessage *e, char *attr1, char *attr2 );
+static char **get_attributes_mail_dn( LDAPMessage *e, char *attr1, char *attr2 );
+static char *canonical( char *s );
 static int  connect_to_x500( void );
 
+static void do_group_errors( LDAPMessage *e, char *dn, char ***to, int *nto, Error **err, int *nerr );
+static void do_group_request( LDAPMessage *e, char *dn, char ***to, int *nto, Error **err, int *nerr );
+static void do_group_owner( LDAPMessage *e, char *dn, char ***to, int *nto, Error **err, int *nerr );
+static void add_member( char *gdn, char *dn, char ***to, int *nto, Group **togroups, int *ngroups, Error **err, int *nerr, char **suppress );
 
 int
 main ( int argc, char **argv )
@@ -194,7 +162,6 @@ main ( int argc, char **argv )
        Group           *togroups;
        int             numto, ngroups, numerr, nargs;
        int             i, j;
-       char            *conffile = NULL;
 
        if ( (myname = strrchr( argv[0], '/' )) == NULL )
                myname = strdup( argv[0] );
@@ -207,20 +174,16 @@ main ( int argc, char **argv )
 
 #ifdef LOG_MAIL
        openlog( myname, OPENLOG_OPTIONS, LOG_MAIL );
-#else
+#elif LOG_DEBUG
        openlog( myname, OPENLOG_OPTIONS );
 #endif
 
-       while ( (i = getopt( argc, argv, "d:C:f:h:l:m:v:" )) != EOF ) {
+       while ( (i = getopt( argc, argv, "d:f:h:l:m:v:" )) != EOF ) {
                switch( i ) {
                case 'd':       /* turn on debugging */
                        debug = atoi( optarg );
                        break;
 
-               case 'C':       /* path to configuration file */
-                       conffile = strdup( optarg );
-                       break;
-
                case 'f':       /* who it's from & where errors should go */
                        mailfrom = strdup( optarg );
                        for ( j = 0; sendmailargs[j] != NULL; j++ ) {
@@ -263,17 +226,11 @@ main ( int argc, char **argv )
                syslog( LOG_ALERT, "required argument -m not present" );
                exit( EX_TEMPFAIL );
        }
-/*     if ( host == NULL ) { */
-/*             syslog( LOG_ALERT, "required argument -h not present" ); */
-/*             exit( EX_TEMPFAIL ); */
-/*     } */
-       if ( conffile == NULL ) {
-               syslog( LOG_ALERT, "required argument -C not present" );
+       if ( host == NULL ) {
+               syslog( LOG_ALERT, "required argument -h not present" );
                exit( EX_TEMPFAIL );
        }
 
-       load_config( conffile );
-
        if ( connect_to_x500() != 0 )
                exit( EX_TEMPFAIL );
 
@@ -303,18 +260,14 @@ main ( int argc, char **argv )
        for ( i = optind; i < argc; i++ ) {
                char    *s;
                int     type;
-               char    *localpart, *domainpart;
-               char    address[1024];
 
-/*  TBC: Make this processing optional */
-/*             for ( j = 0; argv[i][j] != '\0'; j++ ) { */
-/*                     if ( argv[i][j] == '.' || argv[i][j] == '_' ) */
-/*                             argv[i][j] = ' '; */
-/*             } */
+               for ( j = 0; argv[i][j] != '\0'; j++ ) {
+                       if ( argv[i][j] == '.' || argv[i][j] == '_' )
+                               argv[i][j] = ' ';
+               }
 
                type = USER;
-               split_address( argv[i], &localpart, &domainpart );
-               if ( (s = strrchr( localpart, '-' )) != NULL ) {
+               if ( (s = strrchr( argv[i], '-' )) != NULL ) {
                        s++;
 
                        if ((strcasecmp(s, ERROR) == 0) ||
@@ -335,15 +288,7 @@ main ( int argc, char **argv )
                        }
                }
 
-               if ( domainpart ) {
-                       sprintf( address, "%s@%s", localpart, domainpart );
-                       free( localpart );
-                       free( domainpart );
-               } else {
-                       sprintf( address, "%s@%s", localpart, domainpart );
-                       free( localpart );
-               }
-               do_address( address, &tolist, &numto, &togroups, &ngroups,
+               do_address( argv[i], &tolist, &numto, &togroups, &ngroups,
                    &errlist, &numerr, type );
        }
 
@@ -411,263 +356,6 @@ main ( int argc, char **argv )
        return( EX_OK );
 }
 
-static char *
-get_config_line( FILE *cf, int *lineno)
-{
-       static char     buf[2048];
-       int             len;
-       int             pos;
-       int             room;
-
-       pos = 0;
-       room = sizeof( buf );
-       while ( fgets( &buf[pos], room, cf ) ) {
-               (*lineno)++;
-               if ( pos > 0 ) {
-                       /* Delete whitespace at the beginning of new data */
-                       if ( isspace( buf[pos] ) ) {
-                               char *s, *d;
-                               for ( s = buf+pos; isspace(*s); s++ )
-                                       ;
-                               for ( d = buf+pos; *s; s++, d++ ) {
-                                       *d = *s;
-                               }
-                               *d = *s;
-                       }
-               }
-               len = strlen( buf );
-               if ( buf[len-1] != '\n' ) {
-                       syslog( LOG_ALERT, "Definition too long at line %d",
-                               *lineno );
-                       exit( EX_TEMPFAIL );
-               }
-               if ( buf[0] == '#' )
-                       continue;
-               if ( strspn( buf, " \t\n" ) == len )
-                       continue;
-               if ( buf[len-2] == '\\' ) {
-                       pos = len - 2;
-                       room = sizeof(buf) - pos;
-                       continue;
-               }
-               /* We have a real line, we will exit the loop */
-               buf[len-1] = '\0';
-               return( buf );
-       }
-       return( NULL );
-}
-
-static void
-add_url ( char *url, int rdnpref, int typemask )
-{
-       Base            **list_temp;
-       int             size;
-       Base            *b;
-
-       b = calloc(1, sizeof(Base));
-       if ( !b ) {
-               syslog( LOG_ALERT, "Out of memory" );
-               exit( EX_TEMPFAIL );
-       }
-       b->b_url = strdup( url );
-       b->b_rdnpref = rdnpref;
-       b->b_search   = typemask;
-
-       if ( base == NULL ) {
-               base = calloc(2, sizeof(LDAPURLDesc *));
-               if ( !base ) {
-                       syslog( LOG_ALERT, "Out of memory" );
-                       exit( EX_TEMPFAIL );
-               }
-               base[0] = b;
-       } else {
-               for ( size = 0; base[size]; size++ )
-                       ;
-               size += 2;
-               list_temp = realloc( base, size*sizeof(LDAPURLDesc *) );
-               if ( !list_temp ) {
-                       syslog( LOG_ALERT, "Out of memory" );
-                       exit( EX_TEMPFAIL );
-               }
-               base = list_temp;
-               base[size-2] = b;
-               base[size-1] = NULL;
-       }
-}
-
-static void
-add_def_attr( char *s )
-{
-       char *p, *q;
-
-       p = s;
-       while ( *p ) {
-               p += strspn( p, "\t," );
-               q = strpbrk( p, " \t," );
-               if ( q ) {
-                       *q = '\0';
-                       add_single_to( &def_attr, p );
-               } else {
-                       add_single_to( &def_attr, p );
-                       break;
-               }
-               p = q + 1;
-       }
-}
-
-static void
-add_attr_semantics( char *s )
-{
-       char *p, *q;
-       AttrSemantics *as;
-
-       as = calloc( 1, sizeof( AttrSemantics ) );
-       p = s;
-       while ( isspace ( *p ) )
-               p++;
-       q = p;
-       while ( !isspace ( *q ) && *q != '\0' )
-               q++;
-       *q = '\0';
-       as->as_name = strdup( p );
-       p = q + 1;
-
-       while ( *p ) {
-               while ( isspace ( *p ) )
-                       p++;
-               q = p;
-               while ( !isspace ( *q ) && *q != '\0' )
-                       q++;
-               *q = '\0';
-               if ( !strcasecmp( p, "multivalued" ) ) {
-                       as->as_m_valued = 1;
-               } else if ( !strcasecmp( p, "multiple-entries" ) ) {
-                       as->as_m_entries = 1;
-               } else if ( !strcasecmp( p, "final" ) ) {
-                       as->as_final = 1;
-               } else if ( !strcasecmp( p, "local-native-mailbox" ) ) {
-                       as->as_syntax = AS_SYNTAX_NATIVE_MB;
-               } else if ( !strcasecmp( p, "rfc822" ) ) {
-                       as->as_syntax = AS_SYNTAX_RFC822;
-               } else if ( !strcasecmp( p, "rfc822-extended" ) ) {
-                       as->as_syntax = AS_SYNTAX_RFC822_EXT;
-               } else if ( !strcasecmp( p, "dn" ) ) {
-                       as->as_syntax = AS_SYNTAX_DN;
-               } else if ( !strcasecmp( p, "url" ) ) {
-                       as->as_syntax = AS_SYNTAX_URL;
-               } else if ( !strncasecmp( p, "search-with-filter=", 19 ) ) {
-                       as->as_syntax = AS_SYNTAX_BOOL_FILTER;
-                       q = strchr( p, '=' );
-                       if ( q ) {
-                               p = q + 1;
-                               while ( *q && !isspace( *q ) ) {
-                                       q++;
-                               }
-                               if ( *q ) {
-                                       *q = '\0';
-                                       as->as_param = strdup( p );
-                                       p = q + 1;
-                               } else {
-                                       as->as_param = strdup( p );
-                                       p = q;
-                               }
-                       } else {
-                               syslog( LOG_ALERT,
-                                       "Missing filter in %s", s );
-                               exit( EX_TEMPFAIL );
-                       }
-               } else if ( !strcasecmp( p, "host" ) ) {
-                       as->as_kind = AS_SYNTAX_HOST;
-               } else if ( !strcasecmp( p, "forward-to-host" ) ) {
-                       as->as_kind = AS_KIND_FORWARD_TO_HOST;
-               } else if ( !strcasecmp( p, "recipient" ) ) {
-                       as->as_kind = AS_KIND_RECIPIENT;
-               } else if ( !strcasecmp( p, "errors" ) ) {
-                       as->as_kind = AS_KIND_ERRORS;
-               } else if ( !strcasecmp( p, "request" ) ) {
-                       as->as_kind = AS_KIND_REQUEST;
-               } else if ( !strcasecmp( p, "owner" ) ) {
-                       as->as_kind = AS_KIND_OWNER;
-               } else {
-                       syslog( LOG_ALERT,
-                               "Unknown semantics word %s", p );
-                       exit( EX_TEMPFAIL );
-               }
-               p = q + 1;
-       }
-       if ( attr_semantics == NULL ) {
-               attr_semantics = calloc(2, sizeof(AttrSemantics *));
-               if ( !attr_semantics ) {
-                       syslog( LOG_ALERT, "Out of memory" );
-                       exit( EX_TEMPFAIL );
-               }
-               attr_semantics[0] = as;
-       } else {
-               int size;
-               AttrSemantics **list_temp;
-               for ( size = 0; attr_semantics[size]; size++ )
-                       ;
-               size += 2;
-               list_temp = realloc( attr_semantics,
-                                    size*sizeof(AttrSemantics *) );
-               if ( !list_temp ) {
-                       syslog( LOG_ALERT, "Out of memory" );
-                       exit( EX_TEMPFAIL );
-               }
-               attr_semantics = list_temp;
-               attr_semantics[size-2] = as;
-               attr_semantics[size-1] = NULL;
-       }
-}
-
-static void
-load_config( char *filespec )
-{
-       FILE            *cf;
-       char            *line;
-       int             lineno = 0;
-       char            *p;
-       int             rdnpref;
-       int             typemask;
-
-       cf = fopen( filespec, "r" );
-       if ( !cf ) {
-               perror( "Opening config file" );
-               exit( EX_TEMPFAIL );
-       }
-
-       while ( ( line = get_config_line( cf,&lineno ) ) ) {
-               p = strpbrk( line, " \t" );
-               if ( !p ) {
-                       syslog( LOG_ALERT,
-                               "Missing space at line %d", lineno );
-                       exit( EX_TEMPFAIL );
-               }
-               if ( !strncmp( line, "search", p-line ) ) {
-                       p += strspn( p, " \t" );
-                       /* TBC, get these */
-                       rdnpref = 0;
-                       typemask = 0xFF;
-                       add_url( p, rdnpref, typemask );
-               } else if ( !strncmp(line, "attribute", p-line) ) {
-                       p += strspn(p, " \t");
-                       add_attr_semantics( p );
-               } else if ( !strncmp(line, "default-attributes", p-line) ) {
-                       p += strspn(p, " \t");
-                       add_def_attr( p );
-               } else if ( !strncmp(line, "group-classes", p-line) ) {
-                       p += strspn(p, " \t");
-                       add_single_to( &groupclasses, p );
-               } else {
-                       syslog( LOG_ALERT,
-                               "Unparseable config definition at line %d",
-                               lineno );
-                       exit( EX_TEMPFAIL );
-               }
-       }
-       fclose( cf );
-}
-
 static int
 connect_to_x500( void )
 {
@@ -678,10 +366,8 @@ connect_to_x500( void )
                return( -1 );
        }
 
-       /*  TBC: Set this only when it makes sense
        opt = MAIL500_MAXAMBIGUOUS;
        ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &opt);
-       */
        opt = LDAP_DEREF_ALWAYS;
        ldap_set_option(ld, LDAP_OPT_DEREF, &opt);
 
@@ -693,114 +379,33 @@ connect_to_x500( void )
        return( 0 );
 }
 
-static Group *
-new_group( char *dn, Group **list, int *nlist )
-{
-       int     i;
-       Group   *this_group;
-
-       for ( i = 0; i < *nlist; i++ ) {
-               if ( strcmp( dn, (*list)[i].g_dn ) == 0 ) {
-                       syslog( LOG_ALERT, "group loop 2 detected (%s)", dn );
-                       return NULL;
-               }
-       }
-
-       if ( *nlist == 0 ) {
-               *list = (Group *) malloc( sizeof(Group) );
-       } else {
-               *list = (Group *) realloc( *list, (*nlist + 1) *
-                   sizeof(Group) );
-       }
-
-       this_group = *list;
-
-       (*list)[*nlist].g_errorsto = NULL;
-       (*list)[*nlist].g_members = NULL;
-       (*list)[*nlist].g_nmembers = 0;
-       /* save the group's dn so we can check for loops above */
-       (*list)[*nlist].g_dn = strdup( dn );
-
-       (*nlist)++;
-
-       return( this_group );
-}
-
-static void
-split_address(
-       char    *address,
-       char    **localpart,
-       char    **domainpart
-)
-{
-       char            *p;
-
-       if ( ( p = strrchr( address, '@' ) ) == NULL ) {
-               *localpart = strdup( address );
-               *domainpart = NULL;
-       } else {
-               *localpart = malloc( p - address + 1 );
-               strncpy( *localpart, address, p - address );
-               (*localpart)[p - address] = '\0';
-               p++;
-               *domainpart = strdup( p );
-       }
-}
-
 static int
-dn_search(
-       char    **dnlist, 
-       char    *address,
-       char    ***to,
-       int     *nto,
-       Group   **togroups,
-       int     *ngroups,
-       Error   **err,
-       int     *nerr
-)
+mailcmp( char *a, char *b )
 {
-       int             rc;
-       int             i;
-       int             resolved = 0;
-       LDAPMessage     *res, *e;
-       struct timeval  timeout;
+       int     i;
 
-       timeout.tv_sec = MAIL500_TIMEOUT;
-       timeout.tv_usec = 0;
-       for ( i = 0; dnlist[i]; i++ ) {
-               if ( (rc = ldap_search_st( ld, dnlist[i], LDAP_SCOPE_BASE,
-                       "(objectclass=*)", def_attr, 0,
-                        &timeout, &res )) != LDAP_SUCCESS ) {
-                       if ( rc == LDAP_NO_SUCH_OBJECT ) {
-                               add_error( err, nerr, E_BADMEMBER, dnlist[i], NULL );
-                               continue;
-                       } else {
-                               syslog( LOG_ALERT, "member search return 0x%x", rc );
+       for ( i = 0; a[i] != '\0'; i++ ) {
+               if ( a[i] != b[i] ) {
+                       switch ( a[i] ) {
+                       case ' ':
+                       case '.':
+                       case '_':
+                               if ( b[i] == ' ' || b[i] == '.' || b[i] == '_' )
+                                       break;
+                               return( 1 );
 
-                               unbind_and_exit( EX_TEMPFAIL );
-                       }
-               } else {
-                       if ( (e = ldap_first_entry( ld, res )) == NULL ) {
-                               syslog( LOG_ALERT, "member search error parsing entry" );
-                               unbind_and_exit( EX_TEMPFAIL );
-                       }
-                       if ( entry_engine( e, dnlist[i], address, to, nto,
-                                          togroups, ngroups, err, nerr,
-                                          USER | GROUP_MEMBERS ) ) {
-                               resolved = 1;
+                       default:
+                               return( 1 );
                        }
                }
        }
-       return( resolved );
+
+       return( 0 );
 }
 
-static int
-search_ldap_url(
-       char    *url,
-       Subst   *substs,
-       char    *address,
-       int     rdnpref,
-       int     multi_entry,
+static void
+do_address(
+       char    *name,
        char    ***to,
        int     *nto,
        Group   **togroups,
@@ -810,156 +415,112 @@ search_ldap_url(
        int     type
 )
 {
-       LDAPURLDesc     *ludp;
-       char            *p, *s, *d;
-       int             i;
-       char            filter[1024];
-       char            realfilter[1024];
+       int             rc, b, f, match;
        LDAPMessage     *e, *res;
-       int             rc;
-       char            **attrlist;
        struct timeval  timeout;
-       int             match;
-       int             resolved = 0;
        char            *dn;
+       char            filter[1024];
+       char            realfilter[1024];
+       char            **mail, **onvacation = NULL, **uid = NULL;
+
+       /*
+        * Look up the name in X.500, add the appropriate addresses found
+        * to the to list, or to the err list in case of error.  Groups are
+        * handled by the do_group routine, individuals are handled here.
+        * When looking up name, we follow the bases hierarchy, looking
+        * in base[0] first, then base[1], etc.  For each base, there is
+        * a set of search filters to try, in order.  If something goes
+        * wrong here trying to contact X.500, we exit with EX_TEMPFAIL.
+        * If the b_rdnpref flag is set, then we give preference to entries
+        * that matched name because it's their rdn, otherwise not.
+        */
 
        timeout.tv_sec = MAIL500_TIMEOUT;
        timeout.tv_usec = 0;
-
-       rc = ldap_url_parse( url, &ludp );
-       if ( rc ) {
-               switch ( rc ) {
-               case LDAP_URL_ERR_NOTLDAP:
-                       syslog( LOG_ALERT,
-                               "Not an LDAP URL: %s", url );
-                       break;
-               case LDAP_URL_ERR_BADENCLOSURE:
-                       syslog( LOG_ALERT,
-                               "Bad Enclosure in URL: %s", url );
-                       break;
-               case LDAP_URL_ERR_BADURL:
-                       syslog( LOG_ALERT,
-                               "Bad URL: %s", url );
-                       break;
-               case LDAP_URL_ERR_BADHOST:
-                       syslog( LOG_ALERT,
-                               "Host is invalid in URL: %s", url );
-                       break;
-               case LDAP_URL_ERR_BADATTRS:
-                       syslog( LOG_ALERT,
-                               "Attributes are invalid in URL: %s", url );
-                       break;
-               case LDAP_URL_ERR_BADSCOPE:
-                       syslog( LOG_ALERT,
-                               "Scope is invalid in URL: %s", url );
-                       break;
-               case LDAP_URL_ERR_BADFILTER:
-                       syslog( LOG_ALERT,
-                               "Filter is invalid in URL: %s", url );
-                       break;
-               case LDAP_URL_ERR_BADEXTS:
-                       syslog( LOG_ALERT,
-                               "Extensions are invalid in URL: %s", url );
-                       break;
-               case LDAP_URL_ERR_MEM:
-                       syslog( LOG_ALERT,
-                               "Out of memory parsing URL: %s", url );
-                       break;
-               case LDAP_URL_ERR_PARAM:
-                       syslog( LOG_ALERT,
-                               "bad parameter parsing URL: %s", url );
-                       break;
-               default:
-                       syslog( LOG_ALERT,
-                               "Unknown error %d parsing URL: %s",
-                               rc, url );
-                       break;
+       for ( b = 0, match = 0; !match && base[b].b_dn != NULL; b++ ) {
+               if ( ! (base[b].b_search & type) ) {
+                       continue;
                }
-               add_error( err, nerr, E_BADMEMBER,
-                          url, NULL );
-               return 0;
-       }
+               for ( f = 0; base[b].b_filter[f] != NULL; f++ ) {
+                       char    *format, *p, *s, *d;
+                       char    *argv[3];
+                       int     argc;
 
-       if ( substs ) {
-               for ( s = ludp->lud_filter, d = filter; *s; s++,d++ ) {
-                       if ( *s == '%' ) {
-                               s++;
-                               if ( *s == '%' ) {
-                                       *d = '%';
-                                       continue;
-                               }
-                               for ( i = 0; substs[i].sub_char != '\0';
-                                     i++ ) {
-                                       if ( *s == substs[i].sub_char ) {
-                                               for ( p = substs[i].sub_value;
-                                                     *p; p++,d++ ) {
-                                                       *d = *p;
-                                               }
-                                               d--;
+                       for ( argc = 0; argc < 3; argc++ ) {
+                               argv[argc] = NULL;
+                       }
+
+                       format = strdup( base[b].b_filter[f] );
+                       for ( argc = 0, p = format; *p; p++ ) {
+                               if ( *p == '%' ) {
+                                       switch ( *++p ) {
+                                       case 's':       /* %s is the name */
+                                               argv[argc] = name;
+                                               break;
+
+                                       case 'h':       /* %h is the host */
+                                               *p = 's';
+                                               argv[argc] = host;
+                                               break;
+
+                                       default:
+                                               syslog( LOG_ALERT,
+                                                   "unknown format %c", *p );
                                                break;
                                        }
+
+                                       argc++;
                                }
-                               if ( substs[i].sub_char == '\0' ) {
-                                       syslog( LOG_ALERT,
-                                               "unknown format %c", *s );
+                       }
+
+                       /* three names ought to do... */
+                       sprintf( filter, format, argv[0], argv[1], argv[2] );
+                       free( format );
+                       for ( s = filter, d = realfilter; *s; s++, d++ ) {
+                               if ( *s == '*' ) {
+                                       *d++ = '\\';
                                }
-                       } else {
                                *d = *s;
                        }
-               }
-               *d = *s;
-       } else {
-               strncpy( filter, ludp->lud_filter, sizeof( filter ) - 1 );
-               filter[ sizeof( filter ) - 1 ] = '\0';
-       }
+                       *d = '\0';
+
+                       res = NULL;
+                       rc = ldap_search_st( ld, base[b].b_dn,
+                           LDAP_SCOPE_SUBTREE, realfilter, attrs, 0, &timeout,
+                           &res );
+
+                       /* some other trouble - try again later */
+                       if ( rc != LDAP_SUCCESS &&
+                           rc != LDAP_SIZELIMIT_EXCEEDED ) {
+                               syslog( LOG_ALERT, "return 0x%x from X.500",
+                                   rc );
+                               unbind_and_exit( EX_TEMPFAIL );
+                       }
+
+                       if ( (match = ldap_count_entries( ld, res )) != 0 )
+                               break;
 
-       for ( s = filter, d = realfilter; *s; s++, d++ ) {
-               if ( *s == '*' ) {
-                       *d++ = '\\';
+                       ldap_msgfree( res );
                }
-               *d = *s;
-       }
-       *d = '\0';
 
-       if ( ludp->lud_attrs ) {
-               attrlist = ludp->lud_attrs;
-       } else {
-               attrlist = def_attr;
-       }
-       res = NULL;
-       /* TBC: we don't read the host, dammit */
-       rc = ldap_search_st( ld, ludp->lud_dn, ludp->lud_scope,
-                            realfilter, attrlist, 0,
-                            &timeout, &res );
-
-       /* some other trouble - try again later */
-       if ( rc != LDAP_SUCCESS &&
-            rc != LDAP_SIZELIMIT_EXCEEDED ) {
-               syslog( LOG_ALERT, "return 0x%x from X.500",
-                       rc );
-               unbind_and_exit( EX_TEMPFAIL );
+               if ( match )
+                       break;
        }
 
-       match = ldap_count_entries( ld, res );
-
        /* trouble - try again later */
        if ( match == -1 ) {
                syslog( LOG_ALERT, "error parsing result from X.500" );
                unbind_and_exit( EX_TEMPFAIL );
        }
 
-       if ( match == 1 || multi_entry ) {
-               for ( e = ldap_first_entry( ld, res ); e != NULL;
-                     e = ldap_next_entry( ld, e ) ) {
-                       dn = ldap_get_dn( ld, e );
-                       resolved = entry_engine( e, dn, address, to, nto,
-                                                togroups, ngroups,
-                                                err, nerr, type );
-                       if ( !resolved ) {
-                               add_error( err, nerr, E_NOEMAIL, address, res );
-                       }
+       /* no matches - bounce with user unknown */
+       if ( match == 0 ) {
+               if ( type == USER ) {
+                       add_error( err, nerr, E_USERUNKNOWN, name, NULL );
+               } else {
+                       add_error( err, nerr, E_GROUPUNKNOWN, name, NULL );
                }
-               return ( resolved );
+               return;
        }
 
        /* more than one match - bounce with ambiguous user? */
@@ -969,9 +530,9 @@ search_ldap_url(
                char            **xdn;
 
                /* not giving rdn preference - bounce with ambiguous user */
-               if ( rdnpref == 0 ) {
-                       add_error( err, nerr, E_AMBIGUOUS, address, res );
-                       return 0;
+               if ( base[b].b_rdnpref == 0 ) {
+                       add_error( err, nerr, E_AMBIGUOUS, name, res );
+                       return;
                }
 
                /*
@@ -986,7 +547,7 @@ search_ldap_url(
                        xdn = ldap_explode_dn( dn, 1 );
 
                        /* XXX bad, but how else can we do it? XXX */
-                       if ( strcasecmp( xdn[0], address ) == 0 ) {
+                       if ( strcasecmp( xdn[0], name ) == 0 ) {
                                ldap_delete_result_entry( &res, e );
                                ldap_add_result_entry( &tmpres, e );
                        }
@@ -995,353 +556,503 @@ search_ldap_url(
                        free( dn );
                }
 
-               /* nothing matched by rdn - go ahead and bounce */
-               if ( tmpres == NULL ) {
-                       add_error( err, nerr, E_AMBIGUOUS, address, res );
-                       return 0;
+               /* nothing matched by rdn - go ahead and bounce */
+               if ( tmpres == NULL ) {
+                       add_error( err, nerr, E_AMBIGUOUS, name, res );
+                       return;
+
+               /* more than one matched by rdn - bounce with rdn matches */
+               } else if ( (match = ldap_count_entries( ld, tmpres )) > 1 ) {
+                       add_error( err, nerr, E_AMBIGUOUS, name, tmpres );
+                       return;
+
+               /* trouble... */
+               } else if ( match < 0 ) {
+                       syslog( LOG_ALERT, "error parsing result from X.500" );
+                       unbind_and_exit( EX_TEMPFAIL );
+               }
+
+               /* otherwise one matched by rdn - send to it */
+               ldap_msgfree( res );
+               res = tmpres;
+       }
+
+       /*
+        * if we get this far, it means that we found a single match for
+        * name.  for a user, we deliver to the mail attribute or bounce
+        * with address and phone if no mail attr.  for a group, we
+        * deliver to all members or bounce to rfc822ErrorsTo if no members.
+        */
+
+       /* trouble */
+       if ( (e = ldap_first_entry( ld, res )) == NULL ) {
+               syslog( LOG_ALERT, "error parsing entry from X.500" );
+               unbind_and_exit( EX_TEMPFAIL );
+       }
+
+       dn = ldap_get_dn( ld, e );
+
+       if ( type == GROUP_ERRORS ) {
+               /* sent to group-errors - resend to [rfc822]ErrorsTo attr */
+               do_group_errors( e, dn, to, nto, err, nerr );
+
+       } else if ( type == GROUP_REQUEST ) {
+               /* sent to group-request - resend to [rfc822]RequestsTo attr */
+               do_group_request( e, dn, to, nto, err, nerr );
+
+       } else if ( type == GROUP_MEMBERS ) {
+               /* sent to group-members - expand */
+               do_group_members( e, dn, to, nto, togroups, ngroups, err,
+                   nerr );
+
+       } else if ( type == GROUP_OWNER ) {
+               /* sent to group-owner - resend to owner attr */
+               do_group_owner( e, dn, to, nto, err, nerr );
+
+       } else if ( isgroup( e ) ) {
+               /* 
+                * sent to group - resend from [rfc822]ErrorsTo if it's there,
+                * otherwise, expand the group
+                */
+
+               do_group( e, dn, to, nto, togroups, ngroups, err, nerr );
+
+               ldap_msgfree( res );
+
+       } else {
+               /*
+                * sent to user - mail attribute => add it to the to list,
+                * otherwise bounce
+                */
+               if ( (mail = ldap_get_values( ld, e, "mail" )) != NULL ) {
+                       char    buf[1024];
+                       char    *h;
+                       int     i, j;
+
+                       /* try to detect simple mail loops */
+                       sprintf( buf, "%s@%s", name, host );
+                       for ( i = 0; mail[i] != NULL; i++ ) {
+                               /*
+                                * address is the same as the one we're
+                                * sending to - mail loop.  syslog the
+                                * problem, bounce a message back to the
+                                * sender (who else?), and delete the bogus
+                                * addr from the list.
+                                */
+
+                               if ( (h = strchr( mail[i], '@' )) != NULL ) {
+                                       h++;
+                                       if ( strcasecmp( h, host ) == 0 ) {
+                                               syslog( LOG_ALERT,
+                                           "potential loop detected (%s)",
+                                                   mail[i] );
+                                       }
+                               }
+
+                               if ( mailcmp( buf, mail[i] ) == 0 ) {
+                                       syslog( LOG_ALERT,
+                                           "loop detected (%s)", mail[i] );
+
+                                       /* remove the bogus address */
+                                       for ( j = i; mail[j] != NULL; j++ ) {
+                                               mail[j] = mail[j+1];
+                                       }
+                               }
+                       }
+                       if ( mail[0] != NULL ) {
+                               add_to( to, nto, mail );
+                       } else {
+                               add_error( err, nerr, E_NOEMAIL, name, res );
+                       }
+
+                       ldap_value_free( mail );
+               } else {
+                       add_error( err, nerr, E_NOEMAIL, name, res );
+               }
+
+               /*
+                * If the user is on vacation, send a copy of the mail to
+                * the vacation server.  The address is constructed from
+                * the vacationhost (set in a command line argument) and
+                * the uid (XXX this should be more general XXX).
+                */
+
+               if ( vacationhost != NULL && (onvacation = ldap_get_values( ld,
+                   e, "onVacation" )) != NULL && strcasecmp( onvacation[0],
+                   "TRUE" ) == 0 ) {
+                       char    buf[1024];
+                       char    *vaddr[2];
+
+                       if ( (uid = ldap_get_values( ld, e, "uid" )) != NULL ) {
+                               sprintf( buf, "%s@%s", uid[0], vacationhost );
+
+                               vaddr[0] = buf;
+                               vaddr[1] = NULL;
+
+                               add_to( to, nto, vaddr );
+                       } else {
+                               syslog( LOG_ALERT,
+                                   "user without a uid on vacation (%s)",
+                                   name );
+                       }
+               }
+       }
+
+       if ( onvacation != NULL ) {
+               ldap_value_free( onvacation );
+       }
+       if ( uid != NULL ) {
+               ldap_value_free( uid );
+       }
+       free( dn );
+}
+
+static int
+do_group(
+       LDAPMessage *e,
+       char    *dn,
+       char    ***to,
+       int     *nto,
+       Group   **togroups,
+       int     *ngroups,
+       Error   **err,
+       int     *nerr
+)
+{
+       int     i;
+       char    **moderator;
+
+       /*
+        * If this group has an rfc822ErrorsTo attribute, we need to
+        * arrange for errors involving this group to go there, not
+        * to the sender.  Since sendmail only has the concept of a
+        * single sender, we arrange for errors to go to groupname-errors,
+        * which we then handle specially when (if) it comes back to us
+        * by expanding to all the rfc822ErrorsTo addresses.  If it has no
+        * rfc822ErrorsTo attribute, we call do_group_members() to expand
+        * the group.
+        */
+
+       if ( group_loop( dn ) ) {
+               return( -1 );
+       }
+
+       /*
+        * check for moderated groups - if the group has a moderator
+        * attribute, we check to see if the from address is one of
+        * the moderator values.  if so, continue on.  if not, arrange
+        * to send the mail to the moderator(s).  need to do this before
+        * we change the from below.
+        */
+
+       if ( (moderator = ldap_get_values( ld, e, "moderator" )) != NULL ) {
+               /* check if it came from any of the group's moderators */
+               for ( i = 0; moderator[i] != NULL; i++ ) {
+                       if ( strcasecmp( moderator[i], mailfrom ) == 0 )
+                               break;
+               }
+
+               /* not from the moderator? */
+               if ( moderator[i] == NULL ) {
+                       add_to( to, nto, moderator );
+                       ldap_value_free( moderator );
+
+                       return( 0 );
+               }
+               /* else from the moderator - fall through and deliver it */
+       }
+
+       if (strcmp(MAIL500_BOUNCEFROM, mailfrom) != 0 &&
+           has_attributes( e, "rfc822ErrorsTo", "errorsTo" ) ) {
+               add_group( dn, togroups, ngroups );
+
+               return( 0 );
+       }
+
+       do_group_members( e, dn, to, nto, togroups, ngroups, err, nerr );
+
+       return( 0 );
+}
+
+/* ARGSUSED */
+static void
+do_group_members(
+       LDAPMessage *e,
+       char    *dn,
+       char    ***to,
+       int     *nto,
+       Group   **togroups,
+       int     *ngroups,
+       Error   **err,
+       int     *nerr
+)
+{
+       int             i, rc, anymembers;
+       char            *ndn;
+       char            **mail, **member, **joinable, **suppress;
+       char            filter[1024];
+       LDAPMessage     *ee, *res;
+       struct timeval  timeout;
+       int             opt;
+
+       /*
+        * if all has gone according to plan, we've already arranged for
+        * errors to go to the [rfc822]ErrorsTo attributes (if they exist),
+        * so all we have to do here is arrange to send to the
+        * rfc822Mailbox attribute, the member attribute, and anyone who
+        * has joined the group by setting memberOfGroup equal to the
+        * group dn.
+        */
+
+       /* add members in the group itself - mail attribute */
+       anymembers = 0;
+       if ( (mail = ldap_get_values( ld, e, "mail" )) != NULL ) {
+               anymembers = 1;
+               add_to( to, nto, mail );
+
+               ldap_value_free( mail );
+       }
+
+       /* add members in the group itself - member attribute */
+       if ( (member = ldap_get_values( ld, e, "member" )) != NULL ) {
+               suppress = ldap_get_values( ld, e, "suppressNoEmailError" );
+               anymembers = 1;
+               for ( i = 0; member[i] != NULL; i++ ) {
+                       if ( strcasecmp( dn, member[i] ) == 0 ) {
+                               syslog( LOG_ALERT, "group (%s) contains itself",
+                                   dn );
+                               continue;
+                       }
+                       add_member( dn, member[i], to, nto, togroups,
+                           ngroups, err, nerr, suppress );
+               }
+
+               if ( suppress ) {
+                       ldap_value_free( suppress );
+               }
+               ldap_value_free( member );
+       }
+
+       /* add members who have joined by setting memberOfGroup */
+       if ( (joinable = ldap_get_values( ld, e, "joinable" )) != NULL ) {
+               if ( strcasecmp( joinable[0], "FALSE" ) == 0 ) {
+                       if ( ! anymembers ) {
+                               add_error( err, nerr, E_NOMEMBERS, dn,
+                                   NULL );
+                       }
+
+                       ldap_value_free( joinable );
+                       return;
+               }
+               ldap_value_free( joinable );
+
+               sprintf( filter, "(memberOfGroup=%s)", dn );
+
+               timeout.tv_sec = MAIL500_TIMEOUT;
+               timeout.tv_usec = 0;
+
+               /* for each subtree to look in... */
+               opt = MAIL500_MAXAMBIGUOUS;
+               ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &opt);
+               for ( i = 0; base[i].b_dn != NULL; i++ ) {
+                       /* find entries that have joined this group... */
+                       rc = ldap_search_st( ld, base[i].b_dn,
+                           LDAP_SCOPE_SUBTREE, filter, attrs, 0, &timeout,
+                           &res );
+
+                       if ( rc == LDAP_SIZELIMIT_EXCEEDED ||
+                           rc == LDAP_TIMELIMIT_EXCEEDED ) {
+                               syslog( LOG_ALERT,
+                                   "group search limit exceeded %d", rc );
+                               unbind_and_exit( EX_TEMPFAIL );
+                       }
+
+                       if ( rc != LDAP_SUCCESS ) {
+                               syslog( LOG_ALERT, "group search return 0x%x",
+                                   rc );
+                               unbind_and_exit( EX_TEMPFAIL );
+                       }
+
+                       /* for each entry that has joined... */
+                       for ( ee = ldap_first_entry( ld, res ); ee != NULL;
+                           ee = ldap_next_entry( ld, ee ) ) {
+                               anymembers = 1;
+                               if ( isgroup( ee ) ) {
+                                       ndn = ldap_get_dn( ld, ee );
+
+                                       if ( do_group( e, ndn, to, nto,
+                                           togroups, ngroups, err, nerr )
+                                           == -1 ) {
+                                               syslog( LOG_ALERT,
+                                                   "group loop (%s) (%s)",
+                                                   dn, ndn );
+                                       }
+
+                                       free( ndn );
+
+                                       continue;
+                               }
 
-               /* more than one matched by rdn - bounce with rdn matches */
-               } else if ( (match = ldap_count_entries( ld, tmpres )) > 1 ) {
-                       add_error( err, nerr, E_AMBIGUOUS, address, tmpres );
-                       return 0;
+                               /* add them to the to list */
+                               if ( (mail = ldap_get_values( ld, ee, "mail" ))
+                                   != NULL ) {
+                                       add_to( to, nto, mail );
 
-               /* trouble... */
-               } else if ( match < 0 ) {
-                       syslog( LOG_ALERT, "error parsing result from X.500" );
-                       unbind_and_exit( EX_TEMPFAIL );
-               }
+                                       ldap_value_free( mail );
 
-               /* otherwise one matched by rdn - send to it */
-               ldap_msgfree( res );
-               res = tmpres;
+                               /* else generate a bounce */
+                               } else {
+                                       ndn = ldap_get_dn( ld, ee );
 
-               /* trouble */
-               if ( (e = ldap_first_entry( ld, res )) == NULL ) {
-                       syslog( LOG_ALERT, "error parsing entry from X.500" );
-                       unbind_and_exit( EX_TEMPFAIL );
-               }
+                                       add_error( err, nerr,
+                                           E_JOINMEMBERNOEMAIL, ndn, NULL );
 
-               dn = ldap_get_dn( ld, e );
+                                       free( ndn );
+                               }
+                       }
 
-               resolved = entry_engine( e, dn, address, to, nto,
-                                        togroups, ngroups,
-                                        err, nerr, type );
-               if ( !resolved ) {
-                       add_error( err, nerr, E_NOEMAIL, address, res );
-                       /* Don't free res if we passed it to add_error */
-               } else {
                        ldap_msgfree( res );
                }
+               opt = MAIL500_MAXAMBIGUOUS;
+               ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &opt);
+       }
+
+       if ( ! anymembers ) {
+               add_error( err, nerr, E_NOMEMBERS, dn, NULL );
        }
-       return( resolved );
 }
 
-static int
-url_list_search(
-       char    **urllist, 
-       char    *address,
-       int     multi_entry,
+static void
+add_member(
+       char    *gdn,
+       char    *dn,
        char    ***to,
        int     *nto,
        Group   **togroups,
        int     *ngroups,
        Error   **err,
        int     *nerr,
-       int     type
+       char    **suppress
 )
 {
-       int             i;
-       int             resolved = 0;
+       char            *ndn;
+       char            **mail;
+       int             rc;
+       LDAPMessage     *res, *e;
+       struct timeval  timeout;
+
+       timeout.tv_sec = MAIL500_TIMEOUT;
+       timeout.tv_usec = 0;
+       if ( (rc = ldap_search_st( ld, dn, LDAP_SCOPE_BASE, "(objectclass=*)",
+           attrs, 0, &timeout, &res )) != LDAP_SUCCESS ) {
+               if ( rc == LDAP_NO_SUCH_OBJECT ) {
+                       add_error( err, nerr, E_BADMEMBER, dn, NULL );
 
-       for ( i = 0; urllist[i]; i++ ) {
+                       return;
+               } else {
+                       syslog( LOG_ALERT, "member search return 0x%x", rc );
 
-               if ( !strncasecmp( urllist[i], "mail:", 5 ) ) {
-                       char    *vals[2];
+                       unbind_and_exit( EX_TEMPFAIL );
+               }
+       }
 
-                       vals[0] = urllist[i] + 5;
-                       vals[1] = NULL;
-                       add_to( to, nto, vals );
-                       resolved = 1;
+       if ( (e = ldap_first_entry( ld, res )) == NULL ) {
+               syslog( LOG_ALERT, "member search error parsing entry" );
 
-               } else if ( ldap_is_ldap_url( urllist[i] ) ) {
+               unbind_and_exit( EX_TEMPFAIL );
+       }
+       ndn = ldap_get_dn( ld, e );
 
-                       resolved = search_ldap_url( urllist[i], NULL,
-                                                   address, 0, multi_entry,
-                                                   to, nto, togroups, ngroups,
-                                                   err, nerr, type );
-               } else {
-                       /* Produce some sensible error here */
-                       resolved = 0;
+       /* allow groups within groups */
+       if ( isgroup( e ) ) {
+               if ( do_group( e, ndn, to, nto, togroups, ngroups, err, nerr )
+                   == -1 ) {
+                       syslog( LOG_ALERT, "group loop (%s) (%s)", gdn, ndn );
                }
+
+               free( ndn );
+
+               return;
        }
-       return( resolved );
-}
 
-/*
- * The entry engine processes an entry.  Normally, each entry will resolve
- * to one or more values that will be added to the 'to' argument.  This
- * argument needs not be the global 'to' list, it may be the g_to field
- * in a group.  Groups have no special treatment, unless they require
- * a special sender.
- */
+       /* send to the member's mail attribute */
+       if ( (mail = ldap_get_values( ld, e, "mail" )) != NULL ) {
+               add_to( to, nto, mail );
 
-static int
-entry_engine(
+               ldap_value_free( mail );
+
+       /* else generate a bounce */
+       } else {
+               if ( suppress == NULL || strcasecmp( suppress[0], "FALSE" )
+                   == 0 ) {
+                       add_error( err, nerr, E_MEMBERNOEMAIL, ndn, NULL );
+               }
+       }
+
+       free( ndn );
+}
+
+static void
+do_group_request(
        LDAPMessage *e,
        char    *dn,
-       char    *address,
        char    ***to,
        int     *nto,
-       Group   **togroups,
-       int     *ngroups,
        Error   **err,
-       int     *nerr,
-       int     type
+       int     *nerr
 )
 {
-       char    **vals;
-       int     i;
-       int     resolved = 0;
-       char    ***current_to = to;
-       int     *current_nto = nto;
-       Group   *current_group = NULL;
-       char    buf[1024];
-       char    *localpart, *domainpart;
-       Subst   substs[2];
-
-       for ( i=0; attr_semantics[i] != NULL; i++ ) {
-               AttrSemantics   *as = attr_semantics[i];
-               int             nent;
-
-               vals = ldap_get_values( ld, e, as->as_name );
-               if ( !vals || vals[0] == NULL ) {
-                       continue;
-               }
-               nent = count_values( vals );
-               if ( nent > 1 && !as->as_m_valued ) {
-                       add_error( err, nerr, E_AMBIGUOUS, address, e );
-                       return( 0 );
-               }
-               switch ( as->as_kind ) {
-               case AS_KIND_RECIPIENT:
-                       if ( ! ( type & ( USER | GROUP_MEMBERS ) ) )
-                               break;
-                       switch ( as->as_syntax ) {
-                       case AS_SYNTAX_RFC822:
-                               add_to( current_to, current_nto, vals );
-                               resolved = 1;
-                               break;
-                       case AS_SYNTAX_RFC822_EXT:
-                               add_to( current_to, current_nto, vals );
-                               resolved = 1;
-                               break;
-                       case AS_SYNTAX_NATIVE_MB:
-                               /* We used to concatenate mailHost if set here */
-                               /*
-                                * We used to send a copy to the vacation host
-                                * if onVacation to uid@vacationhost
-                                */
-                               add_to( current_to, current_nto, vals );
-                               resolved = 1;
-                               break;
-
-                       case AS_SYNTAX_DN:
-                               if ( dn_search( vals, address,
-                                               current_to, current_nto,
-                                               togroups, ngroups,
-                                               err, nerr ) ) {
-                                       resolved = 1;
-                               }
-                               break;
-
-                       case AS_SYNTAX_URL:
-                               if ( url_list_search( vals, address,
-                                                as->as_m_entries,
-                                                current_to, current_nto,
-                                                togroups, ngroups,
-                                                err, nerr, type ) ) {
-                                       resolved = 1;
-                               }
-                               break;
-
-                       case AS_SYNTAX_BOOL_FILTER:
-                               if ( strcasecmp( vals[0], "true" ) ) {
-                                       break;
-                               }
-                               substs[0].sub_char = 'D';
-                               substs[0].sub_value = dn;
-                               substs[1].sub_char = '\0';
-                               substs[1].sub_value = NULL;
-                               if ( url_list_search( vals, address,
-                                                as->as_m_entries,
-                                                current_to, current_nto,
-                                                togroups, ngroups,
-                                                err, nerr, type ) ) {
-                                       resolved = 1;
-                               }
-                               break;
-
-                       default:
-                               syslog( LOG_ALERT,
-                                       "Invalid syntax %d for kind %d",
-                                       as->as_syntax, as->as_kind );
-                               break;
-                       }
-                       break;
-
-               case AS_KIND_ERRORS:
-                       /* This is a group with special processing */
-                       if ( type & GROUP_ERRORS ) {
-                               switch (as->as_kind) {
-                               case AS_SYNTAX_RFC822:
-                                       add_to( current_to, current_nto, vals );
-                                       resolved = 1;
-                                       break;
-                               case AS_SYNTAX_URL:
-                               default:
-                                       syslog( LOG_ALERT,
-                                               "Invalid syntax %d for kind %d",
-                                               as->as_syntax, as->as_kind );
-                               }
-                       } else {
-                               current_group = new_group( dn, togroups,
-                                                          ngroups );
-                               current_to = &current_group->g_members;
-                               current_nto = &current_group->g_nmembers;
-                               split_address( address,
-                                              &localpart, &domainpart );
-                               if ( domainpart ) {
-                                       sprintf( buf, "%s-%s@%s",
-                                                localpart, ERRORS,
-                                                domainpart );
-                                       free( localpart );
-                                       free( domainpart );
-                               } else {
-                                       sprintf( buf, "%s-%s@%s",
-                                                localpart, ERRORS,
-                                                host );
-                                       free( localpart );
-                               }
-                               current_group->g_errorsto = strdup( buf );
-                       }
-                       break;
+       char            **requeststo;
 
-               case AS_KIND_REQUEST:
-                       /* This is a group with special processing */
-                       if ( type & GROUP_REQUEST ) {
-                               add_to( current_to, current_nto, vals );
-                               resolved = 1;
-                       }
-                       break;
-
-               case AS_KIND_OWNER:
-                       /* This is a group with special processing */
-                       if ( type & GROUP_REQUEST ) {
-                               add_to( current_to, current_nto, vals );
-                               resolved = 1;
-                       }
-                       break;
+       if ( (requeststo = get_attributes_mail_dn( e, "rfc822RequestsTo",
+           "requestsTo" )) != NULL ) {
+               add_to( to, nto, requeststo );
 
-               default:
-                       syslog( LOG_ALERT,
-                               "Invalid kind %d", as->as_kind );
-                       /* Error, TBC */
-               }
-               ldap_value_free( vals );
-               if ( as->as_final ) {
-                       return( resolved );
-               }
+               ldap_value_free( requeststo );
+       } else {
+               add_error( err, nerr, E_NOREQUEST, dn, NULL );
        }
-       return( resolved );
 }
 
-static int
-search_bases(
-       char    *filter,
-       Subst   *substs,
-       char    *name,
+static void
+do_group_errors(
+       LDAPMessage *e,
+       char    *dn,
        char    ***to,
        int     *nto,
-       Group   **togroups,
-       int     *ngroups,
        Error   **err,
-       int     *nerr,
-       int     type
+       int     *nerr
 )
 {
-       int             b, resolved = 0;
+       char            **errorsto;
 
-       for ( b = 0; base[b] != NULL; b++ ) {
+       if ( (errorsto = get_attributes_mail_dn( e, "rfc822ErrorsTo",
+           "errorsTo" )) != NULL ) {
+               add_to( to, nto, errorsto );
 
-               if ( ! (base[b]->b_search & type) ) {
-                       continue;
-               }
-
-               resolved = search_ldap_url( base[b]->b_url, substs, name,
-                                           base[b]->b_rdnpref,
-                                           base[b]->b_m_entries,
-                                           to, nto, togroups, ngroups,
-                                           err, nerr, type );
-               if ( resolved )
-                       break;
+               ldap_value_free( errorsto );
+       } else {
+               add_error( err, nerr, E_NOERRORS, dn, NULL );
        }
-       return( resolved );
 }
 
 static void
-do_address(
-       char    *name,
+do_group_owner(
+       LDAPMessage *e,
+       char    *dn,
        char    ***to,
        int     *nto,
-       Group   **togroups,
-       int     *ngroups,
        Error   **err,
-       int     *nerr,
-       int     type
+       int     *nerr
 )
 {
-       struct timeval  timeout;
-       char            *localpart, *domainpart;
-       int             resolved;
-       Subst   substs[5];
-
-       /*
-        * Look up the name in X.500, add the appropriate addresses found
-        * to the to list, or to the err list in case of error.  Groups are
-        * handled by the do_group routine, individuals are handled here.
-        * When looking up name, we follow the bases hierarchy, looking
-        * in base[0] first, then base[1], etc.  For each base, there is
-        * a set of search filters to try, in order.  If something goes
-        * wrong here trying to contact X.500, we exit with EX_TEMPFAIL.
-        * If the b_rdnpref flag is set, then we give preference to entries
-        * that matched name because it's their rdn, otherwise not.
-        */
+       char            **owner;
 
-       split_address( name, &localpart, &domainpart );
-       timeout.tv_sec = MAIL500_TIMEOUT;
-       timeout.tv_usec = 0;
-       substs[0].sub_char = 'm';
-       substs[0].sub_value = name;
-       substs[1].sub_char = 'h';
-       substs[1].sub_value = host;
-       substs[2].sub_char = 'l';
-       substs[2].sub_value = localpart;
-       substs[3].sub_char = 'd';
-       substs[3].sub_value = domainpart;
-       substs[4].sub_char = '\0';
-       substs[4].sub_value = NULL;
-
-       resolved = search_bases( NULL, substs, name,
-                                to, nto, togroups, ngroups,
-                                err, nerr, type );
-
-       if ( !resolved ) {
-               /* not resolved - bounce with user unknown */
-               if ( type == USER ) {
-                       add_error( err, nerr, E_USERUNKNOWN, name, NULL );
-               } else {
-                       add_error( err, nerr, E_GROUPUNKNOWN, name, NULL );
-               }
+       if ( (owner = get_attributes_mail_dn( e, "", "owner" )) != NULL ) {
+               add_to( to, nto, owner );
+               ldap_value_free( owner );
+       } else {
+               add_error( err, nerr, E_NOOWNER, dn, NULL );
        }
 }
 
@@ -1707,14 +1418,11 @@ do_ambiguous( FILE *fp, Error *err, int namelen )
                        }
                }
 
-               /* 
                if ( isgroup( e ) ) {
                        vals = ldap_get_values( ld, e, "description" );
                } else {
                        vals = ldap_get_values( ld, e, "title" );
                }
-               */
-               vals = ldap_get_values( ld, e, "description" );
 
                fprintf( fp, "    %-20s %s\n", rdn, vals ? vals[0] : "" );
                for ( i = 1; vals && vals[i] != NULL; i++ ) {
@@ -1762,42 +1470,18 @@ add_to( char ***list, int *nlist, char **new )
        (*list)[*nlist] = NULL;
 }
 
-static void
-add_single_to( char ***list, char *new )
-{
-       int     nlist;
-
-       if ( *list == NULL ) {
-               nlist = 0;
-               *list = (char **) malloc( 2 * sizeof(char *) );
-       } else {
-               nlist = count_values( *list );
-               *list = (char **) realloc( *list,
-                                          ( nlist + 2 ) * sizeof(char *) );
-       }
-
-       (*list)[nlist] = strdup( new );
-       (*list)[nlist+1] = NULL;
-}
-
 static int
 isgroup( LDAPMessage *e )
 {
-       int     i, j;
+       int     i;
        char    **oclist;
 
-       if ( !groupclasses ) {
-               return( 0 );
-       }
-
        oclist = ldap_get_values( ld, e, "objectClass" );
 
        for ( i = 0; oclist[i] != NULL; i++ ) {
-               for ( j = 0; groupclasses[j] != NULL; j++ ) {
-                       if ( strcasecmp( oclist[i], groupclasses[j] ) == 0 ) {
-                               ldap_value_free( oclist );
-                               return( 1 );
-                       }
+               if ( strcasecmp( oclist[i], "rfc822MailGroup" ) == 0 ) {
+                       ldap_value_free( oclist );
+                       return( 1 );
                }
        }
        ldap_value_free( oclist );
@@ -1820,6 +1504,52 @@ add_error( Error **err, int *nerr, int code, char *addr, LDAPMessage *msg )
        (*nerr)++;
 }
 
+static void
+add_group( char *dn, Group **list, int *nlist )
+{
+       int     i, namelen;
+       char    **ufn;
+
+       for ( i = 0; i < *nlist; i++ ) {
+               if ( strcmp( dn, (*list)[i].g_dn ) == 0 ) {
+                       syslog( LOG_ALERT, "group loop 2 detected (%s)", dn );
+                       return;
+               }
+       }
+
+       ufn = ldap_explode_dn( dn, 1 );
+       namelen = strlen( ufn[0] );
+
+       if ( *nlist == 0 ) {
+               *list = (Group *) malloc( sizeof(Group) );
+       } else {
+               *list = (Group *) realloc( *list, (*nlist + 1) *
+                   sizeof(Group) );
+       }
+
+       /* send errors to groupname-errors@host */
+       (*list)[*nlist].g_errorsto = (char *) malloc( namelen + sizeof(ERRORS)
+           + hostlen + 2 );
+       sprintf( (*list)[*nlist].g_errorsto, "%s-%s@%s", ufn[0], ERRORS, host );
+       (void) canonical( (*list)[*nlist].g_errorsto );
+
+       /* send to groupname-members@host - make it a list for send_group */
+       (*list)[*nlist].g_members = (char **) malloc( 2 * sizeof(char *) );
+       (*list)[*nlist].g_members[0] = (char *) malloc( namelen +
+           sizeof(MEMBERS) + hostlen + 2 );
+       sprintf( (*list)[*nlist].g_members[0], "%s-%s@%s", ufn[0], MEMBERS,
+           host );
+       (void) canonical( (*list)[*nlist].g_members[0] );
+       (*list)[*nlist].g_members[1] = NULL;
+
+       /* save the group's dn so we can check for loops above */
+       (*list)[*nlist].g_dn = strdup( dn );
+
+       (*nlist)++;
+
+       ldap_value_free( ufn );
+}
+
 static void
 unbind_and_exit( int rc )
 {
@@ -1830,3 +1560,129 @@ unbind_and_exit( int rc )
 
        exit( rc );
 }
+
+static char *
+canonical( char *s )
+{
+       char    *saves = s;
+
+       for ( ; *s != '\0'; s++ ) {
+               if ( *s == ' ' )
+                       *s = '.';
+       }
+
+       return( saves );
+}
+
+static int
+group_loop( char *dn )
+{
+       int             i;
+       static char     **groups;
+       static int      ngroups;
+
+       for ( i = 0; i < ngroups; i++ ) {
+               if ( strcmp( dn, groups[i] ) == 0 )
+                       return( 1 );
+       }
+
+       if ( ngroups == 0 )
+               groups = (char **) malloc( sizeof(char *) );
+       else
+               groups = (char **) realloc( groups,
+                   (ngroups + 1) * sizeof(char *) );
+
+       groups[ngroups++] = strdup( dn );
+
+       return( 0 );
+}
+
+static int
+has_attributes( LDAPMessage *e, char *attr1, char *attr2 )
+{
+       char    **attr;
+
+       if ( (attr = ldap_get_values( ld, e, attr1 )) != NULL ) {
+               ldap_value_free( attr );
+               return( 1 );
+       }
+
+       if ( (attr = ldap_get_values( ld, e, attr2 )) != NULL ) {
+               ldap_value_free( attr );
+               return( 1 );
+       }
+
+       return( 0 );
+}
+
+static char **
+get_attributes_mail_dn(
+    LDAPMessage *e,
+    char *attr1,
+    char *attr2                        /* this one is dn-valued */
+)
+{
+       LDAPMessage     *ee, *res;
+       char            **vals, **dnlist, **mail, **grname;
+        char            *dn;
+       int             nto = 0, i, rc;
+       struct timeval  timeout;
+
+       dn = ldap_get_dn( ld, e );
+
+       vals = ldap_get_values( ld, e, attr1 );
+       for ( nto = 0; vals != NULL && vals[nto] != NULL; nto++ )
+               ;       /* NULL */
+
+       if ( (dnlist = ldap_get_values( ld, e, attr2 )) != NULL ) {
+               timeout.tv_sec = MAIL500_TIMEOUT;
+               timeout.tv_usec = 0;
+
+               for ( i = 0; dnlist[i] != NULL; i++ ) {
+                       if ( (rc = ldap_search_st( ld, dnlist[i],
+                           LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0,
+                           &timeout, &res )) != LDAP_SUCCESS ) {
+                               if ( rc != LDAP_NO_SUCH_OBJECT ) {
+                                       unbind_and_exit( EX_TEMPFAIL );
+                               }
+
+                               syslog( LOG_ALERT, "bad (%s) dn (%s)", attr2,
+                                   dnlist[i] );
+
+                               continue;
+                       }
+
+                       if ( (ee = ldap_first_entry( ld, res )) == NULL ) {
+                               syslog( LOG_ALERT, "error parsing x500 entry" );
+                               continue;
+                       }
+
+                       if ( isgroup(ee) ) {
+                               char    *graddr[2];
+
+                               grname = ldap_explode_dn( dnlist[i], 1 );
+
+                               /* groupname + host + @ + null */
+                               graddr[0] = (char *) malloc( strlen( grname[0] )
+                                   + strlen( host ) + 2 );
+                               graddr[1] = NULL;
+                               sprintf( graddr[0], "%s@%s", grname[0], host);
+                               (void) canonical( graddr[0] );
+
+                               add_to( &vals, &nto, graddr );
+
+                               free( graddr[0] );
+                               ldap_value_free( grname );
+                       } else if ( (mail = ldap_get_values( ld, ee, "mail" ))
+                           != NULL ) {
+                               add_to( &vals, &nto, mail );
+
+                               ldap_value_free( mail );
+                       }
+
+                       ldap_msgfree( res );
+               }
+       }
+
+       return( vals );
+}
index b7ec14d1ce4678e9de37e02851e74738e3c18955..477162f10b71a265dc2e60c4c023c4c0beae354e 100644 (file)
@@ -1,3 +1,8 @@
+#
+# It's recommended use Sendmail's m4 configuration system to avoid
+# mucking directly with .cf files
+#
+
 # Mostly rfc1123 compliant sendmail.cf
 #
 # Mail sendmail-admins-request@itd.umich.edu to join
diff --git a/clients/maildap/Makefile.in b/clients/maildap/Makefile.in
new file mode 100644 (file)
index 0000000..5bff81d
--- /dev/null
@@ -0,0 +1,31 @@
+# $OpenLDAP$
+
+UNIX_PRGS = maildap
+PROGRAMS = $(@PLAT@_PRGS)
+
+SRCS=  main.c
+XSRCS= version.c
+OBJS=  main.o
+
+LDAP_INCDIR= ../../include
+LDAP_LIBDIR= ../../libraries
+
+XLIBS =  -lldap -llber -llutil
+XXLIBS = $(SECURITY_LIBS) $(LUTIL_LIBS)
+
+maildap : version.o
+       $(LTLINK) -o $@ version.o $(OBJS) $(LIBS)
+
+version.c: ${OBJS} $(LDAP_LIBDEPEND)
+       @-$(RM) $@
+       $(MKVERSION) maildap > $@
+
+install-local: $(PROGRAMS) FORCE
+       -$(MKDIR) $(DESTDIR)$(libexecdir)
+       @(                                                              \
+           for prg in $(PROGRAMS); do                                  \
+               $(LTINSTALL) $(INSTALLFLAGS) -s -m 755 $$prg$(EXEEXT)   \
+                   $(DESTDIR)$(libexecdir);                            \
+           done                                                        \
+       )
+
diff --git a/clients/maildap/README b/clients/maildap/README
new file mode 100644 (file)
index 0000000..ef33c14
--- /dev/null
@@ -0,0 +1,357 @@
+
+*** WARNING:  Preliminary ***
+
+This is the README file for maildap, a mailer that does X.500 lookups
+via LDAP.  It is based on mail500.
+
+If you are planning to run maildap at your site, you need to create a
+configuration file.  Previous versions required modifying the source
+code for configuration.  This is no longer necessary.
+there are several
+
+*** WHAT maildap DOES: ***
+
+maildap is designed to be invoked as a mailer (e.g., from sendmail),
+similar to the way /bin/mail works.  It takes a few required arguments
+and then a list of addresses to deliver to.  It expects to find the
+message to deliver on its standard input.  It looks up the addresses in
+X.500 to figure out where to route the mail, and then execs sendmail to
+do the actual delivery.  It supports simple aliases, groups, and
+mailing lists, the details of which are given below.
+
+*** HOW IT WORKS (from the sendmail side): ***
+
+The idea is that you might have a rule like this in your sendmail.cf
+file somewhere in rule set 0:
+
+R$*<@umich.edu>$*      $#maildap$@umich.edu$:<$1>
+
+This rule says that any address that ends in @umich.edu will cause
+the maildap mailer to be called to deliver the mail.  You probably
+also want to do something to prevent addresses like terminator!tim@umich.edu
+or tim%terminator.rs.itd.umich.edu@umich.edu from being passed to maildap.
+At U-M, we do this by adding rules like this to rule set 9 where we
+strip off our local names:
+
+R<@umich.edu>$*:$*                 $>10<@>$1:$2
+R$+%$+<@umich.edu>                 $>10$1%$2<@>
+R$+!$+<@umich.edu>                 $>10$1!$2<@>
+
+You can also feed complete FQDN addresses to maildap.  For instance,
+you could define a class containing the list of domains you want to
+serve like this:
+
+FQ/etc/mail/maildapdomains
+
+and then use a rule in rule set 0 like this:
+
+R$*<$=Q>$*             $#maildap $@$2 $:<$1@$2>
+
+See the sample sendmail.cf in this directory for more details.
+For sendmail 8.9 (and later) users can use MAILER(maildap) if
+maildap.m4 is placed within sendmail's cf/mailer directory.
+
+The maildap mailer should be defined similar to this in the
+sendmail.cf file:
+
+Mmaildap, P=/usr/local/etc/maildap, F=DFMSmnXuh, A=maildap -f $f -h $h -m $n@$w $u
+
+This defines how maildap will be treated by sendmail and what
+arguments it will have when it's called.  The various flags specified
+by the F=... parameter are explained in your local sendmail book (with
+any luck).  The arguments to maildap are as follows:
+
+       -f      Who the mail is from.  This will be used as the address
+               to which any errors should be sent (unless the address
+               specifies a mailing list - see below).  Normally, sendmail
+               defines the $f macro to be the sender.
+
+       -h      The domain for which the mail is destined.  This is passed
+               in to maildap via the $h macro, which is set by the
+               $@ metasymbol in the rule added to rule set 0 above.
+               It's normally used when searching for groups.
+
+       -m      The mailer-daemon address.  If errors have to be sent,
+               this is the address they will come from.  $n is normally
+               set to mailer-daemon and $w is normally the local host
+               name.
+
+The final argument $u is used to stand for the addresses to which to
+deliver the mail.
+
+*** HOW IT WORKS (from the maildap side): ***
+
+When maildap gets invoked with one or more names to which to deliver
+mail, it searches for each name in X.500.  Where it searches, and what
+kind(s) of search(es) is controlled by a configuration file.  There
+are a number of different approaches to handling mail and no general
+rules can be given.  We will however present some examples of what you
+can do.  The new maildap is designed to be flexible and able to
+accommodate most scenarios.
+
+For instance, if you are following the mail distribution model that
+the old maildap used, you need lines in the configuration file like
+these:
+
+search  ldap:///ou=People, dc=OpenLDAP, dc=org??sub?\
+       (|(uid=%25l)(cn==%25l))
+
+search  ldap:///ou=System Groups, ou=Groups, dc=OpenLDAP, dc=org??sub?\
+       (&(cn=%25l)(associatedDomain==%25h))
+
+search  ldap:///ou=User Groups, ou=Groups, dc=OpenLDAP, dc=org??sub?\
+       (&(cn=%25l)(associatedDomain==%25h))
+
+As you can see, searches are described by using LDAP URLs.  You can
+have as many searches as you want, but the first search that succeeds
+completes the processing for a recipient address.  You can provide an
+attribute list in the URL and it will be honored.  Otherwise, the
+attribute list will default as explained below.
+
+Filters can contain substitutions.  Actually, they *should* contain
+substitutions or the search result would not change with the recipient
+address.  Since the usual substitution character is % and it has
+special meaning in URLs, you have to represent it according to the URL
+syntax, that is, %25, 25 being the hex code of %.  The filter can be
+as complex as you want and you may make as many substitutions as you
+want.  Known substitutions at this time are:
+
+        %m   The recipient address we are considering now, maybe fully
+            qualified
+       %h   The host, that is, the value of the -h argument to
+            maildap
+       %l   The local part from %m
+       %d   The domain part from %m
+
+So, in the above example, if the recipient address were
+name@OpenLDAP.org, maildap would do the the following searches,
+stopping if it found anything at any step:
+
+       Search (18) [2]: dc=org@dc=OpenLDAP@ou=People
+       Search subtree (uid=name)
+       Search (18) [3]: dc=org@dc=OpenLDAP@ou=People
+       Search subtree (cn=name)
+
+       Search (18) [4]: dc=org@dc=OpenLDAP@ou=Groups@ou=System Groups
+       Search subtree & ((cn=name)(associatedDomain=OpenLDAP.org))
+
+       Search (18) [5]: dc=org@dc=OpenLDAP@ou=Groups@ou=User Groups
+       Search subtree & ((cn=name)(associatedDomain=OpenLDAP.org))
+
+[Beware: Currently unimplemented]
+You can also specify whether you want search results that matched
+because the entry's RDN matched the search to be given preference
+or not.  At U-M, we only give such preference in the mail group
+portion of the searches.  Beware with this option:  the algorithm
+used to decide whether an entry's RDN matched the search is very
+simple-minded, and may not always be correct.
+
+*** HOW IT WORKS (from the X.500 side): ***
+
+First you need to decide what attributes you will search for and what
+attributes will be used to deliver the message.  In the classical
+maildap, we would search by uid or cn and deliver to the mail
+attribute.  Another model is to search by the mail attribute and
+deliver to something else, such as the uid if determined that the user
+has a local account.
+
+*** THE CONFIGURATION FILE
+
+The configuration file is composed of lines that prescribe the
+operation of maildap.  Blank lines are ignored and lines beginning
+with # are considered comments and ignored.  Outside comments, the
+sequence '\', newline, whitespace is ignored so that long lines can be
+split for readability.
+
+Attribute Definitions
+
+Lines starting with 'attribute' define the semantics of an attribute.
+Notice that attributes will be considered in the order they are
+defined in the configuration file.  This means that the presence of
+some can preempt processing of other attributes and that attributes
+that simply collect needed information must be defined before others
+that use that information.  The format is:
+
+attribute name [multivalued] [final] [multiple-entries] [<syntax>] [<kind>]
+
+If the attribute is "multivalued", all values will be considered.  If
+it is not and several values are found the entry is declared in error.
+
+If the attribute is "final", its presence in an entry prevents further
+analysis of the entry.
+
+If the attribute is "multiple-entries" and it is of an appropriate
+syntax that can point to other entries, all such entries are
+considered, otherwise the entry is in error.
+
+The known kinds are:
+
+recipient              The value(s) of this attribute should be
+                       used as the address(es) to deliver the message
+                       to if they are in an appropriate syntax.  If
+                       they otherwise point at other entries, they
+                       should be retrieved and expanded as necessary
+                       to complete the resolution of this entry.  The
+                       process is recursive and all.
+
+errors                 The value(s) of this attribute represent the
+                       entities that should receive error messages
+                       for mail messages directed to this entry.
+                       The presence of an attribute of this kind
+                       force a change in the envelope sender address
+                       of the message.
+
+The known syntaxes are:
+
+local-native-mailbox   An unqualified mailbox name
+rfc822                 A fully qualified RFC822 mail address
+rfc822-extended                Currently identical to rfc822
+dn                     The Distinguished Name of some other entry
+url                    A URL either of the mailto: or ldap: styles,
+                       others styles, notably file:, could be added.
+                       No substitutions are supported currently.
+search-with-filter=<filter>    Do a search on all known search bases
+                       with the give filter.  The only currenty
+                       substitution available is %D, the DN of the
+                       current entry.
+
+The default attributes to search
+
+A line starting with "default-attributes" contains a comma-separated
+list of attributes to use in searches everytime a specific list is not
+known.
+
+Search bases
+
+As shown in the example above, lines starting with "search" provide
+the search bases to use to initially try to resolve each entry or when
+using attributes of syntax "search-with-filter".
+
+*** EXAMPLES
+
+A configuration file that approximates the operation of the old
+maildap runs as follows:
+
+attribute errorsTo                             errors dn
+attribute rfc822ErrorsTo                       errors rfc822
+attribute requestsTo                           request dn
+attribute rfc822RequestsTo                     request rfc822
+attribute owner                                        owner dn
+attribute mail                 multivalued     recipient rfc822
+attribute member               multivalued     recipient dn
+attribute joinable     multiple-entries        recipient \
+         search-with-filter=(memberOfGroup=%D)
+
+default-attributes objectClass,title,postaladdress,telephoneNumber,\
+       mail,description,owner,errorsTo,rfc822ErrorsTo,requestsTo,\
+       rfc822RequestsTo,joinable,cn,member,moderator,onVacation,uid,\
+       suppressNoEmailError
+
+# Objectclasses that, when present, identify an entry as a group
+group-classes mailGroup
+
+search  ldap:///ou=People, dc=OpenLDAP, dc=org??sub?\
+       (|(uid=%25l)(cn==%25l))
+
+search  ldap:///ou=System Groups, ou=Groups, dc=OpenLDAP, dc=org??sub?\
+       (&(cn=%25l)(associatedDomain==%25h))
+
+search  ldap:///ou=User Groups, ou=Groups, dc=OpenLDAP, dc=org??sub?\
+       (&(cn=%25l)(associatedDomain==%25h))
+
+A configuration that approximates the semantics of the mailRecipient
+and mailGroup classes used by Netscape:
+
+attribute mgrpErrorsTo                         errors url
+attribute rfc822ErrorsTo                       errors rfc822
+attribute mailRoutingAddress   final           recipient rfc822
+attribute mailHost             final           host forward-to-host
+attribute uid                  final           recipient local-native-mailbox
+attribute uniqueMember         multivalued     recipient dn
+attribute mgrpRFC822MailMember multivalued     recipient rfc822-extended
+attribute mgrpDeliverTo                multivalued multiple-entries recipient url
+
+default-attributes objetcClass,mailRoutingAddress,mailHost,uid,uniqueMember,\
+       mgrpRFC822MailMember,mgrpErrorsTo,rfc822ErrorsTo
+
+# Objectclasses that, when present, identify an entry as a group
+group-classes mailGroup
+
+search  ldap://localhost/dc=OpenLDAP,dc=org?\
+       objectClass,mailRoutingAddress,mailHost,uid?\
+       sub?\
+       (&(|(mail=%25m)(mailAlternateAddress=%25m))(objectClass=mailRecipient))
+
+search  ldap://localhost/dc=OpenLDAP,dc=org?\
+       objectClass,uniqueMember,mgrpRFC822MailMember,mgrpErrorsTo,mgrpDeliverTo,rfc822ErrorsTo?\
+       sub?\
+       (&(|(mail=%25m)(mailAlternateAddress=%25m))(objectClass=mailGroup))
+
+[ The rest is from the original README and I did not rewrite it yet ]
+
+In X.500, there are several new attribute types and one new object
+class defined that maildap makes use of.  At its most basic, for normal
+entries maildap will deliver to the value(s) listed in the
+rfc822Mailbox attribute of the entry.  For example, at U-M my entry has
+the attribute
+
+       mail= tim@terminator.rs.itd.umich.edu
+
+So mail sent to tim@umich.edu will be delivered via maildap to that
+address.  If there were multiple values for the mail attribute, multiple
+copies of the mail would be sent.
+
+A new object class, rfc822MailGroup, and several new attributes have
+been defined to handle email groups/mailing lists.  To use this, you
+will need to add this to your local oidtable.oc:
+
+       # object class for representing rfc 822 mailgroups
+       rfc822MailGroup:        umichObjectClass.2 : \
+               top : \
+               cn : \
+               rfc822Mailbox, member, memberOfGroup, owner, \
+               errorsTo, rfc822ErrorsTo, requestsTo, rfc822RequestsTo,
+               joinable, associatedDomain, \
+               description, multiLineDescription, \
+               userPassword, krbName, \
+               telecommunicationAttributeSet, postalAttributeSet
+
+And you will need to add these to your local oidtable.at:
+
+       # attrs for rfc822mailgroups
+       multiLineDescription:   umichAttributeType.2    : CaseIgnoreList
+       rfc822ErrorsTo:         umichAttributeType.26   : CaseIgnoreIA5String
+       rfc822RequestsTo:       umichAttributeType.27   : CaseIgnoreIA5String
+       joinable:               umichAttributeType.28   : Boolean
+       memberOfGroup:          umichAttributeType.29   : DN
+       errorsTo:               umichAttributeType.30   : DN
+       requestsTo:             umichAttributeType.31   : DN
+
+The idea was to define a kind of hybrid mail group that could handle
+people who were in X.500 or not.  So, for example, members of a group
+can be specified via the member attribute (for X.500 members) or the
+rfc822MailBox attribute (for non-X.500 members).  Similarly for the
+errorsTo and rfc822ErrorsTo, and the requestsTo and rfc822RequestsTo
+attributes.
+
+To create a real mailing list, with a list maintainer, all you have to
+do is create an rfc822MailGroup and fill in the errorsTo or
+rfc822ErrorsTo attributes (or both).  That will cause any errors
+encountered when delivering mail to the group to go to the addresses
+listed (or X.500 entry via it's mail attribute).
+
+If you fill in the requestsTo or rfc822RequestsTo (or both) attributes,
+mail sent to groupname-request will be sent to the addresses listed
+there.  maildap does this automatically, so you don't have to explicitly
+add the groupname-request alias to your group.
+
+To allow users to join a group, there is the joinable flag.  If TRUE,
+maildap will search for entries that have a memberOfGroup attribute
+equal to the DN of the group, using the same algorithm it used to find
+the group in the first place (i.e. the DNs and filters listed in the
+base array).  This allows people to join (or subscribe to) a group
+without having to modify the group entry directly.  If joinable is
+FALSE, the search is not done.
+
+Finally, keep in mind that this is somewhat experimental at the moment.
+We are using it in production at U-M, but your mileage may vary...
diff --git a/clients/maildap/maildap.m4 b/clients/maildap/maildap.m4
new file mode 100644 (file)
index 0000000..8e805a7
--- /dev/null
@@ -0,0 +1,53 @@
+PUSHDIVERT(-1)
+## Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms are permitted only
+## as authorized by the OpenLDAP Public License.  A copy of this
+## license is available at http://www.OpenLDAP.org/license.html or
+## in file LICENSE in the top-level directory of the distribution.
+
+dnl
+dnl maildap mailer
+dnl
+dnl This file should be placed in the sendmail's cf/mailer directory.
+dnl To include this mailer in your .cf file, use the directive:
+dnl    MAILER(maildap)
+dnl
+
+ifdef(`MAILDAP_HOST',
+       `define(`MAILDAP_HOST_FLAG', CONCAT(` -l ', CONCAT(MAILDAP_HOST,` ')))',
+       `define(`MAILDAP_HOST_FLAG', `')')
+ifdef(`MAILDAP_CONFIG_PATH',,
+       `define(`MAILDAP_CONFIG_PATH', /etc/mail/maildap.conf)')
+ifdef(`MAILDAP_MAILER_PATH',,
+       `ifdef(`MAILDAP_PATH',
+               `define(`MAILDAP_MAILER_PATH', MAILDAP_PATH)',
+               `define(`MAILDAP_MAILER_PATH', /usr/local/libexec/maildap)')')
+ifdef(`MAILDAP_MAILER_FLAGS',,
+       `define(`MAILDAP_MAILER_FLAGS', `SmnXuh')')
+ifdef(`MAILDAP_MAILER_ARGS',,
+       `define(`MAILDAP_MAILER_ARGS',
+               CONCAT(`maildap',CONCAT(` -C ',MAILDAP_CONFIG_PATH,MAILDAP_HOST_FLAG,`-f $f -m $n@$w $u')))')
+
+POPDIVERT
+
+MAILER_DEFINITIONS
+
+######################*****##############
+###   MAILDAP Mailer specification   ###
+##################*****##################
+
+VERSIONID(`$OpenLDAP$')
+
+Mmaildap,      P=MAILDAP_MAILER_PATH, F=CONCAT(`DFM', MAILDAP_MAILER_FLAGS), S=11/31, R=20/40, T=DNS/RFC822/X-Unix,
+               ifdef(`MAILDAP_MAILER_MAX', `M=500_MAILER_MAX, ')A=MAILDAP_MAILER_ARGS
+
+LOCAL_CONFIG
+# Maildap Domains
+#CQ foo.com
+
+PUSHDIVERT(3)
+# maildap additions
+R$* < @ $=Q > $*       $#maildap $@ $2 $: <$1@$2>              domain handled by maildap
+POPDIVERT
diff --git a/clients/maildap/main.c b/clients/maildap/main.c
new file mode 100644 (file)
index 0000000..d5a258b
--- /dev/null
@@ -0,0 +1,2062 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright (c) 1990 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.
+ *
+ * Copyright 1998-2000 The OpenLDAP Foundation
+ * COPYING RESTRICTIONS APPLY.  See COPYRIGHT File in top level directory
+ * of this package for details.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/stdlib.h>
+
+#include <ac/ctype.h>
+#include <ac/param.h>
+#include <ac/signal.h>
+#include <ac/string.h>
+#include <ac/sysexits.h>
+#include <ac/syslog.h>
+#include <ac/time.h>
+#include <ac/unistd.h>
+#include <ac/wait.h>
+
+#include <sys/stat.h>
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+#include <ldap.h>
+
+#include "ldap_defaults.h"
+
+#ifndef MAIL500_BOUNCEFROM
+#define MAIL500_BOUNCEFROM "<>"
+#endif
+
+#define USER           0x01
+#define GROUP_ERRORS   0x02
+#define GROUP_REQUEST  0x04
+#define GROUP_MEMBERS  0x08
+#define GROUP_OWNER    0x10
+
+#define ERROR          "error"
+#define ERRORS         "errors"
+#define REQUEST                "request"
+#define REQUESTS       "requests"
+#define MEMBERS                "members"
+#define OWNER          "owner"
+#define OWNERS         "owners"
+
+LDAP   *ld;
+char   *vacationhost = NULL;
+char   *errorsfrom = MAIL500_BOUNCEFROM;
+char   *mailfrom = NULL;
+char   *host = NULL;
+char   *ldaphost = NULL;
+int    hostlen = 0;
+int    debug;
+
+typedef struct errs {
+       int             e_code;
+#define E_USERUNKNOWN          1
+#define E_AMBIGUOUS            2
+#define E_NOEMAIL              3
+#define E_NOREQUEST            4
+#define E_NOERRORS             5
+#define E_BADMEMBER            6
+#define E_JOINMEMBERNOEMAIL    7
+#define E_MEMBERNOEMAIL                8
+#define E_LOOP                 9
+#define E_NOMEMBERS            10
+#define        E_NOOWNER               11
+#define E_GROUPUNKNOWN         12
+#define E_NOOWNADDRESS         13
+       char            *e_addr;
+       union e_union_u {
+               char            *e_u_loop;
+               LDAPMessage     *e_u_msg;
+       } e_union;
+#define e_msg  e_union.e_u_msg
+#define e_loop e_union.e_u_loop
+} Error;
+
+typedef struct groupto {
+       char    *g_dn;
+       char    *g_errorsto;
+       char    **g_members;
+       int     g_nmembers;
+} Group;
+
+typedef struct baseinfo {
+       char    *b_url;
+       int     b_m_entries;
+       char    b_rdnpref;      /* give rdn's preference when searching? */
+       int     b_search;       /* ORed with the type of thing the address */
+                               /*  looks like (USER, GROUP_ERRORS, etc.)  */
+                               /*  to see if this should be searched      */
+} Base;
+
+Base   **base = NULL;
+
+char   *sendmailargs[] = { MAIL500_SENDMAIL, "-oMrLDAP", "-odi", "-oi", "-f", NULL, NULL };
+
+typedef struct attr_semantics {
+       char    *as_name;
+       int     as_m_valued;    /* Is multivalued? */
+       int     as_priority;    /* Priority level of this attribut type */
+       int     as_syntax;      /* How to interpret values */
+       int     as_m_entries;   /* Can resolve to several entries? */
+       int     as_kind;        /* Recipient, sender, etc. */
+       char    *as_param;      /* Extra info for filters and things alike */
+} AttrSemantics;
+
+#define AS_SYNTAX_UNKNOWN      0
+#define AS_SYNTAX_NATIVE_MB    1       /* Unqualified mailbox name */
+#define AS_SYNTAX_RFC822       2       /* RFC822 mail address */
+#define AS_SYNTAX_HOST         3
+#define AS_SYNTAX_DN           4       /* A directory entry */
+#define AS_SYNTAX_RFC822_EXT   5
+#define AS_SYNTAX_URL          6       /* mailto: or ldap: URL */
+#define AS_SYNTAX_BOOL_FILTER  7       /* For joinable, filter in as_param */
+#define AS_SYNTAX_PRESENT      8       /* Value irrelevant, only presence is
+                                        * considered. */
+
+#define AS_KIND_UNKNOWN                0
+#define AS_KIND_RECIPIENT      1
+#define AS_KIND_ERRORS         2       /* For ErrorsTo and similar */
+#define AS_KIND_REQUEST                3
+#define AS_KIND_OWNER          4
+#define AS_KIND_ROUTE_TO_HOST  5       /* Expand at some other host */
+#define AS_KIND_ALLOWED_SENDER 6       /* Can send to group */
+#define AS_KIND_MODERATOR      7
+#define AS_KIND_ROUTE_TO_ADDR  8       /* Rewrite recipient address as */
+#define AS_KIND_OWN_ADDR       9       /* RFC822 name of this entry */
+#define AS_KIND_DELIVERY_TYPE  10      /* How to deliver mail to this entry */
+
+AttrSemantics **attr_semantics = NULL;
+int current_priority = 0;
+
+typedef struct subst {
+       char    sub_char;
+       char    *sub_value;
+} Subst;
+
+char   **groupclasses = NULL;
+char   **def_attr = NULL;
+char   **myhosts = NULL;               /* FQDNs not to route elsewhere */
+char   **mydomains = NULL;             /* If an RFC822 address points to one
+                                          of these domains, search it in the
+                                          directory instead of returning it
+                                          to hte MTA */
+
+static void load_config( char *filespec );
+static void split_address( char *address, char **localpart, char **domainpart);
+static int entry_engine( LDAPMessage *e, char *dn, char *address, char ***to, int *nto, Group ***togroups, int *ngroups, Error **err, int *nerr, int type );
+static void do_address( char *name, char ***to, int *nto, Group ***togroups, int *ngroups, Error **err, int *nerr, int type );
+static void send_message( char **to );
+static void send_errors( Error *err, int nerr );
+static void do_noemail( FILE *fp, Error *err, int namelen );
+static void do_ambiguous( FILE *fp, Error *err, int namelen );
+static int count_values( char **list );
+static void add_to( char ***list, int *nlist, char **new );
+static void add_single_to( char ***list, char *new );
+static int  isgroup( LDAPMessage *e );
+static void add_error( Error **err, int *nerr, int code, char *addr, LDAPMessage *msg );
+static void unbind_and_exit( int rc ) LDAP_GCCATTR((noreturn));
+static void send_group( Group **group, int ngroup );
+
+static int  connect_to_x500( void );
+
+
+int
+main ( int argc, char **argv )
+{
+       char            *myname;
+       char            **tolist;
+       Error           *errlist;
+       Group           **togroups;
+       int             numto, ngroups, numerr, nargs;
+       int             i, j;
+       char            *conffile = NULL;
+
+       if ( (myname = strrchr( argv[0], '/' )) == NULL )
+               myname = strdup( argv[0] );
+       else
+               myname = strdup( myname + 1 );
+
+#ifdef SIGPIPE
+       (void) SIGNAL( SIGPIPE, SIG_IGN );
+#endif
+
+#ifdef LOG_MAIL
+       openlog( myname, OPENLOG_OPTIONS, LOG_MAIL );
+#elif LOG_DEBUG
+       openlog( myname, OPENLOG_OPTIONS );
+#endif
+
+       while ( (i = getopt( argc, argv, "d:C:f:h:l:m:v:" )) != EOF ) {
+               switch( i ) {
+               case 'd':       /* turn on debugging */
+                       debug |= atoi( optarg );
+                       break;
+
+               case 'C':       /* path to configuration file */
+                       conffile = strdup( optarg );
+                       break;
+
+               case 'f':       /* who it's from & where errors should go */
+                       mailfrom = strdup( optarg );
+                       for ( j = 0; sendmailargs[j] != NULL; j++ ) {
+                               if ( strcmp( sendmailargs[j], "-f" ) == 0 ) {
+                                       sendmailargs[j+1] = mailfrom;
+                                       break;
+                               }
+                       }
+                       break;
+
+               case 'h':       /* hostname */
+                       host = strdup( optarg );
+                       hostlen = strlen(host);
+                       break;
+
+               case 'l':       /* ldap host */
+                       ldaphost = strdup( optarg );
+                       break;
+
+                               /* mailer-daemon address - who we should */
+               case 'm':       /* say errors come from */
+                       errorsfrom = strdup( optarg );
+                       break;
+
+               case 'v':       /* vacation host */
+                       vacationhost = strdup( optarg );
+                       break;
+
+               default:
+                       syslog( LOG_ALERT, "unknown option" );
+                       break;
+               }
+       }
+
+       if ( mailfrom == NULL ) {
+               syslog( LOG_ALERT, "required argument -f not present" );
+               exit( EX_TEMPFAIL );
+       }
+       if ( errorsfrom == NULL ) {
+               syslog( LOG_ALERT, "required argument -m not present" );
+               exit( EX_TEMPFAIL );
+       }
+/*     if ( host == NULL ) { */
+/*             syslog( LOG_ALERT, "required argument -h not present" ); */
+/*             exit( EX_TEMPFAIL ); */
+/*     } */
+       if ( conffile == NULL ) {
+               syslog( LOG_ALERT, "required argument -C not present" );
+               exit( EX_TEMPFAIL );
+       }
+
+       load_config( conffile );
+
+       if ( connect_to_x500() != 0 )
+               exit( EX_TEMPFAIL );
+
+       setuid( geteuid() );
+
+       if ( debug ) {
+               char    buf[1024];
+               int     i;
+
+               syslog( LOG_ALERT, "running as %d", geteuid() );
+               strcpy( buf, argv[0] );
+               for ( i = 1; i < argc; i++ ) {
+                       strcat( buf, " " );
+                       strcat( buf, argv[i] );
+               }
+
+               syslog( LOG_ALERT, "args: (%s)", buf );
+       }
+
+       tolist = NULL;
+       numto = 0;
+       add_to( &tolist, &numto, sendmailargs );
+       nargs = numto;
+       ngroups = numerr = 0;
+       togroups = NULL;
+       errlist = NULL;
+       for ( i = optind; i < argc; i++ ) {
+               char    *s;
+               int     type;
+               char    *localpart = NULL, *domainpart = NULL;
+               char    address[1024];
+
+               type = USER;
+               split_address( argv[i], &localpart, &domainpart );
+               if ( (s = strrchr( localpart, '-' )) != NULL ) {
+                       s++;
+
+                       if ((strcasecmp(s, ERROR) == 0) ||
+                               (strcasecmp(s, ERRORS) == 0)) {
+                               type = GROUP_ERRORS;
+                               *(--s) = '\0';
+                       } else if ((strcasecmp(s, REQUEST) == 0) ||
+                               (strcasecmp(s, REQUESTS) == 0)) {
+                               type = GROUP_REQUEST;
+                               *(--s) = '\0';
+                       } else if ( strcasecmp( s, MEMBERS ) == 0 ) {
+                               type = GROUP_MEMBERS;
+                               *(--s) = '\0';
+                       } else if ((strcasecmp(s, OWNER) == 0) ||
+                               (strcasecmp(s, OWNERS) == 0)) {
+                               type = GROUP_OWNER;
+                               *(--s) = '\0';
+                       }
+               }
+
+               if ( domainpart ) {
+                       sprintf( address, "%s@%s", localpart, domainpart );
+                       free( localpart );
+                       free( domainpart );
+               } else {
+                       sprintf( address, "%s@%s", localpart, domainpart );
+                       free( localpart );
+               }
+               do_address( address, &tolist, &numto, &togroups, &ngroups,
+                   &errlist, &numerr, type );
+       }
+
+       /*
+        * If we have both errors and successful deliveries to make or if
+        * if there are any groups to deliver to, we basically need to read
+        * the message twice.  So, we have to put it in a tmp file.
+        */
+
+       if ( numerr > 0 && numto > nargs || ngroups > 0 ) {
+               FILE    *fp;
+               char    buf[BUFSIZ];
+
+               umask( 077 );
+               if ( (fp = tmpfile()) == NULL ) {
+                       syslog( LOG_ALERT, "could not open tmp file" );
+                       unbind_and_exit( EX_TEMPFAIL );
+               }
+
+               /* copy the message to a temp file */
+               while ( fgets( buf, sizeof(buf), stdin ) != NULL ) {
+                       if ( fputs( buf, fp ) == EOF ) {
+                               syslog( LOG_ALERT, "error writing tmpfile" );
+                               unbind_and_exit( EX_TEMPFAIL );
+                       }
+               }
+
+               if ( dup2( fileno( fp ), 0 ) == -1 ) {
+                       syslog( LOG_ALERT, "could not dup2 tmpfile" );
+                       unbind_and_exit( EX_TEMPFAIL );
+               }
+
+               fclose( fp );
+       }
+
+       /* deal with errors */
+       if ( numerr > 0 ) {
+               if ( debug ) {
+                       syslog( LOG_ALERT, "sending errors" );
+               }
+               (void) rewind( stdin );
+               send_errors( errlist, numerr );
+       }
+
+       (void) ldap_unbind( ld );
+
+       /* send to groups with errorsTo */
+       if ( ngroups > 0 ) {
+               if ( debug ) {
+                       syslog( LOG_ALERT, "sending to groups with errorsto" );
+               }
+               (void) rewind( stdin );
+               send_group( togroups, ngroups );
+       }
+
+       /* send to expanded aliases and groups w/o errorsTo */
+       if ( numto > nargs ) {
+               if ( debug ) {
+                       syslog( LOG_ALERT, "sending to aliases and groups" );
+               }
+               (void) rewind( stdin );
+               send_message( tolist );
+       }
+
+       return( EX_OK );
+}
+
+static char *
+get_config_line( FILE *cf, int *lineno)
+{
+       static char     buf[2048];
+       int             len;
+       int             pos;
+       int             room;
+
+       pos = 0;
+       room = sizeof( buf );
+       while ( fgets( &buf[pos], room, cf ) ) {
+               (*lineno)++;
+               if ( pos > 0 ) {
+                       /* Delete whitespace at the beginning of new data */
+                       if ( isspace( buf[pos] ) ) {
+                               char *s, *d;
+                               for ( s = buf+pos; isspace(*s); s++ )
+                                       ;
+                               for ( d = buf+pos; *s; s++, d++ ) {
+                                       *d = *s;
+                               }
+                               *d = *s;
+                       }
+               }
+               len = strlen( buf );
+               if ( buf[len-1] != '\n' ) {
+                       syslog( LOG_ALERT, "Definition too long at line %d",
+                               *lineno );
+                       exit( EX_TEMPFAIL );
+               }
+               if ( buf[0] == '#' )
+                       continue;
+               if ( strspn( buf, " \t\n" ) == len )
+                       continue;
+               if ( buf[len-2] == '\\' ) {
+                       pos = len - 2;
+                       room = sizeof(buf) - pos;
+                       continue;
+               }
+               /* We have a real line, we will exit the loop */
+               buf[len-1] = '\0';
+               return( buf );
+       }
+       return( NULL );
+}
+
+static void
+add_url ( char *url, int rdnpref, int typemask )
+{
+       Base            **list_temp;
+       int             size;
+       Base            *b;
+
+       b = calloc(1, sizeof(Base));
+       if ( !b ) {
+               syslog( LOG_ALERT, "Out of memory" );
+               exit( EX_TEMPFAIL );
+       }
+       b->b_url = strdup( url );
+       b->b_rdnpref = rdnpref;
+       b->b_search   = typemask;
+
+       if ( base == NULL ) {
+               base = calloc(2, sizeof(LDAPURLDesc *));
+               if ( !base ) {
+                       syslog( LOG_ALERT, "Out of memory" );
+                       exit( EX_TEMPFAIL );
+               }
+               base[0] = b;
+       } else {
+               for ( size = 0; base[size]; size++ )
+                       ;
+               size += 2;
+               list_temp = realloc( base, size*sizeof(LDAPURLDesc *) );
+               if ( !list_temp ) {
+                       syslog( LOG_ALERT, "Out of memory" );
+                       exit( EX_TEMPFAIL );
+               }
+               base = list_temp;
+               base[size-2] = b;
+               base[size-1] = NULL;
+       }
+}
+
+static void
+add_def_attr( char *s )
+{
+       char *p, *q;
+
+       p = s;
+       while ( *p ) {
+               p += strspn( p, "\t," );
+               q = strpbrk( p, " \t," );
+               if ( q ) {
+                       *q = '\0';
+                       add_single_to( &def_attr, p );
+               } else {
+                       add_single_to( &def_attr, p );
+                       break;
+               }
+               p = q + 1;
+       }
+}
+
+static void
+add_attr_semantics( char *s )
+{
+       char *p, *q;
+       AttrSemantics *as;
+
+       as = calloc( 1, sizeof( AttrSemantics ) );
+       as->as_priority = current_priority;
+       p = s;
+       while ( isspace ( *p ) )
+               p++;
+       q = p;
+       while ( !isspace ( *q ) && *q != '\0' )
+               q++;
+       *q = '\0';
+       as->as_name = strdup( p );
+       p = q + 1;
+
+       while ( *p ) {
+               while ( isspace ( *p ) )
+                       p++;
+               q = p;
+               while ( !isspace ( *q ) && *q != '\0' )
+                       q++;
+               *q = '\0';
+               if ( !strcasecmp( p, "multivalued" ) ) {
+                       as->as_m_valued = 1;
+               } else if ( !strcasecmp( p, "multiple-entries" ) ) {
+                       as->as_m_entries = 1;
+               } else if ( !strcasecmp( p, "local-native-mailbox" ) ) {
+                       as->as_syntax = AS_SYNTAX_NATIVE_MB;
+               } else if ( !strcasecmp( p, "rfc822" ) ) {
+                       as->as_syntax = AS_SYNTAX_RFC822;
+               } else if ( !strcasecmp( p, "rfc822-extended" ) ) {
+                       as->as_syntax = AS_SYNTAX_RFC822_EXT;
+               } else if ( !strcasecmp( p, "dn" ) ) {
+                       as->as_syntax = AS_SYNTAX_DN;
+               } else if ( !strcasecmp( p, "url" ) ) {
+                       as->as_syntax = AS_SYNTAX_URL;
+               } else if ( !strcasecmp( p, "search-with-filter" ) ) {
+                       as->as_syntax = AS_SYNTAX_BOOL_FILTER;
+               } else if ( !strncasecmp( p, "param=", 6 ) ) {
+                       q = strchr( p, '=' );
+                       if ( q ) {
+                               p = q + 1;
+                               while ( *q && !isspace( *q ) ) {
+                                       q++;
+                               }
+                               if ( *q ) {
+                                       *q = '\0';
+                                       as->as_param = strdup( p );
+                                       p = q + 1;
+                               } else {
+                                       as->as_param = strdup( p );
+                                       p = q;
+                               }
+                       }
+               } else if ( !strcasecmp( p, "host" ) ) {
+                       as->as_kind = AS_SYNTAX_HOST;
+               } else if ( !strcasecmp( p, "present" ) ) {
+                       as->as_kind = AS_SYNTAX_PRESENT;
+               } else if ( !strcasecmp( p, "route-to-host" ) ) {
+                       as->as_kind = AS_KIND_ROUTE_TO_HOST;
+               } else if ( !strcasecmp( p, "route-to-address" ) ) {
+                       as->as_kind = AS_KIND_ROUTE_TO_ADDR;
+               } else if ( !strcasecmp( p, "own-address" ) ) {
+                       as->as_kind = AS_KIND_OWN_ADDR;
+               } else if ( !strcasecmp( p, "recipient" ) ) {
+                       as->as_kind = AS_KIND_RECIPIENT;
+               } else if ( !strcasecmp( p, "errors" ) ) {
+                       as->as_kind = AS_KIND_ERRORS;
+               } else if ( !strcasecmp( p, "request" ) ) {
+                       as->as_kind = AS_KIND_REQUEST;
+               } else if ( !strcasecmp( p, "owner" ) ) {
+                       as->as_kind = AS_KIND_OWNER;
+               } else if ( !strcasecmp( p, "delivery-type" ) ) {
+                       as->as_kind = AS_KIND_DELIVERY_TYPE;
+               } else {
+                       syslog( LOG_ALERT,
+                               "Unknown semantics word %s", p );
+                       exit( EX_TEMPFAIL );
+               }
+               p = q + 1;
+       }
+       if ( attr_semantics == NULL ) {
+               attr_semantics = calloc(2, sizeof(AttrSemantics *));
+               if ( !attr_semantics ) {
+                       syslog( LOG_ALERT, "Out of memory" );
+                       exit( EX_TEMPFAIL );
+               }
+               attr_semantics[0] = as;
+       } else {
+               int size;
+               AttrSemantics **list_temp;
+               for ( size = 0; attr_semantics[size]; size++ )
+                       ;
+               size += 2;
+               list_temp = realloc( attr_semantics,
+                                    size*sizeof(AttrSemantics *) );
+               if ( !list_temp ) {
+                       syslog( LOG_ALERT, "Out of memory" );
+                       exit( EX_TEMPFAIL );
+               }
+               attr_semantics = list_temp;
+               attr_semantics[size-2] = as;
+               attr_semantics[size-1] = NULL;
+       }
+}
+
+static void
+load_config( char *filespec )
+{
+       FILE            *cf;
+       char            *line;
+       int             lineno = 0;
+       char            *p;
+       int             rdnpref;
+       int             typemask;
+
+       cf = fopen( filespec, "r" );
+       if ( !cf ) {
+               perror( "Opening config file" );
+               exit( EX_TEMPFAIL );
+       }
+
+       while ( ( line = get_config_line( cf,&lineno ) ) ) {
+               p = strpbrk( line, " \t" );
+               if ( !p ) {
+                       syslog( LOG_ALERT,
+                               "Missing space at line %d", lineno );
+                       exit( EX_TEMPFAIL );
+               }
+               if ( !strncmp( line, "search", p-line ) ) {
+                       p += strspn( p, " \t" );
+                       /* TBC, get these */
+                       rdnpref = 0;
+                       typemask = 0xFF;
+                       add_url( p, rdnpref, typemask );
+               } else if ( !strncmp(line, "attribute", p-line) ) {
+                       p += strspn(p, " \t");
+                       add_attr_semantics( p );
+               } else if ( !strncmp(line, "default-attributes", p-line) ) {
+                       p += strspn(p, " \t");
+                       add_def_attr( p );
+               } else if ( !strncmp(line, "group-classes", p-line) ) {
+                       p += strspn(p, " \t");
+                       add_single_to( &groupclasses, p );
+               } else if ( !strncmp(line, "priority", p-line) ) {
+                       p += strspn(p, " \t");
+                       current_priority = atoi(p);
+               } else if ( !strncmp(line, "domain", p-line) ) {
+                       p += strspn(p, " \t");
+                       add_single_to( &mydomains, p );
+               } else if ( !strncmp(line, "host", p-line) ) {
+                       p += strspn(p, " \t");
+                       add_single_to( &myhosts, p );
+               } else {
+                       syslog( LOG_ALERT,
+                               "Unparseable config definition at line %d",
+                               lineno );
+                       exit( EX_TEMPFAIL );
+               }
+       }
+       fclose( cf );
+}
+
+static int
+connect_to_x500( void )
+{
+       int opt;
+
+       if ( (ld = ldap_init( ldaphost, 0 )) == NULL ) {
+               syslog( LOG_ALERT, "ldap_init failed" );
+               return( -1 );
+       }
+
+       /*  TBC: Set this only when it makes sense
+       opt = MAIL500_MAXAMBIGUOUS;
+       ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &opt);
+       */
+       opt = LDAP_DEREF_ALWAYS;
+       ldap_set_option(ld, LDAP_OPT_DEREF, &opt);
+
+       if ( ldap_simple_bind_s( ld, NULL, NULL ) != LDAP_SUCCESS ) {
+               syslog( LOG_ALERT, "ldap_simple_bind_s failed" );
+               return( -1 );
+       }
+
+       return( 0 );
+}
+
+static Group *
+new_group( char *dn, Group ***list, int *nlist )
+{
+       int     i;
+       Group   *this_group;
+
+       for ( i = 0; i < *nlist; i++ ) {
+               if ( strcmp( dn, (*list)[i]->g_dn ) == 0 ) {
+                       syslog( LOG_ALERT, "group loop 2 detected (%s)", dn );
+                       return NULL;
+               }
+       }
+
+       this_group = (Group *) malloc( sizeof(Group) );
+
+       if ( *nlist == 0 ) {
+               *list = (Group **) malloc( sizeof(Group *) );
+       } else {
+               *list = (Group **) realloc( *list, (*nlist + 1) *
+                   sizeof(Group *) );
+       }
+
+       this_group->g_errorsto = NULL;
+       this_group->g_members = NULL;
+       this_group->g_nmembers = 0;
+       /* save the group's dn so we can check for loops above */
+       this_group->g_dn = strdup( dn );
+
+       (*list)[*nlist] = this_group;
+       (*nlist)++;
+
+       return( this_group );
+}
+
+static void
+split_address(
+       char    *address,
+       char    **localpart,
+       char    **domainpart
+)
+{
+       char            *p;
+
+       if ( ( p = strrchr( address, '@' ) ) == NULL ) {
+               *localpart = strdup( address );
+               *domainpart = NULL;
+       } else {
+               *localpart = malloc( p - address + 1 );
+               strncpy( *localpart, address, p - address );
+               (*localpart)[p - address] = '\0';
+               p++;
+               *domainpart = strdup( p );
+       }
+}
+
+static int
+dn_search(
+       char    **dnlist, 
+       char    *address,
+       char    ***to,
+       int     *nto,
+       Group   ***togroups,
+       int     *ngroups,
+       Error   **err,
+       int     *nerr
+)
+{
+       int             rc;
+       int             i;
+       int             resolved = 0;
+       LDAPMessage     *res, *e;
+       struct timeval  timeout;
+
+       timeout.tv_sec = MAIL500_TIMEOUT;
+       timeout.tv_usec = 0;
+       for ( i = 0; dnlist[i]; i++ ) {
+               if ( (rc = ldap_search_st( ld, dnlist[i], LDAP_SCOPE_BASE,
+                       NULL, def_attr, 0,
+                        &timeout, &res )) != LDAP_SUCCESS ) {
+                       if ( rc == LDAP_NO_SUCH_OBJECT ) {
+                               add_error( err, nerr, E_BADMEMBER, dnlist[i], NULL );
+                               continue;
+                       } else {
+                               syslog( LOG_ALERT, "member search return 0x%x", rc );
+
+                               unbind_and_exit( EX_TEMPFAIL );
+                       }
+               } else {
+                       if ( (e = ldap_first_entry( ld, res )) == NULL ) {
+                               syslog( LOG_ALERT, "member search error parsing entry" );
+                               unbind_and_exit( EX_TEMPFAIL );
+                       }
+                       if ( entry_engine( e, dnlist[i], address, to, nto,
+                                          togroups, ngroups, err, nerr,
+                                          USER | GROUP_MEMBERS ) ) {
+                               resolved = 1;
+                       }
+               }
+       }
+       return( resolved );
+}
+
+static int
+search_ldap_url(
+       char    *url,
+       Subst   *substs,
+       char    *address,
+       int     rdnpref,
+       int     multi_entry,
+       char    ***to,
+       int     *nto,
+       Group   ***togroups,
+       int     *ngroups,
+       Error   **err,
+       int     *nerr,
+       int     type
+)
+{
+       LDAPURLDesc     *ludp;
+       char            *p, *s, *d;
+       int             i;
+       char            filter[1024];
+       LDAPMessage     *e, *res;
+       int             rc;
+       char            **attrlist;
+       struct timeval  timeout;
+       int             match;
+       int             resolved = 0;
+       char            *dn;
+
+       timeout.tv_sec = MAIL500_TIMEOUT;
+       timeout.tv_usec = 0;
+
+       rc = ldap_url_parse( url, &ludp );
+       if ( rc ) {
+               switch ( rc ) {
+               case LDAP_URL_ERR_BADSCHEME:
+                       syslog( LOG_ALERT,
+                               "Not an LDAP URL: %s", url );
+                       break;
+               case LDAP_URL_ERR_BADENCLOSURE:
+                       syslog( LOG_ALERT,
+                               "Bad Enclosure in URL: %s", url );
+                       break;
+               case LDAP_URL_ERR_BADURL:
+                       syslog( LOG_ALERT,
+                               "Bad URL: %s", url );
+                       break;
+               case LDAP_URL_ERR_BADHOST:
+                       syslog( LOG_ALERT,
+                               "Host is invalid in URL: %s", url );
+                       break;
+               case LDAP_URL_ERR_BADATTRS:
+                       syslog( LOG_ALERT,
+                               "Attributes are invalid in URL: %s", url );
+                       break;
+               case LDAP_URL_ERR_BADSCOPE:
+                       syslog( LOG_ALERT,
+                               "Scope is invalid in URL: %s", url );
+                       break;
+               case LDAP_URL_ERR_BADFILTER:
+                       syslog( LOG_ALERT,
+                               "Filter is invalid in URL: %s", url );
+                       break;
+               case LDAP_URL_ERR_BADEXTS:
+                       syslog( LOG_ALERT,
+                               "Extensions are invalid in URL: %s", url );
+                       break;
+               case LDAP_URL_ERR_MEM:
+                       syslog( LOG_ALERT,
+                               "Out of memory parsing URL: %s", url );
+                       break;
+               case LDAP_URL_ERR_PARAM:
+                       syslog( LOG_ALERT,
+                               "bad parameter parsing URL: %s", url );
+                       break;
+               default:
+                       syslog( LOG_ALERT,
+                               "Unknown error %d parsing URL: %s",
+                               rc, url );
+                       break;
+               }
+               add_error( err, nerr, E_BADMEMBER,
+                          url, NULL );
+               return 0;
+       }
+
+       if ( substs ) {
+               for ( s = ludp->lud_filter, d = filter; *s; s++,d++ ) {
+                       if ( *s == '%' ) {
+                               s++;
+                               if ( *s == '%' ) {
+                                       *d = '%';
+                                       continue;
+                               }
+                               for ( i = 0; substs[i].sub_char != '\0';
+                                     i++ ) {
+                                       if ( *s == substs[i].sub_char ) {
+                                               for ( p = substs[i].sub_value;
+                                                     *p; p++,d++ ) {
+                                                       *d = *p;
+                                               }
+                                               d--;
+                                               break;
+                                       }
+                               }
+                               if ( substs[i].sub_char == '\0' ) {
+                                       syslog( LOG_ALERT,
+                                               "unknown format %c", *s );
+                               }
+                       } else {
+                               *d = *s;
+                       }
+               }
+               *d = *s;
+       } else {
+               strncpy( filter, ludp->lud_filter, sizeof( filter ) - 1 );
+               filter[ sizeof( filter ) - 1 ] = '\0';
+       }
+
+       if ( ludp->lud_attrs ) {
+               attrlist = ludp->lud_attrs;
+       } else {
+               attrlist = def_attr;
+       }
+       res = NULL;
+       /* TBC: we don't read the host, dammit */
+       rc = ldap_search_st( ld, ludp->lud_dn, ludp->lud_scope,
+                            filter, attrlist, 0,
+                            &timeout, &res );
+
+       /* some other trouble - try again later */
+       if ( rc != LDAP_SUCCESS &&
+            rc != LDAP_SIZELIMIT_EXCEEDED ) {
+               syslog( LOG_ALERT, "return 0x%x from X.500",
+                       rc );
+               unbind_and_exit( EX_TEMPFAIL );
+       }
+
+       match = ldap_count_entries( ld, res );
+
+       /* trouble - try again later */
+       if ( match == -1 ) {
+               syslog( LOG_ALERT, "error parsing result from X.500" );
+               unbind_and_exit( EX_TEMPFAIL );
+       }
+
+       if ( match == 1 || multi_entry ) {
+               for ( e = ldap_first_entry( ld, res ); e != NULL;
+                     e = ldap_next_entry( ld, e ) ) {
+                       dn = ldap_get_dn( ld, e );
+                       resolved = entry_engine( e, dn, address, to, nto,
+                                                togroups, ngroups,
+                                                err, nerr, type );
+                       if ( !resolved ) {
+                               add_error( err, nerr, E_NOEMAIL, address, res );
+                       }
+               }
+               return ( resolved );
+       }
+
+       /* more than one match - bounce with ambiguous user? */
+       if ( match > 1 ) {
+               LDAPMessage     *next, *tmpres = NULL;
+               char            *dn;
+               char            **xdn;
+
+               /* not giving rdn preference - bounce with ambiguous user */
+               if ( rdnpref == 0 ) {
+                       add_error( err, nerr, E_AMBIGUOUS, address, res );
+                       return 0;
+               }
+
+               /*
+                * giving rdn preference - see if any entries were matched
+                * because of their rdn.  If so, collect them to deal with
+                * later (== 1 we deliver, > 1 we bounce).
+                */
+
+               for ( e = ldap_first_entry( ld, res ); e != NULL; e = next ) {
+                       next = ldap_next_entry( ld, e );
+                       dn = ldap_get_dn( ld, e );
+                       xdn = ldap_explode_dn( dn, 1 );
+
+                       /* XXX bad, but how else can we do it? XXX */
+                       if ( strcasecmp( xdn[0], address ) == 0 ) {
+                               ldap_delete_result_entry( &res, e );
+                               ldap_add_result_entry( &tmpres, e );
+                       }
+
+                       ldap_value_free( xdn );
+                       free( dn );
+               }
+
+               /* nothing matched by rdn - go ahead and bounce */
+               if ( tmpres == NULL ) {
+                       add_error( err, nerr, E_AMBIGUOUS, address, res );
+                       return 0;
+
+               /* more than one matched by rdn - bounce with rdn matches */
+               } else if ( (match = ldap_count_entries( ld, tmpres )) > 1 ) {
+                       add_error( err, nerr, E_AMBIGUOUS, address, tmpres );
+                       return 0;
+
+               /* trouble... */
+               } else if ( match < 0 ) {
+                       syslog( LOG_ALERT, "error parsing result from X.500" );
+                       unbind_and_exit( EX_TEMPFAIL );
+               }
+
+               /* otherwise one matched by rdn - send to it */
+               ldap_msgfree( res );
+               res = tmpres;
+
+               /* trouble */
+               if ( (e = ldap_first_entry( ld, res )) == NULL ) {
+                       syslog( LOG_ALERT, "error parsing entry from X.500" );
+                       unbind_and_exit( EX_TEMPFAIL );
+               }
+
+               dn = ldap_get_dn( ld, e );
+
+               resolved = entry_engine( e, dn, address, to, nto,
+                                        togroups, ngroups,
+                                        err, nerr, type );
+               if ( !resolved ) {
+                       add_error( err, nerr, E_NOEMAIL, address, res );
+                       /* Don't free res if we passed it to add_error */
+               } else {
+                       ldap_msgfree( res );
+               }
+       }
+       return( resolved );
+}
+
+static int
+url_list_search(
+       char    **urllist, 
+       char    *address,
+       int     multi_entry,
+       char    ***to,
+       int     *nto,
+       Group   ***togroups,
+       int     *ngroups,
+       Error   **err,
+       int     *nerr,
+       int     type
+)
+{
+       int             i;
+       int             resolved = 0;
+
+       for ( i = 0; urllist[i]; i++ ) {
+
+               if ( !strncasecmp( urllist[i], "mail:", 5 ) ) {
+                       char    *vals[2];
+
+                       vals[0] = urllist[i] + 5;
+                       vals[1] = NULL;
+                       add_to( to, nto, vals );
+                       resolved = 1;
+
+               } else if ( ldap_is_ldap_url( urllist[i] ) ) {
+
+                       resolved = search_ldap_url( urllist[i], NULL,
+                                                   address, 0, multi_entry,
+                                                   to, nto, togroups, ngroups,
+                                                   err, nerr, type );
+               } else {
+                       /* Produce some sensible error here */
+                       resolved = 0;
+               }
+       }
+       return( resolved );
+}
+
+/*
+ * We should probably take MX records into account to cover all bases,
+ * but really, routing belongs in the MTA.
+ */
+static int
+is_my_host(
+       char * host
+)
+{
+       char **d;
+
+       if ( myhosts == NULL )
+               return 0;
+       for ( d = myhosts; *d; d++ ) {
+               if ( !strcasecmp(*d,host) ) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+static int
+is_my_domain(
+       char * address
+)
+{
+       char **d;
+       char *p;
+
+       if ( mydomains == NULL )
+               return 0;
+       p = strchr( address, '@' );
+       if ( p == NULL)
+               return 0;
+       for ( d = mydomains; *d; d++ ) {
+               if ( !strcasecmp(*d,p+1) ) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+static void
+do_addresses(
+       char    **addresses,
+       char    ***to,
+       int     *nto,
+       Group   ***togroups,
+       int     *ngroups,
+       Error   **err,
+       int     *nerr,
+       int     type
+)
+{
+       int     i, j;
+       int     n;
+
+       /*
+        * Well, this is tricky, every address in my_addresses will be
+        * removed from the list while we shift the other values down
+        * and we do it in a single scan of the address list and
+        * without using additional memory.  We are going to be
+        * modifying the value list in a way that the later
+        * ldap_value_free works.
+        */
+       j = 0;
+       for ( i = 0; addresses[i]; i++ ) {
+               if ( is_my_domain(addresses[i]) ) {
+                       do_address( addresses[i], to, nto, togroups, ngroups,
+                                   err, nerr, type );
+                       ldap_memfree( addresses[i] );
+               } else {
+                       if ( j < i ) {
+                               addresses[j] = addresses[i];
+                       }
+                       j++;
+               }
+       }
+       addresses[j] = NULL;
+       if ( addresses[0] ) {
+               add_to( to, nto, addresses );
+       }
+}
+
+/*
+ * The entry engine processes an entry.  Normally, each entry will resolve
+ * to one or more values that will be added to the 'to' argument.  This
+ * argument needs not be the global 'to' list, it may be the g_to field
+ * in a group.  Groups have no special treatment, unless they require
+ * a special sender.
+ */
+
+static int
+entry_engine(
+       LDAPMessage *e,
+       char    *dn,
+       char    *address,
+       char    ***to,
+       int     *nto,
+       Group   ***togroups,
+       int     *ngroups,
+       Error   **err,
+       int     *nerr,
+       int     type
+)
+{
+       char    **vals;
+       int     i;
+       int     resolved = 0;
+       char    ***current_to = to;
+       int     *current_nto = nto;
+       Group   *current_group = NULL;
+       char    buf[1024];
+       char    *localpart = NULL, *domainpart = NULL;
+       Subst   substs[2];
+       int     cur_priority = 0;
+       char    *route_to_host = NULL;
+       char    *route_to_address = NULL;
+       int     needs_mta_routing = 0;
+       char    **own_addresses = NULL;
+       int     own_addresses_total = 0;
+       char    **delivery_types = NULL;
+       int     delivery_types_total = 0;
+       char    *nvals[2];
+
+       for ( i=0; attr_semantics[i] != NULL; i++ ) {
+               AttrSemantics   *as = attr_semantics[i];
+               int             nent;
+               int             j;
+
+               if ( as->as_priority < cur_priority ) {
+                       /*
+                        * We already got higher priority information,
+                        * so no further work to do, ignore the rest.
+                        */
+                       break;
+               }
+               vals = ldap_get_values( ld, e, as->as_name );
+               if ( !vals || vals[0] == NULL ) {
+                       continue;
+               }
+               nent = count_values( vals );
+               if ( nent > 1 && !as->as_m_valued ) {
+                       add_error( err, nerr, E_AMBIGUOUS, address, e );
+                       return( 0 );
+               }
+               switch ( as->as_kind ) {
+               case AS_KIND_RECIPIENT:
+                       cur_priority = as->as_priority;
+                       if ( ! ( type & ( USER | GROUP_MEMBERS ) ) )
+                               break;
+                       switch ( as->as_syntax ) {
+                       case AS_SYNTAX_RFC822:
+                               do_addresses( vals, current_to, current_nto,
+                                             togroups, ngroups, err, nerr,
+                                             USER );
+                               resolved = 1;
+                               break;
+                       case AS_SYNTAX_RFC822_EXT:
+                               do_addresses( vals, current_to, current_nto,
+                                             togroups, ngroups, err, nerr,
+                                             USER );
+                               resolved = 1;
+                               break;
+                       case AS_SYNTAX_NATIVE_MB:
+                               /* We used to concatenate mailHost if set here */
+                               /*
+                                * We used to send a copy to the vacation host
+                                * if onVacation to uid@vacationhost
+                                */
+                               if ( as->as_param ) {
+                                       for ( j=0; j<delivery_types_total; j++ ) {
+                                               if ( !strcasecmp( as->as_param, delivery_types[j] ) ) {
+                                                       add_to( current_to, current_nto, vals );
+                                                       resolved = 1;
+                                                       break;
+                                               }
+                                       }
+                               } else {
+                                       add_to( current_to, current_nto, vals );
+                                       resolved = 1;
+                               }
+                               break;
+
+                       case AS_SYNTAX_DN:
+                               if ( dn_search( vals, address,
+                                               current_to, current_nto,
+                                               togroups, ngroups,
+                                               err, nerr ) ) {
+                                       resolved = 1;
+                               }
+                               break;
+
+                       case AS_SYNTAX_URL:
+                               if ( url_list_search( vals, address,
+                                                as->as_m_entries,
+                                                current_to, current_nto,
+                                                togroups, ngroups,
+                                                err, nerr, type ) ) {
+                                       resolved = 1;
+                               }
+                               break;
+
+                       case AS_SYNTAX_BOOL_FILTER:
+                               if ( strcasecmp( vals[0], "true" ) ) {
+                                       break;
+                               }
+                               substs[0].sub_char = 'D';
+                               substs[0].sub_value = dn;
+                               substs[1].sub_char = '\0';
+                               substs[1].sub_value = NULL;
+                               if ( url_list_search( vals, address,
+                                                as->as_m_entries,
+                                                current_to, current_nto,
+                                                togroups, ngroups,
+                                                err, nerr, type ) ) {
+                                       resolved = 1;
+                               }
+                               break;
+
+                       default:
+                               syslog( LOG_ALERT,
+                                       "Invalid syntax %d for kind %d",
+                                       as->as_syntax, as->as_kind );
+                               break;
+                       }
+                       break;
+
+               case AS_KIND_ERRORS:
+                       cur_priority = as->as_priority;
+                       /* This is a group with special processing */
+                       if ( type & GROUP_ERRORS ) {
+                               switch (as->as_kind) {
+                               case AS_SYNTAX_RFC822:
+                                       add_to( current_to, current_nto, vals );
+                                       resolved = 1;
+                                       break;
+                               case AS_SYNTAX_URL:
+                               default:
+                                       syslog( LOG_ALERT,
+                                               "Invalid syntax %d for kind %d",
+                                               as->as_syntax, as->as_kind );
+                               }
+                       } else {
+                               current_group = new_group( dn, togroups,
+                                                          ngroups );
+                               current_to = &current_group->g_members;
+                               current_nto = &current_group->g_nmembers;
+                               split_address( address,
+                                              &localpart, &domainpart );
+                               if ( domainpart ) {
+                                       sprintf( buf, "%s-%s@%s",
+                                                localpart, ERRORS,
+                                                domainpart );
+                                       free( localpart );
+                                       free( domainpart );
+                               } else {
+                                       sprintf( buf, "%s-%s@%s",
+                                                localpart, ERRORS,
+                                                host );
+                                       free( localpart );
+                               }
+                               current_group->g_errorsto = strdup( buf );
+                       }
+                       break;
+
+               case AS_KIND_REQUEST:
+                       cur_priority = as->as_priority;
+                       /* This is a group with special processing */
+                       if ( type & GROUP_REQUEST ) {
+                               add_to( current_to, current_nto, vals );
+                               resolved = 1;
+                       }
+                       break;
+
+               case AS_KIND_OWNER:
+                       cur_priority = as->as_priority;
+                       /* This is a group with special processing */
+                       if ( type & GROUP_REQUEST ) {
+                               add_to( current_to, current_nto, vals );
+                               resolved = 1;
+                       }
+                       break;
+
+               case AS_KIND_ROUTE_TO_HOST:
+                       if ( !is_my_host( vals[0] ) ) {
+                               cur_priority = as->as_priority;
+                               if ( as->as_syntax == AS_SYNTAX_PRESENT ) {
+                                       needs_mta_routing = 1;
+                               } else {
+                                       route_to_host = strdup( vals[0] );
+                               }
+                       }
+                       break;
+
+               case AS_KIND_ROUTE_TO_ADDR:
+                       for ( j=0; j<own_addresses_total; j++ ) {
+                               if ( strcasecmp( vals[0], own_addresses[j] ) ) {
+                                       cur_priority = as->as_priority;
+                                       if ( as->as_syntax == AS_SYNTAX_PRESENT ) {
+                                               needs_mta_routing = 1;
+                                       } else {
+                                               route_to_address = strdup( vals[0] );
+                                       }
+                               }
+                               break;
+                       }
+
+               case AS_KIND_OWN_ADDR:
+                       add_to( &own_addresses, &own_addresses_total, vals );
+                       cur_priority = as->as_priority;
+                       break;
+
+               case AS_KIND_DELIVERY_TYPE:
+                       add_to( &delivery_types, &delivery_types_total, vals );
+                       cur_priority = as->as_priority;
+                       break;
+
+               default:
+                       syslog( LOG_ALERT,
+                               "Invalid kind %d", as->as_kind );
+                       /* Error, TBC */
+               }
+               ldap_value_free( vals );
+       }
+       /*
+        * Now check if we are dealing with mail routing.  We support
+        * two modes.
+        *
+        * The first mode and by far the most robust method is doing
+        * routing at the MTA.  In this case, we just checked if the
+        * routing attributes were present and did not seem like
+        * pointing to ourselves.  The only thing we have to do here
+        * is adding to the recipient list any of the RFC822 addresses
+        * of this entry.  That means we needed to retrieve them from
+        * the entry itself because we might have arrived here through
+        * some directory search.  The address received as argument is
+        * not the address of the entry we are processing, but rather
+        * the RFC822 address we are expanding now.  Unfortunately,
+        * this requires an MTA that understands LDAP routing.
+        * Sendmail 8.10.0 does, if compiled properly.
+        *
+        * The second method, that is most emphatically not recommended
+        * is routing in maildap.  This is going to require using the
+        * percent hack.  Moreover, this may occasionally loop.
+        */
+       if ( needs_mta_routing ) {
+               if ( !own_addresses ) {
+                       add_error( err, nerr, E_NOOWNADDRESS, address, e );
+                       return( 0 );
+               }
+               nvals[0] = own_addresses[0];    /* Anyone will do */
+               nvals[1] = NULL;
+               add_to( current_to, current_nto, nvals );
+               resolved = 1;
+       } else if ( route_to_host ) {
+               char *p;
+               if ( !route_to_address ) {
+                       if ( !own_addresses ) {
+                               add_error( err, nerr, E_NOOWNADDRESS, address, e );
+                               return( 0 );
+                       }
+                       route_to_address = strdup( own_addresses[0] );
+               }
+               /* This makes use of the percent hack, but there's no choice */
+               p = strchr( route_to_address, '@' );
+               if ( p ) {
+                       *p = '%';
+               }
+               sprintf( buf, "%s@%s", route_to_address, route_to_host );
+               nvals[0] = buf;
+               nvals[1] = NULL;
+               add_to( current_to, current_nto, nvals );
+               resolved = 1;
+               free( route_to_host );
+               free( route_to_address );
+       } else if ( route_to_address ) {
+               nvals[0] = route_to_address;
+               nvals[1] = NULL;
+               add_to( current_to, current_nto, nvals );
+               resolved = 1;
+               free( route_to_address );
+       }
+       if ( own_addresses ) {
+               ldap_value_free( own_addresses );
+       }
+       if ( delivery_types ) {
+               ldap_value_free( delivery_types );
+       }
+                 
+       return( resolved );
+}
+
+static int
+search_bases(
+       char    *filter,
+       Subst   *substs,
+       char    *name,
+       char    ***to,
+       int     *nto,
+       Group   ***togroups,
+       int     *ngroups,
+       Error   **err,
+       int     *nerr,
+       int     type
+)
+{
+       int             b, resolved = 0;
+
+       for ( b = 0; base[b] != NULL; b++ ) {
+
+               if ( ! (base[b]->b_search & type) ) {
+                       continue;
+               }
+
+               resolved = search_ldap_url( base[b]->b_url, substs, name,
+                                           base[b]->b_rdnpref,
+                                           base[b]->b_m_entries,
+                                           to, nto, togroups, ngroups,
+                                           err, nerr, type );
+               if ( resolved )
+                       break;
+       }
+       return( resolved );
+}
+
+static void
+do_address(
+       char    *name,
+       char    ***to,
+       int     *nto,
+       Group   ***togroups,
+       int     *ngroups,
+       Error   **err,
+       int     *nerr,
+       int     type
+)
+{
+       char            *localpart = NULL, *domainpart = NULL;
+       char            *synthname = NULL;
+       int             resolved;
+       int             i;
+       Subst           substs[6];
+
+       /*
+        * Look up the name in X.500, add the appropriate addresses found
+        * to the to list, or to the err list in case of error.  Groups are
+        * handled by the do_group routine, individuals are handled here.
+        * When looking up name, we follow the bases hierarchy, looking
+        * in base[0] first, then base[1], etc.  For each base, there is
+        * a set of search filters to try, in order.  If something goes
+        * wrong here trying to contact X.500, we exit with EX_TEMPFAIL.
+        * If the b_rdnpref flag is set, then we give preference to entries
+        * that matched name because it's their rdn, otherwise not.
+        */
+
+       split_address( name, &localpart, &domainpart );
+       synthname = strdup( localpart );
+       for ( i = 0; synthname[i] != '\0'; i++ ) {
+               if ( synthname[i] == '.' || synthname[i] == '_' )
+                       synthname[i] = ' ';
+       }
+       substs[0].sub_char = 'm';
+       substs[0].sub_value = name;
+       substs[1].sub_char = 'h';
+       substs[1].sub_value = host;
+       substs[2].sub_char = 'l';
+       substs[2].sub_value = localpart;
+       substs[3].sub_char = 'd';
+       substs[3].sub_value = domainpart;
+       substs[4].sub_char = 's';
+       substs[4].sub_value = synthname;
+       substs[5].sub_char = '\0';
+       substs[5].sub_value = NULL;
+
+       resolved = search_bases( NULL, substs, name,
+                                to, nto, togroups, ngroups,
+                                err, nerr, type );
+
+       if ( localpart ) {
+               free( localpart );
+       }
+       if ( domainpart ) {
+               free( domainpart );
+       }
+       if ( synthname ) {
+               free( synthname );
+       }
+
+       if ( !resolved ) {
+               /* not resolved - bounce with user unknown */
+               if ( type == USER ) {
+                       add_error( err, nerr, E_USERUNKNOWN, name, NULL );
+               } else {
+                       add_error( err, nerr, E_GROUPUNKNOWN, name, NULL );
+               }
+       }
+}
+
+static void
+send_message( char **to )
+{
+       int     pid;
+#ifndef HAVE_WAITPID
+       WAITSTATUSTYPE  status;
+#endif
+
+       if ( debug ) {
+               char    buf[1024];
+               int     i;
+
+               strcpy( buf, to[0] );
+               for ( i = 1; to[i] != NULL; i++ ) {
+                       strcat( buf, " " );
+                       strcat( buf, to[i] );
+               }
+
+               syslog( LOG_ALERT, "send_message execing sendmail: (%s)", buf );
+       }
+
+       /* parent */
+       if ( (pid = fork()) != 0 ) {
+#ifdef HAVE_WAITPID
+               waitpid( pid, (int *) NULL, 0 );
+#else
+               wait4( pid, &status, WAIT_FLAGS, 0 );
+#endif
+       /* child */
+       } else {
+               /* to includes sendmailargs */
+               execv( MAIL500_SENDMAIL, to );
+
+               syslog( LOG_ALERT, "execv failed" );
+
+               exit( EX_TEMPFAIL );
+       }
+}
+
+static void
+send_group( Group **group, int ngroup )
+{
+       int     i, pid;
+       char    **argv;
+       int     argc;
+       char    *iargv[7];
+#ifndef HAVE_WAITPID
+       WAITSTATUSTYPE  status;
+#endif
+
+       for ( i = 0; i < ngroup; i++ ) {
+               (void) rewind( stdin );
+
+               iargv[0] = MAIL500_SENDMAIL;
+               iargv[1] = "-f";
+               iargv[2] = group[i]->g_errorsto;
+               iargv[3] = "-oMrX.500";
+               iargv[4] = "-odi";
+               iargv[5] = "-oi";
+               iargv[6] = NULL;
+
+               argv = NULL;
+               argc = 0;
+               add_to( &argv, &argc, iargv );
+               add_to( &argv, &argc, group[i]->g_members );
+
+               if ( debug ) {
+                       char    buf[1024];
+                       int     i;
+
+                       strcpy( buf, argv[0] );
+                       for ( i = 1; i < argc; i++ ) {
+                               strcat( buf, " " );
+                               strcat( buf, argv[i] );
+                       }
+
+                       syslog( LOG_ALERT, "execing sendmail: (%s)", buf );
+               }
+
+               /* parent */
+               if ( (pid = fork()) != 0 ) {
+#ifdef HAVE_WAITPID
+                       waitpid( pid, (int *) NULL, 0 );
+#else
+                       wait4( pid, &status, WAIT_FLAGS, 0 );
+#endif
+               /* child */
+               } else {
+                       execv( MAIL500_SENDMAIL, argv );
+
+                       syslog( LOG_ALERT, "execv failed" );
+
+                       exit( EX_TEMPFAIL );
+               }
+       }
+}
+
+static void
+send_errors( Error *err, int nerr )
+{
+       int     pid, i, namelen;
+       FILE    *fp;
+       int     fd[2];
+       char    *argv[8];
+       char    buf[1024];
+#ifndef HAVE_WAITPID
+       WAITSTATUSTYPE  status;
+#endif
+
+       if ( strcmp( MAIL500_BOUNCEFROM, mailfrom ) == 0 ) {
+           mailfrom = errorsfrom;
+       }
+
+       argv[0] = MAIL500_SENDMAIL;
+       argv[1] = "-oMrX.500";
+       argv[2] = "-odi";
+       argv[3] = "-oi";
+       argv[4] = "-f";
+       argv[5] = MAIL500_BOUNCEFROM;
+       argv[6] = mailfrom;
+       argv[7] = NULL;
+
+       if ( debug ) {
+               int     i;
+
+               strcpy( buf, argv[0] );
+               for ( i = 1; argv[i] != NULL; i++ ) {
+                       strcat( buf, " " );
+                       strcat( buf, argv[i] );
+               }
+
+               syslog( LOG_ALERT, "execing sendmail: (%s)", buf );
+       }
+
+       if ( pipe( fd ) == -1 ) {
+               syslog( LOG_ALERT, "cannot create pipe" );
+               exit( EX_TEMPFAIL );
+       }
+
+       if ( (pid = fork()) != 0 ) {
+               if ( (fp = fdopen( fd[1], "w" )) == NULL ) {
+                       syslog( LOG_ALERT, "cannot fdopen pipe" );
+                       exit( EX_TEMPFAIL );
+               }
+
+               fprintf( fp, "To: %s\n", mailfrom );
+               fprintf( fp, "From: %s\n", errorsfrom );
+               fprintf( fp, "Subject: undeliverable mail\n" );
+               fprintf( fp, "\n" );
+               fprintf( fp, "The following errors occurred when trying to deliver the attached mail:\n" );
+               for ( i = 0; i < nerr; i++ ) {
+                       namelen = strlen( err[i].e_addr );
+                       fprintf( fp, "\n" );
+
+                       switch ( err[i].e_code ) {
+                       case E_USERUNKNOWN:
+                               fprintf( fp, "%s: User unknown\n", err[i].e_addr );
+                               break;
+
+                       case E_GROUPUNKNOWN:
+                               fprintf( fp, "%s: Group unknown\n", err[i].e_addr );
+                               break;
+
+                       case E_BADMEMBER:
+                               fprintf( fp, "%s: Group member does not exist\n",
+                                   err[i].e_addr );
+                               fprintf( fp, "This could be because the distinguished name of the person has changed\n" );
+                               fprintf( fp, "If this is the case, the problem can be solved by removing and\n" );
+                               fprintf( fp, "then re-adding the person to the group.\n" );
+                               break;
+
+                       case E_NOREQUEST:
+                               fprintf( fp, "%s: Group exists but has no request address\n",
+                                   err[i].e_addr );
+                               break;
+
+                       case E_NOERRORS:
+                               fprintf( fp, "%s: Group exists but has no errors-to address\n",
+                                   err[i].e_addr );
+                               break;
+
+                       case E_NOOWNER:
+                               fprintf( fp, "%s: Group exists but has no owner\n",
+                                   err[i].e_addr );
+                               break;
+
+                       case E_AMBIGUOUS:
+                               do_ambiguous( fp, &err[i], namelen );
+                               break;
+
+                       case E_NOEMAIL:
+                               do_noemail( fp, &err[i], namelen );
+                               break;
+
+                       case E_MEMBERNOEMAIL:
+                               fprintf( fp, "%s: Group member exists but does not have an email address\n",
+                                   err[i].e_addr );
+                               break;
+
+                       case E_JOINMEMBERNOEMAIL:
+                               fprintf( fp, "%s: User has joined group but does not have an email address\n",
+                                   err[i].e_addr );
+                               break;
+
+                       case E_LOOP:
+                               fprintf( fp, "%s: User has created a mail loop by adding address %s to their X.500 entry\n",
+                                   err[i].e_addr, err[i].e_loop );
+                               break;
+
+                       case E_NOMEMBERS:
+                               fprintf( fp, "%s: Group has no members\n",
+                                   err[i].e_addr );
+                               break;
+
+                       case E_NOOWNADDRESS:
+                               fprintf( fp, "%s: Not enough information to perform required routing\n",
+                                   err[i].e_addr );
+                               break;
+
+                       default:
+                               syslog( LOG_ALERT, "unknown error %d", err[i].e_code );
+                               unbind_and_exit( EX_TEMPFAIL );
+                               break;
+                       }
+               }
+
+               fprintf( fp, "\n------- The original message sent:\n\n" );
+
+               while ( fgets( buf, sizeof(buf), stdin ) != NULL ) {
+                       fputs( buf, fp );
+               }
+               fclose( fp );
+
+#ifdef HAVE_WAITPID
+               waitpid( pid, (int *) NULL, 0 );
+#else
+               wait4( pid, &status, WAIT_FLAGS, 0 );
+#endif
+       } else {
+               dup2( fd[0], 0 );
+
+               execv( MAIL500_SENDMAIL, argv );
+
+               syslog( LOG_ALERT, "execv failed" );
+
+               exit( EX_TEMPFAIL );
+       }
+}
+
+static void
+do_noemail( FILE *fp, Error *err, int namelen )
+{
+       int             i, last;
+       char            *dn, *rdn;
+       char            **ufn, **vals;
+
+       fprintf(fp, "%s: User has no email address registered.\n",
+           err->e_addr );
+       fprintf( fp, "%*s  Name, title, postal address and phone for '%s':\n\n",
+           namelen, " ", err->e_addr );
+
+       /* name */
+       dn = ldap_get_dn( ld, err->e_msg );
+       ufn = ldap_explode_dn( dn, 1 );
+       rdn = strdup( ufn[0] );
+       if ( strcasecmp( rdn, err->e_addr ) == 0 ) {
+               if ( (vals = ldap_get_values( ld, err->e_msg, "cn" ))
+                   != NULL ) {
+                       for ( i = 0; vals[i]; i++ ) {
+                               last = strlen( vals[i] ) - 1;
+                               if ( isdigit((unsigned char) vals[i][last]) ) {
+                                       rdn = strdup( vals[i] );
+                                       break;
+                               }
+                       }
+
+                       ldap_value_free( vals );
+               }
+       }
+       fprintf( fp, "%*s  %s\n", namelen, " ", rdn );
+       free( dn );
+       free( rdn );
+       ldap_value_free( ufn );
+
+       /* titles or descriptions */
+       if ( (vals = ldap_get_values( ld, err->e_msg, "title" )) == NULL &&
+           (vals = ldap_get_values( ld, err->e_msg, "description" ))
+           == NULL ) {
+               fprintf( fp, "%*s  No title or description registered\n",
+                   namelen, " " );
+       } else {
+               for ( i = 0; vals[i] != NULL; i++ ) {
+                       fprintf( fp, "%*s  %s\n", namelen, " ", vals[i] );
+               }
+
+               ldap_value_free( vals );
+       }
+
+       /* postal address */
+       if ( (vals = ldap_get_values( ld, err->e_msg, "postalAddress" ))
+           == NULL ) {
+               fprintf( fp, "%*s  No postal address registered\n", namelen,
+                   " " );
+       } else {
+               fprintf( fp, "%*s  ", namelen, " " );
+               for ( i = 0; vals[0][i] != '\0'; i++ ) {
+                       if ( vals[0][i] == '$' ) {
+                               fprintf( fp, "\n%*s  ", namelen, " " );
+                               while ( isspace((unsigned char) vals[0][i+1]) )
+                                       i++;
+                       } else {
+                               fprintf( fp, "%c", vals[0][i] );
+                       }
+               }
+               fprintf( fp, "\n" );
+
+               ldap_value_free( vals );
+       }
+
+       /* telephone number */
+       if ( (vals = ldap_get_values( ld, err->e_msg, "telephoneNumber" ))
+           == NULL ) {
+               fprintf( fp, "%*s  No phone number registered\n", namelen,
+                   " " );
+       } else {
+               for ( i = 0; vals[i] != NULL; i++ ) {
+                       fprintf( fp, "%*s  %s\n", namelen, " ", vals[i] );
+               }
+
+               ldap_value_free( vals );
+       }
+}
+
+/* ARGSUSED */
+static void
+do_ambiguous( FILE *fp, Error *err, int namelen )
+{
+       int             i, last;
+       char            *dn, *rdn;
+       char            **ufn, **vals;
+       LDAPMessage     *e;
+
+       i = ldap_result2error( ld, err->e_msg, 0 );
+
+       fprintf( fp, "%s: Ambiguous user.  %s%d matches found:\n\n",
+           err->e_addr, i == LDAP_SIZELIMIT_EXCEEDED ? "First " : "",
+           ldap_count_entries( ld, err->e_msg ) );
+
+       for ( e = ldap_first_entry( ld, err->e_msg ); e != NULL;
+           e = ldap_next_entry( ld, e ) ) {
+               dn = ldap_get_dn( ld, e );
+               ufn = ldap_explode_dn( dn, 1 );
+               rdn = strdup( ufn[0] );
+               if ( strcasecmp( rdn, err->e_addr ) == 0 ) {
+                       if ( (vals = ldap_get_values( ld, e, "cn" )) != NULL ) {
+                               for ( i = 0; vals[i]; i++ ) {
+                                       last = strlen( vals[i] ) - 1;
+                                       if (isdigit((unsigned char) vals[i][last])) {
+                                               rdn = strdup( vals[i] );
+                                               break;
+                                       }
+                               }
+
+                               ldap_value_free( vals );
+                       }
+               }
+
+               /* 
+               if ( isgroup( e ) ) {
+                       vals = ldap_get_values( ld, e, "description" );
+               } else {
+                       vals = ldap_get_values( ld, e, "title" );
+               }
+               */
+               vals = ldap_get_values( ld, e, "description" );
+
+               fprintf( fp, "    %-20s %s\n", rdn, vals ? vals[0] : "" );
+               for ( i = 1; vals && vals[i] != NULL; i++ ) {
+                       fprintf( fp, "                         %s\n", vals[i] );
+               }
+
+               free( dn );
+               free( rdn );
+               ldap_value_free( ufn );
+               if ( vals != NULL )
+                       ldap_value_free( vals );
+       }
+}
+
+static int
+count_values( char **list )
+{
+       int     i;
+
+       for ( i = 0; list && list[i] != NULL; i++ )
+               ;       /* NULL */
+
+       return( i );
+}
+
+static void
+add_to( char ***list, int *nlist, char **new )
+{
+       int     i, nnew, oldnlist;
+
+       nnew = count_values( new );
+
+       oldnlist = *nlist;
+       if ( *list == NULL || *nlist == 0 ) {
+               *list = (char **) malloc( (nnew + 1) * sizeof(char *) );
+               *nlist = nnew;
+       } else {
+               *list = (char **) realloc( *list, *nlist * sizeof(char *) +
+                   nnew * sizeof(char *) + sizeof(char *) );
+               *nlist += nnew;
+       }
+
+       for ( i = 0; i < nnew; i++ )
+               (*list)[i + oldnlist] = strdup( new[i] );
+       (*list)[*nlist] = NULL;
+}
+
+static void
+add_single_to( char ***list, char *new )
+{
+       int     nlist;
+
+       if ( *list == NULL ) {
+               nlist = 0;
+               *list = (char **) malloc( 2 * sizeof(char *) );
+       } else {
+               nlist = count_values( *list );
+               *list = (char **) realloc( *list,
+                                          ( nlist + 2 ) * sizeof(char *) );
+       }
+
+       (*list)[nlist] = strdup( new );
+       (*list)[nlist+1] = NULL;
+}
+
+static int
+isgroup( LDAPMessage *e )
+{
+       int     i, j;
+       char    **oclist;
+
+       if ( !groupclasses ) {
+               return( 0 );
+       }
+
+       oclist = ldap_get_values( ld, e, "objectClass" );
+
+       for ( i = 0; oclist[i] != NULL; i++ ) {
+               for ( j = 0; groupclasses[j] != NULL; j++ ) {
+                       if ( strcasecmp( oclist[i], groupclasses[j] ) == 0 ) {
+                               ldap_value_free( oclist );
+                               return( 1 );
+                       }
+               }
+       }
+       ldap_value_free( oclist );
+
+       return( 0 );
+}
+
+static void
+add_error( Error **err, int *nerr, int code, char *addr, LDAPMessage *msg )
+{
+       if ( *nerr == 0 ) {
+               *err = (Error *) malloc( sizeof(Error) );
+       } else {
+               *err = (Error *) realloc( *err, (*nerr + 1) * sizeof(Error) );
+       }
+
+       (*err)[*nerr].e_code = code;
+       (*err)[*nerr].e_addr = strdup( addr );
+       (*err)[*nerr].e_msg = msg;
+       (*nerr)++;
+}
+
+static void
+unbind_and_exit( int rc )
+{
+       int     i;
+
+       if ( (i = ldap_unbind( ld )) != LDAP_SUCCESS )
+               syslog( LOG_ALERT, "ldap_unbind failed %d\n", i );
+
+       exit( rc );
+}
index 5af6536f915447af999b9f5ea226e3a01989e691..f0e60b5c0e20e745bdc544abde908a3ec4639313 100644 (file)
@@ -1,6 +1,8 @@
 # $OpenLDAP$
 
-PROGRAMS= rcpt500
+UNIX_PRGS = rcpt500
+PROGRAMS = $(@PLAT@_PRGS)
+
 SRCS= main.c cmds.c help.c query.c
 XSRCS= version.c
 OBJS= main.o cmds.o help.o query.o
@@ -20,7 +22,13 @@ version.c: ${OBJS} $(LDAP_LIBDEPEND)
        $(MKVERSION) rcpt500 > $@
 
 install-local: $(PROGRAMS) rcpt500.help FORCE
-       -$(MKDIR) $(libexecdir) $(datadir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 rcpt500 $(libexecdir)
-       -$(MV) $(datadir)/rcpt500.help $(datadir)/rcpt500.help-
-       $(INSTALL) $(INSTALLFLAGS) -m 644 $(srcdir)/rcpt500.help $(datadir)
+       -$(MKDIR) $(DESTDIR)$(libexecdir) $(DESTDIR)$(datadir)
+       @(                                                              \
+           for prg in $(PROGRAMS); do                                  \
+               $(LTINSTALL) $(INSTALLFLAGS) -s -m 755 $$prg$(EXEEXT)   \
+                   $(DESTDIR)$(libexecdir);                            \
+           done                                                        \
+       )
+       -$(MV) $(DESTDIR)$(datadir)/rcpt500.help $(DESTDIR)$(datadir)/rcpt500.help-
+       $(INSTALL) $(INSTALLFLAGS) -m 644 $(srcdir)/rcpt500.help $(DESTDIR)$(datadir)
+
index 8e33658a3383966095607f60f49386aaee3965aa..d3729ec3f2fa0435066ff0fbfc6c54c8aba91d65 100644 (file)
@@ -12,7 +12,7 @@
 #include <ac/stdlib.h>
 #include "rcpt500.h"
 
-struct command cmds[] = {
+struct command rcpt_cmds[] = {
        "help",         help_cmd,       /* help must be the first command */
        "query for",    query_cmd,      /* must come before "query for" */
        "query",        query_cmd,
index afabd89322a786d7bd609c1538fb9e7f0d529b3e..f970476a5e8012fce75bfe84b2e1eb6320bcc28d 100644 (file)
@@ -126,7 +126,7 @@ main( int argc, char **argv )
         */
 #ifdef LOG_DAEMON
        openlog( prog, OPENLOG_OPTIONS, LOG_DAEMON );
-#else
+#elif LOG_DEBUG
        openlog( prog, OPENLOG_OPTIONS );
 #endif
     }
@@ -141,7 +141,7 @@ main( int argc, char **argv )
     if ( dosyslog ) {
        syslog( LOG_INFO, "processing command \"%s %s\" from %s",
                ( msg.msg_command < 0 ) ? "Unknown" :
-               cmds[ msg.msg_command ].cmd_text,
+               rcpt_cmds[ msg.msg_command ].cmd_text,
                ( msg.msg_arg == NULL ) ? "" : msg.msg_arg, msg.msg_replyto );
     }
 
@@ -151,10 +151,10 @@ main( int argc, char **argv )
 
 /*
     sprintf( reply, "Your request was interpreted as: %s %s\n\n",
-           cmds[ msg.msg_command ].cmd_text, msg.msg_arg );
+           rcpt_cmds[ msg.msg_command ].cmd_text, msg.msg_arg );
 */
 
-    (*cmds[ msg.msg_command ].cmd_handler)( &msg, reply );
+    (*rcpt_cmds[ msg.msg_command ].cmd_handler)( &msg, reply );
 
     if ( send_reply( &msg, reply ) < 0 ) {
        if ( dosyslog ) {
@@ -360,10 +360,10 @@ find_command( char *text, char **argp )
     }
     *s = '\0';
 
-    for ( i = 0; cmds[ i ].cmd_text != NULL; ++i ) {
-       if (( s = strstr( argbuf, cmds[ i ].cmd_text )) != NULL
-           && isspace( (unsigned char) s[ strlen( cmds[ i ].cmd_text ) ] )) {
-           strcpy( argbuf, text + (s - argbuf) + strlen( cmds[ i ].cmd_text ));
+    for ( i = 0; rcpt_cmds[ i ].cmd_text != NULL; ++i ) {
+       if (( s = strstr( argbuf, rcpt_cmds[ i ].cmd_text )) != NULL
+           && isspace( (unsigned char) s[ strlen( rcpt_cmds[ i ].cmd_text ) ] )) {
+           strcpy( argbuf, text + (s - argbuf) + strlen( rcpt_cmds[ i ].cmd_text ));
            *argp = argbuf;
            while ( isspace( (unsigned char) **argp )) {
                ++(*argp);
index 068af6026b0b02de928029296a444521b55aab9b..35194c9c4dc89b65ddec8d4484c23567195a6814 100644 (file)
@@ -41,7 +41,7 @@ int   query_cmd LDAP_P((struct msginfo *msgp, char *reply));
  */
 
 /* cmds.c */
-extern struct command cmds[];
+extern struct command rcpt_cmds[];
 /* main.c */
 extern int dosyslog;
 #ifdef LDAP_CONNECTIONLESS
index 11acdd9cff0cb9d04c9c3d2b361837cca4cefd90..ed54b4de99dae390c89d9cd2e449c5fdbdbac493 100644 (file)
@@ -8,7 +8,10 @@ OBJS   = ldapsearch.o ldapmodify.o ldapdelete.o ldapmodrdn.o ldappasswd.o
 LDAP_INCDIR= ../../include       
 LDAP_LIBDIR= ../../libraries
 
-XLIBS =  -lldif -lldap -llber -llutil
+NT_DYN_DEFS = -DLIBLBER_DECL=dllimport -DLIBLDAP_DECL=dllimport
+CPPFLAGS = $(@PLAT@_@LIB_LINKAGE@_DEFS)
+
+XLIBS =  -llutil -lldif -lldap -llber
 XXLIBS = $(SECURITY_LIBS) $(LDIF_LIBS) $(LUTIL_LIBS)
 
 XSRCS  = ldsversion.c ldmversion.c lddversion.c ldrversion.c ldpversion.c
@@ -55,11 +58,13 @@ ldrversion.c: ldapmodrdn.o $(LDAP_LIBDEPEND)
        $(MKVERSION) ldapmodrdn > $@
 
 install-local: FORCE
-       -$(MKDIR) $(bindir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 ldapsearch $(bindir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 ldapmodify $(bindir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 ldapdelete $(bindir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 ldapmodrdn $(bindir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 ldappasswd $(bindir)
-       $(RM) $(bindir)/ldapadd$(EXEEXT)
-       $(LN) $(bindir)/ldapmodify$(EXEEXT) $(bindir)/ldapadd$(EXEEXT)
+       -$(MKDIR) $(DESTDIR)$(bindir)
+       @(                                                              \
+           for prg in $(PROGRAMS); do                                  \
+               $(LTINSTALL) $(INSTALLFLAGS) -s -m 755 $$prg$(EXEEXT)   \
+                   $(DESTDIR)$(bindir);                                \
+           done                                                        \
+       )
+       $(RM) $(DESTDIR)$(bindir)/ldapadd$(EXEEXT)
+       $(LN) $(DESTDIR)$(bindir)/ldapmodify$(EXEEXT) $(DESTDIR)$(bindir)/ldapadd$(EXEEXT)
+
index 54778c42c87a89c74b36a02546f03d7b3dd469c5..6e06b769e34ef3e005f0d27568e7c7940c8e0e04 100644 (file)
@@ -1,7 +1,7 @@
 /* ldapdelete.c - simple program to delete an entry using LDAP */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 #include <ldap.h>
 
 static char    *binddn = NULL;
-static char    *passwd = NULL;
+static struct berval passwd = { 0, NULL};
 static char    *ldaphost = NULL;
 static int     ldapport = 0;
+static int     prune = 0;
+#ifdef HAVE_CYRUS_SASL
+static char    *sasl_authc_id = NULL;
+static char    *sasl_authz_id = NULL;
+static char    *sasl_mech = NULL;
+static int     sasl_integrity = 0;
+static int     sasl_privacy = 0;
+#endif
+static int     use_tls = 0;
 static int     not, verbose, contoper;
 static LDAP    *ld;
 
@@ -30,12 +39,51 @@ static int dodelete LDAP_P((
     LDAP       *ld,
     char       *dn));
 
+static int deletechildren LDAP_P(( LDAP *ld,
+                                   char *dn ));
+
+static void
+usage( const char *s )
+{
+       fprintf( stderr,
+"Delete entries from an LDAP server\n\n"
+"usage: %s [options] [dn]...\n"
+"      dn: list of DNs to delete. If not given, it will be readed from stdin\n"
+"          or from the file specified with \"-f file\".\n"
+"options:\n"
+"      -c\t\tcontinuous operation mode (do not stop on errors)\n"
+"      -d level\tset LDAP debugging level to `level'\n"
+"      -D binddn\tbind DN\n"
+"      -E\t\trequest SASL privacy (-EE to make it critical)\n"
+"      -f file\t\tdelete DNs listed in `file'\n"
+"      -h host\t\tLDAP server\n"
+"      -I\t\trequest SASL integrity checking (-II to make it\n"
+"              \tcritical)\n"
+"      -k\t\tuse Kerberos authentication\n"
+"      -K\t\tlike -k, but do only step 1 of the Kerberos bind\n"
+"      -M\t\tenable Manage DSA IT control (-MM to make it critical)\n"
+"      -n\t\tshow what would be done but don't actually delete\n"
+"      -p port\t\tport on LDAP server\n"
+"      -P version\tprocotol version (2 or 3)\n"
+"      -r\t\tdelete recursively\n"
+"      -U user\t\tSASL authentication identity (username)\n"
+"      -v\t\trun in verbose mode (diagnostics to standard output)\n"
+"      -w passwd\tbind passwd (for simple authentication)\n"
+"      -W\t\tprompt for bind passwd\n"
+"      -X id\t\tSASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
+"      -Y mech\t\tSASL mechanism\n"
+"      -Z\t\trequest the use of TLS (-ZZ to make it critical)\n"
+,              s );
+
+       exit( EXIT_FAILURE );
+}
+
+
 int
 main( int argc, char **argv )
 {
-       char            *usage = "usage: %s [-n] [-v] [-k] [-W] [-M[M]] [-d debug-level] [-f file] [-h ldaphost] [-P version] [-p ldapport] [-D binddn] [-w passwd] [dn]...\n";
-    char               buf[ 4096 ];
-    FILE               *fp;
+       char            buf[ 4096 ];
+       FILE            *fp;
        int             i, rc, authmethod, want_bindpw, version, debug, manageDSAit;
 
     not = verbose = contoper = want_bindpw = debug = manageDSAit = 0;
@@ -43,23 +91,21 @@ main( int argc, char **argv )
     authmethod = LDAP_AUTH_SIMPLE;
        version = -1;
 
-    while (( i = getopt( argc, argv, "WMnvkKch:P:p:D:w:d:f:" )) != EOF ) {
+    while (( i = getopt( argc, argv, "cD:d:Ef:h:IKkMnP:p:rU:vWw:X:Y:Z" )) != EOF ) {
        switch( i ) {
        case 'k':       /* kerberos bind */
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
                authmethod = LDAP_AUTH_KRBV4;
 #else
-               fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]);
-               fprintf( stderr, usage, argv[0] );
+               fprintf( stderr, "%s was not compiled with Kerberos support\n", argv[0] );
                return( EXIT_FAILURE );
 #endif
            break;
        case 'K':       /* kerberos bind, part one only */
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
                authmethod = LDAP_AUTH_KRBV41;
 #else
-               fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]);
-               fprintf( stderr, usage, argv[0] );
+               fprintf( stderr, "%s was not compiled with Kerberos support\n", argv[0] );
                return( EXIT_FAILURE );
 #endif
            break;
@@ -73,7 +119,7 @@ main( int argc, char **argv )
            binddn = strdup( optarg );
            break;
        case 'w':       /* password */
-           passwd = strdup( optarg );
+           passwd.bv_val = strdup( optarg );
                {
                        char* p;
 
@@ -81,6 +127,7 @@ main( int argc, char **argv )
                                *p = '*';
                        }
                }
+               passwd.bv_len = strlen( passwd.bv_val );
            break;
        case 'f':       /* read DNs from a file */
            if (( fp = fopen( optarg, "r" )) == NULL ) {
@@ -97,6 +144,9 @@ main( int argc, char **argv )
        case 'n':       /* print deletes, don't actually do them */
            ++not;
            break;
+       case 'r':
+               prune = 1;
+               break;
        case 'v':       /* verbose mode */
            verbose++;
            break;
@@ -118,16 +168,109 @@ main( int argc, char **argv )
                        break;
                default:
                        fprintf( stderr, "protocol version should be 2 or 3\n" );
-                   fprintf( stderr, usage, argv[0] );
-                   return( EXIT_FAILURE );
+                       usage( argv[0] );
+                       return( EXIT_FAILURE );
                }
                break;
+       case 'I':
+#ifdef HAVE_CYRUS_SASL
+               sasl_integrity++;
+               authmethod = LDAP_AUTH_SASL;
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'E':
+#ifdef HAVE_CYRUS_SASL
+               sasl_privacy++;
+               authmethod = LDAP_AUTH_SASL;
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'Y':
+#ifdef HAVE_CYRUS_SASL
+               if ( strcasecmp( optarg, "any" ) && strcmp( optarg, "*" ) ) {
+                       sasl_mech = strdup( optarg );
+               }
+               authmethod = LDAP_AUTH_SASL;
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'U':
+#ifdef HAVE_CYRUS_SASL
+               sasl_authc_id = strdup( optarg );
+               authmethod = LDAP_AUTH_SASL;
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'X':
+#ifdef HAVE_CYRUS_SASL
+               sasl_authz_id = strdup( optarg );
+               authmethod = LDAP_AUTH_SASL;
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'Z':
+#ifdef HAVE_TLS
+               use_tls++;
+#else
+               fprintf( stderr, "%s was not compiled with TLS support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
        default:
-           fprintf( stderr, usage, argv[0] );
-           return( EXIT_FAILURE );
+               usage( argv[0] );
+               return( EXIT_FAILURE );
        }
     }
 
+       if ( ( authmethod == LDAP_AUTH_KRBV4 ) || ( authmethod ==
+                       LDAP_AUTH_KRBV41 ) ) {
+               if( version > LDAP_VERSION2 ) {
+                       fprintf( stderr, "Kerberos requires LDAPv2\n" );
+                       return( EXIT_FAILURE );
+               }
+               version = LDAP_VERSION2;
+       }
+       else if ( authmethod == LDAP_AUTH_SASL ) {
+               if( version != -1 && version != LDAP_VERSION3 ) {
+                       fprintf( stderr, "SASL requires LDAPv3\n" );
+                       return( EXIT_FAILURE );
+               }
+               version = LDAP_VERSION3;
+       }
+
+       if( manageDSAit ) {
+               if( version != -1 && version != LDAP_VERSION3 ) {
+                       fprintf(stderr, "manage DSA control requires LDAPv3\n");
+                       return EXIT_FAILURE;
+               }
+               version = LDAP_VERSION3;
+       }
+
+       if( use_tls ) {
+               if( version != -1 && version != LDAP_VERSION3 ) {
+                       fprintf(stderr, "Start TLS requires LDAPv3\n");
+                       return EXIT_FAILURE;
+               }
+               version = LDAP_VERSION3;
+       }
+
     if ( fp == NULL ) {
        if ( optind >= argc ) {
            fp = stdin;
@@ -161,19 +304,71 @@ main( int argc, char **argv )
        /* don't chase referrals */
        ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF );
 
-       if (want_bindpw)
-               passwd = getpass("Enter LDAP Password: ");
-
        if (version != -1 &&
                ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ) != LDAP_OPT_SUCCESS)
        {
                fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version );
        }
 
-    if ( ldap_bind_s( ld, binddn, passwd, authmethod ) != LDAP_SUCCESS ) {
-       ldap_perror( ld, "ldap_bind" );
-       return( EXIT_FAILURE );
-    }
+       if ( use_tls && ldap_start_tls( ld, NULL, NULL ) != LDAP_SUCCESS ) {
+               if ( use_tls > 1 ) {
+                       ldap_perror( ld, "ldap_start_tls" );
+                       return( EXIT_FAILURE );
+               }
+       }
+
+       if (want_bindpw)
+               passwd.bv_val = getpassphrase("Enter LDAP Password: ");
+               passwd.bv_len = strlen( passwd.bv_val );
+
+       if ( authmethod == LDAP_AUTH_SASL ) {
+#ifdef HAVE_CYRUS_SASL
+               int     minssf = 0, maxssf = 0;
+
+               if ( sasl_integrity > 0 )
+                       maxssf = 1;
+               if ( sasl_integrity > 1 )
+                       minssf = 1;
+               if ( sasl_privacy > 0 )
+                       maxssf = 100000; /* Something big value */
+               if ( sasl_privacy > 1 )
+                       minssf = 56;
+               
+               if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MINSSF,
+                               (void *)&minssf ) != LDAP_OPT_SUCCESS ) {
+                       fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MINSSF"
+                               "%d\n", minssf);
+                       return( EXIT_FAILURE );
+               }
+               if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MAXSSF,
+                               (void *)&maxssf ) != LDAP_OPT_SUCCESS ) {
+                       fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MAXSSF"
+                               "%d\n", maxssf);
+                       return( EXIT_FAILURE );
+               }
+               
+               rc = ldap_negotiated_sasl_bind_s( ld, binddn, sasl_authc_id,
+                               sasl_authz_id, sasl_mech,
+                               passwd.bv_len ? &passwd : NULL,
+                               NULL, NULL );
+
+               if( rc != LDAP_SUCCESS ) {
+                       ldap_perror( ld, "ldap_negotiated_sasl_bind_s" );
+                       return( EXIT_FAILURE );
+               }
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+       }
+       else {
+               if ( ldap_bind_s( ld, binddn, passwd.bv_val, authmethod )
+                               != LDAP_SUCCESS ) {
+                       ldap_perror( ld, "ldap_bind" );
+                       return( EXIT_FAILURE );
+               }
+       }
 
        if ( manageDSAit ) {
                int err;
@@ -230,8 +425,12 @@ static int dodelete(
     if ( not ) {
        rc = LDAP_SUCCESS;
     } else {
-       if (( rc = ldap_delete_s( ld, dn )) != LDAP_SUCCESS ) {
-           ldap_perror( ld, "ldap_delete" );
+               /* If prune is on, remove a whole subtree.  Delete the children of the
+                * DN recursively, then the DN requested.
+                */
+               if ( prune ) deletechildren( ld, dn );
+               if (( rc = ldap_delete_s( ld, dn )) != LDAP_SUCCESS ) {
+                       ldap_perror( ld, "ldap_delete" );
        } else if ( verbose ) {
            printf( "\tremoved\n" );
        }
@@ -239,3 +438,59 @@ static int dodelete(
 
     return( rc );
 }
+
+/*
+ * Delete all the children of an entry recursively until leaf nodes are reached.
+ *
+ */
+static int deletechildren( LDAP *ld,
+                           char *dn )
+{
+    LDAPMessage *res, *e;
+    int entries;
+    int rc;
+       int timeout = 30 * 10000;
+
+    ldap_set_option( ld, LDAP_OPT_TIMEOUT, &timeout );
+    if ( verbose ) printf ( "deleting children of: %s\n", dn );
+    /*
+     * Do a one level search at dn for children.  For each, delete its children.
+     */
+    if ( ldap_search_s( ld, dn, LDAP_SCOPE_ONELEVEL, NULL, NULL, 0, &res ) == -1 )
+    {
+        ldap_perror( ld, "ldap_search" );
+               ldap_get_option( ld, LDAP_OPT_ERROR_NUMBER, &rc );
+        return( rc );
+    }
+
+    entries = ldap_count_entries( ld, res );
+    if ( entries > 0 )
+    {
+        int i;
+
+        for (e = ldap_first_entry( ld, res ), i = 0; e != NULL;
+             e = ldap_next_entry( ld, e ), i++ )
+        {
+            if ( (rc = deletechildren( ld, ldap_get_dn( ld, e) )) == -1 )
+            {
+                ldap_perror( ld, "ldap_prune" );
+                return rc;
+            }
+            if ( verbose )
+            {
+                printf( "\tremoving %s\n", ldap_get_dn( ld, e ) );
+            }
+            if ( ( rc = ldap_delete_s( ld, ldap_get_dn( ld, e ) ) ) == -1 )
+            {
+                ldap_perror( ld, "ldap_delete" );
+                return rc;
+            }
+            else if ( verbose )
+            {
+                printf( "\t%s removed\n", ldap_get_dn( ld, e ) );
+            }
+        }
+    }
+    ldap_msgfree( res );
+    return rc;
+}
diff --git a/clients/tools/ldapdelete.dsp b/clients/tools/ldapdelete.dsp
new file mode 100644 (file)
index 0000000..af7b4be
--- /dev/null
@@ -0,0 +1,149 @@
+# Microsoft Developer Studio Project File - Name="ldapdelete" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=ldapdelete - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "ldapdelete.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "ldapdelete.mak" CFG="ldapdelete - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "ldapdelete - Win32 Single Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ldapdelete - Win32 Single Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ldapdelete - Win32 Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ldapdelete - Win32 Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "ldapdelete - Win32 Single Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "ldapdele"
+# PROP BASE Intermediate_Dir "ldapdele"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\ldapdelete"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 oldap32.lib olber32.lib olutil32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\libraries\Debug"
+# ADD LINK32 libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\SDebug"
+
+!ELSEIF  "$(CFG)" == "ldapdelete - Win32 Single Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ldapdel0"
+# PROP BASE Intermediate_Dir "ldapdel0"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\ldapdelete"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 oldap32.lib olber32.lib olutil32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\libraries\Release"
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib sasl.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /out:"SRelease/ldapdelete.exe" /libpath:"..\..\SRelease"
+
+!ELSEIF  "$(CFG)" == "ldapdelete - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "ldapdel1"
+# PROP BASE Intermediate_Dir "ldapdel1"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\ldapdelete"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\libraries\Debug"
+# ADD LINK32 libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Debug"
+
+!ELSEIF  "$(CFG)" == "ldapdelete - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ldapdel2"
+# PROP BASE Intermediate_Dir "ldapdel2"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\ldapdelete"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ws2_32.lib /nologo /subsystem:console /machine:I386 /out:"Release/ldapdelete.exe" /libpath:"..\..\libraries\Release"
+# ADD LINK32 sasl.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /out:"Release/ldapdelete.exe" /libpath:"..\..\Release"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "ldapdelete - Win32 Single Debug"
+# Name "ldapdelete - Win32 Single Release"
+# Name "ldapdelete - Win32 Debug"
+# Name "ldapdelete - Win32 Release"
+# Begin Source File
+
+SOURCE=.\ldapdelete.c
+# End Source File
+# End Target
+# End Project
index 043d3bbc3dafd888a528f3932e88298c0c25daae..d2b453cd1e6fa3892abf1be2be41f51d97af55bd 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* ldapmodify.c - generic program to modify or add entries using LDAP */
@@ -16,7 +16,9 @@
 #include <ac/string.h>
 #include <ac/unistd.h>
 
+#ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
+#endif
 
 #ifdef HAVE_SYS_FILE_H
 #include <sys/file.h>
 
 static char    *prog;
 static char    *binddn = NULL;
-static char    *passwd = NULL;
+static struct berval passwd = { 0, NULL};
 static char    *ldaphost = NULL;
 static int     ldapport = 0;
+#ifdef HAVE_CYRUS_SASL
+static char    *sasl_authc_id = NULL;
+static char    *sasl_authz_id = NULL;
+static char    *sasl_mech = NULL;
+static int     sasl_integrity = 0;
+static int     sasl_privacy = 0;
+#endif
+static int     use_tls = 0;
 static int     new, replace, not, verbose, contoper, force, valsfromfiles;
 static LDAP    *ld;
 
@@ -76,23 +86,34 @@ static void
 usage( const char *prog )
 {
     fprintf( stderr,
-                "Add or modify entries from an LDAP server\n\n"
-            "usage: %s [-abcknrvF] [-M[M]] [-d debug-level] [-P version] [-h ldaphost]\n"
-            "            [-p ldapport] [-D binddn] [-w passwd] [ -f file | < entryfile ]\n"
-            "       a    - add values (default%s)\n"
-            "       b    - read values from files (for binary attributes)\n"
-            "       c    - continuous operation\n"
-            "       D    - bind DN\n"
-                "       M    - enable Manage DSA IT control (-MM for critical)\n"
-            "       d    - debug level\n"
-            "       f    - read from file\n"
-            "       F    - force all changes records to be used\n"
-            "       h    - ldap host\n"
-            "       n    - print adds, don't actually do them\n"
-            "       p    - LDAP port\n"
-            "       r    - replace values\n"
-            "       v    - verbose mode\n"
-            "       w    - password\n"
+"Add or modify entries from an LDAP server\n\n"
+"usage: %s [options]\n"
+"      The list of desired operations are read from stdin or from the file\n"
+"      specified by \"-f file\".\n"
+"options:\n"
+"      -a\t\tadd values (default%s)\n"
+"      -b\t\tread values from files (for binary attributes)\n"
+"      -c\t\tcontinuous operation\n"
+"      -d level\tset LDAP debugging level to `level'\n"
+"      -D dn\t\tbind DN\n"
+"      -E\t\trequest SASL privacy (-EE to make it critical)\n"
+"      -f file\t\tperform sequence of operations listed in file\n"
+"      -F\t\tforce all changes records to be used\n"
+"      -h host\t\tLDAP server\n"
+"      -I\t\trequest SASL integrity checking (-II to make it\n"
+"              \tcritical)\n"
+"      -k\t\tuse Kerberos authentication\n"
+"      -K\t\tlike -k, but do only step 1 of the Kerberos bind\n"
+"      -M\t\tenable Manage DSA IT control (-MM to make it critical)\n"
+"      -n\t\tprint adds, don't actually do them\n"
+"      -p port\t\tport on LDAP server\n"
+"      -r\t\treplace values\n"
+"      -U user\t\tSASL authentication identity (username)\n"
+"      -v\t\tverbose mode\n"
+"      -w passwd\tbind password (for Simple authentication)\n"
+"      -X id\t\tSASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
+"      -Y mech\t\tSASL mechanism\n"
+"      -Z\t\trequest the use of TLS (-ZZ to make it critical)\n"
             , prog, (strcmp( prog, "ldapadd" ) ? " is to replace" : "") );
     exit( EXIT_FAILURE );
 }
@@ -123,7 +144,7 @@ main( int argc, char **argv )
     authmethod = LDAP_AUTH_SIMPLE;
        version = -1;
 
-    while (( i = getopt( argc, argv, "WFMabckKnrtvh:p:D:w:d:f:P:" )) != EOF ) {
+    while (( i = getopt( argc, argv, "abcD:d:EFf:h:IKkMnP:p:rtU:vWw:X:Y:Z" )) != EOF ) {
        switch( i ) {
        case 'a':       /* add */
            new = 1;
@@ -138,20 +159,18 @@ main( int argc, char **argv )
            replace = 1;
            break;
        case 'k':       /* kerberos bind */
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
                authmethod = LDAP_AUTH_KRBV4;
 #else
-               fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]);
-               usage( argv[0] );
+               fprintf( stderr, "%s was not compiled with Kerberos support\n", argv[0] );
                return( EXIT_FAILURE );
 #endif
            break;
        case 'K':       /* kerberos bind, part 1 only */
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
                authmethod = LDAP_AUTH_KRBV41;
 #else
-               fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]);
-               usage( argv[0] );
+               fprintf( stderr, "%s was not compiled with Kerberos support\n", argv[0] );
                return( EXIT_FAILURE );
 #endif
            break;
@@ -165,7 +184,7 @@ main( int argc, char **argv )
            binddn = strdup( optarg );
            break;
        case 'w':       /* password */
-           passwd = strdup( optarg );
+           passwd.bv_val = strdup( optarg );
                {
                        char* p;
 
@@ -173,6 +192,7 @@ main( int argc, char **argv )
                                *p = '*';
                        }
                }
+               passwd.bv_len = strlen( passwd.bv_val );
            break;
        case 'd':
            debug |= atoi( optarg );
@@ -210,6 +230,67 @@ main( int argc, char **argv )
                        usage( argv[0] );
                }
                break;
+       case 'I':
+#ifdef HAVE_CYRUS_SASL
+               sasl_integrity++;
+               authmethod = LDAP_AUTH_SASL;
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'E':
+#ifdef HAVE_CYRUS_SASL
+               sasl_privacy++;
+               authmethod = LDAP_AUTH_SASL;
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'Y':
+#ifdef HAVE_CYRUS_SASL
+               if ( strcasecmp( optarg, "any" ) && strcmp( optarg, "*" ) ) {
+                       sasl_mech = strdup( optarg );
+               }
+               authmethod = LDAP_AUTH_SASL;
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'U':
+#ifdef HAVE_CYRUS_SASL
+               sasl_authc_id = strdup( optarg );
+               authmethod = LDAP_AUTH_SASL;
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'X':
+#ifdef HAVE_CYRUS_SASL
+               sasl_authz_id = strdup( optarg );
+               authmethod = LDAP_AUTH_SASL;
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'Z':
+#ifdef HAVE_TLS
+               use_tls++;
+#else
+               fprintf( stderr, "%s was not compiled with TLS support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
        default:
            usage( prog );
        }
@@ -218,6 +299,38 @@ main( int argc, char **argv )
     if ( argc != optind )
        usage( prog );
 
+       if ( ( authmethod == LDAP_AUTH_KRBV4 ) || ( authmethod ==
+                       LDAP_AUTH_KRBV41 ) ) {
+               if( version > LDAP_VERSION2 ) {
+                       fprintf( stderr, "Kerberos requires LDAPv2\n" );
+                       return( EXIT_FAILURE );
+               }
+               version = LDAP_VERSION2;
+       }
+       else if ( authmethod == LDAP_AUTH_SASL ) {
+               if( version != -1 && version != LDAP_VERSION3 ) {
+                       fprintf( stderr, "SASL requires LDAPv3\n" );
+                       return( EXIT_FAILURE );
+               }
+               version = LDAP_VERSION3;
+       }
+
+       if( manageDSAit ) {
+               if( version != -1 && version != LDAP_VERSION3 ) {
+                       fprintf(stderr, "manage DSA control requires LDAPv3\n");
+                       return EXIT_FAILURE;
+               }
+               version = LDAP_VERSION3;
+       }
+
+       if( use_tls ) {
+               if( version != -1 && version != LDAP_VERSION3 ) {
+                       fprintf(stderr, "Start TLS requires LDAPv3\n");
+                       return EXIT_FAILURE;
+               }
+               version = LDAP_VERSION3;
+       }
+
     if ( infile != NULL ) {
        if (( fp = fopen( infile, "r" )) == NULL ) {
            perror( infile );
@@ -255,19 +368,72 @@ main( int argc, char **argv )
        /* don't chase referrals */
        ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF );
 
-       if (want_bindpw)
-               passwd = getpass("Enter LDAP Password: ");
-
        if (version != -1 &&
                ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ) != LDAP_OPT_SUCCESS)
        {
                fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION to %d\n", version );
        }
 
-       if ( ldap_bind_s( ld, binddn, passwd, authmethod ) != LDAP_SUCCESS ) {
-           ldap_perror( ld, "ldap_bind" );
-           return( EXIT_FAILURE );
+       if ( use_tls && ldap_start_tls( ld, NULL, NULL ) != LDAP_SUCCESS ) {
+               if ( use_tls > 1 ) {
+                       ldap_perror( ld, "ldap_start_tls" );
+                       return( EXIT_FAILURE );
+               }
        }
+
+       if (want_bindpw)
+               passwd.bv_val = getpassphrase("Enter LDAP Password: ");
+               passwd.bv_len = strlen( passwd.bv_val );
+
+       if ( authmethod == LDAP_AUTH_SASL ) {
+#ifdef HAVE_CYRUS_SASL
+               int     minssf = 0, maxssf = 0;
+
+               if ( sasl_integrity > 0 )
+                       maxssf = 1;
+               if ( sasl_integrity > 1 )
+                       minssf = 1;
+               if ( sasl_privacy > 0 )
+                       maxssf = 100000; /* Something big value */
+               if ( sasl_privacy > 1 )
+                       minssf = 56;
+               
+               if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MINSSF,
+                       (void *)&minssf ) != LDAP_OPT_SUCCESS ) {
+                       fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MINSSF"
+                               "%d\n", minssf);
+                       return( EXIT_FAILURE );
+               }
+               if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MAXSSF,
+                       (void *)&maxssf ) != LDAP_OPT_SUCCESS ) {
+                       fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MINSSF"
+                               "%d\n", minssf);
+                       return( EXIT_FAILURE );
+               }
+               
+               rc = ldap_negotiated_sasl_bind_s( ld, binddn, sasl_authc_id,
+                               sasl_authz_id, sasl_mech,
+                               passwd.bv_len ? &passwd : NULL,
+                               NULL, NULL );
+
+               if( rc != LDAP_SUCCESS ) {
+                       ldap_perror( ld, "ldap_negotiated_sasl_bind_s" );
+                       return( EXIT_FAILURE );
+               }
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+       }
+       else {
+               if ( ldap_bind_s( ld, binddn, passwd.bv_val, authmethod )
+                               != LDAP_SUCCESS ) {
+                       ldap_perror( ld, "ldap_bind" );
+                       return( EXIT_FAILURE );
+               }
+       }
+
     }
 
     rc = 0;
@@ -303,10 +469,14 @@ main( int argc, char **argv )
         * has a colon that appears to the left of any equal signs, OR
         * if the first line consists entirely of digits (an entry id)
         */
+#ifdef LDAP_LDIF
+       use_ldif = 1;
+#else
        use_ldif = ( *rbuf == '#' ) ||
                (( p = strchr( rbuf, ':' )) != NULL &&
                (  q = strchr( rbuf, '\n' )) != NULL && p < q &&
                (( q = strchr( rbuf, '=' )) == NULL || p < q ));
+#endif
 
        start = rbuf;
 
@@ -357,7 +527,7 @@ process_ldif_rec( char *rbuf, int count )
 
     new_entry = new;
 
-    rc = got_all = saw_replica = delete_entry = expect_modop = 0;
+    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;
@@ -392,7 +562,7 @@ process_ldif_rec( char *rbuf, int count )
                    *p++ = '\0';
                    replicaport = atoi( p );
                }
-               if ( strcasecmp( value, ldaphost ) == 0 &&
+               if ( ldaphost != NULL && strcasecmp( value, ldaphost ) == 0 &&
                        replicaport == ldapport ) {
                    use_record = 1;
                }
diff --git a/clients/tools/ldapmodify.dsp b/clients/tools/ldapmodify.dsp
new file mode 100644 (file)
index 0000000..9a58a70
--- /dev/null
@@ -0,0 +1,149 @@
+# Microsoft Developer Studio Project File - Name="ldapmodify" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=ldapmodify - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "ldapmodify.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "ldapmodify.mak" CFG="ldapmodify - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "ldapmodify - Win32 Single Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ldapmodify - Win32 Single Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ldapmodify - Win32 Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ldapmodify - Win32 Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "ldapmodify - Win32 Single Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "ldapmodi"
+# PROP BASE Intermediate_Dir "ldapmodi"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\ldapmodify"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 oldap32.lib olber32.lib oldif32.lib olutil32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\libraries\Debug"
+# ADD LINK32 libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /out:"SDebug/ldapmodify.exe" /pdbtype:sept /libpath:"..\..\SDebug"
+
+!ELSEIF  "$(CFG)" == "ldapmodify - Win32 Single Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ldapmod0"
+# PROP BASE Intermediate_Dir "ldapmod0"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\ldapmodify"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 oldap32.lib olber32.lib oldif32.lib olutil32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\libraries\Release"
+# ADD LINK32 sasl.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /out:"SRelease/ldapmodify.exe" /libpath:"..\..\SRelease"
+
+!ELSEIF  "$(CFG)" == "ldapmodify - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "ldapmod1"
+# PROP BASE Intermediate_Dir "ldapmod1"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\ldapmodify"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Release/ldapmodify.exe" /pdbtype:sept /libpath:"..\..\libraries\Debug"
+# ADD LINK32 libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/ldapmodify.exe" /pdbtype:sept /libpath:"..\..\Debug"
+
+!ELSEIF  "$(CFG)" == "ldapmodify - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ldapmod2"
+# PROP BASE Intermediate_Dir "ldapmod2"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\ldapmodify"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ws2_32.lib /nologo /subsystem:console /machine:I386 /out:"Release/ldapmodify.exe" /libpath:"..\..\libraries\Release"
+# ADD LINK32 sasl.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /out:"Release/ldapmodify.exe" /libpath:"..\..\Release"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "ldapmodify - Win32 Single Debug"
+# Name "ldapmodify - Win32 Single Release"
+# Name "ldapmodify - Win32 Debug"
+# Name "ldapmodify - Win32 Release"
+# Begin Source File
+
+SOURCE=.\ldapmodify.c
+# End Source File
+# End Target
+# End Project
index 3bc2e3140df15087121fee3bdf7e95597c4cfa44..3aa05b10f073d3e363b3d821a61be97aa7829071 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* ldapmodrdn.c - generic program to modify an entry's RDN using LDAP.
 #include <ldap.h>
 
 static char    *binddn = NULL;
-static char    *passwd = NULL;
+static struct berval passwd = { 0, NULL};
 static char    *ldaphost = NULL;
 static int     ldapport = 0;
+#ifdef HAVE_CYRUS_SASL
+static char    *sasl_authc_id = NULL;
+static char    *sasl_authz_id = NULL;
+static char    *sasl_mech = NULL;
+static int     sasl_integrity = 0;
+static int     sasl_privacy = 0;
+#endif
+static int     use_tls = 0;
 static int     not, verbose, contoper;
 static LDAP    *ld;
 
-static int domodrdn LDAP_P((
+static int domodrdn(
     LDAP       *ld,
     char       *dn,
     char       *rdn,
-    int                remove,         /* flag: remove old RDN */
-    char       *newSuperior));
+    char       *newSuperior,
+    int                remove );       /* flag: remove old RDN */
+
+static void
+usage( const char *s )
+{
+       fprintf( stderr,
+"Rename LDAP entries\n\n"
+"usage: %s [options] [dn rdn]\n"
+"      dn rdn: If given, rdn will replace the RDN of the entry specified by DN\n"
+"              If not given, the list of modifications is read from stdin or\n"
+"              from the file specified by \"-f file\" (see man page).\n"
+"options:\n"
+"      -c\t\tcontinuous operation mode (do not stop on errors)\n"
+"      -d level\tset LDAP debugging level to `level'\n"
+"      -D binddn\tbind DN\n"
+"      -E\t\trequest SASL privacy (-EE to make it critical)\n"
+"      -f file\t\tdo renames listed in `file'\n"
+"      -h host\t\tLDAP server\n"
+"      -I\t\trequest SASL integrity checking (-II to make it\n"
+"              \tcritical)\n"
+"      -k\t\tuse Kerberos authentication\n"
+"      -K\t\tlike -k, but do only step 1 of the Kerberos bind\n"
+"      -M\t\tenable Manage DSA IT control (-MM to make it critical)\n"
+"      -n\t\tshow what would be done but don't actually do it\n"
+"      -p port\t\tport on LDAP server\n"
+"      -P version\tprocotol version (2 or 3)\n"
+"      -r\t\tremove old RDN\n"
+"      -s newsuperior\tnew superior entry\n"
+"      -U user\t\tSASL authentication identity (username)\n"
+"      -v\t\trun in verbose mode (diagnostics to standard output)\n"
+"      -w passwd\tbind passwd (for simple authentication)\n"
+"      -W\t\tprompt for bind passwd\n"
+"      -X id\t\tSASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
+"      -Y mech\t\tSASL mechanism\n"
+"      -Z\t\trequest the use of TLS (-ZZ to make it critical)\n"
+,              s );
+
+       exit( EXIT_FAILURE );
+}
 
 int
 main(int argc, char **argv)
 {
-       char            *usage = "usage: %s [-nvkWc] [-M[M]] [-d debug-level] [-h ldaphost] [-P version] [-p ldapport] [-D binddn] [-w passwd] [ -f file | < entryfile | dn newrdn ] [-s newSuperior]\n";
-    char               *myname,*infile, *entrydn, *rdn, buf[ 4096 ];
+    char               *myname,*infile, *entrydn = NULL, *rdn = NULL, buf[ 4096 ];
     FILE               *fp;
        int             rc, i, remove, havedn, authmethod, version, want_bindpw, debug, manageDSAit;
     char       *newSuperior=NULL;
@@ -61,24 +106,24 @@ main(int argc, char **argv)
 
     myname = (myname = strrchr(argv[0], '/')) == NULL ? argv[0] : ++myname;
 
-    while (( i = getopt( argc, argv, "WkKMcnvrh:P:p:D:w:d:f:s:" )) != EOF ) {
+    while (( i = getopt( argc, argv, "cD:d:Ef:h:IKkMnP:p:rs:U:vWw:X:Y:Z" )) != EOF ) {
        switch( i ) {
        case 'k':       /* kerberos bind */
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
                authmethod = LDAP_AUTH_KRBV4;
 #else
-               fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]);
+               fprintf( stderr, "%s was not compiled with Kerberos support\n", argv[0] );
                return( EXIT_FAILURE );
 #endif
-           break;
+               break;
        case 'K':       /* kerberos bind, part one only */
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
                authmethod = LDAP_AUTH_KRBV41;
 #else
-               fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]);
+               fprintf( stderr, "%s was not compiled with Kerberos support\n", argv[0] );
                return( EXIT_FAILURE );
 #endif
-           break;
+               break;
        case 'c':       /* continuous operation mode */
            ++contoper;
            break;
@@ -93,7 +138,7 @@ main(int argc, char **argv)
            version = LDAP_VERSION3;    /* This option => force V3 */
            break;
        case 'w':       /* password */
-           passwd = strdup( optarg );
+           passwd.bv_val = strdup( optarg );
                {
                        char* p;
 
@@ -101,6 +146,7 @@ main(int argc, char **argv)
                                *p = '*';
                        }
                }
+               passwd.bv_len = strlen( passwd.bv_val );
            break;
        case 'd':
            debug |= atoi( optarg );
@@ -138,26 +184,117 @@ main(int argc, char **argv)
                        break;
                default:
                        fprintf( stderr, "protocol version should be 2 or 3\n" );
-                   fprintf( stderr, usage, argv[0] );
-                   return( EXIT_FAILURE );
+                       usage( argv[0] );
+                       return( EXIT_FAILURE );
+               }
+               break;
+       case 'I':
+#ifdef HAVE_CYRUS_SASL
+               sasl_integrity++;
+               authmethod = LDAP_AUTH_SASL;
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'E':
+#ifdef HAVE_CYRUS_SASL
+               sasl_privacy++;
+               authmethod = LDAP_AUTH_SASL;
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'Y':
+#ifdef HAVE_CYRUS_SASL
+               if ( strcasecmp( optarg, "any" ) && strcmp( optarg, "*" ) ) {
+                       sasl_mech = strdup( optarg );
                }
+               authmethod = LDAP_AUTH_SASL;
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'U':
+#ifdef HAVE_CYRUS_SASL
+               sasl_authc_id = strdup( optarg );
+               authmethod = LDAP_AUTH_SASL;
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'X':
+#ifdef HAVE_CYRUS_SASL
+               sasl_authz_id = strdup( optarg );
+               authmethod = LDAP_AUTH_SASL;
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'Z':
+#ifdef HAVE_TLS
+               use_tls++;
+#else
+               fprintf( stderr, "%s was not compiled with TLS support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
                break;
        default:
-           fprintf( stderr, usage, argv[0] );
+           usage( argv[0] );
            return( EXIT_FAILURE );
        }
     }
 
+       if ( ( authmethod == LDAP_AUTH_KRBV4 ) || ( authmethod ==
+                       LDAP_AUTH_KRBV41 ) ) {
+               if( version > LDAP_VERSION2 ) {
+                       fprintf( stderr, "Kerberos requires LDAPv2\n" );
+                       return( EXIT_FAILURE );
+               }
+               version = LDAP_VERSION2;
+       }
+       else if ( authmethod == LDAP_AUTH_SASL ) {
+               if( version != -1 && version != LDAP_VERSION3 ) {
+                       fprintf( stderr, "SASL requires LDAPv3\n" );
+                       return( EXIT_FAILURE );
+               }
+               version = LDAP_VERSION3;
+       }
+
+       if( manageDSAit ) {
+               if( version != -1 && version != LDAP_VERSION3 ) {
+                       fprintf(stderr, "manage DSA control requires LDAPv3\n");
+                       return EXIT_FAILURE;
+               }
+               version = LDAP_VERSION3;
+       }
+
+       if( use_tls ) {
+               if( version != -1 && version != LDAP_VERSION3 ) {
+                       fprintf(stderr, "Start TLS requires LDAPv3\n");
+                       return EXIT_FAILURE;
+               }
+               version = LDAP_VERSION3;
+       }
+
     if (newSuperior != NULL) {
                if (version == LDAP_VERSION2) {
                        fprintf( stderr,
                                "%s: version conflict!, -s newSuperior requires LDAPv3\n",
                                myname);
-                       fprintf( stderr, usage, argv[0] );
+                       usage( argv[0] );
                        return( EXIT_FAILURE );
                }
-
-               /* promote to LDAPv3 */
                version = LDAP_VERSION3;
     }
     
@@ -174,7 +311,7 @@ main(int argc, char **argv)
        ++havedn;
     } else if ( argc - optind != 0 ) {
        fprintf( stderr, "%s: invalid number of arguments, only two allowed\n", myname);
-       fprintf( stderr, usage, argv[0] );
+       usage( argv[0] );
        return( EXIT_FAILURE );
     }
 
@@ -214,19 +351,71 @@ main(int argc, char **argv)
        ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF );
 
 
-       if (want_bindpw)
-               passwd = getpass("Enter LDAP Password: ");
-
        if (version != -1 &&
                ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ) != LDAP_OPT_SUCCESS)
        {
                fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version );
        }
 
-    if ( ldap_bind_s( ld, binddn, passwd, authmethod ) != LDAP_SUCCESS ) {
-       ldap_perror( ld, "ldap_bind" );
-       return( EXIT_FAILURE );
-    }
+       if ( use_tls && ldap_start_tls( ld, NULL, NULL ) != LDAP_SUCCESS ) {
+               if ( use_tls > 1 ) {
+                       ldap_perror( ld, "ldap_start_tls" );
+                       return( EXIT_FAILURE );
+               }
+       }
+
+       if (want_bindpw)
+               passwd.bv_val = getpassphrase("Enter LDAP Password: ");
+               passwd.bv_len = strlen( passwd.bv_val );
+
+       if ( authmethod == LDAP_AUTH_SASL ) {
+#ifdef HAVE_CYRUS_SASL
+               int     minssf = 0, maxssf = 0;
+
+               if ( sasl_integrity > 0 )
+                       maxssf = 1;
+               if ( sasl_integrity > 1 )
+                       minssf = 1;
+               if ( sasl_privacy > 0 )
+                       maxssf = 100000; /* Something big value */
+               if ( sasl_privacy > 1 )
+                       minssf = 56;
+               
+               if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MINSSF,
+                       (void *)&minssf ) != LDAP_OPT_SUCCESS ) {
+                       fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MINSSF"
+                               "%d\n", minssf);
+                       return( EXIT_FAILURE );
+               }
+               if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MAXSSF,
+                       (void *)&maxssf ) != LDAP_OPT_SUCCESS ) {
+                       fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MAXSSF"
+                               "%d\n", maxssf);
+                       return( EXIT_FAILURE );
+               }
+               
+               rc = ldap_negotiated_sasl_bind_s( ld, binddn, sasl_authc_id,
+                               sasl_authz_id, sasl_mech,
+                               passwd.bv_len ? &passwd : NULL,
+                               NULL, NULL );
+
+               if( rc != LDAP_SUCCESS ) {
+                       ldap_perror( ld, "ldap_negotiated_sasl_bind_s" );
+                       return( EXIT_FAILURE );
+               }
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+       }
+       else {
+               if ( ldap_bind_s( ld, binddn, passwd.bv_val, authmethod )
+                               != LDAP_SUCCESS ) {
+                       ldap_perror( ld, "ldap_bind" );
+                       return( EXIT_FAILURE );
+               }
+       }
 
        if ( manageDSAit ) {
                int err;
@@ -252,7 +441,7 @@ main(int argc, char **argv)
 
     rc = 0;
     if (havedn)
-       rc = domodrdn(ld, entrydn, rdn, remove, newSuperior);
+       rc = domodrdn( ld, entrydn, rdn, newSuperior, remove );
     else while ((rc == 0 || contoper) && fgets(buf, sizeof(buf), fp) != NULL) {
        if ( *buf != '\0' ) {   /* blank lines optional, skip */
            buf[ strlen( buf ) - 1 ] = '\0';    /* remove nl */
@@ -262,7 +451,7 @@ main(int argc, char **argv)
                     perror( "strdup" );
                     return( EXIT_FAILURE );
                }
-               rc = domodrdn(ld, entrydn, rdn, remove, newSuperior);
+               rc = domodrdn(ld, entrydn, rdn, newSuperior, remove );
                havedn = 0;
            } else if ( !havedn ) {     /* don't have DN yet */
                if (( entrydn = strdup( buf )) == NULL ) {
@@ -284,8 +473,8 @@ static int domodrdn(
     LDAP       *ld,
     char       *dn,
     char       *rdn,
-    int                remove,         /* flag: remove old RDN */
-    char       *newSuperior)
+    char       *newSuperior,
+    int                remove ) /* flag: remove old RDN */
 {
     int        i;
 
@@ -299,7 +488,7 @@ static int domodrdn(
        }
 
     if ( !not ) {
-       i = ldap_rename2_s( ld, dn, rdn, remove, newSuperior );
+       i = ldap_rename2_s( ld, dn, rdn, newSuperior, remove );
        if ( i != LDAP_SUCCESS ) {
            ldap_perror( ld, "ldap_rename2_s" );
        } else if ( verbose ) {
diff --git a/clients/tools/ldapmodrdn.dsp b/clients/tools/ldapmodrdn.dsp
new file mode 100644 (file)
index 0000000..bcf0cc0
--- /dev/null
@@ -0,0 +1,149 @@
+# Microsoft Developer Studio Project File - Name="ldapmodrdn" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=ldapmodrdn - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "ldapmodrdn.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "ldapmodrdn.mak" CFG="ldapmodrdn - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "ldapmodrdn - Win32 Single Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ldapmodrdn - Win32 Single Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ldapmodrdn - Win32 Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ldapmodrdn - Win32 Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "ldapmodrdn - Win32 Single Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "ldapmodr"
+# PROP BASE Intermediate_Dir "ldapmodr"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\ldapmodrdn"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 oldap32.lib olber32.lib olutil32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\libraries\Debug"
+# ADD LINK32 libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\SDebug"
+
+!ELSEIF  "$(CFG)" == "ldapmodrdn - Win32 Single Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ldapmod0"
+# PROP BASE Intermediate_Dir "ldapmod0"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\ldapmodrdn"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 oldap32.lib olber32.lib olutil32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\libraries\Release"
+# ADD LINK32 sasl.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /out:"Release/ldapmodrdn.exe" /libpath:"..\..\SRelease"
+
+!ELSEIF  "$(CFG)" == "ldapmodrdn - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "ldapmod1"
+# PROP BASE Intermediate_Dir "ldapmod1"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\ldapmodrdn"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\libraries\Debug"
+# ADD LINK32 libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Debug"
+
+!ELSEIF  "$(CFG)" == "ldapmodrdn - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ldapmod2"
+# PROP BASE Intermediate_Dir "ldapmod2"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\ldapmodrdn"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ws2_32.lib /nologo /subsystem:console /machine:I386 /out:"Release/ldapmodrdn.exe" /libpath:"..\..\libraries\Release"
+# ADD LINK32 sasl.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /out:"Release/ldapmodrdn.exe" /libpath:"..\..\Release"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "ldapmodrdn - Win32 Single Debug"
+# Name "ldapmodrdn - Win32 Single Release"
+# Name "ldapmodrdn - Win32 Debug"
+# Name "ldapmodrdn - Win32 Release"
+# Begin Source File
+
+SOURCE=.\ldapmodrdn.c
+# End Source File
+# End Target
+# End Project
index 98aa570fedc14df6465beaaa19dfeee03ca1fea6..18b19c2d6143aebcb460273d14a8c544b56081d4 100644 (file)
@@ -1,22 +1,8 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
-/*
- *     Copyright 1998, David E. Storey, All rights reserved.
- *     This software is not subject to any license of The Murphy Group, Inc.
- *     or George Mason University.
- *
- *     Redistribution and use in source and binary forms are permitted only
- *     as authorized by the OpenLDAP Public License.  A copy of this
- *     license is available at http://www.OpenLDAP.org/license.html or
- *     in file LICENSE in the top-level directory of the distribution.
- *
- *     ldappasswd.c - program to modify passwords in an LDAP tree
- *
- *     Author: David E. Storey <dave@tamos.net>
- */
 
 #include "portable.h"
 
 #include <ac/time.h>
 #include <ac/unistd.h>
 
-#include <lber.h>
 #include <ldap.h>
-#include <lutil.h>
-#include <lutil_md5.h>
-#include <lutil_sha1.h>
 
 #include "ldap_defaults.h"
 
-/* local macros */
-#define CEILING(x)     ((double)(x) > (int)(x) ? (int)(x) + 1 : (int)(x))
-
-#define LDAP_PASSWD_ATTRIB "userPassword"
-#define LDAP_PASSWD_CONF   LDAP_SYSCONFDIR LDAP_DIRSEP "passwd.conf"
-
-#define HS_NONE  0
-#define HS_PLAIN 1
-#define HS_CONV  2
-
-typedef enum
-{
-       HASHTYPE_NONE,
-       HASHTYPE_CRYPT,
-       HASHTYPE_MD5,
-       HASHTYPE_SMD5,
-       HASHTYPE_SHA1,
-       HASHTYPE_SSHA1
-}
-HashTypes;
-
-typedef struct salt_t
-{
-       unsigned char  *salt;
-       unsigned int    len;
-}
-Salt;
-
-typedef struct hash_t
-{
-       const char     *name;
-       unsigned int    namesz;
-       char           *(*func) (const char *, Salt *);
-       unsigned char   takes_salt;
-       HashTypes       type;
-       HashTypes       type_salted;
-       unsigned int    default_salt_len;
-}
-Hash;
-
-static int     noupdates = 0;
 static int     verbose = 0;
-static int     want_entryhash = 0;
-static int     auto_gen_pw = 0;
-
-/*** functions ***/
-
-/*
- * pw_encode() essentially base64 encodes a password and its salt
- */
-
-static char *
-pw_encode (unsigned char *passwd, Salt * salt, unsigned int len)
-{
-       int             salted = salt && salt->salt && salt->len;
-       int             b64_len = 0;
-       char           *base64digest = NULL;
-       unsigned char  *npasswd = passwd;
-
-       if (salted)
-       {
-               npasswd = (unsigned char *)malloc (len + salt->len);
-               memcpy (npasswd, passwd, len);
-               memcpy (&npasswd[len], salt->salt, salt->len);
-               len += salt->len;
-       }
-
-       b64_len = CEILING (len / 3) * 4 + 1;
-       base64digest = (char *)malloc (b64_len);
-       if (lutil_b64_ntop (npasswd, len, base64digest, b64_len) < 0)
-       {
-               free (base64digest);
-               base64digest = NULL;
-       }
-
-       if (salted)
-               free (npasswd);
-
-       return (base64digest);
-}
-
-/*
- * if you'd like to write a better salt generator, please, be my guest.
- */
 
 static void
-make_salt (Salt * salt, unsigned int len)
-{
-
-       if (!salt)
-               return;
-
-       salt->len = len;
-       salt->salt = (unsigned char *)malloc (len);
-
-       for (len = 0; len < salt->len; len++)
-               salt->salt[len] = rand () & 0xff;
-}
-
-/*
- * password generator
- */
-
-static char *
-gen_pass (unsigned int len)
-{
-       static const unsigned char autogen[] =
-               "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890.,";
-       unsigned int i;
-       Salt            salt;
-
-       salt.salt = NULL;
-       salt.len = 0;
-
-       make_salt (&salt, len);
-       for (i = 0; i < len; i++)
-               salt.salt[i] = autogen[salt.salt[i] % (sizeof (autogen) - 1)];
-
-       return ((char *)salt.salt);
-}
-
-#ifdef SLAPD_CLEARTEXT
-static char *
-hash_none (const char *pw_in, Salt * salt)
-{
-       return (strdup (pw_in));
-}
-#endif
-
-#ifdef SLAPD_CRYPT
-static char *
-hash_crypt (const char *pw_in, Salt * salt)
-{
-       static const unsigned char crypt64[] =
-               "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890./";
-       char   *crypted_pw = NULL;
-       Salt    lsalt;
-
-       if (salt && salt->salt && strlen ((char *)salt->salt) >= 2)
-       {
-               /* sanity check */
-               if (!(isalnum(salt->salt[0]) || salt->salt[0] == '.' || salt->salt[0] == '/'))
-                       salt->salt[0] = crypt64[salt->salt[0] % (sizeof (crypt64) - 1)];
-               if (!(isalnum(salt->salt[1]) || salt->salt[1] == '.' || salt->salt[1] == '/'))
-                       salt->salt[1] = crypt64[salt->salt[1] % (sizeof (crypt64) - 1)];
-
-               crypted_pw = crypt (pw_in, (char *)salt->salt);
-       }
-       else
-       {
-               make_salt (&lsalt, 2);
-               lsalt.salt[0] = crypt64[lsalt.salt[0] % (sizeof (crypt64) - 1)];
-               lsalt.salt[1] = crypt64[lsalt.salt[1] % (sizeof (crypt64) - 1)];
-               crypted_pw = crypt (pw_in, (char *)lsalt.salt);
-               free (lsalt.salt);
-       }
-       return (strdup (crypted_pw));
-}
-#endif
-
-static char *
-hash_md5 (const char *pw_in, Salt * salt)
-{
-       lutil_MD5_CTX   MD5context;
-       unsigned char   MD5digest[16];
-
-       lutil_MD5Init (&MD5context);
-       lutil_MD5Update (&MD5context,
-                        (const unsigned char *)pw_in, strlen(pw_in));
-       if (salt && salt->salt && salt->len)
-               lutil_MD5Update (&MD5context, salt->salt, salt->len);
-       lutil_MD5Final (MD5digest, &MD5context);
-
-       return (pw_encode (MD5digest, salt, sizeof (MD5digest)));
-}
-
-static char *
-hash_sha1 (const char *pw_in, Salt * salt)
+usage(const char *s)
 {
-       lutil_SHA1_CTX  SHA1context;
-       unsigned char   SHA1digest[20];
-
-       lutil_SHA1Init (&SHA1context);
-       lutil_SHA1Update (&SHA1context,
-                         (const unsigned char *)pw_in, strlen(pw_in));
-       if (salt && salt->salt && salt->len)
-               lutil_SHA1Update (&SHA1context, salt->salt, salt->len);
-       lutil_SHA1Final (SHA1digest, &SHA1context);
+       fprintf(stderr,
+"Change the password of an LDAP entry\n\n"
+"usage: %s [options] dn\n"
+"      dn: the DN of the entry whose password must be changed\n"
+"options:\n"
+"      -a secret\told password\n"
+"      -A\t\tprompt for old password\n"
+"      -d level\tdebugging level\n"
+"      -D binddn\tbind DN\n"
+"      -E\t\trequest SASL privacy (-EE to make it critical)\n"
+"      -h host\t\tLDAP server (default: localhost)\n"
+"      -I\t\trequest SASL integrity checking (-II to make it\n"
+"              \tcritical)\n"
+"      -n\t\tmake no modifications\n"
+"      -p port\t\tport on LDAP server\n"
+"      -S\t\tprompt for new password\n"
+"      -s secret\tnew password\n"
+"      -U user\t\tSASL authentication identity (username)\n"
+"      -v\t\tverbose mode\n"
+"      -w passwd\tbind password (for simple authentication)\n"
+"      -W\t\tprompt for bind password\n"
+"      -X id\t\tSASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
+"      -Y mech\t\tSASL mechanism\n"
+"      -Z\t\trequest the use of TLS (-ZZ to make it critical)\n"
+               , s );
 
-       return (pw_encode (SHA1digest, salt, sizeof (SHA1digest)));
+       exit( EXIT_FAILURE );
 }
 
-static const Hash hashes[] =
-{
-#ifdef SLAPD_CLEARTEXT
-       {"none",  4, hash_none,  0, HASHTYPE_NONE,  HASHTYPE_NONE,  0},
-#endif
-#ifdef SLAPD_CRYPT
-       {"crypt", 5, hash_crypt, 1, HASHTYPE_CRYPT, HASHTYPE_CRYPT, 2},
-#endif
-       {"md5",   3, hash_md5,   0, HASHTYPE_MD5,   HASHTYPE_SMD5,  0},
-       {"smd5",  4, hash_md5,   1, HASHTYPE_SMD5,  HASHTYPE_SMD5,  4},
-       {"sha",   3, hash_sha1,  0, HASHTYPE_SHA1,  HASHTYPE_SSHA1, 0},
-       {"ssha",  4, hash_sha1,  1, HASHTYPE_SSHA1, HASHTYPE_SSHA1, 4},
-       {NULL,    0, NULL,       0, HASHTYPE_NONE,  HASHTYPE_NONE,  0}
-};
-
-static int
-modify_dn (LDAP * ld, char *targetdn, char *pwattr, char *oldpw,
-          char *newpw, HashTypes htype, Salt * salt)
+int
+main( int argc, char *argv[] )
 {
-       int             ret = 0;
-       int             salted = salt->salt ? 1 : 0;
-       int             want_salt = salt->len && !salted;
-       char           *buf = NULL;
-       char           *hashed_pw = NULL;
-       char           *strvals[2];
-       LDAPMod         mod, *mods[2];
-
-       if (!ld || !targetdn || !newpw)
-               return (1);
-
-       /* auto-generate password */
-       if (auto_gen_pw)
-               newpw = gen_pass (auto_gen_pw);
-
-       /* handle salt */
-       if (want_salt)
-       {
-               make_salt (salt, salt->len);
-               htype = hashes[htype].type_salted;
-       }
-       else if (hashes[htype].default_salt_len)
-       {
-               /* user chose a salted hash and needs a salt */
-               if (!salted)
-               {
-                       want_salt++;
-                       salt->len = hashes[htype].default_salt_len;
-                       make_salt (salt, salt->len);
-               }
-       }
-
-       /* hash password */
-       hashed_pw = hashes[htype].func (newpw, salt->len ? salt : NULL);
-
-       /* return salt back to its original state */
-       if (want_salt)
-       {
-               free (salt->salt);
-               salt->salt = NULL;
-       }
-
-       buf = (char *)malloc (hashes[htype].namesz + 3 + strlen (hashed_pw));
-       if (htype)
-               sprintf (buf, "{%s}%s", hashes[htype].name, hashed_pw);
-       else
-               sprintf (buf, "%s", hashed_pw);
-
-       if (verbose > 0)
-       {
-               printf ("%s", targetdn);
-               if (verbose > 1)
-               {
-                       printf (":%s", buf);
-                       if (verbose > 2)
-                               printf (":%s", newpw);
-               }
-               printf ("\n");
-       }
+       int rc;
+       char    *ldaphost = NULL;
 
-       strvals[0] = buf;
-       strvals[1] = NULL;
-       mod.mod_values = strvals;
-       mod.mod_type = pwattr;
-       mod.mod_op = LDAP_MOD_REPLACE;
-       mods[0] = &mod;
-       mods[1] =NULL;
+       char    *dn = NULL;
+       char    *binddn = NULL;
 
-       if (!noupdates && (ret = ldap_modify_s (ld, targetdn, mods)) != LDAP_SUCCESS)
-               ldap_perror (ld, "ldap_modify");
+       struct berval passwd = { 0, NULL};
+       char    *newpw = NULL;
+       char    *oldpw = NULL;
 
-       free (hashed_pw);
-       free (buf);
-       return (ret);
-}
-
-static void
-usage(const char *s)
-{
-       fprintf (stderr, "Usage: %s [options] [filter]\n", s);
-       fprintf (stderr, "  -a attrib\tpassword attribute (default: " LDAP_PASSWD_ATTRIB ")\n");
-       fprintf (stderr, "  -b basedn\tbasedn to perform searches\n");
-/*      fprintf (stderr, "  -C\t\tuse entry's current hash mechanism\n"); */
-       fprintf (stderr, "  -D binddn\tbind dn\n");
-       fprintf (stderr, "  -d level\tdebugging level\n");
-       fprintf (stderr, "  -E\t\tprompt for new password\n");
-       fprintf (stderr, "  -e passwd\tnew password\n");
-       fprintf (stderr, "  -g passlen\tauto-generate passwords with length pwlen\n");
-       fprintf (stderr, "  -H hash\thash type (default: crypt)\n");
-       fprintf (stderr, "  -h host\tldap server (default: localhost)\n");
-#ifdef HAVE_KERBEROS
-       fprintf (stderr, "  -K\t\tuse Kerberos step 1\n");
-       fprintf (stderr, "  -k\t\tuse Kerberos\n");
-#endif
-       fprintf (stderr, "  -l time\ttime limit\n");
-       fprintf (stderr, "  -n\t\tmake no modifications\n");
-       fprintf (stderr, "  -P version\tprotocol version (2 or 3)\n");
-       fprintf (stderr, "  -p port\tldap port\n");
-       fprintf (stderr, "  -s scope\tsearch scope: base, one, sub (default: sub)\n");
-       fprintf (stderr, "  -t targetdn\tdn to change password\n");
-       fprintf (stderr, "  -v\t\tverbose (more v's, more verbose)\n");
-       fprintf (stderr, "  -W\t\tprompt for bind password\n");
-       fprintf (stderr, "  -w passwd\tbind password (for simple authentication)\n");
-       fprintf (stderr, "  -Y saltlen\tsalt length to use\n");
-/*      fprintf (stderr, "  -y salt\tsalt to use\n"); */
-       fprintf (stderr, "  -z size\tsize limit\n");
-       exit( EXIT_FAILURE );
-}
+       int             want_bindpw = 0;
+       int             want_newpw = 0;
+       int             want_oldpw = 0;
 
-int
-main (int argc, char *argv[])
-{
-       char           *base = NULL;
-       char           *binddn = NULL;
-       char           *bindpw = NULL;
-       char           *filtpattern = NULL;
-       char           *ldaphost = NULL;
-       char           *targetdn = NULL;
-       char           *pwattr = LDAP_PASSWD_ATTRIB;
-       char           *newpw = NULL;
-       int             authmethod = LDAP_AUTH_SIMPLE;
-       int             hashtype = HASHTYPE_CRYPT;
-       int             i, j;
+       int             noupdates = 0;
+       int             i;
        int             ldapport = 0;
        int             debug = 0;
-       int             scope = LDAP_SCOPE_SUBTREE;
-       int             sizelimit = -1;
-       int             timelimit = -1;
        int             version = -1;
-       int             want_bindpw = 0;
-       int             want_newpw = 0;
+       int             authmethod = LDAP_AUTH_SIMPLE;
+#ifdef HAVE_CYRUS_SASL
+       char            *sasl_authc_id = NULL;
+       char            *sasl_authz_id = NULL;
+       char            *sasl_mech = NULL;
+       int             sasl_integrity = 0;
+       int             sasl_privacy = 0;
+#endif
+       int             use_tls = 0;
        LDAP           *ld;
-       Salt            salt;
+       struct berval *bv = NULL;
 
-       salt.salt = NULL;
-       salt.len = 0;
+       char    *retoid;
+       struct berval *retdata;
 
        if (argc == 1)
                usage (argv[0]);
 
-       while ((i = getopt (argc, argv, "a:b:C:D:d:Ee:g:H:h:Kkl:nP:p:s:t:vWw:Y:y:z:")) != EOF)
+       while( (i = getopt( argc, argv,
+               "Aa:D:d:EIh:np:Ss:U:vWw:X:Y:Z" )) != EOF )
        {
-               switch (i)
-               {
-               case 'a':       /* password attribute */
-                       pwattr = strdup (optarg);
+               switch (i) {
+               case 'A':       /* prompt for oldr password */
+                       want_oldpw++;
                        break;
+               case 'a':       /* old password (secret) */
+                       oldpw = strdup (optarg);
 
-               case 'b':       /* base search dn */
-                       base = strdup (optarg);
-                       break;
+                       {
+                               char* p;
 
-               case 'C':
-                       want_entryhash++;
+                               for( p = optarg; *p == '\0'; p++ ) {
+                                       *p = '*';
+                               }
+                       }
                        break;
-
                case 'D':       /* bind distinguished name */
                        binddn = strdup (optarg);
                        break;
@@ -414,111 +121,44 @@ main (int argc, char *argv[])
                        debug |= atoi (optarg);
                        break;
 
-               case 'E':       /* prompt for new password */
-                       want_newpw++;
-                       break;
-
-               case 'e':       /* new password */
-                       newpw = strdup (optarg);
-                       break;
-
-               case 'g':
-                       auto_gen_pw = strtol (optarg, NULL, 10);
-                       break;
-
-               case 'H':       /* hashes */
-                       for (j = 0; hashes[j].name; j++)
-                       {
-                               if (!strncasecmp (optarg, hashes[j].name, hashes[j].namesz))
-                               {
-                                       hashtype = hashes[j].type;
-                                       break;
-                               }
-                       }
-
-                       if (!hashes[j].name)
-                       {
-                               fprintf (stderr, "hash type: %s is unknown\n", optarg);
-                               usage (argv[0]);
-                       }
-                       break;
-
                case 'h':       /* ldap host */
                        ldaphost = strdup (optarg);
                        break;
 
-               case 'K':       /* use kerberos bind, 1st part only */
-#ifdef HAVE_KERBEROS
-                       authmethod = LDAP_AUTH_KRBV41;
-#else
-                       fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]);
-                       usage (argv[0]);
-#endif
-                       break;
-
-               case 'k':       /* use kerberos bind */
-#ifdef HAVE_KERBEROS
-                       authmethod = LDAP_AUTH_KRBV4;
-#else
-                       fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]);
-                       usage (argv[0]);
-#endif
-                       break;
-
-               case 'l':       /* time limit */
-                       timelimit = strtol (optarg, NULL, 10);
-                       break;
-
                case 'n':       /* don't update entry(s) */
                        noupdates++;
                        break;
 
-               case 'P':
-                       switch( atoi( optarg ) ) {
-                       case 2:
-                               version = LDAP_VERSION2;
-                               break;
-                       case 3:
-                               version = LDAP_VERSION3;
-                               break;
-                       default:
-                               fprintf( stderr, "protocol version should be 2 or 3\n" );
-                               usage( argv[0] );
-                       }
+               case 'p':       /* ldap port */
+                       ldapport = strtol( optarg, NULL, 10 );
                        break;
 
-               case 'p':       /* ldap port */
-                       ldapport = strtol (optarg, NULL, 10);
+               case 'S':       /* prompt for user password */
+                       want_newpw++;
                        break;
 
-               case 's':       /* scope */
-                       if (strcasecmp (optarg, "base") == 0)
-                               scope = LDAP_SCOPE_BASE;
-                       else if (strcasecmp (optarg, "one") == 0)
-                               scope = LDAP_SCOPE_ONELEVEL;
-                       else if (strcasecmp (optarg, "sub") == 0)
-                               scope = LDAP_SCOPE_SUBTREE;
-                       else
+               case 's':       /* new password (secret) */
+                       newpw = strdup (optarg);
+
                        {
-                               fprintf (stderr, "scope should be base, one, or sub\n");
-                               usage (argv[0]);
-                       }
-                       break;
+                               char* p;
 
-               case 't':       /* target dn */
-                       targetdn = strdup (optarg);
+                               for( p = optarg; *p == '\0'; p++ ) {
+                                       *p = '*';
+                               }
+                       }
                        break;
 
                case 'v':       /* verbose */
                        verbose++;
                        break;
 
-               case 'W':       /* promt for bind password */
+               case 'W':       /* prompt for bind password */
                        want_bindpw++;
                        break;
 
                case 'w':       /* bind password */
-                       bindpw = strdup (optarg);
+                       passwd.bv_val = strdup (optarg);
                        {
                                char* p;
 
@@ -526,19 +166,70 @@ main (int argc, char *argv[])
                                        *p = '*';
                                }
                        }
+                       passwd.bv_len = strlen( passwd.bv_val );
                        break;
 
-               case 'Y':       /* salt length */
-                       salt.len = strtol (optarg, NULL, 10);
+               case 'I':
+#ifdef HAVE_CYRUS_SASL
+                       sasl_integrity++;
+                       authmethod = LDAP_AUTH_SASL;
+#else
+                       fprintf( stderr, "%s was not compiled with SASL "
+                               "support\n", argv[0] );
+                       return( EXIT_FAILURE );
+#endif
                        break;
-
-               case 'y':       /* user specified salt */
-                       salt.len = strlen (optarg);
-                       salt.salt = (unsigned char *)strdup (optarg);
+               case 'E':
+#ifdef HAVE_CYRUS_SASL
+                       sasl_privacy++;
+                       authmethod = LDAP_AUTH_SASL;
+#else
+                       fprintf( stderr, "%s was not compiled with SASL "
+                               "support\n", argv[0] );
+                       return( EXIT_FAILURE );
+#endif
                        break;
-
-               case 'z':       /* time limit */
-                       sizelimit = strtol (optarg, NULL, 10);
+               case 'Y':
+#ifdef HAVE_CYRUS_SASL
+                       if ( strcasecmp( optarg, "any" ) &&
+                                       strcmp( optarg, "*" ) ) {
+                               sasl_mech = strdup( optarg );
+                       }
+                       authmethod = LDAP_AUTH_SASL;
+#else
+                       fprintf( stderr, "%s was not compiled with SASL "
+                               "support\n", argv[0] );
+                       return( EXIT_FAILURE );
+#endif
+                       break;
+               case 'U':
+#ifdef HAVE_CYRUS_SASL
+                       sasl_authc_id = strdup( optarg );
+                       authmethod = LDAP_AUTH_SASL;
+#else
+                       fprintf( stderr, "%s was not compiled with SASL "
+                               "support\n", argv[0] );
+                       return( EXIT_FAILURE );
+#endif
+                       break;
+               case 'X':
+#ifdef HAVE_CYRUS_SASL
+                       sasl_authz_id = strdup( optarg );
+                       authmethod = LDAP_AUTH_SASL;
+#else
+                       fprintf( stderr, "%s was not compiled with SASL "
+                               "support\n", argv[0] );
+                       return( EXIT_FAILURE );
+#endif
+                       break;
+               case 'Z':
+#ifdef HAVE_TLS
+                       use_tls++;
+#else
+                       fprintf( stderr, "%s was not compiled with TLS "
+                               "support\n", argv[0] );
+                       return( EXIT_FAILURE );
+#endif
                        break;
 
                default:
@@ -546,32 +237,53 @@ main (int argc, char *argv[])
                }
        }
 
-       /* grab filter */
-       if (!(argc - optind < 1))
-               filtpattern = strdup (argv[optind]);
+       if( argc - optind != 1 ) {
+               usage( argv[0] );
+       } 
 
-       /* check for target(s) */
-       if (!filtpattern && !targetdn)
-               targetdn = binddn;
+       dn = strdup( argv[optind] );
 
-       /* handle bind password */
-       if (want_bindpw)
-               bindpw = strdup (getpass ("Enter LDAP password: "));
+       if( want_oldpw && oldpw == NULL ) {
+               /* prompt for old password */
+               char *ckoldpw;
+               newpw = strdup(getpassphrase("Old password: "));
+               ckoldpw = getpassphrase("Re-enter old password: ");
 
-       /* handle new password */
-       if (!newpw)
-       {
+               if( strncmp( oldpw, ckoldpw, strlen(oldpw) )) {
+                       fprintf( stderr, "passwords do not match\n" );
+                       return EXIT_FAILURE;
+               }
+       }
+
+       if( want_newpw && newpw == NULL ) {
+               /* prompt for new password */
                char *cknewpw;
-               newpw = strdup (getpass ("New password: "));
-               cknewpw = getpass ("Re-enter new password: ");
+               newpw = strdup(getpassphrase("New password: "));
+               cknewpw = getpassphrase("Re-enter new password: ");
+
+               if( strncmp( newpw, cknewpw, strlen(newpw) )) {
+                       fprintf( stderr, "passwords do not match\n" );
+                       return EXIT_FAILURE;
+               }
+       }
 
-               if (strncmp (newpw, cknewpw, strlen (newpw)))
-               {
-                       fprintf (stderr, "passwords do not match\n");
-                       return ( EXIT_FAILURE );
+       if( binddn == NULL && dn != NULL ) {
+               binddn = dn;
+               dn = NULL;
+
+               if( passwd.bv_val == NULL ) {
+                       passwd.bv_val = oldpw;
+                       passwd.bv_len = oldpw == NULL ? 0 : strlen( oldpw );
                }
        }
 
+       if (want_bindpw && passwd.bv_val == NULL ) {
+               /* handle bind password */
+               fprintf( stderr, "Bind DN: %s\n", binddn );
+               passwd.bv_val = strdup( getpassphrase("Enter bind password: "));
+               passwd.bv_len = strlen( passwd.bv_val );
+       }
+
        if ( debug ) {
                if( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug ) != LBER_OPT_SUCCESS ) {
                        fprintf( stderr, "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug );
@@ -584,107 +296,165 @@ main (int argc, char *argv[])
 #ifdef SIGPIPE
        (void) SIGNAL( SIGPIPE, SIG_IGN );
 #endif
-       /* seed random number generator */
-
-#ifdef HAVE_GETTIMEOFDAY
-       /* this is of questionable value
-        * gettimeofday may not provide much usec
-        */
-       {
-               struct timeval tv;
-               gettimeofday (&tv, NULL);
-               srand(tv.tv_sec * (tv.tv_usec + 1));
-       }
-#else
-       /* The traditional seed */
-       srand((unsigned)time( NULL ));
-#endif
 
        /* connect to server */
-       if ((ld = ldap_init (ldaphost, ldapport)) == NULL)
-       {
-               perror ("ldap_init");
-               return ( EXIT_FAILURE );
+       if ((ld = ldap_init( ldaphost, ldapport )) == NULL) {
+               perror("ldap_init");
+               return EXIT_FAILURE;
        }
 
-       /* set options */
-       if (timelimit != -1 &&
-               ldap_set_option( ld, LDAP_OPT_TIMELIMIT, (void *) &timelimit ) != LDAP_OPT_SUCCESS )
-       {
-               fprintf( stderr, "Could not set LDAP_OPT_TIMELIMIT %d\n", timelimit );
-       }
-       if (sizelimit != -1 &&
-               ldap_set_option( ld, LDAP_OPT_SIZELIMIT, (void *) &sizelimit ) != LDAP_OPT_SUCCESS )
-       {
-               fprintf( stderr, "Could not set LDAP_OPT_SIZELIMIT %d\n", sizelimit );
-       }
-
-       /* this seems prudent */
-       {
-               int deref = LDAP_DEREF_NEVER;
-               ldap_set_option( ld, LDAP_OPT_DEREF, &deref);
-       }
        /* don't chase referrals */
        ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF );
 
-       if (version != -1 &&
-               ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ) != LDAP_OPT_SUCCESS )
-       {
+       /* LDAPv3 only */
+       version = 3;
+       rc = ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
+
+       if(rc != LDAP_OPT_SUCCESS ) {
                fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version );
        }
 
-       /* authenticate to server */
-       if (ldap_bind_s (ld, binddn, bindpw, authmethod) != LDAP_SUCCESS)
-       {
-               ldap_perror (ld, "ldap_bind");
-               return ( EXIT_FAILURE );
+       if ( use_tls && ldap_start_tls( ld, NULL, NULL ) != LDAP_SUCCESS ) {
+               if ( use_tls > 1 ) {
+                       ldap_perror( ld, "ldap_start_tls" );
+                       return( EXIT_FAILURE );
+               }
        }
 
-       if (targetdn)
-       {
-               if (want_entryhash)
-               {
-                       /* insert code here =) */
+       if ( authmethod == LDAP_AUTH_SASL ) {
+#ifdef HAVE_CYRUS_SASL
+               int     minssf = 0, maxssf = 0;
+
+               if ( sasl_integrity > 0 )
+                       maxssf = 1;
+               if ( sasl_integrity > 1 )
+                       minssf = 1;
+               if ( sasl_privacy > 0 )
+                       maxssf = 100000; /* Something big value */
+               if ( sasl_privacy > 1 )
+                       minssf = 56;
+               
+               if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MINSSF,
+                               (void *)&minssf ) != LDAP_OPT_SUCCESS ) {
+                       fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MINSSF"
+                               "%d\n", minssf);
+                       return( EXIT_FAILURE );
+               }
+               if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MAXSSF,
+                               (void *)&maxssf ) != LDAP_OPT_SUCCESS ) {
+                       fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MAXSSF"
+                               "%d\n", maxssf);
+                       return( EXIT_FAILURE );
+               }
+               
+               rc = ldap_negotiated_sasl_bind_s( ld, binddn, sasl_authc_id,
+                               sasl_authz_id, sasl_mech,
+                               passwd.bv_len ? &passwd : NULL,
+                               NULL, NULL );
+
+               if( rc != LDAP_SUCCESS ) {
+                       ldap_perror( ld, "ldap_negotiated_sasl_bind_s" );
+                       return( EXIT_FAILURE );
+               }
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+       }
+       else {
+               if ( ldap_bind_s( ld, binddn, passwd.bv_val, authmethod )
+                               != LDAP_SUCCESS ) {
+                       ldap_perror( ld, "ldap_bind" );
+                       return( EXIT_FAILURE );
                }
-               else
-                       modify_dn (ld, targetdn, pwattr, NULL, newpw, hashtype, &salt);
        }
 
-       if (filtpattern)
-       {
-               char            filter[BUFSIZ];
-               LDAPMessage     *result = NULL, *e;
-               char            *attrs[2];
-               attrs[0] = pwattr;
-               attrs[1] = NULL;
-
-               /* search */
-               sprintf (filter, "%s", filtpattern);
-               i = ldap_search_s (ld, base, scope, filter, attrs, 0, &result);
-               if (i != LDAP_SUCCESS &&
-                   i != LDAP_TIMELIMIT_EXCEEDED &&
-                   i != LDAP_SIZELIMIT_EXCEEDED)
-               {
-                       ldap_perror (ld, "ldap_search");
-                       return ( EXIT_FAILURE );
+       if( dn != NULL || oldpw != NULL || newpw != NULL ) {
+               /* build change password control */
+               BerElement *ber = ber_alloc_t( LBER_USE_DER );
+
+               if( ber == NULL ) {
+                       perror( "ber_alloc_t" );
+                       ldap_unbind( ld );
+                       return EXIT_FAILURE;
                }
 
-               for (e = ldap_first_entry (ld, result); e; e = ldap_next_entry (ld, e))
-               {
-                       char *dn = ldap_get_dn (ld, e);
-                       if (dn)
-                       {
-                               struct berval **pw_vals = ldap_get_values_len (ld, e, pwattr);
-                               modify_dn (ld, dn, pwattr, pw_vals ? pw_vals[0]->bv_val : NULL, newpw, hashtype, &salt);
-                               if (pw_vals)
-                                       ldap_value_free_len (pw_vals);
-                               free (dn);
-                       }
+               ber_printf( ber, "{" /*}*/ );
+
+               if( dn != NULL ) {
+                       ber_printf( ber, "ts",
+                               LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID, dn );
+                       free(dn);
+               }
+
+               if( oldpw != NULL ) {
+                       ber_printf( ber, "ts",
+                               LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, oldpw );
+                       free(oldpw);
+               }
+
+               if( newpw != NULL ) {
+                       ber_printf( ber, "ts",
+                               LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, newpw );
+                       free(newpw);
+               }
+
+               ber_printf( ber, /*{*/ "}" );
+
+               rc = ber_flatten( ber, &bv );
+
+               if( rc < 0 ) {
+                       perror( "ber_flatten" );
+                       ldap_unbind( ld );
+                       return EXIT_FAILURE;
                }
+
+               ber_free( ber, 1 );
+       }
+
+       rc = ldap_extended_operation_s( ld,
+               LDAP_EXOP_X_MODIFY_PASSWD, bv, 
+               NULL, NULL,
+               &retoid, &retdata );
+
+       ber_bvfree( bv );
+
+       if( retdata != NULL ) {
+               ber_tag_t tag;
+               char *s;
+               BerElement *ber = ber_init( retdata );
+
+               if( ber == NULL ) {
+                       perror( "ber_init" );
+                       ldap_unbind( ld );
+                       return EXIT_FAILURE;
+               }
+
+               /* we should check the tag */
+               tag = ber_scanf( ber, "{a}", &s);
+
+               if( tag == LBER_ERROR ) {
+                       perror( "ber_scanf" );
+               } else {
+                       printf("New password: %s\n", s);
+                       free( s );
+               }
+
+               ber_free( ber, 1 );
        }
 
+       if ( rc != LDAP_SUCCESS ) {
+               ldap_perror( ld, "ldap_extended_operation" );
+               ldap_unbind( ld );
+               return EXIT_FAILURE;
+       }
+
+       ldap_memfree( retoid );
+       ber_bvfree( retdata );
+
        /* disconnect from server */
        ldap_unbind (ld);
 
-       return ( EXIT_SUCCESS );
+       return EXIT_SUCCESS;
 }
diff --git a/clients/tools/ldappasswd.dsp b/clients/tools/ldappasswd.dsp
new file mode 100644 (file)
index 0000000..df406df
--- /dev/null
@@ -0,0 +1,145 @@
+# Microsoft Developer Studio Project File - Name="ldappasswd" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=ldappasswd - Win32 Single Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "ldappasswd.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "ldappasswd.mak" CFG="ldappasswd - Win32 Single Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "ldappasswd - Win32 Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ldappasswd - Win32 Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ldappasswd - Win32 Single Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ldappasswd - Win32 Single Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "ldappasswd - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ldappass"
+# PROP BASE Intermediate_Dir "ldappass"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\ldappasswd"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 sasl.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\Release"
+
+!ELSEIF  "$(CFG)" == "ldappasswd - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "ldappas0"
+# PROP BASE Intermediate_Dir "ldappas0"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\ldappasswd"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Debug"
+
+!ELSEIF  "$(CFG)" == "ldappasswd - Win32 Single Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Single Debug"
+# PROP BASE Intermediate_Dir "Single Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\ldappasswd"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\SDebug"
+
+!ELSEIF  "$(CFG)" == "ldappasswd - Win32 Single Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Single Release"
+# PROP BASE Intermediate_Dir "Single Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\ldappasswd"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 sasl.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\SRelease"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "ldappasswd - Win32 Release"
+# Name "ldappasswd - Win32 Debug"
+# Name "ldappasswd - Win32 Single Debug"
+# Name "ldappasswd - Win32 Single Release"
+# Begin Source File
+
+SOURCE=.\ldappasswd.c
+# End Source File
+# End Target
+# End Project
index 1eba56399a33e0d4f1394a109a765ac6dae10059..0bae49a3e1530c3f27b31e876f286ab0582a2781 100644 (file)
@@ -1,8 +1,9 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
+
 #include "portable.h"
 
 #include <stdio.h>
 #include <ac/signal.h>
 #include <ac/string.h>
 #include <ac/unistd.h>
+#include <ac/errno.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
 
 #include <ldap.h>
 
 #include "ldif.h"
 #include "ldap_defaults.h"
 
+#undef DEPSEP
 #define DEFSEP         "="
 
 static void
@@ -33,38 +47,48 @@ usage( const char *s )
 "\t\t+           -- all operational attributes\n"
 "\t\tempty list -- all non-operational attributes\n"
 "options:\n"
-"      -n\t\tshow what would be done but don't actually search\n"
-"      -v\t\trun in verbose mode (diagnostics to standard output)\n"
-"      -t\t\twrite binary values to files in TMPDIR\n"
-"      -tt\t\twrite all values to files in TMPDIR\n"
-"      -T path\twrite files to directory specified by path (default: \"/tmp\")\n"
-"      -V prefix\tURL prefix for files (default: \"file://tmp/\"\n"
-"      -u\t\tinclude User Friendly entry names in the output\n"
+"      -a deref\tone of `never', `always', `search', or `find' (alias\n"
+"              \tdereferencing)\n"
 "      -A\t\tretrieve attribute names only (no values)\n"
+"      -b basedn\tbase dn for search\n"
 "      -B\t\tdo not suppress printing of binary values\n"
-"      -F sep\tprint `sep' instead of `=' between attribute names and values\n"
+"      -d level\tset LDAP debugging level to `level'\n"
+"      -D binddn\tbind DN\n"
+"      -E\t\trequest SASL privacy (-EE to make it critical)\n"
+"      -f file\t\tperform sequence of searches listed in `file'\n"
+"      -F sep\t\tprint `sep' instead of `=' between attribute names and\n"
+"              \tvalues\n"
+"      -h host\t\tLDAP server\n"
+"      -I\t\trequest SASL integrity checking (-II to make it\n"
+"              \tcritical)\n"
+"      -k\t\tuse Kerberos authentication\n"
+"      -K\t\tlike -k, but do only step 1 of the Kerberos bind\n"
+"      -l limit\ttime limit (in seconds) for search\n"
 "      -L\t\tprint entries in LDIF format (implies -B)\n"
 "      -LL\t\tprint entries in LDIF format without comments\n"
-"      -LLL\t\tprint entries in LDIF format without comments and version\n"
+"      -LLL\t\tprint entries in LDIF format without comments and\n"
+"              \tversion\n"
 "      -M\t\tenable Manage DSA IT control (-MM to make critical)\n"
+"      -n\t\tshow what would be done but don't actually search\n"
+"      -p port\t\tport on LDAP server\n"
+"      -P version\tprocotol version (2 or 3)\n"
 "      -R\t\tdo not automatically follow referrals\n"
-"      -S attr\tsort the results by attribute `attr'\n"
-"      -d level\tset LDAP debugging level to `level'\n"
-"      -f file\tperform sequence of searches listed in `file'\n"
-"      -b basedn\tbase dn for search\n"
 "      -s scope\tone of base, one, or sub (search scope)\n"
-"      -a deref\tone of never, always, search, or find (alias dereferencing)\n"
-"      -l limit\ttime limit (in seconds) for search\n"
-"      -z limit\tsize limit (in entries) for search\n"
-"      -D binddn\tbind dn\n"
+"      -S attr\t\tsort the results by attribute `attr'\n"
+"      -t\t\twrite binary values to files in TMPDIR\n"
+"      -tt\t\twrite all values to files in TMPDIR\n"
+"      -T path\t\twrite files to directory specified by path (default:\n"
+"              \t\"/tmp\")\n"
+"      -u\t\tinclude User Friendly entry names in the output\n"
+"      -U user\t\tSASL authentication identity (username)\n"
+"      -v\t\trun in verbose mode (diagnostics to standard output)\n"
+"      -V prefix\tURL prefix for files (default: \"file://tmp/\")\n"
 "      -w passwd\tbind passwd (for simple authentication)\n"
 "      -W\t\tprompt for bind passwd\n"
-#ifdef HAVE_KERBEROS
-"      -k\t\tuse Kerberos instead of Simple Password authentication\n"
-#endif
-"      -h host\tldap server\n"
-"      -p port\tport on ldap server\n"
-"      -P version\tprocotol version (2 or 3)\n"
+"      -X id\t\tSASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
+"      -Y mech\t\tSASL mechanism\n"
+"      -z limit\tsize limit (in entries) for search\n"
+"      -Z\t\trequest the use of TLS (-ZZ to make it critical)\n"
 ,              s );
 
        exit( EXIT_FAILURE );
@@ -97,10 +121,18 @@ static char *tmpdir = NULL;
 static char *urlpre = NULL;
 
 static char    *binddn = NULL;
-static char    *passwd = NULL;
+static struct berval passwd = { 0, NULL };
 static char    *base = NULL;
 static char    *ldaphost = NULL;
 static int     ldapport = 0;
+#ifdef HAVE_CYRUS_SASL
+static char    *sasl_authc_id = NULL;
+static char    *sasl_authz_id = NULL;
+static char    *sasl_mech = NULL;
+static int     sasl_integrity = 0;
+static int     sasl_privacy = 0;
+#endif
+static int     use_tls = 0;
 static char    *sep = DEFSEP;
 static char    *sortattr = NULL;
 static int     skipsortattr = 0;
@@ -110,7 +142,7 @@ int
 main( int argc, char **argv )
 {
        char            *infile, *filtpattern, **attrs, line[ BUFSIZ ];
-       FILE            *fp;
+       FILE            *fp = NULL;
        int                     rc, i, first, scope, deref, attrsonly, manageDSAit;
        int                     referrals, timelimit, sizelimit, debug;
        int             authmethod, version, want_bindpw;
@@ -120,13 +152,16 @@ main( int argc, char **argv )
        debug = verbose = binary = not = vals2tmp =
                attrsonly = manageDSAit = ldif = want_bindpw = 0;
 
-       deref = referrals = sizelimit = timelimit = version = -1;
+       deref = sizelimit = timelimit = version = -1;
+
+       /* default should be off */
+       referrals = 1;
 
        scope = LDAP_SCOPE_SUBTREE;
        authmethod = LDAP_AUTH_SIMPLE;
 
        while (( i = getopt( argc, argv,
-               "WKknuvtMRABLD:s:f:h:b:d:P:p:F:a:w:l:z:S:T:V:")) != EOF )
+               "Aa:Bb:D:d:EF:f:h:IKkLl:MnP:p:RS:s:T:tU:uV:vWw:X:Y:Zz:")) != EOF )
        {
        switch( i ) {
        case 'n':       /* do Not do any searches */
@@ -139,19 +174,22 @@ main( int argc, char **argv )
                debug |= atoi( optarg );
                break;
        case 'k':       /* use kerberos bind */
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
                authmethod = LDAP_AUTH_KRBV4;
 #else
-               fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]);
+               fprintf( stderr, "%s was not compiled with Kerberos support\n", argv[0] );
+               return( EXIT_FAILURE );
 #endif
                break;
        case 'K':       /* use kerberos bind, 1st part only */
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
                authmethod = LDAP_AUTH_KRBV41;
 #else
-               fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]);
+               fprintf( stderr, "%s was not compiled with Kerberos support\n", argv[0] );
+               return( EXIT_FAILURE );
 #endif
                break;
+               break;
        case 'u':       /* include UFN */
                ++includeufn;
                break;
@@ -163,7 +201,7 @@ main( int argc, char **argv )
                manageDSAit++;
                break;
        case 'R':       /* don't automatically chase referrals */
-               referrals = (int) LDAP_OPT_OFF;
+               referrals = 0;
                break;
        case 'A':       /* retrieve attribute names only -- no values */
                ++attrsonly;
@@ -229,7 +267,7 @@ main( int argc, char **argv )
                ldapport = atoi( optarg );
                break;
        case 'w':       /* bind password */
-               passwd = strdup( optarg );
+               passwd.bv_val = strdup( optarg );
                {
                        char* p;
 
@@ -237,6 +275,7 @@ main( int argc, char **argv )
                                *p = '*';
                        }
                }
+               passwd.bv_len = strlen( passwd.bv_val );
                break;
        case 'l':       /* time limit */
                timelimit = atoi( optarg );
@@ -264,11 +303,109 @@ main( int argc, char **argv )
                        usage( argv[0] );
                }
                break;
+       case 'I':
+#ifdef HAVE_CYRUS_SASL
+               sasl_integrity++;
+               authmethod = LDAP_AUTH_SASL;
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'E':
+#ifdef HAVE_CYRUS_SASL
+               sasl_privacy++;
+               authmethod = LDAP_AUTH_SASL;
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'Y':
+#ifdef HAVE_CYRUS_SASL
+               if ( strcasecmp( optarg, "any" ) && strcmp( optarg, "*" ) ) {
+                       sasl_mech = strdup( optarg );
+               }
+               authmethod = LDAP_AUTH_SASL;
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'U':
+#ifdef HAVE_CYRUS_SASL
+               sasl_authc_id = strdup( optarg );
+               authmethod = LDAP_AUTH_SASL;
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'X':
+#ifdef HAVE_CYRUS_SASL
+               sasl_authz_id = strdup( optarg );
+               authmethod = LDAP_AUTH_SASL;
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'Z':
+#ifdef HAVE_TLS
+               use_tls++;
+#else
+               fprintf( stderr, "%s was not compiled with TLS support\n",
+                       argv[0] );
+               return( EXIT_FAILURE );
+#endif
+               break;
        default:
                usage( argv[0] );
        }
        }
 
+#ifdef LDAP_LDIF
+       /* no alternative format */
+       if( ldif < 1 ) ldif = 1;
+#endif
+
+       if ( ( authmethod == LDAP_AUTH_KRBV4 ) || ( authmethod ==
+                       LDAP_AUTH_KRBV41 ) ) {
+               if( version > LDAP_VERSION2 ) {
+                       fprintf( stderr, "Kerberos requires LDAPv2\n" );
+                       return( EXIT_FAILURE );
+               }
+               version = LDAP_VERSION2;
+       }
+       else if ( authmethod == LDAP_AUTH_SASL ) {
+               if( version != -1 && version != LDAP_VERSION3 ) {
+                       fprintf( stderr, "SASL requires LDAPv3\n" );
+                       return( EXIT_FAILURE );
+               }
+               version = LDAP_VERSION3;
+       }
+
+       if( manageDSAit ) {
+               if( version != -1 && version != LDAP_VERSION3 ) {
+                       fprintf(stderr, "manage DSA control requires LDAPv3\n");
+                       return EXIT_FAILURE;
+               }
+               version = LDAP_VERSION3;
+       }
+
+       if( use_tls ) {
+               if( version != -1 && version != LDAP_VERSION3 ) {
+                       fprintf(stderr, "Start TLS requires LDAPv3\n");
+                       return EXIT_FAILURE;
+               }
+               version = LDAP_VERSION3;
+       }
+
        if ( argc - optind < 1 ) {
                usage( argv[ 0 ] );
        }
@@ -312,7 +449,7 @@ main( int argc, char **argv )
        }
 
        if( urlpre == NULL ) {
-               urlpre = malloc( sizeof("file:///") + strlen(tmpdir) );
+               urlpre = malloc( sizeof("file:////") + strlen(tmpdir) );
 
                if( urlpre == NULL ) {
                        perror( "malloc" );
@@ -380,13 +517,65 @@ main( int argc, char **argv )
                fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version );
        }
 
-       if (want_bindpw) {
-               passwd = getpass("Enter LDAP Password: ");
+       if ( use_tls && ldap_start_tls( ld, NULL, NULL ) != LDAP_SUCCESS ) {
+               if ( use_tls > 1 ) {
+                       ldap_perror( ld, "ldap_start_tls" );
+                       return( EXIT_FAILURE );
+               }
        }
 
-       if ( ldap_bind_s( ld, binddn, passwd, authmethod ) != LDAP_SUCCESS ) {
-               ldap_perror( ld, "ldap_bind" );
+       if (want_bindpw) {
+               passwd.bv_val = getpassphrase("Enter LDAP Password: ");
+               passwd.bv_len = strlen( passwd.bv_val );
+       }
+
+       if ( authmethod == LDAP_AUTH_SASL ) {
+#ifdef HAVE_CYRUS_SASL
+               int     minssf = 0, maxssf = 0;
+
+               if ( sasl_integrity > 0 )
+                       maxssf = 1;
+               if ( sasl_integrity > 1 )
+                       minssf = 1;
+               if ( sasl_privacy > 0 )
+                       maxssf = 100000; /* Something big value */
+               if ( sasl_privacy > 1 )
+                       minssf = 56;
+               
+               if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MINSSF,
+                               (void *)&minssf ) != LDAP_OPT_SUCCESS ) {
+                       fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MINSSF"
+                               "%d\n", minssf);
+                       return( EXIT_FAILURE );
+               }
+               if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MAXSSF,
+                               (void *)&maxssf ) != LDAP_OPT_SUCCESS ) {
+                       fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MAXSSF"
+                               "%d\n", maxssf);
+                       return( EXIT_FAILURE );
+               }
+               
+               rc = ldap_negotiated_sasl_bind_s( ld, binddn, sasl_authc_id,
+                               sasl_authz_id, sasl_mech,
+                               passwd.bv_len ? &passwd : NULL,
+                               NULL, NULL );
+
+               if( rc != LDAP_SUCCESS ) {
+                       ldap_perror( ld, "ldap_negotiated_sasl_bind_s" );
+                       return( EXIT_FAILURE );
+               }
+#else
+               fprintf( stderr, "%s was not compiled with SASL support\n",
+                       argv[0] );
                return( EXIT_FAILURE );
+#endif
+       }
+       else {
+               if ( ldap_bind_s( ld, binddn, passwd.bv_val, authmethod )
+                               != LDAP_SUCCESS ) {
+                       ldap_perror( ld, "ldap_bind" );
+                       return( EXIT_FAILURE );
+               }
        }
 
        if ( manageDSAit ) {
@@ -622,6 +811,7 @@ print_entry(
                                if ( vals2tmp > 1 || ( vals2tmp
                                        && ldif_is_not_printable( bvals[i]->bv_val, bvals[i]->bv_len ) ))
                                {
+                                       int tmpfd;
                                        /* write value to file */
                                        sprintf( tmpfname, "%s" LDAP_DIRSEP "ldapsearch-%s-XXXXXX",
                                                tmpdir, a );
@@ -632,7 +822,12 @@ print_entry(
                                                continue;
                                        }
 
-                                       if (( tmpfp = fopen( tmpfname, "w")) == NULL ) {
+                                       if (( tmpfd = open( tmpfname, O_WRONLY|O_CREAT|O_EXCL, 0600 )) == -1 ) {
+                                               perror( tmpfname );
+                                               continue;
+                                       }
+
+                                       if (( tmpfp = fdopen( tmpfd, "w")) == NULL ) {
                                                perror( tmpfname );
                                                continue;
                                        }
diff --git a/clients/tools/ldapsearch.dsp b/clients/tools/ldapsearch.dsp
new file mode 100644 (file)
index 0000000..d3918c8
--- /dev/null
@@ -0,0 +1,149 @@
+# Microsoft Developer Studio Project File - Name="ldapsearch" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=ldapsearch - Win32 Single Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "ldapsearch.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "ldapsearch.mak" CFG="ldapsearch - Win32 Single Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "ldapsearch - Win32 Single Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ldapsearch - Win32 Single Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ldapsearch - Win32 Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ldapsearch - Win32 Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "ldapsearch - Win32 Single Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "ldapsear"
+# PROP BASE Intermediate_Dir "ldapsear"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\ldapsearch"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 oldap32.lib olber32.lib oldif32.lib olutil32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\libraries\Debug"
+# ADD LINK32 libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\SDebug"
+
+!ELSEIF  "$(CFG)" == "ldapsearch - Win32 Single Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ldapsea0"
+# PROP BASE Intermediate_Dir "ldapsea0"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\ldapsearch"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 oldap32.lib olber32.lib oldif32.lib olutil32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\libraries\Release"
+# ADD LINK32 sasl.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\SRelease"
+
+!ELSEIF  "$(CFG)" == "ldapsearch - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ldapsea1"
+# PROP BASE Intermediate_Dir "ldapsea1"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\ldapsearch"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ws2_32.lib /nologo /subsystem:console /machine:I386 /out:"Release/ldapsearch.exe" /libpath:"..\..\libraries\SRelease"
+# ADD LINK32 sasl.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\Release"
+
+!ELSEIF  "$(CFG)" == "ldapsearch - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ldapsea2"
+# PROP BASE Intermediate_Dir "ldapsea2"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\ldapsearch"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MTd /W2 /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ws2_32.lib /nologo /subsystem:console /machine:I386 /out:"Release/ldapsearch.exe" /libpath:"..\..\libraries\SRelease"
+# ADD LINK32 libsasl.lib ws2_32.lib /nologo /subsystem:console /incremental:yes /debug /machine:I386 /libpath:"..\..\Debug"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "ldapsearch - Win32 Single Debug"
+# Name "ldapsearch - Win32 Single Release"
+# Name "ldapsearch - Win32 Release"
+# Name "ldapsearch - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\ldapsearch.c
+# End Source File
+# End Target
+# End Project
index 54c16e29e13ed6144c913d3288bd85c401fdd425..7c22affb6b2494f098383bc037b01a0371f158a0 100644 (file)
@@ -11,7 +11,10 @@ PROGRAMS= ud
 LDAP_INCDIR= ../../include       
 LDAP_LIBDIR= ../../libraries
 
-XLIBS =  -lldif -lldap -llber -llutil
+NT_DYN_DEFS = -DLIBLBER_DECL=dllimport -DLIBLDAP_DECL=dllimport
+CPPFLAGS = $(@PLAT@_@LIB_LINKAGE@_DEFS)
+
+XLIBS =  -llutil -lldif -lldap -llber
 XXLIBS = $(TERMCAP_LIBS) $(SECURITY_LIBS) $(LUTIL_LIBS)
 
 ud : version.o
@@ -22,6 +25,12 @@ version.c: ${OBJS} $(LDAP_LIBDEPEND)
        $(MKVERSION) -s -c -n Version UserDirectory > $@
 
 install-local: FORCE
-       -$(MKDIR) $(bindir)
-       -mv -f $(bindir)/ud $(bindir)/ud-
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 ud $(bindir)
+       -$(MKDIR) $(DESTDIR)$(bindir)
+       -mv -f $(DESTDIR)$(bindir)/ud $(DESTDIR)$(bindir)/ud-
+       @(                                                              \
+           for prg in $(PROGRAMS); do                                  \
+               $(LTINSTALL) $(INSTALLFLAGS) -s -m 755 $$prg$(EXEEXT)   \
+                   $(DESTDIR)$(bindir);                                \
+           done                                                        \
+       )
+
index b757d78169c54226701ab71dcde79ebde0038022..5ae44ef154888c995733d15c1091a6262e4ef939 100644 (file)
@@ -1,4 +1,8 @@
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 /*
  * Copyright (c) 1991, 1992 Regents of the University of Michigan.
  * All rights reserved.
@@ -33,7 +37,7 @@
 #include "ldap_defaults.h"
 #include "ud.h"
 
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
 static char tktpath[20];       /* ticket file path */
 static int kinit();
 static int valid_tgt();
@@ -46,7 +50,7 @@ int
 auth( char *who, int implicit )
 {
        int rc;                 /* return code from ldap_bind() */
-       char *passwd = NULL;    /* returned by getpass() */
+       char *passwd = NULL;    /* returned by getpassphrase() */
        char **rdns;            /* for fiddling with the DN */
        int authmethod;
        int name_provided;      /* was a name passed in? */
@@ -56,7 +60,7 @@ auth( char *who, int implicit )
        char *user;
 #endif
        char uidname[20];
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
        char **krbnames;        /* for kerberos names */
        int kinited, ikrb;
        char buf[5];
@@ -144,7 +148,7 @@ auth( char *who, int implicit )
        rdns = ldap_explode_dn(Entry.DN, TRUE);
        printf("  Authenticating to the directory as \"%s\"...\n", *rdns );
 
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
        /*
         * First, if the user has a choice of auth methods, ask which
         * one they want to use.  if they want kerberos, ask which
@@ -237,13 +241,13 @@ auth( char *who, int implicit )
                authmethod = LDAP_AUTH_SIMPLE;
                sprintf(prompt, "  Enter your LDAP password: ");
                do {
-                       passwd = getpass(prompt);
+                       passwd = getpassphrase(prompt);
                } while (passwd != NULL && *passwd == '\0');
                if (passwd == NULL) {
                        (void) ldap_value_free(rdns);
                        return(0);
                }
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
        }
        (void) ldap_value_free(krbnames);
 #endif
@@ -255,13 +259,13 @@ auth( char *who, int implicit )
                if (ld_errno == LDAP_NO_SUCH_ATTRIBUTE)
                        fprintf(stderr, "  Entry has no password\n");
                else if (ld_errno == LDAP_INVALID_CREDENTIALS)
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
                        if ( authmethod == LDAP_AUTH_KRBV4 ) {
                                fprintf(stderr, "  The Kerberos credentials are invalid.\n");
                        } else {
 #endif
                                fprintf(stderr, "  The password you provided is incorrect.\n");
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
                        }
 #endif
                else
@@ -290,7 +294,7 @@ auth( char *who, int implicit )
        return(0);
 }
 
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
 
 #define FIVEMINS       ( 5 * 60 )
 #define TGT            "krbtgt"
@@ -334,6 +338,8 @@ valid_tgt( char **names )
 
 static char *kauth_name;
 
+#ifndef HAVE_KTH_KERBEROS
+
 /*ARGSUSED*/
 int
 krbgetpass( char *user, char *inst, char *realm, char *pw, C_Block key )
@@ -346,7 +352,7 @@ krbgetpass( char *user, char *inst, char *realm, char *pw, C_Block key )
        sprintf(prompt, "  Enter Kerberos password for %s: ", kauth_name );
 #endif
        do {
-               passwd = getpass(prompt);
+               passwd = getpassphrase(prompt);
        } while (passwd != NULL && *passwd == '\0');
        if (passwd == NULL) {
                return(-1);
@@ -365,6 +371,7 @@ krbgetpass( char *user, char *inst, char *realm, char *pw, C_Block key )
 
        return( 0 );
 }
+#endif /* HAVE_KTH_KERBEROS */
 
 static int
 kinit( char *kname )
@@ -382,14 +389,18 @@ kinit( char *kname )
        }
 
 #ifdef HAVE_AFS_KERBEROS
-       /*
-        * realm must be uppercase for krb_ routines
-        */
+       /* realm must be uppercase for AFS krb_ routines */
        ldap_pvt_str2upper( realm );
 #endif /* HAVE_AFS_KERBEROS */
 
+#ifdef HAVE_KTH_KERBEROS
+       /* Kth kerberos knows how to do both string to keys */
+       rc = krb_get_pw_in_tkt( name, inst, realm, TGT, realm,
+               DEFAULT_TKT_LIFE, 0 );
+#else
        rc = krb_get_in_tkt( name, inst, realm, TGT, realm,
            DEFAULT_TKT_LIFE, krbgetpass, NULL, NULL );
+#endif
 
        if ( rc != KSUCCESS ) {
                switch ( rc ) {
index 67f2ed9a865c8e093c6c7852eaccf780bfe12f0b..de640dc3803d6be6c4be9bc84f57b26c9af02ff9 100644 (file)
@@ -1,4 +1,8 @@
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 /*
  * Copyright (c) 1994  Regents of the University of Michigan.
  * All rights reserved.
@@ -14,6 +18,7 @@
 #include "portable.h"
 
 #include <stdio.h>
+#include <sys/stat.h>
 
 #include <ac/stdlib.h>
 
 #include <ac/wait.h>
 #include <ac/unistd.h>
 
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
 #ifdef HAVE_SYS_RESOURCE_H
 #include <sys/resource.h>
 #endif
 #include <process.h>
 #endif
 
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
 #include <lber.h>
 #include <ldap.h>
 
@@ -43,7 +58,7 @@ static int  print_attrs_and_values( FILE *fp, struct attribute *attrs, short fla
 static int  ovalues( char *attr );
 static void write_entry( void );
 
-static char *entry_temp_file;
+static char entry_temp_file[L_tmpnam];
 
 
 void
@@ -116,7 +131,7 @@ load_editor( void )
 {
        FILE *fp;
        char *cp, *editor = UD_DEFAULT_EDITOR;
-       static char template[MED_BUF_SIZE];
+       int tmpfd;
 #ifndef HAVE_SPAWNLP
        int pid;
        int status;
@@ -129,13 +144,16 @@ load_editor( void )
 #endif
 
        /* write the entry into a temp file */
-       (void) strcpy(template, "/tmp/udEdit.XXXXXX");
-       if ((entry_temp_file = mktemp(template)) == NULL) {
-               perror("mktemp");
-               return(-1);
+       if (tmpnam(entry_temp_file) == NULL) {
+               perror("tmpnam");
+               return -1;
        }
-       if ((fp = fopen(entry_temp_file, "w")) == NULL) {
-               perror("fopen");
+       if ((tmpfd = open(entry_temp_file, O_WRONLY|O_CREAT|O_EXCL, 0600)) == -1) {
+               perror(entry_temp_file);
+               return -1;
+       }
+       if ((fp = fdopen(tmpfd, "w")) == NULL) {
+               perror("fdopen");
                return(-1);
        }
        fprintf(fp, "## Directory entry of %s\n", Entry.name);
index 5e8b8656030c0dd473748de940b2e03ec312b768..f247fcc5bfc002dd7e6764e73b01328f34bf6bc3 100644 (file)
@@ -1,4 +1,8 @@
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 /*
  * Copyright (c) 1991, 1992, 1993 
  * Regents of the University of Michigan.  All rights reserved.
@@ -32,8 +36,8 @@ static int num_picked = 0;    /* used when user picks entry at More prompt */
 int
 vrfy( char *dn )
 {
-       LDAPMessage *results;
-       static char *attrs[2] = { "objectClass", NULL };
+       LDAPMessage *results = NULL;
+       static char *attrs[2] = { "1.1", NULL };
        int ld_errno = 0;
 
 #ifdef DEBUG
@@ -41,7 +45,7 @@ vrfy( char *dn )
                printf("->vrfy(%s)\n", dn);
 #endif
        /* verify that this DN exists in the directory */
-       (void) ldap_search_s(ld, dn, LDAP_SCOPE_BASE, "objectClass=*", attrs, TRUE, &results);
+       (void) ldap_search_s(ld, dn, LDAP_SCOPE_BASE, NULL, attrs, TRUE, &results);
        (void) ldap_msgfree(results);
 
        ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ld_errno);
@@ -65,7 +69,7 @@ disambiguate( LDAPMessage *result, int matches, char **read_attrs, char *who )
        char *namelist[MAX_NUM_NAMES];  /* names found */
        char response[SMALL_BUF_SIZE];  /* results from user */
        char *name = NULL;              /* DN to lookup */
-       LDAPMessage *mp;
+       LDAPMessage *mp = NULL;
        int ld_errno = 0;
 
 #ifdef DEBUG
@@ -92,7 +96,7 @@ disambiguate( LDAPMessage *result, int matches, char **read_attrs, char *who )
        for (;;) {
                printf("  Do you wish to see a list of names? ");
                fflush(stdout);
-               (void) memset(response, 0, sizeof(response));
+               (void) memset(response, '\0', sizeof(response));
                fetch_buffer(response, sizeof(response), stdin);
                switch (response[0]) {
                case 'n' :
@@ -129,7 +133,7 @@ disambiguate( LDAPMessage *result, int matches, char **read_attrs, char *who )
                                printf("     ld = 0x%x\n", ld);
                                printf("     search base = %s\n", name);
                                printf("     scope = LDAP_SCOPE_BASE\n");
-                               printf("     filter = objectClass=*\n");
+                               printf("     filter = (objectClass=*)\n");
                                for (i = 0; read_attrs[i] != NULL; i++)
                                        printf("     read_attrs[%d] = %s\n", i, read_attrs[i]);
                                printf("     read_attrs[%d] = NULL\n", i);
@@ -137,7 +141,7 @@ disambiguate( LDAPMessage *result, int matches, char **read_attrs, char *who )
                                printf("     &mp = 0x%x\n", &mp);
                        }
 #endif
-                       if (ldap_search_s(ld, name, LDAP_SCOPE_BASE, "objectClass=*", read_attrs, FALSE, &mp) != LDAP_SUCCESS) {
+                       if (ldap_search_s(ld, name, LDAP_SCOPE_BASE, NULL, read_attrs, FALSE, &mp) != LDAP_SUCCESS) {
                                ldap_perror(ld, "ldap_search_s");
                                Free(name);
                                ldap_msgfree(mp);
@@ -224,15 +228,10 @@ find( char *who, int quiet )
                        return(NULL);
                } else if (matches == 1) {
                        dn = ldap_get_dn(ld, ldap_first_entry(ld, res));
-                       rc = ldap_search_s(ld, dn, LDAP_SCOPE_BASE, "objectClass=*", read_attrs, FALSE, &res);
+                       rc = ldap_search_s(ld, dn, LDAP_SCOPE_BASE, NULL, read_attrs, FALSE, &res);
                        ldap_memfree(dn);
                        if (rc != LDAP_SUCCESS) {
-                               int ld_errno = 0;
-                               ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ld_errno);
-                               if (ld_errno == LDAP_UNAVAILABLE)
-                                       printf("  Could not contact the LDAP server to find \"%s\".\n", who);
-                               else
-                                       ldap_perror(ld, "ldap_search_s");
+                               ldap_perror(ld, "ldap_search_s");
                                return(NULL);
                        }
                        ldap_set_option(ld, LDAP_OPT_DEREF, &savederef);
@@ -303,7 +302,7 @@ find( char *who, int quiet )
                                printf("     ld = 0x%x\n", ld);
                                printf("     dn = %s\n", dn);
                                printf("     scope = LDAP_SCOPE_BASE\n");
-                               printf("     filter = %s\n", "objectClass=*");
+                               printf("     filter = %s\n", "(objectClass=*)");
                                for (i = 0; read_attrs[i] != NULL; i++)
                                        printf("     read_attrs[%d] = %s\n", i, read_attrs[i]);
                                printf("     read_attrs[%d] = NULL\n", i);
@@ -311,7 +310,7 @@ find( char *who, int quiet )
                                printf("     &results = 0x%x\n", &res);
                        }
 #endif
-                       if (ldap_search_s(ld, dn, LDAP_SCOPE_BASE, "objectClass=*", read_attrs, FALSE, &res) != LDAP_SUCCESS) {
+                       if (ldap_search_s(ld, dn, LDAP_SCOPE_BASE, NULL, read_attrs, FALSE, &res) != LDAP_SUCCESS) {
                                ldap_perror(ld, "ldap_search_s");
                                ldap_msgfree(res);
                                res = NULL;
@@ -462,7 +461,7 @@ fetch_boolean_value( char *who, struct attribute attr )
                printf("->fetch_boolean_value(%s, %s)\n", who, attr.quipu_name);
 #endif
        attributes[0] = attr.quipu_name;
-       if (ldap_search_s(ld, who, LDAP_SCOPE_BASE, "objectClass=*", attributes, FALSE, &result) != LDAP_SUCCESS) {
+       if (ldap_search_s(ld, who, LDAP_SCOPE_BASE, NULL, attributes, FALSE, &result) != LDAP_SUCCESS) {
                int ld_errno = 0;
                ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ld_errno);
                if (ld_errno == LDAP_NO_SUCH_ATTRIBUTE)
index 5927351c5bf9c57b689b9e74a7f4cccc2f7e5f88..3531c75a767cc772291ae4998179c58297cf3fe1 100644 (file)
@@ -1,4 +1,8 @@
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 /*
  * Copyright (c) 1992, 1993, 1994  Regents of the University of Michigan.
  * All rights reserved.
@@ -14,8 +18,7 @@
 #include "portable.h"
 
 #include <stdio.h>
-#include <ac/time.h>           /* portable.h+ldap.h needs time_t */
-#include <lber.h>
+#include <ac/time.h>           /* ldap.h needs time_t */
 #include <ldap.h>
 #include "ud.h"
 
@@ -41,7 +44,7 @@ struct attribute attrlist[] = {
 #ifdef UOFM
        { "multiLineDescription", "Description", change_field, ATTR_FLAG_PERSON | ATTR_FLAG_GROUP | ATTR_FLAG_READ  | ATTR_FLAG_PERSON_MOD | ATTR_FLAG_GROUP_MOD | ATTR_FLAG_IS_MULTILINE },
 #endif
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
        { "krbName", "Kerberos name", 0, ATTR_FLAG_PERSON | ATTR_FLAG_READ },
 #endif
        { "description", "Brief description", 0, ATTR_FLAG_PERSON | ATTR_FLAG_GROUP | ATTR_FLAG_READ },
@@ -66,5 +69,9 @@ struct attribute attrlist[] = {
        { "drink", "Favorite Beverage", change_field, ATTR_FLAG_PERSON | ATTR_FLAG_READ | ATTR_FLAG_PERSON_MOD },
        { "lastModifiedBy", "Last modified by", 0, ATTR_FLAG_GROUP | ATTR_FLAG_PERSON | ATTR_FLAG_IS_A_DN | ATTR_FLAG_READ },
        { "lastModifiedTime", "Last modified at", 0, ATTR_FLAG_GROUP | ATTR_FLAG_PERSON | ATTR_FLAG_READ | ATTR_FLAG_IS_A_DATE },
+       { "modifiersname", "Modifier's Name", 0, ATTR_FLAG_GROUP | ATTR_FLAG_PERSON | ATTR_FLAG_IS_A_DN | ATTR_FLAG_READ },
+       { "modifytimestamp", "Modify Timestamp", 0, ATTR_FLAG_GROUP | ATTR_FLAG_PERSON | ATTR_FLAG_READ | ATTR_FLAG_IS_A_DATE },
+       { "creatorsname", "Creator's Name", 0, ATTR_FLAG_GROUP | ATTR_FLAG_PERSON | ATTR_FLAG_IS_A_DN | ATTR_FLAG_READ },
+       { "createtimestamp", "Create Timestamp", 0, ATTR_FLAG_GROUP | ATTR_FLAG_PERSON | ATTR_FLAG_READ | ATTR_FLAG_IS_A_DATE },
        { NULL, NULL, 0, ATTR_FLAG_NONE }
 };
index 950631d765073030efd897418b09cc4472cdbbc0..fd73738e7763b4a160c89a5699fcd8d95238d0a4 100644 (file)
@@ -1,4 +1,8 @@
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 /*
  * Copyright (c) 1993, 1994  Regents of the University of Michigan.
  * All rights reserved.
@@ -215,9 +219,9 @@ remove_group( char *name )
        if ((dn = bind_and_fetch(name)) == NULL)
                return;
 
-       printf("\n  The group '%s' will be permanently removed from\n",
-               name);
-       printf("  the Directory.  Are you absolutely sure that you want to\n" );        printf("  remove this entire group? ");
+       printf("\n  The entry\n    '%s'\n  will be permanently removed from", dn);
+       printf(" the Directory.\n  Are you absolutely sure that you want to" );
+       printf(" remove this entire group? ");
        fflush(stdout);
        fetch_buffer(tmp, sizeof(tmp), stdin);
        if (!(tmp[0] == 'y' || tmp[0] == 'Y'))
@@ -230,7 +234,7 @@ remove_group( char *name )
                int ld_errno = 0;
                ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ld_errno);
                if (ld_errno == LDAP_INSUFFICIENT_ACCESS)
-                       printf("  You do not own the group \"%s\".\n", name);
+                       printf("  You do not own the entry\n\t\"%s\".\n", dn);
                else
                        ldap_perror(ld, "  ldap_delete_s");
                printf("  Group not removed.\n");
@@ -239,10 +243,12 @@ remove_group( char *name )
        }
        ldap_uncache_entry(ld, dn);
        if (verbose)
+       {
            if (name == NULL)
                printf("  The group has been removed.\n");
            else
                printf("  The group \"%s\" has been removed.\n", name);
+       }
        Free(dn);
        return;
 }
index 027e168e41577b7fb33123cb6f3c3f4623162e9e..0fb0590bf2a57087c5b71c1d2bbe4950832286b4 100644 (file)
@@ -1,4 +1,8 @@
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 /*
  * Copyright (c) 1992, 1993  Regents of the University of Michigan.
  * All rights reserved.
index 7f0d4baa3d1b8eb6185b2e3731c5ef908e1911af..e830c8523839acc5a9201af3226ce898e125c778 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
@@ -280,7 +280,7 @@ do_commands( void )
        printf(" Thank you!\n");
        
        ldap_unbind(ld);
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
        destroy_tickets();
 #endif
        exit( EXIT_SUCCESS );
@@ -353,7 +353,7 @@ change_base( int type, char **base, char *s )
        /*
         *  If s is NULL we need to prompt the user for an argument.
         */
-       while (s == NULL) {
+       if (s == NULL) {
                if (verbose) {
                        printf("  You need to specify how the base is to be changed.  Valid choices are:\n");
                        printf("     ?       - list the choices immediately below this level\n");
@@ -367,6 +367,8 @@ change_base( int type, char **base, char *s )
                fetch_buffer(buf, sizeof(buf), stdin);
                if ((buf != NULL) && (buf[0] != '\0'))
                        s = buf;
+               else
+                       return;
        }
 
        /* set the output string */
@@ -433,7 +435,7 @@ change_base( int type, char **base, char *s )
                 *  the user if they want to see more.  They can also just
                 *  type a number at that point too.
                 */
-               if (ldap_search_s(ld, *base, LDAP_SCOPE_ONELEVEL, "(|(objectClass=quipuNonLeafObject)(objectClass=externalNonLeafObject))", attrs, FALSE, &mp) != LDAP_SUCCESS) {
+               if (ldap_search_s(ld, *base, LDAP_SCOPE_ONELEVEL, NULL, attrs, FALSE, &mp) != LDAP_SUCCESS) {
                        int ld_errno = 0;
                        ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ld_errno);
                        if ((ld_errno == LDAP_TIMELIMIT_EXCEEDED) ||
@@ -658,12 +660,7 @@ initialize_client( void )
        }
        if (ldap_bind_s(ld, (char *) default_bind_object, NULL,
            LDAP_AUTH_SIMPLE) != LDAP_SUCCESS) {
-               int ld_errno = 0;
-               ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ld_errno);
-
-               fprintf(stderr, "  The LDAP Directory is temporarily unavailable.  Please try again later.\n");
-               if (ld_errno != LDAP_UNAVAILABLE)
-                       ldap_perror(ld, "  ldap_bind_s");
+               ldap_perror(ld, "  ldap_bind_s");
                exit( EXIT_FAILURE );
                /* NOTREACHED */
        }
index 40eea363167aad250e3a5e6b9102e1c11d330b93..1a13a967f2e82df614fbf0fb2e06c0ec9444c57e 100644 (file)
@@ -1,4 +1,8 @@
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 /*
  * Copyright (c) 1991,1993  Regents of the University of Michigan.
  * All rights reserved.
@@ -393,7 +397,7 @@ get_value( char *id, char *prompt )
         *  Other attributes may not.
         */
        count = 1;
-       (void) memset(buffer, 0, sizeof(buffer));
+       (void) memset(buffer, '\0', sizeof(buffer));
 #ifdef UOFM
        if (!strcmp(id, "postalAddress") || !strcmp(id, "homePostalAddress") || !strcmp(id, "multiLineDescription") || !strcmp(id, "vacationMessage")) 
 #else
@@ -784,23 +788,22 @@ check_URL( char *url )
 void
 mod_perror( LDAP *ld )
 {
-       int ld_errno = 0;
+       int ld_errno = LDAP_SUCCESS;
+       char *ld_errtext = NULL;
 
-       if(ld != NULL) {
-               ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ld_errno);
-       }
+       ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ld_errno );
 
-       if (( ld == NULL ) || ( ld_errno != LDAP_UNAVAILABLE &&
-           ld_errno != LDAP_UNWILLING_TO_PERFORM ))
-       {
-               ldap_perror( ld, "modify" );
-               return;
-       }
+       if( ld_errno != LDAP_SUCCESS ) {
+               ldap_get_option(ld, LDAP_OPT_ERROR_STRING, &ld_errtext );
+       }       
+
+       fprintf( stderr, "  modify failed: %s (%d)\n",
+               ldap_err2string( ld_errno ), ld_errno );
 
-       fprintf( stderr, "\n  modify: failed because part of the online directory is not able\n" );
-       fprintf( stderr, "  to be modified right now" );
-       if ( ld_errno == LDAP_UNAVAILABLE ) {
-               fprintf( stderr, " or is temporarily unavailable" );
+       if( ld_errtext != NULL ) {
+               fprintf( stderr, "    additional information: %s\n",
+                       ld_errtext );
        }
-       fprintf( stderr, ".\n  Please try again later.\n" );
+
+       fprintf( stderr, "  Please try again later.\n" );
 }
index 8cb5c133dca28a33431e31c23fa2ac4b9b2d0ad8..914b3e3d1be204eb6281011bc5265b93a57a8627 100644 (file)
@@ -1,4 +1,8 @@
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 /*
  * Copyright (c) 1991, 1993 
  * Regents of the University of Michigan.  All rights reserved.
@@ -52,6 +56,8 @@ static char *person_attr_print_order[] = {
        "memberOfGroup",
        "lastModifiedBy",
        "lastModifiedTime",
+       "modifiersname",
+       "modifytimestamp",
        NULL
 };
 
@@ -74,6 +80,10 @@ static char *group_attr_print_order[] = {
        "labeledURL",
        "lastModifiedBy",
        "lastModifiedTime",
+       "modifiersname",
+       "modifytimestamp",
+       "creatorsname",
+       "createtimestamp",
        NULL
 };
 
@@ -195,6 +205,12 @@ print_an_entry( void )
        if (debug & D_TRACE)
                printf("->print_an_entry()\n");
 #endif
+
+       if( Entry.name == NULL ) {
+               printf(" No Entry found.\n");
+               return;
+       }
+
        printf(" \"%s\"\n", Entry.name);
        
        /*
@@ -559,7 +575,7 @@ time2text( char *ldtimestr, int dateonly )
            return( fmterr );
        }
        
-    memset( (char *)&t, 0, sizeof( struct tm ));
+    memset( (char *)&t, '\0', sizeof( struct tm ));
 
     p = ldtimestr;
 
@@ -568,8 +584,10 @@ time2text( char *ldtimestr, int dateonly )
                /* POSIX says tm_year should be year - 1900 */
        t.tm_year = 100 * GET2BYTENUM( p ) - 1900;
                p += 2;
+       } else {
+       t.tm_year = 0;
        }
-    t.tm_year = GET2BYTENUM( p ); p += 2;
+    t.tm_year += GET2BYTENUM( p ); p += 2;
 
     t.tm_mon = GET2BYTENUM( p ) - 1; p += 2;
     t.tm_mday = GET2BYTENUM( p ); p += 2;
index 8a6a5ae70f5c9882d56e95f1426b5296a1c14fbb..120cde80cfddbb7a7377af594b3e8d4d6c71cbce 100644 (file)
@@ -1,11 +1,12 @@
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 #include "portable.h"
 
-#if defined(HAVE_KERBEROS) && !defined(openbsd)
+#if defined(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND) && !defined(openbsd)
 /*
- * $Source: /repo/OpenLDAP/pkg/ldap/clients/ud/string_to_key.c,v $
- * $Author: hallvard $
- *
  * Copyright 1985, 1986, 1987, 1988, 1989 by the Massachusetts Institute
  * of Technology.
  *
@@ -66,7 +67,7 @@ des_string_to_key( char *str, register des_cblock *key )
     length = strlen(str);
 
     /* init key array for bits */
-    memset(k_char, 0, sizeof(k_char));
+    memset(k_char, '\0', sizeof(k_char));
 
 #ifdef USE_DES_DEBUG
     if (des_debug)
@@ -115,7 +116,7 @@ des_string_to_key( char *str, register des_cblock *key )
     (void) des_key_sched(key,key_sked);
     (void) des_cbc_cksum((des_cblock *)in_str,key,length,key_sked,key);
     /* erase key_sked */
-    memset((char *)key_sked, 0, sizeof(key_sked));
+    memset((char *)key_sked, '\0', sizeof(key_sked));
 
     /* now fix up key parity again */
     des_fixup_key_parity(key);
@@ -159,8 +160,8 @@ Andrew_StringToKey(
     int   i;
     int   passlen;
 
-    memset(key, 0, sizeof(des_cblock));
-    memset(password, 0, sizeof(password));
+    memset(key, '\0', sizeof(des_cblock));
+    memset(password, '\0', sizeof(password));
 
     strncpy (password, cell, 8);
     passlen = strlen (str);
diff --git a/clients/ud/ud.dsp b/clients/ud/ud.dsp
new file mode 100644 (file)
index 0000000..2513226
--- /dev/null
@@ -0,0 +1,188 @@
+# Microsoft Developer Studio Project File - Name="ud" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=ud - Win32 Single Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "ud.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "ud.mak" CFG="ud - Win32 Single Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "ud - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "ud - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "ud - Win32 Single Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ud - Win32 Single Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "ud - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\ud"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 oldap32.lib olber32.lib oldif32.lib olutil32.lib hs_regex.lib sasl.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\Release"
+
+!ELSEIF  "$(CFG)" == "ud - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\ud"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 oldap32.lib olber32.lib oldif32.lib olutil32.lib hs_regex.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Debug"
+
+!ELSEIF  "$(CFG)" == "ud - Win32 Single Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ud___Wi0"
+# PROP BASE Intermediate_Dir "ud___Wi0"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\ud"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 oldap32.lib olber32.lib oldif32.lib olutil32.lib ws2_32.lib hs_regex.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\libraries\Release"
+# ADD LINK32 oldap32.lib olber32.lib oldif32.lib olutil32.lib hs_regex.lib sasl.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\SRelease"
+
+!ELSEIF  "$(CFG)" == "ud - Win32 Single Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "ud___Wi1"
+# PROP BASE Intermediate_Dir "ud___Wi1"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\ud"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 oldap32.lib olber32.lib oldif32.lib olutil32.lib ws2_32.lib hs_regex.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\libraries\Debug"
+# ADD LINK32 oldap32.lib olber32.lib oldif32.lib olutil32.lib hs_regex.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\SDebug"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "ud - Win32 Release"
+# Name "ud - Win32 Debug"
+# Name "ud - Win32 Single Release"
+# Name "ud - Win32 Single Debug"
+# Begin Source File
+
+SOURCE=.\auth.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\edit.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\find.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\globals.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\group.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\help.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\main.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mod.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\print.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\string_to_key.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ud.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\util.c
+# End Source File
+# End Target
+# End Project
index fa07c3531d617de4d589c6b6d05d257385e21496..6f6d1b461aa813a58185f18708b4b4b5f81445f1 100644 (file)
@@ -1,12 +1,7 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted only
- * as authorized by the OpenLDAP Public License.  A copy of this
- * license is available at http://www.OpenLDAP.org/license.html or
- * in file LICENSE in the top-level directory of the distribution.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
  * Copyright (c) 1991, 1992, 1993 
@@ -90,7 +85,7 @@
 /*
  *  Authentication method we will be using.
  */
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
 #define UD_AUTH_METHOD         LDAP_AUTH_KRBV4
 #else
 #define UD_AUTH_METHOD         LDAP_AUTH_SIMPLE
@@ -198,7 +193,7 @@ extern char Version[];
 
 /* in auth.c: */
 int  auth      LDAP_P(( char *who, int implicit ));
-#if defined(HAVE_KERBEROS) && defined(_AC_KRB_H)
+#if defined(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND) && defined(_AC_KRB_H)
 int  krbgetpass LDAP_P(( char *u, char *in, char *re, char *pw, C_Block key ));
 void destroy_tickets LDAP_P(( void ));
 #endif
@@ -269,7 +264,7 @@ void print_URL      LDAP_P(( struct attribute A ));
 void print_one_URL     LDAP_P(( char *s, int l_lead, char *tag, int u_lead ));
 
 /* in string_to_key.c: */
-#if defined(HAVE_KERBEROS) && !defined(openbsd) && defined(_AC_KRB_H)
+#if defined(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND) && !defined(openbsd) && defined(_AC_KRB_H)
 #if defined(HAVE_AFS_KERBEROS) || !defined(HAVE_KERBEROS_V)
 void  des_string_to_key        LDAP_P(( char *str, des_cblock *key ));
 #endif
index 27023de75990dfd1d8a96b09ae8d10e9feeb91e1..3cc445e2df61845d8eb0e2dd899d3ea2f7423c3b 100644 (file)
@@ -1,4 +1,8 @@
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 /*
  * Copyright (c) 1992, 1993  Regents of the University of Michigan.
  * All rights reserved.
@@ -100,7 +104,7 @@ fatal( char *s )
 {
        if (errno != 0)
                perror(s);
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
        destroy_tickets();
 #endif
        exit( EXIT_FAILURE );
@@ -405,15 +409,19 @@ isadn( char *s )
 char *
 my_ldap_dn2ufn( char *s )
 {
+#ifdef UD_BASE
        register char **cpp;
        static char short_DN[BUFSIZ];
 
-       if (strstr(s, NULL) == NULL)
+       if (strstr(s, UD_BASE) == NULL)
                return(ldap_dn2ufn(s));
        cpp = ldap_explode_dn(s, TRUE);
        sprintf(short_DN, "%s, %s", *cpp, *(cpp + 1));
        ldap_value_free(cpp);
        return(short_DN);
+#else
+       return(ldap_dn2ufn(s));
+#endif
 }
 
 /* return TRUE if this attribute should be printed as a URL */
index 618b873411ebeb096174948dae9e1a3ef873e897..151a0952b32ef7428900761f6b361bd8e1d26fff 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,14 +1,17 @@
 #! /bin/sh
 # $OpenLDAP$
-# from OpenLDAP: pkg/ldap/configure.in,v 1.223.2.3 1999/09/10 20:25:17 kdz Exp  
+# from OpenLDAP: pkg/ldap/configure.in,v 1.314 2000/06/09 21:09:52 kurt Exp  
 
-# Copyright 1998,1999 The OpenLDAP Foundation.  All Rights Reserved.
+# Copyright 1998-2000 The OpenLDAP Foundation.  All Rights Reserved.
 # 
 # Redistribution and use in source and binary forms are permitted only
 # as authorized by the OpenLDAP Public License.  A copy of this
 # license is available at http://www.OpenLDAP.org/license.html or
 # in file LICENSE in the top-level directory of the distribution.
 
+echo "Copyright 1998-2000 The OpenLDAP Foundation,  All Rights Reserved."
+echo "Copying restrictions apply, see COPYRIGHT file."
+
 # Guess values for system-dependent variables and create Makefiles.
 # Generated automatically using autoconf version 2.13.1 
 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
@@ -31,22 +34,24 @@ ac_help="$ac_help
   --enable-proctitle   enable proctitle support (yes)"
 ac_help="$ac_help
   --enable-cache       enable caching (yes)"
-ac_help="$ac_help
-  --enable-dns         enable V2 DX Referrals extension (no)"
 ac_help="$ac_help
   --enable-referrals   enable V2 Referrals extension (yes)"
+ac_help="$ac_help
+  --enable-kbind       enable V2 Kerberos IV bind (auto)"
 ac_help="$ac_help
   --enable-cldap       enable connectionless ldap (no)"
 ac_help="$ac_help
-  --enable-x-compile   enable cross compiling (no)"
+  --enable-ipv6        enable IPv6 support (auto)"
 ac_help="$ac_help
-  --enable-dmalloc     enable debug malloc support (no)"
+  --enable-unix                enable UNIX domain socket support (auto)"
+ac_help="$ac_help
+  --enable-x-compile   enable cross compiling (no)"
 ac_help="$ac_help
   --with-cyrus-sasl    with Cyrus SASL support (auto)"
 ac_help="$ac_help
   --with-fetch         with fetch URL support (auto)"
 ac_help="$ac_help
-  --with-kerberos      with Kerberos support (auto)"
+  --with-kerberos      with support (auto)"
 ac_help="$ac_help
   --with-readline      with readline support (auto)"
 ac_help="$ac_help
@@ -63,6 +68,10 @@ ac_help="$ac_help
     --enable-cleartext enable cleartext passwords (yes)"
 ac_help="$ac_help
     --enable-crypt     enable crypt(3) passwords (auto)"
+ac_help="$ac_help
+    --enable-kpasswd   enable kerberos password verification (no)"
+ac_help="$ac_help
+    --enable-spasswd   enable (Cyrus) SASL password verification (no)"
 ac_help="$ac_help
     --enable-modules   enable dynamic module support (no)"
 ac_help="$ac_help
@@ -75,14 +84,14 @@ ac_help="$ac_help
     --enable-rlookups  enable reverse lookups (auto)"
 ac_help="$ac_help
     --enable-aci       enable per-object ACIs (no)"
-ac_help="$ac_help
-    --enable-discreteaci       enable discrete rights in ACIs (no)"
 ac_help="$ac_help
     --enable-wrappers  enable tcp wrapper support (no)"
 ac_help="$ac_help
-    --enable-bdb2      enable bdb2 backend (no)"
+    --enable-dynamic   enable linking built binaries with dynamic libs (no)"
+ac_help="$ac_help
+    --enable-dnssrv    enable dnssrv backend (no)"
 ac_help="$ac_help
-      --with-bdb2-module       module type (static)"
+      --with-dnssrv-module     module type (static)"
 ac_help="$ac_help
     --enable-ldap      enable ldap backend (no)"
 ac_help="$ac_help
@@ -99,18 +108,10 @@ ac_help="$ac_help
     --enable-passwd    enable passwd backend (no)"
 ac_help="$ac_help
       --with-passwd-module     module type (static)"
-ac_help="$ac_help
-    --enable-perl      enable perl backend (no)"
-ac_help="$ac_help
-      --with-perl-module       module type (static)"
 ac_help="$ac_help
     --enable-shell     enable shell backend (no)"
 ac_help="$ac_help
       --with-shell-module      module type (static)"
-ac_help="$ac_help
-    --enable-tcl       enable tcl backend (no)"
-ac_help="$ac_help
-      --with-tcl-module        module type (static)"
 ac_help="$ac_help
 SLURPD (Replication Daemon) Options:"
 ac_help="$ac_help
@@ -629,6 +630,16 @@ else
   ac_n= ac_c='\c' ac_t=
 fi
 
+
+# set unset (borrowed from autoconf 2.14a)
+if (unset FOO) >/dev/null 2>&1; then
+  ol_unset=unset
+else
+  ol_unset=false
+fi
+# unset CDPATH
+$ol_unset CDPATH || test "${CDPATH+set}" != set || CDPATH=: && export CDPATH
+
 ac_aux_dir=
 for ac_dir in build $srcdir/build; do
   if test -f $ac_dir/install-sh; then
@@ -639,6 +650,10 @@ for ac_dir in build $srcdir/build; do
     ac_aux_dir=$ac_dir
     ac_install_sh="$ac_aux_dir/install.sh -c"
     break
+  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
@@ -653,9 +668,11 @@ if test -z "$OL_VERSION"; then
        { echo "configure: error: could not determine version" 1>&2; exit 1; }
 fi
 
+echo "Configuring OpenLDAP $OL_VERSION ..."
+
 
 echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:659: checking host system type" >&5
+echo "configure:676: checking host system type" >&5
 if test "x$ac_cv_host" = "x" || (test "x$host" != "xNONE" && test "x$host" != "x$ac_cv_host_alias"); then
 
 # Make sure we can run config.sub.
@@ -696,7 +713,7 @@ host_os=$ac_cv_host_os
 
 
 echo $ac_n "checking target system type""... $ac_c" 1>&6
-echo "configure:700: checking target system type" >&5
+echo "configure:717: checking target system type" >&5
 if test "x$ac_cv_target" = "x" || (test "x$target" != "xNONE" && test "x$target" != "x$ac_cv_target_alias"); then
 
 # Make sure we can run config.sub.
@@ -736,7 +753,7 @@ target_os=$ac_cv_target_os
 
 
 echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:740: checking build system type" >&5
+echo "configure:757: checking build system type" >&5
 if test "x$ac_cv_build" = "x" || (test "x$build" != "xNONE" && test "x$build" != "x$ac_cv_build_alias"); then
 
 # Make sure we can run config.sub.
@@ -813,7 +830,7 @@ test "$host_alias" != "$target_alias" &&
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:817: checking for a BSD compatible install" >&5
+echo "configure:834: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"\${ac_cv_path_install+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -870,7 +887,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
-echo "configure:874: checking whether build environment is sane" >&5
+echo "configure:891: checking whether build environment is sane" >&5
 # Just in case
 sleep 1
 echo timestamp > conftestfile
@@ -931,7 +948,7 @@ 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 $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:935: checking for $ac_word" >&5
+echo "configure:952: checking for $ac_word" >&5
 if eval "test \"\${ac_cv_prog_AWK+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -961,7 +978,7 @@ test -n "$AWK" && break
 done
 
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:965: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:982: checking whether ${MAKE-make} sets \${MAKE}" >&5
 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 $ac_n "(cached) $ac_c" 1>&6
@@ -1001,7 +1018,7 @@ fi
 
 missing_dir=`cd $ac_aux_dir && pwd`
 echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
-echo "configure:1005: checking for working aclocal" >&5
+echo "configure:1022: checking for working aclocal" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -1014,7 +1031,7 @@ else
 fi
 
 echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
-echo "configure:1018: checking for working autoconf" >&5
+echo "configure:1035: checking for working autoconf" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -1027,7 +1044,7 @@ else
 fi
 
 echo $ac_n "checking for working automake""... $ac_c" 1>&6
-echo "configure:1031: checking for working automake" >&5
+echo "configure:1048: checking for working automake" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -1040,7 +1057,7 @@ else
 fi
 
 echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
-echo "configure:1044: checking for working autoheader" >&5
+echo "configure:1061: checking for working autoheader" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -1053,7 +1070,7 @@ else
 fi
 
 echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
-echo "configure:1057: checking for working makeinfo" >&5
+echo "configure:1074: checking for working makeinfo" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -1073,7 +1090,7 @@ 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 $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1077: checking for $ac_word" >&5
+echo "configure:1094: checking for $ac_word" >&5
 if eval "test \"\${ac_cv_prog_AMTAR+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1124,7 +1141,7 @@ EOF
 
 
 echo $ac_n "checking configure arguments""... $ac_c" 1>&6
-echo "configure:1128: checking configure arguments" >&5
+echo "configure:1145: checking configure arguments" >&5
 
 
 top_builddir=`pwd`
@@ -1230,10 +1247,10 @@ else
        ol_enable_cache="yes"
 fi
 # end --enable-cache
-# OpenLDAP --enable-dns
-       # Check whether --enable-dns or --disable-dns was given.
-if test "${enable_dns+set}" = set; then
-  enableval="$enable_dns"
+# OpenLDAP --enable-referrals
+       # Check whether --enable-referrals or --disable-referrals was given.
+if test "${enable_referrals+set}" = set; then
+  enableval="$enable_referrals"
   
        ol_arg=invalid
        for ol_val in auto yes no ; do
@@ -1242,18 +1259,18 @@ if test "${enable_dns+set}" = set; then
                fi
        done
        if test "$ol_arg" = "invalid" ; then
-               { echo "configure: error: bad value $enableval for --enable-dns" 1>&2; exit 1; }
+               { echo "configure: error: bad value $enableval for --enable-referrals" 1>&2; exit 1; }
        fi
-       ol_enable_dns="$ol_arg"
+       ol_enable_referrals="$ol_arg"
 
 else
-       ol_enable_dns="no"
+       ol_enable_referrals="yes"
 fi
-# end --enable-dns
-# OpenLDAP --enable-referrals
-       # Check whether --enable-referrals or --disable-referrals was given.
-if test "${enable_referrals+set}" = set; then
-  enableval="$enable_referrals"
+# end --enable-referrals
+# OpenLDAP --enable-kbind
+       # Check whether --enable-kbind or --disable-kbind was given.
+if test "${enable_kbind+set}" = set; then
+  enableval="$enable_kbind"
   
        ol_arg=invalid
        for ol_val in auto yes no ; do
@@ -1262,14 +1279,14 @@ if test "${enable_referrals+set}" = set; then
                fi
        done
        if test "$ol_arg" = "invalid" ; then
-               { echo "configure: error: bad value $enableval for --enable-referrals" 1>&2; exit 1; }
+               { echo "configure: error: bad value $enableval for --enable-kbind" 1>&2; exit 1; }
        fi
-       ol_enable_referrals="$ol_arg"
+       ol_enable_kbind="$ol_arg"
 
 else
-       ol_enable_referrals="yes"
+       ol_enable_kbind="auto"
 fi
-# end --enable-referrals
+# end --enable-kbind
 # OpenLDAP --enable-cldap
        # Check whether --enable-cldap or --disable-cldap was given.
 if test "${enable_cldap+set}" = set; then
@@ -1290,31 +1307,30 @@ else
        ol_enable_cldap="no"
 fi
 # end --enable-cldap
-# OpenLDAP --enable-x_compile
-       # Check whether --enable-x_compile or --disable-x_compile was given.
-if test "${enable_x_compile+set}" = set; then
-  enableval="$enable_x_compile"
+# OpenLDAP --enable-ipv6
+       # Check whether --enable-ipv6 or --disable-ipv6 was given.
+if test "${enable_ipv6+set}" = set; then
+  enableval="$enable_ipv6"
   
        ol_arg=invalid
-       for ol_val in yes no ; do
+       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 "configure: error: bad value $enableval for --enable-x_compile" 1>&2; exit 1; }
+               { echo "configure: error: bad value $enableval for --enable-ipv6" 1>&2; exit 1; }
        fi
-       ol_enable_x_compile="$ol_arg"
+       ol_enable_ipv6="$ol_arg"
 
 else
-       ol_enable_x_compile="no"
+       ol_enable_ipv6="auto"
 fi
-# end --enable-x_compile
-
-# OpenLDAP --enable-dmalloc
-       # Check whether --enable-dmalloc or --disable-dmalloc was given.
-if test "${enable_dmalloc+set}" = set; then
-  enableval="$enable_dmalloc"
+# end --enable-ipv6
+# OpenLDAP --enable-unix
+       # Check whether --enable-unix or --disable-unix was given.
+if test "${enable_unix+set}" = set; then
+  enableval="$enable_unix"
   
        ol_arg=invalid
        for ol_val in auto yes no ; do
@@ -1323,14 +1339,35 @@ if test "${enable_dmalloc+set}" = set; then
                fi
        done
        if test "$ol_arg" = "invalid" ; then
-               { echo "configure: error: bad value $enableval for --enable-dmalloc" 1>&2; exit 1; }
+               { echo "configure: error: bad value $enableval for --enable-unix" 1>&2; exit 1; }
+       fi
+       ol_enable_unix="$ol_arg"
+
+else
+       ol_enable_unix="auto"
+fi
+# end --enable-unix
+# OpenLDAP --enable-x_compile
+       # Check whether --enable-x_compile or --disable-x_compile was given.
+if test "${enable_x_compile+set}" = set; then
+  enableval="$enable_x_compile"
+  
+       ol_arg=invalid
+       for ol_val in yes no ; do
+               if test "$enableval" = "$ol_val" ; then
+                       ol_arg="$ol_val"
+               fi
+       done
+       if test "$ol_arg" = "invalid" ; then
+               { echo "configure: error: bad value $enableval for --enable-x_compile" 1>&2; exit 1; }
        fi
-       ol_enable_dmalloc="$ol_arg"
+       ol_enable_x_compile="$ol_arg"
 
 else
-       ol_enable_dmalloc="no"
+       ol_enable_x_compile="no"
 fi
-# end --enable-dmalloc
+# end --enable-x_compile
+
 
 # OpenLDAP --with-cyrus_sasl
        # Check whether --with-cyrus_sasl or --without-cyrus_sasl was given.
@@ -1380,7 +1417,7 @@ if test "${with_kerberos+set}" = set; then
   withval="$with_kerberos"
   
        ol_arg=invalid
-       for ol_val in auto k5 k4 afs yes no ; do
+       for ol_val in auto k5 k5only k425 kth k4 afs yes no ; do
                if test "$withval" = "$ol_val" ; then
                        ol_arg="$ol_val"
                fi
@@ -1422,7 +1459,7 @@ if test "${with_threads+set}" = set; then
   withval="$with_threads"
   
        ol_arg=invalid
-       for ol_val in auto posix mach pth lwp yes no manual  ; do
+       for ol_val in auto nt posix mach pth lwp yes no manual  ; do
                if test "$withval" = "$ol_val" ; then
                        ol_arg="$ol_val"
                fi
@@ -1547,6 +1584,46 @@ else
        ol_enable_crypt="auto"
 fi
 # end --enable-crypt
+# OpenLDAP --enable-kpasswd
+       # Check whether --enable-kpasswd or --disable-kpasswd was given.
+if test "${enable_kpasswd+set}" = set; then
+  enableval="$enable_kpasswd"
+  
+       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 "configure: error: bad value $enableval for --enable-kpasswd" 1>&2; exit 1; }
+       fi
+       ol_enable_kpasswd="$ol_arg"
+
+else
+       ol_enable_kpasswd="no"
+fi
+# end --enable-kpasswd
+# OpenLDAP --enable-spasswd
+       # Check whether --enable-spasswd or --disable-spasswd was given.
+if test "${enable_spasswd+set}" = set; then
+  enableval="$enable_spasswd"
+  
+       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 "configure: error: bad value $enableval for --enable-spasswd" 1>&2; exit 1; }
+       fi
+       ol_enable_spasswd="$ol_arg"
+
+else
+       ol_enable_spasswd="no"
+fi
+# end --enable-spasswd
 # OpenLDAP --enable-modules
        # Check whether --enable-modules or --disable-modules was given.
 if test "${enable_modules+set}" = set; then
@@ -1667,10 +1744,10 @@ else
        ol_enable_aci="no"
 fi
 # end --enable-aci
-# OpenLDAP --enable-discreteaci
-       # Check whether --enable-discreteaci or --disable-discreteaci was given.
-if test "${enable_discreteaci+set}" = set; then
-  enableval="$enable_discreteaci"
+# OpenLDAP --enable-wrappers
+       # Check whether --enable-wrappers or --disable-wrappers was given.
+if test "${enable_wrappers+set}" = set; then
+  enableval="$enable_wrappers"
   
        ol_arg=invalid
        for ol_val in auto yes no ; do
@@ -1679,18 +1756,18 @@ if test "${enable_discreteaci+set}" = set; then
                fi
        done
        if test "$ol_arg" = "invalid" ; then
-               { echo "configure: error: bad value $enableval for --enable-discreteaci" 1>&2; exit 1; }
+               { echo "configure: error: bad value $enableval for --enable-wrappers" 1>&2; exit 1; }
        fi
-       ol_enable_discreteaci="$ol_arg"
+       ol_enable_wrappers="$ol_arg"
 
 else
-       ol_enable_discreteaci="no"
+       ol_enable_wrappers="no"
 fi
-# end --enable-discreteaci
-# OpenLDAP --enable-wrappers
-       # Check whether --enable-wrappers or --disable-wrappers was given.
-if test "${enable_wrappers+set}" = set; then
-  enableval="$enable_wrappers"
+# end --enable-wrappers
+# OpenLDAP --enable-dynamic
+       # Check whether --enable-dynamic or --disable-dynamic was given.
+if test "${enable_dynamic+set}" = set; then
+  enableval="$enable_dynamic"
   
        ol_arg=invalid
        for ol_val in auto yes no ; do
@@ -1699,19 +1776,19 @@ if test "${enable_wrappers+set}" = set; then
                fi
        done
        if test "$ol_arg" = "invalid" ; then
-               { echo "configure: error: bad value $enableval for --enable-wrappers" 1>&2; exit 1; }
+               { echo "configure: error: bad value $enableval for --enable-dynamic" 1>&2; exit 1; }
        fi
-       ol_enable_wrappers="$ol_arg"
+       ol_enable_dynamic="$ol_arg"
 
 else
-       ol_enable_wrappers="no"
+       ol_enable_dynamic="no"
 fi
-# end --enable-wrappers
+# end --enable-dynamic
 
-# OpenLDAP --enable-bdb2
-       # Check whether --enable-bdb2 or --disable-bdb2 was given.
-if test "${enable_bdb2+set}" = set; then
-  enableval="$enable_bdb2"
+# OpenLDAP --enable-dnssrv
+       # Check whether --enable-dnssrv or --disable-dnssrv was given.
+if test "${enable_dnssrv+set}" = set; then
+  enableval="$enable_dnssrv"
   
        ol_arg=invalid
        for ol_val in auto yes no ; do
@@ -1720,18 +1797,18 @@ if test "${enable_bdb2+set}" = set; then
                fi
        done
        if test "$ol_arg" = "invalid" ; then
-               { echo "configure: error: bad value $enableval for --enable-bdb2" 1>&2; exit 1; }
+               { echo "configure: error: bad value $enableval for --enable-dnssrv" 1>&2; exit 1; }
        fi
-       ol_enable_bdb2="$ol_arg"
+       ol_enable_dnssrv="$ol_arg"
 
 else
-       ol_enable_bdb2="no"
+       ol_enable_dnssrv="no"
 fi
-# end --enable-bdb2
-# OpenLDAP --with-bdb2_module
-       # Check whether --with-bdb2_module or --without-bdb2_module was given.
-if test "${with_bdb2_module+set}" = set; then
-  withval="$with_bdb2_module"
+# end --enable-dnssrv
+# OpenLDAP --with-dnssrv_module
+       # Check whether --with-dnssrv_module or --without-dnssrv_module was given.
+if test "${with_dnssrv_module+set}" = set; then
+  withval="$with_dnssrv_module"
   
        ol_arg=invalid
        for ol_val in static dynamic ; do
@@ -1740,14 +1817,14 @@ if test "${with_bdb2_module+set}" = set; then
                fi
        done
        if test "$ol_arg" = "invalid" ; then
-               { echo "configure: error: bad value $withval for --with-bdb2_module" 1>&2; exit 1; }
+               { echo "configure: error: bad value $withval for --with-dnssrv_module" 1>&2; exit 1; }
        fi
-       ol_with_bdb2_module="$ol_arg"
+       ol_with_dnssrv_module="$ol_arg"
 
 else
-       ol_with_bdb2_module="static"
+       ol_with_dnssrv_module="static"
 fi
-# end --with-bdb2_module
+# end --with-dnssrv_module
 
 # OpenLDAP --enable-ldap
        # Check whether --enable-ldap or --disable-ldap was given.
@@ -1816,7 +1893,7 @@ if test "${with_ldbm_api+set}" = set; then
   withval="$with_ldbm_api"
   
        ol_arg=invalid
-       for ol_val in auto db2 db mdbm gdbm ndbm manual ; do
+       for ol_val in auto berkeley bcompat mdbm gdbm ; do
                if test "$withval" = "$ol_val" ; then
                        ol_arg="$ol_val"
                fi
@@ -1873,7 +1950,6 @@ else
 fi
 # end --with-ldbm_type
 
-
 # OpenLDAP --enable-passwd
        # Check whether --enable-passwd or --disable-passwd was given.
 if test "${enable_passwd+set}" = set; then
@@ -1915,47 +1991,6 @@ else
 fi
 # end --with-passwd_module
 
-# OpenLDAP --enable-perl
-       # Check whether --enable-perl or --disable-perl was given.
-if test "${enable_perl+set}" = set; then
-  enableval="$enable_perl"
-  
-       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 "configure: error: bad value $enableval for --enable-perl" 1>&2; exit 1; }
-       fi
-       ol_enable_perl="$ol_arg"
-
-else
-       ol_enable_perl="no"
-fi
-# end --enable-perl
-# OpenLDAP --with-perl_module
-       # Check whether --with-perl_module or --without-perl_module was given.
-if test "${with_perl_module+set}" = set; then
-  withval="$with_perl_module"
-  
-       ol_arg=invalid
-       for ol_val in static dynamic ; do
-               if test "$withval" = "$ol_val" ; then
-                       ol_arg="$ol_val"
-               fi
-       done
-       if test "$ol_arg" = "invalid" ; then
-               { echo "configure: error: bad value $withval for --with-perl_module" 1>&2; exit 1; }
-       fi
-       ol_with_perl_module="$ol_arg"
-
-else
-       ol_with_perl_module="static"
-fi
-# end --with-perl_module
-
 # OpenLDAP --enable-shell
        # Check whether --enable-shell or --disable-shell was given.
 if test "${enable_shell+set}" = set; then
@@ -1997,47 +2032,6 @@ else
 fi
 # end --with-shell_module
 
-# OpenLDAP --enable-tcl
-       # Check whether --enable-tcl or --disable-tcl was given.
-if test "${enable_tcl+set}" = set; then
-  enableval="$enable_tcl"
-  
-       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 "configure: error: bad value $enableval for --enable-tcl" 1>&2; exit 1; }
-       fi
-       ol_enable_tcl="$ol_arg"
-
-else
-       ol_enable_tcl="no"
-fi
-# end --enable-tcl
-# OpenLDAP --with-tcl_module
-       # Check whether --with-tcl_module or --without-tcl_module was given.
-if test "${with_tcl_module+set}" = set; then
-  withval="$with_tcl_module"
-  
-       ol_arg=invalid
-       for ol_val in static dynamic ; do
-               if test "$withval" = "$ol_val" ; then
-                       ol_arg="$ol_val"
-               fi
-       done
-       if test "$ol_arg" = "invalid" ; then
-               { echo "configure: error: bad value $withval for --with-tcl_module" 1>&2; exit 1; }
-       fi
-       ol_with_tcl_module="$ol_arg"
-
-else
-       ol_with_tcl_module="static"
-fi
-# end --with-tcl_module
-
 
 # Check whether --with-xxslurpdoptions or --without-xxslurpdoptions was given.
 if test "${with_xxslurpdoptions+set}" = set; then
@@ -2119,20 +2113,11 @@ else
 fi
 
 
-# validate options
-if test $ol_enable_dns = yes ; then
-       if test $ol_enable_referrals = no ; then
-               { echo "configure: error: DNS requires --enable-referrals" 1>&2; exit 1; }
-       fi
-       if test $ol_enable_referrals = auto ; then
-               echo "configure: warning: DNS requires referrals, adding --enable-referrals" 1>&2
-               ol_enable_referrals=yes
-       fi
-fi
 
+# validate options
 if test $ol_enable_slapd = no ; then
-               if test $ol_enable_bdb2 = yes ; then
-               echo "configure: warning: slapd disabled, ignoring --enable-bdb2 argument" 1>&2
+               if test $ol_enable_dnssrv = yes ; then
+               echo "configure: warning: slapd disabled, ignoring --enable-dnssrv argument" 1>&2
        fi
        if test $ol_enable_ldap = yes ; then
                echo "configure: warning: slapd disabled, ignoring --enable-ldap argument" 1>&2
@@ -2143,15 +2128,9 @@ if test $ol_enable_slapd = no ; then
        if test $ol_enable_passwd = yes ; then
                echo "configure: warning: slapd disabled, ignoring --enable-passwd argument" 1>&2
        fi
-       if test $ol_enable_perl = yes ; then
-               echo "configure: warning: slapd disabled, ignoring --enable-perl argument" 1>&2
-       fi
        if test $ol_enable_shell = yes ; then
                echo "configure: warning: slapd disabled, ignoring --enable-shell argument" 1>&2
        fi
-       if test $ol_enable_tcl = yes ; then
-               echo "configure: warning: slapd disabled, ignoring --enable-tcl argument" 1>&2
-       fi
        if test $ol_enable_modules = yes ; then
                echo "configure: warning: slapd disabled, ignoring --enable-modules argument" 1>&2
        fi
@@ -2173,17 +2152,14 @@ if test $ol_enable_slapd = no ; then
        if test $ol_enable_aci = yes ; then
                echo "configure: warning: slapd disabled, ignoring --enable-aci argument" 1>&2
        fi
-       if test $ol_enable_discreteaci = yes ; then
-               echo "configure: warning: slapd disabled, ignoring --enable-discreteaci argument" 1>&2
-       fi
        if test $ol_with_ldbm_api != auto ; then
                echo "configure: warning: slapd disabled, ignoring --with-ldbm-api argument" 1>&2
        fi
        if test $ol_with_ldbm_type != auto ; then
                echo "configure: warning: slapd disabled, ignoring --with-ldbm-type argument" 1>&2
        fi
-       if test $ol_with_bdb2_module != static ; then
-               echo "configure: warning: slapd disabled, ignoring --with-bdb2-module argument" 1>&2
+       if test $ol_with_dnssrv_module != static ; then
+               echo "configure: warning: slapd disabled, ignoring --with-dnssrv-module argument" 1>&2
        fi
        if test $ol_with_ldap_module != static ; then
                echo "configure: warning: slapd disabled, ignoring --with-ldap-module argument" 1>&2
@@ -2194,27 +2170,19 @@ if test $ol_enable_slapd = no ; then
        if test $ol_with_passwd_module != static ; then
                echo "configure: warning: slapd disabled, ignoring --with-passwd-module argument" 1>&2
        fi
-       if test $ol_with_perl_module != static ; then
-               echo "configure: warning: slapd disabled, ignoring --with-perl-module argument" 1>&2
-       fi
        if test $ol_with_shell_module != static ; then
                echo "configure: warning: slapd disabled, ignoring --with-shell-module argument" 1>&2
        fi
-       if test $ol_with_tcl_module != static ; then
-               echo "configure: warning: slapd disabled, ignoring --with-tcl-module argument" 1>&2
-       fi
        if test $ol_enable_slurpd = yes ; then
                { echo "configure: error: slurpd requires slapd" 1>&2; exit 1; }
        fi
 
        # force settings to no
-       ol_enable_bdb2=no
+       ol_enable_dnssrv=no
        ol_enable_ldap=no
        ol_enable_ldbm=no
        ol_enable_passwd=no
-       ol_enable_perl=no
        ol_enable_shell=no
-       ol_enable_tcl=no
 
        ol_enable_modules=no
        ol_enable_multimaster=no
@@ -2222,19 +2190,17 @@ if test $ol_enable_slapd = no ; then
        ol_enable_quipu=no
        ol_enable_rlookups=no
        ol_enable_aci=no
-       ol_enable_discreteaci=no
        ol_enable_wrappers=no
+       ol_enable_dynamic=no
 
        ol_with_ldbm_api=no
        ol_with_ldbm_type=no
 
-       ol_with_bdb2_module=static
+       ol_with_dnssrv_module=static
        ol_with_ldap_module=static
        ol_with_ldbm_module=static
        ol_with_passwd_module=static
-       ol_with_perl_module=static
        ol_with_shell_module=static
-       ol_with_tcl_module=static
 
        ol_enable_slurpd=no
 
@@ -2252,16 +2218,11 @@ elif test $ol_enable_ldbm = no ; then
                echo "configure: warning: LDBM disabled, ignoring --with-ldbm-module argument" 1>&2
        fi
 
-       if test $ol_enable_bdb2 = yes ; then
-               { echo "configure: error: BDB2 requires --enable-ldbm" 1>&2; exit 1; }
-       fi
-
        if test $ol_enable_modules != yes -a \
+               $ol_enable_dnssrv = no -a \
                $ol_enable_ldap = no -a \
                $ol_enable_passwd = no -a \
-               $ol_enable_perl = no -a \
-               $ol_enable_shell = no -a \
-               $ol_enable_tcl = no ; then
+               $ol_enable_shell = no ; then
                { echo "configure: error: slapd requires a backend" 1>&2; exit 1; }
        fi
 
@@ -2269,26 +2230,8 @@ elif test $ol_enable_ldbm = no ; then
        ol_with_ldbm_type=no
        ol_with_ldbm_module=static
 
-elif test $ol_enable_bdb2 = yes ; then
-       
-       if test $ol_with_ldbm_api != auto -a \
-               $ol_with_ldbm_api != db2 ; then
-               { echo "configure: error: BDB2 requires LDBM API DB2" 1>&2; exit 1; }
-       fi
-
-       ol_with_ldbm_api=db2
-
 else
-       
-       if test $ol_enable_bdb2 != no ; then
-               if test $ol_with_ldbm_api != auto -a \
-                       $ol_with_ldbm_api != db2 ; then
-                       echo "configure: warning: BDB2 requires LDBM api db2 or auto" 1>&2
-                       ol_enable_bdb2=no
-               fi
-       fi
-
-       if test $ol_with_ldbm_api = gdbm -a \
+               if test $ol_with_ldbm_api = gdbm -a \
                $ol_with_ldbm_type = btree ; then
                { echo "configure: error: GDBM only supports LDBM type hash" 1>&2; exit 1; }
        fi
@@ -2308,52 +2251,67 @@ if test $ol_enable_slurpd = yes ; then
        fi
 fi
 
+if test $ol_enable_kbind = yes -o $ol_enable_kpasswd = yes ; then
+       if test $ol_with_kerberos = no ; then
+               { echo "configure: error: options require --with-kerberos" 1>&2; exit 1; }
+       fi
+elif test $ol_enable_kbind = no -o $ol_enable_kpasswd = no ; then
+       if test $ol_with_kerberos != auto ; then
+               echo "configure: warning: Kerberos detection enabled unnecessarily" 1>&2;
+       else
+               ol_with_kerberos=no
+       fi
+fi
+
+if test $ol_enable_spasswd = yes ; then
+       if test $ol_with_cyrus_sasl = no ; then
+               { echo "configure: error: options require --with-cyrus-sasl" 1>&2; exit 1; }
+       fi
+       ol_link_spasswd=yes
+fi
+
 echo "$ac_t""done" 1>&6
 
-## Initialize vars
 LDAP_LIBS=
 LDIF_LIBS=
 LDBM_LIBS=
 LTHREAD_LIBS=
 LUTIL_LIBS=
 
+QUIPU_LIBS=
 SLAPD_LIBS=
 SLURPD_LIBS=
 
 BUILD_SLAPD=no
 BUILD_SLURPD=no
 
-BUILD_BDB2=no
+BUILD_QUIPU=no
+BUILD_THREAD=no
+
+BUILD_DNSSRV=no
 BUILD_LDAP=no
 BUILD_LDBM=no
 BUILD_PASSWD=no
-BUILD_PERL=no
-BUILD_QUIPU=no
 BUILD_SHELL=no
-BUILD_TCL=no
-BUILD_THREAD=no
 
-BUILD_BDB2_DYNAMIC=static
+BUILD_DNSSRV_DYNAMIC=static
 BUILD_LDAP_DYNAMIC=static
 BUILD_LDBM_DYNAMIC=static
 BUILD_PASSWD_DYNAMIC=static
-BUILD_PERL_DYNAMIC=static
 BUILD_SHELL_DYNAMIC=static
-BUILD_TCL_DYNAMIC=static
 
 SLAPD_MODULES_LDFLAGS=
 SLAPD_MODULES_CPPFLAGS=
 SLAPD_MODULES_LIST=
 
-SLAPD_PERL_LDFLAGS=
-SLAPD_PERL_CPPFLAGS=
-
-KRB_LIBS=
+KRB4_LIBS=
+KRB5_LIBS=
 READLINE_LIBS=
 SASL_LIBS=
 TERMCAP_LIBS=
 TLS_LIBS=
 MODULES_LIBS=
+AUTH_LIBS=
 
 
 
@@ -2381,7 +2339,7 @@ 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 $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2385: checking for $ac_word" >&5
+echo "configure:2343: checking for $ac_word" >&5
 if eval "test \"\${ac_cv_prog_CC+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2433,7 +2391,7 @@ 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 $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2437: checking for $ac_word" >&5
+echo "configure:2395: checking for $ac_word" >&5
 if eval "test \"\${ac_cv_prog_CC+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2466,6 +2424,7 @@ fi
 
 
 
+
 # Check whether --enable-fast-install or --disable-fast-install was given.
 if test "${enable_fast_install+set}" = set; then
   enableval="$enable_fast_install"
@@ -2492,7 +2451,7 @@ fi
 # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2496: checking for $ac_word" >&5
+echo "configure:2455: checking for $ac_word" >&5
 if eval "test \"\${ac_cv_prog_RANLIB+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2522,7 +2481,7 @@ fi
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2526: checking for $ac_word" >&5
+echo "configure:2485: checking for $ac_word" >&5
 if eval "test \"\${ac_cv_prog_CC+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2552,7 +2511,7 @@ 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 $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2556: checking for $ac_word" >&5
+echo "configure:2515: checking for $ac_word" >&5
 if eval "test \"\${ac_cv_prog_CC+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2603,7 +2562,7 @@ fi
       # Extract the first word of "cl", so it can be a program name with args.
 set dummy cl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2607: checking for $ac_word" >&5
+echo "configure:2566: checking for $ac_word" >&5
 if eval "test \"\${ac_cv_prog_CC+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2635,7 +2594,7 @@ fi
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:2639: checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) works" >&5
+echo "configure:2598: checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -2646,12 +2605,12 @@ cross_compiling=$ac_cv_prog_cc_cross
 
 cat > conftest.$ac_ext << EOF
 
-#line 2650 "configure"
+#line 2609 "configure"
 #include "confdefs.h"
 
 main(){return(0);}
 EOF
-if { (eval echo configure:2655: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2614: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -2677,12 +2636,12 @@ if test $ac_cv_prog_cc_works = no; then
   { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:2681: checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:2640: checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:2686: checking whether we are using GNU C" >&5
+echo "configure:2645: checking whether we are using GNU C" >&5
 if eval "test \"\${ac_cv_prog_gcc+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2691,7 +2650,7 @@ else
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2695: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2654: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -2710,7 +2669,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
 ac_save_CFLAGS="$CFLAGS"
 CFLAGS=
 echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:2714: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:2673: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"\${ac_cv_prog_cc_g+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2753,7 +2712,7 @@ ac_prog=ld
 if test "$ac_cv_prog_gcc" = yes; then
   # Check if gcc -print-prog-name=ld gives a path.
   echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
-echo "configure:2757: checking for ld used by GCC" >&5
+echo "configure:2716: checking for ld used by GCC" >&5
   ac_prog=`($CC -print-prog-name=ld) 2>&5`
   case "$ac_prog" in
     # Accept absolute paths.
@@ -2777,10 +2736,10 @@ echo "configure:2757: checking for ld used by GCC" >&5
   esac
 elif test "$with_gnu_ld" = yes; then
   echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
-echo "configure:2781: checking for GNU ld" >&5
+echo "configure:2740: checking for GNU ld" >&5
 else
   echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
-echo "configure:2784: checking for non-GNU ld" >&5
+echo "configure:2743: checking for non-GNU ld" >&5
 fi
 if eval "test \"\${ac_cv_path_LD+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2814,9 +2773,8 @@ else
   echo "$ac_t""no" 1>&6
 fi
 test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
-
 echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
-echo "configure:2820: checking if the linker ($LD) is GNU ld" >&5
+echo "configure:2778: checking if the linker ($LD) is GNU ld" >&5
 if eval "test \"\${ac_cv_prog_gnu_ld+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2832,7 +2790,7 @@ echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
 
 
 echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
-echo "configure:2836: checking for BSD-compatible nm" >&5
+echo "configure:2794: checking for BSD-compatible nm" >&5
 if eval "test \"\${ac_cv_path_NM+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2867,9 +2825,8 @@ fi
 NM="$ac_cv_path_NM"
 echo "$ac_t""$NM" 1>&6
 
-
 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:2873: checking whether ln -s works" >&5
+echo "configure:2830: checking whether ln -s works" >&5
 if eval "test \"\${ac_cv_prog_LN_S+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2889,6 +2846,17 @@ else
   echo "$ac_t""no" 1>&6
 fi
 
+if test $host != $build; then
+  ac_tool_prefix=${host_alias}-
+else
+  ac_tool_prefix=
+fi
+
+
+case "$target" in
+NONE) lt_target="$host" ;;
+*) lt_target="$target" ;;
+esac
 
 # Check for any special flags to pass to ltconfig.
 libtool_flags="--cache-file=$cache_file"
@@ -2898,7 +2866,7 @@ test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast
 test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
 test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
 libtool_flags="$libtool_flags --enable-dlopen"
-
+libtool_flags="$libtool_flags --enable-win32-dll"
 # Check whether --enable-libtool-lock or --disable-libtool-lock was given.
 if test "${enable_libtool_lock+set}" = set; then
   enableval="$enable_libtool_lock"
@@ -2910,11 +2878,11 @@ test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
 
 # Some flags need to be propagated to the compiler or linker for good
 # libtool support.
-case "$host" in
+case "$lt_target" in
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 2917 "configure"' > conftest.$ac_ext
-  if { (eval echo configure:2918: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  echo '#line 2885 "configure"' > conftest.$ac_ext
+  if { (eval echo configure:2886: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
     case "`/usr/bin/file conftest.o`" in
     *32-bit*)
       LD="${LD-ld} -32"
@@ -2935,19 +2903,19 @@ case "$host" in
   SAVE_CFLAGS="$CFLAGS"
   CFLAGS="$CFLAGS -belf"
   echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
-echo "configure:2939: checking whether the C compiler needs -belf" >&5
+echo "configure:2907: checking whether the C compiler needs -belf" >&5
 if eval "test \"\${lt_cv_cc_needs_belf+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2944 "configure"
+#line 2912 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:2951: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2919: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   lt_cv_cc_needs_belf=yes
 else
@@ -2966,83 +2934,286 @@ echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
   fi
   ;;
 
-
-esac
-
-
-# Save cache, so that ltconfig can load it
-
-
-# Actually configure libtool.  ac_aux_dir is where install-sh is found.
-CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
-LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
-LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
-DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
-${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
-$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
-|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
-
-# Reload cache, that may have been modified by ltconfig
-
-
-# This can be used to rebuild libtool when needed
-LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
-
-# Always use our own libtool.
-LIBTOOL='$(SHELL) $(top_builddir)/libtool'
-
-# Redirect the config.log output again, so that the ltconfig log is not
-# clobbered by the next message.
-exec 5>>./config.log
-
-
-for ac_prog in mawk gawk 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
+*-*-cygwin* | *-*-mingw*)
+  # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3005: checking for $ac_word" >&5
-if eval "test \"\${ac_cv_prog_AWK+set}\" = set"; then
+echo "configure:2942: checking for $ac_word" >&5
+if eval "test \"\${ac_cv_prog_DLLTOOL+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  if test -n "$AWK"; then
-  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+  if test -n "$DLLTOOL"; then
+  ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
 else
   IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
   ac_dummy="$PATH"
   for ac_dir in $ac_dummy; do
     test -z "$ac_dir" && ac_dir=.
     if test -f $ac_dir/$ac_word; then
-      ac_cv_prog_AWK="$ac_prog"
+      ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
       break
     fi
   done
   IFS="$ac_save_ifs"
 fi
 fi
-AWK="$ac_cv_prog_AWK"
-if test -n "$AWK"; then
-  echo "$ac_t""$AWK" 1>&6
+DLLTOOL="$ac_cv_prog_DLLTOOL"
+if test -n "$DLLTOOL"; then
+  echo "$ac_t""$DLLTOOL" 1>&6
 else
   echo "$ac_t""no" 1>&6
 fi
 
-test -n "$AWK" && break
-done
 
-# test for ln hardlink support
-echo $ac_n "checking whether ln works""... $ac_c" 1>&6
-echo "configure:3036: checking whether ln works" >&5
-if eval "test \"\${ol_cv_prog_LN_H+set}\" = set"; then
+if test -z "$ac_cv_prog_DLLTOOL"; then
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2974: checking for $ac_word" >&5
+if eval "test \"\${ac_cv_prog_DLLTOOL+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  rm -f conftest.src conftest.dst
-echo "conftest" > conftest.src
-if ln conftest.src conftest.dst 2>/dev/null
-then
-  ol_cv_prog_LN_H="ln"
+  if test -n "$DLLTOOL"; then
+  ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
 else
-  ol_cv_prog_LN_H="cp"
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_DLLTOOL="dlltool"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_DLLTOOL" && ac_cv_prog_DLLTOOL="false"
+fi
+fi
+DLLTOOL="$ac_cv_prog_DLLTOOL"
+if test -n "$DLLTOOL"; then
+  echo "$ac_t""$DLLTOOL" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+else
+  DLLTOOL="false"
+fi
+fi
+
+  # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
+set dummy ${ac_tool_prefix}as; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3009: checking for $ac_word" >&5
+if eval "test \"\${ac_cv_prog_AS+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$AS"; then
+  ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_AS="${ac_tool_prefix}as"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+AS="$ac_cv_prog_AS"
+if test -n "$AS"; then
+  echo "$ac_t""$AS" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_AS"; then
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "as", so it can be a program name with args.
+set dummy as; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3041: checking for $ac_word" >&5
+if eval "test \"\${ac_cv_prog_AS+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$AS"; then
+  ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_AS="as"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_AS" && ac_cv_prog_AS="false"
+fi
+fi
+AS="$ac_cv_prog_AS"
+if test -n "$AS"; then
+  echo "$ac_t""$AS" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+else
+  AS="false"
+fi
+fi
+
+  # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3076: checking for $ac_word" >&5
+if eval "test \"\${ac_cv_prog_OBJDUMP+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$OBJDUMP"; then
+  ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+OBJDUMP="$ac_cv_prog_OBJDUMP"
+if test -n "$OBJDUMP"; then
+  echo "$ac_t""$OBJDUMP" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_OBJDUMP"; then
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3108: checking for $ac_word" >&5
+if eval "test \"\${ac_cv_prog_OBJDUMP+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$OBJDUMP"; then
+  ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_OBJDUMP="objdump"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_OBJDUMP" && ac_cv_prog_OBJDUMP="false"
+fi
+fi
+OBJDUMP="$ac_cv_prog_OBJDUMP"
+if test -n "$OBJDUMP"; then
+  echo "$ac_t""$OBJDUMP" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+else
+  OBJDUMP="false"
+fi
+fi
+
+  ;;
+
+esac
+
+
+# Save cache, so that ltconfig can load it
+
+
+# Actually configure libtool.  ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $lt_target \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+# Reload cache, that may have been modified by ltconfig
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+
+for ac_prog in mawk gawk 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 $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3176: checking for $ac_word" >&5
+if eval "test \"\${ac_cv_prog_AWK+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_AWK="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+AWK="$ac_cv_prog_AWK"
+if test -n "$AWK"; then
+  echo "$ac_t""$AWK" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$AWK" && break
+done
+
+# test for ln hardlink support
+echo $ac_n "checking whether ln works""... $ac_c" 1>&6
+echo "configure:3207: checking whether ln works" >&5
+if eval "test \"\${ol_cv_prog_LN_H+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  rm -f conftest.src conftest.dst
+echo "conftest" > conftest.src
+if ln conftest.src conftest.dst 2>/dev/null
+then
+  ol_cv_prog_LN_H="ln"
+else
+  ol_cv_prog_LN_H="cp"
 fi
 rm -f conftest.src conftest.dst
 
@@ -3055,7 +3226,7 @@ else
 fi
 
 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:3059: checking whether ln -s works" >&5
+echo "configure:3230: checking whether ln -s works" >&5
 if eval "test \"\${ac_cv_prog_LN_S+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3083,7 +3254,7 @@ fi
 # Extract the first word of "sendmail", so it can be a program name with args.
 set dummy sendmail; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3087: checking for $ac_word" >&5
+echo "configure:3258: checking for $ac_word" >&5
 if eval "test \"\${ac_cv_path_SENDMAIL+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3091,7 +3262,7 @@ else
   /*)
   ac_cv_path_SENDMAIL="$SENDMAIL" # Let the user override the test with a path.
   ;;
-  ?:/*)                         
+  ?:/*)
   ac_cv_path_SENDMAIL="$SENDMAIL" # Let the user override the test with a dos path.
   ;;
   *)
@@ -3119,7 +3290,7 @@ fi
 # Extract the first word of "vi", so it can be a program name with args.
 set dummy vi; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3123: checking for $ac_word" >&5
+echo "configure:3294: checking for $ac_word" >&5
 if eval "test \"\${ac_cv_path_EDITOR+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3127,7 +3298,7 @@ else
   /*)
   ac_cv_path_EDITOR="$EDITOR" # Let the user override the test with a path.
   ;;
-  ?:/*)                         
+  ?:/*)
   ac_cv_path_EDITOR="$EDITOR" # Let the user override the test with a dos path.
   ;;
   *)
@@ -3155,7 +3326,7 @@ fi
 # Extract the first word of "finger", so it can be a program name with args.
 set dummy finger; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3159: checking for $ac_word" >&5
+echo "configure:3330: checking for $ac_word" >&5
 if eval "test \"\${ac_cv_path_FINGER+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3163,7 +3334,7 @@ else
   /*)
   ac_cv_path_FINGER="$FINGER" # Let the user override the test with a path.
   ;;
-  ?:/*)                         
+  ?:/*)
   ac_cv_path_FINGER="$FINGER" # Let the user override the test with a dos path.
   ;;
   *)
@@ -3189,60 +3360,8 @@ else
 fi
 
 
-ol_link_perl=no
-if test $ol_enable_perl != no ; then
-       # Extract the first word of "perl", so it can be a program name with args.
-set dummy perl; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3198: checking for $ac_word" >&5
-if eval "test \"\${ac_cv_path_PERLBIN+set}\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  case "$PERLBIN" in
-  /*)
-  ac_cv_path_PERLBIN="$PERLBIN" # Let the user override the test with a path.
-  ;;
-  ?:/*)                         
-  ac_cv_path_PERLBIN="$PERLBIN" # Let the user override the test with a dos path.
-  ;;
-  *)
-  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
-  ac_dummy="$PATH"
-  for ac_dir in $ac_dummy; do 
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$ac_word; then
-      ac_cv_path_PERLBIN="$ac_dir/$ac_word"
-      break
-    fi
-  done
-  IFS="$ac_save_ifs"
-  test -z "$ac_cv_path_PERLBIN" && ac_cv_path_PERLBIN="/usr/bin/perl"
-  ;;
-esac
-fi
-PERLBIN="$ac_cv_path_PERLBIN"
-if test -n "$PERLBIN"; then
-  echo "$ac_t""$PERLBIN" 1>&6
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-
-       if test "no$PERLBIN" = "no" ; then
-               if test $ol_enable_perl = yes ; then
-                       { echo "configure: error: could not locate perl" 1>&2; exit 1; }
-               fi
-
-       else
-               SLAPD_PERL_LDFLAGS="`$PERLBIN -MExtUtils::Embed -e ldopts|sed -e s/-lc//`"
-               SLAPD_PERL_CPPFLAGS="`$PERLBIN -MExtUtils::Embed -e ccopts`"
-
-                               ol_link_perl=yes
-       fi
-fi
-
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:3246: checking how to run the C preprocessor" >&5
+echo "configure:3365: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -3257,13 +3376,13 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 3261 "configure"
+#line 3380 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3267: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3386: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -3274,13 +3393,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 3278 "configure"
+#line 3397 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3284: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3403: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -3291,13 +3410,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat > conftest.$ac_ext <<EOF
-#line 3295 "configure"
+#line 3414 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3301: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3420: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -3335,9 +3454,9 @@ elif test $cross_compiling = yes -a $ol_enable_x_compile = no; then
 fi
 
 echo $ac_n "checking for AIX""... $ac_c" 1>&6
-echo "configure:3339: checking for AIX" >&5
+echo "configure:3458: checking for AIX" >&5
 cat > conftest.$ac_ext <<EOF
-#line 3341 "configure"
+#line 3460 "configure"
 #include "confdefs.h"
 #ifdef _AIX
   yes
@@ -3359,7 +3478,7 @@ rm -f conftest*
 
 
 echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
-echo "configure:3363: checking for POSIXized ISC" >&5
+echo "configure:3482: checking for POSIXized ISC" >&5
 if test -d /etc/conf/kconfig.d &&
   grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
 then
@@ -3381,17 +3500,17 @@ fi
 
 ac_safe=`echo "minix/config.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for minix/config.h""... $ac_c" 1>&6
-echo "configure:3385: checking for minix/config.h" >&5
+echo "configure:3504: checking for minix/config.h" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3390 "configure"
+#line 3509 "configure"
 #include "confdefs.h"
 #include <minix/config.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3395: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3514: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3430,12 +3549,12 @@ fi
 
 
 echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
-echo "configure:3434: checking for Cygwin environment" >&5
+echo "configure:3553: checking for Cygwin environment" >&5
 if eval "test \"\${ac_cv_cygwin+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3439 "configure"
+#line 3558 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -3446,7 +3565,7 @@ int main() {
 return __CYGWIN__;
 ; return 0; }
 EOF
-if { (eval echo configure:3450: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3569: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_cygwin=yes
 else
@@ -3462,19 +3581,19 @@ echo "$ac_t""$ac_cv_cygwin" 1>&6
 CYGWIN=
 test "$ac_cv_cygwin" = yes && CYGWIN=yes
 echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
-echo "configure:3466: checking for mingw32 environment" >&5
+echo "configure:3585: checking for mingw32 environment" >&5
 if eval "test \"\${ac_cv_mingw32+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3471 "configure"
+#line 3590 "configure"
 #include "confdefs.h"
 
 int main() {
 return __MINGW32__;
 ; return 0; }
 EOF
-if { (eval echo configure:3478: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3597: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_mingw32=yes
 else
@@ -3490,19 +3609,19 @@ echo "$ac_t""$ac_cv_mingw32" 1>&6
 MINGW32=
 test "$ac_cv_mingw32" = yes && MINGW32=yes
 echo $ac_n "checking for EMX OS/2 environment""... $ac_c" 1>&6
-echo "configure:3494: checking for EMX OS/2 environment" >&5
+echo "configure:3613: checking for EMX OS/2 environment" >&5
 if eval "test \"\${ac_cv_emxos2+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3499 "configure"
+#line 3618 "configure"
 #include "confdefs.h"
 
 int main() {
 return __EMX__;
 ; return 0; }
 EOF
-if { (eval echo configure:3506: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3625: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_emxos2=yes
 else
@@ -3521,7 +3640,7 @@ test "$ac_cv_emxos2" = yes && EMXOS2=yes
 
 
 echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
-echo "configure:3525: checking for executable suffix" >&5
+echo "configure:3644: checking for executable suffix" >&5
 if eval "test \"\${ac_cv_exeext+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3531,7 +3650,7 @@ else
   rm -f conftest*
   echo 'int main () { return 0; }' > conftest.$ac_ext
   ac_cv_exeext=
-  if { (eval echo configure:3535: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+  if { (eval echo configure:3654: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
     for file in conftest.*; do
       case $file in
       *.c | *.C | *.o | *.obj | *.xcoff) ;;
@@ -3552,13 +3671,13 @@ echo "$ac_t""${ac_cv_exeext}" 1>&6
 ac_exeext=$EXEEXT
 
 echo $ac_n "checking for object suffix""... $ac_c" 1>&6
-echo "configure:3556: checking for object suffix" >&5
+echo "configure:3675: checking for object suffix" >&5
 if eval "test \"\${ac_cv_objext+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   rm -f conftest*
 echo 'int i = 1;' > conftest.$ac_ext
-if { (eval echo configure:3562: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3681: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   for ac_file in conftest.*; do
     case $ac_file in
     *.c) ;;
@@ -3582,7 +3701,7 @@ EOF
 
 
 echo $ac_n "checking for be_app in -lbe""... $ac_c" 1>&6
-echo "configure:3586: checking for be_app in -lbe" >&5
+echo "configure:3705: checking for be_app in -lbe" >&5
 ac_lib_var=`echo be'_'be_app | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3590,7 +3709,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lbe -lroot -lnet $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3594 "configure"
+#line 3713 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3601,7 +3720,7 @@ int main() {
 be_app()
 ; return 0; }
 EOF
-if { (eval echo configure:3605: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3724: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3627,7 +3746,7 @@ fi
 
 
 echo $ac_n "checking for ${CC-cc} option to accept ANSI C""... $ac_c" 1>&6
-echo "configure:3631: checking for ${CC-cc} option to accept ANSI C" >&5
+echo "configure:3750: checking for ${CC-cc} option to accept ANSI C" >&5
 if eval "test \"\${am_cv_prog_cc_stdc+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3644,7 +3763,7 @@ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIO
 do
   CC="$ac_save_CC $ac_arg"
   cat > conftest.$ac_ext <<EOF
-#line 3648 "configure"
+#line 3767 "configure"
 #include "confdefs.h"
 #include <stdarg.h>
 #include <stdio.h>
@@ -3681,7 +3800,7 @@ return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
 
 ; return 0; }
 EOF
-if { (eval echo configure:3685: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3804: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   am_cv_prog_cc_stdc="$ac_arg"; break
 else
@@ -3715,7 +3834,7 @@ if test -z "${MKDEP}"; then
        OL_MKDEP="${CC-cc}"
        if test -z "${MKDEP_FLAGS}"; then
                echo $ac_n "checking for ${OL_MKDEP} depend flag""... $ac_c" 1>&6
-echo "configure:3719: checking for ${OL_MKDEP} depend flag" >&5
+echo "configure:3838: checking for ${OL_MKDEP} depend flag" >&5
 if eval "test \"\${ol_cv_mkdep+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3725,7 +3844,7 @@ else
                                cat > conftest.c <<EOF
  noCode;
 EOF
-                               if { ac_try='$OL_MKDEP $flag conftest.c'; { (eval echo configure:3729: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } \
+                               if { ac_try='$OL_MKDEP $flag conftest.c'; { (eval echo configure:3848: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } \
                                        | egrep '^conftest\.'"${ac_objext}" >/dev/null 2>&1
                                then
                                        if test ! -f conftest."${ac_object}" ; then
@@ -3757,64 +3876,224 @@ if test "${ol_cv_mkdep}" = no ; then
        echo "configure: warning: do not know how to generate dependencies" 1>&2
 fi
 
-ol_link_modules=no
-if test $ol_enable_modules != no ; then
-       for ac_hdr in ltdl.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:3767: checking for $ac_hdr" >&5
-if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
+echo $ac_n "checking for afopen in -ls""... $ac_c" 1>&6
+echo "configure:3881: checking for afopen in -ls" >&5
+ac_lib_var=`echo s'_'afopen | sed 'y%./+-:%__p__%'`
+if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  cat > conftest.$ac_ext <<EOF
-#line 3772 "configure"
+  ac_save_LIBS="$LIBS"
+LIBS="-ls  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3889 "configure"
 #include "confdefs.h"
-#include <$ac_hdr>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char afopen();
+
+int main() {
+afopen()
+; return 0; }
 EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3777: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
+if { (eval echo configure:3900: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
-  eval "ac_cv_header_$ac_safe=yes"
+  eval "ac_cv_lib_$ac_lib_var=yes"
 else
-  echo "$ac_err" >&5
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  eval "ac_cv_header_$ac_safe=no"
+  eval "ac_cv_lib_$ac_lib_var=no"
 fi
 rm -f conftest*
+LIBS="$ac_save_LIBS"
+
 fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
+  
+       AUTH_LIBS=-ls
+       cat >> confdefs.h <<\EOF
+#define HAVE_AIX_SECURITY 1
 EOF
+
+
 else
   echo "$ac_t""no" 1>&6
 fi
-done
 
 
-       if test $ac_cv_header_ltdl_h = no ; then
-               { echo "configure: error: could not locate libtool ltdl.h" 1>&2; exit 1; }
-
-       fi
 
-       echo $ac_n "checking for lt_dlinit in -lltdl""... $ac_c" 1>&6
-echo "configure:3810: checking for lt_dlinit in -lltdl" >&5
-ac_lib_var=`echo ltdl'_'lt_dlinit | sed 'y%./+-:%__p__%'`
+for ac_func in getaddrinfo 
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3931: checking for $ac_func" >&5
+if eval "test \"\${ac_cv_func_$ac_func+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3936 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* 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();
+char (*f)();
+
+int main() {
+
+/* 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
+f = $ac_func;
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3960: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+if test $ac_cv_func_getaddrinfo = no ; then
+       if test $ol_enable_ipv6 = yes ; then
+               { echo "configure: error: IPv6 support requires getaddrinfo()" 1>&2; exit 1; }
+       fi
+       ol_enable_ipv6=no
+fi
+
+if test $ol_enable_unix != no ; then
+       for ac_hdr in sys/un.h 
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:3997: checking for $ac_hdr" >&5
+if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 4002 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4007: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+       if test $ol_enable_unix = auto ; then
+               ol_enable_unix=$ac_cv_header_sys_un_h
+       elif test $ac_cv_header_sys_un_h = no ; then
+               { echo "configure: error: UNIX domain support requires sys/un.h" 1>&2; exit 1; }
+       fi
+fi
+
+ol_link_modules=no
+if test $ol_enable_modules != no ; then
+       for ac_hdr in ltdl.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:4047: checking for $ac_hdr" >&5
+if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 4052 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4057: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+       if test $ac_cv_header_ltdl_h = no ; then
+               { echo "configure: error: could not locate libtool ltdl.h" 1>&2; exit 1; }
+       fi
+
+       echo $ac_n "checking for lt_dlinit in -lltdl""... $ac_c" 1>&6
+echo "configure:4089: checking for lt_dlinit in -lltdl" >&5
+ac_lib_var=`echo ltdl'_'lt_dlinit | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lltdl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3818 "configure"
+#line 4097 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3825,7 +4104,7 @@ int main() {
 lt_dlinit()
 ; return 0; }
 EOF
-if { (eval echo configure:3829: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4108: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3840,41 +4119,39 @@ LIBS="$ac_save_LIBS"
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo ltdl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
-    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
+  
+           MODULES_LIBS=-lltdl
+           cat >> confdefs.h <<\EOF
+#define HAVE_LIBLTDL 1
 EOF
 
-  LIBS="-lltdl $LIBS"
-
+       
 else
   echo "$ac_t""no" 1>&6
 fi
 
+
        if test "$ac_cv_lib_ltdl_lt_dlinit" = no ; then
                { echo "configure: error: could not locate libtool -lltdl" 1>&2; exit 1; }
        fi
        ol_link_modules=yes
 else
-       ol_with_bdb2_module=static
+       ol_with_dnssrv_module=static
        ol_with_ldap_module=static
        ol_with_ldbm_module=static
        ol_with_passwd_module=static
-       ol_with_perl_module=static
        ol_with_shell_module=static
-       ol_with_tcl_module=static
 fi
 
 # test for EBCDIC
 echo $ac_n "checking for EBCDIC""... $ac_c" 1>&6
-echo "configure:3872: checking for EBCDIC" >&5
+echo "configure:4149: checking for EBCDIC" >&5
 if eval "test \"\${ol_cv_cpp_ebcdic+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
        cat > conftest.$ac_ext <<EOF
-#line 3878 "configure"
+#line 4155 "configure"
 #include "confdefs.h"
 
 #if !('M' == 0xd4)
@@ -3883,7 +4160,7 @@ else
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3887: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4164: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3907,12 +4184,12 @@ EOF
 fi
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:3911: checking for ANSI C header files" >&5
+echo "configure:4188: checking for ANSI C header files" >&5
 if eval "test \"\${ol_cv_header_stdc+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3916 "configure"
+#line 4193 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -3920,7 +4197,7 @@ else
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3924: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4201: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3937,7 +4214,7 @@ rm -f conftest*
 if test $ol_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 3941 "configure"
+#line 4218 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -3955,7 +4232,7 @@ fi
 if test $ol_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 3959 "configure"
+#line 4236 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -3976,7 +4253,7 @@ if test "$cross_compiling" = yes; then
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 3980 "configure"
+#line 4257 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #ifndef HAVE_EBCDIC
@@ -3994,7 +4271,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
 exit (0); }
 
 EOF
-if { (eval echo configure:3998: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4275: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -4028,12 +4305,12 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
-echo "configure:4032: checking for $ac_hdr that defines DIR" >&5
+echo "configure:4309: checking for $ac_hdr that defines DIR" >&5
 if eval "test \"\${ac_cv_header_dirent_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4037 "configure"
+#line 4314 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <$ac_hdr>
@@ -4041,7 +4318,7 @@ int main() {
 DIR *dirp = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:4045: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4322: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   eval "ac_cv_header_dirent_$ac_safe=yes"
 else
@@ -4066,7 +4343,7 @@ done
 # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
 if test $ac_header_dirent = dirent.h; then
 echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
-echo "configure:4070: checking for opendir in -ldir" >&5
+echo "configure:4347: checking for opendir in -ldir" >&5
 ac_lib_var=`echo dir'_'opendir | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -4074,7 +4351,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ldir  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4078 "configure"
+#line 4355 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -4085,7 +4362,7 @@ int main() {
 opendir()
 ; return 0; }
 EOF
-if { (eval echo configure:4089: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4366: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4107,7 +4384,7 @@ fi
 
 else
 echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
-echo "configure:4111: checking for opendir in -lx" >&5
+echo "configure:4388: checking for opendir in -lx" >&5
 ac_lib_var=`echo x'_'opendir | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -4115,7 +4392,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lx  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4119 "configure"
+#line 4396 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -4126,7 +4403,7 @@ int main() {
 opendir()
 ; return 0; }
 EOF
-if { (eval echo configure:4130: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4407: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4149,12 +4426,12 @@ fi
 fi
 
 echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
-echo "configure:4153: checking for sys/wait.h that is POSIX.1 compatible" >&5
+echo "configure:4430: checking for sys/wait.h that is POSIX.1 compatible" >&5
 if eval "test \"\${ac_cv_header_sys_wait_h+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4158 "configure"
+#line 4435 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -4170,7 +4447,7 @@ wait (&s);
 s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
 ; return 0; }
 EOF
-if { (eval echo configure:4174: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4451: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_header_sys_wait_h=yes
 else
@@ -4191,12 +4468,12 @@ EOF
 fi
 
 echo $ac_n "checking POSIX termios""... $ac_c" 1>&6
-echo "configure:4195: checking POSIX termios" >&5
+echo "configure:4472: checking POSIX termios" >&5
 if eval "test \"\${am_cv_sys_posix_termios+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4200 "configure"
+#line 4477 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <unistd.h>
@@ -4206,7 +4483,7 @@ int main() {
    tcgetattr(0, 0);
 ; return 0; }
 EOF
-if { (eval echo configure:4210: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4487: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   am_cv_sys_posix_termios=yes
 else
@@ -4222,7 +4499,7 @@ echo "$ac_t""$am_cv_sys_posix_termios" 1>&6
 
 
  echo $ac_n "checking whether use of TIOCGWINSZ requires sys/ioctl.h""... $ac_c" 1>&6
-echo "configure:4226: checking whether use of TIOCGWINSZ requires sys/ioctl.h" >&5
+echo "configure:4503: checking whether use of TIOCGWINSZ requires sys/ioctl.h" >&5
 if eval "test \"\${am_cv_sys_tiocgwinsz_needs_sys_ioctl_h+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4231,7 +4508,7 @@ else
   gwinsz_in_termios_h=no
   if test $am_cv_sys_posix_termios = yes; then
     cat > conftest.$ac_ext <<EOF
-#line 4235 "configure"
+#line 4512 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #     include <termios.h>
@@ -4251,7 +4528,7 @@ rm -f conftest*
 
   if test $gwinsz_in_termios_h = no; then
     cat > conftest.$ac_ext <<EOF
-#line 4255 "configure"
+#line 4532 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #     include <sys/ioctl.h>
@@ -4290,12 +4567,15 @@ for ac_hdr in \
        arpa/inet.h             \
        arpa/nameser.h  \
        assert.h                \
+       conio.h                 \
        crypt.h                 \
+       direct.h                \
        errno.h                 \
        fcntl.h                 \
        filio.h                 \
        getopt.h                \
        grp.h                   \
+       io.h                    \
        libutil.h               \
        limits.h                \
        locale.h                \
@@ -4304,6 +4584,7 @@ for ac_hdr in \
        memory.h                \
        psap.h                  \
        pwd.h                   \
+       process.h               \
        resolv.h                \
        sgtty.h                 \
        shadow.h                \
@@ -4325,21 +4606,22 @@ for ac_hdr in \
        syslog.h                \
        termios.h               \
        unistd.h                \
+       winsock.h               \
 
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:4333: checking for $ac_hdr" >&5
+echo "configure:4615: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4338 "configure"
+#line 4620 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4343: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4625: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -4368,13 +4650,107 @@ done
 
 
 
+echo $ac_n "checking for sigset in -lV3""... $ac_c" 1>&6
+echo "configure:4655: checking for sigset in -lV3" >&5
+ac_lib_var=`echo V3'_'sigset | sed 'y%./+-:%__p__%'`
+if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lV3  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4663 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char sigset();
+
+int main() {
+sigset()
+; return 0; }
+EOF
+if { (eval echo configure:4674: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo V3 | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lV3 $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+if test $ac_cv_header_winsock_h = yes; then
+       echo $ac_n "checking for winsock""... $ac_c" 1>&6
+echo "configure:4704: checking for winsock" >&5
+if eval "test \"\${ol_cv_winsock+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 4709 "configure"
+#include "confdefs.h"
+#include <winsock.h>
+int main() {
+
+                       socket(0,0,0);
+                       select(0,NULL,NULL,NULL,NULL);
+                       closesocket(0);
+                       gethostname(NULL,0);
+       
+; return 0; }
+EOF
+if { (eval echo configure:4721: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ol_cv_winsock=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ol_cv_winsock=no
+fi
+rm -f conftest*]
+fi
+
+echo "$ac_t""$ol_cv_winsock" 1>&6
+
+       if test $ol_cv_winsock = yes ; then
+               cat >> confdefs.h <<\EOF
+#define HAVE_WINSOCK 1
+EOF
+
+               ac_cv_func_socket=yes
+               ac_cv_func_select=yes
+               ac_cv_func_closesocket=yes
+               ac_cv_func_gethostname=yes
+       fi
+fi
+
+
 echo $ac_n "checking for socket""... $ac_c" 1>&6
-echo "configure:4373: checking for socket" >&5
+echo "configure:4749: checking for socket" >&5
 if eval "test \"\${ac_cv_func_socket+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4378 "configure"
+#line 4754 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char socket(); below.  */
@@ -4398,7 +4774,7 @@ f = socket;
 
 ; return 0; }
 EOF
-if { (eval echo configure:4402: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4778: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_socket=yes"
 else
@@ -4417,7 +4793,7 @@ else
   echo "$ac_t""no" 1>&6
        
        echo $ac_n "checking for main in -lsocket""... $ac_c" 1>&6
-echo "configure:4421: checking for main in -lsocket" >&5
+echo "configure:4797: checking for main in -lsocket" >&5
 ac_lib_var=`echo socket'_'main | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -4425,14 +4801,14 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsocket  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4429 "configure"
+#line 4805 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:4436: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4812: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4460,7 +4836,7 @@ else
 fi
 
        echo $ac_n "checking for main in -lnet""... $ac_c" 1>&6
-echo "configure:4464: checking for main in -lnet" >&5
+echo "configure:4840: checking for main in -lnet" >&5
 ac_lib_var=`echo net'_'main | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -4468,14 +4844,14 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lnet  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4472 "configure"
+#line 4848 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:4479: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4855: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4502,27 +4878,23 @@ else
   echo "$ac_t""no" 1>&6
 fi
 
-       echo $ac_n "checking for socket in -lnet""... $ac_c" 1>&6
-echo "configure:4507: checking for socket in -lnet" >&5
-ac_lib_var=`echo net'_'socket | sed 'y%./+-:%__p__%'`
+       echo $ac_n "checking for main in -lnsl_s""... $ac_c" 1>&6
+echo "configure:4883: checking for main in -lnsl_s" >&5
+ac_lib_var=`echo nsl_s'_'main | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="-lnet  $LIBS"
+LIBS="-lnsl_s  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4515 "configure"
+#line 4891 "configure"
 #include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error.  */
-/* We use char because int might match the return type of a gcc2
-    builtin and then its argument prototype would still apply.  */
-char socket();
 
 int main() {
-socket()
+main()
 ; return 0; }
 EOF
-if { (eval echo configure:4526: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4898: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4537,35 +4909,35 @@ LIBS="$ac_save_LIBS"
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo net | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    ac_tr_lib=HAVE_LIB`echo nsl_s | sed -e 's/[^a-zA-Z0-9_]/_/g' \
     -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
   cat >> confdefs.h <<EOF
 #define $ac_tr_lib 1
 EOF
 
-  LIBS="-lnet $LIBS"
+  LIBS="-lnsl_s $LIBS"
 
 else
   echo "$ac_t""no" 1>&6
 fi
 
-       echo $ac_n "checking for main in -lnsl_s""... $ac_c" 1>&6
-echo "configure:4554: checking for main in -lnsl_s" >&5
-ac_lib_var=`echo nsl_s'_'main | sed 'y%./+-:%__p__%'`
+       echo $ac_n "checking for main in -lnsl""... $ac_c" 1>&6
+echo "configure:4926: checking for main in -lnsl" >&5
+ac_lib_var=`echo nsl'_'main | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="-lnsl_s  $LIBS"
+LIBS="-lnsl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4562 "configure"
+#line 4934 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:4569: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4941: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4580,35 +4952,39 @@ LIBS="$ac_save_LIBS"
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo nsl_s | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
     -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
   cat >> confdefs.h <<EOF
 #define $ac_tr_lib 1
 EOF
 
-  LIBS="-lnsl_s $LIBS"
+  LIBS="-lnsl $LIBS"
 
 else
   echo "$ac_t""no" 1>&6
 fi
 
-       echo $ac_n "checking for main in -lnsl""... $ac_c" 1>&6
-echo "configure:4597: checking for main in -lnsl" >&5
-ac_lib_var=`echo nsl'_'main | sed 'y%./+-:%__p__%'`
+       echo $ac_n "checking for socket in -linet""... $ac_c" 1>&6
+echo "configure:4969: checking for socket in -linet" >&5
+ac_lib_var=`echo inet'_'socket | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="-lnsl  $LIBS"
+LIBS="-linet  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4605 "configure"
+#line 4977 "configure"
 #include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char socket();
 
 int main() {
-main()
+socket()
 ; return 0; }
 EOF
-if { (eval echo configure:4612: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4988: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4623,54 +4999,7 @@ LIBS="$ac_save_LIBS"
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
-    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
-  LIBS="-lnsl $LIBS"
-
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-       echo $ac_n "checking for socket in -linet""... $ac_c" 1>&6
-echo "configure:4640: checking for socket in -linet" >&5
-ac_lib_var=`echo inet'_'socket | sed 'y%./+-:%__p__%'`
-if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  ac_save_LIBS="$LIBS"
-LIBS="-linet  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 4648 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error.  */
-/* We use char because int might match the return type of a gcc2
-    builtin and then its argument prototype would still apply.  */
-char socket();
-
-int main() {
-socket()
-; return 0; }
-EOF
-if { (eval echo configure:4659: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo inet | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    ac_tr_lib=HAVE_LIB`echo inet | sed -e 's/[^a-zA-Z0-9_]/_/g' \
     -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
   cat >> confdefs.h <<EOF
 #define $ac_tr_lib 1
@@ -4683,7 +5012,7 @@ else
 fi
 
        echo $ac_n "checking for main in -lgen""... $ac_c" 1>&6
-echo "configure:4687: checking for main in -lgen" >&5
+echo "configure:5016: checking for main in -lgen" >&5
 ac_lib_var=`echo gen'_'main | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -4691,14 +5020,14 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lgen  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4695 "configure"
+#line 5024 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:4702: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5031: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4730,12 +5059,12 @@ fi
 
 
 echo $ac_n "checking for select""... $ac_c" 1>&6
-echo "configure:4734: checking for select" >&5
+echo "configure:5063: checking for select" >&5
 if eval "test \"\${ac_cv_func_select+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4739 "configure"
+#line 5068 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char select(); below.  */
@@ -4759,7 +5088,7 @@ f = select;
 
 ; return 0; }
 EOF
-if { (eval echo configure:4763: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5092: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_select=yes"
 else
@@ -4780,8 +5109,9 @@ else
 fi
 
 
-echo $ac_n "checking types of arguments for select()""... $ac_c" 1>&6
-echo "configure:4785: checking types of arguments for select()" >&5
+if test "${ac_cv_header_winsock_h}" != yes; then
+                echo $ac_n "checking types of arguments for select()""... $ac_c" 1>&6
+echo "configure:5115: checking types of arguments for select()" >&5
  if eval "test \"\${ac_cv_func_select_arg234+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4795,7 +5125,7 @@ else
      for ac_cv_func_select_arg1 in 'int' 'size_t' 'unsigned long' 'unsigned'; do
       for ac_cv_func_select_arg5 in 'struct timeval *' 'const struct timeval *'; do
        cat > conftest.$ac_ext <<EOF
-#line 4799 "configure"
+#line 5129 "configure"
 #include "confdefs.h"
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -4814,7 +5144,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:4818: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5148: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
           ac_not_found=no ; break 3
 else
@@ -4852,23 +5182,24 @@ EOF
 EOF
 
 
+fi
 
 
 for ac_hdr in regex.h 
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:4862: checking for $ac_hdr" >&5
+echo "configure:5193: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4867 "configure"
+#line 5198 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4872: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:5203: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -4898,12 +5229,12 @@ if test "$ac_cv_header_regex_h" != yes ; then
        { echo "configure: error: POSIX regex.h required." 1>&2; exit 1; }
 fi
 echo $ac_n "checking for regfree""... $ac_c" 1>&6
-echo "configure:4902: checking for regfree" >&5
+echo "configure:5233: checking for regfree" >&5
 if eval "test \"\${ac_cv_func_regfree+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4907 "configure"
+#line 5238 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char regfree(); below.  */
@@ -4927,7 +5258,7 @@ f = regfree;
 
 ; return 0; }
 EOF
-if { (eval echo configure:4931: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5262: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_regfree=yes"
 else
@@ -4950,7 +5281,7 @@ fi
 
 
 echo $ac_n "checking for compatible POSIX regex""... $ac_c" 1>&6
-echo "configure:4954: checking for compatible POSIX regex" >&5
+echo "configure:5285: checking for compatible POSIX regex" >&5
 if eval "test \"\${ol_cv_c_posix_regex+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4959,7 +5290,7 @@ else
   ol_cv_c_posix_regex=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 4963 "configure"
+#line 5294 "configure"
 #include "confdefs.h"
 
 #include <sys/types.h>
@@ -4985,7 +5316,7 @@ main()
        return rc;
 }
 EOF
-if { (eval echo configure:4989: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:5320: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ol_cv_c_posix_regex=yes
 else
@@ -5005,69 +5336,22 @@ if test "$ol_cv_c_posix_regex" = no ; then
        { echo "configure: error: broken POSIX regex!" 1>&2; exit 1; }
 fi
 
-echo $ac_n "checking for sigset in -lV3""... $ac_c" 1>&6
-echo "configure:5010: checking for sigset in -lV3" >&5
-ac_lib_var=`echo V3'_'sigset | sed 'y%./+-:%__p__%'`
-if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  ac_save_LIBS="$LIBS"
-LIBS="-lV3  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 5018 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error.  */
-/* We use char because int might match the return type of a gcc2
-    builtin and then its argument prototype would still apply.  */
-char sigset();
-
-int main() {
-sigset()
-; return 0; }
-EOF
-if { (eval echo configure:5029: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo V3 | sed -e 's/[^a-zA-Z0-9_]/_/g' \
-    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
-  LIBS="-lV3 $LIBS"
-
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-
-echo $ac_n "checking for res_search""... $ac_c" 1>&6
-echo "configure:5058: checking for res_search" >&5
-if eval "test \"\${ac_cv_func_res_search+set}\" = set"; then
+ol_link_dnssrv=no
+echo $ac_n "checking for res_query""... $ac_c" 1>&6
+echo "configure:5342: checking for res_query" >&5
+if eval "test \"\${ac_cv_func_res_query+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5063 "configure"
+#line 5347 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char res_search(); below.  */
+    which can conflict with char res_query(); below.  */
 #include <assert.h>
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
-char res_search();
+char res_query();
 char (*f)();
 
 int main() {
@@ -5075,55 +5359,55 @@ int main() {
 /* 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_res_search) || defined (__stub___res_search)
+#if defined (__stub_res_query) || defined (__stub___res_query)
 choke me
 #else
-f = res_search;
+f = res_query;
 #endif
 
 ; return 0; }
 EOF
-if { (eval echo configure:5087: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5371: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
-  eval "ac_cv_func_res_search=yes"
+  eval "ac_cv_func_res_query=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  eval "ac_cv_func_res_search=no"
+  eval "ac_cv_func_res_query=no"
 fi
 rm -f conftest*
 fi
 
-if eval "test \"`echo '$ac_cv_func_'res_search`\" = yes"; then
+if eval "test \"`echo '$ac_cv_func_'res_query`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   :
 else
   echo "$ac_t""no" 1>&6
 fi
 
-if test $ac_cv_func_res_search = no ; then 
-       echo $ac_n "checking for res_search in -lbind""... $ac_c" 1>&6
-echo "configure:5108: checking for res_search in -lbind" >&5
-ac_lib_var=`echo bind'_'res_search | sed 'y%./+-:%__p__%'`
+if test $ac_cv_func_res_query = no ; then 
+       echo $ac_n "checking for res_query in -lbind""... $ac_c" 1>&6
+echo "configure:5392: checking for res_query in -lbind" >&5
+ac_lib_var=`echo bind'_'res_query | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lbind  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5116 "configure"
+#line 5400 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
-char res_search();
+char res_query();
 
 int main() {
-res_search()
+res_query()
 ; return 0; }
 EOF
-if { (eval echo configure:5127: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5411: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5150,31 +5434,31 @@ else
   echo "$ac_t""no" 1>&6
 fi
 
-       ac_cv_func_res_search=$ac_cv_lib_bind_res_search
+       ac_cv_func_res_query=$ac_cv_lib_bind_res_query
 fi
 
-if test $ac_cv_func_res_search = no ; then 
-       echo $ac_n "checking for __res_search in -lbind""... $ac_c" 1>&6
-echo "configure:5159: checking for __res_search in -lbind" >&5
-ac_lib_var=`echo bind'_'__res_search | sed 'y%./+-:%__p__%'`
+if test $ac_cv_func_res_query = no ; then 
+       echo $ac_n "checking for __res_query in -lbind""... $ac_c" 1>&6
+echo "configure:5443: checking for __res_query in -lbind" >&5
+ac_lib_var=`echo bind'_'__res_query | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lbind  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5167 "configure"
+#line 5451 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
-char __res_search();
+char __res_query();
 
 int main() {
-__res_search()
+__res_query()
 ; return 0; }
 EOF
-if { (eval echo configure:5178: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5462: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5201,31 +5485,31 @@ else
   echo "$ac_t""no" 1>&6
 fi
 
-       ac_cv_func_res_search=$ac_cv_lib_bind___res_search
+       ac_cv_func_res_query=$ac_cv_lib_bind___res_query
 fi
 
-if test $ac_cv_func_res_search = no ; then 
-       echo $ac_n "checking for res_search in -lresolv""... $ac_c" 1>&6
-echo "configure:5210: checking for res_search in -lresolv" >&5
-ac_lib_var=`echo resolv'_'res_search | sed 'y%./+-:%__p__%'`
+if test $ac_cv_func_res_query = no ; then 
+       echo $ac_n "checking for res_query in -lresolv""... $ac_c" 1>&6
+echo "configure:5494: checking for res_query in -lresolv" >&5
+ac_lib_var=`echo resolv'_'res_query | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lresolv  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5218 "configure"
+#line 5502 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
-char res_search();
+char res_query();
 
 int main() {
-res_search()
+res_query()
 ; return 0; }
 EOF
-if { (eval echo configure:5229: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5513: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5252,38 +5536,40 @@ else
   echo "$ac_t""no" 1>&6
 fi
 
-       ac_cv_func_res_search=$ac_cv_lib_resolv_res_search
+       ac_cv_func_res_query=$ac_cv_lib_resolv_res_query
 fi
 
-if test "$ac_cv_func_res_search" = yes ; then
+if test "$ac_cv_func_res_query" = yes ; then
        cat >> confdefs.h <<\EOF
-#define HAVE_RES_SEARCH 1
+#define HAVE_RES_QUERY 1
 EOF
 
-elif test $ol_enable_dns = yes ; then
-       { echo "configure: error: --enable-dns requires res_search" 1>&2; exit 1; }
-elif test $ol_enable_dns != no ; then
-       echo "configure: warning: no res_search, disabling DNS support" 1>&2
+
+       if test $ol_enable_dnssrv != no ; then
+               ol_link_dnssrv=yes
+       fi
 fi
 
+if test "$ol_enable_dnssrv" = yes -a "$ol_link_dnssrv" = no ; then
+       { echo "configure: error: DNSSRV requires res_query()" 1>&2; exit 1; }
+fi
 
-# QUIPU
 if test $ol_enable_quipu != no ; then
        for ac_hdr in quipu/commonarg.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:5277: checking for $ac_hdr" >&5
+echo "configure:5563: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5282 "configure"
+#line 5568 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:5287: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:5573: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -5319,24 +5605,29 @@ done
        fi
 fi
 
-ol_link_kerberos=no
+ol_link_kbind=no
+ol_link_kpasswd=no
+ol_link_krb5=no
+ol_link_krb4=no
 
-if test $ol_with_kerberos = auto -o $ol_with_kerberos = k5 ; then
-       for ac_hdr in kerberosIV/krb.h kerberosIV/des.h
+if test $ol_with_kerberos = auto -o $ol_with_kerberos = k5 \
+       -o $ol_with_kerberos = k5only -o $ol_with_kerberos = k425 ; then
+
+       for ac_hdr in krb5.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:5330: checking for $ac_hdr" >&5
+echo "configure:5621: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5335 "configure"
+#line 5626 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:5340: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:5631: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
 done
 
 
-       if test $ac_cv_header_kerberosIV_krb_h = yes ; then
-               echo $ac_n "checking for main in -lkrb4""... $ac_c" 1>&6
-echo "configure:5369: checking for main in -lkrb4" >&5
-ac_lib_var=`echo krb4'_'main | sed 'y%./+-:%__p__%'`
-if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
+       if test $ac_cv_header_krb5_h = yes ; then
+                               for ac_hdr in heim_err.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:5663: checking for $ac_hdr" >&5
+if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  ac_save_LIBS="$LIBS"
-LIBS="-lkrb4 -lkrb5 -ldes425 $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 5377 "configure"
+  cat > conftest.$ac_ext <<EOF
+#line 5668 "configure"
 #include "confdefs.h"
-
-int main() {
-main()
-; return 0; }
+#include <$ac_hdr>
 EOF
-if { (eval echo configure:5384: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:5673: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
   rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
+  eval "ac_cv_header_$ac_safe=yes"
 else
+  echo "$ac_err" >&5
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
+  eval "ac_cv_header_$ac_safe=no"
 fi
 rm -f conftest*
-LIBS="$ac_save_LIBS"
-
 fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-  have_k5=yes
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
 else
   echo "$ac_t""no" 1>&6
-have_k5=no
 fi
+done
 
+               if test $ac_cv_header_heim_err_h = yes ; then
+                       krb5_impl=heimdal
+               else
+                       krb5_impl=mit
+               fi
 
-               if test $have_k5 = yes ; then
-                       ol_with_kerberos=found
-                       ol_link_kerberos=yes
-
-                       KRB_LIBS="-lkrb4 -lkrb5 -ldes425"
-
-                       LIBS="$KRB_LIBS $LIBS"
-
-                       echo $ac_n "checking for des_debug in Kerberos libraries""... $ac_c" 1>&6
-echo "configure:5415: checking for des_debug in Kerberos libraries" >&5
-if eval "test \"\${ol_cv_var_des_debug+set}\" = set"; then
+               if test $krb5_impl = mit; then
+                       echo $ac_n "checking for main in -lkrb5""... $ac_c" 1>&6
+echo "configure:5707: checking for main in -lkrb5" >&5
+ac_lib_var=`echo krb5'_'main | sed 'y%./+-:%__p__%'`
+if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  
-                                                               save_LIBS="$LIBS"
-                               LIBS="$KRB_LIBS $LIBS"
-                               cat > conftest.$ac_ext <<EOF
-#line 5423 "configure"
+  ac_save_LIBS="$LIBS"
+LIBS="-lkrb5 -lcrypto -lcom_err $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5715 "configure"
 #include "confdefs.h"
 
-#include <kerberosIV/krb.h>
-#include <kerberosIV/des.h>
-extern int des_debug;
-
 int main() {
-
-des_debug = 1;
-
+main()
 ; return 0; }
 EOF
-if { (eval echo configure:5436: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5722: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
-  ol_cv_var_des_debug=yes
+  eval "ac_cv_lib_$ac_lib_var=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  ol_cv_var_des_debug=no
+  eval "ac_cv_lib_$ac_lib_var=no"
 fi
 rm -f conftest*
-                                                               LIBS="$save_LIBS"
-                       
-fi
-
-echo "$ac_t""$ol_cv_var_des_debug" 1>&6
-
-                       if test $ol_cv_var_des_debug = yes ; then
-                               cat >> confdefs.h <<\EOF
-#define HAVE_DES_DEBUG 1
-EOF
-
-                       fi
-
-                       LIBS="$save_LIBS"
-               fi
-       fi
-fi
+LIBS="$ac_save_LIBS"
 
-if test $ol_with_kerberos = auto -o $ol_with_kerberos = k4 ; then
-       for ac_hdr in krb.h des.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:5469: checking for $ac_hdr" >&5
-if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 5474 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:5479: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
-  rm -rf conftest*
-  eval "ac_cv_header_$ac_safe=yes"
-else
-  echo "$ac_err" >&5
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
 fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
+  have_krb5=yes
+                               KRB5_LIBS="-lkrb5 -lcrypto -lcom_err"
 else
   echo "$ac_t""no" 1>&6
+have_krb5=no
 fi
-done
 
 
-       if test $ac_cv_header_krb_h = yes ; then
-               echo $ac_n "checking for main in -lkrb""... $ac_c" 1>&6
-echo "configure:5508: checking for main in -lkrb" >&5
-ac_lib_var=`echo krb'_'main | sed 'y%./+-:%__p__%'`
+               elif test $krb5_impl = heimdal; then
+                       echo $ac_n "checking for main in -lkrb5""... $ac_c" 1>&6
+echo "configure:5747: checking for main in -lkrb5" >&5
+ac_lib_var=`echo krb5'_'main | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="-lkrb -ldes $LIBS"
+LIBS="-lkrb5 -ldes -lasn1 -lroken -lcom_err $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5516 "configure"
+#line 5755 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:5523: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5762: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5534,47 +5773,64 @@ LIBS="$ac_save_LIBS"
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-  have_k4=yes
+  have_krb5=yes
+                               KRB5_LIBS="-lkrb5 -ldes -lasn1 -lroken -lcom_err"
 else
   echo "$ac_t""no" 1>&6
-have_k4=no
+have_krb5=no
 fi
 
 
-               if test $have_k4 = yes ; then
-                       ol_with_kerberos=found
-                       ol_link_kerberos=yes
+                       cat >> confdefs.h <<\EOF
+#define HAVE_HEIMDAL_KERBEROS 1
+EOF
 
-                       KRB_LIBS="-lkrb -ldes"
+               else
+                       have_krb5=no
+                       echo "configure: warning: Unrecongized Kerberos5 Implementation" 1>&2
                fi
-       fi
-fi
 
-if test $ol_link_kerberos = yes ; then
-       cat >> confdefs.h <<\EOF
-#define HAVE_KERBEROS 1
+               if test $have_krb5 = yes ; then
+                       ol_link_krb5=yes
+
+                       cat >> confdefs.h <<\EOF
+#define HAVE_KRB5 1
 EOF
 
+
+                       if test $ol_enable_kpasswd != no ; then
+                               ol_link_kpasswd=yes;
+                       fi
+
+                       if test $ol_with_kerberos = k5only ; then
+                               ol_with_kerberos=found
+                       fi
+
+               elif test $ol_with_kerberos != auto ; then
+                       { echo "configure: error: Required Kerberos 5 support not available" 1>&2; exit 1; }
+               fi
+
+       fi
 fi
 
-ol_link_tls=no
-if test $ol_with_tls != no ; then
-       
-       for ac_hdr in openssl/ssl.h ssl.h
+if test $ol_link_krb5 = yes -a \
+       \( $ol_with_kerberos = auto -o $ol_with_kerberos = k425 \) ; then
+
+       for ac_hdr in kerberosIV/krb.h kerberosIV/des.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:5568: checking for $ac_hdr" >&5
+echo "configure:5824: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5573 "configure"
+#line 5829 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:5578: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:5834: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -5600,29 +5856,26 @@ else
 fi
 done
 
-       
-       if test $ac_cv_header_openssl_ssl_h = yes -o $ac_cv_header_ssl_h = yes ; then
-               echo $ac_n "checking for SSLeay_add_ssl_algorithms in -lssl""... $ac_c" 1>&6
-echo "configure:5607: checking for SSLeay_add_ssl_algorithms in -lssl" >&5
-ac_lib_var=`echo ssl'_'SSLeay_add_ssl_algorithms | sed 'y%./+-:%__p__%'`
+
+       if test $ac_cv_header_kerberosIV_krb_h = yes ; then
+               if test $krb5_impl = mit; then
+                       echo $ac_n "checking for main in -lkrb4""... $ac_c" 1>&6
+echo "configure:5864: checking for main in -lkrb4" >&5
+ac_lib_var=`echo krb4'_'main | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="-lssl -lcrypto $LIBS"
+LIBS="-lkrb4 -ldes425 -lkrb5 -lcrypto -lcom_err $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5615 "configure"
+#line 5872 "configure"
 #include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error.  */
-/* We use char because int might match the return type of a gcc2
-    builtin and then its argument prototype would still apply.  */
-char SSLeay_add_ssl_algorithms();
 
 int main() {
-SSLeay_add_ssl_algorithms()
+main()
 ; return 0; }
 EOF
-if { (eval echo configure:5626: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5879: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5637,36 +5890,32 @@ LIBS="$ac_save_LIBS"
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-  have_ssleay=yes
-                       need_rsaref=no
+  have_k425=yes
+                               KRB4_LIBS="-lkrb4 -ldes425"
 else
   echo "$ac_t""no" 1>&6
-have_ssleay=no
+have_k425=no
 fi
 
-                       
-               if test $have_ssleay = no ; then
-                       echo $ac_n "checking for SSL_library_init in -lssl""... $ac_c" 1>&6
-echo "configure:5651: checking for SSL_library_init in -lssl" >&5
-ac_lib_var=`echo ssl'_'SSL_library_init | sed 'y%./+-:%__p__%'`
-if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
+
+               elif test $krb5_impl = heimdal; then
+                       echo $ac_n "checking for main in -lkrb4""... $ac_c" 1>&6
+echo "configure:5904: checking for main in -lkrb4" >&5
+ac_lib_var=`echo krb4'_'main | sed 'y%./+-:%__p__%'`
+if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="-lssl -lcrypto $LIBS"
+LIBS="-lkrb4 -lkrb5 -ldes -lasn1 -lroken -lcom_err $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5659 "configure"
+#line 5912 "configure"
 #include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error.  */
-/* 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() {
-SSL_library_init()
+main()
 ; return 0; }
 EOF
-if { (eval echo configure:5670: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5919: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5681,37 +5930,148 @@ LIBS="$ac_save_LIBS"
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-  have_ssleay=yes
-                               need_rsaref=no
+  have_k425=yes
+                               KRB4_LIBS="-lkrb4"
 else
   echo "$ac_t""no" 1>&6
-have_ssleay=no
+have_k425=no
 fi
 
+
+               else
+                       have_425=no
+                       echo "configure: warning: Unrecongized Kerberos5 Implementation" 1>&2
                fi
 
-               if test $have_ssleay = no ; then
-                       echo $ac_n "checking for ssl3_accept in -lssl""... $ac_c" 1>&6
-echo "configure:5696: checking for ssl3_accept in -lssl" >&5
-ac_lib_var=`echo ssl'_'ssl3_accept | sed 'y%./+-:%__p__%'`
+               if test $have_k425 = yes ; then
+                       ol_with_kerberos=found
+                       ol_link_krb4=yes
+
+                       cat >> confdefs.h <<\EOF
+#define HAVE_KRB425 1
+EOF
+
+                       cat >> confdefs.h <<\EOF
+#define HAVE_KRB4 1
+EOF
+
+
+                       echo $ac_n "checking for des_debug in Kerberos libraries""... $ac_c" 1>&6
+echo "configure:5961: checking for des_debug in Kerberos libraries" >&5
+if eval "test \"\${ol_cv_var_des_debug+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+                                                               save_LIBS="$LIBS"
+                               LIBS="$KRB4_LIBS $KRB5_LIBS $LIBS"
+                               cat > conftest.$ac_ext <<EOF
+#line 5969 "configure"
+#include "confdefs.h"
+
+#include <kerberosIV/krb.h>
+#include <kerberosIV/des.h>
+extern int des_debug;
+
+int main() {
+
+des_debug = 1;
+
+; return 0; }
+EOF
+if { (eval echo configure:5982: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ol_cv_var_des_debug=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ol_cv_var_des_debug=no
+fi
+rm -f conftest*
+                                                               LIBS="$save_LIBS"
+                       
+fi
+
+echo "$ac_t""$ol_cv_var_des_debug" 1>&6
+
+                       if test $ol_cv_var_des_debug = yes ; then
+                               cat >> confdefs.h <<\EOF
+#define HAVE_DES_DEBUG 1
+EOF
+
+                       fi
+
+                       LIBS="$save_LIBS"
+               fi
+       fi
+fi
+
+if test $ol_link_krb5 = yes ; then
+       ol_with_kerberos=found
+fi
+
+if test $ol_with_kerberos = auto -o $ol_with_kerberos = k4 \
+       -o $ol_with_kerberos = kth ; then
+
+       for ac_hdr in krb.h des.h krb-archaeology.h 
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:6021: checking for $ac_hdr" >&5
+if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 6026 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:6031: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+       if test $ac_cv_header_krb_h = yes ; then
+               echo $ac_n "checking for main in -lkrb""... $ac_c" 1>&6
+echo "configure:6060: checking for main in -lkrb" >&5
+ac_lib_var=`echo krb'_'main | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="-lssl -lcrypto -lRSAglue -lrsaref $LIBS"
+LIBS="-lkrb -ldes $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5704 "configure"
+#line 6068 "configure"
 #include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error.  */
-/* 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()
+main()
 ; return 0; }
 EOF
-if { (eval echo configure:5715: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6075: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5726,97 +6086,84 @@ LIBS="$ac_save_LIBS"
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-  have_ssleay=yes
-                               need_rsaref=yes
+  have_k4=yes
 else
   echo "$ac_t""no" 1>&6
-have_ssleay=no
+have_k4=no
 fi
 
-               fi
 
-               if test $have_ssleay = yes ; then
-                       ol_with_tls=found
-                       ol_link_tls=yes
+               if test $have_k4 = yes ; then
+                       ol_with_kerberos=found
+                       ol_link_krb4=yes
 
                        cat >> confdefs.h <<\EOF
-#define HAVE_SSLEAY 1
+#define HAVE_KRB4 1
 EOF
 
 
-                       if test $need_rsaref = yes; then
+                       KRB4_LIBS="-lkrb -ldes"
+
+                       if test $ac_cv_header_krb_archaeology_h = yes ; then
                                cat >> confdefs.h <<\EOF
-#define HAVE_RSAREF 1
+#define HAVE_KTH_KERBEROS 1
 EOF
 
-
-                               TLS_LIBS="-lssl -lcrypto -lRSAglue -lrsaref"
-                       else
-                               TLS_LIBS="-lssl -lcrypto"
                        fi
                fi
        fi
 fi
 
-if test $ol_link_tls = yes ; then
+if test $ol_link_krb4 = yes -a $ol_enable_kpasswd != no ; then
+       ol_link_kpasswd=yes;
+fi
+
+if test $ol_link_krb4 = yes -o $ol_link_krb5 = yes ; then
        cat >> confdefs.h <<\EOF
-#define HAVE_TLS 1
+#define HAVE_KERBEROS 1
 EOF
 
-fi     
 
-for ac_func in \
-       ctime_r                 \
-       gethostbyname_r gethostbyaddr_r \
+elif test $ol_with_kerberos != auto -a $ol_with_kerberos != no ; then
+       { echo "configure: error: Kerberos detection failed." 1>&2; exit 1; }
+fi
 
+ol_link_tls=no
+if test $ol_with_tls != no ; then
+       
+       for ac_hdr in openssl/ssl.h ssl.h
 do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5775: checking for $ac_func" >&5
-if eval "test \"\${ac_cv_func_$ac_func+set}\" = set"; then
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:6139: checking for $ac_hdr" >&5
+if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5780 "configure"
+#line 6144 "configure"
 #include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $ac_func(); below.  */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error.  */
-/* 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();
-char (*f)();
-
-int main() {
-
-/* 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
-f = $ac_func;
-#endif
-
-; return 0; }
+#include <$ac_hdr>
 EOF
-if { (eval echo configure:5804: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:6149: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
   rm -rf conftest*
-  eval "ac_cv_func_$ac_func=yes"
+  eval "ac_cv_header_$ac_safe=yes"
 else
+  echo "$ac_err" >&5
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  eval "ac_cv_func_$ac_func=no"
+  eval "ac_cv_header_$ac_safe=no"
 fi
 rm -f conftest*
 fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
   cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
+#define $ac_tr_hdr 1
 EOF
  
 else
@@ -5824,70 +6171,312 @@ else
 fi
 done
 
-
-if test "$ac_cv_func_ctime_r" = no ; then
-       ol_cv_func_ctime_r_nargs=0
-else
-       echo $ac_n "checking number of arguments of ctime_r""... $ac_c" 1>&6
-echo "configure:5833: checking number of arguments of ctime_r" >&5
-if eval "test \"\${ol_cv_func_ctime_r_nargs+set}\" = set"; then
+       
+       if test $ac_cv_header_openssl_ssl_h = yes -o $ac_cv_header_ssl_h = yes ; then
+               echo $ac_n "checking for SSLeay_add_ssl_algorithms in -lssl""... $ac_c" 1>&6
+echo "configure:6178: checking for SSLeay_add_ssl_algorithms in -lssl" >&5
+ac_lib_var=`echo ssl'_'SSLeay_add_ssl_algorithms | sed 'y%./+-:%__p__%'`
+if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  cat > conftest.$ac_ext <<EOF
-#line 5838 "configure"
-#include "confdefs.h"
-#include <time.h>
-int main() {
-time_t ti; char *buffer; ctime_r(&ti,buffer,32);
-; return 0; }
-EOF
-if { (eval echo configure:5845: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
-  rm -rf conftest*
-  ol_cv_func_ctime_r_nargs=3
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  cat > conftest.$ac_ext <<EOF
-#line 5853 "configure"
+  ac_save_LIBS="$LIBS"
+LIBS="-lssl -lcrypto $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6186 "configure"
 #include "confdefs.h"
-#include <time.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char SSLeay_add_ssl_algorithms();
+
 int main() {
-time_t ti; char *buffer; ctime_r(&ti,buffer);
+SSLeay_add_ssl_algorithms()
 ; return 0; }
 EOF
-if { (eval echo configure:5860: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6197: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
-  ol_cv_func_ctime_r_nargs=2
+  eval "ac_cv_lib_$ac_lib_var=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  ol_cv_func_ctime_r_nargs=0
-fi
-rm -f conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
 fi
 rm -f conftest*
-fi
-
-echo "$ac_t""$ol_cv_func_ctime_r_nargs" 1>&6
-  if test $ol_cv_func_ctime_r_nargs -gt 1 ; then
-    cat >> confdefs.h <<EOF
-#define CTIME_R_NARGS $ol_cv_func_ctime_r_nargs
-EOF
-
-  fi
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  have_ssleay=yes
+                       need_rsaref=no
+else
+  echo "$ac_t""no" 1>&6
+have_ssleay=no
+fi
+
+                       
+               if test $have_ssleay = no ; then
+                       echo $ac_n "checking for SSL_library_init in -lssl""... $ac_c" 1>&6
+echo "configure:6222: checking for SSL_library_init in -lssl" >&5
+ac_lib_var=`echo ssl'_'SSL_library_init | sed 'y%./+-:%__p__%'`
+if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lssl -lcrypto $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6230 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* 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() {
+SSL_library_init()
+; return 0; }
+EOF
+if { (eval echo configure:6241: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  have_ssleay=yes
+                               need_rsaref=no
+else
+  echo "$ac_t""no" 1>&6
+have_ssleay=no
+fi
+
+               fi
+
+               if test $have_ssleay = no ; then
+                       echo $ac_n "checking for ssl3_accept in -lssl""... $ac_c" 1>&6
+echo "configure:6267: checking for ssl3_accept in -lssl" >&5
+ac_lib_var=`echo ssl'_'ssl3_accept | sed 'y%./+-:%__p__%'`
+if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lssl -lcrypto -lRSAglue -lrsaref $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6275 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* 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; }
+EOF
+if { (eval echo configure:6286: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  have_ssleay=yes
+                               need_rsaref=yes
+else
+  echo "$ac_t""no" 1>&6
+have_ssleay=no
+fi
+
+               fi
+
+               if test $have_ssleay = yes ; then
+                       ol_with_tls=found
+                       ol_link_tls=yes
+
+                       cat >> confdefs.h <<\EOF
+#define HAVE_SSLEAY 1
+EOF
+
+
+                       if test $need_rsaref = yes; then
+                               cat >> confdefs.h <<\EOF
+#define HAVE_RSAREF 1
+EOF
+
+
+                               TLS_LIBS="-lssl -lcrypto -lRSAglue -lrsaref"
+                       else
+                               TLS_LIBS="-lssl -lcrypto"
+                       fi
+               fi
+       fi
+fi
+
+if test $ol_link_tls = yes ; then
+       cat >> confdefs.h <<\EOF
+#define HAVE_TLS 1
+EOF
+
+fi     
+
+for ac_func in \
+       ctime_r                 \
+       gethostbyname_r gethostbyaddr_r \
+
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:6346: checking for $ac_func" >&5
+if eval "test \"\${ac_cv_func_$ac_func+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 6351 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* 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();
+char (*f)();
+
+int main() {
+
+/* 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
+f = $ac_func;
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:6375: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+if test "$ac_cv_func_ctime_r" = no ; then
+       ol_cv_func_ctime_r_nargs=0
+else
+       echo $ac_n "checking number of arguments of ctime_r""... $ac_c" 1>&6
+echo "configure:6404: checking number of arguments of ctime_r" >&5
+if eval "test \"\${ol_cv_func_ctime_r_nargs+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 6409 "configure"
+#include "confdefs.h"
+#include <time.h>
+int main() {
+time_t ti; char *buffer; ctime_r(&ti,buffer,32);
+; return 0; }
+EOF
+if { (eval echo configure:6416: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ol_cv_func_ctime_r_nargs3=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ol_cv_func_ctime_r_nargs3=no
+fi
+rm -f conftest*
+
+       cat > conftest.$ac_ext <<EOF
+#line 6428 "configure"
+#include "confdefs.h"
+#include <time.h>
+int main() {
+time_t ti; char *buffer; ctime_r(&ti,buffer);
+; return 0; }
+EOF
+if { (eval echo configure:6435: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ol_cv_func_ctime_r_nargs2=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ol_cv_func_ctime_r_nargs2=no
+fi
+rm -f conftest*
+
+       if test $ol_cv_func_ctime_r_nargs3 = yes -a \
+               $ol_cv_func_ctime_r_nargs2 = no ; then
+
+               ol_cv_func_ctime_r_nargs=3
+
+       elif test $ol_cv_func_ctime_r_nargs3 = no -a \
+               $ol_cv_func_ctime_r_nargs2 = yes ; then
+
+               ol_cv_func_ctime_r_nargs=2
+
+       else
+               ol_cv_func_ctime_r_nargs=0
+       fi
+  
+fi
+
+echo "$ac_t""$ol_cv_func_ctime_r_nargs" 1>&6
+
+  if test $ol_cv_func_ctime_r_nargs -gt 1 ; then
+       cat >> confdefs.h <<EOF
+#define CTIME_R_NARGS $ol_cv_func_ctime_r_nargs
+EOF
+
+  fi
 
 fi
 
 if test "$ac_cv_func_gethostbyname_r" = yes ; then
        echo $ac_n "checking number of arguments of gethostbyname_r""... $ac_c" 1>&6
-echo "configure:5886: checking number of arguments of gethostbyname_r" >&5
+echo "configure:6475: checking number of arguments of gethostbyname_r" >&5
 if eval "test \"\${ol_cv_func_gethostbyname_r_nargs+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5891 "configure"
+#line 6480 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -5901,15 +6490,19 @@ struct hostent hent; char buffer[BUFSIZE];
                        buffer, bufsize, &h_errno);
 ; return 0; }
 EOF
-if { (eval echo configure:5905: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6494: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
-  ol_cv_func_gethostbyname_r_nargs=5
+  ol_cv_func_gethostbyname_r_nargs5=yes
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  cat > conftest.$ac_ext <<EOF
-#line 5913 "configure"
+  ol_cv_func_gethostbyname_r_nargs5=no
+fi
+rm -f conftest*
+
+       cat > conftest.$ac_ext <<EOF
+#line 6506 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -5918,24 +6511,37 @@ else
 #define BUFSIZE (sizeof(struct hostent)+10)
 int main() {
 struct hostent hent;struct hostent *rhent;
-                       char buffer[BUFSIZE];
-                       int bufsize=BUFSIZE;int h_errno;
-                       (void)gethostbyname_r("localhost", &hent, buffer, bufsize,
-                               &rhent, &h_errno);
+               char buffer[BUFSIZE];
+               int bufsize=BUFSIZE;int h_errno;
+               (void)gethostbyname_r("localhost", &hent, buffer, bufsize,
+                       &rhent, &h_errno);
 ; return 0; }
 EOF
-if { (eval echo configure:5928: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6521: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
-  ol_cv_func_gethostbyname_r_nargs=6
+  ol_cv_func_gethostbyname_r_nargs6=yes
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  ol_cv_func_gethostbyname_r_nargs=0
-fi
-rm -f conftest*
+  ol_cv_func_gethostbyname_r_nargs6=no
 fi
 rm -f conftest*
+
+       if test $ol_cv_func_gethostbyname_r_nargs5 = yes -a \
+               $ol_cv_func_gethostbyname_r_nargs6 = no ; then
+
+               ol_cv_func_gethostbyname_r_nargs=5
+
+       elif test $ol_cv_func_gethostbyname_r_nargs5 = no -a \
+               $ol_cv_func_gethostbyname_r_nargs6 = yes ; then
+
+               ol_cv_func_gethostbyname_r_nargs=6
+
+       else
+               ol_cv_func_gethostbyname_r_nargs=0
+       fi
+  
 fi
 
 echo "$ac_t""$ol_cv_func_gethostbyname_r_nargs" 1>&6
@@ -5952,12 +6558,12 @@ fi
  
 if test "$ac_cv_func_gethostbyaddr_r" = yes ; then
        echo $ac_n "checking number of arguments of gethostbyaddr_r""... $ac_c" 1>&6
-echo "configure:5956: checking number of arguments of gethostbyaddr_r" >&5
+echo "configure:6562: checking number of arguments of gethostbyaddr_r" >&5
 if eval "test \"\${ol_cv_func_gethostbyaddr_r_nargs+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5961 "configure"
+#line 6567 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -5973,15 +6579,19 @@ struct hostent hent; char buffer[BUFSIZE];
                        alen, AF_INET, &hent, buffer, bufsize, &h_errno);
 ; return 0; }
 EOF
-if { (eval echo configure:5977: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6583: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
-  ol_cv_func_gethostbyaddr_r_nargs=7
+  ol_cv_func_gethostbyaddr_r_nargs7=yes
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  cat > conftest.$ac_ext <<EOF
-#line 5985 "configure"
+  ol_cv_func_gethostbyaddr_r_nargs7=no
+fi
+rm -f conftest*
+
+       cat > conftest.$ac_ext <<EOF
+#line 6595 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -5990,30 +6600,43 @@ else
 #define BUFSIZE (sizeof(struct hostent)+10)
 int main() {
 struct hostent hent;
-                       struct hostent *rhent; char buffer[BUFSIZE]; 
-                       struct in_addr add;
-                       size_t alen=sizeof(struct in_addr);
-                       int bufsize=BUFSIZE;int h_errno;
-                       (void)gethostbyaddr_r( (void *)&(add.s_addr),
-                               alen, AF_INET, &hent, buffer, bufsize, 
-                               &rhent, &h_errno);
+               struct hostent *rhent; char buffer[BUFSIZE]; 
+               struct in_addr add;
+               size_t alen=sizeof(struct in_addr);
+               int bufsize=BUFSIZE;int h_errno;
+               (void)gethostbyaddr_r( (void *)&(add.s_addr),
+                       alen, AF_INET, &hent, buffer, bufsize, 
+                       &rhent, &h_errno);
 ; return 0; }
 EOF
-if { (eval echo configure:6003: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6613: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
-  ol_cv_func_gethostbyaddr_r_nargs=8
+  ol_cv_func_gethostbyaddr_r_nargs8=yes
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  ol_cv_func_gethostbyaddr_r_nargs=0
+  ol_cv_func_gethostbyaddr_r_nargs8=no
 fi
 rm -f conftest*
-fi
-rm -f conftest*
-fi
 
-echo "$ac_t""$ol_cv_func_gethostbyaddr_r_nargs" 1>&6
+       if test $ol_cv_func_gethostbyaddr_r_nargs7 = yes -a \
+               $ol_cv_func_gethostbyaddr_r_nargs8 = no ; then
+
+               ol_cv_func_gethostbyaddr_r_nargs=7
+
+       elif test $ol_cv_func_gethostbyaddr_r_nargs7 = no -a \
+               $ol_cv_func_gethostbyaddr_r_nargs8 = yes ; then
+
+               ol_cv_func_gethostbyaddr_r_nargs=8
+
+       else
+               ol_cv_func_gethostbyaddr_r_nargs=0
+       fi
+  
+fi
+
+echo "$ac_t""$ol_cv_func_gethostbyaddr_r_nargs" 1>&6
   if test $ol_cv_func_gethostbyaddr_r_nargs -gt 1 ; then
     cat >> confdefs.h <<EOF
 #define GETHOSTBYADDR_R_NARGS $ol_cv_func_gethostbyaddr_r_nargs
@@ -6043,6 +6666,100 @@ EOF
 fi
 
 ol_link_threads=no
+
+if test $ol_with_threads = auto -o $ol_with_threads = yes \
+       -o $ol_with_threads = nt ; then
+
+       
+       echo $ac_n "checking for NT Threads""... $ac_c" 1>&6
+echo "configure:6676: checking for NT Threads" >&5
+if eval "test \"\${ol_cv_nt_threads+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+               echo $ac_n "checking for _beginthread""... $ac_c" 1>&6
+echo "configure:6682: checking for _beginthread" >&5
+if eval "test \"\${ac_cv_func__beginthread+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 6687 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char _beginthread(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char _beginthread();
+char (*f)();
+
+int main() {
+
+/* 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__beginthread) || defined (__stub____beginthread)
+choke me
+#else
+f = _beginthread;
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:6711: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func__beginthread=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func__beginthread=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'_beginthread`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  ol_cv_nt_threads=yes
+else
+  echo "$ac_t""no" 1>&6
+ol_cv_nt_threads=no
+fi
+
+       
+fi
+
+echo "$ac_t""$ol_cv_nt_threads" 1>&6
+
+       if test $ol_cv_nt_threads = yes ; then
+               cat >> confdefs.h <<\EOF
+#define HAVE_NT_THREADS 1
+EOF
+
+       fi
+
+
+       if test "$ol_cv_nt_threads" = yes ; then
+       ol_link_threads=nt
+       ol_with_threads=found
+       ol_with_yielding_select=yes
+
+               cat >> confdefs.h <<\EOF
+#define HAVE_NT_SERVICE_MANAGER 1
+EOF
+
+               cat >> confdefs.h <<\EOF
+#define HAVE_NT_EVENT_LOG 1
+EOF
+
+       fi
+
+       if test $ol_with_threads = nt ; then
+               { echo "configure: error: could not locate NT Threads" 1>&2; exit 1; }
+       fi
+fi
+
 if test $ol_with_threads = auto -o $ol_with_threads = yes \
        -o $ol_with_threads = posix ; then
 
@@ -6050,17 +6767,17 @@ if test $ol_with_threads = auto -o $ol_with_threads = yes \
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:6054: checking for $ac_hdr" >&5
+echo "configure:6771: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6059 "configure"
+#line 6776 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6064: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6781: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -6089,19 +6806,19 @@ done
 
        if test $ac_cv_header_pthread_h = yes ; then
                echo $ac_n "checking POSIX thread version""... $ac_c" 1>&6
-echo "configure:6093: checking POSIX thread version" >&5
+echo "configure:6810: checking POSIX thread version" >&5
 if eval "test \"\${ol_cv_pthread_version+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
        cat > conftest.$ac_ext <<EOF
-#line 6099 "configure"
+#line 6816 "configure"
 #include "confdefs.h"
 
 #              include <pthread.h>
                /* this check could be improved */
 #              ifdef PTHREAD_ONCE_INIT
-                       pthread_version_final
+                       pthread_version_final;
 #              endif
        
 EOF
@@ -6117,13 +6834,13 @@ rm -f conftest*
 
 
        cat > conftest.$ac_ext <<EOF
-#line 6121 "configure"
+#line 6838 "configure"
 #include "confdefs.h"
 
 #              include <pthread.h>
                /* this check could be improved */
 #              ifdef pthread_once_init
-                       pthread_version_draft4
+                       pthread_version_draft4;
 #              endif
        
 EOF
@@ -6170,12 +6887,12 @@ EOF
 
                
        echo $ac_n "checking for LinuxThreads pthread.h""... $ac_c" 1>&6
-echo "configure:6174: checking for LinuxThreads pthread.h" >&5
+echo "configure:6891: checking for LinuxThreads pthread.h" >&5
 if eval "test \"\${ol_cv_header_linux_threads+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6179 "configure"
+#line 6896 "configure"
 #include "confdefs.h"
 #include <pthread.h>
 EOF
@@ -6202,16 +6919,16 @@ EOF
 
                
        echo $ac_n "checking for GNU Pth pthread.h""... $ac_c" 1>&6
-echo "configure:6206: checking for GNU Pth pthread.h" >&5
+echo "configure:6923: checking for GNU Pth pthread.h" >&5
 if eval "test \"\${ol_cv_header_gnu_pth_pthread_h+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6211 "configure"
+#line 6928 "configure"
 #include "confdefs.h"
 #include <pthread.h>
 #ifdef _POSIX_THREAD_IS_GNU_PTH
-       __gnu_pth__
+       __gnu_pth__;
 #endif
 
 EOF
@@ -6236,17 +6953,17 @@ echo "$ac_t""$ol_cv_header_gnu_pth_pthread_h" 1>&6
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:6240: checking for $ac_hdr" >&5
+echo "configure:6957: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6245 "configure"
+#line 6962 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:6250: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:6967: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -6276,14 +6993,14 @@ done
 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                echo $ac_n "checking for pthread_create in default libraries""... $ac_c" 1>&6
-echo "configure:6280: checking for pthread_create in default libraries" >&5
+echo "configure:6997: checking for pthread_create in default libraries" >&5
 if eval "test \"\${ol_cv_pthread_create+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
                if test "$cross_compiling" = yes; then
   cat > conftest.$ac_ext <<EOF
-#line 6287 "configure"
+#line 7004 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -6302,14 +7019,26 @@ int main() {
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -6327,7 +7056,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:6331: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7060: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_pthread_create=yes
 else
@@ -6339,7 +7068,7 @@ fi
 rm -f conftest*
 else
   cat > conftest.$ac_ext <<EOF
-#line 6343 "configure"
+#line 7072 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -6362,14 +7091,26 @@ int main(argc, argv)
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -6388,7 +7129,7 @@ int main(argc, argv)
 }
 
 EOF
-if { (eval echo configure:6392: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7133: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ol_cv_pthread_create=yes
 else
@@ -6413,7 +7154,7 @@ echo "$ac_t""$ol_cv_pthread_create" 1>&6
 if test "$ol_link_threads" = no ; then
        # try -kthread
        echo $ac_n "checking for pthread link with -kthread""... $ac_c" 1>&6
-echo "configure:6417: checking for pthread link with -kthread" >&5
+echo "configure:7158: checking for pthread link with -kthread" >&5
 if eval "test \"\${ol_cv_pthread_kthread+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6424,7 +7165,7 @@ else
 
                if test "$cross_compiling" = yes; then
   cat > conftest.$ac_ext <<EOF
-#line 6428 "configure"
+#line 7169 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -6443,14 +7184,26 @@ int main() {
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -6468,7 +7221,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:6472: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7225: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_pthread_kthread=yes
 else
@@ -6480,7 +7233,7 @@ fi
 rm -f conftest*
 else
   cat > conftest.$ac_ext <<EOF
-#line 6484 "configure"
+#line 7237 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -6503,14 +7256,26 @@ int main(argc, argv)
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -6529,7 +7294,7 @@ int main(argc, argv)
 }
 
 EOF
-if { (eval echo configure:6533: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7298: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ol_cv_pthread_kthread=yes
 else
@@ -6559,7 +7324,7 @@ fi
 if test "$ol_link_threads" = no ; then
        # try -pthread
        echo $ac_n "checking for pthread link with -pthread""... $ac_c" 1>&6
-echo "configure:6563: checking for pthread link with -pthread" >&5
+echo "configure:7328: checking for pthread link with -pthread" >&5
 if eval "test \"\${ol_cv_pthread_pthread+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6570,7 +7335,7 @@ else
 
                if test "$cross_compiling" = yes; then
   cat > conftest.$ac_ext <<EOF
-#line 6574 "configure"
+#line 7339 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -6589,14 +7354,26 @@ int main() {
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -6614,7 +7391,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:6618: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7395: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_pthread_pthread=yes
 else
@@ -6626,7 +7403,7 @@ fi
 rm -f conftest*
 else
   cat > conftest.$ac_ext <<EOF
-#line 6630 "configure"
+#line 7407 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -6649,14 +7426,26 @@ int main(argc, argv)
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -6675,7 +7464,7 @@ int main(argc, argv)
 }
 
 EOF
-if { (eval echo configure:6679: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7468: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ol_cv_pthread_pthread=yes
 else
@@ -6705,7 +7494,7 @@ fi
 if test "$ol_link_threads" = no ; then
        # try -pthreads
        echo $ac_n "checking for pthread link with -pthreads""... $ac_c" 1>&6
-echo "configure:6709: checking for pthread link with -pthreads" >&5
+echo "configure:7498: checking for pthread link with -pthreads" >&5
 if eval "test \"\${ol_cv_pthread_pthreads+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6716,7 +7505,7 @@ else
 
                if test "$cross_compiling" = yes; then
   cat > conftest.$ac_ext <<EOF
-#line 6720 "configure"
+#line 7509 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -6735,14 +7524,26 @@ int main() {
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -6760,7 +7561,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:6764: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7565: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_pthread_pthreads=yes
 else
@@ -6772,7 +7573,7 @@ fi
 rm -f conftest*
 else
   cat > conftest.$ac_ext <<EOF
-#line 6776 "configure"
+#line 7577 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -6795,14 +7596,26 @@ int main(argc, argv)
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -6821,7 +7634,7 @@ int main(argc, argv)
 }
 
 EOF
-if { (eval echo configure:6825: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7638: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ol_cv_pthread_pthreads=yes
 else
@@ -6851,7 +7664,7 @@ fi
 if test "$ol_link_threads" = no ; then
        # try -mthreads
        echo $ac_n "checking for pthread link with -mthreads""... $ac_c" 1>&6
-echo "configure:6855: checking for pthread link with -mthreads" >&5
+echo "configure:7668: checking for pthread link with -mthreads" >&5
 if eval "test \"\${ol_cv_pthread_mthreads+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6862,7 +7675,7 @@ else
 
                if test "$cross_compiling" = yes; then
   cat > conftest.$ac_ext <<EOF
-#line 6866 "configure"
+#line 7679 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -6881,14 +7694,26 @@ int main() {
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -6906,7 +7731,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:6910: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7735: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_pthread_mthreads=yes
 else
@@ -6918,7 +7743,7 @@ fi
 rm -f conftest*
 else
   cat > conftest.$ac_ext <<EOF
-#line 6922 "configure"
+#line 7747 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -6941,14 +7766,26 @@ int main(argc, argv)
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -6967,7 +7804,7 @@ int main(argc, argv)
 }
 
 EOF
-if { (eval echo configure:6971: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7808: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ol_cv_pthread_mthreads=yes
 else
@@ -6997,7 +7834,7 @@ fi
 if test "$ol_link_threads" = no ; then
        # try -thread
        echo $ac_n "checking for pthread link with -thread""... $ac_c" 1>&6
-echo "configure:7001: checking for pthread link with -thread" >&5
+echo "configure:7838: checking for pthread link with -thread" >&5
 if eval "test \"\${ol_cv_pthread_thread+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7008,7 +7845,7 @@ else
 
                if test "$cross_compiling" = yes; then
   cat > conftest.$ac_ext <<EOF
-#line 7012 "configure"
+#line 7849 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -7027,14 +7864,26 @@ int main() {
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -7052,7 +7901,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:7056: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7905: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_pthread_thread=yes
 else
@@ -7064,7 +7913,7 @@ fi
 rm -f conftest*
 else
   cat > conftest.$ac_ext <<EOF
-#line 7068 "configure"
+#line 7917 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -7087,14 +7936,26 @@ int main(argc, argv)
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -7113,7 +7974,7 @@ int main(argc, argv)
 }
 
 EOF
-if { (eval echo configure:7117: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7978: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ol_cv_pthread_thread=yes
 else
@@ -7144,7 +8005,7 @@ fi
 if test "$ol_link_threads" = no ; then
        # try -lpthread -lmach -lexc -lc_r
        echo $ac_n "checking for pthread link with -lpthread -lmach -lexc -lc_r""... $ac_c" 1>&6
-echo "configure:7148: checking for pthread link with -lpthread -lmach -lexc -lc_r" >&5
+echo "configure:8009: checking for pthread link with -lpthread -lmach -lexc -lc_r" >&5
 if eval "test \"\${ol_cv_pthread_lpthread_lmach_lexc_lc_r+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7155,7 +8016,7 @@ else
 
                if test "$cross_compiling" = yes; then
   cat > conftest.$ac_ext <<EOF
-#line 7159 "configure"
+#line 8020 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -7174,14 +8035,26 @@ int main() {
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -7199,7 +8072,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:7203: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8076: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_pthread_lpthread_lmach_lexc_lc_r=yes
 else
@@ -7211,7 +8084,7 @@ fi
 rm -f conftest*
 else
   cat > conftest.$ac_ext <<EOF
-#line 7215 "configure"
+#line 8088 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -7234,14 +8107,26 @@ int main(argc, argv)
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -7260,7 +8145,7 @@ int main(argc, argv)
 }
 
 EOF
-if { (eval echo configure:7264: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8149: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ol_cv_pthread_lpthread_lmach_lexc_lc_r=yes
 else
@@ -7290,7 +8175,7 @@ fi
 if test "$ol_link_threads" = no ; then
        # try -lpthread -lmach -lexc
        echo $ac_n "checking for pthread link with -lpthread -lmach -lexc""... $ac_c" 1>&6
-echo "configure:7294: checking for pthread link with -lpthread -lmach -lexc" >&5
+echo "configure:8179: checking for pthread link with -lpthread -lmach -lexc" >&5
 if eval "test \"\${ol_cv_pthread_lpthread_lmach_lexc+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7301,7 +8186,7 @@ else
 
                if test "$cross_compiling" = yes; then
   cat > conftest.$ac_ext <<EOF
-#line 7305 "configure"
+#line 8190 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -7320,14 +8205,26 @@ int main() {
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -7345,7 +8242,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:7349: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8246: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_pthread_lpthread_lmach_lexc=yes
 else
@@ -7357,7 +8254,7 @@ fi
 rm -f conftest*
 else
   cat > conftest.$ac_ext <<EOF
-#line 7361 "configure"
+#line 8258 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -7380,14 +8277,26 @@ int main(argc, argv)
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -7406,7 +8315,7 @@ int main(argc, argv)
 }
 
 EOF
-if { (eval echo configure:7410: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8319: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ol_cv_pthread_lpthread_lmach_lexc=yes
 else
@@ -7437,7 +8346,7 @@ fi
 if test "$ol_link_threads" = no ; then
        # try -lpthread -Wl,-woff,85
        echo $ac_n "checking for pthread link with -lpthread -Wl,-woff,85""... $ac_c" 1>&6
-echo "configure:7441: checking for pthread link with -lpthread -Wl,-woff,85" >&5
+echo "configure:8350: checking for pthread link with -lpthread -Wl,-woff,85" >&5
 if eval "test \"\${ol_cv_pthread_lib_lpthread_woff+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7448,7 +8357,7 @@ else
 
                if test "$cross_compiling" = yes; then
   cat > conftest.$ac_ext <<EOF
-#line 7452 "configure"
+#line 8361 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -7467,14 +8376,26 @@ int main() {
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -7492,7 +8413,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:7496: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8417: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_pthread_lib_lpthread_woff=yes
 else
@@ -7504,7 +8425,7 @@ fi
 rm -f conftest*
 else
   cat > conftest.$ac_ext <<EOF
-#line 7508 "configure"
+#line 8429 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -7527,14 +8448,26 @@ int main(argc, argv)
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -7553,7 +8486,7 @@ int main(argc, argv)
 }
 
 EOF
-if { (eval echo configure:7557: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8490: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ol_cv_pthread_lib_lpthread_woff=yes
 else
@@ -7584,7 +8517,7 @@ fi
 if test "$ol_link_threads" = no ; then
        # try -lpthread
        echo $ac_n "checking for pthread link with -lpthread""... $ac_c" 1>&6
-echo "configure:7588: checking for pthread link with -lpthread" >&5
+echo "configure:8521: checking for pthread link with -lpthread" >&5
 if eval "test \"\${ol_cv_pthread_lpthread+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7595,7 +8528,7 @@ else
 
                if test "$cross_compiling" = yes; then
   cat > conftest.$ac_ext <<EOF
-#line 7599 "configure"
+#line 8532 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -7614,14 +8547,26 @@ int main() {
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -7639,7 +8584,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:7643: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8588: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_pthread_lpthread=yes
 else
@@ -7651,7 +8596,7 @@ fi
 rm -f conftest*
 else
   cat > conftest.$ac_ext <<EOF
-#line 7655 "configure"
+#line 8600 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -7674,17 +8619,29 @@ int main(argc, argv)
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
-#if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
-#else
-       status = pthread_create(&t, NULL, task, NULL);
-#endif
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
 
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
        if( status ) exit( status );
 
-       /* make sure pthread_detach() isn't just a stub */
+#define        ATTR    &attr
+#else
+#if HAVE_PTHREADS_D4
+#define        ATTR    pthread_attr_default
+#else
+#define        ATTR    NULL
+#endif
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
+       if( status ) exit( status );
+
+       /* make sure pthread_detach() isn't just a stub */
 #if HAVE_PTHREADS_D4
        status = pthread_detach( &t );
 #else
@@ -7700,7 +8657,7 @@ int main(argc, argv)
 }
 
 EOF
-if { (eval echo configure:7704: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8661: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ol_cv_pthread_lpthread=yes
 else
@@ -7730,7 +8687,7 @@ fi
 if test "$ol_link_threads" = no ; then
        # try -lc_r
        echo $ac_n "checking for pthread link with -lc_r""... $ac_c" 1>&6
-echo "configure:7734: checking for pthread link with -lc_r" >&5
+echo "configure:8691: checking for pthread link with -lc_r" >&5
 if eval "test \"\${ol_cv_pthread_lc_r+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7741,7 +8698,7 @@ else
 
                if test "$cross_compiling" = yes; then
   cat > conftest.$ac_ext <<EOF
-#line 7745 "configure"
+#line 8702 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -7760,14 +8717,26 @@ int main() {
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -7785,7 +8754,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:7789: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8758: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_pthread_lc_r=yes
 else
@@ -7797,7 +8766,7 @@ fi
 rm -f conftest*
 else
   cat > conftest.$ac_ext <<EOF
-#line 7801 "configure"
+#line 8770 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -7820,14 +8789,26 @@ int main(argc, argv)
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -7846,7 +8827,7 @@ int main(argc, argv)
 }
 
 EOF
-if { (eval echo configure:7850: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8831: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ol_cv_pthread_lc_r=yes
 else
@@ -7877,7 +8858,7 @@ fi
 if test "$ol_link_threads" = no ; then
        # try -threads
        echo $ac_n "checking for pthread link with -threads""... $ac_c" 1>&6
-echo "configure:7881: checking for pthread link with -threads" >&5
+echo "configure:8862: checking for pthread link with -threads" >&5
 if eval "test \"\${ol_cv_pthread_threads+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7888,7 +8869,7 @@ else
 
                if test "$cross_compiling" = yes; then
   cat > conftest.$ac_ext <<EOF
-#line 7892 "configure"
+#line 8873 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -7907,14 +8888,26 @@ int main() {
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -7932,7 +8925,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:7936: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8929: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_pthread_threads=yes
 else
@@ -7944,7 +8937,7 @@ fi
 rm -f conftest*
 else
   cat > conftest.$ac_ext <<EOF
-#line 7948 "configure"
+#line 8941 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -7967,14 +8960,26 @@ int main(argc, argv)
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -7993,7 +8998,7 @@ int main(argc, argv)
 }
 
 EOF
-if { (eval echo configure:7997: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:9002: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ol_cv_pthread_threads=yes
 else
@@ -8024,7 +9029,7 @@ fi
 if test "$ol_link_threads" = no ; then
        # try -lpthreads -lmach -lexc -lc_r
        echo $ac_n "checking for pthread link with -lpthreads -lmach -lexc -lc_r""... $ac_c" 1>&6
-echo "configure:8028: checking for pthread link with -lpthreads -lmach -lexc -lc_r" >&5
+echo "configure:9033: checking for pthread link with -lpthreads -lmach -lexc -lc_r" >&5
 if eval "test \"\${ol_cv_pthread_lpthreads_lmach_lexc_lc_r+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8035,7 +9040,7 @@ else
 
                if test "$cross_compiling" = yes; then
   cat > conftest.$ac_ext <<EOF
-#line 8039 "configure"
+#line 9044 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -8054,14 +9059,26 @@ int main() {
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -8079,7 +9096,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:8083: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:9100: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_pthread_lpthreads_lmach_lexc_lc_r=yes
 else
@@ -8091,7 +9108,7 @@ fi
 rm -f conftest*
 else
   cat > conftest.$ac_ext <<EOF
-#line 8095 "configure"
+#line 9112 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -8114,14 +9131,26 @@ int main(argc, argv)
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -8140,7 +9169,7 @@ int main(argc, argv)
 }
 
 EOF
-if { (eval echo configure:8144: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:9173: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ol_cv_pthread_lpthreads_lmach_lexc_lc_r=yes
 else
@@ -8170,7 +9199,7 @@ fi
 if test "$ol_link_threads" = no ; then
        # try -lpthreads -lmach -lexc
        echo $ac_n "checking for pthread link with -lpthreads -lmach -lexc""... $ac_c" 1>&6
-echo "configure:8174: checking for pthread link with -lpthreads -lmach -lexc" >&5
+echo "configure:9203: checking for pthread link with -lpthreads -lmach -lexc" >&5
 if eval "test \"\${ol_cv_pthread_lpthreads_lmach_lexc+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8181,7 +9210,7 @@ else
 
                if test "$cross_compiling" = yes; then
   cat > conftest.$ac_ext <<EOF
-#line 8185 "configure"
+#line 9214 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -8200,14 +9229,26 @@ int main() {
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -8225,7 +9266,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:8229: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:9270: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_pthread_lpthreads_lmach_lexc=yes
 else
@@ -8237,7 +9278,7 @@ fi
 rm -f conftest*
 else
   cat > conftest.$ac_ext <<EOF
-#line 8241 "configure"
+#line 9282 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -8260,14 +9301,26 @@ int main(argc, argv)
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -8286,7 +9339,7 @@ int main(argc, argv)
 }
 
 EOF
-if { (eval echo configure:8290: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:9343: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ol_cv_pthread_lpthreads_lmach_lexc=yes
 else
@@ -8316,7 +9369,7 @@ fi
 if test "$ol_link_threads" = no ; then
        # try -lpthreads -lexc
        echo $ac_n "checking for pthread link with -lpthreads -lexc""... $ac_c" 1>&6
-echo "configure:8320: checking for pthread link with -lpthreads -lexc" >&5
+echo "configure:9373: checking for pthread link with -lpthreads -lexc" >&5
 if eval "test \"\${ol_cv_pthread_lpthreads_lexc+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8327,7 +9380,7 @@ else
 
                if test "$cross_compiling" = yes; then
   cat > conftest.$ac_ext <<EOF
-#line 8331 "configure"
+#line 9384 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -8346,14 +9399,26 @@ int main() {
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -8371,7 +9436,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:8375: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:9440: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_pthread_lpthreads_lexc=yes
 else
@@ -8383,7 +9448,7 @@ fi
 rm -f conftest*
 else
   cat > conftest.$ac_ext <<EOF
-#line 8387 "configure"
+#line 9452 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -8406,14 +9471,26 @@ int main(argc, argv)
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -8432,7 +9509,7 @@ int main(argc, argv)
 }
 
 EOF
-if { (eval echo configure:8436: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:9513: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ol_cv_pthread_lpthreads_lexc=yes
 else
@@ -8463,7 +9540,7 @@ fi
 if test "$ol_link_threads" = no ; then
        # try -lpthreads
        echo $ac_n "checking for pthread link with -lpthreads""... $ac_c" 1>&6
-echo "configure:8467: checking for pthread link with -lpthreads" >&5
+echo "configure:9544: checking for pthread link with -lpthreads" >&5
 if eval "test \"\${ol_cv_pthread_lib_lpthreads+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8474,7 +9551,7 @@ else
 
                if test "$cross_compiling" = yes; then
   cat > conftest.$ac_ext <<EOF
-#line 8478 "configure"
+#line 9555 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -8493,14 +9570,26 @@ int main() {
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -8518,7 +9607,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:8522: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:9611: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_pthread_lib_lpthreads=yes
 else
@@ -8530,7 +9619,7 @@ fi
 rm -f conftest*
 else
   cat > conftest.$ac_ext <<EOF
-#line 8534 "configure"
+#line 9623 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -8553,14 +9642,26 @@ int main(argc, argv)
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -8579,7 +9680,7 @@ int main(argc, argv)
 }
 
 EOF
-if { (eval echo configure:8583: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:9684: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ol_cv_pthread_lib_lpthreads=yes
 else
@@ -8621,12 +9722,12 @@ EOF
                                                                                                for ac_func in sched_yield pthread_yield
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:8625: checking for $ac_func" >&5
+echo "configure:9726: checking for $ac_func" >&5
 if eval "test \"\${ac_cv_func_$ac_func+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8630 "configure"
+#line 9731 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -8650,7 +9751,7 @@ f = $ac_func;
 
 ; return 0; }
 EOF
-if { (eval echo configure:8654: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:9755: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -8678,7 +9779,7 @@ done
                        if test $ac_cv_func_sched_yield = no -a \
                                $ac_cv_func_pthread_yield = no ; then
                                                                echo $ac_n "checking for sched_yield in -lrt""... $ac_c" 1>&6
-echo "configure:8682: checking for sched_yield in -lrt" >&5
+echo "configure:9783: checking for sched_yield in -lrt" >&5
 ac_lib_var=`echo rt'_'sched_yield | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -8686,7 +9787,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lrt  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 8690 "configure"
+#line 9791 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -8697,7 +9798,7 @@ int main() {
 sched_yield()
 ; return 0; }
 EOF
-if { (eval echo configure:8701: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:9802: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -8729,12 +9830,12 @@ fi
                                                                                                for ac_func in thr_yield
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:8733: checking for $ac_func" >&5
+echo "configure:9834: checking for $ac_func" >&5
 if eval "test \"\${ac_cv_func_$ac_func+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8738 "configure"
+#line 9839 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -8758,7 +9859,7 @@ f = $ac_func;
 
 ; return 0; }
 EOF
-if { (eval echo configure:8762: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:9863: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -8789,15 +9890,15 @@ done
                                echo "configure: warning: could not locate sched_yield() or pthread_yield()" 1>&2
                        fi
 
-                                               for ac_func in pthread_kill
+                                               for ac_func in pthread_kill pthread_rwlock_destroy
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:8796: checking for $ac_func" >&5
+echo "configure:9897: checking for $ac_func" >&5
 if eval "test \"\${ac_cv_func_$ac_func+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8801 "configure"
+#line 9902 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -8821,7 +9922,7 @@ f = $ac_func;
 
 ; return 0; }
 EOF
-if { (eval echo configure:8825: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:9926: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -8847,13 +9948,13 @@ done
 
 
                                                                        echo $ac_n "checking for pthread_detach with <pthread.h>""... $ac_c" 1>&6
-echo "configure:8851: checking for pthread_detach with <pthread.h>" >&5
+echo "configure:9952: checking for pthread_detach with <pthread.h>" >&5
 if eval "test \"\${ol_cv_func_pthread_detach+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
                                                                cat > conftest.$ac_ext <<EOF
-#line 8857 "configure"
+#line 9958 "configure"
 #include "confdefs.h"
 
 #include <pthread.h>
@@ -8865,7 +9966,7 @@ int main() {
 pthread_detach(NULL);
 ; return 0; }
 EOF
-if { (eval echo configure:8869: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:9970: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_func_pthread_detach=yes
 else
@@ -8897,12 +9998,12 @@ EOF
                        
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:8901: checking for $ac_func" >&5
+echo "configure:10002: checking for $ac_func" >&5
 if eval "test \"\${ac_cv_func_$ac_func+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8906 "configure"
+#line 10007 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -8926,7 +10027,7 @@ f = $ac_func;
 
 ; return 0; }
 EOF
-if { (eval echo configure:8930: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:10031: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -8953,12 +10054,12 @@ done
 
                        
        echo $ac_n "checking for pthread_kill_other_threads_np""... $ac_c" 1>&6
-echo "configure:8957: checking for pthread_kill_other_threads_np" >&5
+echo "configure:10058: checking for pthread_kill_other_threads_np" >&5
 if eval "test \"\${ac_cv_func_pthread_kill_other_threads_np+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8962 "configure"
+#line 10063 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char pthread_kill_other_threads_np(); below.  */
@@ -8982,7 +10083,7 @@ f = pthread_kill_other_threads_np;
 
 ; return 0; }
 EOF
-if { (eval echo configure:8986: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:10087: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_pthread_kill_other_threads_np=yes"
 else
@@ -9002,7 +10103,7 @@ else
 fi
 
        echo $ac_n "checking for LinuxThreads implementation""... $ac_c" 1>&6
-echo "configure:9006: checking for LinuxThreads implementation" >&5
+echo "configure:10107: checking for LinuxThreads implementation" >&5
 if eval "test \"\${ol_cv_sys_linux_threads+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -9015,7 +10116,7 @@ echo "$ac_t""$ol_cv_sys_linux_threads" 1>&6
        
        
        echo $ac_n "checking for LinuxThreads consistency""... $ac_c" 1>&6
-echo "configure:9019: checking for LinuxThreads consistency" >&5
+echo "configure:10120: checking for LinuxThreads consistency" >&5
 if eval "test \"\${ol_cv_linux_threads+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -9040,7 +10141,7 @@ echo "$ac_t""$ol_cv_linux_threads" 1>&6
                        fi
 
                        echo $ac_n "checking if pthread_create() works""... $ac_c" 1>&6
-echo "configure:9044: checking if pthread_create() works" >&5
+echo "configure:10145: checking if pthread_create() works" >&5
 if eval "test \"\${ol_cv_pthread_create_works+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -9049,7 +10150,7 @@ else
                                ol_cv_pthread_create_works=yes
 else
   cat > conftest.$ac_ext <<EOF
-#line 9053 "configure"
+#line 10154 "configure"
 #include "confdefs.h"
 /* pthread test headers */
 #include <pthread.h>
@@ -9072,14 +10173,26 @@ int main(argc, argv)
        /* pthread test function */
        pthread_t t;
        int status;
+#if HAVE_PTHREADS_FINAL && defined(PTHREAD_CREATE_UNDETACHED)
+       /* This system (e.g. AIX) defaults detached; must override */
+       pthread_attr_t attr;
 
-       /* make sure pthread_create() isn't just a stub */
+       status = pthread_attr_init(&attr);
+       if( status ) exit( status );
+
+       status = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+       if( status ) exit( status );
+
+#define        ATTR    &attr
+#else
 #if HAVE_PTHREADS_D4
-       status = pthread_create(&t, pthread_attr_default, task, NULL);
+#define        ATTR    pthread_attr_default
 #else
-       status = pthread_create(&t, NULL, task, NULL);
+#define        ATTR    NULL
 #endif
-
+#endif
+       /* make sure pthread_create() isn't just a stub */
+       status = pthread_create(&t, ATTR, task, NULL);
        if( status ) exit( status );
 
        /* make sure pthread_detach() isn't just a stub */
@@ -9098,7 +10211,7 @@ int main(argc, argv)
 }
 
 EOF
-if { (eval echo configure:9102: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10215: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ol_cv_pthread_create_works=yes
 else
@@ -9120,7 +10233,7 @@ echo "$ac_t""$ol_cv_pthread_create_works" 1>&6
 
                                                if test $ol_with_yielding_select = auto ; then
                                echo $ac_n "checking if select yields when using pthreads""... $ac_c" 1>&6
-echo "configure:9124: checking if select yields when using pthreads" >&5
+echo "configure:10237: checking if select yields when using pthreads" >&5
 if eval "test \"\${ol_cv_pthread_select_yields+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -9129,7 +10242,7 @@ else
   ol_cv_pthread_select_yields=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 9133 "configure"
+#line 10246 "configure"
 #include "confdefs.h"
 
 #include <sys/types.h>
@@ -9205,7 +10318,7 @@ int main(argc, argv)
        exit(2);
 }
 EOF
-if { (eval echo configure:9209: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10322: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ol_cv_pthread_select_yields=no
 else
@@ -9249,17 +10362,17 @@ if test $ol_with_threads = auto -o $ol_with_threads = yes \
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:9253: checking for $ac_hdr" >&5
+echo "configure:10366: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 9258 "configure"
+#line 10371 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:9263: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:10376: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -9289,12 +10402,12 @@ done
                ol_with_threads=found
 
                                echo $ac_n "checking for cthread_fork""... $ac_c" 1>&6
-echo "configure:9293: checking for cthread_fork" >&5
+echo "configure:10406: checking for cthread_fork" >&5
 if eval "test \"\${ac_cv_func_cthread_fork+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 9298 "configure"
+#line 10411 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char cthread_fork(); below.  */
@@ -9318,7 +10431,7 @@ f = cthread_fork;
 
 ; return 0; }
 EOF
-if { (eval echo configure:9322: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:10435: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_cthread_fork=yes"
 else
@@ -9340,7 +10453,7 @@ fi
 
                if test $ol_link_threads = no ; then
                                                                        echo $ac_n "checking for cthread_fork with -all_load""... $ac_c" 1>&6
-echo "configure:9344: checking for cthread_fork with -all_load" >&5
+echo "configure:10457: checking for cthread_fork with -all_load" >&5
 if eval "test \"\${ol_cv_cthread_all_load+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -9348,7 +10461,7 @@ else
                                                                save_LIBS="$LIBS"
                                LIBS="-all_load $LIBS"
                                cat > conftest.$ac_ext <<EOF
-#line 9352 "configure"
+#line 10465 "configure"
 #include "confdefs.h"
 #include <mach/cthreads.h>
 int main() {
@@ -9357,7 +10470,7 @@ int main() {
                                        
 ; return 0; }
 EOF
-if { (eval echo configure:9361: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:10474: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_cthread_all_load=yes
 else
@@ -9402,17 +10515,17 @@ if test $ol_with_threads = auto -o $ol_with_threads = yes \
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:9406: checking for $ac_hdr" >&5
+echo "configure:10519: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 9411 "configure"
+#line 10524 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:9416: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:10529: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -9441,7 +10554,7 @@ done
 
        if test $ac_cv_header_pth_h = yes ; then
                echo $ac_n "checking for pth_version in -lpth""... $ac_c" 1>&6
-echo "configure:9445: checking for pth_version in -lpth" >&5
+echo "configure:10558: checking for pth_version in -lpth" >&5
 ac_lib_var=`echo pth'_'pth_version | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -9449,7 +10562,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lpth  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 9453 "configure"
+#line 10566 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -9460,7 +10573,7 @@ int main() {
 pth_version()
 ; return 0; }
 EOF
-if { (eval echo configure:9464: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:10577: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -9504,17 +10617,17 @@ if test $ol_with_threads = auto -o $ol_with_threads = yes \
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:9508: checking for $ac_hdr" >&5
+echo "configure:10621: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 9513 "configure"
+#line 10626 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:9518: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:10631: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -9542,7 +10655,7 @@ done
 
        if test $ac_cv_header_thread_h = yes -a $ac_cv_header_synch_h = yes ; then
                echo $ac_n "checking for thr_create in -lthread""... $ac_c" 1>&6
-echo "configure:9546: checking for thr_create in -lthread" >&5
+echo "configure:10659: checking for thr_create in -lthread" >&5
 ac_lib_var=`echo thread'_'thr_create | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -9550,7 +10663,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lthread  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 9554 "configure"
+#line 10667 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -9561,7 +10674,7 @@ int main() {
 thr_create()
 ; return 0; }
 EOF
-if { (eval echo configure:9565: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:10678: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -9601,12 +10714,12 @@ EOF
                        
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:9605: checking for $ac_func" >&5
+echo "configure:10718: checking for $ac_func" >&5
 if eval "test \"\${ac_cv_func_$ac_func+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 9610 "configure"
+#line 10723 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -9630,7 +10743,7 @@ f = $ac_func;
 
 ; return 0; }
 EOF
-if { (eval echo configure:9634: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:10747: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -9661,17 +10774,17 @@ done
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:9665: checking for $ac_hdr" >&5
+echo "configure:10778: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 9670 "configure"
+#line 10783 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:9675: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:10788: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -9699,7 +10812,7 @@ done
 
        if test $ac_cv_header_lwp_lwp_h = yes ; then
                echo $ac_n "checking for lwp_create in -llwp""... $ac_c" 1>&6
-echo "configure:9703: checking for lwp_create in -llwp" >&5
+echo "configure:10816: checking for lwp_create in -llwp" >&5
 ac_lib_var=`echo lwp'_'lwp_create | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -9707,7 +10820,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-llwp  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 9711 "configure"
+#line 10824 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -9718,7 +10831,7 @@ int main() {
 lwp_create()
 ; return 0; }
 EOF
-if { (eval echo configure:9722: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:10835: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -9771,17 +10884,17 @@ if test $ol_with_threads = manual ; then
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:9775: checking for $ac_hdr" >&5
+echo "configure:10888: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 9780 "configure"
+#line 10893 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:9785: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:10898: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -9810,12 +10923,12 @@ done
        for ac_func in sched_yield pthread_yield
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:9814: checking for $ac_func" >&5
+echo "configure:10927: checking for $ac_func" >&5
 if eval "test \"\${ac_cv_func_$ac_func+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 9819 "configure"
+#line 10932 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -9839,7 +10952,7 @@ f = $ac_func;
 
 ; return 0; }
 EOF
-if { (eval echo configure:9843: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:10956: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -9865,12 +10978,12 @@ done
 
        
        echo $ac_n "checking for LinuxThreads pthread.h""... $ac_c" 1>&6
-echo "configure:9869: checking for LinuxThreads pthread.h" >&5
+echo "configure:10982: checking for LinuxThreads pthread.h" >&5
 if eval "test \"\${ol_cv_header_linux_threads+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 9874 "configure"
+#line 10987 "configure"
 #include "confdefs.h"
 #include <pthread.h>
 EOF
@@ -9900,17 +11013,17 @@ EOF
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:9904: checking for $ac_hdr" >&5
+echo "configure:11017: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 9909 "configure"
+#line 11022 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:9914: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:11027: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -9940,17 +11053,17 @@ done
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:9944: checking for $ac_hdr" >&5
+echo "configure:11057: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 9949 "configure"
+#line 11062 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:9954: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:11067: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -9980,17 +11093,17 @@ done
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:9984: checking for $ac_hdr" >&5
+echo "configure:11097: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 9989 "configure"
+#line 11102 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:9994: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:11107: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -10018,7 +11131,7 @@ done
 
 fi
 
-if test $ol_link_threads != no ; then  
+if test $ol_link_threads != no -a $ol_link_threads != nt ; then  
                        cat >> confdefs.h <<\EOF
 #define REENTRANT 1
 EOF
@@ -10049,20 +11162,20 @@ EOF
 
 
                        echo $ac_n "checking for thread specific errno""... $ac_c" 1>&6
-echo "configure:10053: checking for thread specific errno" >&5
+echo "configure:11166: checking for thread specific errno" >&5
 if eval "test \"\${ol_cv_errno_thread_specific+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
                cat > conftest.$ac_ext <<EOF
-#line 10059 "configure"
+#line 11172 "configure"
 #include "confdefs.h"
 #include <errno.h>
 int main() {
 errno = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:10066: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:11179: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_errno_thread_specific=yes
 else
 echo "$ac_t""$ol_cv_errno_thread_specific" 1>&6
 
                        echo $ac_n "checking for thread specific h_errno""... $ac_c" 1>&6
-echo "configure:10082: checking for thread specific h_errno" >&5
+echo "configure:11195: checking for thread specific h_errno" >&5
 if eval "test \"\${ol_cv_h_errno_thread_specific+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
                cat > conftest.$ac_ext <<EOF
-#line 10088 "configure"
+#line 11201 "configure"
 #include "confdefs.h"
 #include <netdb.h>
 int main() {
 h_errno = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:10095: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:11208: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_h_errno_thread_specific=yes
 else
@@ -10138,77 +11251,29 @@ EOF
 
 fi
 
-
 ol_link_ldbm=no 
-if test $ol_with_ldbm_api = auto -o $ol_with_ldbm_api = db2 ; then
-       echo $ac_n "checking for DB2 library""... $ac_c" 1>&6
-echo "configure:10146: checking for DB2 library" >&5
-if eval "test \"\${ol_cv_lib_db2+set}\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-       ol_LIBS="$LIBS"
-       echo $ac_n "checking for db_open in -ldb""... $ac_c" 1>&6
-echo "configure:10152: checking for db_open in -ldb" >&5
-ac_lib_var=`echo db'_'db_open | sed 'y%./+-:%__p__%'`
-if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  ac_save_LIBS="$LIBS"
-LIBS="-ldb  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 10160 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error.  */
-/* We use char because int might match the return type of a gcc2
-    builtin and then its argument prototype would still apply.  */
-char db_open();
-
-int main() {
-db_open()
-; return 0; }
-EOF
-if { (eval echo configure:10171: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-  ol_cv_lib_db2=-ldb
-else
-  echo "$ac_t""no" 1>&6
-ol_cv_lib_db2=no
-fi
 
-       LIBS="$ol_LIBS"
-
-fi
-
-echo "$ac_t""$ol_cv_lib_db2" 1>&6
+if test $ol_with_ldbm_api = auto \
+       -o $ol_with_ldbm_api = berkeley \
+       -o $ol_with_ldbm_api = bcompat ; then
 
-for ac_hdr in db.h
+       if test $ol_with_ldbm_api = bcompat; then \
+               ol_cv_berkeley_db=no
+for ac_hdr in db_185.h db.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:10202: checking for $ac_hdr" >&5
+echo "configure:11267: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 10207 "configure"
+#line 11272 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:10212: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:11277: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
 fi
 done
 
-if test $ac_cv_header_db_h = yes ; then
-       echo $ac_n "checking if db.h is DB2""... $ac_c" 1>&6
-echo "configure:10240: checking if db.h is DB2" >&5
-if eval "test \"\${ol_cv_header_db2+set}\" = set"; then
+if test $ac_cv_header_db_185_h = yes -o $ac_cv_header_db_h = yes; then
+       echo $ac_n "checking if Berkeley DB header compatibility""... $ac_c" 1>&6
+echo "configure:11305: checking if Berkeley DB header compatibility" >&5
+if eval "test \"\${ol_cv_header_db1+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
                cat > conftest.$ac_ext <<EOF
-#line 10246 "configure"
+#line 11311 "configure"
 #include "confdefs.h"
 
-#                      include <db.h>
-                       /* this check could be improved */
-#                      ifdef DB_VERSION_MAJOR
-#                              if DB_VERSION_MAJOR == 2
-                                       __db_version_2
-#                              endif
-#                      endif
-               
+#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
+
 EOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  egrep "__db_version_2" >/dev/null 2>&1; then
+  egrep "__db_version_1" >/dev/null 2>&1; then
   rm -rf conftest*
-  ol_cv_header_db2=yes
+  ol_cv_header_db1=yes
 else
   rm -rf conftest*
-  ol_cv_header_db2=no
+  ol_cv_header_db1=no
 fi
 rm -f conftest*
 
 fi
 
-echo "$ac_t""$ol_cv_header_db2" 1>&6
-else
-       ol_cv_header_db2=no
-fi
-
+echo "$ac_t""$ol_cv_header_db1" 1>&6
 
- echo $ac_n "checking for Berkeley DB2""... $ac_c" 1>&6
-echo "configure:10278: checking for Berkeley DB2" >&5
-if eval "test \"\${ol_cv_berkeley_db2+set}\" = set"; then
+       if test ol_cv_header_db1=yes ; then
+               ol_cv_lib_db=no
+if test $ol_cv_lib_db = no ; then
+       echo $ac_n "checking for Berkeley DB link (default)""... $ac_c" 1>&6
+echo "configure:11348: checking for Berkeley DB link (default)" >&5
+if eval "test \"\${ol_cv_db_none+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
-       if test "$ol_cv_lib_db2" = no -o "$ol_cv_header_db2" = no ; then
-               ol_cv_berkeley_db2=no
-       else
-               ol_cv_berkeley_db2=yes
-       fi
+       ol_DB_LIB=
+       ol_LIBS=$LIBS
+       LIBS="$ol_DB_LIB $LIBS"
 
-fi
+       cat > conftest.$ac_ext <<EOF
+#line 11358 "configure"
+#include "confdefs.h"
 
-echo "$ac_t""$ol_cv_berkeley_db2" 1>&6
- if test $ol_cv_berkeley_db2 = yes ; then
-       cat >> confdefs.h <<\EOF
-#define HAVE_BERKELEY_DB2 1
-EOF
+#ifdef HAVE_DB_185_H
+# include <db_185.h>
+#else
+# include <db.h>
+#endif
 
- fi
+#ifndef DB_VERSION_MAJOR
+# define DB_VERSION_MAJOR 1
+#endif
 
+#ifndef NULL
+#define NULL ((void*)0)
+#endif
 
-       if test $ol_cv_berkeley_db2 = yes ; then
-               ol_link_ldbm=db2
-               ol_with_ldbm_api=db2
+int main() {
 
-               if test $ol_with_ldbm_type = hash ; then
-                       cat >> confdefs.h <<\EOF
-#define LDBM_USE_DBHASH 1
-EOF
+#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
 
-               else
-                       cat >> confdefs.h <<\EOF
-#define LDBM_USE_DBBTREE 1
+; return 0; }
 EOF
+if { (eval echo configure:11387: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ol_cv_db_none=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ol_cv_db_none=no
+fi
+rm -f conftest*
 
-               fi
+       LIBS="$ol_LIBS"
 
-                                               if test $ol_cv_lib_db2 != yes ; then
-                       LDBM_LIBS="$LDBM_LIBS $ol_cv_lib_db2"
-               fi
-       fi
 fi
 
-ol_link_bdb2=no
-if test $ol_link_ldbm = db2 -a $ol_enable_bdb2 != no ; then
-       ol_link_bdb2=yes
+echo "$ac_t""$ol_cv_db_none" 1>&6
+
+       if test $ol_cv_db_none = yes ; then
+               ol_cv_lib_db=yes
+       fi
 fi
 
-if test $ol_with_ldbm_api = auto -o $ol_with_ldbm_api = db ; then
-       echo $ac_n "checking for Berkeley DB library""... $ac_c" 1>&6
-echo "configure:10329: checking for Berkeley DB library" >&5
-if eval "test \"\${ol_cv_lib_db+set}\" = set"; then
+if test $ol_cv_lib_db = no ; then
+       echo $ac_n "checking for Berkeley DB link (-ldb)""... $ac_c" 1>&6
+echo "configure:11411: checking for Berkeley DB link (-ldb)" >&5
+if eval "test \"\${ol_cv_db_db+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
-       for ac_hdr in db1/db.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:10338: checking for $ac_hdr" >&5
-if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 10343 "configure"
+       ol_DB_LIB=-ldb
+       ol_LIBS=$LIBS
+       LIBS="$ol_DB_LIB $LIBS"
+
+       cat > conftest.$ac_ext <<EOF
+#line 11421 "configure"
 #include "confdefs.h"
-#include <$ac_hdr>
+
+#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 > 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; }
 EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:10348: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
+if { (eval echo configure:11450: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
-  eval "ac_cv_header_$ac_safe=yes"
+  ol_cv_db_db=yes
 else
-  echo "$ac_err" >&5
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  eval "ac_cv_header_$ac_safe=no"
+  ol_cv_db_db=no
 fi
 rm -f conftest*
+
+       LIBS="$ol_LIBS"
+
 fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-else
-  echo "$ac_t""no" 1>&6
+
+echo "$ac_t""$ol_cv_db_db" 1>&6
+
+       if test $ol_cv_db_db = yes ; then
+               ol_cv_lib_db=-ldb
+       fi
 fi
-done
 
-       ol_LIBS="$LIBS"
-       echo $ac_n "checking for dbopen""... $ac_c" 1>&6
-echo "configure:10376: checking for dbopen" >&5
-if eval "test \"\${ac_cv_func_dbopen+set}\" = set"; then
+if test $ol_cv_lib_db = no ; then
+       echo $ac_n "checking for Berkeley DB link (-ldb3)""... $ac_c" 1>&6
+echo "configure:11474: checking for Berkeley DB link (-ldb3)" >&5
+if eval "test \"\${ol_cv_db_db3+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  cat > conftest.$ac_ext <<EOF
-#line 10381 "configure"
+  
+       ol_DB_LIB=-ldb3
+       ol_LIBS=$LIBS
+       LIBS="$ol_DB_LIB $LIBS"
+
+       cat > conftest.$ac_ext <<EOF
+#line 11484 "configure"
 #include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char dbopen(); below.  */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error.  */
-/* We use char because int might match the return type of a gcc2
-    builtin and then its argument prototype would still apply.  */
-char dbopen();
-char (*f)();
+
+#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() {
 
-/* 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_dbopen) || defined (__stub___dbopen)
-choke me
+#if DB_VERSION_MAJOR > 2
+       db_env_create( NULL, 0 );
+#elif DB_VERSION_MAJOR > 1
+       db_appexit( NULL );
 #else
-f = dbopen;
+       (void) dbopen( NULL, 0, 0, 0, NULL);
 #endif
 
 ; return 0; }
 EOF
-if { (eval echo configure:10405: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:11513: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
-  eval "ac_cv_func_dbopen=yes"
+  ol_cv_db_db3=yes
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  eval "ac_cv_func_dbopen=no"
+  ol_cv_db_db3=no
 fi
 rm -f conftest*
+
+       LIBS="$ol_LIBS"
+
 fi
 
-if eval "test \"`echo '$ac_cv_func_'dbopen`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-  ol_cv_lib_db=yes
-else
-  echo "$ac_t""no" 1>&6
+echo "$ac_t""$ol_cv_db_db3" 1>&6
 
-               echo $ac_n "checking for dbopen in -ldb1""... $ac_c" 1>&6
-echo "configure:10424: checking for dbopen in -ldb1" >&5
-ac_lib_var=`echo db1'_'dbopen | sed 'y%./+-:%__p__%'`
-if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
+       if test $ol_cv_db_db3 = yes ; then
+               ol_cv_lib_db=-ldb3
+       fi
+fi
+
+if test $ol_cv_lib_db = no ; then
+       echo $ac_n "checking for Berkeley DB link (-ldb2)""... $ac_c" 1>&6
+echo "configure:11537: checking for Berkeley DB link (-ldb2)" >&5
+if eval "test \"\${ol_cv_db_db2+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  ac_save_LIBS="$LIBS"
-LIBS="-ldb1  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 10432 "configure"
+  
+       ol_DB_LIB=-ldb2
+       ol_LIBS=$LIBS
+       LIBS="$ol_DB_LIB $LIBS"
+
+       cat > conftest.$ac_ext <<EOF
+#line 11547 "configure"
 #include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error.  */
-/* We use char because int might match the return type of a gcc2
-    builtin and then its argument prototype would still apply.  */
-char dbopen();
+
+#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() {
-dbopen()
+
+#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; }
 EOF
-if { (eval echo configure:10443: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:11576: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
+  ol_cv_db_db2=yes
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
+  ol_cv_db_db2=no
 fi
 rm -f conftest*
-LIBS="$ac_save_LIBS"
+
+       LIBS="$ol_LIBS"
 
 fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-  ol_cv_lib_db=-ldb1
-else
-  echo "$ac_t""no" 1>&6
 
-                       echo $ac_n "checking for dbopen in -ldb""... $ac_c" 1>&6
-echo "configure:10463: checking for dbopen in -ldb" >&5
-ac_lib_var=`echo db'_'dbopen | sed 'y%./+-:%__p__%'`
-if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
+echo "$ac_t""$ol_cv_db_db2" 1>&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 $ac_n "checking for Berkeley DB link (-ldb1)""... $ac_c" 1>&6
+echo "configure:11600: checking for Berkeley DB link (-ldb1)" >&5
+if eval "test \"\${ol_cv_db_db1+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  ac_save_LIBS="$LIBS"
-LIBS="-ldb  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 10471 "configure"
+  
+       ol_DB_LIB=-ldb1
+       ol_LIBS=$LIBS
+       LIBS="$ol_DB_LIB $LIBS"
+
+       cat > conftest.$ac_ext <<EOF
+#line 11610 "configure"
 #include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error.  */
-/* We use char because int might match the return type of a gcc2
-    builtin and then its argument prototype would still apply.  */
-char dbopen();
+
+#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() {
-dbopen()
+
+#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; }
 EOF
-if { (eval echo configure:10482: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:11639: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
+  ol_cv_db_db1=yes
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
+  ol_cv_db_db1=no
 fi
 rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-  ol_cv_lib_db=-ldb
-else
-  echo "$ac_t""no" 1>&6
-ol_cv_lib_db=no
-fi
 
-               
-fi
+       LIBS="$ol_LIBS"
 
-       
 fi
 
-       LIBS="$ol_LIBS"
+echo "$ac_t""$ol_cv_db_db1" 1>&6
 
+       if test $ol_cv_db_db1 = yes ; then
+               ol_cv_lib_db=-ldb1
+       fi
 fi
 
-echo "$ac_t""$ol_cv_lib_db" 1>&6
 
+               if test "$ol_cv_lib_db" != no ; then
+                       ol_cv_berkeley_db=yes
+               fi
+       fi
+fi
 
-for ac_hdr in db_185.h
+       else
+               ol_cv_berkeley_db=no
+for ac_hdr in db.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:10520: checking for $ac_hdr" >&5
+echo "configure:11674: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 10525 "configure"
+#line 11679 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:10530: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:11684: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
 fi
 done
 
-if test "$ol_cv_header_db2" = yes ; then
-       
-       ol_cv_header_db=$ac_cv_header_db_185_h
+if test $ac_cv_header_db_h = yes; then
+       ol_cv_lib_db=no
+if test $ol_cv_lib_db = no ; then
+       echo $ac_n "checking for Berkeley DB link (default)""... $ac_c" 1>&6
+echo "configure:11714: checking for Berkeley DB link (default)" >&5
+if eval "test \"\${ol_cv_db_none+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
-       ol_cv_header_db=$ac_cv_header_db_h
+  
+       ol_DB_LIB=
+       ol_LIBS=$LIBS
+       LIBS="$ol_DB_LIB $LIBS"
+
+       cat > conftest.$ac_ext <<EOF
+#line 11724 "configure"
+#include "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 > 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; }
+EOF
+if { (eval echo configure:11753: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ol_cv_db_none=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ol_cv_db_none=no
 fi
+rm -f conftest*
 
+       LIBS="$ol_LIBS"
 
- echo $ac_n "checking for Berkeley DB""... $ac_c" 1>&6
-echo "configure:10566: checking for Berkeley DB" >&5
-if eval "test \"\${ol_cv_berkeley_db+set}\" = set"; then
+fi
+
+echo "$ac_t""$ol_cv_db_none" 1>&6
+
+       if test $ol_cv_db_none = yes ; then
+               ol_cv_lib_db=yes
+       fi
+fi
+
+if test $ol_cv_lib_db = no ; then
+       echo $ac_n "checking for Berkeley DB link (-ldb)""... $ac_c" 1>&6
+echo "configure:11777: checking for Berkeley DB link (-ldb)" >&5
+if eval "test \"\${ol_cv_db_db+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
-       if test "$ol_cv_lib_db" = no -o "$ol_cv_header_db" = no ; then
-               ol_cv_berkeley_db=no
-       else
-               ol_cv_berkeley_db=yes
-       fi
+       ol_DB_LIB=-ldb
+       ol_LIBS=$LIBS
+       LIBS="$ol_DB_LIB $LIBS"
 
-fi
+       cat > conftest.$ac_ext <<EOF
+#line 11787 "configure"
+#include "confdefs.h"
 
-echo "$ac_t""$ol_cv_berkeley_db" 1>&6
- if test $ol_cv_berkeley_db = yes ; then
-       cat >> confdefs.h <<\EOF
-#define HAVE_BERKELEY_DB 1
-EOF
+#ifdef HAVE_DB_185_H
+# include <db_185.h>
+#else
+# include <db.h>
+#endif
 
- fi
+#ifndef DB_VERSION_MAJOR
+# define DB_VERSION_MAJOR 1
+#endif
 
+#ifndef NULL
+#define NULL ((void*)0)
+#endif
 
-       if test $ol_cv_berkeley_db = yes ; then
-               ol_link_ldbm=db
-               ol_with_ldbm_api=db
+int main() {
 
-               if test $ol_with_ldbm_type = hash ; then
-                       cat >> confdefs.h <<\EOF
-#define LDBM_USE_DBHASH 1
+#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; }
 EOF
+if { (eval echo configure:11816: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ol_cv_db_db=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ol_cv_db_db=no
+fi
+rm -f conftest*
 
-               else
-                       cat >> confdefs.h <<\EOF
-#define LDBM_USE_DBBTREE 1
+       LIBS="$ol_LIBS"
+
+fi
+
+echo "$ac_t""$ol_cv_db_db" 1>&6
+
+       if test $ol_cv_db_db = yes ; then
+               ol_cv_lib_db=-ldb
+       fi
+fi
+
+if test $ol_cv_lib_db = no ; then
+       echo $ac_n "checking for Berkeley DB link (-ldb3)""... $ac_c" 1>&6
+echo "configure:11840: checking for Berkeley DB link (-ldb3)" >&5
+if eval "test \"\${ol_cv_db_db3+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+       ol_DB_LIB=-ldb3
+       ol_LIBS=$LIBS
+       LIBS="$ol_DB_LIB $LIBS"
+
+       cat > conftest.$ac_ext <<EOF
+#line 11850 "configure"
+#include "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 > 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; }
 EOF
+if { (eval echo configure:11879: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ol_cv_db_db3=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ol_cv_db_db3=no
+fi
+rm -f conftest*
 
-               fi
+       LIBS="$ol_LIBS"
 
-                                               if test $ol_cv_lib_db != yes ; then
-                       LDBM_LIBS="$LDBM_LIBS $ol_cv_lib_db"
-               fi
+fi
+
+echo "$ac_t""$ol_cv_db_db3" 1>&6
+
+       if test $ol_cv_db_db3 = yes ; then
+               ol_cv_lib_db=-ldb3
        fi
 fi
 
-if test $ol_with_ldbm_api = manual ; then
-               ol_link_ldbm=yes
+if test $ol_cv_lib_db = no ; then
+       echo $ac_n "checking for Berkeley DB link (-ldb2)""... $ac_c" 1>&6
+echo "configure:11903: checking for Berkeley DB link (-ldb2)" >&5
+if eval "test \"\${ol_cv_db_db2+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+       ol_DB_LIB=-ldb2
+       ol_LIBS=$LIBS
+       LIBS="$ol_DB_LIB $LIBS"
 
-       echo "configure: warning: LDBM defines and link options must be set manually" 1>&2
+       cat > conftest.$ac_ext <<EOF
+#line 11913 "configure"
+#include "confdefs.h"
 
-       for ac_hdr in db.h db_185.h gdbm.h ndbm.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:10619: checking for $ac_hdr" >&5
-if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
+#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 > 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; }
+EOF
+if { (eval echo configure:11942: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ol_cv_db_db2=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ol_cv_db_db2=no
+fi
+rm -f conftest*
+
+       LIBS="$ol_LIBS"
+
+fi
+
+echo "$ac_t""$ol_cv_db_db2" 1>&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 $ac_n "checking for Berkeley DB link (-ldb1)""... $ac_c" 1>&6
+echo "configure:11966: checking for Berkeley DB link (-ldb1)" >&5
+if eval "test \"\${ol_cv_db_db1+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  cat > conftest.$ac_ext <<EOF
-#line 10624 "configure"
+  
+       ol_DB_LIB=-ldb1
+       ol_LIBS=$LIBS
+       LIBS="$ol_DB_LIB $LIBS"
+
+       cat > conftest.$ac_ext <<EOF
+#line 11976 "configure"
 #include "confdefs.h"
-#include <$ac_hdr>
+
+#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 > 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; }
 EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:10629: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
+if { (eval echo configure:12005: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
-  eval "ac_cv_header_$ac_safe=yes"
+  ol_cv_db_db1=yes
 else
-  echo "$ac_err" >&5
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  eval "ac_cv_header_$ac_safe=no"
+  ol_cv_db_db1=no
 fi
 rm -f conftest*
+
+       LIBS="$ol_LIBS"
+
 fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
+
+echo "$ac_t""$ol_cv_db_db1" 1>&6
+
+       if test $ol_cv_db_db1 = yes ; then
+               ol_cv_lib_db=-ldb1
+       fi
+fi
+
+
+       if test "$ol_cv_lib_db" != no ; then
+               ol_cv_berkeley_db=yes
+               echo $ac_n "checking for Berkeley DB thread support""... $ac_c" 1>&6
+echo "configure:12031: checking for Berkeley DB thread support" >&5
+if eval "test \"\${ol_cv_berkeley_db_thread+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+       ol_LIBS="$LIBS"
+       if test $ol_cv_lib_db != yes ; then
+               LIBS="$ol_cv_lib_db"
+       fi
+
+       if test "$cross_compiling" = yes; then
+  ol_cv_berkeley_db_thread=cross
+else
+  cat > conftest.$ac_ext <<EOF
+#line 12045 "configure"
+#include "confdefs.h"
+
+#ifdef HAVE_DB_185_H
+       choke me;
+#else
+#include <db.h>
+#endif
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+main()
+{
+       int rc;
+       u_int32_t flags = DB_CREATE | DB_THREAD;
+
+
+#if DB_VERSION_MAJOR > 2
+       DB_ENV *env = NULL;
+
+       rc = db_env_create( &env, 0 );
+
+       if( rc == 0 ) {
+               rc = env->open( env, NULL, NULL, flags, 0 );
+       }
+
+#else
+       DB_ENV env;
+       memset( &env, '\0', sizeof(env) );
+
+       rc = db_appinit( NULL, NULL, &env, flags );
+
+       if( rc == 0 ) {
+               db_appexit( &env );
+       }
+#endif
+
+       return rc;
+}
+EOF
+if { (eval echo configure:12085: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ol_cv_berkeley_db_thread=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ol_cv_berkeley_db_thread=no
+fi
+rm -fr conftest*
+fi
+
+
+       LIBS="$ol_LIBS"
+
+       if test $ol_cv_berkeley_db_thread != no ; then
+               cat >> confdefs.h <<\EOF
+#define HAVE_BERKELEY_DB_THREAD 1
+EOF
+
+       fi
+
+fi
+
+echo "$ac_t""$ol_cv_berkeley_db_thread" 1>&6
+       fi
+fi
+
+       fi
+
+       if test $ol_cv_berkeley_db != no ; then
+               cat >> confdefs.h <<\EOF
+#define HAVE_BERKELEY_DB 1
+EOF
+
+
+               ol_link_ldbm=berkeley
+               ol_with_ldbm_api=db
+
+               if test $ol_with_ldbm_type = hash ; then
+                       cat >> confdefs.h <<\EOF
+#define LDBM_USE_DBHASH 1
 EOF
-else
-  echo "$ac_t""no" 1>&6
-fi
-done
 
+               else
+                       cat >> confdefs.h <<\EOF
+#define LDBM_USE_DBBTREE 1
+EOF
+
+               fi
+
+                                               if test $ol_cv_lib_db != yes ; then
+                       LDBM_LIBS="$LDBM_LIBS $ol_cv_lib_db"
+               fi
+       fi
 fi
 
 if test $ol_link_ldbm = no -a $ol_with_ldbm_type = btree ; then
 
 if test $ol_with_ldbm_api = auto -o $ol_with_ldbm_api = mdbm ; then
        echo $ac_n "checking for MDBM library""... $ac_c" 1>&6
-echo "configure:10664: checking for MDBM library" >&5
+echo "configure:12149: checking for MDBM library" >&5
 if eval "test \"\${ol_cv_lib_mdbm+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
        ol_LIBS="$LIBS"
        echo $ac_n "checking for mdbm_set_chain""... $ac_c" 1>&6
-echo "configure:10670: checking for mdbm_set_chain" >&5
+echo "configure:12155: checking for mdbm_set_chain" >&5
 if eval "test \"\${ac_cv_func_mdbm_set_chain+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 10675 "configure"
+#line 12160 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char mdbm_set_chain(); below.  */
@@ -10695,7 +12180,7 @@ f = mdbm_set_chain;
 
 ; return 0; }
 EOF
-if { (eval echo configure:10699: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:12184: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_mdbm_set_chain=yes"
 else
@@ -10714,7 +12199,7 @@ else
   echo "$ac_t""no" 1>&6
 
                echo $ac_n "checking for mdbm_set_chain in -lmdbm""... $ac_c" 1>&6
-echo "configure:10718: checking for mdbm_set_chain in -lmdbm" >&5
+echo "configure:12203: checking for mdbm_set_chain in -lmdbm" >&5
 ac_lib_var=`echo mdbm'_'mdbm_set_chain | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -10722,7 +12207,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lmdbm  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 10726 "configure"
+#line 12211 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -10733,7 +12218,7 @@ int main() {
 mdbm_set_chain()
 ; return 0; }
 EOF
-if { (eval echo configure:10737: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:12222: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -10768,17 +12253,17 @@ echo "$ac_t""$ol_cv_lib_mdbm" 1>&6
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:10772: checking for $ac_hdr" >&5
+echo "configure:12257: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 10777 "configure"
+#line 12262 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:10782: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:12267: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -10805,7 +12290,7 @@ fi
 done
 
  echo $ac_n "checking for db""... $ac_c" 1>&6
-echo "configure:10809: checking for db" >&5
+echo "configure:12294: checking for db" >&5
 if eval "test \"\${ol_cv_mdbm+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
 
 if test $ol_with_ldbm_api = auto -o $ol_with_ldbm_api = gdbm ; then
        echo $ac_n "checking for GDBM library""... $ac_c" 1>&6
-echo "configure:10842: checking for GDBM library" >&5
+echo "configure:12327: checking for GDBM library" >&5
 if eval "test \"\${ol_cv_lib_gdbm+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
        ol_LIBS="$LIBS"
        echo $ac_n "checking for gdbm_open""... $ac_c" 1>&6
-echo "configure:10848: checking for gdbm_open" >&5
+echo "configure:12333: checking for gdbm_open" >&5
 if eval "test \"\${ac_cv_func_gdbm_open+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 10853 "configure"
+#line 12338 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char gdbm_open(); below.  */
@@ -10873,7 +12358,7 @@ f = gdbm_open;
 
 ; return 0; }
 EOF
-if { (eval echo configure:10877: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:12362: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_gdbm_open=yes"
 else
@@ -10892,7 +12377,7 @@ else
   echo "$ac_t""no" 1>&6
 
                echo $ac_n "checking for gdbm_open in -lgdbm""... $ac_c" 1>&6
-echo "configure:10896: checking for gdbm_open in -lgdbm" >&5
+echo "configure:12381: checking for gdbm_open in -lgdbm" >&5
 ac_lib_var=`echo gdbm'_'gdbm_open | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -10900,7 +12385,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lgdbm  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 10904 "configure"
+#line 12389 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -10911,7 +12396,7 @@ int main() {
 gdbm_open()
 ; return 0; }
 EOF
-if { (eval echo configure:10915: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:12400: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -10946,17 +12431,17 @@ echo "$ac_t""$ol_cv_lib_gdbm" 1>&6
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:10950: checking for $ac_hdr" >&5
+echo "configure:12435: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 10955 "configure"
+#line 12440 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:10960: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:12445: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -10983,7 +12468,7 @@ fi
 done
 
  echo $ac_n "checking for db""... $ac_c" 1>&6
-echo "configure:10987: checking for db" >&5
+echo "configure:12472: checking for db" >&5
 if eval "test \"\${ol_cv_gdbm+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -11015,22 +12500,20 @@ EOF
        fi
 fi
 
-if test $ol_with_ldbm_api = auto ; then
-       echo "configure: warning: skipping automatic checking for NDBM, must be manually enabled." 1>&2
-elif test $ol_with_ldbm_api = ndbm ; then
+if test $ol_with_ldbm_api = ndbm ; then
        echo $ac_n "checking for NDBM library""... $ac_c" 1>&6
-echo "configure:11023: checking for NDBM library" >&5
+echo "configure:12506: checking for NDBM library" >&5
 if eval "test \"\${ol_cv_lib_ndbm+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
        ol_LIBS="$LIBS"
        echo $ac_n "checking for dbm_open""... $ac_c" 1>&6
-echo "configure:11029: checking for dbm_open" >&5
+echo "configure:12512: checking for dbm_open" >&5
 if eval "test \"\${ac_cv_func_dbm_open+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 11034 "configure"
+#line 12517 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char dbm_open(); below.  */
@@ -11054,7 +12537,7 @@ f = dbm_open;
 
 ; return 0; }
 EOF
-if { (eval echo configure:11058: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:12541: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_dbm_open=yes"
 else
@@ -11073,7 +12556,7 @@ else
   echo "$ac_t""no" 1>&6
 
                echo $ac_n "checking for dbm_open in -lndbm""... $ac_c" 1>&6
-echo "configure:11077: checking for dbm_open in -lndbm" >&5
+echo "configure:12560: checking for dbm_open in -lndbm" >&5
 ac_lib_var=`echo ndbm'_'dbm_open | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -11081,7 +12564,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lndbm  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 11085 "configure"
+#line 12568 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -11092,7 +12575,7 @@ int main() {
 dbm_open()
 ; return 0; }
 EOF
-if { (eval echo configure:11096: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:12579: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -11112,7 +12595,7 @@ else
   echo "$ac_t""no" 1>&6
 
                        echo $ac_n "checking for dbm_open in -ldbm""... $ac_c" 1>&6
-echo "configure:11116: checking for dbm_open in -ldbm" >&5
+echo "configure:12599: checking for dbm_open in -ldbm" >&5
 ac_lib_var=`echo dbm'_'dbm_open | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -11120,7 +12603,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ldbm  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 11124 "configure"
+#line 12607 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -11131,7 +12614,7 @@ int main() {
 dbm_open()
 ; return 0; }
 EOF
-if { (eval echo configure:11135: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:12618: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -11168,17 +12651,17 @@ echo "$ac_t""$ol_cv_lib_ndbm" 1>&6
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:11172: checking for $ac_hdr" >&5
+echo "configure:12655: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 11177 "configure"
+#line 12660 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:11182: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:12665: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -11205,7 +12688,7 @@ fi
 done
 
  echo $ac_n "checking for db""... $ac_c" 1>&6
-echo "configure:11209: checking for db" >&5
+echo "configure:12692: checking for db" >&5
 if eval "test \"\${ol_cv_ndbm+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -11247,22 +12730,28 @@ if test $ol_link_ldbm = no -a $ol_enable_ldbm != no ; then
        ol_enable_ldbm=no
 fi
 
+if test $ol_enable_dynamic = yes -a $enable_shared = yes ; then
+       LINK_BINS_DYNAMIC="yes"
+else
+       LINK_BINS_DYNAMIC="no"
+fi
+
 if test $ol_enable_wrappers != no ; then
        for ac_hdr in tcpd.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:11256: checking for $ac_hdr" >&5
+echo "configure:12745: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 11261 "configure"
+#line 12750 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:11266: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:12755: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -11292,43 +12781,27 @@ done
        if test $ac_cv_header_tcpd_h != yes ; then
                have_wrappers=no
        else
-               echo $ac_n "checking for main in -lwrap""... $ac_c" 1>&6
-echo "configure:11297: checking for main in -lwrap" >&5
-ac_lib_var=`echo wrap'_'main | sed 'y%./+-:%__p__%'`
-if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  ac_save_LIBS="$LIBS"
-LIBS="-lwrap  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 11305 "configure"
+               cat > conftest.$ac_ext <<EOF
+#line 12786 "configure"
 #include "confdefs.h"
 
+int allow_severity = 0;
+int deny_severity  = 0;
+               
 int main() {
-main()
+hosts_access()
 ; return 0; }
 EOF
-if { (eval echo configure:11312: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:12796: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
+  have_wrappers=yes
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
+  have_wrappers=no
 fi
 rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-  have_wrappers=yes
-else
-  echo "$ac_t""no" 1>&6
-have_wrappers=no
-fi
-
        fi
 
        if test $have_wrappers = yes ; then
 #define HAVE_TCPD 1
 EOF
 
-               SLAPD_LIBS="$SLAPD_LIBS -lwrap"
+               WRAP_LIBS="-lwrap"
 
                                                echo $ac_n "checking for main in -lnsl""... $ac_c" 1>&6
-echo "configure:11343: checking for main in -lnsl" >&5
+echo "configure:12816: checking for main in -lnsl" >&5
 ac_lib_var=`echo nsl'_'main | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -11347,14 +12820,14 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lnsl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 11351 "configure"
+#line 12824 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:11358: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:12831: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
 
                echo "configure: warning: disabling wrappers support" 1>&2
                ol_enable_wrappers=no
+               WRAP_LIBS=""
        fi
 fi
 
 if test $ol_enable_syslog != no ; then
        echo $ac_n "checking for openlog""... $ac_c" 1>&6
-echo "configure:11398: checking for openlog" >&5
+echo "configure:12872: checking for openlog" >&5
 if eval "test \"\${ac_cv_func_openlog+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 11403 "configure"
+#line 12877 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char openlog(); below.  */
@@ -11423,7 +12897,7 @@ f = openlog;
 
 ; return 0; }
 EOF
-if { (eval echo configure:11427: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:12901: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_openlog=yes"
 else
        if test $ac_cv_func_openlog = no -a $ol_enable_syslog = yes; then
                { echo "configure: error: could not find syslog" 1>&2; exit 1; }
        fi
-       ol_enable_syslog=$ac_cv_func_openlog
-fi
-
-if test $ol_enable_dmalloc != no ; then
-       for ac_hdr in dmalloc.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:11457: checking for $ac_hdr" >&5
-if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 11462 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:11467: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
-  rm -rf conftest*
-  eval "ac_cv_header_$ac_safe=yes"
-else
-  echo "$ac_err" >&5
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-else
-  echo "$ac_t""no" 1>&6
-fi
-done
-
-       echo $ac_n "checking for dmalloc_shutdown in -ldmalloc""... $ac_c" 1>&6
-echo "configure:11494: checking for dmalloc_shutdown in -ldmalloc" >&5
-ac_lib_var=`echo dmalloc'_'dmalloc_shutdown | sed 'y%./+-:%__p__%'`
-if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  ac_save_LIBS="$LIBS"
-LIBS="-ldmalloc  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 11502 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error.  */
-/* We use char because int might match the return type of a gcc2
-    builtin and then its argument prototype would still apply.  */
-char dmalloc_shutdown();
-
-int main() {
-dmalloc_shutdown()
-; return 0; }
-EOF
-if { (eval echo configure:11513: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo dmalloc | sed -e 's/[^a-zA-Z0-9_]/_/g' \
-    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
-  LIBS="-ldmalloc $LIBS"
-
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-fi
-
-if test $ol_enable_tcl != no ; then
-       for ac_hdr in tcl.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:11547: checking for $ac_hdr" >&5
-if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 11552 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:11557: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
-  rm -rf conftest*
-  eval "ac_cv_header_$ac_safe=yes"
-else
-  echo "$ac_err" >&5
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-else
-  echo "$ac_t""no" 1>&6
-fi
-done
-
-
-       if test $ac_cv_header_tcl_h != yes ; then
-               have_tcl=no
-       else
-               echo $ac_n "checking for main in -ltcl""... $ac_c" 1>&6
-echo "configure:11588: checking for main in -ltcl" >&5
-ac_lib_var=`echo tcl'_'main | sed 'y%./+-:%__p__%'`
-if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  ac_save_LIBS="$LIBS"
-LIBS="-ltcl  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 11596 "configure"
-#include "confdefs.h"
-
-int main() {
-main()
-; return 0; }
-EOF
-if { (eval echo configure:11603: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-  have_tcl=yes; SLAPD_LIBS="$SLAPD_LIBS -ltcl"
-else
-  echo "$ac_t""no" 1>&6
-have_tcl=no
-fi
-
-
-               if test $have_tcl != yes; then
-                       echo $ac_n "checking for main in -ltcl7.6""... $ac_c" 1>&6
-echo "configure:11627: checking for main in -ltcl7.6" >&5
-ac_lib_var=`echo tcl7.6'_'main | sed 'y%./+-:%__p__%'`
-if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  ac_save_LIBS="$LIBS"
-LIBS="-ltcl7.6  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 11635 "configure"
-#include "confdefs.h"
-
-int main() {
-main()
-; return 0; }
-EOF
-if { (eval echo configure:11642: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-  have_tcl=yes; SLAPD_LIBS="$SLAPD_LIBS -ltcl7.6"
-else
-  echo "$ac_t""no" 1>&6
-have_tcl=no
-fi
-
-               fi
-
-               if test $have_tcl != yes; then
-                       echo $ac_n "checking for main in -ltcl8.0""... $ac_c" 1>&6
-echo "configure:11667: checking for main in -ltcl8.0" >&5
-ac_lib_var=`echo tcl8.0'_'main | sed 'y%./+-:%__p__%'`
-if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  ac_save_LIBS="$LIBS"
-LIBS="-ltcl8.0  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 11675 "configure"
-#include "confdefs.h"
-
-int main() {
-main()
-; return 0; }
-EOF
-if { (eval echo configure:11682: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-  have_tcl=yes; SLAPD_LIBS="$SLAPD_LIBS -ltcl8.0"
-else
-  echo "$ac_t""no" 1>&6
-have_tcl=no
-fi
-
-               fi
-       fi
-
-       if test $have_tcl != yes ; then
-               echo "configure: warning: could not find -ltcl" 1>&2
-               if test $ol_enable_tcl = yes ; then
-                       { echo "configure: error: could not find tcl, select appropriate options or disable" 1>&2; exit 1; }
-               fi
-
-               ol_enable_tcl=no
-       fi
+       ol_enable_syslog=$ac_cv_func_openlog
 fi
 
-# ud needs termcap (should insert check here)
 ol_link_termcap=no
 for ac_hdr in termcap.h ncurses.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:11722: checking for $ac_hdr" >&5
+echo "configure:12931: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 11727 "configure"
+#line 12936 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:11732: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:12941: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -11757,7 +12966,7 @@ done
 
 if test $ol_link_termcap = no ; then
        echo $ac_n "checking for tputs in -ltermcap""... $ac_c" 1>&6
-echo "configure:11761: checking for tputs in -ltermcap" >&5
+echo "configure:12970: checking for tputs in -ltermcap" >&5
 ac_lib_var=`echo termcap'_'tputs | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -11765,7 +12974,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ltermcap  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 11769 "configure"
+#line 12978 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -11776,7 +12985,7 @@ int main() {
 tputs()
 ; return 0; }
 EOF
-if { (eval echo configure:11780: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:12989: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -11809,7 +13018,7 @@ fi
 
 if test $ol_link_termcap = no ; then
        echo $ac_n "checking for initscr in -lncurses""... $ac_c" 1>&6
-echo "configure:11813: checking for initscr in -lncurses" >&5
+echo "configure:13022: checking for initscr in -lncurses" >&5
 ac_lib_var=`echo ncurses'_'initscr | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -11817,7 +13026,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lncurses  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 11821 "configure"
+#line 13030 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -11828,7 +13037,7 @@ int main() {
 initscr()
 ; return 0; }
 EOF
-if { (eval echo configure:11832: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:13041: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -11868,20 +13077,21 @@ EOF
 fi
 
 ol_link_sasl=no
+ol_link_spasswd=no
 if test $ol_with_cyrus_sasl != no ; then
        ac_safe=`echo "sasl.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for sasl.h""... $ac_c" 1>&6
-echo "configure:11875: checking for sasl.h" >&5
+echo "configure:13085: checking for sasl.h" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 11880 "configure"
+#line 13090 "configure"
 #include "confdefs.h"
 #include <sasl.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:11885: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:13095: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -11905,7 +13115,7 @@ fi
 
        if test $ac_cv_header_sasl_h = yes ; then
                echo $ac_n "checking for sasl_client_init in -lsasl""... $ac_c" 1>&6
-echo "configure:11909: checking for sasl_client_init in -lsasl" >&5
+echo "configure:13119: checking for sasl_client_init in -lsasl" >&5
 ac_lib_var=`echo sasl'_'sasl_client_init | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -11913,7 +13123,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsasl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 11917 "configure"
+#line 13127 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -11924,7 +13134,7 @@ int main() {
 sasl_client_init()
 ; return 0; }
 EOF
-if { (eval echo configure:11928: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:13138: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -11961,18 +13171,40 @@ EOF
        fi
 fi
 
+if test $cross_compiling != yes ; then
+       dev=no
+       if test -r /dev/urandom ; then
+               dev="/dev/urandom";
+       elif test -r /idev/urandom ; then
+               dev="/idev/urandom";
+       elif test -r /dev/srandom ; then
+               dev="/dev/srandom";
+       elif test -r /dev/random ; then
+               dev="/dev/random";
+       elif test -r /idev/random ; then
+               dev="/idev/random";
+       fi
+
+       if test $dev != no ; then
+               cat >> confdefs.h <<EOF
+#define URANDOM_DEVICE "$dev"
+EOF
+
+       fi
+fi
+
 ol_link_fetch=no
 if test $ol_with_fetch != no ; then
-       ol=$LIBS
+       ol_LIBS=$LIBS
 LIBS="-lfetch -lcom_err $LIBS"
 echo $ac_n "checking fetch(3) library""... $ac_c" 1>&6
-echo "configure:11970: checking fetch(3) library" >&5
+echo "configure:13202: checking fetch(3) library" >&5
 if eval "test \"\${ol_cv_lib_fetch+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
        cat > conftest.$ac_ext <<EOF
-#line 11976 "configure"
+#line 13208 "configure"
 #include "confdefs.h"
 
 #include <sys/param.h>
@@ -11982,7 +13214,7 @@ int main() {
 struct url *u = fetchParseURL("file:///"); 
 ; return 0; }
 EOF
-if { (eval echo configure:11986: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:13218: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_lib_fetch=yes
 else
@@ -12020,17 +13252,17 @@ if test $ol_with_readline != no ; then
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:12024: checking for $ac_hdr" >&5
+echo "configure:13256: checking for $ac_hdr" >&5
 if eval "test \"\${ac_cv_header_$ac_safe+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 12029 "configure"
+#line 13261 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:12034: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:13266: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -12061,7 +13293,7 @@ done
                save_LIBS="$LIBS"
                LIBS="$TERMCAP_LIBS $LIBS"
                echo $ac_n "checking for readline in -lreadline""... $ac_c" 1>&6
-echo "configure:12065: checking for readline in -lreadline" >&5
+echo "configure:13297: checking for readline in -lreadline" >&5
 ac_lib_var=`echo readline'_'readline | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -12069,7 +13301,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lreadline  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 12073 "configure"
+#line 13305 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -12080,7 +13312,7 @@ int main() {
 readline()
 ; return 0; }
 EOF
-if { (eval echo configure:12084: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:13316: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -12120,15 +13352,14 @@ EOF
 fi
 
 
-# FreeBSD (and others) have crypt(3) in -lcrypt
 if test $ol_enable_crypt != no ; then
        echo $ac_n "checking for crypt""... $ac_c" 1>&6
-echo "configure:12127: checking for crypt" >&5
+echo "configure:13358: checking for crypt" >&5
 if eval "test \"\${ac_cv_func_crypt+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 12132 "configure"
+#line 13363 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char crypt(); below.  */
@@ -12152,7 +13383,7 @@ f = crypt;
 
 ; return 0; }
 EOF
-if { (eval echo configure:12156: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:13387: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_crypt=yes"
 else
@@ -12171,7 +13402,7 @@ else
   echo "$ac_t""no" 1>&6
 
                echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6
-echo "configure:12175: checking for crypt in -lcrypt" >&5
+echo "configure:13406: checking for crypt in -lcrypt" >&5
 ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -12179,7 +13410,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lcrypt  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 12183 "configure"
+#line 13414 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -12190,7 +13421,7 @@ int main() {
 crypt()
 ; return 0; }
 EOF
-if { (eval echo configure:12194: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:13425: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -12231,15 +13462,14 @@ EOF
        fi
 fi
 
-# FreeBSD (and others) have setproctitle(3) in -lutil
 if test $ol_enable_proctitle != no ; then
        echo $ac_n "checking for setproctitle""... $ac_c" 1>&6
-echo "configure:12238: checking for setproctitle" >&5
+echo "configure:13468: checking for setproctitle" >&5
 if eval "test \"\${ac_cv_func_setproctitle+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 12243 "configure"
+#line 13473 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char setproctitle(); below.  */
@@ -12263,7 +13493,7 @@ f = setproctitle;
 
 ; return 0; }
 EOF
-if { (eval echo configure:12267: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:13497: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_setproctitle=yes"
 else
@@ -12282,7 +13512,7 @@ else
   echo "$ac_t""no" 1>&6
 
                echo $ac_n "checking for setproctitle in -lutil""... $ac_c" 1>&6
-echo "configure:12286: checking for setproctitle in -lutil" >&5
+echo "configure:13516: checking for setproctitle in -lutil" >&5
 ac_lib_var=`echo util'_'setproctitle | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -12290,7 +13520,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lutil  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 12294 "configure"
+#line 13524 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -12301,7 +13531,7 @@ int main() {
 setproctitle()
 ; return 0; }
 EOF
-if { (eval echo configure:12305: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:13535: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -12322,6 +13552,7 @@ else
   echo "$ac_t""no" 1>&6
 have_setproctitle=no
                        LIBOBJS="$LIBOBJS setproctitle.o"
+                       LIBSRCS="$LIBSRCS setproctitle.c"
 fi
 
 fi
        fi
 fi
 
-echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
-echo "configure:12340: checking for uid_t in sys/types.h" >&5
-if eval "test \"\${ac_cv_type_uid_t+set}\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 12345 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  egrep "uid_t" >/dev/null 2>&1; then
-  rm -rf conftest*
-  ac_cv_type_uid_t=yes
-else
-  rm -rf conftest*
-  ac_cv_type_uid_t=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_type_uid_t" 1>&6
-if test $ac_cv_type_uid_t = no; then
-  cat >> confdefs.h <<\EOF
-#define uid_t int
-EOF
-
-  cat >> confdefs.h <<\EOF
-#define gid_t int
-EOF
-
-fi
-
-echo $ac_n "checking type of array argument to getgroups""... $ac_c" 1>&6
-echo "configure:12374: checking type of array argument to getgroups" >&5
-if eval "test \"\${ac_cv_type_getgroups+set}\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test "$cross_compiling" = yes; then
-  ac_cv_type_getgroups=cross
-else
-  cat > conftest.$ac_ext <<EOF
-#line 12382 "configure"
-#include "confdefs.h"
-
-/* Thanks to Mike Rendell for this test.  */
-#include <sys/types.h>
-#define NGID 256
-#undef MAX
-#define MAX(x, y) ((x) > (y) ? (x) : (y))
-main()
-{
-  gid_t gidset[NGID];
-  int i, n;
-  union { gid_t gval; long lval; }  val;
-
-  val.lval = -1;
-  for (i = 0; i < NGID; i++)
-    gidset[i] = val.gval;
-  n = getgroups (sizeof (gidset) / MAX (sizeof (int), sizeof (gid_t)) - 1,
-                 gidset);
-  /* Exit non-zero if getgroups seems to require an array of ints.  This
-     happens when gid_t is short but getgroups modifies an array of ints.  */
-  exit ((n > 0 && gidset[n] != val.gval) ? 1 : 0);
-}
-
-EOF
-if { (eval echo configure:12407: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
-then
-    ac_cv_type_getgroups=gid_t
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -fr conftest*
-  ac_cv_type_getgroups=int
-fi
-rm -fr conftest*
-fi
-
-if test $ac_cv_type_getgroups = cross; then
-        cat > conftest.$ac_ext <<EOF
-#line 12421 "configure"
-#include "confdefs.h"
-#include <unistd.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  egrep "getgroups.*int.*gid_t" >/dev/null 2>&1; then
-  rm -rf conftest*
-  ac_cv_type_getgroups=gid_t
-else
-  rm -rf conftest*
-  ac_cv_type_getgroups=int
-fi
-rm -f conftest*
-
-fi
-fi
-
-echo "$ac_t""$ac_cv_type_getgroups" 1>&6
-cat >> confdefs.h <<EOF
-#define GETGROUPS_T $ac_cv_type_getgroups
-EOF
-
- echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:12444: checking for ANSI C header files" >&5
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:13571: checking for ANSI C header files" >&5
 if eval "test \"\${ac_cv_header_stdc+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 12449 "configure"
+#line 13576 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -12453,7 +13580,7 @@ else
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:12457: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:13584: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -12470,7 +13597,7 @@ rm -f conftest*
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 12474 "configure"
+#line 13601 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -12488,7 +13615,7 @@ fi
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 12492 "configure"
+#line 13619 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -12509,18 +13636,25 @@ if test "$cross_compiling" = yes; then
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 12513 "configure"
+#line 13640 "configure"
 #include "confdefs.h"
 #include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
 #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+#define ISLOWER(c) (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+#define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
 #define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
 int main () { int i; for (i = 0; i < 256; i++)
 if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
 exit (0); }
 
 EOF
-if { (eval echo configure:12524: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:13658: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -12544,18 +13678,19 @@ EOF
 fi
 
 echo $ac_n "checking for mode_t""... $ac_c" 1>&6
-echo "configure:12548: checking for mode_t" >&5
+echo "configure:13682: checking for mode_t" >&5
 if eval "test \"\${ac_cv_type_mode_t+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 12553 "configure"
+#line 13687 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
 #include <stdlib.h>
 #include <stddef.h>
 #endif
+
 EOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
   egrep "(^|[^a-zA-Z_0-9])mode_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
@@ -12579,18 +13714,19 @@ EOF
 fi
 
 echo $ac_n "checking for off_t""... $ac_c" 1>&6
-echo "configure:12583: checking for off_t" >&5
+echo "configure:13718: checking for off_t" >&5
 if eval "test \"\${ac_cv_type_off_t+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 12588 "configure"
+#line 13723 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
 #include <stdlib.h>
 #include <stddef.h>
 #endif
+
 EOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
   egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
@@ -12614,18 +13750,19 @@ EOF
 fi
 
 echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:12618: checking for pid_t" >&5
+echo "configure:13754: checking for pid_t" >&5
 if eval "test \"\${ac_cv_type_pid_t+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 12623 "configure"
+#line 13759 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
 #include <stdlib.h>
 #include <stddef.h>
 #endif
+
 EOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
   egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
@@ -12649,19 +13786,19 @@ EOF
 fi
 
 echo $ac_n "checking for ptrdiff_t""... $ac_c" 1>&6
-echo "configure:12653: checking for ptrdiff_t" >&5
+echo "configure:13790: checking for ptrdiff_t" >&5
 if eval "test \"\${am_cv_type_ptrdiff_t+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 12658 "configure"
+#line 13795 "configure"
 #include "confdefs.h"
 #include <stddef.h>
 int main() {
 ptrdiff_t p
 ; return 0; }
 EOF
-if { (eval echo configure:12665: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:13802: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   am_cv_type_ptrdiff_t=yes
 else
@@ -12682,12 +13819,12 @@ EOF
    fi
 
 echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-echo "configure:12686: checking return type of signal handlers" >&5
+echo "configure:13823: checking return type of signal handlers" >&5
 if eval "test \"\${ac_cv_type_signal+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 12691 "configure"
+#line 13828 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <signal.h>
@@ -12704,7 +13841,7 @@ int main() {
 int i;
 ; return 0; }
 EOF
-if { (eval echo configure:12708: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:13845: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_type_signal=void
 else
@@ -12722,81 +13859,123 @@ cat >> confdefs.h <<EOF
 EOF
 
 
-echo $ac_n "checking for sig_atomic_t""... $ac_c" 1>&6
-echo "configure:12727: checking for sig_atomic_t" >&5
-if eval "test \"\${ol_cv_type_sig_atomic_t+set}\" = set"; then
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:13864: checking for size_t" >&5
+if eval "test \"\${ac_cv_type_size_t+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 12732 "configure"
+#line 13869 "configure"
 #include "confdefs.h"
-#include <signal.h>
-int main() {
-sig_atomic_t atomic;
-; return 0; }
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+
 EOF
-if { (eval echo configure:12739: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
   rm -rf conftest*
-  ol_cv_type_sig_atomic_t=yes
+  eval "ac_cv_type_size_t=yes"
 else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
   rm -rf conftest*
-  ol_cv_type_sig_atomic_t=no
+  eval "ac_cv_type_size_t=no"
 fi
 rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_type_'size_t`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+  cat >> confdefs.h <<EOF
+#define size_t unsigned
+EOF
+
 fi
 
-echo "$ac_t""$ol_cv_type_sig_atomic_t" 1>&6
-  if test $ol_cv_type_sig_atomic_t = no; then
-    cat >> confdefs.h <<\EOF
-#define sig_atomic_t int
+
+echo $ac_n "checking for ssize_t""... $ac_c" 1>&6
+echo "configure:13901: checking for ssize_t" >&5
+if eval "test \"\${ac_cv_type_ssize_t+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 13906 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+
 EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "(^|[^a-zA-Z_0-9])ssize_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  rm -rf conftest*
+  eval "ac_cv_type_ssize_t=yes"
+else
+  rm -rf conftest*
+  eval "ac_cv_type_ssize_t=no"
+fi
+rm -f conftest*
 
-  fi
-echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:12760: checking for size_t" >&5
-if eval "test \"\${ac_cv_type_size_t+set}\" = set"; then
+fi
+if eval "test \"`echo '$ac_cv_type_'ssize_t`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+  cat >> confdefs.h <<EOF
+#define ssize_t signed int
+EOF
+
+fi
+
+echo $ac_n "checking for caddr_t""... $ac_c" 1>&6
+echo "configure:13937: checking for caddr_t" >&5
+if eval "test \"\${ac_cv_type_caddr_t+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 12765 "configure"
+#line 13942 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
 #include <stdlib.h>
 #include <stddef.h>
 #endif
+
 EOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  egrep "(^|[^a-zA-Z_0-9])caddr_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
   rm -rf conftest*
-  eval "ac_cv_type_size_t=yes"
+  eval "ac_cv_type_caddr_t=yes"
 else
   rm -rf conftest*
-  eval "ac_cv_type_size_t=no"
+  eval "ac_cv_type_caddr_t=no"
 fi
 rm -f conftest*
 
 fi
-if eval "test \"`echo '$ac_cv_type_'size_t`\" = yes"; then
+if eval "test \"`echo '$ac_cv_type_'caddr_t`\" = yes"; then
   echo "$ac_t""yes" 1>&6
 else
   echo "$ac_t""no" 1>&6
   cat >> confdefs.h <<EOF
-#define size_t unsigned
+#define caddr_t char *
 EOF
 
 fi
 
+
 echo $ac_n "checking for socklen_t""... $ac_c" 1>&6
-echo "configure:12795: checking for socklen_t" >&5
+echo "configure:13974: checking for socklen_t" >&5
 if eval "test \"\${ol_cv_type_socklen_t+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 12800 "configure"
+#line 13979 "configure"
 #include "confdefs.h"
 
 #ifdef HAVE_SYS_TYPES_H
@@ -12810,7 +13989,7 @@ int main() {
 socklen_t len;
 ; return 0; }
 EOF
-if { (eval echo configure:12814: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:13993: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ol_cv_type_socklen_t=yes
 else
@@ -12831,12 +14010,12 @@ EOF
   fi
  
 echo $ac_n "checking for member st_blksize in aggregate type struct stat""... $ac_c" 1>&6
-echo "configure:12835: checking for member st_blksize in aggregate type struct stat" >&5
+echo "configure:14014: checking for member st_blksize in aggregate type struct stat" >&5
 if eval "test \"\${ac_cv_c_struct_member_st_blksize+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 12840 "configure"
+#line 14019 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -12844,7 +14023,7 @@ int main() {
 struct stat foo; foo.st_blksize;
 ; return 0; }
 EOF
-if { (eval echo configure:12848: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:14027: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_struct_member_st_blksize=yes
 else
@@ -12866,12 +14045,12 @@ EOF
 fi
 
 echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:12870: checking whether time.h and sys/time.h may both be included" >&5
+echo "configure:14049: checking whether time.h and sys/time.h may both be included" >&5
 if eval "test \"\${ac_cv_header_time+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 12875 "configure"
+#line 14054 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/time.h>
@@ -12880,7 +14059,7 @@ int main() {
 struct tm *tp;
 ; return 0; }
 EOF
-if { (eval echo configure:12884: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:14063: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_header_time=yes
 else
@@ -12901,12 +14080,12 @@ EOF
 fi
 
 echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
-echo "configure:12905: checking whether struct tm is in sys/time.h or time.h" >&5
+echo "configure:14084: checking whether struct tm is in sys/time.h or time.h" >&5
 if eval "test \"\${ac_cv_struct_tm+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 12910 "configure"
+#line 14089 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <time.h>
@@ -12914,7 +14093,7 @@ int main() {
 struct tm *tp; tp->tm_sec;
 ; return 0; }
 EOF
-if { (eval echo configure:12918: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:14097: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_tm=time.h
 else
@@ -12934,15 +14113,84 @@ EOF
 
 fi
 
+echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
+echo "configure:14118: checking for uid_t in sys/types.h" >&5
+if eval "test \"\${ac_cv_type_uid_t+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 14123 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "uid_t" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_uid_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_type_uid_t" 1>&6
+if test $ac_cv_type_uid_t = no; then
+  cat >> confdefs.h <<\EOF
+#define uid_t int
+EOF
+
+  cat >> confdefs.h <<\EOF
+#define gid_t int
+EOF
+
+fi
+
+echo $ac_n "checking for sig_atomic_t""... $ac_c" 1>&6
+echo "configure:14152: checking for sig_atomic_t" >&5
+if eval "test \"\${ol_cv_type_sig_atomic_t+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 14157 "configure"
+#include "confdefs.h"
+#include <signal.h>
+int main() {
+sig_atomic_t atomic;
+; return 0; }
+EOF
+if { (eval echo configure:14164: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ol_cv_type_sig_atomic_t=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ol_cv_type_sig_atomic_t=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ol_cv_type_sig_atomic_t" 1>&6
+  if test $ol_cv_type_sig_atomic_t = no; then
+    cat >> confdefs.h <<\EOF
+#define sig_atomic_t int
+EOF
+
+  fi
+
+
 # test for pw_gecos in struct passwd
 echo $ac_n "checking struct passwd for pw_gecos""... $ac_c" 1>&6
-echo "configure:12940: checking struct passwd for pw_gecos" >&5
+echo "configure:14188: checking struct passwd for pw_gecos" >&5
 if eval "test \"\${ol_cv_struct_passwd_pw_gecos+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
        cat > conftest.$ac_ext <<EOF
-#line 12946 "configure"
+#line 14194 "configure"
 #include "confdefs.h"
 #include <pwd.h>
 int main() {
@@ -12952,7 +14200,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:12956: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:14204: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ol_cv_struct_passwd_pw_gecos=yes
 else
 
 # test for pw_passwd in struct passwd
 echo $ac_n "checking struct passwd for pw_passwd""... $ac_c" 1>&6
-echo "configure:12978: checking struct passwd for pw_passwd" >&5
+echo "configure:14226: checking struct passwd for pw_passwd" >&5
 if eval "test \"\${ol_cv_struct_passwd_pw_passwd+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
        cat > conftest.$ac_ext <<EOF
-#line 12984 "configure"
+#line 14232 "configure"
 #include "confdefs.h"
 #include <pwd.h>
 int main() {
@@ -12990,7 +14238,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:12994: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:14242: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ol_cv_struct_passwd_pw_passwd=yes
 else
@@ -13012,7 +14260,7 @@ fi
 
 
 echo $ac_n "checking if toupper() requires islower()""... $ac_c" 1>&6
-echo "configure:13016: checking if toupper() requires islower()" >&5
+echo "configure:14264: checking if toupper() requires islower()" >&5
 if eval "test \"\${ol_cv_c_upper_lower+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -13021,7 +14269,7 @@ else
   ol_cv_c_upper_lower=safe
 else
   cat > conftest.$ac_ext <<EOF
-#line 13025 "configure"
+#line 14273 "configure"
 #include "confdefs.h"
 
 #include <ctype.h>
@@ -13033,7 +14281,7 @@ main()
                exit(1);
 }
 EOF
-if { (eval echo configure:13037: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:14285: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ol_cv_c_upper_lower=no
 else
@@ -13056,12 +14304,12 @@ EOF
 fi
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:13060: checking for working const" >&5
+echo "configure:14308: checking for working const" >&5
 if eval "test \"\${ac_cv_c_const+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 13065 "configure"
+#line 14313 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -13110,7 +14358,7 @@ ccp = (char const *const *) p;
 
 ; return 0; }
 EOF
-if { (eval echo configure:13114: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:14362: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -13131,12 +14379,12 @@ EOF
 fi
 
 echo $ac_n "checking if compiler understands volatile""... $ac_c" 1>&6
-echo "configure:13135: checking if compiler understands volatile" >&5
+echo "configure:14383: checking if compiler understands volatile" >&5
 if eval "test \"\${ol_cv_c_volatile+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 13140 "configure"
+#line 14388 "configure"
 #include "confdefs.h"
 int x, y, z;
 int main() {
@@ -13145,7 +14393,7 @@ volatile int a; int * volatile b = x ? &y : &z;
       *b = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:13149: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:14397: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ol_cv_c_volatile=yes
 else
@@ -13173,30 +14421,16 @@ if test $cross_compiling = yes ; then
 #define CROSS_COMPILING 1
 EOF
 
-
-       cat >> confdefs.h <<\EOF
-#define LBER_INT_T long
-EOF
-
-       cat >> confdefs.h <<\EOF
-#define LBER_TAG_T long
-EOF
-
-       cat >> confdefs.h <<\EOF
-#define LBER_SOCKET_T int
-EOF
-
-
 else
        echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
-echo "configure:13193: checking whether byte ordering is bigendian" >&5
+echo "configure:14427: checking whether byte ordering is bigendian" >&5
 if eval "test \"\${ac_cv_c_bigendian+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_cv_c_bigendian=unknown
 # See if sys/param.h defines the BYTE_ORDER macro.
 cat > conftest.$ac_ext <<EOF
-#line 13200 "configure"
+#line 14434 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -13207,11 +14441,11 @@ int main() {
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:13211: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:14445: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   # It does; now see whether it defined to BIG_ENDIAN or not.
 cat > conftest.$ac_ext <<EOF
-#line 13215 "configure"
+#line 14449 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -13222,7 +14456,7 @@ int main() {
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:13226: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:14460: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_bigendian=yes
 else
@@ -13242,7 +14476,7 @@ if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 13246 "configure"
+#line 14480 "configure"
 #include "confdefs.h"
 main () {
   /* Are we little or big endian?  From Harbison&Steele.  */
@@ -13255,7 +14489,7 @@ main () {
   exit (u.c[sizeof (long) - 1] == 1);
 }
 EOF
-if { (eval echo configure:13259: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:14493: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_bigendian=no
 else
 
 fi
 
-       echo $ac_n "checking size of short""... $ac_c" 1>&6
-echo "configure:13283: checking size of short" >&5
+fi
+
+echo $ac_n "checking size of short""... $ac_c" 1>&6
+echo "configure:14519: checking size of short" >&5 
 if eval "test \"\${ac_cv_sizeof_short+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
+  for ac_size in 4 8 1 2 16  ; do # List sizes in rough order of prevalence. 
   cat > conftest.$ac_ext <<EOF
-#line 13291 "configure"
+#line 14525 "configure"
 #include "confdefs.h"
-#include <stdio.h>
-main()
-{
-  FILE *f=fopen("conftestval", "w");
-  if (!f) exit(1);
-  fprintf(f, "%d\n", sizeof(short));
-  exit(0);
-}
+#include "confdefs.h" 
+#include <sys/types.h> 
+
+int main() {
+switch (0) case 0: case (sizeof (short) == $ac_size):;
+; return 0; }
 EOF
-if { (eval echo configure:13302: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
-then
-  ac_cv_sizeof_short=`cat conftestval`
+if { (eval echo configure:14535: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_sizeof_short=$ac_size
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
-  rm -fr conftest*
-  ac_cv_sizeof_short=0
-fi
-rm -fr conftest*
 fi
+rm -f conftest* 
+  if test x$ac_cv_sizeof_short != x ; then break; fi 
+done 
 
 fi
-echo "$ac_t""$ac_cv_sizeof_short" 1>&6
+if test x$ac_cv_sizeof_short = x ; then 
+  { echo "configure: error: cannot determine a size for short" 1>&2; exit 1; } 
+fi 
+echo "$ac_t""$ac_cv_sizeof_short" 1>&6 
 cat >> confdefs.h <<EOF
 #define SIZEOF_SHORT $ac_cv_sizeof_short
 EOF
-
  
-       echo $ac_n "checking size of int""... $ac_c" 1>&6
-echo "configure:13322: checking size of int" >&5
+echo $ac_n "checking size of int""... $ac_c" 1>&6
+echo "configure:14558: checking size of int" >&5 
 if eval "test \"\${ac_cv_sizeof_int+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
+  for ac_size in 4 8 1 2 16  ; do # List sizes in rough order of prevalence. 
   cat > conftest.$ac_ext <<EOF
-#line 13330 "configure"
+#line 14564 "configure"
 #include "confdefs.h"
-#include <stdio.h>
-main()
-{
-  FILE *f=fopen("conftestval", "w");
-  if (!f) exit(1);
-  fprintf(f, "%d\n", sizeof(int));
-  exit(0);
-}
+#include "confdefs.h" 
+#include <sys/types.h> 
+
+int main() {
+switch (0) case 0: case (sizeof (int) == $ac_size):;
+; return 0; }
 EOF
-if { (eval echo configure:13341: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
-then
-  ac_cv_sizeof_int=`cat conftestval`
+if { (eval echo configure:14574: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_sizeof_int=$ac_size
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
-  rm -fr conftest*
-  ac_cv_sizeof_int=0
-fi
-rm -fr conftest*
 fi
+rm -f conftest* 
+  if test x$ac_cv_sizeof_int != x ; then break; fi 
+done 
 
 fi
-echo "$ac_t""$ac_cv_sizeof_int" 1>&6
+if test x$ac_cv_sizeof_int = x ; then 
+  { echo "configure: error: cannot determine a size for int" 1>&2; exit 1; } 
+fi 
+echo "$ac_t""$ac_cv_sizeof_int" 1>&6 
 cat >> confdefs.h <<EOF
 #define SIZEOF_INT $ac_cv_sizeof_int
 EOF
-
  
-       echo $ac_n "checking size of long""... $ac_c" 1>&6
-echo "configure:13361: checking size of long" >&5
+echo $ac_n "checking size of long""... $ac_c" 1>&6
+echo "configure:14597: checking size of long" >&5 
 if eval "test \"\${ac_cv_sizeof_long+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
+  for ac_size in 4 8 1 2 16  ; do # List sizes in rough order of prevalence. 
   cat > conftest.$ac_ext <<EOF
-#line 13369 "configure"
+#line 14603 "configure"
 #include "confdefs.h"
-#include <stdio.h>
-main()
-{
-  FILE *f=fopen("conftestval", "w");
-  if (!f) exit(1);
-  fprintf(f, "%d\n", sizeof(long));
-  exit(0);
-}
+#include "confdefs.h" 
+#include <sys/types.h> 
+
+int main() {
+switch (0) case 0: case (sizeof (long) == $ac_size):;
+; return 0; }
 EOF
-if { (eval echo configure:13380: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
-then
-  ac_cv_sizeof_long=`cat conftestval`
+if { (eval echo configure:14613: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_sizeof_long=$ac_size
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
-  rm -fr conftest*
-  ac_cv_sizeof_long=0
-fi
-rm -fr conftest*
 fi
+rm -f conftest* 
+  if test x$ac_cv_sizeof_long != x ; then break; fi 
+done 
 
 fi
-echo "$ac_t""$ac_cv_sizeof_long" 1>&6
+if test x$ac_cv_sizeof_long = x ; then 
+  { echo "configure: error: cannot determine a size for long" 1>&2; exit 1; } 
+fi 
+echo "$ac_t""$ac_cv_sizeof_long" 1>&6 
 cat >> confdefs.h <<EOF
 #define SIZEOF_LONG $ac_cv_sizeof_long
 EOF
 
 
+if test "$ac_cv_sizeof_int" -lt 4 ; then
+       echo "configure: warning: OpenLDAP requires 'int' to be 32 bits or greater." 1>&2
 
-       if test "$ac_cv_sizeof_int" -lt 4 ; then
-               echo "configure: warning: OpenLDAP requires 'int' to be 32 bits or greater." 1>&2
-
-               cat >> confdefs.h <<\EOF
+       cat >> confdefs.h <<\EOF
 #define LBER_INT_T long
 EOF
 
-               cat >> confdefs.h <<\EOF
-#define LBER_TAG_T long
-EOF
-
-               cat >> confdefs.h <<\EOF
-#define LBER_SOCKET_T int
-EOF
-
-       else
-               cat >> confdefs.h <<\EOF
+else
+       cat >> confdefs.h <<\EOF
 #define LBER_INT_T int
 EOF
 
-               cat >> confdefs.h <<\EOF
-#define LBER_TAG_T long
+fi
+
+cat >> confdefs.h <<\EOF
+#define LBER_LEN_T long
 EOF
 
-               cat >> confdefs.h <<\EOF
+cat >> confdefs.h <<\EOF
 #define LBER_SOCKET_T int
 EOF
 
-       fi
-fi
-
 cat >> confdefs.h <<\EOF
-#define LBER_LEN_T long
+#define LBER_TAG_T long
 EOF
 
 
 echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6
-echo "configure:13437: checking for 8-bit clean memcmp" >&5
+echo "configure:14664: checking for 8-bit clean memcmp" >&5
 if eval "test \"\${ac_cv_func_memcmp_clean+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -13441,7 +14668,7 @@ else
   ac_cv_func_memcmp_clean=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 13445 "configure"
+#line 14672 "configure"
 #include "confdefs.h"
 
 main()
@@ -13451,7 +14678,7 @@ main()
 }
 
 EOF
-if { (eval echo configure:13455: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:14682: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_memcmp_clean=yes
 else
@@ -13469,12 +14696,12 @@ echo "$ac_t""$ac_cv_func_memcmp_clean" 1>&6
 test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}"
 
 echo $ac_n "checking for strftime""... $ac_c" 1>&6
-echo "configure:13473: checking for strftime" >&5
+echo "configure:14700: checking for strftime" >&5
 if eval "test \"\${ac_cv_func_strftime+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 13478 "configure"
+#line 14705 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char strftime(); below.  */
@@ -13498,7 +14725,7 @@ f = strftime;
 
 ; return 0; }
 EOF
-if { (eval echo configure:13502: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:14729: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_strftime=yes"
 else
@@ -13520,7 +14747,7 @@ else
   echo "$ac_t""no" 1>&6
 # strftime is in -lintl on SCO UNIX.
 echo $ac_n "checking for strftime in -lintl""... $ac_c" 1>&6
-echo "configure:13524: checking for strftime in -lintl" >&5
+echo "configure:14751: checking for strftime in -lintl" >&5
 ac_lib_var=`echo intl'_'strftime | sed 'y%./+-:%__p__%'`
 if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -13528,7 +14755,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lintl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 13532 "configure"
+#line 14759 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -13539,7 +14766,7 @@ int main() {
 strftime()
 ; return 0; }
 EOF
-if { (eval echo configure:13543: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:14770: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
 
 
 echo $ac_n "checking for inet_aton()""... $ac_c" 1>&6
-echo "configure:13571: checking for inet_aton()" >&5
+echo "configure:14798: checking for inet_aton()" >&5
 if eval "test \"\${ol_cv_func_inet_aton+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 13576 "configure"
+#line 14803 "configure"
 #include "confdefs.h"
 
 #ifdef HAVE_SYS_TYPES_H
@@ -13594,7 +14821,7 @@ struct in_addr in;
 int rc = inet_aton( "255.255.255.255", &in );
 ; return 0; }
 EOF
-if { (eval echo configure:13598: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:14825: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_func_inet_aton=yes
 else
   fi
  
 
+echo $ac_n "checking for _spawnlp""... $ac_c" 1>&6
+echo "configure:14847: checking for _spawnlp" >&5
+if eval "test \"\${ac_cv_func__spawnlp+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 14852 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char _spawnlp(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char _spawnlp();
+char (*f)();
+
+int main() {
+
+/* 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__spawnlp) || defined (__stub____spawnlp)
+choke me
+#else
+f = _spawnlp;
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:14876: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func__spawnlp=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func__spawnlp=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'_spawnlp`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<\EOF
+#define HAVE_SPAWNLP 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+echo $ac_n "checking for _snprintf""... $ac_c" 1>&6
+echo "configure:14900: checking for _snprintf" >&5
+if eval "test \"\${ac_cv_func__snprintf+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 14905 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char _snprintf(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char _snprintf();
+char (*f)();
+
+int main() {
+
+/* 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__snprintf) || defined (__stub____snprintf)
+choke me
+#else
+f = _snprintf;
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:14929: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func__snprintf=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func__snprintf=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'_snprintf`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  ac_cv_func_snprintf=yes
+       cat >> confdefs.h <<\EOF
+#define snprintf _snprintf
+EOF
+
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+echo $ac_n "checking for _vsnprintf""... $ac_c" 1>&6
+echo "configure:14955: checking for _vsnprintf" >&5
+if eval "test \"\${ac_cv_func__vsnprintf+set}\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 14960 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char _vsnprintf(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char _vsnprintf();
+char (*f)();
+
+int main() {
+
+/* 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__vsnprintf) || defined (__stub____vsnprintf)
+choke me
+#else
+f = _vsnprintf;
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:14984: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func__vsnprintf=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func__vsnprintf=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'_vsnprintf`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  ac_cv_func_vsnprintf=yes
+       cat >> confdefs.h <<\EOF
+#define vsnprintf _vsnprintf
+EOF
+
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
 echo $ac_n "checking for vprintf""... $ac_c" 1>&6
-echo "configure:13620: checking for vprintf" >&5
+echo "configure:15010: checking for vprintf" >&5
 if eval "test \"\${ac_cv_func_vprintf+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 13625 "configure"
+#line 15015 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char vprintf(); below.  */
@@ -13645,7 +15035,7 @@ f = vprintf;
 
 ; return 0; }
 EOF
-if { (eval echo configure:13649: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:15039: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_vprintf=yes"
 else
 
 if test "$ac_cv_func_vprintf" != yes; then
 echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
-echo "configure:13673: checking for _doprnt" >&5
+echo "configure:15063: checking for _doprnt" >&5
 if eval "test \"\${ac_cv_func__doprnt+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 13678 "configure"
+#line 15068 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char _doprnt(); below.  */
@@ -13698,7 +15088,7 @@ f = _doprnt;
 
 ; return 0; }
 EOF
-if { (eval echo configure:13702: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:15092: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func__doprnt=yes"
 else
@@ -13727,12 +15117,12 @@ if test $ac_cv_func_vprintf = yes ; then
                for ac_func in vsnprintf vsprintf
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:13731: checking for $ac_func" >&5
+echo "configure:15121: checking for $ac_func" >&5
 if eval "test \"\${ac_cv_func_$ac_func+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 13736 "configure"
+#line 15126 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -13756,7 +15146,7 @@ f = $ac_func;
 
 ; return 0; }
 EOF
-if { (eval echo configure:13760: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:15150: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -13785,6 +15175,7 @@ fi
 for ac_func in \
        bcopy                   \
        closesocket             \
+       chroot                  \
        endgrent                \
        endpwent                \
        flock                   \
@@ -13792,6 +15183,7 @@ for ac_func in \
        getgrgid                \
        gethostname             \
        getpass                 \
+       getpassphrase   \
        getpwuid                \
        getpwnam                \
        getspnam                \
@@ -13833,12 +15225,12 @@ for ac_func in \
 
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:13837: checking for $ac_func" >&5
+echo "configure:15229: checking for $ac_func" >&5
 if eval "test \"\${ac_cv_func_$ac_func+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 13842 "configure"
+#line 15234 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -13862,7 +15254,7 @@ f = $ac_func;
 
 ; return 0; }
 EOF
-if { (eval echo configure:13866: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:15258: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -13890,12 +15282,12 @@ done
 for ac_func in getopt tempnam
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:13894: checking for $ac_func" >&5
+echo "configure:15286: checking for $ac_func" >&5
 if eval "test \"\${ac_cv_func_$ac_func+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 13899 "configure"
+#line 15291 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -13919,7 +15311,7 @@ f = $ac_func;
 
 ; return 0; }
 EOF
-if { (eval echo configure:13923: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:15315: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -13946,25 +15338,36 @@ done
 
 
 
+if test "$ac_cv_func_getopt" != yes; then
+    LIBSRCS="$LIBSRCS getopt.c"
+fi
+
+if test "$ac_cv_func_tempnam" != yes; then
+    LIBSRCS="$LIBSRCS tempnam.c"
+fi
+
 # Check Configuration
 echo $ac_n "checking declaration of sys_errlist""... $ac_c" 1>&6
-echo "configure:13952: checking declaration of sys_errlist" >&5
+echo "configure:15352: checking declaration of sys_errlist" >&5
 if eval "test \"\${ol_cv_dcl_sys_errlist+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
        cat > conftest.$ac_ext <<EOF
-#line 13958 "configure"
+#line 15358 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
 #include <sys/types.h>
-#include <errno.h> 
+#include <errno.h>
+#ifdef WINNT
+#include <stdlib.h>
+#endif 
 int main() {
 char *c = (char *) *sys_errlist
 ; return 0; }
 EOF
-if { (eval echo configure:13968: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:15371: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ol_cv_dcl_sys_errlist=yes
        ol_cv_have_sys_errlist=yes
@@ -13987,20 +15390,20 @@ EOF
 
 
        echo $ac_n "checking existence of sys_errlist""... $ac_c" 1>&6
-echo "configure:13991: checking existence of sys_errlist" >&5
+echo "configure:15394: checking existence of sys_errlist" >&5
 if eval "test \"\${ol_cv_have_sys_errlist+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
                cat > conftest.$ac_ext <<EOF
-#line 13997 "configure"
+#line 15400 "configure"
 #include "confdefs.h"
 #include <errno.h>
 int main() {
 char *c = (char *) *sys_errlist
 ; return 0; }
 EOF
-if { (eval echo configure:14004: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:15407: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ol_cv_have_sys_errlist=yes
 else
@@ -14047,9 +15450,9 @@ if test "$ol_enable_cache" = no ; then
 EOF
 
 fi
-if test "$ol_enable_dns" != no ; then
+if test "$ol_link_kbind" != no ; then
        cat >> confdefs.h <<\EOF
-#define LDAP_API_FEATURE_X_OPENLDAP_V2_DNS LDAP_VENDOR_VERSION
+#define LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND LDAP_VENDOR_VERSION
 EOF
 
 fi
@@ -14071,10 +15474,15 @@ if test "$ol_enable_cldap" != no ; then
 EOF
 
 fi
+if test "$ol_enable_unix" != no; then
+       cat >> confdefs.h <<\EOF
+#define LDAP_PF_UNIX 1
+EOF
 
-if test "$ol_enable_crypt" != no ; then
+fi
+if test "$ol_enable_ipv6" != no; then
        cat >> confdefs.h <<\EOF
-#define SLAPD_CRYPT 1
+#define LDAP_PF_INET6 1
 EOF
 
 fi
@@ -14083,6 +15491,24 @@ if test "$ol_enable_cleartext" != no ; then
 #define SLAPD_CLEARTEXT 1
 EOF
 
+fi
+if test "$ol_enable_crypt" != no ; then
+       cat >> confdefs.h <<\EOF
+#define SLAPD_CRYPT 1
+EOF
+
+fi
+if test "$ol_link_kpasswd" != no ; then
+       cat >> confdefs.h <<\EOF
+#define SLAPD_KPASSWD 1
+EOF
+
+fi
+if test "$ol_link_spasswd" != no ; then
+       cat >> confdefs.h <<\EOF
+#define SLAPD_SPASSWD 1
+EOF
+
 fi
 if test "$ol_enable_multimaster" != no ; then
        cat >> confdefs.h <<\EOF
@@ -14107,12 +15533,6 @@ if test "$ol_enable_aci" != no ; then
 #define SLAPD_ACI_ENABLED 1
 EOF
 
-fi
-if test "$ol_enable_discreteaci" != no ; then
-       cat >> confdefs.h <<\EOF
-#define SLAPD_ACI_DISCRETE_RIGHTS 1
-EOF
-
 fi
 
 if test "$ol_link_modules" != no ; then
@@ -14121,25 +15541,24 @@ if test "$ol_link_modules" != no ; then
 EOF
 
        BUILD_SLAPD=yes
-       MODULES_LIBS=-lltdl
        SLAPD_MODULES_LDFLAGS="-dlopen self"
 fi
 
-if test "$ol_link_bdb2" != no ; then
+if test "$ol_link_dnssrv" != no ; then
        cat >> confdefs.h <<\EOF
-#define SLAPD_BDB2 1
+#define SLAPD_DNSSRV 1
 EOF
 
        BUILD_SLAPD=yes
-       BUILD_BDB2=yes
-       if test "$ol_with_bdb2_module" != static ; then
+       BUILD_DNSSRV=yes
+       if test "$ol_with_dnssrv_module" != static ; then
                cat >> confdefs.h <<\EOF
-#define SLAPD_BDB2_DYNAMIC 1
+#define SLAPD_DNSSRV_DYNAMIC 1
 EOF
 
-               BUILD_BDB2=mod
-               BUILD_BDB2_DYNAMIC=shared
-               SLAPD_MODULES_LIST="$SLAPD_MODULES_LIST -dlopen \$(SLAP_DIR)back-bdb2/back_bdb2.la"
+               BUILD_DNSSRV=mod
+               BUILD_DNSSRV_DYNAMIC=shared
+               SLAPD_MODULES_LIST="$SLAPD_MODULES_LIST -dlopen \$(SLAP_DIR)back-dnssrv/back_dnssrv.la"
        fi
 fi
 
@@ -14197,24 +15616,6 @@ EOF
        fi
 fi
 
-if test "$ol_link_perl" != no ; then
-       cat >> confdefs.h <<\EOF
-#define SLAPD_PERL 1
-EOF
-
-       BUILD_SLAPD=yes
-       BUILD_PERL=yes
-       if test "$ol_with_perl_module" != static ; then
-               cat >> confdefs.h <<\EOF
-#define SLAPD_PERL_DYNAMIC 1
-EOF
-
-               BUILD_PERL=mod
-               BUILD_PERL_DYNAMIC=shared
-               SLAPD_MODULES_LIST="$SLAPD_MODULES_LIST -dlopen \$(SLAP_DIR)back-perl/back_perl.la"
-       fi
-fi
-
 if test "$ol_enable_shell" != no ; then
        cat >> confdefs.h <<\EOF
 #define SLAPD_SHELL 1
@@ -14233,31 +15634,36 @@ EOF
        fi
 fi
 
-if test "$ol_enable_tcl" != no ; then
-       cat >> confdefs.h <<\EOF
-#define SLAPD_TCL 1
-EOF
+if test "$ol_enable_slurpd" != no -a "$ol_link_threads" != no -a \
+       $BUILD_SLAPD = yes ; then
+       BUILD_SLURPD=yes
+fi
 
-       BUILD_SLAPD=yes
-       BUILD_TCL=yes
-       if test "$ol_with_tcl_module" != static; then
-               cat >> confdefs.h <<\EOF
-#define SLAPD_TCL_DYNAMIC 1
-EOF
 
-               BUILD_TCL=mod
-               BUILD_TCL_DYNAMIC=shared
-               SLAPD_MODULES_LIST="$SLAPD_MODULES_LIST -dlopen \$(SLAP_DIR)back-tcl/back_tcl.la"
-       fi
+if test "$LINK_BINS_DYNAMIC" = yes; then
+    LIB_LINKAGE=DYN
+    LT_LIB_LINKAGE=shared
+else
+    LIB_LINKAGE=STAT
+    LT_LIB_LINKAGE=static
 fi
 
-if test "$ol_enable_slurpd" != no -a "$ol_link_threads" != no -a \
-       $BUILD_SLAPD = yes ; then
-       BUILD_SLURPD=yes
+if test "$ac_cv_mingw32" = yes ; then
+    PLAT=NT
+    DYN_EXT=dll
+else
+    PLAT=UNIX
+    DYN_EXT=so
 fi
 
 
 
+
+
+
+
+
+
   
   
   
   
   
   
-  
-  
-  
-  
+
+
 
 
 
@@ -14368,6 +15772,7 @@ clients/gopher/Makefile:build/top.mk:clients/gopher/Makefile.in:build/rules.mk \
 clients/mail500/Makefile:build/top.mk:clients/mail500/Makefile.in:build/rules.mk \
 clients/rcpt500/Makefile:build/top.mk:clients/rcpt500/Makefile.in:build/rules.mk \
 clients/ud/Makefile:build/top.mk:clients/ud/Makefile.in:build/rules.mk \
+clients/maildap/Makefile:build/top.mk:clients/maildap/Makefile.in:build/rules.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     \
@@ -14377,16 +15782,15 @@ libraries/libldap/Makefile:build/top.mk:libraries/libldap/Makefile.in:build/lib.
 libraries/libldap_r/Makefile:build/top.mk:libraries/libldap_r/Makefile.in:build/lib.mk:build/lib-shared.mk     \
 libraries/libldbm/Makefile:build/top.mk:libraries/libldbm/Makefile.in:build/lib.mk:build/lib-static.mk \
 libraries/libldif/Makefile:build/top.mk:libraries/libldif/Makefile.in:build/lib.mk:build/lib-static.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       \
 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-bdb2/Makefile:build/top.mk:servers/slapd/back-bdb2/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-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-passwd/Makefile:build/top.mk:servers/slapd/back-passwd/Makefile.in:build/mod.mk \
-servers/slapd/back-perl/Makefile:build/top.mk:servers/slapd/back-perl/Makefile.in:build/mod.mk \
 servers/slapd/back-shell/Makefile:build/top.mk:servers/slapd/back-shell/Makefile.in:build/mod.mk \
-servers/slapd/back-tcl/Makefile:build/top.mk:servers/slapd/back-tcl/Makefile.in:build/mod.mk \
 servers/slapd/shell-backends/Makefile:build/top.mk:servers/slapd/shell-backends/Makefile.in:build/srv.mk \
 servers/slapd/tools/Makefile:build/top.mk:servers/slapd/tools/Makefile.in \
 servers/slurpd/Makefile:build/top.mk:servers/slurpd/Makefile.in:build/srv.mk \
@@ -14461,56 +15865,60 @@ s%@top_builddir@%$top_builddir%g
 s%@ldap_subdir@%$ldap_subdir%g
 s%@CC@%$CC%g
 s%@RANLIB@%$RANLIB%g
-s%@LD@%$LD%g
-s%@NM@%$NM%g
 s%@LN_S@%$LN_S%g
+s%@DLLTOOL@%$DLLTOOL%g
+s%@AS@%$AS%g
+s%@OBJDUMP@%$OBJDUMP%g
 s%@LIBTOOL@%$LIBTOOL%g
 s%@LN_H@%$LN_H%g
 s%@SENDMAIL@%$SENDMAIL%g
 s%@EDITOR@%$EDITOR%g
 s%@FINGER@%$FINGER%g
-s%@PERLBIN@%$PERLBIN%g
 s%@CPP@%$CPP%g
 s%@EXEEXT@%$EXEEXT%g
 s%@OBJEXT@%$OBJEXT%g
 s%@OL_MKDEP@%$OL_MKDEP%g
 s%@OL_MKDEP_FLAGS@%$OL_MKDEP_FLAGS%g
 s%@LIBOBJS@%$LIBOBJS%g
+s%@LIBSRCS@%$LIBSRCS%g
+s%@PLAT@%$PLAT%g
+s%@LIB_LINKAGE@%$LIB_LINKAGE%g
+s%@LT_LIB_LINKAGE@%$LT_LIB_LINKAGE%g
+s%@DYN_EXT@%$DYN_EXT%g
 s%@BUILD_SLAPD@%$BUILD_SLAPD%g
-s%@BUILD_BDB2@%$BUILD_BDB2%g
+s%@BUILD_DNSSRV@%$BUILD_DNSSRV%g
 s%@BUILD_LDAP@%$BUILD_LDAP%g
 s%@BUILD_LDBM@%$BUILD_LDBM%g
 s%@BUILD_PASSWD@%$BUILD_PASSWD%g
-s%@BUILD_PERL@%$BUILD_PERL%g
 s%@BUILD_QUIPU@%$BUILD_QUIPU%g
 s%@BUILD_SHELL@%$BUILD_SHELL%g
-s%@BUILD_TCL@%$BUILD_TCL%g
-s%@BUILD_BDB2_DYNAMIC@%$BUILD_BDB2_DYNAMIC%g
+s%@BUILD_DNSSRV_DYNAMIC@%$BUILD_DNSSRV_DYNAMIC%g
 s%@BUILD_LDAP_DYNAMIC@%$BUILD_LDAP_DYNAMIC%g
 s%@BUILD_LDBM_DYNAMIC@%$BUILD_LDBM_DYNAMIC%g
 s%@BUILD_PASSWD_DYNAMIC@%$BUILD_PASSWD_DYNAMIC%g
-s%@BUILD_PERL_DYNAMIC@%$BUILD_PERL_DYNAMIC%g
 s%@BUILD_SHELL_DYNAMIC@%$BUILD_SHELL_DYNAMIC%g
-s%@BUILD_TCL_DYNAMIC@%$BUILD_TCL_DYNAMIC%g
 s%@BUILD_SLURPD@%$BUILD_SLURPD%g
 s%@LDAP_LIBS@%$LDAP_LIBS%g
 s%@LDIF_LIBS@%$LDIF_LIBS%g
 s%@SLAPD_LIBS@%$SLAPD_LIBS%g
+s%@QUIPU_LIBS@%$QUIPU_LIBS%g
 s%@SLURPD_LIBS@%$SLURPD_LIBS%g
 s%@LDBM_LIBS@%$LDBM_LIBS%g
 s%@LTHREAD_LIBS@%$LTHREAD_LIBS%g
 s%@LUTIL_LIBS@%$LUTIL_LIBS%g
+s%@WRAP_LIBS@%$WRAP_LIBS%g
+s%@LINK_BINS_DYNAMIC@%$LINK_BINS_DYNAMIC%g
 s%@SLAPD_MODULES_CPPFLAGS@%$SLAPD_MODULES_CPPFLAGS%g
 s%@SLAPD_MODULES_LDFLAGS@%$SLAPD_MODULES_LDFLAGS%g
 s%@SLAPD_MODULES_LIST@%$SLAPD_MODULES_LIST%g
-s%@SLAPD_PERL_CPPFLAGS@%$SLAPD_PERL_CPPFLAGS%g
-s%@SLAPD_PERL_LDFLAGS@%$SLAPD_PERL_LDFLAGS%g
-s%@KRB_LIBS@%$KRB_LIBS%g
+s%@KRB4_LIBS@%$KRB4_LIBS%g
+s%@KRB5_LIBS@%$KRB5_LIBS%g
 s%@READLINE_LIBS@%$READLINE_LIBS%g
 s%@SASL_LIBS@%$SASL_LIBS%g
 s%@TERMCAP_LIBS@%$TERMCAP_LIBS%g
 s%@TLS_LIBS@%$TLS_LIBS%g
 s%@MODULES_LIBS@%$MODULES_LIBS%g
+s%@AUTH_LIBS@%$AUTH_LIBS%g
 
 CEOF
 EOF
@@ -14567,6 +15975,7 @@ clients/gopher/Makefile:build/top.mk:clients/gopher/Makefile.in:build/rules.mk \
 clients/mail500/Makefile:build/top.mk:clients/mail500/Makefile.in:build/rules.mk \
 clients/rcpt500/Makefile:build/top.mk:clients/rcpt500/Makefile.in:build/rules.mk \
 clients/ud/Makefile:build/top.mk:clients/ud/Makefile.in:build/rules.mk \
+clients/maildap/Makefile:build/top.mk:clients/maildap/Makefile.in:build/rules.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     \
@@ -14576,16 +15985,15 @@ libraries/libldap/Makefile:build/top.mk:libraries/libldap/Makefile.in:build/lib.
 libraries/libldap_r/Makefile:build/top.mk:libraries/libldap_r/Makefile.in:build/lib.mk:build/lib-shared.mk     \
 libraries/libldbm/Makefile:build/top.mk:libraries/libldbm/Makefile.in:build/lib.mk:build/lib-static.mk \
 libraries/libldif/Makefile:build/top.mk:libraries/libldif/Makefile.in:build/lib.mk:build/lib-static.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       \
 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-bdb2/Makefile:build/top.mk:servers/slapd/back-bdb2/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-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-passwd/Makefile:build/top.mk:servers/slapd/back-passwd/Makefile.in:build/mod.mk \
-servers/slapd/back-perl/Makefile:build/top.mk:servers/slapd/back-perl/Makefile.in:build/mod.mk \
 servers/slapd/back-shell/Makefile:build/top.mk:servers/slapd/back-shell/Makefile.in:build/mod.mk \
-servers/slapd/back-tcl/Makefile:build/top.mk:servers/slapd/back-tcl/Makefile.in:build/mod.mk \
 servers/slapd/shell-backends/Makefile:build/top.mk:servers/slapd/shell-backends/Makefile.in:build/srv.mk \
 servers/slapd/tools/Makefile:build/top.mk:servers/slapd/tools/Makefile.in \
 servers/slurpd/Makefile:build/top.mk:servers/slurpd/Makefile.in:build/srv.mk \
@@ -14638,7 +16046,7 @@ for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
   rm -f "$ac_file"
   configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
   case "$ac_file" in
-  *Makefile*) ac_comsub="1i\\
+  *[Mm]akefile*) ac_comsub="1i\\
 # $configure_input" ;;
   *) ac_comsub= ;;
   esac
index 307ee53902170e4798bcdfdac1be2bf8d1ae70d6..4697b764cd7c6c15268758fc94cf7b7f658cdffc 100644 (file)
@@ -1,31 +1,47 @@
 dnl $OpenLDAP$
 dnl
-dnl Copyright 1998,1999 The OpenLDAP Foundation.  All Rights Reserved.
+dnl Copyright 1998-2000 The OpenLDAP Foundation.  All Rights Reserved.
 dnl 
 dnl Redistribution and use in source and binary forms are permitted only
 dnl as authorized by the OpenLDAP Public License.  A copy of this
 dnl license is available at http://www.OpenLDAP.org/license.html or
 dnl in file LICENSE in the top-level directory of the distribution.
 dnl
+dnl ----------------------------------------------------------------
+dnl Redefine AC_INIT_BINSH to provide RCS IDs and copyright notice
+dnl at top of generated configure script.  Prints simple copyright.
 define([AC_INIT_BINSH],
 [[#! /bin/sh
 # $]OpenLDAP[$
 # from] translit([$OpenLDAP$], $")] [
 
-# Copyright 1998,1999 The OpenLDAP Foundation.  All Rights Reserved.
+# Copyright 1998-2000 The OpenLDAP Foundation.  All Rights Reserved.
 # 
 # Redistribution and use in source and binary forms are permitted only
 # as authorized by the OpenLDAP Public License.  A copy of this
 # license is available at http://www.OpenLDAP.org/license.html or
 # in file LICENSE in the top-level directory of the distribution.
-])dnl
 
+echo "Copyright 1998-2000 The OpenLDAP Foundation,  All Rights Reserved."
+echo "Copying restrictions apply, see COPYRIGHT file."
+])dnl
+dnl ----------------------------------------------------------------
 dnl Disable config.cache!
 define([AC_CACHE_LOAD], )dnl
 define([AC_CACHE_SAVE], )dnl
-
+dnl ================================================================
 dnl Configure.in for OpenLDAP
 AC_INIT(build/version)dnl
+
+# set unset (borrowed from autoconf 2.14a)
+if (unset FOO) >/dev/null 2>&1; then
+  ol_unset=unset
+else
+  ol_unset=false
+fi
+# unset CDPATH
+$ol_unset CDPATH || test "${CDPATH+set}" != set || CDPATH=: && export CDPATH
+
 AC_CONFIG_AUX_DIR(build)dnl
 
 OL_VERSION=`cat $ac_aux_dir/version`
@@ -33,7 +49,8 @@ if test -z "$OL_VERSION"; then
        AC_MSG_ERROR([could not determine version])
 fi
 
-dnl ----------------------------------------------------------------
+echo "Configuring OpenLDAP $OL_VERSION ..."
+
 dnl Determine host platform
 dnl            we try not to use this for much
 AC_CANONICAL_SYSTEM
@@ -44,15 +61,14 @@ AC_SUBST(VERSION)
 AC_DEFINE_UNQUOTED(OPENLDAP_PACKAGE,"$PACKAGE",Package)
 AC_DEFINE_UNQUOTED(OPENLDAP_VERSION,"$VERSION",Version)
 
-dnl require: dnl autoconf 2.13.1
-dnl also:
+dnl We use autoconf features new to 2.13.
 dnl aclocal.m4 should be built using aclocal from automake 1.4
 dnl libtool 1.3.3 should be installed.
-AC_PREREQ(2.13.1)dnl Required Autoconf version
+AC_PREREQ(2.13)dnl Required Autoconf version
 
 AC_CONFIG_HEADER(include/portable.h include/ldap_features.h include/lber_types.h)dnl
 
-dnl ----------------------------------------------------------------
+dnl ================================================================
 dnl Start Args
 AC_MSG_CHECKING(configure arguments)
 AC_PREFIX_DEFAULT(/usr/local)
@@ -60,6 +76,8 @@ AC_PREFIX_DEFAULT(/usr/local)
 top_builddir=`pwd`
 AC_SUBST(top_builddir)dnl
 
+dnl ----------------------------------------------------------------
+dnl --with-subdir
 ldap_subdir="/openldap"
 
 AC_ARG_WITH(subdir,
@@ -80,104 +98,100 @@ esac
 
 AC_SUBST(ldap_subdir)dnl
 
+dnl ----------------------------------------------------------------
+dnl General "enable" options
 OL_ARG_ENABLE(debug,[  --enable-debug  enable debugging], yes)dnl
-dnl ol_enable_syslog=no
 OL_ARG_ENABLE(syslog,[  --enable-syslog        enable syslog support], auto)dnl
 OL_ARG_ENABLE(proctitle,[  --enable-proctitle  enable proctitle support], yes)dnl
 OL_ARG_ENABLE(cache,[  --enable-cache  enable caching], yes)dnl
-OL_ARG_ENABLE(dns,[  --enable-dns              enable V2 DX Referrals extension], no)dnl
 OL_ARG_ENABLE(referrals,[  --enable-referrals  enable V2 Referrals extension], yes)dnl
+OL_ARG_ENABLE(kbind,[  --enable-kbind  enable V2 Kerberos IV bind], auto)dnl
 OL_ARG_ENABLE(cldap,[  --enable-cldap  enable connectionless ldap], no)dnl
+OL_ARG_ENABLE(ipv6,[  --enable-ipv6    enable IPv6 support], auto)dnl
+OL_ARG_ENABLE(unix,[  --enable-unix            enable UNIX domain socket support], auto)dnl
 OL_ARG_ENABLE(x_compile,[  --enable-x-compile  enable cross compiling],
        no, [yes no])dnl
 
+dnl ----------------------------------------------------------------
 dnl General "with" options
-OL_ARG_ENABLE(dmalloc,[  --enable-dmalloc      enable debug malloc support], no)dnl
+dnl OL_ARG_ENABLE(dmalloc,[  --enable-dmalloc  enable debug malloc support], no)dnl
 
 OL_ARG_WITH(cyrus_sasl,[  --with-cyrus-sasl    with Cyrus SASL support],
        auto, [auto yes no] )
 OL_ARG_WITH(fetch,[  --with-fetch              with fetch URL support],
        auto, [auto yes no] )
-OL_ARG_WITH(kerberos,[  --with-kerberos        with Kerberos support],
-       auto, [auto k5 k4 afs yes no])
+OL_ARG_WITH(kerberos,[  --with-kerberos        with support],
+       auto, [auto k5 k5only k425 kth k4 afs yes no])
 OL_ARG_WITH(readline,[  --with-readline        with readline support],
        auto, [auto yes no] )
 OL_ARG_WITH(threads,[  --with-threads  use threads],
-       auto, [auto posix mach pth lwp yes no manual] )
+       auto, [auto nt posix mach pth lwp yes no manual] )
 OL_ARG_WITH(tls,[  --with-tls          with TLS/SSL support],
        auto, [auto ssleay openssl yes no] )
 OL_ARG_WITH(yielding_select,[  --with-yielding-select  with implicitly yielding select],
        auto, [auto yes no manual] )
 
+dnl ----------------------------------------------------------------
 dnl Server options
+dnl ----------------------------------------------------------------
 
+dnl ----------------------------------------------------------------
 dnl SLAPD OPTIONS
 AC_ARG_WITH(xxslapdoptions,[SLAPD (Standalone LDAP Daemon) Options:])
 OL_ARG_ENABLE(slapd,[  --enable-slapd  enable building slapd], yes)dnl
 OL_ARG_ENABLE(cleartext,[    --enable-cleartext        enable cleartext passwords], yes)dnl
 OL_ARG_ENABLE(crypt,[    --enable-crypt        enable crypt(3) passwords], auto)dnl
+OL_ARG_ENABLE(kpasswd,[    --enable-kpasswd    enable kerberos password verification], 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
 OL_ARG_ENABLE(multimaster,[    --enable-multimaster    enable multimaster replication], no)dnl
 OL_ARG_ENABLE(phonetic,[    --enable-phonetic  enable phonetic/soundex], no)dnl
 OL_ARG_ENABLE(quipu,[    --enable-quipu        build quipu migration tools], no)dnl
 OL_ARG_ENABLE(rlookups,[    --enable-rlookups  enable reverse lookups], auto)dnl
 OL_ARG_ENABLE(aci,[    --enable-aci    enable per-object ACIs], no)dnl
-OL_ARG_ENABLE(discreteaci,[    --enable-discreteaci    enable discrete rights in ACIs], no)dnl
 OL_ARG_ENABLE(wrappers,[    --enable-wrappers  enable tcp wrapper support], no)dnl
+OL_ARG_ENABLE(dynamic,[    --enable-dynamic    enable linking built binaries with dynamic libs], no)dnl
 
 dnl SLAPD Backend options
-OL_ARG_ENABLE(bdb2,[    --enable-bdb2  enable bdb2 backend], no)dnl
-OL_ARG_WITH(bdb2_module,[      --with-bdb2-module      module type], static,
+OL_ARG_ENABLE(dnssrv,[    --enable-dnssrv      enable dnssrv backend], no)dnl
+OL_ARG_WITH(dnssrv_module,[      --with-dnssrv-module  module type], static,
        [static dynamic])
 OL_ARG_ENABLE(ldap,[    --enable-ldap  enable ldap backend], no)dnl
 OL_ARG_WITH(ldap_module,[      --with-ldap-module      module type], static,
        [static dynamic])
 OL_ARG_ENABLE(ldbm,[    --enable-ldbm  enable ldbm backend], yes)dnl
 OL_ARG_WITH(ldbm_api,[      --with-ldbm-api    use LDBM API], auto,
-       [auto db2 db mdbm gdbm ndbm manual])
+       [auto berkeley bcompat mdbm gdbm])
 OL_ARG_WITH(ldbm_module,[      --with-ldbm-module      module type], static,
        [static dynamic])
 OL_ARG_WITH(ldbm_type,[      --with-ldbm-type  use LDBM type], auto,
        [auto btree hash])
-
 OL_ARG_ENABLE(passwd,[    --enable-passwd      enable passwd backend], no)dnl
 OL_ARG_WITH(passwd_module,[      --with-passwd-module  module type], static,
        [static dynamic])
-OL_ARG_ENABLE(perl,[    --enable-perl  enable perl backend], no)dnl
-OL_ARG_WITH(perl_module,[      --with-perl-module      module type], static,
-       [static dynamic])
 OL_ARG_ENABLE(shell,[    --enable-shell        enable shell backend], no)dnl
 OL_ARG_WITH(shell_module,[      --with-shell-module    module type], static,
        [static dynamic])
-OL_ARG_ENABLE(tcl,[    --enable-tcl    enable tcl backend], no)dnl
-OL_ARG_WITH(tcl_module,[      --with-tcl-module        module type], static,
-       [static dynamic])
 
+dnl ----------------------------------------------------------------
 dnl SLURPD OPTIONS
 AC_ARG_WITH(xxslurpdoptions,[SLURPD (Replication Daemon) Options:])
 OL_ARG_ENABLE(slurpd,[  --enable-slurpd        enable building slurpd], auto)dnl
 
+dnl ----------------------------------------------------------------
 AC_ARG_WITH(xxliboptions,[Library Generation & Linking Options])
 AC_ENABLE_STATIC
 dnl AC_DISABLE_SHARED
 AC_ENABLE_SHARED
 
+dnl ----------------------------------------------------------------
+
 dnl General "enable" options
 # validate options
-if test $ol_enable_dns = yes ; then
-       if test $ol_enable_referrals = no ; then
-               AC_MSG_ERROR([DNS requires --enable-referrals])
-       fi
-       if test $ol_enable_referrals = auto ; then
-               AC_MSG_WARN([DNS requires referrals, adding --enable-referrals])
-               ol_enable_referrals=yes
-       fi
-fi
-
 if test $ol_enable_slapd = no ; then
        dnl SLAPD was specificallly disabled
-       if test $ol_enable_bdb2 = yes ; then
-               AC_MSG_WARN([slapd disabled, ignoring --enable-bdb2 argument])
+       if test $ol_enable_dnssrv = yes ; then
+               AC_MSG_WARN([slapd disabled, ignoring --enable-dnssrv argument])
        fi
        if test $ol_enable_ldap = yes ; then
                AC_MSG_WARN([slapd disabled, ignoring --enable-ldap argument])
@@ -188,15 +202,9 @@ if test $ol_enable_slapd = no ; then
        if test $ol_enable_passwd = yes ; then
                AC_MSG_WARN([slapd disabled, ignoring --enable-passwd argument])
        fi
-       if test $ol_enable_perl = yes ; then
-               AC_MSG_WARN([slapd disabled, ignoring --enable-perl argument])
-       fi
        if test $ol_enable_shell = yes ; then
                AC_MSG_WARN([slapd disabled, ignoring --enable-shell argument])
        fi
-       if test $ol_enable_tcl = yes ; then
-               AC_MSG_WARN([slapd disabled, ignoring --enable-tcl argument])
-       fi
        if test $ol_enable_modules = yes ; then
                AC_MSG_WARN([slapd disabled, ignoring --enable-modules argument])
        fi
@@ -218,17 +226,14 @@ if test $ol_enable_slapd = no ; then
        if test $ol_enable_aci = yes ; then
                AC_MSG_WARN([slapd disabled, ignoring --enable-aci argument])
        fi
-       if test $ol_enable_discreteaci = yes ; then
-               AC_MSG_WARN([slapd disabled, ignoring --enable-discreteaci argument])
-       fi
        if test $ol_with_ldbm_api != auto ; then
                AC_MSG_WARN([slapd disabled, ignoring --with-ldbm-api argument])
        fi
        if test $ol_with_ldbm_type != auto ; then
                AC_MSG_WARN([slapd disabled, ignoring --with-ldbm-type argument])
        fi
-       if test $ol_with_bdb2_module != static ; then
-               AC_MSG_WARN([slapd disabled, ignoring --with-bdb2-module argument])
+       if test $ol_with_dnssrv_module != static ; then
+               AC_MSG_WARN([slapd disabled, ignoring --with-dnssrv-module argument])
        fi
        if test $ol_with_ldap_module != static ; then
                AC_MSG_WARN([slapd disabled, ignoring --with-ldap-module argument])
@@ -239,27 +244,19 @@ if test $ol_enable_slapd = no ; then
        if test $ol_with_passwd_module != static ; then
                AC_MSG_WARN([slapd disabled, ignoring --with-passwd-module argument])
        fi
-       if test $ol_with_perl_module != static ; then
-               AC_MSG_WARN([slapd disabled, ignoring --with-perl-module argument])
-       fi
        if test $ol_with_shell_module != static ; then
                AC_MSG_WARN([slapd disabled, ignoring --with-shell-module argument])
        fi
-       if test $ol_with_tcl_module != static ; then
-               AC_MSG_WARN([slapd disabled, ignoring --with-tcl-module argument])
-       fi
        if test $ol_enable_slurpd = yes ; then
                AC_MSG_ERROR([slurpd requires slapd])
        fi
 
        # force settings to no
-       ol_enable_bdb2=no
+       ol_enable_dnssrv=no
        ol_enable_ldap=no
        ol_enable_ldbm=no
        ol_enable_passwd=no
-       ol_enable_perl=no
        ol_enable_shell=no
-       ol_enable_tcl=no
 
        ol_enable_modules=no
        ol_enable_multimaster=no
@@ -267,19 +264,17 @@ if test $ol_enable_slapd = no ; then
        ol_enable_quipu=no
        ol_enable_rlookups=no
        ol_enable_aci=no
-       ol_enable_discreteaci=no
        ol_enable_wrappers=no
+       ol_enable_dynamic=no
 
        ol_with_ldbm_api=no
        ol_with_ldbm_type=no
 
-       ol_with_bdb2_module=static
+       ol_with_dnssrv_module=static
        ol_with_ldap_module=static
        ol_with_ldbm_module=static
        ol_with_passwd_module=static
-       ol_with_perl_module=static
        ol_with_shell_module=static
-       ol_with_tcl_module=static
 
        ol_enable_slurpd=no
 
@@ -298,16 +293,11 @@ elif test $ol_enable_ldbm = no ; then
                AC_MSG_WARN([LDBM disabled, ignoring --with-ldbm-module argument])
        fi
 
-       if test $ol_enable_bdb2 = yes ; then
-               AC_MSG_ERROR([BDB2 requires --enable-ldbm])
-       fi
-
        if test $ol_enable_modules != yes -a \
+               $ol_enable_dnssrv = no -a \
                $ol_enable_ldap = no -a \
                $ol_enable_passwd = no -a \
-               $ol_enable_perl = no -a \
-               $ol_enable_shell = no -a \
-               $ol_enable_tcl = no ; then
+               $ol_enable_shell = no ; then
                AC_MSG_ERROR([slapd requires a backend])
        fi
 
@@ -315,27 +305,8 @@ elif test $ol_enable_ldbm = no ; then
        ol_with_ldbm_type=no
        ol_with_ldbm_module=static
 
-elif test $ol_enable_bdb2 = yes ; then
-       dnl SLAPD with BDB2
-
-       if test $ol_with_ldbm_api != auto -a \
-               $ol_with_ldbm_api != db2 ; then
-               AC_MSG_ERROR([BDB2 requires LDBM API DB2])
-       fi
-
-       ol_with_ldbm_api=db2
-
 else
        dnl SLAPD with LDBM
-
-       if test $ol_enable_bdb2 != no ; then
-               if test $ol_with_ldbm_api != auto -a \
-                       $ol_with_ldbm_api != db2 ; then
-                       AC_MSG_WARN([BDB2 requires LDBM api db2 or auto])
-                       ol_enable_bdb2=no
-               fi
-       fi
-
        if test $ol_with_ldbm_api = gdbm -a \
                $ol_with_ldbm_type = btree ; then
                AC_MSG_ERROR([GDBM only supports LDBM type hash])
@@ -357,60 +328,78 @@ if test $ol_enable_slurpd = yes ; then
        fi
 fi
 
+if test $ol_enable_kbind = yes -o $ol_enable_kpasswd = yes ; then
+       if test $ol_with_kerberos = no ; then
+               AC_MSG_ERROR([options require --with-kerberos])
+       fi
+elif test $ol_enable_kbind = no -o $ol_enable_kpasswd = no ; then
+       if test $ol_with_kerberos != auto ; then
+               AC_MSG_WARN([Kerberos detection enabled unnecessarily]);
+       else
+               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])
+       fi
+       ol_link_spasswd=yes
+fi
+
 AC_MSG_RESULT(done)
 
-## Initialize vars
+dnl ----------------------------------------------------------------
+dnl Initialize vars
 LDAP_LIBS=
 LDIF_LIBS=
 LDBM_LIBS=
 LTHREAD_LIBS=
 LUTIL_LIBS=
 
+QUIPU_LIBS=
 SLAPD_LIBS=
 SLURPD_LIBS=
 
 BUILD_SLAPD=no
 BUILD_SLURPD=no
 
-BUILD_BDB2=no
+BUILD_QUIPU=no
+BUILD_THREAD=no
+
+BUILD_DNSSRV=no
 BUILD_LDAP=no
 BUILD_LDBM=no
 BUILD_PASSWD=no
-BUILD_PERL=no
-BUILD_QUIPU=no
 BUILD_SHELL=no
-BUILD_TCL=no
-BUILD_THREAD=no
 
-BUILD_BDB2_DYNAMIC=static
+BUILD_DNSSRV_DYNAMIC=static
 BUILD_LDAP_DYNAMIC=static
 BUILD_LDBM_DYNAMIC=static
 BUILD_PASSWD_DYNAMIC=static
-BUILD_PERL_DYNAMIC=static
 BUILD_SHELL_DYNAMIC=static
-BUILD_TCL_DYNAMIC=static
 
 SLAPD_MODULES_LDFLAGS=
 SLAPD_MODULES_CPPFLAGS=
 SLAPD_MODULES_LIST=
 
-SLAPD_PERL_LDFLAGS=
-SLAPD_PERL_CPPFLAGS=
-
-KRB_LIBS=
+KRB4_LIBS=
+KRB5_LIBS=
 READLINE_LIBS=
 SASL_LIBS=
 TERMCAP_LIBS=
 TLS_LIBS=
 MODULES_LIBS=
+AUTH_LIBS=
 
-dnl ----------------------------------------------------------------
+dnl ================================================================
 dnl Checks for programs
 
 dnl AC_PROG_INSTALL
 
 AC_DEFINE(HAVE_MKVERSION, 1, [define this if you have mkversion])
 
+dnl ----------------------------------------------------------------
 dnl
 dnl Determine which C translator to use
 dnl
@@ -464,9 +453,9 @@ dnl The default CFLAGS is empty NOT whatever AC_PROG_CC sets.
 dnl (for now, let autoconf sort this out)
 dnl CFLAGS=${CFLAGS-""}
 
+AC_LIBTOOL_WIN32_DLL
 AC_LIBTOOL_DLOPEN
 AC_PROG_LIBTOOL
-dnl AC_PROG_MAKE_SET
 
 AC_PROG_AWK
 OL_PROG_LN_H
@@ -481,26 +470,10 @@ AC_PATH_PROG(SENDMAIL, sendmail, /usr/lib/sendmail,
 AC_PATH_PROG(EDITOR, vi, /usr/ucb/vi, $PATH:/usr/ucb)
 AC_PATH_PROG(FINGER, finger, /usr/ucb/finger, $PATH:/usr/ucb)
 
-ol_link_perl=no
-if test $ol_enable_perl != no ; then
-       AC_PATH_PROG(PERLBIN, perl, /usr/bin/perl)
-
-       if test "no$PERLBIN" = "no" ; then
-               if test $ol_enable_perl = yes ; then
-                       AC_MSG_ERROR([could not locate perl])
-               fi
-
-       else
-               SLAPD_PERL_LDFLAGS="`$PERLBIN -MExtUtils::Embed -e ldopts|sed -e s/-lc//`"
-               SLAPD_PERL_CPPFLAGS="`$PERLBIN -MExtUtils::Embed -e ccopts`"
-
-               dnl should check perl version
-               ol_link_perl=yes
-       fi
-fi
-
 AC_PROG_CPP
 
+dnl ----------------------------------------------------------------
+dnl Cross compiling checks
 if test $cross_compiling = yes -a $ol_enable_x_compile = yes; then
        AC_MSG_WARN([cross compiling....  some functionality will be removed.])
 
@@ -513,11 +486,13 @@ elif test $cross_compiling = yes -a $ol_enable_x_compile = no; then
        AC_MSG_ERROR([  if cross compiling,  add --enable-x-compile.])
 fi
 
+dnl ----------------------------------------------------------------
 dnl Checks for UNIX Variants
 AC_AIX
 AC_ISC_POSIX
 AC_MINIX
 
+dnl ----------------------------------------------------------------
 dnl Checks for system services
 AC_CYGWIN
 AC_MINGW32
@@ -526,15 +501,18 @@ AC_OBJEXT
 
 AC_DEFINE_UNQUOTED( EXEEXT, "${EXEEXT}", [defined to be the EXE extension])
 
+dnl ----------------------------------------------------------------
 dnl BeOS requires -lbe -lroot -lnet
 AC_CHECK_LIB(be, be_app, [LIBS="$LIBS -lbe -lroot -lnet"], :, [-lroot -lnet])
 
+dnl ----------------------------------------------------------------
 dnl OpenLDAP requires STDC features
 AM_PROG_CC_STDC
 if test "X${am_cv_prog_cc_stdc}" = "Xno" ; then
        AC_MSG_ERROR([OpenLDAP requires compiler to support STDC constructs.])
 fi
 
+dnl ----------------------------------------------------------------
 dnl Check cc depend flags
 OL_MKDEPEND
 if test "${ol_cv_mkdep}" = no ; then
@@ -542,31 +520,61 @@ if test "${ol_cv_mkdep}" = no ; then
        AC_MSG_WARN([do not know how to generate dependencies])
 fi
 
-dnl
+dnl ----------------------------------------------------------------
+dnl Check for AIX security library
+AC_CHECK_LIB(s, afopen, [
+       AUTH_LIBS=-ls
+       AC_DEFINE(HAVE_AIX_SECURITY,1,[define if you have AIX security lib])
+])
+
+
+dnl ----------------------------------------------------------------
+dnl PF_INET6 support requires getaddrinfo
+dnl PF_UNIX may use getaddrinfo in available
+AC_CHECK_FUNCS( getaddrinfo )
+
+if test $ac_cv_func_getaddrinfo = no ; then
+       if test $ol_enable_ipv6 = yes ; then
+               AC_MSG_ERROR([IPv6 support requires getaddrinfo()])
+       fi
+       ol_enable_ipv6=no
+fi
+
+if test $ol_enable_unix != no ; then
+       AC_CHECK_HEADERS( sys/un.h )
+
+       if test $ol_enable_unix = auto ; then
+               ol_enable_unix=$ac_cv_header_sys_un_h
+       elif test $ac_cv_header_sys_un_h = no ; then
+               AC_MSG_ERROR([UNIX domain support requires sys/un.h])
+       fi
+fi
+
+dnl ----------------------------------------------------------------
 dnl Check for module support
-dnl
 ol_link_modules=no
 if test $ol_enable_modules != no ; then
        AC_CHECK_HEADERS(ltdl.h)
 
        if test $ac_cv_header_ltdl_h = no ; then
                AC_MSG_ERROR([could not locate libtool ltdl.h])
-
        fi
 
-       AC_CHECK_LIB(ltdl, lt_dlinit)
+       AC_CHECK_LIB(ltdl, lt_dlinit, [
+           MODULES_LIBS=-lltdl
+           AC_DEFINE(HAVE_LIBLTDL,1,[define if you have libtool -ltdl])
+       ])
+
        if test "$ac_cv_lib_ltdl_lt_dlinit" = no ; then
                AC_MSG_ERROR([could not locate libtool -lltdl])
        fi
        ol_link_modules=yes
 else
-       ol_with_bdb2_module=static
+       ol_with_dnssrv_module=static
        ol_with_ldap_module=static
        ol_with_ldbm_module=static
        ol_with_passwd_module=static
-       ol_with_perl_module=static
        ol_with_shell_module=static
-       ol_with_tcl_module=static
 fi
 
 dnl ----------------------------------------------------------------
@@ -589,12 +597,15 @@ AC_CHECK_HEADERS( \
        arpa/inet.h             \
        arpa/nameser.h  \
        assert.h                \
+       conio.h                 \
        crypt.h                 \
+       direct.h                \
        errno.h                 \
        fcntl.h                 \
        filio.h                 \
        getopt.h                \
        grp.h                   \
+       io.h                    \
        libutil.h               \
        limits.h                \
        locale.h                \
@@ -603,6 +614,7 @@ AC_CHECK_HEADERS(   \
        memory.h                \
        psap.h                  \
        pwd.h                   \
+       process.h               \
        resolv.h                \
        sgtty.h                 \
        shadow.h                \
@@ -624,11 +636,35 @@ AC_CHECK_HEADERS( \
        syslog.h                \
        termios.h               \
        unistd.h                \
+       winsock.h               \
 )
 
+
 dnl ----------------------------------------------------------------
 dnl Checks for libraries
 
+dnl HP-UX requires -lV3
+AC_CHECK_LIB(V3, sigset)
+
+dnl Gotta check for winsock manually
+if test $ac_cv_header_winsock_h = yes; then
+       AC_CACHE_CHECK([for winsock], [ol_cv_winsock], 
+       AC_TRY_LINK([#include <winsock.h>],[
+                       socket(0,0,0);
+                       select(0,NULL,NULL,NULL,NULL);
+                       closesocket(0);
+                       gethostname(NULL,0);
+       ],[ol_cv_winsock=yes],[ol_cv_winsock=no])])
+
+       if test $ol_cv_winsock = yes ; then
+               AC_DEFINE(HAVE_WINSOCK,1,[define if you have winsock])
+               ac_cv_func_socket=yes
+               ac_cv_func_select=yes
+               ac_cv_func_closesocket=yes
+               ac_cv_func_gethostname=yes
+       fi
+fi
+
 dnl Find socket()
 dnl Likely combinations:
 dnl            -lsocket [ -lnsl_s | -lnsl ]
@@ -638,7 +674,6 @@ AC_CHECK_FUNC(socket, :, [
 dnl hopefully we won't include too many libraries
        AC_CHECK_LIB(socket, main)
        AC_CHECK_LIB(net, main)
-       AC_CHECK_LIB(net, socket)
        AC_CHECK_LIB(nsl_s, main)
        AC_CHECK_LIB(nsl, main)
        AC_CHECK_LIB(inet, socket)
@@ -647,16 +682,18 @@ dnl hopefully we won't include too many libraries
 
 dnl require select
 AC_CHECK_FUNC(select, :, AC_MSG_ERROR([select() required.]))
-dnl AC_CHECK_FUNCS(socketpair)
 
-dnl Select arg types
-dnl (if this detection becomes permenent, it and the select() detection
-dnl should be done before the yielding select test) 
-AC_FUNC_SELECT_ARGTYPES
+if test "${ac_cv_header_winsock_h}" != yes; then
+    dnl Select arg types
+    dnl (if this detection becomes permenent, it and the select() detection
+    dnl should be done before the yielding select test) 
+    AC_FUNC_SELECT_ARGTYPES
+fi
 
 dnl check to see if system call automatically restart
 dnl AC_SYS_RESTARTABLE_SYSCALLS
 
+dnl ----------------------------------------------------------------
 dnl require POSIX regex
 AC_CHECK_HEADERS( regex.h )
 if test "$ac_cv_header_regex_h" != yes ; then
@@ -669,37 +706,40 @@ if test "$ol_cv_c_posix_regex" = no ; then
        AC_MSG_ERROR([broken POSIX regex!])
 fi
 
-dnl HP-UX requires -lV3
-AC_CHECK_LIB(V3, sigset)
-
+dnl ----------------------------------------------------------------
 dnl Check for resolver routines
-AC_CHECK_FUNC(res_search,:)
-if test $ac_cv_func_res_search = no ; then 
-       AC_CHECK_LIB(bind, res_search)
-       ac_cv_func_res_search=$ac_cv_lib_bind_res_search
+ol_link_dnssrv=no
+AC_CHECK_FUNC(res_query,:)
+if test $ac_cv_func_res_query = no ; then 
+       AC_CHECK_LIB(bind, res_query)
+       ac_cv_func_res_query=$ac_cv_lib_bind_res_query
 fi
 
-if test $ac_cv_func_res_search = no ; then 
-       AC_CHECK_LIB(bind, __res_search)
-       ac_cv_func_res_search=$ac_cv_lib_bind___res_search
+if test $ac_cv_func_res_query = no ; then 
+       AC_CHECK_LIB(bind, __res_query)
+       ac_cv_func_res_query=$ac_cv_lib_bind___res_query
 fi
 
-if test $ac_cv_func_res_search = no ; then 
-       AC_CHECK_LIB(resolv, res_search)
-       ac_cv_func_res_search=$ac_cv_lib_resolv_res_search
+if test $ac_cv_func_res_query = no ; then 
+       AC_CHECK_LIB(resolv, res_query)
+       ac_cv_func_res_query=$ac_cv_lib_resolv_res_query
 fi
 
-if test "$ac_cv_func_res_search" = yes ; then
-       AC_DEFINE(HAVE_RES_SEARCH,1,
-               [define if you have res_search()])
-elif test $ol_enable_dns = yes ; then
-       AC_MSG_ERROR([--enable-dns requires res_search])
-elif test $ol_enable_dns != no ; then
-       AC_MSG_WARN([no res_search, disabling DNS support])
+if test "$ac_cv_func_res_query" = yes ; then
+       AC_DEFINE(HAVE_RES_QUERY,1,
+               [define if you have res_query()])
+
+       if test $ol_enable_dnssrv != no ; then
+               ol_link_dnssrv=yes
+       fi
 fi
 
+if test "$ol_enable_dnssrv" = yes -a "$ol_link_dnssrv" = no ; then
+       AC_MSG_ERROR([DNSSRV requires res_query()])
+fi
 
-# QUIPU
+dnl ----------------------------------------------------------------
+dnl QUIPU
 if test $ol_enable_quipu != no ; then
        AC_CHECK_HEADERS(quipu/commonarg.h)
 
@@ -712,31 +752,104 @@ if test $ol_enable_quipu != no ; then
        fi
 fi
 
-dnl
-dnl check for kerberos
-dnl
-ol_link_kerberos=no
+dnl ----------------------------------------------------------------
+dnl Kerberos
+ol_link_kbind=no
+ol_link_kpasswd=no
+ol_link_krb5=no
+ol_link_krb4=no
+
+if test $ol_with_kerberos = auto -o $ol_with_kerberos = k5 \
+       -o $ol_with_kerberos = k5only -o $ol_with_kerberos = k425 ; then
+
+       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(krb5, main,
+                               [have_krb5=yes
+                               KRB5_LIBS="-lkrb5 -lcrypto -lcom_err"],
+                               [have_krb5=no],
+                               [-lcrypto -lcom_err])
+
+               elif test $krb5_impl = heimdal; then
+                       AC_CHECK_LIB(krb5, main,
+                               [have_krb5=yes
+                               KRB5_LIBS="-lkrb5 -ldes -lasn1 -lroken -lcom_err"],
+                               [have_krb5=no],
+                               [-ldes -lasn1 -lroken -lcom_err])
+
+                       AC_DEFINE(HAVE_HEIMDAL_KERBEROS, 1,
+                               [define if you have HEIMDAL Kerberos])
+               else
+                       have_krb5=no
+                       AC_MSG_WARN([Unrecongized 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_enable_kpasswd != no ; then
+                               ol_link_kpasswd=yes;
+                       fi
+
+                       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
+fi
+
+if test $ol_link_krb5 = yes -a \
+       \( $ol_with_kerberos = auto -o $ol_with_kerberos = k425 \) ; then
 
-if test $ol_with_kerberos = auto -o $ol_with_kerberos = k5 ; then
        AC_CHECK_HEADERS(kerberosIV/krb.h kerberosIV/des.h)
 
        if test $ac_cv_header_kerberosIV_krb_h = yes ; then
-               AC_CHECK_LIB(krb4, main, [have_k5=yes], [have_k5=no],
-                       [-lkrb5 -ldes425])
+               if test $krb5_impl = mit; then
+                       AC_CHECK_LIB(krb4, main, [have_k425=yes
+                               KRB4_LIBS="-lkrb4 -ldes425"], [have_k425=no],
+                               [-ldes425 -lkrb5 -lcrypto -lcom_err])
 
-               if test $have_k5 = yes ; then
-                       ol_with_kerberos=found
-                       ol_link_kerberos=yes
+               elif test $krb5_impl = heimdal; then
+                       AC_CHECK_LIB(krb4, main, [have_k425=yes
+                               KRB4_LIBS="-lkrb4"], [have_k425=no],
+                               [-lkrb5 -ldes -lasn1 -lroken -lcom_err])
 
-                       KRB_LIBS="-lkrb4 -lkrb5 -ldes425"
+               else
+                       have_425=no
+                       AC_MSG_WARN([Unrecongized Kerberos5 Implementation])
+               fi
+
+               if test $have_k425 = yes ; then
+                       ol_with_kerberos=found
+                       ol_link_krb4=yes
 
-                       LIBS="$KRB_LIBS $LIBS"
+                       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="$KRB_LIBS $LIBS"
+                               LIBS="$KRB4_LIBS $KRB5_LIBS $LIBS"
                                AC_TRY_LINK([
 #include <kerberosIV/krb.h>
 #include <kerberosIV/des.h>
@@ -758,28 +871,48 @@ des_debug = 1;
        fi
 fi
 
-if test $ol_with_kerberos = auto -o $ol_with_kerberos = k4 ; then
-       AC_CHECK_HEADERS(krb.h des.h)
+if test $ol_link_krb5 = yes ; then
+       ol_with_kerberos=found
+fi
+
+if test $ol_with_kerberos = auto -o $ol_with_kerberos = k4 \
+       -o $ol_with_kerberos = kth ; then
+
+       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_kerberos=yes
+                       ol_link_krb4=yes
+
+                       AC_DEFINE(HAVE_KRB4, 1,
+                               [define if you have Kerberos IV])
 
-                       KRB_LIBS="-lkrb -ldes"
+                       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
 fi
 
-if test $ol_link_kerberos = yes ; then
+if test $ol_link_krb4 = yes -a $ol_enable_kpasswd != no ; then
+       ol_link_kpasswd=yes;
+fi
+
+if test $ol_link_krb4 = yes -o $ol_link_krb5 = yes ; then
        AC_DEFINE(HAVE_KERBEROS, 1, [define if you have Kerberos])
+
+elif test $ol_with_kerberos != auto -a $ol_with_kerberos != no ; then
+       AC_MSG_ERROR([Kerberos detection failed.])
 fi
 
-dnl
-dnl Check for SSL/TLS
-dnl
+dnl ----------------------------------------------------------------
+dnl TLS/SSL
 ol_link_tls=no
 if test $ol_with_tls != no ; then
        
@@ -829,6 +962,7 @@ if test $ol_link_tls = yes ; then
        AC_DEFINE(HAVE_TLS, 1, [define if you have TLS])
 fi     
 
+dnl ----------------------------------------------------------------
 dnl Tests for reentrant functions necessary to build a
 dnl thread_safe -lldap.
 AC_CHECK_FUNCS(                \
@@ -869,7 +1003,29 @@ if test "$ac_cv_func_ctime_r" = yes \
        AC_DEFINE(LDAP_API_FEATURE_X_OPENLDAP_REENTRANT,1)
 fi
 
+dnl ----------------------------------------------------------------
+dnl Threads?
 ol_link_threads=no
+
+if test $ol_with_threads = auto -o $ol_with_threads = yes \
+       -o $ol_with_threads = nt ; then
+
+       OL_NT_THREADS
+
+       if test "$ol_cv_nt_threads" = yes ; then
+       ol_link_threads=nt
+       ol_with_threads=found
+       ol_with_yielding_select=yes
+
+               AC_DEFINE(HAVE_NT_SERVICE_MANAGER,1,[if you have NT Service Manager])
+               AC_DEFINE(HAVE_NT_EVENT_LOG,1,[if you have NT Event Log])
+       fi
+
+       if test $ol_with_threads = nt ; then
+               AC_MSG_ERROR([could not locate NT Threads])
+       fi
+fi
+
 if test $ol_with_threads = auto -o $ol_with_threads = yes \
        -o $ol_with_threads = posix ; then
 
@@ -1016,7 +1172,7 @@ dnl                       [ol_cv_pthread_lpthread_lexc])
                        fi
 
                        dnl Check functions for compatibility
-                       AC_CHECK_FUNCS(pthread_kill)
+                       AC_CHECK_FUNCS(pthread_kill pthread_rwlock_destroy)
 
                        dnl Check for pthread_detach with <pthread.h> inclusion
                        dnl as it's symbol may have been mangled.
@@ -1301,7 +1457,7 @@ if test $ol_with_threads = manual ; then
        AC_CHECK_HEADERS(thread.h synch.h)
 fi
 
-if test $ol_link_threads != no ; then  
+if test $ol_link_threads != no -a $ol_link_threads != nt ; then  
        dnl needed to get reentrant/threadsafe versions
        dnl
        AC_DEFINE(REENTRANT,1)
@@ -1408,41 +1564,23 @@ if test $ol_link_threads != no ; then
 fi
 
 dnl ----------------------------------------------------------------
-
 ol_link_ldbm=no 
-if test $ol_with_ldbm_api = auto -o $ol_with_ldbm_api = db2 ; then
-       OL_BERKELEY_DB2
 
-       if test $ol_cv_berkeley_db2 = yes ; then
-               ol_link_ldbm=db2
-               ol_with_ldbm_api=db2
+if test $ol_with_ldbm_api = auto \
+       -o $ol_with_ldbm_api = berkeley \
+       -o $ol_with_ldbm_api = bcompat ; then
 
-               if test $ol_with_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_db2 should be yes or -ldb
-               dnl (it could be no, but that would be an error
-               if test $ol_cv_lib_db2 != yes ; then
-                       LDBM_LIBS="$LDBM_LIBS $ol_cv_lib_db2"
-               fi
+       if test $ol_with_ldbm_api = bcompat; then \
+               OL_BERKELEY_COMPAT_DB
+       else
+               OL_BERKELEY_DB
        fi
-fi
 
-ol_link_bdb2=no
-if test $ol_link_ldbm = db2 -a $ol_enable_bdb2 != no ; then
-       ol_link_bdb2=yes
-fi
+       if test $ol_cv_berkeley_db != no ; then
+               AC_DEFINE(HAVE_BERKELEY_DB,1,
+                       [define this if Berkeley DB is available])
 
-if test $ol_with_ldbm_api = auto -o $ol_with_ldbm_api = db ; then
-       OL_BERKELEY_DB
-
-       if test $ol_cv_berkeley_db = yes ; then
-               ol_link_ldbm=db
+               ol_link_ldbm=berkeley
                ol_with_ldbm_api=db
 
                if test $ol_with_ldbm_type = hash ; then
@@ -1461,15 +1599,6 @@ if test $ol_with_ldbm_api = auto -o $ol_with_ldbm_api = db ; then
        fi
 fi
 
-if test $ol_with_ldbm_api = manual ; then
-       dnl User thinks he can manually configure LDBM api.
-       ol_link_ldbm=yes
-
-       AC_MSG_WARN([LDBM defines and link options must be set manually])
-
-       AC_CHECK_HEADERS(db.h db_185.h gdbm.h ndbm.h)
-fi
-
 if test $ol_link_ldbm = no -a $ol_with_ldbm_type = btree ; then
        AC_MSG_WARN(Could not find LDBM with BTREE support)
        ol_with_ldbm_api=none
@@ -1500,9 +1629,7 @@ if test $ol_with_ldbm_api = auto -o $ol_with_ldbm_api = gdbm ; then
        fi
 fi
 
-if test $ol_with_ldbm_api = auto ; then
-       AC_MSG_WARN([skipping automatic checking for NDBM, must be manually enabled.])
-elif test $ol_with_ldbm_api = ndbm ; then
+if test $ol_with_ldbm_api = ndbm ; then
        OL_NDBM
 
        if test $ol_cv_ndbm = yes ; then
@@ -1525,19 +1652,29 @@ if test $ol_link_ldbm = no -a $ol_enable_ldbm != no ; then
        ol_enable_ldbm=no
 fi
 
+dnl ----------------------------------------------------------------
+if test $ol_enable_dynamic = yes -a $enable_shared = yes ; then
+       LINK_BINS_DYNAMIC="yes"
+else
+       LINK_BINS_DYNAMIC="no"
+fi
+
+dnl ----------------------------------------------------------------
 if test $ol_enable_wrappers != no ; then
        AC_CHECK_HEADERS(tcpd.h)
 
        if test $ac_cv_header_tcpd_h != yes ; then
                have_wrappers=no
        else
-               AC_CHECK_LIB(wrap, main,
-                       [have_wrappers=yes], [have_wrappers=no])
+               AC_TRY_COMPILE([
+int allow_severity = 0;
+int deny_severity  = 0;
+               ],[hosts_access()],[have_wrappers=yes],[have_wrappers=no])
        fi
 
        if test $have_wrappers = yes ; then
                AC_DEFINE(HAVE_TCPD,1, [define if you have -lwrap])
-               SLAPD_LIBS="$SLAPD_LIBS -lwrap"
+               WRAP_LIBS="-lwrap"
 
                dnl We add another check for -lnsl since some libwrap's
                dnl need it, but it isn't always included from above
@@ -1550,9 +1687,11 @@ if test $ol_enable_wrappers != no ; then
 
                AC_MSG_WARN(disabling wrappers support)
                ol_enable_wrappers=no
+               WRAP_LIBS=""
        fi
 fi
 
+dnl ----------------------------------------------------------------
 if test $ol_enable_syslog != no ; then
        AC_CHECK_FUNC(openlog)
        if test $ac_cv_func_openlog = no -a $ol_enable_syslog = yes; then
@@ -1561,45 +1700,8 @@ if test $ol_enable_syslog != no ; then
        ol_enable_syslog=$ac_cv_func_openlog
 fi
 
-if test $ol_enable_dmalloc != no ; then
-       AC_CHECK_HEADERS(dmalloc.h)
-       AC_CHECK_LIB(dmalloc, dmalloc_shutdown)
-fi
-
-if test $ol_enable_tcl != no ; then
-       AC_CHECK_HEADERS(tcl.h)
-
-       if test $ac_cv_header_tcl_h != yes ; then
-               have_tcl=no
-       else
-               AC_CHECK_LIB(tcl,main,
-                       [have_tcl=yes; SLAPD_LIBS="$SLAPD_LIBS -ltcl"],
-                       [have_tcl=no])
-
-               if test $have_tcl != yes; then
-                       AC_CHECK_LIB(tcl7.6,main,
-                               [have_tcl=yes; SLAPD_LIBS="$SLAPD_LIBS -ltcl7.6"],
-                               [have_tcl=no])
-               fi
-
-               if test $have_tcl != yes; then
-                       AC_CHECK_LIB(tcl8.0,main,
-                               [have_tcl=yes; SLAPD_LIBS="$SLAPD_LIBS -ltcl8.0"],
-                               [have_tcl=no])
-               fi
-       fi
-
-       if test $have_tcl != yes ; then
-               AC_MSG_WARN([could not find -ltcl])
-               if test $ol_enable_tcl = yes ; then
-                       AC_MSG_ERROR([could not find tcl, select appropriate options or disable])
-               fi
-
-               ol_enable_tcl=no
-       fi
-fi
-
-# ud needs termcap (should insert check here)
+dnl ----------------------------------------------------------------
+dnl ud needs termcap (should insert check here)
 ol_link_termcap=no
 AC_CHECK_HEADERS(termcap.h ncurses.h)
 
@@ -1626,11 +1728,12 @@ if test $ol_link_termcap = no ; then
        TERMCAP_LIBS=
 fi
 
+dnl ----------------------------------------------------------------
 dnl
-dnl Check for fetch URL support
-dnl            should be extended to support other fetch URL APIs
+dnl Check for Cyrus SASL
 dnl
 ol_link_sasl=no
+ol_link_spasswd=no
 if test $ol_with_cyrus_sasl != no ; then
        AC_CHECK_HEADER(sasl.h)
 
@@ -1650,6 +1753,28 @@ if test $ol_with_cyrus_sasl != no ; then
        fi
 fi
 
+dnl ----------------------------------------------------------------
+dnl Check for entropy sources
+if test $cross_compiling != yes ; then
+       dev=no
+       if test -r /dev/urandom ; then
+               dev="/dev/urandom";
+       elif test -r /idev/urandom ; then
+               dev="/idev/urandom";
+       elif test -r /dev/srandom ; then
+               dev="/dev/srandom";
+       elif test -r /dev/random ; then
+               dev="/dev/random";
+       elif test -r /idev/random ; then
+               dev="/idev/random";
+       fi
+
+       if test $dev != no ; then
+               AC_DEFINE_UNQUOTED(URANDOM_DEVICE,"$dev",[set to urandom device])
+       fi
+fi
+
+dnl ----------------------------------------------------------------
 dnl
 dnl Check for fetch URL support
 dnl            should be extended to support other fetch URL APIs
@@ -1667,6 +1792,7 @@ if test $ol_with_fetch != no ; then
        fi 
 fi
 
+dnl ----------------------------------------------------------------
 dnl
 dnl Check for GNU readline
 dnl
@@ -1695,7 +1821,8 @@ if test $ol_link_readline = yes ; then
 fi
 
 
-# FreeBSD (and others) have crypt(3) in -lcrypt
+dnl ----------------------------------------------------------------
+dnl FreeBSD (and others) have crypt(3) in -lcrypt
 if test $ol_enable_crypt != no ; then
        AC_CHECK_FUNC(crypt, [have_crypt=yes], [
                AC_CHECK_LIB(crypt, crypt, [LUTIL_LIBS="$LUTIL_LIBS -lcrypt"
@@ -1714,14 +1841,16 @@ if test $ol_enable_crypt != no ; then
        fi
 fi
 
-# FreeBSD (and others) have setproctitle(3) in -lutil
+dnl ----------------------------------------------------------------
+dnl FreeBSD (and others) have setproctitle(3) in -lutil
 if test $ol_enable_proctitle != no ; then
        AC_CHECK_FUNC(setproctitle,     [have_setproctitle=yes], [
                AC_CHECK_LIB(util, setproctitle,
                        [have_setproctitle=yes
                        LUTIL_LIBS="$LUTIL_LIBS -lutil"],
                        [have_setproctitle=no
-                       LIBOBJS="$LIBOBJS setproctitle.o"])])
+                       LIBOBJS="$LIBOBJS setproctitle.o"
+                       LIBSRCS="$LIBSRCS setproctitle.c"])])
 
        if test $have_setproctitle = yes ; then
                AC_DEFINE(HAVE_SETPROCTITLE,1,
@@ -1731,18 +1860,25 @@ fi
 
 dnl ----------------------------------------------------------------
 dnl Checks for typedefs, structures, and compiler characteristics.
-AC_TYPE_GETGROUPS dnl requires AC_TYPE_UID_T
 AC_TYPE_MODE_T
 AC_TYPE_OFF_T
 AC_TYPE_PID_T
 AM_TYPE_PTRDIFF_T
 AC_TYPE_SIGNAL
-OL_TYPE_SIG_ATOMIC_T
 AC_TYPE_SIZE_T
+
+AC_CHECK_TYPE(ssize_t, [signed int])
+AC_CHECK_TYPE(caddr_t, [char *])
+
 OL_TYPE_SOCKLEN_T
 AC_STRUCT_ST_BLKSIZE
 AC_HEADER_TIME
 AC_STRUCT_TM
+AC_TYPE_UID_T
+OL_TYPE_SIG_ATOMIC_T
+
+dnl AC_TYPE_GETGROUPS
+
 OL_STRUCT_PASSWD_PW_GECOS
 OL_STRUCT_PASSWD_PW_PASSWD
 
@@ -1752,31 +1888,25 @@ OL_C_VOLATILE
 
 if test $cross_compiling = yes ; then
        AC_DEFINE(CROSS_COMPILING, 1, [define if cross compiling])
-
-       AC_DEFINE(LBER_INT_T,long)
-       AC_DEFINE(LBER_TAG_T,long)
-       AC_DEFINE(LBER_SOCKET_T,int)
-
 else
        AC_C_BIGENDIAN
-       AC_CHECK_SIZEOF(short) 
-       AC_CHECK_SIZEOF(int) 
-       AC_CHECK_SIZEOF(long)
+fi
 
-       if test "$ac_cv_sizeof_int" -lt 4 ; then
-               AC_MSG_WARN([OpenLDAP requires 'int' to be 32 bits or greater.])
+AC_COMPILE_CHECK_SIZEOF(short) 
+AC_COMPILE_CHECK_SIZEOF(int) 
+AC_COMPILE_CHECK_SIZEOF(long)
 
-               AC_DEFINE(LBER_INT_T,long)
-               AC_DEFINE(LBER_TAG_T,long)
-               AC_DEFINE(LBER_SOCKET_T,int)
-       else
-               AC_DEFINE(LBER_INT_T,int)
-               AC_DEFINE(LBER_TAG_T,long)
-               AC_DEFINE(LBER_SOCKET_T,int)
-       fi
+if test "$ac_cv_sizeof_int" -lt 4 ; then
+       AC_MSG_WARN([OpenLDAP requires 'int' to be 32 bits or greater.])
+
+       AC_DEFINE(LBER_INT_T,long)
+else
+       AC_DEFINE(LBER_INT_T,int)
 fi
 
 AC_DEFINE(LBER_LEN_T,long)
+AC_DEFINE(LBER_SOCKET_T,int)
+AC_DEFINE(LBER_TAG_T,long)
 
 dnl ----------------------------------------------------------------
 dnl Checks for library functions.
@@ -1787,8 +1917,17 @@ dnl AM_FUNC_STRTOD
 
 OL_FUNC_INET_ATON
 
-dnl we should use vfork instead of fork in a number of places...
-dnl AC_FUNC_VFORK
+dnl Check for NT specific routines
+AC_CHECK_FUNC(_spawnlp, AC_DEFINE(HAVE_SPAWNLP,1,[if you have spawnlp()]))
+
+AC_CHECK_FUNC(_snprintf, [ac_cv_func_snprintf=yes
+       AC_DEFINE(snprintf, _snprintf, [define to snprintf routine])
+])
+
+AC_CHECK_FUNC(_vsnprintf, [ac_cv_func_vsnprintf=yes
+       AC_DEFINE(vsnprintf, _vsnprintf, [define to vsnprintf routine])
+])
+
 AC_FUNC_VPRINTF
 
 if test $ac_cv_func_vprintf = yes ; then
@@ -1799,6 +1938,7 @@ fi
 AC_CHECK_FUNCS(                \
        bcopy                   \
        closesocket             \
+       chroot                  \
        endgrent                \
        endpwent                \
        flock                   \
@@ -1806,6 +1946,7 @@ AC_CHECK_FUNCS(           \
        getgrgid                \
        gethostname             \
        getpass                 \
+       getpassphrase   \
        getpwuid                \
        getpwnam                \
        getspnam                \
@@ -1849,6 +1990,14 @@ AC_CHECK_FUNCS(          \
 dnl We actually may need to replace more than this.
 AC_REPLACE_FUNCS(getopt tempnam)
 
+if test "$ac_cv_func_getopt" != yes; then
+    LIBSRCS="$LIBSRCS getopt.c"
+fi
+
+if test "$ac_cv_func_tempnam" != yes; then
+    LIBSRCS="$LIBSRCS tempnam.c"
+fi
+
 dnl ----------------------------------------------------------------
 # Check Configuration
 OL_SYS_ERRLIST
@@ -1872,8 +2021,8 @@ if test "$ol_enable_cache" = no ; then
        AC_DEFINE(LDAP_NOCACHE,1,
                [define this to remove -lldap cache support])
 fi
-if test "$ol_enable_dns" != no ; then
-       AC_DEFINE(LDAP_API_FEATURE_X_OPENLDAP_V2_DNS,LDAP_VENDOR_VERSION)
+if test "$ol_link_kbind" != no ; then
+       AC_DEFINE(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND,LDAP_VENDOR_VERSION)
 fi
 if test "$ol_enable_proctitle" != no ; then
        AC_DEFINE(LDAP_PROCTITLE,1,
@@ -1885,13 +2034,24 @@ fi
 if test "$ol_enable_cldap" != no ; then
        AC_DEFINE(LDAP_CONNECTIONLESS,1,[define to support CLDAP])
 fi
-
-if test "$ol_enable_crypt" != no ; then
-       AC_DEFINE(SLAPD_CRYPT,1,[define to support crypt(3) passwords])
+if test "$ol_enable_unix" != no; then
+       AC_DEFINE(LDAP_PF_UNIX,1,[define to support PF_UNIX])
+fi
+if test "$ol_enable_ipv6" != no; then
+       AC_DEFINE(LDAP_PF_INET6,1,[define to support PF_INET6])
 fi
 if test "$ol_enable_cleartext" != no ; then
        AC_DEFINE(SLAPD_CLEARTEXT,1,[define to support cleartext passwords])
 fi
+if test "$ol_enable_crypt" != no ; then
+       AC_DEFINE(SLAPD_CRYPT,1,[define to support crypt(3) passwords])
+fi
+if test "$ol_link_kpasswd" != no ; then
+       AC_DEFINE(SLAPD_KPASSWD,1,[define to support Kerberos passwords])
+fi
+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
@@ -1904,27 +2064,23 @@ fi
 if test "$ol_enable_aci" != no ; then
        AC_DEFINE(SLAPD_ACI_ENABLED,1,[define to support per-object ACIs])
 fi
-if test "$ol_enable_discreteaci" != no ; then
-       AC_DEFINE(SLAPD_ACI_DISCRETE_RIGHTS,1,[define to support discrete rights in ACIs])
-fi
 
 if test "$ol_link_modules" != no ; then
        AC_DEFINE(SLAPD_MODULES,1,[define to support modules])
        BUILD_SLAPD=yes
-       MODULES_LIBS=-lltdl
        SLAPD_MODULES_LDFLAGS="-dlopen self"
 fi
 
-if test "$ol_link_bdb2" != no ; then
-       AC_DEFINE(SLAPD_BDB2,1,[define to support BDB2 backend])
+if test "$ol_link_dnssrv" != no ; then
+       AC_DEFINE(SLAPD_DNSSRV,1,[define to support DNS SRV backend])
        BUILD_SLAPD=yes
-       BUILD_BDB2=yes
-       if test "$ol_with_bdb2_module" != static ; then
-               AC_DEFINE(SLAPD_BDB2_DYNAMIC,1,
-                       [define to support dynamic BDB2 backend])
-               BUILD_BDB2=mod
-               BUILD_BDB2_DYNAMIC=shared
-               SLAPD_MODULES_LIST="$SLAPD_MODULES_LIST -dlopen \$(SLAP_DIR)back-bdb2/back_bdb2.la"
+       BUILD_DNSSRV=yes
+       if test "$ol_with_dnssrv_module" != static ; then
+               AC_DEFINE(SLAPD_DNSSRV_DYNAMIC,1,
+                       [define to support dynamic DNS SRV backend])
+               BUILD_DNSSRV=mod
+               BUILD_DNSSRV_DYNAMIC=shared
+               SLAPD_MODULES_LIST="$SLAPD_MODULES_LIST -dlopen \$(SLAP_DIR)back-dnssrv/back_dnssrv.la"
        fi
 fi
 
@@ -1967,19 +2123,6 @@ if test "$ol_enable_passwd" != no ; then
        fi
 fi
 
-if test "$ol_link_perl" != no ; then
-       AC_DEFINE(SLAPD_PERL,1,[define to support PERL backend])
-       BUILD_SLAPD=yes
-       BUILD_PERL=yes
-       if test "$ol_with_perl_module" != static ; then
-               AC_DEFINE(SLAPD_PERL_DYNAMIC,1,
-                       [define to support dynamic PERL backend])
-               BUILD_PERL=mod
-               BUILD_PERL_DYNAMIC=shared
-               SLAPD_MODULES_LIST="$SLAPD_MODULES_LIST -dlopen \$(SLAP_DIR)back-perl/back_perl.la"
-       fi
-fi
-
 if test "$ol_enable_shell" != no ; then
        AC_DEFINE(SLAPD_SHELL,1,[define to support SHELL backend])
        BUILD_SLAPD=yes
@@ -1993,19 +2136,6 @@ if test "$ol_enable_shell" != no ; then
        fi
 fi
 
-if test "$ol_enable_tcl" != no ; then
-       AC_DEFINE(SLAPD_TCL,1,[define to support TCL backend])
-       BUILD_SLAPD=yes
-       BUILD_TCL=yes
-       if test "$ol_with_tcl_module" != static; then
-               AC_DEFINE(SLAPD_TCL_DYNAMIC,1,
-                       [define to support dynamic TCL backend])
-               BUILD_TCL=mod
-               BUILD_TCL_DYNAMIC=shared
-               SLAPD_MODULES_LIST="$SLAPD_MODULES_LIST -dlopen \$(SLAP_DIR)back-tcl/back_tcl.la"
-       fi
-fi
-
 if test "$ol_enable_slurpd" != no -a "$ol_link_threads" != no -a \
        $BUILD_SLAPD = yes ; then
        BUILD_SLURPD=yes
@@ -2013,45 +2143,66 @@ fi
 
 dnl ----------------------------------------------------------------
 
+if test "$LINK_BINS_DYNAMIC" = yes; then
+    LIB_LINKAGE=DYN
+    LT_LIB_LINKAGE=shared
+else
+    LIB_LINKAGE=STAT
+    LT_LIB_LINKAGE=static
+fi
+
+if test "$ac_cv_mingw32" = yes ; then
+    PLAT=NT
+    DYN_EXT=dll
+else
+    PLAT=UNIX
+    DYN_EXT=so
+fi
+
+AC_SUBST(LIBSRCS)
+
+AC_SUBST(PLAT)
+AC_SUBST(LIB_LINKAGE)
+AC_SUBST(LT_LIB_LINKAGE)
+AC_SUBST(DYN_EXT)
+
 AC_SUBST(BUILD_SLAPD)
-  AC_SUBST(BUILD_BDB2)
+  AC_SUBST(BUILD_DNSSRV)
   AC_SUBST(BUILD_LDAP)
   AC_SUBST(BUILD_LDBM)
   AC_SUBST(BUILD_PASSWD)
-  AC_SUBST(BUILD_PERL)
   AC_SUBST(BUILD_QUIPU)
   AC_SUBST(BUILD_SHELL)
-  AC_SUBST(BUILD_TCL)
-  AC_SUBST(BUILD_BDB2_DYNAMIC)
+  AC_SUBST(BUILD_DNSSRV_DYNAMIC)
   AC_SUBST(BUILD_LDAP_DYNAMIC)
   AC_SUBST(BUILD_LDBM_DYNAMIC)
   AC_SUBST(BUILD_PASSWD_DYNAMIC)
-  AC_SUBST(BUILD_PERL_DYNAMIC)
   AC_SUBST(BUILD_SHELL_DYNAMIC)
-  AC_SUBST(BUILD_TCL_DYNAMIC)
 AC_SUBST(BUILD_SLURPD)
 
 AC_SUBST(LDAP_LIBS)
 AC_SUBST(LDIF_LIBS)
 AC_SUBST(SLAPD_LIBS)
+AC_SUBST(QUIPU_LIBS)
 AC_SUBST(SLURPD_LIBS)
 AC_SUBST(LDBM_LIBS)
 AC_SUBST(LTHREAD_LIBS)
 AC_SUBST(LUTIL_LIBS)
+AC_SUBST(WRAP_LIBS)
+AC_SUBST(LINK_BINS_DYNAMIC)
 
 AC_SUBST(SLAPD_MODULES_CPPFLAGS)
 AC_SUBST(SLAPD_MODULES_LDFLAGS)
 AC_SUBST(SLAPD_MODULES_LIST)
 
-AC_SUBST(SLAPD_PERL_CPPFLAGS)
-AC_SUBST(SLAPD_PERL_LDFLAGS)
-
-AC_SUBST(KRB_LIBS)
+AC_SUBST(KRB4_LIBS)
+AC_SUBST(KRB5_LIBS)
 AC_SUBST(READLINE_LIBS)
 AC_SUBST(SASL_LIBS)
 AC_SUBST(TERMCAP_LIBS)
 AC_SUBST(TLS_LIBS)
 AC_SUBST(MODULES_LIBS)
+AC_SUBST(AUTH_LIBS)
 
 dnl ----------------------------------------------------------------
 dnl final output
@@ -2072,6 +2223,7 @@ clients/gopher/Makefile:build/top.mk:clients/gopher/Makefile.in:build/rules.mk \
 clients/mail500/Makefile:build/top.mk:clients/mail500/Makefile.in:build/rules.mk \
 clients/rcpt500/Makefile:build/top.mk:clients/rcpt500/Makefile.in:build/rules.mk \
 clients/ud/Makefile:build/top.mk:clients/ud/Makefile.in:build/rules.mk \
+clients/maildap/Makefile:build/top.mk:clients/maildap/Makefile.in:build/rules.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     \
@@ -2081,16 +2233,15 @@ libraries/libldap/Makefile:build/top.mk:libraries/libldap/Makefile.in:build/lib.
 libraries/libldap_r/Makefile:build/top.mk:libraries/libldap_r/Makefile.in:build/lib.mk:build/lib-shared.mk     \
 libraries/libldbm/Makefile:build/top.mk:libraries/libldbm/Makefile.in:build/lib.mk:build/lib-static.mk \
 libraries/libldif/Makefile:build/top.mk:libraries/libldif/Makefile.in:build/lib.mk:build/lib-static.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       \
 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-bdb2/Makefile:build/top.mk:servers/slapd/back-bdb2/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-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-passwd/Makefile:build/top.mk:servers/slapd/back-passwd/Makefile.in:build/mod.mk \
-servers/slapd/back-perl/Makefile:build/top.mk:servers/slapd/back-perl/Makefile.in:build/mod.mk \
 servers/slapd/back-shell/Makefile:build/top.mk:servers/slapd/back-shell/Makefile.in:build/mod.mk \
-servers/slapd/back-tcl/Makefile:build/top.mk:servers/slapd/back-tcl/Makefile.in:build/mod.mk \
 servers/slapd/shell-backends/Makefile:build/top.mk:servers/slapd/shell-backends/Makefile.in:build/srv.mk \
 servers/slapd/tools/Makefile:build/top.mk:servers/slapd/tools/Makefile.in \
 servers/slurpd/Makefile:build/top.mk:servers/slurpd/Makefile.in:build/srv.mk \
index e74ed3238d7a8c7c2599a50ed2f88ec7779008c9..74b14db7d4a75d16202e96baa4882c977106659b 100644 (file)
@@ -1,5 +1,5 @@
 # $OpenLDAP$
-## Copyright 1998 The OpenLDAP Foundation, All Rights Reserved.
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
 ## COPYING RESTRICTIONS APPLY, See COPYRIGHT file
 ##
 ## contrib Makefile.in for OpenLDAP
index 488b167feaf91a4388a08b5402d82a0ef9ae5603..26e86aaff122ab3cc91935724fbd33bdc6b344ce 100644 (file)
@@ -1,23 +1,39 @@
-LDAP contrib README
+OpenLDAP Contributed Software README
 
-Contributed code lives underneath this contrib directory.  It is not as
-well-integrated into the LDAP build process as the rest of the LDAP
-distribution.  Please see the README files in each contrib subdirectory
-for build instructions.
+OpenLDAP provides a number of freely-distributable LDAP software
+packages.  Though distributed with OpenLDAP, they are not part of
+OpenLDAP.  Some packages may be out of date.  Each package in
+this directory has it's own use and redistribution restrictions
+as documented within the package.
 
 Current contributions:
+       gtk-tool
+               GTK-based frontend from Predrag Balorda
 
-    saucer     General purpose command-line LDAP client, modeled
+       ldaptcl
+               TCL API from NeoSoft
+
+       php3-tool
+               PHP3-based frontend from Predrag Balorda
+
+    saucer
+               General purpose command-line LDAP client, modeled
                after ISODE's DISH (DIrectory SHell) client.
                Contributed by Eric Rosenquist.  See saucer/README
                and its man page for more information.
 
-    web500gw   HTTP gateway for X.500, modeled after go500gw.
+       web_ldap
+               web frontend (in C) from Jens Moller
+
+    web500gw
+               HTTP gateway for X.500, modeled after go500gw.
                Contributed by Frank Richter.  See web500gw/README
                for more information.
 
-    whois++    WHOIS++ gateway to X.500.  Contributed by Mark Prior.
+    whois++
+               WHOIS++ gateway to X.500.  Contributed by Mark Prior.
                See whois++/README for more information.
 
 
-Please send your contributions to ldap-support@umich.edu
+Please submit your contributions using the OpenLDAP Issue
+Tracking System <http://www.openldap.org/>.
diff --git a/contrib/gtk-tool/COPYRIGHT b/contrib/gtk-tool/COPYRIGHT
new file mode 100644 (file)
index 0000000..755a0dd
--- /dev/null
@@ -0,0 +1,8 @@
+Copyright 1998,1999,2000 Predrag Balorda, London, UK
+All rights reserved.
+
+Redistribution and use in source and binary forms are permitted only
+as authorized by the OpenLDAP Public License.  A copy of this
+license is available at http://www.OpenLDAP.org/license.html or
+in file LICENSE in the top-level directory of the distribution.
+
diff --git a/contrib/gtk-tool/ChangeLog b/contrib/gtk-tool/ChangeLog
new file mode 100644 (file)
index 0000000..cfbf97f
--- /dev/null
@@ -0,0 +1,95 @@
+ChangeLog for gtk-tool
+06/01/2000 - Pele
+       * Added cn=schema
+
+03/01/2000 - Pele
+       * Fixed localtime() bug in Linux ?;)
+
+03/01/19100 - Pele
+       * Auto-select the first server if any supplied as arguments
+       * A visual bug in the former (deselect a bit messy)
+       * Follow aliases (not tested with leaf nodes though)
+       * "Show Debug Info" in "Options" menu
+
+28/12/1999 - Pele
+       * Updated Gtk-- API from 1.0 to 1.1
+       * Added -d switch (for debugging info)
+       * Added "Options" menu
+
+12/01/1999 - Pele
+       * Added some defines for U-MICH compatibility
+       * Updated to the latest Gtk-- API (in Gtk-- CVS tree)
+       * Minor fixes due to the new and cleaner Gtk-- API
+       * A new server can be added by entering a hostname into the
+       "url" field at the top and clicking on "Query Server" button
+       (note that one server still has to be supplied on the command line -
+       I'll try and fix this tomorrow...to do with ldap_get_opt)
+       * Somewhat "smarter" Makefile - can someone please look into integrating
+       gtk-tool into the openldap autoconf stuff?
+
+09/12/1998 - Pele
+       * Display of all ldap options in their proper widgets (sliders for 
+       timeout, radio buttons for booleans etc.) when server selected
+       * Code cleanups
+       * Misc fixes
+
+03/12/1998 - Pele
+       * Added support for multiple servers (via multiple -s options)
+       * More testing
+       * Started experimenting with status bar for display of various info
+       * Got rid of many warning and error messages generate by gtk
+       * Added a new icon for objectclass=alias;
+       * Display of some ldap options aquired with ldap_get_option when
+       server selected.
+       * Traversing set to only 1 subtree (then 1 by 1);
+       * Started experimenting with a progress bar for traversal
+       (so users don't get bored while waiting for subtrees to be aquired and
+       constructed)
+
+02/12/1998 - Pele
+       * Added Gtk_LdapTree class
+       * Added utils (with debug only)
+       * "Smart" traversing of ldap tree (only 2-deep, then add 2 subtrees as
+       the tree gets expanded)
+       * Lots of updates and bug-fixes
+
+29/11/1998 - Pele
+       * Added Gtk_LdapServer class
+       * Started using cn=config, ldap_get_option (not sure about get_option
+       though, cn=config looks much nicer for the future-proofing)
+       * Can traverse, display and serve two (or possibly/hopefully) more
+       databases on the local machine - remote machines also possible - 
+       need to use "-s hostname"
+       * The program needs the "-s" switch! Without it it won't run (temporary
+       "feature")
+
+28/11/1998 - Pele
+       * Fixes, enhancements, started using ldap utility api
+       * It now traverses the whole tree at startup, not sure if it's smart
+       but I did it because of something that has no relevance to network
+       traffic
+
+27/11/1998 - Pele
+       * Added viewports, both sides now scroll automatically
+       * Brought back the "cache" stuff, now data gets reused if it's allready
+       available without redundant searches/listings.
+       * Editing pixmaps by hand is so much, er, fun!
+       * Miniscule fixes
+
+26/11/1998 - Pele
+       * Added nice icons in the browser pane - looks decent now.
+       * Fixed scrolling in the data (right) pane - now scrolls if there is
+       a long tab
+       * removed class My_Scroller
+       * removed file Gtk_LdapItem.cc (useless)
+       * commented-out the part where data gets reused instead of re-querying
+       the server, stupid I know, but for the time being if resolves some
+       problems with replacement of right pane.
+       * Misc. fixes
+
+26/11/1998 - Pele
+       * First appearance of ChangeLog
+       * Fixed removal of scrolled window on the right hand side
+         thus making gtk-tool a viable project to be worked on
+       * added command-line parameter parsing - now accepts
+         -s for server, -p for port, -b for baseDN
diff --git a/contrib/gtk-tool/Gtk_LdapServer.cc b/contrib/gtk-tool/Gtk_LdapServer.cc
new file mode 100644 (file)
index 0000000..8bb7480
--- /dev/null
@@ -0,0 +1,446 @@
+#include "Gtk_LdapServer.h"
+#include <gtk--/base.h>
+
+Gtk_LdapServer::Gtk_LdapServer() : Gtk_TreeItem() {
+       this->hostname = NULL;
+       this->par = NULL;
+       this->base_dn = NULL;
+       this->port = 0;
+}
+
+Gtk_LdapServer::Gtk_LdapServer(My_Window *w, char *h, int p) : Gtk_TreeItem() {
+       char *s, *s2;
+       this->par = w;
+       this->hostname = h;
+       this->port = p;
+       this->notebook = NULL;
+       debug("%s %i\n", this->hostname, this->port);
+       this->setType(1);
+       this->getConfig();
+}
+
+Gtk_LdapServer::Gtk_LdapServer(GtkTreeItem *t) : Gtk_TreeItem(t) {
+}
+
+Gtk_LdapServer::~Gtk_LdapServer() {
+       debug("Bye\n");
+       delete this;
+}
+
+void Gtk_LdapServer::setType(int t) {
+       debug("Gtk_LdapServer::setType(%i)\n", t);
+       Gtk_Pixmap *xpm_icon;
+       Gtk_Label *label;
+       char *c = NULL;
+       if (this->get_child() != NULL) this->remove();
+       xpm_label = new Gtk_HBox();
+       debug(this->hostname);
+       if (strcasecmp(this->hostname,"localhost") == 0)
+               xpm_icon=new Gtk_Pixmap(local_server);
+       else xpm_icon=new Gtk_Pixmap(remote_server);
+//     sprintf(c, "%s:%i", this->hostname, this->port);
+//     printf("%s\n", c);
+       label = new Gtk_Label(this->hostname);
+       xpm_label->pack_start(*xpm_icon, false, false, 1);
+       xpm_label->pack_start(*label, false, false, 1);
+       if (this->get_child() == NULL) this->add(*xpm_label);
+       this->show_all();
+}
+
+int Gtk_LdapServer::showDetails() {
+       debug("Gtk_LdapServer::showDetails()\n");
+       if (this->notebook == NULL) this->getOptions();
+       if (this->notebook != NULL) {
+               debug("Have a notebook here");
+               if (par->viewport2->get_child() != NULL) {
+                       debug(" and viewport has children");
+                       par->viewport2->remove();
+                       debug(" which have been removed\n");
+               }
+               else debug(" and viewport without children\n");
+               par->viewport2->add(*this->notebook);
+       }
+       this->show_all();
+       debug("done\n");
+       return 0;
+}
+
+int Gtk_LdapServer::getMonitor() {
+       debug("Gtk_LdapServer::getMonitor()\n");
+       int error, entriesCount;
+       LDAPMessage *entry, *result_identifier;
+       BerElement *ber;
+       char *attribute, **t;
+
+       if ((this->ld = ldap_open(this->hostname, this->port)) == NULL) {
+               perror("connection");
+       }
+
+       error = ldap_search_s(this->ld, "cn=monitor", LDAP_SCOPE_BASE, "objectclass=*", NULL, 0, &result_identifier);   
+       entriesCount = ldap_count_entries(this->ld, result_identifier);
+       if (entriesCount == 0) {
+               return 0;
+       }
+
+       debug("%i tree(s)\n", entriesCount);
+       for (entry = ldap_first_entry(this->ld, result_identifier); entry != NULL; entry = ldap_next_entry(this->ld, result_identifier)) {
+               for (attribute = ldap_first_attribute(this->ld, entry, &ber); attribute != NULL; attribute = ldap_next_attribute(this->ld, entry, ber)) {
+                       debug("Attrib: %s\n", attribute);
+                       if (strcasecmp(attribute, "database") == 0) {
+                               debug("have database here\n");
+                               this->databases = NULL;
+                               t = ldap_get_values(this->ld, entry, attribute);
+                               for (int i=0; i<ldap_count_values(t); i++) {
+                                       this->databases = g_list_append(this->databases, strdup(t[i]));
+                               }
+                               ldap_value_free(t);
+                               debug("databases loaded\n");
+                               GList *t;
+                               for (int i=0;i>g_list_length(this->databases);i++) {
+                                       t = g_list_nth(this->databases, i);
+                                       debug("database(%i) %s\n", i, (char*) t->data);
+                               }       
+                       }
+               }
+               debug("entry done\n");
+       }
+       return entriesCount;
+}
+
+int Gtk_LdapServer::getConfig() {
+       debug("Gtk_LdapServer::getConfig()\n");
+       int error, entriesCount;
+       LDAPMessage *entry, *result_identifier;
+       BerElement *ber;
+       char *attribute, **t;
+
+       if ((this->ld = ldap_open(this->hostname, this->port)) == NULL) {
+               perror("connection");
+       }
+
+       error = ldap_search_s(this->ld, "cn=config", LDAP_SCOPE_BASE, "objectclass=*", NULL, 0, &result_identifier);    
+       entriesCount = ldap_count_entries(this->ld, result_identifier);
+       if (entriesCount == 0) {
+               return 0;
+       }
+
+//     debug("%i tree(s)\n", entriesCount);
+       for (entry = ldap_first_entry(this->ld, result_identifier); entry != NULL; entry = ldap_next_entry(this->ld, result_identifier)) {
+               for (attribute = ldap_first_attribute(this->ld, entry, &ber); attribute != NULL; attribute = ldap_next_attribute(this->ld, entry, ber)) {
+                       debug("Attrib: %s\n", attribute);
+                       if (strcasecmp(attribute, "database") == 0) {
+                               debug("have database here\n");
+                               this->databases = NULL;
+                               t = ldap_get_values(this->ld, entry, attribute);
+                               for (int i=0; i<ldap_count_values(t); i++) {
+                                       this->databases = g_list_append(this->databases, strdup(t[i]));
+                               }
+                       this->databases = g_list_append(this->databases, "ldbm : cn=config");
+                       this->databases = g_list_append(this->databases, "ldbm : cn=monitor");
+                       this->databases = g_list_append(this->databases, "ldbm : cn=schema");
+                               ldap_value_free(t);
+                               debug("databases loaded\n");
+                               GList *t;
+                               for (int i=0;i<g_list_length(this->databases);i++) {
+                                       t = g_list_nth(this->databases, i);
+                                       debug("database(%i) %s\n", i, (char*) t->data);
+                               }       
+                       }
+               }
+               debug("entry done\n");
+       }
+       return entriesCount;
+}
+
+#ifndef LDAP_GET_OPT /* a temporary fix for usability with (old) U-MICH api */
+char* Gtk_LdapServer::getOptDescription(int option) {
+       debug("Gtk_LdapServer::getOptDescription(%i) ", option);
+       char *c;
+       switch (option) {
+               case LDAP_OPT_API_INFO: c = "API info"; break;
+               case LDAP_OPT_CLIENT_CONTROLS: c = "Client controls"; break;
+               case LDAP_OPT_DEREF: c = "Dereference"; break;
+               case LDAP_OPT_DESC: c = "Description"; break;
+               case LDAP_OPT_DNS: c = "DNS Lookup"; break;
+               case LDAP_OPT_ERROR_NUMBER: c = "Error number"; break;
+               case LDAP_OPT_ERROR_STRING: c = "Error string"; break;
+               case LDAP_OPT_SIZELIMIT: c = "Size limit"; break;
+               case LDAP_OPT_TIMELIMIT: c = "Time limit"; break;
+               case LDAP_OPT_REFERRALS: c = "Referrals"; break;
+               case LDAP_OPT_RESTART: c = "Started"; break;
+               case LDAP_OPT_PROTOCOL_VERSION: c = "Protocol version"; break;
+               case LDAP_OPT_HOST_NAME: c = "Host name"; break;
+               case LDAP_OPT_SERVER_CONTROLS: c = "Server controls"; break;
+               default: c = "No description"; break;
+       }
+       debug("%s\n", c);
+       return c;
+}
+
+int Gtk_LdapServer::getOptType(int option) {
+       debug("Gtk_LdapServer::getOptType(%i) ", option);
+       /* types:
+        * 0 = int, 1 = string, 2 = boolean,
+        * 3 = range, 4 = LDAPAPIInfo, 5 = unknown
+        */
+       int type;
+       switch(option) {
+               /* ints */
+               case LDAP_OPT_DEREF:
+               case LDAP_OPT_DESC:
+               case LDAP_OPT_ERROR_NUMBER:
+               case LDAP_OPT_PROTOCOL_VERSION: type = 0; break;
+               /* strings */
+               case LDAP_OPT_ERROR_STRING:
+               case LDAP_OPT_HOST_NAME: type = 1; break;
+               /* bools */
+               case LDAP_OPT_REFERRALS:
+               case LDAP_OPT_DNS:
+               case LDAP_OPT_RESTART: type = 2; break;
+               /* range */
+               case LDAP_OPT_SIZELIMIT:        
+               case LDAP_OPT_TIMELIMIT: type = 3; break;
+               /* api */
+               case LDAP_OPT_API_INFO: type = 4; break;
+               /* unknowns */
+               case LDAP_OPT_SERVER_CONTROLS:
+               case LDAP_OPT_CLIENT_CONTROLS:
+               default: type = 5; break;
+       }
+       debug("%i\n", type);
+       return type;
+}
+#endif /* LDAP_GET_OPT */
+
+int Gtk_LdapServer::getOptions() {
+       debug("Gtk_LdapServer::getOptions()\n");
+       if (this->notebook != NULL) return 0;
+#ifdef LDAP_GET_OPT /* a temporary fix for usability with (old) U-MICH api */
+       Gtk_Label *label;
+       label = new Gtk_Label("This tool has been compiled with (old) U-MICH API (no LDAP_GET_OPT)\nCompile with the latest -devel (from OpenLDAP cvs tree)\nto get some nice options here");
+       this->notebook = new Gtk_Frame("LDAP Options");
+       this->notebook->add(*label);
+       //label->show();
+       //this->notebook->show();
+       this->notebook->show_all();
+       return 0;
+#else
+       LDAPAPIInfo api;
+       Gtk_HBox *hbox, *mini_hbox;
+       Gtk_VBox *vbox, *mini_vbox;
+       Gtk_Table *table;
+       Gtk_Label *label;       
+       Gtk_RadioButton *radio1, *radio2;
+       Gtk_HScale *scale;
+       Gtk_Adjustment *adjustment;
+       char *description = NULL, *s_value = NULL;
+//     int i_value;
+       string label_string;
+
+       int things[10] = {
+               LDAP_OPT_API_INFO,
+               LDAP_OPT_CLIENT_CONTROLS,
+       //      LDAP_OPT_DESC,
+       //      LDAP_OPT_DEREF,
+               LDAP_OPT_DNS,
+       //      LDAP_OPT_ERROR_NUMBER,
+       //      LDAP_OPT_ERROR_STRING,
+               LDAP_OPT_HOST_NAME,
+               LDAP_OPT_PROTOCOL_VERSION,
+               LDAP_OPT_REFERRALS,
+               LDAP_OPT_RESTART,
+               LDAP_OPT_SERVER_CONTROLS,
+               LDAP_OPT_SIZELIMIT,
+               LDAP_OPT_TIMELIMIT
+       };
+
+/*     if (GTK_TREE_ITEM(this->gtkobj())->subtree == NULL) {
+               this->getSubtree();
+       } */
+
+//     vbox = new Gtk_VBox();
+       table = new Gtk_Table(10, 1, TRUE);
+
+       for (int i=0; i<10; i++) {
+               int i_value;
+       //      debug("%i\n", i);
+               hbox = new Gtk_HBox(TRUE, 2);
+               hbox->set_border_width(2);
+               description = this->getOptDescription(things[i]);
+               label = new Gtk_Label(description);
+               label->set_justify(GTK_JUSTIFY_LEFT);
+               label->set_alignment(0, 0);
+               hbox->pack_start(*label);
+               label->show();
+               switch (this->getOptType(things[i])) {
+                       case 0:
+                               ldap_get_option(this->ld, things[i], &i_value);
+                               debug("%s value %d\n", description, i_value);
+                               sprintf(s_value, "%d", i_value);
+                               label = new Gtk_Label(s_value);
+                               label->set_justify(GTK_JUSTIFY_LEFT);
+                               label->set_alignment(0, 0);
+                               hbox->pack_end(*label);
+                               label->show();
+                               break;
+                       case 1:
+                               ldap_get_option(this->ld, things[i], &s_value);
+                               label = new Gtk_Label(s_value);
+                               label->set_justify(GTK_JUSTIFY_LEFT);
+                               label->set_alignment(0, 0);
+                               hbox->pack_end(*label);
+                               label->show();
+                               break;
+                       case 2:
+                               ldap_get_option(this->ld, things[i], &i_value);
+                               radio1 = new Gtk_RadioButton("Enabled");
+                               radio2 = new Gtk_RadioButton("Disabled");
+                               radio2->set_group(radio1->group());
+                               if (i_value == 1) radio1->set_active(true);
+                               else radio2->set_active(true);
+                               mini_hbox = new Gtk_HBox(FALSE, 2);
+                               mini_hbox->set_border_width(2);
+                               mini_hbox->pack_start(*radio1);
+                               //radio1->show();
+                               mini_hbox->pack_end(*radio2);
+                               //radio2->show();
+                               hbox->pack_end(*mini_hbox);
+                               //mini_hbox->show();
+                               break;
+                       case 3:
+                               ldap_get_option(this->ld, things[i], &i_value);
+                               debug("i_value: %s\n", i_value);
+                               adjustment = new Gtk_Adjustment(i_value, 0.0, 20.0, 1.0, 1.0, 0.0);
+                               scale = new Gtk_HScale(*adjustment);
+                               scale->set_update_policy(GTK_UPDATE_CONTINUOUS);
+                               scale->set_value_pos(GTK_POS_TOP);
+                               scale->set_digits(0);
+                               scale->set_draw_value(true);
+                               hbox->pack_end(*scale);
+                               //scale->show();
+                               break;
+                       case 4:
+#ifdef LDAP_API_INFO_VERSION
+       api.ldapai_info_version = LDAP_API_INFO_VERSION;
+#else
+       api.ldapai_info_version = 1;
+#endif
+                               if (ldap_get_option(this->ld, things[i], &api) != LDAP_SUCCESS) {
+                                       perror(this->getOptDescription(things[i]));
+                                       break;
+                               }
+                               s_value = api.ldapai_vendor_name;
+                               label = new Gtk_Label(s_value);
+                               label->set_justify(GTK_JUSTIFY_LEFT);
+                               label->set_alignment(0, 0);
+                               hbox->pack_end(*label);
+                               //label->show();
+                               break;
+                       default:
+                               label = new Gtk_Label("Not implemented (yet)");
+                               label->set_justify(GTK_JUSTIFY_LEFT);
+                               label->set_alignment(0, 0);
+                               hbox->pack_end(*label);
+                               //label->show();
+                               break;
+               }
+       //      hbox->pack_end(*label);
+       //      label->show();
+               table->attach(*hbox, 0, 1, i, i+1);
+               hbox->show();
+       }
+       table->set_border_width(2);
+       this->notebook = new Gtk_Frame("LDAP Options");
+       this->notebook->add(*table);
+       //table->show();
+       this->notebook->show_all();
+       return 0;
+#endif /* LDAP_GET_OPT */
+}
+
+Gtk_Tree* Gtk_LdapServer::getSubtree() {
+       debug("Gtk_LdapServer::getSubtree()\n");
+       Gtk_LdapTree *tree, *subtree;
+       Gtk_LdapTreeItem *treeitem;
+       int entries;
+
+       debug("this->hostname=%s\n", this->hostname);
+       debug("this->port=%i", this->port);
+
+       char *c;
+       char *tok;
+
+       int len = g_list_length(this->databases);
+       debug("this->databases->length()=%i\n", len);
+
+       tree = new Gtk_LdapTree();
+       for (int i=0; i<len; i++) {
+               GList *t = g_list_nth(this->databases, i);
+               tok = strdup((char*)t->data);
+               tok = strtok(tok, ":");
+       //      c = strtok(NULL, " ");
+               c = strtok(NULL, "\0");
+               debug("database %i %s\n", i, c);
+               treeitem = new Gtk_LdapTreeItem(c, this->par, this->ld);
+               subtree = treeitem->getSubtree(this->ld, 1);
+               debug("inserting %s into %s\n", treeitem->rdn, this->hostname);
+               tree->append(*treeitem);
+               if (subtree != NULL) treeitem->set_subtree(*subtree);
+               treeitem->show();
+       //      treeitem->setDnd();
+       //      tree->show();
+       }
+//     this->set_subtree(*tree);
+       debug("getSubtree() done\n");
+       return tree;
+}
+/*
+void Gtk_LdapServer::show_impl() {
+       debug("%s showed\n", this->hostname);
+       BaseClassType *sig=static_cast<BaseClassType *>(get_parent_class());
+       if (!sig->show) return;
+       sig->show(gtkobj());
+//     Gtk_c_signals_Item *sig=(Gtk_c_signals_Item *)internal_getsignalbase();
+//     sig->show(GTK_WIDGET(gtkobj()));
+}
+*/
+void Gtk_LdapServer::select_impl() {
+       debug("%s selected\n", this->hostname);
+//     Gtk_c_signals_Item *sig=(Gtk_c_signals_Item *)internal_getsignalbase();
+//     if (!sig->select) return;
+       this->showDetails();
+//     sig->select(GTK_ITEM(gtkobj()));
+       Gtk_TreeItem::select_impl();
+}
+
+void Gtk_LdapServer::collapse_impl() {
+       debug("%s collapsed\n", this->hostname);
+//     Gtk_c_signals_TreeItem *sig=(Gtk_c_signals_TreeItem *)internal_getsignalbase();
+//     if (!sig->collapse) return;
+//     sig->collapse(GTK_TREE_ITEM(gtkobj()));
+//     gtk_widget_hide(GTK_WIDGET(GTK_TREE(GTK_TREE_ITEM (this->gtkobj())->subtree)));
+       Gtk_TreeItem::collapse_impl();
+}
+
+void Gtk_LdapServer::expand_impl() {
+       debug("%s expanded\n", this->hostname);
+       Gtk_TreeItem::expand_impl();
+//     BaseClassType *sig=static_cast<BaseClassType *>(get_parent_class());
+//     if (!sig->expand)
+//             { return; }
+//     sig->expand(gtkobj());
+//     Gtk_c_signals_TreeItem *sig=(Gtk_c_signals_TreeItem *)internal_getsignalbase();
+//     if (!sig->expand) return;
+//     sig->expand(GTK_TREE_ITEM(gtkobj()));
+//     Gtk_Tree *t;
+//     t = new Gtk_Tree(GTK_TREE(GTK_TREE_ITEM(this->gtkobj())->subtree));
+//     bool vis = t->visible();
+//     if (vis == false) {
+//             gtk_widget_show(GTK_WIDGET(GTK_TREE(GTK_TREE_ITEM (this->gtkobj())->subtree)));
+//             cout << this->dn << " expanded" << endl;
+//     }
+//     else {
+//             gtk_widget_hide(GTK_WIDGET(GTK_TREE(GTK_TREE_ITEM (this->gtkobj())->subtree)));
+//             cout << this->dn << " collapsed" << endl;
+//     }
+}
diff --git a/contrib/gtk-tool/Gtk_LdapServer.h b/contrib/gtk-tool/Gtk_LdapServer.h
new file mode 100644 (file)
index 0000000..21466a0
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef GTK_LDAPSERVER_H
+#define GTK_LDAPSERVER_H
+#include "gtk.h"
+#include "utils.h"
+#include <My_Window.h>
+#include <Gtk_LdapTree.h>
+#include <Gtk_LdapTreeItem.h>
+#include <lber.h>
+#include <ldap.h>
+#include "icons/local_server.h"
+#include "icons/remote_server.h"
+
+#define LOCAL_SERVER 1
+#define REMOTE_SERVER 2
+
+class My_Window;
+
+class Gtk_LdapServer : public Gtk_TreeItem {
+public:
+       char *dn;
+       char *hostname;
+       LDAPMessage **thing;
+       LDAP *ld;
+       char *host;
+       char *base_dn;
+       int c, port;
+       My_Window *par;
+//     Gtk_Notebook *notebook;
+       Gtk_Frame *notebook;
+       Gtk_HBox *xpm_label;
+//     Gtk_Tree *subtree;
+       Gtk_Menu *popup;
+       GList *databases;
+       Gtk_LdapServer();
+       Gtk_LdapServer(My_Window *w, char *c, int p);
+       Gtk_LdapServer(GtkTreeItem *t);
+       ~Gtk_LdapServer();
+       void setType(int t);
+       int getMonitor();
+       int getConfig();
+       Gtk_Tree* getSubtree();
+#ifndef LDAP_GET_OPT
+       char* getOptDescription(int option);
+       int getOptType(int option);
+#endif
+       int getOptions();
+       int showDetails();
+//     void show_impl();
+       void select_impl();
+       void collapse_impl();
+       void expand_impl();
+};
+#endif
diff --git a/contrib/gtk-tool/Gtk_LdapTree.cc b/contrib/gtk-tool/Gtk_LdapTree.cc
new file mode 100644 (file)
index 0000000..3908621
--- /dev/null
@@ -0,0 +1,26 @@
+#include <Gtk_LdapTree.h>
+
+void Gtk_LdapTree::show_impl() {
+       debug("Gtk_LdapTree::show_impl()\n");
+       Gtk_LdapTree *tree;
+       Gtk_LdapTreeItem *item = NULL;
+       Gtk_LdapTree::ItemList &items = this->tree();
+       Gtk_LdapTree::ItemList::iterator i; // = items.begin();
+       debug("iterator\n");
+       for (i=items.begin(); i!=items.end();++i) {
+//     while (i!=items.end()) {
+               item = (Gtk_LdapTreeItem *)(*i);
+               debug("new item\n");
+               debug("#%s#\n", item->dn);
+               if (item->get_subtree() == NULL) {
+                       debug("ding!\n");
+                       tree = item->getSubtree(item->ld, 1);
+                       if (tree != NULL) { 
+                               item->set_subtree(*tree);
+                       }
+                       item->setDnd();
+               }
+       }
+       debug("done\n");
+       Gtk_Tree::show_impl();
+}
diff --git a/contrib/gtk-tool/Gtk_LdapTreeItem.cc b/contrib/gtk-tool/Gtk_LdapTreeItem.cc
new file mode 100644 (file)
index 0000000..0216a65
--- /dev/null
@@ -0,0 +1,376 @@
+#include "Gtk_LdapTreeItem.h"
+
+Gtk_LdapTreeItem::Gtk_LdapTreeItem() : Gtk_TreeItem() {
+       this->objectClass = NULL;
+}
+
+Gtk_LdapTreeItem::Gtk_LdapTreeItem(char *c, My_Window *w, LDAP *ld) : Gtk_TreeItem() {
+       debug("Gtk_LdapTreeItem::Gtk_LdapTreeItem(%s)\n", c);
+       char **s;
+       this->dn = c;
+       s = ldap_explode_dn(this->dn, 1);
+       this->rdn = g_strdup_printf("%s", s[0]);
+       this->par = w;
+       this->ld = ld;
+       this->objectClass = NULL;
+       this->getDetails();
+       this->createPopupMenu();
+}
+
+void Gtk_LdapTreeItem::setDnd() {
+       debug("Gtk_LdapTreeItem::setDnd()\n");
+       this->set_events(get_events()|GDK_ALL_EVENTS_MASK);
+       this->drag_dest_set(GTK_DEST_DEFAULT_ALL, target_table, n_targets, static_cast <GdkDragAction> (GDK_ACTION_COPY|GDK_ACTION_MOVE));
+       this->drag_data_received.connect(slot(this, &(Gtk_LdapTreeItem::item_drag_data_received)));
+       this->drag_drop.connect(slot(this,&Gtk_LdapTreeItem::target_drag_drop));
+       this->drag_source_set(static_cast<GdkModifierType>(GDK_BUTTON1_MASK|GDK_BUTTON3_MASK), target_table, n_targets, static_cast<GdkDragAction>(GDK_ACTION_COPY|GDK_ACTION_MOVE));
+       gtk_drag_source_set(GTK_WIDGET(this->gtkobj()), static_cast<GdkModifierType>(GDK_BUTTON1_MASK|GDK_BUTTON3_MASK), target_table, n_targets, static_cast<GdkDragAction>(GDK_ACTION_COPY|GDK_ACTION_MOVE));
+       this->drag_data_get.connect(slot(this, &Gtk_LdapTreeItem::source_drag_data_get));
+       this->drag_data_delete.connect(slot(this,&Gtk_LdapTreeItem::source_drag_data_delete));
+       this->drag_leave.connect(slot(this,&Gtk_LdapTreeItem::target_drag_leave));
+
+}
+
+Gtk_LdapTreeItem::Gtk_LdapTreeItem(GtkTreeItem *t) : Gtk_TreeItem(t) {
+}
+
+Gtk_LdapTreeItem::~Gtk_LdapTreeItem() {
+       cout << "Bye" << endl;
+       delete this;
+}
+
+Gtk_LdapTree* Gtk_LdapTreeItem::getSubtree(LDAP *ld, int counter) {
+       debug("Gtk_LdapTreeItem::getSubtree(%s)\n", this->dn);
+       if (counter <= 0) return NULL;
+       if (this->gtkobj()->subtree != NULL) {
+               //return (Gtk_LdapTree *)GTK_TREE(this->gtkobj()->subtree);
+               debug("This item has a subtree\n");
+               return (Gtk_LdapTree *)this->get_subtree(); //gtkobj()->subtree);
+       }
+       counter--;
+       Gtk_LdapTree *subtree = NULL, *tree = NULL;
+       Gtk_LdapTreeItem *subtreeitem = NULL;
+       LDAPMessage *r_i = NULL, *entry = NULL;
+       gchar *c;
+       char **s;
+       int entriesCount = 0, error;
+
+       this->ld = ld;
+       if (this->dn == "cn=config" || this->dn == "cn=monitor" || this->dn == "cn=schema") error = ldap_search_s(this->ld, this->dn, LDAP_SCOPE_BASE, "objectclass=*", NULL, 0, &r_i);
+       else {
+               if (strcasecmp(this->objectClass,"alias") == 0) error = ldap_search_s(this->ld, this->getAttribute("aliasedobjectname"), LDAP_SCOPE_ONELEVEL, "objectclass=*", NULL, 0, &r_i);
+               else error = ldap_search_s(this->ld, this->dn, LDAP_SCOPE_ONELEVEL, "objectclass=*", NULL, 0, &r_i);
+       }
+//     printf("%s\n", ldap_err2string(error));
+       entriesCount = ldap_count_entries(this->ld, r_i);
+       debug("%i results\n", entriesCount);
+       if (entriesCount != 0) { 
+               tree = new Gtk_LdapTree();
+       //      this->set_subtree(*tree);
+               tree->set_selection_mode(GTK_SELECTION_BROWSE);
+               tree->set_view_mode(GTK_TREE_VIEW_ITEM);
+               tree->set_view_lines(false);
+               entry = ldap_first_entry(this->ld, r_i);
+       //      float i = 1;
+               gfloat percent = 100/entriesCount;
+               debug("percent is %f\n", percent);
+       //      this->par->progress.set_percentage(percent/100);
+       //      this->par->progress.show();
+               while (entry != NULL) {
+                       subtreeitem = new Gtk_LdapTreeItem(ldap_get_dn(this->ld, entry), this->par, this->ld);
+                       debug("inserting %s into %s\n",subtreeitem->rdn,this->rdn);
+                       tree->append(*subtreeitem);
+                       subtree = subtreeitem->getSubtree(this->ld, counter);
+                       subtreeitem->show();
+                       if (subtree != NULL) subtreeitem->set_subtree(*subtree);
+               //      subtreeitem->setDnd();
+                       debug("done\n");
+                       entry = ldap_next_entry(this->ld, entry);
+               //      gfloat pvalue = (i*percent)/100;
+               //      cout << pvalue << " %" << endl;
+               //      this->par->progress.update(pvalue);
+               //      this->par->progress.show();
+               //      i++;
+               }
+       //      this->set_subtree(*tree);
+       //      this->par->progress.update(0);
+       //      this->par->progress->show();
+       }
+//     this->getDetails();
+       debug("done\n");
+       return tree;
+}
+
+void Gtk_LdapTreeItem::setType(int t) {
+       debug("Gtk_LdapTreeItem::setType(%s)\n", this->objectClass);
+       Gtk_Pixmap *xpm_icon;
+       Gtk_Label *label;
+       if (this->get_child() != NULL) {
+               debug("got a child here");
+               //xpm_label = new Gtk_HBox(this->get_child());
+               this->remove();
+               /*
+               //xpm_label = new Gtk_HBox(*GTK_HBOX(this->get_child()->gtkobj()));
+               xpm_label = new Gtk_HBox(this->get_child()); //->gtkobj());
+               //xpm_label->remove_c(xpm_label->children().nth_data(0));
+               Gtk_HBox::BoxList &list = xpm_label->children();
+               Gtk_HBox::BoxList::iterator i = list.begin();
+               xpm_label->remove(*i);
+               //xpm_label->remove_c(xpm_label->children().nth_data(0));
+               xpm_label->remove(*xpm_label->children().begin());
+               */
+       }
+       xpm_label = new Gtk_HBox();
+       if (strcasecmp(this->objectClass,"organization") == 0)
+               //xpm_icon=new Gtk_Pixmap(*xpm_label, root_node);
+               xpm_icon=new Gtk_Pixmap(root_node);
+       else if (strcasecmp(this->objectClass,"organizationalunit") == 0)
+               //xpm_icon=new Gtk_Pixmap(*xpm_label, branch_node);
+               xpm_icon=new Gtk_Pixmap(branch_node);
+       else if (strcasecmp(this->objectClass,"person") == 0)
+               //xpm_icon=new Gtk_Pixmap(*xpm_label, leaf_node);
+               xpm_icon=new Gtk_Pixmap(leaf_node);
+       else if (strcasecmp(this->objectClass,"alias") == 0)
+               //xpm_icon=new Gtk_Pixmap(*xpm_label, alias_node);
+               xpm_icon=new Gtk_Pixmap(alias_node);
+       else if (strcasecmp(this->objectClass,"rfc822mailgroup") == 0)
+               //xpm_icon=new Gtk_Pixmap(*xpm_label, rfc822mailgroup_node);
+               xpm_icon=new Gtk_Pixmap(rfc822mailgroup_node);
+       else if (strcasecmp(this->objectClass,"LDAPsubentry") == 0)
+               xpm_icon=new Gtk_Pixmap(monitor);
+       else //xpm_icon=new Gtk_Pixmap(*xpm_label, general_node);
+               xpm_icon=new Gtk_Pixmap(general_node);
+       label = new Gtk_Label(this->rdn);
+       xpm_label->pack_start(*xpm_icon, false, false, 1);
+       xpm_label->pack_start(*label, false, false, 1);
+       if (this->get_child() == NULL) {
+               debug("no children - GREAT!!");
+               this->add(*xpm_label);
+       }
+       //label->show();
+       //xpm_icon->show();
+       //xpm_label->show();
+       show_all();
+}
+
+int Gtk_LdapTreeItem::showDetails() {
+       debug("Gtk_LdapTreeItem::showDetails()\n");
+       if (this->notebook == NULL) this->getDetails();
+       if (this->notebook != NULL) {
+               debug("Have a notebook here");
+               if (par->viewport2->get_child() != NULL) {
+                       debug(" and the viewport has children");
+                       //par->viewport2->remove(par->viewport2->get_child());
+                       par->viewport2->remove();
+                       debug(" which have been removed");
+               }
+               else debug(" and viewport has no children");
+               par->viewport2->add(*this->notebook);
+               this->notebook->show();
+               par->viewport2->show();
+               return 0;
+       }
+       else debug("No notebook and no details");
+       return 0;
+}
+
+char* Gtk_LdapTreeItem::getAttribute(char *c) {
+       int entriesCount, error;
+       BerElement *ber;
+       LDAPMessage *entry;
+       char *attribute, **values;
+       error = ldap_search_s(this->ld, this->dn, LDAP_SCOPE_BASE, "objectclass=*", NULL, 0, &this->result_identifier);
+       entriesCount = ldap_count_entries(this->ld, this->result_identifier);
+       if (entriesCount == 0) return 0;
+       for (entry = ldap_first_entry(ld, result_identifier); entry != NULL; entry = ldap_next_entry(ld, result_identifier)) {
+               for (attribute = ldap_first_attribute(ld, entry, &ber); attribute != NULL; attribute = ldap_next_attribute(ld, entry, ber)) {
+                       values = ldap_get_values(ld, entry, attribute);
+                       if (strcasecmp(attribute, "aliasedobjectname") == 0) {
+                               this->aliasedObjectName = strdup(values[0]);
+                       }
+               }
+       }
+       return this->aliasedObjectName;
+}
+
+int Gtk_LdapTreeItem::getDetails() {
+       debug("Gtk_LdapTreeItem::getDetails()\n");
+       int error, entriesCount;
+       BerElement *ber;
+       LDAPMessage *entry;
+       char *attribute, **values;
+       char attrib[32];
+       Gtk_CList *table;
+       Gtk_Label *label;
+       GList *child_list;
+       Gtk_Viewport *viewport;
+       error = ldap_search_s(this->ld, this->dn, LDAP_SCOPE_BASE, "objectclass=*", NULL, 0, &this->result_identifier);
+       entriesCount = ldap_count_entries(this->ld, this->result_identifier);
+       if (entriesCount == 0) return 0;
+       this->notebook = new Gtk_Notebook();
+       this->notebook->set_tab_pos(GTK_POS_LEFT);
+       const gchar *titles[] = { "values" };
+       
+       for (entry = ldap_first_entry(ld, result_identifier); entry != NULL; entry = ldap_next_entry(ld, result_identifier)) {
+               for (attribute = ldap_first_attribute(ld, entry, &ber); attribute != NULL; attribute = ldap_next_attribute(ld, entry, ber)) {
+                       values = ldap_get_values(ld, entry, attribute);
+                       if (strcasecmp(attribute, "objectclass") == 0) {
+                       //      debug("processing objectclass\n");
+                               if (strcasecmp(values[0],"top") == 0)
+                                       this->objectClass = strdup(values[1]);
+                               else this->objectClass = strdup(values[0]);
+                       }
+                       table = new Gtk_CList(1, titles);
+                       for (int i=0; i<ldap_count_values(values); i++) {
+                       //      debug("%i:%s\n",i, values[i]);
+                               const gchar *t[] = { values[i] };
+                               table->append(t);
+                       }
+                       ldap_value_free(values);
+                       sprintf(attrib, "%s", attribute);
+                       label = new Gtk_Label(attrib);
+                       label->set_alignment(0, 0);
+                       label->set_justify(GTK_JUSTIFY_LEFT);
+                       this->notebook->pages().push_back(Gtk_Notebook_Helpers::TabElem(*table, *label));
+                       table->show();
+                       label->show();
+               }
+       }
+       this->setType(1);
+       debug("done\n");
+       return 0;
+}
+
+void Gtk_LdapTreeItem::createPopupMenu() {
+       debug("Gtk_LdapTreeItem::createPopupMenu()\n");
+       Gtk_MenuItem *item;
+
+       this->menu = new Gtk_Menu();
+       
+       item = new Gtk_MenuItem("Add");
+       this->menu->add(*item);
+       item = new Gtk_MenuItem("Delete");
+       this->menu->add(*item);
+       item = new Gtk_MenuItem();
+       this->menu->add(*item);
+       item = new Gtk_MenuItem("Cut");
+       this->menu->add(*item);
+       item = new Gtk_MenuItem("Copy");
+       this->menu->add(*item);
+       item = new Gtk_MenuItem("Paste");
+       this->menu->add(*item);
+       this->menu->show_all();
+       this->menu->activate();
+}
+/*
+void Gtk_LdapTreeItem::show_impl() {
+       debug("%s showed\n", this->dn);
+//     Gtk_c_signals_Base *sig=(Gtk_c_signals_Base *)internal_getsignalbase();
+//     sig->show(GTK_WIDGET(gtkobj()));
+}
+*/
+/*
+void Gtk_LdapTreeItem::select_impl() {
+       debug("%s selected\n", this->dn);
+       this->showDetails();
+       Gtk_TreeItem::select_impl();
+}
+*/
+
+void Gtk_LdapTreeItem::collapse_impl() {
+       debug("%s collapsed\n", this->dn);
+       Gtk_TreeItem::collapse_impl();
+}
+
+void Gtk_LdapTreeItem::expand_impl() {
+       debug("%s expanded\n",this->dn);
+       Gtk_LdapTreeItem *item;
+       G_List<GtkWidget> *list;
+       Gtk_Tree *tree;
+       Gtk_TreeItem::expand_impl();
+}
+
+void Gtk_LdapTreeItem::click() {
+       debug("%s clicked\n", this->dn);
+}
+
+/*
+gint Gtk_LdapTreeItem::button_press_event_impl(GdkEventButton *p0) {
+       debug("Gtk_LdapTreeItem::button_press_event_impl(%i)\n", p0->button);
+       GdkEventButton *bevent = (GdkEventButton *) p0;
+       if (p0->button == 3) gtk_menu_popup(this->menu->gtkobj(), NULL, NULL, NULL, NULL, bevent->button, bevent->time);
+       Gtk_TreeItem::button_press_event_impl(p0);
+//     Gtk_TreeItem::select_impl();
+}
+*/
+
+void Gtk_LdapTreeItem::item_drag_data_received(GdkDragContext *context,
+                                    gint                x,
+                                    gint                y,
+                                    GtkSelectionData   *data,
+                                    guint               info,
+                                    guint               time) {
+       debug("Gtk_LdapTreeItem::item_drag_data_received\n");
+       Gdk_DragContext gdc(context);
+       if ((data->length >= 0) && (data->format == 8)) {
+               cout << "Received \"" << (gchar *)data->data << "\" in label" << endl;
+               Gtk_Widget::drag_finish(gdc, true, false, time);
+               return;
+       }
+
+       Gtk_Widget::drag_finish(gdc , false, false, time);
+}
+
+gboolean Gtk_LdapTreeItem::target_drag_drop(GdkDragContext *context,
+                            gint x, gint y, guint theTime) {
+       debug("Gtk_LdapTreeItem::target_drag_drop\n");
+       cout << "drop" << endl;
+       have_drag = false;
+
+//     pixmap.set(trashcan_closed, trashcan_closed_mask);
+
+       Gdk_DragContext gdc(context);
+       Gdk_Atom *ga = static_cast <GdkAtom *>(context->targets->data);
+       if (context->targets) {
+               this->drag_get_data(gdc, *ga, theTime);
+               return true;
+       }
+
+       return false;
+}
+
+
+void Gtk_LdapTreeItem::source_drag_data_get(GdkDragContext     *context,
+                                 GtkSelectionData *selection_data,
+                                 guint info, guint32 time) {
+       debug("Gtk_LdapTreeItem::source_drag_data_get\n");
+       if (info == TARGET_ROOTWIN) {
+               cout << "I was dropped on the rootwin" << endl;
+       }
+       else {
+               if ( info == TARGET_URL ) {
+                       gtk_selection_data_set(selection_data,
+                               selection_data->target, 8,
+                               reinterpret_cast < const unsigned char * >
+                               ("file:///home/otaylor/images/weave.png"), 37);
+               }
+               else {
+                       gtk_selection_data_set(selection_data,
+                               selection_data->target, 8,
+                               reinterpret_cast <const unsigned char *>
+                               ("I'm Data!"), 9);
+               }
+       }
+}
+
+void Gtk_LdapTreeItem::source_drag_data_delete(GdkDragContext *context) {
+       debug("Gtk_LdapTreeItem::source_drag_data_delete\n");
+       debug("Delete the data!\n");
+}
+
+void Gtk_LdapTreeItem::target_drag_leave(GdkDragContext *context, guint time) {
+  debug("Gtk_LdapTreeItem::target_drag_leave\n");
+  this->have_drag = false;
+//  pixmap.set(trashcan_closed, trashcan_closed_mask);
+}
+
diff --git a/contrib/gtk-tool/Gtk_LdapTreeItem.h b/contrib/gtk-tool/Gtk_LdapTreeItem.h
new file mode 100644 (file)
index 0000000..fecc277
--- /dev/null
@@ -0,0 +1,83 @@
+#ifndef GTK_LDAPTREEITEM_H
+#define GTK_LDAPTREEITEM_H
+#include "gtk.h"
+#include "utils.h"
+#include <My_Window.h>
+#include <Gtk_LdapTree.h>
+#include <lber.h>
+#include <ldap.h>
+#include "icons/root_node.h"
+#include "icons/branch_node.h"
+#include "icons/leaf_node.h"
+#include "icons/alias_node.h"
+#include "icons/rfc822mailgroup_node.h"
+#include "icons/general_node.h"
+#include "icons/monitor.h"
+
+#define ROOT_NODE 1
+#define BRANCH_NODE 2
+#define LEAF_NODE 3
+
+class My_Window;
+class Gtk_LdapTree;
+
+class Gtk_LdapTreeItem : public Gtk_TreeItem {
+public:
+       char *dn;
+       char *rdn;
+       char *objectClass;
+       char *aliasedObjectName;
+       LDAP *ld;
+       LDAPMessage *result_identifier;
+       My_Window *par;
+       Gtk_Notebook *notebook;
+       Gtk_HBox *xpm_label;
+       Gtk_Menu *menu;
+       enum
+       {
+               TARGET_STRING,
+               TARGET_ROOTWIN,
+               TARGET_URL
+       };
+       bool have_drag;
+
+       //Functions
+       Gtk_LdapTreeItem();
+       Gtk_LdapTreeItem(char *c, My_Window *w, LDAP *ld);
+       Gtk_LdapTreeItem(GtkTreeItem *t);
+       ~Gtk_LdapTreeItem();
+       void setDnd();
+       gchar* getAttribute(char *c);
+       Gtk_LdapTree* getSubtree(LDAP *ld, int i);
+       void setType(int t);
+       int getDetails();
+       void createPopupMenu();
+       int showDetails();
+//     void show_impl();
+//     void select_impl();
+       void collapse_impl();
+       void expand_impl();
+       void click();
+//     gint button_press_event_impl(GdkEventButton *p0);
+       void item_drag_data_received (GdkDragContext *context,
+                               gint x, gint y, GtkSelectionData *data,
+                               guint info, guint32 time);
+       gboolean target_drag_drop ( GdkDragContext *context,
+                               gint x, gint y, guint time);
+
+       void source_drag_data_get(GdkDragContext *context,
+                               GtkSelectionData *selection_data,
+                               guint info, guint32 time);
+       void source_drag_data_delete(GdkDragContext *context);
+       void target_drag_leave(GdkDragContext *context, guint time);
+};
+
+static GtkTargetEntry target_table[] = {
+       { "STRING",     0, Gtk_LdapTreeItem::TARGET_STRING },
+       { "text/plain", 0, Gtk_LdapTreeItem::TARGET_STRING },
+       { "text/uri-list", 0, Gtk_LdapTreeItem::TARGET_URL },
+       { "application/x-rootwin-drop", 0, Gtk_LdapTreeItem::TARGET_ROOTWIN }
+};
+
+static guint n_targets = sizeof(target_table) / sizeof(target_table[0]);
+#endif
diff --git a/contrib/gtk-tool/INSTALL b/contrib/gtk-tool/INSTALL
new file mode 100644 (file)
index 0000000..84a5c59
--- /dev/null
@@ -0,0 +1,13 @@
+Please read this carefully
+
+To copile gtk-tool, although OpenLDAP in itself is a very out-of-the-box 
+straightforward piece of code to compile gtk-tool isn't. You will require following:
+
+       Gtk+1.2.x
+       Gtk--1.1.x 
+
+So, latest gtk stuff and if you successfully compiled and installed all that it should be easy. If you didn't I really hope you can take some comfort in that I have provided you with some snapshots of what the thing actually looks like. I hope in the near future I would be able to provide you with a static binary..next week perhaps..I don't know, I'm looking for a job right now so no promises...
+(I'm no longer looking for a job but the situation with spare time seems even worse - I wish I could do this full-time guys, I really do...)
+
+Pele
+pele@openldap.org
diff --git a/contrib/gtk-tool/Makefile b/contrib/gtk-tool/Makefile
new file mode 100644 (file)
index 0000000..7ac761e
--- /dev/null
@@ -0,0 +1,32 @@
+HOME_LOCATION=$(shell pwd)
+CPLUS= g++
+OPTS=-g #-DDEBUG
+INCLUDES=`gtkmm-config --cflags` -I.
+GTKMMLIBS=`gtkmm-config --libs`
+LDFLAGS=-L/usr/lib -L/usr/X11/lib -L/usr/local/ldap/lib -lldap -llber -L/usr/local/kerberos/lib -lkrb5 -lkrb4 `gtkmm-config --libs`
+LIBS=-lXext -lgtkmm -lX11 -lXt -lXxf86dga
+
+.EXPORT_ALL_VARIABLES:
+
+SOURCES=My_Window.cc Gtk_LdapTree.cc Gtk_LdapTreeItem.cc Gtk_LdapServer.cc utils.cc main.o
+OBJECTS=My_Window.o Gtk_LdapTree.o Gtk_LdapTreeItem.o Gtk_LdapServer.o utils.o main.o
+
+################################################################################
+
+all: main
+main:  $(OBJECTS)
+       $(CPLUS) $(OBJECTS) -o main $(LDFLAGS) $(GTKMMLIBS)
+       exec
+
+main.o: main.cc
+       $(CPLUS) -c $(OPTS) $(INCLUDES) $<
+
+exec:  all
+       chmod a+x main
+       ls -al main
+
+%.o: %.cc %.h
+       $(CPLUS) -c $(OPTS) $(INCLUDES) $<
+
+clean: 
+       rm -f main a.out *.o straced core
diff --git a/contrib/gtk-tool/My_Window.cc b/contrib/gtk-tool/My_Window.cc
new file mode 100644 (file)
index 0000000..ee21e94
--- /dev/null
@@ -0,0 +1,187 @@
+#include <My_Window.h>
+
+My_Window::My_Window(GtkWindowType t) : Gtk_Window(t) {
+       debug("My_Window(t)\n");
+       Gtk_VBox *main_hbox;
+       Gtk_HBox *top_hbox;
+       Gtk_VBox *bottom_hbox;
+       Gtk_Menu *menu, *sub_menu;
+       Gtk_MenuItem *new_menu, *file_menu, *options_menu, *menuitem;
+       Gtk_CheckMenuItem *check_menuitem;
+
+       pane = new Gtk_HPaned();
+       this->scroller = new Gtk_ScrolledWindow();
+       this->viewport = new Gtk_Viewport();
+       this->scroller->set_policy(GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+       this->scroller->add(*this->viewport);
+       pane->add1(*this->scroller);
+       this->scroller->show();
+       this->viewport->show();
+
+       this->scroller2 = new Gtk_ScrolledWindow();
+       this->viewport2 = new Gtk_Viewport();
+       this->scroller2->set_policy(GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+       this->scroller2->add(*this->viewport2);
+       pane->add2(*this->scroller2);   
+       this->scroller2->show();
+       this->viewport2->show();
+
+       top_hbox = new Gtk_HBox();
+
+       menu = new Gtk_Menu();
+
+       sub_menu = new Gtk_Menu();
+       menuitem = new Gtk_MenuItem("Server");
+       menuitem->activate.connect(slot(this,&My_Window::addServer));
+       //connect_to_method(menuitem->activate, this, &addServer);
+       sub_menu->append(*menuitem);
+//     menuitem->show();
+       new_menu = new Gtk_MenuItem("New...");
+       new_menu->set_submenu(*sub_menu);
+//     sub_menu->show();
+       menu->append(*new_menu);
+//     new_menu->show();
+
+       menuitem = new Gtk_MenuItem("Quit");
+       menuitem->activate.connect(Gtk_Main::quit.slot());      
+       menu->append(*menuitem);
+//     menuitem->show();
+       this->menubar = new Gtk_MenuBar();
+       file_menu = new Gtk_MenuItem("File (?)");
+       file_menu->set_submenu(*menu);
+       this->menubar->append(*file_menu);
+//     menu->show();
+
+       menu = new Gtk_Menu();
+       check_menuitem = new Gtk_CheckMenuItem("Show Debug Info");
+       check_menuitem->toggled.connect(slot(this,&My_Window::setDebug));
+       //connect_to_method(check_menuitem->toggled, this, &setDebug);
+       menu->append(*check_menuitem);
+       check_menuitem->show();
+       options_menu = new Gtk_MenuItem("Options");
+       options_menu->set_submenu(*menu);
+       this->menubar->append(*options_menu);
+//     menu->show();
+       
+//     file_menu->show();
+//     options_menu->show();
+
+//     top_hbox->pack_start(*this->menubar, TRUE, TRUE, 1);
+//     this->menubar->show();
+       this->urlfield = new Gtk_Entry();
+       top_hbox->pack_start(*this->urlfield, TRUE, TRUE, 1);
+//     this->urlfield->show();
+       this->display_button = new Gtk_Button("Query Server");
+       this->display_button->clicked.connect(slot(this, &My_Window::getHost));
+       //connect_to_method(this->display_button->clicked, this, &getHost);
+       top_hbox->pack_end(*this->display_button, FALSE, FALSE, 1);
+//     this->display_button->show();
+
+       this->status = new Gtk_Statusbar();
+//     this->progress = new Gtk_ProgressBar();
+//     this->status->add(*progress);
+//     this->progress->show();
+
+       bottom_hbox = new Gtk_VBox();
+       bottom_hbox->pack_start(*pane, TRUE, TRUE, 1);
+       bottom_hbox->pack_end(*status, FALSE, TRUE, 1);
+       pane->show();
+//     status->show();
+
+       main_hbox = new Gtk_VBox();
+       main_hbox->pack_start(*this->menubar, FALSE, FALSE, 1);
+       main_hbox->pack_start(*top_hbox, FALSE, TRUE, 1);
+       main_hbox->pack_end(*bottom_hbox, TRUE, TRUE, 1);
+       top_hbox->show();
+       bottom_hbox->show();
+       this->add(*main_hbox);
+       this->destroy.connect(Gtk_Main::quit.slot());   
+       main_hbox->show();
+//     this->show_all();
+}
+
+My_Window::~My_Window() {
+       cout << "~My_Window()" << endl;
+       delete this;
+}
+
+int My_Window::debug(const char *format,...) {
+       if (debug_level > 1) {
+               va_list args;
+               int ret;
+               char *c;
+               char buff[50];
+               unsigned int m_context_id;
+               va_start(args, format);
+               ret = vprintf(format, args);
+       /*      if (this->status != NULL) {
+                       m_context_id = this->status->get_context_id("gtk-tool");
+                       ret = vsprintf(c, format, args);
+                       g_snprintf(buff, 50, "Action: %s", c);
+                       this->status->push(m_context_id, buff);
+               }
+       */      va_end(args);
+               return ret;
+       }
+}
+
+void My_Window::do_display() {
+       cout << this->urlfield->get_text() << endl;
+}
+
+void My_Window::getHost() {
+       debug("My_Window::getHost()\n");
+       Gtk_Tree *tree, *subtree;
+       Gtk_LdapServer *treeitem;
+       char *host, *prt;
+       int port;
+
+//     viewport = (Gtk_Viewport *) GTK_VIEWPORT(this->scroller->children()->nth_data(1));
+//     viewport = (Gtk_Viewport *)this->scroller->children()->nth_data(1);
+       if (this->viewport->get_child()!=NULL) {
+               tree = (Gtk_Tree *)(this->viewport->get_child());
+       }
+       else {
+               tree = new Gtk_Tree();
+       }
+       string thing;
+       thing = this->urlfield->get_text();
+       gchar **c;
+       c = g_strsplit(thing.c_str(), ":", 2);
+       host = c[0];
+       prt = c[1]; //strtok(NULL, "\0");
+       if (prt != NULL) port = atoi(prt);
+       else port = LDAP_PORT;
+       treeitem = new Gtk_LdapServer(this, host, port);
+       subtree = treeitem->getSubtree();
+       tree->append(*treeitem);
+       treeitem->set_subtree(*subtree);
+       treeitem->show();
+       this->viewport->add(*tree);
+       tree->show();
+       this->viewport->show();
+       this->scroller->show();
+       treeitem->select();
+}
+
+void My_Window::setDebug() {
+       if (debug_level > 0) debug_level = 0;
+       else debug_level = 1;
+}
+
+void My_Window::addServer() {
+       debug("%s\n", "Creating new server");
+       Gtk_Entry *entry = new Gtk_Entry();
+//     entry->connect(slot(entry->activate, this, &getHost));
+       entry->activate.connect(slot(this,&My_Window::getHost));
+       this->dialog = new Gtk_InputDialog();
+//     this->dialog->add(*entry);
+//     entry->show();
+       this->dialog->show();
+       
+}
+
+gint My_Window::delete_event_impl(GdkEventAny*) {
+       //Gtk_Main::instance()->quit();
+       return 0;
+}
diff --git a/contrib/gtk-tool/My_Window.h b/contrib/gtk-tool/My_Window.h
new file mode 100644 (file)
index 0000000..f68c480
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef MY_WINDOW_H
+#define MY_WINDOW_H
+#include "cpluscommon.h"
+#include "gtk.h"
+#include "Gtk_LdapServer.h"
+#include "Gtk_LdapTreeItem.h"
+
+extern int debug_level;
+
+class My_Window : public Gtk_Window {
+public:
+       Gtk_ScrolledWindow *scroller, *scroller2;
+       Gtk_Viewport *viewport, *viewport2;
+       Gtk_Entry *urlfield;
+       Gtk_Button *display_button;
+       Gtk_InputDialog *dialog;
+       Gtk_Paned *pane;
+       Gtk_MenuBar *menubar;
+//     Gtk_ProgressBar *progress;
+       Gtk_Statusbar *status;
+       My_Window(GtkWindowType t);
+       ~My_Window();
+       int debug(const char *c,...);
+       void do_display();
+       void addServer();
+       void getHost();
+       void setDebug();
+       gint delete_event_impl(GdkEventAny *);
+};
+#endif
diff --git a/contrib/gtk-tool/README b/contrib/gtk-tool/README
new file mode 100644 (file)
index 0000000..e2579e5
--- /dev/null
@@ -0,0 +1,39 @@
+README for gtk-tool v0.7a
+
+This package has been tested and run with the latest Gtk+1.2/Gtk--1.1
+OpenLDAP 2.0-devel. It should also compile (i.e. it is backward-compatible) with
+the U-MICH (old) API but it has not been tested (read compiled) - however the siplicity of the "problem" and a few ifdefs lead me to believe everything should
+be allright with gtk-tool now. This thing doesn't run as it should, please
+read TODO!
+
+Just type 'make' to compile and if you have all the necessary stuff it'll do so.
+You do need the latest version of Gtk+ and Gtk-- (which may be tricky to build).
+You can also edit the Makefile and under "OPTS=-g" add " -DDEBUG" (line should
+read "OPTS=-g -DDEBUG") to get a trace of what the gtk-tool is doing (getting
+entries, traversing trees etc...)
+After that, hopefully all goes well, you start the thing by doing:
+./main -s localhost
+
+It no longer has a default base, instead it reads cn=config off your slapd
+and accordignly inserts all available databases under "localhost". If you are
+not running slapd on your local machine, then supply it with a "-s hostname"
+i.e.:
+       ./main -s server02.nowhere.net
+
+or if you feel like having an adventure try multiple servers
+i.e.:
+       ./main -s server02.nowhere.net -s server03.nowhere.com:322
+
+etc...
+It does not accept -b switch as it no longer needs it to aquire databases.
+There's also a -d <level> switch (try it with -d 1) for all the debug info.
+But please feel free to add whatever else you consider neccessary to 
+understanding how this thing works. Enjoy, and I hope this can be useful to 
+you in some miniscule way.
+
+All emails to -devel list, and plase make sure you put "GTK-TOOL"
+in the subject line, so other people who are not interested don't
+have to read our garbage.
+
+Pele
+pele@openldap.org
diff --git a/contrib/gtk-tool/TODO b/contrib/gtk-tool/TODO
new file mode 100644 (file)
index 0000000..d316745
--- /dev/null
@@ -0,0 +1,18 @@
+LOADS!!!
+
+Please someone test this with old U-MICH API - hopefully all is as it should be.
+
+Priorities:
+       Now that we have cn=config we can start using ldap_get_option propperly
+       and be able to run/stop server from the gtk-tool. Other things like
+       new entries would now come in handy.
+       Implement searches
+       Integrate with OpenLDAP build - autoconf stuff (anyone?)
+
+Optional:
+       comments in the source code     
+       port it to NT so we can use it with the NT port of OpenLDAP
+       (they say that there is an NT port of Gtk+?)
+
+Pele
+pele@openldap.org
diff --git a/contrib/gtk-tool/common.h b/contrib/gtk-tool/common.h
new file mode 100644 (file)
index 0000000..c65ba42
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef MY_COMMON
+#define MY_COMMON
+
+#include "system.h"
+#include "cpluscommon.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <error.h>
+#include <string.h>
+extern int errno;
+extern int debug_level;
+#endif
diff --git a/contrib/gtk-tool/cpluscommon.h b/contrib/gtk-tool/cpluscommon.h
new file mode 100644 (file)
index 0000000..48f1a7c
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef MY_CPLUS_COMMON
+#define MY_CPLUS_COMMON
+
+#include <iostream.h>
+#include <iomanip.h>
+#include <fstream.h>
+#include <strstream.h>
+#include <unistd.h>
+#include <stdio.h>
+#endif
diff --git a/contrib/gtk-tool/gtk.h b/contrib/gtk-tool/gtk.h
new file mode 100644 (file)
index 0000000..c966024
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef MY_GTK_INCLUDES
+#define MY_GTK_INCLUDES
+
+#include <gtk--.h>
+#include <gtk/gtk.h>
+#include <gtk--/widget.h>
+#include <gtk--/button.h>
+#include <gtk--/window.h>
+#include <gtk--/list.h>
+#include <gtk--/main.h>
+/*#include <gtk--sig.h>*/
+#include <gtk--/container.h>
+
+#endif
diff --git a/contrib/gtk-tool/icons/monitor.h b/contrib/gtk-tool/icons/monitor.h
new file mode 100644 (file)
index 0000000..ce45960
--- /dev/null
@@ -0,0 +1,286 @@
+/* XPM */
+static char *monitor[] = {
+/* columns rows colors chars-per-pixel */
+"19 19 260 2",
+"   c Gray0",
+".  c #0433043a0433",
+"X  c Gray2",
+"o  c #062c06220626",
+"O  c #0cb40cb50cb4",
+"+  c #0ccd0d540d92",
+"@  c #0d8e0d760e8b",
+"#  c Gray6",
+"$  c #10530f801046",
+"%  c #10da10c610d7",
+"&  c #117f11721184",
+"*  c #11f8120d120c",
+"=  c Gray7",
+"-  c #13a7139113a8",
+";  c #142214191519",
+":  c Gray9",
+">  c #18e718f318ea",
+",  c #19a719aa19a1",
+"<  c Gray12",
+"1  c #234e23382345",
+"2  c #27ad279627c0",
+"3  c #2a872a822a84",
+"4  c #2e0d2de92dfb",
+"5  c Gray24",
+"6  c #3dd03e053df5",
+"7  c #6dde57513ad0",
+"8  c #78ae78d132cd",
+"9  c #7fc87faf3a4e",
+"0  c #417d416c41f8",
+"q  c #43c544184427",
+"w  c #4594460145b7",
+"e  c Gray28",
+"r  c #48b8489a48b0",
+"t  c #49ba49a849b8",
+"y  c #4c834c894c48",
+"u  c Gray30",
+"i  c Gray31",
+"p  c #4fb251055619",
+"a  c #55e2566a426c",
+"s  c #507c5060506d",
+"d  c #5122511750e7",
+"f  c #520551f75202",
+"g  c Gray32",
+"h  c #536853575355",
+"j  c #558b557d5578",
+"k  c #561455fa5621",
+"l  c #531353795e7a",
+"z  c #588d58a8589d",
+"x  c Gray35",
+"c  c #5adf5ad25ada",
+"v  c #5bb45b5e5bd6",
+"b  c #593c59f85ef7",
+"n  c #5cc55d315d83",
+"m  c #5da35da05d68",
+"M  c Gray37",
+"N  c #5f285f3e5f24",
+"B  c #59d65dcc6463",
+"V  c #5bf95e1566e2",
+"C  c #4a576f134a1d",
+"Z  c #4c067f2f4c3e",
+"A  c #659966275b42",
+"S  c #7df565484934",
+"D  c Gray38",
+"F  c #607761f96387",
+"G  c #63f964176407",
+"H  c #646f6454646f",
+"J  c #64fb65246521",
+"K  c #65fe66076606",
+"L  c #661f65e76612",
+"P  c Gray40",
+"I  c #662166a2670b",
+"U  c #669667186662",
+"Y  c #671c674c672b",
+"T  c #624b677e6c07",
+"R  c #628a676a6d3a",
+"E  c #64d764fd6e4d",
+"W  c #655e65cc6e6f",
+"Q  c #668e672c6c5e",
+"!  c #64e36a126edf",
+"~  c #6eae6f8f62d7",
+"^  c #68f368de690a",
+"/  c #69d969e66a08",
+"(  c #69f96a6469be",
+")  c #6af16afd6aff",
+"_  c Gray42",
+"`  c #6b7d6be06e14",
+"'  c #6bb06c496c6a",
+"]  c #6cb76cba6cb7",
+"[  c #6d8c6d806d6a",
+"{  c #6c076dfa6f68",
+"}  c Gray43",
+"|  c #6fc56fda6fa1",
+" . c #66f166e871f5",
+".. c #6a7f6ad97350",
+"X. c #6aee705f75d2",
+"o. c #6ec4724d76ee",
+"O. c #70116fbd7026",
+"+. c #70c26f4a7124",
+"@. c #72996fba72bc",
+"#. c Gray44",
+"$. c #70f0712570c3",
+"%. c #719a71a371c2",
+"&. c #72b372bc7299",
+"*. c #7355733672f5",
+"=. c Gray45",
+"-. c #712f71e47703",
+";. c #7457744d7480",
+":. c #752374e174e1",
+">. c Gray46",
+",. c #7630765675ec",
+"<. c #7660767f7688",
+"1. c #777a7778778d",
+"2. c #72e572f77e86",
+"3. c #71a774037abe",
+"4. c #778677f97e30",
+"5. c #77aa780b7795",
+"6. c #77fb7806780c",
+"7. c #79c570ac7a0a",
+"8. c Gray47",
+"9. c #795579317930",
+"0. c Gray48",
+"q. c #7aff7b1e7b62",
+"w. c #7bc57bbc7b80",
+"e. c #7c3d7bfd7bf5",
+"r. c #7cbd7cd57c8f",
+"t. c Gray49",
+"y. c #7dd67e417e2e",
+"u. c #7ef17f057ece",
+"i. c #7f3c7ef87f3a",
+"p. c Gray50",
+"a. c #7e5e794984ba",
+"s. c #7efa7858883b",
+"d. c #3a32a4303a10",
+"f. c #7f0e802f5593",
+"g. c #47f3d9d747ed",
+"h. c #7df58115862a",
+"j. c #80427f288146",
+"k. c #876b879d4763",
+"l. c #814681036c33",
+"z. c #c9c7849537bf",
+"x. c #f0f6a65957f2",
+"c. c #f3ecf3e9321d",
+"v. c #ff25fefa3c32",
+"b. c #c79cc70d7fb9",
+"n. c #80898076804c",
+"m. c #80ee814b8120",
+"M. c #812c81338115",
+"N. c #8218820b81e7",
+"B. c Gray51",
+"V. c #832d82e3833e",
+"C. c #8361836b8333",
+"Z. c #83ed83c78414",
+"A. c #846b8463848a",
+"S. c #84e1851e84ac",
+"D. c Gray52",
+"F. c #85fa864a8620",
+"G. c #867d867a8661",
+"H. c #874486e4873e",
+"J. c Gray53",
+"K. c #807c815489e4",
+"L. c #80ef80b38a26",
+"P. c #84b683d98c0f",
+"I. c #8808876f87e6",
+"U. c #8ab183538acf",
+"Y. c #880e87bd880f",
+"T. c #8f3485e48ef9",
+"R. c #887d88628873",
+"E. c #88e2890188c4",
+"W. c #8915891388de",
+"Q. c #8a0a89c78a0e",
+"!. c Gray54",
+"~. c #8ad38b0d8b09",
+"^. c #8b7a8ae18b80",
+"/. c #8bb78b818ba7",
+"(. c Gray55",
+"). c #8d4b8ce08d0f",
+"_. c #8da38dc08d9e",
+"`. c #8e2e8dc88e29",
+"'. c #8eb28e598ea6",
+"]. c #8ea98f258eca",
+"[. c Gray56",
+"{. c #908f879d90be",
+"}. c #90768ef190e7",
+"|. c #91ce8ee691f7",
+" X c Gray57",
+".X c #91fb91f39203",
+"XX c #91e4922091fe",
+"oX c #921f91f59219",
+"OX c #920a920a91f4",
+"+X c #92bd9279928f",
+"@X c #930092d792e6",
+"#X c #933792de936c",
+"$X c #937d936f9376",
+"%X c #94bd909d9776",
+"&X c Gray58",
+"*X c #953a95209549",
+"=X c Gray59",
+"-X c #975f9792979d",
+";X c #980d985b9837",
+":X c #98e4990298fc",
+">X c Gray60",
+",X c #9a729a479aac",
+"<X c #9b179b4c9b51",
+"1X c #9bca9c0f9c01",
+"2X c Gray61",
+"3X c #9dda9d6c9d9a",
+"4X c #9dd79dc69e13",
+"5X c Gray62",
+"6X c #9fb19faa9fd2",
+"7X c #9fbda856a021",
+"8X c #a5e89ff7a63c",
+"9X c #b13bb1f1808e",
+"0X c #a0c1a094a15d",
+"qX c #a17aa0e8a162",
+"wX c Gray63",
+"eX c #a1dba20da20b",
+"rX c #a255a249a257",
+"tX c #a315a2e7a359",
+"yX c Gray64",
+"uX c #a424a3f7a3d6",
+"iX c #a4b2a48da4b2",
+"pX c #a55ea54ea56a",
+"aX c #a5d4a63da5e6",
+"sX c #a6e4a679a73f",
+"dX c #a74da730a73e",
+"fX c #a851a80da7f3",
+"gX c Gray66",
+"hX c #a8d2a8baa93b",
+"jX c #a9c8a9a4a9cb",
+"kX c #a9f6aa0ba9f6",
+"lX c #aaf9aaf9aac9",
+"zX c #ab3dab08aaec",
+"xX c #ac1eabdfac00",
+"cX c #ac74ac77ac86",
+"vX c #ad0aac7cad0b",
+"bX c #ae9cae5bae85",
+"nX c #aed5aeeaaf01",
+"mX c #aec9af12aef4",
+"MX c #afe0af87b031",
+"NX c Gray69",
+"BX c #b16ab13bb150",
+"VX c #b1bfb1deb20e",
+"CX c #b1d0b201b1c9",
+"ZX c #b20cb16eb233",
+"AX c Gray70",
+"SX c #b47db456b437",
+"DX c #b500b515b4f6",
+"FX c Gray71",
+"GX c #b635b607b65e",
+"HX c #b7afb78bb787",
+"JX c Gray72",
+"KX c #bab0bafdbb0d",
+"LX c #bc13bb8abc3c",
+"PX c #bf61befebf78",
+"IX c Gray75",
+"UX c #c0eac148c0ce",
+"YX c #c23dc1eec270",
+"TX c #c3f5c376c49a",
+"RX c Gray79",
+"EX c #d690d590d6c8",
+"NX c None",
+/* pixels */
+"NXNXNXNXNXNXNXNXNXNXNXNXNXNXNXNXNXNXNX",
+"KX[.EXTXPXIXLXZXNXMXsXwX0X4X&X+XR.NXNX",
+"HX`.qX2 V.FXc 1 gXoX4 L 4XJ < !.C.NXNX",
+"DX'.^.  F.vXH M bXN.O K ,Xh : =Xn.NXNX",
+"CX).'.. G.vXeXJ.:.D.* P @XpXNXt.e.NXNX",
+"mX!.!.. D.jX6 # 6Xq.o N  X&.3 ) t.NXNX",
+"xXY.R.X A.hXe , zXR._.:XA.i O ].9.NXNX",
+"hXA.C.  i.iXr > iX(.t.N ,.j % !.>.NXNX",
+"aXi./.5  X3Xr , iX1.# z ~.f & J.&.NXNX",
+"tX9.yXkXr.H.t , rX;.- G F.d = S.#.NXNX",
+"6X8.I.$ v #X0 ; ,X' + n y.q @ y.} NXNX",
+"2X>.8X7.{.%XL. .K.h.R X.o...l E ` NXNX",
+">X@.7Xg.d.s.b.c.f.P.x.z.V 9Xv.k.W NXNX",
+"=X+.}.Z C a.l.9 A 3.S 7 B ~ 8 a Q NXNX",
+"$X] |.T.U.j.4.2.-.{ ! T F b l p I NXNX",
+"NXNXNXNXNXNXNXNXNXNXNXNXNXNXNXNXNXNXNX",
+"NXNXNXNXNXNXNXNXNXNXNXNXNXNXNXNXNXNXNX",
+"NXNXNXNXNXNXNXNXNXNXNXNXNXNXNXNXNXNXNX",
+"NXNXNXNXNXNXNXNXNXNXNXNXNXNXNXNXNXNXNX"
+};
diff --git a/contrib/gtk-tool/main.cc b/contrib/gtk-tool/main.cc
new file mode 100644 (file)
index 0000000..55978ed
--- /dev/null
@@ -0,0 +1,113 @@
+#include "cpluscommon.h"
+#include "gtk.h"
+#include <lber.h>
+#include <ldap.h>
+#include <My_Window.h>
+#include <Gtk_LdapItem.h>
+#include <Gtk_LdapServer.h>
+
+int debug_level = 0;
+
+target_drag_leave(GdkDragContext *context, guint time) {
+}
+
+int main(int argc, char **argv) {
+       My_Window *window;
+       Gtk_LdapItem *treeresult;
+       Gtk_Tree *tree = NULL, *subtree = NULL;
+       Gtk_Tree *machine, *machinetree;
+       Gtk_LdapServer *server;
+       Gtk_Viewport *viewport;
+       char *host = NULL, *prt = NULL;
+       char *base_dn = NULL;
+       int c, port = 0;
+       GList *hosts = NULL;
+       int host_count = 0;
+       char *pair[2];
+
+       //hosts = new G_List<char>();
+       while ((c = getopt(argc, argv, "d:s:p:h")) != -1) {
+               switch (c) {
+                       case 'd':
+                               debug_level = atoi(optarg);
+                               break;
+                       case 's':
+                               debug("host\n");
+                               hosts = g_list_append(hosts, (strdup(optarg)));
+                               break;
+                       case 'p':
+                               port = atoi(optarg); break;
+                       case 'h':
+                       default:
+                               fprintf(stderr, "Usage: %s [-d level] [-s server[:port]]*\n", argv[0]);
+                               exit(-1);
+               }
+               fprintf(stderr,"b");
+       }
+       debug("%i hosts\n", g_list_length(hosts));
+       if (g_list_length(hosts) == 0) {
+#ifndef LDAP_GET_OPT
+               ldap_get_option(NULL, LDAP_OPT_HOST_NAME, host);
+#endif /* LDAP_GET_OPT */
+               if (host!=NULL) {
+                       hosts = g_list_append(hosts, host);
+                       debug("Default host: %s\n", host);
+               } else {
+#ifndef LDAP_GET_OPT
+                       fprintf(stderr,"Why isn't your LDAP_OPT_HOST_NAME defined?\n");
+#endif
+                       fprintf(stderr,"Supply me with a host please (hint: use -s)\n");
+               }
+       } else {        
+               for (int f=0; f<g_list_length(hosts); f++) {
+                       debug("%s\n", g_list_nth(hosts,f)->data);
+               }
+       }
+       if (port == 0) port = LDAP_PORT;
+
+       Gtk_Main m(&argc, &argv);
+
+       window = new My_Window(GTK_WINDOW_TOPLEVEL);
+
+       if (hosts!=NULL) {
+               tree = new Gtk_Tree();
+               window->viewport->add(*tree);
+               for (int f=0; f<g_list_length(hosts); f++) {
+                       host = strtok((char*)g_list_nth(hosts, f)->data, ":");
+                       prt = strtok(NULL, "\0");
+                       if (prt != NULL) port = atoi(prt);
+                       else port = LDAP_PORT;
+                       server = new Gtk_LdapServer(window, host, port);
+                       subtree = server->getSubtree();
+                       tree->append(*server);
+                       server->set_subtree(*subtree);
+                       server->show();
+               }
+               //window->viewport->add(*tree);
+//             tree->show();
+       }
+
+//     window->viewport->show();
+//     window->scroller->show();
+
+       //Select first server
+       if (tree != NULL) {
+               Gtk_LdapTree::ItemList &items = tree->tree();
+               Gtk_LdapTree::ItemList::iterator i = items.begin();
+               server = (Gtk_LdapServer *)(* i);
+       //      server->select_impl();
+       }
+
+       window->set_title("gtk-tool");
+       window->activate();
+       window->set_usize(600, 500);
+
+       window->set_events(window->get_events()|GDK_ALL_EVENTS_MASK);
+       window->drag_dest_set(GTK_DEST_DEFAULT_ALL, target_table, n_targets, static_cast <GdkDragAction> (GDK_ACTION_COPY|GDK_ACTION_MOVE));
+       window->drag_source_set(static_cast<GdkModifierType>(GDK_BUTTON1_MASK|GDK_BUTTON3_MASK), target_table, n_targets, static_cast<GdkDragAction>(GDK_ACTION_COPY|GDK_ACTION_MOVE));
+        window->drag_leave.connect(window->slot(window,target_drag_leave));
+       window->show_all();
+
+       m.run();
+       return 0;
+}
diff --git a/contrib/gtk-tool/utils.cc b/contrib/gtk-tool/utils.cc
new file mode 100644 (file)
index 0000000..9f430cd
--- /dev/null
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+extern int debug_level;
+
+int debug(const char *format,...) {
+       if (debug_level > 0) {
+//#ifdef DEBUG
+               va_list args;
+               int ret;
+               va_start(args, format);
+               ret = vprintf(format, args);
+               va_end(args);
+               return ret;
+//#endif
+       }
+}
index c195b1b392f536d3b2967f27dbd89666e4999901..04586ff58ee95a52452a71b54e71470bf136a749 100644 (file)
@@ -21,24 +21,24 @@ exec_prefix =       @exec_prefix@
 # The following definition can be set to non-null for special systems
 # like AFS with replication.  It allows the pathnames used for installation
 # to be different than those used for actually reference files at
-# run-time.  INSTALL_ROOT is prepended to $prefix and $exec_prefix
+# run-time.  DESTDIR is prepended to $prefix and $exec_prefix
 # when installing files.
-INSTALL_ROOT =
+DESTDIR =
 
 # Directory in which to search for tcl libraries
 NEO_LIBRARY    = $(exec_prefix)/lib/ldaptcl$(VERSION)
 
 # Directory in which to install the ldaptcl binary:
-BIN_INSTALL_DIR = $(INSTALL_ROOT)$(exec_prefix)/bin
+BIN_INSTALL_DIR = $(DESTDIR)$(exec_prefix)/bin
 
 # Directory in which to install the .a or .so binary for the Neo library:
-LIB_INSTALL_DIR = $(INSTALL_ROOT)$(exec_prefix)/lib
+LIB_INSTALL_DIR = $(DESTDIR)$(exec_prefix)/lib
 
 # Path to use at runtime to refer to LIB_INSTALL_DIR:
 LIB_RUNTIME_DIR =      $(exec_prefix)/lib
 
 # Top-level directory for man entries:
-MANN_INSTALL_DIR =     $(INSTALL_ROOT)$(prefix)/man/mann
+MANN_INSTALL_DIR =     $(DESTDIR)$(prefix)/man/mann
 
 
 # The symbols below provide support for dynamic loading and shared
index a8d16df5d2f4a0c638ca8a5cec983b6281e7efbf..a1a5880e60607fa699a21546af0c44cc71331029 100644 (file)
@@ -2,7 +2,7 @@ dnl     This file is an input file used by the GNU "autoconf" program to
 dnl    generate the file "configure", which is run during Tk installation
 dnl    to configure the system for the local environment.
 AC_INIT(neoXldap.c)
-# $Id: configure.in,v 1.3 1999/08/03 05:23:03 kunkee Exp $
+# $OpenLDAP$
 
 NEO_VERSION=1.2
 NEO_MAJOR_VERSION=1
diff --git a/contrib/ldaptcl/ldap.n b/contrib/ldaptcl/ldap.n
new file mode 100644 (file)
index 0000000..6855403
--- /dev/null
@@ -0,0 +1,373 @@
+'\"
+'\" Copyright (c) 1998 NeoSoft, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.so man.macros
+.TH ldap n "" Ldap "Ldap Tcl Extension"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+ldap \- connect to and query an LDAP server
+.SH SYNOPSIS
+\fBldap \fBopen \fR \fIcommand\fR \fIhostlist\fR
+.br
+\fBldap \fBinit \fR \fIcommand\fR \fIhostlist\fR
+.br
+\fBldap \fBexplode ?-nonames|-list?\fR \fIdn\fR
+.br
+\fIcommand \fBsubcommand \fIoptions ...\fR
+.BE
+
+.SH OVERVIEW
+.PP
+A new command by the name of \fIcommand\fR will be created to access
+the LDAP database at \fIhostlist\fR.  \fIhostlist\fR may contain elements
+of the format \fBhost:port\fR if a port other than the default LDAP port
+of 389 is required.  The LDAP library will attempt to connect to each
+host in turn until it succeeds or exhausts the list.
+.PP
+The \fBexplode\fR form provides a means (via ldap_explode(3)) to explode a DN
+into its component parts.  \fB-nonames\fR strips off the attribute names,
+and -list returns a list suitable for \fBarray set\fR.
+.PP
+Finally, the last form, described in more detail below, refers genericly
+to how the command created by the first two examples is used.
+.SH DESCRIPTION
+
+The Lightweight Directory Access Protocol provides TCP/IP access to
+X.500 directory services and/or to a stand-alone LDAP server.
+
+This code provides a Tcl interface to the
+Lightweight Directory Access Protocol package using the Netscape
+Software Development Kit.  It can also be used with the freely
+redistributable University of 
+Michigan (http://www.umich.edu/~rsug/ldap) version by defining the
+UMICH_LDAP macro during compilation.
+
+.SH CONNECTING TO AN LDAP SERVER
+
+To create an ldap interface entity, we use the "ldap" command.
+
+    ldap open foo foo.bar.com
+
+This opens a connection to a LDAP server on foo.bar.com, and makes
+a new Tcl command, foo, through which we will manipulate the interface
+and make queries to the remote LDAP server.
+
+    ldap init foo foo.bar.com
+
+Same as above, foo is created, but for "init", opening the connection is 
+deferred until we actually try to do something.
+
+For the purposes of this example, we're going to assume that "foo" is the
+command created by opening a connection using "ldap open".
+
+.SH BINDING
+
+After a connection is made to an LDAP server, an LDAP bind operation must
+be performed before other operations can be attempted over the connection.
+
+Both simple authentication and kerberos authentication are available.
+LDAP version 3 supports many new "SSL"-style authentication and encryption
+systems, which are not currently supported by the OpenLDAP v1.2 server, and
+hence by this interface package.
+
+Currently simple and kerberos-based authentication, are supported.
+
+To use LDAP and still have reasonable security in a networked, 
+Internet/Intranet environment, secure shell can be used to setup
+secure, encrypted connections between client machines and the LDAP
+server, and between the LDAP server and any replica or slave servers
+that might be used.
+
+To perform the LDAP "bind" operation:
+
+    foo bind simple dn password
+
+    foo bind kerberos_ldap
+    foo bind kerberos_dsa
+    foo bind kerberos_both
+
+It either returns nothing (success), or a Tcl error with appropriate error
+text.
+
+For example,
+
+    foo bind simple "cn=Manager,o=NeoSoft Inc,c=us" "secret"
+
+If you attempt to bind with one of the kerberos authentication types
+described above and your LDAP library was not built with KERBEROS
+defined, you will get an unknown auth type error.
+
+To unbind an LDAP connection previously bound with "bind":
+
+    foo unbind
+
+Note that unbinding also deletes the command (\fBfoo\fR in this case).
+Deleting the command has the same affect.
+
+The ability of the library to callback to the client, enabling re-binding
+while following referrals, is not currently supported.
+
+.SH DELETING OBJECTS
+
+To delete an object in the LDAP database, use
+
+    foo delete dn
+
+To rename an object to another relative distinguished name, use
+
+    foo rename_rdn dn rdn
+
+To rename an object to another relative distinguished name, leaving
+the old entry as some kind of attribute (FIX: not sure if this is
+right or how it works)
+
+    foo modify_rdn dn rdn
+
+
+.SH ADDING NEW OBJECTS
+
+    foo add dn attributePairList
+
+This creates a new distinguished name and defines zero or more attributes.
+
+"attributePairList" is a list of key-value pairs, the same as would
+be returned by "array get" if an array had been set up containing the
+key-value pairs.
+
+    foo add "cn=karl, ou=People, o=NeoSoft Inc, c=US" {cn karl ...}
+
+Some directory servers and/or their client SDKs will automatically
+add the leaf attribute value for you.
+
+Here is a more precise description of how an attributePairList looks:
+
+    {cn {karl {Karl Lehenbauer}} telephone 713-968-5800}
+
+Note here that two cn values, "karl" and "Karl Lehenbauer", are added.
+Is it an error to write:
+
+    {cn {Karl Lehenbauer}}
+
+Which adds two cn values, "Karl" and "Lehenbauer", when the intention
+was to give a single cn value of "Karl Lehenbauer".  In real life, one
+finds oneself making prodigous use of the \fBlist\fR command rather than
+typing hard-coded lists.
+
+We have noticed that the Netscape server will automatically add the
+left-most rdn portion of the DN (ie. cn=karl), whereas the University
+of Michigan and OpenLDAP 1.2 versions do not.
+
+.SH ADDING, DELETING, AND REPLACING OBJECT ATTRIBUTES
+
+You can have multiple values for a given attribute in an LDAP object.
+These are represented in search results, through the Tcl interface,
+as a list.
+
+    foo add_attributes dn attributePairList
+
+This adds key-value pairs to an existing DN.  If an attribute being
+added already exists, the new value will be appended to the list.
+If a particular value being added to an attribute already exists in
+the object a Tcl error is raised.
+
+    foo replace_attributes dn attributePairList
+
+This replaces the specified attributes in an existing DN, leaving
+unnamed ones untouched.  Any previous values for the supplied attributes
+(if any) are discarded.
+
+    foo delete_attributes dn attributePairList
+
+This deletes attributes in the list.  If an attribute "foo" has the
+value list {bar snap}, and you delete using the attributePairList "foo bar",
+"foo" will still have "snap".
+
+If you provide an empty string ("") for the value list,
+the entire attribute will be deleted.
+
+.SH SEARCHING
+
+The Tcl interface to searching takes a control array, which contains
+a couple of mandatory key-value pairs, and can contain a number of
+optional key-value pairs as well, for controlling the search, a
+destination array, into which the specified attributes (or all attributes
+of matching DNs if none are specified) and values are stored.
+
+The "code" part is executed repeatedly, once for each DN matching the
+search criteria.
+
+    foo search controlArray destArray code
+
+       Using data in the control array, a search is performed of the
+       LDAP server opened when foo was created.  Possible elements
+       of the control array are enumerated blow.
+
+       controlArray(base) is the DN being searched from. (required)
+
+       controlArray(filter) contains the search criteria. (required)
+
+       controlArray(scope) must be "base", "one_level", or "subtree".
+           If not specified, scope defaults to "subtree".
+
+       controlArray(deref) must be "never", "search", "find", or "always"
+           If not specified, deref defaults to "never"
+
+       controlArray(attributes) is a list of attributes to be fetched.
+           If not specified, all attributes are fetched.
+
+       controlArray(timeout) a timeout value in seconds (may contain
+           fractional values -- extremely very small values are useful
+           for forcing timeout conditions to test timeouts).
+
+        For each matching record, destArray is populated with none,
+       some or all attribute-value pairs.
+
+Note:  There are some additional parameters that can be set, such as
+how long the synchronous version of the routines should wait before
+timing out, the interfaces for which are not available in the current
+version.
+
+.SH CACHING (Note: Netscape clients do not have caching interfaces).
+
+The UMich and OpenLDAP client libraries offers the client application fairly
+fine-grained control of caching of results retrieved from searches, 
+offering significant performance improvement and reduced
+network traffic.
+
+By default, the cache is disabled.
+
+To enable caching of data received from an LDAP connection,
+
+    foo cache enable timeout maxmem
+
+       ...where timeout is specified in seconds, and maxmem is the
+       maximum memory to be used for caching, in bytes.
+
+       If maxmem is 0, the cache size is restricted only by the timeout.
+
+    foo cache disable
+
+       ...temporarily inhibits use of the cache (while disabled, new requests
+       are not cached and the cache is not checked when returning results).
+
+       Disabling the cache does not delete its contents.
+
+    foo cache destroy
+
+       ...turns off caching and completely removes the cache from memory.
+
+    foo cache flush
+
+       ...deletes the entire cache contents, but does not affect
+       whether or not the cache is being used.
+
+    foo cache uncache dn
+
+       ...removes from the cache all request results that make reference 
+       to the specified DN.
+
+       This should be used, for example, after doing an add_attributes,
+       delete_attributes, or replace_attributes (ldap_modify(3)) 
+       involving the requested DN.  Generally this should not be needed,
+       as the Tcl interface automatically performs this operation on
+       any dn that is modified (add,replace,delete) while caching is
+       enabled.
+
+    foo cache no_errors
+
+       ...suppresses caching of any requests that result in an error.
+
+    foo cache size_errors
+
+       ...suppresses caching of any requests that result in an error,
+       except for requests resulting in "sizelimit exceeded", which 
+       are cached.  This is the default.
+
+    foo cache all_errors
+
+        ...enables caching of all requests, including those that result
+       in errors.
+
+.SH IMPLEMENTATION DECISIONS
+
+Because we used the new "Tcl object" C interfaces, this package only works
+with Tcl 8.0 or above.
+
+This package interfaces with the University of Michigan LDAP protocol
+package, version 3.3, and OpenLDAP version 1.2, both of which are
+implementations of version 2 of the LDAP protocol.
+
+Although an LDAP client (or server) could be written in native Tcl 8.0,
+as Tcl 8.0 and above can do binary I/O, and Tcl 8 and above have strings 
+that are fully eight-bit clean, for a first implementation, to minimize 
+compatibility problems, we created a C interface to the UMich LDAP library.
+
+A native Tcl implementation would be cool because we could bring the receiving
+of messages into the normal Tcl event loop and run the LDAP interface fully
+asynchronous.
+
+This implementation is blocking, and blocking only.  That is to say that
+the Tcl event loop is frozen while the ldap routines are waiting on data.
+
+This could be fixed either by recoding all of the I/O in the LDAP library
+to use Tcl's I/O system instead, or by simply coding the LDAP interface in
+native Tcl, as mentioned above.
+
+Another advantage of coding in high-level Tcl, of course, is that the
+client would immediately be cross-platform to Windows and the Mac, as
+well as Unix.
+
+Binary data is not currently supported.  It will probably be trivial to 
+add, we just haven't dug into it yet.
+
+
+.SH FOR MORE INFORMATION
+
+This document principally describes how to use our Tcl interface to the 
+LDAP library works.
+
+For more information on LDAP and the University of Michigan LDAP package,
+please visit the website mentioned above.  The package includes substantial
+documentation in the form of UNIX manual pages, a SLAPD/SLURPD guide
+in Adobe Portable Document Format (pdf), and a number of Internet RFCs
+related to LDAP services.
+
+.SH AUTHORS
+It was written by Karl Lehenbauer, of NeoSoft, Inc., in August and
+September of 1997.  Ldap explode, and numerous bug fixes and extensions
+by Randy Kunkee, also of NeoSoft, Inc., in 1998-1999.
+
+.SH KEYWORDS
+element, join, list, separator
+.SH BUGS
+The \fBldap init\fR syntax fails to return anything useful.  Use
+\fBldap open\fR instead.
+
+\fBPackage require Ldaptcl\fR won't work unless the ldap and lber libraries
+are also shared, and ldaptcl.so is itself created with the correct flags
+(eg. -R for Solaris).  In short there's a lot of details to make this part
+work, but it should work out of the box for Solaris.  Other systems may
+require that LD_LIBRARY_PATH or other appropraite environment variables
+be set at build and/or runtime.
+
+An asynchronous interface should be provided with callbacks.
+
+We have never tested Kerberos authentication.
+
+It does not tolerate some illegal operations very well.
+
+It is possible to create empty attributes, ie. attributes which are present
+but have no value.  This is done by deleting the attribute values rather
+than, eg. "foo delete_attributes dn {telephone {}}" which would delete
+the telephone attribute altogether.  A search for presence of the attribute
+may return an object, and yet it may have no value.  This interface presents
+such an object as not having the attribute at all (ie. you cannot tell).
+The Netscape SDK does this for you, so this makes the behavior consistent
+when using UMICH_LDAP.
+
+\--enable-netscape configuration support has not been tested and probably
+has bugs.
index 978ea6aafa4abeed83f6bb1c772b6ae8f330e79b..2ba7b6545b4545e3f2ab5eb1a5c02763c25f1e99 100644 (file)
@@ -23,7 +23,7 @@
  * Requests for permission may be sent to NeoSoft Inc, 1770 St. James Place,
  * Suite 500, Houston, TX, 77056.
  *
- * $Id: neoXldap.c,v 1.5 1999/08/03 05:23:03 kunkee Exp $
+ * $OpenLDAP$
  *
  */
 
@@ -76,7 +76,6 @@
        ** In OpenLDAP 2.x-devel, its 2000 + the draft number, ie 2002.
        ** This section is for OPENLDAP.
        */
-#define ldap_attributefree(p) ldap_memfree(p)
 #define ldap_memfree(p) free(p)
 #ifdef LDAP_OPT_ERROR_NUMBER
 #define ldap_get_lderrno(ld)   (ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &lderrno), lderrno)
@@ -89,7 +88,6 @@
        /*
        ** Netscape SDK w/ ldap_set_option, ldap_get_option
        */
-#define ldap_attributefree(p) ldap_memfree(p)
 #define LDAP_ERR_STRING(ld)  \
        ldap_err2string(ldap_get_lderrno(ldap))
 #else
@@ -99,7 +97,6 @@
 #define ldap_memfree(p) free(p)
 #define ldap_ber_free(p, n) ber_free(p, n)
 #define ldap_value_free_len(bvals) ber_bvecfree(bvals)
-#define ldap_attributefree(p) 
 #define ldap_get_lderrno(ld) (ld->ld_errno)
 #define LDAP_ERR_STRING(ld)  \
        ldap_err2string(ld->ld_errno)
 
 typedef struct ldaptclobj {
     LDAP       *ldap;
-    int                flags
+    int                caching;        /* flag 1/0 if caching is enabled */
+    long       timeout;        /* timeout from last cache enable */
+    long       maxmem;         /* maxmem from last cache enable */
+    Tcl_Obj    *trapCmdObj;    /* error handler */
+    int                *traplist;      /* list of errorCodes to trap */
+    int                flags;
 } LDAPTCL;
 
+
 #define LDAPTCL_INTERRCODES    0x001
 
 #include "ldaptclerr.h"
@@ -117,7 +120,7 @@ typedef struct ldaptclobj {
 static
 LDAP_SetErrorCode(LDAPTCL *ldaptcl, int code, Tcl_Interp *interp)
 {
-    char shortbuf[6];
+    char shortbuf[16];
     char *errp;
     int   lderrno;
 
@@ -131,6 +134,33 @@ LDAP_SetErrorCode(LDAPTCL *ldaptcl, int code, Tcl_Interp *interp)
        errp = ldaptclerrorcode[code];
 
     Tcl_SetErrorCode(interp, errp, NULL);
+    if (ldaptcl->trapCmdObj) {
+       int *i;
+       Tcl_Obj *cmdObj;
+       if (ldaptcl->traplist != NULL) {
+           for (i = ldaptcl->traplist; *i && *i != code; i++)
+               ;
+           if (*i == 0) return;
+       }
+       (void) Tcl_EvalObj(interp, ldaptcl->trapCmdObj);
+    }
+}
+
+static
+LDAP_ErrorStringToCode(Tcl_Interp *interp, char *s)
+{
+    int offset;
+    int code;
+
+    offset = (strncasecmp(s, "LDAP_", 5) == 0) ? 0 : 5;
+    for (code = 0; code < LDAPTCL_MAXERR; code++) {
+       if (!ldaptclerrorcode[code]) continue;
+       if (strcasecmp(s, ldaptclerrorcode[code]+offset) == 0)
+           return code;
+    }
+    Tcl_ResetResult(interp);
+    Tcl_AppendResult(interp, s, " is an invalid code", (char *) NULL);
+    return -1;
 }
 
 /*-----------------------------------------------------------------------------
@@ -149,7 +179,7 @@ LDAP_SetErrorCode(LDAPTCL *ldaptcl, int code, Tcl_Interp *interp)
  *   o TCL_ERROR if an error occured, with error message in interp.
  *-----------------------------------------------------------------------------
  */
-static int
+int
 LDAP_ProcessOneSearchResult (interp, ldap, entry, destArrayNameObj, evalCodeObj)
     Tcl_Interp     *interp;
     LDAP           *ldap;
@@ -178,6 +208,8 @@ LDAP_ProcessOneSearchResult (interp, ldap, entry, destArrayNameObj, evalCodeObj)
            return TCL_ERROR;
        ldap_memfree(dn);
     }
+    attributeNameObj = Tcl_NewObj();
+    Tcl_IncrRefCount (attributeNameObj);
     for (attributeName = ldap_first_attribute (ldap, entry, &ber); 
       attributeName != NULL;
       attributeName = ldap_next_attribute(ldap, entry, ber)) {
@@ -191,17 +223,17 @@ LDAP_ProcessOneSearchResult (interp, ldap, entry, destArrayNameObj, evalCodeObj)
               as an error, we ignore it to present a consistent interface
               with Netscape's server
            */
-           attributeNameObj = Tcl_NewStringObj (attributeName, -1);
-           Tcl_IncrRefCount (attributeNameObj);
            attributeDataObj = Tcl_NewObj();
+           Tcl_SetStringObj(attributeNameObj, attributeName, -1);
            for (i = 0; bvals[i] != NULL; i++) {
                Tcl_Obj *singleAttributeValueObj;
 
-               singleAttributeValueObj = Tcl_NewStringObj (bvals[i]->bv_val, -1);
+               singleAttributeValueObj = Tcl_NewStringObj(bvals[i]->bv_val, bvals[i]->bv_len);
                if (Tcl_ListObjAppendElement (interp, 
                                              attributeDataObj, 
                                              singleAttributeValueObj) 
                  == TCL_ERROR) {
+                   ber_free(ber, 0);
                    return TCL_ERROR;
                }
            }
@@ -215,10 +247,9 @@ LDAP_ProcessOneSearchResult (interp, ldap, entry, destArrayNameObj, evalCodeObj)
                                TCL_LEAVE_ERR_MSG) == NULL) {
                return TCL_ERROR;
            }
-           Tcl_DecrRefCount (attributeNameObj);
        }
-       ldap_attributefree(attributeName);
     }
+    Tcl_DecrRefCount (attributeNameObj);
     return Tcl_EvalObj (interp, evalCodeObj);
 }
 
@@ -244,8 +275,9 @@ LDAP_ProcessOneSearchResult (interp, ldap, entry, destArrayNameObj, evalCodeObj)
  *   o TCL_ERROR if an error occured, with error message in interp.
  *-----------------------------------------------------------------------------
  */
-static int 
-LDAP_PerformSearch (interp, ldaptcl, base, scope, attrs, filtpatt, value, destArrayNameObj, evalCodeObj, timeout_p)
+int 
+LDAP_PerformSearch (interp, ldaptcl, base, scope, attrs, filtpatt, value,
+       destArrayNameObj, evalCodeObj, timeout_p, all, sortattr)
     Tcl_Interp     *interp;
     LDAPTCL        *ldaptcl;
     char           *base;
@@ -256,6 +288,8 @@ LDAP_PerformSearch (interp, ldaptcl, base, scope, attrs, filtpatt, value, destAr
     Tcl_Obj        *destArrayNameObj;
     Tcl_Obj        *evalCodeObj;
     struct timeval *timeout_p;
+    int                    all;
+    char          *sortattr;
 {
     LDAP        *ldap = ldaptcl->ldap;
     char          filter[BUFSIZ];
@@ -264,18 +298,17 @@ LDAP_PerformSearch (interp, ldaptcl, base, scope, attrs, filtpatt, value, destAr
     int                  abandon;
     int                  tclResult = TCL_OK;
     int                  msgid;
-    LDAPMessage  *resultMessage;
-    LDAPMessage  *entryMessage;
+    LDAPMessage  *resultMessage = 0;
+    LDAPMessage  *entryMessage = 0;
+    char         *sortKey;
 
-    Tcl_Obj      *resultObj;
     int                  lderrno;
 
-    resultObj = Tcl_GetObjResult (interp);
-
     sprintf(filter, filtpatt, value);
 
+    fflush(stderr);
     if ((msgid = ldap_search (ldap, base, scope, filter, attrs, 0)) == -1) {
-       Tcl_AppendStringsToObj (resultObj,
+       Tcl_AppendResult (interp,
                                "LDAP start search error: ",
                                        LDAP_ERR_STRING(ldap),
                                (char *)NULL);
@@ -284,73 +317,85 @@ LDAP_PerformSearch (interp, ldaptcl, base, scope, attrs, filtpatt, value, destAr
     }
 
     abandon = 0;
-    while ((resultCode = ldap_result (ldap, 
-                             msgid, 
-                             0,
-                             timeout_p,
-                             &resultMessage)) == LDAP_RES_SEARCH_ENTRY) {
+    if (sortattr)
+       all = 1;
+    tclResult = TCL_OK;
+    while (!abandon) {
+       resultCode = ldap_result (ldap, msgid, all, timeout_p, &resultMessage);
+       if (resultCode != LDAP_RES_SEARCH_RESULT &&
+           resultCode != LDAP_RES_SEARCH_ENTRY)
+               break;
 
+       if (sortattr) {
+           sortKey = (strcasecmp(sortattr, "dn") == 0) ? NULL : sortattr;
+           ldap_sort_entries(ldap, &resultMessage, sortKey, strcasecmp);
+       }
        entryMessage = ldap_first_entry(ldap, resultMessage);
 
-       tclResult = LDAP_ProcessOneSearchResult  (interp, 
-                               ldap, 
-                               entryMessage,
-                               destArrayNameObj,
-                               evalCodeObj);
-       ldap_msgfree(resultMessage);
-       if (tclResult != TCL_OK) {
-           if (tclResult == TCL_CONTINUE) {
-               tclResult = TCL_OK;
-           } else if (tclResult == TCL_BREAK) {
-               tclResult = TCL_OK;
-               abandon = 1;
-               break;
-           } else if (tclResult == TCL_ERROR) {
-               char msg[100];
-               sprintf(msg, "\n    (\"search\" body line %d)",
-                       interp->errorLine);
-               Tcl_AddObjErrorInfo(interp, msg, -1);
-               abandon = 1;
-               break;
-           } else {
-               abandon = 1;
-               break;
+       while (entryMessage) {
+           tclResult = LDAP_ProcessOneSearchResult  (interp, 
+                                   ldap, 
+                                   entryMessage,
+                                   destArrayNameObj,
+                                   evalCodeObj);
+           if (tclResult != TCL_OK) {
+               if (tclResult == TCL_CONTINUE) {
+                   tclResult = TCL_OK;
+               } else if (tclResult == TCL_BREAK) {
+                   tclResult = TCL_OK;
+                   abandon = 1;
+                   break;
+               } else if (tclResult == TCL_ERROR) {
+                   char msg[100];
+                   sprintf(msg, "\n    (\"search\" body line %d)",
+                           interp->errorLine);
+                   Tcl_AddObjErrorInfo(interp, msg, -1);
+                   abandon = 1;
+                   break;
+               } else {
+                   abandon = 1;
+                   break;
+               }
            }
+           entryMessage = ldap_next_entry(ldap, entryMessage);
        }
+       if (resultCode == LDAP_RES_SEARCH_RESULT || all)
+           break;
+       if (resultMessage)
+       ldap_msgfree(resultMessage);
+       resultMessage = NULL;
     }
-    if (abandon || resultCode == 0) {
-       ldap_abandon(ldap, msgid);
-       if (resultCode == 0) {
-           Tcl_SetErrorCode (interp, "TIMEOUT", (char*) NULL);
-           Tcl_SetStringObj (resultObj, "LDAP timeout retrieving results", -1);
-           return TCL_ERROR;
-       }
-    } else {
-       if (resultCode == LDAP_RES_SEARCH_RESULT) {
-           if ((errorCode = ldap_result2error (ldap, resultMessage, 0))
-             != LDAP_SUCCESS) {
-             Tcl_AppendStringsToObj (resultObj,
-                                     "LDAP search error: ",
-                                     ldap_err2string(errorCode),
-                                     (char *)NULL);
-             ldap_msgfree(resultMessage);
-             LDAP_SetErrorCode(ldaptcl, errorCode, interp);
-             return TCL_ERROR;
-           }
-       }
-
-
-       if (resultCode == -1) {
-           Tcl_AppendStringsToObj (resultObj,
-                                   "LDAP result search error: ",
-                                   LDAP_ERR_STRING(ldap),
-                                   (char *)NULL);
-           LDAP_SetErrorCode(ldaptcl, -1, interp);
-           return TCL_ERROR;
-       } else
+    if (abandon) {
+       if (resultMessage)
            ldap_msgfree(resultMessage);
+       if (resultCode == LDAP_RES_SEARCH_ENTRY)
+           ldap_abandon(ldap, msgid);
+       return tclResult;
+    }
+    if (resultCode == -1) {
+       Tcl_ResetResult (interp);
+       Tcl_AppendResult (interp,
+                               "LDAP result search error: ",
+                               LDAP_ERR_STRING(ldap),
+                               (char *)NULL);
+       LDAP_SetErrorCode(ldaptcl, -1, interp);
+       return TCL_ERROR;
     }
 
+    if ((errorCode = ldap_result2error (ldap, resultMessage, 0))
+      != LDAP_SUCCESS) {
+      Tcl_ResetResult (interp);
+      Tcl_AppendResult (interp,
+                             "LDAP search error: ",
+                             ldap_err2string(errorCode),
+                             (char *)NULL);
+      if (resultMessage)
+         ldap_msgfree(resultMessage);
+      LDAP_SetErrorCode(ldaptcl, errorCode, interp);
+      return TCL_ERROR;
+    }
+    if (resultMessage)
+       ldap_msgfree(resultMessage);
     return tclResult;
 }
 
@@ -366,7 +411,7 @@ LDAP_PerformSearch (interp, ldaptcl, base, scope, attrs, filtpatt, value, destAr
  *      See the user documentation.
  *-----------------------------------------------------------------------------
  */     
-static int
+int
 NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
     ClientData    clientData;
     Tcl_Interp   *interp;
@@ -383,6 +428,7 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
     int           mod_op = 0;
     char        *m, *s, *errmsg;
     int                 errcode;
+    int                 tclResult;
 
     Tcl_Obj      *resultObj = Tcl_GetObjResult (interp);
 
@@ -586,11 +632,11 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
 
        nPairs = attribObjc / 2;
 
-       modArray = (LDAPMod **)ckalloc (sizeof(LDAPMod *) * (nPairs + 1));
+       modArray = (LDAPMod **)malloc (sizeof(LDAPMod *) * (nPairs + 1));
        modArray[nPairs] = (LDAPMod *) NULL;
 
        for (i = 0; i < nPairs; i++) {
-           mod = modArray[i] = (LDAPMod *) ckalloc (sizeof(LDAPMod));
+           mod = modArray[i] = (LDAPMod *) malloc (sizeof(LDAPMod));
            mod->mod_op = mod_op;
            mod->mod_type = Tcl_GetStringFromObj (attribObjv [i * 2], NULL);
 
@@ -600,7 +646,7 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
            }
 
            valPtrs = mod->mod_vals.modv_strvals = \
-               (char **)ckalloc (sizeof (char *) * (valuesObjc + 1));
+               (char **)malloc (sizeof (char *) * (valuesObjc + 1));
            valPtrs[valuesObjc] = (char *)NULL;
 
            for (j = 0; j < valuesObjc; j++) {
@@ -610,7 +656,7 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
                 * value be NULL to indicate entire attribute is to be 
                 * deleted */
                if ((*valPtrs [j] == '\0') 
-                   && (mod->mod_op == LDAP_MOD_DELETE)) {
+                   && (mod->mod_op == LDAP_MOD_DELETE || mod->mod_op == LDAP_MOD_REPLACE)) {
                        valPtrs [j] = NULL;
                }
            }
@@ -620,14 +666,16 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
            result = ldap_add_s (ldap, dn, modArray);
        } else {
            result = ldap_modify_s (ldap, dn, modArray);
+           if (ldaptcl->caching)
+               ldap_uncache_entry (ldap, dn);
        }
 
         /* free the modArray elements, then the modArray itself. */
        for (i = 0; i < nPairs; i++) {
-           ckfree ((char *) modArray[i]->mod_vals.modv_strvals);
-           ckfree ((char *) modArray[i]);
+           free ((char *) modArray[i]->mod_vals.modv_strvals);
+           free ((char *) modArray[i]);
        }
-       ckfree ((char *) modArray);
+       free ((char *) modArray);
 
        /* FIX: memory cleanup required all over the place here */
         if (result != LDAP_SUCCESS) {
@@ -666,6 +714,12 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
        double       timeoutTime;
        struct timeval timeout, *timeout_p;
 
+       char        *paramString;
+       int          cacheThis = -1;
+       int          all = 0;
+
+       char        *sortattr;
+
        Tcl_Obj     *destArrayNameObj;
        Tcl_Obj     *evalCodeObj;
 
@@ -701,7 +755,7 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
                                           "filter",
                                           0);
        if (filterPatternString == (char *)NULL) {
-           filterPatternString = "objectclass=*";
+           filterPatternString = "(objectclass=*)";
        }
 
        /* Fetch scope setting from control array.
@@ -795,6 +849,20 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
            timeout_p = &timeout;
        }
 
+       paramString = Tcl_GetVar2 (interp, controlArrayName, "cache", 0);
+       if (paramString) {
+           if (Tcl_GetInt(interp, paramString, &cacheThis) == TCL_ERROR)
+               return TCL_ERROR;
+       }
+
+       paramString = Tcl_GetVar2 (interp, controlArrayName, "all", 0);
+       if (paramString) {
+           if (Tcl_GetInt(interp, paramString, &all) == TCL_ERROR)
+               return TCL_ERROR;
+       }
+
+       sortattr = Tcl_GetVar2 (interp, controlArrayName, "sort", 0);
+
 #ifdef UMICH_LDAP
        ldap->ld_deref = deref; 
        ldap->ld_timelimit = 0;
@@ -802,7 +870,23 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
        ldap->ld_options = 0;
 #endif
 
-        return LDAP_PerformSearch (interp, 
+       /* Caching control within the search: if the "cache" control array */
+       /* value is set, disable/enable caching accordingly */
+
+#if 0
+       if (cacheThis >= 0 && ldaptcl->caching != cacheThis) {
+           if (cacheThis) {
+               if (ldaptcl->timeout == 0) {
+                   Tcl_SetStringObj(resultObj, "Caching never before enabled, I have no timeout value to use", -1);
+                   return TCL_ERROR;
+               }
+               ldap_enable_cache(ldap, ldaptcl->timeout, ldaptcl->maxmem);
+           }
+           else
+               ldap_disable_cache(ldap);
+       }
+#endif
+       tclResult = LDAP_PerformSearch (interp, 
                                    ldaptcl, 
                                    baseString, 
                                    scope, 
@@ -811,7 +895,20 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
                                    "",
                                    destArrayNameObj,
                                    evalCodeObj,
-                                   timeout_p);
+                                   timeout_p,
+                                   all,
+                                   sortattr);
+       /* Following the search, if we changed the caching behavior, change */
+       /* it back. */
+#if 0
+       if (cacheThis >= 0 && ldaptcl->caching != cacheThis) {
+           if (cacheThis)
+               ldap_disable_cache(ldap);
+           else
+               ldap_enable_cache(ldap, ldaptcl->timeout, ldaptcl->maxmem);
+       }
+#endif
+       return tclResult;
     }
 
 #if defined(UMICH_LDAP) || (defined(OPEN_LDAP) && !defined(LDAP_API_VERSION))
@@ -840,19 +937,28 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
        }
 
        if (STREQU (cacheCommand, "enable")) {
-           long   timeout;
-           long   maxmem;
+           long   timeout = ldaptcl->timeout;
+           long   maxmem = ldaptcl->maxmem;
 
-           if (objc != 5)
+           if (objc > 5)
                return TclX_WrongArgs (interp, 
                                       objv [0],
-                                      "cache enable timeout maxmem");
+                                      "cache enable ?timeout? ?maxmem?");
 
-            if (Tcl_GetLongFromObj (interp, objv [3], &timeout) == TCL_ERROR)
+           if (objc > 3) {
+               if (Tcl_GetLongFromObj (interp, objv [3], &timeout) == TCL_ERROR)
+                   return TCL_ERROR;
+           }
+           if (timeout == 0) {
+               Tcl_SetStringObj(resultObj,
+                   objc > 3 ? "timeouts must be greater than 0" : 
+                   "no previous timeout to reference", -1);
                return TCL_ERROR;
+           }
 
-            if (Tcl_GetLongFromObj (interp, objv [4], &maxmem) == TCL_ERROR)
-               return TCL_ERROR;
+           if (objc > 4)
+               if (Tcl_GetLongFromObj (interp, objv [4], &maxmem) == TCL_ERROR)
+                   return TCL_ERROR;
 
            if (ldap_enable_cache (ldap, timeout, maxmem) == -1) {
                Tcl_AppendStringsToObj (resultObj,
@@ -862,6 +968,9 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
                LDAP_SetErrorCode(ldaptcl, -1, interp);
                return TCL_ERROR;
            }
+           ldaptcl->caching = 1;
+           ldaptcl->timeout = timeout;
+           ldaptcl->maxmem = maxmem;
            return TCL_OK;
        }
 
@@ -869,11 +978,13 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
 
        if (STREQU (cacheCommand, "disable")) {
            ldap_disable_cache (ldap);
+           ldaptcl->caching = 0;
            return TCL_OK;
        }
 
        if (STREQU (cacheCommand, "destroy")) {
            ldap_destroy_cache (ldap);
+           ldaptcl->caching = 0;
            return TCL_OK;
        }
 
@@ -911,6 +1022,75 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
        return TCL_ERROR;
     }
 #endif
+    if (STREQU (subCommand, "trap")) {
+       Tcl_Obj *listObj, *resultObj;
+       int *p, l, i, code;
+
+       if (objc > 4) 
+           return TclX_WrongArgs (interp, objv [0],
+                                  "trap command ?errorCode-list?");
+       if (objc == 2) {
+           if (!ldaptcl->trapCmdObj)
+               return TCL_OK;
+           resultObj = Tcl_NewListObj(0, NULL);
+           Tcl_ListObjAppendElement(interp, resultObj, ldaptcl->trapCmdObj);
+           if (ldaptcl->traplist) {
+               listObj = Tcl_NewObj();
+               for (p = ldaptcl->traplist; *p; p++) {
+                   Tcl_ListObjAppendElement(interp, listObj, 
+                       Tcl_NewStringObj(ldaptclerrorcode[*p], -1));
+               }
+               Tcl_ListObjAppendElement(interp, resultObj, listObj);
+           }
+           Tcl_SetObjResult(interp, resultObj);
+           return TCL_OK;
+       }
+       if (ldaptcl->trapCmdObj) {
+           Tcl_DecrRefCount (ldaptcl->trapCmdObj);
+           ldaptcl->trapCmdObj = NULL;
+       }
+       if (ldaptcl->traplist) {
+           free(ldaptcl->traplist);
+           ldaptcl->traplist = NULL;
+       }
+       Tcl_GetStringFromObj(objv[2], &l);
+       if (l == 0)
+           return TCL_OK;              /* just turn off trap */
+       ldaptcl->trapCmdObj = objv[2];
+       Tcl_IncrRefCount (ldaptcl->trapCmdObj);
+       if (objc < 4)
+           return TCL_OK;              /* no code list */
+       if (Tcl_ListObjLength(interp, objv[3], &l) != TCL_OK)
+           return TCL_ERROR;
+       if (l == 0)
+           return TCL_OK;              /* empty code list */
+       ldaptcl->traplist = (int*)malloc(sizeof(int) * (l + 1));
+       ldaptcl->traplist[l] = 0;
+       for (i = 0; i < l; i++) {
+           Tcl_ListObjIndex(interp, objv[3], i, &resultObj);
+           code = LDAP_ErrorStringToCode(interp, Tcl_GetStringFromObj(resultObj, NULL));
+           if (code == -1) {
+               free(ldaptcl->traplist);
+               ldaptcl->traplist = NULL;
+               return TCL_ERROR;
+           }
+           ldaptcl->traplist[i] = code;
+       }
+       return TCL_OK;
+    }
+    if (STREQU (subCommand, "trapcodes")) {
+       int code;
+       Tcl_Obj *resultObj;
+       Tcl_Obj *stringObj;
+       resultObj = Tcl_GetObjResult(interp);
+
+       for (code = 0; code < LDAPTCL_MAXERR; code++) {
+           if (!ldaptclerrorcode[code]) continue;
+           Tcl_ListObjAppendElement(interp, resultObj,
+                       Tcl_NewStringObj(ldaptclerrorcode[code], -1));
+       }
+       return TCL_OK;
+    }
 #ifdef LDAP_DEBUG
     if (STREQU (subCommand, "debug")) {
        if (objc != 3) {
@@ -948,8 +1128,12 @@ NeoX_LdapObjDeleteCmd(clientData)
     LDAPTCL      *ldaptcl = (LDAPTCL *)clientData;
     LDAP         *ldap = ldaptcl->ldap;
 
+    if (ldaptcl->trapCmdObj)
+       Tcl_DecrRefCount (ldaptcl->trapCmdObj);
+    if (ldaptcl->traplist)
+       free(ldaptcl->traplist);
     ldap_unbind(ldap);
-    ckfree((char*) ldaptcl);
+    free((char*) ldaptcl);
 }
 
 /*-----------------------------------------------------------------------------
@@ -1081,8 +1265,13 @@ NeoX_LdapObjCmd (clientData, interp, objc, objv)
     ldap->ld_deref = LDAP_DEREF_NEVER;  /* Turn off alias dereferencing */
 #endif
 
-    ldaptcl = (LDAPTCL *) ckalloc(sizeof(LDAPTCL));
+    ldaptcl = (LDAPTCL *) malloc(sizeof(LDAPTCL));
     ldaptcl->ldap = ldap;
+    ldaptcl->caching = 0;
+    ldaptcl->timeout = 0;
+    ldaptcl->maxmem = 0;
+    ldaptcl->trapCmdObj = NULL;
+    ldaptcl->traplist = NULL;
     ldaptcl->flags = 0;
 
     Tcl_CreateObjCommand (interp,
diff --git a/contrib/ldaptcl/tkAppInit.c b/contrib/ldaptcl/tkAppInit.c
new file mode 100644 (file)
index 0000000..68fd956
--- /dev/null
@@ -0,0 +1,119 @@
+/* 
+ * tkXAppInit.c --
+ *
+ * Provides a default version of the Tcl_AppInit procedure for use with
+ * applications built with Extended Tcl and Tk on Unix systems.  This is based
+ * on the the UCB Tk file tkAppInit.c
+ *-----------------------------------------------------------------------------
+ * Copyright 1991-1996 Karl Lehenbauer and Mark Diekhans.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies.  Karl Lehenbauer and
+ * Mark Diekhans make no representations about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or
+ * implied warranty.
+ *-----------------------------------------------------------------------------
+ * $OpenLDAP$
+ *-----------------------------------------------------------------------------
+ */
+
+#include "tclExtend.h"
+#include "tk.h"
+
+/*
+ * The following variable is a special hack that insures the tcl
+ * version of matherr() is used when linking against shared libraries
+ * Even if matherr is not used on this system, there is a dummy version
+ * in libtcl.
+ */
+EXTERN int matherr ();
+int (*tclDummyMathPtr)() = matherr;
+
+\f
+/*-----------------------------------------------------------------------------
+ * main --
+ *
+ * This is the main program for the application.
+ *-----------------------------------------------------------------------------
+ */
+#ifdef __cplusplus
+int
+main (int    argc,
+      char **argv)
+#else
+int
+main (argc, argv)
+    int    argc;
+    char **argv;
+#endif
+{
+#ifdef USE_TCLX
+    TkX_Main(argc, argv, Tcl_AppInit);
+#else
+    Tk_Main(argc, argv, Tcl_AppInit);
+#endif
+    return 0;                   /* Needed only to prevent compiler warning. */
+}
+\f
+/*-----------------------------------------------------------------------------
+ * Tcl_AppInit --
+ *
+ * This procedure performs application-specific initialization. Most
+ * applications, especially those that incorporate additional packages, will
+ * have their own version of this procedure.
+ *
+ * Results:
+ *    Returns a standard Tcl completion code, and leaves an error message in
+ * interp->result if an error occurs.
+ *-----------------------------------------------------------------------------
+ */
+#ifdef __cplusplus
+int
+Tcl_AppInit (Tcl_Interp *interp)
+#else
+int
+Tcl_AppInit (interp)
+    Tcl_Interp *interp;
+#endif
+{
+    if (Tcl_Init (interp) == TCL_ERROR) {
+        return TCL_ERROR;
+    }
+#ifdef USE_TCLX
+    if (Tclx_Init(interp) == TCL_ERROR) {
+        return TCL_ERROR;
+    }
+    Tcl_StaticPackage(interp, "Tclx", Tclx_Init, Tclx_SafeInit);
+#endif
+    if (Tk_Init(interp) == TCL_ERROR) {
+        return TCL_ERROR;
+    }
+    Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL);
+#ifdef USE_TCLX
+    if (Tkx_Init(interp) == TCL_ERROR) {
+        return TCL_ERROR;
+    }
+    Tcl_StaticPackage(interp, "Tkx", Tkx_Init, (Tcl_PackageInitProc *) NULL);
+#endif
+
+    if (Ldaptcl_Init(interp) == TCL_ERROR) {
+       return TCL_ERROR;
+    }
+    Tcl_StaticPackage(interp, "Ldaptcl", Ldaptcl_Init,
+            (Tcl_PackageInitProc *) NULL);
+
+    /*
+     * Call Tcl_CreateCommand for application-specific commands, if
+     * they weren't already created by the init procedures called above.
+     */
+
+    /*
+     * Specify a user-specific startup file to invoke if the application
+     * is run interactively.  Typically the startup file is "~/.apprc"
+     * where "app" is the name of the application.  If this line is deleted
+     * then no user-specific startup file will be run under any conditions.
+     */
+    Tcl_SetVar(interp, "tcl_rcFileName", "~/.wishxrc", TCL_GLOBAL_ONLY);
+    return TCL_OK;
+}
diff --git a/contrib/php3-tool/COPYRIGHT b/contrib/php3-tool/COPYRIGHT
new file mode 100644 (file)
index 0000000..755a0dd
--- /dev/null
@@ -0,0 +1,8 @@
+Copyright 1998,1999,2000 Predrag Balorda, London, UK
+All rights reserved.
+
+Redistribution and use in source and binary forms are permitted only
+as authorized by the OpenLDAP Public License.  A copy of this
+license is available at http://www.OpenLDAP.org/license.html or
+in file LICENSE in the top-level directory of the distribution.
+
diff --git a/contrib/php3-tool/index.php3 b/contrib/php3-tool/index.php3
new file mode 100644 (file)
index 0000000..c767776
--- /dev/null
@@ -0,0 +1,111 @@
+<!DOCTYPE PUBLIC HTML "-//W3C//HTML3.2 Final//En">
+<html>
+<head>
+       <!-- copyright, (C) Predrag Balorda, OpenLDAP Foundation, 1998,1999,2000 -->
+       <title>PHP3 Thingy</title>
+       <link rel="stylesheet" type="text/css" href="style.css">
+</head>
+<body>
+<?
+include ('include/preferences.inc');
+include ('include/ldap_manager.inc');
+include ('include/query_manager.inc');
+include ('include/search_form.inc');
+$FILE = "http://$HTTP_HOST$SCRIPT_NAME";
+$JPEGFILE = "http://$HTTP_HOST/ldap/php3-tool/ldap-photo.php3";
+$qm = new query_manager;
+$lm = new ldap_manager;
+$prefs = new preferences;
+
+function main() {
+       $main_start_time = microtime();
+       global $lm, $qm, $prefs, $FILE;
+       $qm = new query_manager;
+       $lm = new ldap_manager;
+       $prefs = new preferences;
+       $lm->ldap_action = $qm->get_action();
+       $lm->base_dn = $qm->get_base_dn();
+       $lm->host = $qm->get_host();
+       $lm->search_filter = $qm->get_search_filter();
+       $prefs->loadPreferences();
+       display_advanced_form();
+       if (!$lm->connect($lm->host)) {
+               echo "Couldn't connect to <b>".$lm->host."</b><br>\n";
+               echo "Bye";
+               return 0;
+       }
+       if (!$lm->ldapTakeAction($lm->ldap_action) || $lm->entriesCount == 0) {
+               echo "Didn't find anything for ".$lm->ldap_action." on ".$lm->search_filter." from ".$lm->base_dn."<br>\n";
+               return 0;
+       }
+       else {
+       //      echo "I got <b>".$lm->entriesCount."</b> entries for ".$lm->ldap_action." on ".$lm->search_filter." from ".$lm->base_dn."<br>\n";
+               $get_entries_s_t = microtime();
+               $lm->getEntries();
+               $get_entries_e_t = microtime();
+       //      echo "Disconnecting from <b>".$lm->host."</b><br>\n";
+               $lm->disconnect();
+       }
+       if (($qm->get_mode() == "tree") && ($lm->ldap_action == "list")) {
+               $display_entries_s_t = microtime();
+               ?><table width="100%" border=1 cellpadding=0 cellspacing=0>
+               <tr>
+                       <td bgcolor="#9380DB" align=center valign=absmiddle>
+                               <h3 class=head><?echo $lm->formatHTMLBaseDN($lm->base_dn);?></h3>
+                               </td>
+                       </tr>
+               </table>
+               <p>
+               <script language="JavaScript" src="javascript/expandable-outlines.js">
+               </script><?
+               $tokens = array( 0 => " ", 1 => ",");
+               $e = $lm->entries[0];
+               $s = ldap_dn2ufn($e->dn);
+               $firstel = $lm->stripString($s, $tokens);
+               for ($i=0; $i<count($lm->entries); $i++) {
+                       $c = "";
+                       $e = $lm->entries[$i];
+                       $s = ldap_dn2ufn($e->dn);
+                       $tin = $lm->stripString($s, $tokens);
+                       ?><div id="<? echo $tin; ?>Parent" class=parent>
+                       <h3 class=subsection>
+                       <a href="#" onClick="expandIt('<? echo $tin; ?>'); return false">
+                       <img name="imEx" src="false.gif" border=0 alt=""></a>
+                       <? $n = ldap_explode_dn($e->dn, 1); echo $n[0]; ?></h3>
+                       </div>
+                       <div id="<? echo $tin; ?>Child" class=child>
+                       <table border=1 cellspacing=0 cellpadding=0>
+                       <? $c .= $e->formatHTMLAttributes(); echo $c; ?>
+                       </table>
+                       <br>
+                       </div><?
+               }
+               ?><script language="JavaScript"><!--
+               if (NS4) {
+                       firstEl = "<? echo $firstel; ?>Parent";
+                       firstInd = getIndex(firstEl);
+                       showAll();
+                       arrange();
+               }
+               //--></script><?
+       }
+       else {
+               $display_entries_s_t = microtime();
+               $c = $lm->formatHTMLEntries();
+               echo $c;
+       }
+       $display_entries_e_t = microtime();
+//     echo "<div align=right valign=bottom>";
+//     $t1 = $lm->calculateTime("getEntries()", $get_entries_s_t, $get_entries_e_t);
+//     $t2 = $lm->calculateTime("displayEntries()", $display_entries_s_t, $display_entries_e_t);
+//     $main_end_time = microtime();
+//     $t3 = $lm->calculateTime("main()", $main_start_time, $main_end_time);
+//     $t = $t3 - ($t1 + $t2);
+//     echo "Ether : ".$t." seconds<br>\n";
+//     echo "</div>";
+       return 1;
+}
+$return = main();
+?>
+</body>
+</html>
index 3d5479968b1d4a1eb48a5812bd9237781d70c36a..ca810b5672a2780961b8e45ca42f2ae460d7815f 100644 (file)
@@ -17,7 +17,7 @@ saucer:       ${OBJS} $(LDAP_LIBDEPEND)
        $(LTLINK) -o $@ $(OBJS) $(LIBS)
 
 install-local: $(PROGRAMS) FORCE
-       -$(MKDIR) $(bindir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 saucer $(bindir)
-       -test -d $(MANDIR) || $(MKDIR) $(mandir) $(MANDIR)
-       $(INSTALL) $(INSTALLFLAGS) -m 644 $(srcdir)/saucer.1 $(MANDIR)/saucer.1
+       -$(MKDIR) $(DESTDIR)$(bindir)
+       $(LTINSTALL) $(INSTALLFLAGS) -m 755 saucer $(DESTDIR)$(bindir)
+       -$(MKDIR) $(DESTDIR)$(MANDIR)
+       $(INSTALL) $(INSTALLFLAGS) -m 644 $(srcdir)/saucer.1 $(DESTDIR)$(MANDIR)/saucer.1
index a49a3bf896a84cdb3b7f6132807550603e26f586..f736a70a21e413ba224a7fd558cd1ddc7db3ef02 100644 (file)
@@ -67,7 +67,7 @@ extern int    optind;
 int                    option;
 int                    portnum = LDAP_PORT;
 char           *progname;
-char           true_filter[] = "objectClass=*";        /* Always succeeds */
+char           true_filter[] = "(objectClass=*)";      /* Always succeeds */
 char           *username;
 
 int                    cmd_help(char **cmdargv, int cmdargc);
index 218a65d074dd70637e9273fa20f486a7b91d0aa1..bbb9ba4b2713a85d4f09b3a75c7ac34b378eeba9 100644 (file)
@@ -15,7 +15,7 @@
 #            Creation date:                Z   D  D   V   V                *
 #            August 16 1995               Z    D   D   V V                 *
 #            Last modification:          Z     D  D    V V                 *
-#            September 9 1999           ZZZZ   DDD      V                  *
+#            September 13 1999          ZZZZ   DDD      V                  *
 #                                                                          *
 #/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/*/
 #-----------------------------------------------------------------------------
 #########################################################################
 
 # where is your LDAP client library located
-LDAP_RUNTIME=/LDAP
-LDAP_SOURCE =/LDAP/ldap-3.3
+# WE NEED portable.h AND ldap_log.h, SO POINT TO THE SOURCE TREE
+LDAP_RUNTIME=../..
+LDAP_SOURCE =../..
 
-LIBDIR= $(LDAP_RUNTIME)/lib
+LIBDIR= $(LDAP_RUNTIME)/libraries
 INCDIR= $(LDAP_RUNTIME)/include
 
 # where is some version information for your LDAP client library
index 91b088d5fe6e3c7238defea58b717516a2af0aec..ddda6edb0fc75102cc3f9d4147bb19021d4c3bff 100644 (file)
@@ -14,7 +14,7 @@
 *            Creation date:                Z   D  D   V   V                *
 *            September 14 1995            Z    D   D   V V                 *
 *            Last modification:          Z     D  D    V V                 *
-*            January 19 1999            ZZZZ   DDD      V                  *
+*            September 13 1999          ZZZZ   DDD      V                  *
 *                                                                          *
 _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/*/
 
@@ -69,6 +69,19 @@ INSTALLATION
    several configuration parameters TWEB provides for runtime
    configuration of the program.
 
+   SINCE THE CODE IS ONLY THE CORE GATEWAY, WITH SOME PRIVATE EXTENSIONS
+   NOT INCLUDED INTO THAT DISTRIBUTION, DO NOT DELETE CODE BETWEEN
+
+      #ifdef TUE_TEL
+      #endif
+
+   AND
+
+     #ifdef AMBIXGW
+     #endif
+
+   IN ANY OF THE SUPPORTED FILES !!!
+
 
 SUPPORT
 
index 7518372cbefc0c84dbf828875a0e3be9ecdcb2ba..86060bbfe93a9ea741cdc081847beabac9f3781b 100644 (file)
 *            Creation date:                Z   D  D   V   V                *
 *            April 24 1996                Z    D   D   V V                 *
 *            Last modification:          Z     D  D    V V                 *
-*            December 14 1996           ZZZZ   DDD      V                  *
+*            September 13 1999          ZZZZ   DDD      V                  *
 *                                                                          *
 _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_*/
 
 /*
- * $Id: dn.c,v 1.6 1999/09/10 15:01:16 zrnsk01 Exp $
+ * $Id: dn.c,v 1.8 1999/09/13 13:47:44 zrnsk01 Exp $
  *
  */
 
 /* dn.c - routines for dealing with distinguished names */
 
 #include "tgeneral.h"
+#include "tglobal.h"
 #include "strng_exp.h"
 #include "dn.h"
 
+#if OL_LDAPV == 2
+#define LDAP_DEBUG_ANY  0xffff
+#endif
+
+
 /*
  * dn_normalize - put dn into a canonical format.  the dn is
  * normalized in place, as well as returned.
@@ -119,10 +125,7 @@ char *dn;
                        break;
                default:
 
-#if defined LDAP_VENDOR_NAME && defined LDAP_API_VERSION
-#  if LDAP_API_VERSION > 2001 && LDAP_API_VERSION < 2010
-
-#    define LDAP_DEBUG_ANY  0xffff
+#if OL_LDAPV >= 2
 
             if ( ldap_debug & LDAP_DEBUG_ANY )
                 fprintf( stderr, "dn_normalize - unknown state %d\n", state );
@@ -131,7 +134,6 @@ char *dn;
                 syslog( ldap_syslog_level,
                              "dn_normalize - unknown state %d\n", state );
 
-#  endif
 #else
                        Debug( LDAP_DEBUG_ANY,
                            "dn_normalize - unknown state %d\n", state, 0, 0 );
index 7406c624bf236ede8df756284b05d485f4900a77..abaa35d14cd1607baf112c550eefafa01cb59849 100644 (file)
@@ -252,7 +252,7 @@ GLOB_STRUCT *glob;
         char            *cPtr, *ptype;
     char            *tattr;
 
-    if ( (rc = ldap_search_s( ld, dn, LDAP_SCOPE_BASE, "objectClass=*",
+    if ( (rc = ldap_search_s( ld, dn, LDAP_SCOPE_BASE, NULL,
         NULL, 0, &res )) != LDAP_SUCCESS ) {
         do_error(fp, rc, NOT_FOUND, glob);
         return;
@@ -342,7 +342,7 @@ GLOB_STRUCT *glob;
 
     timeout.tv_sec = glob->timeout;
     timeout.tv_usec = 0;
-    if ( (rc = ldap_search_st( ld, dn, LDAP_SCOPE_BASE, "objectClass=*",
+    if ( (rc = ldap_search_st( ld, dn, LDAP_SCOPE_BASE, NULL,
         NULL, 0, &timeout, &res )) != LDAP_SUCCESS ) {
         do_error(fp, rc, NOT_FOUND, glob);
         return;
index 1e0ebb40cc4588a03a5bf74e1e507387ccb27738..5c194484653c8d88ab06514a592dce347881a1be 100644 (file)
 *            Creation date:                Z   D  D   V   V                *
 *            August 16 1995               Z    D   D   V V                 *
 *            Last modification:          Z     D  D    V V                 *
-*            May 11 1999                ZZZZ   DDD      V                  *
+*            September 13 1999          ZZZZ   DDD      V                  *
 *                                                                          *
 _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_*/
 
 /*
- * $Id: queries.c,v 1.6 1999/09/10 15:01:18 zrnsk01 Exp $
+ * $Id: queries.c,v 1.8 1999/09/13 13:47:47 zrnsk01 Exp $
  *
  */
 
@@ -43,6 +43,10 @@ struct hostent *hp;
     LDAP        *ld;
     char tstring[100];
 
+#if OL_LDAPV > 0
+       int ldap_opt;
+#endif
+
     /* get time for performance log */
     gettimeofday(&timestore[2], NULL);
 
@@ -85,7 +89,13 @@ struct hostent *hp;
     len = strlen( buf );
     if ( debug ) {
         fprintf( stderr, "got %d bytes\n", len );
+
+#if OL_LDAPV > 2
+        ber_bprint( buf, len );
+#else
         lber_bprint( buf, len );
+#endif
+
     }
 
     /* strip of white spaces */
@@ -309,23 +319,21 @@ struct hostent *hp;
             rewind(fp);
 
             /*  follow aliases while searching */
-#if defined LDAP_VENDOR_NAME && defined LDAP_API_VERSION
-#  if LDAP_API_VERSION > 2001 && LDAP_API_VERSION < 2010
+#if OL_LDAPV > 0
 
-            ldap_set_option( ld, LDAP_OPT_DEREF, LDAP_DEREF_ALWAYS );
+                       ldap_opt = LDAP_DEREF_ALWAYS;
+            ldap_set_option( ld, LDAP_OPT_DEREF, &ldap_opt );
 
-#  endif
 #else
             ld->ld_deref = LDAP_DEREF_ALWAYS;
 #endif
 
             if ( !searchaliases )
-#if defined LDAP_VENDOR_NAME && defined LDAP_API_VERSION
-#  if LDAP_API_VERSION > 2001 && LDAP_API_VERSION < 2010
+#if OL_LDAPV > 0
 
-            ldap_set_option( ld, LDAP_OPT_DEREF, LDAP_DEREF_FINDING );
+                       ldap_opt = LDAP_DEREF_FINDING;
+            ldap_set_option( ld, LDAP_OPT_DEREF, &ldap_opt );
 
-#  endif
 #else
                      ld->ld_deref = LDAP_DEREF_FINDING;
 #endif
@@ -376,32 +384,29 @@ struct hostent *hp;
                                glob->svc_cnt);
 
     /*  accesses with resolvation of alias-entries */
-#if defined LDAP_VENDOR_NAME && defined LDAP_API_VERSION
-#  if LDAP_API_VERSION > 2001 && LDAP_API_VERSION < 2010
+#if OL_LDAPV > 0
 
-    ldap_set_option( ld, LDAP_OPT_DEREF, LDAP_DEREF_ALWAYS );
+                       ldap_opt = LDAP_DEREF_ALWAYS;
+            ldap_set_option( ld, LDAP_OPT_DEREF, &ldap_opt );
 
-#  endif
 #else
     ld->ld_deref = LDAP_DEREF_ALWAYS;
 #endif
 
     if ( !searchaliases )
-#if defined LDAP_VENDOR_NAME && defined LDAP_API_VERSION
-#  if LDAP_API_VERSION > 2001 && LDAP_API_VERSION < 2010
+#if OL_LDAPV > 0
 
-             ldap_set_option( ld, LDAP_OPT_DEREF, LDAP_DEREF_FINDING );
+                       ldap_opt = LDAP_DEREF_FINDING;
+            ldap_set_option( ld, LDAP_OPT_DEREF, &ldap_opt );
 
-#  endif
 #else
              ld->ld_deref = LDAP_DEREF_FINDING;
 #endif
     
     /*  bind to DSA by order of the user as Web-DN
-        (if with DN1 or DN2 was decided at check4access) */
+        (DN1 or DN2 was decided at check4access) */
 
-#if defined LDAP_VENDOR_NAME && defined LDAP_API_VERSION
-#  if LDAP_API_VERSION > 2001 && LDAP_API_VERSION < 2010
+#if OL_LDAPV > 0
 
     /*  a dummy call as long as socket connections are not settled
      *  with OpenLDAP
@@ -409,12 +414,6 @@ struct hostent *hp;
     if ( dosyslog )
            syslog( LOG_INFO, "do_queries(): calling ldap_simple_bind_s()...\n" );
 
-#  else
-
-    if ( dosyslog )
-           syslog( LOG_INFO, "do_queries(): calling ldap_simple_bind_s()...\n" );
-
-#  endif
 #endif
 
     if ( (rc=ldap_simple_bind_s( ld, glob->webdn, glob->webpw ))
index 4eb0adcbf890d41a3abd29df572c01d596337681..bdaf57be7fd1f84725643fdd354033ae237adec0 100644 (file)
 *            Creation date:                Z   D  D   V   V                *
 *            August 16 1995               Z    D   D   V V                 *
 *            Last modification:          Z     D  D    V V                 *
-*            May 14 1999                ZZZZ   DDD      V                  *
+*            September 13 1999          ZZZZ   DDD      V                  *
 *                                                                          *
 _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_*/
 
 /*
- * $Id: tgeneral.h,v 1.6 1999/09/10 15:01:20 zrnsk01 Exp $
+ * $Id: tgeneral.h,v 1.8 1999/09/13 13:47:47 zrnsk01 Exp $
  *
  */
 
@@ -68,6 +68,24 @@ _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_*/
 #include <stdlib.h>
 #include <unistd.h>
 
+/*  Support of LDAP API versions */
+#if LDAP_API_VERSION >= 2003 && LDAP_API_VERSION <= 2010
+#define OL_LDAPV               3
+#else
+#  if LDAP_API_VERSION >= 2001 && LDAP_API_VERSION <= 2010
+#  define OL_LDAPV             2
+#  else
+#    define OL_LDAPV   0
+#  endif
+#endif
+
+#  define ldap_debug debug
+
+#if OL_LDAPV > 2
+#  include "portable.h"
+#  include "ldap_log.h"
+#endif
+
 extern   int   errno;
 
 
index f115592ad58ddcf75f3af948fce17107320908c2..147c32049b0779db3d8623a6237aa87e670e69da 100644 (file)
 *            Creation date:                Z   D  D   V   V                *
 *            August 16 1996               Z    D   D   V V                 *
 *            Last modification:          Z     D  D    V V                 *
-*            December 29 1998           ZZZZ   DDD      V                  *
+*            September 13 1999          ZZZZ   DDD      V                  *
 *                                                                          *
 _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_*/
 
 /*
- * $Id: tglobal.h,v 1.6 1999/09/10 15:01:20 zrnsk01 Exp $
+ * $Id: tglobal.h,v 1.8 1999/09/13 13:47:47 zrnsk01 Exp $
  *
  */
 
@@ -32,21 +32,18 @@ _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_*/
 
 extern int     debug;
 extern int     dosyslog;
+extern int  ldap_syslog;
+extern int  ldap_syslog_level;
+
 extern struct timeval timestore[];
 extern int items_displayed;
 
 extern int             searchaliases;
 
-#if defined LDAP_VENDOR_NAME && defined LDAP_API_VERSION
-#  if LDAP_API_VERSION > 2001 && LDAP_API_VERSION < 2010
-
-extern LDAPFriendlyMap      *fm;
-
-#  else
+#if OL_LDAPV >= 2
 
 extern LDAPFriendlyMap      *fm;
 
-#  endif
 #else
 
 extern FriendlyMap      *fm;
index fe1d49ec61b4ec8dc05f6fb21dbbf65f8ff36c52..1c6869e851b8e765ca8295badf3f07ef6372f811 100644 (file)
 *            Creation date:                Z   D  D   V   V                *
 *            August 16 1995               Z    D   D   V V                 *
 *            Last modification:          Z     D  D    V V                 *
-*            December 31 1998           ZZZZ   DDD      V                  *
+*            September 13 1999          ZZZZ   DDD      V                  *
 *                                                                          *
 _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_*/
 
 /*
- * $Id: tweb.h,v 1.6 1999/09/10 15:01:20 zrnsk01 Exp $
+ * $Id: tweb.h,v 1.8 1999/09/13 13:47:47 zrnsk01 Exp $
  *
  */
 
@@ -34,23 +34,20 @@ _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_*/
 #include "support_exp.h"
 
 PRIVATE void do_child();
-int    debug;
+int    debug                 = 0;
+int ldap_syslog           = 0;
+int ldap_syslog_level     = 0;
+
 int    dosyslog = 0;
 
 GLOB_STRUCT *globP;
 
 int            searchaliases = 1;
 
-#if defined LDAP_VENDOR_NAME && defined LDAP_API_VERSION
-#  if LDAP_API_VERSION > 2001 && LDAP_API_VERSION < 2010
-
-LDAPFriendlyMap     *fm = NULL;
-
-#  else
+#if OL_LDAPV >= 2
 
 LDAPFriendlyMap     *fm = NULL;
 
-#  endif
 #else
 
 FriendlyMap     *fm = NULL;
index a8a02f70a2155e5c85b1f6179cdfd5cc30b70daf..447060fbdef3b6a951164242d8400b9a8a774272 100644 (file)
 *            Creation date:                Z   D  D   V   V                *
 *            August 16 1995               Z    D   D   V V                 *
 *            Last modification:          Z     D  D    V V                 *
-*            September 10 1999          ZZZZZ  DDD      V                  *
+*            September 13 1999          ZZZZZ  DDD      V                  *
 *                                                                          *
 _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_*/
 
 /*
- * $Id: x500.c,v 1.8 1999/09/10 15:01:20 zrnsk01 Exp $
+ * $Id: x500.c,v 1.10 1999/09/13 13:47:48 zrnsk01 Exp $
  *
  */
 
@@ -143,6 +143,10 @@ GLOB_STRUCT *glob;
     int count;
     char           *ufn;
 
+#if OL_LDAPV > 0
+       int         ldap_opt;
+#endif
+
     if(!attrs)
         attrs = (char**) charray_dup(sattrs);
 
@@ -162,12 +166,11 @@ GLOB_STRUCT *glob;
         timeout.tv_sec = glob->timeout;
         timeout.tv_usec = 0;
 
-#if defined LDAP_VENDOR_NAME && defined LDAP_API_VERSION
-#  if LDAP_API_VERSION > 2001 && LDAP_API_VERSION < 2010
+#if OL_LDAPV > 0
 
-        ldap_set_option( ld, LDAP_OPT_DEREF, LDAP_DEREF_ALWAYS );
+               ldap_opt = LDAP_DEREF_FINDING;
+        ldap_set_option( ld, LDAP_OPT_DEREF, &ldap_opt );
 
-#  endif
 #else
         ld->ld_deref = LDAP_DEREF_FINDING;
 #endif
@@ -182,12 +185,11 @@ GLOB_STRUCT *glob;
 
         if (rc == LDAP_SIZELIMIT_EXCEEDED) glob->persRestricted = TRUE;
 
-#if defined LDAP_VENDOR_NAME && defined LDAP_API_VERSION
-#  if LDAP_API_VERSION > 2001 && LDAP_API_VERSION < 2010
+#if OL_LDAPV > 0
 
-        ldap_set_option( ld, LDAP_OPT_DEREF, LDAP_DEREF_ALWAYS );
+               ldap_opt = LDAP_DEREF_ALWAYS;
+        ldap_set_option( ld, LDAP_OPT_DEREF, &ldap_opt );
 
-#  endif
 #else
         ld->ld_deref = LDAP_DEREF_ALWAYS;
 #endif
@@ -348,6 +350,10 @@ GLOB_STRUCT *glob;
     char               *ufn;
     char title[BUFSIZ], title2[BUFSIZ];
 
+#if OL_LDAPV > 0
+       int         ldap_opt;
+#endif
+
     glob->no_browse = FALSE;
     
 /* query string: base-DN?[OS]=filter 
@@ -384,14 +390,12 @@ GLOB_STRUCT *glob;
     filtertype = (scope == LDAP_SCOPE_ONELEVEL ? "web500gw onelevel" :
         "web500gw subtree");
 
-#if defined LDAP_VENDOR_NAME && defined LDAP_API_VERSION
-#  if LDAP_API_VERSION > 2001 && LDAP_API_VERSION < 2010
+#if OL_LDAPV > 0
 
-        ldap_set_option( ld, LDAP_OPT_DEREF,
-                          scope == LDAP_SCOPE_ONELEVEL ? LDAP_DEREF_FINDING :
-                                   LDAP_DEREF_ALWAYS );
+               ldap_opt = ( scope == LDAP_SCOPE_ONELEVEL ? LDAP_DEREF_FINDING :
+                                                LDAP_DEREF_ALWAYS );
+        ldap_set_option( ld, LDAP_OPT_DEREF, &ldap_opt );
 
-#  endif
 #else
     ld->ld_deref = (scope == LDAP_SCOPE_ONELEVEL ? LDAP_DEREF_FINDING :
                                                   LDAP_DEREF_ALWAYS);
@@ -408,8 +412,7 @@ GLOB_STRUCT *glob;
 
             if (dosyslog) {
 
-#if defined LDAP_VENDOR_NAME && defined LDAP_API_VERSION
-#  if LDAP_API_VERSION > 2001 && LDAP_API_VERSION < 2010
+#if OL_LDAPV > 0
 
                 int ld_errno;
 
@@ -417,7 +420,6 @@ GLOB_STRUCT *glob;
                 syslog (LOG_INFO, "ldap_search_st(): %s",
                     ldap_err2string ( ld_errno ));
 
-#  endif
 #else
                 syslog (LOG_INFO, "ldap_search_st(): %s",
                     ldap_err2string (ld->ld_errno));
@@ -437,12 +439,11 @@ GLOB_STRUCT *glob;
     }
     items_displayed = count;
 
-#if defined LDAP_VENDOR_NAME && defined LDAP_API_VERSION
-#  if LDAP_API_VERSION > 2001 && LDAP_API_VERSION < 2010
+#if OL_LDAPV > 0
 
-        ldap_set_option( ld, LDAP_OPT_DEREF, LDAP_DEREF_ALWAYS );
+               ldap_opt = LDAP_DEREF_ALWAYS;
+        ldap_set_option( ld, LDAP_OPT_DEREF, &ldap_opt );
 
-#  endif
 #else
     ld->ld_deref = LDAP_DEREF_ALWAYS;
 #endif
@@ -1660,6 +1661,10 @@ GLOB_STRUCT *glob;
     char *url = NULL;
     char **uri = NULL, *urlnola, raw_string[BUFSIZ];
 
+#if OL_LDAPV > 0
+       int         ldap_opt;
+#endif
+
     oc = ldap_get_values( ld, e, "objectClass" );
 
     if(!(aoc = make_oc_to_string(oc))) return;
@@ -1816,12 +1821,11 @@ GLOB_STRUCT *glob;
             timeout.tv_sec = glob->timeout;
             timeout.tv_usec = 0;
     
-#if defined LDAP_VENDOR_NAME && defined LDAP_API_VERSION
-#  if LDAP_API_VERSION > 2001 && LDAP_API_VERSION < 2010
+#if OL_LDAPV > 0
 
-        ldap_set_option( ld, LDAP_OPT_DEREF, LDAP_DEREF_ALWAYS );
+               ldap_opt = LDAP_DEREF_ALWAYS;
+        ldap_set_option( ld, LDAP_OPT_DEREF, &ldap_opt );
 
-#  endif
 #else
             ld->ld_deref = LDAP_DEREF_ALWAYS;
 #endif
index 0157d0f452cf84132739f6ce67eb2abf29240708..1b3d64f47d0c5bf3f5dd951477e9ab57be29b181 100644 (file)
@@ -13,6 +13,6 @@ web_ldap: ${OBJS} $(LDAP_LIBDEPEND)
        $(LTLINK) -o $@ $(OBJS) $(LIBS)
 
 install-local: $(PROGRAMS) FORCE
-       -test -d $(libexecdir) || $(MKDIR) $(libexecdir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 web_ldap $(libexecdir)
+       -$(MKDIR) $(DESTDIR)$(libexecdir)
+       $(LTINSTALL) $(INSTALLFLAGS) -m 755 web_ldap $(DESTDIR)$(libexecdir)
        @echo ">> You must copy and edit web_ldap.cfg and web_ldap.html as needed. <<"
index a2f9b2eccc710312c03df0c227d73bad7742c1a5..1c29f747a5b8eb2ed3df7be756c793ac592812b7 100644 (file)
@@ -19,10 +19,17 @@ FACILITY    = LOG_LOCAL3
 #
 #SYSLIBS       = -li -lsyslog
 #
+# If you want POSIX international support (format of dates), on ultrix
+#
+#INTERNATIONAL = -DINTERNATIONAL
+#
 # If you want RFC931 logging you must have log_tcp source available
 #
+#RFC931DEF     = -DRFC931
+#RFC931SRC     = /local/src/log_tcp/rfc931.c
+
 SRCS   = whois++.c command.c config.c describe.c help.c output.c template.c \
-         util.c version.c # /local/src/log_tcp/rfc931.c
+         util.c version.c $(RFC931SRC)
 HDRS   = whois++.h
 OBJS   = ${SRCS:.c=.o}
 HOST   = `hostname`
@@ -36,7 +43,8 @@ DEFINES = -DETCDIR=\"$(ETCDIR)\" -DBUILD="\"$(USER)@$(HOST) on $(DATE)\"" \
          -DCONFIG_DIRECTORY=\"$(CONFIG_DIRECTORY)\" -DMAIN \
          -DHELP_DIRECTORY=\"$(HELP_DIRECTORY)\" -DREVISION="$(REVISION)" \
          -DPROTOCOL="\"[FIRST DRAFT - 15 April 1993]\"" -DRELEASE=\"BETA\" \
-         -DFACILITY=$(FACILITY) -DDEFAULT_LDAPHOST=\"$(LDAPHOST)\" # -DRFC931
+         -DFACILITY=$(FACILITY) -DDEFAULT_LDAPHOST=\"$(LDAPHOST)\" \
+         $(INTERNATIONAL) $(RFC931DEF)
 
 CFLAGS = -I$(LDAPSRC)/include -I/usr/local/include $(ACFLAGS)
 LIBS   = -L$(LDAPSRC)/libraries/libldap -lldap -L$(LDAPSRC)/libraries/liblber \
@@ -52,16 +60,17 @@ whois++.o:  whois++.c $(HDRS)
 
 install:       inst-whois++
 
-inst-whois++:  $(ETCDIR)/whois++d
-       -mkdir -p $(CONFIG_DIRECTORY)
-       cp -r templates $(CONFIG_DIRECTORY)
-       -mkdir -p $(HELP_DIRECTORY)
-       cp -r helpfiles/* $(HELP_DIRECTORY)
-       sed -e 's#ETCDIR#$(ETCDIR)#' whois++d.man > $(MANDIR)/man$(MANSEC)/whois++d.$(MANSEC)
+inst-whois++: $(DESTDIR)$(ETCDIR)/whois++d
+       -$(MKDIR) $(DESTDIR)$(CONFIG_DIRECTORY)
+       cp -r templates $(DESTDIR)$(CONFIG_DIRECTORY)
+       -$(MKDIR) $(DESTDIR)$(HELP_DIRECTORY)
+       cp -r helpfiles/* $(DESTDIR)$(HELP_DIRECTORY)
+       -$(MKDIR) $(DESTDIR)$(MANDIR)/man$(MANSEC)
+       sed -e 's#ETCDIR#$(ETCDIR)#' whois++d.man > $(DESTDIR)$(MANDIR)/man$(MANSEC)/whois++d.$(MANSEC)
        @echo "Don't forget to modify and install the tailor file"
 
-$(ETCDIR)/whois++d:    whois++d
-       install -c -m 755 whois++d $(ETCDIR)
+$(DESTDIR)$(ETCDIR)/whois++d: whois++d
+       install -c -m 755 whois++d $(DESTDIR)$(ETCDIR)
 
 lint:;
        lint $(SRCS)
index ce807193e21db96656fd96c4678e465d93bfa2ae..d353408a9423df7d16e77c4d8eb9dc9a07f830cb 100644 (file)
@@ -53,6 +53,7 @@ char  **argv;
        struct hostent          *hp;
        static struct sockaddr  sa;
        struct sockaddr_in      *sin = (struct sockaddr_in *) (&sa);
+       /* #### length should be socklen_t when we include portable.h #### */
        int                     length = sizeof(sa);
        static char             options[] = "[-b searchbase] [-d debug ] \
 [-h ldaphost ] [-i] [-l] [-s sizelimit] [-t timelimit] [-T tailorfile ] \
@@ -178,10 +179,10 @@ char      **argv;
                }
        }
 
-       if ( (ld = ldap_open( ldaphost, LDAP_PORT )) == NULL ) {
+       if ( (ld = ldap_init( ldaphost, LDAP_PORT )) == NULL ) {
                printFormatted( lineLength, TRUE, stdout,
                        "Connection to LDAP port on %s has failed", ldaphost );
-               syslog( LOG_ERR, "Connection to LDAP port on %s has failed",
+               syslog( LOG_ERR, "Initialization of LDAP session (%s)",
                        ldaphost );
                exit( 1 );
        }
@@ -194,13 +195,6 @@ char       **argv;
        case LDAP_SUCCESS:
                break;
 
-       case LDAP_UNAVAILABLE:
-               printFormatted( lineLength, TRUE, stdout,
-                       "Sorry, the X.500 service is temporarily unavailable. \
-Please try again later." );
-               syslog( LOG_NOTICE, "X.500 service temporarily unavailable" );
-               exit( 1 );
-
        default:
                printFormatted( lineLength, TRUE, stdout,
                        "Bind to Directory failed, %s",
@@ -220,7 +214,7 @@ Please try again later." );
                exit( 1 );
        }
        entry = ldap_first_entry( ld, result );
-       organisation = strdup( ldap_dn2ufn( ldap_get_dn( ld, entry ) ) );
+       organisation = ldap_dn2ufn( ldap_get_dn( ld, entry ) );
        category = ldap_get_values( ld, entry, "businessCategory" );
 
        printFormatted( lineLength, FALSE, stdout,
index 754eee763d458edddb0705ecf87bca4baaa22f8f..d292b0480f01ecc36dcf2cfe651f26fce2b98c8a 100644 (file)
@@ -1,5 +1,5 @@
 # $OpenLDAP$
-## Copyright 1998 The OpenLDAP Foundation, All Rights Reserved.
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
 ## COPYING RESTRICTIONS APPLY, See COPYRIGHT file
 ##
 ## doc Makefile.in for OpenLDAP
diff --git a/doc/devel/asn-layman.txt b/doc/devel/asn-layman.txt
new file mode 100644 (file)
index 0000000..d4fbe64
--- /dev/null
@@ -0,0 +1,1855 @@
+A Layman's Guide to a Subset of ASN.1, BER, and DER
+
+An RSA Laboratories Technical Note
+Burton S. Kaliski Jr.
+Revised November 1, 1993
+
+
+Supersedes June 3, 1991 version, which was also published as
+NIST/OSI Implementors' Workshop document SEC-SIG-91-17.
+PKCS documents are available by electronic mail to
+<pkcs@rsa.com>.
+
+Copyright (C) 1991-1993 RSA Laboratories, a division of RSA
+Data Security, Inc. License to copy this document is granted
+provided that it is identified as "RSA Data Security, Inc.
+Public-Key Cryptography Standards (PKCS)" in all material
+mentioning or referencing this document.
+003-903015-110-000-000
+
+
+Abstract. This note gives a layman's introduction to a
+subset of OSI's Abstract Syntax Notation One (ASN.1), Basic
+Encoding Rules (BER), and Distinguished Encoding Rules
+(DER). The particular purpose of this note is to provide
+background material sufficient for understanding and
+implementing the PKCS family of standards.
+
+
+1. Introduction
+
+It is a generally accepted design principle that abstraction
+is a key to managing software development. With abstraction,
+a designer can specify a part of a system without concern
+for how the part is actually implemented or represented.
+Such a practice leaves the implementation open; it
+simplifies the specification; and it makes it possible to
+state "axioms" about the part that can be proved when the
+part is implemented, and assumed when the part is employed
+in another, higher-level part. Abstraction is the hallmark
+of most modern software specifications.
+
+One of the most complex systems today, and one that also
+involves a great deal of abstraction, is Open Systems
+Interconnection (OSI, described in X.200). OSI is an
+internationally standardized architecture that governs the
+interconnection of computers from the physical layer up to
+the user application layer. Objects at higher layers are
+defined abstractly and intended to be implemented with
+objects at lower layers. For instance, a service at one
+layer may require transfer of certain abstract objects
+between computers; a lower layer may provide transfer
+services for strings of ones and zeroes, using encoding
+rules to transform the abstract objects into such strings.
+OSI is called an open system because it supports many
+different implementations of the services at each layer.
+
+OSI's method of specifying abstract objects is called ASN.1
+(Abstract Syntax Notation One, defined in X.208), and one
+set of rules for representing such objects as strings of
+ones and zeros is called the BER (Basic Encoding Rules,
+defined in X.209). ASN.1 is a flexible notation that allows
+one to define a variety data types, from simple types such
+as integers and bit strings to structured types such as sets
+and sequences, as well as complex types defined in terms of
+others. BER describes how to represent or encode values of
+each ASN.1 type as a string of eight-bit octets. There is
+generally more than one way to BER-encode a given value.
+Another set of rules, called the Distinguished Encoding
+Rules (DER), which is a subset of BER, gives a unique
+encoding to each ASN.1 value.
+
+The purpose of this note is to describe a subset of ASN.1,
+BER and DER sufficient to understand and implement one OSI-
+based application, RSA Data Security, Inc.'s Public-Key
+Cryptography Standards. The features described include an
+overview of ASN.1, BER, and DER and an abridged list of
+ASN.1 types and their BER and DER encodings. Sections 2-4
+give an overview of ASN.1, BER, and DER, in that order.
+Section 5 lists some ASN.1 types, giving their notation,
+specific encoding rules, examples, and comments about their
+application to PKCS. Section 6 concludes with an example,
+X.500 distinguished names.
+
+Advanced features of ASN.1, such as macros, are not
+described in this note, as they are not needed to implement
+PKCS. For information on the other features, and for more
+detail generally, the reader is referred to CCITT
+Recommendations X.208 and X.209, which define ASN.1 and BER.
+
+Terminology and notation. In this note, an octet is an eight-
+bit unsigned integer. Bit 8 of the octet is the most
+significant and bit 1 is the least significant.
+
+The following meta-syntax is used for in describing ASN.1
+notation:
+
+     BIT  monospace denotes literal characters in the type
+          and value notation; in examples, it generally
+          denotes an octet value in hexadecimal
+
+     n1   bold italics denotes a variable
+
+     []   bold square brackets indicate that a term is
+          optional
+
+     {}   bold braces group related terms
+
+     |    bold vertical bar delimits alternatives with a
+          group
+
+     ...  bold ellipsis indicates repeated occurrences
+
+     =    bold equals sign expresses terms as subterms
+
+
+2. Abstract Syntax Notation One
+
+Abstract Syntax Notation One, abbreviated ASN.1, is a
+notation for describing abstract types and values.
+
+In ASN.1, a type is a set of values. For some types, there
+are a finite number of values, and for other types there are
+an infinite number. A value of a given ASN.1 type is an
+element of the type's set. ASN.1 has four kinds of type:
+simple types, which are "atomic" and have no components;
+structured types, which have components; tagged types, which
+are derived from other types; and other types, which include
+the CHOICE type and the ANY type. Types and values can be
+given names with the ASN.1 assignment operator (::=) , and
+those names can be used in defining other types and values.
+
+Every ASN.1 type other than CHOICE and ANY has a tag, which
+consists of a class and a nonnegative tag number. ASN.1
+types are abstractly the same if and only if their tag
+numbers are the same. In other words, the name of an ASN.1
+type does not affect its abstract meaning, only the tag
+does. There are four classes of tag:
+
+     Universal, for types whose meaning is the same in all
+          applications; these types are only defined in
+          X.208.
+
+     Application, for types whose meaning is specific to an
+          application, such as X.500 directory services;
+          types in two different applications may have the
+          same application-specific tag and different
+          meanings.
+
+     Private, for types whose meaning is specific to a given
+          enterprise.
+
+     Context-specific, for types whose meaning is specific
+          to a given structured type; context-specific tags
+          are used to distinguish between component types
+          with the same underlying tag within the context of
+          a given structured type, and component types in
+          two different structured types may have the same
+          tag and different meanings.
+
+The types with universal tags are defined in X.208, which
+also gives the types' universal tag numbers. Types with
+other tags are defined in many places, and are always
+obtained by implicit or explicit tagging (see Section 2.3).
+Table 1 lists some ASN.1 types and their universal-class
+tags.
+
+    Type                     Tag number     Tag number
+                             (decimal)      (hexadecimal)
+    INTEGER                  2              02
+    BIT STRING               3              03
+    OCTET STRING             4              04
+    NULL                     5              05
+    OBJECT IDENTIFIER        6              06
+    SEQUENCE and SEQUENCE OF 16             10
+    SET and SET OF           17             11
+    PrintableString          19             13
+    T61String                20             14
+    IA5String                22             16
+    UTCTime                  23             17
+
+     Table 1. Some types and their universal-class tags.
+
+ASN.1 types and values are expressed in a flexible,
+programming-language-like notation, with the following
+special rules:
+
+     o    Layout is not significant; multiple spaces and
+          line breaks can be considered as a single space.
+
+     o    Comments are delimited by pairs of hyphens (--),
+          or a pair of hyphens and a line break.
+
+     o    Identifiers (names of values and fields) and type
+          references (names of types) consist of upper- and
+          lower-case letters, digits, hyphens, and spaces;
+          identifiers begin with lower-case letters; type
+          references begin with upper-case letters.
+
+The following four subsections give an overview of simple
+types, structured types, implicitly and explicitly tagged
+types, and other types. Section 5 describes specific types
+in more detail.
+
+
+2.1 Simple types
+
+Simple types are those not consisting of components; they
+are the "atomic" types. ASN.1 defines several; the types
+that are relevant to the PKCS standards are the following:
+
+     BIT STRING, an arbitrary string of bits (ones and
+          zeroes).
+
+     IA5String, an arbitrary string of IA5 (ASCII)
+          characters.
+
+     INTEGER, an arbitrary integer.
+
+     NULL, a null value.
+
+     OBJECT IDENTIFIER, an object identifier, which is a
+          sequence of integer components that identify an
+          object such as an algorithm or attribute type.
+
+     OCTET STRING, an arbitrary string of octets (eight-bit
+          values).
+
+     PrintableString, an arbitrary string of printable
+          characters.
+
+     T61String, an arbitrary string of T.61 (eight-bit)
+          characters.
+
+     UTCTime, a "coordinated universal time" or Greenwich
+          Mean Time (GMT) value.
+
+Simple types fall into two categories: string types and non-
+string types. BIT STRING, IA5String, OCTET STRING,
+PrintableString, T61String, and UTCTime are string types.
+
+String types can be viewed, for the purposes of encoding, as
+consisting of components, where the components are
+substrings. This view allows one to encode a value whose
+length is not known in advance (e.g., an octet string value
+input from a file stream) with a constructed, indefinite-
+length encoding (see Section 3).
+
+The string types can be given size constraints limiting the
+length of values.
+
+
+2.2 Structured types
+
+Structured types are those consisting of components. ASN.1
+defines four, all of which are relevant to the PKCS
+standards:
+
+     SEQUENCE, an ordered collection of one or more types.
+
+     SEQUENCE OF, an ordered collection of zero or more
+          occurrences of a given type.
+
+     SET, an unordered collection of one or more types.
+
+     SET OF, an unordered collection of zero or more
+          occurrences of a given type.
+
+The structured types can have optional components, possibly
+with default values.
+
+
+2.3 Implicitly and explicitly tagged types
+
+Tagging is useful to distinguish types within an
+application; it is also commonly used to distinguish
+component types within a structured type. For instance,
+optional components of a SET or SEQUENCE type are typically
+given distinct context-specific tags to avoid ambiguity.
+
+There are two ways to tag a type: implicitly and explicitly.
+
+Implicitly tagged types are derived from other types by
+changing the tag of the underlying type. Implicit tagging is
+denoted by the ASN.1 keywords [class number] IMPLICIT (see
+Section 5.1).
+
+Explicitly tagged types are derived from other types by
+adding an outer tag to the underlying type. In effect,
+explicitly tagged types are structured types consisting of
+one component, the underlying type. Explicit tagging is
+denoted by the ASN.1 keywords [class number] EXPLICIT (see
+Section 5.2).
+
+The keyword [class number] alone is the same as explicit
+tagging, except when the "module" in which the ASN.1 type is
+defined has implicit tagging by default. ("Modules" are
+among the advanced features not described in this note.)
+
+For purposes of encoding, an implicitly tagged type is
+considered the same as the underlying type, except that the
+tag is different. An explicitly tagged type is considered
+like a structured type with one component, the underlying
+type. Implicit tags result in shorter encodings, but
+explicit tags may be necessary to avoid ambiguity if the tag
+of the underlying type is indeterminate (e.g., the
+underlying type is CHOICE or ANY).
+
+
+2.4 Other types
+
+Other types in ASN.1 include the CHOICE and ANY types. The
+CHOICE type denotes a union of one or more alternatives; the
+ANY type denotes an arbitrary value of an arbitrary type,
+where the arbitrary type is possibly defined in the
+registration of an object identifier or integer value.
+
+
+3. Basic Encoding Rules
+
+The Basic Encoding Rules for ASN.1, abbreviated BER, give
+one or more ways to represent any ASN.1 value as an octet
+string. (There are certainly other ways to represent ASN.1
+values, but BER is the standard for interchanging such
+values in OSI.)
+
+There are three methods to encode an ASN.1 value under BER,
+the choice of which depends on the type of value and whether
+the length of the value is known. The three methods are
+primitive, definite-length encoding; constructed, definite-
+length encoding; and constructed, indefinite-length
+encoding. Simple non-string types employ the primitive,
+definite-length method; structured types employ either of
+the constructed methods; and simple string types employ any
+of the methods, depending on whether the length of the value
+is known. Types derived by implicit tagging employ the
+method of the underlying type and types derived by explicit
+tagging employ the constructed methods.
+
+In each method, the BER encoding has three or four parts:
+
+     Identifier octets. These identify the class and tag
+          number of the ASN.1 value, and indicate whether
+          the method is primitive or constructed.
+
+     Length octets. For the definite-length methods, these
+          give the number of contents octets. For the
+          constructed, indefinite-length method, these
+          indicate that the length is indefinite.
+
+     Contents octets. For the primitive, definite-length
+          method, these give a concrete representation of
+          the  value. For the constructed methods, these
+          give the concatenation of the BER encodings of the
+          components of the value.
+
+     End-of-contents octets. For the constructed, indefinite-
+          length method, these denote the end of the
+          contents. For the other methods, these are absent.
+
+The three methods of encoding are described in the following
+sections.
+
+
+3.1 Primitive, definite-length method
+
+This method applies to simple types and types derived from
+simple types by implicit tagging. It requires that the
+length of the value be known in advance. The parts of the
+BER encoding are as follows:
+
+Identifier octets. There are two forms: low tag number (for
+tag numbers between 0 and 30) and high tag number (for tag
+numbers 31 and greater).
+
+     Low-tag-number form. One octet. Bits 8 and 7 specify
+          the class (see Table 2), bit 6 has value "0,"
+          indicating that the encoding is primitive, and
+          bits 5-1 give the tag number.
+
+                  Class            Bit  Bit
+                                   8    7
+                  universal        0    0
+                  application      0    1
+                  context-specific 1    0
+                  private          1    1
+
+        Table 2. Class encoding in identifier octets.
+
+     High-tag-number form. Two or more octets. First octet
+          is as in low-tag-number form, except that bits 5-1
+          all have value "1." Second and following octets
+          give the tag number, base 128, most significant
+          digit first, with as few digits as possible, and
+          with the bit 8 of each octet except the last set
+          to "1."
+
+Length octets. There are two forms: short (for lengths
+between 0 and 127), and long definite (for lengths between 0
+and 21008-1).
+
+     Short form. One octet. Bit 8 has value "0" and bits 7-1
+          give the length.
+
+     Long form. Two to 127 octets. Bit 8 of first octet has
+          value "1" and bits 7-1 give the number of
+          additional length octets. Second and following
+          octets give the length, base 256, most significant
+          digit first.
+
+Contents octets. These give a concrete representation of the
+value (or the value of the underlying type, if the type is
+derived by implicit tagging). Details for particular types
+are given in Section 5.
+
+
+3.2 Constructed, definite-length method
+
+This method applies to simple string types, structured
+types, types derived simple string types and structured
+types by implicit tagging, and types derived from anything
+by explicit tagging. It requires that the length of the
+value be known in advance. The parts of the BER encoding are
+as follows:
+
+Identifier octets. As described in Section 3.1, except that
+bit 6 has value "1," indicating that the encoding is
+constructed.
+
+Length octets. As described in Section 3.1.
+
+Contents octets. The concatenation of the BER encodings of
+the components of the value:
+
+     o    For simple string types and types derived from
+          them by implicit tagging, the concatenation of the
+          BER encodings of consecutive substrings of the
+          value (underlying value for implicit tagging).
+
+     o    For structured types and types derived from them
+          by implicit tagging, the concatenation of the BER
+          encodings of components of the value (underlying
+          value for implicit tagging).
+
+     o    For types derived from anything by explicit
+          tagging, the BER encoding of the underlying value.
+
+Details for particular types are given in Section 5.
+
+
+3.3 Constructed, indefinite-length method
+
+This method applies to simple string types, structured
+types, types derived simple string types and structured
+types by implicit tagging, and types derived from anything
+by explicit tagging. It does not require that the length of
+the value be known in advance. The parts of the BER encoding
+are as follows:
+
+Identifier octets. As described in Section 3.2.
+
+Length octets. One octet, 80.
+
+Contents octets. As described in Section 3.2.
+
+End-of-contents octets. Two octets, 00 00.
+
+Since the end-of-contents octets appear where an ordinary
+BER encoding might be expected (e.g., in the contents octets
+of a sequence value), the 00 and 00 appear as identifier and
+length octets, respectively. Thus the end-of-contents octets
+is really the primitive, definite-length encoding of a value
+with universal class, tag number 0, and length 0.
+
+
+4. Distinguished Encoding Rules
+
+The Distinguished Encoding Rules for ASN.1, abbreviated DER,
+are a subset of BER, and give exactly one way to represent
+any ASN.1 value as an octet string. DER is intended for
+applications in which a unique octet string encoding is
+needed, as is the case when a digital signature is computed
+on an ASN.1 value. DER is defined in Section 8.7 of X.509.
+
+DER adds the following restrictions to the rules given in
+Section 3:
+
+     1.   When the length is between 0 and 127, the short
+          form of length must be used
+
+     2.   When the length is 128 or greater, the long form
+          of length must be used, and the length must be
+          encoded in the minimum number of octets.
+
+     3.   For simple string types and implicitly tagged
+          types derived from simple string types, the
+          primitive, definite-length method must be
+          employed.
+
+     4.   For structured types, implicitly tagged types
+          derived from structured types, and explicitly
+          tagged types derived from anything, the
+          constructed, definite-length method must be
+          employed.
+
+Other restrictions are defined for particular types (such as
+BIT STRING, SEQUENCE, SET, and SET OF), and can be found in
+Section 5.
+
+
+5. Notation and encodings for some types
+
+This section gives the notation for some ASN.1 types and
+describes how to encode values of those types under both BER
+and DER.
+
+The types described are those presented in Section 2. They
+are listed alphabetically here.
+
+Each description includes ASN.1 notation, BER encoding, and
+DER encoding. The focus of the encodings is primarily on the
+contents octets; the tag and length octets follow Sections 3
+and 4. The descriptions also explain where each type is used
+in PKCS and related standards. ASN.1 notation is generally
+only for types, although for the type OBJECT IDENTIFIER,
+value notation is given as well.
+
+
+5.1 Implicitly tagged types
+
+An implicitly tagged type is a type derived from another
+type by changing the tag of the underlying type.
+
+Implicit tagging is used for optional SEQUENCE components
+with underlying type other than ANY throughout PKCS, and for
+the extendedCertificate alternative of PKCS #7's
+ExtendedCertificateOrCertificate type.
+
+ASN.1 notation:
+
+[[class] number] IMPLICIT Type
+
+class = UNIVERSAL  |  APPLICATION  |  PRIVATE
+
+where Type is a type, class is an optional class name, and
+number is the tag number within the class, a nonnegative
+integer.
+
+In ASN.1 "modules" whose default tagging method is implicit
+tagging, the notation [[class] number] Type is also
+acceptable, and the keyword IMPLICIT is implied. (See
+Section 2.3.) For definitions stated outside a module, the
+explicit inclusion of the keyword IMPLICIT is preferable to
+prevent ambiguity.
+
+If the class name is absent, then the tag is context-
+specific. Context-specific tags can only appear in a
+component of a structured or CHOICE type.
+
+Example: PKCS #8's PrivateKeyInfo type has an optional
+attributes component with an implicit, context-specific tag:
+
+PrivateKeyInfo ::= SEQUENCE {
+  version Version,
+  privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
+  privateKey PrivateKey,
+  attributes [0] IMPLICIT Attributes OPTIONAL }
+
+Here the underlying type is Attributes, the class is absent
+(i.e., context-specific), and the tag number within the
+class is 0.
+
+BER encoding. Primitive or constructed, depending on the
+underlying type. Contents octets are as for the BER encoding
+of the underlying value.
+
+Example: The BER encoding of the attributes component of a
+PrivateKeyInfo value is as follows:
+
+     o    the identifier octets are 80 if the underlying
+          Attributes value has a primitive BER encoding and
+          a0 if the underlying Attributes value has a
+          constructed BER encoding
+
+     o    the length and contents octets are the same as the
+          length and contents octets of the BER encoding of
+          the underlying Attributes value
+
+DER encoding. Primitive or constructed, depending on the
+underlying type. Contents octets are as for the DER encoding
+of the underlying value.
+
+
+5.2 Explicitly tagged types
+
+Explicit tagging denotes a type derived from another type by
+adding an outer tag to the underlying type.
+
+Explicit tagging is used for optional SEQUENCE components
+with underlying type ANY throughout PKCS, and for the
+version component of X.509's Certificate type.
+
+ASN.1 notation:
+
+[[class] number] EXPLICIT Type
+
+class = UNIVERSAL  |  APPLICATION  |  PRIVATE
+
+where Type is a type, class is an optional class name, and
+number is the tag number within the class, a nonnegative
+integer.
+
+If the class name is absent, then the tag is context-
+specific. Context-specific tags can only appear in a
+component of a SEQUENCE, SET or CHOICE type.
+
+In ASN.1 "modules" whose default tagging method is explicit
+tagging, the notation [[class] number] Type is also
+acceptable, and the keyword EXPLICIT is implied. (See
+Section 2.3.) For definitions stated outside a module, the
+explicit inclusion of the keyword EXPLICIT is preferable to
+prevent ambiguity.
+
+Example 1: PKCS #7's ContentInfo type has an optional
+content component with an explicit, context-specific tag:
+
+ContentInfo ::= SEQUENCE {
+  contentType ContentType,
+  content
+    [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
+
+Here the underlying type is ANY DEFINED BY contentType, the
+class is absent (i.e., context-specific), and the tag number
+within the class is 0.
+
+Example 2: X.509's Certificate type has a version component
+with an explicit, context-specific tag, where the EXPLICIT
+keyword is omitted:
+
+Certificate ::= ...
+  version [0] Version DEFAULT v1988,
+...
+
+The tag is explicit because the default tagging method for
+the ASN.1 "module" in X.509 that defines the Certificate
+type is explicit tagging.
+
+BER encoding. Constructed. Contents octets are the BER
+encoding of the underlying value.
+
+Example: the BER encoding of the content component of a
+ContentInfo value is as follows:
+
+     o    identifier octets are a0
+
+     o    length octets represent the length of the BER
+          encoding of the underlying ANY DEFINED BY
+          contentType value
+
+     o    contents octets are the BER encoding of the
+          underlying ANY DEFINED BY contentType value
+
+DER encoding. Constructed. Contents octets are the DER
+encoding of the underlying value.
+
+
+5.3 ANY
+
+The ANY type denotes an arbitrary value of an arbitrary
+type, where the arbitrary type is possibly defined in the
+registration of an object identifier or associated with an
+integer index.
+
+The ANY type is used for content of a particular content
+type in PKCS #7's ContentInfo type, for parameters of a
+particular algorithm in X.509's AlgorithmIdentifier type,
+and for attribute values in X.501's Attribute and
+AttributeValueAssertion types. The Attribute type is used by
+PKCS #6, #7, #8, #9 and #10, and the AttributeValueAssertion
+type is used in X.501 distinguished names.
+
+ASN.1 notation:
+
+ANY [DEFINED BY identifier]
+
+where identifier is an optional identifier.
+
+In the ANY form, the actual type is indeterminate.
+
+The ANY DEFINED BY identifier form can only appear in a
+component of a SEQUENCE or SET type for which identifier
+identifies some other component, and that other component
+has type INTEGER or OBJECT IDENTIFIER (or a type derived
+from either of those by tagging). In that form, the actual
+type is determined by the value of the other component,
+either in the registration of the object identifier value,
+or in a table of integer values.
+
+Example: X.509's AlgorithmIdentifier type has a component of
+type ANY:
+
+AlgorithmIdentifier ::= SEQUENCE {
+  algorithm OBJECT IDENTIFIER,
+  parameters ANY DEFINED BY algorithm OPTIONAL }
+
+Here the actual type of the parameter component depends on
+the value of the algorithm component. The actual type would
+be defined in the registration of object identifier values
+for the algorithm component.
+
+BER encoding. Same as the BER encoding of the actual value.
+
+Example: The BER encoding of the value of the parameter
+component is the BER encoding of the value of the actual
+type as defined in the registration of object identifier
+values for the algorithm component.
+
+DER encoding. Same as the DER encoding of the actual value.
+
+
+5.4 BIT STRING
+
+The BIT STRING type denotes an arbitrary string of bits
+(ones and zeroes). A BIT STRING value can have any length,
+including zero. This type is a string type.
+
+The BIT STRING type is used for digital signatures on
+extended certificates in PKCS #6's ExtendedCertificate type,
+for digital signatures on certificates in X.509's
+Certificate type, and for public keys in certificates in
+X.509's SubjectPublicKeyInfo type.
+
+ASN.1 notation:
+
+BIT STRING
+
+Example: X.509's SubjectPublicKeyInfo type has a component
+of type BIT STRING:
+
+SubjectPublicKeyInfo ::= SEQUENCE {
+  algorithm AlgorithmIdentifier,
+  publicKey BIT STRING }
+
+BER encoding. Primitive or constructed. In a primitive
+encoding, the first contents octet gives the number of bits
+by which the length of the bit string is less than the next
+multiple of eight (this is called the "number of unused
+bits"). The second and following contents octets give the
+value of the bit string, converted to an octet string. The
+conversion process is as follows:
+
+     1.   The bit string is padded after the last bit with
+          zero to seven bits of any value to make the length
+          of the bit string a multiple of eight. If the
+          length of the bit string is a multiple of eight
+          already, no padding is done.
+
+     2.   The padded bit string is divided into octets. The
+          first eight bits of the padded bit string become
+          the first octet, bit 8 to bit 1, and so on through
+          the last eight bits of the padded bit string.
+
+In a constructed encoding, the contents octets give the
+concatenation of the BER encodings of consecutive substrings
+of the bit string, where each substring except the last has
+a length that is a multiple of eight bits.
+
+Example: The BER encoding of the BIT STRING value
+"011011100101110111" can be any of the following, among
+others, depending on the choice of padding bits, the form of
+length octets, and whether the encoding is primitive or
+constructed:
+
+03 04 06 6e 5d c0                               DER encoding
+
+03 04 06 6e 5d e0                       padded with "100000"
+
+03 81 04 06 6e 5d c0              long form of length octets
+
+23 09        constructed encoding: "0110111001011101" + "11"
+   03 03 00 6e 5d
+   03 02 06 c0
+
+DER encoding. Primitive. The contents octects are as for a
+primitive BER encoding, except that the bit string is padded
+with zero-valued bits.
+
+Example: The DER encoding of the BIT STRING value
+"011011100101110111" is
+
+03 04 06 6e 5d c0
+
+
+5.5 CHOICE
+
+The CHOICE type denotes a union of one or more alternatives.
+
+The CHOICE type is used to represent the union of an
+extended certificate and an X.509 certificate in PKCS #7's
+ExtendedCertificateOrCertificate type.
+
+ASN.1 notation:
+
+CHOICE {
+  [identifier1] Type1,
+  ...,
+  [identifiern] Typen }
+
+where identifier1 , ..., identifiern are optional, distinct
+identifiers for the alternatives, and Type1, ..., Typen are
+the types of the alternatives. The identifiers are primarily
+for documentation; they do not affect values of the type or
+their encodings in any way.
+
+The types must have distinct tags. This requirement is
+typically satisfied with explicit or implicit tagging on
+some of the alternatives.
+
+Example: PKCS #7's ExtendedCertificateOrCertificate type is
+a CHOICE type:
+
+ExtendedCertificateOrCertificate ::= CHOICE {
+  certificate Certificate, -- X.509
+  extendedCertificate [0] IMPLICIT ExtendedCertificate
+}
+
+Here the identifiers for the alternatives are certificate
+and extendedCertificate, and the types of the alternatives
+are Certificate and [0] IMPLICIT ExtendedCertificate.
+
+BER encoding. Same as the BER encoding of the chosen
+alternative. The fact that the alternatives have distinct
+tags makes it possible to distinguish between their BER
+encodings.
+
+Example: The identifier octets for the BER encoding are 30
+if the chosen alternative is certificate, and a0 if the
+chosen alternative is extendedCertificate.
+
+DER encoding. Same as the DER encoding of the chosen
+alternative.
+
+
+5.6 IA5String
+
+The IA5String type denotes an arbtrary string of IA5
+characters. IA5 stands for International Alphabet 5, which
+is the same as ASCII. The character set includes non-
+printing control characters. An IA5String value can have any
+length, including zero. This type is a string type.
+
+The IA5String type is used in PKCS #9's electronic-mail
+address, unstructured-name, and unstructured-address
+attributes.
+
+ASN.1 notation:
+
+IA5String
+
+BER encoding. Primitive or constructed. In a primitive
+encoding, the contents octets give the characters in the IA5
+string, encoded in ASCII. In a constructed encoding, the
+contents octets give the concatenation of the BER encodings
+of consecutive substrings of the IA5 string.
+
+Example: The BER encoding of the IA5String value
+"test1@rsa.com" can be any of the following, among others,
+depending on the form of length octets and whether the
+encoding is primitive or constructed:
+
+16 0d 74 65 73 74 31 40 72 73 61 2e 63 6f 6d DER encoding
+
+16 81 0d                       long form of length octets
+   74 65 73 74 31 40 72 73 61 2e 63 6f 6d
+
+36 13     constructed encoding: "test1" + "@" + "rsa.com"
+   16 05 74 65 73 74 31
+   16 01 40
+   16 07 72 73 61 2e 63 6f 6d
+
+DER encoding. Primitive. Contents octets are as for a
+primitive BER encoding.
+
+Example: The DER encoding of the IA5String value
+"test1@rsa.com" is
+
+16 0d 74 65 73 74 31 40 72 73 61 2e 63 6f 6d
+
+
+5.7 INTEGER
+
+The INTEGER type denotes an arbitrary integer. INTEGER
+values can be positive, negative, or zero, and can have any
+magnitude.
+
+The INTEGER type is used for version numbers throughout
+PKCS, cryptographic values such as modulus, exponent, and
+primes in PKCS #1's RSAPublicKey and RSAPrivateKey types and
+PKCS #3's DHParameter type, a message-digest iteration count
+in PKCS #5's PBEParameter type, and version numbers and
+serial numbers in X.509's Certificate type.
+
+ASN.1 notation:
+
+INTEGER [{ identifier1(value1) ... identifiern(valuen) }]
+
+where identifier1, ..., identifiern are optional distinct
+identifiers and value1, ..., valuen are optional integer
+values. The identifiers, when present, are associated with
+values of the type.
+
+Example: X.509's Version type is an INTEGER type with
+identified values:
+
+Version ::= INTEGER { v1988(0) }
+
+The identifier v1988 is associated with the value 0. X.509's
+Certificate type uses the identifier v1988 to give a default
+value of 0 for the version component:
+
+Certificate ::= ...
+  version Version DEFAULT v1988,
+...
+
+BER encoding. Primitive. Contents octets give the value of
+the integer, base 256, in two's complement form, most
+significant digit first, with the minimum number of octets.
+The value 0 is encoded as a single 00 octet.
+
+Some example BER encodings (which also happen to be DER
+encodings) are given in Table 3.
+
+                    Integer   BER encoding
+                    value
+                    0         02 01 00
+                    127       02 01 7F
+                    128       02 02 00 80
+                    256       02 02 01 00
+                    -128      02 01 80
+                    -129      02 02 FF 7F
+
+      Table 3. Example BER encodings of INTEGER values.
+
+DER encoding. Primitive. Contents octets are as for a
+primitive BER encoding.
+
+
+5.8 NULL
+
+The NULL type denotes a null value.
+
+The NULL type is used for algorithm parameters in several
+places in PKCS.
+
+ASN.1 notation:
+
+NULL
+
+BER encoding. Primitive. Contents octets are empty.
+
+Example: The BER encoding of a NULL value can be either of
+the following, as well as others, depending on the form of
+the length octets:
+
+05 00
+
+05 81 00
+
+DER encoding. Primitive. Contents octets are empty; the DER
+encoding of a NULL value is always 05 00.
+
+
+5.9 OBJECT IDENTIFIER
+
+The OBJECT IDENTIFIER type denotes an object identifier, a
+sequence of integer components that identifies an object
+such as an algorithm, an attribute type, or perhaps a
+registration authority that defines other object
+identifiers. An OBJECT IDENTIFIER value can have any number
+of components, and components can generally have any
+nonnegative value. This type is a non-string type.
+
+OBJECT IDENTIFIER values are given meanings by registration
+authorities. Each registration authority is responsible for
+all sequences of components beginning with a given sequence.
+A registration authority typically delegates responsibility
+for subsets of the sequences in its domain to other
+registration authorities, or for particular types of object.
+There are always at least two components.
+
+The OBJECT IDENTIFIER type is used to identify content in
+PKCS #7's ContentInfo type, to identify algorithms in
+X.509's AlgorithmIdentifier type, and to identify attributes
+in X.501's Attribute and AttributeValueAssertion types. The
+Attribute type is used by PKCS #6, #7, #8, #9, and #10, and
+the AttributeValueAssertion type is used in X.501
+distinguished names. OBJECT IDENTIFIER values are defined
+throughout PKCS.
+
+ASN.1 notation:
+
+OBJECT IDENTIFIER
+
+The ASN.1 notation for values of the OBJECT IDENTIFIER type
+is
+
+{ [identifier] component1 ... componentn }
+
+componenti = identifieri | identifieri (valuei) | valuei
+
+where identifier, identifier1, ..., identifiern are
+identifiers, and value1, ..., valuen are optional integer
+values.
+
+The form without identifier is the "complete" value with all
+its components; the form with identifier abbreviates the
+beginning components with another object identifier value.
+The identifiers identifier1, ..., identifiern are intended
+primarily for documentation, but they must correspond to the
+integer value when both are present. These identifiers can
+appear without integer values only if they are among a small
+set of identifiers defined in X.208.
+
+Example: The following values both refer to the object
+identifier assigned to RSA Data Security, Inc.:
+
+{ iso(1) member-body(2) 840 113549 }
+{ 1 2 840 113549 }
+
+(In this example, which gives ASN.1 value notation, the
+object identifier values are decimal, not hexadecimal.)
+Table 4 gives some other object identifier values and their
+meanings.
+
+ Object identifier value       Meaning
+ { 1 2 }                       ISO member bodies
+ { 1 2 840 }                   US (ANSI)
+ { 1 2 840 113549 }            RSA Data Security, Inc.
+ { 1 2 840 113549 1 }          RSA Data Security, Inc. PKCS
+ { 2 5 }                       directory services (X.500)
+ { 2 5 8 }                     directory services-algorithms
+
+ Table 4. Some object identifier values and their meanings.
+
+BER encoding. Primitive. Contents octets are as follows,
+where value1, ..., valuen denote the integer values of the
+components in the complete object identifier:
+
+     1.   The first octet has value 40 * value1 + value2.
+          (This is unambiguous, since value1 is limited to
+          values 0, 1, and 2; value2 is limited to the range
+          0 to 39 when value1 is 0 or 1; and, according to
+          X.208, n is always at least 2.)
+
+     2.   The following octets, if any, encode value3, ...,
+          valuen. Each value is encoded base 128, most
+          significant digit first, with as few digits as
+          possible, and the most significant bit of each
+          octet except the last in the value's encoding set
+          to "1."
+
+Example: The first octet of the BER encoding of RSA Data
+Security, Inc.'s object identifier is 40 * 1 + 2 = 42 =
+2a16. The encoding of 840 = 6 * 128 + 4816 is 86 48 and the
+encoding of 113549 = 6 * 1282 + 7716 * 128 + d16 is 86 f7
+0d. This leads to the following BER encoding:
+
+06 06 2a 86 48 86 f7 0d
+
+DER encoding. Primitive. Contents octets are as for a
+primitive BER encoding.
+
+
+5.10 OCTET STRING
+
+The OCTET STRING type denotes an arbitrary string of octets
+(eight-bit values). An OCTET STRING value can have any
+length, including zero. This type is a string type.
+
+The OCTET STRING type is used for salt values in PKCS #5's
+PBEParameter type, for message digests, encrypted message
+digests, and encrypted content in PKCS #7, and for private
+keys and encrypted private keys in PKCS #8.
+
+ASN.1 notation:
+
+OCTET STRING [SIZE ({size | size1..size2})]
+
+where size, size1, and size2 are optional size constraints.
+In the OCTET STRING SIZE (size) form, the octet string must
+have size octets. In the OCTET STRING SIZE (size1..size2)
+form, the octet string must have between size1 and size2
+octets. In the OCTET STRING form, the octet string can have
+any size.
+
+Example: PKCS #5's PBEParameter type has a component of type
+OCTET STRING:
+
+PBEParameter ::= SEQUENCE {
+  salt OCTET STRING SIZE(8),
+  iterationCount INTEGER }
+
+Here the size of the salt component is always eight octets.
+
+BER encoding. Primitive or constructed. In a primitive
+encoding, the contents octets give the value of the octet
+string, first octet to last octet. In a constructed
+encoding, the contents octets give the concatenation of the
+BER encodings of substrings of the OCTET STRING value.
+
+Example: The BER encoding of the OCTET STRING value 01 23 45
+67 89 ab cd ef can be any of the following, among others,
+depending on the form of length octets and whether the
+encoding is primitive or constructed:
+
+04 08 01 23 45 67 89 ab cd ef                   DER encoding
+
+04 81 08 01 23 45 67 89 ab cd ef  long form of length octets
+
+24 0c            constructed encoding: 01 ... 67 + 89 ... ef
+   04 04 01 23 45 67
+   04 04 89 ab cd ef
+
+DER encoding. Primitive. Contents octets are as for a
+primitive BER encoding.
+
+Example: The BER encoding of the OCTET STRING value 01 23 45
+67 89 ab cd ef is
+
+04 08 01 23 45 67 89 ab cd ef
+
+
+5.11 PrintableString
+
+The PrintableString type denotes an arbitrary string of
+printable characters from the following character set:
+
+                         A, B, ..., Z
+                         a, b, ..., z
+                         0, 1, ..., 9
+               (space) ' ( ) + , - . / : = ?
+
+This type is a string type.
+
+The PrintableString type is used in PKCS #9's challenge-
+password and unstructuerd-address attributes, and in several
+X.521 distinguished names attributes.
+
+ASN.1 notation:
+
+PrintableString
+
+BER encoding. Primitive or constructed. In a primitive
+encoding, the contents octets give the characters in the
+printable string, encoded in ASCII. In a constructed
+encoding, the contents octets give the concatenation of the
+BER encodings of consecutive substrings of the string.
+
+Example: The BER encoding of the PrintableString value "Test
+User 1" can be any of the following, among others, depending
+on the form of length octets and whether the encoding is
+primitive or constructed:
+
+13 0b 54 65 73 74 20 55 73 65 72 20 31          DER encoding
+
+13 81 0b                          long form of length octets
+   54 65 73 74 20 55 73 65 72 20 31
+
+33 0f               constructed encoding: "Test " + "User 1"
+   13 05 54 65 73 74 20
+   13 06 55 73 65 72 20 31
+
+DER encoding. Primitive. Contents octets are as for a
+primitive BER encoding.
+
+Example: The DER encoding of the PrintableString value "Test
+User 1" is
+
+13 0b 54 65 73 74 20 55 73 65 72 20 31
+
+
+5.12 SEQUENCE
+
+The SEQUENCE type denotes an ordered collection of one or
+more types.
+
+The SEQUENCE type is used throughout PKCS and related
+standards.
+
+ASN.1 notation:
+
+SEQUENCE {
+  [identifier1] Type1 [{OPTIONAL | DEFAULT value1}],
+  ...,
+  [identifiern] Typen [{OPTIONAL | DEFAULT valuen}]}
+
+where identifier1 , ..., identifiern are optional, distinct
+identifiers for the components, Type1, ..., Typen are the
+types of the components, and value1, ..., valuen are optional
+default values for the components. The identifiers are
+primarily for documentation; they do not affect values of
+the type or their encodings in any way.
+
+The OPTIONAL qualifier indicates that the value of a
+component is optional and need not be present in the
+sequence. The DEFAULT qualifier also indicates that the
+value of a component is optional, and assigns a default
+value to the component when the component is absent.
+
+The types of any consecutive series of components with the
+OPTIONAL or DEFAULT qualifier, as well as of any component
+immediately following that series, must have distinct tags.
+This requirement is typically satisfied with explicit or
+implicit tagging on some of the components.
+
+Example: X.509's Validity type is a SEQUENCE type with two
+components:
+
+Validity ::= SEQUENCE {
+  start UTCTime,
+  end UTCTime }
+
+Here the identifiers for the components are start and end,
+and the types of the components are both UTCTime.
+
+BER encoding. Constructed. Contents octets are the
+concatenation of the BER encodings of the values of the
+components of the sequence, in order of definition, with the
+following rules for components with the OPTIONAL and DEFAULT
+qualifiers:
+
+     o    if the value of a component with the OPTIONAL or
+          DEFAULT qualifier is absent from the sequence,
+          then the encoding of that component is not
+          included in the contents octets
+
+     o    if the value of a component with the DEFAULT
+          qualifier is the default value, then the encoding
+          of that component may or may not be included in
+          the contents octets
+
+DER encoding. Constructed. Contents octets are the same as
+the BER encoding, except that if the value of a component
+with the DEFAULT qualifier is the default value, the
+encoding of that component is not included in the contents
+octets.
+
+
+5.13 SEQUENCE OF
+
+The SEQUENCE OF type denotes an ordered collection of zero
+or more occurrences of a given type.
+
+The SEQUENCE OF type is used in X.501 distinguished names.
+
+ASN.1 notation:
+
+SEQUENCE OF Type
+
+where Type is a type.
+
+Example: X.501's RDNSequence type consists of zero or more
+occurences of the RelativeDistinguishedName type, most
+significant occurrence first:
+
+RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+
+BER encoding. Constructed. Contents octets are the
+concatenation of the BER encodings of the values of the
+occurrences in the collection, in order of occurence.
+
+DER encoding. Constructed. Contents octets are the
+concatenation of the DER encodings of the values of the
+occurrences in the collection, in order of occurence.
+
+
+5.14 SET
+
+The SET type denotes an unordered collection of one or more
+types.
+
+The SET type is not used in PKCS.
+
+ASN.1 notation:
+
+SET {
+  [identifier1] Type1 [{OPTIONAL | DEFAULT value1}],
+  ...,
+  [identifiern] Typen [{OPTIONAL | DEFAULT valuen}]}
+
+where identifier1, ..., identifiern are optional, distinct
+identifiers for the components, Type1, ..., Typen are the
+types of the components, and value1, ..., valuen are
+optional default values for the components. The identifiers
+are primarily for documentation; they do not affect values
+of the type or their encodings in any way.
+
+The OPTIONAL qualifier indicates that the value of a
+component is optional and need not be present in the set.
+The DEFAULT qualifier also indicates that the value of a
+component is optional, and assigns a default value to the
+component when the component is absent.
+
+The types must have distinct tags. This requirement is
+typically satisfied with explicit or implicit tagging on
+some of the components.
+
+BER encoding. Constructed. Contents octets are the
+concatenation of the BER encodings of the values of the
+components of the set, in any order, with the following
+rules for components with the OPTIONAL and DEFAULT
+qualifiers:
+
+     o    if the value of a component with the OPTIONAL or
+          DEFAULT qualifier is absent from the set, then the
+          encoding of that component is not included in the
+          contents octets
+
+     o    if the value of a component with the DEFAULT
+          qualifier is the default value, then the encoding
+          of that component may or may not be included in
+          the contents octets
+
+DER encoding. Constructed. Contents octets are the same as
+for the BER encoding, except that:
+
+     1.   If the value of a component with the DEFAULT
+          qualifier is the default value, the encoding of
+          that component is not included.
+
+     2.   There is an order to the components, namely
+          ascending order by tag.
+
+
+5.15 SET OF
+
+The SET OF type denotes an unordered collection of zero or
+more occurrences of a given type.
+
+The SET OF type is used for sets of attributes in PKCS #6,
+#7, #8, #9 and #10, for sets of message-digest algorithm
+identifiers, signer information, and recipient information
+in PKCS #7, and in X.501 distinguished names.
+
+ASN.1 notation:
+
+SET OF Type
+
+where Type is a type.
+
+Example: X.501's RelativeDistinguishedName type consists of
+zero or more occurrences of the AttributeValueAssertion
+type, where the order is unimportant:
+
+RelativeDistinguishedName ::=
+  SET OF AttributeValueAssertion
+
+BER encoding. Constructed. Contents octets are the
+concatenation of the BER encodings of the values of the
+occurrences in the collection, in any order.
+
+DER encoding. Constructed. Contents octets are the same as
+for the BER encoding, except that there is an order, namely
+ascending lexicographic order of BER encoding. Lexicographic
+comparison of two different BER encodings is done as
+follows: Logically pad the shorter BER encoding after the
+last octet with dummy octets that are smaller in value than
+any normal octet. Scan the BER encodings from left to right
+until a difference is found. The smaller-valued BER encoding
+is the one with the smaller-valued octet at the point of
+difference.
+
+
+5.16 T61String
+
+The T61String type denotes an arbtrary string of T.61
+characters. T.61 is an eight-bit extension to the ASCII
+character set. Special "escape" sequences specify the
+interpretation of subsequent character values as, for
+example, Japanese; the initial interpretation is Latin. The
+character set includes non-printing control characters. The
+T61String type allows only the Latin and Japanese character
+interepretations, and implementors' agreements for directory
+names exclude control characters [NIST92]. A T61String value
+can have any length, including zero. This type is a string
+type.
+
+The T61String type is used in PKCS #9's unstructured-address
+and challenge-password attributes, and in several X.521
+attributes.
+
+ASN.1 notation:
+
+T61String
+
+BER encoding. Primitive or constructed. In a primitive
+encoding, the contents octets give the characters in the
+T.61 string, encoded in ASCII. In a constructed encoding,
+the contents octets give the concatenation of the BER
+encodings of consecutive substrings of the T.61 string.
+
+Example: The BER encoding of the T61String value "cl'es
+publiques" (French for "public keys") can be any of the
+following, among others, depending on the form of length
+octets and whether the encoding is primitive or constructed:
+
+14 0f                                           DER encoding
+   63 6c c2 65 73 20 70 75 62 6c 69 71 75 65 73
+
+14 81 0f                          long form of length octets
+   63 6c c2 65 73 20 70 75 62 6c 69 71 75 65 73
+
+34 15      constructed encoding: "cl'es" + " " + "publiques"
+   14 05 63 6c c2 65 73
+   14 01 20
+   14 09 70 75 62 6c 69 71 75 65 73
+
+The eight-bit character c2 is a T.61 prefix that adds an
+acute accent (') to the next character.
+
+DER encoding. Primitive. Contents octets are as for a
+primitive BER encoding.
+
+Example: The DER encoding of the T61String value "cl'es
+publiques" is
+
+14 0f 63 6c c2 65 73 20 70 75 62 6c 69 71 75 65 73
+
+
+5.17 UTCTime
+
+The UTCTime type denotes a "coordinated universal time" or
+Greenwich Mean Time (GMT) value. A UTCTime value includes
+the local time precise to either minutes or seconds, and an
+offset from GMT in hours and minutes. It takes any of the
+following forms:
+
+YYMMDDhhmmZ
+YYMMDDhhmm+hh'mm'
+YYMMDDhhmm-hh'mm'
+YYMMDDhhmmssZ
+YYMMDDhhmmss+hh'mm'
+YYMMDDhhmmss-hh'mm'
+
+where:
+
+     YY is the least significant two digits of the year
+
+     MM is the month (01 to 12)
+
+     DD is the day (01 to 31)
+
+     hh is the hour (00 to 23)
+
+     mm are the minutes (00 to 59)
+
+     ss are the seconds (00 to 59)
+
+     Z indicates that local time is GMT, + indicates that
+          local time is later than GMT, and - indicates that
+          local time is earlier than GMT
+
+     hh' is the absolute value of the offset from GMT in
+          hours
+
+     mm' is the absolute value of the offset from GMT in
+          minutes
+
+This type is a string type.
+
+The UTCTime type is used for signing times in PKCS #9's
+signing-time attribute and for certificate validity periods
+in X.509's Validity type.
+
+ASN.1 notation:
+
+UTCTime
+
+BER encoding. Primitive or constructed. In a primitive
+encoding, the contents octets give the characters in the
+string, encoded in ASCII. In a constructed encoding, the
+contents octets give the concatenation of the BER encodings
+of consecutive substrings of the string. (The constructed
+encoding is not particularly interesting, since UTCTime
+values are so short, but the constructed encoding is
+permitted.)
+
+Example: The time this sentence was originally written was
+4:45:40 p.m. Pacific Daylight Time on May 6, 1991, which can
+be represented with either of the following UTCTime values,
+among others:
+
+"910506164540-0700"
+
+"910506234540Z"
+
+These values have the following BER encodings, among others:
+
+17 0d 39 31 30 35 30 36 32 33 34 35 34 30 5a
+
+17 11 39 31 30 35 30 36 31 36 34 35 34 30 2D 30 37 30
+      30
+
+DER encoding. Primitive. Contents octets are as for a
+primitive BER encoding.
+
+
+6. An example
+
+This section gives an example of ASN.1 notation and DER
+encoding: the X.501 type Name.
+
+
+6.1 Abstract notation
+
+This section gives the ASN.1 notation for the X.501 type
+Name.
+
+Name ::= CHOICE {
+  RDNSequence }
+
+RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+
+RelativeDistinguishedName ::=
+  SET OF AttributeValueAssertion
+
+AttributeValueAssertion ::= SEQUENCE {
+   AttributeType,
+   AttributeValue }
+
+AttributeType ::= OBJECT IDENTIFIER
+
+AttributeValue ::= ANY
+
+The Name type identifies an object in an X.500 directory.
+Name is a CHOICE type consisting of one alternative:
+RDNSequence. (Future revisions of X.500 may have other
+alternatives.)
+
+The RDNSequence type gives a path through an X.500 directory
+tree starting at the root. RDNSequence is a SEQUENCE OF type
+consisting of zero or more occurences of
+RelativeDistinguishedName.
+
+The RelativeDistinguishedName type gives a unique name to an
+object relative to the object superior to it in the
+directory tree. RelativeDistinguishedName is a SET OF type
+consisting of zero or more occurrences of
+AttributeValueAssertion.
+
+The AttributeValueAssertion type assigns a value to some
+attribute of a relative distinguished name, such as country
+name or common name. AttributeValueAssertion is a SEQUENCE
+type consisting of two components, an AttributeType type and
+an AttributeValue type.
+
+The AttributeType type identifies an attribute by object
+identifier. The AttributeValue type gives an arbitrary
+attribute value. The actual type of the attribute value is
+determined by the attribute type.
+
+
+6.2 DER encoding
+
+This section gives an example of a DER encoding of a value
+of type Name, working from the bottom up.
+
+The name is that of the Test User 1 from the PKCS examples
+[Kal93]. The name is represented by the following path:
+
+                           (root)
+                              |
+                     countryName = "US"
+                              |
+          organizationName = "Example Organization"
+                              |
+                 commonName = "Test User 1"
+
+Each level corresponds to one RelativeDistinguishedName
+value, each of which happens for this name to consist of one
+AttributeValueAssertion value. The AttributeType value is
+before the equals sign, and the AttributeValue value (a
+printable string for the given attribute types) is after the
+equals sign.
+
+The countryName, organizationName, and commonUnitName are
+attribute types defined in X.520 as:
+
+attributeType OBJECT IDENTIFIER ::=
+  { joint-iso-ccitt(2) ds(5) 4 }
+
+countryName OBJECT IDENTIFIER ::= { attributeType 6 }
+organizationName OBJECT IDENTIFIER ::=
+  { attributeType 10 }
+commonUnitName OBJECT IDENTIFIER ::=
+  { attributeType 3 }
+
+
+6.2.1 AttributeType
+
+The three AttributeType values are OCTET STRING values, so
+their DER encoding follows the primitive, definite-length
+method:
+
+06 03 55 04 06                                   countryName
+
+06 03 55 04 0a                              organizationName
+
+06 03 55 04 03                                    commonName
+
+The identifier octets follow the low-tag form, since the tag
+is 6 for OBJECT IDENTIFIER. Bits 8 and 7 have value "0,"
+indicating universal class, and bit 6 has value "0,"
+indicating that the encoding is primitive. The length octets
+follow the short form. The contents octets are the
+concatenation of three octet strings derived from
+subidentifiers (in decimal): 40 * 2 + 5 = 85 = 5516; 4; and
+6, 10, or 3.
+
+
+6.2.2 AttributeValue
+
+The three AttributeValue values are PrintableString values,
+so their encodings follow the primitive, definite-length
+method:
+
+13 02 55 53                                             "US"
+
+13 14                                 "Example Organization"
+   45 78 61 6d 70 6c 65 20 4f 72 67 61 6e 69 7a 61
+   74 69 6f 6e
+
+13 0b                                          "Test User 1"
+   54 65 73 74 20 55 73 65 72 20 31
+
+The identifier octets follow the low-tag-number form, since
+the tag for PrintableString, 19 (decimal), is between 0 and
+30. Bits 8 and 7 have value "0" since PrintableString is in
+the universal class. Bit 6 has value "0" since the encoding
+is primitive. The length octets follow the short form, and
+the contents octets are the ASCII representation of the
+attribute value.
+
+
+6.2.3 AttributeValueAssertion
+
+The three AttributeValueAssertion values are SEQUENCE
+values, so their DER encodings follow the constructed,
+definite-length method:
+
+30 09                                     countryName = "US"
+   06 03 55 04 06
+   13 02 55 53
+
+30 1b              organizationName = "Example Organizaiton"
+   06 03 55 04 0a
+   13 14 ... 6f 6e
+
+30 12                             commonName = "Test User 1"
+   06 03 55 04 0b
+   13 0b ... 20 31
+
+The identifier octets follow the low-tag-number form, since
+the tag for SEQUENCE, 16 (decimal), is between 0 and 30.
+Bits 8 and 7 have value "0" since SEQUENCE is in the
+universal class. Bit 6 has value "1" since the encoding is
+constructed. The length octets follow the short form, and
+the contents octets are the concatenation of the DER
+encodings of the attributeType and attributeValue
+components.
+
+
+6.2.4 RelativeDistinguishedName
+
+The three RelativeDistinguishedName values are SET OF
+values, so their DER encodings follow the constructed,
+definite-length method:
+
+31 0b
+   30 09 ... 55 53
+
+31 1d
+   30 1b ... 6f 6e
+
+31 14
+   30 12 ... 20 31
+
+The identifier octets follow the low-tag-number form, since
+the tag for SET OF, 17 (decimal), is between 0 and 30. Bits
+8 and 7 have value "0" since SET OF is in the universal
+class Bit 6 has value "1" since the encoding is constructed.
+The lengths octets follow the short form, and the contents
+octets are the DER encodings of the respective
+AttributeValueAssertion values, since there is only one
+value in each set.
+
+
+6.2.5 RDNSequence
+
+The RDNSequence value is a SEQUENCE OF value, so its DER
+encoding follows the constructed, definite-length method:
+
+30 42
+   31 0b ... 55 53
+   31 1d ... 6f 6e
+   31 14 ... 20 31
+
+The identifier octets follow the low-tag-number form, since
+the tag for SEQUENCE OF, 16 (decimal), is between 0 and 30.
+Bits 8 and 7 have value "0" since SEQUENCE OF is in the
+universal class. Bit 6 has value "1" since the encoding is
+constructed. The lengths octets follow the short form, and
+the contents octets are the concatenation of the DER
+encodings of the three RelativeDistinguishedName values, in
+order of occurrence.
+
+
+6.2.6 Name
+
+The Name value is a CHOICE value, so its DER encoding is the
+same as that of the RDNSequence value:
+
+30 42
+   31 0b
+      30 09
+         06 03 55 04 06          attributeType = countryName
+         13 02 55 53                   attributeValue = "US"
+   31 1d
+      30 1b
+         06 03 55 04 0a     attributeType = organizationName
+         13 14       attributeValue = "Example Organization"
+            45 78 61 6d 70 6c 65 20 4f 72 67 61 6e 69 7a 61
+            74 69 6f 6e
+
+   31 14
+      30 12
+         06 03 55 04 03           attributeType = commonName
+         13 0b                attributeValue = "Test User 1"
+            54 65 73 74 20 55 73 65 72 20 31
+
+
+References
+
+PKCS #1   RSA Laboratories. PKCS #1: RSA Encryption
+          Standard. Version 1.5, November 1993.
+
+PKCS #3   RSA Laboratories. PKCS #3: Diffie-Hellman Key-
+          Agreement Standard. Version 1.4, November 1993.
+
+PKCS #5   RSA Laboratories. PKCS #5: Password-Based
+          Encryption Standard. Version 1.5, November 1993.
+
+PKCS #6   RSA Laboratories. PKCS #6: Extended-Certificate
+          Syntax Standard. Version 1.5, November 1993.
+
+PKCS #7   RSA Laboratories. PKCS #7: Cryptographic Message
+          Syntax Standard. Version 1.5, November 1993.
+
+PKCS #8   RSA Laboratories. PKCS #8: Private-Key Information
+          Syntax Standard. Version 1.2, November 1993.
+
+PKCS #9   RSA Laboratories. PKCS #9: Selected Attribute
+          Types. Version 1.1, November 1993.
+
+PKCS #10  RSA Laboratories. PKCS #10: Certification Request
+          Syntax Standard. Version 1.0, November 1993.
+
+X.200     CCITT. Recommendation X.200: Reference Model of
+          Open Systems Interconnection for CCITT
+          Applications. 1984.
+
+X.208     CCITT. Recommendation X.208: Specification of
+          Abstract Syntax Notation One (ASN.1). 1988.
+
+X.209     CCITT. Recommendation X.209: Specification of
+          Basic Encoding Rules for Abstract Syntax Notation
+          One (ASN.1). 1988.
+
+X.500     CCITT. Recommendation X.500: The
+          Directory--Overview of Concepts, Models and
+          Services. 1988.
+
+X.501     CCITT. Recommendation X.501: The Directory--
+          Models. 1988.
+
+X.509     CCITT. Recommendation X.509: The Directory--
+          Authentication Framework. 1988.
+
+X.520     CCITT. Recommendation X.520: The Directory--
+          Selected Attribute Types. 1988.
+
+[Kal93]   Burton S. Kaliski Jr. Some Examples of the PKCS
+          Standards. RSA Laboratories, November 1993.
+
+[NIST92]  NIST. Special Publication 500-202: Stable
+          Implementation Agreements for Open Systems
+          Interconnection Protocols. Part 11 (Directory
+          Services Protocols). December 1992.
+
+
+Revision history
+
+
+June 3, 1991 version
+
+The June 3, 1991 version is part of the initial public
+release of PKCS. It was published as NIST/OSI Implementors'
+Workshop document SEC-SIG-91-17.
+
+
+November 1, 1993 version
+
+The November 1, 1993 version incorporates several editorial
+changes, including the addition of a revision history. It is
+updated to be consistent with the following versions of the
+PKCS documents:
+
+     PKCS #1: RSA Encryption Standard. Version 1.5, November
+          1993.
+
+     PKCS #3: Diffie-Hellman Key-Agreement Standard. Version
+          1.4, November 1993.
+
+     PKCS #5: Password-Based Encryption Standard. Version
+          1.5, November 1993.
+
+     PKCS #6: Extended-Certificate Syntax Standard. Version
+          1.5, November 1993.
+
+     PKCS #7: Cryptographic Message Syntax Standard. Version
+          1.5, November 1993.
+
+     PKCS #8: Private-Key Information Syntax Standard.
+          Version 1.2, November 1993.
+
+     PKCS #9: Selected Attribute Types. Version 1.1,
+          November 1993.
+
+     PKCS #10: Certification Request Syntax Standard.
+          Version 1.0, November 1993.
+
+The following substantive changes were made:
+
+     Section 5: Description of T61String type is added.
+
+     Section 6: Names are changed, consistent with other
+          PKCS examples.
+
+
+Author's address
+
+Burton S. Kaliski Jr., Ph.D.
+Chief Scientist
+RSA Laboratories              (415) 595-7703
+100 Marine Parkway            (415) 595-4126 (fax)
+Redwood City, CA  94065  USA  burt@rsa.com
diff --git a/doc/devel/guidelines b/doc/devel/guidelines
new file mode 100644 (file)
index 0000000..3f81652
--- /dev/null
@@ -0,0 +1,110 @@
+$OpenLDAP$
+
+This document is being replaced with:
+       http://www.openldap.org/devel/programming.html
+and
+       http://www.openldap.org/devel/contributing.html
+
+However, some of the info here is still useful.
+
+Coding guide lines and and hints for OpenLDAP developers.
+=========================================================
+
+Please add to this file when new points come up.
+
+
+C source
+--------
+
+OpenLDAP requires many Standard C features to *build*.  This
+includes functional prototypes and offsetof macro.  It is
+possible to *build* OpenLDAP with a number of C translators
+which are not fully compliant with Standard C.
+
+OpenLDAP supports compiling and linking *with* applications
+with most C compilers and libraries.   The installed headers
+are designed to provide K&R C compatiable function declarations
+on non-standard compilers.  In cases where the compiler does
+not define __STDC__ but requires prototypes (ie: MSVC), the
+application should define LDAP_NEEDS_PROTOTYPES.  In cases
+where the compiler does define __STDC__ but does not support
+prototypes, the application should define LDAP_NO_PROTOTYPES.
+
+.c files in the OpenLDAP source tree MUST #include "portable.h" before
+any other include file, even system includes.  portable.h may control
+aspects of system includes, such as whether or not thread-safe library
+functions are used.  (Separate applications can't use portable.h, since
+it is not installed.  They can use ldap_features.h, though.)
+
+.h files that are NOT INSTALLED may depend on features from portable.h.
+.h files that *are* installed (from include/) should not depend on it.
+
+Avoid unnecessary changes, like reindenting code, even if that leaves
+the code a little ugly.  Often switching your editors tab stops to
+4 or 8 may make code easier to read.  Unnecessary changes make it
+harder to maintain and merge different CVS branches of the source.
+
+Please follow the style of surrounding code.
+
+Use feature-specific #if tests (like #ifdef HAVE_LWP) which configure
+can figure out, not system-specific test (like #ifdef __SunOS_5_6).
+
+When available, use include files from ldap/include/ac/ to get system
+features or functions.  The <ac/xxx.h> files try to fix crippled system
+includes, and to hide #ifdef messes that portable programs need in order
+to find a feature.  Note that a file <ac/xxx.h> is not necessarily
+designed to be equivalent to standard C's <xxx.h> file.
+
+Nonstatic function and variable definitions in .c files should be
+preceded by their declarations in .h files.  Avoid implicit function
+declarations.  External declarations with should be avoided.  In
+.c files, include the appropriate .h file to obtain the declaration.
+If the declaration is not available in any system header, add it
+to the most appropriate ac/xxx.h header.  Do NOT add extern
+declarations to .c files.
+
+When a function returns non-void, it should return a meaningful value.
+Avoid implicit int.
+
+It is recommended that ldap_cdef.h macros LDAP_F and LDAP_P be used
+even for non-installed headers.  See lber.h and ldap.h for examples.
+
+
+CVS updating
+------------
+
+<URL:http://www.openldap.org/software/repo.html> describes how to check out
+-stable.  To get the -devel (HEAD) branch, omit `-r OPENLDAP_STABLE'.
+You can use 'cvs status -v README' to get a list available CVS tags.
+
+Core members should subscribe to the -core mailing list.  This
+list is for private discussions between core team members.  The
+openldap-devel@openldap.org mailing list is the primary developer
+forum for both  technical disscusions and coordinating efforts.
+
+Please test patches before committing.  This should include compiling
+and linking the system AND running the test suite.
+
+In general, a patch/bugfix should be applied to -devel and tested.
+When the patch is considered stable, then it can be merged into -stable.
+Same goes for other release engineering branches (like
+OPENLDAP_REL_ENG_1_1).  (-stable is rel eng 1.0).
+Specific procjects may get their own branches, to be merged later.
+
+Log messages: Just describe the change and reason.  CVS adds your name,
+date, etc.
+
+
+Various tips and hints
+----------------------
+
+How to correct a CVS log message:
+Commit the unchanged files again with the `-f' flag and with a log
+message stating how the previous log was in error:
+       cvs commit -f cldap.c os-ip.c
+Preferably, prepend a line something like this to the message:
+"Forced commit to correct previous log, files were not changed."
+
+Modify ldapconfig.h instead of ldapconfig.h.edit.  Then `cvs commit'
+from the include directory won't accidentally commit your private
+ldapconfig.h.edit.
index f6dfd9cbb32cbcef64eae52740758adfe2b59a2e..cfe85242af4048c2bd5595f069e4ca147f4582a5 100644 (file)
@@ -6,3 +6,11 @@ Internet-Drafts are draft documents valid for a maximum of six months
 and may be updated, replaced, or obsoleted by other documents at any
 time.  It is inappropriate to use Internet-Drafts as reference material
 or to cite them other than as "work in progress."
+
+OpenLDAP maintains copies of drafts for which we have and/or
+are planning "experimental" implementations of.  The I-D
+found in this directory may be stale, expired, or otherwise
+out of date.
+
+Please refer to http://www.ietf.org/ for latest revisions (and
+status).
index 56654338ee8185eeae0310e8fd6a8ff4555b88ed..86d5589c90e2ebaea7ad7b71ae394e18f73fc3b2 100644 (file)
@@ -1,12 +1,9 @@
-
-
-
 LDAP Data Interchange Format (LDIF)                         Gordon Good
 INTERNET-DRAFT                                  Netscape Communications
-                                                       22 February 1999
+Status: Standards-Track                                 19 October 1999
 
    The LDAP Data Interchange Format (LDIF) - Technical Specification
-                 Filename: draft-good-ldap-ldif-03.txt
+                 Filename: draft-good-ldap-ldif-05.txt
 
 Status of this Memo
 
@@ -27,7 +24,7 @@ Status of this Memo
    To view the list Internet-Draft Shadow Directories, see
    http://www.ietf.org/shadow.html.
 
-   This Internet Draft expires August 22nd, 1999.
+   This Internet Draft expires 19 April, 2000.
 
 
 Abstract
@@ -52,14 +49,14 @@ Background and Intended Usage
 
 
 
-Good                       February 22, 1999                    [Page 1]
+Good                        October 18, 1999                    [Page 1]
 \f
-INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
+INTERNET-DRAFT        LDAP Data Interchange Format       19 October 1999
 
 
    of data import tools from legacy systems is facilitated.  A fairly
    simple set of tools written in awk or perl can, for example, convert
-   a database of personnel information into an LDIF file. Thie file can
+   a database of personnel information into an LDIF file. This file can
    then be imported into a directory server, regardless of the internal
    database representation the target directory server uses.
 
@@ -73,8 +70,8 @@ INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
    The application/directory MIME content-type [1] is a general
    framework and format for conveying directory information, and is
    independent of any particular directory service.  The LDIF format is
-   a simpler format which is perhaps easier to create, and also may also
-   be used, as noted, to describe a set of changes to be applied to a
+   a simpler format which is perhaps easier to create, and may also be
+   used, as noted, to describe a set of changes to be applied to a
    directory.
 
    The key words "MUST", "MAY", and "SHOULD" used in this document are
@@ -92,9 +89,9 @@ Definition of the LDAP Data Interchange Format
    entry.  An LDIF file specifies a set of directory entries, or a set
    of changes to be applied to directory entries, but not both.
 
-   There is a one-to-one correlation between LDAP operations which
-   modify the directory (add, delete, modify, and modrdn), and the types
-   of changerecords described below ("add", "delete", "modify", and
+   There is a one-to-one correlation between LDAP operations that modify
+   the directory (add, delete, modify, and modrdn), and the types of
+   changerecords described below ("add", "delete", "modify", and
    "modrdn" or "moddn").  This correspondence is intentional, and
    permits a straightforward translation from LDIF changerecords to
    protocol operations.
@@ -102,84 +99,186 @@ Definition of the LDAP Data Interchange Format
 Formal Syntax Definition of LDIF
 
    The following definition uses the augmented Backus-Naur Form
-   specified in RFC 822 [2].
+   specified in RFC 2234 [2].
+
+   ldif-file                = ldif-content / ldif-changes
+
+
+
+Good                        October 18, 1999                    [Page 2]
+\f
+INTERNET-DRAFT        LDAP Data Interchange Format       19 October 1999
+
+
+   ldif-content             = version-spec 1*(1*SEP ldif-attrval-record)
+
+   ldif-changes             = version-spec 1*(1*SEP ldif-change-record)
+
+   ldif-attrval-record      = dn-spec SEP 1*attrval-spec
+
+   ldif-change-record       = dn-spec SEP *control changerecord
+
+   version-spec             = "version:" FILL version-number
+
+   version-number           = 1*DIGIT
+                              ; version-number MUST be "1" for the
+                              ; LDIF format described in this document.
+
+   dn-spec                  = "dn:" (FILL distinguishedName /
+                                     ":" FILL base64-distinguishedName)
+
+   distinguishedName        = SAFE-UTF8-STRING
+                              ; a distinguished name, as defined in [3]
+
+   base64-distinguishedName = BASE64-UTF8-STRING
+                              ; a distinguishedName which has been base64
+                              ; encoded (see note 10, below)
+
+   rdn                      = SAFE-UTF8-STRING
+                              ; a relative distinguished name, defined as
+                              ; <name-component> in [3]
+
+   base64-rdn               = BASE64-UTF8-STRING
+                              ; an rdn which has been base64 encoded (see
+                              ; note 10, below)
+
+   control                  = "control:" FILL ldap-oid        ; controlType
+                              0*1(1*SPACE ("true" / "false")) ; criticality
+                              0*1(value-spec)                 ; controlValue
+                              SEP
+                              ; (See note 9, below)
+
+   ldap-oid                 = 1*DIGIT 0*1("." 1*DIGIT)
+                              ; An LDAPOID, as defined in [4]
+
+   attrval-spec             = AttributeDescription value-spec SEP
+
+   value-spec               = ":" (    FILL 0*1(SAFE-STRING) /
+                                   ":" FILL (BASE64-STRING) /
+                                   "<" FILL url)
+                              ; See notes 7 and 8, below
+
+
 
-   ldif-file            = ldif-content / ldif-changes
 
+Good                        October 18, 1999                    [Page 3]
+\f
+INTERNET-DRAFT        LDAP Data Interchange Format       19 October 1999
+
+
+   url                      = <a Uniform Resource Locator, as defined in [6]>
+                                      ; (See Note 6, below)
+
+   AttributeDescription     = AttributeType [";" options]
+                              ; Definition taken from [4]
+
+   AttributeType            = ldap-oid / (ALPHA *(attr-type-chars))
+
+   options                  = option / (option ";" options)
+
+   option                   = 1*opt-char
+
+   attr-type-chars          = ALPHA / DIGIT / "-"
+
+   opt-char                 = attr-type-chars
+
+   changerecord             = "changetype:" FILL
+                              (change-add / change-delete /
+                               change-modify / change-moddn)
+
+   change-add               = "add"                SEP 1*attrval-spec
+
+   change-delete            = "delete"             SEP
+
+   change-moddn             = ("modrdn" / "moddn") SEP
+                               "newrdn:" (    FILL rdn /
+                                          ":" FILL base64-rdn) SEP
+                               "deleteoldrdn:" FILL ("0" / "1")  SEP
+                               0*1("newsuperior:"
+                               (    FILL distinguishedName /
+                                ":" FILL base64-distinguishedName) SEP)
 
+   change-modify            = "modify"             SEP *mod-spec
 
-Good                       February 22, 1999                    [Page 2]
+   mod-spec                 = ("add:" / "delete:" / "replace:")
+                              FILL AttributeDescription SEP
+                              *attrval-spec
+                              "-" SEP
+
+   SPACE                    = %x20
+                              ; ASCII SP, space
+
+   FILL                     = *SPACE
+
+   SEP                      = (CR LF / LF)
+
+   CR                       = %x0D
+                              ; ASCII CR, carriage return
+
+
+
+Good                        October 18, 1999                    [Page 4]
 \f
-INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
-
-
-   ldif-content         = version-spec 1*SEP
-                          ldif-attrval-record *(1*SEP ldif-attrval-record)
-   ldif-changes         = version-spec 1*SEP
-                          ldif-change-record *(1*SEP ldif-change-record)
-   ldif-attrval-record  = dn-spec SEP 1*(attrval-spec SEP)
-   ldif-change-record   = dn-spec SEP 1*(changerecord SEP)
-
-   version-spec         = "version:" *SPACE version-number
-   version-number       = 1*DIGIT  ; version-number MUST be "1" for the
-                                   ; LDIF format described in this document.
-
-   dn-spec              = ("dn:" *SPACE dn) / ("dn::" *SPACE base64-dn)
-   dn                   = <a distinguished name, as defined in RFC 2253 [3]>
-   base64-dn            = <a dn which has been base-64 encoded, as
-                          defined in RFC 1521 [5]>
-   rdn                  = <a relative distinguished name, as defined in RFC
-                          2253 [3]>
-   base64-rdn           = <an rdn which has been base-64 encoded, as
-                          defined in RFC 1521 [5]>
-
-   attrval-spec         = attribute-description ((":") / (":" *SPACE value) /
-                                                 ("::" *SPACE base64-value) /
-                                                 (":<" *SPACE url))
-   url                  = <a Uniform Resource Locator, as defined in [6]>
-                                  ; (See Note 6, below)
-   attribute-description = <an attribute description, as defined in [4].
-                            An attribute description MAY NOT contain a
-                            colon ":">
-   value                = 1*safe-initval *safe
-                                  ; (See Note 9, below)
-   safe                 = <any value except CR or LF>
-   safe-initval         = <any value except CR, LF, colon (":", ASCII 58
-                          decimal), SPACE, and less-than ("<" , ASCII 60
-                          decimal)>
-   base64-value         = <base-64-encoded value, as defined in RFC 1521 [5]>
-
-   changerecord         = change-add / change-delete / change-modify /
-                          change-moddn
-   change-add           = "changetype:" *SPACE "add" 1*(SEP attrval-spec)
-   change-delete        = "changetype:" *SPACE "delete"
-   change-moddn         = "changetype:" *SPACE ("modrdn" / "moddn") SEP
-                          ("newrdn:" *SPACE rdn /
-                           "newrdn::" *SPACE base-64-rdn) SEP
-                          "deleteoldrdn:" *SPACE ("0" / "1")
-                          0,1*(SEP (("newsuperior:" *SPACE dn) /
-                                    ("newsuperior::" *SPACE base-64-dn)))
-   change-modify        = "changetype:" *SPACE "modify" 1*(SEP mod-spec)
-   mod-spec             = mod-add-spec / mod-delete-spec / mod-replace-spec
-
-
-
-Good                       February 22, 1999                    [Page 3]
+INTERNET-DRAFT        LDAP Data Interchange Format       19 October 1999
+
+
+   LF                       = %x0A
+                              ; ASCII LF, line feed
+
+   ALPHA                    = %x41-5A / %x61-7A
+                              ; A-Z / a-z
+
+   DIGIT                    = %x30-39
+                              ; 0-9
+
+   UTF8-1                   = %x80-BF
+
+   UTF8-2                   = %xC0-DF UTF8-1
+
+   UTF8-3                   = %xE0-EF 2UTF8-1
+
+   UTF8-4                   = %xF0-F7 3UTF8-1
+
+   UTF8-5                   = %xF8-FB 4UTF8-1
+
+   UTF8-6                   = %xFC-FD 5UTF8-1
+
+   SAFE-CHAR                = %x01-09 / %x0B-0C / %x0E-7F
+                              ; any value <= 127 decimal except NUL, LF, and CR
+
+   SAFE-INIT-CHAR           = %x01-09 / %x0B-0C / %x0E-1F /
+                              %x21-39 / %x3B / %x3D-7F
+                              ; any value <= 127 except NUL, LF, CR,
+                              ; SPACE, colon (":", ASCII 58 decimal)
+                              ; and less-than ("<" , ASCII 60 decimal)
+
+   SAFE-STRING              = [SAFE-INIT-CHAR *SAFE-CHAR]
+
+   SAFE-UTF8-CHAR           = SAFE-CHAR / UTF8-2 / UTF8-3 /
+                              UTF8-4 / UTF8-5 / UTF8-6
+
+   SAFE-INIT-UTF8-CHAR      = SAFE-INIT-CHAR / UTF8-2 / UTF8-3 /
+                              UTF8-4 / UTF8-5 / UTF8-6
+
+   SAFE-UTF8-STRING         = [SAFE-INIT-UTF8-CHAR *SAFE-UTF8-CHAR]
+
+   BASE64-UTF8-STRING       = BASE64-STRING
+                              ; MUST be the base64 encoding of a valid
+                              ; string of UTF-8 characters
+
+   BASE64-CHAR              = %x2B / %x2F / %x30-39 / %x3D / %x41-5A / %x61-7A
+                              ; +, /, 0-9, =, A-Z, and a-z
+                              ; as specified in [5]
+
+
+
+
+Good                        October 18, 1999                    [Page 5]
 \f
-INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
+INTERNET-DRAFT        LDAP Data Interchange Format       19 October 1999
 
 
-   mod-add-spec         = "add:" *SPACE attribute-description
-                          1*(SEP attrval-spec) SEP "-"
-   mod-delete-spec      = "delete:" *SPACE attribute-description
-                          *(SEP attrval-spec) SEP "-"
-   mod-replace-spec     = "replace:" *SPACE attribute-description
-                          *(SEP attrval-spec) SEP "-"
-   SPACE                = <ASCII SP, space>
-   SEP                  = (CR LF / LF)
-   CR                   = <ASCII CR, carriage return>
-   LF                   = <ASCII LF, line feed>
-   DIGIT                = <any ASCII decimal digit (60 - 71 decimal) >
+   BASE64-STRING            = [*(BASE64-CHAR)]
 
 
    Notes on LDIF Syntax
@@ -189,23 +288,32 @@ INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
    choose to interpret the contents as an older LDIF file format,
    supported by the University of Michigan ldap-3.3 implementation [8].
 
-   2) Any line, including comment lines, in an LDIF file MAY be wrapped
-   by inserting a line separator (SEP) and a SPACE.  Any line which
-   begins with a single space MUST be treated as a continuation of the
-   previous line. When joining folded lines, exactly one space character
-   at the beginning of each continued line must be discarded.
-
-   3) Any line which begins with a pound-sign ("#", ASCII 35) is a
+   2) Any non-empty line, including comment lines, in an LDIF file MAY
+   be folded by inserting a line separator (SEP) and a SPACE.  Folding
+   MUST NOT occur before the first character of the line. In other
+   words, folding a line into two lines, the first of which is empty, is
+   not permitted. Any line that begins with a single space MUST be
+   treated as a continuation of the previous (non-empty) line. When
+   joining folded lines, exactly one space character at the beginning of
+   each continued line must be discarded. Implementations SHOULD NOT
+   fold lines in the middle of a multi-byte UTF-8 character.
+
+   3) Any line that begins with a pound-sign ("#", ASCII 35) is a
    comment line, and MUST be ignored when parsing an LDIF file.
 
-   4) Any dn or value which contains characters other than those defined
-   as "safe", or begins with a character other than those defined as
-   "safe-initval", above, MUST be base-64 encoded.  Other values MAY be
-   base-64 encoded.
+   4) Any dn or rdn that contains characters other than those defined as
+   "SAFE-UTF8-CHAR", or begins with a character other than those defined
+   as "SAFE-INIT-UTF8-CHAR", above, MUST be base-64 encoded.  Other
+   values MAY be base-64 encoded.  Any value that contains characters
+   other than those defined as "SAFE-CHAR", or begins with a character
+   other than those defined as "SAFE-INIT-CHAR", above, MUST be base-64
+   encoded.  Other values MAY be base-64 encoded.
 
-   5) To represent a zero-length attribute value, use an attrval-spec of
-   "attribute-description:".  For example, "seeAlso:" represents a
-   zero-length "seeAlso" attribute value.
+   5) When a zero-length attribute value is to be included directly in
+   an LDIF file, it MUST be represented as AttributeDescription ":" FILL
+   SEP.  For example, "seeAlso:" followed by a newline represents a
+   zero-length "seeAlso" attribute value.  It is also permissible for
+   the value referred to by a URL to be of zero length.
 
    6) When a URL is specified in an attrval-spec, the following
    conventions apply:
@@ -216,28 +324,41 @@ INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
          associated with each supported URL will be documented in
          an associated Applicability Statement.
 
-   7) While it is permissible for character values larger than 126 to be
+   7) Distinguished names, relative distinguished names, and attribute
+   values of DirectoryString syntax MUST be valid UTF-8 strings.
 
 
 
-Good                       February 22, 1999                    [Page 4]
+Good                        October 18, 1999                    [Page 6]
 \f
-INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
-
-
-   contained in an attribute value, implementations SHOULD base-64
-   encode any value which contains such characters when generating LDIF.
-   However, implementations MAY leave the values unencoded.  This
-   relaxation is designed to allow editing of LDIF files containing
-   UTF-8 data.
-
-   8) Attribute values contained in LDIF files represent directory data,
-   and therefore MUST be valid UTF-8 strings. Implementations which read
-   LDIF MAY interpret files in which the values are stored in some other
-   character set encoding, but implementations MUST NOT generate LDIF
-   content which does not contain valid UTF-8 data.
-
-   9) Values that end with SPACE SHOULD be base-64 encoded.
+INTERNET-DRAFT        LDAP Data Interchange Format       19 October 1999
+
+
+   Implementations that read LDIF MAY interpret files in which these
+   entities are stored in some other character set encoding, but
+   implementations MUST NOT generate LDIF content which does not contain
+   valid UTF-8 data.
+
+   8) Values or distinguished names that end with SPACE SHOULD be base-
+   64 encoded.
+
+   9) When controls are included in an LDIF file, implementations MAY
+   choose to ignore some or all of them. This may be necessary if the
+   changes described in the LDIF file are being sent on an LDAPv2
+   connection (LDAPv2 does not support controls), or the particular
+   controls are not supported by the remote server. If the criticality
+   of a control is "true", then the implementation MUST either include
+   the control, or MUST NOT send the operation to a remote server.
+
+   10) When an attrval-spec, distinguishedName, or rdn is base64-
+   encoded, the encoding rules specified in [5] are used with the
+   following exceptions:  a) The requirement that base64 output streams
+   must be represented as lines of no more than 76 characters is
+   removed. Lines in LDIF files may only be folded according to the
+   folding rules described in note 2, above.  b) Base64 strings in [5]
+   may contain characters other than those defined in BASE64-CHAR, and
+   are ignored. LDIF does not permit any extraneous characters, other
+   than those used for line folding.
 
 Examples of LDAP Data Interchange Format
 
@@ -261,6 +382,14 @@ Examples of LDAP Data Interchange Format
    objectclass: top
    objectclass: person
    objectclass: organizationalPerson
+
+
+
+Good                        October 18, 1999                    [Page 7]
+\f
+INTERNET-DRAFT        LDAP Data Interchange Format       19 October 1999
+
+
    cn: Bjorn Jensen
    sn: Jensen
    telephonenumber: +1 408 555 1212
@@ -273,21 +402,13 @@ Examples of LDAP Data Interchange Format
    objectclass:person
    objectclass:organizationalPerson
    cn:Barbara Jensen
-
-
-
-Good                       February 22, 1999                    [Page 5]
-\f
-INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
-
-
    cn:Barbara J Jensen
    cn:Babs Jensen
    sn:Jensen
    uid:bjensen
    telephonenumber:+1 408 555 1212
-   description:Babs is a big sailing fan, and travels extensively in search of
-    perfect sailing conditions.
+   description:Babs is a big sailing fan, and travels extensively in sea
+    rch of perfect sailing conditions.
    title:Product Manager, Rod and Reel Division
 
    Example 3: A file containing a base-64-encoded value
@@ -317,6 +438,14 @@ INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
    objectclass: organizationalUnit
    ou:: 5Za25qWt6YOo
    # ou:: <JapaneseOU>
+
+
+
+Good                        October 18, 1999                    [Page 8]
+\f
+INTERNET-DRAFT        LDAP Data Interchange Format       19 October 1999
+
+
    ou;lang-ja:: 5Za25qWt6YOo
    # ou;lang-ja:: <JapaneseOU>
    ou;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2
@@ -329,14 +458,6 @@ INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
    userpassword: {SHA}O3HSv1MusyL4kTjP+HKI5uxuNoM=
    objectclass: top
    objectclass: person
-
-
-
-Good                       February 22, 1999                    [Page 6]
-\f
-INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
-
-
    objectclass: organizationalPerson
    objectclass: inetOrgPerson
    uid: rogasawara
@@ -374,6 +495,13 @@ INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
 
    Example 5: A file containing a reference to an external file
 
+
+
+Good                        October 18, 1999                    [Page 9]
+\f
+INTERNET-DRAFT        LDAP Data Interchange Format       19 October 1999
+
+
    version: 1
    dn: cn=Horatio Jensen, ou=Product Testing, dc=airius, dc=com
    objectclass: top
@@ -386,13 +514,6 @@ INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
    telephonenumber: +1 408 555 1212
    jpegphoto:< file:///usr/local/directory/photos/hjensen.jpg
 
-
-
-Good                       February 22, 1999                    [Page 7]
-\f
-INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
-
-
    Example 6: A file containing a series of change records and comments
 
    version: 1
@@ -429,6 +550,14 @@ INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
    # Modify an entry: add an additional value to the postaladdress attribute,
    # completely delete the description attribute, replace the telephonenumber
    # attribute with two values, and delete a specific value from the
+
+
+
+Good                        October 18, 1999                   [Page 10]
+\f
+INTERNET-DRAFT        LDAP Data Interchange Format       19 October 1999
+
+
    # facsimiletelephonenumber attribute
    dn: cn=Paula Jensen, ou=Product Development, dc=airius, dc=com
    changetype: modify
@@ -441,18 +570,32 @@ INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
    telephonenumber: +1 408 555 1234
    telephonenumber: +1 408 555 5678
    -
-
-
-
-Good                       February 22, 1999                    [Page 8]
-\f
-INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
-
-
    delete: facsimiletelephonenumber
    facsimiletelephonenumber: +1 408 555 9876
    -
 
+   # Modify an entry: replace the postaladdress attribute with an empty
+   # set of values (which will cause the attribute to be removed), and
+   # delete the entire description attribute. Note that the first will
+   # always succeed, while the second will only succeed if at least
+   # one value for the description attribute is present.
+   dn: cn=Ingrid Jensen, ou=Product Support, dc=airius, dc=com
+   changetype: modify
+   replace: postaladdress
+   -
+   delete: description
+   -
+
+   Example 7: An LDIF file containing a change record with a control
+   version: 1
+   # Delete an entry. The operation will attach the LDAPv3
+   # Tree Delete Control defined in [9]. The criticality
+   # field is "true" and the controlValue field is
+   # absent, as required by [9].
+   dn: ou=Product Development, dc=airius, dc=com
+   control: 1.2.840.113556.1.4.805 true
+   changetype: delete
+
 
 Security Considerations
 
@@ -463,6 +606,14 @@ Security Considerations
 
    Since ":<" directives can cause external content to be included when
    processing an LDIF file, one should be cautious of accepting LDIF
+
+
+
+Good                        October 18, 1999                   [Page 11]
+\f
+INTERNET-DRAFT        LDAP Data Interchange Format       19 October 1999
+
+
    files from external sources.  A "trojan" LDIF file could name a file
    with sensitive contents and cause it to be included in a directory
    entry, which a hostile entity could read via LDAP.
@@ -497,14 +648,6 @@ Appendix A: Differences from previous versions of this document
    ldif-02.txt
 
    1) The BNF has been modified such that a simple attribute name
-
-
-
-Good                       February 22, 1999                    [Page 9]
-\f
-INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
-
-
    ("attrname") has been replaced with an "attribute-description" as
    defined in the LDAPv3 protocol document [4].  This permits language
    codes and other attribute options to be carried in an LDIF file.
@@ -520,9 +663,16 @@ INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
    Differences between draft-ietf-asid-ldif-02.txt and draft-good-ldap-
    ldif-00.txt
 
+
+
+Good                        October 18, 1999                   [Page 12]
+\f
+INTERNET-DRAFT        LDAP Data Interchange Format       19 October 1999
+
+
    1) The "charset-option" and "charset-name" productions were removed
    from the BNF, due to objections within the working group.  UTF-8 is
-   the only character set which may be used in LDIF.
+   the only character set that may be used in LDIF.
 
    2) Examples were reworked to reflect the above change, and to include
    an example of a non-western language represented in UTF-8.
@@ -532,9 +682,9 @@ INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
 
    1) Added version identifiers to the examples - they were missing.
 
-   2) Clarified that LDIF file must use UTF-8.
+   2) Clarified that LDIF files must use UTF-8.
 
-   Differences between draft-ietf-good-ldif-01.txt and draft-good-ldap-
+   Differences between draft-good-ldap-ldif-01.txt and draft-good-ldap-
    ldif-02.txt
 
    1) Added a recommendation that values ending in SPACE should be
@@ -544,7 +694,7 @@ INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
 
    3) Updated header to reflect new IETF I-D guidelines.
 
-   Differences between draft-ietf-good-ldif-02.txt and draft-good-ldap-
+   Differences between draft-good-ldap-ldif-02.txt and draft-good-ldap-
    ldif-03.txt
 
    1) Fixed reference from RFC 1779 to RFC 2253.
@@ -554,13 +704,6 @@ INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
    3) Comment lines may be folded (this is now explicitly mentioned in
    note 2).
 
-
-
-Good                       February 22, 1999                   [Page 10]
-\f
-INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
-
-
    4) Moved this section (differences between draft versions) to an
    appendix.
 
@@ -569,6 +712,87 @@ INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
 
    6) Cleaned up references section.
 
+   Differences between draft-good-ldap-ldif-03.txt and draft-good-ldap-
+   ldif-04.txt
+
+   1) The grammar now requires that an LDIF file end with one or more
+   SEP sequences (newlines). This was inadvertently prohibited in
+   earlier revisions of the grammar.
+
+
+
+Good                        October 18, 1999                   [Page 13]
+\f
+INTERNET-DRAFT        LDAP Data Interchange Format       19 October 1999
+
+
+   2) Several minor spelling and typographical errors were fixed.
+
+   3) Reworked the grammar to make it more readable. Hallvard Furuseth
+   (University of Oslo) provided the new BNF.
+
+   4) Excluded NUL from "safe" production.
+
+   5) Changed "0,1*xxx" "0*1xxx" in compliance with RFC822.
+
+   6) Fixed a glitch in the grammar that allowed multiple changetypes
+   within a single LDIF change record. The intent is that only one
+   changetype per change record is permitted.
+
+   7) Fixed a mistake in example 2 (folded attribute value).
+
+   8) The BNF now explicitly requires that zero-length attribute values
+   be encoded as attribute-description ":" FILL SEP.
+
+   9) Factored "changetype: FILL" out of the productions for change-add,
+   change-delete, change-moddn, and change-modify.
+
+   10) RFC 2251 permits an LDAP modify operation with no modifications,
+   and also permits an attribute with no values. Although it's unclear
+   what the purpose of these constructs might be, I altered the BNF to
+   allow these to be described in LDIF.
+
+   11) The BNF may now carry LDAP v3 controls in ldif-change-records.
+   The "value-spec" production was factored out to allow it to be used
+   in the definition of a control.
+
+   12) Clarified the rules for line-folding to prohibit a line from
+   being folded into two lines, the first of which is empty. This
+   guarantees that the sequence SEP SEP terminates an LDIF record, and
+   allows, for example, "perl -n00" to be used to read an entire LDIF
+   record into the $_ variable.
+
+   Differences between draft-good-ldap-ldif-04.txt and draft-good-ldap-
+   ldif-05.txt
+
+   1) The grammar has been rewritten to use the RFC2234 ABNF, replacing
+   the RFC822 ABNF.
+
+   2) The grammar makes fewer uses of <prose-val>.
+
+   3) DNs, RDNs, and attribute values with DirectoryString are now
+   explicitly called out as UTF-8 strings.
+
+   4) An error in the BNF for "control" was fixed.
+
+
+
+Good                        October 18, 1999                   [Page 14]
+\f
+INTERNET-DRAFT        LDAP Data Interchange Format       19 October 1999
+
+
+   5) An additional ldif-change-record was added to example 6.
+
+   6) Since RFC 1521 defines base-64 encoding with different folding
+   rules, and permits illegal characters (which should be ignored), an
+   explanatory note has been added. This note explains that lines must
+   be folded according to LDIF rules, not RFC 1521 rules, and that
+   extraneous characters are not permitted.
+
+   7) DNs, values, and rdns containing octets > 127 must be base-64
+   encoded.
+
 
 Acknowledgments
 
@@ -578,6 +802,10 @@ Acknowledgments
    supported by the National Science Foundation under Grant No.  NCR-
    9416667.
 
+   Members of the IETF LDAP Extensions Working group provided many
+   helpful suggestions. In particular, Hallvard B. Furuseth of the
+   University of Oslo made many significant contributions to this
+   document, including a thorough review and rewrite of the BNF.
 
 References
 
@@ -586,9 +814,9 @@ References
         mation", RFC 2425, September 1998,
         <URL:http://www.ietf.org/rfc/rfc2245.txt>
 
-   [2]  Crocker,  D.H., "Standard for the Format of ARPA Internet Text
-        Messages", RFC 822, August 1982,
-        <URL:http://ds.internic.net/rfc/rfc822.txt>
+   [2]  Crocker,  D., Overell, P., "Augmented BNF for Syntax Specifica-
+        tions: ABNF" , RFC 2234, November 1997,
+        <URL:http://ds.internic.net/rfc/rfc2234.txt>
 
    [3]  Wahl, M., Kille, S., Howes, T., "A String Representation of Dis-
         tinguished Names", RFC 2253,
@@ -602,21 +830,21 @@ References
         Extensions) Part One: Mechanisms for Specifying and Describing
         the Format of Internet Message Bodies", section 5.2, "Base64
         Content-Transfer-Encoding", RFC 1521, December 1993,
-        <URL:http://ds.internic.net/rfc/rfc1521.txt>
 
-   [6]  T. Berners-Lee,  L.  Masinter, M. McCahill, "Uniform Resource
-        Locators (URL)", RFC 1738, December 1994,
-        <URL:http://ds.internic.net/rfc/rfc1738.txt>
 
-   [7]  S. Bradner, "Key Words for use in RFCs to Indicate Requirement
 
+Good                        October 18, 1999                   [Page 15]
+\f
+INTERNET-DRAFT        LDAP Data Interchange Format       19 October 1999
 
 
-Good                       February 22, 1999                   [Page 11]
-\f
-INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
+        <URL:http://ds.internic.net/rfc/rfc1521.txt>
 
+   [6]  T. Berners-Lee,  L.  Masinter, M. McCahill, "Uniform Resource
+        Locators (URL)", RFC 1738, December 1994,
+        <URL:http://ds.internic.net/rfc/rfc1738.txt>
 
+   [7]  S. Bradner, "Key Words for use in RFCs to Indicate Requirement
         Levels", Harvard University, RFC 2119, March 1997,
         <URL:http://ds.internic.net/rfc/rfc2119.txt>
 
@@ -624,6 +852,11 @@ INTERNET-DRAFT        LDAP Data Interchange Format      22 February 1999
         gan, April 1996.  <URL:
         http://www.umich.edu/~dirsvcs/ldap/doc/guides/slapd/toc.html>
 
+   [9]  M. P. Armijo, "Tree Delete Control", Microsoft Corporation,
+        INTERNET-DRAFT June 1999, <URL:http://www.ietf.org/internet-
+        drafts/draft-armijo-ldap-treedelete-01.txt>
+
+
 
 
 Author's Address
@@ -636,7 +869,7 @@ Author's Address
         Phone:  +1 650 937-3825
         EMail:  ggood@netscape.com
 
-                 This Internet Draft expires August 22nd, 1999.
+                  This Internet Draft expires 19 April, 2000.
 
 
 
@@ -656,17 +889,5 @@ Author's Address
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-Good                       February 22, 1999                   [Page 12]
-\f
+Good                        October 18, 1999                   [Page 16]
+\f
\ No newline at end of file
diff --git a/doc/drafts/draft-ietf-asid-ldapv3-attributes-03.txt b/doc/drafts/draft-ietf-asid-ldapv3-attributes-03.txt
new file mode 100644 (file)
index 0000000..d622f7e
--- /dev/null
@@ -0,0 +1,2261 @@
+
+Network Working Group                                            M. Wahl
+INTERNET-DRAFT                                       Critical Angle Inc.
+Obsoletes: RFC 1778                                          A. Coulbeck
+                                                        ISODE Consortium
+                                                                T. Howes
+                                           Netscape Communications Corp.   
+                                                                S. Kille
+                                                        ISODE Consortium
+Intended Category: Standards Track                      October 22, 1996
+
+
+                   Lightweight Directory Access Protocol:
+                  Standard and Pilot Attribute Definitions
+                 <draft-ietf-asid-ldapv3-attributes-03.txt> 
+
+1. Status of this Memo
+
+   This document is an Internet-Draft.  Internet-Drafts are working 
+   documents of the Internet Engineering Task Force (IETF), its areas, and
+   its working groups.  Note that other groups may also distribute working
+   documents as Internet-Drafts.
+   Internet-Drafts are draft documents valid for a maximum of six months
+   and may be updated, replaced, or obsoleted by other documents at any
+   time.  It is inappropriate to use Internet-Drafts as reference material
+   or to cite them other than as "work in progress."
+   To learn the current status of any Internet-Draft, please check the
+   "1id-abstracts.txt" listing  contained in the Internet-Drafts Shadow
+   Directories on ds.internic.net (US East Coast), nic.nordu.net (Europe),
+   ftp.isi.edu (US West Coast), or munnari.oz.au (Pacific Rim).
+
+2. Abstract
+
+   The Lightweight Directory Access Protocol (LDAP) [1] requires that the 
+   contents of AttributeValue fields in protocol elements be octet 
+   strings.  This document defines the requirements that must be 
+   satisfied by encoding rules used to render directory attribute 
+   syntaxes into a form suitable for use in the LDAP, then goes on to 
+   define the encoding rules for the standard set of attribute syntaxes 
+   of [2],[3] and [4].  It also identifies all the attribute types, object 
+   classes and matching rules for LDAP version 3.
+
+3. Overview
+
+   Section 4 states the general requirements and notations for attribute 
+   types, object classes, syntax and matching rule definitions.
+
+   The core definitions are given in section 5, those which are based on 
+   X.500(1993) in section 6, and other optional definitions in section 7.
+
+
+
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 1]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+4. General Issues
+
+4.1. Attribute Types
+
+   The attribute types are described by sample values for the subschema 
+   "attributeTypes" attribute, which is written in the 
+   AttributeTypeDescription syntax.  While lines have been folded for 
+   readability, the values transferred in protocol would not contain 
+   newlines.  
+
+   The AttributeTypeDescription is encoded according to the following BNF,
+   and the productions for <oid>, <DirectoryStrings> and <DirectoryString>
+   are given in sections 4.2.1.
+
+      <AttributeTypeDescription> ::= "("
+          <oid>   -- AttributeType identifier
+          [ "NAME" <DirectoryStrings> ] -- name used in AttributeType
+          [ "DESC" <DirectoryString> ]
+          [ "OBSOLETE" ]
+          [ "SUP" <oid> ]         -- derived from this other AttributeType
+          [ "EQUALITY" <oid> ]    -- Matching Rule name
+          [ "ORDERING" <oid> ]    -- Matching Rule name
+          [ "SUBSTR" <oid> ]      -- Matching Rule name 
+          [ "SYNTAX" <DirectoryString> ] -- see section 4.2
+          [ "SINGLE-VALUE" ]              -- default multi-valued
+          [ "COLLECTIVE" ]                -- default not collective
+          [ "NO-USER-MODIFICATION" ]      -- default user modifiable
+          [ "USAGE" <AttributeUsage> ]    -- default user applications
+          ")"
+    
+      <AttributeUsage> ::=
+          "userApplications"
+      |   "directoryOperation"
+      |   "distributedOperation"  -- DSA-shared
+      |   "dSAOperation"          -- DSA-specific, value depends on server
+
+   Servers are not required to provide the same or any text 
+   in the description part of the subschema values they maintain.
+
+   Servers must implement all the attribute types in section 5.1, and 
+   may also implement the types listed in sections 6.1 and 7.1.  Servers must
+   be able to perform equality matching of values, but need not perform 
+   any additional validity checks on attribute values.
+   
+   Servers may recognize additional names and attributes not listed in this
+   document.  Later documents may define additional types.
+
+   Servers may implement additional attribute types not listed in this 
+   document, and if they do so, must publish the definitions of the types
+   in the attributeTypes attribute of their subschema subentries.
+
+   AttributeDescriptions may be used as the value in a NAME part of an
+   AttributeTypeDescription.  Note that these are case insensitive.
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 2]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+4.2. Syntaxes
+
+   This section defines general requirements for LDAP attribute value
+   syntax encodings. All documents defining attribute syntax encodings for
+   use with LDAP are expected to conform to these requirements.
+
+   The encoding rules defined for a given attribute syntax must produce
+   octet strings.  To the greatest extent possible, encoded octet
+   strings should be usable in their native encoded form for display
+   purposes. In particular, encoding rules for attribute syntaxes
+   defining non-binary values should produce strings that can be
+   displayed with little or no translation by clients implementing 
+   LDAP.  There are a few cases (e.g. Audio) however, when it is not sensible
+   to produce a printable representation, and clients must not assume that
+   an unrecognized syntax is a string representation.
+
+4.2.1. Common Encoding Aspects
+
+   In these encodings where an arbitrary string is used as part of a larger 
+   production (other than a Distinguished Name), a backslash quoting mechanism 
+   is used to encode the following separator symbol character (such as ''', 
+   '$' or '#') if it should occur in that string.  The backslash is followed 
+   by a pair of hexadecimal digits representing the next character.  A 
+   backslash itself in the string which forms part of a larger syntax is   
+   always transmitted as '\5C' or '\5c'.
+
+   For the purposes of defining the encoding rules for attribute syntaxes,
+   the following auxiliary BNF definitions will be used:
+
+     <a> ::= 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' |
+             'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' |
+             's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | 'A' |
+             'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' |
+             'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' |
+             'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z'
+
+     <d> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
+
+     <hex-digit> ::= <d> | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' |
+                      'A' | 'B' | 'C' | 'D' | 'E' | 'F'
+
+     <k> ::= <a> | <d> | '-'
+
+     <p> ::= <a> | <d> | ''' | '(' | ')' | '+' | ',' | '-' | '.' |
+             '/' | ':' | '?' | ' '
+
+     <letterstring> ::= <a> | <a> <letterstring>
+
+     <numericstring> ::= <d> | <d> <numericstring>
+
+     <keystring> ::= <a> | <a> <anhstring>
+
+     <anhstring> ::= <k> | <k> <anhstring>
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 3]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+     <printablestring> ::= <p> | <p> <printablestring>
+
+     <space> ::= ' ' | ' ' <space>
+
+     <whsp> ::= <space> | empty
+
+     <utf8> ::= any sequence of octets formed from the UTF-8 [11]  
+                transformation of a character from ISO 10646 [12]
+
+     <dstring> ::= <utf8> | <utf8> <dstring>
+
+     <DirectoryStrings> ::= <DirectoryString> | '(' <DirectoryStringList> ')'
+
+     <DirectoryStringList> ::= <DirectoryStringList> <DirectoryString> | ""
+
+     <DirectoryString> ::= ''' <dstring> '''
+  
+     <oids> ::= <oid> | '(' <oidlist> ')'
+    
+     <oidlist> ::= <oidlist> '$' <oid> | <oid>   
+
+     -- <oid> is defined in 5.2.1.15
+
+4.2.2  Binary Transfer of Values
+
+   This encoding format is used if the binary encoding is requested by the 
+   client for an attribute, or if the attribute syntax name is 'Binary'.  The 
+   value, an instance of the ASN.1 AttributeValue type, is BER-encoded, 
+   subject to the restrictions of section 5.1 of [1], and this sequence of 
+   octets is used as the value.  
+
+   All servers must implement this form for both generating Search responses
+   and parsing Add, Compare and Modify requests.  Clients must be prepared 
+   receiving values in binary (e.g. userCertificate or audio), and must not
+   simply display binary or unrecognized values to users.
+
+4.2.3. Syntax Namees
+
+   Names of syntaxes for use with LDAP are ASCII strings which either
+   begin with a letter and contain only letters or digits.  The names are 
+   case insensitive.  Historically since syntaxes correspond to ASN.1 types, 
+   they have been named starting with a capital letter.  A suggested upper
+   bound on the number of characters in value with a DirectoryString or 
+   IA5String syntax or the number of bytes in a value for all other syntaxes
+   may be indicated by appending this bound count inside of curly braces, e.g.
+   "DirectoryString{64}".  Note that a single character of the DirectoryString
+   may be encoded in more than one byte since UTF-8 is a variable-length 
+   encoding.
+
+   Syntax names do not have global scope: two clients or servers may 
+   know of different syntaxes with the same name.  
+
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 4]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+   The definition of additional arbitrary syntaxes is strongly depreciated 
+   since it will hinder interoperability: today's client and server 
+   implementations generally do not have the ability to dynamically recognize
+   new syntaxes.  In most cases attributes will be defined with the 
+   DirectoryString syntax. 
+
+   The following syntax names are used for attributes in this document.
+   Servers are only required to implement the syntaxes in section 5.2.  
+
+      AccessPoint                       ACIItem                        
+      AttributeTypeDescription          Audio                          
+      Binary                            BitString                      
+      Certificate                       CertificateList                
+      CertificatePair                   DataQualitySyntax              
+      DeliveryMethod                    DirectoryString                
+      DITContentRuleDescription         DN                             
+      DSAQualitySyntax                  DSEType                        
+      EnhancedGuide                     FacsimileTelephoneNumber       
+      Fax                               GeneralizedTime                
+      Guide                             IA5String                      
+      INTEGER                           JPEG                           
+      MailPreference                    MasterAndShadowAccessPoints    
+      MatchingRuleDescription           MatchingRuleUseDescription     
+      ModifyRight                       NameAndOptionalUID             
+      NameFormDescription               NumericString                  
+      ObjectClassDescription            OID                            
+      OtherMailbox                      Password                       
+      PostalAddress                     PresentationAddress            
+      PrintableString                   ProtocolInformation            
+      SubtreeSpecification              SupplierAndConsumers           
+      SupplierInformation               SupplierOrConsumer             
+      TelephoneNumber                   TeletexTerminalIdentifier      
+      TelexNumber                       UTCTime                        
+
+4.3. Object Classes
+
+   These are described as sample values for the subschema "objectClasses" 
+   attribute for a server which implements the LDAP schema.
+   While lines have been folded for readability, the values transferred in 
+   protocol would not contain newlines.
+
+   Object class descriptions are written according to the following BNF:
+
+      <ObjectClassDescription> ::= "("
+          <oid>   -- ObjectClass identifier
+          [ "NAME" <DirectoryStrings> ]
+          [ "DESC" <DirectoryString> ]
+          [ "OBSOLETE" ]
+          [ "SUP" <oids> ]    -- Superior ObjectClasses
+          [ ( "ABSTRACT" | "STRUCTURAL" | "AUXILIARY" ) ] -- default structural
+          [ "MUST" <oids> ]   -- AttributeTypes
+          [ "MAY" <oids> ]    -- AttributeTypes
+      ")"
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 5]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+   Servers must implement all the object classes in section 5.3:
+      account                           alias                 
+      applicationEntity                 applicationProcess          
+      certificationAuthority            country                     
+      dNSDomain                         dSA                        
+      device                            document                   
+      documentSeries                    domain                     
+      domainRelatedObject               friendlyCountry             
+      groupOfNames                      groupOfUniqueNames          
+      locality                          newPilotPerson              
+      organization                      organizationalPerson        
+      organizationalRole                organizationalUnit            
+      person                            pilotDSA                    
+      pilotObject                       pilotOrganization           
+      qualityLabelledData               rFC822localPart             
+      residentialPerson                 room                         
+      simpleSecurityObject              strongAuthenticationUser    
+      top                                     
+
+   and may also implement the object classes of 6.3 and 7.3.
+
+   Servers may implement additional object classes not listed in this 
+   document, and if they do so, must publish the definitions of the classes
+   in the objectClasses attribute of their subschema subentries.  Later 
+   documents may define additional object classes.
+
+4.4. Matching Rules
+
+   Matching rules are used by servers to compare attribute values against
+   assertion values when performing Search and Compare operations.  
+  
+   Most of the attributes given in this document will have an equality 
+   matching rule defined.
+
+   Matching rule descriptions are written according to the following BNF:
+
+      <MatchingRuleDescription> ::= "("
+          <oid>   -- MatchingRule identifier
+          [ "NAME" <DirectoryStrings> ]
+          [ "DESC" <DirectoryString> ]
+          [ "OBSOLETE" ]
+          "SYNTAX" <DirectoryString>
+         ")"
+
+   Servers must implement all the matching rules in section 5.4:
+      bitStringMatch                    caseExactIA5Match                
+      caseIgnoreIA5Match                caseIgnoreListMatch              
+      caseIgnoreMatch                   distinguishedNameMatch           
+      generalizedTimeMatch              integerMatch                     
+      numericStringMatch                objectIdentifierMatch            
+      octetStringMatch                  telephoneNumberMatch             
+
+   and may also implement the matching rules of 6.4 and 7.4.
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 6]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+   Servers may implement additional matching rules not listed in this 
+   document, and if they do so, must publish the definitions of the 
+   matching rules in the matchingRules attribute of their 
+   subschema subentries.
+
+5. Mandatory Definitions
+
+   Section 5 contains definitions which must be implemented by all servers.
+   
+
+5.1. Attribute Types
+
+   Servers must recognize all the attributes of this section (5.1.1 - 5.1.5).
+
+5.1.1. Standard User Attributes
+
+   The attributes listed in this section are those defined in X.520(1993),
+   likely to be present in user entries.  Servers must recognize all the
+   attributes of this section.  The semantics of attributes 2.5.4.0 through
+   2.5.4.40 are summarized in RFC 1274.
+
+    ( 2.5.4.0 NAME 'objectClass' EQUALITY objectIdentifierMatch SYNTAX 'OID' ) 
+
+    ( 2.5.4.1 NAME 'aliasedObjectName' EQUALITY distinguishedNameMatch
+      SYNTAX 'DN' SINGLE-VALUE ) 
+
+    ( 2.5.4.2 NAME 'knowledgeInformation' EQUALITY caseIgnoreMatch 
+      SYNTAX 'DirectoryString{32768}' ) 
+
+    ( 2.5.4.3 NAME 'cn' SUP name )
+
+    ( 2.5.4.4 NAME 'sn' SUP name )
+
+    ( 2.5.4.5 NAME 'serialNumber' EQUALITY caseIgnoreMatch 
+      SUBSTRINGS caseIgnoreSubstringsMatch SYNTAX 'PrintableString{64}' ) 
+
+    ( 2.5.4.6 NAME 'c' SUP name SINGLE-VALUE ) 
+
+    ( 2.5.4.7 NAME 'l' SUP name )
+
+    ( 2.5.4.8 NAME 'st' SUP name )
+
+    ( 2.5.4.9 NAME 'street' EQUALITY caseIgnoreMatch 
+      SUBSTRINGS caseIgnoreSubstringsMatch SYNTAX 'DirectoryString{128}' ) 
+
+    ( 2.5.4.10 NAME 'o' SUP name )
+
+    ( 2.5.4.11 NAME 'ou' SUP name )
+
+    ( 2.5.4.12 NAME 'title' SUP name )
+
+    ( 2.5.4.13 NAME 'description' EQUALITY caseIgnoreMatch
+      SUBSTRINGS caseIgnoreSubstringsMatch SYNTAX 'DirectoryString{1024}' ) 
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 7]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+    ( 2.5.4.14 NAME 'searchGuide' SYNTAX 'Guide' ) 
+
+    ( 2.5.4.15 NAME 'businessCategory' EQUALITY caseIgnoreMatch
+      SUBSTRINGS caseIgnoreSubstringsMatch SYNTAX 'DirectoryString{128}' ) 
+
+    ( 2.5.4.16 NAME 'postalAddress' EQUALITY caseIgnoreListMatch 
+      SUBSTRINGS caseIgnoreListSubstringsMatch SYNTAX 'PostalAddress' ) 
+
+    ( 2.5.4.17 NAME 'postalCode' EQUALITY caseIgnoreMatch
+      SUBSTRINGS caseIgnoreSubstringsMatch SYNTAX 'DirectoryString{40}' ) 
+
+    ( 2.5.4.18 NAME 'postOfficeBox' EQUALITY caseIgnoreMatch
+      SUBSTRINGS caseIgnoreSubstringsMatch SYNTAX 'DirectoryString{40}' ) 
+
+    ( 2.5.4.19 NAME 'physicalDeliveryOfficeName' EQUALITY caseIgnoreMatch
+      SUBSTRINGS caseIgnoreSubstringsMatch SYNTAX 'DirectoryString{128}' ) 
+
+    ( 2.5.4.20 NAME 'telephoneNumber' EQUALITY telephoneNumberMatch 
+      SUBSTRINGS telephoneNumberSubstringsMatch SYNTAX 'TelephoneNumber{32}' ) 
+
+    ( 2.5.4.21 NAME 'telexNumber' SYNTAX 'TelexNumber' ) 
+
+    ( 2.5.4.22 NAME 'teletexTerminalIdentifier' 
+      SYNTAX 'TeletexTerminalIdentifier' ) 
+
+    ( 2.5.4.23 NAME 'facsimileTelephoneNumber' 
+      SYNTAX 'FacsimileTelephoneNumber' ) 
+
+    ( 2.5.4.24 NAME 'x121Address' EQUALITY numericStringMatch
+      SUBSTRINGS numericStringSubstringsMatch SYNTAX 'NumericString{15}' ) 
+
+    ( 2.5.4.25 NAME 'internationaliSDNNumber' EQUALITY numericStringMatch
+      SUBSTRINGS numericStringSubstringsMatch SYNTAX 'NumericString{16}' ) 
+
+    ( 2.5.4.26 NAME 'registeredAddress' SUP postalAddress 
+      SYNTAX 'PostalAddress' ) 
+
+    ( 2.5.4.27 NAME 'destinationIndicator' EQUALITY caseIgnoreMatch
+      SUBSTRINGS caseIgnoreSubstringsMatch SYNTAX 'PrintableString{128}' ) 
+
+    ( 2.5.4.28 NAME 'preferredDeliveryMethod' SYNTAX 'DeliveryMethod' 
+      SINGLE-VALUE ) 
+
+    ( 2.5.4.29 NAME 'presentationAddress' EQUALITY presentationAddressMatch
+      SYNTAX 'PresentationAddress' SINGLE-VALUE ) 
+
+    ( 2.5.4.30 NAME 'supportedApplicationContext' 
+      EQUALITY objectIdentifierMatch SYNTAX 'OID' ) 
+
+    ( 2.5.4.31 NAME 'member' SUP distinguishedName ) 
+
+    ( 2.5.4.32 NAME 'owner' SUP distinguishedName ) 
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 8]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+    ( 2.5.4.33 NAME 'roleOccupant' SUP distinguishedName ) 
+
+    ( 2.5.4.34 NAME 'seeAlso' SUP distinguishedName ) 
+
+    ( 2.5.4.35 NAME 'userPassword' EQUALITY octetStringMatch
+      SYNTAX 'Password{128}' ) 
+
+    ( 2.5.4.36 NAME 'userCertificate' SYNTAX 'Certificate' ) 
+
+    ( 2.5.4.37 NAME 'cACertificate' SYNTAX 'Certificate' ) 
+
+    ( 2.5.4.38 NAME 'authorityRevocationList' SYNTAX 'CertificateList' ) 
+
+    ( 2.5.4.39 NAME 'certificateRevocationList' SYNTAX 'CertificateList' ) 
+
+    ( 2.5.4.40 NAME 'crossCertificatePair' SYNTAX 'CertificatePair' ) 
+
+    ( 2.5.4.41 NAME 'name' 
+      DESC 'The name attribute type is the attribute supertype from which
+            string attribute types typically used for naming may be formed.'
+      EQUALITY caseIgnoreMatch 
+      SUBSTRINGS caseIgnoreSubstringsMatch SYNTAX 'DirectoryString{32768}' ) 
+
+    ( 2.5.4.42 NAME 'givenName' SUP name )
+
+    ( 2.5.4.43 NAME 'initials' 
+      DESC 'The initials attribute type contains the initials of some or all 
+            of an individuals names, but not the surname(s).'
+      SUP name )
+
+    ( 2.5.4.44 NAME 'generationQualifier' 
+      DESC 'e.g. Jr or II.'
+      SUP name )
+
+    ( 2.5.4.45 NAME 'x500UniqueIdentifier' 
+      DESC 'used to distinguish between objects when a distinguished name has
+            been reused.'
+      EQUALITY bitStringMatch SYNTAX 'BitString' ) 
+
+    ( 2.5.4.46 NAME 'dnQualifier' 
+      DESC 'The dnQualifier attribute type specifies disambiguating 
+            information to add to the relative distinguished name of an
+            entry.  It is intended to be used for entries held in multiple
+            DSAs which would otherwise have the same name, and that its
+            value be the same in a given DSA for all entries to which this 
+            information has been added.'
+      EQUALITY caseIgnoreMatch
+      ORDERING caseIgnoreOrderingMatch SUBSTRINGS caseIgnoreSubstringsMatch
+      SYNTAX 'PrintableString' ) 
+
+    ( 2.5.4.47 NAME 'enhancedSearchGuide' SYNTAX 'EnhancedGuide' ) 
+
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 9]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+    ( 2.5.4.48 NAME 'protocolInformation' EQUALITY protocolInformationMatch
+      SYNTAX 'ProtocolInformation' ) 
+
+    ( 2.5.4.49 NAME 'distinguishedName' 
+      DESC 'This is not the name of the object itself, but a base type 
+            from which attributes with DN syntax inherit.'
+      EQUALITY distinguishedNameMatch
+      SYNTAX 'DN' ) 
+
+    ( 2.5.4.50 NAME 'uniqueMember' EQUALITY uniqueMemberMatch 
+      SYNTAX 'NameAndOptionalUID' ) 
+
+    ( 2.5.4.51 NAME 'houseIdentifier' EQUALITY caseIgnoreMatch
+      SUBSTRINGS caseIgnoreSubstringsMatch SYNTAX 'DirectoryString{32768}' ) 
+
+5.1.2. Pilot User Attributes
+
+   These attributes are defined in RFC 1274.  Servers must recognize all the 
+   attributes of this section.
+
+    ( 0.9.2342.19200300.100.1.1 NAME 'uid' EQUALITY caseIgnoreMatch
+      SUBSTRINGS caseIgnoreSubstringsMatch SYNTAX 'DirectoryString{256}' ) 
+
+    ( 0.9.2342.19200300.100.1.2 NAME 'textEncodedORaddress' 
+      EQUALITY caseIgnoreMatch SUBSTRINGS caseIgnoreSubstringsMatch 
+      SYNTAX 'DirectoryString{256}' ) 
+
+    ( 0.9.2342.19200300.100.1.3 NAME 'mail' EQUALITY caseIgnoreIA5Match
+      SUBSTRINGS caseIgnoreIA5SubstringsMatch SYNTAX 'IA5String{256}' ) 
+
+    ( 0.9.2342.19200300.100.1.4 NAME 'info' EQUALITY caseIgnoreMatch
+      SUBSTRINGS caseIgnoreSubstringsMatch SYNTAX 'DirectoryString{2048}' ) 
+
+    ( 0.9.2342.19200300.100.1.5 NAME 'drink' EQUALITY caseIgnoreMatch
+      SUBSTRINGS caseIgnoreSubstringsMatch SYNTAX 'DirectoryString{256}' ) 
+
+    ( 0.9.2342.19200300.100.1.6 NAME 'roomNumber' EQUALITY caseIgnoreMatch
+      SUBSTRINGS caseIgnoreSubstringsMatch SYNTAX 'DirectoryString{256}' ) 
+
+    ( 0.9.2342.19200300.100.1.7 NAME 'photo' SYNTAX 'Fax{250000}' ) 
+
+    ( 0.9.2342.19200300.100.1.8 NAME 'userClass' EQUALITY caseIgnoreMatch
+      SUBSTRINGS caseIgnoreSubstringsMatch SYNTAX 'DirectoryString{256}' ) 
+
+    ( 0.9.2342.19200300.100.1.9 NAME 'host' EQUALITY caseIgnoreMatch
+      SUBSTRINGS caseIgnoreSubstringsMatch SYNTAX 'DirectoryString{256}' ) 
+
+    ( 0.9.2342.19200300.100.1.10 NAME 'manager' 
+      EQUALITY distinguishedNameMatch SYNTAX 'DN' ) 
+
+    ( 0.9.2342.19200300.100.1.11 NAME 'documentIdentifier' 
+      EQUALITY caseIgnoreMatch SUBSTRINGS caseIgnoreSubstringsMatch 
+      SYNTAX 'DirectoryString{256}' ) 
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 10]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+    ( 0.9.2342.19200300.100.1.12 NAME 'documentTitle' EQUALITY caseIgnoreMatch
+      SUBSTRINGS caseIgnoreSubstringsMatch SYNTAX 'DirectoryString{256}' ) 
+
+    ( 0.9.2342.19200300.100.1.13 NAME 'documentVersion' 
+      EQUALITY caseIgnoreMatch SUBSTRINGS caseIgnoreSubstringsMatch 
+      SYNTAX 'DirectoryString{256}' ) 
+
+    ( 0.9.2342.19200300.100.1.14 NAME 'documentAuthor' 
+      EQUALITY distinguishedNameMatch SYNTAX 'DN' ) 
+
+    ( 0.9.2342.19200300.100.1.15 NAME 'documentLocation' 
+      EQUALITY caseIgnoreMatch SUBSTRINGS caseIgnoreSubstringsMatch 
+      SYNTAX 'DirectoryString{256}' ) 
+
+    ( 0.9.2342.19200300.100.1.20 NAME 'homePhone' EQUALITY telephoneNumberMatch
+      SUBSTRINGS telephoneNumberSubstringsMatch SYNTAX 'TelephoneNumber{32}' ) 
+
+    ( 0.9.2342.19200300.100.1.21 NAME 'secretary' 
+      EQUALITY distinguishedNameMatch SYNTAX 'DN' ) 
+
+    ( 0.9.2342.19200300.100.1.22 NAME 'otherMailbox' SYNTAX 'OtherMailbox' ) 
+
+    ( 0.9.2342.19200300.100.1.25 NAME 'dc' EQUALITY caseIgnoreIA5Match 
+      SUBSTRINGS caseIgnoreIA5SubstringsMatch SYNTAX 'IA5String' ) 
+
+    ( 0.9.2342.19200300.100.1.26 NAME 'dNSRecord' 
+      EQUALITY caseExactIA5Match SYNTAX 'IA5String'  ) 
+
+    ( 0.9.2342.19200300.100.1.37 NAME 'associatedDomain' 
+      EQUALITY caseIgnoreIA5Match SUBSTRINGS caseIgnoreIA5SubstringsMatch
+      SYNTAX 'IA5String' ) 
+
+    ( 0.9.2342.19200300.100.1.38 NAME 'associatedName' 
+      EQUALITY distinguishedNameMatch SYNTAX 'DN' ) 
+
+    ( 0.9.2342.19200300.100.1.39 NAME 'homePostalAddress' 
+      EQUALITY caseIgnoreListMatch 
+      SUBSTRINGS caseIgnoreListSubstringsMatch SYNTAX 'PostalAddress' ) 
+
+    ( 0.9.2342.19200300.100.1.40 NAME 'personalTitle' 
+      EQUALITY caseIgnoreMatch SUBSTRINGS caseIgnoreSubstringsMatch 
+      SYNTAX 'DirectoryString' ) 
+
+    ( 0.9.2342.19200300.100.1.41 NAME 'mobile' EQUALITY telephoneNumberMatch
+      SUBSTRINGS telephoneNumberSubstringsMatch SYNTAX 'TelephoneNumber{32}' ) 
+
+    ( 0.9.2342.19200300.100.1.42 NAME 'pager' EQUALITY telephoneNumberMatch
+      SUBSTRINGS telephoneNumberSubstringsMatch SYNTAX 'TelephoneNumber{32}' ) 
+
+    ( 0.9.2342.19200300.100.1.43 NAME 'co' EQUALITY caseIgnoreMatch
+      SUBSTRINGS caseIgnoreSubstringsMatch SYNTAX 'DirectoryString' ) 
+
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 11]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+    ( 0.9.2342.19200300.100.1.44 NAME 'uniqueIdentifier' 
+      EQUALITY caseIgnoreMatch SUBSTRINGS caseIgnoreSubstringsMatch 
+      SYNTAX 'DirectoryString' ) 
+
+    ( 0.9.2342.19200300.100.1.45 NAME 'organizationalStatus' 
+      EQUALITY caseIgnoreMatch SUBSTRINGS caseIgnoreSubstringsMatch
+      SYNTAX 'DirectoryString{256}' ) 
+
+    ( 0.9.2342.19200300.100.1.46 NAME 'janetMailbox' 
+      EQUALITY caseIgnoreIA5Match SUBSTRINGS caseIgnoreIA5SubstringsMatch 
+      SYNTAX 'IA5String{256}' ) 
+
+    ( 0.9.2342.19200300.100.1.47 NAME 'mailPreferenceOption' 
+      SYNTAX 'INTEGER' SINGLE-VALUE }
+
+    ( 0.9.2342.19200300.100.1.48 NAME 'buildingName' 
+      EQUALITY caseIgnoreMatch SUBSTRINGS caseIgnoreSubstringsMatch
+      SYNTAX 'DirectoryString{256}' ) 
+    ( 0.9.2342.19200300.100.1.49 NAME 'dSAQuality' 
+      SYNTAX 'DSAQualitySyntax' SINGLE-VALUE ) 
+    ( 0.9.2342.19200300.100.1.50 NAME 'singleLevelQuality' 
+      SYNTAX 'DataQualitySyntax' SINGLE-VALUE ) 
+    ( 0.9.2342.19200300.100.1.51 NAME 'subtreeMinimumQuality' 
+      SYNTAX 'DataQualitySyntax' SINGLE-VALUE ) 
+    ( 0.9.2342.19200300.100.1.52 NAME 'subtreeMaximumQuality' 
+      SYNTAX 'DataQualitySyntax' SINGLE-VALUE ) 
+    ( 0.9.2342.19200300.100.1.53 NAME 'personalSignature' 
+      SYNTAX 'Fax{50000}' ) 
+    ( 0.9.2342.19200300.100.1.54 NAME 'dITRedirect' 
+      EQUALITY distinguishedNameMatch SYNTAX 'DN' ) 
+    ( 0.9.2342.19200300.100.1.55 NAME 'audio' SYNTAX 'Audio{250000}' ) 
+    ( 0.9.2342.19200300.100.1.56 NAME 'documentPublisher' 
+      EQUALITY caseIgnoreMatch SUBSTRINGS caseIgnoreSubstringsMatch 
+      SYNTAX 'DirectoryString' ) 
+    ( 0.9.2342.19200300.100.1.60 NAME 'jpegPhoto' SYNTAX 'JPEG' ) 
+
+
+
+
+
+
+
+
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 12]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+5.1.3. Standard Operational Attributes
+
+   All servers must recognize the attribute types defined in this
+   section.
+
+    ( 2.5.18.1 NAME 'createTimestamp' EQUALITY generalizedTimeMatch
+      ORDERING generalizedTimeOrderingMatch SYNTAX 'GeneralizedTime' 
+      SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation ) 
+    ( 2.5.18.2 NAME 'modifyTimestamp' EQUALITY generalizedTimeMatch
+      ORDERING generalizedTimeOrderingMatch SYNTAX 'GeneralizedTime' 
+      SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation ) 
+    ( 2.5.18.3 NAME 'creatorsName' EQUALITY distinguishedNameMatch SYNTAX 'DN' 
+      SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation ) 
+    ( 2.5.18.4 NAME 'modifiersName' EQUALITY distinguishedNameMatch SYNTAX 'DN'
+      SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation ) 
+
+    ( 2.5.18.10 NAME 'subschemaSubentry' 
+      DESC 'The value of this attribute is the name of a subschema subentry, 
+            an entry in which the server makes available attributes specifying 
+            the schema.' 
+      EQUALITY distinguishedNameMatch SYNTAX 'DN' NO-USER-MODIFICATION 
+      SINGLE-VALUE USAGE directoryOperation )
+
+    ( 2.5.21.5 NAME 'attributeTypes' 
+      EQUALITY objectIdentifierFirstComponentMatch
+      SYNTAX 'AttributeTypeDescription' USAGE directoryOperation ) 
+
+    ( 2.5.21.6 NAME 'objectClasses' 
+      EQUALITY objectIdentifierFirstComponentMatch
+      SYNTAX 'ObjectClassDescription' USAGE directoryOperation ) 
+
+5.1.4. LDAP Operational Attributes
+
+   All servers must recognize the attribute types defined in this section.  
+   (Of course, it is not required that the server provide values for these 
+   attributes, when the attribute corresponds to a feature which the server 
+   does not implement.)
+
+    ( 1.3.6.1.4.1.1466.101.120.1 NAME 'administratorsAddress' 
+     DESC 'This attribute\27s values are string containing the addresses of
+           the LDAP server\27s human administrator.  This information may 
+           be of use when tracking down problems in an Internet distributed 
+           directory.  For simplicity the syntax of the values are limited to 
+           being URLs of the mailto form with an RFC 822 address: 
+           "mailto:user@domain".  Future versions of this protocol may permit 
+           other forms of addresses.' 
+     SYNTAX 'IA5String' USAGE dSAOperation )
+
+
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 13]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+    ( 1.3.6.1.4.1.1466.101.120.2 NAME 'currentTime'
+     DESC 'This attribute has a single value, a string containing a 
+           GeneralizedTime character string.  This attribute need only 
+           be present if the server supports LDAP strong or protected 
+           simple authentication. Otherwise if the server does not know 
+           the current time, or does not choose to present it to clients,
+           this attribute need not be present. The client may wish to 
+           use this value to detect whether a strong or protected bind 
+           is failing because the client and server clocks are not 
+           sufficiently synchronized.  Clients must not use this time 
+           field for setting their own system clock.' 
+      SYNTAX 'GeneralizedTime' SINGLE-VALUE USAGE dSAOperation )
+
+    ( 1.3.6.1.4.1.1466.101.120.3 NAME 'serverName'  
+     DESC 'This attribute\27s value is the server\27s Distinguished Name.  
+           If the server does not have a Distinguished Name it will not 
+           be able to accept X.509-style strong authentication, and this 
+           attribute must be absent.  However the presence of this 
+           attribute does not guarantee that the server will be able to 
+           perform strong authentication.  If the server acts as a 
+           gateway to more than one X.500 DSA capable of strong 
+           authentication, there may be multiple values of this 
+           attribute, one per DSA.  (Note: this attribute is distinct 
+           from myAccessPoint, for it is not required that a server 
+           have a presentation address in order to perform strong 
+           authentication.)  (Note: it is likely that clients will
+           retrieve this attribute in binary.)' 
+     SYNTAX 'DN' USAGE dSAOperation )
+
+    ( 1.3.6.1.4.1.1466.101.120.4 NAME 'certificationPath'
+     DESC 'This attribute contains a binary DER encoding of an 
+           AF.CertificatePath data type, which is the certificate 
+           path for a server.  If the server does not have a certificate
+           path this attribute must be absent.  (Note: this attribute
+           may only be retrieved in binary.)'
+     SYNTAX 'CertificatePath' USAGE dSAOperation )
+
+    ( 1.3.6.1.4.1.1466.101.120.5 NAME 'namingContexts'
+     DESC 'The values of this attribute correspond to naming contexts 
+           which this server masters or shadows.  If the server does 
+           not master any information (e.g. it is an LDAP gateway to a 
+           public X.500 directory) this attribute must be absent.  If 
+           the server believes it contains the entire directory, the 
+           attribute must have a single value, and that value must
+           be the empty string (indicating the null DN of the root).
+           This attribute will allow clients to choose suitable base 
+           objects for searching when it has contacted a server.'
+     SYNTAX 'DN' USAGE dSAOperation )
+
+
+
+
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 14]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+    ( 1.3.6.1.4.1.1466.101.120.6 NAME 'altServer'
+     DESC 'The values of this attribute are URLs of other servers which 
+           may be contacted when this server becomes unavailable.  If 
+           the server does not know of any other servers which could be 
+           used this attribute must be absent. Clients may cache this 
+           information in case their preferred LDAP server later becomes 
+           unavailable.'
+     SYNTAX 'IA5String' USAGE dSAOperation )
+
+    ( 1.3.6.1.4.1.1466.101.120.7 NAME 'supportedExtension'
+     DESC 'The values of this attribute are OBJECT IDENTIFIERs,
+           the names of supported extended operations
+           which the server supports.   If the server does not support 
+           any extensions this attribute must be absent.'
+     SYNTAX 'OID' USAGE dSAOperation )
+
+    ( 1.3.6.1.4.1.1466.101.120.13 NAME 'supportedControl'
+     DESC 'The values of this attribute are the names of supported session
+           controls which the server supports.   If the server does not 
+           support any controls this attribute must be absent.'
+     SYNTAX 'LDAPString' USAGE dSAOperation )
+
+    ( 1.3.6.1.4.1.1466.101.120.14 NAME 'supportedSASLMechanisms'
+     DESC 'The values of this attribute are the names of supported SASL
+           mechanisms which the server supports.   If the server does not 
+           support any mechanisms this attribute must be absent.'
+     SYNTAX 'LDAPString' USAGE dSAOperation )
+
+    ( 1.3.6.1.4.1.1466.101.120.8 NAME 'entryName'   
+     SYNTAX 'DN' SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )
+
+    ( 1.3.6.1.4.1.1466.101.120.9 NAME 'modifyRights'
+     SYNTAX 'ModifyRight' NO-USER-MODIFICATION USAGE dSAOperation )
+
+    ( 1.3.6.1.4.1.1466.101.120.10 NAME 'incompleteEntry'
+     SYNTAX 'BOOLEAN' NO-USER-MODIFICATION USAGE dSAOperation )
+
+    ( 1.3.6.1.4.1.1466.101.120.11 NAME 'fromEntry'
+     SYNTAX 'BOOLEAN' NO-USER-MODIFICATION USAGE dSAOperation )
+
+5.1.5. LDAP User Attributes
+
+   The following attributes may be of use in naming entries, or as 
+   descriptive attributes in entries.
+
+   ( 1.3.6.1.4.1.1466.101.121.1 NAME 'url'
+     DESC 'Uniform Resource Locator'
+     EQUALITY caseExactIA5Match SYNTAX 'IA5String' )
+     
+   Note that the associatedDomain attribute may be used to hold a DNS name.
+
+
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 15]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+5.2. Syntaxes
+
+5.2.1. Standard User Syntaxes
+
+   Servers must recognize all the syntaxes described in this section.
+
+5.2.1.1. BitString
+
+   The encoding of a value with BitString syntax is according to the 
+   following BNF:
+
+      <bitstring> ::= ''' <binary-digits> ''B' 
+
+      <binary-digits> ::= '0' <binary-digits> | '1' <binary-digits> | 
+      empty
+
+5.2.1.2. PrintableString
+
+   The encoding of a value with PrintableString syntax is the string
+   value itself.  PrintableString is limited to the characters in 
+   production <p> of section 4.1.
+
+5.2.1.3. DirectoryString
+
+   A string with DirectoryString syntax is encoded in the UTF-8 form of 
+   ISO 10646 (a superset of Unicode).  Servers and clients must be prepared to 
+   receive arbitrary Unicode characters in values.
+
+   For characters in the PrintableString form, the value is encoded as the 
+   string value itself.
+
+   If it is of the TeletexString form, then the characters are transliterated
+   to their equivalents in UniversalString, and encoded in UTF-8 [11].
+
+   If it is of the UniversalString or BMPString forms [12], UTF-8 is used to 
+   encode them.  
+
+   Note: the form of DirectoryString is not indicated in protocol unless the
+   attribute value is carried in binary.  Servers which convert to DAP must 
+   choose an appropriate form.  Servers must not reject values merely because 
+   they contain legal Unicode characters outside of the range of printable 
+   ASCII.
+
+5.2.1.4. Certificate
+
+   Because of the changes from X.509(1988) and X.509(1993) and additional 
+   changes to the ASN.1 definition to support certificate extensions, no 
+   string representation is defined, and values with Certificate syntax 
+   must only be transferred using the binary encoding, by requesting or 
+   returning the attributes with descriptions "userCertificate;binary" or 
+   "caCertificate;binary".  The BNF notation in RFC 1778 for 
+   "User Certificate" is not recommended to be used.
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 16]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+5.2.1.5. CertificateList
+
+   Because of the incompatibility of the X.509(1988) and X.509(1993) 
+   definitions of revocation lists, values with CertificateList syntax
+   must only be transferred using a binary encoding, by requesting or 
+   returning the attributes with descriptions 
+   "certificateRevocationList;binary" or "authorityRevocationList;binary".  
+   The BNF notation in RFC 1778  for "Authority Revocation List" is not 
+   recommended to be used.
+
+5.2.1.6. CertificatePair
+
+   Because the Certificate is being carried in binary, values with 
+   CertificatePair syntax must only be transferred using a binary encoding, 
+   by requesting or returning the attribute description 
+   "crossCertificatePair;binary".  The BNF notation in RFC 1778 for 
+   "Certificate Pair" is not recommended to be used.
+
+5.2.1.7. CountryString
+
+   A value of CountryString syntax is encoded the same as a value of
+   DirectoryString syntax.  Note that this syntax is limited to values of
+   exactly two printable string characters.
+
+      <CountryString>  ::= <p> <p>
+
+5.2.1.8. DN
+
+   Values with DN (Distinguished Name) syntax are encoded to have the
+   representation defined in [5].  Note that this representation is not 
+   reversible to the original ASN.1 encoding as the CHOICE of any 
+   DirectoryString element in an RDN is no longer known.
+
+5.2.1.9. DeliveryMethod
+
+   Values with DeliveryMethod syntax are encoded according to the 
+   following BNF:
+
+      <delivery-value> ::= <pdm> | <pdm> '$' <delivery-value>
+
+      <pdm> ::= 'any' | 'mhs' | 'physical' | 'telex' | 'teletex' |
+                'g3fax' | 'g4fax' | 'ia5' | 'videotex' | 'telephone'
+
+5.2.1.10. EnhancedGuide
+
+   Values with the EnhancedGuide syntax are encoded according to the 
+   following BNF:
+
+       <EnhancedGuide> ::= <objectclass> '#' <criteria> '#' <subset>
+
+       <subset> ::= "baseobject" | "oneLevel" | "wholeSubtree"
+
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 17]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+   The <criteria> production is defined in the Guide syntax below.
+   This syntax has been added subsequent to RFC 1778.
+
+5.2.1.11. FacsimileTelephoneNumber
+
+   Values with the FacsimileTelephoneNumber syntax are encoded according  
+   to the following BNF:
+
+      <fax-number> ::= <printablestring> [ '$' <faxparameters> ]
+
+      <faxparameters> ::= <faxparm> | <faxparm> '$' <faxparameters>
+
+      <faxparm> ::= 'twoDimensional' | 'fineResolution' | 'unlimitedLength' |
+                   'b4Length' | 'a3Width' | 'b4Width' | 'uncompressed'
+
+   In the above, the first <printablestring> is the actual fax number,
+   and the <faxparm> tokens represent fax parameters.
+
+5.2.1.12. Guide
+
+   Values with the Guide syntax are encoded according to the following 
+   BNF:
+
+      <guide-value> ::= [ <object-class> '#' ] <criteria>
+
+     <object-class> ::= an encoded value with OID syntax
+
+     <criteria> ::= <criteria-item> | <criteria-set> | '!' <criteria>
+
+     <criteria-set> ::= [ '(' ] <criteria> '&' <criteria-set> [ ')' ] |
+                        [ '(' ] <criteria> '|' <criteria-set> [ ')' ]
+
+     <criteria-item> ::= [ '(' ] <attributetype> '$' <match-type> [ ')' ]
+
+     <match-type> ::= "EQ" | "SUBSTR" | "GE" | "LE" | "APPROX"
+
+5.2.1.13. NameAndOptionalUID
+
+   The encoding of a value with the NameAndOptionalUID syntax is according
+   to the following BNF:
+
+      <NameAndOptionalUID> ::= 
+                <DistinguishedName> [ '#' <BitString> ]
+
+   Although the '#' character may occur in a string representation of a 
+   distinguished name, no additional special quoting is done in the 
+   distinguished name other than that of [5].  
+
+   This syntax has been added subsequent to RFC 1778.
+
+
+
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 18]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+5.2.1.14. NumericString
+
+   The encoding of a string with the NumericString syntax is the string
+   value itself.
+
+5.2.1.15. OID
+
+   Values with OID (Object Identifier) syntax are encoded according to the
+   following BNF:
+
+      <oid> ::= <descr> | <numericoid>
+
+      <descr> ::= <keystring>
+
+      <numericoid> ::= <numericstring> | <numericstring> '.' <numericoid>
+
+   In the above BNF, <descr> is the syntactic representation of an
+   object descriptor, which must consist of letters and digits, starting 
+   with a letter. When encoding values with OID syntax, the first encoding
+   option must be used in preference to the second. That is, in encoding 
+   object identifiers, object descriptors (where assigned and known by 
+   the implementation) must be used in preference to numeric oids to 
+   the greatest extent possible. All permitted object descriptors for use
+   in LDAP are given in this document.  No other object descriptors may be 
+   used.  (Note that clients must expect that LDAPv2 implementations 
+   will return object descriptors other than those listed.)
+
+5.2.1.16. Password
+
+   Values with Password syntax are encoded as octet strings.
+
+5.2.1.17. PostalAddress
+
+   Values with the PostalAddress syntax are encoded according to the 
+   following BNF:
+
+      <postal-address> ::= <dstring> | <dstring> '$' <postal-address>
+
+   In the above, each <dstring> component of a postal address value is
+   encoded as a value of type DirectoryString syntax.  Backslashes and 
+   dollar characters, if they occur in the component, are quoted as 
+   described in section 4.2. 
+
+5.2.1.18. PresentationAddress
+
+   Values with the PresentationAddress syntax are encoded to have the
+   representation described in [6].  
+
+5.2.1.20. TelephoneNumber
+
+   Values with the TelephoneNumber syntax are encoded as if they were
+   Printable String types.  Telephone numbers are recommended in X.520 to
+   be in international form, e.g. "+1 512 305 0280".
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 19]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+5.2.1.21. TeletexTerminalIdentifier
+
+   Values with the TeletexTerminalIdentifier syntax are encoded according 
+   to the following BNF:
+
+      <teletex-id> ::= <ttx-term>  0*('$' <ttx-param>)
+
+      <ttx-term> ::= <printablestring>
+
+      <ttx-param> ::= <ttx-key> ':' <ttx-value>
+
+      <ttx-key> ::= 'graphic' | 'control' | 'misc' | 'page' | 'private'
+
+      <ttx-value> ::= <octetstring>
+
+   In the above, the first <printablestring> is the encoding of the
+   first portion of the teletex terminal identifier to be encoded, and
+   the subsequent 0 or more <octetstrings> are subsequent portions
+   of the teletex terminal identifier.
+
+5.2.1.22. TelexNumber
+
+   Values with the TelexNumber syntax are encoded according to the
+   following BNF:
+
+      <telex-number> ::= <actual-number> '$' <country> '$' <answerback>
+
+      <actual-number> ::= <printablestring>
+
+      <country> ::= <printablestring>
+
+      <answerback> ::= <printablestring>
+
+   In the above, <actual-number> is the syntactic representation of the
+   number portion of the TELEX number being encoded, <country> is the
+   TELEX country code, and <answerback> is the answerback code of a
+   TELEX terminal.
+
+5.2.1.23. UTCTime
+
+   Values with UTCTime syntax are encoded as if they were printable
+   strings with the strings containing a UTCTime value.  This is historical;
+   new attribute definitions must use GeneralizedTime instead.
+
+5.2.1.24. Boolean
+
+   Values with Boolean syntax are encoded according to the following
+   BNF:
+
+      <boolean> ::= "TRUE" | "FALSE"
+
+   Boolean values have an encoding of "TRUE" if they are logically true,
+   and have an encoding of "FALSE" otherwise.
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 20]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+5.2.2. Pilot Syntaxes
+
+   Servers must recognize all the syntaxes described in this section.
+
+5.2.2.1. Audio
+
+   The encoding of a value with Audio syntax is the octets of the value
+   itself, an 8KHz uncompressed encoding compatible with the SunOS 
+   4.1.3 'play' utility.
+
+5.2.2.2. DSAQualitySyntax
+
+   Values with this syntax are encoded according to the following BNF:
+
+      <DsaQualitySyntax> ::= <DSAKeyword> [ '#' <description> ]
+
+      <DSAKeyword> ::= 'DEFUNCT' | 'EXPERIMENTAL' | 'BEST-EFFORT' |
+                       'PILOT-SERVICE' | 'FULL-SERVICE'
+
+      <description> ::= encoded as a PrintableString
+
+5.2.2.3. DataQualitySyntax
+
+   Values with this syntax are encoded according to the following BNF:
+
+      <DataQualitySyntax> ::= <compKeyword> '#' <attrQuality> '#' 
+                              <listQuality> [ '#' <description> ]
+
+      <attrQuality> ::= <levelKeyword> '+' <compKeyword>
+   
+      <listQuality> ::= <list> '$' <list><listQuality>
+
+      <list> ::= <attribute> '+' <attrQuality>
+
+      <compKeyword> ::= 'NONE' | 'SAMPLE' | 'SELECTED' | 
+                        'SUBSTANTIAL' | 'FULL'
+      <levelKeyword> ::= 'UNKNOWN' | 'EXTERNAL' | 'SYSTEM-MAINTAINED' |
+                        'USER-SUPPLIED'
+
+5.2.2.4. IA5String
+
+   The encoding of a value with IA5String syntax is the string value
+   itself.
+
+5.2.2.5. JPEG
+
+   Values with JPEG syntax are encoded as if they were octet strings
+   containing JPEG images in the JPEG File Interchange Format (JFIF), as
+   described in [8].
+
+
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 21]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+5.2.2.6. MailPreference
+
+   Values with MailPreference syntax are encoded according to the
+   following BNF:
+
+      <mail-preference> ::= "NO-LISTS" | "ANY-LIST" | "PROFESSIONAL-LISTS"
+
+5.2.2.7. OtherMailbox
+
+   Values of the OtherMailbox syntax are encoded according to the
+   following BNF:
+
+      <otherMailbox> ::= <mailbox-type> '$' <mailbox>
+
+      <mailbox-type> ::= an encoded Printable String
+
+      <mailbox> ::= an encoded IA5 String
+
+   In the above, <mailbox-type> represents the type of mail system in
+   which the mailbox resides, for example "MCIMail"; and <mailbox> is the 
+   actual mailbox in the mail system defined by <mailbox-type>.
+
+5.2.2.8. Fax
+
+   Values with Fax syntax are encoded as if they were octet strings
+   containing Group 3 Fax images as defined in [7].
+
+5.2.3. Operational Syntaxes
+
+   Servers must recognize all the syntaxes described in this section.
+
+5.2.3.1. AttributeTypeDescription
+
+   Values with this syntax are encoded according to the BNF given at the
+   start of section 4.1. For example,
+
+        ( 2.5.4.0 NAME 'objectClass' SYNTAX 'OID' )
+
+5.2.3.2. GeneralizedTime
+
+   Values of this syntax are encoded as printable strings, represented 
+   as specified in X.208.  Note that the time zone must be specified.
+   It is strongly recommended that Zulu time zone be used.  For example, 
+        
+                199412161032Z
+
+5.2.3.3. INTEGER
+
+   Values with INTEGER syntax are encoded as the decimal representation  
+   of their values, with each decimal digit represented by the its 
+   character equivalent. So the number 1321 is represented by the character 
+   string "1321".
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 22]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+5.2.3.4. ObjectClassDescription
+
+   Values of this syntax are encoded according to the BNF in section 4.3.
+
+5.3. Object Classes
+
+5.3.1. Standard Classes
+
+   Servers must recognize the object classes listed here as values of 
+   the objectClass attribute.  With the exception of groupOfUniqueNames,
+   they are described in RFC 1274. 
+
+    ( 2.5.6.0 NAME 'top' ABSTRACT MUST objectClass ) 
+
+    ( 2.5.6.1 NAME 'alias' SUP top STRUCTURAL MUST aliasedObjectName ) 
+
+    ( 2.5.6.2 NAME 'country' SUP top STRUCTURAL MUST c 
+      MAY ( searchGuide $ description ) ) 
+
+    ( 2.5.6.3 NAME 'locality' SUP top STRUCTURAL 
+      MAY ( street $ seeAlso $ searchGuide $ st $ l $ description ) ) 
+
+    ( 2.5.6.4 NAME 'organization' SUP top STRUCTURAL MUST o 
+      MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $ 
+      x121Address $ registeredAddress $ destinationIndicator $ 
+      preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ 
+      telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $ 
+      street $ postOfficeBox $ postalCode $ postalAddress $ 
+      physicalDeliveryOfficeName $ st $ l $ description ) ) 
+
+    ( 2.5.6.5 NAME 'organizationalUnit' SUP top STRUCTURAL MUST ou 
+      MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $ 
+      x121Address $ registeredAddress $ destinationIndicator $ 
+      preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ 
+      telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $ 
+      street $ postOfficeBox $ postalCode $ postalAddress $ 
+      physicalDeliveryOfficeName $ st $ l $ description ) ) 
+
+    ( 2.5.6.6 NAME 'person' SUP top STRUCTURAL MUST ( sn $ cn ) 
+      MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) ) 
+
+    ( 2.5.6.7 NAME 'organizationalPerson' SUP person STRUCTURAL 
+      MAY ( title $ x121Address $ registeredAddress $ destinationIndicator $ 
+      preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $  
+      telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $
+      street $ postOfficeBox $ postalCode $ postalAddress $  
+      physicalDeliveryOfficeName $ ou $ st $ l ) ) 
+
+
+
+
+
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 23]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+    ( 2.5.6.8 NAME 'organizationalRole' SUP top STRUCTURAL MUST cn 
+      MAY ( x121Address $ registeredAddress $ destinationIndicator $  
+      preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $  
+      telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $ 
+      seeAlso $ roleOccupant $ preferredDeliveryMethod $ street $ 
+      postOfficeBox $ postalCode $ postalAddress $ 
+      physicalDeliveryOfficeName $ ou $ st $ l $ description ) ) 
+
+    ( 2.5.6.9 NAME 'groupOfNames' SUP top STRUCTURAL MUST ( member $ cn ) 
+      MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description ) ) 
+
+    ( 2.5.6.10 NAME 'residentialPerson' SUP person STRUCTURAL MUST l 
+      MAY ( businessCategory $ x121Address $ registeredAddress $  
+      destinationIndicator $ preferredDeliveryMethod $ telexNumber $  
+      teletexTerminalIdentifier $ telephoneNumber $ internationaliSDNNumber $
+      facsimileTelephoneNumber $ preferredDeliveryMethod $ street $  
+      postOfficeBox $ postalCode $ postalAddress $ 
+      physicalDeliveryOfficeName $ st $ l ) ) 
+
+    ( 2.5.6.11 NAME 'applicationProcess' SUP top STRUCTURAL MUST cn 
+      MAY ( seeAlso $ ou $ l $ description ) )
+    ( 2.5.6.12 NAME 'applicationEntity' SUP top STRUCTURAL 
+      MUST ( presentationAddress $ cn ) 
+      MAY ( supportedApplicationContext $ seeAlso $ ou $ o $ l $ 
+      description ) ) 
+
+    ( 2.5.6.13 NAME 'dSA' SUP applicationEntity STRUCTURAL 
+      MAY knowledgeInformation ) 
+
+    ( 2.5.6.14 NAME 'device' SUP top STRUCTURAL MUST cn 
+      MAY ( serialNumber $ seeAlso $ owner $ ou $ o $ l $ description ) ) 
+
+    ( 2.5.6.15 NAME 'strongAuthenticationUser' SUP top STRUCTURAL 
+      MUST userCertificate ) 
+
+    ( 2.5.6.16 NAME 'certificationAuthority' SUP top STRUCTURAL 
+      MUST ( authorityRevocationList $ certificateRevocationList $      
+      cACertificate ) MAY crossCertificatePair ) 
+
+    ( 2.5.6.17 NAME 'groupOfUniqueNames' SUP top STRUCTURAL 
+      MUST ( uniqueMember $ cn ) 
+      MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description ) ) 
+
+5.3.2. Pilot Classes
+
+   These object classes are defined in RFC 1274.  All servers must recognize
+   these object class names.
+
+    ( 0.9.2342.19200300.100.4.3 NAME 'pilotObject' SUP top STRUCTURAL 
+      MAY ( jpegPhoto $ audio $ dITRedirect $ lastModifiedBy $ 
+      lastModifiedTime $  uniqueIdentifier $ manager $ photo $ info ) ) 
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 24]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+    ( 0.9.2342.19200300.100.4.4 NAME 'newPilotPerson' SUP person 
+      STRUCTURAL MAY ( personalSignature $ mailPreferenceOption $  
+      organizationalStatus $ pagerTelephoneNumber $ mobileTelephoneNumber $  
+      otherMailbox $ janetMailbox $ businessCategory $ 
+      preferredDeliveryMethod $ personalTitle $ secretary $ 
+      homePostalAddress $ homePhone $ userClass $ roomNumber $ 
+      favouriteDrink $ rfc822Mailbox $ textEncodedORaddress $ userid ) )
+
+    ( 0.9.2342.19200300.100.4.5 NAME 'account' SUP top STRUCTURAL 
+      MUST userid MAY ( host $ ou $ o $ l $ seeAlso $ description ) ) 
+
+    ( 0.9.2342.19200300.100.4.6 NAME 'document' SUP ( top $ pilotObject ) 
+      STRUCTURAL MUST documentIdentifier 
+      MAY ( documentPublisher $ documentStore $ documentAuthorSurName $  
+      documentAuthorCommonName $ abstract $ subject $ keywords $ 
+      updatedByDocument $ updatesDocument $ obsoletedByDocument $ 
+      obsoletesDocument $ documentLocation $ documentAuthor $ 
+      documentVersion $ documentTitle $ ou $ o $ l $ seeAlso $ description $ 
+      cn ) ) 
+
+    ( 0.9.2342.19200300.100.4.7 NAME 'room' SUP top STRUCTURAL MUST cn 
+      MAY ( telephoneNumber $ seeAlso $ description $ roomNumber ) ) 
+
+    ( 0.9.2342.19200300.100.4.9 NAME 'documentSeries' SUP top STRUCTURAL 
+      MUST cn MAY ( ou $ o $ l $ telephoneNumber $ seeAlso $ description ) ) 
+
+    ( 0.9.2342.19200300.100.4.13 NAME 'domain' SUP top STRUCTURAL 
+      MUST dc 
+      MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $ 
+      x121Address $ registeredAddress $ destinationIndicator $ 
+      preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ 
+      telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $ 
+      street $ postOfficeBox $ postalCode $ postalAddress $ 
+      physicalDeliveryOfficeName $ st $ l $ description $ o $ 
+      associatedName ) ) 
+
+    ( 0.9.2342.19200300.100.4.14 NAME 'rFC822localPart' SUP domain 
+      STRUCTURAL 
+      MAY ( x121Address $ registeredAddress $ destinationIndicator $  
+      preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $  
+      telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $ 
+      streetAddress $ postOfficeBox $ postalCode $ postalAddress $  
+      physicalDeliveryOfficeName $ telephoneNumber $ seeAlso $ description $
+      sn $ cn ) ) 
+
+    ( 0.9.2342.19200300.100.4.15 NAME 'dNSDomain' SUP domain STRUCTURAL 
+      MAY dNSRecord ) 
+
+    ( 0.9.2342.19200300.100.4.17 NAME 'domainRelatedObject' SUP top 
+      STRUCTURAL MUST associatedDomain ) 
+
+    ( 0.9.2342.19200300.100.4.18 NAME 'friendlyCountry' SUP country 
+      STRUCTURAL MUST co ) 
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 25]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+    ( 0.9.2342.19200300.100.4.19 NAME 'simpleSecurityObject' SUP top 
+      STRUCTURAL MUST userPassword ) 
+
+    ( 0.9.2342.19200300.100.4.20 NAME 'pilotOrganization' 
+      SUP ( organization $ organizationalUnit ) STRUCTURAL 
+      MAY buildingName ) 
+
+    ( 0.9.2342.19200300.100.4.21 NAME 'pilotDSA' SUP dSA STRUCTURAL 
+      MUST dSAQuality ) 
+
+    ( 0.9.2342.19200300.100.4.23 NAME 'qualityLabelledData' SUP top 
+      STRUCTURAL MUST singleLevelQuality 
+      MAY ( subtreeMaximumQuality $ subtreeMinimumQuality ) ) 
+
+5.4. Matching Rules
+
+   Servers must recognize the following matching rules, used for equality
+   matching, and must be capable of performing the matching rules.
+   For all these rules, the assertion syntax is the same as the value syntax.
+
+    ( 2.5.13.0 NAME 'objectIdentifierMatch' SYNTAX 'OID' )
+    ( 2.5.13.1 NAME 'distinguishedNameMatch' SYNTAX 'DN' )
+    ( 2.5.13.2 NAME 'caseIgnoreMatch' SYNTAX 'DirectoryString' )
+    ( 2.5.13.8 NAME 'numericStringMatch' SYNTAX 'NumericString' )
+    ( 2.5.13.11 NAME 'caseIgnoreListMatch' SYNTAX 'PostalAddress' )
+    ( 2.5.13.14 NAME 'integerMatch' SYNTAX 'INTEGER' )
+    ( 2.5.13.16 NAME 'bitStringMatch' SYNTAX 'BitString' )  
+    ( 2.5.13.17 NAME 'octetStringMatch' SYNTAX 'Password' )
+    ( 2.5.13.20 NAME 'telephoneNumberMatch' SYNTAX 'TelephoneNumber' )
+    ( 2.5.13.27 NAME 'generalizedTimeMatch' SYNTAX 'GeneralizedTime' )
+    ( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' SYNTAX 'IA5String' )
+    ( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' SYNTAX 'IA5String' )
+
+   When performing the caseIgnoreMatch, caseIgnoreListMatch, 
+   telephoneNumberMatch, caseExactIA5Match and caseIgnoreIA5Match, 
+   multiple adjoining whitespace characters are treated the same as
+   an individual space, and leading and trailing whitespace is ignored.
+
+6. X.500 Definitions
+
+   Servers which implement the X.500(1993) protocols are required to recognize 
+   these attributes types, syntaxes, object classes and matching rules, where
+   they correspond to X.500 features implemented by that server.  No other 
+   servers are required to implement any definitions in section 6, although 
+   they may do so.
+
+   Clients must not assume these definitions are recognized by all servers.
+
+6.1. Attribute Types
+
+6.1.1. User Attributes
+
+   All user attributes of X.500 are listed in section 5.1.1.
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 26]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+6.1.2. Collective Attributes
+   These attributes are stored in collective attribute subentries, but may
+   be visible in user entries if requested.  
+   Each of these collective attributes is a subtype of the attribute which
+   has the OID without the final ".1", e.g. "collectivePostalCode" is a 
+   subtype of "postalCode".
+    ( 2.5.4.7.1 NAME 'collectiveLocalityName' SUP l COLLECTIVE )
+    ( 2.5.4.8.1 NAME 'collectiveStateOrProvinceName' SUP st COLLECTIVE )
+    ( 2.5.4.9.1 NAME 'collectiveStreetAddress' SUP street COLLECTIVE )
+    ( 2.5.4.10.1 NAME 'collectiveOrganizationName' SUP o COLLECTIVE )
+    ( 2.5.4.11.1 NAME 'collectiveOrganizationalUnitName' SUP ou COLLECTIVE )
+        
+    ( 2.5.4.16.1 NAME 'collectivePostalAddress' SUP postalAddress COLLECTIVE ) 
+    ( 2.5.4.17.1 NAME 'collectivePostalCode' SUP postalCode COLLECTIVE )
+    ( 2.5.4.18.1 NAME 'collectivePostOfficeBox' SUP postOfficeBox COLLECTIVE )
+    ( 2.5.4.19.1 NAME 'collectivePhysicalDeliveryOfficeName' 
+      SUP physicalDeliveryOfficeName COLLECTIVE )
+      
+    ( 2.5.4.20.1 NAME 'collectiveTelephoneNumber' SUP telephoneNumber
+      COLLECTIVE )
+    ( 2.5.4.21.1 NAME 'collectiveTelexNumber' SUP 'TelexNumber' COLLECTIVE ) 
+    ( 2.5.4.22.1 NAME 'collectiveTeletexTerminalIdentifier' 
+      SUP teletexTerminalIdentifier COLLECTIVE )
+    ( 2.5.4.23.1 NAME 'collectiveFacsimileTelephoneNumber' 
+      SUP facsimileTelephoneNumber COLLECTIVE )
+    ( 2.5.4.25.1 NAME 'collectiveInternationaliSDNNumber' 
+      SUP internationaliSDNNumber COLLECTIVE )
+6.1.3. Standard Operational Attributes
+
+   These attributes are defined in X.501(1993) Annexes B through E.
+
+    ( 2.5.18.5 NAME 'administrativeRole' EQUALITY objectIdentifierMatch 
+      SYNTAX 'OID' USAGE directoryOperation )
+    ( 2.5.18.6 NAME 'subtreeSpecification' SYNTAX 'SubtreeSpecification' 
+      SINGLE-VALUE USAGE directoryOperation ) 
+
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 27]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+    ( 2.5.18.7 NAME 'collectiveExclusions' EQUALITY objectIdentifierMatch 
+      SYNTAX 'OID' USAGE directoryOperation ) 
+    ( 2.5.21.1 NAME 'dITStructureRules' EQUALITY integerFirstComponentMatch
+      SYNTAX 'DITStructureRuleDescription' USAGE directoryOperation ) 
+    ( 2.5.21.2 NAME 'dITContentRules' 
+      EQUALITY objectIdentifierFirstComponentMatch 
+      SYNTAX 'DITContentRuleDescription' USAGE directoryOperation ) 
+    ( 2.5.21.4 NAME 'matchingRules' 
+      EQUALITY objectIdentifierFirstComponentMatch
+      SYNTAX 'MatchingRuleDescription' USAGE directoryOperation ) 
+    ( 2.5.21.7 NAME 'nameForms' 
+      EQUALITY objectIdentifierFirstComponentMatch
+      SYNTAX 'NameFormDescription' USAGE directoryOperation ) 
+    ( 2.5.21.8 NAME 'matchingRuleUse' 
+      EQUALITY objectIdentifierFirstComponentMatch
+      SYNTAX 'MatchingRuleUseDescription' USAGE directoryOperation ) 
+    ( 2.5.21.9 NAME 'structuralObjectClass' EQUALITY objectIdentifierMatch
+      SYNTAX 'OID' SINGLE-VALUE NO-USER-MODIFICATION 
+      USAGE directoryOperation )
+    ( 2.5.21.10 NAME 'governingStructuralRule' EQUALITY integerMatch 
+      SYNTAX 'INTEGER' SINGLE-VALUE NO-USER-MODIFICATION 
+      USAGE directoryOperation ) 
+    ( 2.5.24.1 NAME 'accessControlScheme' EQUALITY objectIdentifierMatch
+      SYNTAX 'OID' SINGLE-VALUE USAGE directoryOperation ) 
+
+    ( 2.5.24.4 NAME 'prescriptiveACI' 
+      EQUALITY directoryStringFirstComponentMatch SYNTAX 'ACIItem' 
+      USAGE directoryOperation ) 
+
+    ( 2.5.24.5 NAME 'entryACI' 
+      EQUALITY directoryStringFirstComponentMatch SYNTAX 'ACIItem' 
+      USAGE directoryOperation ) 
+
+    ( 2.5.24.6 NAME 'subentryACI' 
+      EQUALITY directoryStringFirstComponentMatch SYNTAX 'ACIItem' 
+      USAGE directoryOperation ) 
+
+    ( 2.5.12.0 NAME 'dseType' EQUALITY bitStringMatch SYNTAX 'DSEType' 
+      SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation ) 
+
+    ( 2.5.12.1 NAME 'myAccessPoint' EQUALITY accessPointMatch 
+      SYNTAX 'AccessPoint' SINGLE-VALUE NO-USER-MODIFICATION 
+      USAGE dSAOperation ) 
+
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 28]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+    ( 2.5.12.2 NAME 'superiorKnowledge' EQUALITY accessPointMatch 
+      SYNTAX 'AccessPoint' SINGLE-VALUE NO-USER-MODIFICATION 
+      USAGE dSAOperation ) 
+
+    ( 2.5.12.3 NAME 'specificKnowledge' 
+      EQUALITY masterAndShadowAccessPointsMatch
+      SYNTAX 'MasterAndShadowAccessPoints' 
+      SINGLE-VALUE NO-USER-MODIFICATION USAGE distributedOperation ) 
+
+    ( 2.5.12.4 NAME 'nonSpecificKnowledge' 
+      EQUALITY masterAndShadowAccessPointsMatch
+      SYNTAX 'MasterAndShadowAccessPoints' NO-USER-MODIFICATION 
+      USAGE distributedOperation ) 
+
+    ( 2.5.12.5 NAME 'supplierKnowledge' 
+      EQUALITY supplierOrConsumerInformationMatch
+      SYNTAX 'SupplierInformation' 
+      NO-USER-MODIFICATION USAGE dSAOperation ) 
+
+    ( 2.5.12.6 NAME 'consumerKnowledge' 
+      EQUALITY supplierOrConsumerInformationMatch
+      SYNTAX 'SupplierOrConsumer'  
+      NO-USER-MODIFICATION USAGE dSAOperation ) 
+
+    ( 2.5.12.7 NAME 'secondaryShadows' 
+      EQUALITY supplierAndConsumersMatch
+      SYNTAX 'SupplierAndConsumers' 
+      NO-USER-MODIFICATION USAGE dSAOperation ) 
+
+6.1.4. LDAP-defined Operational Attributes
+
+6.1.4.1. targetSystem
+
+    ( 1.3.6.1.4.1.1466.101.120.12 NAME 'targetSystem'
+     SYNTAX 'AccessPoint' SINGLE-VALUE NO-USER-MODIFICATION 
+     USAGE distributedOperation )
+
+   The value of this attribute may be supplied in an AddEntry operation 
+   to inform the Directory of the target server on which the entry is to
+   be held.  This is used to create a new naming context in the directory 
+   tree.  A server which does not permit the use of this attribute must
+   return an appropriate error code if it is present in the attribute list.
+   This attribute will generally not be present in the entry after the add
+   is completed.
+
+
+
+
+
+
+
+
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 29]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+6.2. Syntaxes
+
+6.2.1. Standard Syntaxes
+
+6.2.1.1. ACIItem
+
+   This syntax appears too complicated for a compact string representation
+   to be useful.  Clients must only request and servers must only return 
+   values which use the the binary encoding of the value, e.g. 
+   "entryACI;binary". 
+
+   It is recommended that clients that wish to only determine whether they 
+   have been granted permission to modify an entry use the "modifyRights" 
+   attribute rather than attempt to parse this syntax.
+
+6.2.1.2. AccessPoint
+
+   Values with AccessPoint syntax are encoded according to the 
+   following BNF:
+
+      <AccessPoint> ::= ( '(' <DistinguishedName> '#' 
+                          <PresentationAddress> ')' ) |
+                   -- Optional protocol info absent, parenthesis required
+                          ( '(' <DistinguishedName> '#' 
+                                <PresentationAddress> '#'
+                                <SetOfProtocolInformation ')' )
+
+      <SetOfProtocolInformation> ::= <ProtocolInformation> | 
+                                 '(' <ProtocolInformationList> ')'
+
+      <ProtocolInformationList> ::= <ProtocolInformation> |
+                            <ProtocolInformation> '$' 
+                            <ProtocolInformationList>
+
+6.2.1.3. DITContentRuleDescription
+
+   Values with this syntax are encoded according to the following BNF:
+
+      <DITContentRuleDescription> ::= "("
+          <oid>   -- Structural ObjectClass identifier
+          [ "NAME" <DirectoryStrings> ]
+          [ "DESC" <DirectoryString> ]
+          [ "OBSOLETE" ]
+          [ "AUX" <oids> ]    -- Auxiliary ObjectClasses
+          [ "MUST" <oids> ]   -- AttributeType identifiers
+          [ "MAY" <oids> ]    -- AttributeType identifiers
+          [ "NOT" <oids> ]    -- AttributeType identifiers
+         ")"
+
+
+
+
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 30]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+   
+6.2.1.4. DITStructureRuleDescription
+
+   Values with this syntax are encoded according to the following BNF:
+
+      <DITStructureRuleDescription> ::= "("
+          <RuleIdentifier>    -- DITStructureRule identifier
+          [ "NAME" <DirectoryStrings> ]
+          [ "DESC" <DirectoryString> ]
+          [ "OBSOLETE" ]
+          "FORM" <oid>                -- NameForm
+          [ "SUP" <RuleIdentifiers> ] -- superior DITStructureRules
+      ")"
+
+      <RuleIdentifier> ::= <integer>
+   
+      <RuleIdentifiers> ::=
+          <RuleIdentifier> |
+          "(" <RuleIdentifierList> ")"
+
+      <RuleIdentifierList> ::=
+          <RuleIdentifierList> <RuleIdentifier>
+      |
+          -- empty list
+
+6.2.1.5. DSEType
+
+   Values with DSEType syntax are encoded according to the following BNF:
+
+      <DSEType> ::= '(' <DSEBitList> ')'
+
+      <DSEBitList> ::= <DSEBit> | <DSEBit> '$' <DSEBitList>      
+
+      <DSEBit> ::= 'root' | 'glue' | 'cp' | 'entry' | 'alias' | 'subr' |
+                   'nssr' | 'supr' | 'xr' | 'admPoint' | 'subentry' |
+                   'shadow' | 'zombie' | 'immSupr' | 'rhob' | 'sa'
+
+6.2.1.6. MasterAndShadowAccessPoints
+
+   Values of this syntax are encoded according to the following BNF:
+
+      <MasterAndShadowAccessPoints> ::= <MasterOrShadowAccessPoint> |
+                                '(' <MasterAndShadowAccessPointList ')'
+
+      <MasterAndShadowAccessPointList> ::= <MasterOrShadowAccessPoint> |
+        <MasterOrShadowAccessPoint> '$' <MasterAndShadowAccessPointList>
+
+      <MasterOrShadowAccessPoint> ::= <category> '#' <AccessPoint>
+
+      <category> ::= 'master' | 'shadow'
+
+6.2.1.7. MatchingRuleDescription
+
+   Values of this syntax are encoded according to the BNF of section 4.4.
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 31]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+6.2.1.8. MatchingRuleUseDescription
+
+   Values of this syntax are encoded according to the following BNF:
+
+      <MatchingRuleUseDescription> ::= "("
+          <oid>   -- MatchingRule identifier
+          [ "NAME" <DirectoryStrings> ]
+          [ "DESC" <DirectoryString> ]
+          [ "OBSOLETE" ]
+         "APPLIES" <oids>    -- AttributeType identifiers
+         ")"
+
+6.2.1.9. NameFormDescription
+
+   Values of this syntax are encoded according to the following BNF:
+
+      <NameFormDescription> ::= "("
+          <oid>   -- NameForm identifier
+          [ "NAME" <DirectoryStrings> ]
+          [ "DESC" <DirectoryString> ]
+          [ "OBSOLETE" ]
+          "OC" <oid>          -- Structural ObjectClass
+          "MUST" <oids>       -- AttributeTypes
+          [ "MAY" <oids> ]    -- AttributeTypes
+      ")"
+
+6.2.1.10. SubtreeSpecification              
+
+   Values of this syntax are encoded according to the following BNF:
+
+      <SubtreeSpecification> ::= '(' [<localname>] '#' 
+                                 [<exclusionlist>] '#' 
+                                 [<minimum>] '#' [<maximum>] '#' 
+                                 [<refinement>] ')'
+
+      <localname> ::= <DistinguishedName>
+
+      <exclusionlist> ::= '(' <exclusions> ')'
+
+      <exclusions> ::= <exclusion> | <exclusion> '$' <exclusionlist>
+
+      <exclusion> ::= ( 'before ' <DistinguishedName> ) |
+                      ( 'after ' <DistinguishedName> )
+      <minimum> ::= <numericstring>
+
+      <maximum> ::= <numericstring>
+  
+      <refinement> ::= <oid> | '!' <refinement> | 
+                       '( &' <refinements> ')' |
+                       '( |' <refinements> ')'
+
+      <refinements> ::= <refinement> | <refinement> '$' <refinements>
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 32]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+6.2.1.11. SupplierInformation
+
+   Values of this syntax are encoded according to the following BNF:
+
+      <SupplierInformation> ::= 
+         -- supplier is master --    
+         '(' 'master' '#' <SupplierOrConsumer> ')' |
+
+         -- supplier is not master, master unspecified --
+         '(' 'shadow' '#' <SupplierOrConsumer> ')' |
+
+         -- supplier not master, master specified --
+         ['('] 'shadow' '#' <SupplierOrConsumer> '#' <AccessPoint> [')']
+
+6.2.1.12. SupplierOrConsumer
+
+   Values of this syntax are encoded according to the following BNF:
+
+     <SupplierOrConsumer> ::= <Agreement> '#' <AccessPoint>
+  
+     <Agreement> ::= <bindingid> '.' <bindingversion>
+
+     <bindingid> ::= <numericstring>
+
+     <bindingversion> ::= <numericstring>
+
+6.2.1.13. SupplierAndConsumers
+
+   Values of this syntax are encoded according to the following BNF:
+
+      <SupplierAndConsumers> ::= <Supplier> '#' <Consumers>
+
+      <Suppliers> ::= <AccessPoint>
+
+      <Consumers> ::= <AccessPoint> | '(' <AccessPointList> ')'
+
+      <AccessPointList> ::= <AccessPoint> | 
+                            <AccessPoint> '$' <AccessPointList>
+
+6.2.1.14. ProtocolInformation
+
+   A value with the ProtocolInformation syntax is encoded according to the
+   following BNF:
+   
+      <ProtocolInformation> ::= <NetworkAddress> <space> '#' 
+                                <SetOfProtocolIdentifier>
+
+      <NetworkAddress> ::=   As appears in PresentationAddress
+    
+      <SetOfProtocolIdentifiers> ::= <ProtocolIdentifier> |
+                                '(' <ProtocolIdentifiers> ')'
+
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 33]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+        
+      <ProtocolIdentifiers> ::= <ProtocolIdentifier> | 
+                           <ProtocolIdentifier> '$' <ProtocolIdentifiers>
+
+      <ProtocolIdentifier> ::= <oid>
+
+   For example,
+        
+        NS+12345678 # 1.2.3.4.5
+
+6.2.2. LDAP-defined Syntaxes
+
+   There is currently one syntax defined here.
+
+6.2.2.1 ModifyRight
+
+   This syntax is a printable encoding of the following ASN.1 data type:
+
+    ModifyRight ::= SEQUENCE {
+     item CHOICE { 
+       entry     [0] NULL,
+       attribute [1] AttributeType,
+       value     [2] AttributeValueAssertion },
+     permission  [3] BIT STRING { add(0), remove(1), rename(2), move(3) } }
+
+   The syntax is encoded according to the following BNF:
+
+    <ModifyRight> ::= [<perm-list>] <octo> <item> 
+       -- perm list is absent when none of the bits set in permission
+
+    <item> ::= <entry> | <attribute> | <value>
+
+    <entry> ::= 'entry'
+
+    <attribute> ::= 'attribute' <dollar> <attributetype>
+    <value> ::= 'value' <dollar> <attributetype> <dollar> <strvalue>
+           
+    -- <strvalue> is the string encoding of the value
+
+    <perm-list> ::= <perm> | <perm> <dollar> <perm-list> 
+       -- one or more of the bits in permission, if set
+
+    <perm> ::= 'add' | 'remove' | 'rename' | 'move'
+
+    <octo> ::= [ <whsp> ] '#' [ <whsp> ]
+   
+    <dollar> ::= [ <whsp> ] '$' [ <whsp> ]
+
+
+
+
+
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 34]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+   For example,
+
+       # entry 
+       add $ remove # attribute $ cn 
+       add $ remove # attribute $ sn
+       remove # value $ memberName $ CN=Babs, O=Michigan, C=US
+
+6.3. Object Classes
+
+   The following object classes may be recognized.
+
+    ( 2.5.17.0 NAME 'subentry' SUP top STRUCTURAL 
+      MUST ( cn $ subtreeSpecification ) )
+
+    ( 2.5.17.1 NAME 'accessControlSubentry' AUXILIARY )
+        
+    ( 2.5.17.2 NAME 'collectiveAttributeSubentry' AUXILIARY )
+
+    ( 2.5.20.1 NAME 'subschema' AUXILIARY 
+      MAY ( dITStructureRules $ nameForms $ ditContentRules $ 
+      objectClasses $ attributeTypes $ matchingRules $ matchingRuleUse ) )
+
+6.4. Matching Rules
+
+   Only servers which implement the attribute types which reference these 
+   matching rules in their definition are required to implement these rules.
+
+   The definitions of the rules can be found in [2] and [3].
+
+   Name                                  OID         
+   ===================================== =========== 
+   caseIgnoreOrderingMatch               2.5.13.3    
+   caseIgnoreSubstringsMatch             2.5.13.4    
+   caseExactMatch                        2.5.13.5
+   caseExactOrderingMatch                2.5.13.6
+   caseExactSubstringsMatch              2.5.13.7
+   numericStringOrderingMatch            2.5.13.9
+   numericStringSubstringsMatch          2.5.13.10  
+   caseIgnoreListSubstringsMatch         2.5.13.12  
+   booleanMatch                          2.5.13.13
+   integerOrderingMatch                  2.5.13.15
+   octetStringOrderingMatch              2.5.13.18
+   octetStringSubstringsMatch            2.5.13.19
+   telephoneNumberSubstringsMatch        2.5.13.21  
+   presentationAddressMatch              2.5.13.22  
+   uniqueMemberMatch                     2.5.13.23  
+   protocolInformationMatch              2.5.13.24  
+   uTCTimeMatch                          2.5.13.25
+   uTCTimeOrderingMatch                  2.5.13.26
+   generalizedTimeOrderingMatch          2.5.13.28   
+   integerFirstComponentMatch            2.5.13.29  
+   objectIdentifierFirstComponentMatch   2.5.13.30  
+   directoryStringFirstComponentMatch    2.5.13.31  
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 35]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+   wordMatch                             2.5.13.32
+   keywordMatch                          2.5.13.33
+   accessPointMatch                      2.5.14.0    
+   masterAndShadowAccessPointsMatch      2.5.14.1   
+   supplierOrConsumerInformationMatch    2.5.14.2   
+   supplierAndConsumersMatch             2.5.14.3   
+
+6.5. Other
+
+   The string 'excludeAllCollectiveAttributes' is defined as a synonym
+   for the OID 2.5.18.0.  It would typically be used as a value of the 
+   collectiveExclusions attribute.
+
+7. Other Optional Definitions
+
+7.1. Attribute Types
+
+7.1.1. Obsolete Attributes
+
+   Implementors must use modifyTimestamp and modifiersName instead.
+
+    ( 0.9.2342.19200300.100.1.23 NAME 'lastModifiedTime' OBSOLETE
+      SYNTAX 'UTCTime' ) 
+
+    ( 0.9.2342.19200300.100.1.24 NAME 'lastModifiedBy' OBSOLETE
+      EQUALITY distinguishedNameMatch SYNTAX 'DN' ) 
+
+7.2. Syntaxes
+
+7.2.1 MHSORAddress
+
+   Values of type MHSORAddress are encoded as strings, according to
+   the format defined in [10].
+
+7.2.2 DLSubmitPermission
+
+   Values of type DLSubmitPermission are encoded as strings, according
+   to the following BNF:
+     <dlsubmit-perm> ::= <dlgroup_label> ':' <dlgroup-value>
+                             | <dl-label> ':' <dl-value>
+     <dlgroup-label> ::= 'group_member'
+     <dlgroup-value> ::= <name>
+     <name> ::= an encoded Distinguished Name
+     <dl-label> ::= 'individual' | 'dl_member' | 'pattern'
+     <dl-value> ::= <orname>
+
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 36]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+     <orname> ::= <address> '#' <dn>
+            |  <address>
+     <address> ::= <add-label> ':' <oraddress>
+     <dn> ::= <dn-label> ':' <name>
+     <add-label> = 'X400'
+     <dn-label> = 'X500'
+   where <oraddress> is as defined in RFC 1327.
+
+7.3. Object Classes
+
+7.3.1. Obsolete Classes
+
+    ( 0.9.2342.19200300.100.4.22 NAME 'oldQualityLabelledData' SUP top 
+      STRUCTURAL MUST dSAQuality 
+      MAY ( subtreeMaximumQuality $ subtreeMinimumQuality ) ) 
+
+   The oldQualityLabelledData object class is historical and must not be
+   used for defining new objects.
+
+7.3.2. extensibleObject
+
+    ( 1.3.6.1.4.1.1466.101.120.111 NAME 'extensibleObject' 
+      SUP top AUXILIARY )  
+
+   This class, if present in an entry, permits that entry to optionally 
+   hold any attribute.  The MAY attribute list of this class is implicitly 
+   the set of all attributes known to the server.  The mandatory attributes 
+   of the other object classes of this entry are still required to be 
+   present.     
+
+   Note that not all servers will implement this object class, and those 
+   which do not will reject requests to add entries which contain this 
+   object class, or modify an entry to add this object class.
+
+7.4. Matching Rules
+
+7.4.1. caseIgnoreIA5SubstringsMatch
+
+   ( 1.3.6.1.4.1.1466.109.114.3 
+     NAME 'caseIgnoreIA5SubstringsMatch' SYNTAX 'IA5String' )
+
+   This matching rule may be used to compare components of an IA5 string
+   against an attribute whose values have IA5 string syntax.
+
+8. Security Considerations
+
+   Security issues are not discussed in this memo.
+
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 37]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+9. Acknowledgements
+
+   This document is based substantially on RFC 1778, written by Tim Howes,
+   Steve Kille, Wengyik Yeong and Colin Robbins.
+
+   Many of the attribute syntax encodings defined in this document are
+   adapted from those used in the QUIPU and the IC R3 X.500 
+   implementations. The contributions of the authors of both these 
+   implementations in the specification of syntaxes in this document are 
+   gratefully acknowledged.
+
+10. Authors Addresses
+
+       Mark Wahl
+       Critical Angle Inc.
+       4815 West Braker Lane #502-385
+       Austin, TX 78759
+       USA
+
+       EMail:  M.Wahl@critical-angle.com
+
+
+       Andy Coulbeck
+       ISODE Consortium
+       The Dome, The Square
+       Richmond  TW9 1DT
+       United Kingdom
+
+       Phone:  +44 181-332-9091
+       EMail:  A.Coulbeck@isode.com
+
+
+
+
+       Tim Howes
+       Netscape Communications Corp.
+       501 E. Middlefield Rd
+       Mountain View, CA 94043
+       USA
+       
+       Phone:  +1 415 254-1900
+       EMail:   howes@netscape.com
+
+
+       Steve Kille
+       ISODE Consortium
+       The Dome, The Square
+       Richmond
+       TW9 1DT
+       UK
+
+       Phone:  +44-181-332-9091
+       EMail:  S.Kille@isode.com
+
+Wahl, Coulbeck, Howes & Kille                                    [Page 38]     
+\f
+INTERNET-DRAFT       LDAP Standard and Pilot Attributes     October 1996     
+
+11. Bibliography
+
+   [1] M. Wahl, T. Howes, S. Kille, "Lightweight Directory Access Protocol 
+       (Version 3)", INTERNET-DRAFT <draft-ietf-asid-ldapv3-protocol-03.txt>, 
+       October 1996.
+   [2] The Directory: Selected Attribute Types.  ITU-T Recommendation 
+       X.520, 1993.
+
+   [3] The Directory: Models. ITU-T Recommendation X.501, 1993.
+
+   [4] P. Barker, S. Kille, "The COSINE and Internet X.500 Schema", RFC 
+       1274, November 1991.
+   
+   [5] M. Wahl, S. Kille, "A UTF-8 String Representation of Distinguished 
+       Names", INTERNET-DRAFT <draft-ietf-asid-ldapv3-dn-00.txt>, August 1996.
+
+   [6] S. Kille, "A String Representation for Presentation Addresses",
+       RFC 1278, University College London, November 1991.
+
+   [7] Terminal Equipment and Protocols for Telematic Services -
+       Standardization of Group 3 facsimile apparatus for document
+       transmission.  CCITT, Recommendation T.4.
+
+   [8] JPEG File Interchange Format (Version 1.02).  Eric Hamilton, 
+       C-Cube Microsystems, Milpitas, CA, September 1, 1992.
+
+   [9] The Directory: Selected Object Classes.  ITU-T Recommendation
+       X.521, 1993.
+
+   [10] H. Alvestrand, S. Kille, R. Miles, M. Rose, S. Thompson,
+        "Mapping between X.400 and RFC-822 Message Bodies", RFC 1495,
+        August 1993.
+
+   [11] M. Davis, UTF-8, (WG2 N1036) DAM for ISO/IEC 10646-1.
+
+   [12] Universal Multiple-Octet Coded Character Set (UCS) - Architecture
+        and Basic Multilingual Plane, ISO/IEC 10646-1 : 1993.
+
+   [13] The Directory: Authentication Framework. ITU-T Recommendation 
+        X.509 (1993).
+
+   [14] Abstract Syntax Notation One (ASN.1) - Specification of Basic 
+        Notation. ITU-T Recommendation X.680, 1994.
+
+
+
+
+
+
+
+
+<draft-ietf-asid-ldapv3-attributes-03.txt> 
+Expires: April 1997
+Wahl, Coulbeck, Howes & Kille                                    [Page 39]     
index ecdb41cd81538f7d21abdfd4a94ba3dfb82260ed..9beb721f9f60975d25387479f14e1534a7adb940 100644 (file)
@@ -1,11 +1,19 @@
+
+
+
+
+
+
+
           Internet-Draft                                     E. Stokes
           LDAP Extensions WG                                  D. Byrne
-          Intended Category: Standards Track                B. Blakley
-          Expires: 25 December 1999                                IBM
-                                                          25 June 1999
+          Intended Category: Standards Track                       IBM
+          Expires: 10 September 2000                        B. Blakley
+                                                                Dascom
+                                                         10 March 2000
 
                          Access Control Model for LDAP
-                     <draft-ietf-ldapext-acl-model-03.txt>
+                     <draft-ietf-ldapext-acl-model-05.txt>
 
           STATUS OF THIS MEMO
 
@@ -18,7 +26,7 @@
              working documents as Internet-Drafts. Internet-Drafts are
              draft documents valid for a maximum of six months and may
              be updated, replaced, or obsoleted by other documents at
-             any time. It is inappropriate to use Internet- Drafts as
+             any time. It is inappropriate to use Internet-Drafts as
              reference material or to cite them other than as "work in
              progress."
 
 
              This document describes the access control model for the
              Lightweight Directory Application Protocol (LDAP)
-             directory service. It includes a description of the
 
 
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999         [Page 1]
+          Stokes, Byrne, Blakley   Expires 10 September 2000        [Page 1]
 
 
 
 
 
 
-          Internet-Draft      Access Control Model        25 June 1999
+          Internet-Draft      Access Control Model       10 March 2000
 
 
 
+             directory service. It includes a description of the
              model, the LDAP controls, and the extended operations to
-             the LDAP protocol.  A separate document defines the
-             corresponding application programming interfaces (APIs).
-             RFC2219 [Bradner97] terminology is used.
+             the LDAP protocol.  The current LDAP APIs are sufficient
+             for most access control operations.  An API (in a
+             separate document) is needed for the extended operation
+             getEffectiveAccess and specifyCredentials.
+
+             The keywords "MUST", "SHOULD", and "MAY" used in this
+             document are to be interpreted as described in
+             [Bradner97].
 
 
 
              need to provide an access control model definition for
              LDAP directory content among servers within an enterprise
              and the Internet.  Currently LDAP does not define an
-             access control model, but is needed to ensure consistent
-             secure access across heterogeneous LDAP implementations.
-             The major objective is to provide a simple, but secure,
-             highly efficient access control model for LDAP while also
-             providing the appropriate flexibility to meet the needs
-             of both the Internet and enterprise environments and
-             policies.  This document defines the model and the
-             protocol extensions (controls and extended operations).
-             A separate document defines the corresponding application
-             programming interfaces (APIs).
+             access control model, but one is needed to ensure
+             consistent secure access across heterogeneous LDAP
+             implementations. The major objective is to provide a
+             simple, but secure, highly efficient access control model
+             for LDAP while also providing the appropriate flexibility
+             to meet the needs of both the Internet and enterprise
+             environments and policies.  This document defines the
+             model and the protocol extensions (controls and extended
+             operations).
 
 
           2.  Overview
              subject and the rules which govern the use of the target
              object.
 
-             This proposal defines the protocol elements for
-             transmission of this access control policy data in an
-             LDAP environment and an attribute that defines the access
-             control mechanism in effect for a given part of the LDAP
-             namespace.  The instantiation of an access control model
-
-
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999         [Page 2]
 
 
+          Stokes, Byrne, Blakley   Expires 10 September 2000        [Page 2]
 
 
 
 
-          Internet-Draft      Access Control Model        25 June 1999
 
 
+          Internet-Draft      Access Control Model       10 March 2000
 
-             at the directory server is not defined in this document.
-             By defining only what flows on the wire allows existing
-             access control mechanisms to be used at the directory
-             server.
-
-             No mechanisms are defined in this document to control
-             access to access control information or for storage of
-             access control information at the server; this is vendor
-             dependent.
 
-             A separate requirements document for access control
-             exists.  The access control model used the requirements
-             documents as a guideline for the development of this
-             specification and are reflected in this specification to
-             the extent that the working group could agree on an
-             access control model.
 
              The access control model defines
 
                 - A wire protocol for interoperability:  The existing
-                  LDAP protocol flows for add, delete, modify, etc are
-                  used to manipulate access control information.
-                  There are additional LDAP controls and extended
-                  protocol operations defined to further help
-                  management of access control information:
-                  getEffectiveRights and specifyCredentials.
+                  LDAP protocol flows for add, delete, modify, and
+                  search are used to manipulate access control
+                  information.  There is an additional LDAP control
+                  and extended protocol operation defined,
+                  getEffectiveRights, to further help management of
+                  access control information.
 
                 - A set of access control information (ACI) attributes
                   for application portability:  These attributes are
                   information.
 
                 - A set of attributes to identity the access control
-                  mechanisms supported by a server.
+                  mechanisms supported by a server and in a given part
+                  of the namespace.
 
              Encoding of access control information on the wire is per
              the LDAPv3 specifications.
 
+             The instantiation of an access control model at the
+             directory server is not defined in this document.
+
+             No mechanisms are defined in this document to control
+             access to access control information or for storage of
+             access control information at the server; this is vendor
+             dependent.
+
+             A separate requirements document for access control
+             exists.  The access control model used the requirements
+             documents as a guideline for the development of this
+             specification and are reflected in this specification to
+             the extent that the working group could agree on an
+             access control model.
+
+
 
 
 
 
 
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999         [Page 3]
+          Stokes, Byrne, Blakley   Expires 10 September 2000        [Page 3]
 
 
 
 
 
 
-          Internet-Draft      Access Control Model        25 June 1999
+          Internet-Draft      Access Control Model       10 March 2000
 
 
 
              security attribute's granted rights for the objects
              governed by the access control list to which it belongs.
 
-             The "access control policy information" (acpi) for an
-             object or a collection of objects defines which subject
-             security attributes entitle a subject to which granted
-             rights.  The access control policy information for an
-             object is stored in an access control list.
+             The "access control information" (aci) for an object or a
+             collection of objects defines which subject security
+             attributes entitle a subject to which granted rights.
+             The access control information for an object may be
+             stored in an access control list.
 
              An "access decision" is a boolean-valued function which
              answers the question: "can the subject with these subject
 
              An "access decision function" is an algorithm which makes
              an access decision based on subject security attributes,
-             access control policy information, an object identifier,
-             and an operation name (possibly augmented by additional
+             access control information, an object identifier, and an
+             operation name (possibly augmented by additional
              contextual information).
 
              An "access decision function interface" is a programmatic
 
 
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999         [Page 4]
+          Stokes, Byrne, Blakley   Expires 10 September 2000        [Page 4]
 
 
 
 
 
 
-          Internet-Draft      Access Control Model        25 June 1999
+          Internet-Draft      Access Control Model       10 March 2000
 
 
 
              An "identity" is a subject security attribute which is
              unique to a single subject.
 
-             An "object" is the target of operations in an information
-             system.
-
-             An "operation" is the result of executing the code
-             accessed through a named entry point in an information
-             system.
-
-             An "operation name" is the name of the entry point
-             through which an operation is invoked in an information
-             system.
-
              A "privilege attribute" is a subject security attribute
              which may be shared by several subjects.
 
              to authorize a requester to perform a specific operation
              on an object of a specific type.
 
-             A "right" is the basic unit of access control policy
+             A "right" is the basic unit of access control
              administration.  For each object type in an information
              system, a security administrator defines a set of
              required rights for each operation.  For each object in
              specified target object.
 
              A "role" is a privilege attribute asserting a subject's
+             organizational position and entitlement to perform the
+             operations appropriate to that organizational position.
 
+             A "subject' is an entity which initiate actions in an
+             information system.
 
+             A "subject security attribute" is a defined property
+             which is used by a security policy evaluation system to
+             make policy decisions.
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999         [Page 5]
 
 
 
 
+          Stokes, Byrne, Blakley   Expires 10 September 2000        [Page 5]
 
 
-          Internet-Draft      Access Control Model        25 June 1999
 
 
 
-             organizational position and entitlement to perform the
-             operations appropriate to that organizational position.
 
-             A "subject" is an entity which intiates actions in an
-             information system.
+          Internet-Draft      Access Control Model       10 March 2000
 
-             A "subject security attribute" is a defined property
-             which is used by a security policy evaluation system to
-             make policy decisions.
 
 
           4.  The Model
 
+             The access control mechanism described in this draft
+             addresses these activities:
 
-          4.1  Access Control Activity Lifecycle
-
-             The access control proposal described in this draft
-             addresses four activities:
+                - Definition of subject security attributes
+                  information
 
-                - Creation of subject security attribute information
-                  and access control policy information
+                - Definition of access control policy
 
-                - Retrieval of subject security attribute information
-                  at the time an access request is made
+                - Retrieval of subject security attributes
 
-                - Evaluation of access requests against policy,
-                  resulting in an access decision
+                - Retrieval of effective access rights
 
-                - Replication of access control policy information
-                  from one server to another
+                - Externalization of access control policy information
 
-          4.2  Access Control Information Model
+          4.1  Access Control Information Model
 
              This document does not define formats for storage of
              access control information; it does define the
 
 
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999         [Page 6]
 
 
 
 
 
 
-          Internet-Draft      Access Control Model        25 June 1999
 
 
 
-             The diagram below illustrates the componentry of an LDAP
+
+
+
+
+
+
+          Stokes, Byrne, Blakley   Expires 10 September 2000        [Page 6]
+
+
+
+
+
+
+          Internet-Draft      Access Control Model       10 March 2000
+
+
+
+             The diagram below illustrates the componentry of a LDAP
              system and the placement of the function specified in
              this draft.
 
-                         +-------------+
-                         | Application |
-                         +-------------+
-                           +--------+
-                           | LDAP   |
-                           | Client |
-                           +--------+
-                               |
-                               |
-                               | <-- LDAP Extended Access Control
-             Controls
-                               |     or Extended Access Control
-             Operations
-                               v
-                    +-----------------------------+
-                    |   LDAP Server (e.g. SLAPD)  |
-                    +-----------------------------+
-                          .                 |
-                          .                 |
-                          .                 |
-                          .                 |
-                          v                 v
-                    +----------+      +-----------+
-                    | Access   |      |           |
-                    | Control  |<.....| Datastore |
-                    | Manager  |      |           |
-                    +----------+      +-----------+
-
-             LDAP clients use the controls and extended operations
+                   +-------------+
+                   | Application |<--attrs to address ACI
+                   +-------------+    - ldapACI
+                     +--------+       - policyOwner
+                     | LDAP   |
+                     | Client |
+                     +--------+
+                         |
+                         | <-- LDAP control
+                         |       - getEffectiveAccess
+                         |
+                         | <-- LDAP extended operation
+                         |       - getEffectiveAccess
+                         v
+              +-----------------------------+
+              |   LDAP Server (e.g. SLAPD)  |
+              +-----------------------------+
+                    .               |
+                    .               |
+                    .               |
+                    .               |
+                    v               v
+              +----------+   +-----------+
+              | Access   |   |           |<-attrs to define
+              | Control  |<--| Datastore |  access control mechanisms
+              | Manager  |   |           |   - supportedACIMechanisms
+              +----------+   +-----------+   - aCIMechanisms
+
+             LDAP clients use the control and extended operation
              specified in this document to administer access control
              policy enforced by LDAP servers.  Servers may store
              access control information in any way they choose. In
              of their datastores to store and enforce LDAP access
              control, or they may implement access control managers
              external to their datastores.  Datastores and external
-             access control managers may implement  any access control
+             access control managers may implement any access control
              rule syntax and semantics they choose, as long as the
-             semantics is compatible with that defined in the section
+             semantics are compatible with that defined in the section
              titled "Operational Semantics of Access Control
-             Operations" (found after the control and extended
-
+             Operations".
 
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999         [Page 7]
 
+          Stokes, Byrne, Blakley   Expires 10 September 2000        [Page 7]
 
 
 
 
 
-          Internet-Draft      Access Control Model        25 June 1999
 
+          Internet-Draft      Access Control Model       10 March 2000
 
 
-             operation definition).
 
              The access control administration mechanisms specified in
              this document are neutral with respect to policy
              inheritance mechanisms, explicit vs.  implicit denial,
              and group nesting.
 
-          4.3  Bind and Credentials
-
-             A bind authenticates a principal to the directory.  A
-             principal is represented by a DN.  A principal has a set
-             of credentials that are used for determining whether
-             access to resources specified in ldap operations.  These
-             credentials may be pushed to the server by the client or
-             may be pulled by the server from the directory data.
-             Credentials may be local with respect to the server.  If
-             not local (owned by another server or administrative
-             scope), then the server may decide to define a trust
-             model that states how to evaluate the trust of a
-             credential at bind time.  The definition of such a trust
-             model is outside the scope of this document.
-
 
-          5.  Access Control Information Schema
+          5.  Access Control Mechanism Attributes
 
+             There are several attributes defined associated with
+             access control.  Two attributes are defined to identify
+             which access control mechanisms are supported by a given
+             server and by a given subtree:  supportedACIMechanisms
+             and aCIMechanisms.
 
-          5.1  Attributes
 
+          5.1  Root DSE Attribute for Access Control Mechanism
 
-          5.1.1  Root DSE Attribute for Access Control Mechanism
-
-             The following attribute may be included in the Root DSE.
+             The server advertises which access control mechanisms it
+             supports by inclusion of the 'supportedACIMechanisms'
+             attribute in the root DSE.  This attribute is a list of
+             OIDs, each of which identify an access control mechanism
+             supported by the server.
 
               (<OID to be assigned>
                  NAME      'supportedACIMechanisms'
                  DESC      list of access control mechanisms supported
                              by this directory server
                  SYNTAX    LDAPOID
+                 USAGE     dSAOperation
               )
 
-             Two access control mechanisms are defined by this
-             document:
+             The access control mechanism defined is:
                   LDAPv3     <OID to be assigned>
-                  X500       <OID to be assigned>
 
+             Other vendor access control mechanisms can be defined (by
+             OID) and are the responsibility of those vendors to
+             provide the definition and OID.
 
 
+          5.2  Subschema Attribute for Access Control Mechanism
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999         [Page 8]
+             A given naming context must provide information about
+             which access control mechanisms are in effect for that
+             portion of the namespace.  The following attribute must
+             be in each subschema entry associated with a naming
 
 
 
+          Stokes, Byrne, Blakley   Expires 10 September 2000        [Page 8]
 
 
 
-          Internet-Draft      Access Control Model        25 June 1999
 
 
 
-             Other vendor access control mechanisms can be defined (by
-             OID) and are the responsibility of those vendors to
-             provide the definition and OID.
+          Internet-Draft      Access Control Model       10 March 2000
+
 
-          5.1.2  Subschema Attribute for Access Control Mechanism
 
-             A given naming context must provide information about
-             which access control mechanism is in effect for that
-             portion of the namespace.  The following attribute must
-             be in each subschema entry associated with a naming
              context whose access control mechanism is different from
              adjacent naming contexts supported by that directory
              server.
 
-                - aCIMechanism lists the value (an OID) that defines
-                  the access control mechanism in effect for the scope
-                  of that subschema entry
-
-          5.2  Other Defined Parameters/OIDs
-
+             aCIMechanisms lists the values (list of OIDs) that
+             defines the access control mechanism in effect for the
+             scope of that subschema entry.  More than one mechanism
+             may be in effect for the scope of that subschema entry.
 
-          5.2.1  Rights Families and Rights
+              (<OID to be assigned>
+                 NAME      'aCIMechanisms'
+                 DESC      list of access control mechanisms supported
+                             in this subtree
+                 SYNTAX    LDAPOID
+                 USAGE     dSAOperation
+              )
 
-             The following rights families are defined:
-                  LDAPv3     <OID to be assigned>
-                  X500       <OID to be assigned>
 
-             Other parties can (and will) define other rights
-             families.  It is the responsibility of those parties to
-             provide the definition and OID.
 
-          5.2.1.1  LDAPv3 Rights Family
+          6.  Access Control Information Attributes
 
-             Access rights can apply to an entire object or to
-             attributes of the object.  Each of the LDAP access rights
-             are discrete. One permission does not imply another
-             permission.  The rights may be ORed together to provide
-             the desired rights list.
 
-             Rights which apply to attributes are:
+             The intent of the following attribute definitions is to
+             design a common interchange format.  Any given LDAP
+             server should be able to translate the below defined
+             attributes into a meaningful operation requests. Each
+             server should be able to understand the attributes; there
+             should not be any ambiguity into what any part of the
+             syntax means.
 
-                1   Read     Read attribute values
-                2   Write    Write attribute values
-                4   Search   Search entries with specified attributes
-                8   Compare  Compare attributes
+             While the end goal is to have a common behavior model
+             between different LDAP server implementations, the
+             attribute definition alone will not ensure identical ACL
+             processing behavior between servers.  The semantics of
+             how a server interprets the ACI syntax are defined in the
+             "Operational Semantics of Access Control' section of this
+             document.  Additionally, while the server must recognize
+             and act on the attribute when received over the wire,
+             there are no requirements for the server to physically
+             store this attribute.
 
+             The attribute definition maintains an assumption that the
+             receiving server supports inheritance within the security
+             model. If the server does not support inheritance, the
+             receiving server must expand any inherited information
 
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999         [Page 9]
 
+          Stokes, Byrne, Blakley   Expires 10 September 2000        [Page 9]
 
 
 
 
 
-          Internet-Draft      Access Control Model        25 June 1999
 
+          Internet-Draft      Access Control Model       10 March 2000
 
 
-             Rights that apply to an entire object are:
 
-                16   Add      Add an object below this object
-                32   Delete   Delete this object
-                64   EditDN   Edit an object's DN
+             based on the scope flag.  If the server does not support
+             partial inheritance and both the entry and subtree scope
+             are used, then entry is the prevailing scope.
 
-             Rights that apply to the object to which the directory
-             object points are:
+             Two attributes are defined so access control information
+             (ACI) can be addressed in a server independent of server
+             implementation.  These attributes are used in typical
+             LDAP APIs and in LDIF output of ACI. These two attributes
+             may be queried or set on all directory objects:  ldapACI
+             and policyOwner.  Their BNF and definitions are defined
+             below.
 
-               128   Manage   Perform a privileged operation; used to
-                              restrict access to operations which
-                              read or write especially sensitive data
-               256   Use      Execute; useful in controlling access to
-                              the objects referred to by directory
-                              entries than in controlling access to
-                              the directory entries themselves
-               512   Get      Get retrieves the attribute values
-              1024   Set      Set writes the attribute values
 
-          5.2.1.2  The X.500 Rights Family
+          6.1  The BNF
 
-             <define the rights for X.500>
+          < ldapACI > ::= < acl entry syntax >
 
-          5.2.2  DN Types
+          < acl entry syntax > ::= <familyOID> + '#' + <scope > + '#'
+                             + < rights >  + '#' + < dnType >
+                             + '#' + < subjectDn >
 
-             The following DN Types are defined:
+          < policyOwner > ::= < familyOid > + '#' + <scope >
+                             + '#' +< dnType > + '#' + < subjectDn >
 
-                - access-id, OID=<OID to be assigned>
+          < subjectDn > ::= < printable string > | "public" | "this"
 
-                - group, OID=<OID to be assigned>
+          < familyOid > ::= < oid >
 
-                - role, OID=<OID to be assigned>
+          <scope > ::= "entry"  | "subtree"
 
-             access-id, group, and role MUST be supported.  An acess-
-             id is a non-collection (non-group and non-role objects)
-             DN that can be authenticated.
+          < dnType > ::= "access-id" | "role" | "group" | "subtree"
+                       | "ipAddress" | "kerberosID"
+                       | <printableString>
 
-             Other parties can (and will) define other DN Types.  It
-             is the responsibility of those parties to provide the
-             definition and OID.
+          < kerberosID > ::= < userID > + '@' + < realm >
 
+          < userID > ::= < printableString >
 
+          < realm > ::= < printableString >
 
+          < rights > ::= "grant" + ';' + <permissions> + ';'+<attr>
+             | "deny" + ';' + <permissions> + ';'+<attr> |
+             "grant"+';'+<permissions>+';'+"deny"+';'+<permissions>+';'+<attr>
 
+          < permissions > ::= [ ] | [ <permission>
 
 
 
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 10]
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 10]
 
 
 
 
 
+          Internet-Draft      Access Control Model       10 March 2000
 
-          Internet-Draft      Access Control Model        25 June 1999
 
 
+                              + [ ',' + <permission> ] ]*
 
-          6.  Access Control Parameters for LDAP Controls & Extended
-          Operations
+          < attr > ::= ["collection" + ':' + [ "[all]" | "[entry]"
+                            | <printableString>] ]
+                            | ["attribute" + ':' <printableString>]
 
-             This section defines the parameters used in the access
-             control LDAP controls and extended operations in this
-             document.
+          < permission > ::= "a" | "d" | "r" | "s" | "w" |
+                             "c" | "e" | "b"
 
-             targetDN specifies the initial directory entry in DN
-             syntax on which the control or extended operation is
-             performed.
+          These are the permissions defined for the IETF LDAP family
+          OID.
+               "a" corresponds to add
+               "d" corresponds to delete
+               "r" corresponds to read
+               "s" corresponds to search
+               "w" corresponds to write
+               "c" corresponds to compare
+               "e" corresponds to editDN
+               "b" corresponds to browseDN
 
-             whichObject specifies whether the access control
-             information which is get/set is for the target directory
-             entry (ENTRY) or the target directory entry and its
-             subtree (SUBTREE).
 
-             rightsFamily specifies the family of rights that will be
-             get/set for the control or extended operation performed.
-             A rights family has a defined set of rights.
+          6.2  Other Defined Parameters
 
-             rightsList in the SearchResultEntry is of the form
-             specified in the LDIF BNF for <right>.
+             This section defines additional parameters that are used
+             in the two attributes that address access control
+             information.
 
-             dnType speficies the type of subject security attribute.
-             Defined types are access-id, group, and role.
 
-             subjectDN is a LDAP string that defines the subject or
-             value of the dnType.  The subjectDN may be a DN or
-             another string such as IPAddress (dotted-decimal string
-             representation) on which access control is get/set.  If
-             the subject is an entry in the directory, then the syntax
-             of the LDAP string is DN.  We define two well-known
-             subjectDNs, the strings
+          6.2.1  Families and Rights
 
-                - public - meaning public access for all users
+             The familyOID tells what permission set etc. will follow
+             in the string. This allows a different permission set,
+             scope etc.,  but with the same syntax.
 
-                - this - meaning the user whose name matches the entry
-                  being accessed
+             The following family is defined:
+                  IETF-LDAPv3     <OID to be assigned>
 
-             Four operations are defined:
+             Other families can be defined (by OID).  It is the
+             responsibility of those parties to provide the definition
+             and OID.
 
-                - ACI_GRANT grants the rights specified in the
-                  rightsList for the given subject. If an access
-                  control list does not exist for the specified
-                  entry/attribute, then the access control list is
 
+          6.2.1.1  IETF-LDAPv3 Family
 
+             Access rights can apply to an entire object or to
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 11]
 
 
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 11]
 
 
 
 
-          Internet-Draft      Access Control Model        25 June 1999
 
 
+          Internet-Draft      Access Control Model       10 March 2000
 
-                  created with the granted rights for the given
-                  subject.  If the access control list already exists
-                  for the specified entry/attribute, then the access
-                  control list is modified to grant the rights for the
-                  given subject.
 
-                - ACI_DENY denies the rights specified in the
-                  rightsList for the given subject.  No implementation
-                  is implied for this operation.  For example, denial
-                  of rights may be implemented as explicit denial
-                  (negative rights) on the access control list or
-                  removal of rights from the access control list.
 
-                - ACI_REPLACE replaces the entire access control list
-                  for the specified entry/attribute.  If an access
-                  control list does not exist for the specified
-                  entry/attribute, then the access control list is
-                  created with the granted rights for the given
-                  subject.
+             attributes of the object.  Each of the LDAP access rights
+             are discrete. One permission does not imply another
+             permission.  The rights which apply to attributes and the
+             entry parallel the type of ldap operations that can be
+             performed.
 
-                - ACI_DELETE deletes the entire access control list
-                  for the specified entry/attribute.
+             Rights which apply to attributes:
 
-             attrs specifies the list of attributes against which the
-             operation is performed.  attrs can be defined using a
-             LDAP filter expression.
+                r   Read     Read attribute values
+                w   Write    Write attribute values
+                s   Search   Search entries with specified attributes
+                c   Compare  Compare attributes
 
+             Rights that apply to an entire entry:
 
-          7.  Access Control Information (ACI) Controls
+                a    Add      Add an entry below this entry
+                d    Delete   Delete this entry
+                e    EditDN   Edit an entry's DN
+                b    BrowseDN Browse an entry's DN
 
-             The access control information controls provide a way to
-             manipulate access control information in conjunction with
-             an LDAP operation such as ldap_add, ldap_modify, or
-             ldap_search.  Three LDAP controls are defined for
-             transmission of access control information.  These
-             controls allow access control information to be get/set
-             while manipulating other directory information.  The
-             controls are:
+             When searching, the ldap search filter specifies the
+             returned set of attributes.  To do the search, browse (b)
+             must be set for the entry (you can search only entries
+             that you have permission to search so you can't discover
+             things you don't have permission to) and search (s) must
+             be set for all attributes used in the filter if you are
+             testing for existence, otherwise search (s) and read (r)
+             must be set for all attributes used in the filter because
+             the filter specifies a test for other than existence.
+             For a search to return attribute names only, search (s)
+             must be set for the attribute.  For a search to return
+             attribute names and values, search (s) and read (r) must
+             be set for the attribute.  Search (s) implies knowledge
+             of the attribute; read (r) implies knowledge of the
+             value.
 
-                - getEffectiveRights to obtain the effective rights
-                  for a given directory entry(s) for a given subject
-                  during a ldap_search operation
 
-                - specifyCredentials to specify a set of credentials
-                  for the bind identity (DN) during a ldap_bind
+          6.2.2  DN Types
 
+             The following DN Types strings are defined and MUST be
+             supported:
 
+                - access-id
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 12]
 
 
 
 
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 12]
 
 
-          Internet-Draft      Access Control Model        25 June 1999
 
 
 
-                  operation
 
-          7.1  getEffectiveRights Control
+          Internet-Draft      Access Control Model       10 March 2000
 
 
-          7.1.1  Request Control
 
-             This control is  included in  the ldap_search  message as
-             part of the controls  field  of the  LDAPMessage, as
-             defined in  Section  4.1.12 of [LDAPv3].
+                - group
 
-             The controlType is set to <OID to be assigned>. The
-             criticality MAY be either TRUE or FALSE (where absent is
-             also equivalent to FALSE) at the client's option.  The
-             controlValue is an OCTET STRING, whose value is the BER
-             encoding of a value of the following SEQUENCE:
+                - role
 
-              getEffectiveRightsRequest ::= SEQUENCE {
-                   targetDN  LDAPDN,
-                   effectiveRightsRequest   SEQUENCE OF SEQUENCE {
-                               rightsFamily  LDAPOID | "*",
-                               whichObject   ENUMERATED {
-                                               LDAP_ENTRY (1),
-                                               LDAP_SUBTREE (2)
-                                               },
-                               dnType        LDAPOID | "*",
-                               subjectDN     LDAPString,
-                               }
-              }
+             The following DN Types strings are defined and SHOULD be
+             supported:
 
-             The targetDN specifies the initial directory entry in DN
-             syntax on which the getEffectiveRights control is
-             performed.  request is a set of sequences that state the
-             whichObject (entry or entry plus subtree) and specifics
-             of the control request to be performed.  One or more
-             rightsFamily can be be obtained for a given subjectDN ad
-             dnType.  A "*" in the rightsFamily field indicates that
-             the rights for all rights families defined for the
-             subjectDN / dnType are to be returned.  This control is
-             applied to the scope set by the ldap_search operation,
-             i.e.  base, one-level, subtree.
+                - ipAddress
 
-          7.1.2  Response Control
+                - kerberosID
 
-             This control is included in the ldap_search_response
+             An access-id is a non-collection (non-group and non-role
+             objects) DN that can be authenticated.
 
+             groupOfNames and groupOfUniqueNames (or subclasses from
+             those object classes) must be recognized as a collection
+             object.  This aids in interoperability during
+             replication.
 
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 13]
+             Other parties can (and will) define other DN Types.  It
+             is the responsibility of those parties to provide the
+             definition.
 
+          6.3  Basic ACI Attribute (ldapACI)
 
+              (<OID to be assigned>
+                NAME      'ldapACI'
+                DESC      'ldap access control information'
+                EQUALITY  caseIgnoreMatch
+                SYNTAX    directoryString
+                USAGE     directoryOperation
+              )
 
+             Within the access control syntax, the family OID
+             describes the permissions, dnType, subjectDn and scope
+             that will be found in the following string. If the OID
+             within the ldapACI attribute is listed as other than the
+             IETF-LDAPv3 family OID, the syntax is the same, but one
+             or more of the scope, dnType, subjectDn or permissions
+             may vary from the defined syntax.
 
+             Within the access control syntax, there is a string which
+             describes the rights. This is a composite of the
+             permissions and resources to which the subject is being
 
 
-          Internet-Draft      Access Control Model        25 June 1999
 
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 13]
 
 
-             message as part of the controls field of the LDAPMessage,
-             as defined in Section 4.1.12 of [LDAPv3].
 
-             The controlType is set to <OID to be assigned>. The
-             criticality MAY be either TRUE or FALSE (where absent is
-             also equivalent to FALSE).  The controlValue is an OCTET
-             STRING, whose value is the BER encoding of a value of the
-             following SEQUENCE:
 
-              getEffectiveRightsResponse ::= {
-                result  ENUMERATED {
-                   success                       (0),
-                   operationsError               (1),
-                   unavailableCriticalExtension (12),
-                   noSuchAttribute              (16),
-                   undefinedAttributeType       (17),
-                   invalidAttributeSyntax       (21),
-                   unavailable                  (52),
-                   unwillingToPerform           (53),
-                   other                        (80)
-                   }
-              }
 
-             The effective rights returned are returned with each
-             entry returned by the search result.  The control
-             response for ldap_search is:
 
-              PartialEffectiveRightsList ::= SEQUENCE OF SEQUENCE {
-                 rightFamily   LDAPOID,
-                 rightsList    ENUMERATED,
-                 whichObject   ENUMERATED {
-                                   LDAP_ENTRY (1),
-                                   LDAP_SUBTREE (2)
-                                   }
-              }
+          Internet-Draft      Access Control Model       10 March 2000
 
-             Although this extends the search operation, there are no
-             incompatibilities between versions.  LDAPv2 cannot send a
-             control, hence the above structure cannot be returned to
-             a LDAPv2 client.  A LDAPv3 client cannot send this
-             request to a LDAPv2 server.  A LDAPv3 server not
-             supporting this control cannot return the additional
-             data.
 
 
+             granted or denied access. The set of permissions is
+             fixed. Either or both of the actions "grant" | "deny"
+             may be used when creating or updating ldapACI.
 
+             <attr> describes either an attribute name or an attribute
+             collection.  The keyword attribute indicates that the
+             following printable string refers to an attribute name.
+             If the string refers to an attribute not defined in the
+             given server's schema, the server SHOULD report an error.
+             The keyword "collection" indicates that the string that
+             follows describes a group of attributes.  The method for
+             grouping attributes is server specific.  Another option
+             for the collection printable string is "[entry]". This is
+             provided to describe permissions which apply to an entire
+             object. This could mean actions such as delete the
+             object, or add a child object. The third option for a
+             collection is "[all]" which means the permission set
+             should apply to all attributes.  Even if the server does
+             not support attribute grouping, it MUST recognize the
+             "[all]" and "[entry]" keywords.  If the server receives
+             an unrecognized attribute collection name, the server
+             SHOULD return an error.  If the server supports grouping,
+             the grouping is server and implementation specific.
 
+             If the keyword "[all]" and another attribute are both
+             specified within an aci, the more specific permission set
+             for the attribute overrides the less specific permission
+             set for "[all]".
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 14]
+             All permissions (for grant and deny) for an attribute and
+             a given DN MUST be contained within one ldapACI value,
+             i.e. (in abbreviated form)
 
+              ldapACI:  ...grant attr1 DN1
+              ldapACI:  ...deny attr1 DN1
 
+             must be ldapACI:  ...grant ... deny... attr1 DN1
 
+             Using the defined BNF it is possible for the permission
+             string to be empty. The ACI
 
+              ldapACI: 1.2.3.4#subtree#grant;;
+                         attribute:attr1#group#cn=Dept XYZ,c=US
 
+              ldapACI: 1.2.3.4#subtree#grant;r,s;
 
-          Internet-Draft      Access Control Model        25 June 1999
 
 
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 14]
 
-          7.1.3  Client-Server Interaction
 
-             The getEffectiveRightsRequest control requests the rights
-             that MUST be in effect for requested directory
-             entry/attribute based on the subject DN.  The server that
-             consumes the search operation looks up the rights for the
-             returned directory information based on the subject DN
-             and returns that rights information.
 
-             There are six possible scenarios that may occur as a
-             result of the getEffectiveRights control being included
-             on the search request:
 
 
-               1.  If the server does not support this control and the
-                   client specified TRUE for the control's criticality
-                   field, then the server MUST return
-                   unavailableCriticalExtension as a return code in
-                   the searchResponse message and not send back any
-                   other results.  This behavior is specified in
-                   section 4.1.12 of [LDAPv3].
 
-               2.  If the server does not support this control and the
-                   client specified FALSE for the control's
-                   criticality field, then the server MUST ignore the
-                   control and process the request as if it were not
-                   present.  This behavior is specified in section
-                   4.1.12 of [LDAPv3].
+          Internet-Draft      Access Control Model       10 March 2000
 
-               3.  If the server supports this control but for some
-                   reason such as cannot process specified
-                   rightsFamily and the client specified TRUE for the
-                   control's criticality field, then the server SHOULD
-                   do the following: return
-                   unavailableCriticalExtension as a return code in
-                   the searchResult message.
 
-               4.  If the server supports this control but for some
-                   reason such as cannot process specified
-                   rightsFamily and the client specified FALSE for the
-                   control's criticality field, then the server should
-                   process as 'no rights returned for that family' and
-                   include the result Unavailable in the
-                   getEffectiveRightsResponse control in the
-                   searchResult message.
 
+                         collection:[all]#group#cn=Dept XYZ,c=US
 
+             means that this group (Dept XYZ) is granted permission to
+             read and search all attributes except attr1 because attr1
+             is more specific than "[all]".
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 15]
 
+          6.3.1  LDAP Operations
 
+             The attributes which are defined for access control
+             interchange may be used in all LDAP operations.
 
+             Within the ldapmodify-delete operation, the entire acl
+             may be deleted by specifying
 
+              dn: cn = some Entry
+              changetype: modify
+              delete: ldapACI
 
+             In this case, the entry would then inherit its ACI from
+             some other node in the tree depending on the server
+             inheritance model.
 
-          Internet-Draft      Access Control Model        25 June 1999
+             Similarly, if all values of ldapACI are deleted, then the
+             access control information for that entry is defined by
+             that implementation's inheritance model.
 
 
+          6.3.2  Grant/Deny Evaluation Rules
 
-               5.  If the server supports this control and can return
-                   the rights per the rightsFamily information, then
-                   it should include the getEffectiveRightsResponse
-                   control in the searchResult message with a result
-                   of success.
+             More specific policies must override less specific ones
+             (e.g. individual user entry in ACI takes precedence over
+             group entry).
 
-               6.  If the search request failed for any other reason,
-                   then the server SHOULD omit the
-                   getEffectiveRightsResponse control from the
-                   searchResult message.
+             Deny takes precedence over Grant. When there are
+             conflicting ACI values, deny takes precedence over grant.
+             Deny is the default when there is no access control
+             information.
 
-             The client application is assured that the correct rights
-             are returned for scope of the search operation if and
-             only if the getEffectiveRightsResponse control returns
-             the rights.  If the server omits the
-             getEffectiveRightsResponse control from the searchResult
-             message, the client SHOULD assume that the control was
-             ignored by the server.
+             Precendence of Scope Types (highest to lowest)
 
-             The getEffectiveRightsResponse control, if included by
-             the server in the searchResponse message, should have the
-             getEffectiveRightsResult set to either success if the
-             rights are returned or set to the appropriate error code
-             as to why the rights could not be returned.
+                - entry
 
-             The server may not be able to return a right because it
-             may not exist in that directory object's attribute; in
-             this case, the rights request is ignored with success.
+                - subtree
 
-          7.2  specifyCredentials Control
 
 
-          7.2.1  Request Control
 
-             This control is included in  the ldap_bind  message as
-             part of the controls  field  of the  LDAPMessage, as
-             defined in  Section  4.1.12 of [LDAPv3].
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 15]
 
-             The controlType is set to <OID to be assigned>. The
-             criticality MAY be either TRUE or FALSE (where absent is
-             also equivalent to FALSE) at the client's option.  The
-             controlValue is an OCTET STRING, whose value is the BER
-             encoding of a value of the following SEQUENCE:
 
-              specifyCredentialRequest ::= SEQUENCE {
 
 
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 16]
 
+          Internet-Draft      Access Control Model       10 March 2000
 
 
 
+             Precedence of Privilege Attribute dnTypes within a scope
+             (highest to lowest):
 
+                - ipAddress
 
-          Internet-Draft      Access Control Model        25 June 1999
+                - access-id, kerberosID (both same precedence)
 
+                - group
 
+                - role
 
-                   credential  LDAPString
-                               }
-              }
+                - subtree
 
-             The credential specifies the credential (e.g. groups,
-             roles, etc) that the client is requesting be associated
-             with the bind DN for access control determination in
-             subsequent ldap operations.  This provides a 'push' model
-             for credentials where the client attempts to 'push' the
-             credential to the server.  The server may process at bind
-             time as follows:
+             Although other types can be defined given the BNF, use of
+             the well-known types aids in interoperability and
+             operational consistency.
 
-                - server may unconditionally ignore
 
-                - server may unconditionally accept
+          6.4  Policy Owner Attribute (policyOwner)
 
-                - server may define trust model and evaluate of the
-                  trust of each credential
+              (<OID to be assigned>
+                 NAME      'policyOwner'
+                 DESC      'Policy Owner Access Control Information'
+                 EQUALITY  caseIgnoreMatch
+                 SYNTAX    directoryString
+                 USAGE     directoryOperation
+              )
 
-             If this control is not used, it is assumed that the
-             server determines (pulls) the credentials associated with
-             the bind DN when needed in subsequent ldap operations to
-             provide access control.
+             Policy ownership controls administrative subdomains. It
+             can also control who has permission to set / change acls
+             for implementations that do not have ACI controlling
+             access to itself.   If there are multiple policy owners
+             it is implementation specific as to the behavior of
+             whether policy owner #1 can override policy owner # 2.
 
-          7.2.2  Response Control
+             The syntax for policyOwner includes the 'scope' flag.
+             Servers which do not support inheritance must expand the
+             policyOwner inheritance similar to the expansion of the
+             ACI.  The scope and any inheritance hierarchy for policy
+             ownership is distinct from any inheritance hierarchy
+             defined for ACI values.
 
-             This control is included in the ldap_bind message as part
-             of the controls field of the LDAPMessage, as defined in
-             Section 4.1.12 of [LDAPv3].
+             If the policy owner is not specified for any object in
+             the tree, behavior is implementation defined. For
+             instance, if no object anywhere in the tree has a policy
 
-             The controlType is set to <OID to be assigned>. The
-             criticality MAY be either TRUE or FALSE (where absent is
-             also equivalent to FALSE).  The controlValue is an OCTET
-             STRING, whose value is the BER encoding of a value of the
-             following SEQUENCE:
 
-              specifyCredentialsResponse ::= {
-                result  ENUMERATED {
-                   success                       (0),
-                   operationsError               (1),
-                   unavailableCriticalExtension (12),
-                   unavailable                  (52),
-                   unwillingToPerform           (53),
-                   other                        (80)
-                   }
 
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 16]
 
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 17]
 
 
 
 
+          Internet-Draft      Access Control Model       10 March 2000
 
 
-          Internet-Draft      Access Control Model        25 June 1999
 
+             owner, then the server could simply assert that the 'root
+             DN' is considered the policy owner for all objects. An
+             alternate approach might be that the implementation
+             defines the entryDN to be the policy owner.
 
 
-              }
+          6.5  ACI Examples
 
-             No data is returned; just the result is returned.
+             The examples use a family OID = 1.2.3.4
 
-             Although this extends the bind operation, there are no
-             incompatibilities between versions.  LDAPv2 cannot send a
-             control.  A LDAPv3 client cannot send this request to a
-             LDAPv2 server.  A LDAPv3 server not supporting this
-             control cannot return the additional data.
 
-          7.2.3  Client-Server Interaction
+          6.5.1  Attribute Definition
 
-             The specifyCredentialsRequest control specifies the
-             credentials that the client wants the server to use for
-             access control in subsequent ldap operations.  The server
-             that consumes the bind operation may unconditionally
-             accept, ignore, or evaluate the trust of the specified
-             credentials at bind time and returns only a success or
-             failure response (no data returned).
+             The following two examples show an administrative
+             subdomain being established. The first example shows a
+             single user being assigned the policyOwner for the entire
+             domain. The second example shows a group of IDs assigned
+             to the policy Owner.
 
-             There are six possible scenarios that may occur as a
-             result of the specifyCredential control being included on
-             the bind request:
+             policyOwner: 1.2.3.4#subtree#access-id#cn=Hoyt
 
+             policyOwner: 1.2.3.4#subtree#group#cn=System
+             Owners,o=Company
 
-               1.  If the server does not support this control and the
-                   client specified TRUE for the control's criticality
-                   field, then the server MUST return
-                   unavailableCriticalExtension as a return code in
-                   the bindResponse message.  This behavior is
-                   specified in section 4.1.12 of [LDAPv3].
+             The next example shows a ldapACI attribute where a group
+             "cn=Dept XYZ, c=US" is being given permissions to read,
+             search and compare attribute attr1. The permission
+             applies to the entire subtree below the node containing
+             this ACI.
 
-               2.  If the server does not support this control and the
-                   client specified FALSE for the control's
-                   criticality field, then the server MUST ignore the
-                   control and process the request as if it were not
-                   present.  This behavior is specified in section
-                   4.1.12 of [LDAPv3].
+              ldapACI:1.2.3.4#subtree#grant;r,s,c;
+                   attribute:attr1#group#cn=Dept XYZ,c=US
 
-               3.  If the server supports this control but for some
-                   reason such as cannot process specified credential
-                   (e.g. server decided to evaluate the trust of that
-                   credential and the result is the server not
-                   trusting all the credentials or unconditionally
-                   ignores the credential) and the client specified
+             The next example shows an ACI attribute where a role
+             "cn=SysAdmins,o=Company"  is being given permissions to
+             add objects below this node and read, search, and compare
+             attributes attr2 and attr3. The permission applies to the
+             entire subtree below the node containing this ACI.
 
+              ldapACI: 1.2.3.4#subtree#grant;a;
+                         collection:[entry]#role#cn=SysAdmins,o=Company
 
+              ldapACI: 1.2.3.4#subtree#grant;r,s,c;
+                         attribute:attr2#role#cn=SysAdmins,o=Company
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 18]
 
 
 
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 17]
 
 
 
-          Internet-Draft      Access Control Model        25 June 1999
 
 
 
-                   TRUE for the control's criticality field, then the
-                   server SHOULD do the following: return
-                   unavailableCriticalExtension as a return code in
-                   the bindResult message and omit the
-                   specifyCredentialResponse control in the bindResult
-                   message.
+          Internet-Draft      Access Control Model       10 March 2000
 
-               4.  If the server supports this control but for some
-                   reason such as cannot process specified credential
-                   (e.g. server decided to evaluate the trust of that
-                   credential and the result is the server not
-                   trusting all the credentials or unconditionally
-                   ignores the credential) and the client specified
-                   FALSE for the control's criticality field, then the
-                   server should process as 'credential ignored' and
-                   include the result Unavailable in the
-                   specifyCredentialResponse control in the bindResult
-                   message.
-
-               5.  If the server supports this control and evaulates
-                   the trust of that credential and the result is the
-                   server trusting all the credentials, then it should
-                   include the specifyCredentialResponse control in
-                   the bindResult message with a result of success.
-
-               6.  If the bind request failed for any other reason,
-                   then the server SHOULD omit the
-                   specifyCredentialResponse control from the
-                   bindResult message.
 
-             The client application is assured that the correct
-             credentials are used by the server when specified by the
-             client for subsequent ldap operations if and only if the
-             specifyCredentialResponse is successful.  If the server
-             omits the specifyCredentialResponse control from the
-             bindResponse message, the client SHOULD assume that the
-             control was ignored by the server.
 
-             The specifyCredentialResponse control, if included by the
-             server in the bindResponse message, should have the
-             bindResult set to either success if the credentials were
-             accepted by the server or set to the appropriate error
-             code as to why the credentials were not accepted.
+              ldapACI: 1.2.3.4#subtree#grant;r,s,c;
+                 attribute:attr3#role#cn=SysAdmins,o=Company
 
 
+          6.5.2  Modifying the ldapACI Values
 
+          Modify-Replace works as defined in the ldap oepration
+          modify. If the attribute value does not exist, create the
+          value. If the attribute does exist, replace the value.  If
+          the ldapACI value is replaced, all ldapACI values are
+          replaced.
 
+          A given ldapACI for an entry:
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 19]
+           ldapACI: 1.2.3.4#subtree#deny;r,w;
+                      collection:[all]#group#cn=Dept ABC
 
+           ldapACI: 1.2.3.4#subtree#grant;r;
+                      attribute:attr1#group#cn=Dept XYZ
 
+          perform the following change:
 
+            dn: cn=someEntry
+            changetype: modify
+            replace: ldapACI
+            ldapACI: 1.2.3.4#subtree#grant;r,w;
+                       collection:[all];#group#cn=Dept LMN
 
+          The resulting ACI is:
 
+          ldapACI: 1.2.3.4#subtree#grant;r,w;
+                     collection:[all];#group#cn=Dept LMN
 
-          Internet-Draft      Access Control Model        25 June 1999
+          ( ldapACI values for Dept XYZ and ABC are lost through the
+          replace )
 
+          During an ldapmodify-add, if the ACI does not exist, the
+          create the ACI with the specific ldapACI value(s).  If the
+          ACI does exist, then add the specified values to the given
+          ldapACI.  For example a given ACI:
 
+          ldapACI: 1.2.3.4#subtree#grant;r,w;
+                     collection:[all]#group#cn=Dept XYZ
 
-          8.  Access Control Extended Operations
+          with a modification:
 
-             Two extended operations (analogous to the controls) are
-             defined for transmission of access control information.
-             These operations help with the management of access
-             control information independent of manipulating other
-             directory information.  The extended operations are:
 
-                - LDAP Get Effective Rights to obtain the effective
-                  rights for a given directory entry for a given
-                  subject
 
-          8.1  LDAP Get Effective Rights Operation
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 18]
 
-             ldapGetEffectiveRightsRequest ::= [APPLICATION 23]
-             SEQUENCE {
-                requestName      [0] <OID to be assigned>,
-                requestValue     [1] OCTET STRING OPTIONAL }
 
-                where
 
-                requestValue ::= SEQUENCE {
-                   targetDN  LDAPDN,
-                   updates   SEQUENCE OF SEQUENCE {
-                               rightsFamily  LDAPOID | "*",
-                               whichObject   ENUMERATED {
-                                               LDAP_ENTRY (1),
-                                               LDAP_SUBTREE (2)
-                                               },
-                               dnType        LDAPOID | "*",
-                               subjectDN     LDAPString,
-                               }
-                   }
 
 
-             The requestName is a dotted-decimal representation of the
-             OBJECT IDENTIFIER corresponding to the request. The
-             requestValue is information in a form defined by that
-             request, encapsulated inside an OCTET STRING.
 
-             The server will respond to this with an LDAPMessage
-             containing the ExtendedResponse which is a rights list.
+          Internet-Draft      Access Control Model       10 March 2000
 
-             ldpGetEffectiveRightsResponse ::= [APPLICATION 24]
-             SEQUENCE {
 
 
+            dn: cn=someEntry
+            changetype: modify
+            add: ldapACI
+            ldapACI: 1.2.3.4#subtree#grant;r;
+                   attribute:attr1#group#cn=Dept XYZ
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 20]
+          would yield an multi-valued aci of:
 
+           ldapACI: 1.2.3.4#subtree#grant;r,w;
+                      collection:[all]#group#cn=Dept XYZ
 
+           ldapACI: 1.2.3.4#subtree#grant;r;
+                      attribute:attr1#group#cn=Dept XYZ
 
+          To delete a particular ACI value, use the regular ldapmodify
+          - delete syntax
 
+          Given an ACI of:
 
+           ldapACI: 1.2.3.4#subtree#grant;r,w;
+                      collection:[all]#group#cn=Dept XYZ
+           ldapACI: 1.2.3.4#subtree#grant;r;
+                      attribute:attr1#group#cn=Dept XYZ
 
-          Internet-Draft      Access Control Model        25 June 1999
+            dn: cn = some Entry
+            changetype: modify
+            delete: ldapACI
+            ldapACI: 1.2.3.4#subtree#grant;r;
+                       attribute:attr1#group#cn=Dept XYZ
 
+          would yield a remaining ACI on the server of
 
+          ldapACI: 1.2.3.4#subtree#grant;r,w;
+                     collection:[all]#group#cn=Dept XYZ
 
-                COMPONENTS OF LDAPResult,
-                responseName     [10] <OID to be assigned> OPTIONAL,
-                effectiveRights  [11] OCTET STRING OPTIONAL }
 
-                where
+          6.5.3  Evaluation
 
-                effectiveRights ::= SEQUENCE OF SEQUENCE {
-                   rightFamily   LDAPOID,
-                   rightsList    ENUMERATED,
-                   whichObject   ENUMERATED {
-                                    LDAP_ENTRY (1),
-                                    LDAP_SUBTREE (2)
-                                    },
-                   subjectDnType LDAPOID,
-                   subjectDN     LDAPSTRING
-                }
+             These examples assume that the ldapACI entries listed in
+             each example are the only ACI which applies to the entry
+             in question; if backing-store ACI also exists, the
+             effective policy may be different from that listed in
+             each example.  See section 7 for a discussion of the
+             semantics of ldapACI entries when backing-store ACI
+             administration is also used.
 
-             If the server does not recognize the request name, it
-             MUST return only the response fields from LDAPResult,
-             containing the protocolError result code.
 
 
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 19]
 
-          9.  Access Control Information Attributes/LDIF
 
-          The intent of the following attribute definitions is to
-          design a common interchange format.  Any given LDAP server
-          should be able to translate the below defined attributes
-          into a meaningful operation requests. Each server should be
-          able to understand the attributes; there should not be any
-          ambiguity into what any part of the syntax means.
 
-          While the end goal is to have a common behavior model
-          between different LDAP server implementations, the attribute
-          definition alone will not ensure identical ACL processing
-          behavior between servers.  The semantics of how a server
-          interprets the ACI syntax are not defined here. What 'deny'
-          means on server1 might be different than on server2.
-          Additionally, while the server must recognize and act on the
-          attribute when received over the wire, there are no
-          requirements for the server to actually implement this
-          attribute.
 
-          The attribute definition maintains an assumption that the
-          receiving server supports inheritance within the security
 
 
+          Internet-Draft      Access Control Model       10 March 2000
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 21]
 
 
+             Assume cn=jsmith is a member of group cn=G1.  Assume
+             cn=jsmith is a member of group cn=G2.
 
+              Example #1
+              dn: o=XYZ, c=US
+              ldapACI: 1.2.3.4#subtree#grant;r;attribute:attr1;
+                         #access-id#cn=jsmith,ou=ABC,o=XYZ,c=US
+              ldapACI: 1.2.3.4#subtree#grant;w;attribute:attr1;
+                         #group#cn=G1,ou=ABC,o=XYZ,c=US
 
+              What rights does cn=jsmith have to attr1 of o=XYZ,c=US?
+              Read (r) access; access-id is higher precedence than
+              group.
 
 
-          Internet-Draft      Access Control Model        25 June 1999
+              Example #2
+              dn: o=XYZ, c=US
+              ldapACI: 1.2.3.4#subtree#grant;r;attribute:attr2;
+                         #group#cn=G1,ou=ABC,o=XYZ,c=US
+              ldapACI: 1.2.3.4#subtree#grant;w;attribute:attr2;
+                         #group#cn=G2,ou=ABC,o=XYZ,c=US
 
+              What rights does cn=jsmith have to attr2 of o=XYZ,c=US?
+              Read-write (r,w) access; ACI is combined because both
+              dnTypes (group) have same precedence.
 
 
-          model. If the server does not support inheritance, the
-          receiving server must expand any inherited information based
-          on the scope flag.
+              Example #3
+              dn: o=XYZ, c=US
+              ldapACI: 1.2.3.4#subtree#grant;r,w;attribute:attr3;
+                         #group#cn=G1,ou=ABC,o=XYZ,c=US
+              ldapACI: 1.2.3.4#subtree#deny;w;attribute:attr3;
+                         #group#cn=G2,ou=ABC,o=XYZ,c=US
 
+              What rights does cn=jsmith have to attr3 of o=XYZ, c=US?
+              Read access; write is denied (deny has precedence over
+              grant).
 
-          9.1  ACI Attributes
 
-          There are three attributes which may be queried or set on
-          all directory objects:  aci, vendorAci and policyOwner. The
-          syntax of these attributes is defined below.
+              Example #4
+              dn: o=XYZ, c=US
+              ldapACI: 1.2.3.4#subtree#grant;w;attribute:attr4;
+                         #access-id#cn=jsmith,ou=ABC,o=XYZ,c=US
+              ldapACI: 1.2.3.4#subtree#grant;r;attribute:attr4;
+                         #subtree#ou=ABC,ou=XYZ,c=US
 
 
-          9.1.1  The BNF
 
-          < aci > ::= < acl syntax >
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 20]
 
-          < vendorAci > ::= <oid> + '#' + < printable string >
 
-          < acl syntax > ::= <familyOID> + '#' + <scope > + '#'
-                             + < rights >  + '#' + < dnType >
-                             + '#' + < subjectDn >
 
-          < policyOwner > ::= < familyOid > + '#' + <scope >
-                             + '#' +< dnType > + '#' + < subjectDn >
 
-          < subjectDn > ::= < printable string >
 
-          < familyOid > ::= < oid >
 
-          <scope > ::= "entry"  | "subtree" | <level>
+          Internet-Draft      Access Control Model       10 March 2000
 
-          < level > ::= numericstring
 
-          < dnType > ::= "access-id" | "role" | "group"
 
-          < rights > ::= [  ]   |   [ < right > + [ '$'
-                         + <right> ] * ]
+              What rights does cn=jsmith have to attr4 of o=XYZ, c=US?
+              Write (w); rights given to an access-id take precedence
+              over those given to a subtree.
 
-          < right > ::= <action > + ';' + <permissions>
-                        + ';' +  <attrs>
 
-          < action > ::= "grant" | "deny"
 
-          < permissions > ::= [  ]  |   [ < permission >
-                              + [ ',' + <permission> ] *  ]
 
+          7.  Operational Semantics of Access Control Operations
 
+             The semantics of access control operations described in
+             this document are defined operationally in terms of
+             "histories".  A history is a sequence of actions (x1, x2,
+             ..., xN).
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 22]
 
+          7.1  Types of actions
 
+             We consider five types of actions:
 
+                - LDAP Access Control Policy Update actions:
+                  invocations of ldap modify when used to add, delete,
+                  or replace the aci attribute; invocations of ldap
+                  add when used to add an entry with an aci attribute.
+                  A LDAP Access Control Policy Update action may
+                  replace the policy (by completely replacing the aci
+                  attribute with new policy information) or it may
+                  grant or deny specific rights while leaving others
+                  unaffected.
 
+                - LDAP Access Control Policy Query operations:
+                  invocations of ldap search when used to retrieve the
+                  aci attribute; invocations of ldap search with the
+                  getEffectiveRightsRequest control; invocations of
+                  the ldapGetEffectiveRightsRequest extended
+                  operation.
 
+                - Datastore Access Control Policy Update Actions: any
+                  operation implemented by the server which LDAP is
+                  using as its datastore which changes the access
+                  policy enforced with respect to attempts to access
+                  LDAP directory entries and their attributes.
 
-          Internet-Draft      Access Control Model        25 June 1999
+                - LDAP Access Request operations: invocations of LDAP
+                  entry or attribute access operations (Read, Update,
+                  Search, Compare, etc...).
 
 
 
-          < attrs > ::= [ < attributeString>
-                         + [ ',' + < attributeString > ] * ]
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 21]
 
-          < attributeString > ::= "[all]" | "[entry]"
-                                  | <printableString >
 
-          < permission > ::= "a" | "d" | "r" | "s" | "w" |
-                             "c" | "g" | "s" | "m" | "u" | "e"
 
-          These are the permissions defined for the IETF family OID.
-               "a" corresponds to add
-               "d" corresponds to delete
-               "r" corresponds to read
-               "w" corresponds to write
-               "c" corresponds to compare
-               "g" corresponds to get
-               "s" corresponds to set
-               "m" corresponds to manage
-               "u" corresponds to use
-               "e" corresponds to editDn
 
 
-          9.1.2  VendorACI
 
-          ( vendorAciOID NAME 'vendorACI'  DESC  'Vendor specific
-          Access control information' EQUALITY caseIgnoreMatch SYNTAX
-          directoryString )
+          Internet-Draft      Access Control Model       10 March 2000
 
-          The Vendor specific ACI information is listed in its own
-          attribute.  This may be used by vendors to provide vendor
-          specific access control related information which can not be
-          expressed in defined ACISyntax. Within the vendorACI, the
-          oid determines the format or the printable string to follow.
 
 
-          9.1.3  Policy Owner
+                - Other operations: anything else, including Datastore
+                  operations which do not change the access policy
+                  enforced by the server.
 
-          ( policySyntaxOID  DESC  'PolicyOwner Syntax' ) (
-          policyOwnerOID NAME 'policyOwner' DESC  'Policy Owner Access
-          Control Information' EQUALITY caseIgnoreMatch SYNTAX
-          policySyntaxOID )
 
-          Policy ownership controls administrative subdomains. It can
-          also control who has permission to set / change acls for
-          implementations that do not have ACI controlling access to
+          7.2  Semantics of Histories
 
+             The semantics of histories are defined as follows:
 
+                - LDAP Update (Replace), LDAP Query
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 23]
+                  The Query will show that the subject has all rights
+                  granted by the Update operation, and no rights not
+                  granted by the Update operation.
 
+                - LDAP Update (Grant), LDAP Query
 
+                  The Query will show that the subject has all rights
+                  granted by the Update operation.  The Query may show
+                  that the subject also has other rights not granted
+                  by the Update operation, depending on the policy in
+                  force before the Update operation.
 
+                - LDAP Update (Deny), LDAP Query
 
+                  The Query will show that the subject does not have
+                  any right denied by the Update operation.  The Query
+                  may show that the subject has rights not denied by
+                  the Update operation, depending on the policy in
+                  force before the Update operation.
 
+                - LDAP Update (Replace), LDAP Access Request
 
-          Internet-Draft      Access Control Model        25 June 1999
+                  The Request will succeed if it requires only rights
+                  granted to the requesting subject by the Update
+                  operation.  The Request will fail if it requires any
+                  right not granted by the Update operation.
 
+                - LDAP Update (Grant), LDAP Access Request
 
+                  The Request will succeed if it requires only rights
+                  granted to the requesting subject by the Update
+                  operation.  The Request may succeed if it requires
+                  rights not granted by the Update operation,
+                  depending on the policy in force before the Update
 
-          itself.   If there are multiple policy owners it is
-          implementation specific as to the behavior of whether policy
-          owner #1 can override policy owner # 2.
 
-          The syntax for policyOwner includes the 'scope' flag.
-          Servers which do not support inheritance must expand the
-          policyOwner inheritance similar to the expansion of the ACI.
-          The scope and any inheritance hierarchy for policy ownership
-          is distinct from any inheritance hierarchy defined for ACI
-          values.
 
-          If the policy owner is not specified for any object in the
-          tree, behavior is implementation defined. For instance, if
-          no object anywhere in the tree has a policy owner, then the
-          server could simply assert that the 'root DN' is considered
-          the policy owner for all objects. An alternate approach
-          might be that the implementation defines the entryDN to be
-          the policy owner.
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 22]
 
 
-          9.1.4  ACI
 
-          ( aciSyntaxOID  DESC  'ACI Syntax' )
-           ( aciOID NAME 'aci' DESC  'Access control information'
-          EQUALITY caseIgnoreMatch SYNTAX  aciSyntaxOID  )
 
-          Within the access control syntax, the family OID describes
-          the permissions, dnType, subjectDn and scope  that will be
-          found in the following string. If the OID within the ACI
-          attribute is listed as other than the IETF family oid, the
-          syntax is the same as listed below, but one or more of the
-          scope, dnType, subjectDn or permissions may vary from the
-          IETF defined syntax.
 
-          Within the access control syntax, there is a string which
-          describes the rights. This is a composite of the permissions
-          and resources to which the user is being granted or denied
-          access. The set of permissions is fixed. Either of the
-          actions "grant" | "deny"  may be used when creating or
-          updating ACI.
 
-          The attributeString is an attribute Name (defined to be a
-          printable string).  If the string refers to an attribute not
-          defined in the given server's schema, the server SHOULD
-          report an error.   Another option for the attributeString is
+          Internet-Draft      Access Control Model       10 March 2000
 
 
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 24]
+                  operation.
 
+                - LDAP Update (Deny), LDAP Access Request
 
+                  The Request will fail if it requires any right
+                  denied to the requesting subject by the Update
+                  operation.  If the Request requires only rights
+                  which were not denied by the Update operation, it
+                  may succeed, depending on the policy in force before
+                  the Update operation.
 
+                - LDAP Update (Replace), Other, LDAP Query
 
+                  The Query will show that the subject has all rights
+                  granted by the Update operation, and no rights not
+                  granted by the Update operation.
 
+                - LDAP Update (Grant), Other, LDAP Query
 
-          Internet-Draft      Access Control Model        25 June 1999
+                  The Query will show that the subject has all rights
+                  granted by the Update operation.  The Query may show
+                  that the subject also has other rights not granted
+                  by the Update operation, depending on the policy in
+                  force before the Update operation.
 
+                - LDAP Update (Deny), Other, LDAP Query
 
+                  The Query will show that the subject does not have
+                  any right denied by the Update operation.  The Query
+                  may show that the subject has rights not denied by
+                  the Update operation, depending on the policy in
+                  force before the Update operation.
 
-          "[entry]". This is provided to describe permissions which
-          apply to an entire object. This could mean actions such as
-          delete the object, or add a child object. The third option
-          for attributeString is "[all]" which means the permission
-          set should apply to all attributes.
+                - LDAP Update (Replace), Other, LDAP Access Request
 
-          If the keyword "[all]" and another attribute are both
-          specified within an aci, the more specific permission set
-          for the attribute overrides the less specific permission set
-          for "[all]".
+                  The Request will succeed if it requires only rights
+                  granted to the requesting subject by the Update
+                  operation.  The Request will fail if it requires any
+                  right not granted by the Update operation.
 
-          If two ACIs contain identical familyOID, scope, DnTypes and
-          DNs, the permission given DN is specified in two distinct
-          acis on any given entry, the rights lists can be combined
-          into one list. For example,
+                - LDAP Update (Grant), Other, LDAP Access Request
 
-           aci: 1.2.3.4#subtree#grant;r,w;[all]#group#cn=Dept XYZ
-           aci: 1.2.3.4#subtree#grant;r;attribute1#group#cn=Dept XYZ
+                  The Request will succeed if it requires only rights
+                  granted to the requesting subject by the Update
+                  operation.  The Request may succeed if it requires
 
-          is the equivalent of
 
-           aci: 1.2.3.4#subtree#grant;r,w;[all];
-                 r,attribute1#group#cn=Dept XYZ
 
-          Using the defined BNF it is possible for the permission
-          string to be empty. The ACI
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 23]
 
-           aci: 1.2.3.4#subtree#grant;;attribute1$grant;r,s;
-                 [all]#group#cn=Dept XYZ,c=US
 
-          means that this group is granted permission to read and
-          search all attributes except attribute1.
 
-          Similarly, the ACI
 
-          aci: 1.2.3.4#subtree##group#cn=Dept XYZ, c=US
 
-          simply means that no permissions have been defined for this
-          group. It is up to the server implementation as to whether
-          the group does or does not receive permission to attributes
-          on an entry with an empty rights list.
 
-          Multiple attributeStrings can be listed after any given
-          permission set; for instance, "r,w ; attribute1,
-          attribute2". This means that if the server supports a
+          Internet-Draft      Access Control Model       10 March 2000
 
 
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 25]
+                  rights not granted by the Update operation,
+                  depending on the policy in force before the Update
+                  operation.
 
+                - LDAP Update (Deny), Other, LDAP Access Request
 
+                  The Request will fail if it requires any right
+                  denied to the requesting subject by the Update
+                  operation.  If the Request requires only rights
+                  which were not denied by the Update operation, it
+                  may succeed, depending on the policy in force before
+                  the Update operation.
 
+                - LDAP Update (Replace), Datastore Policy Update, LDAP
+                  Query
 
+                  The result of the Query is not defined.
 
+                - LDAP Update (Grant), Datastore Policy Update, LDAP
+                  Query
 
-          Internet-Draft      Access Control Model        25 June 1999
+                  The result of the Query is not defined.
 
+                - LDAP Update (Deny), Datastore Policy Update, LDAP
+                  Query
 
+                  The result of the Query is not defined.
 
-          attribute aggregation mechanism, attribute1 and attribute2
-          should be considered to be part of the same group. If the
-          server does not support a grouping mechanism, the permission
-          set applies independently to attribute1 and attribute2. For
-          servers that do not support attribute grouping, "grant ; r,w
-          ; attribute1, attribute2" results in the same operations as
-          "grant ; r,w; attribute1$grant; r,w; attribute2"
+                - LDAP Update (Replace), Datastore Policy Update, LDAP
+                  Access Request
 
+                  The result of the Access Request is not defined.
 
-          9.1.5  LDAP Operations
+                - LDAP Update (Grant), Datastore Policy Update, LDAP
+                  Access Request
 
-          The attributes which are defined for access control
-          interchange may be used in all LDAP operations.
+                  The result of the Access Request is not defined.
 
-          Within the ldapmodify-delete operation, the entire acl may
-          be deleted by specifying
+                - LDAP Update (Deny), Datastore Policy Update, LDAP
+                  Access Request
 
-           dn: cn = some Entry
-           changetype: modify
-           delete: aci
+                  The result of the Access Request is not defined.
 
-          In this case, the entry would then inherit its ACI from some
-          other node in the tree depending on the server inheritance
-          model.
 
-          Deleting the last ACI value from an entry is not the same as
-          deleting the ACI from the entry. It is possible for an entry
-          to contain an ACI with no values. In this case, nothing is
-          returned to the client when querying the aci. It is server
-          dependent whether access is granted or denied in the absence
-          of any ACI information.  Deleting an ACI value which does
-          not exist will result in an unchanged ACI and a return code
-          specifying that the attribute value does not exist.
 
 
-          9.2  Examples
 
 
-          9.2.1  Attribute Definition
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 24]
 
-             Pretend IETFFamilyOID = 1.2.3.4
 
-             The following two examples show an administrative
-             subdomain being established. The first example shows a
-             single user being assigned the policyOwner for the entire
 
 
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 26]
 
+          Internet-Draft      Access Control Model       10 March 2000
 
 
 
+          8.  Access Control Parameters for LDAP Controls & Extended
+          Operations
 
+             This section defines the parameters used in the access
+             control LDAP controls and extended operations in this
+             document.
 
-          Internet-Draft      Access Control Model        25 June 1999
+             targetDN specifies the initial directory entry in DN
+             syntax on which the control or extended operation is
+             performed.
 
+             whichObject specifies whether the access control
+             information (in the get effective rights control) which
+             is retrieved is for the target directory entry (ENTRY) or
+             the target directory entry and its subtree (SUBTREE).
 
+             family specifies the family OID that will be retrieved
+             for the get effective rights control or extended
+             operation performed.  A family has a defined set of
+             rights, among other things.
 
-             domain. The second example shows a group of ids assigned
-             to the policy Owner.
+             rights in the get effective rights control or extended
+             operation response is of the form specified in the BNF
+             for <rights>.
 
-             policyOwner: 1.2.3.4#subtree#access-id#cn=Hoyt
+             dnType speficies the type of subject security attribute.
+             Defined types are specified in the BNF.
 
-             policyOwner: 1.2.3.4#subtree#group#cn=System Owners,
-             o=Company
+             subjectDN is a LDAP string that defines the subject or
+             value of the dnType.  The subjectDN may be a DN or
+             another string such as IPAddress (dotted-decimal string
+             representation) on which access control is get/set.  If
+             the subject is an entry in the directory, then the syntax
+             of the LDAP string is DN.  The well-known subjectDNs
+             strings are defined
 
-             The next example shows an aci attribute where a group
-             "cn=Dept XYZ, c=US" is being given permissions to read,
-             search and compare attribute1. The permission should
-             apply to the entire subtree below the node containing
-             this ACI.
+                - public - meaning public access for all users
 
-              aci:1.2.3.4#subtree#grant;r,s,c;
-                   attribute1#group#cn=Dept XYZ,c=US
+                - this - meaning the user whose name matches the entry
+                  being accessed
 
-             The next example shows an ACI attribute where a role
-             "cn=SysAdmins,o=Company"  is being given permissions to
-             add objects below this node, and read, search and compare
-             attributes 2 and 3. The permission should apply to the
-             entire subtree below the node containing this ACI.
+                - *  - meaning everyone who has access to the entry
 
-               aci: 1.2.3.4#subtree#grant;a;[entry]$grant;
-                    r,s,c;attribute2, attribute3#role#
-                    cn=SysAdmins,o=Company
 
 
-          9.2.2  Modifying the ACI Values
 
-          Replace works similarly to all other attributes. If the
-          attribute value does not exist, create the value. If the
-          attribute does exist, replace the value.  If the ACI value
-          is replaced, all ACI values are replaced.
 
-          A given aci for an entry:
 
-           aci: 1.2.3.4#subtree#deny;r,w;[all]$grant;r,s,c;
-                attribute2#group#cn=Dept ABC
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 25]
 
-           aci: 1.2.3.4#subtree#grant;r;[all]$grant;r,s,c;
-                attribute1#group#cn=Dept XYZ
 
-          perform the following change:
 
 
 
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 27]
+          Internet-Draft      Access Control Model       10 March 2000
 
 
 
+          9.  Access Control Information (ACI) Controls
 
+             The access control information controls provide a way to
+             manipulate access control information in conjunction with
+             a LDAP operation.  One LDAP control is defined.  This
+             control allows access control information to be get/set
+             while manipulating other directory information for that
+             entry.  The control is:
 
+                - getEffectiveRights to obtain the effective rights
+                  for a given directory entry(s) for a given subject
+                  during a ldap_search operation
 
-          Internet-Draft      Access Control Model        25 June 1999
+          9.1  getEffectiveRights Control
 
 
+          9.1.1  Request Control
 
-            dn: cn=someEntry
-            changetype: modify
-            replace: aci
-            aci: 1.2.3.4#subtree#grant;r,w;[all];#group#cn=Dept LMN
+             This control may only be included in the ldap_search
+             message as  part of the controls  field  of the
+             LDAPMessage, as  defined in  Section  4.1.12 of [LDAPv3].
 
-          The resulting acl is:
+             The controlType is set to <OID to be assigned>. The
+             criticality MAY be either TRUE or FALSE (where absent is
+             also equivalent to FALSE) at the client's option.  The
+             controlValue is an OCTET STRING, whose value is the BER
+             encoding of a value of the following SEQUENCE:
 
-          aci: 1.2.3.4#subtree#grant;r,w;[all];#group#cn=Dept LMN
+              getEffectiveRightsRequest ::= SEQUENCE {
+                effectiveRightsRequest   SEQUENCE OF SEQUENCE {
+                    family        LDAPOID | "*",
+                    whichObject   ENUMERATED {
+                                  LDAP_ENTRY (1),
+                                  LDAP_SUBTREE (2)
+                                  },
+                    dnType        "access-id"|"group"|"role"|
+                                    "ipAddress"|"kerberosID"|
+                                    <printableString> | "*",
+                    subjectDN     LDAPString | "public" |
+                                    "this" |  "*"
+                    }
+              }
 
-          ( aci values for Dept XYZ and ABC are lost through the
-          replace )
+             The effectiveRightsRequest is a set of sequences that
+             state the whichObject (entry or entry plus subtree) and
 
-          During an ldapmodify-add, if the ACI does not exist, the
-          create the ACI with the specific aci value(s).  If the ACI
-          does exist, then add the specified values to the given ACI.
-          For example a given ACI:
 
-          aci: 1.2.3.4#subtree#grant;r,w;[all]#group#cn=Dept XYZ
 
-          with a modification:
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 26]
 
-            dn: cn=someEntry
-            changetype: modify
-            add: aci
-            aci: 1.2.3.4#subtree#grant;r;attribute1#group#cn=Dept XYZ
 
-          would yield an multi-valued aci of:
 
-            aci: 1.2.3.4#subtree#grant;r,w;[all]#group#cn=Dept XYZ
-            aci: 1.2.3.4#subtree#grant;r;attribute1#group#cn=Dept XYZ
-          To delete a particular aci value, use the regular ldapmodify
-          - delete syntax
 
-          Given an ACI of:
 
-            aci: 1.2.3.4#subtree#grant;r,w;[all]#group#cn=Dept XYZ
-            aci: 1.2.3.4#subtree#grant;r;attribute1#group#cn=Dept XYZ
 
-            dn: cn = some Entry
-            changetype: modify
-            delete: aci
-            aci: 1.2.3.4#subtree#grant;r;attribute1#group#cn=Dept XYZ
+          Internet-Draft      Access Control Model       10 March 2000
 
-          would yield a remaining ACI on the server of
+
+
+             specifics of the control request to be performed.  One or
+             more family can be be obtained for a given subjectDN ad
+             dnType.  A "*" in the family field indicates that the
+             rights for all families defined for the subjectDN /
+             dnType are to be returned.  A "*" in the dnType field
+             specifies that all DN types are to be used in returning
+             the effective rights.  This control is applied to the
+             filter and scope set by the ldap_search operation, i.e.
+             base, one-level, subtree.  So the attributes/values
+             returned are defined by the ldap_search operation.
+
+          9.1.2  Response Control
+
+             This control is included in the ldap_search_response
+             message as part of the controls field of the LDAPMessage,
+             as defined in Section 4.1.12 of [LDAPv3].
+
+             The controlType is set to <OID to be assigned>. There is
+             no need to set the criticality on the response.  The
+             controlValue is an OCTET STRING, whose value is the BER
+             encoding of a value of the following SEQUENCE:
+
+              getEffectiveRightsResponse ::= {
+                result  ENUMERATED {
+                   success                       (0),
+                   operationsError               (1),
+                   unavailableCriticalExtension (12),
+                   noSuchAttribute              (16),
+                   undefinedAttributeType       (17),
+                   invalidAttributeSyntax       (21),
+                   insufficientRights           (50),
+                   unavailable                  (52),
+                   unwillingToPerform           (53),
+                   other                        (80)
+                   }
+              }
+
+             The effective rights returned are returned with each
+             entry returned by the search result.  The control
+             response for ldap_search is:
+
+              PartialEffectiveRightsList ::= SEQUENCE OF SEQUENCE {
+                 family        LDAPOID,
+                 rights        <see <rights> in BNF>,
+                 whichObject   ENUMERATED {
+
+
+
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 27]
+
+
+
+
+
+
+          Internet-Draft      Access Control Model       10 March 2000
+
+
+
+                                   LDAP_ENTRY (1),
+                                   LDAP_SUBTREE (2)
+                                   },
+                 dnType        "access-id"|"group"|
+                                "role"|"ipAddress"|
+                                "kerberosID"|
+                                <printableString> |
+                                "*",
+                 subjectDN     LDAPString | "public" |
+                                    "this" | "*"
+              }
+
+             Although this extends the search operation, there are no
+             incompatibilities between versions.  LDAPv2 cannot send a
+             control, hence the above structure cannot be returned to
+             a LDAPv2 client.  A LDAPv3 client cannot send this
+             request to a LDAPv2 server.  A LDAPv3 server not
+             supporting this control cannot return the additional
+             data.
+
+          9.1.3  Client-Server Interaction
+
+             The getEffectiveRightsRequest control requests the rights
+             that MUST be in effect for requested directory
+             entry/attribute based on the subject DN.  The server that
+             consumes the search operation looks up the rights for the
+             returned directory information based on the subject DN
+             and returns that rights information.
+
+             There are six possible scenarios that may occur as a
+             result of the getEffectiveRights control being included
+             on the search request:
+
+
+               1.  If the server does not support this control and the
+                   client specified TRUE for the control's criticality
+                   field, then the server MUST return
+                   unavailableCriticalExtension as a return code in
+                   the searchResponse message and not send back any
+                   other results.  This behavior is specified in
+                   section 4.1.12 of [LDAPv3].
+
+               2.  If the server does not support this control and the
+                   client specified FALSE for the control's
+                   criticality field, then the server MUST ignore the
+
+
+
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 28]
 
 
 
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 28]
 
 
+          Internet-Draft      Access Control Model       10 March 2000
 
 
 
+                   control and process the request as if it were not
+                   present.  This behavior is specified in section
+                   4.1.12 of [LDAPv3].
 
-          Internet-Draft      Access Control Model        25 June 1999
+               3.  If the server supports this control but for some
+                   reason such as cannot process specified family and
+                   the client specified TRUE for the control's
+                   criticality field, then the server SHOULD do the
+                   following: return unavailableCriticalExtension as a
+                   return code in the searchResult message.
 
+               4.  If the server supports this control but for some
+                   reason such as cannot process specified family and
+                   the client specified FALSE for the control's
+                   criticality field, then the server should process
+                   as 'no rights returned for that family' and include
+                   the result Unavailable in the
+                   getEffectiveRightsResponse control in the
+                   searchResult message.
 
+               5.  If the server supports this control and can return
+                   the rights per the family information, then it
+                   should include the getEffectiveRightsResponse
+                   control in the searchResult message with a result
+                   of success.
 
-          aci: 1.2.3.4#subtree#grant;r,w;[all]#group#cn=Dept XYZ
+               6.  If the search request failed for any other reason,
+                   then the server SHOULD omit the
+                   getEffectiveRightsResponse control from the
+                   searchResult message.
 
+             The client application is assured that the correct rights
+             are returned for scope of the search operation if and
+             only if the getEffectiveRightsResponse control returns
+             the rights.  If the server omits the
+             getEffectiveRightsResponse control from the searchResult
+             message, the client SHOULD assume that the control was
+             ignored by the server.
+
+             The getEffectiveRightsResponse control, if included by
+             the server in the searchResponse message, should have the
+             getEffectiveRightsResult set to either success if the
+             rights are returned or set to the appropriate error code
+             as to why the rights could not be returned.
+
+
+
+
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 29]
+
+
+
+
+
+
+          Internet-Draft      Access Control Model       10 March 2000
+
+
+
+             The server may not be able to return a right because it
+             may not exist in that directory object's attribute; in
+             this case, the rights request is ignored with success.
+
+
+          10.  Access Control Extended Operation
+
+             An extended operation, get effective rights, is defined
+             to obtain the effective rights for a given directory
+             entry for a given subject.  This operation may help with
+             the management of access control information independent
+             of manipulating other directory information.
+
+
+          10.1  LDAP Get Effective Rights Operation
+
+             ldapGetEffectiveRightsRequest ::= [APPLICATION 23]
+             SEQUENCE {
+                requestName      [0] <OID to be assigned>,
+                requestValue     [1] OCTET STRING OPTIONAL }
+
+                where
+
+                requestValue ::= SEQUENCE {
+                   targetDN  LDAPDN,
+                   updates   SEQUENCE OF SEQUENCE {
+                               family        LDAPOID | "*",
+                               whichObject   ENUMERATED {
+                                               LDAP_ENTRY (1),
+                                               LDAP_SUBTREE (2)
+                                               },
+                               attr SEQUENCE {
+                                  attr   <see <attr> in BNF >
+                                  },
+                               dnType        "access-id"|"group"|
+                                               "role"|"ipAddress"|
+                                               "kerberosID"|
+                                               <printableString> |
+                                               "*",
+                               subjectDN     LDAPString | "public" |
+                                               "this" | "*"
+                               }
+                   }
 
 
-          10.  Security Considerations
 
-             This draft proposes protocol elements for transmission of
-             security policy information.  Security considerations are
-             discussed throughout this draft.  Because subject
+
+
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 30]
+
+
+
+
+
+
+          Internet-Draft      Access Control Model       10 March 2000
+
+
+
+             The requestName is a dotted-decimal representation of the
+             OBJECT IDENTIFIER corresponding to the request. The
+             requestValue is information in a form defined by that
+             request, encapsulated inside an OCTET STRING.
+
+             The server will respond to this with an LDAPMessage
+             containing the ExtendedResponse which is a rights list.
+
+             ldapGetEffectiveRightsResponse ::= [APPLICATION 24]
+             SEQUENCE {
+                COMPONENTS OF LDAPResult,
+                responseName     [10] <OID to be assigned> OPTIONAL,
+                effectiveRights  [11] OCTET STRING OPTIONAL }
+
+                where
+
+                effectiveRights ::= SEQUENCE OF SEQUENCE {
+                   family        LDAPOID,
+                   rights        <see <rights> in BNF>,
+                   whichObject   ENUMERATED {
+                                    LDAP_ENTRY (1),
+                                    LDAP_SUBTREE (2)
+                                    },
+                   dnType        "access-id"|"group"|"role"|
+                                    "ipAddress"|"kerberosID"|
+                                    <printableString>,
+                   subjectDN     LDAPString | "public" | "this"
+                }
+
+             If the server does not recognize the request name, it
+             MUST return only the response fields from LDAPResult,
+             containing the protocolError result code.
+
+
+
+          11.  Security Considerations
+
+             This document proposes protocol elements for transmission
+             of security policy information.  Security considerations
+             are discussed throughout this draft.  Because subject
              security attribute information is used to evaluate
              decision requests, it is security-sensitive information
              and must be protected against unauthorized modification
 
 
 
-          11.  References
+
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 31]
+
+
+
+
+
+
+          Internet-Draft      Access Control Model       10 March 2000
+
+
+
+          12.  References
 
              [LDAPv3] M. Wahl, T. Howes, S. Kille, "Lightweight
              Directory Access Protocol (v3)", RFC 2251, December 1997.
              Framework" ECMA TR/46, July 1988
 
              [REQTS] Stokes, Byrne, Blakley, "Access Control
-             Requirements for LDAP, INTERNET-DRAFT <draft-ietf-
-             ldapext-acl-reqts-01.txt>, August 1998.
+             Requirements for LDAP", INTERNET-DRAFT <draft-ietf-
+             ldapext-acl-reqts-03.txt>, February 2000.
 
              [ATTR] M.Wahl, A, Coulbeck, T. Howes, S. Kille,
              "Lightweight Directory Access Protocol (v3)": Attribute
               Ellen Stokes                       Bob Blakley
               IBM                                Dascom
               11400 Burnet Rd                    5515 Balcones Drive
-
-
-
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 29]
-
-
-
-
-
-
-          Internet-Draft      Access Control Model        25 June 1999
-
-
-
               Austin, TX 78758                   Austin, TX 78731
               USA                                USA
               mail-to: stokes@austin.ibm.com     mail-to: blakley@dascom.com
 
 
 
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 32]
 
 
 
 
 
 
+          Internet-Draft      Access Control Model       10 March 2000
 
 
 
 
 
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 30]
 
 
 
 
 
 
-          Internet-Draft      Access Control Model        25 June 1999
 
 
 
 
 
 
+          Stokes, Byrne, Blakley   Expires 10 September 2000         [Page 33]
 
 
 
 
 
 
+                                    CONTENTS
 
 
+           1.  Introduction.......................................   2
 
+           2.  Overview...........................................   2
 
+           3.  Terminology........................................   4
 
+           4.  The Model..........................................   6
+               4.1   Access Control Information Model.............   6
+
+           5.  Access Control Mechanism Attributes................   8
+               5.1   Root DSE Attribute for Access Control
+                     Mechanism....................................   8
+               5.2   Subschema Attribute for Access Control
+                     Mechanism....................................   8
+
+           6.  Access Control Information Attributes..............   9
+               6.1   The BNF......................................  10
+               6.2   Other Defined Parameters.....................  11
+                     6.2.1  Families and Rights  11
+                     6.2.2  DN Types  12
+               6.3   Basic ACI Attribute (ldapACI)................  13
+                     6.3.1  LDAP Operations  15
+                     6.3.2  Grant/Deny Evaluation Rules  15
+               6.4   Policy Owner Attribute (policyOwner).........  16
+               6.5   ACI Examples.................................  17
+                     6.5.1  Attribute Definition  17
+                     6.5.2  Modifying the ldapACI Values  18
+                     6.5.3  Evaluation  19
+
+           7.  Operational Semantics of Access Control
+               Operations.........................................  21
+               7.1   Types of actions.............................  21
+               7.2   Semantics of Histories.......................  22
+
+           8.  Access Control Parameters for LDAP Controls &
+               Extended Operations................................  25
+
+           9.  Access Control Information (ACI) Controls..........  26
+               9.1   getEffectiveRights Control...................  26
+                     9.1.1  Request Control  26
+                     9.1.2  Response Control  27
+                     9.1.3  Client-Server Interaction  28
 
 
 
+                                     - i -
 
 
 
 
 
 
-          Stokes, Byrne, Blakley   Expires 25 December 1999        [Page 31]
+          10.  Access Control Extended Operation..................  30
+               10.1  LDAP Get Effective Rights Operation..........  30
+
+          11.  Security Considerations............................  31
+
+          12.  References.........................................  32
+
 
 
 
 
 
 
-                                    CONTENTS
 
 
-           1.  Introduction.......................................   2
 
-           2.  Overview...........................................   2
 
-           3.  Terminology........................................   4
 
-           4.  The Model..........................................   6
-               4.1  Access Control Activity Lifecycle.............   6
-               4.2  Access Control Information Model..............   6
-               4.3  Bind and Credentials..........................   8
 
-           5.  Access Control Information Schema..................   8
-               5.1  Attributes....................................   8
-                    5.1.1  Root DSE Attribute for Access Control
-                           Mechanism   8
-                    5.1.2  Subschema Attribute for Access Control
-                           Mechanism   9
-               5.2  Other Defined Parameters/OIDs.................   9
-                    5.2.1  Rights Families and Rights   9
-                    5.2.2  DN Types  10
 
-           6.  Access Control Parameters for LDAP Controls &
-               Extended Operations................................  11
 
-           7.  Access Control Information (ACI) Controls..........  12
-               7.1  getEffectiveRights Control....................  13
-                    7.1.1  Request Control  13
-                    7.1.2  Response Control  13
-                    7.1.3  Client-Server Interaction  15
-               7.2  specifyCredentials Control....................  16
-                    7.2.1  Request Control  16
-                    7.2.2  Response Control  17
-                    7.2.3  Client-Server Interaction  18
 
-           8.  Access Control Extended Operations.................  20
-               8.1  LDAP Get Effective Rights Operation...........  20
 
-          10.  Security Considerations............................  29
 
-          11.  References.........................................  29
 
 
 
 
 
-                                     - i -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                     - ii -
 
 
 
 
 
 
-                                     - ii -
+                                    - iii -
 
 
 
diff --git a/doc/drafts/draft-ietf-ldapext-authmeth-xx.txt b/doc/drafts/draft-ietf-ldapext-authmeth-xx.txt
deleted file mode 100644 (file)
index 62102e3..0000000
+++ /dev/null
@@ -1,784 +0,0 @@
-
-Network Working Group                                            M. Wahl
-INTERNET-DRAFT                              Innosoft International, Inc.
-                                                           H. Alvestrand
-                                                              MaXware AS
-                                                               J. Hodges
-                                                     Stanford University
-                                                         RL "Bob" Morgan
-                                                     Stanford University
-Expires in six months from                                 June 21, 1999
-
-
-                      Authentication Methods for LDAP
-                   <draft-ietf-ldapext-authmeth-04.txt>
-
-1. Status of this Memo
-
-   This document is an Internet-Draft.  Internet-Drafts are working 
-   documents of the Internet Engineering Task Force (IETF), its 
-   areas, and its working groups.  Note that other groups may also 
-   distribute working documents as Internet-Drafts.
-
-   Internet-Drafts are draft documents valid for a maximum of six 
-   months and may be updated, replaced, or obsoleted by other 
-   documents at any time.  It is inappropriate to use Internet-Drafts 
-   as reference material or to cite them other than as "work in 
-   progress."
-
-   To view the entire list of current Internet-Drafts, please check
-   the "1id-abstracts.txt" listing contained in the Internet-Drafts
-   Shadow Directories on ftp.is.co.za (Africa), ftp.nordu.net
-   (Northern Europe), ftp.nis.garr.it (Southern Europe), munnari.oz.au
-   (Pacific Rim), ftp.ietf.org (US East Coast), or ftp.isi.edu
-   (US West Coast).
-
-2. Abstract
-
-   This document specifies particular combinations of security 
-   mechanisms which are required and recommended in LDAP [1] 
-   implementations.
-
-3. Introduction
-
-   LDAP version 3 is a powerful access protocol for directories.
-
-   It offers means of searching, fetching and manipulating directory
-   content, and ways to access a rich set of security functions.
-
-   In order to function for the best of the Internet, it is vital
-   that these security functions be interoperable; therefore there
-   has to be a minimum subset of security functions that is common to
-   all implementations that claim LDAPv3 conformance.
-
-
-
-Wahl, Alvestrand, Hodges, Morgan                              Page 1
-\f
-INTERNET-DRAFT        Authentication Methods for LDAP         June 1999
-
-   Basic threats to an LDAP directory service include:
-
-     (1)   Unauthorized access to data via data-fetching operations,
-
-     (2)   Unauthorized access to reusable client authentication
-           information by monitoring others' access,
-
-     (3)   Unauthorized access to data by monitoring others' access,
-
-     (4)   Unauthorized modification of data,
-
-     (5)   Unauthorized modification of configuration,
-
-     (6)   Unauthorized or excessive use of resources (denial of 
-           service), and
-
-     (7)   Spoofing of directory: Tricking a client into believing
-           that information came from the directory when in fact it
-           did not, either by modifying data in transit or misdirecting
-           the client's connection.
-
-   Threats (1), (4), (5) and (6) are due to hostile clients.  Threats
-   (2), (3) and (7) are due to hostile agents on the path between client
-   and server, or posing as a server.
-
-   The LDAP protocol suite can be protected with the following
-   security mechanisms:
-
-     (1)   Client authentication by means of the SASL [2] mechanism set,
-           possibly backed by the TLS credentials exchange mechanism,
-
-     (2)   Client authorization by means of access control based on
-           the requestor's authenticated identity,
-
-     (3)   Data integrity protection by means of the TLS protocol or
-           data-integrity SASL mechanisms,
-
-     (4)   Protection against snooping by means of the TLS protocol 
-           or data-encrypting SASL mechanisms,
-
-     (5)   Resource limitation by means of administrative limits on
-           service controls, and
-
-     (6)   Server authentication by means of the TLS protocol or SASL
-           mechanism.
-
-   At the moment, imposition of access controls is done by means
-   outside the scope of the LDAP protocol.  
-
-   In this document, the term "user" represents any application which
-   is an LDAP client using the directory to retrieve or store information.
-
-Wahl, Alvestrand, Hodges, Morgan                              Page 2
-\f
-INTERNET-DRAFT        Authentication Methods for LDAP         June 1999
-
-   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 
-   "SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and "OPTIONAL" in 
-   this document are to be interpreted as described in RFC 2119 [3].
-
-4.  Example deployment scenarios
-
-   The following scenarios are typical for LDAP directories on the 
-   Internet, and have different security requirements. (In the 
-   following, "sensitive" means data that will cause real damage to 
-   the owner if revealed; there may be data that is protected but 
-   not sensitive).  This is not intended to be a comprehensive list, 
-   other scenarios are possible, especially on physically protected
-   networks.
-
-     (1)   A read-only directory, containing no sensitive data,
-           accessible to "anyone", and TCP connection hijacking
-           or IP spoofing is not a problem.  This directory requires 
-           no security functions except administrative service limits.
-
-     (2)   A read-only directory containing no sensitive data; read
-           access is granted based on identity.  TCP connection 
-           hijacking is not currently a problem. This scenario requires 
-          a secure authentication function.  
-
-     (3)   A read-only directory containing no sensitive data; and
-           the client needs to ensure that the directory data is 
-           authenticated by the server and not modified while being 
-           returned from the server.
-
-     (4)   A read-write directory, containing no sensitive data; read
-           access is available to "anyone", update access to properly
-           authorized persons.  TCP connection hijacking is not 
-           currently a problem.  This scenario requires a secure 
-           authentication function.  
-
-     (5)   A directory containing sensitive data.  This scenario
-           requires session confidentiality protection AND secure 
-           authentication.
-
-5.  Authentication and Authorization:  Definitions and Concepts
-
-   This section defines basic terms, concepts, and interrelationships
-   regarding authentication, authorization, credentials, and identity.
-   These concepts are used in describing how various security 
-   approaches are utilized in client authentication and authorization.
-
-
-
-
-
-
-
-Wahl, Alvestrand, Hodges, Morgan                              Page 3
-\f
-INTERNET-DRAFT        Authentication Methods for LDAP         June 1999
-
-5.1.  Access Control Policy
-
-   An access control policy is a set of rules defining the protection 
-   of resources, generally in terms of the capabilities of persons or 
-   other entities accessing those resources.  A common expression of an 
-   access control policy is an access control list.  Security objects 
-   and mechanisms, such as those described here, enable the expression of 
-   access control policies and their enforcement.  Access control 
-   policies are typically expressed in terms of access control attributes 
-   as described below.
-
-5.2.  Access Control Factors
-
-   A request, when it is being processed by a server, may be associated
-   with a wide variety of security-related factors (section 4.2 of [1]). 
-   The server uses these factors to determine whether and how to process 
-   the request.  These are called access control factors (ACFs).  They
-   might include source IP address, encryption strength, the type of
-   operation being requested, time of day, etc.  Some factors may be
-   specific to the request itself, others may be associated with the 
-   connection via which the request is transmitted, others (e.g. time of 
-   day) may be "environmental".
-
-   Access control policies are expressed in terms of access control 
-   factors.  E.g., a request having ACFs i,j,k can perform operation Y 
-   on resource Z. The set of ACFs that a server makes available for such
-   expressions is implementation-specific.
-
-5.3.  Authentication, Credentials, Identity
-
-   Authentication credentials are the evidence supplied by one party to
-   another, asserting the identity of the supplying party (e.g. a user) 
-   who is attempting to establish an association with the other party 
-   (typically a server).  Authentication is the process of generating, 
-   transmitting, and verifying these credentials and thus the identity
-   they assert.  An authentication identity is the name presented in a 
-   credential.
-
-   There are many forms of authentication credentials -- the form used
-   depends upon the particular authentication mechanism negotiated by the
-   parties.  For example: X.509 certificates, Kerberos tickets, simple
-   identity and password pairs.  Note that an authentication mechanism may
-   constrain the form of authentication identities used with it.
-
-5.4.  Authorization Identity
-
-   An authorization identity is one kind of access control factor.  It is
-   the name of the user or other entity that requests that operations be
-   performed.  Access control policies are often expressed in terms of
-   authorization identities; e.g., entity X can perform operation Y on
-   resource Z.
-
-Wahl, Alvestrand, Hodges, Morgan                              Page 4
-\f
-INTERNET-DRAFT        Authentication Methods for LDAP         June 1999
-
-   The authorization identity bound to an association is often exactly the
-   same as the authentication identity presented by the client, but it may
-   be different.  SASL allows clients to specify an authorization identity
-   distinct from the authentication identity asserted by the client's
-   credentials.  This permits agents such as proxy servers to authenticate
-   using their own credentials, yet request the access privileges of the
-   identity for which they are proxying [2].  Also, the form of 
-   authentication identity supplied by a service like TLS may not 
-   correspond to the authorization identities used to express a server's 
-   access control  policy, requiring a server-specific mapping to be done.
-   The method by which a server composes and validates an authorization 
-   identity from the authentication credentials supplied by a client is 
-   implementation-specific.
-
-6. Required security mechanisms
-
-   It is clear that allowing any implementation, faced with the above
-   requirements, to pick and choose among the possible alternatives
-   is not a strategy that is likely to lead to interoperability. In
-   the absence of mandates, clients will be written that do not
-   support any security function supported by the server, or worse,
-   support only mechanisms like cleartext passwords that provide
-   clearly inadequate security.
-
-   Active intermediary attacks are the most difficult for an attacker 
-   to perform, and for an implementation to protect against.  Methods 
-   that protect only against hostile client and passive eavesdropping 
-   attacks are useful in situations where the cost of protection 
-   against active intermediary attacks is not justified based on the
-   perceived risk of active intermediary attacks.
-
-   Given the presence of the Directory, there is a strong desire to
-   see mechanisms where identities take the form of a Distinguished
-   Name and authentication data can be stored in the directory; this
-   means that either this data is useless for faking authentication
-   (like the Unix "/etc/passwd" file format used to be), or its
-   content is never passed across the wire unprotected - that is,
-   it's either updated outside the protocol or it is only updated in
-   sessions well protected against snooping.  It is also desirable 
-   to allow authentication methods to carry authorization identities
-   based on existing forms of user identities for backwards compatibility 
-   with non-LDAP-based authentication services.
-
-   Therefore, the following implementation conformance requirements
-   are in place:
-
-     (1)   For a read-only, public directory, anonymous authentication, 
-          described in section 7, can be used.
-
-
-
-
-Wahl, Alvestrand, Hodges, Morgan                              Page 5
-\f
-INTERNET-DRAFT        Authentication Methods for LDAP         June 1999
-
-     (2)   Implementations providing password-based authenticated access
-           MUST support authentication using Digest, as described in 
-           section 8.1.  This provides client authentication with 
-           protection against passive eavesdropping attacks, but does
-           not provide protection against active intermediary attacks.
-
-     (3)   For a directory needing session protection and
-           authentication, the Start TLS extended operation, and either
-           the simple authentication choice or the SASL EXTERNAL 
-           mechanism, are to be used together.  Implementations SHOULD 
-           support authentication with a password as described in 
-           section 8.2, and SHOULD support authentication with a 
-           certificate as described in section 9.1.  Together, these
-           can provide integrity and disclosure protection of 
-           transmitted data, and authentication of client and server,
-           including protection against active intermediary attacks.
-
-   If TLS is negotated, the client MUST discard all information about 
-   the server fetched prior to the TLS negotiation.  In particular, the 
-   value of supportedSASLMechanisms MAY be different after TLS has been 
-   negotiated (specifically, the EXTERNAL mechanism or the proposed 
-   PLAIN mechanism are likely to only be listed after a TLS negotiation 
-   has been performed).
-
-   If a SASL security layer is negotiated, the client MUST discard all
-   information about the server fetched prior to SASL.  In particular, if 
-   the client is configured to support multiple SASL mechanisms, it SHOULD
-   fetch supportedSASLMechanisms both before and after the SASL security 
-   layer is negotiated and verify that the value has not changed after the
-   SASL security layer was negotiated.  This detects active attacks which
-   remove supported SASL mechanisms from the supportedSASLMechanisms list.
-
-7. Anonymous authentication
-
-   Directory operations which modify entries or access protected 
-   attributes or entries generally require client authentication.  
-   Clients which do not intend to perform any of these operations 
-   typically use anonymous authentication.
-
-   LDAP implementations MUST support anonymous authentication, as 
-   defined in section 7.1.
-
-   LDAP implementations MAY support anonymous authentication with TLS,
-   as defined in section 7.2.  
-
-   While there MAY be access control restrictions to prevent access to 
-   directory entries, an LDAP server SHOULD allow an anonymously-bound 
-   client to retrieve the supportedSASLMechanisms attribute of the root 
-   DSE.
-
-
-
-Wahl, Alvestrand, Hodges, Morgan                              Page 6
-\f
-INTERNET-DRAFT        Authentication Methods for LDAP         June 1999
-
-   An LDAP server MAY use other information about the client provided
-   by the lower layers or external means to grant or deny access even
-   to anonymously authenticated clients. 
-
-7.1. Anonymous authentication procedure
-
-   An LDAP client which has not successfully completed a bind operation 
-   on a connection is anonymously authenticated.
-
-   An LDAP client MAY also specify anonymous authentication in a bind 
-   request by using a zero-length OCTET STRING with the simple
-   authentication choice.
-
-7.2. Anonymous authentication and TLS
-
-   An LDAP client MAY use the Start TLS operation [5] to negotiate the
-   use of TLS security [6].  If the client has not bound beforehand,
-   then until the client uses the EXTERNAL SASL mechanism to negotiate
-   the recognition of the client's certificate, the client is 
-   anonymously authenticated.  
-
-   Recommendations on TLS ciphersuites are given in section 12.
-
-   An LDAP server which requests that clients provide their certificate
-   during TLS negotiation MAY use a local security policy to determine
-   whether to successfully complete TLS negotiation if the client did not 
-   present a certificate which could be validated.
-
-8. Password-based authentication
-
-   LDAP implementations MUST support authentication with a password using
-   the DIGEST-MD5 mechanism for password protection, as defined in section 
-   8.1.  
-
-   LDAP implementations SHOULD support authentication with the "simple"
-   password choice when the connection is protected against eavesdropping
-   using TLS, as defined in section 8.2.  
-  
-8.1. Digest authentication
-
-   An LDAP client MAY determine whether the server supports this 
-   mechanism by performing a search request on the root DSE, requesting
-   the supportedSASLMechanisms attribute, and checking whether the 
-   string "DIGEST-MD5" is present as a value of this attribute.
-
-   In the first stage of authentication, when the client is performing
-   an "initial authentication" as defined in section 2.1 of [4], the 
-   client sends a bind request in which the version number is 3, the 
-   authentication choice is sasl, the sasl mechanism name is "DIGEST-MD5", 
-   and the credentials are absent.  The client then waits for a response 
-   from the server to this request.
-
-Wahl, Alvestrand, Hodges, Morgan                              Page 7
-\f
-INTERNET-DRAFT        Authentication Methods for LDAP         June 1999
-
-   The server will respond with a bind response in which the resultCode
-   is saslBindInProgress, and the serverSaslCreds field is present.  The
-   contents of this field is a string defined by "digest-challenge" in 
-   section 2.1.1 of [4].  The server SHOULD include a realm indication and
-   MUST indicate support for UTF-8.
-
-   The client will send a bind request with a distinct mesage id, in which
-   the version number is 3, the authentication choice is sasl, the sasl
-   mechanism name is "DIGEST-MD5", and the credentials contain the string
-   defined by "digest-response" in section 2.1.2 of [4].  The serv-type 
-   is "ldap".
-
-   The server will respond with a bind response in which the resultCode
-   is either success, or an error indication.  If the authentication is
-   successful and the server does not support subsequent authentication,
-   then the credentials field is absent.  If the authentication is 
-   successful and the server supports subsequent authentication, then
-   the crendentials field contains the string defined by "response-auth"
-   in section 2.1.3 of [4].   Support for subsequent authentication is 
-   OPTIONAL in clients and servers.
-
-8.2. "simple" authentication choice under TLS encryption
-
-   A user who has a directory entry containing a userPassword attribute
-   MAY authenticate to the directory by performing a simple password
-   bind sequence following the negotiation of a TLS ciphersuite 
-   providing connection confidentiality [6].
-
-   The client will use the Start TLS operation [5] to negotiate the 
-   use of TLS security [6] on the connection to the LDAP server.  The
-   client need not have bound to the directory beforehand.
-
-   For this authentication procedure to be successful, the client and 
-   server MUST negotiate a ciphersuite which contains a bulk encryption
-   algorithm of appropriate strength.  Recommendations on cipher
-   suites are given in section 12. 
-
-   Following the successful completion of TLS negotiation, the client
-   MUST send an LDAP bind request with the version number of 3, the 
-   name field containing the name of the user's entry, and the "simple" 
-   authentication choice, containing a password.
-
-   The server will, for each value of the userPassword attribute in 
-   the named user's entry, compare these for case-sensitive equality 
-   with the client's presented password.  If there is a match, then the 
-   server will respond with resultCode success, otherwise the server will
-   respond with resultCode invalidCredentials.
-
-
-
-
-
-Wahl, Alvestrand, Hodges, Morgan                              Page 8
-\f
-INTERNET-DRAFT        Authentication Methods for LDAP         June 1999
-
-8.3. Other authentication choices with TLS
-   
-   It is also possible to perform a SASL authentication exchange of 
-   passwords following the negotiation of TLS.  In this case the 
-   client and server need not negotiate a ciphersuite which provides 
-   confidentiality if the only service required is data integrity.
-
-9. Certificate-based authentication
-
-   LDAP implementations SHOULD support authentication via a client 
-   certificate in TLS, as defined in section 9.1.  
-
-9.1. Certificate-based authentication with TLS
-
-   A user who has a public/private key pair in which the public key has
-   been signed by a Certification Authority may use this key pair to
-   authenticate to the directory server if the user's certificate is 
-   requested by the server.  The user's certificate subject field 
-   SHOULD be the name of the user's directory entry, and the 
-   Certification Authority must be sufficiently trusted by the 
-   directory server to have issued the certificate in order that the 
-   server can process the certificate.  The means by which servers
-   validate certificate paths is outside the scope of this document.
-
-   A server MAY support mappings for certificates in which the subject 
-   field name is different from the name of the user's directory entry. 
-   A server which supports mappings of names MUST be capable of being
-   configured to support certificates for which no mapping is required.
-
-   The client will use the Start TLS operation [5] to negotiate the 
-   use of TLS security [6] on the connection to the LDAP server.  The
-   client need not have bound to the directory beforehand.
-
-   In the TLS negotiation, the server MUST request a certificate.  The
-   client will provide its certificate to the server, and MUST perform 
-   a private key-based encryption, proving it has it private key 
-   associated with the certificate.  
-
-   As deployments will require protection of sensitive data in transit,
-   the client and server MUST negotiate a ciphersuite which contains a 
-   bulk encryption algorithm of appropriate strength.  Recommendations
-   of cipher suites are given in section 12.
-
-   The server MUST verify that the client's certificate is valid. 
-   The server will normally check that the certificate is issued by a 
-   known CA, and that none of the certificates on the client's 
-   certificate chain are invalid or revoked.  There are several 
-   procedures by which the server can perform these checks.
-
-   Following the successful completion of TLS negotiation, the client
-   will send an LDAP bind request with the SASL "EXTERNAL" mechanism.  
-
-Wahl, Alvestrand, Hodges, Morgan                              Page 9
-\f
-INTERNET-DRAFT        Authentication Methods for LDAP         June 1999
-
-10. Other mechanisms
-
-   The LDAP "simple" authentication choice is not suitable for 
-   authentication on the Internet where there is no network or transport 
-   layer confidentiality.
-
-   As LDAP includes a native anonymous and plaintext authentication 
-   methods, the "ANONYMOUS" and "PLAIN" SASL mechanisms are not used 
-   with LDAP.  If an authorization identity of a form different from
-   a DN is requested by the client, a mechanism that protects the
-   password in transit SHOULD be used.
-
-   The following SASL-based mechanisms are not considered in this 
-   document: KERBEROS_V4, GSSAPI and SKEY.  
-
-   The "EXTERNAL" SASL mechanism can be used to request the LDAP server
-   make use of security credentials exchanged by a lower layer. If a 
-   TLS session has not been established between the client and server 
-   prior to making the SASL EXTERNAL Bind request and there is no other 
-   external source of authentication credentials (e.g.  IP-level 
-   security [8]), or if, during the process of establishing the 
-   TLS session, the server did not request the client's authentication 
-   credentials, the SASL EXTERNAL bind MUST fail with a result code of 
-   inappropriateAuthentication. Any authentication identity and 
-   authorization identity, as well as TLS connection, which were in 
-   effect prior to making the Bind request, MUST remain in force.
-
-11. Authorization Identity
-
-   The authorization identity is carried as part of the SASL credentials
-   field in the LDAP Bind request and response.  
-
-   When the "EXTERNAL" mechanism is being negotiated, if the 
-   credentials field is present, it contains an authorization identity
-   of the authzId form described below.
-
-   Other mechanisms define the location of the authorization 
-   identity in the credentials field.
-   The authorization identity is a string in the UTF-8 character set, 
-   corresponding to the following ABNF [7]:
-
-   ; Specific predefined authorization (authz) id schemes are
-   ; defined below -- new schemes may be defined in the future.
-
-   authzId    = dnAuthzId / uAuthzId
-
-   ; distinguished-name-based authz id.
-   dnAuthzId  = "dn:" dn
-   dn         = utf8string    ; with syntax defined in RFC 2253
-
-
-Wahl, Alvestrand, Hodges, Morgan                              Page 10
-\f
-INTERNET-DRAFT        Authentication Methods for LDAP         June 1999
-
-   ; unspecified userid, UTF-8 encoded.
-   uAuthzId   = "u:" userid
-   userid     = utf8string    ; syntax unspecified
-
-   A utf8string is defined to be the UTF-8 encoding of one or more
-   ISO 10646 characters.
-
-   All servers which support the storage of authentication credentials, 
-   such as passwords or certificates, in the directory MUST support the 
-   dnAuthzId choice. 
-
-   The uAuthzId choice allows for compatibility with client applications 
-   which wish to authenticate to a local directory but do not know their
-   own Distinguished Name or have a directory entry.  The format of the 
-   string is defined as only a sequence of UTF-8 encoded ISO 10646 
-   characters, and further interpretation is subject to prior agreement 
-   between the client and server.  
-
-   For example, the userid could identify a user of a specific directory 
-   service, or be a login name or the local-part of an RFC 822 email 
-   address. In general a uAuthzId MUST NOT be assumed to be globally 
-   unique.
-
-   Additional authorization identity schemes MAY be defined in future
-   versions of this document.
-
-12. TLS Ciphersuites
-
-   The following ciphersuites defined in [6] MUST NOT be used for
-   confidentiality protection of passwords or data:
-
-         TLS_NULL_WITH_NULL_NULL
-         TLS_RSA_WITH_NULL_MD5
-         TLS_RSA_WITH_NULL_SHA
-
-   The following ciphersuites defined in [6] can be cracked easily
-   (less than a week of CPU time on a standard CPU in 1997).  The 
-   client and server SHOULD carefully consider the value of the
-   password or data being protected before using these ciphersuites:
-
-         TLS_RSA_EXPORT_WITH_RC4_40_MD5
-         TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5
-         TLS_RSA_EXPORT_WITH_DES40_CBC_SHA
-         TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA
-         TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA
-         TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
-         TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
-         TLS_DH_anon_EXPORT_WITH_RC4_40_MD5
-         TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA
-
-
-
-Wahl, Alvestrand, Hodges, Morgan                              Page 11
-\f
-INTERNET-DRAFT        Authentication Methods for LDAP         June 1999
-
-   The following ciphersuites are vulnerable to man-in-the-middle
-   attacks, and SHOULD NOT be used to protect passwords or sensitive
-   data, unless the network configuration is such that the danger of
-   a man-in-the-middle attack is tolerable:
-        
-         TLS_DH_anon_EXPORT_WITH_RC4_40_MD5
-         TLS_DH_anon_WITH_RC4_128_MD5
-         TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA
-         TLS_DH_anon_WITH_DES_CBC_SHA
-         TLS_DH_anon_WITH_3DES_EDE_CBC_SHA
-
-   A client or server that supports TLS MUST support at least 
-   TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA.
-
-13. SASL service name for LDAP
-
-   For use with SASL [2], a protocol must specify a service name to be
-   used with various SASL mechanisms, such as GSSAPI.  For LDAP, the
-   service name is "ldap", which has been registered with the IANA
-   as a GSSAPI service name.
-
-14. Security Considerations
-
-   Security issues are discussed throughout this memo; the
-   (unsurprising) conclusion is that mandatory security is important,
-   and that session encryption is required when snooping is a
-   problem.
-
-   Servers are encouraged to prevent modifications by anonymous 
-   users. Servers may also wish to minimize denial of service attacks 
-   by timing out idle connections, and returning the unwillingToPerform
-   result code rather than performing computationally expensive 
-   operations requested by unauthorized clients.
-
-   A connection on which the client has not performed the Start TLS 
-   operation or negotiated a suitable SASL mechanism for connection 
-   integrity and encryption services is subject to man-in-the-middle 
-   attacks to view and modify information in transit.  
-
-   Additional security considerations relating to the EXTERNAL
-   EXTERNAL mechanism to negotiate TLS can be found in [2], [5]
-   and [6].  
-
-15. Acknowledgements
-
-   This document is a product of the LDAPEXT Working Group of the 
-   IETF.  The contributions of its members is greatly appreciated.
-
-
-
-
-
-Wahl, Alvestrand, Hodges, Morgan                              Page 12
-\f
-INTERNET-DRAFT        Authentication Methods for LDAP         June 1999
-
-16. Bibliography
-
-   [1] M. Wahl, T. Howes, S. Kille, "Lightweight Directory Access 
-       Protocol (v3)", Dec. 1997, RFC 2251.
-
-   [2] J. Myers, "Simple Authentication and Security Layer (SASL)", 
-       Oct. 1997, RFC 2222.
-
-   [3] S. Bradner, "Key words for use in RFCs to Indicate Requirement
-       Levels", RFC 2119.
-
-   [4] P. Leach, C. Newman, "Using Digest Authentication as a SASL 
-       Mechanism", INTERNET DRAFT <draft-leach-digest-sasl-00.txt>.
-
-   [5] J. Hodges, RL Morgan, M. Wahl, "LDAPv3 Extension for Transport
-       Layer Security", Oct. 1998, INTERNET DRAFT
-       <draft-ietf-ldapext-ldapv3-tls-03.txt>.
-
-   [6] T. Diers, C. Allen, "The TLS Protocol Version 1.0", Jan. 1999,
-       RFC 2246.
-
-   [7] D. Crocker, Ed., P. Overell, "Augmented BNF for Syntax
-       Specifications: ABNF", RFC 2234.
-
-   [8] S. Kent, R. Atkinson, "Security Architecture for the Internet 
-       Protocol", Nov. 1998, RFC 2401.
-
-17. Authors Address
-
-    Mark Wahl
-    Innosoft International, Inc.
-    8911 Capital of Texas Hwy, Suite 4140
-    Austin, TX 78759 
-    USA
-    Phone: +1 512 231 1600
-    EMail:  Mark.Wahl@innosoft.com
-
-    Harald Tveit Alvestrand
-    EMail: Harald.Alvestrand@maxware.no
-
-    Jeff Hodges
-    Computing & Communication Services
-    Stanford University
-    Pine Hall
-    241 Panama Street
-    Stanford, CA 94305-4122
-    USA
-    Phone: +1-650-723-2452
-    EMail: Jeff.Hodges@Stanford.edu
-
-
-
-Wahl, Alvestrand, Hodges, Morgan                              Page 13
-\f
-INTERNET-DRAFT        Authentication Methods for LDAP         June 1999
-
-    RL "Bob" Morgan
-    Computing & Communication Services
-    Stanford University
-    Pine Hall
-    241 Panama Street
-    Stanford, CA 94305-4122
-    USA
-    Phone: +1-650-723-9711
-    EMail: Bob.Morgan@Stanford.edu
-
-Full Copyright Statement
-
-   Copyright (C) The Internet Society (1998).  All Rights Reserved.
-
-   This document and translations of it may be copied and furnished to
-   others, and derivative works that comment on or otherwise explain it
-   or assist in its implementation may be prepared, copied, published
-   and distributed, in whole or in part, without restriction of any
-   kind, provided that the above copyright notice and this paragraph are
-   included on all such copies and derivative works.  However, this
-   document itself may not be modified in any way, such as by removing
-   the copyright notice or references to the Internet Society or other
-   Internet organizations, except as needed for the purpose of
-   developing Internet standards in which case the procedures for
-   copyrights defined in the Internet Standards process must be
-   followed, or as required to translate it into languages other than
-   English.
-
-   The limited permissions granted above are perpetual and will not be
-   revoked by the Internet Society or its successors or assigns.
-
-   This document and the information contained herein is provided on an
-   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
-   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
-   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
-   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
-   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Wahl, Alvestrand, Hodges, Morgan                              Page 14
-
index 6fd89dd23e309b6cd24baf5d4ed44233436221ed..74fdf7327ef214c5fa8e69af0258b3acab444977 100644 (file)
@@ -1,8 +1,8 @@
 Network Working Group                                   M. Smith, Editor
 INTERNET-DRAFT                             Netscape Communications Corp.
 Intended Category: Standards Track                              T. Howes
-Obsoletes: RFC 1823                        Netscape Communications Corp.
-Expires: 2 December 1999                                       A. Herron
+Obsoletes: RFC 1823
+Expires: 8 April 2000                                          A. Herron
                                                          Microsoft Corp.
                                                                  M. Wahl
                                             Innosoft International, Inc.
@@ -10,10 +10,10 @@ Expires: 2 December 1999                                       A. Herron
                                                          Microsoft Corp.
 
 
-                                                             2 June 1999
+                                                          8 October 1999
 
                 The C LDAP Application Program Interface
-                 <draft-ietf-ldapext-ldap-c-api-03.txt>
+                 <draft-ietf-ldapext-ldap-c-api-04.txt>
 
 
 1.  Status of this Memo
@@ -49,10 +49,10 @@ information.
 
 
 
-Expires: 2 December 1999                                        [Page 1]
+Expires: 8 April 2000                                           [Page 1]
 
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
 
 2.  Introduction
@@ -65,6 +65,10 @@ LDAP protocol.  New extended operation functions were added to support
 LDAPv3 features such as controls.  In addition, other LDAP API changes
 were made to support information hiding and thread safety.
 
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+"SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and "OPTIONAL" in this
+document are to be interpreted as described in RFC 2119[1].
+
 The C LDAP API is designed to be powerful, yet simple to use. It defines
 compatible synchronous and asynchronous interfaces to LDAP to suit a
 wide variety of applications. This document gives a brief overview of
@@ -82,97 +86,99 @@ list of changes made since the last revision of this document.
 2.     Introduction...................................................2
 3.     Table of Contents..............................................2
 4.     Overview of the LDAP Model.....................................4
-5.     Overview of LDAP API Use.......................................4
-6.     Header File Requirements.......................................6
-7.     Common Data Structures.........................................7
-8.     Retrieving Information About the API Implementation............8
-8.1.      Retrieving Information at Compile Time......................9
-8.2.      Retrieving Information During Execution.....................10
-9.     LDAP Error Codes...............................................13
-10.    Performing LDAP Operations.....................................14
-10.1.     Initializing an LDAP Session................................14
-10.2.     LDAP Session Handle Options.................................15
-10.3.     Working With Controls.......................................20
-10.3.1.      A Client Control That Governs Referral Processing........22
-10.4.     Authenticating to the directory.............................22
-10.5.     Closing the session.........................................25
-10.6.     Searching...................................................26
-10.7.     Reading an Entry............................................29
-10.8.     Listing the Children of an Entry............................30
-10.9.     Comparing a Value Against an Entry..........................30
-10.10.    Modifying an entry..........................................32
-10.11.    Modifying the Name of an Entry..............................34
-10.12.    Adding an entry.............................................36
-
-
-
-Expires: 2 December 1999                                        [Page 2]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
-10.13.    Deleting an entry...........................................38
-10.14.    Extended Operations.........................................39
-11.    Abandoning An Operation........................................41
-12.    Obtaining Results and Peeking Inside LDAP Messages.............42
-13.    Handling Errors and Parsing Results............................44
-14.    Stepping Through a List of Results.............................46
-15.    Parsing Search Results.........................................47
-15.1.     Stepping Through a List of Entries or References............48
-15.2.     Stepping Through the Attributes of an Entry.................49
-15.3.     Retrieving the Values of an Attribute.......................50
-15.4.     Retrieving the name of an entry.............................51
-15.5.     Retrieving controls from an entry...........................52
-15.6.     Parsing References..........................................53
-16.    Encoded ASN.1 Value Manipulation...............................54
-16.1.     General.....................................................54
-16.2.     Encoding....................................................55
-16.3.     Encoding Example............................................58
-16.4.     Decoding....................................................59
-16.5.     Decoding Example............................................61
-17.    Security Considerations........................................64
-18.    Acknowledgements...............................................64
-19.    Copyright......................................................64
-20.    Bibliography...................................................65
-21.    Authors' Addresses.............................................66
-22.    Appendix A - Sample C LDAP API Code............................66
-23.    Appendix B - Namespace Consumed By This Specification..........68
-24.    Appendix C - Summary of Requirements for API Extensions........68
-24.1.     Compatibility...............................................69
-24.2.     Style.......................................................69
-24.3.     Dependence on Externally Defined Types......................69
-24.4.     Compile Time Information....................................69
-24.5.     Runtime Information.........................................69
-24.6.     Values Used for Session Handle Options......................70
-25.    Appendix D - Known Incompatibilities with RFC 1823.............70
-25.1.     Opaque LDAP Structure.......................................70
-25.2.     Additional Error Codes......................................70
-25.3.     Freeing of String Data with ldap_memfree()..................71
-25.4.     Changes to ldap_result()....................................71
-25.5.     Changes to ldap_first_attribute() and ldap_next_attribute...71
-25.6.     Changes to ldap_modrdn() and ldap_modrdn_s() Functions......71
-25.7.     Changes to the berval structure.............................71
-25.8.     API Specification Clarified.................................72
-25.9.     Deprecated Functions........................................72
-26.    Appendix E - Data Types and Legacy Implementations.............72
-27.    Appendix F - Changes Made Since Last Document Revision.........73
-27.1.     API Changes.................................................73
-27.2.     Editorial Changes...........................................74
-28.    Appendix G - Changes Made Since draft-ietf-ldapext-ldap-c-api-.74
-28.1.     API Changes.................................................74
-28.2.     Editorial changes...........................................75
-
-Expires: 2 December 1999                                        [Page 3]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+5.     Overview of LDAP API Use and General Requirements..............4
+6.     Header Requirements............................................6
+7.     Common Data Structures and Types...............................7
+8.     Memory Handling Overview.......................................9
+9.     Retrieving Information About the API Implementation............9
+9.1.      Retrieving Information at Compile Time......................9
+9.2.      Retrieving Information During Execution.....................11
+10.    LDAP Error Codes...............................................14
+11.    Performing LDAP Operations.....................................15
+11.1.     Initializing an LDAP Session................................15
+11.2.     LDAP Session Handle Options.................................16
+11.3.     Working With Controls.......................................22
+11.3.1.      A Client Control That Governs Referral Processing........23
+11.4.     Authenticating to the directory.............................24
+11.5.     Closing the session.........................................26
+11.6.     Searching...................................................27
+11.7.     Reading an Entry............................................31
+
+
+
+Expires: 8 April 2000                                           [Page 2]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+11.8.     Listing the Children of an Entry............................31
+11.9.     Comparing a Value Against an Entry..........................31
+11.10.    Modifying an entry..........................................33
+11.11.    Modifying the Name of an Entry..............................36
+11.12.    Adding an entry.............................................38
+11.13.    Deleting an entry...........................................40
+11.14.    Extended Operations.........................................41
+12.    Abandoning An Operation........................................43
+13.    Obtaining Results and Peeking Inside LDAP Messages.............43
+14.    Handling Errors and Parsing Results............................45
+15.    Stepping Through a List of Results.............................48
+16.    Parsing Search Results.........................................49
+16.1.     Stepping Through a List of Entries or References............49
+16.2.     Stepping Through the Attributes of an Entry.................51
+16.3.     Retrieving the Values of an Attribute.......................52
+16.4.     Retrieving the name of an entry.............................53
+16.5.     Retrieving controls from an entry...........................54
+16.6.     Parsing References..........................................55
+17.    Encoded ASN.1 Value Manipulation...............................56
+17.1.     BER Data Structures and Types...............................56
+17.2.     Memory Disposal and Utility Functions.......................57
+17.3.     Encoding....................................................58
+17.4.     Encoding Example............................................61
+17.5.     Decoding....................................................62
+17.6.     Decoding Example............................................65
+18.    Security Considerations........................................67
+19.    Acknowledgements...............................................68
+20.    Copyright......................................................68
+21.    Bibliography...................................................68
+22.    Authors' Addresses.............................................69
+23.    Appendix A - Sample C LDAP API Code............................70
+24.    Appendix B - Namespace Consumed By This Specification..........72
+25.    Appendix C - Summary of Requirements for API Extensions........72
+25.1.     Compatibility...............................................72
+25.2.     Style.......................................................73
+25.3.     Dependence on Externally Defined Types......................73
+25.4.     Compile Time Information....................................73
+25.5.     Runtime Information.........................................73
+25.6.     Values Used for Session Handle Options......................73
+26.    Appendix D - Known Incompatibilities with RFC 1823.............74
+26.1.     Opaque LDAP Structure.......................................74
+26.2.     Additional Error Codes......................................74
+26.3.     Freeing of String Data with ldap_memfree()..................74
+26.4.     Changes to ldap_result()....................................75
+26.5.     Changes to ldap_first_attribute() and ldap_next_attribute...75
+26.6.     Changes to ldap_modrdn() and ldap_modrdn_s() Functions......75
+26.7.     Changes to the berval structure.............................75
+26.8.     API Specification Clarified.................................75
+26.9.     Deprecated Functions........................................76
+
+
+
+Expires: 8 April 2000                                           [Page 3]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+27.    Appendix E - Data Types and Legacy Implementations.............76
+28.    Appendix F - Changes Made Since Last Document Revision.........77
+28.1.     API Changes.................................................77
+28.2.     Editorial Changes...........................................79
+
 
 
 4.  Overview of the LDAP Model
 
 LDAP is the lightweight directory access protocol, described in [2] and
-[6]. It can provide a lightweight frontend to the X.500 directory [1],
+[3]. It can provide a lightweight frontend to the X.500 directory [4],
 or a stand-alone service. In either mode, LDAP is based on a client-
 server model in which a client makes a TCP connection to an LDAP server,
 over which it sends requests and receives responses.
@@ -198,7 +204,7 @@ is constructed by concatenating the sequence of RDNs from the entry up
 to the root of the tree. For example, if Babs worked for the University
 of Michigan, the DN of her U-M entry might be "cn=Barbara Jensen,
 o=University of Michigan, c=US". The DN format used by LDAP is defined
-in [4].
+in [5].
 
 Operations are provided to authenticate, search for and retrieve infor-
 mation, modify information, and add and delete entries from the tree.
@@ -207,24 +213,25 @@ descriptions of the LDAP API calls that implement all of these func-
 tions.
 
 
-5.  Overview of LDAP API Use
+5.  Overview of LDAP API Use and General Requirements
 
 An application generally uses the C LDAP API in four simple steps.
 
-   1.   Initialize an LDAP session with a primary LDAP server. The
-        ldap_init() function returns a handle to the session, allowing
-        multiple connections to be open at once.
 
-   2.   Authenticate to the LDAP server. The ldap_sasl_bind() function
-        and friends support a variety of authentication methods.
 
 
+Expires: 8 April 2000                                           [Page 4]
+
 
-Expires: 2 December 1999                                        [Page 4]
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+   1.   Initialize an LDAP session with a primary LDAP server. The
+        ldap_init() function returns a handle to the session, allowing
+        multiple connections to be open at once.
 
+   2.   Authenticate to the LDAP server. The ldap_sasl_bind() function
+        and friends support a variety of authentication methods.
 
    3.   Perform some LDAP operations and obtain some results.
         ldap_search() and friends return results which can be parsed by
@@ -250,7 +257,7 @@ entries and attributes returned, etc. Routines are also provided to
 interpret errors. Later sections of this document describe these rou-
 tines in more detail.
 
-LDAP version 3 servers may return referrals and references to other
+LDAP version 3 servers can return referrals and references to other
 servers.  By default, implementations of this API will attempt to follow
 referrals automatically for the application.  This behavior can be dis-
 abled globally (using the ldap_set_option() call) or on a per-request
@@ -259,41 +266,46 @@ basis through the use of a client control.
 All DN and string attribute values passed into or produced by this C
 LDAP API are represented using the character set of the underlying LDAP
 protocol version in use.  When this API is used with LDAPv3, DN and
-string values are represented as UTF-8[10] characters.  When this API is
-used with LDAPv2, the US-ASCII[12] or T.61[12] character set are used.
-Future documents may specific additional APIs supporting other character
+string values are represented as UTF-8[6] characters.  When this API is
+used with LDAPv2, the US-ASCII[7] or T.61[7] character set are used.
+Future documents MAY specify additional APIs supporting other character
 sets.
 
 For compatibility with existing applications, implementations of this
 API will by default use version 2 of the LDAP protocol.  Applications
 that intend to take advantage of LDAP version 3 features will need to
-use the ldap_set_option() call with a LDAP_OPT_PROTOCOL_VERSION to
-switch to version 3.
 
-Note that this API is designed for use in environments where the 'int'
-type is at least 32 bits in size.
 
 
+Expires: 8 April 2000                                           [Page 5]
+
 
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
 
-Expires: 2 December 1999                                        [Page 5]
+use the ldap_set_option() call with a LDAP_OPT_PROTOCOL_VERSION to
+switch to version 3.
 
+Unless otherwise indicated, conformant implementations of this specifi-
+cation MUST implement all of the C LDAP API functions as described in
+this document, and they MUST use the function prototypes, macro defini-
+tions, and types defined in this document.
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+Note that this API is designed for use in environments where the 'int'
+type is at least 32 bits in size.
 
 
-6.  Header File Requirements
+6.  Header Requirements
 
-To promote portability of applications, implementations of this C LDAP
-API must conform to the following requirements of the header files used
-by applications to access the services of this API:
+To promote portability of applications, the following requirements are
+imposed on the headers used by applications to access the services of
+this API:
 
 Name and Inclusion
-        Applications are only required to include a single header file
-        named ldap.h to access all of the API services described in this
-        document.  Therefore, the following C source program must com-
-        pile without errors:
+        Applications only need to include a single header named ldap.h
+        to access all of the API services described in this document.
+        Therefore, the following C source program MUST compile without
+        errors:
 
            #include <ldap.h>
 
@@ -303,67 +315,68 @@ Name and Inclusion
                return 0;
            }
 
-        Note that it is permissible for the ldap.h header file to
-        include other implementation-specific header files.
+        The ldap.h header MAY include other implementation-specific
+        headers.
 
-Implementations SHOULD also provide a header file named lber.h to faci-
-late development of applications desiring compatibility with older LDAP
-implementations.  The lber.h header file may be empty.
+Implementations SHOULD also provide a header named lber.h to facilitate
+development of applications desiring compatibility with older LDAP
+implementations.  The lber.h header MAY be empty.  Old applications that
+include lber.h in order to use BER facilities will need to include
+ldap.h.
 
 
 Idempotence
-        All header files should be idempotent; that is, if they are
-        included more than once the effect is as if they had only been
-        included once.
+        All headers SHOULD be idempotent; that is, if they are included
+        more than once the effect is as if they had only been included
+        once.
 
 Must Be Included Before API Is Used
-        An application must include the ldap.h header file before
-        referencing any of the function or type definitions described in
-        this API specification.
 
-Mutual Independence
-        If possible, header files should be mutually independent with
-        minimal dependence on system or any other header files.
 
-Use of the 'const' Keyword
-        This API specification is defined in terms of ISO C[13].  It
-        makes use of function prototypes and the 'const' keyword.  The
-        use of 'const' in this specification is limited to simple, non-
-        array function parameters to avoid forcing applications to
-        declare parameters and variables that accept return values from
 
+Expires: 8 April 2000                                           [Page 6]
 
 
-Expires: 2 December 1999                                        [Page 6]
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+        An application MUST include the ldap.h header before referencing
+        any of the function or type definitions described in this API
+        specification.
 
+Mutual Independence
+        Headers SHOULD be mutually independent with minimal dependence
+        on system or any other headers.
 
+Use of the 'const' Keyword
+        This API specification is defined in terms of ISO C[8].  It
+        makes use of function prototypes and the 'const' keyword.  The
+        use of 'const' in this specification is limited to simple, non-
+        array function parameters to avoid forcing applications to
+        declare parameters and variables that accept return values from
         LDAP API functions as 'const.'  Implementations specifically
-        designed to be used with non-ISO C translators may provide func-
-        tion declarations without prototypes or function prototypes
+        designed to be used with non-ISO C translators SHOULD provide
+        function declarations without prototypes or function prototypes
         without specification of 'const' arguments.
 
 Definition of 'struct timeval'
         This API specification uses the 'struct timeval' type.  Imple-
-        mentations of this API should ensure that the struct timeval
-        type is by default defined as a consequence of including the
-        ldap.h header file.  Because struct timeval is usually defined
-        in one or more system header files, it is possible for header
-        file conflicts to occur if ldap.h also defines it or arranges
-        for it to be defined by including another header file.  There-
-        fore, applications may want to arrange for struct timeval to be
-        defined before they include ldap.h.  To support this, the ldap.h
-        header file must not itself define struct timeval if the prepro-
-        cessor symbol LDAP_TYPE_TIMEVAL_DEFINED is defined before ldap.h
-        is included.
+        mentations of this API MUST ensure that the struct timeval type
+        is by default defined as a consequence of including the ldap.h
+        header.  Because struct timeval is usually defined in one or
+        more system headers, it is possible for header conflicts to
+        occur if ldap.h also defines it or arranges for it to be defined
+        by including another header.  Therefore, applications MAY want
+        to arrange for struct timeval to be defined before they include
+        ldap.h.  To support this, the ldap.h header MUST NOT itself
+        define struct timeval if the preprocessor symbol
+        LDAP_TYPE_TIMEVAL_DEFINED is defined before ldap.h is included.
 
 
-7.  Common Data Structures
+7.  Common Data Structures and Types
 
-Some data structures that are common to several LDAP API functions are
-defined here:
+Data structures and types that are common to several LDAP API functions
+are defined here:
 
        typedef struct ldap LDAP;
 
@@ -371,40 +384,38 @@ defined here:
 
        typedef struct berelement BerElement;
 
-       typedef ber_len_t;  /* actual definition is implementation-specific */
+       typedef impl_len_t ber_len_t;
 
-       typedef ber_tag_t;  /* actual definition is implementation-specific */
-
-       struct berval {
+       typedef struct berval {
            ber_len_t       bv_len;
-           char            *bv_val;
-       };
 
-       struct timeval {
-               long        tv_sec;
-               long        tv_usec;
-       };
 
-The LDAP structure is an opaque data type that represents an LDAP ses-
-sion Typically this corresponds to a connection to a single server, but
-it may encompass several server connections in the face of LDAPv3
 
+Expires: 8 April 2000                                           [Page 7]
 
 
-Expires: 2 December 1999                                        [Page 7]
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+           char            *bv_val;
+       } BerValue;
 
+       struct timeval {
+           impl_sec_t      tv_sec;
+           impl_usec_t     tv_usec;
+       };
 
-referrals.
+The LDAP structure is an opaque data type that represents an LDAP ses-
+sion Typically this corresponds to a connection to a single server, but
+it MAY encompass several server connections in the face of LDAPv3 refer-
+rals.
 
 The LDAPMessage structure is an opaque data type that is used to return
 entry, reference, result, and error information.  An LDAPMessage struc-
-ture may represent the beginning of a list, or chain of messages that
+ture can represent the beginning of a list, or chain of messages that
 consists of a series of entries, references, and result messages as
 returned by LDAP operations such as search.  LDAP API functions such as
-ldap_parse_result() that operate on message chains that may contain more
+ldap_parse_result() that operate on message chains that can contain more
 than one result message always operate on the first result message in
 the chain.  See the "Obtaining Results and Peeking Inside LDAP Messages"
 section of this document for more information.
@@ -414,16 +425,16 @@ data and state information about encoded data.  It is described in more
 detail in the section "Encoded ASN.1 Value Manipulation" later in this
 document.
 
-The ber_len_t type is an unsigned integral data type that is large
+The `ber_len_t' type is an unsigned integral data type that is large
 enough to contain the length of the largest piece of data supported by
-the API implementation.  Similarly, the ber_tag_t type is an unsigned
-integral data type that is large enough to hold the largest BER tag sup-
-ported by the API implementation.  Both of these types should be at
-least 32 bits in size.  See the appendix "Data Types and Legacy Imple-
-mentations" for additional considerations.
+the API implementation.  The `impl_len_t' in the `ber_len_t' typedef
+MUST be replaced with an appropriate type.  The width (number of signi-
+ficant bits) of `ber_len_t' MUST be at least 32 and no larger than that
+of `unsigned long'.  See the appendix "Data Types and Legacy Implementa-
+tions" for additional considerations.
 
-The berval structure is used to represent arbitrary binary data and its
-fields have the following meanings:
+The BerValue structure is used to represent arbitrary binary data and
+its fields have the following meanings:
 
 bv_len   Length of data in bytes.
 
@@ -435,32 +446,72 @@ fields have the following meanings:
 
 tv_sec   Seconds component of time interval.
 
+
+
+Expires: 8 April 2000                                           [Page 8]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
 tv_usec  Microseconds component of time interval.
 
-See the earlier section "Header File Requirements" for more information
-on struct timeval.
+Note that because the struct timeval definition typically is derived
+from a system header, the types used for the tv_sec and tv_usec com-
+ponents are implementation-specific integral types.  Therefore,
+`impl_sec_t' and `impl_usec_t' in the struct timeval definition MUST be
+replaced with appropriate types.  See the earlier section "Header
+Requirements" for more information on struct timeval.
+
+
+8.  Memory Handling Overview
+
+All memory that is allocated by a function in this C LDAP API and
+returned to the caller SHOULD be disposed of by calling the appropriate
+"free" function provided by this API.  The correct "free" function to
+call is documented in each section of this document where a function
+that allocates memory is described.
 
+Memory that is allocated through means outside of the C LDAP API MUST
+NOT be disposed of using a function provided by this API.
 
-8.  Retrieving Information About the API Implementation
+If a pointer value passed to one of the C LDAP API "free" functions is
+NULL, graceful failure (i.e, ignoring of the NULL pointer) MUST occur.
+
+The complete list of "free" functions that are used to dispose of allo-
+cated memory is:
+
+   ber_bvecfree()
+   ber_bvfree()
+   ber_free()
+   ldap_control_free()
+   ldap_controls_free()
+   ldap_memfree()
+   ldap_msgfree()
+   ldap_value_free()
+   ldap_value_free_len()
+
+
+9.  Retrieving Information About the API Implementation
 
 Applications developed to this specification need to be able to deter-
 mine information about the particular API implementation they are using
+both at compile time and during execution.
 
 
+9.1.  Retrieving Information at Compile Time
 
-Expires: 2 December 1999                                        [Page 8]
+All conformant implementations MUST include the following five
 
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
 
+Expires: 8 April 2000                                           [Page 9]
 
-both at compile time and during execution.
 
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-8.1.  Retrieving Information at Compile Time
 
-All conformant implementations MUST include the following five defini-
-tions in a header file so compile time tests can be done by LDAP
+definitions in a header so compile time tests can be done by LDAP
 software developers:
 
    #define LDAP_API_VERSION     level
@@ -478,7 +529,7 @@ where:
      ported by the implementation.
 
      max-version is replaced with the highest LDAP protocol version sup-
-     ported by the implementation.  This should be 3.
+     ported by the implementation.  This SHOULD be 3.
 
      "vend-name" is replaced with a text string that identifies the
      party that supplies the API implementation.
@@ -486,9 +537,9 @@ where:
      "vend-version" is a supplier-specific version number multiplied
      times 100.
 
-Note that the LDAP_VENDOR_NAME macro may be defined as "" if no vendor
-name is available and the LDAP_VENDOR_VERSION macro may be defined as 0
-if no vendor-specific version information is available.
+Note that the LDAP_VENDOR_NAME macro SHOULD be defined as "" if no ven-
+dor name is available and the LDAP_VENDOR_VERSION macro SHOULD be
+defined as 0 if no vendor-specific version information is available.
 
 For example, if this specification is published as RFC 88888, Netscape
 Communication's version 4.0 implementation that supports LDAPv2 and v3
@@ -503,22 +554,23 @@ might include macro definitions like these:
 and application code can test the C LDAP API version level using a
 construct such as this one:
 
+   #if (LDAP_API_VERSION >= 88888)
+           /* use features supported in RFC 88888 or later */
+   #endif
+
+Until such time as this document is published as an RFC, implementations
 
 
-Expires: 2 December 1999                                        [Page 9]
 
+Expires: 8 April 2000                                          [Page 10]
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
 
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-   #if (LDAP_API_VERSION >= 88888)
-           /* use features supported in RFC 88888 or later */
-   #endif
 
-Until such time as this document is published as an RFC, implementations
-should use the value 2000 plus the revision number of this draft for
+SHOULD use the value 2000 plus the revision number of this draft for
 LDAP_API_VERSION.  For example, the correct value for LDAP_API_VERSION
-for revision 03 of this draft is 2003.
+for revision 04 of this draft is 2004.
 
 Documents that extend this specification SHOULD define a macro of the
 form:
@@ -536,13 +588,21 @@ tations to define a macro like this:
    #define LDAP_API_FEATURE_TLS 99999
 
 
-Private or experimental API extensions may be indicated by defining a
+Private or experimental API extensions SHOULD be indicated by defining a
 macro of this same form where "x" (the extension's name) begins with the
 string "X_" and "level" is replaced with a integer number that is
 specific to the extension.
 
+It is RECOMMENDED that private or experimental API extensions use only
+the following prefixes for macros, types, and function names:
+       LDAP_X_
+       LBER_X_
+       ldap_x_
+       ber_x_
+and that these prefixes not be used by standard extensions.
+
 
-8.2.  Retrieving Information During Execution
+9.2.  Retrieving Information During Execution
 
 The ldap_get_option() call (described in greater detail later in this
 document) can be used during execution in conjunction with an option
@@ -550,24 +610,24 @@ parameter value of LDAP_OPT_API_INFO (0x00) to retrieve some basic
 information about the API and about the specific implementation being
 used.  The ld parameter to ldap_get_option() can be either NULL or a
 valid LDAP session handle which was obtained by calling ldap_init().
-The optdata parameter to ldap_get_option() MUST be the address of an
+The optdata parameter to ldap_get_option() SHOULD be the address of an
 LDAPAPIInfo structure which is defined as follows:
 
    typedef struct ldapapiinfo {
        int  ldapai_info_version;     /* version of this struct (1) */
        int  ldapai_api_version;      /* revision of API supported */
-       int  ldapai_protocol_version; /* highest LDAP version supported */
-       char **ldapai_extensions;     /* names of API extensions */
-       char *ldapai_vendor_name;     /* name of supplier */
 
 
 
-Expires: 2 December 1999                                       [Page 10]
+Expires: 8 April 2000                                          [Page 11]
 
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
 
+       int  ldapai_protocol_version; /* highest LDAP version supported */
+       char **ldapai_extensions;     /* names of API extensions */
+       char *ldapai_vendor_name;     /* name of supplier */
        int  ldapai_vendor_version;   /* supplier-specific version times 100 */
    } LDAPAPIInfo;
 
@@ -577,7 +637,7 @@ ition:
    #define LDAP_API_INFO_VERSION    1
 
 Note that the ldapai_info_version field of the LDAPAPIInfo structure
-should be set to the value LDAP_API_INFO_VERSION (1) before calling
+SHOULD be set to the value LDAP_API_INFO_VERSION (1) before calling
 ldap_get_option() so that it can be checked for consistency.  All other
 fields are set by the ldap_get_option() function.
 
@@ -585,7 +645,7 @@ The members of the LDAPAPIInfo structure are:
 
 ldapai_info_version
           A number that identifies the version of the LDAPAPIInfo struc-
-          ture.  This should be set to the value LDAP_API_INFO_VERSION
+          ture.  This SHOULD be set to the value LDAP_API_INFO_VERSION
           (1) before calling ldap_get_option().  If the value received
           is not recognized by the API implementation, the
           ldap_get_option() function sets ldapai_info_version to a valid
@@ -595,7 +655,7 @@ ldapai_info_version
 
 ldapai_api_version
           A number that matches that assigned to the C LDAP API RFC sup-
-          ported by the API implementation.  This should match the value
+          ported by the API implementation.  This SHOULD match the value
           of the LDAP_API_VERSION macro defined earlier.
 
 ldapai_protocol_version
@@ -613,21 +673,22 @@ ldapai_extensions
           API extensions.  If no API extensions are supported, this
           field will be set to NULL.  The caller is responsible for
           disposing of the memory occupied by this array by passing it
-          to ldap_value_free() which is described later in this docu-
-          ment.  To retrieve more information about a particular exten-
-          sion, the ldap_get_option() call can be used with an option
 
 
 
-Expires: 2 December 1999                                       [Page 11]
+Expires: 8 April 2000                                          [Page 12]
 
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
 
+          to ldap_value_free() which is described later in this docu-
+          ment.  To retrieve more information about a particular exten-
+          sion, the ldap_get_option() call can be used with an option
           parameter value of LDAP_OPT_API_FEATURE_INFO (0x15).  The opt-
-          data parameter to the ldap_get_option() MUST be the address of
-          an LDAPAPIFeatureInfo structure which is defined as follows:
+          data parameter to the ldap_get_option() SHOULD be the address
+          of an LDAPAPIFeatureInfo structure which is defined as fol-
+          lows:
 
              typedef struct ldap_apifeature_info {
                  int   ldapaif_info_version; /* version of this struct (1) */
@@ -641,9 +702,9 @@ C LDAP API        C LDAP Application Program Interface       2 June 1999
              #define LDAP_FEATURE_INFO_VERSION    1
 
           Note that the ldapaif_info_version field of the LDAPAPI-
-          FeatureInfo structure should be set to the value
+          FeatureInfo structure SHOULD be set to the value
           LDAP_FEATURE_INFO_VERSION (1) and the ldapaif_name field
-          should be set to the extension name string as described below
+          SHOULD be set to the extension name string as described below
           before ldap_get_option() is called.  The call will fill in the
           ldapaif_version field of the LDAPAPIFeatureInfo structure.
 
@@ -651,7 +712,7 @@ C LDAP API        C LDAP Application Program Interface       2 June 1999
 
    ldapaif_info_version
              A number that identifies the version of the LDAPAPI-
-             FeatureInfo structure.  This should be set to the value
+             FeatureInfo structure.  This SHOULD be set to the value
              LDAP_FEATURE_INFO_VERSION (1) before calling
              ldap_get_option().  If the value received is not recognized
              by the API implementation, the ldap_get_option() function
@@ -669,24 +730,26 @@ C LDAP API        C LDAP Application Program Interface       2 June 1999
              ldap_get_option().  It is a number that matches that
              assigned to the C LDAP API extension RFC supported for this
              extension.  For private or experimental API extensions, the
-             value is extension-specific.  In either case, the value of
-             ldapaxi_ext_version should be identical to the value of the
-             LDAP_API_FEATURE_x macro defined for the extension
-             (described above).
 
 
 
-Expires: 2 December 1999                                       [Page 12]
+Expires: 8 April 2000                                          [Page 13]
+
 
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+
+             value is extension-specific.  In either case, the value of
+             ldapaxi_ext_version SHOULD be identical to the value of the
+             LDAP_API_FEATURE_x macro defined for the extension
+             (described above).
 
 
-9.  LDAP Error Codes
+10.  LDAP Error Codes
 
 Many of the LDAP API routines return LDAP error codes, some of which
-indicate local errors and some of which may be returned by servers.  All
-of the LDAP error codes returned will be positive integers.  Supported
+indicate local errors and some of which are returned by servers.  All of
+the LDAP error codes returned will be non-negative integers.  Supported
 error codes are (hexadecimal values are given in parentheses after the
 constant):
 
@@ -724,21 +787,21 @@ constant):
            LDAP_LOOP_DETECT (0x36)
            LDAP_NAMING_VIOLATION (0x40)
            LDAP_OBJECT_CLASS_VIOLATION (0x41)
-           LDAP_NOT_ALLOWED_ON_NONLEAF (0x42)
-           LDAP_NOT_ALLOWED_ON_RDN (0x43)
-           LDAP_ALREADY_EXISTS (0x44)
-           LDAP_NO_OBJECT_CLASS_MODS (0x45)
-           LDAP_RESULTS_TOO_LARGE (0x46)                   -- reserved for CLDAP
-           LDAP_AFFECTS_MULTIPLE_DSAS (0x47)               -- new in LDAPv3
 
 
 
-Expires: 2 December 1999                                       [Page 13]
+Expires: 8 April 2000                                          [Page 14]
 
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
 
+           LDAP_NOT_ALLOWED_ON_NONLEAF (0x42)
+           LDAP_NOT_ALLOWED_ON_RDN (0x43)
+           LDAP_ALREADY_EXISTS (0x44)
+           LDAP_NO_OBJECT_CLASS_MODS (0x45)
+           LDAP_RESULTS_TOO_LARGE (0x46)                   -- reserved for CLDAP
+           LDAP_AFFECTS_MULTIPLE_DSAS (0x47)               -- new in LDAPv3
            LDAP_OTHER (0x50)
            LDAP_SERVER_DOWN (0x51)
            LDAP_LOCAL_ERROR (0x52)
@@ -759,7 +822,7 @@ C LDAP API        C LDAP Application Program Interface       2 June 1999
            LDAP_REFERRAL_LIMIT_EXCEEDED (0x61)
 
 
-10.  Performing LDAP Operations
+11.  Performing LDAP Operations
 
 This section describes each LDAP operation API call in detail. All func-
 tions take a "session handle," a pointer to an LDAP structure containing
@@ -768,7 +831,7 @@ sage structure. These structures and others are described as needed
 below.
 
 
-10.1.  Initializing an LDAP Session
+11.1.  Initializing an LDAP Session
 
 ldap_init() initializes a session with an LDAP server. The server is not
 actually contacted until an operation is performed that requires it,
@@ -781,32 +844,33 @@ allowing various options to be set after initialization.
 
 Use of the following routine is deprecated:
 
-        LDAP *ldap_open(
-                const char      *hostname,
-                int             portno
-        );
-Unlike ldap_init(), ldap_open() attempts to make a server connection
-before returning to the caller.
 
 
 
-Expires: 2 December 1999                                       [Page 14]
+Expires: 8 April 2000                                          [Page 15]
+
 
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
 
+        LDAP *ldap_open(
+                const char      *hostname,
+                int             portno
+        );
+Unlike ldap_init(), ldap_open() attempts to make a server connection
+before returning to the caller.  A more complete description can be
+found in RFC 1823.
 
 Parameters are:
 
 hostname Contains a space-separated list of hostnames or dotted strings
          representing the IP address of hosts running an LDAP server to
-         connect to. Each hostname in the list can include an optional
-         port number which is separated from the host itself with a
-         colon (:) character.  The hosts will be tried in the order
-         listed, stopping with the first one to which a successful con-
-         nection is made.
+         connect to. Each hostname in the list MAY include a port number
+         which is separated from the host itself with a colon (:) char-
+         acter.  The hosts will be tried in the order listed, stopping
+         with the first one to which a successful connection is made.
 
-   Note: A suitable representation for including a literal IPv6[11]
+   Note: A suitable representation for including a literal IPv6[10]
    address in the hostname parameter is desired, but has not yet been
    determined or implemented in practice.
 
@@ -816,13 +880,13 @@ portno   Contains the TCP port number to connect to. The default LDAP
          ter is ignored.
 
 ldap_init() and ldap_open() both return a "session handle," a pointer to
-an opaque structure that should be passed to subsequent calls pertaining
+an opaque structure that MUST be passed to subsequent calls pertaining
 to the session. These routines return NULL if the session cannot be ini-
 tialized in which case the operating system error reporting mechanism
 can be checked to see why the call failed.
 
 Note that if you connect to an LDAPv2 server, one of the LDAP bind calls
-described below must be completed before other operations can be per-
+described below SHOULD be completed before other operations can be per-
 formed on the session.  LDAPv3 does not require that a bind operation be
 completed before other operations can be performed.
 
@@ -830,7 +894,7 @@ The calling program can set various attributes of the session by calling
 the routines described in the next section.
 
 
-10.2.  LDAP Session Handle Options
+11.2.  LDAP Session Handle Options
 
 The LDAP session handle returned by ldap_init() is a pointer to an
 opaque data type representing an LDAP session. In RFC 1823 this data
@@ -838,21 +902,20 @@ type was a structure exposed to the caller, and various fields in the
 structure could be set to control aspects of the session, such as size
 and time limits on searches.
 
-In the interest of insulating callers from inevitable changes to this
-structure, these aspects of the session are now accessed through a pair
-of accessor functions, described below.
-
-ldap_get_option() is used to access the current value of various
-session-wide parameters. ldap_set_option() is used to set the value of
 
 
+Expires: 8 April 2000                                          [Page 16]
 
-Expires: 2 December 1999                                       [Page 15]
 
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
 
+In the interest of insulating callers from inevitable changes to this
+structure, these aspects of the session are now accessed through a pair
+of accessor functions, described below.
 
+ldap_get_option() is used to access the current value of various
+session-wide parameters. ldap_set_option() is used to set the value of
 these parameters.  Note that some options are READ-ONLY and cannot be
 set; it is an error to call ldap_set_option() and attempt to set a
 READ-ONLY option.
@@ -886,7 +949,7 @@ ld     The session handle.  If this is NULL, a set of global defaults is
        defaults.
 
 option The name of the option being accessed or set. This parameter
-       should be one of the following constants, which have the indi-
+       SHOULD be one of the following constants, which have the indi-
        cated meanings.  After the constant the actual hexadecimal value
        of the constant is listed in parentheses.
 
@@ -896,248 +959,260 @@ option The name of the option being accessed or set. This parameter
 
       Type for outvalue parameter: LDAPAPIInfo *
 
+
+
+Expires: 8 April 2000                                          [Page 17]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
       Description:
            Used to retrieve some basic information about the LDAP API
            implementation at execution time.  See the section "Retriev-
            ing Information About the API Implementation" above for more
            information.  This option is READ-ONLY and cannot be set.
 
+   LDAP_OPT_DEREF (0x02)
+      Type for invalue parameter: int *
 
+      Type for outvalue parameter: int *
 
-Expires: 2 December 1999                                       [Page 16]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+      Description:
+           Determines how aliases are handled during search. It SHOULD
+           have one of the following values: LDAP_DEREF_NEVER (0x00),
+           LDAP_DEREF_SEARCHING (0x01), LDAP_DEREF_FINDING (0x02), or
+           LDAP_DEREF_ALWAYS (0x03).  The LDAP_DEREF_SEARCHING value
+           means aliases are dereferenced during the search but not when
+           locating the base object of the search. The
+           LDAP_DEREF_FINDING value means aliases are dereferenced when
+           locating the base object but not during the search.  The
+           default value for this option is LDAP_DEREF_NEVER.
 
+   LDAP_OPT_SIZELIMIT (0x03)
+      Type for invalue parameter: int *
 
-      LDAP_OPT_DESC (0x01)
-         Type for invalue parameter: not applicable (option is READ-
-         ONLY)
+      Type for outvalue parameter: int *
 
-         Type for outvalue parameter: int *
+      Description:
+           A limit on the number of entries to return from a search. A
+           value of LDAP_NO_LIMIT (0) means no limit.  The default value
+           for this option is LDAP_NO_LIMIT.
 
-         Description:
-              The underlying socket descriptor corresponding to the pri-
-              mary LDAP connection.  This option is READ-ONLY and cannot
-              be set.
+   LDAP_OPT_TIMELIMIT (0x04)
+      Type for invalue parameter: int *
 
-      LDAP_OPT_DEREF (0x02)
-         Type for invalue parameter: int *
+      Type for outvalue parameter: int *
 
-         Type for outvalue parameter: int *
+      Description:
+           A limit on the number of seconds to spend on a search. A
+           value of LDAP_NO_LIMIT (0) means no limit.  This value is
+           passed to the server in the search request only; it does not
+           affect how long the C LDAP API implementation itself will
+           wait locally for search results.  The timeout parameter
+           passed to ldap_search_ext_s() or ldap_result() -- both of
+           which are described later in this document -- can be used to
+           specify both a local and server side time limit.  The default
+           value for this option is LDAP_NO_LIMIT.
 
-         Description:
-              Determines how aliases are handled during search. It can
-              have one of the following values: LDAP_DEREF_NEVER (0x00),
-              LDAP_DEREF_SEARCHING (0x01), LDAP_DEREF_FINDING (0x02), or
-              LDAP_DEREF_ALWAYS (0x03).  The LDAP_DEREF_SEARCHING value
-              means aliases should be dereferenced during the search but
-              not when locating the base object of the search. The
-              LDAP_DEREF_FINDING value means aliases should be derefer-
-              enced when locating the base object but not during the
-              search.
 
-      LDAP_OPT_SIZELIMIT (0x03)
-         Type for invalue parameter: int *
 
-         Type for outvalue parameter: int *
 
-         Description:
-              A limit on the number of entries to return from a search.
-              A value of LDAP_NO_LIMIT (0) means no limit.
+Expires: 8 April 2000                                          [Page 18]
 
-      LDAP_OPT_TIMELIMIT (0x04)
-         Type for invalue parameter: int *
 
-         Type for outvalue parameter: int *
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-         Description:
-              A limit on the number of seconds to spend on a search. A
-              value of LDAP_NO_LIMIT (0) means no limit.  This value is
-              passed to the server in the search request only; it does
-              not affect how long the C LDAP API implementation itself
-              will wait locally for search results.  The timeout parame-
-              ter passed to ldap_search_ext_s() or ldap_result() -- both
 
+   LDAP_OPT_REFERRALS (0x08)
+      Type for invalue parameter: void * (LDAP_OPT_ON or LDAP_OPT_OFF)
 
+      Type for outvalue parameter: int *
 
-Expires: 2 December 1999                                       [Page 17]
+      Description:
+           Determines whether the LDAP library automatically follows
+           referrals returned by LDAP servers or not. It MAY be set to
+           one of the constants LDAP_OPT_ON or LDAP_OPT_OFF; any non-
+           NULL pointer value passed to ldap_set_option() enables this
+           option.  When reading the current setting using
+           ldap_get_option(), a zero value means OFF and any non-zero
+           value means ON.  By default, this option is ON.
 
+   LDAP_OPT_RESTART (0x09)
+      Type for invalue parameter: void * (LDAP_OPT_ON or LDAP_OPT_OFF)
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+      Type for outvalue parameter: int *
 
+      Description:
+           Determines whether LDAP I/O operations are automatically res-
+           tarted if they abort prematurely. It MAY be set to one of the
+           constants LDAP_OPT_ON or LDAP_OPT_OFF; any non-NULL pointer
+           value passed to ldap_set_option() enables this option.  When
+           reading the current setting using ldap_get_option(), a zero
+           value means OFF and any non-zero value means ON. This option
+           is useful if an LDAP I/O operation can be interrupted prema-
+           turely, for example by a timer going off, or other interrupt.
+           By default, this option is OFF.
 
-              of which are described later in this document -- can be
-              used to specify both a local and server side time limit.
+   LDAP_OPT_PROTOCOL_VERSION (0x11)
+      Type for invalue parameter: int *
 
-      LDAP_OPT_REFERRALS (0x08)
-         Type for invalue parameter: void * (LDAP_OPT_ON or
-         LDAP_OPT_OFF)
+      Type for outvalue parameter: int *
 
-         Type for outvalue parameter: int *
+      Description:
+           This option indicates the version of the LDAP protocol used
+           when communicating with the primary LDAP server. It SHOULD be
+           one of the constants LDAP_VERSION2 (2) or LDAP_VERSION3 (3).
+           If no version is set the default is LDAP_VERSION2 (2).
 
-         Description:
-              Determines whether the LDAP library automatically follows
-              referrals returned by LDAP servers or not. It can be set
-              to one of the constants LDAP_OPT_ON or LDAP_OPT_OFF; any
-              non-NULL pointer value passed to ldap_set_option() enables
-              this option.  When reading the current setting using
-              ldap_get_option(), a zero value means off and any non-zero
-              value means on.
+   LDAP_OPT_SERVER_CONTROLS (0x12)
+      Type for invalue parameter: LDAPControl **
 
-      LDAP_OPT_RESTART (0x09)
-         Type for invalue parameter: void * (LDAP_OPT_ON or
-         LDAP_OPT_OFF)
+      Type for outvalue parameter: LDAPControl ***
 
-         Type for outvalue parameter: int *
+      Description:
+           A default list of LDAP server controls to be sent with each
 
-         Description:
-              Determines whether LDAP I/O operations should automati-
-              cally be restarted if they abort prematurely. It should be
-              set to one of the constants LDAP_OPT_ON or LDAP_OPT_OFF;
-              any non-NULL pointer value passed to ldap_set_option()
-              enables this option.  When reading the current setting
-              using ldap_get_option(), a zero value means off and any
-              non-zero value means on. This option is useful if an LDAP
-              I/O operation may be interrupted prematurely, for example
-              by a timer going off, or other interrupt.
 
-      LDAP_OPT_PROTOCOL_VERSION (0x11)
-         Type for invalue parameter: int *
 
-         Type for outvalue parameter: int *
+Expires: 8 April 2000                                          [Page 19]
 
-         Description:
-              This option indicates the version of the LDAP protocol
-              used when communicating with the primary LDAP server. It
-              must be one of the constants LDAP_VERSION2 (2) or
-              LDAP_VERSION3 (3).  If no version is set the default is
-              LDAP_VERSION2 (2).
 
-      LDAP_OPT_SERVER_CONTROLS (0x12)
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
 
+           request.  See the Working With Controls section below.
 
-Expires: 2 December 1999                                       [Page 18]
+   LDAP_OPT_CLIENT_CONTROLS (0x13)
+      Type for invalue parameter: LDAPControl **
 
+      Type for outvalue parameter: LDAPControl ***
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+      Description:
+           A default list of client controls that affect the LDAP ses-
+           sion.  See the Working With Controls section below.
 
+   LDAP_OPT_API_FEATURE_INFO (0x15)
+      Type for invalue parameter: not applicable (option is READ-ONLY)
 
-         Type for invalue parameter: LDAPControl **
+      Type for outvalue parameter: LDAPAPIFeatureInfo *
 
-         Type for outvalue parameter: LDAPControl ***
+      Description:
+           Used to retrieve version information about LDAP API extended
+           features at execution time.  See the section "Retrieving
+           Information About the API Implementation" above for more
+           information.  This option is READ-ONLY and cannot be set.
 
-         Description:
-              A default list of LDAP server controls to be sent with
-              each request.  See the Working With Controls section
-              below.
+   LDAP_OPT_HOST_NAME (0x30)
+      Type for invalue parameter: char *
 
-      LDAP_OPT_CLIENT_CONTROLS (0x13)
-         Type for invalue parameter: LDAPControl **
+      Type for outvalue parameter: char **
 
-         Type for outvalue parameter: LDAPControl ***
+      Description:
+           The host name (or list of hosts) for the primary LDAP server.
+           See the definition of the hostname parameter to ldap_init()
+           for the allowed syntax.
 
-         Description:
-              A default list of client controls that affect the LDAP
-              session.  See the Working With Controls section below.
+   LDAP_OPT_ERROR_NUMBER (0x31)
+      Type for invalue parameter: int *
 
-      LDAP_OPT_API_FEATURE_INFO (0x15)
-         Type for invalue parameter: not applicable (option is READ-
-         ONLY)
+      Type for outvalue parameter: int *
 
-         Type for outvalue parameter: LDAPAPIFeatureInfo *
+      Description:
+           The code of the most recent LDAP error that occurred for this
+           session.
 
-         Description:
-              Used to retrieve version information about LDAP API
-              extended features at execution time.  See the section
-              "Retrieving Information About the API Implementation"
-              above for more information.  This option is READ-ONLY and
-              cannot be set.
+   LDAP_OPT_ERROR_STRING (0x32)
+      Type for invalue parameter: char *
 
-      LDAP_OPT_HOST_NAME (0x30)
-         Type for invalue parameter: char *
+      Type for outvalue parameter: char **
 
-         Type for outvalue parameter: char **
+      Description:
+           The message returned with the most recent LDAP error that
 
-         Description:
-              The host name (or list of hosts) for the primary LDAP
-              server.  See the definition of the hostname parameter to
-              ldap_init() for the allowed syntax.
 
-      LDAP_OPT_ERROR_NUMBER (0x31)
-         Type for invalue parameter: int *
 
-         Type for outvalue parameter: int *
+Expires: 8 April 2000                                          [Page 20]
 
-         Description:
-              The code of the most recent LDAP error that occurred for
 
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
 
-Expires: 2 December 1999                                       [Page 19]
+           occurred for this session.
 
+   LDAP_OPT_MATCHED_DN (0x33)
+      Type for invalue parameter: char *
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+      Type for outvalue parameter: char **
 
+      Description:
+           The matched DN value returned with the most recent LDAP error
+           that occurred for this session.
+
+
+outvalue The address of a place to put the value of the option. The
+         actual type of this parameter depends on the setting of the
+         option parameter.  For outvalues of type char ** and LDAPCon-
+         trol **, a copy of the data that is associated with the LDAP
+         session ld is returned; callers should dispose of the memory by
+         calling ldap_memfree() or ldap_controls_free(), depending on
+         the type of data returned.
+
+invalue  A pointer to the value the option is to be given. The actual
+         type of this parameter depends on the setting of the option
+         parameter. The data associated with invalue is copied by the
+         API implementation to allow callers of the API to dispose of or
+         otherwise change their copy of the data after a successful call
+         to ldap_set_option().  If a value passed for invalue is invalid
+         or cannot be accepted by the implementation, ldap_set_option()
+         should return -1 to indicate an error.
 
-              this session.
+Both ldap_get_option() and ldap_set_option() return 0 if successful and
+-1 if an error occurs.  If -1 is returned by either function, a specific
+error code MAY be retrieved by calling ldap_get_option() with an option
+value of LDAP_OPT_ERROR_NUMBER.  Note that there is no way to retrieve a
+more specific error code if a call to ldap_get_option() with an option
+value of LDAP_OPT_ERROR_NUMBER fails.
+
+When a call to ldap_get_option() succeeds, the API implementation MUST
+NOT change the state of the LDAP session handle or the state of the
+underlying implementation in a way that affects the behavior of future
+LDAP API calls.  When a call to ldap_get_option() fails, the only ses-
+sion handle change permitted is setting the LDAP error code (as returned
+by the LDAP_OPT_ERROR_NUMBER option).
+
+When a call to ldap_set_option() fails, it MUST NOT change the state of
+the LDAP session handle or the state of the underlying implementation in
+a way that affects the behavior of future LDAP API calls.
 
-      LDAP_OPT_ERROR_STRING (0x32)
-         Type for invalue parameter: char *
+Standards track documents that extend this specification and specify new
 
-         Type for outvalue parameter: char **
 
-         Description:
-              The message returned with the most recent LDAP error that
-              occurred for this session.
 
+Expires: 8 April 2000                                          [Page 21]
 
-   outvalue The address of a place to put the value of the option. The
-            actual type of this parameter depends on the setting of the
-            option parameter.  For outvalues of type char ** and LDAP-
-            Control **, a copy of the data that is associated with the
-            LDAP session ld is returned; callers should dispose of the
-            memory by calling ldap_memfree() or ldap_controls_free().
 
-   invalue  A pointer to the value the option is to be given. The actual
-            type of this parameter depends on the setting of the option
-            parameter. The data associated with invalue is copied by the
-            API implementation to allow callers of the API to dispose of
-            or otherwise change their copy of the data after a success-
-            ful call to ldap_set_option().  If a value passed for
-            invalue is invalid or cannot be accepted by the implementa-
-            tion, ldap_set_option() should return -1 to indicate an
-            error.
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-Both ldap_get_option() and ldap_set_option() return 0 if successful and
--1 if an error occurs.
 
-Standards track documents that extend this specification and specify new
-options MUST use values for option macros that are between 0x1000 and
-0x3FFF inclusive.  Private and experimental extensions MUST use values
+options SHOULD use values for option macros that are between 0x1000 and
+0x3FFF inclusive.  Private and experimental extensions SHOULD use values
 for the option macros that are between 0x4000 and 0x7FFF inclusive.  All
 values below 0x1000 and above 0x7FFF that are not defined in this docu-
-ment are reserved and MUST NOT be used.
+ment are reserved and SHOULD NOT be used.  The following macro MUST be
+defined by C LDAP API implementations to aid extension implementors:
+   #define LDAP_OPT_PRIVATE_EXTENSION_BASE 0x4000  /* to 0x7FFF inclusive */
+
 
 
-10.3.  Working With Controls
+11.3.  Working With Controls
 
 LDAPv3 operations can be extended through the use of controls.  Controls
-may be sent to a server or returned to the client with any LDAP message.
+can be sent to a server or returned to the client with any LDAP message.
 These controls are referred to as server controls.
 
 The LDAP API also supports a client-side extension mechanism through the
 use of client controls. These controls affect the behavior of the LDAP
-
-
-
-Expires: 2 December 1999                                       [Page 20]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
 API only and are never sent to a server.  A common data structure is
 used to represent both types of controls:
 
@@ -1145,7 +1220,7 @@ used to represent both types of controls:
                    char            *ldctl_oid;
                    struct berval   ldctl_value;
                    char            ldctl_iscritical;
-           } LDAPControl, *PLDAPControl;
+           } LDAPControl;
 
 The fields in the ldapcontrol structure have the following meanings:
 
@@ -1169,8 +1244,17 @@ Some LDAP API calls allocate an ldapcontrol structure or a NULL-
 terminated array of ldapcontrol structures.  The following routines can
 be used to dispose of a single control or an array of controls:
 
+
+
+Expires: 8 April 2000                                          [Page 22]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
            void ldap_control_free( LDAPControl *ctrl );
            void ldap_controls_free( LDAPControl **ctrls );
+If the ctrl or ctrls parameter is NULL, these calls do nothing.
 
 A set of controls that affect the entire session can be set using the
 ldap_set_option() function (see above).  A list of controls can also be
@@ -1181,21 +1265,14 @@ terminated array of pointers to ldapcontrol structures.
 
 Server controls are defined by LDAPv3 protocol extension documents; for
 example, a control has been proposed to support server-side sorting of
-search results [7].
+search results [11].
 
 One client control is defined in this document (described in the follow-
-ing section).  Other client controls may be defined in future revisions
+ing section).  Other client controls MAY be defined in future revisions
 of this document or in documents that extend this API.
 
 
-
-Expires: 2 December 1999                                       [Page 21]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
-10.3.1.  A Client Control That Governs Referral Processing
+11.3.1.  A Client Control That Governs Referral Processing
 
 As described previously in the section "LDAP Session Handle Options,"
 applications can enable and disable automatic chasing of referrals on a
@@ -1208,50 +1285,50 @@ ral chasing on per-request basis.  A client control with an OID of
    #define LDAP_CONTROL_REFERRALS              "1.2.840.113556.1.4.616"
 
    /* Flags for referrals client control value */
-   #define LDAP_CHASE_SUBORDINATE_REFERRALS    0x00000020
-   #define LDAP_CHASE_EXTERNAL_REFERRALS       0x00000040
+   #define LDAP_CHASE_SUBORDINATE_REFERRALS    0x00000020U
+   #define LDAP_CHASE_EXTERNAL_REFERRALS       0x00000040U
 
 To create a referrals client control, the ldctl_oid field of an LDAPCon-
-trol structure should be set to LDAP_CONTROL_REFERRALS
-("1.2.840.113556.1.4.616") and the ldctl_value field should be set to a
+trol structure MUST be set to LDAP_CONTROL_REFERRALS
+("1.2.840.113556.1.4.616") and the ldctl_value field MUST be set to a
 4-octet value that contains a set of flags.  The ldctl_value.bv_len
-field should always be set to 4.  The ldctl_value.bv_val field should
-point to a 4-octet integer flags value.  This flags value can be set to
-zero to disable automatic chasing of referrals and LDAPv3 references
-altogether.  Alternatively, the flags value can be set to the value
-LDAP_CHASE_SUBORDINATE_REFERRALS (0x00000020) to indicate that only
-LDAPv3 search continuation references should be automatically chased by
+field MUST always be set to 4.  The ldctl_value.bv_val field MUST point
+to a 4-octet integer flags value.  This flags value can be set to zero
+to disable automatic chasing of referrals and LDAPv3 references alto-
+gether.  Alternatively, the flags value can be set to the value
+LDAP_CHASE_SUBORDINATE_REFERRALS (0x00000020U) to indicate that only
+LDAPv3 search continuation references are to be automatically chased by
 the API implementation, to the value LDAP_CHASE_EXTERNAL_REFERRALS
-(0x00000040) to indicate that only LDAPv3 referrals should be automati-
-cally chased, or the logical OR of the two flag values (0x00000060) to
-indicate that both referrals and references should be automatically
-chased.
+(0x00000040U) to indicate that only LDAPv3 referrals are to be
 
 
-10.4.  Authenticating to the directory
 
-The following functions are used to authenticate an LDAP client to an
-LDAP directory server.
+Expires: 8 April 2000                                          [Page 23]
 
-The ldap_sasl_bind() and ldap_sasl_bind_s() functions can be used to do
-general and extensible authentication over LDAP through the use of the
-Simple Authentication Security Layer [8].  The routines both take the dn
-to bind as, the method to use, as a dotted-string representation of an
-OID identifying the method, and a struct berval holding the credentials.
-The special constant value LDAP_SASL_SIMPLE (NULL) can be passed to
-request simple authentication, or the simplified routines
-ldap_simple_bind() or ldap_simple_bind_s() can be used.
 
-           int ldap_sasl_bind(
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
 
+automatically chased, or the logical OR of the two flag values
+(0x00000060U) to indicate that both referrals and references are to be
+automatically chased.
 
-Expires: 2 December 1999                                       [Page 22]
 
+11.4.  Authenticating to the directory
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+The following functions are used to authenticate an LDAP client to an
+LDAP directory server.
 
+The ldap_sasl_bind() and ldap_sasl_bind_s() functions can be used to do
+general and extensible authentication over LDAP through the use of the
+Simple Authentication Security Layer [12].  The routines both take the
+dn to bind as, the method to use, as a dotted-string representation of
+an OID identifying the method, and a struct berval holding the creden-
+tials. The special constant value LDAP_SASL_SIMPLE (NULL) can be passed
+to request simple authentication, or the simplified routines
+ldap_simple_bind() or ldap_simple_bind_s() can be used.
 
+           int ldap_sasl_bind(
                    LDAP                    *ld,
                    const char              *dn,
                    const char              *mechanism,
@@ -1280,10 +1357,20 @@ C LDAP API        C LDAP Application Program Interface       2 June 1999
            int ldap_simple_bind_s(
                    LDAP                    *ld,
                    const char              *dn,
+
+
+
+Expires: 8 April 2000                                          [Page 24]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
                    const char              *passwd
            );
 
-   The use of the following routines is deprecated:
+   The use of the following routines is deprecated and more complete
+   descriptions can be found in RFC 1823:
 
            int ldap_bind( LDAP *ld, const char *dn, const char *cred,
                    int method );
@@ -1301,14 +1388,6 @@ ld           The session handle.
 
 dn           The name of the entry to bind as.
 
-
-
-Expires: 2 December 1999                                       [Page 23]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
 mechanism    Either LDAP_SASL_SIMPLE (NULL) to get simple authentica-
              tion, or a text string identifying the SASL method.
 
@@ -1330,12 +1409,20 @@ msgidp       This result parameter will be set to the message id of the
 servercredp  This result parameter will be filled in with the creden-
              tials passed back by the server for mutual authentication,
              if given. An allocated berval structure is returned that
-             should be disposed of by calling ber_bvfree().  NULL may be
-             passed to ignore this field.
+             SHOULD be disposed of by calling ber_bvfree().  NULL SHOULD
+             be passed to ignore this field.
 
 Additional parameters for the deprecated routines are not described.
 Interested readers are referred to RFC 1823.
 
+
+
+Expires: 8 April 2000                                          [Page 25]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
 The ldap_sasl_bind() function initiates an asynchronous bind operation
 and returns the constant LDAP_SUCCESS if the request was successfully
 sent, or another LDAP error code if not.  See the section below on error
@@ -1357,17 +1444,8 @@ LDAP_SUCCESS if the operation was successful, or another LDAP error code
 if it was not. See the section below on error handling for more informa-
 tion about possible errors and how to interpret them.
 
-
-
-
-Expires: 2 December 1999                                       [Page 24]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
 Note that if an LDAPv2 server is contacted, no other operations over the
-connection should be attempted before a bind call has successfully com-
+connection can be attempted before a bind call has successfully com-
 pleted.
 
 Subsequent bind calls can be used to re-authenticate over the same con-
@@ -1375,7 +1453,7 @@ nection, and multistep SASL sequences can be accomplished through a
 sequence of calls to ldap_sasl_bind() or ldap_sasl_bind_s().
 
 
-10.5.  Closing the session
+11.5.  Closing the session
 
 The following functions are used to unbind from the directory, close
 open connections, and dispose of the session handle.
@@ -1393,6 +1471,15 @@ ld           The session handle.
 
 serverctrls  List of LDAP server controls.
 
+
+
+
+Expires: 8 April 2000                                          [Page 26]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
 clientctrls  List of client controls.
 
 The ldap_unbind_ext(), ldap_unbind() and ldap_unbind_s() all work syn-
@@ -1414,16 +1501,7 @@ trol sent with an unbind request.
 
 
 
-
-
-
-Expires: 2 December 1999                                       [Page 25]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
-10.6.  Searching
+11.6.  Searching
 
 The following functions are used to search the LDAP directory, returning
 a requested set of attributes for each entry matched.  There are five
@@ -1450,6 +1528,15 @@ variations.
                    const char      *filter,
                    char            **attrs,
                    int             attrsonly,
+
+
+
+Expires: 8 April 2000                                          [Page 27]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
                    LDAPControl     **serverctrls,
                    LDAPControl     **clientctrls,
                    struct timeval  *timeout,
@@ -1471,15 +1558,6 @@ variations.
                    const char      *base,
                    int             scope,
                    const char      *filter,
-
-
-
-Expires: 2 December 1999                                       [Page 26]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
                    char            **attrs,
                    int             attrsonly,
                    LDAPMessage     **res
@@ -1506,61 +1584,80 @@ scope        One of LDAP_SCOPE_BASE (0x00), LDAP_SCOPE_ONELEVEL (0x01),
              or LDAP_SCOPE_SUBTREE (0x02), indicating the scope of the
              search.
 
-filter       A character string as described in [3], representing the
+filter       A character string as described in [13], representing the
+
+
+
+Expires: 8 April 2000                                          [Page 28]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
              search filter.  The value NULL can be passed to indicate
              that the filter "(objectclass=*)" which matches all entries
-             should be used.  Note that if the caller of the API is
-             using LDAPv2, only a subset of the filter functionality
-             described in [3] can be successfully used.
+             is to be used.  Note that if the caller of the API is using
+             LDAPv2, only a subset of the filter functionality described
+             in [13] can be successfully used.
 
 attrs        A NULL-terminated array of strings indicating which attri-
              butes to return for each matching entry. Passing NULL for
              this parameter causes all available user attributes to be
              retrieved.  The special constant string LDAP_NO_ATTRS
-             ("1.1") can be used as the only string in the array to
-             indicate that no attribute types should be returned by the
+             ("1.1") MAY be used as the only string in the array to
+             indicate that no attribute types are to be returned by the
              server.  The special constant string LDAP_ALL_USER_ATTRS
              ("*") can be used in the attrs array along with the names
              of some operational attributes to indicate that all user
-             attributes plus the listed operational attributes should be
+             attributes plus the listed operational attributes are to be
              returned.
 
-attrsonly    A boolean value that should be zero if both attribute types
-             and values are to be returned, non-zero if only types are
-             wanted.
-
-
-
-Expires: 2 December 1999                                       [Page 27]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
+attrsonly    A boolean value that MUST be zero if both attribute types
+             and values are to be returned, and non-zero if only types
+             are wanted.
 
 timeout      For the ldap_search_st() function, this specifies the local
              search timeout value (if it is NULL, the timeout is infin-
-             ite).  For the ldap_search_ext() and ldap_search_ext_s()
-             functions, this specifies both the local search timeout
-             value and the operation time limit that is sent to the
-             server within the search request.  For the
-             ldap_search_ext() and ldap_search_ext_s() functions, pass-
-             ing a NULL value for timeout causes the global default
-             timeout stored in the LDAP session handle (set by using
+             ite).  If a zero timeout (where tv_sec and tv_usec are both
+             zero) is passed, API implementations SHOULD return
+             LDAP_PARAM_ERROR.
+
+             For the ldap_search_ext() and ldap_search_ext_s() func-
+             tions, the timeout parameter specifies both the local
+             search timeout value and the operation time limit that is
+             sent to the server within the search request.  Passing a
+             NULL value for timeout causes the global default timeout
+             stored in the LDAP session handle (set by using
              ldap_set_option() with the LDAP_OPT_TIMELIMIT parameter) to
              be sent to the server with the request but an infinite
-             local search timeout to be used.
+             local search timeout to be used.  If a zero timeout (where
+             tv_sec and tv_usec are both zero) is passed in, API imple-
+             mentations SHOULD return LDAP_PARAM_ERROR.  If a zero value
+             for tv_sec is used but tv_usec is non-zero, an operation
+             time limit of 1 SHOULD be passed to the LDAP server as the
+             operation time limit.  For other values of tv_sec, the
+             tv_sec value itself SHOULD be passed to the LDAP server.
 
 sizelimit    For the ldap_search_ext() and ldap_search_ext_s() calls,
              this is a limit on the number of entries to return from the
              search.  A value of LDAP_NO_LIMIT (0) means no limit.
 
-res          For the synchronous calls, this is a result parameter which
-             will contain the results of the search upon completion of
-             the call.  If no results are returned, *res is set to NULL.
 
-serverctrls  List of LDAP server controls.
 
-clientctrls  List of client controls.
+
+Expires: 8 April 2000                                          [Page 29]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
+res          For the synchronous calls, this is a result parameter which
+             will contain the results of the search upon completion of
+             the call.  If no results are returned, *res is set to NULL.
+
+serverctrls  List of LDAP server controls.
+
+clientctrls  List of client controls.
 
 msgidp       This result parameter will be set to the message id of the
              request if the ldap_search_ext() call succeeds.
@@ -1583,20 +1680,11 @@ LDAP_OPT_TIMELIMIT
 LDAP_OPT_DEREF
              One of LDAP_DEREF_NEVER (0x00), LDAP_DEREF_SEARCHING
              (0x01), LDAP_DEREF_FINDING (0x02), or LDAP_DEREF_ALWAYS
-             (0x03), specifying how aliases should be handled during the
-             search. The LDAP_DEREF_SEARCHING value means aliases should
-
-
-
-Expires: 2 December 1999                                       [Page 28]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
-             be dereferenced during the search but not when locating the
+             (0x03), specifying how aliases are handled during the
+             search. The LDAP_DEREF_SEARCHING value means aliases are
+             dereferenced during the search but not when locating the
              base object of the search. The LDAP_DEREF_FINDING value
-             means aliases should be dereferenced when locating the base
+             means aliases are dereferenced when locating the base
              object but not during the search.
 
 The ldap_search_ext() function initiates an asynchronous search opera-
@@ -1610,8 +1698,17 @@ can be parsed using the result parsing routines described in detail
 later.
 
 Similar to ldap_search_ext(), the ldap_search() function initiates an
-asynchronous search operation and returns the message id of the opera-
-tion initiated.  As for ldap_search_ext(), a subsequent call to
+asynchronous search operation and returns the message id of the
+
+
+
+Expires: 8 April 2000                                          [Page 30]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
+operation initiated.  As for ldap_search_ext(), a subsequent call to
 ldap_result(), described below, can be used to obtain the result of the
 bind. In case of error, ldap_search() will return -1, setting the ses-
 sion error parameters in the LDAP structure appropriately.
@@ -1623,8 +1720,8 @@ another LDAP error code if it was not. See the section below on error
 handling for more information about possible errors and how to interpret
 them.  Entries returned from the search (if any) are contained in the
 res parameter. This parameter is opaque to the caller.  Entries, attri-
-butes, values, etc., should be extracted by calling the parsing routines
-described below. The results contained in res should be freed when no
+butes, values, etc., can be extracted by calling the parsing routines
+described below. The results contained in res SHOULD be freed when no
 longer in use by calling ldap_msgfree(), described later.
 
 The ldap_search_ext() and ldap_search_ext_s() functions support LDAPv3
@@ -1637,24 +1734,15 @@ tion will wait for a search to complete.  After the local search timeout
 expires, the API implementation will send an abandon operation to abort
 the search operation.
 
-10.7.  Reading an Entry
+11.7.  Reading an Entry
 
 LDAP does not support a read operation directly. Instead, this operation
 is emulated by a search with base set to the DN of the entry to read,
 scope set to LDAP_SCOPE_BASE, and filter set to "(objectclass=*)" or
-
-
-
-Expires: 2 December 1999                                       [Page 29]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
 NULL. attrs contains the list of attributes to return.
 
 
-10.8.  Listing the Children of an Entry
+11.8.  Listing the Children of an Entry
 
 LDAP does not support a list operation directly. Instead, this operation
 is emulated by a search with base set to the DN of the entry to list,
@@ -1662,52 +1750,53 @@ scope set to LDAP_SCOPE_ONELEVEL, and filter set to "(objectclass=*)" or
 NULL. attrs contains the list of attributes to return for each child
 entry.
 
-10.9.  Comparing a Value Against an Entry
+11.9.  Comparing a Value Against an Entry
 
 The following routines are used to compare a given attribute value
 assertion against an LDAP entry.  There are four variations:
 
            int ldap_compare_ext(
-                   LDAP            *ld,
-                   const char      *dn,
-                   const char      *attr,
-                   struct berval   *bvalue
-                   LDAPControl     **serverctrls,
-                   LDAPControl     **clientctrls,
-                   int             *msgidp
+
+
+
+Expires: 8 April 2000                                          [Page 31]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
+                   LDAP                    *ld,
+                   const char              *dn,
+                   const char              *attr,
+                   const struct berval     *bvalue,
+                   LDAPControl             **serverctrls,
+                   LDAPControl             **clientctrls,
+                   int                     *msgidp
            );
 
            int ldap_compare_ext_s(
-                   LDAP            *ld,
-                   const char      *dn,
-                   const char      *attr,
-                   struct berval   *bvalue,
-                   LDAPControl     **serverctrls,
-                   LDAPControl     **clientctrls
+                   LDAP                    *ld,
+                   const char              *dn,
+                   const char              *attr,
+                   const struct berval     *bvalue,
+                   LDAPControl             **serverctrls,
+                   LDAPControl             **clientctrls
            );
 
            int ldap_compare(
-                   LDAP            *ld,
-                   const char      *dn,
-                   const char      *attr,
-                   const char      *value
+                   LDAP                    *ld,
+                   const char              *dn,
+                   const char              *attr,
+                   const char              *value
            );
 
            int ldap_compare_s(
-                   LDAP            *ld,
-                   const char      *dn,
-                   const char      *attr,
-                   const char      *value
+                   LDAP                    *ld,
+                   const char              *dn,
+                   const char              *attr,
+                   const char              *value
            );
 
-
-
-Expires: 2 December 1999                                       [Page 30]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
 Parameters are:
 
 ld           The session handle.
@@ -1724,6 +1813,15 @@ bvalue       The attribute value to compare against those found in the
 value        A string attribute value to compare against, used by the
              ldap_compare() and ldap_compare_s() functions.  Use
              ldap_compare_ext() or ldap_compare_ext_s() if you need to
+
+
+
+Expires: 8 April 2000                                          [Page 32]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
              compare binary values.
 
 serverctrls  List of LDAP server controls.
@@ -1758,14 +1856,7 @@ The ldap_compare_ext() and ldap_compare_ext_s() functions support LDAPv3
 server controls and client controls.
 
 
-
-Expires: 2 December 1999                                       [Page 31]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
-10.10.  Modifying an entry
+11.10.  Modifying an entry
 
 The following routines are used to modify an existing LDAP entry.  There
 are four variations:
@@ -1773,12 +1864,21 @@ are four variations:
            typedef struct ldapmod {
                    int             mod_op;
                    char            *mod_type;
-                   union {
+                   union mod_vals_u {
                            char            **modv_strvals;
                            struct berval   **modv_bvals;
                    } mod_vals;
            } LDAPMod;
            #define mod_values      mod_vals.modv_strvals
+
+
+
+Expires: 8 April 2000                                          [Page 33]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
            #define mod_bvalues     mod_vals.modv_bvals
 
            int ldap_modify_ext(
@@ -1814,14 +1914,6 @@ Parameters are:
 
 ld           The session handle.
 
-
-
-Expires: 2 December 1999                                       [Page 32]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
 dn           The name of the entry to modify.
 
 mods         A NULL-terminated array of modifications to make to the
@@ -1836,7 +1928,15 @@ msgidp       This result parameter will be set to the message id of the
 
 The fields in the LDAPMod structure have the following meanings:
 
-mod_op       The modification operation to perform. It should be one of
+
+
+Expires: 8 April 2000                                          [Page 34]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
+mod_op       The modification operation to perform. It MUST be one of
              LDAP_MOD_ADD (0x00), LDAP_MOD_DELETE (0x01), or
              LDAP_MOD_REPLACE (0x02).  This field also indicates the
              type of values included in the mod_vals union. It is logi-
@@ -1846,7 +1946,7 @@ mod_op       The modification operation to perform. It should be one of
 mod_type     The type of the attribute to modify.
 
 mod_vals     The values (if any) to add, delete, or replace. Only one of
-             the mod_values or mod_bvalues variants should be used,
+             the mod_values or mod_bvalues variants can be used,
              selected by ORing the mod_op field with the constant
              LDAP_MOD_BVALUES. mod_values is a NULL-terminated array of
              zero-terminated strings and mod_bvalues is a NULL-
@@ -1858,7 +1958,7 @@ entry, creating the attribute if necessary.
 
 For LDAP_MOD_DELETE modifications, the given values are deleted from the
 entry, removing the attribute if no values remain. If the entire attri-
-bute is to  be deleted, the mod_vals field should be set to NULL.
+bute is to be deleted, the mod_vals field can be set to NULL.
 
 For LDAP_MOD_REPLACE modifications, the attribute will have the listed
 values after the modification, having been created if necessary, or
@@ -1870,15 +1970,6 @@ tion and returns the constant LDAP_SUCCESS if the request was success-
 fully sent, or another LDAP error code if not.  See the section below on
 error handling for more information about possible errors and how to
 interpret them.  If successful, ldap_modify_ext() places the message id
-
-
-
-Expires: 2 December 1999                                       [Page 33]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
 of the request in *msgidp. A subsequent call to ldap_result(), described
 below, can be used to obtain the result of the modify.
 
@@ -1892,14 +1983,23 @@ sion error parameters in the LDAP structure appropriately.
 The synchronous ldap_modify_ext_s() and ldap_modify_s() functions both
 return the result of the operation, either the constant LDAP_SUCCESS if
 the operation was successful, or another LDAP error code if it was not.
-See the section below on error handling for more information about pos-
-sible errors and how to interpret them.
+See the section below on error handling for more information about
+
+
+
+Expires: 8 April 2000                                          [Page 35]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
+possible errors and how to interpret them.
 
 The ldap_modify_ext() and ldap_modify_ext_s() functions support LDAPv3
 server controls and client controls.
 
 
-10.11.  Modifying the Name of an Entry
+11.11.  Modifying the Name of an Entry
 
 In LDAPv2, the ldap_modrdn(), ldap_modrdn_s(), ldap_modrdn2(), and
 ldap_modrdn2_s() routines were used to change the name of an LDAP entry.
@@ -1927,21 +2027,13 @@ cated.
                    const char      *dn,
                    const char      *newrdn,
                    const char      *newparent,
-
-
-
-Expires: 2 December 1999                                       [Page 34]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
                    int             deleteoldrdn,
                    LDAPControl     **serverctrls,
                    LDAPControl     **clientctrls
            );
 
-   Use of the following routines is deprecated.
+   The use of the following routines is deprecated and more complete
+   descriptions can be found in RFC 1823:
 
            int ldap_modrdn(
                    LDAP            *ld,
@@ -1949,6 +2041,15 @@ C LDAP API        C LDAP Application Program Interface       2 June 1999
                    const char      *newrdn
            );
            int ldap_modrdn_s(
+
+
+
+Expires: 8 April 2000                                          [Page 36]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
                    LDAP            *ld,
                    const char      *dn,
                    const char      *newrdn
@@ -1976,26 +2077,16 @@ newrdn       The new RDN to give the entry.
 
 newparent    The new parent, or superior entry.  If this parameter is
              NULL, only the RDN of the entry is changed.  The root DN
-             may be specified by passing a zero length string, "".  The
-             newparent parameter should always be NULL when using ver-
-             sion 2 of the LDAP protocol; otherwise the server's
+             SHOULD be specified by passing a zero length string, "".
+             The newparent parameter SHOULD always be NULL when using
+             version 2 of the LDAP protocol; otherwise the server's
              behavior is undefined.
 
 deleteoldrdn This parameter only has meaning on the rename routines if
              newrdn is different than the old RDN. It is a boolean
-             value, if non-zero indicating that the old RDN value(s)
-
-
-
-Expires: 2 December 1999                                       [Page 35]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
-             should be removed, if zero indicating that the old RDN
-             value(s) should be retained as non-distinguished values of
-             the entry.
+             value, if non-zero indicating that the old RDN value(s) is
+             to be removed, if zero indicating that the old RDN value(s)
+             is to be retained as non-distinguished values of the entry.
 
 serverctrls  List of LDAP server controls.
 
@@ -2007,6 +2098,15 @@ msgidp       This result parameter will be set to the message id of the
 The ldap_rename() function initiates an asynchronous modify DN operation
 and returns the constant LDAP_SUCCESS if the request was successfully
 sent, or another LDAP error code if not.  See the section below on error
+
+
+
+Expires: 8 April 2000                                          [Page 37]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
 handling for more information about possible errors and how to interpret
 them.  If successful, ldap_rename() places the DN message id of the
 request in *msgidp. A subsequent call to ldap_result(), described below,
@@ -2022,7 +2122,7 @@ The ldap_rename() and ldap_rename_s() functions both support LDAPv3
 server controls and client controls.
 
 
-10.12.  Adding an entry
+11.12.  Adding an entry
 
 The following functions are used to add entries to the LDAP directory.
 There are four variations:
@@ -2041,15 +2141,6 @@ There are four variations:
                    const char      *dn,
                    LDAPMod         **attrs,
                    LDAPControl     **serverctrls,
-
-
-
-Expires: 2 December 1999                                       [Page 36]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
                    LDAPControl     **clientctrls
            );
 
@@ -2065,6 +2156,14 @@ C LDAP API        C LDAP Application Program Interface       2 June 1999
                    LDAPMod         **attrs
            );
 
+
+
+Expires: 8 April 2000                                          [Page 38]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
 Parameters are:
 
 ld           The session handle.
@@ -2073,7 +2172,7 @@ dn           The name of the entry to add.
 
 attrs        The entry's attributes, specified using the LDAPMod struc-
              ture defined for ldap_modify(). The mod_type and mod_vals
-             fields should be filled in.  The mod_op field is ignored
+             fields MUST be filled in.  The mod_op field is ignored
              unless ORed with the constant LDAP_MOD_BVALUES, used to
              select the mod_bvalues case of the mod_vals union.
 
@@ -2098,15 +2197,6 @@ can be used to obtain the result of the add.
 Similar to ldap_add_ext(), the ldap_add() function initiates an asyn-
 chronous add operation and returns the message id of the operation ini-
 tiated.  As for ldap_add_ext(), a subsequent call to ldap_result(),
-
-
-
-Expires: 2 December 1999                                       [Page 37]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
 described below, can be used to obtain the result of the add. In case of
 error, ldap_add() will return -1, setting the session error parameters
 in the LDAP structure appropriately.
@@ -2122,7 +2212,16 @@ controls and client controls.
 
 
 
-10.13.  Deleting an entry
+
+
+
+Expires: 8 April 2000                                          [Page 39]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
+11.13.  Deleting an entry
 
 The following functions are used to delete a leaf entry from the LDAP
 directory.  There are four variations:
@@ -2156,14 +2255,6 @@ Parameters are:
 
 ld           The session handle.
 
-
-
-Expires: 2 December 1999                                       [Page 38]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
 dn           The name of the entry to delete.
 
 serverctrls  List of LDAP server controls.
@@ -2177,13 +2268,22 @@ Note that the entry to delete must be a leaf entry (i.e., it must have
 no children). Deletion of entire subtrees in a single operation is not
 supported by LDAP.
 
-The ldap_delete_ext() function initiates an asynchronous delete opera-
-tion and returns the constant LDAP_SUCCESS if the request was success-
-fully sent, or another LDAP error code if not.  See the section below on
-error handling for more information about possible errors and how to
-interpret them.  If successful, ldap_delete_ext() places the message id
-of the request in *msgidp. A subsequent call to ldap_result(), described
-below, can be used to obtain the result of the delete.
+The ldap_delete_ext() function initiates an asynchronous delete
+
+
+
+Expires: 8 April 2000                                          [Page 40]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
+operation and returns the constant LDAP_SUCCESS if the request was suc-
+cessfully sent, or another LDAP error code if not.  See the section
+below on error handling for more information about possible errors and
+how to interpret them.  If successful, ldap_delete_ext() places the mes-
+sage id of the request in *msgidp. A subsequent call to ldap_result(),
+described below, can be used to obtain the result of the delete.
 
 Similar to ldap_delete_ext(), the ldap_delete() function initiates an
 asynchronous delete operation and returns the message id of the opera-
@@ -2202,39 +2302,38 @@ The ldap_delete_ext() and ldap_delete_ext_s() functions support LDAPv3
 server controls and client controls.
 
 
-10.14.  Extended Operations
+11.14.  Extended Operations
 
 The ldap_extended_operation() and ldap_extended_operation_s() routines
 allow extended LDAP operations to be passed to the server, providing a
 general protocol extensibility mechanism.
 
            int ldap_extended_operation(
-                   LDAP            *ld,
-                   const char      *requestoid,
-                   struct berval   *requestdata,
+                   LDAP                    *ld,
+                   const char              *requestoid,
+                   const struct berval     *requestdata,
+                   LDAPControl             **serverctrls,
+                   LDAPControl             **clientctrls,
+                   int                     *msgidp
+           );
 
+           int ldap_extended_operation_s(
+                   LDAP                    *ld,
+                   const char              *requestoid,
+                   const struct berval     *requestdata,
+                   LDAPControl             **serverctrls,
+                   LDAPControl             **clientctrls,
+                   char                    **retoidp,
+                   struct berval           **retdatap
+           );
 
 
-Expires: 2 December 1999                                       [Page 39]
 
+Expires: 8 April 2000                                          [Page 41]
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
 
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-                   LDAPControl     **serverctrls,
-                   LDAPControl     **clientctrls,
-                   int             *msgidp
-           );
-
-           int ldap_extended_operation_s(
-                   LDAP            *ld,
-                   const char      *requestoid,
-                   struct berval   *requestdata,
-                   LDAPControl     **serverctrls,
-                   LDAPControl     **clientctrls,
-                   char            **retoidp,
-                   struct berval   **retdatap
-           );
 
 Parameters are:
 
@@ -2242,7 +2341,7 @@ ld           The session handle.
 
 requestoid   The dotted-OID text string naming the request.
 
-requestdata  The arbitrary data required by the operation (if NULL, no
+requestdata  The arbitrary data needed by the operation (if NULL, no
              data is sent to the server).
 
 serverctrls  List of LDAP server controls.
@@ -2254,12 +2353,12 @@ msgidp       This result parameter will be set to the message id of the
 
 retoidp      Pointer to a character string that will be set to an allo-
              cated, dotted-OID text string returned by the server.  This
-             string should be disposed of using the ldap_memfree() func-
+             string SHOULD be disposed of using the ldap_memfree() func-
              tion.  If no OID was returned, *retoidp is set to NULL.
 
 retdatap     Pointer to a berval structure pointer that will be set an
              allocated copy of the data returned by the server.  This
-             struct berval should be disposed of using ber_bvfree().  If
+             struct berval SHOULD be disposed of using ber_bvfree().  If
              no data is returned, *retdatap is set to NULL.
 
 The ldap_extended_operation() function initiates an asynchronous
@@ -2269,15 +2368,6 @@ tion below on error handling for more information about possible errors
 and how to interpret them.  If successful, ldap_extended_operation()
 places the message id of the request in *msgidp. A subsequent call to
 ldap_result(), described below, can be used to obtain the result of the
-
-
-
-Expires: 2 December 1999                                       [Page 40]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
 extended operation which can be passed to ldap_parse_extended_result()
 to obtain the OID and data contained in the response.
 
@@ -2293,7 +2383,16 @@ The ldap_extended_operation() and ldap_extended_operation_s() functions
 both support LDAPv3 server controls and client controls.
 
 
-11.  Abandoning An Operation
+
+
+
+Expires: 8 April 2000                                          [Page 42]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
+12.  Abandoning An Operation
 
 The following calls are used to abandon an operation in progress:
 
@@ -2327,28 +2426,29 @@ ldap_abandon() is identical to ldap_abandon_ext() except that it does
 not accept client or server controls and it returns zero if the abandon
 was successful, -1 otherwise.
 
-
-
-Expires: 2 December 1999                                       [Page 41]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
 After a successful call to ldap_abandon() or ldap_abandon_ext(), results
 with the given message id are never returned from a subsequent call to
 ldap_result().  There is no server response to LDAP abandon operations.
 
 
-12.  Obtaining Results and Peeking Inside LDAP Messages
+13.  Obtaining Results and Peeking Inside LDAP Messages
 
 ldap_result() is used to obtain the result of a previous asynchronously
 initiated operation. Note that depending on how it is called,
-ldap_result() may actually return a list or "chain" of result messages.
+ldap_result() can actually return a list or "chain" of result messages.
 The ldap_result() function only returns messages for a single request,
 so for all LDAP operations other than search only one result message is
-expected; that is, the only time the "result chain" may contain more
+expected; that is, the only time the "result chain" can contain more
 than one message is if results from a search operation are returned.
+
+
+
+Expires: 8 April 2000                                          [Page 43]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
 Once a chain of messages has been returned to the caller, it is no
 longer tied in any caller-visible way to the LDAP request that produced
 it.  Therefore, a chain of messages returned by calling ldap_result() or
@@ -2382,17 +2482,9 @@ Parameters are:
 ld       The session handle.
 
 msgid    The message id of the operation whose results are to be
-         returned, or the constant LDAP_RES_ANY (-1) if any result is
-
-
-
-Expires: 2 December 1999                                       [Page 42]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
-         desired.
+         returned, the constant LDAP_RES_UNSOLICITED (0) if an unsoli-
+         cited result is desired, or or the constant LDAP_RES_ANY (-1)
+         if any result is desired.
 
 all      Specifies how many messages will be retrieved in a single call
          to ldap_result().  This parameter only has meaning for search
@@ -2400,11 +2492,20 @@ all      Specifies how many messages will be retrieved in a single call
          message at a time.  Pass LDAP_MSG_ALL (0x01) to request that
          all results of a search be received before returning all
          results in a single chain.  Pass LDAP_MSG_RECEIVED (0x02) to
-         indicate that all messages retrieved so far should be returned
+         indicate that all messages retrieved so far are to be returned
          in the result chain.
 
 timeout  A timeout specifying how long to wait for results to be
          returned.  A NULL value causes ldap_result() to block until
+
+
+
+Expires: 8 April 2000                                          [Page 44]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
          results are available.  A timeout value of zero seconds speci-
          fies a polling behavior.
 
@@ -2434,28 +2535,19 @@ ldap_result() returns 0 if the timeout expired and -1 if an error
 occurs, in which case the error parameters of the LDAP session handle
 will be set accordingly.
 
-ldap_msgfree() frees the result structure pointed to by res and returns
-the type of the message it freed.  If res is NULL, nothing is done and
-the value zero is returned.
+ldap_msgfree() frees each message in the result chain pointed to by res
+and returns the type of the last message in the chain.  If res is NULL,
+nothing is done and the value zero is returned.
 
 ldap_msgtype() returns the type of the LDAP message it is passed as a
 parameter. The type will be one of the types listed above, or -1 on
-
-
-
-Expires: 2 December 1999                                       [Page 43]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
 error.
 
 ldap_msgid() returns the message ID associated with the LDAP message
-passed as a parameter.
+passed as a parameter, or -1 on error.
 
 
-13.  Handling Errors and Parsing Results
+14.  Handling Errors and Parsing Results
 
 The following calls are used to extract information from results and
 handle errors returned by other LDAP API routines.  Note that
@@ -2463,6 +2555,14 @@ ldap_parse_sasl_bind_result() and ldap_parse_extended_result() must typ-
 ically be used in addition to ldap_parse_result() to retrieve all the
 result information from SASL Bind and Extended Operations respectively.
 
+
+
+Expires: 8 April 2000                                          [Page 45]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
            int ldap_parse_result(
                    LDAP            *ld,
                    LDAPMessage     *res,
@@ -2489,23 +2589,17 @@ result information from SASL Bind and Extended Operations respectively.
                    int             freeit
            );
 
+           #define LDAP_NOTICE_OF_DISCONNECTION    "1.3.6.1.4.1.1466.20036"
+
            char *ldap_err2string( int err );
 
-   The use of the following routines is deprecated.
+   The use of the following routines is deprecated and more complete
+   descriptions can be found in RFC 1823:
 
            int ldap_result2error(
                    LDAP            *ld,
                    LDAPMessage     *res,
                    int             freeit
-
-
-
-Expires: 2 December 1999                                       [Page 44]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
            );
 
            void ldap_perror( LDAP *ld, const char *msg );
@@ -2518,34 +2612,43 @@ res          The result of an LDAP operation as returned by
              ldap_result() or one of the synchronous API operation
              calls.
 
+
+
+Expires: 8 April 2000                                          [Page 46]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
 errcodep     This result parameter will be filled in with the LDAP error
              code field from the LDAPMessage message.  This is the indi-
              cation from the server of the outcome of the operation.
-             NULL may be passed to ignore this field.
+             NULL SHOULD be passed to ignore this field.
 
 matcheddnp   In the case of a return of LDAP_NO_SUCH_OBJECT, this result
              parameter will be filled in with a DN indicating how much
-             of the name in the request was recognized. NULL may be
-             passed to ignore this field.  The matched DN string should
+             of the name in the request was recognized. NULL SHOULD be
+             passed to ignore this field.  The matched DN string SHOULD
              be freed by calling ldap_memfree() which is described later
              in this document.
 
 errmsgp      This result parameter will be filled in with the contents
              of the error message field from the LDAPMessage message.
-             The error message string should be freed by calling
+             The error message string SHOULD be freed by calling
              ldap_memfree() which is described later in this document.
-             NULL may be passed to ignore this field.
+             NULL SHOULD be passed to ignore this field.
 
 referralsp   This result parameter will be filled in with the contents
              of the referrals field from the LDAPMessage message, indi-
              cating zero or more alternate LDAP servers where the
-             request should be retried.  The referrals array should be
+             request is to be retried.  The referrals array SHOULD be
              freed by calling ldap_value_free() which is described later
-             in this document.  NULL may be passed to ignore this field.
+             in this document.  NULL SHOULD be passed to ignore this
+             field.
 
 serverctrlsp This result parameter will be filled in with an allocated
              array of controls copied out of the LDAPMessage message.
-             The control array should be freed by calling
+             The control array SHOULD be freed by calling
              ldap_controls_free() which was described earlier.
 
 freeit       A boolean that determines whether the res parameter is
@@ -2554,34 +2657,38 @@ freeit       A boolean that determines whether the res parameter is
              tion.  This is provided as a convenience; you can also use
              ldap_msgfree() to free the result later.  If freeit is
              non-zero, the entire chain of messages represented by res
+             is disposed of.
 
+servercredp  For SASL bind results, this result parameter will be filled
+             in with the credentials passed back by the server for
+             mutual authentication, if given. An allocated berval struc-
+             ture is returned that SHOULD be disposed of by calling
+             ber_bvfree().  NULL SHOULD be passed to ignore this field.
 
+retoidp      For extended results, this result parameter will be filled
+             in with the dotted-OID text representation of the name of
+             the extended operation response.  This string SHOULD be
 
-Expires: 2 December 1999                                       [Page 45]
 
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+Expires: 8 April 2000                                          [Page 47]
 
 
-             is disposed of.
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-servercredp  For SASL bind results, this result parameter will be filled
-             in with the credentials passed back by the server for
-             mutual authentication, if given. An allocated berval struc-
-             ture is returned that should be disposed of by calling
-             ber_bvfree().  NULL may be passed to ignore this field.
 
-retoidp      For extended results, this result parameter will be filled
-             in with the dotted-OID text representation of the name of
-             the extended operation response.  This string should be
-             disposed of by calling ldap_memfree().  NULL may be passed
-             to ignore this field.
+             disposed of by calling ldap_memfree().  NULL SHOULD be
+             passed to ignore this field.  The
+             LDAP_NOTICE_OF_DISCONNECTION macro is defined as a conveni-
+             ence for clients that wish to check an OID to see if it
+             matches the one used for the unsolicited Notice of Discon-
+             nection (defined in RFC 2251[2] section 4.4.1).
 
 retdatap     For extended results, this result parameter will be filled
              in with a pointer to a struct berval containing the data in
-             the extended operation response.  It should be disposed of
-             by calling ber_bvfree(). NULL may be passed to ignore this
-             field.
+             the extended operation response.  It SHOULD be disposed of
+             by calling ber_bvfree(). NULL SHOULD be passed to ignore
+             this field.
 
 err          For ldap_err2string(), an LDAP error code, as returned by
              ldap_parse_result() or another LDAP API call.
@@ -2589,43 +2696,43 @@ err          For ldap_err2string(), an LDAP error code, as returned by
 Additional parameters for the deprecated routines are not described.
 Interested readers are referred to RFC 1823.
 
-All three of the ldap_parse_*_result() routines skip over messages of
-type LDAP_RES_SEARCH_ENTRY and LDAP_RES_SEARCH_REFERENCE when looking
-for a result message to parse.  They return the constant LDAP_SUCCESS if
-the result was successfully parsed and another LDAP error code if not.
-Note that the LDAP error code that indicates the outcome of the opera-
-tion performed by the server is placed in the errcodep
-ldap_parse_result() parameter.  If a chain of messages that contains
-more than one result message is passed to these routines they always
-operate on the first result in the chain.
+The ldap_parse_result(), ldap_parse_sasl_bind_result(), and
+ldap_parse_extended_result() functions all skip over messages of type
+LDAP_RES_SEARCH_ENTRY and LDAP_RES_SEARCH_REFERENCE when looking for a
+result message to parse.  They return the constant LDAP_SUCCESS if the
+result was successfully parsed and another LDAP error code if not.  Note
+that the LDAP error code that indicates the outcome of the operation
+performed by the server is placed in the errcodep ldap_parse_result()
+parameter.  If a chain of messages that contains more than one result
+message is passed to these routines they always operate on the first
+result in the chain.
 
 ldap_err2string() is used to convert a numeric LDAP error code, as
-returned by one of the three ldap_parse_*_result() routines, or one of
-the synchronous API operation calls, into an informative zero-terminated
-character string message describing the error.  It returns a pointer to
-static data.
+returned by ldap_parse_result(), ldap_parse_sasl_bind_result(),
+ldap_parse_extended_result() or one of the synchronous API operation
+calls, into an informative zero-terminated character string message
+describing the error.  It returns a pointer to static data.
 
 
-14.  Stepping Through a List of Results
+15.  Stepping Through a List of Results
 
 The ldap_first_message() and ldap_next_message() routines are used to
 step through the list of messages in a result chain returned by
-ldap_result().  For search operations, the result chain may actually
-
+ldap_result().  For search operations, the result chain can actually
+include referral messages, entry messages, and result messages.
+ldap_count_messages() is used to count the number of messages returned.
+The ldap_msgtype() function, described above, can be used to distinguish
+between the different message types.
 
+           LDAPMessage *ldap_first_message( LDAP *ld, LDAPMessage *res );
 
-Expires: 2 December 1999                                       [Page 46]
 
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+Expires: 8 April 2000                                          [Page 48]
 
 
-include referral messages, entry messages, and result messages.
-ldap_count_messages() is used to count the number of messages returned.
-The ldap_msgtype() function, described above, can be used to distinguish
-between the different message types.
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-           LDAPMessage *ldap_first_message( LDAP *ld, LDAPMessage *res );
 
            LDAPMessage *ldap_next_message( LDAP *ld, LDAPMessage *msg );
 
@@ -2647,44 +2754,43 @@ returned if an error occurs while stepping through the entries, in which
 case the error parameters in the session handle ld will be set to indi-
 cate the error.
 
-ldap_count_messages() returns the number of messages contained in a
-chain of results. It can also be used to count the number of messages
-that remain in a chain if called with a message, entry, or reference
-returned by ldap_first_message(), ldap_next_message(),
-ldap_first_entry(), ldap_next_entry(), ldap_first_reference(),
-ldap_next_reference().
+If successful, ldap_count_messages() returns the number of messages con-
+tained in a chain of results; if an error occurs such as the res parame-
+ter being invalid, -1 is returned.  The ldap_count_messages() call can
+also be used to count the number of messages that remain in a chain if
+called with a message, entry, or reference returned by
+ldap_first_message(), ldap_next_message(), ldap_first_entry(),
+ldap_next_entry(), ldap_first_reference(), ldap_next_reference().
 
 
-15.  Parsing Search Results
+16.  Parsing Search Results
 
 The following calls are used to parse the entries and references
 returned by ldap_search() and friends. These results are returned in an
-opaque structure that should only be accessed by calling the routines
-described below. Routines are provided to step through the entries and
-references returned, step through the attributes of an entry, retrieve
-the name of an entry, and retrieve the values associated with a given
-attribute in an entry.
-
-
+opaque structure that MAY be accessed by calling the routines described
+below. Routines are provided to step through the entries and references
+returned, step through the attributes of an entry, retrieve the name of
+an entry, and retrieve the values associated with a given attribute in
+an entry.
 
 
+16.1.  Stepping Through a List of Entries or References
 
+The ldap_first_entry() and ldap_next_entry() routines are used to step
+through and retrieve the list of entries from a search result chain.
+The ldap_first_reference() and ldap_next_reference() routines are used
+to step through and retrieve the list of continuation references from a
+search result chain.  ldap_count_entries() is used to count the number
+of entries returned. ldap_count_references() is used to count the number
 
 
-Expires: 2 December 1999                                       [Page 47]
 
+Expires: 8 April 2000                                          [Page 49]
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
 
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-15.1.  Stepping Through a List of Entries or References
 
-The ldap_first_entry() and ldap_next_entry() routines are used to step
-through and retrieve the list of entries from a search result chain.
-The ldap_first_reference() and ldap_next_reference() routines are used
-to step through and retrieve the list of continuation references from a
-search result chain.  ldap_count_entries() is used to count the number
-of entries returned. ldap_count_references() is used to count the number
 of references returned.
 
            LDAPMessage *ldap_first_entry( LDAP *ld, LDAPMessage *res );
@@ -2720,26 +2826,29 @@ case the error parameters in the session handle ld will be set to indi-
 cate the error.
 
 ldap_count_entries() returns the number of entries contained in a chain
-of entries. It can also be used to count the number of entries that
-remain in a chain if called with a message, entry or reference returned
-by ldap_first_message(), ldap_next_message(), ldap_first_entry(),
-ldap_next_entry(), ldap_first_reference(), ldap_next_reference().
+of entries; if an error occurs such as the res parameter being invalid,
+-1 is returned.  The ldap_count_entries() call can also be used to count
+the number of entries that remain in a chain if called with a message,
+entry or reference returned by ldap_first_message(),
+ldap_next_message(), ldap_first_entry(), ldap_next_entry(),
+ldap_first_reference(), ldap_next_reference().
 
+ldap_count_references() returns the number of references contained in a
+chain of search results; if an error occurs such as the res parameter
+being invalid, -1 is returned.  The ldap_count_references() call can
+also be used to count the number of references that remain in a chain.
 
 
 
-Expires: 2 December 1999                                       [Page 48]
 
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+Expires: 8 April 2000                                          [Page 50]
 
 
-ldap_count_references() returns the number of references contained in a
-chain of search results. It can also be used to count the number of
-references that remain in a chain.
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
 
-15.2.  Stepping Through the Attributes of an Entry
+16.2.  Stepping Through the Attributes of an Entry
 
 The ldap_first_attribute() and ldap_next_attribute() calls are used to
 step through the list of attribute types returned with an entry.
@@ -2775,41 +2884,40 @@ ptr    In ldap_first_attribute(), the address of a pointer used inter-
 mem    A pointer to memory allocated by the LDAP library, such as the
        attribute type names returned by ldap_first_attribute() and
        ldap_next_attribute, or the DN returned by ldap_get_dn().  If mem
-       is NULL, nothing is done.
+       is NULL, the ldap_memfree() call does nothing.
 
 ldap_first_attribute() and ldap_next_attribute() will return NULL when
 the end of the attributes is reached, or if there is an error, in which
 case the error parameters in the session handle ld will be set to indi-
 cate the error.
 
+Both routines return a pointer to an allocated buffer containing the
+current attribute name. This SHOULD be freed when no longer in use by
+calling ldap_memfree().
 
+ldap_first_attribute() will allocate and return in ptr a pointer to a
 
 
-Expires: 2 December 1999                                       [Page 49]
 
+Expires: 8 April 2000                                          [Page 51]
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
 
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-Both routines return a pointer to an allocated buffer containing the
-current attribute name. This should be freed when no longer in use by
-calling ldap_memfree().
 
-ldap_first_attribute() will allocate and return in ptr a pointer to a
-BerElement used to keep track of the current position. This pointer
-should be passed in subsequent calls to ldap_next_attribute() to step
-through the entry's attributes. After a set of calls to
-ldap_first_attribute() and ldap_next_attribute(), if ptr is non-NULL, it
-should be freed by calling ber_free( ptr, 0 ). Note that it is very
-important to pass the second parameter as 0 (zero) in this call, since
-the buffer associated with the BerElement does not point to separately
-allocated memory.
+BerElement used to keep track of the current position. This pointer MAY
+be passed in subsequent calls to ldap_next_attribute() to step through
+the entry's attributes. After a set of calls to ldap_first_attribute()
+and ldap_next_attribute(), if ptr is non-NULL, it SHOULD be freed by
+calling ber_free( ptr, 0 ). Note that it is very important to pass the
+second parameter as 0 (zero) in this call, since the buffer associated
+with the BerElement does not point to separately allocated memory.
 
 The attribute type names returned are suitable for passing in a call to
 ldap_get_values() and friends to retrieve the associated values.
 
 
-15.3.  Retrieving the Values of an Attribute
+16.3.  Retrieving the Values of an Attribute
 
 ldap_get_values() and ldap_get_values_len() are used to retrieve the
 values of a given attribute from an entry. ldap_count_values() and
@@ -2840,19 +2948,20 @@ Parameters are:
 
 ld     The session handle.
 
+entry  The entry from which to retrieve values, as returned by
+       ldap_first_entry() or ldap_next_entry().
 
+attr   The attribute whose values are to be retrieved, as returned by
+       ldap_first_attribute() or ldap_next_attribute(), or a caller-
 
-Expires: 2 December 1999                                       [Page 50]
 
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+Expires: 8 April 2000                                          [Page 52]
 
 
-entry  The entry from which to retrieve values, as returned by
-       ldap_first_entry() or ldap_next_entry().
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
 
-attr   The attribute whose values are to be retrieved, as returned by
-       ldap_first_attribute() or ldap_next_attribute(), or a caller-
        supplied string (e.g., "mail").
 
 vals   The values returned by a previous call to ldap_get_values() or
@@ -2868,12 +2977,15 @@ found for attr or if an error occurs.
 ldap_count_values() and ldap_count_values_len() return -1 if an error
 occurs such as the vals parameter being invalid.
 
-Note that the values returned are dynamically allocated and should be
+If a NULL vals parameter is passed to ldap_value_free() or
+ldap_value_free_len(), nothing is done.
+
+Note that the values returned are dynamically allocated and SHOULD be
 freed by calling either ldap_value_free() or ldap_value_free_len() when
 no longer in use.
 
 
-15.4.  Retrieving the name of an entry
+16.4.  Retrieving the name of an entry
 
 ldap_get_dn() is used to retrieve the name of an entry.
 ldap_explode_dn() and ldap_explode_rdn() are used to break up a name
@@ -2897,45 +3009,46 @@ entry   The entry whose name is to be retrieved, as returned by
 
 dn      The dn to explode, such as returned by ldap_get_dn().
 
+rdn     The rdn to explode, such as returned in the components of the
+
 
 
-Expires: 2 December 1999                                       [Page 51]
+Expires: 8 April 2000                                          [Page 53]
 
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
 
-rdn     The rdn to explode, such as returned in the components of the
         array returned by ldap_explode_dn().
 
 notypes A boolean parameter, if non-zero indicating that the dn or rdn
-        components should have their type information stripped off
+        components are to have their type information stripped off
         (i.e., "cn=Babs" would become "Babs").
 
 ldap_get_dn() will return NULL if there is some error parsing the dn,
 setting error parameters in the session handle ld to indicate the error.
-It returns a pointer to newly allocated space that the caller should
+It returns a pointer to newly allocated space that the caller SHOULD
 free by calling ldap_memfree() when it is no longer in use.  Note the
-format of the DNs returned is given by [4].
+format of the DNs returned is given by [5].
 
 ldap_explode_dn() returns a NULL-terminated char * array containing the
 RDN components of the DN supplied, with or without types as indicated by
 the notypes parameter. The components are returned in the order they
-appear in the dn.  The array returned should be freed when it is no
+appear in the dn.  The array returned SHOULD be freed when it is no
 longer in use by calling ldap_value_free().
 
 ldap_explode_rdn() returns a NULL-terminated char * array containing the
 components of the RDN supplied, with or without types as indicated by
 the notypes parameter. The components are returned in the order they
-appear in the rdn.  The array returned should be freed when it is no
+appear in the rdn.  The array returned SHOULD be freed when it is no
 longer in use by calling ldap_value_free().
 
 ldap_dn2ufn() converts the DN into the user friendly format described in
-[5]. The UFN returned is newly allocated space that should be freed by a
-call to ldap_memfree() when no longer in use.
+[14]. The UFN returned is newly allocated space that SHOULD be freed by
+call to ldap_memfree() when no longer in use.
 
 
-15.5.  Retrieving controls from an entry
+16.5.  Retrieving controls from an entry
 
 ldap_get_entry_controls() is used to extract LDAP controls from an
 entry.
@@ -2956,15 +3069,16 @@ entry        The entry to extract controls from, as returned by
 
 
 
-Expires: 2 December 1999                                       [Page 52]
 
+Expires: 8 April 2000                                          [Page 54]
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
 
 serverctrlsp This result parameter will be filled in with an allocated
              array of controls copied out of entry. The control array
-             should be freed by calling ldap_controls_free().  If ser-
+             SHOULD be freed by calling ldap_controls_free().  If ser-
              verctrlsp is NULL, no controls are returned.
 
 ldap_get_entry_controls() returns an LDAP error code that indicates
@@ -2973,7 +3087,7 @@ goes well).
 
 
 
-15.6.  Parsing References
+16.6.  Parsing References
 
 ldap_parse_reference() is used to extract referrals and controls from a
 SearchResultReference message.
@@ -2997,13 +3111,13 @@ ref          The reference to parse, as returned by ldap_result(),
 referralsp   This result parameter will be filled in with an allocated
              array of character strings.  The elements of the array are
              the referrals (typically LDAP URLs) contained in ref.  The
-             array should be freed when no longer in used by calling
+             array SHOULD be freed when no longer in used by calling
              ldap_value_free().  If referralsp is NULL, the referral
              URLs are not returned.
 
 serverctrlsp This result parameter will be filled in with an allocated
              array of controls copied out of ref. The control array
-             should be freed by calling ldap_controls_free().  If ser-
+             SHOULD be freed by calling ldap_controls_free().  If ser-
              verctrlsp is NULL, no controls are returned.
 
 freeit       A boolean that determines whether the ref parameter is
@@ -3013,10 +3127,10 @@ freeit       A boolean that determines whether the ref parameter is
 
 
 
-Expires: 2 December 1999                                       [Page 53]
+Expires: 8 April 2000                                          [Page 55]
 
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
 
              ldap_msgfree() to free the result later.
@@ -3026,9 +3140,9 @@ the reference could be successfully parsed (LDAP_SUCCESS if all goes
 well).
 
 
-16.  Encoded ASN.1 Value Manipulation
+17.  Encoded ASN.1 Value Manipulation
 
-This section describes routines which may be used to encode and decode
+This section describes routines which MAY be used to encode and decode
 BER-encoded ASN.1 values, which are often used inside of control and
 extension values.
 
@@ -3036,19 +3150,74 @@ With the exceptions of two new functions ber_flatten() and ber_init(),
 these functions are compatible with the University of Michigan LDAP 3.3
 implementation of BER.
 
+Note that the functions defined in this section all provide a method for
+determining success or failure but generally do not provide access to
+specific error codes.  Therefore, applications that require precise
+error information when encoding or decoding ASN.1 values SHOULD NOT use
+these functions.
+
+
+17.1.  BER Data Structures and Types
+
+The following additional integral types are defined for use in manipula-
+tion of BER encoded ASN.1 values:
+           typedef impl_tag_t ber_tag_t;   /* for BER tags */
+
+           typedef impl_int_t ber_int_t;   /* for BER ints, enums, and Booleans */
+
+           typedef impl_unit_t ber_uint_t; /* unsigned equivalent of ber_int_t */
+
+           typedef impl_slen_t ber_slen_t; /* signed equivalent of ber_len_t */
+
+Note that the actual definition for these four integral types is imple-
+mentation specific; that is, `impl_tag_t', `impl_int_t', `impl_uint_t',
+and `impl_slen_t' MUST each be replaced with an appropriate
+implementation-specific type.
+
+The `ber_tag_t' type is an unsigned integral data type that is large
+enough to hold the largest BER tag supported by the API implementation.
+The width (number of significant bits) of `ber_tag_t' MUST be at least
+32, greater than or equal to that of `unsigned int' (so that integer
+promotions won't promote it to `int'), and no wider than that of
+`unsigned long'.
+
+
+
+
+Expires: 8 April 2000                                          [Page 56]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
 
-16.1.  General
+The `ber_int_t' and `ber_uint_t' types are the signed and unsigned vari-
+ants of an integral type that is large enough to hold integers for pur-
+poses of BER encoding and decoding.  The width of `ber_int_t' MUST be at
+least 32 and no larger than that of `long'.  The width (number of signi-
+ficant bits) of `ber_uint_t' MUST be at least 32 and no larger than that
+of `unsigned long'.  Note that the `ber_uint_t' type is not used
+directly in the C LDAP API but is provided for the convenience of appli-
+cation developers and for use by extensions to the API.
 
-           struct berval {
+The `ber_slen_t' type is the signed variant of the `ber_len_t' integral
+type that is large enough to contain the length of the largest piece of
+data supported by the API implementation.  The `impl_slen_t' in the
+`ber_len_t' typedef MUST be replaced with an appropriate type.  The
+width of `ber_slen_t' MUST be at least 32 and no larger than that of
+`unsigned long'.  Note that `ber_slen_t' is not used directly in the C
+LDAP API but is provided for the convenience of application developers
+and for use by extensions to the API.
+
+           typedef struct berval {
                    ber_len_t       bv_len;
                    char            *bv_val;
-           };
+           } BerValue;
 
-As defined earlier in the section "Common Data Structures", a struct
-berval contains an arbitrary sequence of bytes and an indication of its
-length.  The bv_len element is an unsigned integer.  The bv_val is not
-necessarily zero-terminated.  Applications may allocate their own berval
-structures.
+As defined earlier in the section "Common Data Structures", a berval
+structure contains an arbitrary sequence of bytes and an indication of
+its length.  The bv_len element is an unsigned integer.  The bv_val is
+not necessarily zero-terminated.  Applications MAY allocate their own
+berval structures.
 
 As defined earlier in the section "Common Data Structures", the BerEle-
 ment structure is an opaque structure:
@@ -3058,56 +3227,60 @@ ment structure is an opaque structure:
 It contains not only a copy of the encoded value, but also state infor-
 mation used in encoding or decoding.  Applications cannot allocate their
 own BerElement structures.  The internal state is neither thread-
-specific nor locked, so two threads should not manipulate the same
+specific nor locked, so two threads SHOULD NOT manipulate the same
 BerElement value simultaneously.
 
 A single BerElement value cannot be used for both encoding and decoding.
 
+17.2.  Memory Disposal and Utility Functions
+
            void ber_bvfree( struct berval *bv );
 
-ber_bvfree() frees a berval returned from this API.  Both the bv->bv_val
-string and the berval itself are freed.  Applications should not use
+ber_bvfree() frees a berval structure returned from this API.  Both the
+bv->bv_val string and the berval structure itself are freed.  If bv is
 
 
 
-Expires: 2 December 1999                                       [Page 54]
+Expires: 8 April 2000                                          [Page 57]
 
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
 
-ber_bvfree() with bervals which the application has allocated.
+NULL, this call does nothing.
 
            void ber_bvecfree( struct berval **bv );
 
-ber_bvecfree() frees an array of bervals returned from this API.  Each
-of the bervals in the array are freed using ber_bvfree(), then the array
-itself is freed.
+ber_bvecfree() frees an array of berval structures returned from this
+API.  Each of the berval structures in the array are freed using
+ber_bvfree(), then the array itself is freed.  If bv is NULL, this call
+does nothing.
 
            struct berval *ber_bvdup( const struct berval *bv );
 
-ber_bvdup() returns a copy of a berval.  The bv_val field in the
-returned berval points to a different area of memory than the bv_val
-field in the argument berval.  The NULL pointer is returned on error
-(e.g. out of memory).
+ber_bvdup() returns a copy of a berval structure.  The bv_val field in
+the returned berval structure points to a different area of memory than
+the bv_val field in the bv argument.  The NULL pointer is returned on
+error (e.g. out of memory).
 
            void ber_free( BerElement *ber, int fbuf );
 
 ber_free() frees a BerElement which is returned from the API calls
-ber_alloc_t() or ber_init().  Each BerElement must be freed by the
-caller.  The second argument fbuf should always be set to 1 to ensure
+ber_alloc_t() or ber_init().  Each BerElement SHOULD be freed by the
+caller.  The second argument fbuf SHOULD always be set to 1 to ensure
 that the internal buffer used by the BER functions is freed as well as
-the BerElement container itself.
+the BerElement container itself.  If ber is NULL, this call does noth-
+ing.
 
 
-16.2.  Encoding
+17.3.  Encoding
 
            BerElement *ber_alloc_t( int options );
 
 ber_alloc_t() constructs and returns BerElement.  The NULL pointer is
 returned on error.  The options field contains a bitwise-or of options
 which are to be used when generating the encoding of this BerElement.
-One option is defined and must always be supplied:
+One option is defined and SHOULD always be supplied:
 
            #define LBER_USE_DER 0x01
 
@@ -3122,16 +3295,16 @@ put as defined in X.509 and X.680 can be produced.
 Unrecognized option bits are ignored.
 
 The BerElement returned by ber_alloc_t() is initially empty.  Calls to
-ber_printf() will append bytes to the end of the ber_alloc_t().
 
 
 
+Expires: 8 April 2000                                          [Page 58]
 
-Expires: 2 December 1999                                       [Page 55]
 
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
 
+ber_printf() will append bytes to the end of the ber_alloc_t().
 
            int ber_printf( BerElement *ber, const char *fmt, ... )
 
@@ -3139,113 +3312,116 @@ The ber_printf() routine is used to encode a BER element in much the
 same way that sprintf() works.  One important difference, though, is
 that state information is kept in the ber argument so that multiple
 calls can be made to ber_printf() to append to the end of the BER ele-
-ment. ber must be a pointer to a BerElement returned by ber_alloc_t().
+ment. ber MUST be a pointer to a BerElement returned by ber_alloc_t().
 ber_printf() interprets and formats its arguments according to the for-
 mat string fmt.  ber_printf() returns -1 if there is an error during
-encoding and a positive number if successful.  As with sprintf(), each
-character in fmt refers to an argument to ber_printf().
+encoding and a non-negative number if successful.  As with sprintf(),
+each character in fmt refers to an argument to ber_printf().
 
 The format string can contain the following format characters:
 
 't'     Tag.  The next argument is a ber_tag_t specifying the tag to
         override the next element to be written to the ber.  This works
-        across calls.  The integer tag value must contain the tag class,
-        constructed bit, and tag value.  For example, a tag of "[3]" for
-        a constructed type is 0xA3.  All implementations must support
-        tags that fit in a single octet (i.e., where the tag value is
-        less than 32) and they may support larger tags.
-
-'b'     Boolean.  The next argument is an int, containing either 0 for
-        FALSE or 0xff for TRUE.  A boolean element is output.  If this
-        format character is not preceded by the 't' format modifier, the
-        tag 0x01 is used for the element.
-
-'i'     Integer.  The next argument is an int, containing the integer in
-        the host's byte order.  An integer element is output. If this
-        format character is not preceded by the 't' format modifier, the
-        tag 0x02 is used for the element.
-
-'X'     Bitstring.  The next two arguments are a char * pointer to the
-        start of the bitstring, followed by an int containing the number
-        of bits in the bitstring.  A bitstring element is output, in
-        primitive form.  If this format character is not preceded by the
-        't' format modifier, the tag 0x03 is used for the element.
-
-'n'     Null.  No argument is required.  An ASN.1 NULL element is out-
-        put.  If this format character is not preceded by the 't' format
-        modifier, the tag 0x05 is used for the element.
+        across calls.  The integer tag value SHOULD contain the tag
+        class, constructed bit, and tag value.  For example, a tag of
+        "[3]" for a constructed type is 0xA3U.  All implementations MUST
+        support tags that fit in a single octet (i.e., where the tag
+        value is less than 32) and they MAY support larger tags.
 
-'o'     Octet string.  The next two arguments are a char *, followed by
-        an int with the length of the string.  The string may contain
-        null bytes and need not be zero-terminated.   An octet string
-        element is output, in primitive form.  If this format character
-        is not preceded by the 't' format modifier, the tag 0x04 is used
-        for the element.
+'b'     Boolean.  The next argument is an ber_int_t, containing either 0
+        for FALSE or 0xff for TRUE.  A boolean element is output.  If
+        this format character is not preceded by the 't' format modif-
+        ier, the tag 0x01U is used for the element.
+
+'e'     Enumerated.  The next argument is a ber_int_t, containing the
+        enumerated value in the host's byte order.  An enumerated ele-
+        ment is output.  If this format character is not preceded by the
+        't' format modifier, the tag 0x0AU is used for the element.
+
+'i'     Integer.  The next argument is a ber_int_t, containing the
+        integer in the host's byte order.  An integer element is output.
+        If this format character is not preceded by the 't' format
+        modifier, the tag 0x02U is used for the element.
+
+'B'     Bitstring.  The next two arguments are a char * pointer to the
+        start of the bitstring, followed by a ber_len_t containing the
+        number of bits in the bitstring.  A bitstring element is output,
+        in primitive form.  If this format character is not preceded by
+        the 't' format modifier, the tag 0x03U is used for the element.
 
+'n'     Null.  No argument is needed.  An ASN.1 NULL element is output.
+        If this format character is not preceded by the 't' format
+        modifier, the tag 0x05U is used for the element.
 
 
-Expires: 2 December 1999                                       [Page 56]
 
+Expires: 8 April 2000                                          [Page 59]
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
 
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
+'o'     Octet string.  The next two arguments are a char *, followed by
+        a ber_len_t with the length of the string.  The string MAY con-
+        tain null bytes and are do not have to be zero-terminated.   An
+        octet string element is output, in primitive form.  If this for-
+        mat character is not preceded by the 't' format modifier, the
+        tag 0x04U is used for the element.
 
 's'     Octet string.  The next argument is a char * pointing to a
         zero-terminated string.  An octet string element in primitive
         form is output, which does not include the trailing '\0' (null)
         byte. If this format character is not preceded by the 't' format
-        modifier, the tag 0x04 is used for the element.
+        modifier, the tag 0x04U is used for the element.
 
 'v'     Several octet strings.  The next argument is a char **, an array
         of char * pointers to zero-terminated strings.  The last element
-        in the array must be a NULL pointer. The octet strings do not
+        in the array MUST be a NULL pointer. The octet strings do not
         include the trailing '\0' (null) byte.  Note that a construct
-        like '{v}' is required to get an actual SEQUENCE OF octet
-        strings.  The 't' format modifier cannot be used with this for-
-        mat character.
+        like '{v}' is used to get an actual SEQUENCE OF octet strings.
+        The 't' format modifier cannot be used with this format charac-
+        ter.
 
-'V'     Several octet strings.  A NULL-terminated array of berval *'s is
-        supplied. Note that a construct like '{V}' is required to get an
-        actual SEQUENCE OF octet strings. The 't' format modifier cannot
-        be used with this format character.
+'V'     Several octet strings.  A NULL-terminated array of struct berval
+        *'s is supplied.  Note that a construct like '{V}' is used to
+        get an actual SEQUENCE OF octet strings. The 't' format modifier
+        cannot be used with this format character.
 
-'{'     Begin sequence.  No argument is required.  If this format char-
-        acter is not preceded by the 't' format modifier, the tag 0x30
-        is used.
+'{'     Begin sequence.  No argument is needed.  If this format charac-
+        ter is not preceded by the 't' format modifier, the tag 0x30U is
+        used.
 
-'}'     End sequence.  No argument is required.  The 't' format modifier
+'}'     End sequence.  No argument is needed.  The 't' format modifier
         cannot be used with this format character.
 
-'['     Begin set.  No argument is required.  If this format character
-        is not preceded by the 't' format modifier, the tag 0x31 is
-        used.
+'['     Begin set.  No argument is needed.  If this format character is
+        not preceded by the 't' format modifier, the tag 0x31U is used.
 
-']'     End set.  No argument is required.  The 't' format modifier can-
-        not be used with this format character.
+']'     End set.  No argument is needed.  The 't' format modifier cannot
+        be used with this format character.
 
-Each use of a '{' format character must be matched by a '}' character,
+Each use of a '{' format character SHOULD be matched by a '}' character,
 either later in the format string, or in the format string of a subse-
 quent call to ber_printf() for that BerElement.  The same applies to the
 '[' and ']' format characters.
 
-Sequences and sets nest, and implementations of this API must maintain
+Sequences and sets nest, and implementations of this API MUST maintain
 internal state to be able to properly calculate the lengths.
 
-           int ber_flatten( const BerElement *ber, struct berval **bvPtr );
+           int ber_flatten( BerElement *ber, struct berval **bvPtr );
 
-The ber_flatten routine allocates a struct berval whose contents are a
-BER encoding taken from the ber argument. The bvPtr pointer points to
-the returned berval, which must be freed using ber_bvfree().  This rou-
-tine returns 0 on success and -1 on error.
 
 
+Expires: 8 April 2000                                          [Page 60]
 
 
-Expires: 2 December 1999                                       [Page 57]
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
+The ber_flatten routine allocates a struct berval whose contents are a
+BER encoding taken from the ber argument. The bvPtr pointer points to
+the returned berval structure, which SHOULD be freed using ber_bvfree().
+This routine returns 0 on success and -1 on error.
 
 The ber_flatten API call is not present in U-M LDAP 3.3.
 
@@ -3254,7 +3430,7 @@ modifiers have not been properly matched is an error (i.e., -1 will be
 returned by ber_flatten() if this situation is exists).
 
 
-16.3.  Encoding Example
+17.4.  Encoding Example
 
 The following is an example of encoding the following ASN.1 data type:
 
@@ -3265,7 +3441,8 @@ The following is an example of encoding the following ASN.1 data type:
       }
 
 
-      int encode_example1(const char *s,int val1,int val2,struct berval **bvPtr)
+      int encode_example1(const char *s, ber_int_t val1, ber_int_t val2,
+               struct berval **bvPtr)
       {
            BerElement *ber;
            int rc = -1;
@@ -3279,7 +3456,7 @@ The following is an example of encoding the following ASN.1 data type:
            }
 
            if (val2 != 0) {
-                   if (ber_printf(ber,"ti",0x80,val2) == -1) {
+                   if (ber_printf(ber,"ti",(ber_tag_t)0x80,val2) == -1) {
                            goto done;
                    }
            }
@@ -3290,26 +3467,34 @@ The following is an example of encoding the following ASN.1 data type:
 
            rc = ber_flatten(ber,bvPtr);
 
-   done:
-           ber_free(ber,1);
-           return rc;
-      }
 
 
+Expires: 8 April 2000                                          [Page 61]
+
 
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-Expires: 2 December 1999                                       [Page 58]
 
+   done:
+           ber_free(ber,1);
+           return rc;
+      }
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
 
+17.5.  Decoding
 
-16.4.  Decoding
+The following two macros are available to applications: LBER_ERROR and
+LBER_DEFAULT.  Both of these macros MUST be #define'd as integer con-
+stants that are both compatible with the ber_tag_t type and for which
+all bits have the value one.  For example, ISO C guarantees that these
+definitions will work:
 
-The following two symbols are available to applications.
+           #define LBER_ERROR   ((ber_tag_t)-1)
+           #define LBER_DEFAULT ((ber_tag_t)-1)
 
-           #define LBER_ERROR   (ber_tag_t)0xffffffff
-           #define LBER_DEFAULT (ber_tag_t)0xffffffff
+The intent is that LBER_ERROR and LBER_DEFAULT are both defined as the
+integer value that has all bits set to 1, as such a value is not a valid
+BER tag.
 
            BerElement *ber_init( const struct berval *bv );
 
@@ -3323,7 +3508,7 @@ The ber_scanf() routine is used to decode a BER element in much the same
 way that sscanf() works.  One important difference, though, is that some
 state information is kept with the ber argument so that multiple calls
 can be made to ber_scanf() to sequentially read from the BER element.
-The ber argument must be a pointer to a BerElement returned by
+The ber argument SHOULD be a pointer to a BerElement returned by
 ber_init().  ber_scanf interprets the bytes according to the format
 string fmt, and stores the results in its additional arguments.
 ber_scanf() returns LBER_ERROR on error, and a different value on suc-
@@ -3333,110 +3518,134 @@ The format string contains conversion specifications which are used to
 direct the interpretation of the BER element.  The format string can
 contain the following characters:
 
-'a'     Octet string.  A char ** argument should be supplied.  Memory is
+'a'     Octet string.  A char ** argument MUST be supplied.  Memory is
         allocated, filled with the contents of the octet string, zero-
         terminated, and the pointer to the string is stored in the argu-
-        ment.  The returned value must be freed using ldap_memfree.  The
-        tag of the element must indicate the primitive form (constructed
-        strings are not supported) but is otherwise ignored and dis-
-        carded during the decoding.  This format cannot be used with
-        octet strings which could contain null bytes.
+        ment.  The returned value SHOULD be freed using ldap_memfree.
+        The tag of the element MUST indicate the primitive form
+
+
 
-'O'     Octet string.  A struct berval ** argument should be supplied,
+Expires: 8 April 2000                                          [Page 62]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
+        (constructed strings are not supported) but is otherwise ignored
+        and discarded during the decoding.  This format cannot be used
+        with octet strings which could contain null bytes.
+
+'O'     Octet string.  A struct berval ** argument MUST be supplied,
         which upon return points to an allocated struct berval contain-
-        ing the octet string and its length.  ber_bvfree() must be
+        ing the octet string and its length.  ber_bvfree() SHOULD be
         called to free the allocated memory.  The tag of the element
-        must indicate the primitive form (constructed strings are not
+        MUST indicate the primitive form (constructed strings are not
         supported) but is otherwise ignored during the decoding.
 
-'b'     Boolean.  A pointer to an int should be supplied. The int value
-        stored will be 0 for FALSE or nonzero for TRUE.  The tag of the
-        element must indicate the primitive form but is otherwise
+'b'     Boolean.  A pointer to a ber_int_t MUST be supplied. The
+        ber_int_t value stored will be 0 for FALSE or nonzero for TRUE.
+        The tag of the element MUST indicate the primitive form but is
+        otherwise ignored during the decoding.
+
+'e'     Enumerated.  A pointer to a ber_int_t MUST be supplied. The
+        enumerated value stored will be in host byte order.  The tag of
+        the element MUST indicate the primitive form but is otherwise
+        ignored during the decoding.  ber_scanf() will return an error
+        if the value of the enumerated value cannot be stored in a
+        ber_int_t.
 
+'i'     Integer.  A pointer to a ber_int_t MUST be supplied. The
+        ber_int_t value stored will be in host byte order.  The tag of
+        the element MUST indicate the primitive form but is otherwise
+        ignored during the decoding.  ber_scanf() will return an error
+        if the integer cannot be stored in a ber_int_t.
 
+'B'     Bitstring.  A char ** argument MUST be supplied which will point
+        to the allocated bits, followed by a ber_len_t * argument, which
+        will point to the length (in bits) of the bitstring returned.
+        ldap_memfree SHOULD be called to free the bitstring.  The tag of
+        the element MUST indicate the primitive form (constructed bit-
+        strings are not supported) but is otherwise ignored during the
+        decoding.
 
-Expires: 2 December 1999                                       [Page 59]
+'n'     Null.  No argument is needed.  The element is verified to have a
+        zero-length value and is skipped.  The tag is ignored.
 
+'t'     Tag.  A pointer to a ber_tag_t MUST be supplied.  The ber_tag_t
+        value stored will be the tag of the next element in the BerEle-
+        ment ber, represented so it can be written using the 't' format
+        of ber_printf().  The decoding position within the ber argument
+        is unchanged by this; that is, the fact that the tag has been
+        retrieved does not affect future use of ber.
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+'v'     Several octet strings.  A char *** argument MUST be supplied,
 
 
-        ignored during the decoding.
 
-'i'     Integer.  A pointer to an int should be supplied. The int value
-        stored will be in host byte order.  The tag of the element must
-        indicate the primitive form but is otherwise ignored during the
-        decoding.  ber_scanf() will return an error if the integer can-
-        not be stored in an int.
+Expires: 8 April 2000                                          [Page 63]
 
-'B'     Bitstring.  A char ** argument should be supplied which will
-        point to the allocated bits, followed by a ber_len_t * argument,
-        which will point to the length (in bits) of the bitstring
-        returned.  ldap_memfree must be called to free the bitstring.
-        The tag of the element must indicate the primitive form (con-
-        structed bitstrings are not supported) but is otherwise ignored
-        during the decoding.
 
-'n'     Null.  No argument is required.  The element is verified to have
-        a zero-length value and is skipped.  The tag is ignored.
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
 
-'v'     Several octet strings.  A char *** argument should be supplied,
         which upon return points to an allocated NULL-terminated array
         of char *'s containing the octet strings.  NULL is stored if the
-        sequence is empty.  ldap_memfree must be called to free each
+        sequence is empty.  ldap_memfree SHOULD be called to free each
         element of the array and the array itself.  The tag of the
         sequence and of the octet strings are ignored.
 
 'V'     Several octet strings (which could contain null bytes).  A
-        struct berval *** should be supplied, which upon return points
-        to a allocated NULL-terminated array of struct berval *'s con-
-        taining the octet strings and their lengths.  NULL is stored if
-        the sequence is empty. ber_bvecfree() can be called to free the
+        struct berval *** MUST be supplied, which upon return points to
+        a allocated NULL-terminated array of struct berval *'s contain-
+        ing the octet strings and their lengths.  NULL is stored if the
+        sequence is empty. ber_bvecfree() can be called to free the
         allocated memory.  The tag of the sequence and of the octet
         strings are ignored.
 
 'x'     Skip element.  The next element is skipped.  No argument is
-        required.
+        needed.
 
-'{'     Begin sequence.  No argument is required.  The initial sequence
+'{'     Begin sequence.  No argument is needed.  The initial sequence
         tag and length are skipped.
 
-'}'     End sequence.  No argument is required.
+'}'     End sequence.  No argument is needed.
 
-'['     Begin set.  No argument is required.  The initial set tag and
+'['     Begin set.  No argument is needed.  The initial set tag and
         length are skipped.
 
-']'     End set.  No argument is required.
-
-           ber_tag_t ber_peek_tag( const BerElement *ber,
-
-
-
-Expires: 2 December 1999                                       [Page 60]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
+']'     End set.  No argument is needed.
 
+           ber_tag_t ber_peek_tag( BerElement *ber,
                ber_len_t *lenPtr );
 
 ber_peek_tag() returns the tag of the next element to be parsed in the
 BerElement argument.  The length of this element is stored in the
 *lenPtr argument.  LBER_DEFAULT is returned if there is no further data
-to be read.  The ber argument is not modified.
+to be read.  The decoding position within the ber argument is unchanged
+by this call; that is, the fact that ber_peek_tag() has been called does
+not affect future use of ber.
 
            ber_tag_t ber_skip_tag( BerElement *ber, ber_len_t *lenPtr );
 
 ber_skip_tag() is similar to ber_peek_tag(), except that the state
 pointer in the BerElement argument is advanced past the first tag and
 length, and is pointed to the value part of the next element.  This rou-
-tine should only be used with constructed types and situations when a
+tine SHOULD only be used with constructed types and situations when a
 BER encoding is used as the value of an OCTET STRING.  The length of the
 value is stored in *lenPtr.
 
            ber_tag_t ber_first_element( BerElement *ber,
                    ber_len_t *lenPtr, char **opaquePtr );
 
+
+
+Expires: 8 April 2000                                          [Page 64]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
            ber_tag_t ber_next_element( BerElement *ber,
                    ber_len_t *lenPtr, char *opaque );
 
@@ -3449,11 +3658,11 @@ ber_next_element() positions the state at the start of the next element
 in the constructed type.  LBER_DEFAULT is returned if there are no
 further values.
 
-The len and opaque values should not be used by applications other than
+The len and opaque values SHOULD NOT be used by applications other than
 as arguments to ber_next_element(), as shown in the example below.
 
 
-16.5.  Decoding Example
+17.6.  Decoding Example
 
 The following is an example of decoding an ASN.1 data type:
 
@@ -3466,34 +3675,34 @@ The following is an example of decoding an ASN.1 data type:
            tonly BOOLEAN,
            attrs SEQUENCE OF OCTET STRING, -- must be printable
            [0] SEQUENCE OF SEQUENCE {
-
-
-
-Expires: 2 December 1999                                       [Page 61]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
               type  OCTET STRING -- must be printable,
               crit  BOOLEAN DEFAULT FALSE,
               value OCTET STRING
            } OPTIONAL }
 
-      #define TAG_CONTROL_LIST 0xA0L /* context specific cons 0 */
+      #define TAG_CONTROL_LIST 0xA0U /* context specific cons 0 */
 
       int decode_example2(struct berval *bv)
       {
            BerElement *ber;
            ber_len_t len;
            ber_tag_t res;
-           int scope, ali, size, time, tonly;
+           ber_int_t scope, ali, size, time, tonly;
            char *dn = NULL, **attrs = NULL;
            int i,rc = 0;
 
            ber = ber_init(bv);
            if (ber == NULL) {
                    fputs("ERROR ber_init failed\n", stderr);
+
+
+
+Expires: 8 April 2000                                          [Page 65]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
                    return -1;
            }
 
@@ -3523,19 +3732,10 @@ C LDAP API        C LDAP Application Program Interface       2 June 1999
                         tag != LBER_DEFAULT;
                         tag = ber_next_element (ber,&len,opaque)) {
 
-
-
-
-Expires: 2 December 1999                                       [Page 62]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
                            ber_len_t tlen;
                            ber_tag_t ttag;
                            char *type;
-                           int crit;
+                           ber_int_t crit;
                            struct berval *value;
 
                            if (ber_scanf(ber,"{a",&type) == LBER_ERROR) {
@@ -3546,15 +3746,24 @@ C LDAP API        C LDAP Application Program Interface       2 June 1999
                            ldap_memfree(type);
 
                            ttag = ber_peek_tag(ber,&tlen);
-                           if (ttag == 0x01) {  /* boolean */
+                           if (ttag == 0x01U) {  /* boolean */
                                    if (ber_scanf(ber,"b",
                                                  &crit) == LBER_ERROR) {
                                            fputs("ERROR cannot parse crit\n",
                                                stderr);
+
+
+
+Expires: 8 April 2000                                          [Page 66]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
                                            rc = -1;
                                            break;
                                    }
-                           } else if (ttag == 0x04) { /* octet string */
+                           } else if (ttag == 0x04U) { /* octet string */
                                    crit = 0;
                            } else {
                                    fputs("ERROR extra field in controls\n",
@@ -3572,7 +3781,11 @@ C LDAP API        C LDAP Application Program Interface       2 June 1999
                    }
            }
 
-           ber_scanf(ber,"}");
+           if ( rc == 0 ) {        /* no errors so far */
+                   if (ber_scanf(ber,"}") == LBER_ERROR) {
+                           rc = -1;
+                   }
+           }
 
            ber_free(ber,1);
 
@@ -3581,29 +3794,30 @@ C LDAP API        C LDAP Application Program Interface       2 June 1999
 
 
 
-
-
-Expires: 2 December 1999                                       [Page 63]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
-17.  Security Considerations
+18.  Security Considerations
 
 LDAPv2 supports security through protocol-level authentication using
-clear-text passwords.  LDAPv3 adds support for SASL [8] (Simple Authen-
+clear-text passwords.  LDAPv3 adds support for SASL [12] (Simple Authen-
 tication Security Layer) methods.  LDAPv3 also supports operation over a
 secure transport layer using Transport Layer Security TLS [9].  Readers
 are referred to the protocol documents for discussion of related secu-
 rity considerations.
 
-Implementations of this API should be cautious when handling authentica-
+Implementations of this API SHOULD be cautious when handling authentica-
 tion credentials.  In particular, keeping long-lived copies of creden-
 tials without the application's knowledge is discouraged.
 
 
-18.  Acknowledgements
+
+
+
+Expires: 8 April 2000                                          [Page 67]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
+19.  Acknowledgements
 
 Many members of the IETF ASID and LDAPEXT working groups as well as
 members of the Internet at large have provided useful comments and
@@ -3615,7 +3829,7 @@ The original material upon which this specification is based was sup-
 ported by the National Science Foundation under Grant No.  NCR-9416667.
 
 
-19.  Copyright
+20.  Copyright
 
 Copyright (C) The Internet Society (1997-1999). All Rights Reserved.
 
@@ -3637,89 +3851,94 @@ revoked by the Internet Society or its successors or assigns.
 
 This document and the information contained herein is provided on an "AS
 IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK
+FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT
+INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FIT-
+NESS FOR A PARTICULAR PURPOSE.
 
 
+21.  Bibliography
 
-Expires: 2 December 1999                                       [Page 64]
+[1]  Bradner, S., "Key words for use in RFCs to Indicate Requirement
+     Levels", RFC 2119, March 1997.
 
+[2]  M. Wahl, T. Howes, S. Kille, "Lightweight Directory Access Protocol
+     (v3)", RFC 2251, December 1997.
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
 
 
-FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
-LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT
-INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FIT-
-NESS FOR A PARTICULAR PURPOSE.
 
+Expires: 8 April 2000                                          [Page 68]
 
-20.  Bibliography
 
-[1]  The Directory: Selected Attribute Syntaxes.  CCITT, Recommendation
-     X.520.
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
 
-[2]  M. Wahl, A. Coulbeck, T. Howes, S. Kille, W. Yeong, C. Robbins,
+[3]  M. Wahl, A. Coulbeck, T. Howes, S. Kille, W. Yeong, C. Robbins,
      "Lightweight Directory Access Protocol (v3): Attribute Syntax
      Definitions", RFC 2252, December 1997.
 
-[3]  T. Howes, "The String Representation of LDAP Search Filters," RFC
-     2254, December 1997.
+[4]  The Directory: Selected Attribute Syntaxes.  CCITT, Recommendation
+     X.520.
 
-[4]  M. Wahl, S. Kille, T. Howes, "Lightweight Directory Access Protocol
+[5]  M. Wahl, S. Kille, T. Howes, "Lightweight Directory Access Protocol
      (v3): A UTF-8 String Representation of Distinguished Names", RFC
      2253, December 1997.
 
-[5]  S. Kille, "Using the OSI Directory to Achieve User Friendly Nam-
-     ing," RFC 1781, March 1995.
+[6]  F. Yergeau, "UTF-8, a transformation format of Unicode and ISO
+     10646", RFC 2044, October 1996.
 
-[6]  M. Wahl, T. Howes, S. Kille, "Lightweight Directory Access Protocol
-     (v3)", RFC 2251, December 1997.
+[7]  K. Simonsen, "Character Mnemonics and Character Sets," RFC 1345,
+     June 1992.
 
-[7]  A. Herron, T. Howes, M. Wahl, C. Weider, A. Anantha, "LDAP Control
-     Extension for Server Side Sorting of Search Results", INTERNET-
-     DRAFT <draft-ietf-ldapext-sorting-01.txt>, 7 August 1998.
+[8]  "Programming Languages - C", ANSI/ISO Standard 9899, revised 1997.
 
-[8]  J. Meyers, "Simple Authentication and Security Layer (SASL)", RFC
-     2222, October 1997.
+[9]  J. Hodges, R. Morgan, M. Wahl, "Lightweight Directory Access Proto-
+     col (v3):  Extension for Transport Layer Security", INTERNET-DRAFT
+     (work in progress) <draft-ietf-ldapext-ldapv3-tls-05.txt>, June
+     1999.
+
+[10] R. Hinden, S. Deering, "IP Version 6 Addressing Architecture," RFC
+     1884, December 1995.
 
-[9]  "Lightweight Directory Access Protocol (v3): Extension for Tran-
-     sport Layer Security", INTERNET-DRAFT <draft-ietf-ldapext-ldapv3-
-     tls-04.txt>, November 1998.
+[11] A. Herron, T. Howes, M. Wahl, A. Anantha, "LDAP Control Extension
+     for Server Side Sorting of Search Results", INTERNET-DRAFT (work in
+     progress) <draft-ietf-ldapext-sorting-02.txt>, 5 April 1999.
 
-[10] "UTF-8, a transformation format of Unicode and ISO 10646", RFC
-     2044, October 1996.
+[12] J. Meyers, "Simple Authentication and Security Layer (SASL)", RFC
+     2222, October 1997.
 
-[11] "IP Version 6 Addressing Architecture,", RFC 1884, December 1995.
+[13] T. Howes, "The String Representation of LDAP Search Filters," RFC
+     2254, December 1997.
 
-[12] "Character Mnemonics and Character Sets," RFC 1345, June 1992.
+[14] S. Kille, "Using the OSI Directory to Achieve User Friendly Nam-
+     ing," RFC 1781, March 1995.
 
-[13] "Programming Languages - C", ANSI/ISO Standard 9899, revised 1997.
 
+22.  Authors' Addresses
 
+   Mark Smith (document editor)
+   Netscape Communications Corp.
+   501 E. Middlefield Rd., Mailstop MV068
+   Mountain View, CA 94043
+   USA
 
 
-Expires: 2 December 1999                                       [Page 65]
 
+Expires: 8 April 2000                                          [Page 69]
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
 
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-21.  Authors' Addresses
 
-   Mark Smith (document editor)
-   Netscape Communications Corp.
-   501 E. Middlefield Rd., Mailstop MV068
-   Mountain View, CA 94043
-   USA
    +1 650 937-3477
    mcs@netscape.com
 
    Tim Howes
-   Netscape Communications Corp.
-   501 E. Middlefield Rd., Mailstop MV068
-   Mountain View, CA 94043
-   USA
-   +1 650 937-3419
-   howes@netscape.com
+   1345 Fairway Dr.
+   Los Altos, CA 94024
+   +1 650 787-5384
+   timhowes@yahoo.com
 
    Andy Herron
    Microsoft Corp.
@@ -3746,20 +3965,11 @@ C LDAP API        C LDAP Application Program Interface       2 June 1999
    anoopa@microsoft.com
 
 
-22.  Appendix A - Sample C LDAP API Code
+23.  Appendix A - Sample C LDAP API Code
 
    #include <stdio.h>
    #include <ldap.h>
 
-
-
-
-Expires: 2 December 1999                                       [Page 66]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
    main()
    {
            LDAP            *ld;
@@ -3769,6 +3979,15 @@ C LDAP API        C LDAP Application Program Interface       2 June 1999
            BerElement      *ptr;
            char            **vals;
 
+
+
+
+Expires: 8 April 2000                                          [Page 70]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
            /* open an LDAP session */
            if ( (ld = ldap_init( "dotted.host.name", LDAP_PORT )) == NULL )
                    return 1;
@@ -3808,15 +4027,6 @@ C LDAP API        C LDAP Application Program Interface       2 June 1999
 
                            /* print each value */
                            vals = ldap_get_values( ld, e, a );
-
-
-
-Expires: 2 December 1999                                       [Page 67]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
                            for ( i = 0; vals[i] != NULL; i++ ) {
                                    printf( "\t\tvalue: %s\n", vals[i] );
                            }
@@ -3826,6 +4036,15 @@ C LDAP API        C LDAP Application Program Interface       2 June 1999
                    if ( ptr != NULL ) {
                            ber_free( ptr, 0 );
                    }
+
+
+
+Expires: 8 April 2000                                          [Page 71]
+
+
+C LDAP API        C LDAP Application Program Interface    8 October 1999
+
+
            }
            /* free the search results */
            ldap_msgfree( res );
@@ -3837,7 +4056,7 @@ C LDAP API        C LDAP Application Program Interface       2 June 1999
    }
 
 
-23.  Appendix B - Namespace Consumed By This Specification
+24.  Appendix B - Namespace Consumed By This Specification
 
 The following 2 prefixes are used in this specification to name func-
 tions:
@@ -3860,50 +4079,55 @@ macros:
    mod_
 
 
-24.  Appendix C - Summary of Requirements for API Extensions
+25.  Appendix C - Summary of Requirements for API Extensions
 
 As the LDAP protocol is extended, this C LDAP API will need to be
 extended as well.  For example, an LDAPv3 control extension has already
-been defined for server-side sorting of search results [7].  This
+been defined for server-side sorting of search results [7].  This appen-
+dix summarizes the requirements for extending this API.
 
+25.1.  Compatibility
 
+Extensions to this document SHOULD NOT, by default, alter the behavior
+of any of the APIs specified in this document.  If an extension option-
+ally changes the behavior of any existing C LDAP API function calls, the
+behavior change MUST be well documented.
 
-Expires: 2 December 1999                                       [Page 68]
 
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
 
+Expires: 8 April 2000                                          [Page 72]
 
-appendix summarizes the requirements for extending this API.
 
-24.1.  Compatibility
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-Extensions to this document should not, by default, alter the behavior
-of any of the APIs specified in this document.  If an extension option-
-ally changes the behavior of any existing C LDAP API function calls, the
-behavior change must be well documented.
 
-24.2.  Style
+25.2.  Style
 
-Extensions to this API should follow the general style and naming con-
-ventions used in this document.  For example, function names should
+Extensions to this API SHOULD follow the general style and naming con-
+ventions used in this document.  For example, function names SHOULD
 start with "ldap_" or "ber_" and consist entirely of lowercase letters,
-digits, and underscore ('_') characters.  More information can be found
-in the preceding appendix called "Namespace Consumed By This Specifica-
-tion."
-
-24.3.  Dependence on Externally Defined Types
-
-Extensions to this API should minimize dependencies on types and macros
-that are defined in system header files and generally use only intrinsic
+digits, and underscore ('_') characters.  It is RECOMMENDED that private
+and experimental extensions use only the following prefixes for macros,
+types, and function names:
+       LDAP_X_
+       LBER_X_
+       ldap_x_
+       ber_x_
+and that these prefixes not be used by standard extensions.
+
+25.3.  Dependence on Externally Defined Types
+
+Extensions to this API SHOULD minimize dependencies on types and macros
+that are defined in system headers and generally use only intrinsic
 types that are part of the C language, types defined in this specifica-
 tion, or types defined in the extension document itself.
 
-24.4.  Compile Time Information
+25.4.  Compile Time Information
 
-Extensions to this API should conform to the requirements contained in
+Extensions to this API SHOULD conform to the requirements contained in
 the "Retrieving Information at Compile Time" section of this document.
-That is, extensions should define a macro of the form:
+That is, extensions SHOULD define a macro of the form:
 
    #define LDAP_API_FEATURE_x level
 
@@ -3911,30 +4135,30 @@ so that applications can detect the presence or absence of the extension
 at compile time and also test the version or level of the extension pro-
 vided by an API implementation.
 
-24.5.  Runtime Information
+25.5.  Runtime Information
 
-Extensions to this API should conform to the requirements contained in
+Extensions to this API SHOULD conform to the requirements contained in
 the "Retrieving Information During Execution" section of this document.
-That is, each extension should be given a character string name and that
-name should appear in the ldapai_extensions array field of the LDAPAPI-
+That is, each extension SHOULD be given a character string name and that
+name SHOULD appear in the ldapai_extensions array field of the LDAPAPI-
 Info structure following a successful call to ldap_get_option() with an
 option parameter value of LDAP_OPT_API_INFO.  In addition, information
-about the extension should be available via a call to ldap_get_option()
+about the extension SHOULD be available via a call to ldap_get_option()
 with an option parameter value of LDAP_OPT_API_FEATURE_INFO.
 
+25.6.  Values Used for Session Handle Options
 
+Extensions to this API that add new session options (for use with the
+ldap_get_option() and ldap_set_option() functions) SHOULD meet the
 
 
-Expires: 2 December 1999                                       [Page 69]
 
+Expires: 8 April 2000                                          [Page 73]
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
 
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-24.6.  Values Used for Session Handle Options
 
-Extensions to this API that add new session options (for use with the
-ldap_get_option() and ldap_set_option() functions) should meet the
 requirements contained in the last paragraph of the "LDAP Session Handle
 Options" section of this document.  Specifically, standards track docu-
 ments MUST use values for option macros that are between 0x1000 and
@@ -3942,14 +4166,14 @@ ments MUST use values for option macros that are between 0x1000 and
 for the option macros that are between 0x4000 and 0x7FFF inclusive.
 
 
-25.  Appendix D - Known Incompatibilities with RFC 1823
+26.  Appendix D - Known Incompatibilities with RFC 1823
 
 This appendix lists known incompatibilities between this API specifica-
 tion and the one contained in RFC 1823, beyond the additional API func-
 tions added in support of LDAPv3.
 
 
-25.1.  Opaque LDAP Structure
+26.1.  Opaque LDAP Structure
 
 In RFC 1823, some fields in the LDAP structure were exposed to applica-
 tion programmers.  To provide a cleaner interface and to make it easier
@@ -3959,7 +4183,7 @@ opaque.  The new ldap_set_option() and ldap_get_option() calls can be
 used to manipulate per-session and global options.
 
 
-25.2.  Additional Error Codes
+26.2.  Additional Error Codes
 
 The following new error code macros were introduced to support LDAPv3:
    LDAP_REFERRAL
@@ -3977,26 +4201,22 @@ The following new error code macros were introduced to support LDAPv3:
    LDAP_REFERRAL_LIMIT_EXCEEDED
 
 
+26.3.  Freeing of String Data with ldap_memfree()
 
+All strings received from the API (e.g., those returned by the
+ldap_get_dn() or ldap_dn2ufn() functions) SHOULD be freed by calling
+ldap_memfree() not free().  RFC 1823 did not define an ldap_memfree()
+function.
 
 
 
+Expires: 8 April 2000                                          [Page 74]
 
-Expires: 2 December 1999                                       [Page 70]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
-25.3.  Freeing of String Data with ldap_memfree()
 
-All strings received from the API (e.g., those returned by the
-ldap_get_dn() or ldap_dn2ufn() functions) should be freed by calling
-ldap_memfree() not free().  RFC 1823 did not define an ldap_memfree()
-function.
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
 
-25.4.  Changes to ldap_result()
+26.4.  Changes to ldap_result()
 
 The meaning of the all parameter to ldap_result has changed slightly.
 Nonzero values from RFC 1823 correspond to LDAP_MSG_ALL (0x01).  There
@@ -4007,20 +4227,20 @@ LDAP_RES_MODRDN.  The actual value for these two macros is the same
 (0x6D).
 
 
-25.5.  Changes to ldap_first_attribute() and ldap_next_attribute
+26.5.  Changes to ldap_first_attribute() and ldap_next_attribute
 
-Each non-NULL return value should be freed by calling ldap_memfree()
+Each non-NULL return value SHOULD be freed by calling ldap_memfree()
 after use.  In RFC 1823, these two functions returned a pointer to a
 per-session buffer, which was not very thread-friendly.
 
 After the last call to ldap_first_attribute() or ldap_next_attribute(),
-the value set in the ptr parameter should be freed by calling ber_free(
-ptr, 0 ).  RFC 1823 did not mention that the ptr value should be freed.
+the value set in the ptr parameter SHOULD be freed by calling ber_free(
+ptr, 0 ).  RFC 1823 did not mention that the ptr value SHOULD be freed.
 
 The type of the ptr parameter was changed from void * to BerElement *.
 
 
-25.6.  Changes to ldap_modrdn() and ldap_modrdn_s() Functions
+26.6.  Changes to ldap_modrdn() and ldap_modrdn_s() Functions
 
 In RFC 1823, the ldap_modrdn() and ldap_modrdn_s() functions include a
 parameter called deleteoldrdn.  This does not match the great majority
@@ -4030,33 +4250,33 @@ functions that support deleteoldrdn and are widely implemented as well
 were added to this specification: ldap_modrdn2() and ldap_modrdn2_s().
 
 
-25.7.  Changes to the berval structure
+26.7.  Changes to the berval structure
 
 In RFC 1823, the bv_len element of the berval structure was defined as
-an unsigned long.  In this specification, the type is implementation-
-specific, although it must be an unsigned integral type that is at least
-32 bits in size.  See the appendix "Data Types and Legacy
+an `unsigned long'.  In this specification, the type is implementation-
+specific, although it MUST be an unsigned integral type that is at least
+32 bits in size.  See the appendix "Data Types and Legacy Implementa-
+tions" for additional considerations.
 
 
+26.8.  API Specification Clarified
 
-Expires: 2 December 1999                                       [Page 71]
+RFC 1823 left many things unspecified, including behavior of various
+memory disposal functions when a NULL pointer is presented, requirements
+for headers, values of many macros, and so on.  This specification is
 
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
 
+Expires: 8 April 2000                                          [Page 75]
 
-Implementations" for additional considerations.
 
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-25.8.  API Specification Clarified
 
-RFC 1823 left many things unspecified, including behavior of various
-memory disposal functions when a NULL pointer is presented, requirements
-for header files, values of many macros, and so on.  This specification
-is more complete and generally tighter than the one in RFC 1823.
+more complete and generally tighter than the one in RFC 1823.
 
 
-25.9.  Deprecated Functions
+26.9.  Deprecated Functions
 
 A number of functions that are in RFC 1823 are labeled as "deprecated"
 in this specification.  In most cases, a replacement that provides
@@ -4088,36 +4308,39 @@ are:
            Use ldap_parse_result() instead.
 
 
-26.  Appendix E - Data Types and Legacy Implementations
+27.  Appendix E - Data Types and Legacy Implementations
 
-The data types associated with the length of a ber value (ber_len_t) and
-the tag (ber_tag_t) have been defined in this specification as unsigned
-integral types of implementation-specific size.  This was done so that
+The data types associated with the length of a ber value (ber_len_t),
+and the tag (ber_tag_t) have been defined in this specification as
+unsigned integral types of implementation-specific size.  The data type
+used for encoding and decoding ber integer, enumerated, and boolean
+values has been defined in this specification as a signed integral type
+of implementation-specific size.  This was done so that source and
+binary compatibility of the C LDAP API can be maintained across ILP32
+environments (where int, long, and pointers are all 32 bits in size) and
+LP64 environments (where ints remain 32 bits but longs and pointers grow
+to 64 bits).
 
 
 
-Expires: 2 December 1999                                       [Page 72]
 
+Expires: 8 April 2000                                          [Page 76]
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
 
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-source and binary compatibility of the C LDAP API can be maintained
-across ILP32 environments (where int, long, and pointers are all 32 bits
-in size) and LP64 environments (where ints remain 32 bits but longs and
-pointers grow to 64 bits).
 
 In older implementations of the C LDAP API, such as those based on RFC
-1823, implementors may have chosen to use an unsigned long for these
-types.  If a long data type was used, a port of an application to a 64-
-bit operating system using the LP64 data model would find the size of
-the BER length and tag types used by the C LDAP API to increase.  Also,
-if the legacy implementation had chosen to implement the types as an
-unsigned int, adoption of a specification that mandated use of unsigned
-longs would cause a source incompatibility in an LP64 application.  By
-using an implementation-specific data type, the C LDAP API implementa-
-tion is free to choose the correct data type and the ability to maintain
-source compatibility.
+1823, implementors may have chosen to use an `unsigned long' for length
+and tag values.  If a long data type was used for either of these items,
+a port of an application to a 64-bit operating system using the LP64
+data model would find the size of the types used by the C LDAP API to
+increase.  Also, if the legacy implementation had chosen to implement
+the tag and types as an unsigned int, adoption of a specification that
+mandated use of unsigned longs would cause a source incompatibility in
+an LP64 application.  By using implementation-specific data types, the C
+LDAP API implementation is free to choose the correct data type and the
+ability to maintain source compatibility.
 
 For example, suppose a legacy implementation chose to define the return
 value of ber_skip_tag() as an unsigned long but wishes to have the
@@ -4125,308 +4348,199 @@ library return a 32-bit quantity in both ILP32 and LP64 data models.
 The following typedefs for ber_tag_t will provide a fixed sized data
 structure while preserving existing ILP32 source -- all without generat-
 ing compiler warnings:
-           #if defined(_LP64)
+           #include <limits.h>     /* provides UINT_MAX in ISO C */
+           #if UINT_MAX >= 0xffffffffU
                typedef unsigned int ber_tag_t;
            #else
                typedef unsigned long ber_tag_t;
            #endif
-The above assumes that the the preprocessor symbol _LP64 is defined if
-and only if the code is being compiled in an LP64 environment.  Similar
-code can be used to define an appropriate ber_len_t type.
-
-
-27.  Appendix F - Changes Made Since Last Document Revision
-
-The previous version of this document was draft-ietf-ldapext-ldap-c-
-api-02.txt, dated 23 February, 1999.  This appendix lists all of the
-changes made to that document to produce this one.
-
-27.1.  API Changes
 
-   Types: added the ber_len_t and ber_tag_t implementation-specific
-   unsigned integral data types to support source and binary compatibil-
-   ity between ILP32 and LP64 environments.  Changes were made to the
-   "Common Data Structures" and "Encoded ASN.1 Value Manipulation" sec-
-   tions of this document.
+Similar code can be used to define appropriate ber_len_t and ber_int_t
+types.
 
 
+28.  Appendix F - Changes Made Since Last Document Revision
 
+The previous version of this document was draft-ietf-ldapext-ldap-c-
+api-03.txt, dated 2 June 1999.  This appendix lists all of the changes
+made to that document to produce this one.
 
+28.1.  API Changes
 
-Expires: 2 December 1999                                       [Page 73]
-
-
-C LDAP API        C LDAP Application Program Interface       2 June 1999
-
-
-27.2.  Editorial Changes
-
-   General: Added Appendix E - Data Types and Legacy Implementations;
-   moved list of recent document changes to Appendices F and G.
+   Types: Added BerValue typedef for struct berval.  Clarified width
+   requirements for integral types.   Made it clear that the types for
+   the fields within struct timeval are implementation-specific.
 
-   "Retrieving Information During Execution" section: removed misplaced
-   ldapai_vendor_name and ldapai_vendor_version from the LDAPAPI-
-   FeatureInfo structure description.
+   Namespace: Added recommendation that private and experimental exten-
+   sions use the LDAP_X_, LBER_X_, ldap_x_, and ber_x_ portions of the
+   namespace only.
 
-   "Extended Operations" section: changed the names of the "requestoid"
-   and "requestdata" parameters in the function prototypes to match the
-   parameter descriptions.  The old names were "exoid" and "exdata."
+   Macro-defined constants: Added missing 'U' suffix to unsigned
+   integral values.
 
-   Appendix D - "Appendix D - Known Incompatibilities with RFC 1823 ":
-   Added note about changes to the berval structure.
 
 
-28.  Appendix G - Changes Made Since draft-ietf-ldapext-ldap-c-api-
-01.txt
 
-The version of this document that preceded draft-ietf-ldapext-ldap-c-
-api-02.txt was draft-ietf-ldapext-ldap-c-api-01.txt, dated 7 August
-1998.  This appendix lists all of the changes made to that document to
-produce draft-ietf-ldapext-ldap-c-api-02.txt.
+Expires: 8 April 2000                                          [Page 77]
 
 
-28.1.  API Changes
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-   General: added the 'const' keyword to function prototypes where
-   appropriate.
 
-   Added two new sections that specify additional features and require-
-   ments for API implementors:
-      "Header File Requirements"
-      "A Client Control That Governs Referral Processing"
+   "LDAP Error Codes" section: Corrected text to say that LDAP error
+   codes are non-negative integers (used to say "positive integers"
+   which excluded LDAP_SUCCESS).
 
+   "LDAP Session Handle Option" section: Removed LDAP_OPT_DESC because
+   the definition was insufficient to allow interoperable use.  Added
+   new option LDAP_OPT_MATCHED_DN.  Documented the defaults for options.
+   Added text to specify required behavior with respect to state in the
+   session handle when a call to ldap_get_option() or ldap_set_option()
+   succeeds or fails.  Added the LDAP_OPT_PRIVATE_EXTENSION_BASE macro.
 
-   LDAP_VERSION_MAX, LDAP_VENDOR_NAME, and LDAP_VENDOR_VERSION macros.
-   Corrected LDAP_API_VERSION example code to use >= instead of >.
-   Added note about what value to use for LDAP_API_VERSION prior to pub-
-   lication of this draft as an RFC (2000 + draft revision number).
+   "Working With Controls" section: Removed PLDAPControl typedef (was a
+   pointer to an LDAPControl, but was not used anywhere in the API).
 
-   "Retrieving Information During Execution" section: added
-   LDAP_API_INFO_VERSION macro and clarified the text to explain the
-   behavior when there is a mismatch between LDAPAPIInfo structure ver-
-   sions.  Added LDAP_OPT_API_FEATURE_INFO to allow applications to
-   retrieve version information about API extended features.
+   "Searching" section: Added text to describe how the operation timel-
+   imit that is passed to the LDAP server for an LDAP search operation
+   is derived from the timeout parameter that is passed to
+   ldap_search_ext() and ldap_search_ext_s().
 
+   "Comparing a Value Against an Entry" section: Added `const' to
+   declarations of `bvalue' in ldap_compare_ext() and
+   ldap_compare_ext_s().  Also added missing trailing commas in proto-
+   types.
 
+   "Extended Operations" section: Added `const' to declarations of
+   `requestdata' in ldap_extended_operation() and
+   ldap_extended_operation_s() prototypes.
 
+   "Obtaining Results and Peeking Inside LDAP Messages" section: Added
+   LDAP_RES_UNSOLICITED macro for use as the `msgid' parameter to
+   ldap_result().  Added text to indicate that ldap_msgid() returns -1
+   on error.
 
-Expires: 2 December 1999                                       [Page 74]
+   "Handling Errors and Parsing Results" section: Added
+   LDAP_NOTICE_OF_DISCONNECTION macro.
 
+   "Stepping Through a List of Results" section: Added text to indicate
+   that ldap_count_messages(), ldap_count_entries(), and
+   ldap_count_references() return -1 if an error occurs.
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
+   "Encoded ASN.1 Value Manipulation" section: Added ber_int_t,
+   ber_uint_t, and ber_slen_t integral types.  Changed functions to use
+   ber_int_t where appropriate.  Added support for encoding and decoding
+   enumerated values (format 'e').  Added support for the 't' format to
+   ber_scanf() (works like ber_peek_tag()).  Changed the format specif-
+   ier for Bitstring in ber_printf() from 'X' to 'B' to match
+   ber_scanf().  Corrected text to say that ber_printf() returns a non-
+   negative number if successful (used to say positive, but zero is a
 
 
-   "LDAP Session Handle Options" section:  Added macro definitions for
-   LDAP_OPT_ON and LDAP_OPT_OFF and changed the "invalue" type for
-   Boolean options from "int" to "void *".  For consistency, we now
-   require that applications dispose of "char *" and "LDAPControl *"
-   values that are returned.  Added note about which option value ranges
-   are to be used for various purposes.
 
-   "Closing the session" section: added new function ldap_unbind_ext()
-   to allow controls to be used with unbind operations.
+Expires: 8 April 2000                                          [Page 78]
 
-   "Searching" section: added requirement that *res be set to NULL by
-   synchronous calls that fail to return any results.
 
-   "Modifying the Name of an Entry" section: added function prototypes
-   for ldap_modrdn2() and ldap_modrdn2_s() and corrected the ones for
-   ldap_modrdn() and ldap_modrdn_s() to match the most widely imple-
-   mented APIs.
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-   "Obtaining Results and Peeking Inside LDAP Messages" section: added
-   requirement that "*res" be set to NULL when ldap_result() fails to
-   return any results.  Added requirement that ldap_msgfree() accept a
-   NULL "res" parameter.
 
-   "Stepping Through the Attributes of an Entry" section:  added
-   requirement that ldap_memfree() accept a NULL "mem" parameter.
+   valid return value).  Removed `const' qualifier from BerElement
+   parameters in ber_flatten() and ber_peek_tag() function prototypes
+   and added note about preserving the state of the underlying BerEle-
+   ment when ber_peek_tag() is called.  Revised LBER_ERROR and
+   LBER_DEFAULT macros to use more portable definitions.  Updated exam-
+   ples to reflect changes.
 
-   "Encoded ASN.1 Value Manipulation - Encoding" section: added note
-   that implementations may support tags with a value larger than 32
-   (but this is not required).
 
-   "Encoded ASN.1 Value Manipulation - Decoding" section: changed the
-   LBER_ERROR and LBER_DEFAULT macros to end in "UL" instead of "L"
-   since all the functions that return these two values return an
-   "unsigned long" value.
+28.2.  Editorial Changes
 
+   General: Changed document to reference RFC 2119 ("Key words for use
+   in RFCs to Indicate Requirement Levels") and to use the key words
+   consistently.  Reordered references to list them in the order they
+   appear in the document.  Added text for deprecated functions to indi-
+   cate that more complete descriptions can be found in RFC 1823.
 
-28.2.  Editorial changes
+   Section names: Renamed "Overview of LDAP API Use" to "Overview of
+   LDAP API Use and General Requirements."  Renamed "Header File
+   Requirements" to "Header Requirements."  Renamed "Common Data Struc-
+   tures" to "Common Data Structures and Types."  Renamed "General" sec-
+   tion within "Encoded ASN.1 Value Manipulation" section to "BER Data
+   Structures and Types."
 
+   Types: Modified implementation-specific typedefs to use `impl_XXX_t'
+   convention.  Moved definition of `ber_tag_t' from "Common Data Struc-
+   tures and Types" section to "Encoded ASN.1 Value Manipulation" sec-
+   tion.
 
-   Removed section: "Appendix - Outstanding Issues."
+   "Overview of LDAP API Use and General Requirements" section: added
+   note that conformant implementations MUST implement all of the func-
+   tions and so on defined in this specification.
 
-   Added two new editorial sections:
-      "Appendix - Summary of Requirements for API Extensions"
-      "Appendix - Known Incompatibilities with RFC 1823".
+   "Header Requirements" section: Removed all references to the term
+   "header file(s)" and replaced with the simpler and less restrictive
+   term "header(s)."
 
-   General: replaced all occurrences of "LDAP C API" with "C LDAP API"
-   for consistency.
+   "Memory Handling Overview" section: New section added.  Also cleaned
+   up text throughout the document to consistently state that "free"
+   routines do nothing when a NULL pointer is passed in.
 
+   "LDAP Session Handle Options" section: Clarified text to better indi-
+   cate whether ldap_memfree() or ldap_controls_free() should be used to
+   dispose of char * and LDAPControl * values returned by
+   ldap_get_option().
 
+   "Handling Errors and Parsing Results" section: Removed confusing use
+   of ldap_parse_*_result() pattern (all function names are spelled out
+   now).
 
 
-Expires: 2 December 1999                                       [Page 75]
 
+Expires: 8 April 2000                                          [Page 79]
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
 
+C LDAP API        C LDAP Application Program Interface    8 October 1999
 
-   "Status of Memo" section: added a statement that this document is in
-   full conformance with all provisions of Section 10 of RFC2026.  Also
-   revised the text about the Internet Draft current and shadow direc-
-   tories to match the latest I-D guidelines.
 
-   Document authors: removed Chris Weider from the list of authors (at
-   his own request) and added an explicit mention of him in the "Ack-
-   nowledgements" section.  Updated Mark Wahl's company affiliation in
-   document preface.  Added "(document editor)" after Mark Smith's name
-   in the "Authors' Addresses" section.
+   "Encoded ASN.1 Value Manipulation" section: Added note about lack of
+   specific error codes from BER functions.  Cleaned up references to
+   berval to always say "struct berval" or "berval structure."
 
-   Copyright: updated the year to 1999.
+   "Authors" section: Updated Tim Howes' contact information.
 
-   "Introduction" section: expanded the sentence that mentioned the sam-
-   ple code appendix to mention all of the appendices.
 
-   "Overview of LDAP API Use" section: numbered the four simple steps
-   for using the API. Added mention of the referrals client control.
-   Clarified the text on character sets.  Replaced mention of
-   ldap_bind() with ldap_sasl_bind() because the former is deprecated.
-   Added note that this API is designed for use in environments where
-   the 'int' type is at least 32 bits in size.
 
-   "Common Data Structures" section: added definition of BerElement so
-   it is defined before it is used.  Added reference back to "Header
-   File Requirements" for "struct timeval" related considerations.
 
-   "Initializing an LDAP Session" section: moved note about ldap_open()
-   attempting to make a server connection closer to the ldap_open()
-   function prototype.  Added note that using literal IPv6 addresses in
-   the "hostname" parameter is not yet supported.
 
-   "LDAP Session Handle Options" section: replaced one instance of
-   "Formerly" with "In RFC 1823."  Added note about inheritance of
-   options when automatic referral following is enabled.  Added
-   LDAP_OPT_API_INFO and LDAP_OPT_API_FEATURE_INFO for completeness (not
-   previously included in this section).  Replaced erroneous references
-   to the "Using Controls" section with references to the "Working With
-   Controls" section.  In the text describing the LDAP_OPT_HOST_NAME
-   option, added a reference to the "hostname" parameter of ldap_init()
-   for the syntax of the option value.  Clarified that ldap_set_option()
-   makes a copy of the "invalue" data.
 
-   "Working With Controls" section: added a note to remind the reader
-   that server controls that are marked critical should not be used with
-   unbind and abandon operations since those two operations have no
-   server response.
 
 
 
 
-Expires: 2 December 1999                                       [Page 76]
 
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
 
 
-   "Closing the session" section: made it clear that all open connec-
-   tions associated with a session handle are closed when any of the
-   unbind API functions are called.
 
-   "Searching" section: added note that only a subset of the filter
-   functionality is available when communicating with an LDAPv2 server.
-   Clarified text to explain when a local timeout is used and when it is
-   not.
 
-   "Abandoning An Operation" section: removed some redundant text from
-   the paragraph that explains the differences between ldap_abandon()
-   and ldap_abandon_ext().
 
-   "Obtaining Results and Peeking Inside LDAP Messages" section: clari-
-   fied that ldap_result() only returns messages for one request at a
-   time.
 
-   "Handling Errors and Parsing Results" section: replace a few
-   occurrences of LDAPResult with LDAPMessage (there is no type called
-   LDAPResult).  Changed the names of the "resultoidp" and "resultdatap"
-   parameters to "retoidp" and "retdatap" to avoid confusion with LDAP
-   result messages.
 
-   "Stepping Through a List of Entries or References" section: added "or
-   References" to the section name to better reflect its contents.
-   Added missing description of "ref" parameter.  Added mention of
-   ldap_first_reference() and ldap_next_reference() in sentence about
-   function return values.
 
-   "Stepping Through the Attributes of an Entry" section:  added forward
-   reference for BerElement type.
 
-   "Parsing References" section: in the description of the "ref" parame-
-   ter, changed the phrase "these routines" to the more accurate "this
-   routine."
 
-   "Encoded ASN.1 Value Manipulation - General" section: changed text to
-   make sense given that the definition of BerElement now appears first
-   in the "Common Data Structures" section.
 
-   "Encoded ASN.1 Value Manipulation - Encoding" section: Changed the
-   style of function prototypes to better match the rest of the docu-
-   ment.  Corrected a typo in the ber_bvdup() description ("as the"
-   replaced with "than the").  Changed "null" to "NULL" where appropri-
-   ate to be consistent with use elsewhere in the document.  Removed
-   mention of sequences from the discussion of the LBER_USE_DER option.
-   Fixed some truncated sentences (by adding some missing '\' characters
-   to the nroff document source).
 
 
 
-Expires: 2 December 1999                                       [Page 77]
 
 
-C LDAP API        C LDAP Application Program Interface       2 June 1999
 
 
-   "Encoded ASN.1 Value Manipulation - Encoding Example" section:  sim-
-   plified the error handling in the example code through the use of a
-   'goto' statement.
 
-   "Encoded ASN.1 Value Manipulation - Decoding" section: Changed the
-   style of function prototypes to better match the rest of the docu-
-   ment.  Changed "null" to "NULL" and "null-terminated" to "zero-
-   terminated" where appropriate to be consistent with use elsewhere in
-   the document.  Fixed a typo (the text now says "an allocated" instead
-   of "a allocated.").  Clarified the description of the 'n' format
-   character for ber_scanf().
 
-   "Encoded ASN.1 Value Manipulation - Decoding Example" section:
-   changed code to not define a macro that begins with "LDAP" since that
-   prefix is reserved for the API.  Removed an extra 'i' from the format
-   string used in the first call to ber_scanf().  Changed error report-
-   ing code to send messages to stderr instead of stdout.  Changed
-   declaration of "res" local variable from "int" to "unsigned long" and
-   corrected one test of the ber_scanf() return value to test against
-   LBER_ERROR instead of -1.  Fixed improperly rendered strings (by
-   adding '\' characters to the nroff source for this document so that
-   '\t' and '\n' are correctly rendered).
 
-   "Acknowledgements" section: added the mention of Chris Weider.
-   Rephrased the text that gives credit to the National Science Founda-
-   tion (it now says "The original material upon which this specifica-
-   tion is based was supported by ..." instead of "This original
-   material upon which this revision is based was based upon work sup-
-   ported by ..."
 
-   In the "Bibliography" section:  Added a reference to RFC 1345 and
-   ANSI/ISO C.  Updated the LDAPv3 TLS and Sorting references to point
-   to the latest revisions of those documents.
 
-   "Appendix - Sample C LDAP API Code": added #include <stdio.h> to the
-   sample code.  Changed the code to demonstrate good error handling by
-   freeing all memory and calling ldap_unbind() before returning.
-   Replaced calls to exit() with return statements.  Fixed improperly
-   rendered strings (by adding '\' characters to the nroff source for
-   this document so that '\t' and '\n' are correctly rendered).
 
 
 
@@ -4438,6 +4552,6 @@ C LDAP API        C LDAP Application Program Interface       2 June 1999
 
 
 
-Expires: 2 December 1999                                       [Page 78]
+Expires: 8 April 2000                                          [Page 80]
 
 
diff --git a/doc/drafts/draft-ietf-ldapext-ldapv3-vlv-xx.txt b/doc/drafts/draft-ietf-ldapext-ldapv3-vlv-xx.txt
new file mode 100644 (file)
index 0000000..e7bb99e
--- /dev/null
@@ -0,0 +1,655 @@
+
+INTERNET-DRAFT                                   David Boreham, Netscape
+                                                 Jim Sermersheim, Novell
+                                                Anoop Anantha, Microsoft
+                                               Michael Armijo, Microsoft
+ldapext Working Group                                      6 April, 2000
+
+
+     LDAP Extensions for Scrolling View Browsing of Search Results
+
+                  draft-ietf-ldapext-ldapv3-vlv-04.txt
+                This document expires on 5 October 2000
+
+1.  Status of this Memo
+
+This document is an Internet-Draft and is in full conformance  with  all
+provisions  of Section 10 of RFC2026.  Internet-Drafts are working docu-
+ments of the Internet Engineering Task Force (IETF), its areas, and  its
+working  groups.   Note  that  other  groups may also distribute working
+documents as Internet-Drafts.
+
+Internet-Drafts are draft documents valid for a maximum  of  six  months
+and  may  be  updated,  replaced, or obsoleted by other documents at any
+time.  It is inappropriate to use Internet- Drafts as reference material
+or to cite them other than as "work in progress."
+
+The   list   of   current   Internet-Drafts   can   be    accessed    at
+http://www.ietf.org/ietf/1id-abstracts.txt
+
+The list  of  Internet-Draft  Shadow  Directories  can  be  accessed  at
+http://www.ietf.org/shadow.html.
+
+2.  Abstract
+
+This document describes a Virtual List View control  extension  for  the
+LDAP  Search  operation.  This control is designed to allow the "virtual
+list box" feature, common in existing  commercial  e-mail  address  book
+applications, to be supported efficiently by LDAP servers. LDAP servers'
+inability to support this client feature is a significant impediment  to
+LDAP replacing proprietary protocols in commercial e-mail systems.
+
+The control allows a client to specify that the  server  return,  for  a
+given  LDAP search with associated sort keys, a contiguous subset of the
+search result set. This subset is specified in terms of offsets into the
+ordered list, or in terms of a greater than or equal comparison value.
+
+3.  Background
+
+A Virtual List is a graphical user interface  technique  employed  where
+
+
+
+Boreham et al                                                   [Page 1]
+
+
+
+
+
+RFC DRAFT                                                     April 2000
+
+
+ordered lists containing a large number of entries need to be displayed.
+A window containing a small number of visible list entries is drawn. The
+visible  portion of the list may be relocated to different points within
+the list by means of user input. This input  can  be  to  a  scroll  bar
+slider; from cursor keys; from page up/down keys; from alphanumeric keys
+for "typedown".  The user is given the impression that they  may  browse
+the  complete  list  at  will,  even  though  it may contain millions of
+entries. It is the fact  that  the  complete  list  contents  are  never
+required  at  any one time that characterizes Virtual List View.  Rather
+than fetch the complete list from wherever it is stored (typically  from
+disk  or  a  remote  server), only that information which is required to
+display the part of the list currently in view is fetched.  The  subject
+of  this  document is the interaction between client and server required
+to implement this functionality in the context of  the  results  from  a
+sorted LDAP search request.
+
+For example, suppose an e-mail address book application displays a  list
+view  onto  the  list  containing the names of all the holders of e-mail
+accounts at a large  university.  The  list  is  sorted  alphabetically.
+While  there  may  be  tens  of  thousands  of entries in this list, the
+address book list view displays only 20 such accounts at any  one  time.
+The  list has an accompanying scroll bar and text input window for type-
+down.  When first displayed, the list view shows the first 20 entries in
+the  list,  and  the  scroll  bar slider is positioned at the top of its
+range. Should the user drag the slider to the bottom of its  range,  the
+displayed  contents  of the list view should be updated to show the last
+20 entries in the list. Similarly, if the slider is positioned somewhere
+in  the  middle  of  its travel, the displayed contents of the list view
+should be updated to contain the 20 entries  located  at  that  relative
+position  within the complete list.  Starting from any display point, if
+the user uses the cursor keys or clicks on the  scroll  bar  to  request
+that  the  list  be scrolled up or down by one entry, the displayed con-
+tents should be updated to reflect this. Similarly the  list  should  be
+displayed  correctly  when  the  user requests a page scroll up or down.
+Finally, when the user types characters in  the  type-down  window,  the
+displayed  contents of the list should "jump" or "seek" to the appropri-
+ate point within the list.  For example, if  the  user  types  "B",  the
+displayed  list could center around the first user with a name beginning
+with the letter "B".  When this happens, the scroll  bar  slider  should
+also be updated to reflect the new relative location within the list.
+
+This document defines a request control which extends  the  LDAP  search
+operation.  Always  used  in  conjunction  with  the server side sorting
+control[SSS], this allows a client  to  retrieve  selected  portions  of
+large  search result set in a fashion suitable for the implementation of
+a virtual list view.
+
+The key words "MUST", "SHOULD", and "MAY" used in this document  are  to
+
+
+
+Boreham et al                                                   [Page 2]
+
+
+
+
+
+RFC DRAFT                                                     April 2000
+
+
+be interpreted as described in [Bradner97].
+
+4.  Client-Server Interaction
+
+The Virtual List View control extends a regular  LDAP  Search  operation
+which must also include a server-side sorting control[SSS].  Rather than
+returning the complete set of  appropriate  SearchResultEntry  messages,
+the server is instructed to return a contiguous subset of those entries,
+taken from the sorted result set, centered around  a  particular  target
+entry. Henceforth, in the interests of brevity, the sorted search result
+set will be referred to as "the list".
+
+The sort control MAY  contain  any  sort  specification  valid  for  the
+server.  The  attributeType field in the first SortKeyList sequence ele-
+ment has special significance for "typedown".
+
+The desired target entry, and the number of entries to be returned  both
+before,  and after, that target entry in the list, are determined by the
+client's VirtualListViewRequest control.
+
+When the server returns the set of entries to the client, it attaches  a
+VirtualListViewResponse  control  to  the SearchResultDone message.  The
+server returns in this control: its current estimate for the  list  con-
+tent  count,  the  location  within the list corresponding to the target
+entry, and any error codes.
+
+The target entry is specified in the VirtualListViewRequest  control  by
+one  of  two methods. The first method is for the client to indicate the
+target entry's offset within the list.  The second way is for the client
+to  supply  an  attribute assertion value. The value is compared against
+the values of the attribute specified as the primary  sort  key  in  the
+sort  control  attached  to the search operation.  The first sort key in
+the SortKeyList is the primary sort key.  The target entry is the  first
+entry  in  the  list with value greater than or equal to (in the primary
+sort order), the presented value.  The  order  is  determined  by  rules
+defined  in  [SSS].   Selection  of  the  target  entry by this means is
+designed to implement "typedown".  Note that  it  is  possible  that  no
+entry  satisfies  these  conditions,  in  which  case there is no target
+entry. This condition is indicated by the server returning  the  special
+value contentCount + 1 in the target position field.
+
+Because the server may not have an accurate estimate of  the  number  of
+entries in the list, and to take account of cases where the list size is
+changing during the time the user browses  the  list,  and  because  the
+client  needs  a  way  to indicate specific list targets "beginning" and
+"end", offsets within the list are transmitted between client and server
+as  ratios---offset  to content count. The server sends its latest esti-
+mate as to the number of entries in the  list  (content  count)  to  the
+
+
+
+Boreham et al                                                   [Page 3]
+
+
+
+
+
+RFC DRAFT                                                     April 2000
+
+
+client  in  every  response control.  The client sends its assumed value
+for the content count in every request control.  The server examines the
+content  count  and  offsets  presented  by  the client and computes the
+corresponding offsets within the list, based on its own idea of the con-
+tent count.
+
+     Si = Sc * (Ci / Cc)
+
+     Where:
+     Si is the actual list offset used by the server
+     Sc is the server's estimate for content count
+     Ci is the client's submitted offset
+     Cc is the client's submitted content count
+     The result is rounded to the nearest integer.
+
+If the content count is stable, and the client returns to the server the
+content  count most recently received, Cc = Sc and the offsets transmit-
+ted become the actual server list offsets.
+
+The following special cases are allowed:  a  client  sending  a  content
+count  of zero (Cc = 0) means "client has no idea what the content count
+is, server MUST use its own content  count  estimate  in  place  of  the
+client's".  An offset value of one (Ci = 1) always means that the target
+is the first entry in the list. Client specifying an offset which equals
+the  content count specified in the same request control (Ci = Cc) means
+that the target is the last entry in the list.  Ci may only  equal  zero
+when Cc is also zero. This signifies the last entry in the list.
+
+Because the server always returns contentCount and  targetPosition,  the
+client  can always determine which of the returned entries is the target
+entry. Where the number of entries returned is the same  as  the  number
+requested,  the  client  is able to identify the target by simple arith-
+metic. Where the number of entries returned  is  not  the  same  as  the
+number  requested  (because the requested range crosses the beginning or
+end of the list, or both), the client must use the target  position  and
+content  count  values  returned  by  the  server to identify the target
+entry. For example, suppose that 10 entries before and 10 after the tar-
+get  were  requested, but the server returns 13 entries, a content count
+of 100 and a target position of 3. The client  can  determine  that  the
+first entry must be entry number 1 in the list, therefore the 13 entries
+returned are the first 13 entries in the list, and  the  target  is  the
+third one.
+
+A server-generated context identifier MAY be  returned  to  clients.   A
+client  receiving  a  context identifier SHOULD return it unchanged in a
+subsequent request which relates to the same list.  The purpose of  this
+interaction  is  to enhance the performance and effectiveness of servers
+which employ approximate positioning.
+
+
+
+Boreham et al                                                   [Page 4]
+
+
+
+
+
+RFC DRAFT                                                     April 2000
+
+
+5.  The Controls
+
+Support for the virtual list view control extension is indicated by  the
+presence  of  the  OID "2.16.840.1.113730.3.4.9" in the supportedControl
+attribute of a server's root DSE.
+
+5.1.  Request Control
+
+This control is included in the SearchRequest message  as  part  of  the
+controls  field  of  the  LDAPMessage,  as  defined in Section 4.1.12 of
+[LDAPv3].  The controlType is set to "2.16.840.1.113730.3.4.9". The cri-
+ticality   SHOULD be set to TRUE. If this control is included in a Sear-
+chRequest message, a Server Side Sorting request control [SSS] MUST also
+be  present  in  the  message. The controlValue is an OCTET STRING whose
+value is the BER-encoding of the following SEQUENCE:
+
+          VirtualListViewRequest ::= SEQUENCE {
+                  beforeCount    INTEGER (0..maxInt),
+                  afterCount     INTEGER (0..maxInt),
+                  CHOICE {
+                          byoffset [0] SEQUENCE {
+                           offset          INTEGER (0 .. maxInt),
+                           contentCount    INTEGER (0 .. maxInt) },
+                          greaterThanOrEqual [1] AssertionValue },
+                  contextID     OCTET STRING OPTIONAL }
+
+beforeCount indicates how many  entries  before  the  target  entry  the
+client  wants  the  server  to  send. afterCount indicates the number of
+entries after the target entry the client  wants  the  server  to  send.
+offset and contentCount identify the target entry as detailed in section
+4.  greaterThanOrEqual  is  an  attribute  assertion  value  defined  in
+[LDAPv3].  If  present, the value supplied in greaterThanOrEqual is used
+to determine the target entry by  comparison  with  the  values  of  the
+attribute  specified as the primary sort key. The first list entry who's
+value is no less than (less than or equal to  when  the  sort  order  is
+reversed)  the  supplied value is the target entry. If present, the con-
+textID field contains the value of the most recently received  contextID
+field  from  a  VirtualListViewResponse control. The type AssertionValue
+and value maxInt are defined in  [LDAPv3].   contextID  values  have  no
+validity outwith the connection on which they were received.  That is, a
+client should not submit a contextID which it received from another con-
+nection, a connection now closed, or a different server.
+
+
+5.2.  Response Control
+
+This control is included in the SearchResultDone message as part of  the
+controls   field  of the  LDAPMessage, as  defined in Section  4.1.12 of
+
+
+
+Boreham et al                                                   [Page 5]
+
+
+
+
+
+RFC DRAFT                                                     April 2000
+
+
+[LDAPv3].
+
+The controlType is set to "2.16.840.1.113730.3.4.10". The criticality is
+FALSE (MAY be absent).  The controlValue is an OCTET STRING, whose value
+is the BER encoding of a value of the following SEQUENCE:
+
+     VirtualListViewResponse ::= SEQUENCE {
+             targetPosition    INTEGER (0 .. maxInt),
+             contentCount     INTEGER (0 .. maxInt),
+             virtualListViewResult ENUMERATED {
+             success (0),
+             operationsError (1),
+             unwillingToPerform (53),
+             insufficientAccessRights (50),
+             busy (51),
+             timeLimitExceeded (3),
+             adminLimitExceeded (11),
+             sortControlMissing (60),
+             offsetRangeError (61),
+             other (80) },
+             contextID     OCTET STRING OPTIONAL }
+
+targetPosition gives the list offset for the target entry.  contentCount
+gives  the  server's  estimate  of  the current number of entries in the
+list.  Together these give sufficient  information  for  the  client  to
+update  a  list box slider position to match the newly retrieved entries
+and identify the target entry. The contentCount value returned SHOULD be
+used  in  a  subsequent  VirtualListViewRequest control.  contextID is a
+server-defined octet string. If present, the contents of  the  contextID
+field  SHOULD be returned to the server by a client in a subsequent Vir-
+tualListViewRequest control.
+
+The virtualListViewResult codes which  are  common  to  the  LDAP  sear-
+chResponse  (adminLimitExceeded,  timeLimitExceeded, busy, operationsEr-
+ror, unwillingToPerform, insufficientAccessRights) have the  same  mean-
+ings  as  defined  in [LDAPv3], but they pertain specifically to the VLV
+operation.  For example, the server could exceed an administration limit
+processing  a  SearchRequest with a VirtualListViewRequest control. How-
+ever, the same administration limit would not  be  exceeded  should  the
+same  SearchRequest  be submitted by the client without the VirtualList-
+ViewRequest control.  In this case, the client  can  determine  that  an
+administration limit has been exceeded in servicing the VLV request, and
+can if it chooses resubmit the SearchRequest  without  the  VirtualList-
+ViewRequest control.
+
+insufficientAccessRights means that the server denied the client permis-
+sion to perform the VLV operation.
+
+
+
+
+Boreham et al                                                   [Page 6]
+
+
+
+
+
+RFC DRAFT                                                     April 2000
+
+
+If the server determines that the results of the search presented exceed
+the  range  provided  by  the  32-bit  offset  values,  it  MUST  return
+offsetRangeError.
+
+6.  Protocol Example
+
+Here we walk through the client-server interaction for a  specific  vir-
+tual list view example:  The task is to display a list of all 78564 peo-
+ple in the US company "Ace Industry".  This will be done by  creating  a
+graphical  user  interface  object  to display the list contents, and by
+repeatedly sending different versions of  the  same  virtual  list  view
+search  request  to the server. The list view displays 20 entries on the
+screen at a time.
+
+We form a search with baseDN "o=Ace Industry, c=us"; search  scope  sub-
+tree;  filter "objectClass=inetOrgPerson". We attach a server sort order
+control to the search, specifying ascending sort on attribute  "cn".  To
+this  base  search,  we  attach a virtual list view request control with
+contents determined by the user activity and  send  the  search  to  the
+server.  We  display the results from each search in the list window and
+update the slider position.
+
+When the list view is first displayed, we want to  initialize  the  con-
+tents showing the beginning of the list. Therefore, we set beforeCount =
+0, afterCount = 19, contentCount = 0, offset = 1 and send the request to
+the  server.  The  server duly returns the first 20 entries in the list,
+plus the content count = 78564 and  targetPosition  =  1.  We  therefore
+leave  the  scroll  bar  slider  at its current location (the top of its
+range).
+
+Say that next the user drags the scroll bar slider down to the bottom of
+its  range.   We now wish to display the last 20 entries in the list, so
+we set beforeCount = 19, afterCount = 0, contentCount = 78564, offset  =
+78564 and send the request to the server. The server returns the last 20
+entries in the list, plus the content count = 78564 and targetPosition =
+78564.
+
+Next the user presses a page up key. Our page size  is  20,  so  we  set
+beforeCount  =  0,  afterCount  =  19,  contentCount  =  78564, offset =
+78564-19-20 and send the request to the server. The server  returns  the
+preceding  20  entries  in  the list, plus the content count = 78564 and
+targetPosition = 78525.
+
+Now the user grabs the scroll bar slider and drags it to 68% of the  way
+down its travel. 68% of 78564 is 53424 so we set beforeCount = 9, after-
+Count = 10, contentCount = 78564, offset = 53424 and send the request to
+the  server.  The  server  returns the preceding 20 entries in the list,
+plus the content count = 78564 and targetPosition = 53424.
+
+
+
+Boreham et al                                                   [Page 7]
+
+
+
+
+
+RFC DRAFT                                                     April 2000
+
+
+Lastly, the user types the letter "B". We set beforeCount  =  9,  after-
+Count  =  10  and  greaterThanOrEqual  = "B". The server finds the first
+entry in the list not less  than  "B",  let's  say  "Babs  Jensen",  and
+returns the nine preceding entries, the target entry, and the proceeding
+10 entries.  The server returns content count = 78564 and targetPosition
+=  5234  and so the client updates its scroll bar slider to 6.7% of full
+scale.
+
+7.  Notes for Implementers
+
+While the feature is expected  to  be  generally  useful  for  arbitrary
+search  and  sort  specifications, it is specifically designed for those
+cases where the result set is very large.  The intention  is  that  this
+feature be implemented efficiently by means of pre-computed indices per-
+taining to a set of specific cases. For example, an offset  relating  to
+"all  the  employees in the local organization, sorted by surname" would
+be a common case.
+
+The intention for client software is that the feature should fit  easily
+with  the  host  platform's  graphical user interface facilities for the
+display of scrolling lists. Thus the task  of  the  client  implementers
+should  be  one of reformatting up the requests for information received
+from the list view code to match the format of  the  virtual  list  view
+request and response controls.
+
+Client implementers should note that any offset value  returned  by  the
+server  may  be  approximate. Do not design clients > which only operate
+correctly when offsets are exact.
+
+Server implementers using indexing technology which features approximate
+positioning  should  consider  returning context identifiers to clients.
+The use of a context identifier will allow  the  server  to  distinguish
+between client requests which relate to different displayed lists on the
+client. Consequently the server can decide more intelligently whether to
+reposition an existing database cursor accurately to within a short dis-
+tance of its current position, or to reposition to an approximate  posi-
+tion. Thus the client will see precise offsets for "short" repositioning
+(e.g. paging up or down), but approximate offsets for a  "long"  reposi-
+tion (e.g. a slider movement).
+
+Server implementers are free to return  status  code  unwillingToPerform
+should  their  server  be  unable  to service any particular VLV search.
+This might be because the resolution of the  search  is  computationally
+infeasible,  or  because excessive server resources would be required to
+service the search.
+
+Client implementers should note that this control is only defined  on  a
+client  interaction  with a single server. If a server returns referrals
+
+
+
+Boreham et al                                                   [Page 8]
+
+
+
+
+
+RFC DRAFT                                                     April 2000
+
+
+as a part of its response to the search request, the client is responsi-
+ble  for  deciding when and how to apply this control to the referred-to
+servers, and how to collate the results from multiple servers.
+
+
+8.  Relationship to "Simple Paged Results"
+
+These controls are designed to support the virtual list view, which  has
+proved  hard  to  implement  with  the  Simple  Paged  Results mechanism
+[SPaged]. However, the controls described  here  support  any  operation
+possible with the Simple Paged Results mechanism. The two mechanisms are
+not complementary, rather one has a superset of  the  other's  features.
+One  area where the mechanism presented here is not a strict superset of
+the Simple Paged Results scheme is that here we require a sort order  to
+be specified. No such requirement is made for paged results.
+
+
+9.  Security Considerations
+
+Server implementers may wish to consider whether  clients  are  able  to
+consume  excessive  server  resources  in requesting virtual list opera-
+tions. Access control to the feature itself; configuration options  lim-
+iting  the  feature's  use  to certain predetermined search base DNs and
+filters; throttling mechanisms designed to limit  the  ability  for  one
+client to soak up server resources, may be appropriate.
+
+Consideration should be given as to whether a client  will  be  able  to
+retrieve  the complete contents, or a significant subset of the complete
+contents of the directory using this feature. This may be undesirable in
+some  circumstances and consequently it may be necessary to enforce some
+access control.
+
+Clients can, using this control, determine how  many  entries  are  con-
+tained  within  a  portion  of  the  DIT. This may constitute a security
+hazard. Again, access controls may be appropriate.
+
+Server implementers SHOULD exercise caution concerning  the  content  of
+the  contextID.   Should the contextID contain internal server state, it
+may be possible for a malicious client to use that information  to  gain
+unauthorized access to information.
+
+10.  Acknowledgements
+
+Chris Weider of Microsoft co-authored a previous version of  this  docu-
+ment.
+
+
+
+
+
+
+Boreham et al                                                   [Page 9]
+
+
+
+
+
+RFC DRAFT                                                     April 2000
+
+
+11.  References
+
+[LDAPv3]
+     Wahl, M, S. Kille and T. Howes, "Lightweight Directory Access  Pro-
+     tocol (v3)", Internet Standard, December, 1997. RFC2251.
+
+[SPaged]
+     Weider, C, A. Herron, A.  Anantha,  and  T.  Howes,  "LDAP  Control
+     Extension  for  Simple   Paged   Results   Manipulation", September
+     1999. RFC2696
+
+[SSS]Wahl, M, A. Herron and T. Howes, "LDAP Control Extension for Server
+     Side  Sorting  of  Search  Results",  Internet  Draft, April, 1999.
+     Available as draft-ietf-asid-ldapv3-sorting-02.txt.
+
+[Bradner97]
+     Bradner, S., "Key Words for use in  RFCs  to  Indicate  Requirement
+     Levels", BCP 14, RFC 2119, March 1997.
+
+12.  Authors' Addresses
+
+   David Boreham
+   iPlanet e-commerce solutions
+   501 E. Middlefield Road
+   Mountain View, CA 94043, USA
+   +1 650 937-5206
+   dboreham@netscape.com
+
+   Jim Sermersheim
+   Novell
+   122 East 1700 South
+   Provo, Utah 84606, USA
+   jimse@novell.com
+
+   Anoop Anantha
+   Microsoft Corp.
+   1 Microsoft Way
+   Redmond, WA 98052, USA
+   +1 425 882-8080
+   anoopa@microsoft.com
+
+   Michael Armijo
+   Microsoft Corp.
+   1 Microsoft Way
+   Redmond, WA 98052, USA
+   +1 425 882-8080
+   micharm@microsoft.com
+   This document expires on 5 October 2000
+
+
+
+Boreham et al                                                  [Page 10]
+
+
+
+
+
+RFC DRAFT                                                     April 2000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Boreham et al                                                  [Page 11]
+
+
diff --git a/doc/drafts/draft-ietf-ldapext-locate-xx.txt b/doc/drafts/draft-ietf-ldapext-locate-xx.txt
new file mode 100644 (file)
index 0000000..3fb0d19
--- /dev/null
@@ -0,0 +1,205 @@
+INTERNET-DRAFT                                         Michael P. Armijo
+<draft-ietf-ldapext-locate-02.txt>                          Levon Esibov
+April, 2000                                                   Paul Leach
+Expires: October, 2000                             Microsoft Corporation
+                                                            R.L. Morgan
+                                               University of Washington
+
+                Discovering LDAP Services with DNS
+
+Status of this Memo
+
+   This document is an Internet-Draft and is in full conformance with
+   all provisions of Section 10 of RFC2026.
+
+   Internet-Drafts are working documents of the Internet Engineering
+   Task Force (IETF), its areas, and its working groups.  Note that
+   other groups may also distribute working documents as Internet-
+   Drafts.
+
+   Internet-Drafts are draft documents valid for a maximum of six months
+   and may be updated, replaced, or obsoleted by other documents at any
+   time.  It is inappropriate to use Internet- Drafts as reference
+   material or to cite them other than as "work in progress."
+
+   The list of current Internet-Drafts can be accessed at
+   http://www.ietf.org/ietf/1id-abstracts.txt
+
+   The list of Internet-Draft Shadow Directories can be accessed at
+   http://www.ietf.org/shadow.html.
+
+   Distribution of this memo is unlimited.  It is filed as <draft-
+   ietf-ldapext-locate-02.txt>, and expires on October 15, 2000.  
+   Please send comments to the authors.
+
+
+1. Abstract
+
+   A Lightweight Directory Access Protocol (LDAP) request must be
+   directed to an appropriate server for processing.  This document
+   specifies a method for discovering such servers using information in
+   the Domain Name System. 
+
+
+2. Introduction
+
+   The LDAPv3 protocol [1] is designed to be a lightweight access
+   protocol for directory services supporting X.500 models.  As a
+   distributed directory service, the complete set of directory
+   information (known as the Directory Information Base) is spread
+   across many different servers.  Hence there is the need to
+   determine, when initiating or processing a request, which servers
+   hold the relevant information.  In LDAP, the Search, Modify, Add,
+   Delete, ModifyDN, and Compare operations all specify a Distinguished
+   Name (DN) [2] on which the operation is performed.  A client, or a
+   server acting on behalf of a client, must be able to determine the
+   server(s) that hold the naming context containing that DN, since
+   that server (or one of that set of servers) must receive and process
+   the request.  This determination process is called "server
+   location".  To support dynamic distributed operation, the
+   information needed to support server location must be available via
+   lookups done at request processing time, rather than, for example,
+   as static data configured into each client or server.
+
+   It is possible to maintain the information needed to support server
+   location in the directory itself, and X.500 directory deployments
+   typically do so.  In practice, however, this only permits location
+   of servers within a limited X.500-connected set.  LDAP-specific
+   methods of maintaining server location information in the directory
+   have not yet been standardized.  This document defines an
+   alternative method of managing server location information using the
+   Domain Name System. This method takes advantage of the global
+   deployment of the DNS, by allowing LDAP server location information
+   for any existing DNS domain to be published by creating the records
+   described below.  A full discussion of the benefits and drawbacks of
+   the various directory location and naming methods is beyond the
+   scope of this document.
+
+   RFC 2247[3] defines an algorithm for mapping DNS domain names into
+   DNs.  This document defines the inverse mapping, from DNs to DNS
+   domain names, based on the conventions in [3], for use in this
+   server location method.  The server location method described in
+   this document is only defined for DNs that can be so mapped, i.e.,
+   those DNs that are based on domain names.  In practice this is
+   reasonable because many objects of interest are named with domain
+   names, and use of domain-name-based DNs is becoming common.
+
+
+3. Mapping Distinguished Names into Domain Names
+
+   This section defines a method of converting a DN into a DNS domain
+   name for use in the server location method described below.  Some
+   DNs cannot be converted into a domain name.
+
+   The output domain name is initially empty.  For each RDN component
+   of the DN, beginning with the first, if the attribute type is "DC",
+   then the attribute value is used as a domain name component (label).
+   The first such value becomes the most significant (i.e., rightmost)
+   domain name component, and successive values occupy less significant
+   positions (i.e., extending leftward), in order.  If the attribute
+   type is not "DC", then processing stops.  If the first RDN component
+   of the DN is not of type "DC" then the DN cannot be converted to a
+   domain name.
+
+
+4. Locating LDAP servers through DNS
+
+   LDAP server location information is to be stored using DNS Service
+   Location Record (SRV)[5].  The data in a SRV record contains the DNS
+   name of the server that provides the LDAP service, corresponding
+   Port number, and parameters that enable the client to choose an
+   appropriate server from multiple servers according to the algorithm
+   described in [5].  The name of this record has the following format:
+
+      _<Service>._<Proto>.<Domain>
+
+   where <Service> is always "ldap", and <Proto> is a protocol that can
+   be either "udp" or "tcp".  <Domain> is the domain name formed by
+   converting the DN of a naming context mastered by the LDAP Server
+   into a domain name using the algorithm in Section 2.  Note that
+   "ldap" is the symbolic name for the LDAP service in Assigned
+   Numbers[6], as required by [5].
+
+   Presence of such records enables clients to find the LDAP servers
+   using standard DNS query [4].  A client (or server) seeking an LDAP
+   server for a particular DN converts that DN to a domain name using
+   the algorithm of Section 2, does a SRV record query using the DNS
+   name formed as described in the preceding paragraph, and interprets
+   the response as described in [5] to determine a host (or hosts) to
+   contact. As an example, a client that searches for an LDAP server
+   for the DN "ou=foo,dc=example,dc=net" that supports the TCP protocol
+   will submit a DNS query for a set of SRV records with owner name:
+
+      _ldap._tcp.example.net.
+
+   The client will receive the list of SRV records published in DNS
+   that satisfy the requested criteria.  The following is an example of
+   such a record:
+
+      _ldap._tcp.example.net.   IN       SRV  0 0 389 phoenix.example.net.
+
+   The set of returned records may contain multiple records in the case
+   where multiple LDAP servers serve the same domain.
+
+
+
+5. Security Considerations
+
+   This document describes a method that uses DNS SRV records to 
+   discover LDAP servers.  All security considerations related to DNS
+   SRV records are inherited by this document.  See the security 
+   considerations section in [6] for more details.
+
+
+6. References
+
+   [1]  Wahl, M., Howes, T. and S. Kille, "Lightweight Directory Access
+        Protocol(v3)", RFC 2251, December 1997.
+
+   [2]  Wahl, M., Kille, S. and T. Howes, "Lightweight Directory Access
+        Protocol (v3):  UTF-8 String Representation of Distinguished
+        Names", RFC 2253, December 1997.
+
+   [3]  Kille, S. and M. Wahl, "Using Domains in LDAP/X.500
+        Distinguished Names", RFC 2247, January 1998.
+
+   [4]  Mockapetris, P., "DOMAIN NAMES - CONCEPTS AND FACILITIES", RFC
+        1034, STD 13, November 1987.
+
+   [5]  Gulbrandsen, A., Vixie, P. and L. Esibov, "A DNS RR for
+        specifying the location of services (DNS SRV)", RFC 2782,
+        February 2000.
+
+   [6]  Reynolds, J. and J. Postel, "Assigned Numbers", STD 2, RFC
+        1700, October 1994.
+
+
+6. Authors' Addresses
+
+   Michael P. Armijo
+   One Microsoft Way
+   Redmond, WA 98052
+   micharm@microsoft.com
+
+   Paul Leach
+   One Microsoft Way
+   Redmond, WA 98052
+   paulle@microsoft.com
+
+   Levon Esibov
+   One Microsoft Way
+   Redmond, WA 98052
+   levone@microsoft.com
+
+   RL "Bob" Morgan
+   University of Washington
+   4545 15th Ave NE
+   Seattle, WA  98105
+   US
+
+   Phone: +1 206 221 3307
+   EMail: rlmorgan@washington.edu
+   URI:   http://staff.washington.edu/rlmorgan/
+
+   Expires October, 2000
+
diff --git a/doc/drafts/draft-ietf-ldapext-sorting-xx.txt b/doc/drafts/draft-ietf-ldapext-sorting-xx.txt
new file mode 100644 (file)
index 0000000..8a7b99f
--- /dev/null
@@ -0,0 +1,303 @@
+
+Network Working Group                             A. Herron, Microsoft
+INTERNET DRAFT                                      T. Howes, Netscape
+Expire in six months                       M. Wahl, Critical Angle Inc
+                                                 A. Anantha, Microsoft
+                                                         April 5, 1999
+
+   LDAP Control Extension for Server Side Sorting of Search Results
+               draft-ietf-ldapext-sorting-02.txt
+
+
+1.  Status of this Memo
+
+This document is an Internet-Draft.  Internet-Drafts are  working docu-
+ments  of the Internet Engineering Task Force (IETF), its areas, and its
+working groups.  Note that other  groups  may  also  distribute working
+documents as Internet-Drafts.
+
+Internet-Drafts are draft documents valid for a maximum  of  six months
+and  may  be  updated,  replaced, or obsoleted by other documents at any
+time.  It is inappropriate to use Internet- Drafts as reference material
+or to cite them other than as ``work in progress.''
+
+To learn the current status of  any  Internet-Draft,  please  check the
+``1id-abstracts.txt''  listing  contained in the Internet- Drafts Shadow
+Directories on ds.internic.net (US East Coast), nic.nordu.net (Europe),
+ftp.isi.edu (US West Coast), or munnari.oz.au (Pacific Rim).
+
+This document expires on October 5, 1999.
+
+2.  Abstract
+
+This  document  describes two LDAPv3 control extensions for  server side
+sorting of search results. These controls allows a client to specify the
+attribute types and  matching rules a  server should  use when returning
+the results to an LDAP search request.  The controls may be useful when
+the  LDAP client  has limited  functionality or  for some  other reason
+cannot sort the results  but still needs them sorted.  Other permissible
+controls on search operations are not defined in this extension.
+
+The sort controls allow a server to return a result code for the sorting
+of the results  that is independent  of the result code returned for the
+search operation.
+
+The key words "MUST", "SHOULD", and "MAY" used in this document are to
+be interpreted as described in [bradner97].
+
+3.  The Controls
+
+3.1 Request Control
+
+This control is  included in  the searchRequest  message as  part of the
+controls  field  of the  LDAPMessage, as  defined in  Section  4.1.12 of
+[LDAPv3].
+
+The controlType is set to "1.2.840.113556.1.4.473". The criticality
+MAY be either TRUE or FALSE (where absent is also equivalent to
+FALSE) at the client's option.  The controlValue is an OCTET STRING,
+whose value is the BER encoding of a value of the following SEQUENCE:
+
+     SortKeyList ::= SEQUENCE OF SEQUENCE {
+                attributeType   AttributeDescription,
+                orderingRule    [0] MatchingRuleId OPTIONAL,
+                reverseOrder    [1] BOOLEAN DEFAULT FALSE }
+
+The SortKeyList sequence is in order of highest to lowest sort key
+precedence.
+
+The MatchingRuleID SHOULD be one that is valid for the attribute type 
+it applies to. If it is not, the server MUST return unwillingToPerform.
+
+Each attributeType should only  occur in the  SortKeyList  once.  If an
+attributeType is included in  the sort  key list  multiple  times,  the
+server should return an error in the sortResult of unwillingToPerform.
+
+If the orderingRule is omitted, the ordering MatchingRule defined for use
+with this attribute MUST be used.
+
+Any conformant implementation of this control MUST allow a sort key 
+list with at least one key.
+
+3.2 Response Control
+
+This control is included in the searchResultDone message as part of the
+controls  field  of the  LDAPMessage, as  defined in Section  4.1.12 of
+[LDAPv3].
+
+The controlType is set to "1.2.840.113556.1.4.474". The criticality is
+FALSE (MAY be absent).  The controlValue is an OCTET STRING, whose
+value is the BER encoding of a value of the following SEQUENCE:
+
+     SortResult ::= SEQUENCE {
+        sortResult  ENUMERATED {
+            success                   (0), -- results are sorted
+            operationsError           (1), -- server internal failure
+            timeLimitExceeded         (3), -- timelimit reached before
+                                           -- sorting was completed
+            strongAuthRequired        (8), -- refused to return sorted
+                                           -- results via insecure
+                                           -- protocol
+            adminLimitExceeded       (11), -- too many matching entries
+                                           -- for the server to sort
+            noSuchAttribute          (16), -- unrecognized attribute
+                                           -- type in sort key
+            inappropriateMatching    (18), -- unrecognized or inappro-
+                                           -- priate matching rule in
+                                           -- sort key
+            insufficientAccessRights (50), -- refused to return sorted
+                                           -- results to this client
+            busy                     (51), -- too busy to process
+            unwillingToPerform       (53), -- unable to sort
+            other                    (80)
+            },
+      attributeType [0] AttributeDescription OPTIONAL }
+
+4.  Client-Server Interaction
+
+The  sortKeyRequestControl  specifies one  or more  attribute types and
+matching rules for the results returned by a search request. The server
+SHOULD return all results for the search request in the order specified
+by the sort keys.  If the  reverseOrder field is set  to TRUE, then the
+entries will  be presented in  reverse sorted  order for  the specified
+key.
+
+There are six possible scenarios that may occur as a result of the sort
+control being included on the search request :
+
+1 - If the server does not support this sorting control and the client
+specified TRUE for the control's criticality field, then the server
+MUST return unavailableCriticalExtension as a return code in the
+searchResultDone message and not send back any other results.  This
+behavior is specified in section 4.1.12 of [LDAPv3].
+
+2 - If the server does not support this sorting control and the client
+specified FALSE for the control's criticality field, then the server
+MUST ignore the sort control and process the search request as if it
+were not present.  This behavior is specified in section 4.1.12 of
+[LDAPv3].
+
+3 - If the server supports this sorting control but for some reason
+cannot sort the search results using the specified sort keys and the
+client specified TRUE for the control's criticality field, then the
+server SHOULD do the following: return unavailableCriticalExtension as
+a return code in the searchResultDone message; include the
+sortKeyResponseControl in the searchResultDone message, and not send
+back any search result entries.
+
+4 - If the server supports this sorting control but for some reason
+cannot sort the search results using the specified sort keys and the
+client specified FALSE for the control's criticality field, then the
+server should return all search results unsorted and include the
+sortKeyResponseControl in the searchResultDone message.
+
+5 - If the server supports this sorting control and can sort the search
+results using the specified sort keys, then it should include the
+sortKeyResponseControl in the searchResultDone message with a
+sortResult of success.
+
+6 - If the search request failed for any reason and/or there are no
+searchResultEntry messages returned for the search response, then the
+server SHOULD omit the sortKeyResponseControl from the
+searchResultDone message.
+
+The client application is assured that the results are sorted in the
+specified key order if and only if the result code in the
+sortKeyResponseControl is success.  If the server omits the
+sortKeyResponseControl from the searchResultDone message, the client
+SHOULD assume that the sort control was ignored by the server.
+
+The sortKeyResponseControl, if included by the server in the
+searchResultDone message, should have the sortResult set to either
+success if the results were sorted in accordance with the keys 
+specified in the sortKeyRequestControl or set to the appropriate error
+code as to why it could not sort the data (such as noSuchAttribute or
+inappropriateMatching).  Optionally, the server MAY set the
+attributeType to the first attribute type specified in the SortKeyList
+that was in error.  The client SHOULD ignore the attributeType field if
+the sortResult is success.
+
+The server may not be able to sort the results using the specified sort
+keys because it may not recognize one of the attribute types, the
+matching rule associated with an attribute type is not applicable, or
+none of the attributes in the search response are of these types.
+Servers may also restrict the number of keys allowed in the control,
+such as only supporting a single key.
+
+Servers that chain requests to other LDAP servers should ensure that
+the server satisfying the client's request sort the entire result set
+prior to sending back the results.
+
+4.1 Behavior in a chained environment
+
+If a server receives a sort request, the client expects to receive a 
+set of sorted results. If a client submits a sort request to a server 
+which chains the request and gets entries from multiple servers, and 
+the client has set the criticality of the sort extension to TRUE, the 
+server MUST merge sort the results before returning them to the client 
+or MUST return unwillingToPerform.
+
+4.2 Other sort issues
+
+An entry that meets the search criteria may be missing one or more of 
+the sort keys. In that case, the entry is considered to have a value of 
+NULL for that key. This standard considers NULL to be a larger value 
+than all other valid values for that key. For example, if only one key 
+is specified, entries which meet the search criteria but do not have 
+that key collate after all the entries which do have that key. If the 
+reverseOrder flag is set, and only one key is specified, entries which 
+meet the search criteria but do not have that key collate BEFORE all 
+the entries which do have that key.  
+
+If a sort key is a multi-valued attribute, and an entry happens to have 
+multiple values for that attribute and no other controls are present that
+affect the sorting order, then the server SHOULD use the least value
+(according to the ORDERING rule for that attribute).
+
+5.  Interaction with other search controls
+
+When the sortKeyRequestControl control is included with the
+pagedResultsControl control as specified in [LdapPaged], then the
+server should send the searchResultEntry messages sorted according to
+the sort keys applied to the entire result set.  The server should not
+simply sort each page, as this will give erroneous results to the
+client.
+
+The sortKeyList must be present on each searchRequest message for the
+paged result.  It also must not change between searchRequests for the
+same result set.  If the server has sorted the data, then it SHOULD
+send back a sortKeyResponseControl control on every searchResultDone
+message for each page.  This will allow clients to quickly determine
+if the result set is sorted, rather than waiting to receive the entire
+result set.
+
+
+6.  Security Considerations
+
+Implementors and administrators should be aware that allowing sorting
+of results could enable the retrieval of a large number of records from
+a given directory service, irregardless of administrative limits set on
+the maximum number of records to return.
+
+A client that desired to pull all records out of a directory service
+could use a combination of sorting and updating of search filters to
+retrieve all records in a database in small result sets, thus
+circumventing administrative limits.
+
+This behavior can be overcome by the judicious use of permissions on
+the directory entries by the administrator and by intelligent
+implementations of administrative limits on the number of records
+retrieved by a client.
+
+
+7.  References
+
+[LDAPv3]
+     Wahl, M, S. Kille and T. Howes, "Lightweight Directory Access  
+Pro-
+     tocol  (v3)",  RFC 2251, December, 1997. 
+
+[Bradner97]
+     Bradner, Scott, "Key Words for use in RFCs to Indicate  
+Requirement
+     Levels",   RFC 2119,  March,  1997.  
+
+[LdapPaged]
+    C. Weider, A. Herron, and T. Howes, "LDAP Control Extension for
+    Simple Paged Results Manipulation", Internet Draft, February, 1997.
+    Available as draft-ietf-asid-ldapv3-simplepaged-00.txt.
+
+
+8.  Author's Address
+
+   Anoop Anantha
+   Microsoft Corp.
+   1 Microsoft Way
+   Redmond, WA 98052
+   USA
+   Anoopa@microsoft.com
+   +1 425 882-8080
+   
+   Andy Herron
+   Microsoft Corp.
+   1 Microsoft Way
+   Redmond, WA 98052
+   USA
+   andyhe@microsoft.com
+   +1 425 882-8080
+
+   Tim Howes
+   Netscape Communications Corp.
+   501 E. Middlefield Road
+   Mountain View, CA 94043
+   USA
+   howes@netscape.com
+   +1 415 937-2600
+
+   Mark Wahl
+   Critical Angle Inc.
+   4815 W Braker Lane #502-385
+   Austin, TX 78759
+   USA
+   M.Wahl@critical-angle.com
+   
diff --git a/doc/drafts/draft-ietf-ldup-framing-xx.txt b/doc/drafts/draft-ietf-ldup-framing-xx.txt
new file mode 100644 (file)
index 0000000..404e8ac
--- /dev/null
@@ -0,0 +1,340 @@
+
+Extended Operations for Framing LDAP Operations
+Internet-Draft
+Intended Category: Standards Track
+Expires: September 10, 2000
+
+
+                                                            Ellen Stokes
+                                                         IBM Corporation
+
+                                                          Roger Harrison
+                                                            Novell, Inc.
+
+                                                             Gordon Good
+                                           Netscape Communications Corp.
+
+                                                          March 10, 2000
+
+            Extended Operations for Framing LDAP Operations
+                Filename: draft-ietf-ldup-framing-00.txt
+
+Table of Contents
+
+1.    Status of this Memo.............................................2
+2.    Abstract........................................................2
+3.    Overview........................................................2
+4.    Protocol element definitions....................................3
+4.1   StartFramedProtocolRequest Extended Operation...................3
+4.2   StartFramedProtocolResponse Extended Operation..................3
+4.3   EndFramedProtocolRequest Extended Operation.....................4
+4.4   EndFramedProtocolResponse Extended Operation....................4
+5.    Acknowledgments.................................................5
+6.    References......................................................5
+7.    Author's Addresses..............................................5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stokes, Harrison and Good                                       [Page 1]
+\f
+Internet-Draft               LDUP Workgroup               March 10, 2000
+
+
+1. Status of this Memo
+
+   This document is an Internet-Draft and is in full conformance with
+   all provisions of Section 10 of RFC2026.
+
+   Internet-Drafts are working documents of the Internet Engineering
+   Task Force (IETF), its areas, and its working groups. Note that other
+   groups may also distribute working documents as Internet-Drafts.
+
+   Internet-Drafts are draft documents valid for a maximum of six months
+   and may be updated, replaced, or obsoleted by other documents at any
+   time.  It is inappropriate to use Internet- Drafts as reference
+   material or to cite them other than as "work in progress."
+
+    The list of current Internet-Drafts can be accessed at
+     http://www.ietf.org/ietf/1id-abstracts.txt
+
+     The list of Internet-Draft Shadow Directories can be accessed at
+     http://www.ietf.org/shadow.html.
+
+.
+
+   This Internet Draft expires September 10, 2000.
+
+
+2. Abstract
+
+   Certain types of LDAP applications can benefit from the ability to
+   specify the beginning and end of a related group of operations.  For
+   example, the LDUP multimaster update protocol [ARCHITECTURE] requires
+   that two servers agree to begin a session to transfer pending
+   replication updates. This document provides a framework for
+   constructing protocols that feature a framed set of related
+   operations.  It defines a pair of LDAPv3 extended operations that
+   provide begin-end framing, and a pair of extended operations used to
+   respond the begin-end framing operations. The nature of the actual
+   LDAP operations carried inside these framing operations is not
+   specified in this document.
+
+   All protocol elements described here are LDAP Version 3 extended
+   operations. LDAP Version 3 is described in RFC 2251 [LDAPv3].
+
+   Certain terms used in this document are defined in the document "LDAP
+   Replication Architecture" [ARCHITECTURE].
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", and "MAY" in this document are
+   to be interpreted as described in RFC 2119 [KEYWORDS].
+
+3. Overview
+
+   This document describes two LDAPv3 Extended Operations that are used
+   to signal the beginning and end of a set of grouped operations, and
+
+
+
+Stokes, Harrison and Good                                       [Page 2]
+\f
+Internet-Draft               LDUP Workgroup               March 10, 2000
+
+
+   two LDAPv3 extended operations that are used to respond to these
+   operations. These extended operations provide a framework that may be
+   used when developing a protocol that requires begin-end framing.
+
+4. Protocol element definitions
+
+4.1 StartFramedProtocolRequest Extended Operation
+
+   The StartFramedProtocolRequest extended operation indicates that the
+   initiator wishes to begin transmission of a set of related LDAP
+   operations. The requestValue of the StartFramedProtocolRequest
+   extended operation contains an OID that describes the specific framed
+   protocol being initiated, and a protocol-specific payload.
+
+   An LDAPv3 Extended Request is defined in [LDAPv3] as follows:
+
+      ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
+          requestName    [0] LDAPOID,
+          requestValue   [1] OCTET STRING OPTIONAL
+      }
+
+   The requestName portion of the StartFramedProtocolRequest must be the
+   OID "2.16.840.1.113719.1.142.100.1".
+
+   The requestValue of the StartFramedProtocolRequest must be set to the
+   BER-encoding of the following:
+
+      StartFramedProtocolRequestValue ::= SEQUENCE {
+                framedProtocolOID LDAPOID,
+                framedProtocolPayload OPTIONAL OCTET STRING
+      }
+
+   The parameters in the requestValue of the StartFramedProtocolRequest
+   are:
+
+      - framedProtocolOID: An OID that uniquely identifies the protocol
+        framed by this operation.  - framedProtocolPayload: An octet
+      string that contains protocol-specific
+        information.
+
+
+4.2 StartFramedProtocolResponse Extended Operation
+
+   The StartFramedProtocolResponse extended operation is sent in
+   response to a StartFramedProtocolResponse extended operation.
+
+   An LDAPv3 Extended Response is defined in [LDAPv3] as follows:
+
+
+
+
+Stokes, Harrison and Good                                       [Page 3]
+\f
+Internet-Draft               LDUP Workgroup               March 10, 2000
+
+
+      ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
+          COMPONENTS of LDAPResult,
+          responseName  [10] LDAPOID OPTIONAL,
+          response      [11] OCTET STRING OPTIONAL
+      }
+
+   The responseName of the StartFramedProtocolResponse must be the OID
+   "2.16.840.1.113719.1.142.100.2".
+
+   The response of the StartFramedProtocolResponse is set to the BER-
+   encoding of a protocol-specific response.
+
+4.3 EndFramedProtocolRequest Extended Operation
+
+   The EndFramedProtocolRequest extended operation indicates the end a
+   set of related LDAP operations. The requestValue of the
+   EndFramedProtocolRequest extended operation contains a protocol-
+   specific payload.
+
+   An LDAPv3 Extended Request is defined in [LDAPv3] as follows:
+
+      ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
+          requestName    [0] LDAPOID,
+          requestValue   [1] OCTET STRING OPTIONAL
+      }
+
+   The requestName of the EndFramedProtocolRequest must be the OID
+   "2.16.840.1.113719.1.142.100.4".
+
+   The requestValue of the EndFramedProtocolRequest is set to the BER-
+   encoding of a protocol-specific response.
+
+4.4 EndFramedProtocolResponse Extended Operation
+
+   The EndFramedProtocolResponse extended operation is sent in response
+   to an EndFramedProtocolRequest.
+
+   An LDAPv3 Extended Response is defined in [LDAPv3] as follows:
+
+      ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
+          COMPONENTS of LDAPResult,
+          responseName  [10] LDAPOID OPTIONAL,
+          response      [11] OCTET STRING OPTIONAL
+      }
+
+   The responseName of the EndFramedProtocolResponse must be the OID
+   "2.16.840.1.113719.1.142.100.5".
+
+
+
+
+Stokes, Harrison and Good                                       [Page 4]
+\f
+Internet-Draft               LDUP Workgroup               March 10, 2000
+
+
+   The response of the EndFramedProtocolResponse is set to the BER-
+   encoding of a protocol-specific response.
+
+5. Acknowledgments
+
+The authors gratefully acknowledge the contributions of the IETF LDUP
+working group.
+
+6. References
+
+
+[KEYWORDS]
+     S. Bradner, "Key Words for use in RFCs to Indicate Requirement Lev-
+     els", Harvard University, RFC 2119, March 1997.
+
+
+[ARCHITECTURE]
+     J. Merrells, E. Reed, U. Srinivasan, "LDAP Replication Architec-
+     ture", Internet-Draft, draft-ietf-ldup-model-02.txt, October 1999.
+
+
+[LDAPv3]
+     M. Wahl, S. Kille, T. Howes, "Lightweight Directory Access Protocol
+     (v3)", RFC 2251, December 1997.
+
+7. Author's Addresses
+
+   Ellen Stokes
+   IBM
+   11400 Burnet Rd
+   Austin, TX 78758
+   USA
+   EMail: stokes@austin.ibm.com
+   phone: +1 512 838 3725
+   fax:   +1 512 838 0156
+
+   Roger Harrison
+   Novell, Inc.
+   122 E. 1700 S.
+   Provo, UT 84606
+   USA
+   EMail: roger_harrison@novell.com
+   Phone: +1 801 861 2642
+
+   Gordon Good
+   Netscape Communications Corp.
+   501 E. Middlefield Rd.
+   Mailstop MV068
+
+
+
+Stokes, Harrison and Good                                       [Page 5]
+\f
+Internet-Draft               LDUP Workgroup               March 10, 2000
+
+
+   Mountain View, CA 94043
+   USA
+   EMail:  ggood@netscape.com
+   Phone:  +1 650 937-3825
+
+
+Appendix A - Complete ASN.1 Definition
+
+StartFramedProtocolRequest ::= ExtendedRequest
+
+StartFramedProtocolRequestValue ::= SEQUENCE {
+          framedProtocolOID LDAPOID,
+          framedProtocolPayload OPTIONAL OCTET STRING
+}
+
+StartFramedProtocolResponse ::= ExtendedResponse
+
+EndFramedProtocolRequest ::= ExtendedRequest
+
+EndFramedProtocolResponse ::= ExtendedResponse
+
+Full Copyright Statement
+
+Copyright (C) The Internet Society (1999).  All Rights Reserved.
+
+This document and translations of it may be copied and furnished to oth-
+ers, and derivative works that comment on or otherwise explain it or
+assist in its implementation may be prepared, copied, published and dis-
+tributed, in whole or in part, without restriction of any kind, provided
+that the above copyright notice and this paragraph are included on all
+such copies and derivative works.  However, this document itself may not
+be modified in any way, such as by removing the copyright notice or
+references to the Internet Society or other Internet organizations,
+except as needed for the purpose of developing Internet standards in
+which case the procedures for copyrights defined in the Internet Stan-
+dards process must be followed, or as required to translate it into
+languages other than English.
+
+The limited permissions granted above are perpetual and will not be
+revoked by the Internet Society or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS
+IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK
+FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT
+INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FIT-
+NESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+Stokes, Harrison and Good                                       [Page 6]
diff --git a/doc/drafts/draft-ietf-ldup-infomod-xx.txt b/doc/drafts/draft-ietf-ldup-infomod-xx.txt
new file mode 100644 (file)
index 0000000..b1e5ab1
--- /dev/null
@@ -0,0 +1,1021 @@
+INTERNET-DRAFT 
+draft-ietf-ldup-infomod-01.txt 
+                                                     Ed Reed 
+                                         Reed-Matthews, Inc. 
+                                               March 9, 2000 
+                                                             
+        LDUP Replication Information Model 
+
+
+1. Status of this Memo 
+
+This document is an Internet-Draft and is in full conformance with all 
+provisions of Section 10 of RFC2026. 
+
+Internet-Drafts are working documents of the Internet Engineering Task 
+Force (IETF), its areas, and its working groups. Note that other 
+groups may also distribute working documents as Internet-Drafts.  
+
+Internet-Drafts are draft documents valid for a maximum of six months 
+and may be updated, replaced, or obsoleted by other documents at any 
+time. It is inappropriate to use Internet-Drafts as reference material 
+or to cite them other than as "work in progress."  
+
+The list of current Internet-Drafts can be accessed at 
+http://www.ietf.org/ietf/1id-abstracts.txt.  
+
+The list of Internet-Draft Shadow Directories can be accessed at 
+http://www.ietf.org/shadow.html. 
+
+This Internet-Draft expires on May 11, 1999. 
+
+
+2. Abstract 
+
+[LDUP Model] describes the architectural approach to replication of 
+LDAP directory contents.  This document describes the information 
+model and schema elements which support LDAP Replication Services 
+which conform to [LDUP Model]. 
+
+Directory schema is extended to provide object classes, subentries, 
+and attributes to describe areas of the namespace which are under 
+common administrative authority, units of replication (ie, subtrees, 
+or partitions of the namespace, which are replicated), servers which 
+hold replicas of various types for the various partitions of the 
+namespace, which namespaces are held on given servers, and the 
+progress of various namespace management and replication operations.  
+Among other things, this knowledge of where directory content is 
+
+
+
+Reed                                                         [Page 1] 
+            Expires September 9, 2000 \f
+
+
+INTERNET-DRAFT                                           9 March 2000 
+        LDUP Replication Information Model 
+
+located will provide the basis for dynamic generation of LDAP 
+referrals for clients who can follow them. 
+
+The controlling framework by which the relationships, types, and 
+health of replicas of the directory content will be defined so that, 
+as much as possible, directory content is itself used to monitor and 
+control the environment. 
+
+Security information, including access control policy identifiers and 
+information will be treated as directory content by the replication 
+protocols when specified by the LDAPEXT group.  
+
+The information model will describe required and optional house-
+keeping duties for compliant systems to implement, such as garbage 
+collection of deleted objects, reconciliation of moved and renamed 
+objects, update sequencing and transaction bracketing of changes, etc. 
+
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 
+"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and  "OPTIONAL" in this 
+document are to be interpreted as described in RFC 2119 [RFC2119]. The 
+sections below reiterate these definitions and include some additional 
+ones. 
+
+
+2.1 Changes in this version 
+
+LDAP Subentry definition is moved to its own document [SUBENTRY]. 
+
+LDAP Schedule Subentry definition is defined. 
+
+LDAP Access Point removed in favor of just using the DN of the server 
+holding the replica (so a new syntax isn't required). 
+
+LDAP Change Sequence Number syntax eleminated in favor of just calling 
+it a CaseIgnoreString, so new comparison rules aren't required. 
+
+Deleted ldapSearchFilter definition from here.  Sparse replicas is 
+deferred. Might sparse be supported for single-master configurations 
+(read-only, of course).   
+
+Fractional are okay in multi-master configurations, but again, only on 
+read-only replicas. 
+
+Changed the naming convention upper-lower case usage to look less 
+weird. 
+
+Note: 
+
+
+Reed                                                         [Page 2] 
+            Expires September 9, 2000 
+\f
+
+
+INTERNET-DRAFT                                           9 March 2000 
+        LDUP Replication Information Model 
+
+Consistency discussion 
+
+Schema document must clearly indicate that clients can and should 
+inspect the replica subentries to understand the single-master/multi-
+master nature of the naming context to which they're talking. 
+
+The paradigm change, to distributed data, needs to be exhaustively 
+discussed in the profile documents.  How old applications which assume 
+single-master behave or misbehave in a multi-master environment is 
+critical to make clear.  Draw examples from SMP pre-emptive 
+programming practices, from DNS vs host file models, etc. 
+
+
+
+Decisions from wash ietf_ 
+
+1) define two simple schema classes _ event driven histeresis 
+   buckets, and cron-like thing.  Then, the replica has a single 
+   value pointer to a schedule.  More schedule things can be 
+   defined in the future. 
+
+2) Create attribute ReplicaURI to provide service access point for 
+   that replica.  No DSA entry requirement. 
+
+3) Replica id table discussion should move to protocol spec. 
+
+To do: 
+1) define the cron schedule subentry class 
+2) define the rest of the attributes used in the classes 
+3) verify LDUP OID number with Novell (!) one more time 
+4) verify all OIDs assigned 
+5) verify all OIDs documented at the end of the document 
+6) scrub editorial comments 
+7) cross reference with arch document on schema element names 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Reed                                                         [Page 3] 
+            Expires September 9, 2000 
+\f
+
+
+INTERNET-DRAFT                                           9 March 2000 
+        LDUP Replication Information Model 
+
+Table of Contents 
+1. Status of this Memo .............................................1 
+2. Abstract                      1 
+2.1  Changes in this version........................................2 
+3. Introduction ....................................................4 
+3.1  Scope  4 
+3.2  Terms and Definitions..........................................5 
+4. Data design: ....................................................5 
+5. Directory Knowledge .............................................5 
+6. Schema   6 
+6.1  Data Structure Definitions.....................................6 
+6.1.1     ldapChangeSequenceNumber..................................6 
+6.2  Attribute Definitions..........................................7 
+6.2.1     attributeExclusionFilter..................................7 
+6.2.2     attributeInclusionFilter..................................8 
+6.2.3     replicaURI................................................8 
+6.2.4     replicationStatus.........................................9 
+6.2.5     replicaType...............................................9 
+6.2.6     SecsToWait Attributes....................................11 
+6.2.6.1     secsToWaitCat1 ........................................11 
+6.2.6.2     secsToWaitCat2 ........................................11 
+6.2.6.3     secsToWaitCat3 ........................................11 
+6.2.6.4     secsToWaitCat4 ........................................11 
+6.2.6.5     secsToWaitCat5 ........................................11 
+6.2.7     updateVector.............................................12 
+6.3  Class Definitions.............................................12 
+6.3.1     nameContext..............................................12 
+6.3.2     replicaSubentry..........................................12 
+6.3.3     replicaAgreementSubentry.................................13 
+6.3.4     eventScheduledSubentry Class.............................14 
+6.3.5     timeScheduledSubentry Class..............................15 
+7. Object Identifier Assignments ..................................15 
+8. Security Considerations ........................................16 
+9. References .....................................................16 
+10.             Copyright Notice ...............................................17 
+11.             Acknowledgements ...............................................17 
+12.             Author's Address ...............................................18 
+
+
+3. Introduction 
+
+
+3.1 Scope 
+
+This document describes schema of subentries representing replicas, 
+replication agreements and their dependencies. 
+
+
+
+Reed                                                         [Page 4] 
+            Expires September 9, 2000 
+\f
+
+
+INTERNET-DRAFT                                           9 March 2000 
+        LDUP Replication Information Model 
+
+Management and status schema elements may be defined if there is 
+sufficient consensus. 
+
+Semantic interpretation of schema elements, including any special 
+handling expectations are to be provided here. 
+
+
+3.2 Terms and Definitions 
+
+Definitions are provided in [LDUP Requirements], and may be reproduced 
+here for the convenience of the reader. 
+
+
+
+4. Data design:  
+
+As described in [LDUP Model], knowledge of replicated portions of the 
+directory information tree (DIT) is stored in the directory itself.   
+
+An auxiliary class is defined to designate containers, or nodes, in 
+the DIT which are the root-most, or base, of naming contexts 
+[RFC2251].  Directory subentries [X501] are used to hold information 
+about replicas and replica agreements.   
+
+
+
+5. Directory Knowledge 
+
+Information about what replicas exist, what they contain, their types, 
+where they are stored, and how they may be contacted inevitably 
+provides the basis for distributed directory knowledge.  As namespaces 
+from stand-alone servers are inter-connected with one another, this 
+replica information can and will be used by name resolution operations 
+to locate servers holding copies of specific objects, and to optimize 
+distributed searches which span multiple Naming Contexts. 
+
+However, the focus of this document is NOT to fully enable such 
+distributed directory uses.  Instead, we are focused on how portions 
+of the namespace (Directory Information Tree - DIT) may be replicated, 
+and how those replicas are configured and related to one another via 
+Replication Agreements. 
+
+As such, the following high level description (from [LDUP Model])of 
+the information model envisioned is provided as reference for the 
+reader before presenting the detailed specifications. 
+
+Generally, the DSE Naming Context attribute of an LDAPv3 server names 
+the Naming Contexts for which there are replicas on that server. 
+
+Reed                                                         [Page 5] 
+            Expires September 9, 2000 
+\f
+
+
+INTERNET-DRAFT                                           9 March 2000 
+        LDUP Replication Information Model 
+
+The Naming Context Auxiliary Class (nameContext) is added to container 
+objects which may have separately defined replication policy. 
+
+Immediately subordinate to a Naming Context object are the Replica 
+Subentry containers which identify where the identified replica 
+resides (ie, its LDAP Access Point), its type (Primary, Updateable, 
+ReadOnly), if it is sparse, the LDAP search filter which defines what 
+object classes it holds, and if it is fractional, the attributes it 
+does or does not hold. 
+
+Immediately subordinate in the namespace to a Replica Subentry are 
+Replication Agreement leaf entries which each identify another 
+Replica, the scheduling policy for replication operations (including 
+times when replication is to be performed, when it is not to be 
+performed, or the policies governing event-driven replication 
+initiation). 
+
+
+
+6. Schema 
+
+
+6.1 Data Structure Definitions 
+
+For the purposes of defining the encoding rules for attribute 
+structures, the BNF definitions in section 4.1 of [RFC2252] will be 
+used.  They are based on the BNF styles of [RFC822]. 
+
+To avoid requiring new syntax support to be added unnecessarily to 
+existing LDAPv3 directory service implementations (and the 
+accompanying matching rules, etc. they would entail), a string 
+encoding is defined for ldapChangeSequenceNumber which can use 
+CaseIgnoreString matching rules for ordering and equality. 
+
+6.1.1 ldapChangeSequenceNumber 
+
+( 1.3.6.1.4.1.1466.115.121.1.TBD DESC 'LDAP Change Sequence Number' ) 
+
+Values in this syntax are encoded according to the following BNF.  
+Note there MUST NOT be any whitespace separators, unless they are in 
+replicaID, which must be encoded according to the instructions below. 
+
+This encoding is specified so that the CaseIgnoreString equality and 
+ordering rules will work correctly when replicaNumber is used. 
+
+When replicaID is used, CaseIgnoreString comparison rules will not 
+work unless each replicaID is exactly the same length with no padded 
+
+
+Reed                                                         [Page 6] 
+            Expires September 9, 2000 
+\f
+
+
+INTERNET-DRAFT                                           9 March 2000 
+        LDUP Replication Information Model 
+
+white spaces (because CaseIgnoreString suppresses duplicate adjacent 
+white space when it compares two strings). 
+
+LDAPChangeSequenceNumber = GeneralizedZTime "#" S1 "#" replicaID 
+   "#" S2  
+GeneralizedZTime = yyyy | mm | dd | hh | mi | ss | "Z" 
+yyyy = dddd <four digit year, e.g. 1998> 
+mm = dd <two digit month of the year, e.g. 06> 
+dd = dd <two digit day of month, e.g. 17> 
+hh = dd <two digit hour of the day, inclusive range (00..23)> 
+mi = dd <two digit minute of the hour, inclusive range (00..59)> 
+ss = dd <two digit seconds of the minute, inclusive range (00..59)> 
+replicaID = dstring  
+S1, S2 = numericstring 
+
+The GeneralizedTime is used as described (cf. [X680] section 39.3 case 
+b) without separators or whitespace, and representing a coordinated 
+universal time (i.e., Greenwich Mean Time, or GMT).  All times 
+referenced by this syntax MUST be normalized to GMT - no local times, 
+nor time zone offsets are permitted.  To simplify comparisons of two 
+CSNs, the "Z" MUST be the UTF-8 capital-Z character. 
+
+The ReplicaID represents the specific Replica of this Naming Context 
+where the event associated with this LDAPChangeSequenceNumber 
+occurred. Note that in actual transfer, the ReplicaID MAY be 
+represented by a number (see the specification of the 
+replicaLookupTable, above).   
+
+S1 and S2 are sequence numbers which are used to order two events with 
+the same Generalized Time and ReplicaID.  In order to use string 
+matching rules for equality and ordering with values with this 
+encoding, the length of each field must be consistent.  Thus, all 
+instances of S1 MUST be represented with the same number of digits, 
+using leading zeros as necessary.  The same with S2 and replicaID.  
+
+
+
+
+6.2 Attribute Definitions 
+
+
+6.2.1 attributeExclusionFilter 
+
+( 2.16.840.1.113719.142.4.1 NAME 'attributeExclusionFilter' 
+ SYNTAX OCTET STRING 
+ SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation ) 
+
+
+
+Reed                                                         [Page 7] 
+            Expires September 9, 2000 
+\f
+
+
+INTERNET-DRAFT                                           9 March 2000 
+        LDUP Replication Information Model 
+
+The attributeExclusionFilter is intended to contain a list of 
+attributes in the form of an AttributeDescriptionList as described in 
+section 4.5.1. Search Request of [RFC2251] with the following 
+interpretation:  an empty attributeExclusionFilter means that no 
+attributes are excluded; the special values "*" and "1.1" mean that 
+ALL attributes are excluded.  
+
+A non-empty attributeExclusionFilter attribute on a replica subEntry 
+describes the attributes NOT PRESENT on entries held by that replica.  
+Replicas MUST NOT accept changes for attributes they're not permitted 
+to hold, per the attributeInclusionFilter and attributeExclusionFilter 
+attributes on their replica subEntry. 
+
+A non-empty attributeExclusionFilter attribute on a 
+replicationAgreement subEntry describes which additional attributes 
+are to be excluded from the updates to be sent from the supplier 
+replica to the consumer replica.  
+
+
+6.2.2 attributeInclusionFilter 
+
+( {2.16.840.1.113719.142.4.2 NAME 'attributeInclusionFilter' 
+ SYNTAX OCTET STRING 
+ SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation ) 
+
+The attributeInclusionFilter is intended to contain a list of 
+attributes in the form of an AttributeDescriptionList as described in 
+section 4.5.1. Search Request of [RFC2251] with the following 
+interpretation:  an empty attributeInclusionFilter means that all 
+attributes are included; the special value "*" means that ALL 
+attributes are included; the special value "1.1" is meaningless and is 
+ignored in this usage. 
+
+A non-empty attributeInclusionFilter attribute on a replica subEntry 
+describes the attributes that may be PRESENT on entries held by that 
+replica.  Replicas MUST NOT accept changes for attributes they're not 
+permitted to hold, per the attributeIncludionFilter and 
+attributeExclusionFilter attributes on their replica subEntry. 
+
+
+6.2.3 replicaURI 
+
+(2.16.840.1.113719.142.4.x NAME `replicaURI' 
+ DESC `how to connect to this replica' 
+ SYNTAX ldapURI 
+ USAGE dSAOperation ) 
+
+
+
+Reed                                                         [Page 8] 
+            Expires September 9, 2000 
+\f
+
+
+INTERNET-DRAFT                                           9 March 2000 
+        LDUP Replication Information Model 
+
+6.2.4 replicationStatus 
+
+(2.16.840.1.113719.142.4.3 NAME 'replicationStatus' 
+ DESC 'human readable status of last replication attempt' 
+ SYNTAX DirectoryString 
+ SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation ) 
+
+
+The replicationStatus attribute MAY be used to hold a human readable 
+message describing the most recent replication session attempt for a 
+replicationAgreement. 
+
+For example, such a messages might include  
+
+1) 19980805162203Z # Success # 
+
+2) 19980805162322Z # Failure # Server too busy, try again 
+
+3) 19980805170215Z # Failure # Unable to connect to DSA 
+
+4) 19980806002301Z # Failure # Authentication failed 
+
+5) 19980806003201Z # Failure # lost connection, reset by peer 
+
+It is suggested, but not required, that the time of a replication 
+attempt (completion, if successful or failure, if not), the result of 
+the attempt, and any additional information about a failure be 
+included in the string message. 
+
+It is suggested, but not required, that the messages be stored with 
+language tags (English, French, German, Japanese, Chinese, per [LANG 
+TAG]) particularly if multiple translations of the error messages are 
+available to the DSA implementers. 
+
+Note that this is a single-valued attribute.  Sequences of status 
+entries SHOULD be written to log files or other persistent storage, or 
+in multi-valued replication history attributes, but are not specified 
+here. 
+
+
+6.2.5 replicaType 
+
+(2.16.840.1.113719.142.4.4 NAME 'replicaType' 
+ DESC 'Enum: 0-reserved, 1-Primary, 2-Updateable, 3-ReadOnly, all 
+others reserved' 
+ EQUALITY integerMatch 
+ SYNTAX INTEGER 
+ SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation ) 
+
+Reed                                                         [Page 9] 
+            Expires September 9, 2000 
+\f
+
+
+INTERNET-DRAFT                                           9 March 2000 
+        LDUP Replication Information Model 
+
+ReplicaType is a simple enumeration, used to identify what kind of 
+replica is being described in a Replica object entry. 
+
+A ReadOnly replica only accepts LDAP Search operations (to Read 
+entries, list containers, and search for entries).  Because no updates 
+ever originate from ReadOnly replicas, they never have changes to send 
+to another replica.  However, a ReadOnly replica may be designated a 
+supplier DSA in a replica agreement, if it is simply passing along 
+information it receives from other Updateable replicas about entries 
+and their changes. 
+
+ReadOnly replicas may be incomplete replicas. 
+
+An Updateable replica may accept both LDAP Search operations (to read, 
+list, or search entries), as well as modification operations (to add, 
+modify, or delete entries).   
+
+The consequences of having incomplete updateable replicas are not 
+fully understood.  LDAP DSAs MAY require updateable replicas to be 
+complete replicas. 
+
+A Primary replica is an Updateable replica, but it is "more special" 
+than other Updateable replicas.  When LDAP application want to direct 
+their operations to a single replica, so that the application can be 
+sure that all application LDAP modification (add, delete, modify) 
+operations will be immediately visible to application readers, the 
+Primary replica is a good choice.  Such a use would be consistent with 
+High Confidence DAP option [X518].  One such application might be a 
+management application which creates new naming contexts or joins two 
+naming contexts into a single naming context.  Another application 
+might be one which creates new replicas, or replication agreements. 
+
+There SHOULD be only one Primary replica defined for a naming context 
+at any time.  If applications, expecting there to be a Primary replica 
+discover, by search or inspection of ReplicaType attributes of the 
+defined Replicas of a naming context, find more than one _ they should 
+realize that something is wrong.   
+
+There MAY be NO primary replica defined for a naming context.   
+
+Primary replicas MAY NOT be incomplete replicas. 
+
+The way in which replicas change their type, as from ReadOnly to 
+Updateable, or Updateable to Primary is outside the scope of this 
+document. 
+
+Section 5.1 "Replica Type" of [LDUP MODEL] details the permissible 
+combinations of replica types and sparse/fractional replicas. 
+
+Reed                                                        [Page 10] 
+            Expires September 9, 2000 
+\f
+
+
+INTERNET-DRAFT                                           9 March 2000 
+        LDUP Replication Information Model 
+
+6.2.6 SecsToWait Attributes 
+
+The secsToWait attributes document the number of seconds a replica is 
+to wait after the occurrence of a "category n" change event before 
+initiating a new replication session for replicationAgreements 
+governed by an eventScheduledSubentry.  The definition of a "category 
+n" change event is implementation dependent, and may be defined 
+differently by different directory servers.  The absence of a value 
+for any of these attributes MUST be interpreted as meaning "do not 
+initiate a replication session for change events of this category".   
+
+
+6.2.6.1 secsToWaitCat1 
+
+( 2.16.840.1.113719.142.4.5.1 NAME 'secsToWaitCat1' 
+ SYNTAX INTEGER 
+ USAGE dSAOperation ) 
+
+
+6.2.6.2 secsToWaitCat2 
+
+( 2.16.840.1.113719.142.4.5.2 NAME 'secsToWaitCat2' 
+ SYNTAX INTEGER 
+ USAGE dSAOperation ) 
+
+
+6.2.6.3 secsToWaitCat3 
+
+( 2.16.840.1.113719.142.4.5.3 NAME 'secsToWaitCat3' 
+ SYNTAX INTEGER 
+ USAGE dSAOperation ) 
+
+
+6.2.6.4 secsToWaitCat4 
+
+( 2.16.840.1.113719.142.4.5.4 NAME 'secsToWaitCat4' 
+ SYNTAX INTEGER 
+ USAGE dSAOperation ) 
+
+
+6.2.6.5 secsToWaitCat5 
+
+( 2.16.840.1.113719.142.4.5.5 NAME 'secsToWaitCat5' 
+ SYNTAX INTEGER 
+ USAGE dSAOperation ) 
+
+
+
+
+Reed                                                        [Page 11] 
+            Expires September 9, 2000 
+\f
+
+
+INTERNET-DRAFT                                           9 March 2000 
+        LDUP Replication Information Model 
+
+6.2.7 updateVector 
+
+( 2.16.840.1.113719.142.4.6 NAME 'updateVector' 
+ SYNTAX ldapChangeSequenceNumberSyntax 
+ NO-USER-MODIFICATION USAGE dSAOperation ) 
+
+The attribute updateVector is a multi-valued attribute which contains 
+information for a replica describing the latest changes received by 
+the replica from other replicas. 
+
+There may be only one ldapChangeSequenceNumber entry from each replica 
+in the updateVector.  That is to say, there is a unique value 
+constraint on the ReplicaID component of entries in the list. 
+
+
+6.3 Class Definitions 
+
+
+6.3.1 nameContext 
+
+( 2.16.840.1.113719.142.6.2.1 NAME 'nameContext' SUP top AUXILIARY ) 
+
+
+The nameContext auxiliary class, when present on an object, indicates 
+the beginning, or root, of a naming context.  The naming context is 
+said to be rooted at the entry with the nameContext auxiliary class in 
+its list of object classes.  The root-most entry of a naming context 
+is the entry with the nameContext auxiliary class in its list of 
+object classes.   
+
+Characteristics of the replication topology of a naming context are 
+defined in the replicaSubentry sub-entries associated with the naming 
+context. 
+
+The attribute accessControlPolicyOID has been removed from here, and 
+should be published as an ldapSubEntry subordinate to the nameContext, 
+instead. 
+
+The attribute nameContextCreationTimestamp used here in previous 
+drafts has been eliminated as redundant.  The ldapChangeSequenceNumber 
+associated with the nameContext value in the list of objectClasses 
+attribute serves the same purpose.  
+
+
+6.3.2 replicaSubentry 
+
+( 2.16.840.1.113719.142.6.3.1 NAME 'replicaSubentry' SUP ldapSubEntry 
+ STRUCTURAL 
+
+Reed                                                        [Page 12] 
+            Expires September 9, 2000 
+\f
+
+
+INTERNET-DRAFT                                           9 March 2000 
+        LDUP Replication Information Model 
+
+ MUST (cn, replicaURI, replicaType) 
+ MAY (attributeExclusionFilter, attributeInclusionFilter, 
+description, updateVector) ) 
+
+Entries of type replicaSubentry MAY be named by their cn attribute.  
+
+The attributes attributeExclusionFilter and attributeInclusionFilter, 
+if present, govern which entries and attributes from the local naming 
+context are to be sent (or not sent) to the replica named in replicaDN 
+of replica agreements for this replica. The attributeExclusionFilter 
+names attributes which SHOULD NOT be sent.  The 
+attributeInclusionFilter names attributes which SHOULD be sent. 
+
+The attribute replicaURI contains information in ldapURI format that 
+can be used to contact (ie, open a connection to) this replica. 
+
+The attribute description contains a human-readable description of the 
+sub-entry.  
+
+The attribute updateVector contains a set of 
+ldapChangeSequenceNumbers, one for each of the other replicas for this 
+naming context, which records, from this replicas perspective, the 
+last change event received from the other indicated replica. 
+
+
+6.3.3 replicaAgreementSubentry 
+
+( 2.16.840.1.113719.142.6.4.1 NAME 'replicaAgreementSubentry'  
+ SUP ldapSubEntry STRUCTURAL 
+ MUST ( cn ) 
+ MAY ( attributeExclusionFilter, description, replicaDN, 
+replicationMechanismOID, replicationStatus, scheduleDN ) )  
+
+Entries of type replicaAgreementSubentry MAY be named by their cn 
+attribute. 
+
+The attributes attributeExclusionFilter, and ldapSearchFilter, if 
+present, govern which entries and attributes from the local naming 
+context are to be sent (or not sent) to the replica named in 
+replicaDN. The attributeExclusionFilter names attributes SHOULD NOT be 
+sent.  Note there is no attributeInclusionFilter, because the list of 
+attributes that may be sent may not be extended beyond those 
+documented in the attributeInclusionFilter on the replicaSubentry. 
+
+Processing of allowable changes to be sent is as follows: 
+
+1) the attributeInclusionFilter from the replica subentry defines a 
+ set of attributes which SHOULD be sent, less exclusions; 
+
+Reed                                                        [Page 13] 
+            Expires September 9, 2000 
+\f
+
+
+INTERNET-DRAFT                                           9 March 2000 
+        LDUP Replication Information Model 
+
+2) the union of attributes excluded by the attributeExclusionFilter 
+ from the replicasubentry and the attributeExclusionFilter from the 
+ replicaAgreementSubentry defines a set of attributes which SHOULD 
+ NOT be sent; 
+
+3) the subtraction of attributes which SHOULD NOT be sent by (2) from 
+ the attributes which SHOULD be sent by (1) constitute the set of 
+ attributes for which changes MAY be sent. 
+
+The attribute description contains a human-readable description of the 
+sub-entry. 
+
+The attribute replicaDN of syntax DN names another sub-entry of type 
+replicaSubentry to whom changes are to be sent.  If there is no value 
+for the replicaDN attribute on a replicaAgreementSubentry, the 
+replicaAgreementSubentry is ignored.  Absence of a value may occur 
+briefly when replicas and replica agreements are first being created, 
+or when the replica to which a replica agreement applies is being 
+deleted. 
+
+The attribute replicationStatus MAY be used to record the most recent 
+result of an attempt to send changes to the replica named in 
+replicaDN, whether success, or if failure, the nature of the problem 
+encountered. 
+
+The attribute schedule, if present, names one or more entries of type 
+scheduleSubentry which govern the schedule for replication attempts.  
+If not present, replication MUST be attempted when there are changes 
+to be sent. 
+
+
+6.3.4 eventScheduledSubentry Class 
+
+( 2.16.840.1.113719.142.6.1.1 NAME 'eventScheduledSubentry'  
+ SUP ldapSubEntry STRUCTURAL 
+ MUST ( cn ) 
+ MAY ( description, secsToWaitCat1, secsToWaitCat2, secsToWaitCat3, 
+secsToWaitCat4, secsToWaitCat5 ) )  
+
+Note that replication agreements using eventScheduledSubentry policy 
+are, by definition, supplier-initiated.    
+
+The description attribute may be used by the administrator to document 
+or comment on this subentry. 
+
+The secsToWaitCat1 attribute documents the number of seconds a replica 
+is to wait after the occurrence of a "category 1" change event before 
+initiating a new replication session for replicationAgreements 
+
+Reed                                                        [Page 14] 
+            Expires September 9, 2000 
+\f
+
+
+INTERNET-DRAFT                                           9 March 2000 
+        LDUP Replication Information Model 
+
+governed by this eventScheduledSubentry.  The definition of a 
+"category 1" change event is implementation dependent, and may be 
+defined differently by different directory servers.  The absence of a 
+value for this attribute MUST be interpreted as meaning "do not 
+initiate a replication session for change events of this category".   
+
+The secsToWaitCat2 _ secsToWaitCat5 attributes are similarly defined 
+for their respective categoriess of change events. 
+
+6.3.5 timeScheduledSubentry Class 
+
+( 2.16.840.1.113719.142.6.5.1 NAME 'timeScheduledSubentry'  
+ SUP ldapSubEntry STRUCTURAL 
+ MUST ( cn ) 
+ MAY ( description ) )  
+
+
+
+
+7. Object Identifier Assignments 
+
+The LDUP OID prefix is  
+
+ID ::= OBJECT IDENTIFIER 
+
+ldup           ID ::= { joint-iso-ccitt(2) country(16) us(840) 
+          organization(1) novell(113719) ldup(142) } 
+
+The OID assignments defined in this document are: 
+
+Attributes: 
+attributeExclusionFilter ID ::= 2.16.840.1.113719.142.4.1 
+attributeInclusionFilter ID ::= 2.16.840.1.113719.142.4.2 
+replicationStatus        ID ::= 2.16.840.1.113719.142.4.3 
+replicaType              ID ::= 2.16.840.1.113719.142.4.4 
+secsToWaitClass1         ID ::= 2.16.840.1.113719.142.4.5.1 
+secsToWaitClass2         ID ::= 2.16.840.1.113719.142.4.5.2 
+secsToWaitClass3         ID ::= 2.16.840.1.113719.142.4.5.3 
+secsToWaitClass4         ID ::= 2.16.840.1.113719.142.4.5.4 
+secsToWaitClass5         ID ::= 2.16.840.1.113719.142.4.5.5 
+updateVector             ID ::= 2.16.840.1.113719.142.4.6 
+
+Object Classes: 
+eventScheduledSubentry   ID ::= 2.16.840.1.113719.142.6.1.1 
+nameContext              ID ::= 2.16.840.1.113719.142.6.2.1 
+replicaSubentry          ID ::= 2.16.840.1.113719.142.6.3.1 
+replicaAgreementSubentry ID ::= 2.16.840.1.113719.142.6.4.1 
+timeScheduledSubentry    ID ::= 2.16.840.1.113719.142.6.5.1 
+
+Reed                                                        [Page 15] 
+            Expires September 9, 2000 
+\f
+
+
+INTERNET-DRAFT                                           9 March 2000 
+        LDUP Replication Information Model 
+
+
+Note:  Object Class OIDs have version numbers, Attribute OIDs don't. 
+
+
+8. Security Considerations 
+
+Many of the attributes and object classes described in this document 
+should be considered _security sensitive_, and protected from 
+unintended modification by LDAP servers.  Generally, creating Naming 
+Contexts, Replicas and Replica Agreement entries should only be 
+allowed by directory administrators who are authorized to do so.   
+
+The values of attributes defined here are intended to control the 
+behavior of the directory service agents, themselves.  Unintended 
+modification of their values may result in incomplete replication of 
+data (if ldapSearchFilter or attributeExclusionFilter are changed), 
+inappropriate disclosure of information (if attributeInclusionFilter 
+is changed), or updates may be lost (if updateVector is changed).  
+
+To avoid depending to much on the ldapAccessPoint values for other 
+replicas, connections between LDAP servers for the purpose of 
+replication MUST ALWAYS be authenticated using an authentication 
+mechanism appropriate for the nature of information to be exchanged. 
+
+
+
+9. References 
+
+[LANG TAG] _ M. Wahl, T. Howes, _Use of Language Codes in LDAP_, 
+Internet draft, draft-ietf-ldapext-lang-01.txt 
+
+[LDUP Model] - J. Merrells, E. Reed, U. Srinivisan, _An Abstract Model 
+of LDAP Replication_, Internet draft, draft-merrells-ldup-model-01.txt 
+
+[LDUP Requirements] - R. Weiser, E. Stokes _LDAP Replication 
+Requirements_, Internet draft, draft-weiser-replica-req-02.txt, April 
+1998 
+
+[RFC2251] _ M. Wahl, T. Howes, S. Kille, _Lightweight Directory Access 
+Protocol (v3)_, December 1997, RFC 2251 
+
+[RFC2252] _ M. Wahl, A. Coulbeck, T. Howes, S. Kille, _Lightweight 
+Directory Access Protocol (v3): Attribute Syntax Definitions_, 
+December 1997, RFC 2252 
+
+[X525] - ITU-T Recommendation X.525 (1997) | ISO/IEC 9594-9:1997, 
+Information Technology _ Open Systems Interconnection _ The Directory:  
+Replication 
+
+Reed                                                        [Page 16] 
+            Expires September 9, 2000 
+\f
+
+
+INTERNET-DRAFT                                           9 March 2000 
+        LDUP Replication Information Model 
+
+[X680] - ITU-T Recommendation X.680 (1994) | ISO/IEC 8824-1:1995, 
+Information technology _ Abstract Syntax Notation One (ASN.1): 
+Specification of Basic Notation 
+
+
+
+10. Copyright Notice 
+
+Copyright (C) The Internet Society (1999). All Rights Reserved.  
+
+This document and translations of it may be copied and furnished to 
+others, and derivative works that comment on or otherwise explain it 
+or assist in its implmentation may be prepared, copied, published and 
+distributed, in whole or in part, without restriction of any kind, 
+provided that the above copyright notice and this paragraph are 
+included on all such copies and derivative works. However, this 
+document itself may not be modified in any way, such as by removing 
+the copyright notice or references to the Internet Society or other 
+Internet organizations, except as needed for the purpose of developing 
+Internet standards in which case the procedures for copyrights defined 
+in the Internet Standards process must be followed, or as required to 
+translate it into languages other than English. 
+
+The limited permissions granted above are perpetual and will not be 
+revoked by the Internet Society or its successors or assigns. 
+
+This document and the information contained herein is provided on an 
+"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING 
+TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT 
+NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN 
+WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF 
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE." 
+
+
+11. Acknowledgements 
+
+The use of subEntry object class to store Replica and Replication 
+Agreement information is due primarily to the lucid explanation by 
+Mark Wahl, Innosoft, of how they could be used and extended. 
+
+The IETF takes no position regarding the validity or scope of any 
+intellectual property or other rights that might be claimed to pertain 
+to the implementation or use of the technology described in this 
+document or the extent to which any license under such rights might or 
+might not be available; neither does it represent that it has made any 
+effort to identify any such rights. Information on the IETF's 
+procedures with respect to rights in standards-track and standards-
+related documentation can be found in BCP-11. Copies of claims of 
+
+Reed                                                        [Page 17] 
+            Expires September 9, 2000 
+\f
+
+
+INTERNET-DRAFT                                           9 March 2000 
+        LDUP Replication Information Model 
+
+rights made available for publication and any assurances of licenses 
+to be made available, or the result of an attempt made to obtain a 
+general license or permission for the use of such proprietary rights 
+by implementors or users of this specification can be obtained from 
+the IETF Secretariat. 
+
+The IETF invites any interested party to bring to its attention any 
+copyrights, patents or patent applications, or other proprietary 
+rights which may cover technology that may be required to practice 
+this standard. Please address the information to the IETF Executive 
+Director. 
+
+
+
+12. Author's Address 
+
+   Edwards E. Reed 
+   Reed-Matthews, Inc. 
+   1064 East 140 North 
+   Lindon, UT  84042 
+   USA 
+   E-mail:   eer@oncalldba.com  
+    
+   LDUP Mailing List:  ietf-ldup@idc.org 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Reed                                                        [Page 18] 
+            Expires September 9, 2000 
+\f
diff --git a/doc/drafts/draft-ietf-ldup-model-xx.txt b/doc/drafts/draft-ietf-ldup-model-xx.txt
new file mode 100644 (file)
index 0000000..1567971
--- /dev/null
@@ -0,0 +1,2468 @@
+INTERNET-DRAFT
+
+draft-ietf-ldup-model-03.txt
+
+
+                                                 John Merrells
+                                   Netscape Communications Corp.
+                                                      Ed Reed
+                                            Reed-Matthews, Inc.
+                                             Uppili Srinivasan
+                                                 Oracle, Inc.
+                                                March 10, 2000
+
+                    LDAP Replication Architecture
+
+Copyright (C) The Internet Society (1998,1999, 2000).
+All Rights Reserved.
+
+Status of this Memo
+
+This document is an Internet-Draft and is in full conformance with all
+provisions of Section 10 of RFC2026.
+
+Internet-Drafts are working documents of the Internet Engineering Task
+Force (IETF), its areas, and its working groups.  Note that other
+groups may also distribute working documents as Internet-Drafts.
+
+Internet-Drafts are draft documents valid for a maximum of six months
+and may be updated, replaced, or made obsolete by other documents at
+any time.  It is inappropriate to use Internet-Drafts as reference
+material or to cite them other than as "work in progress."
+
+The list of current Internet-Drafts can be accessed at
+http://www.ietf.org/ietf/1id-abstracts.txt
+
+The list of Internet-Draft Shadow Directories can be accessed at
+http://www.ietf.org/shadow.html.
+
+This draft, file name draft-ietf-ldup-model-03.txt, is intended to be
+become a Proposed Standard RFC, to be published by the IETF Working
+Group LDUP.  Distribution of this document is unlimited. Comments
+should be sent to the LDUP Replication mailing list <ldup@imc.org> or
+to the authors.
+
+This Internet-Draft expires on 10 September 2000.
+
+
+
+
+
+
+
+Merrells, Reed, Srinivasan                                   [Page  1]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+
+
+
+
+
+
+1 Abstract
+
+This architectural document outlines a suite of schema and protocol
+extensions to LDAPv3 that enables the robust, reliable, server-to-
+server exchange of directory content and changes.
+
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and  "OPTIONAL" in this
+document are to be interpreted as described in RFC 2119 [RFC2119]. The
+sections below reiterate these definitions and include some additional
+ones.
+
+
+2 Table of Contents
+
+1    Abstract......................................................2
+2    Table of Contents.............................................2
+3    Introduction..................................................4
+3.1  Scope.........................................................4
+3.2  Document Objectives...........................................5
+3.3  Document Non-Objectives.......................................6
+3.4  Existing Implementations......................................6
+3.4.1      Replication Log Implementations.........................6
+3.4.2      State-Based Implementations.............................7
+3.5  Terms and Definitions.........................................7
+3.6  Consistency Models............................................8
+3.7  LDAP Constraints..............................................9
+4    Directory Model..............................................10
+4.1  Replica Type.................................................10
+4.1.1      Primary Replica........................................10
+4.1.2      Updatable Replica......................................10
+4.1.3      Read-Only Replica......................................10
+4.1.4      Fractional Replicas....................................10
+4.2  Sub-Entries..................................................11
+4.3  Glue Entries.................................................11
+4.4  Unique Identifiers...........................................11
+4.5  Change Sequence Number.......................................11
+4.5.1      CSN Composition........................................11
+4.5.2      CSN Representation.....................................12
+4.5.3      CSN Generation.........................................12
+4.6  State Change Information.....................................13
+4.1.1      Entry Change State Storage and Representation..........13
+4.1.2      Attribute Change State Storage.........................14
+
+Merrells, Reed, Srinivasan                                   [Page  2]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+4.1.3      Attribute Value Change State Storage...................14
+4.2  LDAP Update Operations.......................................14
+5    Information Model............................................15
+5.1  Entries,
+           Semantics and Relationships............................15
+5.2  Root DSE Attributes..........................................15
+5.3  Naming Context...............................................15
+5.4  Replica Object Class and Entries.............................16
+5.5  Lost and Found Entry.........................................16
+5.6  Replication Agreement Object Class and Entries...............16
+5.6.1      Replication Schedule...................................17
+6    Policy Information...........................................18
+6.1  Schema Knowledge.............................................18
+7    LDUP Update Transfer Protocol Framework......................18
+7.1  Replication Session Initiation...............................19
+7.1.1      Authentication.........................................19
+7.1.2      Consumer Initiated.....................................19
+7.1.3      Supplier Initiated.....................................19
+7.2  Start Replication Session....................................20
+7.2.1      Start Replication Request..............................20
+7.2.2      Start Replication Response.............................20
+7.3  Update Transfer..............................................20
+7.4  End Replication Session......................................20
+7.5  Integrity & Confidentiality..................................21
+8    LDUP Update Protocols........................................21
+8.1  Replication Updates and Update Primitives....................21
+8.2  Fractional Updates...........................................21
+9    LDUP Full Update Transfer Protocol...........................22
+9.1  Full Update Transfer.........................................22
+9.2  Replication Update Generation................................22
+9.3  Replication Update Consumption...............................22
+9.4  Full Update, End Replication Session.........................22
+9.5  Interrupted Transmission.....................................23
+10   LDUP Incremental Update Transfer Protocol....................23
+10.1 Update Vector................................................23
+10.2 Supplier Initiated, Incremental Update, 
+         Start Replication Session................................24
+10.3 Replication Update Generation................................24
+10.3.1       Replication Log Implementation.......................25
+10.3.2       State-Based Implementation...........................25
+10.4 Replication Update Consumption...............................25
+10.5 Update Resolution Procedures.................................25
+10.5.1       URP: Distinguished Names.............................26
+10.5.2       URP: Orphaned Entries................................26
+10.5.3       URP: Distinguished Not Present.......................26
+10.5.4       URP: Schema - Single Valued Attributes...............26
+10.5.5       URP: Schema - Required Attributes....................27
+10.5.6       URP: Schema - Extra Attributes.......................27
+
+
+Merrells, Reed, Srinivasan                                   [Page  3]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+10.5.7       URP: Duplicate Attribute Values......................27
+10.5.8       URP: Ancestry Graph Cycle............................27
+10.6 Incremental Update, End Replication Session..................27
+10.7 Interrupted Transmission.....................................28
+11   Purging State Information....................................28
+11.1 Purge Vector.................................................28
+11.2 Purging Deleted Entries, Attributes, and Attribute Values....29
+12   Replication Configuration and Management.....................29
+13   Time.........................................................30
+14   Security Considerations......................................31
+15   Acknowledgements.............................................31
+16   References...................................................32
+17   Intellectual Property Notice.................................32
+18   Copyright Notice.............................................33
+19   Authors' Address.............................................33
+20   Appendix A - LDAP Constraints................................34
+20.1 LDAP Constraints Clauses.....................................34
+20.2 LDAP Data Model Constraints..................................35
+20.3 LDAP Operation Behaviour Constraints.........................36
+20.4 New LDAP Constraints.........................................37
+20.4.1       New LDAP Data Model Constraints......................37
+20.4.2       New LDAP Operation Behaviour Constraints.............37
+
+
+
+
+
+
+3 Introduction
+
+
+3.1  Scope
+
+This architectural document provides an outline of an LDAP based
+replication scheme. Further detailed design documents will draw
+guidance from here.
+
+The design proceeds from prior work in the industry, including
+concepts from the ITU-T Recommendation X.525 (1993, 1997) Directory
+Information Shadowing Protocol (DISP) [X525], experience with widely
+deployed distributed directories in network operating systems,
+electronic mail address books, and other database technologies.  The
+emphasis of the design is on:
+
+1. Simplicity of operation.
+
+2. Flexibility of configuration.
+
+3. Manageability of replica operations among mixed heterogeneous
+  vendor LDAP servers under common administration.
+
+
+Merrells, Reed, Srinivasan                                   [Page  4]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+4. Security of content and configuration information when LDAP servers
+  from more than one administrative authority are interconnected.
+
+A range of deployment scenarios are supported, including multi-master
+and single-master topologies. Replication networks may include
+transitive and redundant relationships between LDAP servers.
+
+The controlling framework used to define the relationships, types, and
+state of replicas of the directory content is defined. In this way the
+directory content can itself be used to monitor and control the
+replication network. The directory schema is extended to define object
+classes, auxiliary classes, and attributes that describe areas of the
+namespace which are replicated, LDAP servers which hold replicas of
+various types for the various partitions of the namespace, LDAP Access
+Points (network addresses) where such LDAP servers may be contacted,
+which namespaces are held on given LDAP servers, and the progress of
+replication operations. Among other things, this knowledge of where
+directory content is located could serve as the basis for dynamic
+generation of LDAP referrals.
+
+An update transfer protocol, which actually brings a replica up to
+date with respect to changes in directory content at another replica,
+is defined using LDAPv3 protocol extensions.  The representation of
+directory content and changes will be defined by the LDAP Replication
+Update Transfer Protocol sub-team. Incremental and full update
+transfer mechanisms are described.  Replication protocols are required
+to include initial population, change updates, and removal of
+directory content.
+
+Security information, including access control policy will be treated
+as directory content by the replication protocols.  Confidentiality
+and integrity of replication information is required to be provided by
+lower-level transport/session protocols such as IPSEC and/or TLS.
+
+
+
+3.2  Document Objectives
+
+The objectives of this document are:
+
+a) To define the architectural foundations for LDAP Replication, so
+  that further detailed design documents may be written. For
+  instance, the Information Model, Update Transfer Protocol, and
+  Update Resolution Procedures documents.
+
+b) To provide an architectural solution for each clause of the
+  requirements document [LDUP Requirements].
+
+c) To preserve the LDAP Data Model and Operation Behavior
+constraints
+  defined for LDAP in RFC 2251 [See Appendix A]
+
+d) To avoid tying the LDUP working group to the schedule of any other
+  working group.
+
+e) Not to infringe upon known registered intellectual property rights.
+
+
+Merrells, Reed, Srinivasan                                   [Page  5]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+
+
+
+3.3  Document Non-Objectives
+
+This document does not address the following issues, as they are
+considered beyond the scope of the Working Group.
+
+a) How LDAP becomes a distributed directory.  There are many issues
+  beyond replication that should be considered. Such as, support for
+  external references, algorithms for computing referrals from the
+  distributed directory knowledge, etc.
+
+b) Specifying management protocols to create naming contexts or new
+  replicas.  LDAP may be sufficient for this. The document describes
+  how new replicas and naming contexts are represented, in the
+  directory, as entries, attributes, and attribute values.
+
+c) How transactions will be replicated. However, the architecture
+  should not knowingly prevent or impede them, given the Working
+  Group's incomplete understanding of the issues at this time.
+
+d) The mapping or merging of disparate Schema definitions.
+
+e) Support of overlapping replicated regions.
+
+f) The case where separate attributes of an entry may be mastered by
+  different LDAP servers. This might be termed a 'Split Primary'.
+  Replica roles are defined in section 4.1.
+
+g) The specification of a replication system that supports Sparse
+  Replication. A Sparse Replica contains a subset of the naming
+  context entries, being modified by an Entry Selection Filter
+  criteria associated with the replica. An Entry Selection Filter is
+  an LDAP filter expression that describes the entries to be
+  replicated. The design and implementation of this functionality is
+  not yet well enough understood to specify here.
+
+
+
+3.4  Existing Implementations
+
+In order to define a standard replication scheme that may be readily
+implemented we must consider the architectures of current LDAP server
+implementations. Existing systems currently support proprietary
+replication schemes based on one of two general approaches: log-based
+or state-based. Some sections of this text may specifically address
+the concerns of one approach. They will be clearly marked.
+
+
+
+3.4.1R
+      eplication Log Implementations
+
+Implementations based on the original University of Michigan LDAP
+server code record LDAP operations to a operation log. During a
+replication session operations are replayed from this log to bring the
+
+Merrells, Reed, Srinivasan                                   [Page  6]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+Consumer replica up to date. Example implementations of this type at
+this time are the Innosoft, Netscape, and Open LDAP Directory Servers.
+
+
+
+3.4.2S
+      tate-Based Implementations
+
+Directory Server implementations from Novell and Microsoft at this
+time do not replay LDAP operations from a operation log. When a
+replication session occurs each entry in the Replicated Area is
+considered in turn, compared against the update state of the Consumer,
+and any resultant changes transmitted. These changes are a set of
+assertions about the presence or absence of entries, attributes, and
+their values.
+
+
+
+3.5  Terms and Definitions
+
+The definitions from the Replication Requirements document have been
+copied here and extended.
+
+For brevity, an LDAP server implementation is referred to throughout
+as 'the server'.
+
+The LDAP update operations; Add, Delete, Modify, Modify RDN (LDAPv2)
+and Modify DN (LDAPv3), are collectively referred to as LDAP Update
+Operations.
+
+A Naming Context is a subtree of entries in the Directory Information
+Tree (DIT).  There may be multiple Naming Contexts stored on a single
+server. Naming Contexts are defined in section 17 of [X501].
+
+A Naming Context is based at an entry identified as its root and
+includes all its subordinate entries down the tree until another
+Naming Context is encountered.
+
+A Replica is an instance of a replicated Naming Context.
+
+A replicated Naming Context is said to be single-mastered if there is
+only one Replica where it may be updated, and multi-mastered if there
+is more than one Replica where it may be updated.
+
+A Replication Relationship is established between two or more Replicas
+that are hosted on servers that cooperate to service a common area of
+the DIT.
+
+A Replication Agreement is defined between two parties of a
+Replication Relationship.  The properties of the agreement codify the
+Unit of Replication, the Update Transfer Protocol to be used, and the
+Replication Schedule of a Replication Session.
+
+A Replication Session is an LDAP session between the two servers
+identified by a replication agreement. Interactions occur between the
+two servers, resulting in the transfer of updates from the supplier
+replica to the consumer replica.
+
+Merrells, Reed, Srinivasan                                   [Page  7]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+
+The Initiator of a Replication Session is the initiating server.
+
+A Responder server responds to the replication initiation request from
+the Initiator server.
+
+A Supplier server is the source of the updates to be transferred.
+
+A Consumer server is the recipient of the update sequence.
+
+The Update Transfer Protocol is the means by which the Replication
+Session proceeds.  It defines the protocol for exchanging updates
+between the Replication Relationship partners.
+
+A Replication Update is an LDAP Extended Operation that contains
+updates to be applied to the DIT. The Update Transfer Protocol carries
+a sequence of these messages from the Supplier to the Consumer.
+
+The Update Resolution Procedures repair constraint violations that
+occur when updates to a multi-mastered Replica collide.
+
+A Fractional Entry Specification is a list of entry attributes to be
+included, or a list of attributes to be excluded in a replica. An
+empty specification implies that all entry attributes are included.
+
+A Fractional Entry is an entry that contains only a subset of its
+original attributes. It results from  the replication of changes
+governed by a Fractional Entry
+Specification.
+
+A Fractional Replica is a replica that holds Fractional Entries of its
+naming context.
+
+
+
+3.6  Consistency Models
+
+This replication architecture supports a loose consistency model
+between replicas of a naming context. It does not attempt to provide
+the appearance of a single copy of a replica. The contents of each
+replica may be different, but over time they will be converging
+towards the same state. This architecture is not intended to support
+LDAP Clients that require a tight consistency model, where the state
+of all replicas is always equivalent.
+
+Three levels of consistency are available to LDAP Clients, which are
+characterized by their deployment topologies. Single-Server, where
+there is just the naming context and no replicas. Single-master, where
+there are replicas, but only one may be updated. And, multi-master,
+where there is more than one replica to which LDAP update operations
+may be directed. The consistency properties of each model are rooted
+in their serialization of read and write operations.
+
+1) A single-server deployment of a naming context provides tight
+consistency to LDAP applications. LDAP Clients have no choice but to
+direct all their operations to a single server, serializing both read
+
+
+Merrells, Reed, Srinivasan                                   [Page  8]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+and write operations.
+
+2) A single-mastered deployment of a naming context provides both
+tight and loose consistency to LDAP applications. LDAP Clients must
+direct all write operations to the single updateable replica, but may
+direct their reads to any of the replicas. A client experiences tight
+consistency by directing all its operations to the single updatable
+replica, and loose consistency by directing any read operations to any
+other replica.
+
+3) A multi-mastered deployment of a naming context can provide only
+loose consistency to LDAP applications. Across the system writes and
+reads are not serialized. An LDAP Client could direct their read and
+write operations to a single updateable replica, but they will not
+receive tight consistency as interleaved writes could be occurring at
+another replica.
+
+Tight consistency can be achieved in a multi-master deployment for a
+particular LDAP application if and only if all instances of its client
+are directed towards the same updateable replica, and the application
+data is not updated by any other LDAP application. Introducing these
+constraints to an application and deployment of a naming-context
+ensures that writes are serialized providing tight consistency for the
+application.
+
+Future work could make use of the architecture proposed in this
+document as a basis for allowing clients to request session guarantees
+from a server when establishing a connection.
+
+
+
+3.7  LDAP Constraints
+
+The LDAP-v3 Internet RFC [LDAPv3] defines a set of Data Model and
+Operation Behaviour constraints that a compliant LDAP server must
+enforce. The server must reject an LDAP Update Operation if its
+application to the target entry would violate any one of these LDAP
+Constraints. [Appendix A B contains the original text clauses from RFC
+2251, and also a summary.]
+
+In the case of a single-server or single-mastered naming context all
+LDAP Constraints are immediately enforced at the single updateable
+replica. An error result code is returned to an LDAP Client that
+presents an operation that would violate the constraints.
+
+In the case of a multi-mastered naming context not all LDAP
+Constraints can be immediately enforced at the updateable replica to
+which the LDAP Update Operation is applied. This loosely consistent
+replication architecture ensures that at each replica all constraints
+are imposed, but as updates are replicated constraint violations may
+arise
+that can not be reported to the appropriate client. Any constraint
+violations that occur are repaired by a set of update resolution
+procedures.
+
+Any LDAP client that has been implemented to expect immediate
+
+
+Merrells, Reed, Srinivasan                                   [Page  9]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+enforcement of all LDAP Constraints  may not behave as expected
+against a multi-mastered naming context.
+
+
+
+4 Directory Model
+
+
+This section describes extensions to the LDAP Directory Model that are
+required by this replication architecture.
+
+
+
+4.1  Replica Type
+
+Each Replica is characterized with a replica type.  This may be
+Primary, Updatable, or Read-Only.  A Read-Only Replica may be further
+defined as being Fractional.
+
+
+
+4.1.1 
+     Primary Replica
+
+The Primary Replica is a full copy of the Replica, to which all
+applications that require tight consistency should direct their LDAP
+Operations. There can be only one Primary Replica within the set of
+Replicas of a given Naming Context.  It is also permissible for none
+of the Replicas to be designated the Primary. The Primary Replica MUST
+NOT be a Fractional Replica.
+
+
+4.1.2 
+     Updatable Replica
+
+An Updatable Replica is a Replica that accepts all the LDAP Update
+Operations, but is not the Primary Replica.  There could be none, one,
+or many Updatable Replicas within the set of Replicas of a given
+Naming Context. An Updatable Replica MUST NOT be a Fractional Replica.
+
+
+
+4.1.3 
+     Read-Only Replica
+
+A Read-Only Replica will accept only non-modifying LDAP operations.
+All modification operations shall be referred to an updateable
+Replica. The server referred to would usually be a Supplier of this
+Replica.
+
+
+
+4.1.4 
+     Fractional Replicas
+
+Fractional Replicas must always be Read-Only. All LDAP Update
+Operations must be referred to an Updatable Replica. The server
+referred to would usually be a Supplier of this Fractional Replica.
+
+
+Merrells, Reed, Srinivasan                                   [Page  10]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+4.2  Sub-Entries
+
+Replication management entries are to be stored at the base of the
+replicated naming context.  They will be of a 'ldapSubentry'
+objectclass
+to exclude them from regular searches. Entries with the objectclass
+subentry are not returned as the result of a search unless the filter
+component "(objectclass=ldapSubentry)" is included in the search
+filter.
+
+
+
+4.3  Glue Entries
+
+A glue entry is an entry that contains knowledge of its name only. No
+other information is held with it. Such glue entries will be
+distinguished through a special object class defined for that purpose.
+Glue entries may be created during a replication session to repair a
+constraint violation.
+
+
+4.4  Unique Identifiers
+
+Distinguished names can change, so are therefore unreliable as
+identifiers. A Unique Identifier must therefore be assigned to each
+entry as it is created. This identifier will be stored as an
+operational attribute of the entry, named 'entryUUID'. The entryUUID
+attribute is single valued. A consistent algorithm for generating such
+unique identifiers should be defined for use in the LDUP standards
+documents that detail the LDUP information model and LDUP protocols.
+
+
+4.5  Change Sequence Number
+
+Change Sequence Numbers (CSNs) are used to impose a total ordering
+upon the causal sequence of updates applied to all the replicas of a
+naming context. Every LDAP Update Operation is assigned at least one
+CSN. A Modify operation MUST be assigned one CSN per modification.
+
+
+
+4.5.1 
+     CSN Composition
+
+A CSN is formed of four components.  In order of significance they
+are; the time, a change count, a Replica Identifier, and a
+modification number. The CSN is composed thus to ensure the uniqueness
+of every generated CSN. When CSNs are compared to determine their
+ordering they are compared component by component. First the time,
+then the change count, then the replica identifier, and finally the
+modification number.
+
+The time component is a year-2000-safe representation of the real
+world time, with a granularity of one second.
+
+Because many LDAP Update Operations, at a single replica, may be
+
+Merrells, Reed, Srinivasan                                   [Page  11]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+applied to the same data in a single second, the change count
+component of the CSN is provided to further order the changes.  Each
+replica maintains a count of LDAP update operations applied against
+it. It is reset to zero at the start of each second, and is
+monotonically increasing within that second, incremented for each and
+every update operation. Should LDAP Update Operations occur at
+different replicas, to the same data, within the same single second,
+and happen to be assigned the same change count number, then the
+Replica Identifier is used to further order the changes.
+
+The Replica Identifier is the value of the RDN attribute on the
+Replica Subentry. The Replica Identifier could be assigned
+programmatically or administratively, in either case short values are
+advised to minimise resource usage. The IA5CaseIgnoreString syntax is
+used to compare and order Replica Identifier values.
+
+The fourth and final CSN component, the modification number, is used
+for ordering the modifications within an LDAP Modify operation.
+
+
+
+4.5.2 
+     CSN Representation
+
+The preferred CSN representation is:
+     yyyy mm dd hh:mi:ssz # 0xSSSS # replica id # 0xssss
+
+The 'z' in the time stipulates that the time is expressed in GMT
+without any daylight savings time offsets permitted, and the 0xssss
+represents the hexadecimal representation of an unsigned
+integer.
+Implementations must support 16 bit change counts and should support
+longer ones (32, 64, or 128 bits).
+
+An example CSN would be " 1998081018:44:31z#0x000F#1#0x0000 ". The
+update assigned this CSN would have been applied at time
+1998081018:44:31z happened to be the 16th operation  which was applied
+in that second, was made against the replica with identifier '1', and
+was the first modification of the operation that caused the change.
+
+
+
+4.5.3 
+     CSN Generation
+
+Because Change Sequence Numbers are primarily based on timestamps,
+clock differences between servers can cause unexpected change
+ordering. The synchronization of server clocks is not required, though
+it is preferable that clocks are accurate. If timestamps are not
+accurate, and a server consistently produces timestamps which are
+significantly older than those of other servers, its updates will not
+have effect and the real world time ordering of updates will not be
+maintained.
+
+However, an implementation may choose to require clock
+synchronisation. The Network Time Protocol [NTP] [SNTP] offers a
+protocol means by which heterogeneous server hosts may be time
+synchronised.
+
+Merrells, Reed, Srinivasan                                   [Page  12]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+
+The modifications which made up an LDAP Modify operation are presented
+in a sequence. This must be preserved when the resultant changes of
+this operation are replicated.
+
+
+
+
+4.5.3.1 CSN Generation - Log Based Implementation
+
+
+The modification number component may not be required, since the
+ordering of the modifications within an LDAP Modify operation have
+been preserved in the operation log.
+
+
+4.5.3.2 CSN Generation - State Based Implementation
+
+
+The modification number component may be needed to ensure that the
+order of the modifications within an LDAP Modify operation are
+faithfully replicated.
+
+
+4.6  State Change Information
+
+State changes can be introduced via either LDAP Update Operations or
+via Replication Updates. A CSN is included with all changes made to an
+entry, its attributes, and attribute values. This state information
+must be recorded for the entry to enable a total ordering of updates.
+The CSN recorded is the CSN assigned to the state change at the server
+where the state change was first made. CSNs are only assigned to state
+changes that originate from LDAP Update Operations.
+
+Each of the LDAP Update Operations change their target entry in
+different ways, and record the CSN of the change differently. The
+state information for the resultant state changes are recorded at
+three levels. The entry level, attribute level, and attribute value
+level. The state change may be shown through.
+
+1) The creation of a deletion CSN for the entry, an attribute, or an
+  attribute value.
+
+2) In the addition of a new entry, attribute or attribute value, and
+  its existence CSN.
+
+3) An update to an existing attribute, attribute value, entry
+  distinguished name, or entry superior name, and its update CSN.
+
+
+
+4.1.1 
+     Entry Change State Storage and Representation
+
+When an entry is created, with the LDAP Add operation, the CSN of the
+change is added to the entry as the value of an operational attribute
+
+
+Merrells, Reed, Srinivasan                                   [Page  13]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+named 'createdEntryCSN', of syntax type LDAPChangeSequenceNumber.
+
+     createdEntryCSN ::= csn
+
+Deleted entries are marked as deleted by the addition of the object
+class 'deletedEntry'. The attribute 'deletedEntryCSN', of syntax type
+LDAP Change Sequence Number, is added to record where and when the
+entry was deleted.  Deleted entries are not visible to LDAP clients -
+they may not be read, they don't appear in lists or search results,
+and they may not be changed once deleted.  Names of deleted entries
+are available for reuse by new entries immediately after the deleted
+entry is so marked. It may be desirable to allow deleted entries to be
+accessed and manipulated by management and data recovery applications,
+but that is outside the scope of this document.
+
+     deletedEntryCSN ::= csn
+
+A CSN is recorded for both the RDN, and the Superior DN of the entry.
+
+
+4.1.2A
+      ttribute Change State Storage
+
+When all values of an attribute have been deleted, the attribute is
+marked as deleted and the CSN of the deletion is recorded. The deleted
+state and CSN are stored by the server, but have no representation on
+the entry, and may not be the subject of a search operation. This
+state information must be stored to enable the Update Resolution
+Procedures to be performed.
+
+
+
+4.1.3 
+     Attribute Value Change State Storage
+
+The Modification CSN for each value is to be set by the server when it
+accepts a modification request to the value, or when a new value with
+a later Modification CSN is received via Replication.  The modified
+value and the Modification CSN changes are required to be atomic, so
+that the value and its Modification CSN cannot be out of synch on a
+given server.  The state information is stored by the server, but it
+has no representation on the entry, and may not be the subject of a
+search operation.
+
+When the value of an attribute is deleted the state of its deletion
+must be recorded, with the CSN of the modifying change. It must be
+stored to enable the Update Resolution Procedures to be performed.
+
+
+
+4.2  LDAP Update Operations
+
+The server must reject LDAP client update operations with a CSN that
+is older than the state information that would be replaced if the
+operation were performed. This could occur in a replication topology
+where the difference between the clocks of updateable replicas was too
+large. Result code 72, serverClocksOutOfSync, is returned to the
+client.
+
+Merrells, Reed, Srinivasan                                   [Page  14]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+5 Information Model
+
+
+This section describes the object classes of the entries that
+represent the replication topology. The operational information for
+replication are administered through these entries. The LDUP Working
+Group will work towards defining an Internet standard to fully detail
+all these schema elements.
+
+
+5.1  Entries, Semantics and Relationships
+
+This section defines the organization of operational data for directory
+replication in terms of the relative placement of the entries that
+represent Naming Contexts, its Replicas, and their associated
+Replication agreements. This section also describes the purpose of
+these objects and abstractly describes their content.
+A Naming Context defines an area of DIT with independent replication
+policies. There are many mechanisms available to identify the set of
+Naming Contexts in a Directory, including through special auxiliary
+classes or through operational attributes in root DSE pointing to
+such entries. The LDUP information model standards will detail an
+appropriate mechanism.
+
+Entries representing the set of Replicas associated with a Naming
+Context are created immediately below (children) the Naming Context
+entries. Replica entries are defined as subentries and are
+intended to hold attributes that identify the Replica's LDAP Access
+Point, its Replica Type, and if it is a Fractional Replica, the
+attributes it does or does not hold. The attribute value of the entry's
+Relative Distinguished Name (RDN) is termed the Replica Identifier and
+is used as a component of each CSN associated with the replica.
+
+Immediately subordinate to each Replica Subentry are the entries
+representing the Replication Agreements between this replica and
+another replica on some other server in the network. A Replication
+Agreement entry is associated with exactly one remote replica.
+These entries are defined to hold attributes identifying
+the remote Replica associated with this agreement, the scheduling
+policy for replication operations, including times when replication is
+to be performed, when it is not to be performed, or the policies
+governing event-driven replication initiation another Replica, the
+scheduling policy for replication operations, including  times when
+replication is to be performed, when it is not to be performed, or the
+policies governing event-driven replication initiation.
+
+
+
+5.2  Root DSE Attributes
+
+LDUP information model will define Root DSE attributes to identify the
+set of naming Contexts and replicas present in an LDAP server.
+
+5.3  Naming Context
+
+The LDUP Information Model will implement schema elements for
+
+Merrells, Reed, Srinivasan                                   [Page  15]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+representing configuration and policy information common for all
+replicas of the Naming Context.  Attributes for recording the location
+and time of creation of naming contexts may also be identified by the
+information model.
+
+In future LDAP Access Control standards would define mechanisms for
+identifying the ACL policy associated with a Naming Context as well as
+the syntax and semantics of its representation.
+
+
+5.4  Replica Object Class and Entries
+
+Each Replica is characterized by a replica type.  This may be Primary,
+Updatable, or Read-Only.  The latter two types may be further defined
+as being Fractional. The Replica entry will include a Fractional Entry
+Specification for a Fractional Replica.
+
+There is a need to represent network addresses of servers holding
+replicas participating in Replication Agreements.  For this,
+the LDUP information model will define an attribute with an
+appropriate syntax to represent an LDAP server addresses with which to
+contact replicas.
+
+
+An Update Vector describes the point to which the Replica has been
+updated, in respect to all the other Replicas of the Naming Context.
+The vector is used at the initiation of a replication session to
+determine the sequence of updates that should be transferred.
+
+Enabling LDAP to be a fully distributed service is not an objective
+for the design of LDUP information model, though the information stored
+in replica entries could facilitate certain distributed operations.
+
+
+5.5  Lost and Found Entry
+
+When replicating operations between servers, conflicts may arise that
+cause a parent entry to be removed causing its child entries to become
+orphaned. In this case the Update Resolution Procedures will make the
+Lost and Found Entry the child's new superior.
+
+Each Replica Entry names it's Lost and Found Entry, which would
+usually be an entry below the Replica Entry itself. This well known
+place allows administrators, and their tools, to find and repair
+abandoned entries.
+
+
+
+5.6  Replication Agreement Object Class and Entries
+
+The Replication Agreement defines:
+
+1. The schedule for Replication Sessions initiation.
+
+2. The server that initiates the Replication Session, either the
+  Consumer or the Supplier.
+
+Merrells, Reed, Srinivasan                                   [Page  16]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+
+3. The authentication credentials that will be presented between
+  servers.
+
+4. The network/transport security scheme that will be employed in
+  order to ensure data confidentiality.
+
+5. The replication protocols and relevant protocol parameters to be
+  used for Full and Incremental updates. An OID is used to identify
+  the update transfer protocol, thus allowing for future extensions
+  or bilaterally agreed upon alternatives.
+
+6. If the Replica is Fractional, the Fractional Entry Specification for
+the attributes to be included or excluded
+
+Permission to participate in replication sessions will be controlled,
+at least in part, by the presence and content of replica agreements.
+
+The Supplier must be subject to the access control policy enforced by
+the Consumer. Since the access control policy information is stored
+and replicated as directory content, the access control imposed on the
+Supplier by the Consumer must be stored in the Consumer's Replication
+Agreement.
+
+
+
+5.6.1 
+     Replication Schedule
+
+There are two broad mechanisms for initiating replication sessions:
+(1) scheduled event driven and (2) change event driven.  The mechanism
+used to schedule replication operations between two servers is
+determined by the Schedule information that is part of the Replication
+Agreement governing the Replicas on those two servers.  Because each
+Replication Agreement describes the policy for one direction of the
+relationship, it is possible that events propagate via scheduled
+events in one direction, and by change events in the other.
+
+Change event driven replication sessions are, by their nature,
+initiated by suppliers of change information.  The server, which the
+change is made against, schedules a replication session in response to
+the change itself, so that notification of the change is passed on to
+other Replicas.
+
+Scheduled event driven replication sessions can be initiated by either
+consumers or suppliers of change information.  The schedule defines a
+calendar of time periods during which Replication Sessions should be
+initiated.
+
+Schedule information may include both scheduled and change event
+driven mechanisms. For instance, one such policy may be to begin
+replication within 15 seconds of any change event, or every 30 minutes
+if no change events are received.
+
+
+
+
+
+Merrells, Reed, Srinivasan                                   [Page  17]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+6 Policy Information
+
+
+Administrative policy information governs the behavior of the server
+This policy information needs to be consistently known and
+applied by all replicas of a Naming Context. It may be
+represented in the DIT as sub-entries, attributes, and attribute
+values. Auxiliary classes are a convenient way to hold such
+policy information and to uniformly replicate them among all its
+replicas.  For a naming context to be faithfully reproduced, all
+applicable prescriptive policy information represented among its
+ancestral entries must also be replicated. In all cases such
+policy information is transmitted as if it were an element of
+the Replica root entry.
+
+Policy information is always replicated in the same manner as any
+other entries, attributes, and attribute values.
+
+
+
+6.1  Schema Knowledge
+
+Schema subentries should be subordinate to the naming contexts to
+which they apply.  Given our model, a single server may hold replicas
+of several naming contexts. It is therefore essential that schema
+should not be considered to be a server-wide policy, but rather to be
+scoped by the namespace to which it applies.
+
+Schema modifications replicate in the same manner as other directory
+data.  Given the strict ordering of replication events, schema
+modifications will naturally be replicated prior to entry creations
+which use them, and subsequent to data deletions which eliminate
+references to schema elements to be deleted.  Servers MUST NOT
+replicate information about entries which are not defined in the
+schema.  Servers should not replicate modifications to existing schema
+definitions for which there are existing entries and/or attributes
+which rely on the schema element.
+
+Should a schema change cause an entry to be in violation of the new
+schema, it is recommended that the server preserve the entry for
+administrative repair. The server could add a known object class to
+make the entry valid and to mark the entry for maintenance.
+
+
+
+7 LDUP Update Transfer Protocol Framework
+
+
+A Replication Session occurs between a Supplier server and Consumer
+server over an LDAP connection.  This section describes the process by
+which a Replication Session is initiated, started and stopped.
+
+The session initiator, termed the Initiator, could be either the
+Supplier or Consumer. The Initiator sends an LDAP extended operation
+to the Responder identifying the replication agreement being acted on.
+The Supplier then sends a sequence of updates to the Consumer.
+
+Merrells, Reed, Srinivasan                                   [Page  18]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+
+All transfers are in one direction only.  A two way exchange requires
+two replication sessions; one session in each direction.
+
+
+7.1  Replication Session Initiation
+
+The Initiator starts the Replication Session by opening an LDAP
+connection to its Responder.  The Initiator binds using the
+authentication credentials provided in the Replication Agreement.
+The LDUP Update Transfer Protocol will define the LDAP extended
+operation the Initiator should perform to initialize an LDUP session.
+For the sake of convenience, this extended LDAP operation for
+initializing a replication session is referred to as the "Start
+Replication" operation.  Among other things, this operation will
+identify the role each
+server will perform, and what type of replication is to be performed.
+
+One server is to be the Consumer, the other the Supplier, and the
+replication may be either Full or Incremental.
+
+
+
+7.1.1 
+     Authentication
+
+
+The initiation of a Replication Session is to be restricted to
+privileged clients.  The identity and the credentials for the client
+eligible for initiating a replication session will be defined as
+attributes within Replication Agreements.
+
+7.1.2 
+     Consumer Initiated
+
+The Consumer binds to the Supplier using the authentication
+credentials provided in the Replication Agreement. The Consumer sends
+the "Start Replication" extended request to begin the Replication
+Session. The Supplier returns a "Start Replication" extended response
+containing a response code. The Consumer then disconnects from the
+Supplier. If the Supplier has agreed to the replication session
+initiation, it binds to the Consumer and behaves just as if the
+Supplier initiated the replication.
+
+
+
+7.1.3 
+     Supplier Initiated
+
+The Supplier binds to the Consumer using the authentication
+credentials provided in the Replication Agreement. The Supplier sends
+the "Start Replication" extended request to begin the
+Replication Session. The Consumer returns a "Start Replication"
+extended
+response containing a response code, and possibly its Update Vector.
+If the Consumer has agreed to the Replication Session initiation, then
+the transfer protocol begins.
+
+
+
+Merrells, Reed, Srinivasan                                   [Page  19]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+
+
+7.2  Start Replication Session
+
+7.2.1S
+      tart Replication Request
+
+
+The LDUP Update Transfer Protocol would define an LDAP Extended
+Request, referred to in this document as "Start Replication Request",
+that is sent from the Initiator to Responder. The parameters of the
+"Start Replication Request" would identify the Replication Agreement
+associated with the session, the Update Transfer Protocol associated \
+with the replication session, and other state information necessary
+to resume replication between the two servers.
+
+
+7.2.2S
+      tart Replication Response
+
+
+The LDUP Update Transfer Protocol would define an LDAP Extended
+Response, "Start Replication Response", sent in reply to a Start
+Replication Request, from the Responder to the Initiator. The
+parameters of the Start Replication Response include an response code,
+and an optional Update Vector.
+
+
+
+7.3  Update Transfer
+
+Each Update Transfer Protocol is identified by an OID. An LDUP
+conformant server implementation must support those update protocols
+that are
+defined as mandatory in the Update Transfer Protocol standard , and
+may support many others. A server will advertise its
+protocols in the Root DSE multi-valued attribute
+'supportedReplicationProtocols'.
+
+The Update Transfer Protocol would define the mechanisms for a
+Consumer to receive a complete (full) update or incremental update
+based on the current state of replication represented in the Update
+Vector. A full update is necessary for initializing a consumer
+replica upon establishment of replication agreements.
+
+
+
+7.4  End Replication Session
+
+A Replication Session is terminated by the "End Replication Request"
+initiated by the supplier.  The purpose of this request and response
+is to secure the state of the Update Vector associated with the two
+replicas that participated in replication.  This is necessary for
+proper resumption of replication during subsequent LDUP sessions
+
+
+
+
+Merrells, Reed, Srinivasan                                   [Page  20]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+7.5  Integrity & Confidentiality
+
+Data integrity (ie, protection from unintended changes) and
+confidentiality (ie, protection from unintended disclosure to
+eavesdroppers) SHOULD be provided by appropriate selection of
+underlying transports, for instance TLS, or IPSEC.  Replication MUST
+be supported across TLS LDAP connections.  Servers MAY be configured
+to refuse replication connections over unprotected TCP connections.
+
+
+
+
+8 LDUP Update Protocols
+
+
+This Internet-Draft defines two transfer protocols for the supplier to
+push changes to the consumer.   Other protocols could be defined to
+transfer changes, including those which pull changes from the supplier
+to the consumer, but those are left for future work.
+
+
+
+8.1  Replication Updates and Update Primitives
+
+Both LDUP Update Protocols define how Replication Updates are
+transferred from the Supplier to the Consumer. Each Replication Update
+consists of a set of Update Primitives that describe the state changes
+that have been made to a single entry. Each Replication Update is
+associated with a single entry identified by its UUID.
+
+
+ The Update Transfer Protocol would define a set of Update Primitives
+each of which codifies an assertion about the state change of an entry
+that resulted from a  directory update operation. The primitives will
+include sufficient data to allow recreation of corresponding state
+changes on the consumer's replica.  An assertion based approach has
+been chosen in such a way that the Primitives are idempotent, meaning
+that re-application of a Primitive to an Entry will cause no change to
+the entry. This is desirable as it provides some resilience against
+some kinds of system failures.
+
+Each Update Primitive contains a CSN that represents an ordering among
+all such primitives generated anywhere in the
+network. This ordering information is used by the consumer to reconcile
+among those primitives that lead to consistency violation
+ier.
+
+
+8.2  Fractional Updates
+
+When fully populating or incrementally bringing up to date a
+Fractional Replica each of the Replication Updates must only contain
+updates to the attributes in the Fractional Entry Specification.
+
+
+
+Merrells, Reed, Srinivasan                                   [Page  21]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+9 LDUP Full Update Transfer Protocol
+
+
+
+
+9.1  Full Update Transfer
+
+This Full Update Protocol provides a bulk transfer of the replica
+contents for the initial population of new replicas, and the
+refreshing of existing replicas.  The LDUP Update Transfer protocol
+standard will define the ways for this transfer is initiated.
+
+The Consumer must replace its entire replica contents with that sent
+from the Supplier.
+
+The Consumer need not service any requests for this Naming Context
+whilst the full update is in progress. The Consumer could instead
+return a
+referral to another replica, possibly the supplier.
+
+
+
+9.2  Replication Update Generation
+
+The entire state of a Replicated Area can be mapped onto a sequence of
+Replication Updates, each of which contains a sequence of Update
+Primitives that describe the entire state of a single entry.
+
+The sequence of Replication Updates must be ordered such that no entry
+is created before its parent.
+
+
+
+9.3  Replication Update Consumption
+
+A Consumer will receive the Replication Updates, extract the sequence
+of Update Primitives, and must apply them to the DIB in the order
+provided.
+
+
+
+9.4  Full Update, End Replication Session
+
+
+A Full Update should also result in the replication of all appropriate
+LDUP meta data (which are part of the replicated naming context), such
+as the sub-entry representing the Replica being updated and the Update
+Vector associated with it.
+The Supplier could be accepting updates whilst the update is in
+progress.  Once the Full Update has completed, an Incremental Update
+should be performed to transfer these changes.
+
+
+
+
+
+Merrells, Reed, Srinivasan                                   [Page  22]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+9.5  Interrupted Transmission
+
+If the Replication Session terminates before the End Replication
+Request is sent, then the Replica could be in an inconsistent state.
+ Until the replica is restored to a consistent
+state, the consumer might not permit LDAP Clients to access the
+incomplete replica. The Consumer could refer the Client to the
+Supplier Replica, or return an error result code.
+
+
+
+10 LDUP Incremental Update Transfer Protocol
+
+
+For efficiency, the Incremental Update Protocol transmits only those
+changes that have been made to the Supplier replica that the Consumer
+has not already received. In a replication topology with transitive
+redundant replication agreements, changes may propagate through the
+replica network via different routes.
+
+The Consumer must not support multiple concurrent replication sessions
+with more than one Supplier for the same Naming Context. A Supplier
+that attempts to initiate a Replication Session with a Consumer
+already participating as a Consumer in another Replication Session
+will receive appropriate error. .
+
+
+
+10.1 Update Vector
+
+The Supplier uses the Consumer's Update Vector to determine the
+sequence of updates that should be sent to the Consumer.
+
+Each Replica entry includes an Update Vector to record the point to
+which the replica has been updated. The vector is a set of CSN values,
+one value for each known updateable Replica. Each CSN value in the
+vector corresponds to the most recent change that occurred in an
+updateable replica that has been replicated to the replica whose
+replication state this Update Vector represents.
+
+For example, consider two updatable replicas of a naming context, one
+is assigned replica identifier  '1', the other replica identifier '2'.
+Each is responsible for maintaining its own update vector, which will
+contain two CSNs, one for each replica. So, if both replicas are
+identical they will have equivalent update vectors.
+
+Both Update Vectors =
+
+{1998081018:44:31z#0x000F#1#0x0000, 1998081018:51:20z#0x0001#2#0x0000}
+
+Subsequently, at 7pm, an update is applied to replica '2', so its
+update vector is updated.
+
+Replica '1' Update Vector =
+
+{1998081018:44:31z#0x000F#1#0x0000, 1998081018:51:20z#0x0001#2#0x0000}
+
+Merrells, Reed, Srinivasan                                   [Page  23]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+
+Replica '2' Update Vector =
+
+{1998081018:44:31z#0x000F#1#0x0000, 1998081019:00:00z#0x0000#2#0x0000}
+
+Since the Update Vector records the state to which the replica has
+been updated, a supplier server, during Replication Session
+initiation, can determine the sequence of updates that should be sent
+to the consumer. From the example above no updates need to be sent
+from replica '1' to replica '2', but there is an update pending from
+replica '2' to replica '1'.
+
+Because the Update Vector embodies knowledge of updates made at all
+known replicas it supports replication topologies that include
+transitive and redundant connections between replicas. It ensures that
+changes are not transferred to a consumer multiple times even though
+redundant replication agreements may exist. It also ensures that
+updates are passed across the replication network between replicas
+that are not directly linked to each other.
+
+It may be the case that a CSN for a given replica is absent, for one
+of two reasons.
+
+1. CSNs for Read-Only replicas might be absent because no changes will
+  have ever been applied to that Replica, so there are no changes to
+  replicate.
+
+2. CSNs for newly created replicas may be absent because no changes to
+  that replica have yet been propagated.
+
+An Update Vector might also contain a CSN for a replica that no longer
+exists.  The replica may have been temporarily taken out of service,
+or may have been removed from the replication topology permanently. An
+implementation may choose to retire a CSN after some configurable time
+period.
+
+
+
+10.2 Supplier Initiated, Incremental Update, Start Replication Session
+
+The Consumer Responder must return its Update Vector to the Supplier
+Initiator. The Supplier uses this to determine the sequence of
+Replication Updates that need to be sent to the Consumer.
+
+
+
+10.3 Replication Update Generation
+
+The Supplier generates a sequence of Replication Updates to be sent to
+the consumer. To enforce LDAP Constraint 20.1.6, that the LDAP Modify
+must be applied atomically, each Replication Update must contain the
+entire sequence of Update Primitives for all the LDAP Operations for
+which the Replication Update contains Update Primitives. Stated less
+formally, for each primitive the update contains, it must also contain
+all the other primitives that came from the same operation.
+
+
+Merrells, Reed, Srinivasan                                   [Page  24]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+
+
+10.3.1    Replication Log Implementation
+
+A log-based implementation might take the approach of mapping LDAP
+Operations onto an equivalent  sequence of Update Primitives. A
+systematic procedure for achieving this will be fully described in the
+standard document defining Update Reconciliation Procedures.
+
+The Consumer Update Vector is used to determine the sequence of LDAP
+Operations in the operation log that the Consumer has not yet seen.
+
+
+
+10.3.2    State-Based Implementation
+
+A state-based implementation might consider each entry of the replica
+in turn using the Update Vector of the consumer to find all the state
+changes that need to be transferred. Each state change (entry,
+attribute, or value - creation, deletion, or update) is mapped onto
+the equivalent Update Primitive. All the Update Primitives for a
+single entry might be collected into a single Replication Update.
+Consequently, it could contain the resultant primitives of many LDAP
+operations.
+
+
+
+10.4 Replication Update Consumption
+
+A Consumer will receive Replication Updates, extract the sequence of
+Update Primitives, and must apply them to the DIB in the order
+provided. LDAP Constraint 20.1.6 states that the modifications within
+an LDAP Modify operation must be applied in the sequence provided.
+
+Those Update Primitives must be reconciled with the current replica
+contents and any previously received updates.  In short,,
+updates are compared to the state information associated with the item
+being operated on. If the change has a more recent CSN, then it is
+applied to the directory contents. If the change has an older CSN it
+is no longer relevant and its change must not be effected.
+
+If the consumer acts as a supplier to other replicas then the updates
+are retained for forwarding.
+
+
+
+10.5 Update Resolution Procedures
+
+The LDAP Update Operations must abide by the constraints imposed by
+the LDAP Data Model and LDAP Operational Behaviour, Appendix A. An
+operation that would violate at least one of these constraints is
+rejected with an error result code.
+
+The loose consistency model of this replication architecture and its
+support for multiple updateable replicas of a naming context means
+
+
+Merrells, Reed, Srinivasan                                   [Page  25]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+that LDAP Update Operations could be valid at one replica, but not in
+another. At the time of acceptance, the accepting
+replica may not have received other updates that would cause a
+constraint to be violated, and the operation to be rejected.
+
+Replication Updates must never be rejected because of a violation of
+an LDAP Constraint. If the result of applying the Replication Update
+causes a constraint violation to occur, then some remedial action must
+be taken to satisfy the constraint. These Update Resolution Procedures
+are introduced here will be fully defined withinLDUP Update Resolution
+Procedures.
+
+
+
+10.5.1    URP: Distinguished Names
+
+LDAP Constraints 20.1.1 and 20.1.10 ensure that each entry in the
+replicated area has a unique DN. A Replication Update could violate
+this constraint producing two entries, with different unique
+identifiers, but with the same DN. The resolution procedure is to
+rename the most recently named entry so that its RDN includes its own
+unique identifier. This ensures that the new DN of the entry shall be
+unique.
+
+
+
+10.5.2    URP: Orphaned Entries
+
+LDAP Constraints 20.1.11 ensures that every entry must have a parent
+entry. A Replication Update could violate this constraint producing an
+entry with no parent entry. The resolution procedure is to create a
+Glue Entry to take the place of the absent parent. The Glue Entry's
+superior will be the Lost and Found Entry. This well known place
+allows administrators and their tools to find and repair abandoned
+entries.
+
+
+
+10.5.3    URP: Distinguished Not Present
+
+LDAP Constraints 20.1.8 and 20.1.9 ensure that the components of an
+RDN appear as attribute values of the entry. A Replication Update
+could violate this constraint producing an entry without its
+distinguished values. The resolution procedure is to add the missing
+attribute values, and mark them as distinguished not present, so that
+they can be deleted when the attribute values are no longer
+distinguished.
+
+
+
+10.5.4    URP: Schema - Single Valued Attributes
+
+LDAP Constraint 20.1.7 enforces the single-valued attribute schema
+restriction. A Replication Update could violate this constraint
+creating a multi-value single-valued attribute. The resolution
+
+
+Merrells, Reed, Srinivasan                                   [Page  26]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+procedure is to consider the value of a single-valued attribute as
+always being equal. In this way the most recently added value will be
+retained, and the older one discarded.
+
+
+
+10.5.5    URP: Schema - Required Attributes
+
+LDAP Constraint 20.1.7 enforces the schema objectclass definitions on
+an entry. A Replication Update could violate this constraint creating
+an entry that does not have attribute values for required attributes.
+The resolution procedure is to ignore the schema violation and mark
+the entry for administrative repair.
+
+
+
+10.5.6    URP: Schema - Extra Attributes
+
+LDAP Constraint 20.1.3 and 20.1.7 enforces the schema objectclass
+definitions on an entry. A Replication Update could violate this
+constraint creating an entry that has attribute values not allowed by
+the objectclass values of the entry. The resolution procedure is to
+ignore the schema violation and mark the entry for administrative
+repair.
+
+
+
+10.5.7    URP: Duplicate Attribute Values
+
+LDAP Constraint 20.1.5 ensures that the values of an attribute
+constitute a set of unique values. A Replication Update could violate
+this constraint. The resolution procedure is to enforce this
+constraint, recording the most recently assigned CSN with the value.
+
+
+
+10.5.8    URP: Ancestry Graph Cycle
+
+LDAP Constraint 20.4.2.1 prevents against a cycle in the DIT. A
+Replication Update could violate this constraint causing an entry to
+become it's own parent, or for it to appear even higher in it's
+ancestry graph. The resolution procedure is to break the cycle by
+changing the parent of the entry closest to be the lost and found
+entry.
+
+
+
+10.6 Incremental Update, End Replication Session
+
+If the Supplier sent none of its own updates to the Consumer, then the
+Supplier's CSN within the Supplier's update vector should be updated
+with the earliest possible CSN that it could generate, to record the
+time of the last successful replication session. The Consumer will
+have received the Supplier's Update Vector in the replica sub-entry it
+holds for the Supplier replica.
+
+Merrells, Reed, Srinivasan                                   [Page  27]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+
+The Consumer's resultant Update Vector CSN values will be at least as
+great as the Supplier's Update Vector.
+
+The Supplier may request that the Consumer return its resultant Update
+Vector so that the Supplier can update its replica sub-entry for the
+Consumer Replica. The Supplier requests this by setting a flag in the
+End Replication Request. The default flag value is TRUE meaning the
+Consumer Update Vector must be returned.
+
+
+
+10.7 Interrupted Transmission
+
+If the Replication Session terminates before the End Replication
+Request is sent then the Consumer's Update Vector may or may not be
+updated to reflect the updates received. The Start Replication request
+includes a Replication Update Ordering flag which states whether the
+updates were sent in CSN order per replica.
+
+If updates are sent in CSN order per replica then it is possible to
+update the Consumer Update Vector to reflect that some portion of the
+updates to have been sent have been received and successfully applied.
+The next Incremental Replication Session will pick up where the failed
+session left off.
+
+If updates are not sent in CSN order per replica then the Consumer
+Update can not be updated. The next Incremental Replication Session
+will begin where the failed session began. Some updates will be
+replayed, but because the application of Replication Updates is
+idempotent they will not cause any state changes.
+
+
+
+11 Purging State Information
+
+
+The state information stored with each entry need not be stored
+indefinitely. A server implementation may choose to periodically, or
+continuously, remove state information that is no longer required. The
+mechanism is implementation-dependent, but to ensure interoperability
+between implementations, the state information must not be purged
+until all known replicas have received and acknowledged the change
+associated with a CSN. This is determined from the Purge Vector
+[11.1].
+
+All the CSNs stored that are lower than the Purge Vector may be
+purged, because no changes with older CSNs can be replicated to this
+replica.
+
+
+
+11.1 Purge Vector
+
+The Purge Vector is an Update Vector constructed from the Update
+Vectors of all known replicas. Each replica has a sub-entry for each
+
+Merrells, Reed, Srinivasan                                   [Page  28]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+known replica stored below its naming context. Each of those entries
+contains the last known update vector for that replica. The lowest CSN
+for each replica are taken from these update vectors to form the Purge
+Vector. The Purge Vector is used to determine when state information
+and updates need no longer be stored.
+
+
+
+11.2 Purging Deleted Entries, Attributes, and Attribute Values
+
+The following conditions must hold before an item can be deleted from
+the Directory Information Base.
+
+1) The LDAP delete operation has been propagated to all replication
+agreement partners.
+
+2) All the updates from all the other replicas with CSNs less than the
+CSN on the deletion have been propagated to the server holding the
+deleted entry (similarly for deleted attributes and attribute values).
+
+3) The CSN generator of the other Replicas must have advanced beyond
+the deletion CSN of the deleted entry. Otherwise, it is possible for
+one of those Replicas to generate operations with CSNs earlier than
+the deleted entry.
+
+
+12 Replication Configuration and Management
+
+
+Replication management entries, such as replica or replication
+agreement entries, can be altered on any updateable replica. These
+entries are implicitly included in the directory entries governed by
+any agreement associated with this naming context.  As a result, all
+servers with a replica of a naming context will have access to
+information about all other replicas and associated agreements.
+
+The deployment and maintenance of a replicated directory network
+involves the creation and management of all the replicas of a naming
+context and replication agreements among these replicas.  This section
+outlines, through an example, the administrative actions necessary to
+create a new replica and establish replication agreements.  Typically,
+administrative tools will guide the administrator and facilitate these
+actions.  The objective of this example is to illustrate the
+architectural relationship among various replication related
+operational information.
+
+A copy of an agreement should exist on both the supplier and consumer
+side for the replication update transfer protocol to be able to start.
+For this purpose, the root of the naming context, replica objects and
+the replication agreement objects are created first on one of the
+servers.  A copy of these objects are then manually created on the
+second server associated with the agreement.
+
+The scenario below starts with a server (named DSA1) that holds an
+updateable replica of a naming context NC1.  Procedures to establish
+an updateable replica of the naming context on a second server (DSA2)
+
+Merrells, Reed, Srinivasan                                   [Page  29]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+are outlined.
+
+On DSA1:
+
+1) Add the context prefix for NC1 to the Root DSE attribute
+  'replicaRoot' if it does not already exist.
+
+2) Alter the 'ObjectClass' attribute of the root entry of NC1 to
+  include the "namingContext" auxiliary class.
+
+3) Create a replica object, NC1R1, (as a child of the root of NC1) to
+  represent the replica on DSA1.  The attributes include replica type
+  (updateable, read-only etc.) and DSA1 access point information.
+
+4) Create a copy of the replica object NC1R2 (after it is created on
+  DSA2)
+
+5) Create a replication agreement, NC1R1-R2 to represent update
+  transfer from NC1R1 to NC1R2.  This object is a child of NC1R1.
+
+On DSA2:
+
+1) Add NC1's context prefix to the Root DSE attribute 'replicaRoot'.
+
+2) Create a copy of the root entry of NC1 as a copy of the one in DSA1
+  (including the namingContext auxiliary class)
+
+3) Create a copy of the replica object NC1R1
+
+4) Create a second replica object, NC1R2 (as a sibling of NC1R1) to
+  represent the replica on DSA2.
+
+5) Create a copy of the replication agreement, NC1R1-R2
+
+6) Create a replication agreement, NC1R2-R1, to represent update
+  transfer from NC1R2 to NC1R1.  This object is a sibling of NC1R1-
+  R2.
+
+After these actions update transfer to satisfy either of the two
+agreements can commence.
+
+If data already existed in one of the replicas, the update transfer
+protocol should perform a complete update of the data associated with
+the agreement before normal replication begins.
+
+
+
+13 Time
+
+
+The server assigns a CSN for every LDAP update operation it receives.
+Since the CSN is principally based on time, the CSN is susceptible to
+the Replica clocks drifting in relation to each other (either forwards
+or backwards).
+
+The server must never assign a CSN older than or equal to the last CSN
+it assigned.
+
+Merrells, Reed, Srinivasan                                   [Page  30]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+
+The server must reject update operations, from any source, which would
+result in setting a CSN on an entry or a value which is earlier than
+the one that is there.  The error code serverClocksOutOfSync (72)
+should be returned.
+
+
+14 Security Considerations
+
+
+The preceding architecture discussion covers the server
+authentication, session confidentiality, and session integrity in
+sections 7.1.1 and 7.5
+
+The internet draft "Authentication Methods" for LDAP, provides a
+detailed LDAP security discussion.  Its introductory passage is
+paraphrased below. [AUTH]
+
+A Replication Session can be protected with the following security
+mechanisms.
+
+1) Authentication by means of the SASL mechanism set, possibly backed
+  by the TLS credentials exchange mechanism,
+
+2) Authorization by means of access control based on the Initiators
+  authenticated identity,
+
+3) Data integrity protection by means of the TLS protocol or data-
+  integrity SASL mechanisms,
+
+4) Protection against snooping by means of the TLS protocol or data-
+  encrypting SASL mechanisms,
+
+The configuration entries that represent Replication Agreements may
+contain authentication information. This information must never be
+replicated between replicas.
+
+Updates to a multi-mastered entry may collide causing the Update
+Resolution Procedures [10.5] to reject or reverse one of the changes
+to the entry. The URP algorithms resolve conflicts by using the total
+ordering of updates imposed by the assignment of CSNs for every
+operation. As a consequence updates originating from system
+administrators have no priority over updates originating from regular
+system users.
+
+
+
+15 Acknowledgements
+
+
+This document is a product of the LDUP Working Group of the IETF. The
+contributions of its members is greatly appreciated.
+
+
+
+
+
+Merrells, Reed, Srinivasan                                   [Page  31]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+16 References
+
+
+[AUTH] - M. Wahl, H. Alvestrand, J. Hodges, RL "Bob" Morgan,
+"Authentication Methods for LDAP", Internet Draft, draft-ietf-ldapext-
+authmeth-02.txt, June 1998.
+
+[BCP-11] - R. Hovey, S. Bradner, "The Organizations Involved in the
+IETF Standards Process", BCP 11, RFC 2028, October 1996.
+
+[LDAPv3] - M. Wahl, S. Kille, T. Howes, "Lightweight Directory Access
+Protocol (v3)", RFC 2251, December1997.
+
+[LDUP Requirements] - R. Weiser, E. Stokes 'LDAP Replication
+Requirements', Internet Draft, draft-weiser-replica-req-02.txt,
+October, 1999
+
+[NTP] - D. L. Mills, "Network Time Protocol (Version 3)", RFC 1305,
+March, 1992.
+
+[RFC2119] - S. Bradner, "Key words for use in RFCs to Indicate
+Requirement Levels", RFC 2119.
+
+[RFC2252] - M. Wahl, A. Coulbeck, T. Howes, S. Kille, 'Lightweight
+Directory Access Protocol (v3): Attribute Syntax Definitions', RFC
+2252, December 1997.
+
+[SNTP] - D. L. Mills, "Simple Network Time Protocol (SNTP) Version 4
+for IPv4, IPv6 and OSI", RFC 2030, University of Delaware, October
+1996.
+
+[TLS] -  J. Hodges, R. L. "Bob" Morgan, M. Wahl, "Lightweight
+Directory Access Protocol (v3):                Extension for Transport
+Layer Security", Internet draft, draft-ietf-ldapext-ldapv3-tls-01.txt,
+June 1998.
+
+[X501] - ITU-T Recommendation X.501 (1993), ) | ISO/IEC 9594-2:1993,
+Information Technology - Open Systems Interconnection - The Directory:
+Models
+
+[X680] - ITU-T Recommendation X.680 (1994) | ISO/IEC 8824-1:1995,
+Information technology - Abstract Syntax Notation One (ASN.1):
+Specification of Basic Notation
+
+[X525] - ITU-T Recommendation X.525 (1997) | ISO/IEC 9594-9:1997,
+Information Technology - Open Systems Interconnection - The Directory:
+Replication
+
+
+17 Intellectual Property Notice
+
+
+The IETF takes no position regarding the validity or scope of any
+intellectual property or other rights that might be claimed to
+pertain to the implementation or use of the technology described in
+this document or the extent to which any license under such rights
+
+
+Merrells, Reed, Srinivasan                                   [Page  32]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+might or might not be available; neither does it represent that it has
+made any effort to identify any such rights.  Information on the
+IETF's procedures with respect to rights in standards-track and
+standards-related documentation can be found in BCP-11. [BCP-11]
+Copies of claims of rights made available for publication and any
+assurances of licenses to be made available, or the result of an
+attempt made to obtain a general license or permission for the use of
+such proprietary rights by implementors or users of this specification
+can be obtained from the IETF Secretariat.
+
+The IETF invites any interested party to bring to its attention any
+copyrights, patents or patent applications, or other proprietary
+rights which may cover technology that may be required to practice
+this standard.  Please address the information to the IETF Executive
+Director.
+
+
+18 Copyright Notice
+
+
+ Copyright (C) The Internet Society (1998,1999). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to
+others, and derivative works that comment on or otherwise explain it
+or assist in its implementation may be prepared, copied, published and
+distributed, in whole or in part, without restriction of any kind,
+provided that the above copyright notice and this paragraph are
+included on all such copies and derivative works.  However, this
+document itself may not be modified in any way, such as by removing
+the copyright notice or references to the Internet Society or other
+Internet organizations, except as needed for the  purpose of
+developing Internet standards in which case the procedures for
+copyrights defined in the Internet Standards process must be followed,
+or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be
+revoked by the Internet Society or its successors or assigns.
+
+This document and the information contained herein is provided on an
+"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN
+WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+19 Authors' Address
+
+
+     John Merrells
+     Netscape Communications, Inc.
+     501 East Middlefield Road
+     Mountain View
+     CA 94043
+     USA
+     E-mail: merrells@netscape.com
+
+
+Merrells, Reed, Srinivasan                                   [Page  33]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+     Phone: +1 650-937-5739
+
+     Edwards E. Reed
+     Reed-Matthews, Inc.
+     1064 East 140 North
+     Lindon
+     UT  84042
+     USA
+     E-mail: eer@oncalldba.com
+     Phone: +1 801-796-7065
+
+     Uppili Srinivasan
+     Oracle, Inc.
+     Redwood Shores
+     CA
+     USA
+     E-mail: usriniva@us.oracle.com
+     Phone: +1 650 506 3039
+
+     LDUP Engineering Mailing List: ldup-repl@external.cisco.com
+     LDUP Working Group Mailing List: ietf-ldup@imc.org
+
+
+20 Appendix A - LDAP Constraints
+
+
+20.1 LDAP Constraints Clauses
+
+This is an enumeration of the Data Model and Operation Behaviour
+constraint clauses defined in RFC 2251. [LDAPv3]
+
+1) Data Model - Entries have names: one or more attribute values from
+  the entry form its relative distinguished name (RDN), which MUST be
+  unique among all its siblings. (p5)
+
+2) Data Model - Attributes of Entries - Each entry MUST have an
+  objectClass attribute. (p6)
+
+3) Data Model - Attributes of Entries - Servers MUST NOT permit
+  clients to add attributes to an entry unless those attributes are
+  permitted by the object class definitions. (p6)
+
+4) Relationship to X.500 - This document defines LDAP in terms of
+  X.500 as an X.500 access mechanism.  An LDAP server MUST act in
+  accordance with the X.500 (1993) series of ITU recommendations when
+  providing the service. However, it is not required that an LDAP
+  server make use of any X.500 protocols in providing this service,
+  e.g. LDAP can be mapped onto any other directory system so long as
+  the X.500 data and service model as used in LDAP is not violated in
+  the LDAP interface. (p8)
+
+5) Elements of Protocol - Common Elements - Attribute - Each attribute
+  value is distinct in the set (no duplicates). (p14)
+
+6) Elements of Protocol - Modify Operation - The entire list of entry
+  modifications MUST be performed in the order they are listed, as a
+
+Merrells, Reed, Srinivasan                                   [Page  34]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+  single atomic operation. (p33)
+
+7) Elements of Protocol - Modify Operation - While individual
+  modifications may violate the directory schema, the resulting entry
+  after the entire list of modifications is performed MUST conform to
+  the requirements of the directory schema. (p33)
+
+8) Elements of Protocol - Modify Operation - The Modify Operation
+  cannot be used to remove from an entry any of its distinguished
+  values, those values which form the entry's relative distinguished
+  name. (p34)
+
+9) Elements of Protocol - Add Operation - Clients MUST include
+  distinguished values (those forming the entry's own RDN) in this
+  list, the objectClass attribute, and values of any mandatory
+  attributes of the listed object classes. (p35)
+
+10)  Elements of Protocol - Add Operation - The entry named in the
+  entry field of the AddRequest MUST NOT exist for the AddRequest to
+  succeed. (p35)
+
+11)  Elements of Protocol - Add Operation - The parent of the entry to
+  be added MUST exist. (p35)
+
+12)  Elements of Protocol - Delete Operation - ... only leaf entries
+  (those with no subordinate entries) can be deleted with this
+  operation. (p35)
+
+13)  Elements of Protocol - Modify DN Operation - If there was already
+  an entry with that name [the new DN], the operation would fail.
+  (p36)
+
+14)  Elements of Protocol - Modify DN Operation - The server may not
+  perform the operation and return an error code if the setting of
+  the deleteoldrdn parameter would cause a schema inconsistency in
+  the entry. (p36)
+
+
+
+20.2 LDAP Data Model Constraints
+
+The LDAP Data Model Constraint clauses as written in RFC 2251 [LDAPv3]
+may be summarised as follows.
+
+a) The parent of an entry must exist. (LDAP Constraint 11 & 12.)
+
+b) The RDN of an entry is unique among all its siblings. (LDAP
+  Constraint 1.)
+
+c) The components of the RDN must appear as attribute values of the
+  entry. (LDAP Constraint 8 & 9.)
+
+d) An entry must have an objectclass attribute. (LDAP Constraint 2 &
+  9.)
+
+e) An entry must conform to the schema constraints.  (LDAP Constraint
+
+
+Merrells, Reed, Srinivasan                                   [Page  35]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+  3 & 7.)
+
+f) Duplicate attribute values are not permitted. (LDAP Constraint 5.)
+
+
+
+20.3 LDAP Operation Behaviour Constraints
+
+The LDAP Operation Behaviour Constraint clauses as written in RFC 2251
+[LDAPv3] may be summarised as follows.
+
+A) The Add Operation will fail if an entry with the target DN already
+exists. (LDAP Constraint 10.)
+
+B) The Add Operation will fail if the entry violates data constraints:
+
+     a - The parent of the entry does not exist. (LDAP Constraint 11.)
+
+     b - The entry already exists. (LDAP Constraint 10.)
+
+     c - The entry RDN components appear as attribute values on the
+     entry. (LDAP Constraint 9.)
+
+     d - The entry has an objectclass attribute. (LDAP Constraint 9.)
+
+     e - The entry conforms to the schema constraints. (LDAP
+     Constraint 9.)
+
+     f - The entry has no duplicated attribute values. (LDAP
+Constraint 5.)
+
+C) The modifications of a Modify Operation are applied in the order
+presented. (LDAP Constraint 6.)
+
+D) The modifications of a Modify Operation are applied atomically.
+(LDAP Constraint 6.)
+
+E) A Modify Operation will fail if it results in an entry that
+violates data constraints:
+
+     c - If it attempts to remove distinguished attribute values.
+     (LDAP Constraint 8.)
+
+     d - If it removes the objectclass attribute. (LDAP Constraint 2.)
+
+     e - If it violates the schema constraints. (LDAP Constraint 7.)
+
+     f - If it creates duplicate attribute values. (LDAP Constraint
+     5.)
+
+F) The Delete Operation will fail if it would result in a DIT that
+violates data constraints:
+
+     a - The deleted entry must not have any children. (LDAP
+Constraint 12.)
+
+
+
+Merrells, Reed, Srinivasan                                   [Page  36]
+                        Expires 10 September 2000
+
+
+
+
+
+INTERNET-DRAFT      LDAP Replication Architecture      March 10, 2000
+
+
+G) The ModDN Operation will fail if it would result in a DIT or entry
+that violates data constraints:
+
+     b - The new Superior entry must exist. (Derived LDAP Data Model
+     Constraint A)
+
+     c - An entry with the new DN must not already exist. (LDAP
+     Constraint 13.)
+
+     c - The new RDN components do not appear as attribute values on
+     the entry. (LDAP Constraint 1.)
+
+     d - If it removes the objectclass attribute. (LDAP Constraint 2.)
+
+     e - It is permitted for the operation to result in an entry that
+     violates the schema constraints. (LDAP Constraint 14.)
+
+
+
+20.4 New LDAP Constraints
+
+The introduction of support for multi-mastered entries, by the
+replication scheme presented in this document, necessitates the
+imposition of new constraints upon the Data Model and LDAP Operation
+Behaviour.
+
+
+
+20.4.1    New LDAP Data Model Constraints
+
+1) Each entry shall have a unique identifier generated by the UUID
+algorithm available through the 'entryUUID' operational attribute. The
+entryUUID attribute is single valued.
+
+
+
+20.4.2    New LDAP Operation Behaviour Constraints
+
+1) The LDAP Data Model Constraints do not prevent cycles in the
+  ancestry graph. Existing constraints Data Model Constraint - 20.4.1
+  - (a) and Operation Constraint - 20.4.2 - (B) would prevent this in
+  the single master case, but not in the presence of multiple
+  masters.
+
+2) The LDAP Data Model Constraints state that only the LDAP Modify
+  Operation is atomic. All other LDAP Update Operations are also
+  considered to be atomically applied to the DIB.
+
+
+
+
+
+
+
+
+
+Merrells, Reed, Srinivasan                                   [Page  37]
+                        Expires 10 September 2000
+
+
diff --git a/doc/drafts/draft-ietf-ldup-protocol-xx.txt b/doc/drafts/draft-ietf-ldup-protocol-xx.txt
new file mode 100644 (file)
index 0000000..9108794
--- /dev/null
@@ -0,0 +1,895 @@
+
+LDUP Replication Update Protocol
+Internet-Draft
+Intended Category: Standards Track
+Expires: September 10, 2000
+
+
+                                                            Ellen Stokes
+                                                         IBM Corporation
+
+                                                             Gordon Good
+                                           Netscape Communications Corp.
+
+                                                           March 10 2000
+
+                  The LDUP Replication Update Protocol
+               Filename: draft-ietf-ldup-protocol-01.txt
+
+Table of Contents
+
+1.    Status of this Memo.............................................2
+2.    Abstract........................................................2
+3.    Overview of Protocol............................................2
+4.    High-level Description of Protocol Flow.........................3
+4.1   Supplier-initiated incremental replication protocol.............3
+4.2.     Consumer-initiated replication protocol......................4
+5.    Replication protocol element definitions........................5
+5.1   StartFramedProtocolRequest Extended Operation...................5
+5.2   StartFramedProtocolResponse Extended Operation..................6
+5.3   ReplicationUpdate Extended Operation............................7
+5.3.1    UniqueIdentifier.............................................8
+5.3.2    ReplicationPrimitive.........................................8
+5.3.2.1     AddEntryPrimitive.........................................8
+5.3.2.2     MoveEntryPrimitive........................................9
+5.3.2.3     RenameEntryPrimitive......................................9
+5.3.2.4     RemoveEntryPrimitive......................................9
+5.3.2.5     AddAttributeValuePrimitive................................10
+5.3.2.6     RemoveAttributeValuePrimitive.............................10
+5.3.2.7     RemoveAttributePrimitive..................................10
+5.4   EndFramedProtocolRequest Extended Operation.....................11
+5.5   EndFramedProtocolResponse Extended Operation....................11
+5.6   ReplicationUpdateResponse Extended Operation....................12
+6.    Semantics of Full and Incremental Update protocols..............13
+7.    Summary of response codes.......................................13
+8.    Implications for log-based and state-based servers..............13
+9.    Replication of access control and schema information............13
+10.   Security Considerations.........................................14
+11.   Glossary of Terms...............................................14
+12.   Acknowledgments.................................................14
+13.   References......................................................14
+14.   Author's Addresses..............................................15
+
+
+
+Stokes and Good                                                 [Page 1]
+\f
+Internet-Draft               LDUP Workgroup                March 10 2000
+
+
+1. Status of this Memo
+
+   This document is an Internet-Draft and is in full conformance with
+   all provisions of Section 10 of RFC2026.
+
+   Internet-Drafts are working documents of the Internet Engineering
+   Task Force (IETF), its areas, and its working groups. Note that other
+   groups may also distribute working documents as Internet-Drafts.
+
+   Internet-Drafts are draft documents valid for a maximum of six months
+   and may be updated, replaced, or obsoleted by other documents at any
+   time.  It is inappropriate to use Internet- Drafts as reference
+   material or to cite them other than as "work in progress."
+
+   To view the list Internet-Draft Shadow Directories, see
+   http://www.ietf.org/shadow.html.
+
+   This Internet Draft expires September 10, 2000.
+
+
+2. Abstract
+
+   The protocol described in this document is designed to allow one LDAP
+   server to replicate its directory content to another LDAP server. The
+   protocol is designed to be used in a replication configuration where
+   multiple updatable servers are present. Provisions are made in the
+   protocol to carry information that allows the server receiving
+   updates to apply a total ordering to all updates in the replicated
+   system. This total ordering allows all replicas to correctly resolve
+   conflicts that arise when LDAP clients submit changes to different
+   servers that later replicate to one another.
+
+   All protocol elements described here are LDAP Version 3 extended
+   operations. LDAP Version 3 is described in RFC 2251 [LDAPv3].
+
+   Certain terms used in this document are defined in the document "LDAP
+   Replication Architecture" (draft-ietf-ldup-model-00.txt).
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", and "MAY" in this document are
+   to be interpreted as described in RFC 2119 [KEYWORDS].
+
+3. Overview of Protocol
+
+   The LDAP Replication Architecture [ARCHITECTURE] describes the
+   overall approach used in ensuring consistency of multiple updatable
+   replicas of directory content. The protocol described in this
+   document implements the approach desribed in that document.
+
+
+
+Stokes and Good                                                 [Page 2]
+\f
+Internet-Draft               LDUP Workgroup                March 10 2000
+
+
+   LDAP Version 3 extended operations are used to carry replicated
+   content from one server to another. The extended operations defined
+   in this document are used to initiate and end a replication session,
+   and to exchange updates. These updates carry with them information
+   that allows the receiving server to apply a total ordering to all of
+   the updates in a replicated system. All servers that receive
+   replication updates apply a consistent set of update resolution
+   policies, described in [URP]. Consistent application of the update
+   resolution policies ensures that all replicas eventually converge and
+   contain the same directory data.
+
+   This protocol is based upon the extended operations defined in
+   [FRAMING].
+
+   This protocol is intended to meet the requirements set forth in
+   [REQ].
+
+4. High-level Description of Protocol Flow
+
+   The following section provides a high-level overview of the
+   replication protocol. Throughout this section, the supplier server is
+   indicated by the letter "S" and the consumer server by the letter
+   "C". The construct "S -> C" indicates that the supplier is sending an
+   LDAPv3 extended operation to the consumer, and "C -> S" indicates
+   that the consumer is sending an LDAPv3 extended operation to the
+   supplier.
+
+4.1 Supplier-initiated incremental replication protocol
+
+      S -> C: LDAP bind operation (identity and credentials
+             used are implementation-defined)
+
+      C -> S: Bind response
+
+      S -> C: StartFramedProtocolRequest LDAPv3 extended
+              operation. The parameters are:
+
+                1) The OID for the LDUP incremental replication protocol or the
+                   LDUP total update protocol, depending on whether an incremental
+                   or complete refresh of the replica is to be performed.
+                2) A protocol-specific payload containing:
+                  a) The root of replicated area (unambiguously
+                     identifies the replicated area)
+                  b) The supplier's replicaID
+                  c) The protocol initiation type - Supplier-Initiated
+                     in this case.
+
+      C -> S: StartFramedProtocolResponse LDAPv3 extended operation. The
+
+
+
+Stokes and Good                                                 [Page 3]
+\f
+Internet-Draft               LDUP Workgroup                March 10 2000
+
+
+              parameters are:
+
+                1) A protocol-specific payload containing:
+                  a) A response code (see section 7)
+                  b) An optional update vector that is included
+                     if and only if the response code is REPL_SUCCESS.
+
+      S -> C: The supplier may send zero or more ReplicationUpdate LDAPv3
+              extended operations. The parameters are:
+
+                1) The UUID of the entry being updated
+                2) One or more Replication Primitives (The supplier
+                   may send as many of these as required to bring
+                   the consumer up to date)
+
+      C -> S: At any time, the consumer may send an unsolicited
+              ReplicationUpdateResponse LDAPv3 extended operation. The
+              parameters are:
+
+                1) An optional update vector.  If sent, this indicates that
+                   the consumer has committed all updates whose CSNs are
+                   covered by the transmitted update vector [see glossary
+                   for a definition of "covered by"].
+                2) An optional AbortUpdate boolean flag.  If a supplier
+                   receives a ReplicationUpdateResponse from a consumer with
+                   the AbortUpdate flag set to true, the supplier server MUST
+                   immediately cease sending updates and terminate its
+                   connection to the consumer.
+
+      S -> C: After all required updates have been sent to the consumer, the
+              supplier sends an EndFramedProtocolRequest LDAPv3 extended
+              operation.
+
+      C -> S: The consumer responds by sending an EndFramedProtocolResponse
+              LDAPv3 extended operation, and then closes the connection.
+
+4.2. Consumer-initiated replication protocol
+
+   C -> S: LDAP bind operation (identity and credentials
+          used are implementation-defined)
+
+   S -> C: Bind response
+
+   C -> S: StartFramedProtocolRequest LDAPv3 extended
+           operation. The parameters are:
+
+             1) The OID for the LDUP incremental replication protocol or the
+                LDUP total update protocol, depending on whether an incremental
+
+
+
+Stokes and Good                                                 [Page 4]
+\f
+Internet-Draft               LDUP Workgroup                March 10 2000
+
+
+                or complete refresh of the replica is to be performed.
+             2) A protocol-specific payload containing:
+               a) The root of replicated area (unambiguously
+                  identifies the replicated area)
+               b) The consumer's replicaID
+               c) The protocol initiation type - Consumer-Initiated
+                  in this case.
+
+   S -> C: StartFramedProtocolResponse LDAPv3 extended operation. The
+           parameters are:
+
+             1) A protocol-specific payload containing:
+               a) A response code (see section 7)
+
+   S -> C: The supplier server disconnects from the consumer server,
+           and then connects to the consumer, beginning a Supplier-
+           Initiated protocol session (see section 4.1).
+
+
+5. Replication protocol element definitions
+
+5.1 StartFramedProtocolRequest Extended Operation
+
+   The StartFramedProtocolRequest extended operation is sent by a replication
+   initiator to a server to indicate that a replication session should
+   commence. For supplier-initiated replication, the supplier sends this
+   extended operation to the replication consumer to indicate that a
+   replication session should commence. For consumer-initiated
+   replication, the consumer sends this extended operation to the
+   replication supplier to indicate that the supplier should initiate a
+   replication session to the consumer as soon as possible.
+
+   The StartFramedProtocolRequest extended operation is defined
+   in [FRAMING]. When signaling the beginning of a replication
+   session, then requestValue of the StartFramedProtocolRequest
+   is set to the following:
+
+      requestValue ::= SEQUENCE {
+          framedProtocolOID LDAPOID,
+          framedProtocolPayload OPTIONAL OCTET STRING
+      }
+
+   The framedProtocolOID of the StartReplicationRequest must be the OID
+   for the LDUP incremental replication protocol,
+   2.16.840.1.113719.1.142.1.4.3, or the LDUP total update protocol,
+   2.16.840.1.113719.1.142.1.4.4.  See section 7 for information on the
+   semantic behavior of these update protocols.  Implementations MUST
+   support the two update protocols defined in this document.
+
+
+
+Stokes and Good                                                 [Page 5]
+\f
+Internet-Draft               LDUP Workgroup                March 10 2000
+
+
+   The framedProtocolPayload of the StartFramedProtocolRequestValue must
+   be set to the BER-encoding of the following:
+
+      framedProtocolPayload ::= SEQUENCE {
+          replicaRoot            LDAPDN,
+          replicaID              LDAPString,
+          replicationInitiator   ENUMERATED {
+              supplier (0),
+              consumer (1)
+          }
+      }
+
+   The parameters in the framedProtocolPayload of the
+   StartFramedProtocolRequestValue are:
+
+      - replicaRoot: the distinguished name of the entry at the top of
+      the replicated area, and uniquely identifies the unit of
+      replication.
+
+      - replicaID: the replica identifier of the replication initiator.
+      Each replica of a given replicated area is identified by a unique
+      identifier, described in [ARCHITECTURE].
+
+      - replicationInitiator: used to differentiate between a supplier-
+      initiated session and a consumer-initiated session.  If the
+      replicationInitiator contains the enumerated value <supplier>,
+      then the initiator is the supplier, and the receiver of this
+      operation should prepare to receive a set of replication updates
+      (or should reject the operation is replication updates are not
+      permitted for some reasonm, perhaps due to access control
+      restrictions).  If the replicationInitiator contains the
+      enumerated value <consumer>, then the receiver should prepare to
+      establish a supplier-initiated replication session with the
+      consumer as soon as possible, updating the replicated are given by
+      replicaRoot and using the update protocol given by
+      replicationProtocolOID.
+
+5.2 StartFramedProtocolResponse Extended Operation
+
+   The StartFramedProtocolResponse extended operation is sent in
+   response to a StartFramedProtocolRequest extended operation.
+
+   For a supplier-initiated session, the response field of the
+   StartFramedProtocolResponse extended response indicates that the
+   consumer is or is not prepared to accept a set of updates. If the
+   consumer is prepared to accept updates, it sends a response field
+   containing a success code and the consumer's replica update vector.
+   If the consumer is unwilling or unable to accept updates, it sends a
+
+
+
+Stokes and Good                                                 [Page 6]
+\f
+Internet-Draft               LDUP Workgroup                March 10 2000
+
+
+   response field containing an error code.
+
+   For a consumer-initiated session, the response field of the
+   StartFramedProtocolResponse extended respons indicates that the
+   supplier is or is not prepared to send a set of updates to the
+   consumer. If the supplier is prepared to send updates to the
+   consumer, it sends a response field containing a success code. If the
+   supplier is unwilling or unable to send updates to the consumer, it
+   sends a response field containing an error code. In both cases, the
+   supplier disconnects from the consumer. If the supplier sent a
+   success code to the consumer, it opens a connection to the consumer
+   as soon as possible and initiates a supplier-initiated replication
+   session.
+
+   The StartFramedProtocolResponse extended operation is defined in
+   [FRAMING]. When responding to a StartFramedProtocolRequest signaling
+   the beginning of an LDUP replication session, the response field of
+   the StartFramedProtocolResponse is set to the following:
+
+      StartFramedProtocolResponseValue ::= SEQUENCE {
+          responseCode           LDUPResponseCode,
+          replicaUpdateVector    Attribute,
+      }
+
+   LDUPResponseCodes are defined in section 8.
+
+   The replicaUpdateVector contains a replica update vector, as defined
+   in [INFOMOD]. The update vector is encoded as a normal LDAP
+   attribute, defined in [LDAPv3].
+
+
+5.3 ReplicationUpdate Extended Operation
+
+The ReplicationUpdate extended operation carries a set of replication
+primitives that represent the desired final state of a single entry.
+
+The ReplicationUpdate extended operation is defined as follows:
+
+An LDAPv3 Extended Request is defined in [LDAPv3] as follows:
+
+   ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
+       requestName  [0] LDAPOID
+       requestValue [1] OCTET STRING OPTIONAL
+   }
+
+The requestName of the ReplicationUpdate must be the OID
+2.16.840.1.113719.1.142.100.3.
+
+
+
+
+Stokes and Good                                                 [Page 7]
+\f
+Internet-Draft               LDUP Workgroup                March 10 2000
+
+
+The requestValue of the ReplicationUpdate must be set to the BER-
+encoding of the following:
+
+   requestValue ::= SEQUENCE {
+       uniqueID     UniqueIdentifier,
+       updates      SET OF ReplicationPrimitive
+   }
+
+5.3.1 UniqueIdentifier
+
+   The Distinguished Name of an entry may be changed (by renaming the
+   entry), or the entry may not have a distinguished name (if it was
+   deleted).  The Unique Identifier provides an immutable name,
+   independent of the current name or deletion status, for an entry. All
+   replicated operations address entries by their Unique Identifiers.
+
+      UniqueIdentifier ::= LDAPString
+
+
+5.3.2 ReplicationPrimitive
+
+   A ReplicationPrimitive carries a single assertion about the the final
+   state of an entry, attribute, or attribute value. There are seven
+   types of primitives.
+
+      ReplicationPrimitive ::= CHOICE {
+          addEntryPrimitive                AddEntryPrimitive,
+          moveEntryPrimitive               MoveEntryPrimitive,
+          renameEntryPrimitive             RenameEntryPrimitive,
+          removeEntryPrimitive             RemoveEntryPrimitive,
+          addAttributeValuePrimitive       AddAttributeValuePrimitive,
+          removeAttributeValuePrimitive    RemoveAttributeValuePrimitive,
+          removeAttributePrimitive         RemoveAttributePrimitive
+      }
+
+   Each primitive applies to the entry referred to by the
+   uniqueIdentifier in the enclosing ReplicationUpdate extended
+   operation.
+
+   Each primitive carries an lLDAPChangeSequenceNumber that is used by
+   the consumer server to correctly resolve update conflicts. [URP]
+   describes the update reconciliation procedures.
+
+5.3.2.1 AddEntryPrimitive
+
+   The AddEntryPrimitive is used to add a new entry.
+
+      AddEntryPrimitive ::= [APPLICATION 0] SEQUENCE {
+
+
+
+Stokes and Good                                                 [Page 8]
+\f
+Internet-Draft               LDUP Workgroup                March 10 2000
+
+
+          csn       lDAPChangeSequenceNumber,
+          superior  UniqueIdentifier,
+          rdn       RelativeLDAPDN
+      }
+
+   Parameters of the AddEntryPrimitive are:
+
+      - csn: The change sequence number of the primitive.
+
+      - superior: The unique identifier of the superior (parent) entry.
+
+      - rdn: The relative distinguished name of the new entry.
+
+5.3.2.2 MoveEntryPrimitive
+
+   The MoveEntryPrimitive is used to move an entry to a new location in
+   the DIT.
+
+      MoveEntryPrimitive ::= [APPLICATION 1] SEQUENCE {
+          csn      lDAPChangeSequenceNumber,
+          superior UniqueIdentifier
+      }
+
+   Parameters of the MoveEntryPrimitive are:
+
+      - csn: The change sequence number of the primitive.
+
+      - superior: The unique identifier of the new superior (parent)
+      entry.
+
+5.3.2.3 RenameEntryPrimitive
+
+   The RenameEntryPrimitive is used to change the RDN of an entry.
+
+      RenameEntryPrimitive ::= [APPLICATION 2] SEQUENCE {
+          csn lDAPChangeSequenceNumber,
+          rdn RelativeLDAPDN
+      }
+
+   Parameters of the RenameEntryPrimitive are:
+
+      - csn: The change sequence number of the primitive.
+
+      - rdn: The new relative distinguished name of the entry.
+
+5.3.2.4 RemoveEntryPrimitive
+
+   The RemoveEntryPrimitive is used to delete an entry from the DIT.
+
+
+
+Stokes and Good                                                 [Page 9]
+\f
+Internet-Draft               LDUP Workgroup                March 10 2000
+
+
+      RemoveEntryPrimitive ::= [APPLICATION 3] SEQUENCE {
+          csn lDAPChangeSequenceNumber
+      }
+
+   Parameters of the RemoveEntryPrimitive are:
+
+      - csn: The change sequence number of the primitive.
+
+5.3.2.5 AddAttributeValuePrimitive
+
+   The AddAttributeValuePrimitive is use to add a new attribute value to
+   an entry.
+
+      AddAttributeValuePrimitive ::= [APPLICATION 4] SEQUENCE {
+          csn     lDAPChangeSequenceNumber,
+          type    AttributeDescription,
+          value   AttributeValue
+      }
+
+   Parameters of the AddAttributeValuePrimitive are:
+
+      - csn: The change sequence number of the primitive.
+
+      - type: The type of the attribute being added.
+
+      - value: The value being added. Multiple values are not permitted.
+
+5.3.2.6 RemoveAttributeValuePrimitive
+
+   The RemoveAttributeValuePrimitive is used to remove a particular
+   attribute value from an entry.
+
+      RemoveAttributeValuePrimitive ::= [APPLICATION 5] SEQUENCE {
+          csn   lDAPChangeSequenceNumber,
+          type  AttributeDescription,
+          value AttributeValue
+      }
+
+   Parameters of the RemoveAttributeValuePrimitive are:
+
+      - csn: The change sequence number of the primitive.
+
+      - type: The type of the attribute being removed.
+
+      - value: The value being removed. Multiple values are not
+      permitted.
+
+5.3.2.7 RemoveAttributePrimitive
+
+
+
+Stokes and Good                                                [Page 10]
+\f
+Internet-Draft               LDUP Workgroup                March 10 2000
+
+
+   The RemoveAttributePrimitive is used to remove an attribute and all
+   its values from an entry.
+
+      RemoveAttributePrimitive ::= [APPLICATION 6] SEQUENCE {
+          csn  lDAPChangeSequenceNumber,
+          type AttributeDescription
+      }
+
+   Parameters of the RemoveAttributePrimitive are:
+
+      - csn: The change sequence number of the primitive.
+
+      - type: The type of the attribute being removed.
+
+
+5.4 EndFramedProtocolRequest Extended Operation
+
+   The EndFramedProtocolRequest extended operation is sent from the
+   replication supplier to the replication consumer to indicate the end
+   of the sequence of replication updates. In the event that the
+   supplier is sending a total update, the requestValue field of the
+   EndFramedProtocolRequest extended operation contains a replica update
+   vector. The consumer server must replace its replica update vector,
+   if present, with the one provided by the supplier. In the event that
+   the supplier is sending an incremental update, the replica update
+   vector is absent.
+
+   The EndFramedProtocolRequest extended operation is defined in
+   [FRAMING]. When used to signal the termination of an LDUP incremental
+   or total update session, the requestValue field of the
+   EndFramedProtocolRequest is set to the following:
+
+      requestValue ::= SEQUENCE {
+          replicaUpdateVector    Attribute OPTIONAL,
+          returnConsumerUpdateVector BOOLEAN
+      }
+
+   If returnConsumerUpdateVector is TRUE, the consumer server must
+   return its current update vector to the supplier in the response
+   field of the EndFramedProtocolResponse extended response (defined in
+   section 5.5).  Typically, the supplier will request the consumer's
+   update vector for read-only replicas, since the read-only replica
+   will never initiate a replication session, and will therefore never
+   have the opportunity to provide its update vector to other servers.
+
+
+5.5 EndFramedProtocolResponse Extended Operation
+
+
+
+
+Stokes and Good                                                [Page 11]
+\f
+Internet-Draft               LDUP Workgroup                March 10 2000
+
+
+   The EndFramedProtocolResponse extended operation is defined in
+   [FRAMING]. It is used to respond to a EndFramedProtocolRequest.  The
+   response field of the EndFramedProtocolResponse extended operation is
+   set to the following:
+
+      response ::= SEQUENCE {
+          replicaUpdateVector    Attribute OPTIONAL
+      }
+
+   The replicaUpdateVector contains the consumer's current replica
+   update vector, and is optional. The consumer server should only send
+   the replicaUpdateVector if requested by the supplier server in the
+   EndReplicationRequest extended operation.
+
+5.6 ReplicationUpdateResponse Extended Operation
+
+The ReplicationUpdateResponse extended operation is sent, unsolicited,
+by a consumer to a supplier when the consumer wishes the supplier to
+stop sending updates.
+
+An LDAPv3 extended response is defined in [LDAPv3] as follows:
+
+   ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
+       COMPONENTS of LDAPResult,
+       responseName  [10] LDAPOID OPTIONAL,
+       response      [11] OCTET STRING OPTIONAL
+   }
+
+The responseName of the ReplicationUpdateResponse must be the OID [OID
+to be assigned].
+
+The response field of the ReplicationUpdateResponse must be set to the
+BER-encoding of the following:
+
+   response ::= SEQUENCE {
+       replicaUpdateVector  Attribute OPTIONAL
+       abortUpdate          BOOLEAN
+   }
+
+The parameters of the ReplicationUpdateResponse are:
+
+- An optional update vector.  If sent, this indicates that the consumer
+has committed all updates whose CSNs are covered by the transmitted
+update vector [see glossary for a definition of "covered by"].  - An
+optional AbortUpdate boolean flag.  If a supplier receives a
+ReplicationUpdateResponse from a consumer with the AbortUpdate flag set
+to true, the supplier server MUST immediately cease sending updates and
+terminate its connection to the consumer.
+
+
+
+Stokes and Good                                                [Page 12]
+\f
+Internet-Draft               LDUP Workgroup                March 10 2000
+
+
+6. Semantics of Full and Incremental Update protocols
+
+[To be written]
+
+7. Summary of response codes
+
+The following list describes the response codes that may be included in
+the StartFramedProtocolResponse, EndFramedProtocolResponse, and
+ReplicationUpdateResponse extended operations.
+
+   LDUPResponseCode  ::= SEQUENCE {
+       resultCode  ENUMERATED {
+                 success                   (0),
+                 operationsError           (1),
+                 protocolError             (2),
+                 insufficientAccessRights (50),
+                 busy                     (51),
+                 excessiveCSNSkew        (200),
+
+                 other              (80) },
+       errorMessage LDAPString }
+
+The meanings of the response codes are as follows:
+
+   success..................... As defined in [LDAPv3].
+   operationsError............. As defined in [LDAPv3].
+   protocolError............... As defined in [LDAPv3].
+   insufficientAccessRights.... Access denied. The identity that the
+                                initiator provided in the bind request does
+                                not have sufficient privileges to perform
+                                the operation.
+   busy........................ The replica is temporarily unable to accept
+                                updates.
+   excessiveCSNSkew............ The consumer server has detected that the
+                                CSNs being generated by the supplier are
+                                too small (perhaps because the supplier's
+                                clock was set back). Updates from the
+                                supplier will not be applied.
+   other....................... Some other error occurred.
+
+8. Implications for log-based and state-based servers
+
+To be written, or possibly incorporated into [ARCHITECTURE].
+
+9. Replication of access control and schema information
+
+To be written, or possibly incorporated into [ARCHITECTURE].
+
+
+
+
+Stokes and Good                                                [Page 13]
+\f
+Internet-Draft               LDUP Workgroup                March 10 2000
+
+
+10. Security Considerations
+
+To be written.
+
+11. Glossary of Terms
+
+   Covered by: We say that a CSN is "covered by" an update vector if and
+   only if the CSN is less than or equal to the component of the update
+   vector corresponding to the replica ID in the CSN. In other words,
+   given a CSN with components <t,S,r,s> and an update vector with CSNs
+   <t0,S0,r0,s0>,<t1,S1,r1,s1>...<tn,Sn,Rn,sn>, then the CSN is covered
+   by the RUV if and only if one of the following holds for some value
+   i:
+      a) r = ri and t < ti
+      b) r = ri and t = ti and S < Si
+      c) r = ri and t = ti and S = Si and s < si
+
+
+12. Acknowledgments
+
+To be written.
+
+13. References
+
+
+[ARCHITECTURE]
+     J. Merrells, E. Reed, U. Srinivasan, "LDAP Replication Architec-
+     ture", Internet-Draft, draft-ietf-ldup-model-02.txt, October 1999.
+
+
+[FRAMING]
+     E. Stokes, G. Good, "Extended Operations for Framing LDAP Bulk
+     Update Operations", Internet-Draft, draft-ietf-ldup-framing-00.txt,
+     March 2000.
+
+
+[INFOMOD]
+     E. Reed, "LDAP Replication Information Model", Internet-Draft,
+     draft-reed-ldup-infomod-00.txt, June 1999.
+
+
+[KEYWORDS]
+     S. Bradner, "Key Words for use in RFCs to Indicate Requirement Lev-
+     els", Harvard University, RFC 2119, March 1997.
+
+
+[LDAPv3]
+     M. Wahl, S. Kille, T. Howes, "Lightweight Directory Access Protocol
+
+
+
+Stokes and Good                                                [Page 14]
+\f
+Internet-Draft               LDUP Workgroup                March 10 2000
+
+
+     (v3)", RFC 2251, December 1997.
+
+
+[REQ]R. Weiser, E. Stokes, "LDAP V3 Replication Requirements",
+     Internet-Draft, draft-ietf-ldup-replica-req-02.txt, October 1999.
+
+
+[URP]S. Legg, A. Payne, "LDUP Update Reconciliation Procedures",
+     Internet-Draft, draft-ietf-ldup-urp-02.txt, October 1999.
+
+14. Author's Addresses
+
+   Ellen Stokes
+   IBM
+   11400 Burnet Rd
+   Austin, TX 78758
+   USA
+   EMail: stokes@austin.ibm.com
+   phone: +1 512 838 3725
+   fax:   +1 512 838 0156
+
+   Gordon Good
+   Netscape Communications Corp.
+   501 E. Middlefield Rd.
+   Mailstop MV068
+   Mountain View, CA 94043
+   USA
+   EMail:  ggood@netscape.com
+   Phone:  +1 650 937-3825
+
+   15. Document Revision History
+   (This section will be removed prior to this document's publication
+   as a proposed standard)
+
+   Differences between draft-ietf-ldup-protocol-00.txt and
+   draft-ietf-ldup-protocol-01.txt:
+
+   1) The document was reworked to use the ldup framed protocol
+   draft [FRAMING].
+
+
+Appendix A - Complete ASN.1 Definition
+
+To be written.
+
+Full Copyright Statement
+
+Copyright (C) The Internet Society (1999).  All Rights Reserved.
+
+
+
+Stokes and Good                                                [Page 15]
+\f
+Internet-Draft               LDUP Workgroup                March 10 2000
+
+
+This document and translations of it may be copied and furnished to oth-
+ers, and derivative works that comment on or otherwise explain it or
+assist in its implementation may be prepared, copied, published and dis-
+tributed, in whole or in part, without restriction of any kind, provided
+that the above copyright notice and this paragraph are included on all
+such copies and derivative works.  However, this document itself may not
+be modified in any way, such as by removing the copyright notice or
+references to the Internet Society or other Internet organizations,
+except as needed for the purpose of developing Internet standards in
+which case the procedures for copyrights defined in the Internet Stan-
+dards process must be followed, or as required to translate it into
+languages other than English.
+
+The limited permissions granted above are perpetual and will not be
+revoked by the Internet Society or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS
+IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK
+FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT
+INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FIT-
+NESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Stokes and Good                                                [Page 16]
diff --git a/doc/drafts/draft-ietf-ldup-replica-req-xx.txt b/doc/drafts/draft-ietf-ldup-replica-req-xx.txt
new file mode 100644 (file)
index 0000000..ac8a526
--- /dev/null
@@ -0,0 +1,1035 @@
+         INTERNET-DRAFT                                     Russel F. Weiser
+         Informational Draft                     Digital Signature Trust Co.
+         Expires 21 April 2000                                  Ellen Stokes
+                                                                         IBM
+                                                             21 October 1999
+
+
+
+
+
+                        LDAP V3 Replication Requirements
+
+                        <draft-ietf-ldup-replica-req-02.txt>
+
+
+
+  Status of this Memo
+
+
+
+      This document is am Internet-Draft and is in full conformance with
+      all provisions of Section 10 of RFC2026.
+
+
+      Internet-Drafts are working documents of the Internet Engineering
+      Task Force (IETF), its areas, and its working groups.  Note that
+      other groups may also distribute working documents as Internet-
+      Drafts.
+
+
+      Internet-Drafts are draft documents valid for a maximum of six
+      months and may be updated, replaced, or obsoleted by other documents
+      at any time.  It is inappropriate to use Internet-Drafts as
+      reference material or to cite them other than as ``work in
+      progress.''
+
+
+      The list of current Internet-Drafts can be accessed at
+      http://www.ietf.org/ietf/lid-abstracts.txt
+
+
+      The list of Internet-Drafts Shadow Directories can be accessed at
+      http://www.ietf.org/shadow.html.
+
+
+
+
+  Abstract
+
+
+      This document discusses the fundamental requirements for replication
+      of data accessible via the LDAPv3 [RFC2251] protocol. It is intended
+      to be a gathering place for general replication requirements needed
+      to provide interoperability between informational directories.
+
+
+      The key words MUST, MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+      SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+      document are to be interpreted as described in [RFC2119].
+
+
+
+
+
+
+
+         Weiser & Stokes       21 April   2000                    [PAGE 1]\f
+
+
+         INTERNET-DRAFT     LDAP Replication Requirements     21 October 1999
+
+
+
+
+
+
+
+                             Table of Contents
+
+
+      1.Introduction.....................................................3
+      2. Terminology.....................................................3
+      3. Objective.......................................................5
+      4. Applicability Statement.........................................5
+      5. Replication Model..............................................10
+      6. Replication Protocol...........................................12
+      7. Schema.........................................................13
+      8. Administration and Management Considerations...................13
+      9. Acknowledgement................................................14
+      10. References....................................................15
+      11. Author's Address..............................................15
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+         Weiser & Stokes       21 April 2000                   [Page 2]\f
+
+
+         INTERNET-DRAFT     LDAP Replication Requirements     21 October 1999
+
+
+
+
+
+
+
+
+
+  1. Introduction
+
+
+      The ability to distribute directory information throughout the
+      network provides a two fold benefit to the network: (1) increasing
+      the reliability of the directory through fault tolerance, and
+      (2) brings the directory content closer to the clients using the
+      data. LDAPÆs acceptance as an access protocol for directory
+      information is driving the need to distribute LDAP directory content
+      among servers within enterprise and Internet.  Currently LDAP does
+      not define a replication mechanism and only generally mentions LDAP
+      shadow servers (see [RFC2251] and [Changelog]) in passing. The
+      requirements for replication are critical to the successful
+      deployment and acceptance of LDAP in the market place.
+
+
+
+  2.  Terminology
+
+
+      For the purposes of this document, the following terminology
+      definitions are used:
+
+
+      Area of replication - A whole or portion of a directory tree(DIT)
+      making up a distinct unit of data to be replicated. This may also be
+      known as "unit of replication".
+
+      Atomic operation - The ability to treat and contain several updates
+      or attribute changes as a single operation for replication purposes
+      to guarantee that the several updates or attribute changes are
+      propagated to a replica as a single unit.
+
+      Authoritative Master Replica - The Primary updateable replica of the
+      replicated information.
+
+
+      Conflict resolution - Deterministic procedures within replication
+      protocols, utilized to resolve change information conflicts that may
+      arise due to conflicting changes affecting a directory entry.
+
+
+      Fractional replication - The capability to replicate a subset of
+      attributes of any given entry.
+
+      Incremental Update - The process of updating a replica, or copy, of
+      a naming context, by updating only those fields or objects which
+      have changed.
+
+
+      Master Slave, or Single Master Replication - Replication model that
+      assumes only one server, the master, allows write access to the
+      replicated data. Note that Master-Slave replication can be
+      considered a proper subset of multi-master replication.
+
+
+
+         Weiser & Stokes       21 April 2000                   [Page 3]\f
+
+
+         INTERNET-DRAFT     LDAP Replication Requirements     21 October 1999
+
+
+
+
+
+
+
+      Multi-Master Replication - A replication model where entries can be
+      written and updated on any of several updateable replica copies
+      without requiring communication with other updateable replicas
+      before the write or update is performed.
+
+
+      Naming Context - Suffix of a Sub-tree. A sub-tree of entries held in
+      a single server [X.500].
+
+
+      One-way Replication  - The process of synchronization in a single
+      direction where the authoritative source information is provided to
+      a replica.
+
+
+      Partial Replication - The capability to replicate some subset of
+      entries in a naming context.
+
+
+      Propagation behavior - The general behavior of the actual
+      synchronization process between a consumer and a provider of
+      replication information.
+
+      Read-only Replica - A read-only copy of a replicated directory. A
+      read-only replica is assumed to be a slave replica of master slave
+      or single master replication definition.
+
+
+      Replica - A single instance of a whole or portion of the Directory
+      tree (DIT) as defined by area of replication.
+
+
+      Replica Ring - A set of servers, which hold in common the same DIT
+      information as, defined by Ã´Area of replicationö. These servers may
+      be managed under a single replication agreement that handles all
+      members of the set of servers as a group.
+
+
+      Replica Cycle - When a change or groups of changes need to be
+      propagated to the other member of a replica ring. The process of
+      contacting a replica member would be considered the beginning of a
+      replication cycle; the termination of communications with a replica
+      is the end of the cycle whether its due to an error or successful
+      exchange of update records.
+
+
+      Replication - The process of copying portions of naming context
+      information and content between multiple LDAP servers, such that
+      certain predefined portions of the information are available from
+      different servers. Replication can occur between either homogeneous
+      implementations across heterogeneous platforms (operating systems)
+      or heterogeneous implementations supporting identical replication
+      across heterogeneous platforms (operating systems).
+
+
+      Sparse Replica - A incomplete copy of a sub-tree which maybe
+      inclusive with updateable, or Read-only. See Partial replication and
+
+
+
+
+         Weiser & Stokes       21 April 2000                   [Page 4]\f
+
+
+         INTERNET-DRAFT     LDAP Replication Requirements     21 October 1999
+
+
+
+
+
+      Fractional replication.
+
+
+      Topology - Refers to the shape of the directed graph describing the
+      relationships between replicas, as in the replicated directory
+      topology.
+
+
+      Two-way Replication  - The process of synchronization where change
+      information may flow bi-directionally between two replica.
+
+      Update Propagation - Protocol-based process by which directory
+      replicas are reconciled.
+
+
+      Updateable Replica - A Non-authoritative read-writeable copy of the
+      replicated information. Such that during conflict resolution a
+      authoritative master takes precedents in resolving conflicts.
+
+
+
+  3.  Objective
+
+
+      The major objective is to provide an interoperable LDAP V3 directory
+      synchronization protocol which is simple, highly efficient and
+      flexible enough to support both multi-master and master-slave
+      replication operations to meet the needs of both the internet and
+      enterprise environments.
+
+
+  4.  Applicability Statement
+
+
+      Generally replication can be characterized by looking at data
+      consistency models across existing technologies. This may provide
+      insight to LDAP v3 replication requirements. The following is a
+      brief examination of the following data models.
+
+
+      Model 1: Tight Consistency -- Includes environments where all
+      replicas must always contain exactly the same directory content. Two
+      phase commit transaction models may be used to preserve transaction
+      consistency.
+
+
+      Model 2: Eventual Consistency or Transient Consistency -- Includes
+      X.500 Directories, Bayou [XEROX], and NDS (Novell Directory
+      Services) names service where definite knowledge of the global
+      replica topology is provided through predetermined replication
+      agreements. Such that every update propagates to every replica that
+      it can reach via a path of stepwise eventual connectivity.
+      Transaction consistency is preserved for transactions directed at
+      the master server in X.500 implementations. NDS additionally
+      provides deterministic consistency over time to all replicas due to
+      its inherent replication policies.
+
+
+
+
+         Weiser & Stokes       21 April 2000                   [Page 5]\f
+
+
+         INTERNET-DRAFT     LDAP Replication Requirements     21 October 1999
+
+
+
+
+
+      Model 3: Limited Effort Eventual Consistency -- Includes Xerox
+      Clearinghouse [XEROX] that provides a statistical probability of
+      convergence with global knowledge of replica topology. Similar to
+      "Eventual Consistency", except where replicas may purge updates
+      therefore dropping propagation changes when some replica time
+      boundary is exceeded, thus leaving some changes replicated to a
+      portion of the replica topology. Transactional consistency is not
+      preserved, though some weaker constraints on consistency are
+      available.
+
+      Model 4: Loosest Consistency -- Includes opportunistic or simple
+      cache where information is provided from the cache until stale.
+
+
+      Model 5: Ad hoc -- A copy of a date store where no follow up checks
+      are made for the accuracy/freshness of the data.
+
+
+      Consistency models 2, and 3 involve the use of prearranged
+      replication agreements or "Predefined Replication Agreements"
+      between cooperating servers. The complexity of Model 1's use of 2-
+      phase commit adds additional overhead that should not considered at
+      this time. Models 4 and 5 involve unregistered replicas which
+      "pull" updates from another directory server without that server's
+      knowledge. These models can be considered to violate a directory's
+      security policies. Therefore models 1, 4, and 5 are declared to be
+      out of scope of this working group.
+
+
+      So through further review of these consistency models two
+      application areas can then be derived with even further
+      characterizations of the data types usages.
+
+      Eventual Consistency or Transient Consistency (Model 2) - This model
+      provides policy configuration through security management
+      parameters; the data is more dynamic and utilizes dynamic address
+      information.
+
+      Limited Effort Eventual Consistency (Model 3) - This model matches a
+      white-pages environment which contains fairly static data and
+      address information. This model mainly replicates message
+      attributes.
+
+      Therefore it is believed an LDAP replication should be flexible
+      enough to cover the above range of capabilities. The generalized use
+      of LDUP replication environment is to provide for the distribution
+      of LDAP directory information in order to improve accessibility and
+      consistency of the information held by the directory.
+
+
+
+      4.1 Replication Scenarios
+
+
+
+
+
+         Weiser & Stokes       21 April 2000                   [Page 6]\f
+
+
+         INTERNET-DRAFT     LDAP Replication Requirements     21 October 1999
+
+
+
+
+
+      The following directory deployment examples are intended to
+      substantiate and validate our replication requirements. It is
+      assumed in all cases that directory implementations from different
+      vendors are involved.
+
+      4.1.1 Extranet Example
+
+
+      A company has a trading partner to whom it wishes to provide
+      directory information.  This information may be as simple as a
+      corporate telephone directory, or as complex as an extranet work
+      flow application.  For performance reasons the company may wish to
+      have a replica of its directory within the Partner Company, rather
+      than simply exposed beyond its firewall.
+
+
+       The requirements, which follow from this scenario, are:
+
+      - One-way replication, single mastered.
+      - Authentication of clients.
+      - Common access control and access control identification.
+      - Secure transmission of updates.
+      - Selective attribute replication (Fractional Replication), so that
+        only partial entries can be replicated.
+
+
+
+        4.1.2 Consolidation Example
+
+
+      Company A acquires company B. In the transition period, whilst the
+      organizations are merged, both directory services must coexist.
+      Company A may wish to attach company B's directory to its own.
+
+      The requirements, which follow from this scenario, are:
+
+      - Multi-Master replication.
+      - Common access control model. Access control model identification.
+      - Secure transmission of updates.
+      - Replication between DITs with potentially differing schema.
+
+
+        4.1.3 Replication Heterogeneous Deployment Example
+
+      An organization may deliberately deploy multiple directory services
+      within their enterprise to employ the differing benefits of each
+      service.  In this case multi-master replication will be required to
+      ensure that the multiple updateable replicas of the DIT are
+      synchronized. Some vendors may provide directory clients, which are
+      tied to their own directory service.
+
+
+      The requirements, which follow from this scenario, are:
+
+
+      - Multi-Master replication
+
+
+
+         Weiser & Stokes       21 April 2000                   [Page 7]\f
+
+
+         INTERNET-DRAFT     LDAP Replication Requirements     21 October 1999
+
+
+
+
+
+      - Common access control model and Access control model
+      identification.
+      - Secure transmission of updates.
+      - Replication between DITs with potentially differing schemas.
+
+      4.1.4 Shared Name Space Example
+
+
+      Two organizations may choose to cooperate on some venture and need a
+      shared name space to manage their operation.  Both organizations
+      will require administrative rights over the shared name space.
+
+      The requirements, which follow from this scenario, are:
+
+      - Multi-Master replication.
+      - Common access control model and Access control model
+      identification.
+      - Secure transmission of updates.
+
+      4.1.5 Supplier Initiated Replication
+
+      A single master environment, which maintains a number of replicas of
+      the DIT by pushing changes, based on a defined schedule.
+
+
+      The requirements, which follow from this scenario, are:
+
+      - Single-master environment.
+      - Supplier-initiated replication.
+      - Secure transmission of updates.
+
+
+      4.1.6 Consumer Initiated Replication
+
+
+      Again a single mastered replication topology, but the replica
+      initiates the replication exchange rather than the master. An
+      example of this is a replica that resides on a laptop computer that
+      may run disconnected for a period of time.
+
+
+      The requirements, which follow from this scenario, are:
+
+      - Single-master environment.
+      - Consumer initiated replication.
+      - Open scheduling (anytime).
+
+      4.1.7 Prioritized attribute replication
+
+
+      The password attribute can provide an example of the requirement for
+      prioritized attribute replication. A user is working in Utah and the
+      administrator resides in California. The user has forgotten his
+      password. So the user calls or emails the administrator to request a
+      new password. The administrator provides the updated password (a
+      change). Policy states that this attribute is critical and must be
+
+
+
+         Weiser & Stokes       21 April 2000                   [Page 8]\f
+
+
+         INTERNET-DRAFT     LDAP Replication Requirements     21 October 1999
+
+
+
+
+
+      available to the user for login immediately (e.g. shortly) after the
+      administrator changed it. Replication needs to occur immediately for
+      critical attributes/objects.
+
+
+      The requirements, which follow from this scenario, are:
+
+      - Incremental replication of changes.
+      - Automatic replication on change of certain attributes.
+      - Replicate based on time/attribute semantics.
+
+      4.1.8 Bandwidth issues
+
+
+      The replication of Server (A) R/W replica (a) in Katmandu is handled
+      via a dial up phone link to Paris where server (B) R/W replica of
+      (a) resides. Server (C) R/W replica of(a) is connected by a T1
+      connection to server (B). Each connection has a different
+      performance characteristic.
+
+
+      The requirements, which follow from this scenario, are:
+            
+      - Minimize repetitive updates when replicating from multiple
+        replication paths.
+      - Incremental replication of changes.
+      - Provide replication cycles to delay and/or retry when connections
+        can not be reached.
+      - Allowances for consumer initiated or supplier initiated
+        replication.
+
+
+      4.1.9 Interoperable Administration and Management
+
+      The administrator with administrative authority of the corporate
+      directory which is replicated by numerous geographically dispersed
+      LDAP servers from different vendors notices that the replication
+      process is not completing correctly as the change log is continuing
+      to grow and/or error message informs him. The administrator uses his
+      $19.95 RepCo LDAP directory replication diagnostics tools to look at
+      Root DSE replica knowledge on server 17 and determines that server
+      42 made by LDAPÆRUS Inc. is not replicating properly due to an
+      Object conflict. Using his Repco Remote repair tools he connects to
+      server 42 and resolves the conflict on the remote server.
+
+
+      The requirements, which follow from this scenario, are:
+
+      - Provides replication audit history.
+      - Provisions for managing conflict resolution.
+      - Provide LDAP access to predetermined agreements, topology and
+        policy attributes.
+      - Provide operations for comparing replicaÆs content for validity.
+      - Provide LDAP access to status and audit information.
+
+
+
+
+         Weiser & Stokes       21 April 2000                   [Page 9]\f
+
+
+         INTERNET-DRAFT     LDAP Replication Requirements     21 October 1999
+
+
+
+
+
+      4.1.10 Enterprise Directory Replication Mesh
+
+
+      A Corporation builds a mesh of directory servers within the
+      enterprise utilizing LDAP servers from various vendors. Five servers
+      are holding the same area of replication. The predetermined
+      replication agreement(s) for the enterprise mesh are under a single
+      management, and the security domain allows a single predetermined
+      replication agreement to manage the 5 servers replication.
+
+
+      The requirements, which follow from this scenario, are:
+
+      - Predefined replication agreements that manage more than a single
+        area of replication that is held on numerous servers.
+      - Common support of replication management knowledge across vendor
+        implementation.
+      - Rescheduling and continuation of a replication cycle when one
+        server in a replica ring is busy and/or unavailable.  
+
+  5. Replication Model
+
+
+      5.1  LDAP Replication MUST be allowed to span different vendors
+           directory services in order to provide interoperability.
+
+      5.2  All replicas MUST eventually be updated with the changed
+           information, if specified by the replication policy.
+
+
+      5.3  Replication schedules MUST be configurable to allow for
+           periodic replication, with the replication period determined by
+           administrator of the replicated system.
+
+
+      5.4  Replication Model MUST enable replication cycle to be initiated
+           on change or based on the number of pending changes.
+
+      5.5  The replication model MUST allow for administrative
+           initiation of replication cycle for any replica that may have
+           just come back online or was unavailable during previous 
+           replication cycles.
+
+      5.6  The replication model MUST support both master-slave and
+           authoritative multi-updateable replica relationships.
+
+
+      5.7  All replicated information between the master database and its
+          replica databases MUST be identical including all non-user
+           modify operational attributes such as time stamps. Note this
+           does not imply that the entire database is identical from
+           replica to replica, but that the subset of data, chosen to
+           replicate is identical from replica to replica. Some
+           operational attributes may be dynamically evaluated; these
+           attributes will not necessarily appear to be identical.
+
+
+
+
+
+
+         Weiser & Stokes       21 April 2000                   [Page 10]\f
+
+
+         INTERNET-DRAFT     LDAP Replication Requirements     21 October 1999
+
+
+
+
+
+      5.8  In distributed multi-vendor environment, LDAP replication MUST
+           NOT require all copies of the replicated information be
+           complete copies of the replicated object.
+
+
+      5.9  LDAP replication MUST encompass common schema objects and
+           attributes, access control, and name space information.
+
+
+      5.10 Sub-tree Replication MUST be defined to allow for greater
+           flexibility in replication topologies of the DIT as defined by
+           the area of replication called partial replication.
+
+
+      5.11 Replication of critical values MUST be synchronized and have
+           priority over non-critical values. An example of a critical
+           value might be a password or certificate value.
+
+      5.12 Replication activities MUST occur within the context of a
+           predefined replication agreement that addresses proper
+           knowledge of access requirements and credentials between the
+           synchronizing directories. Currently X.525 DISP [X.525]
+           discusses this as a shadowing agreement including such
+           information as unit of replication, update mode, and access
+           point defining many of the policies between the master and a
+           replica.
+
+
+      5.13 The acceptance and usage of the Internet requires that LDAP
+           replication be available across disparate vendor directory
+           services.
+
+
+      5.14 LDAP replication MUST provide scalability to both enterprise
+           and Internet environments, e.g. an LDAP server may provide
+           replication services to replicas within an enterprise as well
+           as across the Internet.
+
+
+      5.15 The replication model MUST define deterministic policy such
+           that replication cycle startup time conflicts between two or
+           more competing master replicas may be resolved
+           programmatically. An example might be automatic submission and
+           rescheduling by one of the masters.  In such a case, these
+           replication "conflicts" MUST be resolved by the replication
+           policy.
+
+
+      5.16 Any replication capable LDAP server MUST allow replication
+           where the 2 replicating servers agree they can replicate. This
+           may be accomplished through administrative agreements assuming
+           compatible access control model and common schema are provided.
+
+
+      5.17 The replication model MUST be able to handle convergence and
+           resurrection of attributes and objects. This is a consequence
+           of delete and move with respect to the replication process.
+
+
+
+
+         Weiser & Stokes       21 April 2000                   [Page 11]\f
+
+
+         INTERNET-DRAFT     LDAP Replication Requirements     21 October 1999
+
+
+
+
+
+      5.18 It is not realistic to assume that all vendors have cooperating
+           schemas, but that replication may be allowed between diverse
+           schema. The Model MAY allow for replication between divergent
+           schema of objects.
+
+
+  6. Replication Protocol
+
+
+      6.1  The act of replication SHOULD have minimal impact on both the
+           system and network performance.
+
+      6.2  The replica synchronization SHOULD be handled in such a manner
+           as to not saturate network with repetitive entry replication
+           from multiple synchronization providers points.
+
+
+      6.3  Replication MUST only be allowed after the authentication and
+           verification of authorization of both the replica and the
+           source directory.
+
+
+      6.4  The transport for LDAP synchronization MUST allow for the
+           integrity and confidentiality of each replicated server.
+
+
+      6.5  Replicated data MUST be transferable in a secure manner.
+
+
+      6.6  Replication protocol MUST provide for recovery and rescheduling
+           of a replication cycle due to a replication initiation
+           conflicts (e.g. consumer busy replicating with other servers)
+           and or loss of connection(e.g. supplier cannot reach a
+           replica). The replication protocol MUST include restarting at
+           the last acknowledged update prior to interruption rather than
+           re-sending updates it had already sent to a consuming replica.
+
+
+      6.7  LDAP replication MUST allow for full update to facilitate
+           replica initialization and reset loading utilizing a
+           standardized format such as LDIF [LDIF] format.
+
+      6.8  The replication standard SHOULD NOT limit the size of a
+           replica. The area of replication is defined to be a whole or
+           portion of a DIT, also allowing a portion of a naming context
+           to be replicated. Incremental replication SHOULD be allowed.
+
+      6.9 The replication agreements MUST accommodate multiple servers
+           receiving the same replica under a single predefined agreement.
+
+
+      6.10 The replication protocol MUST allow either a master or replica
+           to initiate the replication process.
+
+
+      6.11 Additionally the initiator MUST be allowed to determine
+           whether it will become a consumer or supplier during the
+           synchronization startup process. This would allow a replica to
+
+
+
+         Weiser & Stokes       21 April 2000                   [Page 12]\f
+
+
+         INTERNET-DRAFT     LDAP Replication Requirements     21 October 1999
+
+
+
+
+
+           be periodically connected and synchronized from remote sites at
+           the local administrator's discretion.
+
+
+      6.12 Multiple LDAP changes to a single server: If transactional
+           consistency is propagated during replication, then multiple LDAP
+           changes submitted to a single server SHOULD BE treated as a 
+           single 'atomic unit of work'.
+
+
+      6.13 An LDAP Replication Standard SHOULD NOT limit the transaction
+           rate of a replication session.
+
+
+      6.14 Entry change information MUST be purged or discarded in a
+           timely manner when change information becomes outdated due to
+           propagated to all replica members.
+
+
+
+
+      7. Schema
+
+
+      7.1  Replica knowledge MUST be provided as DSE attributes.
+
+      7.2  The Replication Protocol documents MUST define standard schema
+           for representing replication agreements, and MUST define the
+           semantics associated with modifying the attributes of
+           replication agreements. The documents MUST also define a
+           standard method for determining the location of these
+           agreements accessible utilizing LDAP.
+
+
+      7.3  The Replication Protocol documents MUST define standard schema
+           for publishing state information about a given replica, and
+           MUST define a standard method for determining the location of
+           this information.
+
+
+      7.4  A location independent management point MUST be defined to
+           provide authorized administrators with well known access to the
+           replication policies, regardless of network location.
+
+
+      7.5  Replication agreements of all servers containing replicated
+           information MUST be accessible via LDAP.
+
+
+      7.6  All objects MUST be uniquely identifiable throughout the object
+           lifetime .
+
+
+
+
+  8. Administration and Management Considerations
+
+
+
+      8.1  Replication policies MUST allow replication of changed
+           information to be administratively postponed to a more
+
+
+
+         Weiser & Stokes       21 April 2000                   [Page 13]\f
+
+
+         INTERNET-DRAFT     LDAP Replication Requirements     21 October 1999
+
+
+
+
+
+           convenient period.
+
+
+      8.2  Allowance for non-scheduled replication of a replica MUST be
+           provided upon request such that the replica server has been
+           down or unconnected for a period of time.
+
+
+      8.3  Each copy of a replica MUST maintain audit history information
+           of which servers it has replicated with and which servers have
+           replicated with it.
+
+      8.4  A replica MUST store conflicted versions of the replicated
+           object to allow optional human review and intervention.
+
+
+      8.5  Access to replication predetermined agreements, topologies, and
+           policies attributes MUST be provided through LDAP access.
+
+
+      8.6  The capability to check the differences between two replicas
+           for the same information SHOULD be provided for. This should
+           entail a client invoking an operation at some server, which
+           causes that server to extract the contents from some other
+           server it has a replication agreement with and report the
+           differences back to the client as the result.
+
+
+      8.7  Authenticated access SHOULD be provided so that Administrative
+           LDAP clients may query a server for the current state and
+           replication history for each replica that the server maintains
+           replication agreements with.
+
+
+      8.8  The ability to view replication conflicts, and override the
+           resolution derived by the replication policy MUST be provided.
+
+
+      8.9  The deletion of sensitive data MUST be handled in an orderly
+           manner so that at no time will that data be available without
+           proper access control. That is, access control information
+           (ACI) associated with sensitive data must be deleted after or
+           simultaneously with the delete of the sensitive data. Likewise,
+           when adding sensitive data, ACI MUST be added first or
+           simultaneously with the addition of that data.
+
+
+
+
+  9. Acknowledgement
+
+
+      This document is based on input from IETF members interested in LDUP
+      Replication.
+
+
+
+
+
+
+
+
+         Weiser & Stokes       21 April 2000                   [Page 14]\f
+
+
+         INTERNET-DRAFT     LDAP Replication Requirements     21 October 1999
+
+
+
+
+
+  10. References
+
+
+
+      [RFC2251]  M. Wahl, T. Howes, S. Kille "Lightweight Directory Access
+      Protocal", RFC 2251.
+
+
+      [RFC2119]  S.Bradner, " Key words for use in RFCs to indicate
+      Requirement Levels", RFC 2119.
+
+
+      [LDIF]  Gordon Good, "The LDAP Data Interchange Format (LDIF)",
+      Internet draft,  draft-ietf-asid-ldif-00.txt, November 1996.
+
+
+      [Changelog]  Gordon Good, "Definitions of an Object Class to Hold
+      LDAP Change records", Internet Draft, draft-ietf-asid-changelog-
+      00.txt,  November  1996.
+
+
+      [X.501] ITU-T Recommendation X.501 (1993), | ISO/IEC 9594-2: 1993,
+      Information Technology - Open Systems Interconnection - The
+      Directory: Models
+
+      [XEROX] Hauser, C. "Managing update conflicts in Bayou, a weakly
+      connected replicated storage system". Palo Alto, CA: Xerox PARC,
+      Computer Science Laboratory; 1995 August; CSL-95-4. [CSL-95-04]
+
+
+
+   11. Author's Address
+
+
+      Russel F. Weiser
+      Digital Signature Trust Co.
+      One South Main Street
+      Salt Lake City, Utah 84111
+      USA
+
+
+      E-mail: rweiser@digsigtrust.com
+      Telephone: +1-801-983-4415
+      Fax +1-801-983-4408
+
+
+
+      Ellen J. Stokes
+      IBM
+      11400 Burnet Rd.
+      Austin, Texas 78758
+      USA
+
+      E-mail: stokes@austin.ibm.com
+      Telephone: +1-512-838-3725
+      Fax: +1-512-838-0156
+
+
+
+
+
+         Weiser & Stokes       21 April 2000                   [Page 15]\f
index c02b3e7e0d93cb9c1743bd0e3bddd7239eb736ba..f715b9464c3e61dd4ee3db8226886bf4ecd445af 100644 (file)
@@ -1,8 +1,8 @@
 INTERNET-DRAFT
-draft-ietf-ldup-subentry-00.txt
+draft-ietf-ldup-subentry-01.txt
                                                                Ed Reed
                                                           Novell, Inc.
-                                                       August 15, 1999
+                                                       August 29, 1999
 
                          LDAP Subentry Schema
 
@@ -27,14 +27,15 @@ http://www.ietf.org/ietf/1id-abstracts.txt.
 The list of Internet-Draft Shadow Directories can be accessed at
 http://www.ietf.org/shadow.html.
 
-This Internet-Draft expires on January 9, 1999.
+This Internet-Draft expires on February 29, 1999.
 
 
 2. Abstract
 
-This document describes an object class called lDAPsubEntry which MAY
+This document describes an object class called ldapSubEntry which MAY
 be used to indicate operations and management related entries in the
-directory, called LDAP Subentries.
+directory, called LDAP Subentries.  This version of this document is
+updated with an assigned OID for the ldapSubEntry object class.
 
 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and  "OPTIONAL" in this
@@ -47,35 +48,34 @@ ones.
 
 
 
-
 Reed                                                         [Page 1]
-                       Expires January 15, 2000\f
+                      Expires February 29, 2000\f
 
 
-INTERNET-DRAFT                                         15 August 1999
+INTERNET-DRAFT                                         29 August 1999
                          LDAP Subentry Schema
 
 3. Definition
 
 
-3.1 LDAPsubEntry Class
+3.1 ldapSubEntry Class
 
-( 1.3.6.1.4.1.1466.115.121.1.?? NAME 'LDAPsubEntry'
-   DESC 'LDAP Subentry class, named by cn'
+( 2.16.840.1.113719.2.142.6.1.1 NAME 'ldapSubEntry'
+   DESC 'LDAP Subentry class, version 1'
      SUP top STRUCTURAL
      MUST ( cn ) )
 
-The class lDAPsubEntry is intended to be used as a super class when
+The class ldapSubEntry is intended to be used as a super class when
 defining other structural classes to be used as LDAP Subentries.  The
-presence of lDAPsubEntry in the list of super-classes of an entry in
+presence of ldapSubEntry in the list of super-classes of an entry in
 the directory makes that entry an LDAP Subentry.  Object classes
-derived from lDAPsubEntry are themselves considered lDAPsubEntry
+derived from ldapSubEntry are themselves considered ldapSubEntry
 classes, for the purpose of this discussion.
 
 LDAP Subentries MAY be named by their commonName attribute [LDAPv3].
 Other naming attributes are also permitted.
 
-LDAP Subentries MAY be containers, unlike their [X.500] counterparts.
+LDAP Subentries MAY be containers, unlike their [X.501] counterparts.
 
 LDAP Subentries MAY be contained by, and will usually be located in
 the directory information tree immediately subordinate to,
@@ -90,27 +90,39 @@ same way that "operational attributes" are not regularly provided in
 search results and read operations when only user attributes are
 requested).
 
-NOTE:  No special treatment of LDAP Subentries by applications is
-required, but it might be worth considering creating an LDAPv3 control
-to indicate when LDAP Subentries are desired to be returned (subject
-to access controls and search filters, of course) for LDAP search
-operations.
+LDAP servers SHOULD implement the following special handling of
+ldapSubEntry entries:
 
+a) search operations which include a matching criteria
+"objectclass=ldapSubEntry" MUST include entries derived from the
+ldapSubEntry class in the scope of their operations;
 
+b) search operations which do not include a matching criteria
+"objectclass=ldapSubEntry" MUST IGNORE entries derived from the
+ldapSubEntry class, and exclude them from the scope of their
+operations.
 
-4. Security Considerations
 
-LDAP Subentries will frequently be used to hold data which reflects
-either the actual or intended behavior of the directory service.  As
-such, permission to read such entries MAY need to be restricted to
 
 Reed                                                         [Page 2]
-                       Expires January 15, 2000\f
+                      Expires February 29, 2000\f
 
 
-INTERNET-DRAFT                                         15 August 1999
+INTERNET-DRAFT                                         29 August 1999
                          LDAP Subentry Schema
 
+The combination of SHOULD and MUST in the special handling
+instructions, above, are meant to convey this:  Servers SHOULD support
+this special handling, and if they do they MUST do it as described,
+and not some other way.
+
+
+
+4. Security Considerations
+
+LDAP Subentries will frequently be used to hold data which reflects
+either the actual or intended behavior of the directory service.  As
+such, permission to read such entries MAY need to be restricted to
 authorized users.  More importantly, IF a directory service treats the
 information in an LDAP Subentry as the authoritative source of policy
 to be used to control the behavior of the directory, then permission
@@ -124,10 +136,10 @@ to authorized administrators.
 [LDUPINFO] _ E. Reed, "LDUP Replication Information Model", draft-
 ietf-ldup-infomod-01.txt
 
-[LDAPv3] Kille, S., Wahl, M., and T. Howes, "Lightweight Directory
+[LDAPv3] S. Kille, M. Wahl, and T. Howes, "Lightweight Directory
 Access Protocol (v3)", RFC 2251, December 1997
 
-[X.500] ITU-T Rec. X.501, "The Directory: Models", 1993
+[X.501] ITU-T Rec. X.501, "The Directory: Models", 1993
 
 
 
@@ -148,6 +160,14 @@ Internet standards in which case the procedures for copyrights defined
 in the Internet Standards process must be followed, or as required to
 translate it into languages other than English.
 
+Reed                                                         [Page 3]
+                      Expires February 29, 2000\f
+
+
+INTERNET-DRAFT                                         29 August 1999
+                         LDAP Subentry Schema
+
+
 The limited permissions granted above are perpetual and will not be
 revoked by the Internet Society or its successors or assigns.
 
@@ -159,14 +179,6 @@ WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE."
 
 
-
-Reed                                                         [Page 3]
-                       Expires January 15, 2000\f
-
-
-INTERNET-DRAFT                                         15 August 1999
-                         LDAP Subentry Schema
-
 7. Acknowledgements
 
 The use of subEntry object class to store Replica and Replication
@@ -203,6 +215,14 @@ Director.
      USA
      E-mail: Ed_Reed@Novell.com
 
+
+Reed                                                         [Page 4]
+                      Expires February 29, 2000\f
+
+
+INTERNET-DRAFT                                         29 August 1999
+                         LDAP Subentry Schema
+
      LDUP Mailing List: ietf-ldup@imc.org
 
 
@@ -216,5 +236,41 @@ Director.
 
 
 
-Reed                                                         [Page 4]
-                       Expires January 15, 2000\f
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Reed                                                         [Page 5]
+                      Expires February 29, 2000\f
diff --git a/doc/drafts/draft-ietf-ldup-urp-xx.txt b/doc/drafts/draft-ietf-ldup-urp-xx.txt
new file mode 100644 (file)
index 0000000..91f24cf
--- /dev/null
@@ -0,0 +1,1554 @@
+INTERNET-DRAFT                                                S. Legg
+draft-ietf-ldup-urp-02.txt                                    Telstra
+                                                             A. Payne
+                                               PricewaterhouseCoopers
+                                                     October 22, 1999
+
+
+                 LDUP Update Reconciliation Procedures
+
+    Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+   Status of this Memo
+
+
+   This document is an Internet-Draft and is in full conformance with
+   all provisions of Section 10 of RFC2026.
+
+   Internet-Drafts are working documents of the Internet Engineering
+   Task Force (IETF), its areas, and its working groups.  Note that
+   other groups may also distribute working documents as Internet-
+   Drafts.
+
+   Internet-Drafts are draft documents valid for a maximum of six months
+   and may be updated, replaced, or obsoleted by other documents at any
+   time.  It is inappropriate to use Internet-Drafts as reference
+   material or to cite them other than as "work in progress".
+
+   The list of current Internet-Drafts can be accessed at
+   http://www.ietf.org/ietf/1id-abstracts.txt
+
+   The list of Internet-Draft Shadow Directories can be accessed at
+   http://www.ietf.org/shadow.html.
+
+   This draft is published by the IETF LDUP Working Group.  Distribution
+   of this document is unlimited.  Comments should be sent to the LDUP
+   Replication mailing list <ldup@imc.org> or to the authors.
+
+   This Internet-Draft expires on 22 April 2000.
+
+   1. Abstract
+
+   This document describes the procedures used by directory servers to
+   reconcile updates performed by autonomously operating directory
+   servers in a distributed, replicated directory service.
+
+
+
+
+
+
+
+Legg & Payne             Expires 22 April 2000                  [Page 1]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+   2. Table of Contents
+
+   1. Abstract                                                          1
+   2. Table of Contents                                                 2
+   3. Introduction                                                      2
+   4. Model Extensions                                                  3
+   4.1  Unique Identifier                                               3
+   4.2  Timestamps & Existence                                          3
+   4.3  Replication Primitives                                          4
+   4.4  Lost & Found                                                    5
+   5. Replication Procedures                                            6
+   5.1  Processing LDAP, DAP or DSP Operations on the DIT               6
+   5.1.1  Add Entry                                                     7
+   5.1.2  Remove Entry                                                  7
+   5.1.3  Modify Entry                                                  7
+   5.1.4  Modify DN                                                     9
+   5.2  Generating Replication Primitives                               9
+   5.3  Processing Replication Primitives on the DIT                   11
+   5.3.1  Saving Deletion Records                                      12
+   5.3.2  Glue Entries                                                 13
+   5.3.3  Generating Change Sequence Numbers                           13
+   5.3.4  Comparison of Attribute Values                               14
+   5.3.5  Entry Naming                                                 14
+   5.3.6  Processing Add Attribute Value Primitive                     17
+   5.3.7  Processing Remove Attribute Value Primitive                  17
+   5.3.8  Processing Remove Attribute Primitive                        19
+   5.3.9  Processing Add Entry Primitive                               19
+   5.3.10  Processing Remove Entry Primitive                           20
+   5.3.11  Processing Move Entry Primitive                             21
+   5.3.12  Processing Rename Entry Primitive                           22
+   6. Security Considerations                                          23
+   7. Acknowledgements                                                 23
+   8. References                                                       23
+   9. Intellectual Property Notice                                     23
+   10. Copyright Notice                                                24
+   11. Authors' Address                                                25
+   12. Appendix A - Changes From Previous Drafts                       25
+   12.1 Changes in Draft 01                                            25
+   12.2 Changes in Draft 02                                            26
+   13. Appendix B - Open Issues                                        26
+
+
+   3. Introduction
+
+   Each DAP, LDAP or DSP operation successfully performed by a DSA is
+   subsequently reported to other DSAs with which it has a replication
+   agreement as a set of one or more simple timestamped replication
+   primitives.  These primitives reflect the intended final state of an
+
+
+
+Legg & Payne             Expires 22 April 2000                  [Page 2]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+   update operation rather than the specific changes required to achieve
+   that state.
+
+   A DSA will receive replication primitives from its various agreement
+   partners according to the agreement schedules. Those primitives must
+   be reconciled with the current DSA contents.  In broad outline,
+   received replication primitives are compared to the timestamp
+   information associated with the directory data item being operated
+   on. If the primitive has a more recent timestamp a change in the
+   directory contents is made (which may involve only the revision of
+   the timestamp). If the DSA has other replication agreements then the
+   change will be reflected in primitives sent during replication
+   sessions for those other agreements.  If the primitive has an older
+   timestamp it is no longer relevant and is simply ignored.
+
+   The update reconciliation procedures are designed to produce a
+   consistent outcome at all participating DSAs regardless of the order
+   in which the primitives are received. The primitives can also be
+   safely replayed in the event that an exchange of replication
+   information with another DSA is interrupted. This greatly simplifies
+   the recovery mechanisms required in the replication protocol.
+
+   4. Model Extensions
+
+   This section describes the extensions to the data model required to
+   effect multiple master replication.
+
+   4.1 Unique Identifier
+
+   A Unique Identifier is associated with each entry in the global DIT.
+   This Unique Identifier must be globally unique for all time in the
+   Directory. This can be achieved by defining a unique DSA prefix for
+   each DSA and then ensuring that the suffix of the Unique Identifier
+   is locally unique.
+
+   Some pre-allocated global Unique Identifier values will be used to
+   indicate the X.500 global root entry, and the Lost & Found entry (see
+   Section 4.4).
+
+   4.2 Timestamps & Existence
+
+   The timestamp for a replication primitive or directory data item is
+   in the form of a Change Sequence Number (CSN). The components of the
+   CSN are, from most significant to least significant, a time in
+   seconds, a change count, a Replica Identifier and a modification
+   number.  Notionally a CSN is associated with an entry's Relative
+   Distinguished Name (the Name CSN), the reference to its superior
+   entry (the Parent CSN) and each of its attribute values (including
+
+
+
+Legg & Payne             Expires 22 April 2000                  [Page 3]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+   the distinguished values), to record the time of the most recent
+   action on that part of the entry.
+
+   The entry itself has a CSN (the Entry CSN) asserting the most recent
+   time at which the entry was added.  An entry is permitted to be
+   removed and then re-added at one or more DSAs.  In this context re-
+   adding an entry means reusing the Unique Identifier of a removed
+   entry and does not refer to the case of reusing the RDN of a removed
+   entry. The reuse of a Unique Identifier can arise by the explicit
+   action of a directory administrator to restore an entry that was
+   mistakenly removed.  The mechanism by which an administrator adds an
+   entry with a reused Unique Identifier is outside the scope of the
+   X.500 and LDAP standards since the Unique Identifier of an entry is
+   not a user modifiable attribute. Note that from the perspective of a
+   consumer DSA of a partial area of replication an entry may appear to
+   be removed and added several times because modifications to the entry
+   change whether the entry satisfies the replication agreement
+   specification for the area of replication.
+
+   Additionally, a deletion record is kept for each of the recently
+   deleted entries, attributes, or attribute values. The deletion record
+   contains a CSN and asserts that the associated directory object no
+   longer existed at the particular time.
+
+   4.3 Replication Primitives
+
+   Each update operation performed on an entry in a part of the DIT
+   subject to one or more replication agreements must be subsequently
+   reported as replication primitives to the replication partner DSAs of
+   those agreements.  The collection of primitives sent by a DSA to a
+   replication partner may reflect both the results of locally processed
+   user update requests and also of replicated updates received from
+   other DSAs.  A single update operation will decompose in one or more
+   primitives.
+
+   Common to all update primitives is an entry identifier argument, uid,
+   containing the Unique Identifier of the target entry of the change,
+   and a CSN argument, csn, to indicate the time of the change.  In the
+   case of adding a new entry, the Unique Identifier for the entry is
+   allocated by the DSA in the course of processing the operation.
+   Additional arguments are present depending on the type of replication
+   primitive.
+
+   The p-add-entry(uid, csn, superior, rdn) primitive is used to add a
+   new entry with minimal contents.  The superior argument contains the
+   Unique Identifier of the immediate superior entry of the added entry.
+   The rdn argument contains the Relative Distinguished Name of the
+   added entry.
+
+
+
+Legg & Payne             Expires 22 April 2000                  [Page 4]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+   The p-move-entry(uid, csn, superior) primitive is used to change the
+   immediate superior of an entry.  The superior argument contains the
+   Unique Identifier of the new superior entry.
+
+   The p-rename-entry(uid, csn, rdn) primitive is used to change the
+   Relative Distinguished Name of an entry.  The rdn argument contains
+   the new RDN for the entry.
+
+   The p-remove-entry(uid, csn) primitive is used to remove an entry.
+
+   The p-add-attribute-value(uid, csn, type, value) primitive is used to
+   add a single attribute value to an entry.  The type argument contains
+   the attribute type of the value and the value argument contains the
+   attribute value.
+
+   The p-remove-attribute-value(uid, csn, type, value) primitive is used
+   to remove a single attribute value from an entry.  The type argument
+   contains the attribute type of the value and the value argument
+   contains the attribute value.
+
+   The p-remove-attribute(uid, csn, type) primitive is used to remove
+   all values of an attribute from an entry.  The type argument contains
+   the attribute type to be removed.
+
+   These primitives reflect the intended final state of an update
+   operation rather than the specific changes required to achieve that
+   state.
+
+   4.4 Lost & Found
+
+   Each connected set of mastering DSAs have a Lost & Found entry
+   nominated. As a result of conflicting updates at two or more master
+   DSAs, an entry may be left with a reference to a non-existent
+   superior entry.  Such an entry is called an orphaned entry. When this
+   situation arises, the DSA creates a glue entry for the missing
+   superior entry. This glue entry is made a subordinate of the Lost &
+   Found entry and the orphaned entry becomes a subordinate of the glue
+   superior entry (see Section 5.3.2).  Entries that exist in the Lost &
+   Found subtree may still be modified by actions of the replication
+   protocol since entries are identified by Unique Identifiers in the
+   protocol, independent of their positioning in the global DIT.
+
+   Entries will also be explicitly moved to become immediate
+   subordinates of the Lost & Found entry to prevent the formation of a
+   loop in the superior-subordinate relationships in the DIT. This
+   situation can only arise through conflicting move entry operations at
+   two or more master DSAs.
+
+
+
+
+Legg & Payne             Expires 22 April 2000                  [Page 5]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+   Entries that exist under the Lost & Found entry may be returned to a
+   suitable position in the DIT by an administrator or user with
+   appropriate access rights.
+
+   5. Replication Procedures
+
+   The procedures defined in this section ensure the consistent and
+   correct application of the results of DAP, LDAP or DSP operations
+   across all multi-master replication DSAs.
+
+   5.1 Processing LDAP, DAP or DSP Operations on the DIT
+
+   A successful DAP, LDAP or DSP operation applied to a part of the DIT
+   subject to a replication agreement will create or replace one or more
+   CSNs on an entry or its contents, and create zero, one or more
+   deletion records referencing the entry or its contents.  The CSNs and
+   deletion records generated from an operation are atomic with that
+   operation. That is, either the operation succeeds, the CSNS are
+   revised and the deletion records are stored, or the operation fails,
+   no CSNs are revised and no deletion records are stored.  In all
+   cases, all current error conditions (i.e. reasons for rejecting an
+   LDAP, DAP or DSP update operation) remain.
+
+   At some later time, possibly immediately following the update or
+   concurrently with it, the CSNs on entry contents and deletion records
+   are used to generate the replication primitives that will report the
+   update to other DSAs via a replication session.
+
+   All the CSNs generated from a single update operation must use the
+   same time, change count and Replica Identifier.  The modification
+   number is permitted to vary but must be assigned such that when the
+   CSNs resulting from the operation, including those in the deletion
+   records, are compared to the CSNs resulting from any other operation
+   they are all strictly greater than or all strictly less than those
+   other CSNs (i.e.  in a global CSN ordering of the primitives
+   resulting from all operations the primitives of each operation must
+   be contiguous in that ordering).  In order for the update to be
+   consistently applied when replicated to other DSAs the CSNs generated
+   during that update must generally be greater than any pre-existing
+   CSNs on the updated entry's contents. It is expected that DSAs will
+   normally use the current time according to their system clocks in
+   generating the CSNs for an operation. However in an environment where
+   DSA clocks are not necessarily synchronized the current time may be
+   older than existing CSNs on entry contents. The constraints the new
+   CSNs must satisfy with respect to pre-existing CSNs on entry data are
+   covered in the sections on each type of update operation. The current
+   LDUP architecture draft [LDUP Model] requires client update
+   operations to be rejected if the current time does not satisfy the
+
+
+
+Legg & Payne             Expires 22 April 2000                  [Page 6]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+   constraints on the generation of the CSNs.  As written, URP allows a
+   DSA to generate CSNs in advance of its current time to satisfy the
+   constraints and proceed with the update.
+
+   The LDUP Update Vector mechanism imposes the additional constraint
+   that the CSN generated for an update operation must also be greater
+   than the highest CSN generated by the DSA that has already been seen
+   by any other DSA. An implementation that generates successively
+   greater CSNs for each operation will satisfy this constraint.
+
+   The following sections describe the additional actions to support
+   replication carried out in processing each particular type of update
+   operation.
+
+   5.1.1 Add Entry
+
+   The LDAP Add operation or DAP addEntry operation is used to add a
+   leaf entry to the DIT.  A successful request will generate a CSN for
+   the entry.  The CSN on the entry's RDN, the CSN on the entry's
+   superior reference, and the CSN on each distinguished and non-
+   distinguished value added to the entry by the add entry operation are
+   set to this same value.  The affected values include any operational
+   attributes automatically generated by the DSA.
+
+   The Unique Identifier generated for an entry created by a user
+   request is required to be globally unique for all time, so there
+   cannot be a pre-existing entry deletion record for the same Unique
+   Identifier.  However it is recognized that, in practice, Directory
+   administrators may need to restore a deleted entry using its original
+   Unique Identifier (the mechanism used to achieve this is undefined
+   and outside the scope of this specification). In this case the CSN
+   for the entry must be generated such that it is greater than or equal
+   to the CSN of any existing entry, attribute or value deletion records
+   and greater than any of the CSNs contained in an existing glue entry,
+   for the same Unique Identifier.
+
+   5.1.2 Remove Entry
+
+   The LDAP Delete operation or DAP removeEntry operation is used to
+   remove a leaf entry from the DIT. If the request succeeds then an
+   entry deletion record is stored containing the Unique Identifier of
+   the removed entry.  The CSN for the entry deletion record must be
+   generated such that it is greater than the entry CSN of the removed
+   entry.
+
+   5.1.3 Modify Entry
+
+   The LDAP Modify operation (ModifyRequest) or DAP modifyEntry
+
+
+
+Legg & Payne             Expires 22 April 2000                  [Page 7]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+   operation is used to perform a series of one or more modifications to
+   an entry.  If the request succeeds then zero, one or more new values
+   with CSNs are added to the entry contents, and zero, one or more
+   value or attribute deletion records are stored.
+
+   The modifications described by the modification argument of the LDAP
+   ModifyRequest have the following additional effects:
+
+      a) The add alternative associates a CSN with each of the added
+      attribute values.
+
+      b) The delete alternative with no listed values generates an
+      attribute deletion record for the removed attribute type.
+
+      c) The delete alternative with listed values generates a value
+      deletion record for each of the removed values.
+
+      d) The replace alternative first generates an attribute deletion
+      record for the removed attribute type.  A CSN is then associated
+      with each of the added values.
+
+   The modifications described by the changes argument of the X.500
+   modifyEntry operation have the following additional effects:
+
+      a) The addAttribute and addValues alternatives associate a CSN
+      with each of the added attribute values. These two alternatives
+      are equivalent from the point of view of URP since there is no CSN
+      associated specifically with the attribute type.
+
+      b) The removeAttribute alternative generates an attribute deletion
+      record for the removed attribute type.
+
+      c) The removeValues alternative generates a value deletion record
+      for each of the removed values.
+
+      d) The alterValues alternative first generates a value deletion
+      record for each of the old values.  Secondly, a CSN is associated
+      with each of the new values.
+
+      e) The resetValues alternative generates a value deletion record
+      for each value actually removed.
+
+   The CSNs generated by a modify operation must be greater than the CSN
+   of any pre-existing attribute value that is removed, greater than or
+   equal to the CSN of any pre-existing attribute deletion record or
+   value deletion record applying to an added attribute value, and
+   greater than or equal to the CSN of the entry.
+
+
+
+
+Legg & Payne             Expires 22 April 2000                  [Page 8]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+   A further constraint applies to the modification number component of
+   the CSNs generated by a single modify operation.  The CSN generated
+   for an added attribute value must be greater than or equal to the CSN
+   on any applicable value deletion record or attribute deletion record
+   already created by this same operation.  This constraint is satisfied
+   if the same modification number is used in all the CSNs generated by
+   a single modify operation, or if the CSNs generated as the sequence
+   of modifications in the operation are applied in order use
+   monotonically increasing modification numbers.  The modification
+   numbers need not be consecutive in this case.
+
+   Whenever a new value is added to the entry contents any value
+   deletion record for the same entry, attribute type and attribute
+   value may be discarded.
+
+   5.1.4 Modify DN
+
+   The LDAP Modify DN operation and DAP modifyDN operation are used to
+   change the Relative Distinguished Name of an entry and/or to move an
+   entry to a new superior in the DIT.  If the entry is moved to a new
+   superior in the DIT then the CSN on the entry's superior reference is
+   replaced.  If the entry's RDN is changed then the CSN on the entry's
+   RDN is replaced.  A value deletion record is stored for each of the
+   formally distinguished attribute values removed from the entry as a
+   consequence of the deleteOldRDN (modifyDN) flag or deleteoldrdn
+   (ModifyDNRequest) flag being set.
+
+   If the CSN on the entry's superior reference is revised then the new
+   value must be greater than the previous value.  If the CSN on the
+   entry's RDN is revised then the new value must be greater than the
+   previous value of the CSN on the RDN.  The CSNs for any value
+   deletion records must be greater than the CSNs on the removed
+   attribute values.
+
+   5.2 Generating Replication Primitives
+
+   Each time a replication session is invoked, the supplier DSA must
+   generate and send replication primitives for updates known to the
+   supplier but not yet known to the consumer DSA. The supplier uses the
+   Update Vector of the consumer to determine what to send.
+   Conceptually, the supplier scans all the glue and non-glue entries
+   and deletion records covered by the replication agreement with the
+   consumer and generates primitives where the CSNs held by the supplier
+   are greater than the CSN for the corresponding identified replica in
+   the consumer's Update Vector.
+
+   A p-add-entry primitive is generated for each entry whose entry CSN
+   is greater than the Update Vector CSN for the same replica.  The
+
+
+
+Legg & Payne             Expires 22 April 2000                  [Page 9]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+   superior argument of the p-add-entry primitive contains the Unique
+   Identifier of the immediate superior entry of the added entry.  The
+   rdn argument of the p-add-entry primitive contains the Relative
+   Distinguished Name of the created entry except that the Unique
+   Identifier, if distinguished, is always omitted from the RDN.  The
+   superior and rdn arguments are provided even if the CSN on the
+   superior reference or the RDN are greater than the CSN on the entry.
+
+   A p-add-attribute-value primitive is generated for each distinguished
+   value that has a CSN greater than the Update Vector CSN for the same
+   replica and greater than the CSN on the RDN of its entry, and for
+   each non-distinguished value that has a CSN greater than the Update
+   Vector CSN for the same replica.  The p-add-attribute-value primitive
+   uses the CSN of the corresponding value.  There are no separate
+   primitives generated for the distinguished values that have the same
+   CSN as the CSN on their entry's RDN.
+
+   If the CSN on an entry's RDN is greater than the Update Vector CSN
+   for the same replica and greater than the CSN on the entry then a p-
+   rename-entry primitive is generated.  The CSN for this primitive is
+   the CSN on the entry's RDN and the rdn argument contains the Relative
+   Distinguished Name of the entry.
+
+   If the CSN on the entry's superior reference is greater than the
+   Update Vector CSN for the same replica and greater than the CSN on
+   the entry then a p-move-entry primitive is generated.  The CSN for
+   this primitive is the CSN on the entry's superior reference and the
+   superior argument of the contains the Unique Identifier of the
+   immediate superior entry.
+
+   A p-remove-attribute-value primitive is generated for each value
+   deletion record having a CSN greater than the Update Vector CSN for
+   the same replica.  The primitive uses exactly the same arguments as
+   the value deletion record.
+
+   A p-remove-attribute primitive is generated for each attribute
+   deletion record having a CSN greater than the Update Vector CSN for
+   the same replica.  The primitive uses exactly the same arguments as
+   the attribute deletion record.
+
+   A p-remove-entry primitive is generated for each entry deletion
+   record having a CSN greater than the Update Vector CSN for the same
+   replica.  The primitive uses exactly the same arguments as the entry
+   deletion record.
+
+   Rather than scanning the DIT, an implementation may choose to
+   generate replication primitives as the user update requests are being
+   processed and put these primitives into a replication log in
+
+
+
+Legg & Payne             Expires 22 April 2000                 [Page 10]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+   preparation for sending during the next replication session.  Any
+   replication primitives generated from an operation in this way MUST
+   be atomic with that operation. That is, either the operation
+   succeeds, and primitives are added to the replication log, or the
+   operation fails, and no primitives are added to the log.  The
+   replication log may be filtered prior to sending to eliminate any
+   primitives that are superseded by later primitives in the log, and
+   any primitives having CSNs less than or equal to the relevant CSNs
+   contained in a consumer DSA's Update Vector.
+
+   In a log based implementation, the p-add-attribute-value primitive
+   supersedes a p-remove-attribute-value primitive for the same entry,
+   attribute type, attribute value and equal or older CSN. It supersedes
+   another p-add-attribute-value primitive for the same entry, attribute
+   type, attribute value and older CSN.
+
+   The p-remove-attribute-value primitive supersedes a p-add-attribute-
+   value primitive for the same entry, attribute type, attribute value
+   and older CSN. It supersedes another p-remove-attribute-value
+   primitive for the same entry, attribute type, attribute value and
+   equal or older CSN.
+
+   The p-remove-attribute primitive supersedes a p-add-attribute-value
+   primitive for the same entry, attribute type and older CSN. It
+   supersedes a p-remove-attribute-value or another p-remove-attribute
+   primitive for the same entry, attribute type and equal or older CSN.
+
+   The p-remove-entry primitive supersedes a p-add-attribute-value, p-
+   add-entry, p-move-entry or p-rename-entry primitive for the same
+   entry and older CSN. It supersedes a p-remove-attribute-value or p-
+   remove-attribute or another p-remove-entry primitive for the same
+   entry and equal or older CSN.
+
+   The p-move-entry primitive supersedes another p-move-entry primitive
+   for the same entry and older CSN.
+
+   5.3 Processing Replication Primitives on the DIT
+
+   Each replication primitive received from another DSA during a
+   replication session is processed against the DIT.
+
+   This section defines some commonly used sub-procedures and the
+   algorithms for processing each of the primitives. Components of
+   primitives, entries, attributes and values are referenced with the .
+   operator. In particular the notation X.csn refers to the CSN of the
+   directory object X. The operators, < and > when applied to CSNs, use
+   the convention of CSNs becoming greater with the progression of time,
+   so older CSNs are less than younger CSNs.  In the case where the CSN
+
+
+
+Legg & Payne             Expires 22 April 2000                 [Page 11]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+   for object X has been discarded through the purging mechanism, X.csn
+   is assumed to have the least possible CSN value. In some of the
+   procedures a CSN will be explicitly purged. An implementation may
+   instead keep the CSN but set it to some value that is old enough for
+   it to be eligible for purging (e.g. the least possible CSN value)
+   without affecting the correctness of the procedures.
+
+   For an entry, E, the notation E.rdn refers to the entry's Relative
+   Distinguished Name, E.dn refers to the entry's Distinguished Name,
+   and E.superior refers to the Unique Identifier of the entry's
+   superior in the DIT.
+
+
+   5.3.1 Saving Deletion Records
+
+   It is necessary for a DSA to remember that some entry, attribute or
+   attribute value has been deleted, for a period after the processing
+   of the update operation or primitive causing the deletion. These
+   records are called deletion records in the sections that follow and
+   are of three kinds: entry deletion records, attribute deletion
+   records and value deletion records.
+
+   Value deletion records result from, and have the same parameters as,
+   the p-remove-attribute-value primitive. The StoreValueDeletion
+   procedure creates a value deletion record from the actual arguments
+   and stores it for later access by the various primitive processing
+   procedures. When an attribute value is added to an entry, a value
+   deletion record for the same entry, attribute type and value, and
+   with an older CSN, may be discarded.
+
+   Attribute deletion records result from, and have the same parameters
+   as, the p-remove-attribute primitive. The StoreAttributeDeletion
+   procedure creates an attribute deletion record from the actual
+   arguments and stores it for later access. When an attribute deletion
+   record is stored any value deletion records for the same entry and
+   attribute type, and with equal or older CSNs, may be discarded.
+
+   Entry deletion records result from, and have the same parameters as,
+   the p-remove-entry primitive. The StoreEntryDeletion procedure
+   creates an entry deletion record from the actual arguments and stores
+   it for later access. When an entry deletion record is stored any
+   value deletion records and attribute deletion records for the same
+   entry, and with equal or older CSNs, may be discarded.
+
+   Since the deletion records have the same components as their
+   associated remove primitives an implementation may choose to use the
+   same internal structures for both.
+
+
+
+
+Legg & Payne             Expires 22 April 2000                 [Page 12]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+   5.3.2 Glue Entries
+
+   Entries are permitted to be re-added and this can lead to situations
+   where applicable primitives are received in the period after an entry
+   is removed but before the arrival of the notification of it being
+   re-added.  In these cases a glue entry is created for the Unique
+   Identifier to preserve relevant updates in the event that a p-add-
+   entry primitive with an older CSN is later received for the same
+   entry. A glue entry is upgraded to a normal entry by a subsequent p-
+   add-entry primitive.
+
+   A glue entry with no subordinate entries and containing only CSNs (on
+   itself or its component parts) that are eligible to be purged
+   (according to the Purge Vector in LDUP, or the Oldest Time in DMRP)
+   may be removed. A glue entry is discarded if its contents are
+   completely superseded by another p-remove-entry primitive.
+
+   The CreateGlueEntry function is called when required to create a glue
+   entry as a subordinate of Lost & Found. CreateGlueEntry takes a
+   single parameter which is the Unique Identifier for the glue entry.
+   The Unique Identifier also becomes the RDN for the glue entry. No
+   CSNs are associated with the entry, the entry's superior reference,
+   or the entry's name (or equivalently they are set to the least
+   possible CSN value).
+
+   5.3.3 Generating Change Sequence Numbers
+
+   There are circumstances where conflicts arise in the processing of a
+   replication primitive. It is necessary in these cases for the DSA
+   processing the primitives to make corrective changes and emit
+   additional primitives to ensure that all other DSAs reach the same
+   consistent state. The GenerateNextCSN function is used to obtain a
+   CSN for the corrective change.  An implementation that generates
+   replication primitives as the user update requests are being
+   processed and puts them into a replication log must take the
+   additional step of creating a primitive to convey the corrective
+   change to other DSAs. Implementations that generate primitives by
+   scanning entries will pick up the corrective change automatically.
+
+   As is the case for CSNs generated from DAP, DSP or LDAP operations, a
+   CSN is typically generated from the current clock time of the DSA.
+   The conditions imposed for the correct operation of the LDUP Update
+   Vector must also be satisfied.
+
+   GenerateNextCSN takes a single CSN parameter. In addition to all
+   other conditions the CSN generated by the function must be greater
+   than this parameter. Since the CSN parameter passed to
+   GenerateNextCSN is always an actual CSN from some directory object
+
+
+
+Legg & Payne             Expires 22 April 2000                 [Page 13]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+   stored in the local DSA, an implementation may choose to allocate
+   CSNs from an incrementing internal CSN register that is reset after
+   each replication session to a value greater than the largest CSN seen
+   so far, and thereby be safely able to disregard the parameter to
+   GenerateNextCSN.
+
+   5.3.4 Comparison of Attribute Values
+
+   Values in primitives, in deletion records or in entries are compared
+   using the equality matching rule for the associated attribute type
+   where that type is permitted to be multi-valued. This means that two
+   values that are considered equal may nonetheless have minor
+   differences. For example, two commonName values may be equal, but use
+   different letter case and have different numbers of leading or
+   trailing spaces. Whenever a CSN for some value is refreshed the value
+   is also refreshed using the exact value from the primitive so that
+   all DSAs use exactly the same representation for the value.
+
+   Compared values for a single-valued attribute type are all considered
+   to be equal even though they may be significantly different according
+   to that attribute type's equality matching rule. In effect the
+   equality operator, '=', in the following procedures is
+   unconditionally true when used to compare values of a single-valued
+   attribute type.  Whenever a CSN for the value of a single-valued
+   attribute is refreshed the value is also refreshed using the value
+   from the primitive. One significant consequence is that an entry
+   whose RDN contains a value of a single-valued attribute type is
+   effectively renamed by a p-add-attribute-value primitive with a more
+   recent value for the attribute type.
+
+   A value in an entry that is replaced by the exact representation from
+   a primitive retains its distinguished or non-distinguished status.
+   This includes replaced values of single-valued attribute types.
+
+   5.3.5 Entry Naming
+
+   Independent changes at two or more DSAs can lead to the situation of
+   two distinct entries having the same name. The procedure,
+   CheckUniqueness(E, S, R), takes an entry and determines whether it is
+   uniquely named.  If not, it disambiguates the names of the entries by
+   adding the Unique Identifier of each of the conflicting entries to
+   their own RDN.
+
+   The procedure CheckUniqueness is called in each circumstance where
+   the Relative Distinguished Name of an entry might conflict with
+   another entry, either because the entry has been renamed or because
+   it has been moved to a new superior.  An entry can be renamed
+   directly by a p-rename-entry primitive, or as a side-effect of other
+
+
+
+Legg & Payne             Expires 22 April 2000                 [Page 14]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+   primitives causing changes to distinguished values.  While each move
+   or rename of an entry potentially causes a conflict with some other
+   entry already having the new Distinguished Name, it also potentially
+   removes a previous conflict on the old Distinguished Name.  The
+   enable the CheckUniqueness function to remove the Unique Identifier
+   from an entry's RDN when it is no longer needed the old name for an
+   entry is passed through the second and third parameters. The
+   parameter, S, is the Unique Identifier of the old superior entry of
+   E, and the parameter, R, is the old RDN of E. CheckUniqueness needs
+   to ignore distinguished UniqueIdentifiers when comparing entry RDNs.
+   The function BaseRDN(rdn) returns its argument minus any
+   distinguished UniqueIdentifiers to support these comparisons.
+
+   CheckUniqueness(E, S, R)
+      {
+      make E.uid non-distinguished
+      IF there exists exactly one subordinate entry, C, of S
+            where BaseRDN(C.rdn) = BaseRDN(R)
+         make C.uid non-distinguished
+      IF E.rdn is empty
+         make C.uid distinguished
+      ELSE IF there exists a subordinate entry, C, of E.superior
+            where E <> C AND BaseRDN(C.rdn) = BaseRDN(E.rdn)
+         {
+         make C.uid distinguished
+         make E.uid distinguished
+         }
+      }
+
+   Because updates are performed in isolation at multiple DSAs in a
+   multimaster configuration it is possible to encounter a situation
+   where there is a request to delete a distinguished value in an entry.
+   The recommended practice in these circumstances is to remove the
+   distinguished value and call CheckUniqueness to correct any resulting
+   name conflicts.  An implementation may instead reassert the existence
+   of the distinguished value with a more recent CSN to avoid altering
+   the entry's RDN. This option is only available to updatable replicas.
+   Read-only replicas MUST remove the distinguished value.  The function
+   ProtectDistinguished() returns true for an updatable part of the DIT
+   in an DSA that implements this option, and false otherwise.  DSAs
+   exercising this option must generate p-add-attribute-value primitive
+   so that other DSAs are guaranteed to also reassert the distinguished
+   value.  DSAs that implement the option will correctly interwork with
+   servers that do not.
+
+   The primitives p-add-entry and p-rename-entry contain common elements
+   that are applied to the Relative Distinguished Name of an entry in
+   the same way. This common processing is described in the RenameEntry
+
+
+
+Legg & Payne             Expires 22 April 2000                 [Page 15]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+   procedure. The parameters to this procedure are the entry, E, and the
+   p-add-entry or p-rename-entry primitive specifying the new RDN. The
+   procedure assumes that the entry does not currently contain any
+   distinguished values. It is the responsibility of the calling
+   procedure to first reset any pre-existing distinguished values to
+   non-distinguished.  The procedure then resets the CSNs and sets the
+   distinguished flags for existing values and adds distinguished values
+   if necessary. The CSN for the entry's RDN, as distinct from the CSNs
+   on each of the distinguished values making up the RDN, is also set.
+
+   RenameEntry(E, P)
+      {
+      FOREACH AttributeTypeAndValue, N, in P.rdn
+         IF there exists an attribute value, V, in E of type N.type
+            where V = N.value
+            {
+            IF P.csn > V.csn
+               {
+               replace V with N.value if they are not identical
+               V.csn := P.csn
+               }
+            make V distinguished
+            }
+         ELSE IF ProtectDistinguished()
+            {
+            V := N.value
+            add V to E as a distinguished value
+            V.csn := P.csn
+            FOREACH attribute deletion record (uid, type, csn)
+                  where (uid = P.uid AND type = N.type)
+               IF csn > V.csn
+                  V.csn := csn
+            FOREACH value deletion record (uid, type, value, csn)
+                  where (uid = P.uid AND type = N.type AND value = N.value)
+               IF csn > V.csn
+                  V.csn := csn
+            V.csn := GenerateNextCSN(V.csn)
+            }
+         ELSE IF no attribute deletion record (uid, type, csn) exists
+               where (uid = P.uid AND type = N.type AND csn > P.csn)
+            AND no value deletion record (uid, type, value, csn) exists
+               where (uid = P.uid AND type = N.type AND
+                  value = N.value AND csn > P.csn)
+            {
+            V := N.value
+            add V to E as a distinguished value
+            V.csn := P.csn
+            }
+
+
+
+Legg & Payne             Expires 22 April 2000                 [Page 16]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+      E.rdn.csn := P.csn
+      }
+
+
+   5.3.6 Processing Add Attribute Value Primitive
+
+   This section describes the algorithm for processing the p-add-
+   attribute-value (P.uid, P.type, P.value, P.csn) primitive, which is
+   responsible for adding a single attribute value.
+
+      IF no value deletion record (uid, type, value, csn) exists where
+            (uid = P.uid AND type = P.type
+               AND value = P.value AND csn > P.csn)
+         AND no attribute deletion record (uid, type, csn) exists where
+            (uid = P.uid and type = P.type AND csn > P.csn)
+         AND no entry deletion record (uid, csn) exists where
+            (uid = P.uid AND csn > P.csn)
+         {
+         IF entry, E, with uid = P.uid does not exist
+            E := CreateGlueEntry(P.uid)
+         IF P.csn >= E.csn
+            IF attribute value V, of type P.type
+               where V = P.value exists in E
+               {
+               IF P.csn > V.csn
+                  {
+                  V.csn := P.csn
+                  R := E.rdn
+                  replace V with P.value if they are not identical
+                  IF V is distinguished
+                     AND P.type is a single-valued attribute type
+                     CheckUniqueness(E, E.superior, R)
+                  }
+               }
+            ELSE
+               {
+               V := P.value
+               Add V to E as a non-distinguished attribute value
+               V.csn := P.csn
+               }
+         }
+
+
+   5.3.7 Processing Remove Attribute Value Primitive
+
+   This section describes the algorithm for processing the p-remove-
+   attribute-value (P.uid, P. type, P.value, P.csn) primitive, which is
+   responsible for removing a single attribute value. A value that is
+
+
+
+Legg & Payne             Expires 22 April 2000                 [Page 17]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+   distinguished is tagged as distinguished-not-present rather than
+   being immediately removed. Such a value will be physically removed
+   when it becomes non-distinguished.
+
+      IF no value deletion record (uid, type, value, csn) exists
+            where (uid = P.uid AND type = P.type AND
+               value = P.value AND csn >= P.csn)
+         AND
+            no attribute deletion record (uid, type, csn) exists
+               where (uid = P.uid AND type = P.type AND csn >= P.csn)
+         AND
+            no entry deletion record (uid, csn) exists
+               where (uid = P.uid AND csn >= P.csn)
+         IF entry, E, with uid = P.uid exists
+            {
+            IF P.csn > E.csn
+               IF attribute value, V, of P.type
+                  where V = P.value, exists in E
+                  {
+                  IF P.csn > V.csn
+                     IF V is distinguished
+                        IF ProtectDistinguished()
+                           V.csn := GenerateNextCSN(P.csn)
+                        ELSE
+                           {
+                           R := E.rdn
+                           remove value V
+                           CheckUniqueness(E, E.superior, R)
+                           StoreValueDeletion (P.uid, P.type, P.value, P.csn)
+                           }
+                     ELSE
+                        {
+                        remove value V
+                        StoreValueDeletion (P.uid, P.type, P.value, P.csn)
+                        }
+                  }
+               ELSE
+                  StoreValueDeletion (P.uid, P.type, P.value, P.csn)
+            }
+         ELSE
+            StoreValueDeletion (P.uid, P.type, P.value, P.csn)
+
+   The presence of a younger deletion record for the entry, attribute or
+   value provides a convenient test for whether the p-remove-attribute-
+   value primitive needs to be processed at all. If the value exists to
+   be removed then there cannot be a deletion record affecting it that
+   has a younger CSN. If there is a younger deletion record than the
+   primitive then there cannot be an older value to remove.
+
+
+
+Legg & Payne             Expires 22 April 2000                 [Page 18]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+   5.3.8 Processing Remove Attribute Primitive
+
+   This section describes the algorithm for processing the p-remove-
+   attribute (P.uid, P.type, P.csn) primitive, which is responsible for
+   removing all attribute values of P.type. Values that are
+   distinguished are tagged as distinguished-not-present rather than
+   being immediately removed. Such values will be physically removed
+   when they become non-distinguished.
+
+      IF no attribute deletion record (uid, type, csn) exists
+            where (uid = P.uid AND type = P.type AND csn >= P.csn)
+         AND no entry deletion record (uid, csn) exists where
+            (uid = P.uid AND csn >= P.csn)
+         IF entry, E, with uid = P.uid exists
+            {
+            IF P.csn > E.csn
+               {
+               FOREACH attribute value, V, of type P.type in E (if any)
+                  IF P.csn > V.csn
+                     IF V is distinguished
+                        IF ProtectDistinguished()
+                           V.csn := GenerateNextCSN(P.csn)
+                        ELSE
+                           {
+                           R := E.rdn
+                           remove value V
+                           CheckUniqueness(E, E.superior, R)
+                           }
+                     ELSE
+                        remove value V
+               StoreAttributeDeletion (P.uid, P.type, P.csn)
+               }
+            }
+         ELSE
+            StoreAttributeDeletion (P.uid, P.type, P.csn)
+
+
+   5.3.9 Processing Add Entry Primitive
+
+   This section describes the algorithm for processing the p-add-entry
+   (P.uid, P.superior, P.rdn, P.csn) primitive, which is responsible for
+   adding an entry.  The CSN on an entry records the time of the latest
+   p-add-entry primitive for the Unique Identifier.  In normal
+   circumstances there will only ever be one p-add-entry primitive
+   associated with an entry.  The entry CSN may be discarded when it
+   becomes eligible to be purged according to the Purge Vector.
+
+      IF no entry deletion record (uid, csn) exists where
+
+
+
+Legg & Payne             Expires 22 April 2000                 [Page 19]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+           (uid = P.uid AND csn > P.csn)
+         IF entry, E, with uid = P.uid exists
+            {
+            IF P.csn > E.csn
+               {
+               E.csn := P.csn
+               FOREACH attribute value, V, in E
+                  IF V.csn < P.csn
+                     remove value V
+               process P according to
+                  p-rename-entry(P.uid, P.rdn, P.csn)
+               process P according to
+                  p-move-entry(P.uid, P.superior, P.csn)
+               }
+            }
+         ELSE
+            {
+            create entry E
+            E.csn := P.csn
+            E.uid := P.uid
+            E.uid.csn := P.csn
+            IF an entry with uid = P.superior does not exist
+               CreateGlueEntry(P.superior)
+            E.superior = P.superior
+            E.superior.csn := P.csn
+            RenameEntry(E, P)
+            CheckUniqueness(E, E.superior, E.rdn)
+            }
+
+
+   5.3.10 Processing Remove Entry Primitive
+
+   This section describes the algorithm for processing the p-remove-
+   entry (P.uid, P.csn) primitive, which is responsible for removing an
+   entry.  If the target entry has attribute values with CSNs greater
+   than the primitive's CSN, a superior reference with a greater CSN, or
+   if it has any subordinate entries, it becomes a glue entry instead of
+   being removed.  Unless it has a CSN for its superior reference that
+   is greater than the CSN of the p-remove-entry it is also moved to
+   Lost & Found.
+
+      IF no entry deletion record (uid, csn) exists
+            where (uid = P.uid AND csn >= P.csn)
+         IF entry, E, with uid = P.uid exists
+            {
+            IF P.csn > E.csn
+               {
+               IF E.superior.csn >= P.csn
+
+
+
+Legg & Payne             Expires 22 April 2000                 [Page 20]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+                  OR any value, V, with csn >= P.csn exists
+                  OR E has subordinates
+                  {
+                  R := E.rdn
+                  S := E.superior
+                  make E a glue entry
+                  purge E.csn
+                  IF E.superior.csn < P.csn
+                     {
+                     E.superior := LOST_AND_FOUND
+                     purge E.superior.csn
+                     }
+                  IF E.rdn.csn < P.csn
+                     purge E.rdn.csn
+                  FOREACH attribute value, V, in E
+                     IF V.csn < P.csn
+                        remove value V
+                  CheckUniqueness(E, S, R)
+                  }
+               ELSE
+                  remove entry E
+               StoreEntryDeletion (P.uid, P.csn)
+               }
+            }
+         ELSE
+            StoreEntryDeletion (P.uid, P.csn)
+
+
+   5.3.11 Processing Move Entry Primitive
+
+   This section describes the algorithm for processing the p-move-entry
+   (P.uid, P.superior,  P.csn) primitive, which is responsible for
+   moving an entry. If the new superior specified by the primitive does
+   not exist or is a direct or indirect subordinate of the entry being
+   moved then the entry is moved to Lost & Found instead.
+
+      IF no entry deletion record (uid, csn) exists
+            where (uid = P.uid AND csn > P.csn)
+         {
+         IF entry, E, with uid = P.uid does not exist
+            E := CreateGlueEntry(P.uid)
+         IF P.csn > E.superior.csn
+            {
+            R := E.rdn
+            O := E.superior
+            IF entry, S, with uid = P.superior does not exist
+               S := CreateGlueEntry(P.superior)
+            IF S is not in the subtree of E
+
+
+
+Legg & Payne             Expires 22 April 2000                 [Page 21]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+               {
+               E.superior := P.superior
+               E.superior.csn = P.csn
+               }
+            ELSE
+               {
+               E.superior := LOST_AND_FOUND;
+               E.superior.csn := GenerateNextCSN(P.csn)
+               }
+            CheckUniqueness(E, O, R)
+            }
+         }
+
+
+   5.3.12 Processing Rename Entry Primitive
+
+   This section describes the algorithm for processing the p-rename-
+   entry (P.uid, P.rdn, P.csn) primitive, which changes the Relative
+   Distinguished Name of an entry.  A p-rename-entry primitive that is
+   older than current name of an entry is not simply ignored since it
+   may contain attribute values that would have been added to the entry
+   had the primitives arrived in CSN order.  These extra values would
+   now be non-distinguished.
+
+      IF no entry deletion record (uid, csn) exists
+         where (uid = P.uid AND csn >= P.csn)
+         {
+         IF entry, E, with uid = P.uid does not exist
+            E := CreateGlueEntry(P.uid)
+         IF P.csn > E.rdn.csn
+            {
+            R := E.rdn
+            FOREACH distinguished attribute value, V, in entry E
+               make V non-distinguished
+            RenameEntry(E, P)
+            CheckUniqueness(E, E.superior, R)
+            }
+         ELSE
+            FOREACH AttributeTypeAndValue, N, in P.rdn
+               {
+               IF there exists an attribute value, V, in E of type
+                     N.type AND V = N.value
+                  {
+                  IF P.csn > V.csn
+                     {
+                     replace V with N.value if they are not identical
+                     V.csn := P.csn
+                     }
+
+
+
+Legg & Payne             Expires 22 April 2000                 [Page 22]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+                  }
+               ELSE
+                  {
+                  IF no value deletion record (uid, type, value, csn)
+                        exists where (uid = P.uid AND type = N.type AND
+                        value = N.value AND csn > P.csn)
+                     AND
+                        no attribute deletion record (uid, type, csn)
+                        exists where (uid = P.uid AND type = N.type AND
+                        csn > P.csn)
+                     {
+                     V := N.value
+                     Add V to E
+                     V.csn := P.csn
+                     }
+                  }
+               }
+         }
+
+
+   6. Security Considerations
+
+   [To be supplied]
+
+
+   7. Acknowledgements
+
+   The authors would like to thank Suellen Faulks, Tony Robertson and
+   Mark Ennis from Telstra Research Laboratories who contributed to the
+   design and verification of the procedures described in this document.
+
+   The authors would also like to thank the members of the LDUP
+   architecture group for their input into the refinement of the design.
+
+
+   8. References
+
+   [LDUP Model] - E. Reed, "LDUP Replication Architecture", Internet
+   Draft, draft-merrells-ldup-model-01.txt, November 1998.
+
+   [BCP-11] - R. Hovey, S. Bradner, "The Organizations Involved in the
+   IETF Standards Process", BCP 11, RFC 2028, October 1996.
+
+
+   9. Intellectual Property Notice
+
+   The IETF takes no position regarding the validity or scope of any
+   intellectual property or other rights that might be claimed to
+
+
+
+Legg & Payne             Expires 22 April 2000                 [Page 23]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+   pertain to the implementation or use of the technology described in
+   this document or the extent to which any license under such rights
+   might or might not be available; neither does it represent that it
+   has made any effort to identify any such rights.  Information on the
+   IETF's procedures with respect to rights in standards-track and
+   standards-related documentation can be found in BCP-11. [BCP-11]
+   Copies of claims of rights made available for publication and any
+   assurances of licenses to be made available, or the result of an
+   attempt made to obtain a general license or permission for the use of
+   such proprietary rights by implementors or users of this
+   specification can be obtained from the IETF Secretariat.
+
+   The IETF invites any interested party to bring to its attention any
+   copyrights, patents or patent applications, or other proprietary
+   rights which may cover technology that may be required to practice
+   this standard.  Please address the information to the IETF Executive
+   Director.
+
+
+   10. Copyright Notice
+
+      Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+Legg & Payne             Expires 22 April 2000                 [Page 24]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+   11. Authors' Address
+
+   Steven Legg
+   Telstra Research Laboratories
+   770 Blackburn Road
+   Clayton, Victoria 3168
+   AUSTRALIA
+
+   Phone: +61 3 9253 6771
+     Fax: +61 3 9253 6485
+   EMail: s.legg@trl.telstra.com.au
+
+   Alison Payne
+   PricewaterhouseCoopers
+   St Jakobs Strasse 25
+   CH-4002 Basel
+   SWITZERLAND
+
+   Phone: +41-79-458 4177
+   EMail: alison.b.payne@ch.pwcglobal.com
+
+   12. Appendix A - Changes From Previous Drafts
+
+   12.1 Changes in Draft 01
+
+   Some of the terminology has been changed to better align with the
+   terminology used in the LDUP architecture draft.
+
+   Descriptions on the usage of CSNs have been revised to account for
+   the extra modification number component.
+
+   The semantics of re-added entries has been simplified so that only
+   changes after the latest re-add are preserved instead of all those
+   after the earliest re-add. This eliminates the need for Addition CSNs
+   in the entry.  It is anticipated that new replication primitives will
+   be introduced to manage entries that come and go from partial
+   replicas instead of using p-add-entry and p-remove-entry.
+
+   Orphaned entries are no longer moved directly to Lost & Found.
+   Instead a glue entry is created in Lost & Found for the missing
+   superior and the orphaned entry becomes a subordinate of that. This
+   change eliminates the need for explicit propagated primitives for
+   moving orphaned entries to Lost & Found.
+
+   Glue entries have also been used as the mechanism for saving
+   primitives.  There are no longer any references to saved primitives
+   though the functionality is still present.
+
+
+
+
+Legg & Payne             Expires 22 April 2000                 [Page 25]
+
+
+
+
+
+INTERNET-DRAFT   LDUP Update Reconciliation Procedures  October 22, 1999
+
+
+   The procedures for processing received replication primitives have
+   been rearranged to follow a more consistent pattern where the
+   presence of deletion records is tested first.
+
+   12.2 Changes in Draft 02
+
+   Multimaster replication has been dropped as a work item for the next
+   edition of X.500 so references to the proposed X.500 multimaster
+   replication protocol have been removed.
+
+   The treatment of distinguished values has been simplified. Previously
+   an attempt to remove a distinguished value caused the value to be
+   tagged distinguished-not-present. Now the distinguished value is
+   removed, and if necessary, the Unique Identifier is made
+   distinguished to avoid an empty RDN. Optionally, the value to be
+   removed can be reasserted by emitting an explicit p-add-attribute-
+   value primitive.
+
+   The current draft is more implementation neutral. A replication log
+   no longer figures prominently in the specification.  The previous
+   descriptions had the user updates generating replication primitives,
+   which in turn were used to determine the CSNs and deletion records.
+   The new descriptions have user updates generating CSNs and deletion
+   records and the primitives are subsequently generated from them.
+
+   13. Appendix B - Open Issues
+
+   The precise location of the Lost & Found entry has not yet been
+   decided.
+
+   Extensions to the algorithms to properly deal with partial replicas
+   are still to be decided.
+
+   The draft needs some editing to use MAY, MUST, etc, in the proper
+   way.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Legg & Payne             Expires 22 April 2000                 [Page 26]
+
+
diff --git a/doc/drafts/draft-lachman-laser-ldap-mail-routing-xx.txt b/doc/drafts/draft-lachman-laser-ldap-mail-routing-xx.txt
new file mode 100644 (file)
index 0000000..6fc6594
--- /dev/null
@@ -0,0 +1,615 @@
+INTERNET-DRAFT                                                H. Lachman
+Intended Category: Standards Track         Netscape Communications Corp.
+Filename: draft-lachman-laser-ldap-mail-routing-01.txt        G. Shapiro
+                                                          Sendmail, Inc.
+Expires: April 2000                                         October 1999
+
+                 LDAP Schema for Intranet Mail Routing
+
+Status of this Memo
+
+   This document is an Internet-Draft and is in full conformance with
+   all provisions of Section 10 of RFC2026.
+
+   Internet-Drafts are working documents of the Internet Engineering
+   Task Force (IETF), its areas, and its working groups.  Note that
+   other groups may also distribute working documents as Internet-
+   Drafts.
+
+   Internet-Drafts are draft documents valid for a maximum of six months
+   and may be updated, replaced, or obsoleted by other documents at any
+   time.  It is inappropriate to use Internet-Drafts as reference
+   material or to cite them other than as "work in progress."
+
+   The list of current Internet-Drafts can be accessed at
+   http://www.ietf.org/ietf/1id-abstracts.txt
+
+   The list of Internet-Draft Shadow Directories can be accessed at
+   http://www.ietf.org/shadow.html.
+
+   This draft is being discussed on the Laser mailing list at
+   <laser@sunroof.eng.sun.com>.  Subscription requests can be sent to
+   <laser-request@sunroof.eng.sun.com> (send an email message with the
+   word "subscribe" in the body).  More information on the mailing list
+   along with an archive of back messages is available at
+   <http://playground.sun.com/laser/>.
+
+   [[Section X will be removed before the document is submitted to the
+     IESG.]]
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (1999).  All Rights Reserved.
+
+Abstract
+
+   This document defines an LDAP [1] object class called
+   'inetLocalMailRecipient' and associated attributes that provide a way
+   to designate an LDAP entry as one that represents a local (intra-
+   organizational) email recipient, to specify the recipient's email
+   address(es), and to provide routing information pertinent to the
+   recipient.  This is intended to support SMTP [2] message transfer
+   agents in routing RFC 822-based email [3] within a private enterprise
+   only, and is not to be used in the process of routing email across
+   the public Internet.
+
+Lachman, et. al.                                                [Page 1]
+
+INTERNET-DRAFT   LDAP Schema for Intranet Mail Routing      October 1999
+
+1.  Conventions Used in this Document
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY" and "OPTIONAL" in this
+   document are to be interpreted as described in [10].
+
+2.  Background and Motivation
+
+   LDAP-based directory services are currently being used in many
+   organizations as a repository of information about users and other
+   network entities (such as groups of users, network resources, etc.).
+   In cases where LDAP entries are used to represent entities that are
+   email recipients (e.g., a mail user or a mailing list), the LDAP
+   entries provide a convenient place to store per-recipient data, such
+   as a recipient's email address.
+
+   In many organizations, an email recipient may have an email address
+   (e.g., "joe@example.com") that does not specify the host that
+   receives mail for that recipient (e.g., "host42.example.com").  A
+   message transfer agent (MTA) responsible for routing mail within the
+   organization needs some way to determine the appropriate target host
+   for such a recipient.  A common solution is the sendmail "aliases"
+   database which may contain a record that provides the necessary per-
+   recipient routing information (e.g., "joe: joe@host42").  A drawback
+   of this solution is that if the organization hosts more than one DNS
+   domain (e.g., "example.com" and "example.org", with "joe" in each
+   domain being different recipients), a more explicit mapping is
+   desirable.  The schema defined in this document provides a way to
+   represent such mappings in LDAP and X.500 [4] directory services.
+
+   An LDAP entry that represents an email recipient could conceivably
+   contain a variety of attributes related to email, such as disk quota
+   and delivery preferences.  We consider here only attributes that
+   specify address information and routing information; these attributes
+   may be useful to multiple MTAs within the organization since one or
+   more MTAs may be responsible for intra-organizational routing.  The
+   various MTAs in an organization may have been developed by different
+   implementors, so a common schema is desirable for such attributes.
+
+3.  Overview
+
+   The 'inetLocalMailRecipient' object class and associated attributes
+   identify an LDAP entry as representing an SMTP mail recipient (in the
+   sense "recipient" is used in [2]).  A recipient may be a mail user, a
+   mailing list, an auto-responder of some kind (e.g., a mailing list
+   subscription program), a network device such as a printer or fax
+   machine, or other recipient type.  Address attributes and routing
+   attributes are provided to aid SMTP MTAs in routing mail within an
+   organization to the appropriate target MTA for each recipient.
+
+Lachman, et. al.                                                [Page 2]
+
+INTERNET-DRAFT   LDAP Schema for Intranet Mail Routing      October 1999
+
+   Once on the target MTA, a message is handled as per the recipient
+   type and options (which may be specified using other auxiliary object
+   classes and is outside the scope of this document).  For example, the
+   message may be delivered to a user mailbox, or to a program or
+   network device, and/or forwarded to another recipient.  Or, the
+   target MTA may be a gateway to a non-SMTP mail routing and delivery
+   system including non-SMTP MTAs.  Note that, in this discussion,
+   "target MTA" refers to the final SMTP destination of messages for the
+   recipient in question, as we are considering routing of mail only
+   among the SMTP MTAs within an organization.
+
+   The target MTA checks to see if the destination domain of the
+   recipient address is one that it is responsible for LDAP-based
+   routing.  If so, checks for matching e-mail addresses in LDAP by
+   looking up the envelope recipient address in LDAP using the object
+   class described in section 4.1 and the attribute discussed in section
+   4.2.  If it gets back an unambiguous match, it interprets the routing
+   attributes as described in section 4.3.
+
+   Routing of mail between different organizations across the public
+   Internet is outside the scope of this document, as the mechanism for
+   this is already standardized [5,6].  An 'inetLocalMailRecipient'
+   entry represents a mail recipient that is local to the organization
+   in question, not recipients in other organizations.  This means that
+   the domain names that appear within the 'mailLocalAddress' and
+   'mailHost' attribute values in an 'inetLocalMailRecipient' entry must
+   be DNS domain names that are within the administrative authority of
+   the organization in question (i.e., the organization within which
+   MTAs are accessing such entries and using these attributes for mail
+   routing).
+
+   LDAP entries that are not 'inetLocalMailRecipient' entries should be
+   ignored by MTAs for the purpose of routing.  An example is a
+   conference room whose LDAP entry contains contact information (e.g.,
+   email address and telephone number) for the person who books
+   reservations for the room; the conference room is not a mail
+   recipient, and can safely be ignored by MTAs doing route
+   determination based on recipient address.
+
+4.  Object Class and Attribute Definitions
+
+   The 'inetLocalMailRecipient' object class and associated attributes
+   are defined (using syntaxes given in [7]) as follows.
+
+Lachman, et. al.                                                [Page 3]
+
+INTERNET-DRAFT   LDAP Schema for Intranet Mail Routing      October 1999
+
+ 4.1  The inetLocalMailRecipient Object Class
+
+       ( 2.16.840.1.113730.3.2.[[TBD]]
+           NAME 'inetLocalMailRecipient'
+           SUP top
+           AUXILIARY
+           MAY ( mailLocalAddress $
+               mailHost $ mailRoutingAddress
+           )
+       )
+
+   The 'inetLocalMailRecipient' object class signifies that the entry
+   represents an entity within the organization that can receive SMTP
+   mail, such as a mail user or a mailing list.  In any case of an entry
+   containing the 'inetLocalMailRecipient' object class, attributes
+   defined in this document MUST be interpreted as specified in this
+   document.
+
+ 4.2  Address Attribute
+
+       ( 2.16.840.1.113730.3.1.13
+           NAME 'mailLocalAddress'
+           DESC 'RFC 822 email address of this recipient'
+           EQUALITY caseIgnoreIA5Match
+           SYNTAX '1.3.6.1.4.1.1466.115.121.1.26{256}'
+       )
+
+   The 'mailLocalAddress' attribute is used to specify email addresses,
+   for the recipient; for example, "nickname@example.com".  The address
+   conforms to the syntax of an 'addr-spec' as defined in [3].
+
+   The 'mailLocalAddress' attribute MUST contain all addresses that
+   represent each recipient of the target MTA.  Commonly, the value of
+   the 'mail' attribute should also be among the addresses listed in
+   the 'mailLocalAddress' attribute if it is expected to be used for
+   LDAP mail routing.
+
+   When determining the disposition of a given message, MTAs using LDAP
+   (directly or indirectly) to route mail MUST search for an entry
+   with object class 'inetLocalMailRecipient' and a 'mailLocalAddress'
+   attribute matching the message's recipient address.  If exactly one
+   matching entry is found, MTAs MUST regard the message as being
+   addressed to the entity that is represented by the directory entry.
+
+   If multiple entries are found, but all share an identical match for
+   both mailRoutingAddress and mailHost (e.g., their presence or absence
+   is the same as well as their values if present), the MTA MAY treat
+   this as a single match.  Duplicate entries that return different
+   routing attributes or contradict each other are errors, however, and
+   should be handled by the MTA in some locally-appropriate way, such as
+   returning a DSN [11] to the sender.
+
+Lachman, et. al.                                                [Page 4]
+
+INTERNET-DRAFT   LDAP Schema for Intranet Mail Routing      October 1999
+
+   If there is no match found by the above, MTAs SHOULD have the
+   capability of searching for the recipient domain against the
+   'mailLocalAddress' attribute using the "wildcard domain" address
+   "@<full-local-domain>" , e.g., "@example.org".  In other words, if
+   mail arrives for "someone@example.org", and there is no recipient
+   with that address specified as 'mailLocalAddress', then the recipient
+   with the wildcard domain address should receive the mail.
+
+   MTAs MAY do other searches but only after the above are done.
+
+   In short, the address attribute 'mailLocalAddress' may be used by an
+   LDAP entry to answer the question "what is/are this account's email
+   address(es)?"
+
+ 4.3  Routing Attributes
+
+       ( 2.16.840.1.113730.3.1.18
+           NAME 'mailHost'
+           DESC 'fully-qualified hostname of the MTA that is the final
+               SMTP destination of messages to this recipient'
+           EQUALITY caseIgnoreIA5Match
+           SYNTAX '1.3.6.1.4.1.1466.115.121.1.26{256}'
+           SINGLE-VALUE
+       )
+
+   The 'mailHost' attribute indicates which SMTP MTA considers the
+   recipient's mail to be locally handleable.  This information can be
+   used for routing, in that an intermediary MTA may take it to be the
+   destination for messages addressed to this recipient.  Normal mail
+   routing requirements (i.e., use of MX records) apply to the specified
+   hostname unless overridden by local conventions.  In other words, the
+   mail should be sent to the specified host without changing the
+   recipient address.  The hostname is specified as a fully-qualified
+   DNS hostname with no trailing dot (e.g., "host42.example.com").
+
+   If the 'inetLocalMailRecipient' object class is present, the
+   'mailHost' attribute for each entry MAY contain a value.  If it does,
+   that value MUST be the fully qualified name of the server containing
+   the host MTA for this person.  If 'mailHost' is present then it MUST
+   be taken as the host for this user, and all mail to this user MUST be
+   routed to this machine.
+
+       ( 2.16.840.1.113730.3.1.47
+           NAME 'mailRoutingAddress'
+           DESC 'RFC 822 address to use when routing messages to
+               the SMTP MTA of this recipient'
+           EQUALITY caseIgnoreIA5Match
+           SYNTAX '1.3.6.1.4.1.1466.115.121.1.26{256}'
+           SINGLE-VALUE
+       )
+
+Lachman, et. al.                                                [Page 5]
+
+INTERNET-DRAFT   LDAP Schema for Intranet Mail Routing      October 1999
+
+   The 'mailRoutingAddress' attribute indicates a routing address for
+   the recipient.  The address MUST conform to the syntax of an
+   'addr-spec' in [3].  An intermediary MTA MUST use this information to
+   route the message to the MTA that handles mail for this recipient,
+   e.g., the envelope address MUST be rewritten to this value.  This is
+   useful in cases where, for a given recipient, the target MTA prefers
+   a particular address to appear as the recipient address in the SMTP
+   envelope.  'mailRoutingAddress' MAY be used as an alternative to
+   'mailHost', and is intended to have the same effect as 'mailHost'
+   except that 'mailRoutingAddress' is an address for rewriting the
+   envelope.  With 'mailHost', the envelope address either is not
+   rewritten, or is rewritten according to implementation-specific rules
+   and/or configuration.
+
+   If both 'mailHost' and 'mailRoutingAddress' are present, MTAs MAY
+   interpret it to mean that messages are to be routed to the host
+   indicated by 'mailHost', while rewriting the envelope as per
+   'mailRoutingAddress'.  In theory, there could be peculiar cases where
+   this is necessary, but this is not normally expected.
+
+   Absence of both 'mailHost' and 'mailRoutingAddress' MAY be considered an
+   error, unless "location-independent" recipient types are supported by
+   the various MTAs within the organization.  This would allow any MTA in
+   the organization to handle the processing of mail for, say, a mailing
+   list.  This presumes that the various MTAs all recognize the recipient
+   type in question, suggesting a need to standardize recipient types that
+   could be "location-independent".
+
+   In short, routing attributes may be used by an LDAP entry to answer
+   the question "how should MTAs route mail to this account?"
+   (analogous to using the sendmail "aliases" database for per-user
+   routing within an organization).  This is in contrast with
+   "forwarding"; forwarding and delivery options may be specified in an
+   LDAP entry to answer the question "what happens to mail once it
+   arrives at this account?", which may include forwarding to some other
+   account within or outside the organization (analogous to using the
+   sendmail ".forward" file).  Such options are outside the scope of the
+   'inetLocalMailRecipient' schema definition.
+
+   The following possibilities exist as a result of an LDAP lookup on an
+   address:
+
+        mailHost is     mailRoutingAddress is   Results in
+        -----------     ---------------------   ----------
+        set to a        set                     mail routed to
+        "local" host                            mailRoutingAddress
+
+        set to a        not set                 delivered to
+        "local" host                            original address
+
+Lachman, et. al.                                                [Page 6]
+
+INTERNET-DRAFT   LDAP Schema for Intranet Mail Routing      October 1999
+
+        set to a        set                     MAY relay to mailHost
+        remote host                             using mailRoutingAddress
+
+        set to a        not set                 original address
+        remote host                             relayed to mailHost
+
+        not set         set                     mail routed to
+                                                mailRoutingAddress
+
+        not set         not set                 error or
+                                                "location-independent"
+
+   The term "local" host above means the host specified is one that the
+   local (target) MTA considers to be a local delivery.  The local MTA
+   MAY rewrite the original address when mailRoutingAddress is not set
+   if local conventions warrant the change.
+
+5.  Examples
+
+   The following examples illustrate possible uses of the
+   'inetLocalMailRecipient' object class.
+
+   Here is an example of an LDAP entry representing a mail user:
+
+       dn: uid=joe,o=Example Corp,c=US
+       objectClass: top
+       objectClass: person
+       objectClass: organizationalPerson
+       objectClass: inetOrgPerson
+       objectClass: inetLocalMailRecipient
+       objectClass: nsMessagingServerUser
+       cn: Joe User
+       sn: User
+       uid: joe
+       userPassword: {crypt}y2KxtbzMYnApU
+       mail: joe@example.com
+       mailLocalAddress: joe@example.com
+       mailLocalAddress: joe@another.example.com
+       mailHost: nsmail1.example.com
+       mailDeliveryOption: mailbox
+       mailQuota: 1000000
+       mailForwardingAddress: mary@example.com
+
+   Joe User is a user of a hypothetical mail system called NS Messaging.
+   Let's say mail arrives on an MTA called "mx.example.com", addressed
+   to "joe@example.com".  That MTA searches the directory for a mail
+   recipient with that address, using an LDAP search filter [8] such as:
+
+       (&(objectClass=inetLocalMailRecipient)
+         (mailLocalAddress=joe@example.com))
+
+Lachman, et. al.                                                [Page 7]
+
+INTERNET-DRAFT   LDAP Schema for Intranet Mail Routing      October 1999
+
+   It finds Joe's LDAP entry, and routes the message to the target MTA
+   "nsmail1.example.com", while not rewriting the SMTP envelope
+   recipient address.  Then, "nsmail1.example.com" receives the message,
+   searches for and finds the recipient in the directory, ascertains
+   that it is the recipient's target MTA, and handles the message as per
+   other attributes in the recipient's entry and/or the MTA
+   configuration (in this case, the message is delivered to a mailbox,
+   and forwarded to another recipient).
+
+   Note that this document does not specify the rules an MTA is to use
+   to ascertain whether or not it is the target MTA for a given
+   recipient (it could check the recipient's 'mailHost' value against
+   its own hostname, or check the recipient's 'mailRoutingAddress', or
+   check the MTA configuration, or some combination of these).
+
+   Here is another example of an LDAP entry representing a mail user:
+
+       dn: uid=john,o=Example Corp,c=US
+       objectClass: top
+       objectClass: person
+       objectClass: organizationalPerson
+       objectClass: inetOrgPerson
+       objectClass: inetLocalMailRecipient
+       objectClass: xyzMailUser
+       cn: John Doe
+       sn: Doe
+       uid: john
+       userPassword: {crypt}y2KxtbzMYnApU
+       mail: john@example.com
+       mailLocalAddress: john@example.com
+       mailRoutingAddress: John_Doe@xyz-gw.example.com
+       xyzPostOfficeName: PO_1
+       xyzClusterNumber: 3
+       xyzMessageStoreId: 9
+
+   John Doe is a user of a hypothetical mail system called XYZ Mail.
+   Let's say mail arrives on an MTA called "mx.example.com", addressed
+   to "john@example.com".  That MTA searches the directory for a mail
+   recipient with that address, and routes the message to "xyz-
+   gw.example.com", rewriting the SMTP envelope recipient address to
+   "John_Doe@xyz-gw.example.com", as per the 'mailRoutingAddress'.  On
+   "xyz-gw.example.com", the message is gatewayed into the XYZ Mail
+   system and then dealt with as per other attributes.
+
+Lachman, et. al.                                                [Page 8]
+
+INTERNET-DRAFT   LDAP Schema for Intranet Mail Routing      October 1999
+
+   Here is an example of an LDAP entry representing a mailing list:
+
+       dn: cn=Scuba Group,o=Example Corp,c=US
+       objectClass: top
+       objectClass: groupOfUniqueNames
+       objectClass: inetLocalMailRecipient
+       objectClass: mailGroup
+       cn: Scuba Group
+       mail: scuba@example.com
+       mailLocalAddress: scuba@example.com
+       mailHost: host42.example.com
+       mgrpRFC822MailMember: joe@example.com
+       mgrpRFC822MailMember: john@example.com
+
+   The Scuba Group is a mail group (mailing list) that includes two
+   members.  A message addressed to "scuba@example.com" is routed to
+   "host42.example.com" where it is then resent to the mailing list
+   members.  The 'mailGroup' object class is specified elsewhere [9].
+
+   Here is an example of an LDAP entry representing a forwarding alias:
+
+       dn: cn=Jane Roe Forwarding Alias,o=Example,c=US
+       objectClass: top
+       objectClass: inetLocalMailRecipient
+       objectClass: mailForwardingAlias
+       mail: janeroe@example.org
+       mailLocalAddress: janeroe@example.org
+       mailHost: mail.example.org
+       mailForwardingAddress: janeroe@elsewhere.example.com
+       cn: Jane Roe Forwarding Alias
+
+   This entry uses a hypothetical object class 'mailForwardingAlias'
+   that is not specified here, but is used as an example of how an LDAP
+   entry might represent such a recipient type.  A message addressed to
+   "janeroe@example.org" is routed to "mail.example.org" where it is
+   then forwarded.  In this case, Jane Roe may be a former member of the
+   Example Organization, and they are forwarding her mail to her new
+   address elsewhere.
+
+6.  Security Considerations
+
+   As in all cases where account information is stored in an LDAP-based
+   directory service, network administrators must be careful to ensure
+   that their directory service controls users' access to the entries
+   and attributes stored therein, according to site policy.  In
+   particular, mail routing information should not be accessible from
+   outside the organization, since it is intended for use only by MTAs
+   within the organization.
+
+Lachman, et. al.                                                [Page 9]
+
+INTERNET-DRAFT   LDAP Schema for Intranet Mail Routing      October 1999
+
+7.  Acknowledgments
+
+   The 'inetLocalMailRecipient' object class is based on an earlier
+   design done by the Netscape Messaging and Directory Server teams,
+   which was implemented and deployed to customers as part of Netscape
+   Messaging Server.  Various team members contributed to the design,
+   including Bill Fitler, Bruce Steinback, Prabhat Keni, Mike Macgirvin,
+   John Myers, John Kristian, Tim Howes, Mark Smith, and Leif Hedstrom.
+   Thanks also to Jeff Hodges of Stanford for contributing to the early
+   design discussions, and to the other participants in the IETF LASER
+   BOF, including, from Sun Microsystems, John Beck, Anil Srivastava,
+   and Darryl Huff.
+
+8.  References
+
+   [1]  M. Wahl, T. Howes, S. Kille, "Lightweight Directory Access
+   Protocol (v3)", RFC 2251, December 1997.
+
+   [2]  J. Postel, "Simple Mail Transfer Protocol", STD 10, RFC 821,
+   August 1982.
+
+   [3]  D. Crocker, "Standard for the Format of ARPA Internet Text
+   Messages", STD 11, RFC 822, August 1982.
+
+   [4]  "Information Processing Systems - Open Systems Interconnection -
+   The Directory: Overview of Concepts, Models and Service", ISO/IEC JTC
+   1/SC21, International Standard 9594-1, 1988.
+
+   [5]  C. Partridge, "Mail routing and the domain system", STD 14, RFC
+   974, January 1986.
+
+   [6]  R. Braden, "Requirements for Internet hosts - application and
+   support", STD 3, RFC 1123, October 1989.
+
+   [7]  M. Wahl, A. Coulbeck, T. Howes, S. Kille, "Lightweight X.500
+   Directory Access Protocol (v3): Attribute Syntax Definitions", RFC
+   2252, December 1997.
+
+   [8]  T. Howes, "The String Representation of LDAP Search Filters",
+   RFC 2254, December 1997.
+
+   [9]  B. Steinback, "Using LDAP for SMTP Mailing Lists and Aliases",
+   Internet-Draft (work in progress).
+
+   [10]  S. Bradner, "Key words for use in RFCs to Indicate Requirement
+   Levels", BCP 14, RFC 2119, March 1997.
+
+   [11]  K. Moore, "SMTP Service Extension for Delivery Status
+   Notifications", RCP 1891, January 1996.
+
+Lachman, et. al.                                               [Page 10]
+
+INTERNET-DRAFT   LDAP Schema for Intranet Mail Routing      October 1999
+
+9.  Authors' Addresses
+
+   Hans Lachman
+   Netscape Communications Corp.
+   501 East Middlefield Road
+   Mountain View, CA  94043
+   Phone: (650) 254-1900
+   EMail: lachman@netscape.com
+
+   Gregory Neil Shapiro
+   Sendmail, Inc.
+   6603 Shellmound Street
+   Emeryville, CA 94608-1042
+   Phone: +1 510-594-5522
+   Fax:   +1 510-594-5411
+   EMail: gshapiro@sendmail.org
+
+X. Change Summary
+
+X.1.1 Substantive changes between
+      draft-lachman-laser-ldap-mail-routing-00.txt and
+      draft-lachman-laser-ldap-mail-routing-01.txt
+
+   (i)     Added Gregory Neil Shapiro as another author.
+   (ii)    Changed Draft heaer.
+   (iii)   Added "Conventions Used in this Document" section.
+   (iv)    Replaced RFC mentions with reference numbers.
+   (v)     Add new MUST/SHOULD/MAY sections to bring more in line with
+           RFC documents.
+   (vi)    Clarify job of MTA in Overview by adding third paragraph.
+   (vii)   mailRoutingAddress can be outside of administrative control.
+   (viii)  Eliminated use of 'mail' attribute for mail routing.
+   (ix)    Changed name of 'mailAlternateAddress' to 'mailLocalAddress'.
+   (x)     Remove "routable" from 'mailLocalAddress' description.
+   (xi)    Clarify which addresses MUST be in 'mailLocalAddress'.
+   (xii)   Allow for multiple responses if they all have the same
+           routing attribute values.
+   (xiii)  Clarify use of MX records on routing attributes.
+   (xiv)   Add a table to clarify use of 'mailHost' and
+           'mailRoutingAddress'.
+   (xv)    Remove document weakening statements from section 5.
+   (xvi)   Only use reserved domains (example.com, example.org) in
+           examples.
+   (xvii)  Clean up references
+   (xviii) Added section X to list the changes between draft versions.
+
+Lachman, et. al.                                               [Page 11]
+
+INTERNET-DRAFT   LDAP Schema for Intranet Mail Routing      October 1999
+
+10.  Full Copyright Statement
+
+   Copyright (C) The Internet Society (1999).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished
+   to others, and derivative works that comment on or otherwise
+   explain it or assist in its implementation may be prepared, copied,
+   published and distributed, in whole or in part, without
+   restriction of any kind, provided that the above copyright notice
+   and this paragraph are included on all such copies and derivative
+   works.  However, this document itself may not be modified in any
+   way, such as by removing the copyright notice or references to the
+   Internet Society or other Internet organizations, except as needed
+   for the purpose of developing Internet standards in which case the
+   procedures for copyrights defined in the Internet Standards
+   process must be followed, or as required to translate it into
+   languages other than English.
+
+   The limited permissions granted above are perpetual and will not
+   be revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on
+   an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET
+   ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR
+   IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
+   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Lachman, et. al.                                               [Page 12]
diff --git a/doc/drafts/draft-leach-uuids-guids-01.txt b/doc/drafts/draft-leach-uuids-guids-01.txt
new file mode 100644 (file)
index 0000000..d611d06
--- /dev/null
@@ -0,0 +1,1708 @@
+
+
+
+
+
+
+Network Working Group               Paul J. Leach, Microsoft
+INTERNET-DRAFT                             Rich Salz, Certco
+<draft-leach-uuids-guids-01.txt>
+Category: Standards Track
+Expires August 4, 1998                      February 4, 1998
+
+
+
+                             UUIDs and GUIDs
+
+STATUS OF THIS MEMO
+
+  This document is an Internet-Draft. Internet-Drafts are working
+  documents of the Internet Engineering Task Force (IETF), its areas,
+  and its working groups. Note that other groups may also distribute
+  working documents as Internet-Drafts.
+
+  Internet-Drafts are draft documents valid for a maximum of six months
+  and may be updated, replaced, or obsoleted by other documents at any
+  time. It is inappropriate to use Internet-Drafts as reference
+  material or to cite them other than as "work in progress".
+
+  To learn the current status of any Internet-Draft, please check the
+  "1id-abstracts.txt" listing contained in the Internet-Drafts Shadow
+  Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe),
+  munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or
+  ftp.isi.edu (US West Coast).
+
+  Distribution of this document is unlimited.  Please send comments to
+  the authors or the CIFS mailing list at <cifs@discuss.microsoft.com>.
+  Discussions of the mailing list are archived at
+  <URL:http://discuss.microsoft.com/archives/index.
+
+
+ABSTRACT
+
+  This specification defines the format of UUIDs (Universally Unique
+  IDentifier), also known as GUIDs (Globally Unique IDentifier). A UUID
+  is 128 bits long, and if generated according to the one of the
+  mechanisms in this document, is either guaranteed to be different
+  from all other UUIDs/GUIDs generated until 3400 A.D. or extremely
+  likely to be different (depending on the mechanism chosen). UUIDs
+  were originally used in the Network Computing System (NCS) [1] and
+  later in the Open Software Foundation's (OSF) Distributed Computing
+  Environment [2].
+
+  This specification is derived from the latter specification with the
+  kind permission of the OSF.
+
+
+Table of Contents
+
+1. Introduction .......................................................3
+
+
+[Page 1]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+2. Motivation .........................................................3
+
+3. Specification ......................................................3
+
+ 3.1 Format............................................................4
+
+   3.1.1  Variant......................................................4
+
+   3.1.2  UUID layout..................................................5
+
+   3.1.3  Version......................................................5
+
+   3.1.4  Timestamp....................................................6
+
+   3.1.5  Clock sequence...............................................6
+
+   3.1.6  Node.........................................................7
+
+   3.1.7  Nil UUID.....................................................7
+
+ 3.2 Algorithms for creating a time-based UUID.........................7
+
+   3.2.1  Basic algorithm..............................................7
+
+   3.2.2  Reading stable storage.......................................8
+
+   3.2.3  System clock resolution......................................8
+
+   3.2.4  Writing stable storage.......................................9
+
+   3.2.5  Sharing state across processes...............................9
+
+   3.2.6  UUID Generation details......................................9
+
+ 3.3 Algorithm for creating a name-based UUID.........................10
+
+ 3.4 Algorithms for creating a UUID from truly random or pseudo-random
+ numbers .............................................................11
+
+ 3.5 String Representation of UUIDs...................................12
+
+ 3.6 Comparing UUIDs for equality.....................................12
+
+ 3.7 Comparing UUIDs for relative order...............................13
+
+ 3.8 Byte order of UUIDs..............................................13
+
+4. Node IDs when no IEEE 802 network card is available ...............14
+
+5. Obtaining IEEE 802 addresses ......................................15
+
+6. Security Considerations ...........................................15
+
+7. Acknowledgements ..................................................15
+
+  Leach, Salz              expires  Aug 1998                    [Page 2]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+8. References ........................................................15
+
+9. Authors' addresses ................................................16
+
+10.Notice ............................................................16
+
+11.Full Copyright Statement ..........................................16
+
+Appendix A _ UUID Sample Implementation...............................17
+
+Appendix B _ Sample output of utest...................................27
+
+Appendix C _ Some name space IDs......................................27
+
+
+
+
+1. Introduction
+
+  This specification defines the format of UUIDs (Universally Unique
+  IDentifiers), also known as GUIDs (Globally Unique IDentifiers). A
+  UUID is 128 bits long, and if generated according to the one of the
+  mechanisms in this document, is either guaranteed to be different
+  from all other UUIDs/GUIDs generated until 3400 A.D. or extremely
+  likely to be different (depending on the mechanism chosen).
+
+
+2. Motivation
+
+  One of the main reasons for using UUIDs is that no centralized
+  authority is required to administer them (beyond the one that
+  allocates IEEE 802.1 node identifiers). As a result, generation on
+  demand can be completely automated, and they can be used for a wide
+  variety of purposes. The UUID generation algorithm described here
+  supports very high allocation rates: 10 million per second per
+  machine if you need it, so that they could even be used as
+  transaction IDs.
+
+  UUIDs are fixed-size (128-bits) which is reasonably small relative to
+  other alternatives. This fixed, relatively small size lends itself
+  well to sorting, ordering, and hashing of all sorts, storing in
+  databases, simple allocation, and ease of programming in general.
+
+
+3. Specification
+
+  A UUID is an identifier that is unique across both space and time,
+  with respect to the space of all UUIDs. To be precise, the UUID
+  consists of a finite bit space. Thus the time value used for
+  constructing a UUID is limited and will roll over in the future
+  (approximately at A.D. 3400, based on the specified algorithm). A
+  UUID can be used for multiple purposes, from tagging objects with an
+  extremely short lifetime, to reliably identifying very persistent
+  objects across a network.
+
+  Leach, Salz              expires  Aug 1998                    [Page 3]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+  The generation of UUIDs does not require that a registration
+  authority be contacted for each identifier. Instead, it requires a
+  unique value over space for each UUID generator. This spatially
+  unique value is specified as an IEEE 802 address, which is usually
+  already available to network-connected systems. This 48-bit address
+  can be assigned based on an address block obtained through the IEEE
+  registration authority. This section of the UUID specification
+  assumes the availability of an IEEE 802 address to a system desiring
+  to generate a UUID, but if one is not available section 4 specifies a
+  way to generate a probabilistically unique one that can not conflict
+  with any properly assigned IEEE 802 address.
+
+
+3.1 Format
+
+  In its most general form, all that can be said of the UUID format is
+  that a UUID is 16 octets, and that some bits of octet 8 of the UUID
+  called the variant field (specified in the next section) determine
+  finer structure.
+
+
+3.1.1 Variant
+  The variant field determines the layout of the UUID. That is, the
+  interpretation of all other bits in the UUID depends on the setting
+  of the bits in the variant field. The variant field consists of a
+  variable number of the msbs of octet 8 of the UUID.
+
+  The following table lists the contents of the variant field.
+
+       Msb0  Msb1   Msb2  Description
+
+        0      -     -    Reserved, NCS backward compatibility.
+
+        1      0     -    The variant specified in this document.
+
+        1      1     0    Reserved, Microsoft Corporation backward
+                          compatibility
+
+        1      1     1    Reserved for future definition.
+
+
+
+  Other UUID variants may not interoperate with the UUID variant
+  specified in this document, where interoperability is defined as the
+  applicability of operations such as string conversion and lexical
+  ordering across different systems. However, UUIDs allocated according
+  to the stricture of different variants, though they may define
+  different interpretations of the bits outside the variant field, will
+  not result in duplicate UUID allocation, because of the differing
+  values of the variant field itself.
+
+  The remaining fields described below (version, timestamp, etc.) are
+  defined only for the UUID variant noted above.
+
+
+  Leach, Salz              expires  Aug 1998                    [Page 4]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+3.1.2 UUID layout
+  The following table gives the format of a UUID for the variant
+  specified herein. The UUID consists of a record of 16 octets. To
+  minimize confusion about bit assignments within octets, the UUID
+  record definition is defined only in terms of fields that are
+  integral numbers of octets. The fields are in order of significance
+  for comparison purposes, with "time_low" the most significant, and
+  "node" the least significant.
+
+   Field                  Data Type     Octet  Note
+                                        #
+
+   time_low               unsigned 32   0-3    The low field of the
+                          bit integer          timestamp.
+
+   time_mid               unsigned 16   4-5    The middle field of the
+                          bit integer          timestamp.
+
+   time_hi_and_version    unsigned 16   6-7    The high field of the
+                          bit integer          timestamp multiplexed
+                                               with the version number.
+
+   clock_seq_hi_and_rese  unsigned 8    8      The high field of the
+   rved                   bit integer          clock sequence
+                                               multiplexed with the
+                                               variant.
+
+   clock_seq_low          unsigned 8    9      The low field of the
+                          bit integer          clock sequence.
+
+   node                   unsigned 48   10-15  The spatially unique
+                          bit integer          node identifier.
+
+
+
+
+3.1.3 Version
+  The version number is in the most significant 4 bits of the time
+  stamp (time_hi_and_version).
+
+  The following table lists currently defined versions of the UUID.
+
+       Msb0  Msb1   Msb2  Msb3   Version  Description
+
+        0      0     0      1       1     The time-based version
+                                          specified in this
+                                          document.
+
+        0      0     1      0       2     Reserved for DCE
+                                          Security version, with
+                                          embedded POSIX UIDs.
+
+        0      0     1      1       3     The name-based version
+                                          specified in this
+
+  Leach, Salz              expires  Aug 1998                    [Page 5]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+                                          document
+
+        0      1     0      0       4     The randomly or pseudo-
+                                          randomly generated
+                                          version specified in
+                                          this document
+
+
+3.1.4 Timestamp
+  The timestamp is a 60 bit value. For UUID version 1, this is
+  represented by Coordinated Universal Time (UTC) as a count of 100-
+  nanosecond intervals since 00:00:00.00, 15 October 1582 (the date of
+  Gregorian reform to the Christian calendar).
+
+  For systems that do not have UTC available, but do have local time,
+  they MAY use local time instead of UTC, as long as they do so
+  consistently throughout the system. This is NOT RECOMMENDED, however,
+  and it should be noted that all that is needed to generate UTC, given
+  local time, is a time zone offset.
+
+  For UUID version 3, it is a 60 bit value constructed from a name.
+
+  For UUID version 4, it is a randomly or pseudo-randomly generated 60
+  bit value.
+
+
+3.1.5 Clock sequence
+  For UUID version 1, the clock sequence is used to help avoid
+  duplicates that could arise when the clock is set backwards in time
+  or if the node ID changes.
+
+  If the clock is set backwards, or even might have been set backwards
+  (e.g., while the system was powered off), and the UUID generator can
+  not be sure that no UUIDs were generated with timestamps larger than
+  the value to which the clock was set, then the clock sequence has to
+  be changed. If the previous value of the clock sequence is known, it
+  can be just incremented; otherwise it should be set to a random or
+  high-quality pseudo random value.
+
+  Similarly, if the node ID changes (e.g. because a network card has
+  been moved between machines), setting the clock sequence to a random
+  number minimizes the probability of a duplicate due to slight
+  differences in the clock settings of the machines. (If the value of
+  clock sequence associated with the changed node ID were known, then
+  the clock sequence could just be incremented, but that is unlikely.)
+
+  The clock sequence MUST be originally (i.e., once in the lifetime of
+  a system) initialized to a random number to minimize the correlation
+  across systems. This provides maximum protection against node
+  identifiers that may move or switch from system to system rapidly.
+  The initial value MUST NOT be correlated to the node identifier.
+
+  For UUID version 3, it is a 14 bit value constructed from a name.
+
+
+  Leach, Salz              expires  Aug 1998                    [Page 6]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+  For UUID version 4, it is a randomly or pseudo-randomly generated 14
+  bit value.
+
+
+3.1.6 Node
+  For UUID version 1, the node field consists of the IEEE address,
+  usually the host address. For systems with multiple IEEE 802
+  addresses, any available address can be used. The lowest addressed
+  octet (octet number 10) contains the global/local bit and the
+  unicast/multicast bit, and is the first octet of the address
+  transmitted on an 802.3 LAN.
+
+  For systems with no IEEE address, a randomly or pseudo-randomly
+  generated value may be used (see section 4). The multicast bit must
+  be set in such addresses, in order that they will never conflict with
+  addresses obtained from network cards.
+
+  For UUID version 3, the node field is a 48 bit value constructed from
+  a name.
+
+  For UUID version 4, the node field is a randomly or pseudo-randomly
+  generated 48 bit value.
+
+
+3.1.7 Nil UUID
+  The nil UUID is special form of UUID that is specified to have all
+  128 bits set to 0 (zero).
+
+
+3.2 Algorithms for creating a time-based UUID
+
+  Various aspects of the algorithm for creating a version 1 UUID are
+  discussed in the following sections. UUID generation requires a
+  guarantee of uniqueness within the node ID for a given variant and
+  version. Interoperability is provided by complying with the specified
+  data structure.
+
+
+3.2.1 Basic algorithm
+  The following algorithm is simple, correct, and inefficient:
+
+  .  Obtain a system wide global lock
+
+  .  From a system wide shared stable store (e.g., a file), read the
+     UUID generator state: the values of the time stamp, clock sequence,
+     and node ID used to generate the last UUID.
+
+  .  Get the current time as a 60 bit count of 100-nanosecond intervals
+     since 00:00:00.00, 15 October 1582
+
+  .  Get the current node ID
+
+
+
+
+  Leach, Salz              expires  Aug 1998                    [Page 7]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+  .  If the state was unavailable (non-existent or corrupted), or the
+     saved node ID is different than the current node ID, generate a
+     random clock sequence value
+
+  .  If the state was available, but the saved time stamp is later than
+     the current time stamp, increment the clock sequence value
+
+  .  Format a UUID from the current time stamp, clock sequence, and node
+     ID values according to the structure in section 3.1 (see section
+     3.2.6 for more details)
+
+  .  Save the state (current time stamp, clock sequence, and node ID)
+     back to the stable store
+
+  .  Release the system wide global lock
+
+  If UUIDs do not need to be frequently generated, the above algorithm
+  may be perfectly adequate. For higher performance requirements,
+  however, issues with the basic algorithm include:
+
+  .  Reading the state from stable storage each time is inefficient
+
+  .  The resolution of the system clock may not be 100-nanoseconds
+
+  .  Writing the state to stable storage each time is inefficient
+
+  .  Sharing the state across process boundaries may be inefficient
+
+  Each of these issues can be addressed in a modular fashion by local
+  improvements in the functions that read and write the state and read
+  the clock. We address each of them in turn in the following sections.
+
+
+3.2.2 Reading stable storage
+  The state only needs to be read from stable storage once at boot
+  time, if it is read into a system wide shared volatile store (and
+  updated whenever the stable store is updated).
+
+  If an implementation does not have any stable store available, then
+  it can always say that the values were unavailable. This is the least
+  desirable implementation, because it will increase the frequency of
+  creation of new clock sequence numbers, which increases the
+  probability of duplicates.
+
+  If the node ID can never change (e.g., the net card is inseparable
+  from the system), or if any change also reinitializes the clock
+  sequence to a random value, then instead of keeping it in stable
+  store, the current node ID may be returned.
+
+
+3.2.3 System clock resolution
+  The time stamp is generated from the system time, whose resolution
+  may be less than the resolution of the UUID time stamp.
+
+
+  Leach, Salz              expires  Aug 1998                    [Page 8]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+  If UUIDs do not need to be frequently generated, the time stamp can
+  simply be the system time multiplied by the number of 100-nanosecond
+  intervals per system time interval.
+
+  If a system overruns the generator by requesting too many UUIDs
+  within a single system time interval, the UUID service MUST either:
+  return an error, or stall the UUID generator until the system clock
+  catches up.
+
+  A high resolution time stamp can be simulated by keeping a count of
+  how many UUIDs have been generated with the same value of the system
+  time, and using it to construction the low-order bits of the time
+  stamp. The count will range between zero and the number of 100-
+  nanosecond intervals per system time interval.
+
+  Note: if the processors overrun the UUID generation frequently,
+  additional node identifiers can be allocated to the system, which
+  will permit higher speed allocation by making multiple UUIDs
+  potentially available for each time stamp value.
+
+
+3.2.4 Writing stable storage
+  The state does not always need to be written to stable store every
+  time a UUID is generated. The timestamp in the stable store can be
+  periodically set to a value larger than any yet used in a UUID; as
+  long as the generated UUIDs have time stamps less than that value,
+  and the clock sequence and node ID remain unchanged, only the shared
+  volatile copy of the state needs to be updated. Furthermore, if the
+  time stamp value in stable store is in the future by less than the
+  typical time it takes the system to reboot, a crash will not cause a
+  reinitialization of the clock sequence.
+
+
+3.2.5 Sharing state across processes
+  If it is too expensive to access shared state each time a UUID is
+  generated, then the system wide generator can be implemented to
+  allocate a block of time stamps each time it is called, and a per-
+  process generator can allocate from that block until it is exhausted.
+
+
+3.2.6 UUID Generation details
+  UUIDs are generated according to the following algorithm:
+
+  - Determine the values for the UTC-based timestamp and clock sequence
+  to be used in the UUID, as described above.
+
+  - For the purposes of this algorithm, consider the timestamp to be a
+  60-bit unsigned integer and the clock sequence to be a 14-bit
+  unsigned integer. Sequentially number the bits in a field, starting
+  from 0 (zero) for the least significant bit.
+
+  - Set the time_low field equal to the least significant 32-bits (bits
+  numbered 0 to 31 inclusive) of the time stamp in the same order of
+  significance.
+
+  Leach, Salz              expires  Aug 1998                    [Page 9]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+  - Set the time_mid field equal to the bits numbered 32 to 47
+  inclusive of the time stamp in the same order of significance.
+
+  - Set the 12 least significant bits (bits numbered 0 to 11 inclusive)
+  of the time_hi_and_version field equal to the bits numbered 48 to 59
+  inclusive of the time stamp in the same order of significance.
+
+  - Set the 4 most significant bits (bits numbered 12 to 15 inclusive)
+  of the time_hi_and_version field to the 4-bit version number
+  corresponding to the UUID version being created, as shown in the
+  table in section 3.1.3.
+
+  - Set the clock_seq_low field to the 8 least significant bits (bits
+  numbered 0 to 7 inclusive) of the clock sequence in the same order of
+  significance.
+
+  - Set the 6 least significant bits (bits numbered 0 to 5 inclusive)
+  of the clock_seq_hi_and_reserved field to the 6 most significant bits
+  (bits numbered 8 to 13 inclusive) of the clock sequence in the same
+  order of significance.
+
+  - Set the 2 most significant bits (bits numbered 6 and 7) of the
+  clock_seq_hi_and_reserved to 0 and 1, respectively.
+
+  - Set the node field to the 48-bit IEEE address in the same order of
+  significance as the address.
+
+
+3.3 Algorithm for creating a name-based UUID
+
+  The version 3 UUID is meant for generating UUIDs from "names" that
+  are drawn from, and unique within, some "name space". Some examples
+  of names (and, implicitly, name spaces) might be DNS names, URLs, ISO
+  Object IDs (OIDs), reserved words in a programming language, or X.500
+  Distinguished Names (DNs); thus, the concept of name and name space
+  should be broadly construed, and not limited to textual names. The
+  mechanisms or conventions for allocating names from, and ensuring
+  their uniqueness within, their name spaces are beyond the scope of
+  this specification.
+
+  The requirements for such UUIDs are as follows:
+
+  .  The UUIDs generated at different times from the same name in the
+     same namespace MUST be equal
+
+  .  The UUIDs generated from two different names in the same namespace
+     should be different (with very high probability)
+
+  .  The UUIDs generated from the same name in two different namespaces
+     should be different with (very high probability)
+
+  .  If two UUIDs that were generated from names are equal, then they
+     were generated from the same name in the same namespace (with very
+     high probability).
+
+  Leach, Salz              expires  Aug 1998                   [Page 10]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+  The algorithm for generating the a UUID from a name and a name space
+  are as follows:
+
+  .  Allocate a UUID to use as a "name space ID" for all UUIDs generated
+     from names in that name space
+
+  .  Convert the name to a canonical sequence of octets (as defined by
+     the standards or conventions of its name space); put the name space
+     ID in network byte order
+
+  .  Compute the MD5 [3] hash of the name space ID concatenated with the
+     name
+
+  .  Set octets 0-3 of  time_low field to octets 0-3 of the MD5 hash
+
+  .  Set octets 0-1 of  time_mid field to octets 4-5 of the MD5 hash
+
+  .  Set octets 0-1 of  time_hi_and_version field to octets 6-7 of the
+     MD5 hash
+
+  .  Set the clock_seq_hi_and_reserved field to octet 8 of the MD5 hash
+
+  .  Set the clock_seq_low field to octet 9 of the MD5 hash
+
+  .  Set octets 0-5 of the node field to octets 10-15 of the MD5 hash
+
+  .  Set the 2 most significant bits (bits numbered 6 and 7) of the
+     clock_seq_hi_and_reserved to 0 and 1, respectively.
+
+  .  Set the 4 most significant bits (bits numbered 12 to 15 inclusive)
+     of the time_hi_and_version field to the 4-bit version number
+     corresponding to the UUID version being created, as shown in the
+     table above.
+
+  .  Convert the resulting UUID to local byte order.
+
+
+3.4 Algorithms for creating a UUID from truly random or pseudo-random
+numbers
+
+  The version 4 UUID is meant for generating UUIDs from truly-random or
+  pseudo-random numbers.
+
+  The algorithm is as follows:
+
+  .  Set the 2 most significant bits (bits numbered 6 and 7) of the
+     clock_seq_hi_and_reserved to 0 and 1, respectively.
+
+  .  Set the 4 most significant bits (bits numbered 12 to 15 inclusive)
+     of the time_hi_and_version field to the 4-bit version number
+     corresponding to the UUID version being created, as shown in the
+     table above.
+
+
+
+  Leach, Salz              expires  Aug 1998                   [Page 11]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+  .  Set all the other bits to randomly (or pseudo-randomly) chosen
+     values.
+
+  Here are several possible ways to generate the random values:
+
+  .  Use a physical source of randomness: for example, a white noise
+     generator, radioactive decay, or a lava lamp.
+
+  .  Use a cryptographic strength random number generator.
+
+
+3.5 String Representation of UUIDs
+
+  For use in human readable text, a UUID string representation is
+  specified as a sequence of fields, some of which are separated by
+  single dashes.
+
+  Each field is treated as an integer and has its value printed as a
+  zero-filled hexadecimal digit string with the most significant digit
+  first. The hexadecimal values a to f inclusive are output as lower
+  case characters, and are case insensitive on input. The sequence is
+  the same as the UUID constructed type.
+
+  The formal definition of the UUID string representation is provided
+  by the following extended BNF:
+
+  UUID                   = <time_low> "-" <time_mid> "-"
+                           <time_high_and_version> "-"
+                           <clock_seq_and_reserved>
+                           <clock_seq_low> "-" <node>
+  time_low               = 4*<hexOctet>
+  time_mid               = 2*<hexOctet>
+  time_high_and_version  = 2*<hexOctet>
+  clock_seq_and_reserved = <hexOctet>
+  clock_seq_low          = <hexOctet>
+  node                   = 6*<hexOctet
+  hexOctet               = <hexDigit> <hexDigit>
+  hexDigit =
+        "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
+        | "a" | "b" | "c" | "d" | "e" | "f"
+        | "A" | "B" | "C" | "D" | "E" | "F"
+
+  The following is an example of the string representation of a UUID:
+
+       f81d4fae-7dec-11d0-a765-00a0c91e6bf6
+
+3.6 Comparing UUIDs for equality
+
+  Consider each field of the UUID to be an unsigned integer as shown in
+  the table in section 3.1. Then, to compare a pair of UUIDs,
+  arithmetically compare the corresponding fields from each UUID in
+  order of significance and according to their data type. Two UUIDs are
+  equal if and only if all the corresponding fields are equal.
+
+
+  Leach, Salz              expires  Aug 1998                   [Page 12]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+  Note: as a practical matter, on many systems comparison of two UUIDs
+  for equality can be performed simply by comparing the 128 bits of
+  their in-memory representation considered as a 128 bit unsigned
+  integer. Here, it is presumed that by the time the in-memory
+  representation is obtained the appropriate byte-order
+  canonicalizations have been carried out.
+
+
+3.7 Comparing UUIDs for relative order
+
+  Two UUIDs allocated according to the same variant can also be ordered
+  lexicographically. For the UUID variant herein defined, the first of
+  two UUIDs follows the second if the most significant field in which
+  the UUIDs differ is greater for the first UUID. The first of a pair
+  of UUIDs precedes the second if the most significant field in which
+  the UUIDs differ is greater for the second UUID.
+
+
+3.8 Byte order of UUIDs
+
+  UUIDs may be transmitted in many different forms, some of which may
+  be dependent on the presentation or application protocol where the
+  UUID may be used.  In such cases, the order, sizes and byte orders of
+  the UUIDs fields on the wire will depend on the relevant presentation
+  or application protocol.  However, it is strongly RECOMMENDED that
+  the order of the fields conform with ordering set out in section 3.1
+  above. Furthermore, the payload size of each field in the application
+  or presentation protocol MUST be large enough that no information
+  lost in the process of encoding them for transmission.
+
+  In the absence of explicit application or presentation protocol
+  specification to the contrary, a UUID is encoded as a 128-bit object,
+  as follows: the fields are encoded as 16 octets, with the sizes and
+  order of the fields defined in section 3.1, and with each field
+  encoded with the Most Significant Byte first (also known as network
+  byte order).
+
+  0                   1                   2                   3
+   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  |                          time_low                             |
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  |       time_mid                |         time_hi_and_version   |
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  |clk_seq_hi_res |  clk_seq_low  |         node (0-1)            |
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  |                         node (2-5)                            |
+  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+
+
+
+
+
+  Leach, Salz              expires  Aug 1998                   [Page 13]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+4. Node IDs when no IEEE 802 network card is available
+
+  If a system wants to generate UUIDs but has no IEE 802 compliant
+  network card or other source of IEEE 802 addresses, then this section
+  describes how to generate one.
+
+  The ideal solution is to obtain a 47 bit cryptographic quality random
+  number, and use it as the low 47 bits of the node ID, with the most
+  significant bit of the first octet of the node ID set to 1. This bit
+  is the unicast/multicast bit, which will never be set in IEEE 802
+  addresses obtained from network cards; hence, there can never be a
+  conflict between UUIDs generated by machines with and without network
+  cards.
+
+  If a system does not have a primitive to generate cryptographic
+  quality random numbers, then in most systems there are usually a
+  fairly large number of sources of randomness available from which one
+  can be generated. Such sources are system specific, but often
+  include:
+
+  - the percent of memory in use
+  - the size of main memory in bytes
+  - the amount of free main memory in bytes
+  - the size of the paging or swap file in bytes
+  - free bytes of paging or swap file
+  - the total size of user virtual address space in bytes
+  - the total available user address space bytes
+  - the size of boot disk drive in bytes
+  - the free disk space on boot drive in bytes
+  - the current time
+  - the amount of time since the system booted
+  - the individual sizes of files in various system directories
+  - the creation, last read, and modification times of files in various
+  system directories
+  - the utilization factors of various system resources (heap, etc.)
+  - current mouse cursor position
+  - current caret position
+  - current number of running processes, threads
+  - handles or IDs of the desktop window and the active window
+  - the value of stack pointer of the caller
+  - the process and thread ID of caller
+  - various processor architecture specific performance counters
+  (instructions executed, cache misses, TLB misses)
+
+  (Note that it precisely the above kinds of sources of randomness that
+  are used to seed cryptographic quality random number generators on
+  systems without special hardware for their construction.)
+
+  In addition, items such as the computer's name and the name of the
+  operating system, while not strictly speaking random, will help
+  differentiate the results from those obtained by other systems.
+
+  The exact algorithm to generate a node ID using these data is system
+  specific, because both the data available and the functions to obtain
+
+  Leach, Salz              expires  Aug 1998                   [Page 14]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+  them are often very system specific. However, assuming that one can
+  concatenate all the values from the randomness sources into a buffer,
+  and that a cryptographic hash function such as MD5 [3] is available,
+  then any 6 bytes of the MD5 hash of the buffer, with the multicast
+  bit (the high bit of the first byte) set will be an appropriately
+  random node ID.
+
+  Other hash functions, such as SHA-1 [4], can also be used. The only
+  requirement is that the result be suitably random _ in the sense that
+  the outputs from a set uniformly distributed inputs are themselves
+  uniformly distributed, and that a single bit change in the input can
+  be expected to cause half of the output bits to change.
+
+
+5. Obtaining IEEE 802 addresses
+
+  At the time of writing, the following URL
+
+       http://standards.ieee.org/db/oui/forms/
+
+  contains information on how to obtain an IEEE 802 address block. At
+  the time of writing, the cost is $1250 US.
+
+
+6. Security Considerations
+
+  It should not be assumed that UUIDs are hard to guess; they should
+  not be used as capabilities.
+
+
+7. Acknowledgements
+
+  This document draws heavily on the OSF DCE specification for UUIDs.
+  Ted Ts'o provided helpful comments, especially on the byte ordering
+  section which we mostly plagiarized from a proposed wording he
+  supplied (all errors in that section are our responsibility,
+  however).
+
+
+8. References
+
+  [1]  Lisa Zahn, et. al., Network Computing Architecture, Prentice
+     Hall, Englewood Cliffs, NJ, 1990
+
+  [2] DCE: Remote Procedure Call, Open Group CAE Specification C309
+  ISBN 1-85912-041-5 28cm. 674p. pbk. 1,655g. 8/94
+
+  [3] R. Rivest, RFC 1321, "The MD5 Message-Digest Algorithm",
+     04/16/1992.
+
+  [4] NIST FIPS PUB 180-1, "Secure Hash Standard," National Institute
+  of Standards and Technology, U.S. Department of Commerce, DRAFT, May
+  31, 1994.
+
+
+  Leach, Salz              expires  Aug 1998                   [Page 15]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+9. Authors' addresses
+
+  Paul J. Leach
+  Microsoft
+  1 Microsoft Way
+  Redmond, WA, 98052, U.S.A.
+  paulle@microsoft.com
+  Tel. 425 882 8080
+  Fax. 425 936 7329
+
+  Rich Salz
+  100 Cambridge Park Drive
+  Cambridge MA  02140
+  salzr@certco.com
+  Tel. 617 499 4075
+  Fax. 617 576 0019
+
+
+10. Notice
+
+  The IETF takes no position regarding the validity or scope of any
+  intellectual property or other rights that might be claimed to
+  pertain to the implementation or use of the technology described in
+  this document or the extent to which any license under such rights
+  might or might not be available; neither does it represent that it
+  has made any effort to identify any such rights.  Information on the
+  IETF's procedures with respect to rights in standards-track and
+  standards-related documentation can be found in BCP-11.  Copies of
+  claims of rights made available for publication and any assurances of
+  licenses to be made available, or the result of an attempt made to
+  obtain a general license or permission for the use of such
+  proprietary rights by implementors or users of this specification can
+  be obtained from the IETF Secretariat.
+
+  The IETF invites any interested party to bring to its attention any
+  copyrights, patents or patent applications, or other proprietary
+  rights which may cover technology that may be required to practice
+  this standard.  Please address the information to the IETF Executive
+  Director.
+
+
+11. Full Copyright Statement
+
+  Copyright (C) The Internet Society 1997. All Rights Reserved.
+
+  This document and translations of it may be copied and furnished to
+  others, and derivative works that comment on or otherwise explain it
+  or assist in its implementation may be prepared, copied, published
+  and distributed, in whole or in part, without restriction of any
+  kind, provided that the above copyright notice and this paragraph are
+  included on all such copies and derivative works.  However, this
+  document itself may not be modified in any way, such as by removing
+  the copyright notice or references to the Internet Society or other
+  Internet organizations, except as needed for the purpose of
+
+  Leach, Salz              expires  Aug 1998                   [Page 16]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+  developing Internet standards in which case the procedures for
+  copyrights defined in the Internet Standards process must be
+  followed, or as required to translate it into languages other than
+  English.
+
+  The limited permissions granted above are perpetual and will not be
+  revoked by the Internet Society or its successors or assigns.
+
+  This document and the information contained herein is provided on an
+  "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+  TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+  BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+  HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+  MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+ Appendix A _ UUID Sample Implementation
+
+  This implementation consists of 5 files: uuid.h, uuid.c, sysdep.h,
+  sysdep.c and utest.c. The uuid.* files are the system independent
+  implementation of the UUID generation algorithms described above,
+  with all the optimizations described above except efficient state
+  sharing across processes included. The code has been tested on Linux
+  (Red Hat 4.0) with GCC (2.7.2), and Windows NT 4.0 with VC++ 5.0. The
+  code assumes 64 bit integer support, which makes it a lot clearer.
+
+  All the following source files should be considered to have the
+  following copyright notice included:
+
+  copyrt.h
+
+  /*
+  ** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
+  ** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. &
+  ** Digital Equipment Corporation, Maynard, Mass.
+  ** Copyright (c) 1998 Microsoft.
+  ** To anyone who acknowledges that this file is provided "AS IS"
+  ** without any express or implied warranty: permission to use, copy,
+  ** modify, and distribute this file for any purpose is hereby
+  ** granted without fee, provided that the above copyright notices and
+  ** this notice appears in all source code copies, and that none of
+  ** the names of Open Software Foundation, Inc., Hewlett-Packard
+  ** Company, or Digital Equipment Corporation be used in advertising
+  ** or publicity pertaining to distribution of the software without
+  ** specific, written prior permission.  Neither Open Software
+  ** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital
+  Equipment
+  ** Corporation makes any representations about the suitability of
+  ** this software for any purpose.
+  */
+
+
+  uuid.h
+
+
+  Leach, Salz              expires  Aug 1998                   [Page 17]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+  #include "copyrt.h"
+  #undef uuid_t
+  typedef struct _uuid_t {
+      unsigned32          time_low;
+      unsigned16          time_mid;
+      unsigned16          time_hi_and_version;
+      unsigned8           clock_seq_hi_and_reserved;
+      unsigned8           clock_seq_low;
+      byte                node[6];
+  } uuid_t;
+
+  /* uuid_create -- generate a UUID */
+  int uuid_create(uuid_t * uuid);
+
+  /* uuid_create_from_name -- create a UUID using a "name"
+     from a "name space" */
+  void uuid_create_from_name(
+    uuid_t * uuid,        /* resulting UUID */
+    uuid_t nsid,          /* UUID to serve as context, so identical
+                             names from different name spaces generate
+                             different UUIDs */
+    void * name,          /* the name from which to generate a UUID */
+    int namelen           /* the length of the name */
+  );
+
+  /* uuid_compare --  Compare two UUID's "lexically" and return
+          -1   u1 is lexically before u2
+           0   u1 is equal to u2
+           1   u1 is lexically after u2
+     Note:   lexical ordering is not temporal ordering!
+  */
+  int uuid_compare(uuid_t *u1, uuid_t *u2);
+
+  uuid.c
+
+  #include "copyrt.h"
+  #include <string.h>
+  #include <stdio.h>
+  #include <stdlib.h>
+  #include <time.h>
+  #include "sysdep.h"
+  #include "uuid.h"
+
+  /* various forward declarations */
+  static int read_state(unsigned16 *clockseq, uuid_time_t *timestamp,
+  uuid_node_t * node);
+  static void write_state(unsigned16 clockseq, uuid_time_t timestamp,
+  uuid_node_t node);
+  static void format_uuid_v1(uuid_t * uuid, unsigned16 clockseq,
+  uuid_time_t timestamp, uuid_node_t node);
+  static void format_uuid_v3(uuid_t * uuid, unsigned char hash[16]);
+  static void get_current_time(uuid_time_t * timestamp);
+  static unsigned16 true_random(void);
+
+
+  Leach, Salz              expires  Aug 1998                   [Page 18]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+  /* uuid_create -- generator a UUID */
+  int uuid_create(uuid_t * uuid) {
+    uuid_time_t timestamp, last_time;
+    unsigned16 clockseq;
+    uuid_node_t node;
+    uuid_node_t last_node;
+    int f;
+
+    /* acquire system wide lock so we're alone */
+    LOCK;
+
+    /* get current time */
+    get_current_time(&timestamp);
+
+    /* get node ID */
+    get_ieee_node_identifier(&node);
+
+    /* get saved state from NV storage */
+    f = read_state(&clockseq, &last_time, &last_node);
+
+    /* if no NV state, or if clock went backwards, or node ID changed
+       (e.g., net card swap) change clockseq */
+    if (!f || memcmp(&node, &last_node, sizeof(uuid_node_t)))
+        clockseq = true_random();
+    else if (timestamp < last_time)
+        clockseq++;
+
+    /* stuff fields into the UUID */
+    format_uuid_v1(uuid, clockseq, timestamp, node);
+
+    /* save the state for next time */
+    write_state(clockseq, timestamp, node);
+
+    UNLOCK;
+    return(1);
+  };
+
+  /* format_uuid_v1 -- make a UUID from the timestamp, clockseq,
+                       and node ID */
+  void format_uuid_v1(uuid_t * uuid, unsigned16 clock_seq, uuid_time_t
+  timestamp, uuid_node_t node) {
+      /* Construct a version 1 uuid with the information we've gathered
+       * plus a few constants. */
+    uuid->time_low = (unsigned long)(timestamp & 0xFFFFFFFF);
+      uuid->time_mid = (unsigned short)((timestamp >> 32) & 0xFFFF);
+      uuid->time_hi_and_version = (unsigned short)((timestamp >> 48) &
+         0x0FFF);
+      uuid->time_hi_and_version |= (1 << 12);
+      uuid->clock_seq_low = clock_seq & 0xFF;
+      uuid->clock_seq_hi_and_reserved = (clock_seq & 0x3F00) >> 8;
+      uuid->clock_seq_hi_and_reserved |= 0x80;
+      memcpy(&uuid->node, &node, sizeof uuid->node);
+  };
+
+
+  Leach, Salz              expires  Aug 1998                   [Page 19]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+  /* data type for UUID generator persistent state */
+  typedef struct {
+    uuid_time_t ts;       /* saved timestamp */
+    uuid_node_t node;     /* saved node ID */
+    unsigned16 cs;        /* saved clock sequence */
+    } uuid_state;
+
+  static uuid_state st;
+
+  /* read_state -- read UUID generator state from non-volatile store */
+  int read_state(unsigned16 *clockseq, uuid_time_t *timestamp,
+  uuid_node_t *node) {
+    FILE * fd;
+    static int inited = 0;
+
+    /* only need to read state once per boot */
+    if (!inited) {
+        fd = fopen("state", "rb");
+        if (!fd)
+             return (0);
+        fread(&st, sizeof(uuid_state), 1, fd);
+        fclose(fd);
+        inited = 1;
+    };
+    *clockseq = st.cs;
+    *timestamp = st.ts;
+    *node = st.node;
+    return(1);
+  };
+
+  /* write_state -- save UUID generator state back to non-volatile
+  storage */
+  void write_state(unsigned16 clockseq, uuid_time_t timestamp,
+  uuid_node_t node) {
+    FILE * fd;
+    static int inited = 0;
+    static uuid_time_t next_save;
+
+    if (!inited) {
+        next_save = timestamp;
+        inited = 1;
+    };
+    /* always save state to volatile shared state */
+    st.cs = clockseq;
+    st.ts = timestamp;
+    st.node = node;
+    if (timestamp >= next_save) {
+        fd = fopen("state", "wb");
+        fwrite(&st, sizeof(uuid_state), 1, fd);
+        fclose(fd);
+        /* schedule next save for 10 seconds from now */
+        next_save = timestamp + (10 * 10 * 1000 * 1000);
+    };
+  };
+
+  Leach, Salz              expires  Aug 1998                   [Page 20]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+
+  /* get-current_time -- get time as 60 bit 100ns ticks since whenever.
+    Compensate for the fact that real clock resolution is
+    less than 100ns. */
+  void get_current_time(uuid_time_t * timestamp) {
+      uuid_time_t                time_now;
+      static uuid_time_t  time_last;
+      static unsigned16   uuids_this_tick;
+    static int                   inited = 0;
+
+    if (!inited) {
+          get_system_time(&time_now);
+        uuids_this_tick = UUIDS_PER_TICK;
+        inited = 1;
+    };
+
+      while (1) {
+          get_system_time(&time_now);
+
+        /* if clock reading changed since last UUID generated... */
+          if (time_last != time_now) {
+             /* reset count of uuids gen'd with this clock reading */
+              uuids_this_tick = 0;
+             break;
+        };
+          if (uuids_this_tick < UUIDS_PER_TICK) {
+             uuids_this_tick++;
+             break;
+        };
+        /* going too fast for our clock; spin */
+      };
+    /* add the count of uuids to low order bits of the clock reading */
+    *timestamp = time_now + uuids_this_tick;
+  };
+
+  /* true_random -- generate a crypto-quality random number.
+     This sample doesn't do that. */
+  static unsigned16
+  true_random(void)
+  {
+    static int inited = 0;
+    uuid_time_t time_now;
+
+    if (!inited) {
+        get_system_time(&time_now);
+        time_now = time_now/UUIDS_PER_TICK;
+        srand((unsigned int)(((time_now >> 32) ^ time_now)&0xffffffff));
+        inited = 1;
+    };
+
+      return (rand());
+  }
+
+
+
+  Leach, Salz              expires  Aug 1998                   [Page 21]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+  /* uuid_create_from_name -- create a UUID using a "name" from a "name
+  space" */
+  void uuid_create_from_name(
+    uuid_t * uuid,        /* resulting UUID */
+    uuid_t nsid,          /* UUID to serve as context, so identical
+                             names from different name spaces generate
+                             different UUIDs */
+    void * name,          /* the name from which to generate a UUID */
+    int namelen           /* the length of the name */
+  ) {
+    MD5_CTX c;
+    unsigned char hash[16];
+    uuid_t net_nsid;      /* context UUID in network byte order */
+
+    /* put name space ID in network byte order so it hashes the same
+        no matter what endian machine we're on */
+    net_nsid = nsid;
+    htonl(net_nsid.time_low);
+    htons(net_nsid.time_mid);
+    htons(net_nsid.time_hi_and_version);
+
+    MD5Init(&c);
+    MD5Update(&c, &net_nsid, sizeof(uuid_t));
+    MD5Update(&c, name, namelen);
+    MD5Final(hash, &c);
+
+    /* the hash is in network byte order at this point */
+    format_uuid_v3(uuid, hash);
+  };
+
+  /* format_uuid_v3 -- make a UUID from a (pseudo)random 128 bit number
+  */
+  void format_uuid_v3(uuid_t * uuid, unsigned char hash[16]) {
+      /* Construct a version 3 uuid with the (pseudo-)random number
+       * plus a few constants. */
+
+      memcpy(uuid, hash, sizeof(uuid_t));
+
+    /* convert UUID to local byte order */
+    ntohl(uuid->time_low);
+    ntohs(uuid->time_mid);
+    ntohs(uuid->time_hi_and_version);
+
+    /* put in the variant and version bits */
+      uuid->time_hi_and_version &= 0x0FFF;
+      uuid->time_hi_and_version |= (3 << 12);
+      uuid->clock_seq_hi_and_reserved &= 0x3F;
+      uuid->clock_seq_hi_and_reserved |= 0x80;
+  };
+
+  /* uuid_compare --  Compare two UUID's "lexically" and return
+         -1   u1 is lexically before u2
+          0   u1 is equal to u2
+          1   u1 is lexically after u2
+
+  Leach, Salz              expires  Aug 1998                   [Page 22]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+      Note:   lexical ordering is not temporal ordering!
+  */
+  int uuid_compare(uuid_t *u1, uuid_t *u2)
+  {
+    int i;
+
+  #define CHECK(f1, f2) if (f1 != f2) return f1 < f2 ? -1 : 1;
+    CHECK(u1->time_low, u2->time_low);
+    CHECK(u1->time_mid, u2->time_mid);
+    CHECK(u1->time_hi_and_version, u2->time_hi_and_version);
+    CHECK(u1->clock_seq_hi_and_reserved, u2->clock_seq_hi_and_reserved);
+    CHECK(u1->clock_seq_low, u2->clock_seq_low)
+    for (i = 0; i < 6; i++) {
+        if (u1->node[i] < u2->node[i])
+             return -1;
+        if (u1->node[i] > u2->node[i])
+        return 1;
+      }
+    return 0;
+  };
+
+  sysdep.h
+
+  #include "copyrt.h"
+  /* remove the following define if you aren't running WIN32 */
+  #define WININC 0
+
+  #ifdef WININC
+  #include <windows.h>
+  #else
+  #include <sys/types.h>
+  #include <sys/time.h>
+  #include <sys/sysinfo.h>
+  #endif
+
+  /* change to point to where MD5 .h's live */
+  /* get MD5 sample implementation from RFC 1321 */
+  #include "global.h"
+  #include "md5.h"
+
+  /* set the following to the number of 100ns ticks of the actual
+  resolution of
+  your system's clock */
+  #define UUIDS_PER_TICK 1024
+
+  /* Set the following to a call to acquire a system wide global lock
+  */
+  #define LOCK
+  #define UNLOCK
+
+  typedef unsigned long   unsigned32;
+  typedef unsigned short  unsigned16;
+  typedef unsigned char   unsigned8;
+  typedef unsigned char   byte;
+
+  Leach, Salz              expires  Aug 1998                   [Page 23]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+
+  /* Set this to what your compiler uses for 64 bit data type */
+  #ifdef WININC
+  #define unsigned64_t unsigned __int64
+  #define I64(C) C
+  #else
+  #define unsigned64_t unsigned long long
+  #define I64(C) C##LL
+  #endif
+
+
+  typedef unsigned64_t uuid_time_t;
+  typedef struct {
+    char nodeID[6];
+  } uuid_node_t;
+
+  void get_ieee_node_identifier(uuid_node_t *node);
+  void get_system_time(uuid_time_t *uuid_time);
+  void get_random_info(char seed[16]);
+
+
+  sysdep.c
+
+  #include "copyrt.h"
+  #include <stdio.h>
+  #include "sysdep.h"
+
+  /* system dependent call to get IEEE node ID.
+     This sample implementation generates a random node ID
+     */
+  void get_ieee_node_identifier(uuid_node_t *node) {
+    char seed[16];
+    FILE * fd;
+    static inited = 0;
+    static uuid_node_t saved_node;
+
+    if (!inited) {
+        fd = fopen("nodeid", "rb");
+        if (fd) {
+             fread(&saved_node, sizeof(uuid_node_t), 1, fd);
+             fclose(fd);
+        }
+        else {
+             get_random_info(seed);
+             seed[0] |= 0x80;
+             memcpy(&saved_node, seed, sizeof(uuid_node_t));
+             fd = fopen("nodeid", "wb");
+             if (fd) {
+                    fwrite(&saved_node, sizeof(uuid_node_t), 1, fd);
+                    fclose(fd);
+             };
+        };
+        inited = 1;
+    };
+
+  Leach, Salz              expires  Aug 1998                   [Page 24]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+    *node = saved_node;
+  };
+
+  /* system dependent call to get the current system time.
+     Returned as 100ns ticks since Oct 15, 1582, but resolution may be
+     less than 100ns.
+  */
+  #ifdef _WINDOWS_
+
+  void get_system_time(uuid_time_t *uuid_time) {
+    ULARGE_INTEGER time;
+
+    GetSystemTimeAsFileTime((FILETIME *)&time);
+
+      /* NT keeps time in FILETIME format which is 100ns ticks since
+       Jan 1, 1601.  UUIDs use time in 100ns ticks since Oct 15, 1582.
+       The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec)
+       + 18 years and 5 leap days.
+    */
+
+      time.QuadPart +=
+            (unsigned __int64) (1000*1000*10)       // seconds
+          * (unsigned __int64) (60 * 60 * 24)       // days
+          * (unsigned __int64) (17+30+31+365*18+5); // # of days
+
+    *uuid_time = time.QuadPart;
+
+  };
+
+  void get_random_info(char seed[16]) {
+    MD5_CTX c;
+    typedef struct {
+        MEMORYSTATUS m;
+        SYSTEM_INFO s;
+        FILETIME t;
+        LARGE_INTEGER pc;
+        DWORD tc;
+        DWORD l;
+        char hostname[MAX_COMPUTERNAME_LENGTH + 1];
+    } randomness;
+    randomness r;
+
+    MD5Init(&c);
+    /* memory usage stats */
+    GlobalMemoryStatus(&r.m);
+    /* random system stats */
+    GetSystemInfo(&r.s);
+    /* 100ns resolution (nominally) time of day */
+    GetSystemTimeAsFileTime(&r.t);
+    /* high resolution performance counter */
+    QueryPerformanceCounter(&r.pc);
+    /* milliseconds since last boot */
+    r.tc = GetTickCount();
+    r.l = MAX_COMPUTERNAME_LENGTH + 1;
+
+  Leach, Salz              expires  Aug 1998                   [Page 25]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+    GetComputerName(r.hostname, &r.l );
+    MD5Update(&c, &r, sizeof(randomness));
+    MD5Final(seed, &c);
+  };
+  #else
+
+  void get_system_time(uuid_time_t *uuid_time)
+  {
+      struct timeval tp;
+
+      gettimeofday(&tp, (struct timezone *)0);
+
+      /* Offset between UUID formatted times and Unix formatted times.
+         UUID UTC base time is October 15, 1582.
+         Unix base time is January 1, 1970.
+      */
+      *uuid_time = (tp.tv_sec * 10000000) + (tp.tv_usec * 10) +
+        I64(0x01B21DD213814000);
+  };
+
+  void get_random_info(char seed[16]) {
+    MD5_CTX c;
+    typedef struct {
+        struct sysinfo s;
+        struct timeval t;
+        char hostname[257];
+    } randomness;
+    randomness r;
+
+    MD5Init(&c);
+    sysinfo(&r.s);
+    gettimeofday(&r.t, (struct timezone *)0);
+    gethostname(r.hostname, 256);
+    MD5Update(&c, &r, sizeof(randomness));
+    MD5Final(seed, &c);
+  };
+
+  #endif
+
+  utest.c
+
+  #include "copyrt.h"
+  #include "sysdep.h"
+  #include <stdio.h>
+  #include "uuid.h"
+
+  uuid_t NameSpace_DNS = { /* 6ba7b810-9dad-11d1-80b4-00c04fd430c8 */
+      0x6ba7b810,
+      0x9dad,
+      0x11d1,
+      0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8
+    };
+
+
+
+  Leach, Salz              expires  Aug 1998                   [Page 26]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+  /* puid -- print a UUID */
+  void puid(uuid_t u);
+
+  /* Simple driver for UUID generator */
+  void main(int argc, char **argv) {
+    uuid_t u;
+    int f;
+
+    uuid_create(&u);
+    printf("uuid_create()             -> "); puid(u);
+
+    f = uuid_compare(&u, &u);
+    printf("uuid_compare(u,u): %d\n", f);     /* should be 0 */
+    f = uuid_compare(&u, &NameSpace_DNS);
+    printf("uuid_compare(u, NameSpace_DNS): %d\n", f); /* s.b. 1 */
+    f = uuid_compare(&NameSpace_DNS, &u);
+    printf("uuid_compare(NameSpace_DNS, u): %d\n", f); /* s.b. -1 */
+
+    uuid_create_from_name(&u, NameSpace_DNS, "www.widgets.com", 15);
+    printf("uuid_create_from_name() -> "); puid(u);
+  };
+
+  void puid(uuid_t u) {
+    int i;
+
+    printf("%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", u.time_low, u.time_mid,
+        u.time_hi_and_version, u.clock_seq_hi_and_reserved,
+        u.clock_seq_low);
+    for (i = 0; i < 6; i++)
+        printf("%2.2x", u.node[i]);
+    printf("\n");
+  };
+
+Appendix B _ Sample output of utest
+
+  uuid_create()             -> 7d444840-9dc0-11d1-b245-5ffdce74fad2
+  uuid_compare(u,u): 0
+  uuid_compare(u, NameSpace_DNS): 1
+  uuid_compare(NameSpace_DNS, u): -1
+  uuid_create_from_name()   -> e902893a-9d22-3c7e-a7b8-d6e313b71d9f
+
+Appendix C _ Some name space IDs
+
+  This appendix lists the name space IDs for some potentially
+  interesting name spaces, as initialized C structures and in the
+  string representation defined in section 3.5
+
+  uuid_t NameSpace_DNS = { /* 6ba7b810-9dad-11d1-80b4-00c04fd430c8 */
+      0x6ba7b810,
+      0x9dad,
+      0x11d1,
+      0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8
+    };
+
+
+  Leach, Salz              expires  Aug 1998                   [Page 27]\f
+
+
+  Internet-Draft        UUIDs and GUIDs (DRAFT)                 02/04/98
+
+
+  uuid_t NameSpace_URL = { /* 6ba7b811-9dad-11d1-80b4-00c04fd430c8 */
+      0x6ba7b811,
+      0x9dad,
+      0x11d1,
+      0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8
+    };
+
+  uuid_t NameSpace_OID = { /* 6ba7b812-9dad-11d1-80b4-00c04fd430c8 */
+      0x6ba7b812,
+      0x9dad,
+      0x11d1,
+      0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8
+    };
+
+  uuid_t NameSpace_X500 = { /* 6ba7b814-9dad-11d1-80b4-00c04fd430c8 */
+      0x6ba7b814,
+      0x9dad,
+      0x11d1,
+      0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8
+    };
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/drafts/draft-rharrison-ldap-extpartresp-xx.txt b/doc/drafts/draft-rharrison-ldap-extpartresp-xx.txt
new file mode 100644 (file)
index 0000000..c3b747e
--- /dev/null
@@ -0,0 +1,176 @@
+Individual Submission to LDAPExt Working Group              R. Harrison
+Internet Draft                                             Novell, Inc.
+Document: draft-rharrison-ldap-extpartresp-00.txt         October, 1999
+Category: Proposed Standard
+
+
+                       Extended Partial Response
+                    Protocol Enhancement to LDAP v3
+
+
+Status of this Memo
+
+   This document is an Internet-Draft and is in full conformance with
+   all provisions of Section 10 of RFC2026 [1].
+
+   Internet-Drafts are working documents of the Internet Engineering
+   Task Force (IETF), its areas, and its working groups. Note that
+   other groups may also distribute working documents as Internet-
+   Drafts. Internet-Drafts are draft documents valid for a maximum of
+   six months and may be updated, replaced, or obsoleted by other
+   documents at any time. It is inappropriate to use Internet- Drafts
+   as reference material or to cite them other than as "work in
+   progress."
+   The list of current Internet-Drafts can be accessed at
+   http://www.ietf.org/ietf/1id-abstracts.txt
+   The list of Internet-Draft Shadow Directories can be accessed at
+   http://www.ietf.org/shadow.html.
+
+
+1. Abstract
+
+   This document describes the ExtendedPartialResponse, an element of
+   LDAP v3 protocol which allows multiple responses to LDAP v3 extended
+   requests.  Extended partial responses are backward compatible with
+   the existing LDAP v3 Extended Operation defined in [LDAPv3].
+
+2. Conventions used in this document
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and "OPTIONAL" in
+   this document are to be interpreted as described in [RFC2119].
+
+
+3. Motivation for the Extended Partial Response
+
+   The Extended Operation ([LDAPv3] Section 4.12) was defined in LDAP
+   v3 to allow additional operations to be defined as part of the
+   protocol without requiring a new revision of the protocol.
+
+   The LDAP v3 Extended Operation allows for a single extended response
+   to each extended request, but this paradigm may not be efficient
+   enough for some directory operations.  For instance, the LDAP search
+   operation is a directory operation that is much more efficient when
+   multiple partial responses are used to service a single request. The
+
+Harrison    Individual Submission Ã» Expires April 14, 2000           1
+\f
+                  LDAP v3 Extended Partial Response     October, 1999
+
+
+   extended partial response generalizes the current extended operation
+   definition to give LDAP server implementers the ability to make use
+   of a single-request-multiple-response paradigm for extended LDAP
+   operations that would benefit from it.
+
+4. Element of Protocol
+
+   The ExtendedPartialResponse is defined as
+
+   ExtendedPartialResponse ::= [APPLICATION 25] SEQUENCE {
+           responseName     [0] LDAPOID,
+           response         [1] OCTET STRING OPTIONAL }
+
+   An LDAP server responds to an LDAP v3 ExtendedRequest with zero or
+   more ExtendedPartialResponses followed by one ExtendedResponse. This
+   ensures backward compatibility with existing LDAP extensions which
+   do not make use of the ExtendedPartialResponse.  As with all LDAP
+   extensions, LDAP extensions that make use of the
+   ExtendedPartialResponse have predefined syntax and semantics that
+   are defined in RFCs or are private to a particular implementation.
+
+5. Security Considerations
+
+   This draft describes an enhancement to the LDAP v3 protocol
+   [LDAPv3].  All security considerations of [LDAPv3] apply to this
+   draft, however it does not introduce any new security considerations
+   to the LDAP v3 protocol.
+
+6. References
+
+    [LDAPv3]
+        Wahl, M., Howes, T., and S. Kille, "Lightweight Directory
+        Access Protocol (v3)", RFC 2251, December 1997.
+
+   [ReqsKeywords]
+        Scott Bradner. "Key Words for use in RFCs to Indicate
+        Requirement Levels". RFC 2119.
+
+
+7. Acknowledgments
+
+   The author would like to acknowledge the readers of the LDAP
+   Extensions working group mail list who responded to the suggestion
+   that a multiple-response paradigm might be useful for LDAP extended
+   requests.  Special thanks go to two individuals: David Wilbur who
+   first introduced the idea on the working group list, and Thomas
+   Salter, who succinctly summarized the discussion and suggested the
+   name ExtendedPartialResponse in his summary.
+
+8. Author's Addresses
+
+   Roger Harrison
+   Novell, Inc.
+
+Harrison    Individual Submission Ã» Expires April 14, 2000           2
+\f
+                  LDAP v3 Extended Partial Response     October, 1999
+
+
+   122 E. 1700 S.
+   Provo, UT 84606
+   +1 801 861 2642
+   roger_harrison@novell.com
+
+Full Copyright Statement
+
+   "Copyright (C) The Internet Society (date). All Rights Reserved.
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implmentation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph
+   are included on all such copies and derivative works. However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Harrison    Individual Submission Ã» Expires April 14, 2000           3
+\f
diff --git a/doc/drafts/draft-smith-ldap-c-api-ext-vlv-xx.txt b/doc/drafts/draft-smith-ldap-c-api-ext-vlv-xx.txt
new file mode 100644 (file)
index 0000000..6b4f28b
--- /dev/null
@@ -0,0 +1,468 @@
+Network Working Group                                           M. Smith
+INTERNET-DRAFT                             Netscape Communications Corp.
+Intended Category: Standards Track
+Expires: 18 April 2000
+
+                                                          18 October 1999
+
+                 LDAP C API Virtual List View Extension
+                <draft-smith-ldap-c-api-ext-vlv-00.txt>
+
+1.  Status of this Memo
+
+This document is an Internet-Draft and is in full conformance with all
+provisions of Section 10 of RFC2026.  Internet-Drafts are working docu-
+ments of the Internet Engineering Task Force (IETF), its areas, and its
+working groups.  Note that other groups may also distribute working
+documents as Internet-Drafts.
+
+Internet-Drafts are draft documents valid for a maximum of six months
+and may be updated, replaced, or obsoleted by other documents at any
+time.  It is inappropriate to use Internet-Drafts as reference material
+or to cite them other than as "work in progress."
+
+The list of current Internet-Drafts can be accessed at
+http://www.ietf.org/ietf/1id-abstracts.txt.
+
+The list of Internet-Draft Shadow Directories can be accessed at
+http://www.ietf.org/shadow.html.
+
+This draft document will be submitted to the RFC Editor as a Standards
+Track document. Distribution of this memo is unlimited.  Technical dis-
+cussion of this document will take place on the IETF LDAP Extension
+Working Group mailing list <ietf-ldapext@netscape.com>.  Please send
+editorial comments directly to the author <mcs@netscape.com>.
+
+Copyright (C) The Internet Society (1998-1999). All Rights Reserved.
+
+Please see the Copyright section near the end of this document for more
+information.
+
+Expires: 18 April 2000                                          [Page 1]
+
+INTERNET-DRAFT   LDAP C API Virtual List View Extension  18 October 1999
+
+2.  Introduction
+
+This document defines a virtual list view extension for the LDAP C API
+to support the LDAP protocol extensions for scrolling view browsing of
+search results.  More specifically, this document defines functions to
+create virtual list view request controls and to parse virtual list view
+response controls.
+
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+"SHOULD", "SHOULD NOT", "RECOMMENDED",  and "MAY" in this document are
+to be interpreted as described in RFC 2119 [KEYWORDS].
+
+3.  Table of Contents
+
+1.     Status of this Memo............................................1
+2.     Introduction...................................................2
+3.     Table of Contents..............................................2
+4.     Background and Intended Usage..................................2
+5.     Advertising the Virtual List View C LDAP API Extension.........3
+6.     Creating a Virtual List View Request Control...................3
+7.     Parsing a Virtual List View Response Control...................6
+8.     Example Code...................................................8
+9.     Security Considerations........................................8
+10.    Copyright......................................................8
+11.    Bibliography...................................................9
+12.    Author's Address...............................................9
+13.    Appendix A - Summary of Additions to the C LDAP API............9
+
+4.  Background and Intended Usage
+
+The LDAP C API [CAPI] defines a C language application programming
+interface (API) to the Lightweight Directory Access Protocol [LDAP].
+This document defines an extension to that API to support an optional
+LDAP protocol extension for scrolling view browsing of search results,
+also known as Virtual List View [VLV].
+
+The scrolling view browsing LDAP extension itself is designed to allow a
+"virtual list box" feature to be supported efficiently by LDAP servers
+and clients.  The protocol extension consists of two LDAP controls:  a
+Virtual List View (VLV) Request control which is sent by a client to a
+server along with an LDAP search request and a Virtual List View
+Response control which is returned by the server to send back status
+information about the VLV request.
+
+LDAP clients that wish to use the "virtual list box" feature SHOULD
+first check the supportedControls attribute in a server's rootDSE to
+
+Expires: 18 April 2000                                          [Page 2]
+
+INTERNET-DRAFT   LDAP C API Virtual List View Extension  18 October 1999
+
+determine if a value identical to the Virtual List View Request
+control's OID is present.  If the OID is present and the client chooses
+to use the VLV feature, it MUST construct a Virtual List View Request
+control and a Server Side Sorting Control [SSS] and send both controls
+to the server within an LDAP searchRequest message.  Both controls
+SHOULD be marked critical.  Client applications MAY use the
+ldap_create_vlv_control() function described in this document to create
+a Virtual List View Request control.
+
+At the end of the search request processing, the server SHOULD return a
+Virtual List View Response control in the LDAP searchResultDone message.
+A Virtual List View Response control MAY be parsed to extract its con-
+tents by using the ldap_parse_vlv_control() function described in this
+document.
+
+5.  Advertising the Virtual List View C LDAP API Extension
+
+To conform with the requirements defined in the C LDAP API specification
+[CAPI], implementations that support this extension SHOULD advertise the
+existence of this extension as follows:
+
+   Define the macro LDAP_API_FEATURE_VIRTUAL_LIST_VIEW as a value that
+   corresponds to the "level" or revision of this specification.  When
+   this document is published as an RFC, the value to use for
+   LDAP_API_FEATURE_VIRTUAL_LIST_VIEW is the RFC number itself.  While
+   this document is an Internet Draft, the value to use is 1000 plus the
+   revision number of this draft, i.e., 1000 for the -00 revision of
+   this draft, 1001 for the -01 version, and so on.
+
+   Return the text string VIRTUAL_LIST_VIEW in the ldapai_extensions
+   array of the LDAPAPIInfo structure following a successful call to
+   ldap_get_option() with an option parameter value of
+   LDAP_OPT_API_INFO.
+
+   Return information about the extension when the ldapaif_name field in
+   the LDAPAPIFeatureInfo structure is set to the text string
+   VIRTUAL_LIST_VIEW and a call to ldap_get_option() with an option
+   parameter value of LDAP_OPT_API_FEATURE_INFO is made.
+
+6.  Creating a Virtual List View Request Control
+
+The LDAPVLVInfo structure describes a Virtual List View Request control
+and is passed to the ldap_create_vlv_control() function to create a Vir-
+tualListViewRequest control.  The resulting control SHOULD be passed to
+
+Expires: 18 April 2000                                          [Page 3]
+
+INTERNET-DRAFT   LDAP C API Virtual List View Extension  18 October 1999
+
+the ldap_search_ext() or ldap_search_ext_s() functions described in
+[CAPI] to send them to the server.  The ldap_create_sort_control() func-
+tion described in [SSSAPI] MAY be used to create a Sort control that is
+be passed to the server along with the VirtualListViewRequest control.
+
+The LDAPVLVInfo structure MAY also be used by applications to manage the
+state information associated with a series of virtual list view
+client/server interactions.
+
+    /* LDAPVLVInfo structure: */
+    typedef struct ldapvlvinfo {
+        int             ldvlv_version;    /* version of this struct (1) */
+        unsigned long   ldvlv_before_count;
+        unsigned long   ldvlv_after_count;
+        unsigned long   ldvlv_offset;     /* used if ldvlv_attrvalue is NULL
+*/
+        unsigned long   ldvlv_count;      /* used if ldvlv_attrvalue is NULL
+*
+        struct berval   *ldvlv_attrvalue;
+        struct berval   *ldvlv_context;
+        void            *ldvlv_extradata; /* for use by application */
+    } LDAPVLVInfo;
+
+    /* value for the ldvlv_version field of the LDAPVLVInfo structure: */
+    #define LDAP_VLVINFO_VERSION        1
+
+    /* function used to create a VirtualListViewRequest control: */
+    int ldap_create_vlv_control(
+        LDAP            *ld,
+        LDAPVLVInfo     *vlvinfop,
+        LDAPControl     **ctrlp
+    );
+
+    /* OID of the VirtualListViewRequest control: */
+    #define LDAP_CONTROL_VLVREQUEST     "2.16.840.1.113730.3.4.9"
+
+The parameters to the ldap_create_vlv_control() function are:
+
+ld                  An LDAP session handle, as obtained from a call to
+                    ldap_init().
+
+vlvinfop            The address of an LDAPVLVInfo structure whose con-
+                    tents are used to construct the value of the control
+                    that is created.
+
+ctrlp               A result parameter that will be assigned the address
+                    of an LDAPControl structure that contains the Virtu-
+                    alListViewRequest control created by this function.
+                    The memory occupied by the LDAPControl structure
+                    SHOULD be freed when it is no longer in use by
+
+Expires: 18 April 2000                                          [Page 4]
+
+INTERNET-DRAFT   LDAP C API Virtual List View Extension  18 October 1999
+
+                    calling ldap_control_free().
+
+The ldap_create_vlv_control() function returns a C LDAP API error code
+to indicate success or failure (LDAP_SUCCESS if all goes well).
+
+The members of the LDAPVLVInfo structure are:
+
+ldvlv_version       A number that identifies the version of the
+                    LDAPVLVInfo structure.  This SHOULD always be set to
+                    the value LDAP_VLVINFO_VERSION (1).
+
+ldvlv_before_count  A count of the number of entries before the target
+                    entry the client wants the server to send back.
+                    This field corresponds to the beforeCount element of
+                    the BER-encoded VirtualListViewRequest control value
+                    itself.
+
+ldvlv_after_count   A count of the number of entries after the target
+                    entry the client wants the server to send back.
+                    This field corresponds to the afterCount element of
+                    the BER-encoded VirtualListViewRequest control value
+                    itself.
+
+ldvlv_offset        This field is only used if ldvlv_attrvalue is NULL,
+                    i.e, if the byoffset choice within the VirtualList-
+                    ViewRequest control is to be used.  ldvlv_offset is
+                    used along with the ldvlv_count value by the server
+                    to determine the target entry.  This field
+                    corresponds to the offset element within the BER-
+                    encoded VirtualListViewRequest control value itself.
+
+ldvlv_count         This field is only used if ldvlv_attrvalue is NULL,
+                    i.e., if the byIndex choice within the VirtualList-
+                    ViewRequest control is to be used.  ldvlv_count is
+                    used along with the ldvlv_offset value by the server
+                    to determine the target entry.  This field
+                    corresponds to the contentCount element within the
+                    BER-encoded VirtualListViewRequest control value
+                    itself.
+
+ldvlv_attrvalue     If this is not NULL, it indicates that the
+                    greaterThanOrEqual choice within the VirtualList-
+                    ViewRequest is to be used.  ldvlv_attrvalue
+                    corresponds to the assertionValue element of the
+                    BER-encoded VirtualListViewRequest control value
+                    itself.  This value is compared by the server with
+                    the values of the attribute specified by the primary
+                    sort key to determine the target entry.
+
+Expires: 18 April 2000                                          [Page 5]
+
+INTERNET-DRAFT   LDAP C API Virtual List View Extension  18 October 1999
+
+ldvlv_context       If this is not NULL, it is included as the context
+                    identifier in the VirtualListViewRequest control;
+                    ldvlv_context corresponds to the contextID element
+                    within the BER-encoded VirtualListViewRequest con-
+                    trol value itself.  If ldvlv_context is NULL, no
+                    context identifier is included in the VirtualList-
+                    ViewRequest control.
+
+ldvlv_extradata     This field is reserved for application-specific use
+                    and is not used by the ldap_create_vlv_control()
+                    function; it has no effect on the control that is
+                    created.
+
+7.  Parsing a Virtual List View Response Control
+
+When an application receives the result from a VLV search, it SHOULD use
+the ldap_parse_vlv_control() function to look for and parse the Virtual
+List View Response control returned by the server.
+
+    /* function used to look for and parse a VirtualListViewResponse
+control: */
+    int ldap_parse_vlv_control(
+        LDAP            *ld,
+        LDAPControl     **ctrls,
+        unsigned long   *target_posp,
+        unsigned long   *list_countp,
+        struct berval   **contextp,
+        int             *errcodep
+    );
+
+    /* OID of the VirtualListViewResponse control: */
+    #define LDAP_CONTROL_VLVRESPONSE        "2.16.840.1.113730.3.4.10"
+
+    /* new error codes: */
+    #define LDAP_SORT_CONTROL_MISSING       0x3C    /* 60 */
+    #define LDAP_INDEX_RANGE_ERROR          0x3D    /* 61 */
+
+The parameters to the ldap_parse_vlv_control() function are:
+
+ld                  An LDAP session handle.
+
+ctrls               The address of a NULL-terminated array of LDAPCon-
+                    trol structures, typically obtained by a call to
+                    ldap_parse_result().
+
+target_posp         This result parameter is filled in with the list
+                    index of the target entry.  If this parameter is
+                    NULL, the target position is not returned.  The
+
+Expires: 18 April 2000                                          [Page 6]
+
+INTERNET-DRAFT   LDAP C API Virtual List View Extension  18 October 1999
+
+                    value for this result parameter is pulled from the
+                    targetPosition element of the BER-encoded Virtual-
+                    ListViewResponse control value itself.
+
+list_countp         This result parameter is filled in with the server's
+                    estimate of the size of the list.  If this parameter
+                    is NULL, the size is not returned.  The value for
+                    this result parameter is pulled from the con-
+                    tentCount element of the BER-encoded VirtualList-
+                    ViewResponse control value itself.
+
+contextp            This result parameter is filled in with the address
+                    of a struct berval that contains the server-
+                    generated context identifier if one was returned by
+                    the server.  If the server did not return a context
+                    identifier, this parameter will be set to NULL.  The
+                    struct berval returned SHOULD be disposed of by cal-
+                    ling ber_bvfree() when it is no longer needed.  If
+                    NULL is passed for contextp, the context identifier
+                    is not returned.
+
+errcodep            This result parameter is filled in with the VLV
+                    result code.  If this parameter is NULL, the result
+                    code is not returned.  The value for this result
+                    parameter is pulled from the virtualListViewResult
+                    element of the BER-encoded VirtualListViewResponse
+                    control value itself.  As specified in the VLV pro-
+                    tocol extension [VLV], it will have one of the fol-
+                    lowing values:
+
+                       LDAP_SUCCESS                (0);  defined in [CAPI]
+                       LDAP_OPERATIONS_ERROR       (1);  defined in [CAPI]
+                       LDAP_UNWILLING_TO_PERFORM   (53); defined in [CAPI]
+                       LDAP_INSUFFICIENT_ACCESS    (50); defined in [CAPI]
+                       LDAP_BUSY                   (51); defined in [CAPI]
+                       LDAP_TIMELIMIT_EXCEEDED     (3);  defined in [CAPI]
+                       LDAP_ADMINLIMIT_EXCEEDED    (11); defined in [CAPI]
+                       LDAP_SORT_CONTROL_MISSING   (60); defined above
+                       LDAP_INDEX_RANGE_ERROR      (61); defined above
+                       LDAP_OTHER                  (80); defined in [CAPI]
+
+The ldap_parse_vlv_control() function returns an LDAP error code that
+indicates whether a VLV Result control was found and whether the parsing
+was successful.  LDAP_SUCCESS is returned if all goes well,
+LDAP_CONTROL_NOT_FOUND is returned if the ctrls array does not include a
+VirtualListViewResponse control, and another LDAP error code that is
+defined in [CAPI] is returned if a parsing error or other problem
+occurs.
+
+Expires: 18 April 2000                                          [Page 7]
+
+INTERNET-DRAFT   LDAP C API Virtual List View Extension  18 October 1999
+
+8.  Example Code
+
+To be provided.
+
+9.  Security Considerations
+
+Most servers will be configured to restrict access to the Virtual List
+View feature since poorly-behaved or malicious clients may cause many
+resources to be consumed on the server, or allow users to retrieve too
+many entries, or allow users to get an accurate count of the number of
+entries present in a portion of the DIT.  Clients should take care to
+not abuse the VLV feature and should be prepared for servers to refuse
+to service a particular VLV request due to access control or other
+site-defined policies.
+
+Please see the protocol extension document [VLV] for a discussion of
+related security considerations.
+
+10.  Copyright
+
+Copyright (C) The Internet Society (1998-1999). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to oth-
+ers, and derivative works that comment on or otherwise explain it or
+assist in its implementation may be prepared, copied, published and dis-
+tributed, in whole or in part, without restriction of any kind, provided
+that the above copyright notice and this paragraph are included on all
+such copies and derivative works.  However, this document itself may not
+be modified in any way, such as by removing the copyright notice or
+references to the Internet Society or other Internet organizations,
+except as needed for the  purpose of developing Internet standards in
+which case the procedures for copyrights defined in the Internet Stan-
+dards process must be followed, or as required to translate it into
+languages other than English.
+
+The limited permissions granted above are perpetual and will not be
+revoked by the Internet Society or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS
+IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK
+FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT
+INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FIT-
+NESS FOR A PARTICULAR PURPOSE.
+
+Expires: 18 April 2000                                          [Page 8]
+
+INTERNET-DRAFT   LDAP C API Virtual List View Extension  18 October 1999
+
+11.  Bibliography
+
+[CAPI]      M. Smith, T. Howes, A. Herron, M. Wahl, A. Anantha, "The C
+            LDAP Application Program Interface", INTERNET-DRAFT,
+            <draft-ietf-ldapext-ldap-c-api-04.txt>, 8 October 1999.
+
+[KEYWORDS]  S. Bradner, "Key words for use in RFCs to Indicate Require-
+            ment Levels", RFC 2119, March 1997.
+
+[LDAP]      M. Wahl, T. Howes, S. Kille, "Lightweight Directory Access
+            Protocol (v3)", RFC 2251, December 1997.
+
+[SSS]       A. Herron, T. Howes, M. Wahl, A. Anantha, "LDAP Control
+            Extension for Server Side Sorting of Search Results",
+            INTERNET-DRAFT, April 1999.
+
+[SSSAPI]    C. Weider, A. Herron, T. Howes, M. Smith, M. Wahl, "LDAP API
+            Extensions for Sort and Simple Paged Results", INTERNET-
+            DRAFT, <draft-ietf-asid-ldapv3-api-ext-00.txt>, July 1997.
+
+[VLV]       D. Boreham, J. Sermersheim, A. Anantha, M. Armijo, "LDAP
+            Extensions for Scrolling View Browsing of Search Results",
+            INTERNET-DRAFT <draft-ietf-ldapext-ldapv3-vlv-03.txt>, 11
+            June 1999.
+
+12.  Author's Address
+
+   Mark Smith
+   Netscape Communications Corp.
+   501 E. Middlefield Rd., Mailstop MV068
+   Mountain View, CA 94043
+   USA
+   +1 650 937-3477
+   mcs@netscape.com
+
+13.  Appendix A - Summary of Additions to the C LDAP API
+
+This extension introduces the following macros:
+
+   LDAP_API_FEATURE_VIRTUAL_LIST_VIEW
+   LDAP_VLVINFO_VERSION
+   LDAP_CONTROL_VLVREQUEST
+   LDAP_CONTROL_VLVRESPONSE
+   LDAP_SORT_CONTROL_MISSING
+   LDAP_INDEX_RANGE_ERROR
+
+Expires: 18 April 2000                                          [Page 9]
+
+INTERNET-DRAFT   LDAP C API Virtual List View Extension  18 October 1999
+
+This extension introduces the following structures and typedefs:
+
+   ldapvlvinfo
+   LDAPVLVInfo
+
+This extension introduces the following functions:
+
+   ldap_create_vlv_control()
+   ldap_parse_vlv_control()
+
+Expires: 18 April 2000                                         [Page 10]
diff --git a/doc/man/Makefile.in b/doc/man/Makefile.in
new file mode 100644 (file)
index 0000000..ace0d25
--- /dev/null
@@ -0,0 +1,6 @@
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+## COPYING RESTRICTIONS APPLY, See COPYRIGHT file
+##
+## man Makefile.in for OpenLDAP
+
+SUBDIRS= man1 man3 man5 man8
diff --git a/doc/man/man1/Makefile.in b/doc/man/man1/Makefile.in
new file mode 100644 (file)
index 0000000..a23d711
--- /dev/null
@@ -0,0 +1,6 @@
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+## COPYING RESTRICTIONS APPLY, See COPYRIGHT file
+##
+## man1 Makefile.in for OpenLDAP
+
+MANSECT=1
index 0fd09f4a9852297f4a744b9ba595af74b58b9948..22eb9a2f9d4136609959102166482972cfe52f54 100644 (file)
@@ -1,4 +1,7 @@
-.TH LDAPDELETE 1 "17 August 1999" "OpenLDAP LDVERSION"
+.TH LDAPDELETE 1 "20 April 2000" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldapdelete \- LDAP delete entry tool
 .SH SYNOPSIS
@@ -32,6 +35,18 @@ ldapdelete \- LDAP delete entry tool
 [\c
 .BI \-p \ ldapport\fR]
 [\c
+.BR \-E[E] ]
+[\c
+.BR \-I[I] ]
+[\c
+.BI \-U \ username\fR]
+[\c
+.BI \-X \ authzid\fR]
+[\c
+.BI \-Y \ mech\fR]
+[\c
+.BR \-Z[Z] ]
+[\c
 .IR dn ]...
 .SH DESCRIPTION
 .I ldapdelete
@@ -108,6 +123,54 @@ Specify an alternate TCP port where the ldap server is listening.
 .TP
 .BI \-P \ 2\fR\||\|\fI3
 Specify the LDAP protocol version to use.
+.TP
+.BI \-r
+Do a recursive delete.  If the DN specified isn't a leaf, its
+children, and all their children are deleted down the tree.  No
+verification is done, so if you add this switch, ldapdelete will
+happily delete large portions of your tree.  Use with care.
+.TP
+.B \-E[E]
+Requset the use of SASL privacy (encryption). If the server allows it, data
+sent between the client and the server will be encrypted. If the server
+requires the use of encryption and this flag is not specified, the command
+will fail. If you use
+.B \-EE\c
+, the command will fail if the server does not support encryption.
+.B \-E[E]
+implies
+.B \-I[I]
+.TP
+.B \-I[I]
+Request the use of SASL integrity checking. It protects data sent between the
+client and the server from being modified along the way, but it does not
+prevent sniffing. If the server requires the use of integrity checking and
+this flag is not specified, the command will fail.If you use
+.B \-II\c
+, the command will fail if the server does not support this function. 
+.TP
+.BI \-U \ username
+Specify the username for SASL bind. The syntax of the username depends on the
+actual SASL mechanism used.
+.TP
+.BI \-X \ authzid
+Specify the requested authorization ID for SASL bind.
+.I authzid
+must be one of the following formats:
+.B dn:\c
+.I <distinguished name>
+or
+.B u:\c
+.I <username>
+.TP
+.BI \-Y \ mech
+Specify the SASL mechanism to be used for authentication. If it's not
+specified, the program will choose the best mechanism the server knows.
+.TP
+.B \-Z[Z]
+Request the use of TLS (Transport Layer Security). If you use
+.B \-ZZ\c
+, the command will fail if TLS negotiation does not succeed for some reason.
 .SH EXAMPLE
 The following command:
 .LP
index 3da8bcd94449c046a9bbb74fb76b1b203753c0fb..25eec8031e1f7c12144c2193f920f44c8acf5410 100644 (file)
@@ -1,4 +1,7 @@
-.TH LDAPMODIFY 1 "17 August 1999" "OpenLDAP LDVERSION"
+.TH LDAPMODIFY 1 "20 April 2000" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldapmodify, ldapadd \- LDAP modify entry and LDAP add entry tools
 .SH SYNOPSIS
@@ -18,6 +21,8 @@ ldapmodify, ldapadd \- LDAP modify entry and LDAP add entry tools
 [\c
 .BR \-k ]
 [\c
+.BR \-K ]
+[\c
 .BR \-M[M] ]
 [\c
 .BI \-d \ debuglevel\fR]
@@ -34,6 +39,18 @@ ldapmodify, ldapadd \- LDAP modify entry and LDAP add entry tools
 [\c
 .BI \-P \ 2\fR\||\|\fI3\fR]
 [\c
+.BR \-E[E] ]
+[\c
+.BR \-I[I] ]
+[\c
+.BI \-U \ username\fR]
+[\c
+.BI \-X \ authzid\fR]
+[\c
+.BI \-Y \ mech\fR]
+[\c
+.BR \-Z[Z] ]
+[\c
 .BI \-f \ file\fR]
 .LP
 .B ldapadd
@@ -52,16 +69,34 @@ ldapmodify, ldapadd \- LDAP modify entry and LDAP add entry tools
 [\c
 .BR \-K ]
 [\c
+.BR \-M[M] ]
+[\c
 .BI \-d \ debuglevel\fR]
 [\c
 .BI \-D \ binddn\fR]
 [\c
+.BR \-W ]
+[\c
 .BI \-w \ passwd\fR]
 [\c
 .BI \-h \ ldaphost\fR]
 [\c
 .BI \-p \ ldapport\fR]
 [\c
+.BI \-P \ 2\fR\||\|\fI3\fR]
+[\c
+.BR \-E[E] ]
+[\c
+.BR \-I[I] ]
+[\c
+.BI \-U \ username\fR]
+[\c
+.BI \-X \ authzid\fR]
+[\c
+.BI \-Y \ mech\fR]
+[\c
+.BR \-Z[Z] ]
+[\c
 .BI \-f \ file\fR]
 .SH DESCRIPTION
 .B ldapmodify
@@ -159,6 +194,48 @@ Specify an alternate TCP port where the ldap server is listening.
 .TP
 .BI \-P \ 2\fR\||\|\fI3
 Specify the LDAP protocol version to use.
+.TP
+.B \-E[E]
+Requset the use of SASL privacy (encryption). If the server allows it, data
+sent between the client and the server will be encrypted. If the server
+requires the use of encryption and this flag is not specified, the command
+will fail. If you use
+.B \-EE\c
+, the command will fail if the server does not support encryption.
+.B \-E[E]
+implies
+.B \-I[I]
+.TP
+.B \-I[I]
+Request the use of SASL integrity checking. It protects data sent between the
+client and the server from being modified along the way, but it does not
+prevent sniffing. If the server requires the use of integrity checking and
+this flag is not specified, the command will fail.If you use
+.B \-II\c
+, the command will fail if the server does not support this function. 
+.TP
+.BI \-U \ username
+Specify the username for SASL bind. The syntax of the username depends on the
+actual SASL mechanism used.
+.TP
+.BI \-X \ authzid
+Specify the requested authorization ID for SASL bind.
+.I authzid
+must be one of the following formats:
+.B dn:\c
+.I <distinguished name>
+or
+.B u:\c
+.I <username>
+.TP
+.BI \-Y \ mech
+Specify the SASL mechanism to be used for authentication. If it's not
+specified, the program will choose the best mechanism the server knows.
+.TP
+.B \-Z[Z]
+Request the use of TLS (Transport Layer Security). If you use
+.B \-ZZ\c
+, the command will fail if TLS negotiation does not succeed for some reason.
 .SH INPUT FORMAT
 The contents of \fIfile\fP (or standard input if no \-f flag is given on
 the command line) should conform to the format defined in
index a177cf9425bf7c1794a79e049762a82343e6b12f..790731e0d424fece27b7fb5907c13368feccf565 100644 (file)
@@ -1,4 +1,7 @@
-.TH LDAPMODRDN 1 "17 August 1999" "OpenLDAP LDVERSION"
+.TH LDAPMODRDN 1 "20 April 2000" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldapmodrdn \- LDAP rename entry tool
 .SH SYNOPSIS
@@ -32,6 +35,18 @@ ldapmodrdn \- LDAP rename entry tool
 [\c
 .BI \-P \ 2\fR\||\|\fI3\fR]
 [\c
+.BR \-E[E] ]
+[\c
+.BR \-I[I] ]
+[\c
+.BI \-U \ username\fR]
+[\c
+.BI \-X \ authzid\fR]
+[\c
+.BI \-Y \ mech\fR]
+[\c
+.BR \-Z[Z] ]
+[\c
 .BI \-f \ file\fR]
 [\c
 .I dn  rdn\fR]
@@ -110,6 +125,48 @@ Specify an alternate TCP port where the ldap server is listening.
 .TP
 .BI \-P \ 2\fR\||\|\fI3
 Specify the LDAP protocol version to use.
+.TP
+.B \-E[E]
+Requset the use of SASL privacy (encryption). If the server allows it, data
+sent between the client and the server will be encrypted. If the server
+requires the use of encryption and this flag is not specified, the command
+will fail. If you use
+.B \-EE\c
+, the command will fail if the server does not support encryption.
+.B \-E[E]
+implies
+.B \-I[I]
+.TP
+.B \-I[I]
+Request the use of SASL integrity checking. It protects data sent between the
+client and the server from being modified along the way, but it does not
+prevent sniffing. If the server requires the use of integrity checking and
+this flag is not specified, the command will fail.If you use
+.B \-II\c
+, the command will fail if the server does not support this function. 
+.TP
+.BI \-U \ username
+Specify the username for SASL bind. The syntax of the username depends on the
+actual SASL mechanism used.
+.TP
+.BI \-X \ authzid
+Specify the requested authorization ID for SASL bind.
+.I authzid
+must be one of the following formats:
+.B dn:\c
+.I <distinguished name>
+or
+.B u:\c
+.I <username>
+.TP
+.BI \-Y \ mech
+Specify the SASL mechanism to be used for authentication. If it's not
+specified, the program will choose the best mechanism the server knows.
+.TP
+.B \-Z[Z]
+Request the use of TLS (Transport Layer Security). If you use
+.B \-ZZ\c
+, the command will fail if TLS negotiation does not succeed for some reason.
 .SH INPUT FORMAT
 If the command-line arguments \fIdn\fP and \fIrdn\fP are given, \fIrdn\fP
 will replace the RDN of the entry specified by the DN, \fIdn\fP.
diff --git a/doc/man/man1/ldappasswd.1 b/doc/man/man1/ldappasswd.1
new file mode 100644 (file)
index 0000000..d2b1391
--- /dev/null
@@ -0,0 +1,151 @@
+.TH LDAPPASSWD 1 "20 April 2000" "LDAPPasswd"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.SH NAME
+ldappasswd \- change the password of an LDAP entry
+.SH SYNOPSIS
+.B ldappasswd
+[\c
+.BR \-A ]
+[\c
+.BI \-a \ oldPasswd\fR]
+.BI \-D \ binddn\fR
+[\c
+.BI \-d \ debuglevel\fR]
+[\c
+.BI \-h \ ldaphost\fR]
+[\c
+.BR \-n ]
+[\c
+.BI \-p \ ldapport\fR]
+[\c
+.BR \-S ]
+[\c
+.BI \-s \ newPasswd\fR]
+[\c
+.BR \-v ]
+[\c
+.BR \-W ]
+[\c
+.BI \-w \ passwd\fR]
+[\c
+.BR \-E[E] ]
+[\c
+.BR \-I[I] ]
+[\c
+.BI \-U \ username\fR]
+[\c
+.BI \-X \ authzid\fR]
+[\c
+.BI \-Y \ mech\fR]
+[\c
+.BR \-Z[Z] ]
+.SH DESCRIPTION
+.B ldappasswd
+is a tool to set the password of an LDAP user.
+It is neither designed nor intended to be a replacement for
+.BR passwd (1)
+and should not be installed as such.
+.LP
+.B ldappasswd
+sets the password of associated with the user.  If the new
+password is not specified on the command line or the user
+doesn't enable prompting, the server will be asked to generate
+a password for the user.
+.SH OPTIONS
+.TP
+.BI \-A
+Prompt for old password.
+This is used instead of specifying the password on the command line.
+.TP
+.BI \-a \ oldPasswd
+Set the old password to \fIoldPasswd\fP.
+.TP
+.BI \-D \ binddn
+Use \fIbinddn\fP to bind to the LDAP directory. \fIbinddn\fP should
+be a string-represented DN as defined in RFC 2253.
+This flag is not optional.  The user DN will be used if the
+bind DN is not provided.
+.TP
+.BI \-d \ debuglevel
+Set the LDAP debugging level to \fIdebuglevel\fP.
+.B ldappasswd
+must be compiled with LDAP_DEBUG defined for this option to have any effect.
+.TP
+.BI \-h \ ldaphost
+Specify an alternate host on which the ldap server is running.
+.TP
+.B \-n
+Do not set password. (Can be useful when used in conjunction with
+.BR \-v \ or
+.BR \-d )
+.TP
+.BI \-S
+Prompt for new password.
+This is used instead of specifying the password on the command line.
+.TP
+.BI \-s \ newPasswd
+Set the new password to \fInewPasswd\fP.
+.TP
+.BI \-p \ ldapport
+Specify an alternate port on which the ldap server is running.
+.TP
+.B \-v
+Increase the verbosity of output.  Can be specified multiple times.
+.TP
+.BI \-W
+Prompt for bind password.
+This is used instead of specifying the password on the command line.
+.TP
+.BI \-w \ passwd
+Use \fIpasswd\fP as the password to bind with.
+.TP
+.B \-E[E]
+Requset the use of SASL privacy (encryption). If the server allows it, data
+sent between the client and the server will be encrypted. If the server
+requires the use of encryption and this flag is not specified, the command
+will fail. If you use
+.B \-EE\c
+, the command will fail if the server does not support encryption.
+.B \-E[E]
+implies
+.B \-I[I]
+.TP
+.B \-I[I]
+Request the use of SASL integrity checking. It protects data sent between the
+client and the server from being modified along the way, but it does not
+prevent sniffing. If the server requires the use of integrity checking and
+this flag is not specified, the command will fail.If you use
+.B \-II\c
+, the command will fail if the server does not support this function. 
+.TP
+.BI \-U \ username
+Specify the username for SASL bind. The syntax of the username depends on the
+actual SASL mechanism used.
+.TP
+.BI \-X \ authzid
+Specify the requested authorization ID for SASL bind.
+.I authzid
+must be one of the following formats:
+.B dn:\c
+.I <distinguished name>
+or
+.B u:\c
+.I <username>
+.TP
+.BI \-Y \ mech
+Specify the SASL mechanism to be used for authentication. If it's not
+specified, the program will choose the best mechanism the server knows.
+.TP
+.B \-Z[Z]
+Request the use of TLS (Transport Layer Security). If you use
+.B \-ZZ\c
+, the command will fail if TLS negotiation does not succeed for some reason.
+.SH SEE ALSO
+.BR ldap_bind (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.  
index 7a53977f76df5a3297914f27cbeb69072deef2a9..91be9d6d44746f134e96a3aab20716722285a577 100644 (file)
@@ -1,4 +1,7 @@
-.TH LDAPSEARCH 1 "17 August 1999" "OpenLDAP LDVERSION"
+.TH LDAPSEARCH 1 "20 April 2000" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldapsearch \- LDAP search tool
 .SH SYNOPSIS
@@ -53,6 +56,18 @@ ldapsearch \- LDAP search tool
 .BI \-l \ timelimit\fR]
 [\c
 .BI \-z \ sizelimit\fR]
+[\c
+.BR \-E[E] ]
+[\c
+.BR \-I[I] ]
+[\c
+.BI \-U \ username\fR]
+[\c
+.BI \-X \ authzid\fR]
+[\c
+.BI \-Y \ mech\fR]
+[\c
+.BR \-Z[Z] ]
 .I filter
 [\c
 .IR attrs... ]
@@ -222,6 +237,48 @@ of
 limit.
 A server may impose a maximal sizelimit which only
 the root user may override.
+.TP
+.B \-E[E]
+Requset the use of SASL privacy (encryption). If the server allows it, data
+sent between the client and the server will be encrypted. If the server
+requires the use of encryption and this flag is not specified, the command
+will fail. If you use
+.B \-EE\c
+, the command will fail if the server does not support encryption.
+.B \-E[E]
+implies
+.B \-I[I]
+.TP
+.B \-I[I]
+Request the use of SASL integrity checking. It protects data sent between the
+client and the server from being modified along the way, but it does not
+prevent sniffing. If the server requires the use of integrity checking and
+this flag is not specified, the command will fail.If you use
+.B \-II\c
+, the command will fail if the server does not support this function. 
+.TP
+.BI \-U \ username
+Specify the username for SASL bind. The syntax of the username depends on the
+actual SASL mechanism used.
+.TP
+.BI \-X \ authzid
+Specify the requested authorization ID for SASL bind.
+.I authzid
+must be one of the following formats:
+.B dn:\c
+.I <distinguished name>
+or
+.B u:\c
+.I <username>
+.TP
+.BI \-Y \ mech
+Specify the SASL mechanism to be used for authentication. If it's not
+specified, the program will choose the best mechanism the server knows.
+.TP
+.B \-Z[Z]
+Request the use of TLS (Transport Layer Security). If you use
+.B \-ZZ\c
+, the command will fail if TLS negotiation does not succeed for some reason.
 .SH OUTPUT FORMAT
 If one or more entries are found, each entry is written to standard output
 in the form:
index 43284a7f74d6177743c76e0f5b07cb85b4aa2c49..373c7a4724d8be04cb88f07210be309e7ddfacf5 100644 (file)
@@ -1,16 +1,21 @@
-.TH UD 1 "18 March 1993" "U-M LDAP LDVERSION"
+.TH UD 1 "12 September 1999" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .UC 6
 .SH NAME
-ud \- interactive X.500 Directory Server query program
+ud \- interactive LDAP Directory Server query program
 .SH SYNOPSIS
 .B ud
-[-Dv] [-s 
+[\c
+.BR -Dv ]
+.RB [ -s 
 .IR server ]
-[-d
+.RB [ -d
 .IR debug-mask ]
-[-l
+.RB [ -l
 .IR ldap-debug-mask ]
-[-f
+.RB [ -f
 .IR file ]
 .SH DESCRIPTION
 .IR ud
@@ -18,7 +23,7 @@ is used to interogate a directory server via the Lightweight Directory
 Access Protocol (LDAP).
 .SH OPTIONS
 .TP 1i
-.B \-s
+.BI \-s \ server
 Used to specify the name of an LDAP server to which
 .B ud
 should connect.  If this
@@ -34,7 +39,7 @@ the name
 can be resolved (presumably through the use of a CNAME or A record in the DNS
 and the appropriate search path specified in the resolver config file).
 .TP 1i
-.B \-d
+.BI \-d \ debug-mask
 Sets the
 .B ud
 debug mask to the value specified.  
@@ -42,10 +47,10 @@ Values for the mask can be dumped by using the
 .IR \-D
 flag.
 .TP 1i
-.B \-f
+.BI \-f \ file
 Sets the configuration file to the name specified.
 .TP 1i
-.B \-l
+.BI \-l \ ldap-debug-mask
 Sets the LDAP debug mask to the value specified.  
 .TP 1i
 .B \-v
@@ -59,6 +64,7 @@ Prints out a list of valid ud debug masks.
 ETCDIR/ud.conf         The ud configuration file.
 .SH "SEE ALSO"
 .BR ud.conf (5),
+.BR ldap.conf (5),
 .BR ldap (3)
 .SH DIAGNOSTICS
 .B ud
@@ -71,3 +77,8 @@ uses the ldap_perror() routine to print an informative diagnostic.
 Too numerous to mention.
 .SH AUTHOR
 Bryan Beecher, University of Michigan
+.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.  
diff --git a/doc/man/man3/Makefile.in b/doc/man/man3/Makefile.in
new file mode 100644 (file)
index 0000000..b1ec689
--- /dev/null
@@ -0,0 +1,6 @@
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+## COPYING RESTRICTIONS APPLY, See COPYRIGHT file
+##
+## man3 Makefile.in for OpenLDAP
+
+MANSECT=3
index 7896ba0923e248cac99183ddc2c673930f204551..9e1e9d07e334628f1dda33442c3a0975ea5e26cf 100644 (file)
@@ -1,10 +1,12 @@
-.TH CLDAP_CLOSE 3  "18 November 1994" "U-M LDAP LDVERSION"
+.TH CLDAP_CLOSE 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 cldap_close \- Dispose of Connectionless LDAP Pointer
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
@@ -28,3 +30,8 @@ returned by a previous call to
 .BR cldap_open (3),
 .BR cldap_search_s (3),
 .BR cldap_setretryinfo (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.  
index 738bda2324fbebc97e6e3bc1e1648817d0f86d31..735800110ac964ab5b92ce5740a0affaa48f012a 100644 (file)
@@ -1,10 +1,12 @@
-.TH CLDAP_OPEN 3  "18 November 1994" "U-M LDAP LDVERSION"
+.TH CLDAP_OPEN 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 cldap_open \- Prepare for Connectionless LDAP Communication
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
@@ -51,3 +53,8 @@ will return NULL and errno will be set appropriately.
 .BR cldap_setretryinfo (3),
 .BR cldap_close (3),
 .BR udp (4p)
+.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.  
index 1c4da546f9fc0f47bd1e66ce3df9762474bed5c7..826144f26e355e665c09221bd75ff8c2f69c081e 100644 (file)
@@ -1,10 +1,12 @@
-.TH CLDAP_SEARCH_S 3  "18 November 1994" "U-M LDAP LDVERSION"
+.TH CLDAP_SEARCH_S 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 cldap_search_s \- Connectionless LDAP Search
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
@@ -103,3 +105,8 @@ for more information.
 .BR cldap_setretryinfo (3),
 .BR cldap_close (3),
 .BR udp (4p)
+.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.  
index 55ef67159d102d12f92ccefeefadbe7ae32a7535..37f6d3932c519361199b0c32ec2dc6bacdf89966 100644 (file)
@@ -1,10 +1,12 @@
-.TH CLDAP_SETRETRYINFO 3  "18 November 1994" "U-M LDAP LDVERSION"
+.TH CLDAP_SETRETRYINFO 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 cldap_setretryinfo \- Set Connectionless LDAP Request Retransmission Parameters
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
@@ -40,3 +42,8 @@ algorithm used.
 .BR cldap_open (3),
 .BR cldap_search_s (3),
 .BR cldap_close (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.  
index e05fb33c4b70ce9c9264d5aa6e5ef875027068d0..70b260f2a33f3a0d8f082c1e598901c465abc25d 100644 (file)
@@ -1,6 +1,9 @@
-.TH LBER-DECODE 3  "18 November 1994"
+.TH LBER_DECODE 3 "12 May 2000" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ber_get_next, ber_skiptag, ber_peek_tag, ber_scanf, ber_get_int, ber_get_stringb, ber_get_stringa, 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_null, ber_get_boolean, ber_get_bitstring, ber_first_element, ber_next_element \- LBER simplified Basic Encoding Rules library routines for decoding
 .SH SYNOPSIS
 .nf
 .ft B
@@ -10,154 +13,117 @@ ber_get_next, ber_skiptag, ber_peek_tag, ber_scanf, ber_get_int, ber_get_stringb
 .LP
 .nf
 .ft B
-typedef struct berelement {
-    char *ber_buf;
-    char *ber_ptr;
-    char *ber_end;
-    struct seqorset *ber_sos;
-    int ber_tag;
-    int ber_usertag;
-} BerElement;
+ber_tag_t ber_get_next(
+       Sockbuf *sb,
+       ber_len_t \(**len,
+       BerElement \(**ber);
 .ft
 .fi
 .LP
 .nf
 .ft B
-typedef struct sockbuf {
-    int sb_sd;
-    BerElement sb_ber;
-} Sockbuf;
+ber_tag_t ber_skip_tag(
+       BerElement \(**ber,
+       ber_len_t long \(**len);
 .ft
 .fi
 .LP
 .nf
 .ft B
-typedef struct berval {
-    unsigned long bv_len;
-    char *bv_val;
-};
+ber_tag_t ber_peek_tag(
+       BerElement \(**ber,
+       ber_len_t \(**len);
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_get_next(sb, len, ber)
-Sockbuf *sb;
-unsigned long \(**len;
-BerElement \(**ber;
+ber_tag_t ber_scanf(
+       BerElement \(**ber,
+       const char \(**fmt, ...);
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_skip_tag(ber, len)
-BerElement \(**ber;
-unsigned long \(**len;
+ber_tag_t ber_get_int(
+       BerElement \(**ber,
+       ber_int_t \(**num);
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_peek_tag(ber, len)
-BerElement \(**ber;
-unsigned long \(**len;
+ber_tag_t ber_get_enum(
+       BerElement \(**ber,
+       ber_int_t \(**num);
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_get_int(ber, num)
-BerElement \(**ber;
-long \(**num;
+ber_tag_t ber_get_stringb(
+       BerElement \(**ber,
+       char \(**buf,
+       ber_len_t \(**len);
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_get_stringb(ber, buf, len)
-BerElement \(**ber;
-char \(**buf;
-unsigned long \(**len;
+ber_tag_t ber_get_stringa(
+       BerElement \(**ber,
+       char \(***buf);
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_get_stringa(ber, buf)
-BerElement \(**ber;
-char \(***buf;
+ber_tag_t ber_get_stringal(
+       BerElement \(**ber,
+       struct berval \(***bv);
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_get_stringal(ber, bv)
-BerElement \(**ber;
-struct berval \(***bv;
+ber_tag_t ber_get_null(
+       BerElement \(**ber );
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_get_null(ber)
-BerElement \(**ber;
+ber_tag_t ber_get_boolean(
+       BerElement \(**ber,
+       ber_int_t \(**bool);
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_get_boolean(ber, bool)
-BerElement \(**ber;
-int \(**bool;
+ber_tag_t ber_get_bitstringa(
+       BerElement \(**ber,
+       char \(***buf,
+       ber_len_t \(**blen);
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_get_bitstringa(ber, buf, blen)
-BerElement \(**ber;
-char \(***buf;
-unsigned long \(**blen;
+ber_tag_t ber_first_element(
+       BerElement \(**ber,
+       ber_len_t \(**len,
+       char \(***cookie);
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_first_element(ber, len, cookie)
-BerElement \(**ber;
-unsigned long \(**len;
-char \(***cookie;
-.ft
-.fi
-.LP
-.nf
-.ft B
-ber_next_element(ber, len, cookie)
-BerElement \(**ber;
-unsigned long \(**len;
-char \(**cookie;
-.ft
-.fi
-.LP
-.nf
-.ft B
-ber_scanf(ber, fmt [, arg...] )
-BerElement \(**ber;
-char \(**fmt;
-.ft
-.fi
-.LP
-.nf
-.ft B
-ber_bvfree(bv)
-struct berval \(**bv;
-.ft
-.fi
-.LP
-.nf
-.ft B
-ber_bvecfree(bvec)
-struct berval \(***bvec;
+ber_tag_t ber_next_element(
+       BerElement \(**ber,
+       ber_len_t \(**len,
+       const char \(**cookie);
 .SH DESCRIPTION
 .LP
 These routines provide a subroutine interface to a simplified
@@ -172,6 +138,7 @@ in the descriptions below, it refers to the tag, class, and primitive
 or constructed bit in the first octet of the encoding.  This man page
 describes the decoding routines in the lber library.  See lber-encode(3)
 for details on the corresponding encoding routines.
+Consult lber-types(3) for information about types, allocators, and deallocators.
 .LP
 Normally, the only routines that need be called by an application
 are ber_get_next() to get the next BER element and ber_scanf()
@@ -207,27 +174,38 @@ characters.
 Octet string.  A char ** should be supplied.  Memory is allocated,
 filled with the contents of the octet string, null-terminated, and
 returned in the parameter.
+The caller should free the returned ber_val using ber_memfree().
 .TP
 .SM s
 Octet string.  A char * buffer should be supplied, followed by a pointer
-to an integer initialized to the size of the buffer.  Upon return, the
+to a ber_len_t initialized to the size of the buffer.  Upon return, the
 null-terminated octet string is put into the buffer, and the integer is
 set to the actual size of the octet string.
 .TP
 .SM O
 Octet string.  A struct ber_val ** should be supplied, which upon return
-points to a malloced struct berval containing the octet string and its
-length.  ber_bvfree() can be called to free the malloced memory.
+points to a dynamically allocated struct berval containing the octet string
+and its length.
+The caller should free the returned structure using ber_bvfree().
+.TP
+.SM o
+Octet string.  A struct ber_val * should be supplied, which upon return
+points containing the dynamically allocated octet string and its length.
+The caller should free the returned octet string using ber_memfree().
 .TP
 .SM b
-Boolean.  A pointer to an integer should be supplied.
+Boolean.  A pointer to a ber_int_t should be supplied.
+.TP
+.SM e
+Enumeration.  A pointer to a ber_int_t should be supplied.
 .TP
 .SM i
-Integer.  A pointer to an integer should be supplied.
+Integer.  A pointer to a ber_int_t should be supplied.
 .TP
 .SM B
-Bitstring.  A char ** should be supplied which will point to the malloced
-bits, followed by an unsigned long *, which will point to the length
+Bitstring.  A char ** should be supplied which will point to the
+dynamically allocated
+bits, followed by an ber_len_t *, which will point to the length
 (in bits) of the bitstring returned.
 .TP
 .SM n
@@ -236,16 +214,28 @@ it is recognized.
 .TP
 .SM v
 Sequence of octet strings.  A char *** should be supplied, which upon
-return points to a malloced null-terminated array of char *'s
+return points to a dynamically allocated null-terminated array of char *'s
 containing the octet strings.  NULL is returned if the sequence is empty.
+The caller should free the returned array and octet strings using
+ber_memvfree().
 .TP
 .SM V
 Sequence of octet strings with lengths.
 A struct berval *** should be supplied, which upon
-return points to a malloced null-terminated array of struct berval *'s
+return points to a dynamically allocated null-terminated array of
+struct berval *'s
 containing the octet strings and their lengths.
-NULL is returned if the sequence is empty.  ber_bvecfree() can be called
-to free the malloced memory.
+NULL is returned if the sequence is empty.  
+The caller should free the returned structures using ber_bvecfree().
+.TP
+.SM l
+Length of the next element.  A pointer to a ber_len_t should be supplied.
+.TP
+.SM t
+Tag of the next element.  A pointer to a ber_tag_t should be supplied.
+.TP
+.SM T
+Skip element and return its tag.  A pointer to a ber_tag_t should be supplied.
 .TP
 .SM x
 Skip element.  The next element is skipped.
@@ -267,7 +257,7 @@ End set.  No parameter is required and no action is taken.
 .LP
 The ber_get_int() routine tries to interpret the next element as an integer,
 returning the result in \fInum\fP.  The tag of whatever it finds is returned
-on success, -1 on failure.
+on success, LBER_ERROR (\-1) on failure.
 .LP
 The ber_get_stringb() routine is used to read an octet string into a
 preallocated buffer.  The \fIlen\fP parameter should be initialized to
@@ -275,23 +265,28 @@ the size of the buffer, and will contain the length of the octet string
 read upon return.  The buffer should be big enough to take the octet
 string value plus a terminating NULL byte.
 .LP
-The ber_get_stringa() routine is used to malloc space into which an octet
-string is read.
+The ber_get_stringa() routine is used to dynamically allocate space into
+which an octet string is read.
+The caller should free the returned string using ber_memfree().
 .LP
-The ber_get_stringal() routine is used to malloc space into which an octet
-string and its length are read.  It takes a struct berval **, and returns
-the result in this parameter.
+The ber_get_stringal() routine is used to dynamically allocate space
+into which an octet string and its length are read.  It takes a
+struct berval **, and returns the result in this parameter.
+The caller should free the returned structure using ber_bvfree().
 .LP
 The ber_get_null() routine is used to read a NULL element.  It returns
 the tag of the element it skips over.
 .LP
-The ber_get_boolean() routine is used to read a boolean value.  It is called
-the same way that ber_get_int() is called.
+The ber_get_boolean() routine is used to read a boolean value.
+It is called the same way that ber_get_int() is called.
+.LP
+The ber_get_enum() routine is used to read a enumeration value.
+It is called the same way that ber_get_int() is called.
 .LP
 The ber_get_bitstringa() routine is used to read a bitstring value.  It
-takes a char ** which will hold the malloced bits, followed by an
-unsigned long *, which will point to the length (in bits) of the
-bitstring returned.
+takes a char ** which will hold the dynamically allocated bits, followed by an
+ber_len_t *, which will point to the length (in bits) of the bitstring returned.
+The caller should free the returned string using ber_memfree().
 .LP
 The ber_first_element() routine is used to return the tag and length
 of the first element in a set or sequence.  It also returns in \fIcookie\fP
@@ -325,30 +320,42 @@ the following ASN.1 object:
 The element can be decoded using ber_scanf() as follows.
 .LP
 .nf
-      int    scope, ali, size, time, attrsonly;
+      ber_int_t    scope, deref, size, time, attrsonly;
       char   *dn, **attrs;
+      ber_tag_t tag;
 
-      if ( ber_scanf( ber, "{aiiiib{v}}", &dn, &scope, &ali,
-          &size, &time, &attrsonly, &attrs ) == -1 )
+      tag = ber_scanf( ber, "{aeeiib{v}}",
+          &dn, &scope, &deref,
+          &size, &time, &attrsonly, &attrs );
+
+      if( tag == LBER_ERROR ) {
               /* error */
-      else
+      } else {
               /* success */
+      }
+
+      ber_memfree( dn );
+      ber_memvfree( attrs );
 .fi
 .SH ERRORS
-If an error occurs during decoding, generally these routines return -1.
+If an error occurs during decoding, generally these routines return
+LBER_ERROR (\-1).
 .LP
 .SH NOTES
 .LP
 The return values for all of these functions are declared in the
-<lber.h> header file.  Some routines may malloc memory.
+<lber.h> header file.
+Some routines may dynamically allocate memory
+which must be freed by the caller using supplied deallocation routines.
 .SH SEE ALSO
 .BR lber-encode (3)
+.BR lber-types (3)
 .BR ldap-parse (3)
 .BR ldap-sync (3)
 .BR ldap-async (3)
 .LP
-Yeong, W., Howes, T., and Hardcastle-Kille, S., "Lightweight Directory Access
-Protocol", OSI-DS-26, April 1992.
+Yeong, W., Howes, T., and Hardcastle-Kille, S.,
+"Lightweight Directory Access Protocol", OSI-DS-26, April 1992.
 .LP
 Information Processing - Open Systems Interconnection - Model and Notation -
 Service Definition - Specification of Basic Encoding Rules for Abstract
@@ -356,3 +363,8 @@ Syntax Notation One, International Organization for Standardization,
 International Standard 8825.
 .SH AUTHOR
 Tim Howes, University of Michigan
+.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.  
diff --git a/doc/man/man3/lber-decode.3.links b/doc/man/man3/lber-decode.3.links
new file mode 100644 (file)
index 0000000..3ec9328
--- /dev/null
@@ -0,0 +1,13 @@
+ber_get_next.3
+ber_skip_tag.3
+ber_peek_tag.3
+ber_scanf.3
+ber_get_int.3
+ber_get_stringa.3
+ber_get_stringb.3
+ber_get_null.3
+ber_get_enum.3
+ber_get_boolean.3
+ber_get_bitstring.3
+ber_first_element.3
+ber_next_element.3
index 01304810b7c6e54c1247f863f879506a8509fee4..9d5fbb980dc7b3179383570e369ab9c49faad3d7 100644 (file)
@@ -1,6 +1,9 @@
-.TH LBER-ENCODE 3  "15 June 1992"
+.TH LBER_ENCODE 3 "12 May 2000" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ber_alloc, ber_flush, ber_printf, ber_put_int, 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_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
 .SH SYNOPSIS
 .nf
 .ft B
@@ -10,131 +13,118 @@ ber_alloc, ber_flush, ber_printf, ber_put_int, ber_put_ostring, ber_put_string,
 .LP
 .nf
 .ft B
-typedef struct berelement {
-    char *ber_buf;
-    char *ber_ptr;
-    char *ber_end;
-    struct seqorset *ber_sos;
-    int ber_tag;
-    int ber_usertag;
-} BerElement;
+BerElement *ber_alloc_t( int options );
 .ft
 .fi
 .LP
 .nf
 .ft B
-typedef struct sockbuf {
-    int sb_sd;
-    BerElement sb_ber;
-} Sockbuf;
+int ber_flush(
+       Sockbuf *sb,
+       BerElement *ber,
+       int freeit);
 .ft
 .fi
 .LP
 .nf
 .ft B
-BerElement *ber_alloc()
+int ber_printf(
+       BerElement *ber,
+       const char \(**fmt, ...);
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_flush(sb, ber, freeit)
-Sockbuf *sb;
-BerElement *ber;
-int freeit;
+int ber_put_int(
+       BerElement *ber,
+       ber_int_t num,
+       ber_tag_t tag);
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_printf(ber, fmt [, arg... ] )
-BerElement *ber;
-char \(**fmt;
+int ber_put_enum(
+       BerElement *ber,
+       ber_int_t num,
+       ber_tag_t tag);
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_put_int(ber, num, tag)
-BerElement *ber;
-long num;
-char tag;
+int ber_put_ostring(
+       BerElement *ber,
+       const char \(**str,
+       ber_len_t long len,
+       ber_tag_t tag);
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_put_ostring(ber, str, len, tag)
-BerElement *ber;
-char \(**str;
-unsigned long len;
-char tag;
+int ber_put_string(
+       BerElement *ber,
+       const char \(**str,
+       ber_tag_t tag);
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_put_string(ber, str, tag)
-BerElement *ber;
-char \(**str;
-char tag;
+int ber_put_null(
+       BerElement *ber;
+       ber_tag_t tag);
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_put_null(ber, tag)
-BerElement *ber;
-char tag;
+int ber_put_boolean(
+       BerElement *ber;
+       ber_int_t bool;
+       ber_tag_t tag;
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_put_boolean(ber, bool, tag)
-BerElement *ber;
-int bool;
-char tag;
+int ber_put_bitstring(
+       BerElement *ber,
+       const char *str,
+       ber_len_t blen,
+       ber_tag_t tag);
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_put_bitstring(ber, str, blen, tag)
-BerElement *ber;
-char *str;
-int blen;
-char tag;
+int ber_start_seq(
+       BerElement *ber,
+       ber_tag_t tag);
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_start_seq(ber, tag)
-BerElement *ber;
-char tag;
+int ber_start_set(
+       BerElement *ber,
+       ber_tag_t tag);
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_start_set(ber, tag)
-BerElement *ber;
-char tag;
+int ber_put_seq(
+       BerElement *ber);
 .ft
 .fi
 .LP
 .nf
 .ft B
-ber_put_seq(ber)
-BerElement *ber;
-.ft
-.fi
-.LP
-.nf
-.ft B
-ber_put_set(ber)
-BerElement *ber;
+int ber_put_set(
+       BerElement *ber);
 .SH DESCRIPTION
 .LP
 These routines provide a subroutine interface to a simplified
@@ -149,16 +139,18 @@ in the descriptions below, it refers to the tag, class, and primitive
 or constructed bit in the first octet of the encoding.  This
 man page describes the encoding routines in the lber library.  See
 lber-decode(3) for details on the corresponding decoding routines.
+Consult lber-types(3) for information about types, allocators, and deallocators.
 .LP
 Normally, the only routines that need be called by an application
-are ber_alloc() to allocate a BER element for encoding, ber_printf()
+are ber_alloc_t() to allocate a BER element for encoding, ber_printf()
 to do the actual encoding, and ber_flush() to actually write the
 element.  The other routines are provided for those
 applications that need more control than ber_printf() provides.  In
 general, these routines return the length of the element encoded, or
 -1 if an error occurred.
 .LP
-The ber_alloc() routine is used to allocate a new BER element.  The
+The ber_alloc_t() routine is used to allocate a new BER element.  It
+should be called with an argument of LBER_USE_DER.  The
 ber_flush() routine is used to actually write the element to a socket
 (or file) descriptor, once it has been fully encoded (using ber_printf()
 and friends).  The \fIsb\fP structure contains the descriptor and a
@@ -177,11 +169,15 @@ The format string can contain the following characters:
 .LP
 .TP 3
 .SM b
-Boolean.  An integer parameter should be supplied.  A boolean element
+Boolean.  An ber_int_t parameter should be supplied.  A boolean element
 is output.
 .TP
+.SM e
+Enumeration.  An ber_int_t parameter should be supplied.  An
+enumeration element is output.
+.TP
 .SM i
-Integer.  An integer parameter should be supplied.  An integer element
+Integer.  An ber_int_t parameter should be supplied.  An integer element
 is output.
 .TP
 .SM B
@@ -196,19 +192,28 @@ Null.  No parameter is required.  A null element is output.
 Octet string.  A char * is supplied, followed by the length of the
 string pointed to.  An octet string element is output.
 .TP
+.SM O
+Octet string.  A struct berval * is supplied.
+An octet string element is output.
+.TP
 .SM s
 Octet string.  A null-terminated string is supplied.  An octet string
 element is output, not including the trailing NULL octet.
 .TP
 .SM t
-Tag.  An int specifying the tag to give the next element is provided.
-This works across calls.
+Tag.  A ber_tag_t specifying the tag to give the next element
+is provided.  This works across calls.
 .TP
 .SM v
 Several octet strings.  A null-terminated array of char *'s is
 supplied.  Note that a construct like '{v}' is required to get
 an actual SEQUENCE OF octet strings.
 .TP
+.SM V
+Several octet strings.  A null-terminated array of struct berval *'s
+is supplied.  Note that a construct like '{V}' is required to get
+an actual SEQUENCE OF octet strings.
+.TP
 .SM {
 Begin sequence.  No parameter is required.
 .TP
@@ -225,6 +230,9 @@ End set.  No parameter is required.
 The ber_put_int() routine writes the integer element \fInum\fP to
 the BER element \fIber\fP.
 .LP
+The ber_put_enum() routine writes the enumberation element
+\fInum\fP to the BER element \fIber\fP.
+.LP
 The ber_put_boolean() routine writes the boolean value given by
 \fIbool\fP to the BER element.
 .LP
@@ -278,18 +286,27 @@ the following ASN.1 object:
 can be achieved like so:
 .LP
 .nf
-      int    scope, ali, size, time, attrsonly;
+      int rc;
+      ber_int_t    scope, ali, size, time, attrsonly;
       char   *dn, **attrs;
+      BerElement *ber;
 
       /* ... fill in values ... */
-      if ( (ber = ber_alloc()) == NULLBER )
+
+      ber = ber_alloc_t( LBER_USE_DER );
+
+      if ( ber == NULL ) {
                /* error */
+      }
 
-      if ( ber_printf( ber, "{siiiib{v}}", dn, scope, ali,
-          size, time, attrsonly, attrs ) == -1 )
+      rc = ber_printf( ber, "{siiiib{v}}", dn, scope, ali,
+          size, time, attrsonly, attrs );
+
+      if( rc == -1 ) {
               /* error */
-      else
+      } else {
               /* success */
+      }
 .fi
 .SH ERRORS
 If an error occurs during encoding, generally these routines return -1.
@@ -299,13 +316,14 @@ If an error occurs during encoding, generally these routines return -1.
 The return values for all of these functions are declared in the
 <lber.h> header file.
 .SH SEE ALSO
+.BR lber-decode (3)
+.BR lber-types (3)
 .BR ldap-async (3)
 .BR ldap-sync (3)
 .BR ldap-parse (3)
-.BR lber-decode (3)
 .LP
-Yeong, W., Howes, T., and Hardcastle-Kille, S., "Lightweight Directory Access
-Protocol", OSI-DS-26, April 1992.
+Yeong, W., Howes, T., and Hardcastle-Kille, S.,
+"Lightweight Directory Access Protocol", OSI-DS-26, April 1992.
 .LP
 Information Processing - Open Systems Interconnection - Model and Notation -
 Service Definition - Specification of Basic Encoding Rules for Abstract
@@ -313,3 +331,8 @@ Syntax Notation One, International Organization for Standardization,
 International Standard 8825.
 .SH AUTHOR
 Tim Howes, University of Michigan
+.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.  
diff --git a/doc/man/man3/lber-encode.3.links b/doc/man/man3/lber-encode.3.links
new file mode 100644 (file)
index 0000000..54cd0e9
--- /dev/null
@@ -0,0 +1,11 @@
+ber_alloc_t.3
+ber_flush.3
+ber_printf.3
+ber_put_int.3
+ber_put_ostring.3
+ber_put_string.3
+ber_put_null.3
+ber_put_enum.3
+ber_start_set.3
+ber_put_seq.3
+ber_put_set.3
index 8f2c20e9e0bdac534a38f2b38e847a9d63165d6a..ca7ee336272afd74cdcaa7fac72e0770eb71f7a2 100644 (file)
@@ -1,10 +1,12 @@
-.TH LDAP 3  "13 November 1995" "U-M LDAP LDVERSION"
+.TH LDAP 3 "13 May 2000" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap - Lightweight Directory Access Protocol package
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .ft
 .fi
@@ -12,10 +14,8 @@ ldap - Lightweight Directory Access Protocol package
 .LP
 The Lightweight Directory Access Protocol provides TCP/IP access to
 the X.500 Directory or to a stand-alone LDAP server.
-The University of Michigan LDAP package includes a stand-alone server in
+The OpenLDAP LDAP package includes a stand-alone server in
 .BR slapd (8),
-an LDAP to X.500 gateway in
-.BR ldapd (8),
 various LDAP clients, and an LDAP client library used to provide
 programmatic access to the LDAP protocol. This man page gives an
 overview of the LDAP library routines.
@@ -192,10 +192,7 @@ equivalent to
 .BR ldap_unbind (3)
 .TP
 .SM ldap_memfree (3)
-dispose of memory allocated by LDAP routines (this is only used on the
-Microsoft Windows platforms; use
-.BR free (3)
-on all other platforms).
+dispose of memory allocated by LDAP routines.
 .TP
 .SM ldap_enable_cache(3)
 enable LDAP client caching
@@ -326,6 +323,9 @@ extract the DN from an entry
 .SM ldap_explode_dn(3)
 convert a DN into its component parts
 .TP
+.SM ldap_explode_rdn(3)
+convert a RDN into its component parts
+.TP
 .SM ldap_explode_dns(3)
 convert a DNS-style DN into its component parts (experimental)
 .TP
@@ -398,6 +398,12 @@ depreciated - use ldap_modrdn2_s(3)
 .SM ldap_msgfree(3)
 free results allocated by ldap_result(3)
 .TP
+.SM ldap_msgtype(3)
+return the message type of a message from ldap_result(3)
+.TP
+.SM ldap_msgid(3)
+return the message id of a message from ldap_result(3)
+.TP
 .SM ldap_search(3)
 asynchronously search the directory
 .TP
@@ -494,8 +500,12 @@ set retry and timeout information using connectionless LDAP
 .SM cldap_close(3)
 terminate a connectionless LDAP session
 .SH SEE ALSO
-.BR ldapd (8),
 .BR slapd (8)
 .SH AUTHORS
 Tim Howes, Mark Smith, Gordon Good, Lance Sloan, and Steve Rothwell from
 the University of Michigan, along with help from lots of others.
+.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.  
index 770513cb3d99732438f065e8c16a6a39c36201b0..6aff579d5f0b9c427d59db03b5317f8bcee09478 100644 (file)
@@ -1,10 +1,12 @@
-.TH LDAP_ABANDON 3  "1 December 1994" "U-M LDAP LDVERSION"
+.TH LDAP_ABANDON 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap_abandon \- Abandon an LDAP operation in progress
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
@@ -40,3 +42,8 @@ for details.
 .BR ldap(3),
 .BR ldap_result(3),
 .B 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.  
index 85290ad94eac0d8a676e31fa1e8bfab9acffa65b..12482ab5765f944a3f687a0dbcd1097e0b795966 100644 (file)
@@ -1,10 +1,12 @@
-.TH LDAP_ADD 3  "15 November 1994" "U-M LDAP LDVERSION"
+.TH LDAP_ADD 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap_add, ldap_add_s \- Perform an LDAP add operation
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
@@ -58,3 +60,8 @@ directly (LDAP_SUCCESS if everything went ok, some error otherwise).
 .SH SEE ALSO
 .BR ldap(3),
 .B 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.  
index c172b28c3ac3911e882ea4fe8221b0b9e2e5b746..4eb5d8210166ac28432bf855d4f3637bdc7d8a26 100644 (file)
@@ -1,10 +1,12 @@
-.TH LDAP_BIND 3  "28 March 1996" "U-M LDAP LDVERSION"
+.TH LDAP_BIND 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 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_kerberos_bind_s, ldap_kerberos_bind1, ldap_kerberos_bind1_s, ldap_kerberos_bind2, ldap_kerberos_bind2_s, ldap_unbind, ldap_unbind_s, ldap_set_rebind_proc \- LDAP bind routines
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
@@ -194,3 +196,8 @@ for more information.
 .BR ldap(3),
 .BR ldap_error(3),
 .BR ldap_open(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.  
index fbc8b0fcb0186ec6e022e0ac4beb0ced5a6bcb51..db7e9f22e2603be3034cbf299781c9d074aff02b 100644 (file)
@@ -1,10 +1,12 @@
-.TH LDAP_CACHE 3  "14 November 1994" "U-M LDAP LDVERSION"
+.TH LDAP_CACHE 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap_enable_cache, ldap_disable_cache, ldap_destroy_cache, ldap_flush_cache, ldap_uncache_entry, ldap_uncache_request, ldap_set_cache_options \- LDAP client caching routines
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .ft
 .LP
@@ -115,3 +117,8 @@ void and return nothing.
 .BR ldap_search (3),
 .BR ldap_compare (3),
 .BR cldap_search_s (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.  
index c926b07e6a8a5e1e0d4f3537adf3c7ea731c8163..37c9eeab838c8b39adcae0501b96d9ca32546738 100644 (file)
@@ -1,4 +1,7 @@
-.TH LDAP_CHARSET 3  "28 March 1996" "U-M LDAP LDVERSION"
+.TH LDAP_CHARSET 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap_set_string_translators,
 ldap_t61_to_8859,
@@ -9,7 +12,6 @@ ldap_enable_translation \- LDAP character set translation routines
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .ft
 .LP
@@ -95,7 +97,7 @@ to be translated and \fI*lenp\fP should contain the number of bytes to
 translate.  If \fIfree_input\fP is non-zero, the input buffer will be
 freed if translation is a success.  If the translation is a success,
 LDAP_SUCCESS will be returned, \fI*bufp\fP will point to a newly
-malloc'd buffer that contains the translated characters, and
+dynamically allocated buffer that contains the translated characters, and
 \fI*lenp\fP will contain the length of the result.  If translation
 fails, an LDAP error code will be returned.
 
@@ -125,3 +127,8 @@ For example, you would not want to translate a binary attributes such as
 jpegPhoto.
 .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.  
index 3df8ca9c6b8340adb41fadd08334b21aa10cd593..1051c68503f15a3f4242c5bd47388fae49a197a7 100644 (file)
@@ -1,10 +1,12 @@
-.TH LDAP_COMPARE 3  "15 November 1994" "U-M LDAP LDVERSION"
+.TH LDAP_COMPARE 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap_compare, ldap_compare_s \- Perform an LDAP compare operation
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
@@ -49,3 +51,8 @@ There is no way to compare binary values, but there should be.
 .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.  
index 3149890d84bb1cf9f0a1ab8bba15626745606889..cff482e13c89038cb33455320bac1716ca470b36 100644 (file)
@@ -1,10 +1,12 @@
-.TH LDAP_DELETE 3  "15 November 1994" "U-M LDAP LDVERSION"
+.TH LDAP_DELETE 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap_delete, ldap_delete_s \- Perform an LDAP delete operation
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
@@ -46,3 +48,8 @@ non-negative message id of the request if things went ok.
 .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.  
index 03c1e656ecc374f5a7e255d0e67987921c49b8ec..b04488245158901b21de9476c591fcc8dd3ffeeb 100644 (file)
@@ -1,4 +1,7 @@
-.TH LDAP_DISPTMPL 3  "13 December 1994" "U-M LDAP LDVERSION"
+.TH LDAP_DISPTMPL 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap_init_templates, ldap_init_templates_buf, ldap_free_templates, ldap_first_disptmpl, ldap_next_disptmpl, ldap_oc2template, ldap_tmplattrs, ldap_first_tmplrow, ldap_next_tmplrow, ldap_first_tmplcol, ldap_next_tmplcol, \- LDAP display template routines
 .SH SYNOPSIS
@@ -448,3 +451,8 @@ upon error.
 .BR ldap (3),
 .BR ldap_entry2text (3),
 .BR ldaptemplates.conf (5)
+.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.  
index 54454253a1f06e8f1125fa523e95637e034edae9..263eb9a65bf80565c241eb003b9772e4f14c97d9 100644 (file)
@@ -1,10 +1,12 @@
-.TH LDAP_ENTRY2TEXT 3  "13 November 1994" "U-M LDAP %LDVERSION%"
+.TH LDAP_ENTRY2TEXT 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap_entry2text, ldap_entry2text_search, ldap_vals2text \- LDAP entry display routines
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 #include <disptmpl.h>
 .ft
@@ -324,3 +326,8 @@ ETCDIR/ldaptemplates.conf
 .BR ldap (3),
 .BR ldap_disptmpl (3),
 .BR ldaptemplates.conf (5)
+.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.  
index c517b7e6e327ad41e7ca4e97a29cef4b4895d446..cc77bbb2fce17ea8b8c051d5ab8b02ccf751bca2 100644 (file)
@@ -1,10 +1,12 @@
-.TH LDAP_ERROR 3  "15 November 1994" "U-M LDAP LDVERSION"
+.TH LDAP_ERROR 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap_perror, ld_errno, ldap_result2error, ldap_errlist, ldap_err2string \- LDAP protocol error handling routines
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
@@ -189,7 +191,7 @@ An unknown error occurred.
 The LDAP library can't contact the LDAP server.
 .TP
 .SM LDAP_LOCAL_ERROR
-Some local error occurred.  This is usually a failed malloc.
+Some local error occurred.  This is usually a failed dynamic memory allocation.
 .TP
 .SM LDAP_ENCODING_ERROR
 An error was encountered encoding parameters to send to the LDAP server.
@@ -212,8 +214,14 @@ An ldap routine was called with a bad parameter (e.g., a NULL ld
 pointer, etc.).
 .TP
 .SM LDAP_NO_MEMORY
-An memory allocation (e.g., malloc(3)) call failed in an ldap
+An memory allocation (e.g., malloc(3) or other dynamic memory
+allocator) call failed in an ldap
 library routine.
 .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.  
index 452a928bf19800cab8df000c14150812691ad8ba..52716a6ca7608c4158fd95f94d98e8c7d173f384 100644 (file)
@@ -1,10 +1,12 @@
-.TH LDAP_FIRST_ATTRIBUTE 3  "25 November 1994" "U-M LDAP LDVERSION"
+.TH LDAP_FIRST_ATTRIBUTE 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap_first_attribute, ldap_next_attribute \- step through LDAP entry attributes
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
@@ -43,15 +45,9 @@ 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
-to effectively step through the entry's attributes.  This pointer
-is freed by
-.B ldap_next_attribute()
-when there are no more attributes (that
-is, when
-.B ldap_next_attribute()
-returns NULL).  Otherwise, the caller is
-responsible for freeing the BerElement pointed to by \fIberptr\fP when
-it is no longer needed by calling
+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
 .BR ber_free (3).
 When calling
 .BR ber_free (3)
@@ -69,11 +65,15 @@ for a description of possible error codes.
 .SH NOTES
 The
 .B ldap_first_attribute()
-routine mallocs memory that may need to
-be freed by the caller via
-.BR ber_free (3).
+routine dyanamically allocated memory that must be freed by the caller via
+.BR ber_free (3).   
 .SH SEE ALSO
 .BR ldap(3),
 .BR ldap_first_entry(3),
 .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.  
index 368ad0ffff64d0043dbf89f529152163a323f74e..1eb45be7b62328c78cd1eff6b009c475ce7e7b25 100644 (file)
@@ -1,10 +1,12 @@
-.TH LDAP_FIRST_ENTRY 3  "25 November 1994" "U-M LDAP LDVERSION"
+.TH LDAP_FIRST_ENTRY 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap_first_entry, ldap_next_entry, ldap_count_entries \- LDAP result entry parsing and counting routines
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
@@ -81,3 +83,8 @@ for a description of possible error codes.
 .BR ldap_first_attribute(3),
 .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.  
index 1cf254b4756dda8d5c2d6ca6cc32bf07a2076124..a6dea4cbe09a3ed05e08a7843aa3d68d103369cc 100644 (file)
@@ -1,29 +1,31 @@
-.TH LDAP_FRIENDLY 3  "11 October 1993" "U-M LDAP LDVERSION"
+.TH LDAP_FRIENDLY 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap_friendly_name, ldap_free_friendlymap \- LDAP unfriendly to friendly name mapping routine
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
-typedef struct friendly {
-        char *f_unfriendly;
-        char *f_friendly;
-} FriendlyMap;
+typedef struct ldap_friendly {
+        char *lf_unfriendly;
+        char *lf_friendly;
+} LDAPFriendlyMap;
 .LP
 .ft B
 char *ldap_friendly_name(filename, name, map)
 .ft
 char *filename;
 char *name;
-FriendlyMap **map;
+LDAPFriendlyMap **map;
 .LP
 .ft B
 void ldap_free_friendlymap(map)
 .ft
-FriendlyMap **map;
+LDAPFriendlyMap **map;
 .SH DESCRIPTION
 This routine is used to map one set of strings to another.  Typically,
 this is done for country names, to map from the two-letter country
@@ -40,10 +42,10 @@ For example:
 .LP
 .nf
 .ft tt
-        FriendlyMap *map = NULL;
+        LDAPFriendlyMap *map = NULL;
 
         printf( "unfriendly %s => friendly %s\\n", name,
-            ldap_friendly_name( "ETCDIR/ldapfriendly", name, &map ) );
+            ldap_friendly_name( "DATADIR/ldapfriendly", name, &map ) );
 .ft
 .fi
 .LP
@@ -63,6 +65,11 @@ NULL is returned by
 if there is an error opening \fIfilename\fP, or if the file has a bad
 format, or if the \fImap\fP parameter is NULL.
 .SH FILES
-ETCDIR/ldapfriendly.conf
+DATADIR/ldapfriendly.conf
 .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.  
index 55530fcbd45d49b6e18acfa98f77740830acf07e..c76f28242c4f3ac4d1ab25ff848565b5d71cb6f4 100644 (file)
@@ -1,10 +1,12 @@
-.TH LDAP_GET_DN 3  "16 June 1995" "U-M LDAP LDVERSION"
+.TH LDAP_GET_DN 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ldap_get_dn, ldap_explode_dn, ldap_dn2ufn, ldap_is_dns_dn, ldap_explode_dns \- LDAP DN handling routines
+ldap_get_dn, ldap_explode_dn, ldap_explode_rdn, ldap_dn2ufn, ldap_is_dns_dn, ldap_explode_dns \- LDAP DN handling routines
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
@@ -20,6 +22,12 @@ char *dn;
 int notypes;
 .LP
 .ft B
+char **ldap_explode_rdn(rdn, notypes)
+.ft
+char *rdn;
+int notypes;
+.LP
+.ft B
 char *ldap_dn2ufn(dn)
 .ft
 char *dn;
@@ -47,10 +55,9 @@ routine takes an \fIentry\fP as returned by
 or
 .BR ldap_next_entry (3)
 and returns a copy of
-the entry's DN.  Space for the DN will have been obtained via
-.BR malloc (3),
-and should be freed by the caller by a call to
-.BR free (3).
+the entry's DN.  Space for the DN will be obtained dynamically
+and should be freed by the caller using 
+.BR ldap_memfree (3).
 .LP
 The
 .B ldap_explode_dn()
@@ -68,16 +75,24 @@ c=US" would return as either { "cn=Bob", "c=US", NULL } or { "Bob",
 The result can be freed by calling
 .BR ldap_value_free (3).
 .LP
+Similarly, the
+.B ldap_explode_rdn()
+routine takes an RDN as returned by
+.B ldap_explode_dn(dn,0)
+and breaks it up into its "type=value" component parts (or just "value",
+if the \fInotypes\fP parameter is set).  The result can be freed by
+calling
+.BR ldap_value_free (3).
+.LP
 .B ldap_dn2ufn()
 is used to turn a DN as returned by
 .B ldap_get_dn()
 into a more user-friendly form, stripping off type names.  See
 RFC 1781 "Using the Directory to Achieve User Friendly Naming"
 for more details on the UFN format.  The space for the UFN returned
-is obtained by a call to
-.BR malloc (3),
-and the user is responsible for freeing it via a call to
-.BR free (3).
+is obtained dynamically and the user is responsible for freeing it
+via a call to
+.BR ldap_memfree (3).
 .LP
 .B ldap_is_dns_dn()
 returns non-zero if the dn string is an experimental
@@ -101,6 +116,7 @@ field in the \fIld\fP parameter is set to indicate the error.  See
 .BR ldap_error (3)
 for a description of possible error codes.
 .BR ldap_explode_dn() ,
+.BR ldap_explode_rdn() ,
 .B ldap_explode_dns()
 and
 .B ldap_dn2ufn()
@@ -108,9 +124,15 @@ will return NULL with
 .BR errno (3)
 set appropriately in case of trouble.
 .SH NOTES
-These routines malloc memory that the caller must free.
+These routines dyanamically allocate memory that the caller must free.
 .SH SEE ALSO
 .BR ldap(3),
-.BR ldap_first_entry(3),
 .BR ldap_error(3),
+.BR ldap_first_entry(3),
+.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.  
index ac0dcdb6b371f2f3f16debc45d2bfeb048f099df..f87ceb8c57d74c13ee2e17748c9eaf93b6dff05a 100644 (file)
@@ -1,10 +1,12 @@
-.TH LDAP_GET_VALUES 3  "25 November 1994" "U-M LDAP LDVERSION"
+.TH LDAP_GET_VALUES 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap_get_values, ldap_get_values_len, ldap_count_values \- LDAP attribute value handling routines
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 
 typedef struct berval {
@@ -91,9 +93,15 @@ indicate the error.  See
 .BR ldap_error (3)
 for a description of possible error codes.
 .SH NOTES
-These routines malloc memory that the caller must free.
+These routines dynamically allocate memory which the caller must free
+using the supplied routines.
 .SH SEE ALSO
 .BR ldap(3),
 .BR ldap_first_entry(3),
 .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.  
index 67a8df3ccda43591f6753e09c8fd5c8b160b335f..0d02b1b89e7469b5098ca8536fd59b8c8d50a8cb 100644 (file)
@@ -1,11 +1,13 @@
-.TH LDAP_GETFILTER 3  "28 November 1994" "U-M LDAP LDVERSION"
+.TH LDAP_GETFILTER 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap_init_getfilter, ldap_init_getfilter_buf, ldap_getfilter_free,
 ldap_getfirstfilter, ldap_getnextfilter, ldap_build_filter \- LDAP filter generating routines
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .ft
 .fi
@@ -185,9 +187,16 @@ are no more appropriate filters to return.
 .SH NOTES
 .LP
 The return values for all of these functions are declared in the
-<ldap.h> header file.  Some routines may malloc memory.
+<ldap.h> header file.
+Some routines may dynamically allocate memory
+which the caller must free using the supplied deallocator routines.
 .SH FILES
 ETCDIR/ldapfilter.conf
 .SH SEE ALSO
 .BR ldap (3),
 .BR ldapfilter.conf (5)
+.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.  
index baf71a373617cac76221eb0652af930114124711..4434ba202b275fdd38261f490efad406bf9af789 100644 (file)
@@ -1,10 +1,12 @@
-.TH LDAP_MODIFY 3  "15 November 1994" "U-M LDAP LDVERSION"
+.TH LDAP_MODIFY 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap_modify, ldap_modify_s \- Perform an LDAP modify operation
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
@@ -111,3 +113,8 @@ field of \fIld\fP.
 .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.  
index 1b382758f12f87adf9e0635aa613726f0cfee5dd..e566036c2609d656019790a43f39e94af0f66138 100644 (file)
@@ -1,10 +1,12 @@
-.TH LDAP_MODRDN 3  "1 December 1994" "U-M LDAP LDVERSION"
+.TH LDAP_MODRDN 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap_modrdn, ldap_modrdn_s, ldap_modrdn2, ldap_modrdn2_s \- Perform an LDAP modify RDN operation
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
@@ -73,3 +75,8 @@ for more details.
 .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.  
index 746e66509ac86bc9164df69d6d2a81ce75ab0985..8c03c0dbaa48b0e3c4a7c68aec5928d23eaf2c24 100644 (file)
@@ -1,10 +1,12 @@
-.TH LDAP_OPEN 3  "28 March 1996" "U-M LDAP LDVERSION"
+.TH LDAP_OPEN 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 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
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
@@ -81,8 +83,8 @@ 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,
 .B ldap_init()
-should only
-be used if the LDAP library is compiled with LDAP_REFERRALS defined.
+is preferred.  
+.B ldap_open() will be depreciated in a later release.
 .SH ERRORS
 If an error occurs, these routines will return NULL and errno should be
 set appropriately.
@@ -111,3 +113,8 @@ in the LDAP structure.
 .BR ldap (3),
 .BR ldap_bind (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.  
index 306e8be44cc18d5cceb7fc244c0c97b0f2d97a97..68ca6f9cb84bff8b13171bff8de143b1944f031c 100644 (file)
@@ -1,10 +1,12 @@
-.TH LDAP_RESULT 3  "26 November 1994" "U-M LDAP LDVERSION"
+.TH LDAP_RESULT 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap_result \- Wait for the result of an LDAP operation
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
@@ -19,6 +21,16 @@ LDAPMessage **result;
 int ldap_msgfree(msg)
 .ft
 LDAPMessage *msg;
+.LP
+.ft B
+int ldap_msgtype(msg)
+.ft
+LDAPMessage *msg;
+.LP
+.ft B
+int ldap_msgid(msg)
+.ft
+LDAPMessage *msg;
 .SH DESCRIPTION
 The
 .B ldap_result()
@@ -92,15 +104,32 @@ or
 and friends.  It takes
 a pointer to the result to be freed and returns the type of the
 message it freed.
+.LP
+The
+.B ldap_msgtype()
+routine returns the type of a message.
+.LP
+The
+.B ldap_msgid()
+routine returns the message id of a message.
 .SH ERRORS
 .B ldap_result()
 returns -1 if something bad happens, and zero if the
 timeout specified was exceeded.
+.B ldap_msgtype()
+and
+.B ldap_msgid()
+return -1 on error.
 .SH NOTES
-This routine mallocs memory for results that it receives.  The memory
-can be freed by calling
+This routine dynamically allocates memory for results that it receives.
+The memory can be freed by the caller using
 .BR ldap_msgfree .
 .SH SEE ALSO
 .BR ldap (3),
 .BR ldap_search (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.  
diff --git a/doc/man/man3/ldap_schema.3 b/doc/man/man3/ldap_schema.3
new file mode 100644 (file)
index 0000000..79c4b5c
--- /dev/null
@@ -0,0 +1,328 @@
+.TH LDAP_SCHEMA 3 "4 June 2000" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 2000 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
+.SH SYNOPSIS
+.nf
+.ft B
+#include <ldap.h>
+.LP
+.ft B
+LDAP_SYNTAX * ldap_str2syntax(s, code, errp, flags)
+.ft
+const char * s;
+int * code;
+const char ** errp;
+const int flags;
+.LP
+.ft B
+char * ldap_syntax2str(syn)
+.ft
+const LDAP_SYNTAX * syn;
+.LP
+.ft B
+const char * ldap_syntax2name(syn)
+.ft
+LDAP_SYNTAX * syn;
+.LP
+.ft B
+ldap_syntax_free(syn)
+.ft
+LDAP_SYNTAX * syn;
+.LP
+.ft B
+LDAP_MATCHING_RULE * ldap_str2matchingrule(s, code, errp, flags)
+.ft
+const char * s;
+int * code;
+const char ** errp;
+const int flags;
+.LP
+.ft B
+char * ldap_matchingrule2str(mr);
+.ft
+const LDAP_MATCHING_RULE * mr;
+.LP
+.ft B
+const char * ldap_matchingrule2name(mr)
+.ft
+LDAP_MATCHING_RULE * mr;
+.LP
+.ft B
+ldap_matchingrule_free(mr)
+.ft
+LDAP_MATCHING_RULE * mr;
+.LP
+.ft B
+LDAP_ATTRIBUTE_TYPE * ldap_str2attributetype(s, code, errp, flags)
+.ft
+const char * s;
+int * code;
+const char ** errp;
+const int flags;
+.LP
+.ft B
+char * ldap_attributetype2str(at)
+.ft
+const LDAP_ATTRIBUTE_TYPE * at;
+.LP
+.ft B
+const char * ldap_attributetype2name(at)
+.ft
+LDAP_ATTRIBUTE_TYPE * at;
+.LP
+.ft B
+ldap_attributetype_free(at)
+.ft
+LDAP_ATTRIBUTE_TYPE * at;
+.LP
+.ft B
+LDAP_OBJECT_CLASS * ldap_str2objectclass(s, code, errp, flags)
+.ft
+const char * s;
+int * code;
+const char ** errp;
+const int flags;
+.LP
+.ft B
+char * ldap_objectclass2str(oc)
+.ft
+const LDAP_OBJECT_CLASS * oc;
+.LP
+.ft B
+const char * ldap_objectclass2name(oc)
+.ft
+LDAP_OBJECT_CLASS * oc;
+.LP
+.ft B
+ldap_objectclass_free(oc)
+.ft
+LDAP_OBJECT_CLASS * oc;
+.LP
+.ft B
+char * ldap_scherr2str(code)
+.ft
+int code;
+.SH DESCRIPTION
+These routines are used to parse schema definitions in the syntax
+defined in RFC2252 into structs and handle these structs.  These
+routines handle four kinds of definitions: syntaxes, matching rules,
+attribute types and objectclasses.  For each definition kind, four
+routines are provided.
+.LP
+.B ldap_str2xxx()
+takes a definition in RFC2252 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
+responsible for freeing the struct by calling
+.B ldap_xxx_free()
+when not needed any longer.  The routine returns NULL if some problem
+happened.  In this case, the integer pointed at by argument
+.IR code
+will receive an error code (see below the description of
+.B ldap_scherr2str()
+for an explanation of the values) and a pointer to a NUL-terminated
+string will be placed where requested by argument
+.IR errp
+, indicating where in argument
+.IR s
+the error happened, so it must not be freed by the caller.  Argument
+.IR flags
+is a bit mask of parsing options controlling the relaxation of the
+syntax recognized.  The following values are defined:
+.TP
+.B LDAP_SCHEMA_ALLOW_NONE
+strict parsing according to RFC2252.
+.TP
+.B LDAP_SCHEMA_ALLOW_NO_OID
+permit definitions that do not contain an initial OID.
+.TP
+.B LDAP_SCHEMA_ALLOW_QUOTED
+permit quotes around some items that should not have them.
+.TP
+.B LDAP_SCHEMA_ALLOW_DESCR
+permit a
+.B descr
+instead of a numeric OID in places where the syntax expect the latter.
+.TP
+.B LDAP_SCHEMA_ALLOW_DESCR_PREFIX
+permit that the initial numeric OID contains a prefix in
+.B descr
+format.
+.TP
+.B LDAP_SCHEMA_ALLOW_ALL
+be very liberal, include all options.
+.LP
+The structures returned are as follows:
+.sp
+.RS
+.nf
+.ne 7
+.ta 8n 16n 32 n
+typedef struct ldap_schema_extension_item {
+       char *lsei_name;        /* Extension name */
+       char **lsei_values;     /* Extension values */
+} LDAP_SCHEMA_EXTENSION_ITEM;
+
+typedef struct ldap_syntax {
+       char *syn_oid;          /* OID */
+       char **syn_names;       /* Names */
+       char *syn_desc;         /* Description */
+       LDAP_SCHEMA_EXTENSION_ITEM **syn_extensions; /* Extension */
+} LDAP_SYNTAX;
+
+typedef struct ldap_matchingrule {
+       char *mr_oid;           /* OID */
+       char **mr_names;        /* Names */
+       char *mr_desc;          /* Description */
+       int  mr_obsolete;       /* Is obsolete? */
+       char *mr_syntax_oid;    /* Syntax of asserted values */
+       LDAP_SCHEMA_EXTENSION_ITEM **mr_extensions; /* Extensions */
+} LDAP_MATCHING_RULE;
+
+typedef struct ldap_attributetype {
+       char *at_oid;           /* OID */
+       char **at_names;        /* Names */
+       char *at_desc;          /* Description */
+       int  at_obsolete;       /* Is obsolete? */
+       char *at_sup_oid;       /* OID of superior type */
+       char *at_equality_oid;  /* OID of equality matching rule */
+       char *at_ordering_oid;  /* OID of ordering matching rule */
+       char *at_substr_oid;    /* OID of substrings matching rule */
+       char *at_syntax_oid;    /* OID of syntax of values */
+       int  at_syntax_len;     /* Suggested minimum maximum length */
+       int  at_single_value;   /* Is single-valued?  */
+       int  at_collective;     /* Is collective? */
+       int  at_no_user_mod;    /* Are changes forbidden through LDAP? */
+       int  at_usage;          /* Usage, see below */
+       LDAP_SCHEMA_EXTENSION_ITEM **at_extensions; /* Extensions */
+} LDAP_ATTRIBUTE_TYPE;
+
+typedef struct ldap_objectclass {
+       char *oc_oid;           /* OID */
+       char **oc_names;        /* Names */
+       char *oc_desc;          /* Description */
+       int  oc_obsolete;       /* Is obsolete? */
+       char **oc_sup_oids;     /* OIDs of superior classes */
+       int  oc_kind;           /* Kind, see below */
+       char **oc_at_oids_must; /* OIDs of required attribute types */
+       char **oc_at_oids_may;  /* OIDs of optional attribute types */
+       LDAP_SCHEMA_EXTENSION_ITEM **oc_extensions; /* Extensions */
+} LDAP_OBJECT_CLASS;
+.ta
+.fi
+.RE
+.PP
+Some integer fields (those described with a question mark) have a
+truth value, for these fields the possible values are:
+.TP
+.B LDAP_SCHEMA_NO
+The answer to the question is no.
+.TP
+.B LDAP_SCHEMA_YES
+The answer to the question is yes.
+.LP
+For attribute types, the following usages are possible:
+.TP
+.B LDAP_SCHEMA_USER_APPLICATIONS
+the attribute type is non-operational.
+.TP
+.B LDAP_SCHEMA_DIRECTORY_OPERATION
+the attribute type is operational and is pertinent to the directory
+itself, i.e. it has the same value on all servers that master the
+entry containing this attribute type.
+.TP
+.B LDAP_SCHEMA_DISTRIBUTED_OPERATION
+the attribute type is operational and is pertinent to replication,
+shadowing or other distributed directory aspect.  TBC.
+.TP
+.B LDAP_SCHEMA_DSA_OPERATION
+the attribute type is operational and is pertinent to the directory
+server itself, i.e. it may have different values for the same entry
+when retrieved from different servers that master the entry.
+.LP
+Object classes can be of three kinds:
+.TP
+.B LDAP_SCHEMA_ABSTRACT
+the object class is abstract, i.e. there cannot be entries of this
+class alone.
+.TP
+.B LDAP_SCHEMA_STRUCTURAL
+the object class is structural, i.e. it describes the main role of the
+entry.  On some servers, once the entry is created the set of
+structural object classes assigned cannot be changed: none of those
+present can be removed and none other can be added.
+.TP
+.B LDAP_SCHEMA_AUXILIARY
+the object class is auxiliary, i.e. it is intended to go with other,
+structural, object classes.  These can be added or removed at any time
+if attribute types are added or removed at the same time as needed by
+the set of object classes resulting from the operation.
+.LP
+Routines
+.B ldap_xxx2name()
+return a canonical name for the definition.
+.LP
+Routines
+.B ldap_xxx2str()
+return a string representation in the format described by RFC2252 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.
+.LP
+.B ldap_scherr2str()
+returns a NUL-terminated string with a text description of the error
+found.  This is a pointer to a static area, so it must not be freed by
+the caller.  The argument
+.IR code
+comes from one of the parsing routines and can adopt the following
+values:
+.TP
+.B LDAP_SCHERR_OUTOFMEM
+Out of memory.
+.TP
+.B LDAP_SCHERR_UNEXPTOKEN
+Unexpected token.
+.TP
+.B LDAP_SCHERR_NOLEFTPAREN
+Missing opening parenthesis.
+.TP
+.B LDAP_SCHERR_NORIGHTPAREN
+Missing closing parenthesis.
+.TP
+.B LDAP_SCHERR_NODIGIT
+Expecting digit.
+.TP
+.B LDAP_SCHERR_BADNAME
+Expecting a name.
+.TP
+.B LDAP_SCHERR_BADDESC
+Bad description.
+.TP
+.B LDAP_SCHERR_BADSUP
+Bad superiors.
+.TP
+.B LDAP_SCHERR_DUPOPT
+Duplicate option.
+.TP
+.B LDAP_SCHERR_EMPTY
+Unexpected end of data.
+
+.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.  
+
diff --git a/doc/man/man3/ldap_schema.3.links b/doc/man/man3/ldap_schema.3.links
new file mode 100644 (file)
index 0000000..05e1675
--- /dev/null
@@ -0,0 +1,17 @@
+ldap_str2syntax.3
+ldap_syntax2str.3
+ldap_syntax2name.3
+ldap_syntax_free.3
+ldap_str2matchingrule.3
+ldap_matchingrule2str.3
+ldap_matchingrule2name.3
+ldap_matchingrule_free.3
+ldap_str2attributetype.3
+ldap_attributetype2str.3
+ldap_attributetype2name.3
+ldap_attributetype_free.3
+ldap_str2objectclass.3
+ldap_objectclass2str.3
+ldap_objectclass2name.3
+ldap_objectclass_free.3
+ldap_scherr2str.3
index e1a7022bcdab160f92d892c4a8f7d6ca812eafb8..a008db650fad6d76fe83930584f19a43045a49a9 100644 (file)
@@ -1,11 +1,13 @@
-.TH LDAP_SEARCH 3  "23 November 1994" "U-M LDAP LDVERSION"
+.TH LDAP_SEARCH 3 "25 July 1999" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 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
 .SH SYNOPSIS
 .nf
 .ft B
 #include <sys/time.h> /* for struct timeval definition */
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
@@ -87,8 +89,16 @@ filters.  See
 for routines to help in constructing search filters automatically.
 .LP
 \fIAttrs\fP is a null-terminated array of attribute types to return
-from entries that match \fIfilter\fP.  If NULL is specified, all
-attributes will be returned.  \fIAttrsonly\fP should be set to 1 if
+from entries that match \fIfilter\fP.
+If NULL is specified, all attributes will be returned.
+The type "*" (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)
+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
@@ -107,10 +117,17 @@ 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 malloc memory.  Return values are contained
+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>.
 .SH SEE ALSO
 .BR ldap (3),
 .BR ldap_result (3),
 .BR ldap_getfilter (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.  
index 98b6e78d7799474170c57de9165fc5363ca2c44f..02a404c9422018fe92ec5f210825f5544ceffed6 100644 (file)
@@ -1,4 +1,7 @@
-.TH SEARCHPREFS 3  "13 June 1994" "U-M LDAP LDVERSION"
+.TH SEARCHPREFS 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap_init_searchprefs, ldap_init_searchprefs_buf, ldap_free_searchprefs, ldap_first_searchobj, ldap_next_searchobj \- LDAP search preference configuration routeines
 .SH SYNOPSIS
@@ -156,3 +159,8 @@ OSI-DS-23, April 1992.
 Information Processing - Open Systems Interconnection - The Directory,
 International Organization for Standardization.  International Standard
 9594, (1988).
+.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.  
index f56122af0b9a9291bec1a1c98bb33a30fbacf06f..3d451e55ff5a1b4d89b6a9c11effee486404d783 100644 (file)
@@ -1,10 +1,12 @@
-.TH LDAP_SORT 3  "14 November 1994" "U-M LDAP LDVERSION"
+.TH LDAP_SORT 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 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
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
@@ -93,9 +95,16 @@ 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 malloc memory.
+<ldap.h> header file.  Some routines may dynamically allocate memory.
+Callers are responsible for freeing such memory using the supplied
+deallocation routines.
 .SH SEE ALSO
 .BR ldap (3),
 .BR ldap_search (3),
 .BR ldap_result (3),
 .BR qsort (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.  
index 6fe1a5123d4643309ba15dd8f47b112b6349a48d..b0c8a13d20376a71065db3f8a9d6bd1b3ee89d8b 100644 (file)
@@ -1,10 +1,12 @@
-.TH LDAP_UFN 3  "23 November 1994" "U-M LDAP LDVERSION"
+.TH LDAP_UFN 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap_ufn_search_s, ldap_ufn_search_c, ldap_ufn_search_ct, ldap_ufn_setfilter, ldap_ufn_setfilter, ldap_ufn_setprefix, ldap_ufn_timeout \- Perform an LDAP user friendly search operation
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .LP
 .ft B
@@ -119,7 +121,9 @@ should actually be a pointer to a struct timeval (this is so
 .B ldap_ufn_timeout()
 can be used as a cancelproc in the above routines).
 .SH NOTES
-These routines may malloc memory.  Return values are contained
+These routines may dynamically allocate memory.  The caller is
+required to free such memory using the supplied deallocation routines.
+Return values are contained
 in <ldap.h>.
 .SH SEE ALSO
 .BR gettimeofday (2),
@@ -128,3 +132,8 @@ in <ldap.h>.
 .BR ldap_getfilter (3),
 .BR ldapfilter.conf (5),
 .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.  
index 7e04bcc3370026dd2121cad9d234aae011f2b2cf..8b48e4c4d5cee373365bd50d394b0d531441bd65 100644 (file)
@@ -1,4 +1,7 @@
-.TH LDAP_URL 3  "28 March 1996" "U-M LDAP LDVERSION"
+.TH LDAP_URL 3 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldap_is_ldap_url,
 ldap_url_parse,
@@ -9,7 +12,6 @@ ldap_url_search_st \- LDAP Uniform Resource Locator routines
 .SH SYNOPSIS
 .nf
 .ft B
-#include <lber.h>
 #include <ldap.h>
 .ft
 .LP
@@ -71,10 +73,10 @@ LDAP URLs look like this:
 
 where:
   \fIhostport\fP is a host name with an optional ":portnumber"
-  \fIdn\f is the base DN to be used for an LDAP search operation
+  \fIdn\fP is the base DN to be used for an LDAP search operation
   \fIattributes\fP is a comma separated list of attributes to be retrieved
   \fIscope\fP is one of these three strings:  base one sub (default=base)
-  \fIfilter\f is LDAP search filter as used in a call to ldap_search(3)
+  \fIfilter\fP is LDAP search filter as used in a call to ldap_search(3)
 
 e.g.,  ldap://ldap.itd.umich.edu/c=US?o,description?one?o=umich
 .fi
@@ -134,3 +136,8 @@ Currently available at this URL:
 .nf
 ftp://ds.internic.net/internet-drafts/draft-ietf-asid-ldap-format-03.txt
 .fi
+.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.  
diff --git a/doc/man/man5/Makefile.in b/doc/man/man5/Makefile.in
new file mode 100644 (file)
index 0000000..b83e294
--- /dev/null
@@ -0,0 +1,6 @@
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+## COPYING RESTRICTIONS APPLY, See COPYRIGHT file
+##
+## man5 Makefile.in for OpenLDAP
+
+MANSECT=5
index 00d9d4adc0ccdf329c3047120bee45f69da95217..1e9e5266e9345e2c7ecda4094f4d1b262f8956f2 100644 (file)
@@ -1,9 +1,13 @@
 .TH LDAP.CONF 5 "29 November 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .UC 6
 .SH NAME
-ldap.conf \- ldap configuration file
+ldap.conf, .ldaprc \- ldap configuration file
 .SH SYNOPSIS
 ETCDIR/ldap.conf
+\fP.ldaprc\fP
 .SH DESCRIPTION
 The
 .I ldap.conf
@@ -29,13 +33,24 @@ Environmental variables may also be used to augment the file based defaults.
 The name of the option is the as listed but with a prefix of \fBLDAP\fP.
 For example, to define \fBBASE\fP via the environment, define the variable
 \fBLDAPBASE\fP to desired value.
+.LP
+Some options are user\-only.  Such options are ignored if present
+in the
+.IR ldap.conf
+(or file specified by
+.BR LDAPCONF ).
 .SH OPTIONS
 The different configuration options are:
 .TP 1i
 \fBBASE <base>\fP
-Used to specify the default base dn to use when performing ldap operations.
+Used to specify the default base DN to use when performing ldap operations.
 The base must be specified as a Distinguished Name in LDAP format.
 .TP 1i
+\fBBINDDN <dn>\fP
+Used to specify 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.
+.TP 1i
 \fBHOST <name[:port] ...>\fP
 Used to specify the name(s) of an LDAP server(s) to which 
 .I ldap 
index 954bc2fd4d86b34dfe09abc86e18496bd2109e46..97d720dae9defff668f102709dbd1db6aa393688 100644 (file)
@@ -1,4 +1,7 @@
-.TH LDAPFILTER.CONF 5  "21 September 1994" "U-M LDAP LDVERSION"
+.TH LDAPFILTER.CONF 5 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldapfilter.conf \- configuration file for LDAP get filter routines
 .SH SYNOPSIS
@@ -196,3 +199,8 @@ ETCDIR/ldapfilter.conf
 .SH SEE ALSO
 .BR ldap (3),
 .BR ldap_getfilter (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.  
index 088fd135603e99b2d438d25db7311803a9ff376e..3cf6f02edc8ba65f49aa27b48e05b083d405847a 100644 (file)
@@ -1,16 +1,19 @@
-.TH LDAPFRIENDLY 5  "24 November 1994" "U-M LDAP LDVERSION"
+.TH LDAPFRIENDLY 5 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ldapfriendly \- configuration file for LDAP friendly routines
+ldapfriendly \- data file for LDAP friendly routines
 .SH SYNOPSIS
-ETCDIR/ldapfriendly
+DATADIR/ldapfriendly
 .SH DESCRIPTION
 .LP
-The file ETCDIR/ldapfriendly contains simple mapping information
+The file DATADIR/ldapfriendly contains simple mapping information
 used by the
 .BR ldap_friendly_name (3)
 routine.  Blank lines and
 lines that have a first character of `#' are treated as comments and
-ignored.  The configuration information consists of lines that contain
+ignored.  The information consists of lines that contain
 an "unfriendly" name, a tab, and a "friendly" name.
 .LP
 Other friendly mapping files can be created and used by
@@ -20,7 +23,12 @@ above and include the file name in the
 .B ldap_friendly_name()
 call.
 .SH FILES
-ETCDIR/ldapfriendly
+DATADIR/ldapfriendly
 .SH SEE ALSO
 .BR ldap (3),
 .BR ldap_friendly_name (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.  
index 7f58505ed35e443b2cb7972c99204368d150f671..a075148c78475b831e7753d5a63156e44de065b2 100644 (file)
@@ -1,4 +1,7 @@
-.TH LDAPSEARCHPREFS.CONF 5  "1 December 1994" "U-M LDAP LDVERSION"
+.TH LDAPSEARCHPREFS.CONF 5 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldapsearchprefs.conf \- configuration file for LDAP search preference routines
 .SH SYNOPSIS
@@ -244,3 +247,8 @@ ETCDIR/ldapsearchprefs.conf
 .SH SEE ALSO
 .BR ldap (3).
 .BR ldap-searchprefs (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.  
index 6a68e721f0569d8af77b4ef99fd58d28b7be8c71..e5a87b6c80adac755fb6c8a5e128ed28c1a4c402 100644 (file)
@@ -1,4 +1,7 @@
 .TH LDAPTEMPLATES.CONF 5 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldaptemplates.conf \- configuration file for LDAP display template routines
 .SH SYNOPSIS
index a0cb4774c6d0715e2a6b25548d2da81dbd93f3ea..1cb621a5dc5c1dac265515b1aaa963cba7af1947 100644 (file)
@@ -1,4 +1,7 @@
 .TH LDIF 5 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldif \- LDAP Data Interchange Format
 .SH DESCRIPTION
index 44feb794fabc38e6bebceb1b683f27439b2f86fa..4016f9df5541c8516a1e610c933b39e1da046e55 100644 (file)
@@ -1,4 +1,7 @@
 .TH SLAPD.CONF 5 "5 August 1999" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 slapd.conf \- configuration file for slapd, the stand-alone LDAP daemon
 .SH SYNOPSIS
@@ -64,26 +67,23 @@ overridden in a backend definition. Arguments that should be replaced by
 actual text are shown in brackets <>.
 .TP
 .B
-access to <what> [ by <who> <accesslevel> ]+
-Grant access (specified by <accesslevel>) to a set of entries and/or
+access 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>).  Refer to "The SLAPD and SLURPD Administrator's Guide" for
-information on using the
-.B slapd
-access-control mechanisms.
+by <who>).
+See Developer's FAQ (http://www.openldap.org/faq/) for details.
 .TP
 .B
-attribute ( <oid> [NAME <name>] [DESC <description>] [OBSOLETE] \
+attributetype ( <oid> [NAME <name>] [DESC <description>] [OBSOLETE] \
 [SUP <oid>] [EQUALITY <oid>] [ORDERING <oid>] [SUBSTR <oid>] \
 [SYNTAX <oidlen>] [SINGLE-VALUE] [COLLECTIVE] [NO-USER-MODIFICATION] \
 [USAGE <attributeUsage>] )
 Specify an attribute type using the LDAPv3 syntax defined in RFC 2252.
-This is the preferred format for attribute type definitions. The slapd
-parser extends the RFC 2252 definition by allowing string forms as well
-as numeric OIDs to be used for the attribute OID and attribute syntax OID.
+The slapd parser extends the RFC 2252 definition by allowing string
+forms as well as numeric OIDs to be used for the attribute OID and
+attribute syntax OID.
 (See the
-.B
-objectidentifier
+.B objectidentifier
 description.) Currently the syntax name parser is case-sensitive.
 The known syntax names are:
 .RS
@@ -103,40 +103,18 @@ SubstringAssertion NISnetgrouptriple Bootparameter
 .RE
 .RE
 .TP
-.B 
-attribute <name> [<name2>] { bin | ces | cis | tel | dn }
-Associate a syntax with an attribute name. This directive is deprecated
-in favor of the one above. By default, an 
-attribute is assumed to have syntax
-.BR cis .
-An optional alternate name can be 
-given for an attribute. The possible syntaxes and their meanings are:
-.RS
-.RS
-.PD 0
-.TP
-.B bin
-binary
-.TP
-.B ces
-case exact string
-.TP
-.B cis
-case ignore string
-.TP
-.B tel
-telephone number string
-.TP
-.B dn
-distinguished name
-.PD
-.RE
-.RE
+.B concurrency <integer>
+Specify a desired level of concurrency.  Provided to the underlying
+thread system as a hint.  The default is not to provdide any hint.
 .TP
 .B
-defaultaccess [self]{ none | compare | search | read | write }
-Specify the default access to grant requestors not matched by 
-any other access line.  The default behavior is to grant read access.
+defaultaccess { none | auth | compare | search | read | write }
+Specify the default access level to grant requestors when
+no access directives were provided for the database.
+The default behavior is to grant 'read' access.  It is
+recommended that
+.B access
+directives be used instead.
 .TP
 .B idletimeout <integer>
 Specify the number of seconds to wait before forcibly closing
@@ -225,18 +203,12 @@ objectclass ( <oid> [NAME <name>] [DESC <description] [OBSOLETE] \
 [SUP <oids>] [{ ABSTRACT | STRUCTURAL | AUXILIARY }] [MUST <oids>] \
 [MAY <oids>] )
 Specify an objectclass using the LDAPv3 syntax defined in RFC 2252.
-This is the preferred format for object class definitions. The slapd
-parser extends the RFC 2252 definition by allowing string forms as well
-as numeric OIDs to be used for the object class OID. (See the
+The slapd parser extends the RFC 2252 definition by allowing string
+forms as well as numeric OIDs to be used for the object class OID.
+(See the
 .B
 objectidentifier
-description.) Object classes are "STRUCTURAL" by default.
-.TP
-.B
-objectclass <name> requires <attrs> allows <attrs>
-Define the schema rules for the object class named <name>.  These are
-used in conjunction with the schemacheck option. This directive is
-deprecated in favor of the one above.
+description.)  Object classes are "STRUCTURAL" by default.
 .TP
 .B objectidentifier <name> { <oid> | <name>[:<suffix>] }
 Define a string name that equates to the given OID. The string can be used
@@ -347,9 +319,10 @@ or administrative limit restrictions for operations on this database.
 .TP
 .B rootpw <password>
 Specify a password (or hash of the password) for the rootdn.
-This option accepts all password formats known to the server
-including \fB{SHA}\fP, \fB{MD5}\fP, \fB{CRYPT}\fP, and cleartext.  
-Cleartext passwords are not recommended.
+This option accepts all RFC 2307 userPassword formats known to
+the server including \fB{SSHA}\fP, \fB{SHA}\fP, \fB{SMD5}\fP,
+\fB{MD5}\fP, \fB{CRYPT}\fP, and cleartext schemes.  Cleartext
+and \fB{CRYPT}\fP passwords are not recommended.
 .TP
 .B suffix <dn suffix>
 Specify the DN suffix of queries that will be passed to this 
@@ -384,20 +357,25 @@ 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 dbcachenowsync
-Specify that database writes should not be immediately synchronized
-with in memory changes.  Enabling this option may improve performance
-at the expense of data security.
+.B dbnolocking
+Specify that no database locking should be performed.  
+Enabling this option may improve performance at the expense of data security.
+.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 directory <directory>
-Specify the directory where the LDBM files containing the database and
-associated indexes live.  The default is
-.B /usr/tmp.
+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-ldbm .
 .TP
 .B
 index { <attrlist> | default } [ pres,eq,approx,sub,none ]
 Specify the indexes to maintain for the given attribute. If only 
-an <attr> is given, all possible indexes are maintained.
+an <attr> is given, the indices specified for \fBdefault\fR
+are maintained.
 .TP
 .B mode <integer>
 Specify the file protection mode that newly created database 
index 83d0cc69fd9a11f660789ac3f91cbbf9bf94eb61..3f600f27b3c021c5c2838dd05067dbf1286e6fb6 100644 (file)
@@ -1,4 +1,7 @@
-.TH SLAPD.REPLOG 5  "11 April 1995" "U-M LDAP LDVERSION"
+.TH SLAPD.REPLOG 5 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 slapd.replog \- slapd replication log format
 .SH SYNOPSIS
@@ -156,3 +159,8 @@ slapd.replog.lock
 .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.  
index 13575bf7ea579c6d7d18513f5899f5feb1360070..f9610f833580fb771a7629d5b41462fe113157e6 100644 (file)
@@ -1,9 +1,12 @@
-.TH UD.CONF 5 "18 March 1993" "U-M LDAP LDVERSION"
+.TH UD.CONF 5 "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .UC 6
 .SH NAME
 ud.conf \- ud configuration file
 .SH SYNOPSIS
-/etc/ud.conf
+ETCDIR/ud.conf
 .SH DESCRIPTION
 The
 .I ud
@@ -17,13 +20,13 @@ configuration file.
 .SH OPTIONS
 The different configuration options are:
 .TP 1i
-\fBserver <name>\fP
+\fBHOST <name>\fP
 Used to specify the name of an LDAP server to which 
 .I ud 
 should connect.  There may be only one entry per config file.
 The server's name can be specified as a domain-style name or an IP address.
 .TP 1i
-\fBbase <base>\fP
+\fBBASE <base>\fP
 Used to specify the search base to use when performing search operations.
 The base may be changed by those using
 .I ud
@@ -33,7 +36,7 @@ command.
 There may be only one entry per config file.
 The base must be specified as a Distinguished Name in LDAP format.
 .TP 1i
-\fBgroupbase <base>\fP
+\fBGROUPBASE <base>\fP
 Used to specify the base used when creating groups.
 The base may be changed by those using
 .I ud
@@ -43,7 +46,7 @@ command.
 There may be only one entry per config file.
 The base must be specified as a Distinguished Name in LDAP format.
 .TP 1i
-\fBsearch <algorithm>\fP
+\fBSEARCH <algorithm>\fP
 Used to specify a search algorithm to use when performing searches.  More than
 one algorithm may be specified, and each is tried in turn until a suitable
 response is found.
@@ -88,9 +91,14 @@ For example,
 causes this algorithm to be applied when the number of fields is exactly equal
 to one.  If there is exactly one field, the token is looked up as a UID.
 .SH FILES
-.I  /etc/ud.conf
+.I  ETCDIR/ud.conf
 .SH "SEE ALSO"
 ud(1),
 ldap(3)
 .SH AUTHOR
 Bryan Beecher, University of Michigan
+.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.  
diff --git a/doc/man/man8/Makefile.in b/doc/man/man8/Makefile.in
new file mode 100644 (file)
index 0000000..795dd92
--- /dev/null
@@ -0,0 +1,6 @@
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+## COPYING RESTRICTIONS APPLY, See COPYRIGHT file
+##
+## man8 Makefile.in for OpenLDAP
+
+MANSECT=8
index 680e9b971de3942e50c47fade6ae4279a58fe237..361f1aa6b4d42446f59aa30f40a948ebc12c26db 100644 (file)
@@ -1,8 +1,11 @@
-.TH CENTIPEDE 8C "2 December 1995" "U-M LDAP LDVERSION"
+.TH CENTIPEDE 8C "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 centipede \- LDAP centroid index generation and maintenance program
 .SH SYNOPSIS
-.B ETCDIR/centipede
+.B SBINDIR/centipede
 .B [\-f filter]
 .B [\-F] [\-R]
 .B [\-f filter] [\-t directory]
@@ -25,7 +28,7 @@ The basic form of the command is as follows
 .LP
 .nf
 .ft tt
-       ETCDIR/centipede [options]
+       SBINDIR/centipede [options]
                -s "ldap://[host/]subtree-to-index-dn"
                -d "ldap://[host/]parent-of-index-entry-dn"
                attributes
@@ -61,7 +64,7 @@ like this:
 .LP
 .nf
 .ft tt
-       ETCDIR/centipede -f '(objectclass=person)'
+       SBINDIR/centipede -f '(objectclass=person)'
                -m simple -b your-rootdn -p your-rootdnpw
                -s "ldap://babs.com/o=BabsCo, c=US"
                -d "ldap://vertigo.rs.itd.umich.edu/c=US"
@@ -152,3 +155,8 @@ etc.). A future version may also allow weights to be generated.
 .BR slapd (8)
 .LP
 "The SLAPD and SLURPD Administrator's Guide"
+.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.  
index e99dfd81c9c8f2296d729f94be5c5b295b0320a7..d17c83cc5c519d17b85391fba6d44a30d2a2e612 100644 (file)
@@ -1,9 +1,12 @@
-.TH CHLOG2REPLOG 8C "26 April 1996" "U-M LDAP LDVERSION"
+.TH CHLOG2REPLOG 8C "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 chlog2replog \- convert an X.500 DSA-style changelog to an LDAP-style
 replication log
 .SH SYNOPSIS
-.B ETCDIR/chlog2replog
+.B SBINDIR/chlog2replog
 .B \-r hostname:port [\-r hostname:port ...]
 .B \-d dn\-suffix [\-o output\-file] < input\-file
 .LP
@@ -64,7 +67,7 @@ DNs, and including a replica: entry for host "ldapserver," port
 .LP
 .nf
 .ft tt
-       ETCDIR/chlog2replog -d ", o=University of Michigan, c=US"
+       SBINDIR/chlog2replog -d ", o=University of Michigan, c=US"
        -r ldapserver:389 < changelog
 .ft
 .fi
@@ -75,7 +78,7 @@ give this command:
 .LP
 .nf
 .ft tt
-       ETCDIR/chlog2replog -d ", o=University of Michigan, c=US"
+       SBINDIR/chlog2replog -d ", o=University of Michigan, c=US"
        -r ldapserver:389 -o replog < changelog
 .ft
 .fi
@@ -86,7 +89,7 @@ give this command:
 .LP
 .nf
 .ft tt
-       tail +0f changelog  | ETCDIR/chlog2replog
+       tail +0f changelog  | SBINDIR/chlog2replog
        -d ", o=University of Michigan, c=US"
        -r ldapserver:389 -o replog < changelog
 .ft
@@ -100,3 +103,8 @@ give this command:
 .BR slapd (8),
 .LP
 "The SLAPD and SLURPD Administrator's Guide"
+.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.  
index d2573287d614f1157394bdbef4326380d70a31f9..bcfcadbe4f6dbc786e0684883bed0d6f4f3c3fc7 100644 (file)
@@ -1,4 +1,7 @@
 .TH EDB2LDIF 8C "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 edb2ldif \- QUIPU EDB file to LDIF conversion tool
 .SH SYNOPSIS
index 6fbbf8f5d31969d9e759e90661732924db0f5c6e..d7c2a8cb035eabb6821c643d96d4d53725ae3953 100644 (file)
@@ -1,8 +1,11 @@
-.TH GO500 8C "27 November 1994" "U-M LDAP LDVERSION"
+.TH GO500 8C "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 go500 \- Local Gopher index search to X.500 search gateway
 .SH SYNOPSIS
-.B ETCDIR/go500 [\-b searchbase] [\-d level] [\-l]
+.B LIBEXECDIR/go500 [\-b searchbase] [\-d level] [\-l]
 .B [\-x hostname] [\-c rdncount] [\-f filterfile]
 .B [\-t templatefile]
 .B [\-p port] [\-I]
@@ -27,7 +30,7 @@ as a stand-alone server, simply start it with no arguments
 .LP
 .nf
 .ft tt
-       ETCDIR/go500
+       LIBEXECDIR/go500
 .ft
 .fi
 .LP
@@ -38,8 +41,8 @@ or equivalent file:
 .LP
 .nf
 .ft tt
-       if [ -f ETCDIR/go500 ]; then
-               ETCDIR/go500; echo ' go500'
+       if [ -f LIBEXECDIR/go500 ]; then
+               LIBEXECDIR/go500; echo ' go500'
        fi
 .ft
 .fi
@@ -65,7 +68,7 @@ file, or the equivalent:
 .LP
 .nf
 .ft tt
-    go500   stream  tcp     nowait  nobody  ETCDIR/go500    go500 -I
+    go500   stream  tcp     nowait  nobody  LIBEXECDIR/go500    go500 -I
 .ft
 .fi
 .LP
@@ -168,3 +171,8 @@ include file.
 .BR inetd (8),
 .BR gopherd (8),
 .BR go500gw (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.  
index 4464a88b43de7042502462524436269bda9e356b..066fec91af7be0131165a0420defeba0adad1dea 100644 (file)
@@ -1,8 +1,11 @@
-.TH GO500GW 8C "27 November 1994" "U-M LDAP LDVERSION"
+.TH GO500GW 8C "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 go500gw \- General Gopher to X.500 gateway for browsing and searching
 .SH SYNOPSIS
-.B ETCDIR/go500gw [\-a] [\-d level] [\-f filterfile]
+.B LIBEXECDIR/go500gw [\-a] [\-d level] [\-f filterfile]
 .B [\-t templatefile] [\-c rdncount]
 .B [\-h helpfile] [\-l] [\-p listenport]
 .B [\-P ldapport] [\-x ldaphost] [\-I]
@@ -27,7 +30,7 @@ as a stand-alone server, simply start it with no arguments
 .LP
 .nf
 .ft tt
-       ETCDIR/go500gw
+       LIBEXECDIR/go500gw
 .ft
 .fi
 .LP
@@ -38,8 +41,8 @@ or equivalent file:
 .LP
 .nf
 .ft tt
-       if [ -f ETCDIR/go500gw ]; then
-               ETCDIR/go500gw; echo ' go500gw'
+       if [ -f LIBEXECDIR/go500gw ]; then
+               LIBEXECDIR/go500gw; echo ' go500gw'
        fi
 .ft
 .fi
@@ -64,7 +67,7 @@ file, or the equivalent:
 .LP
 .nf
 .ft tt
-    go500gw  stream  tcp  nowait  nobody  ETCDIR/go500gw    go500gw -I
+    go500gw  stream  tcp  nowait  nobody  LIBEXECDIR/go500gw    go500gw -I
 .ft
 .fi
 .LP
@@ -168,3 +171,8 @@ include file.
 .BR inetd (8),
 .BR gopherd (8),
 .BR go500 (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.  
index a2cf788b18f6d31c07d9fcb80ad258b9eb54486f..5f65271896e2004ad9d6b1c5ded18a56bf574342 100644 (file)
@@ -1,8 +1,11 @@
-.TH IN.XFINGERD 8C "27 November 1994" "U-M LDAP LDVERSION"
+.TH IN.XFINGERD 8C "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 in.xfingerd \- Finger to LDAP/X.500 gateway daemon
 .SH SYNOPSIS
-.B ETCDIR/in.xfingerd [\-f filterfile] [\-i]
+.B LIBEXECDIR/in.xfingerd [\-f filterfile] [\-i]
 .B [\-l] [\-t templatefile] [\-c rdncount] [\-x hostname]
 .B [\-p port]
 .SH DESCRIPTION
@@ -22,7 +25,7 @@ file, or the equivalent:
 .LP
 .nf
 .ft tt
-    finger stream tcp nowait nobody ETCDIR/in.xfingerd in.xfingerd
+    finger stream tcp nowait nobody LIBEXECDIR/in.xfingerd in.xfingerd
 .ft
 .fi
 .LP
@@ -77,3 +80,8 @@ for your site.
 .BR ldap (3),
 .BR ldap_getfilter (3),
 .BR inetd (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.  
index 3e052e16c6bd51b35eafb50f1f5b61d56b849a81..be3bc42847ccb44b6d6349452fdb9b07ae4bbc64 100644 (file)
@@ -1,4 +1,7 @@
 .TH LDIF 8C "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 ldif \- convert arbitrary data to LDIF format
 .SH SYNOPSIS
index fd9bffb1055ab0c6bcbf32e5659e12934d8011a9..cc40891ead867c03a16ee22f5373d563ed9b1381 100644 (file)
@@ -1,14 +1,17 @@
-.TH MAIL500 8C "30 November 1994" "U-M LDAP LDVERSION"
+.TH MAIL500 8C "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 mail500 \- X.500 capable mailer
 .LP
 fax500 \- X.500 capable fax delivery agent
 .SH SYNOPSIS
-.B ETCDIR/mail500 [\-d level] [\-f mailfrom]
+.B LIBEXECDIR/mail500 [\-d level] [\-f mailfrom]
 .B [\-h hostname] [\-l ldaphost]
 .B [\-m address] [\-v vacationhost]
 .LP
-.B ETCDIR/fax500 [\-d level] [\-f mailfrom]
+.B LIBEXECDIR/fax500 [\-d level] [\-f mailfrom]
 .B [\-h hostname] [\-l ldaphost]
 .B [\-m address]
 .SH DESCRIPTION
@@ -253,8 +256,8 @@ The mail500 and fax500 mailers should be defined similar to this in the
 sendmail.cf file:
 .LP
 .nf
-Mmail500, P=ETCDIR/mail500, F=DFMSmnXuh, A=mail500 -f $f -h $h -m $n@$w $u
-Mfax500, P=ETCDIR/fax500, F=DFMSmnXuh, A=fax500 -f $f -h $h -m $n@$w $u
+Mmail500, P=LIBEXECDIR/mail500, F=DFMSmnXuh, A=mail500 -f $f -h $h -m $n@$w $u
+Mfax500, P=LIBEXECDIR/fax500, F=DFMSmnXuh, A=fax500 -f $f -h $h -m $n@$w $u
 .fi
 .LP
 This defines how mail500/fax500 will be treated by sendmail and what
@@ -285,3 +288,8 @@ but not to fax500.
 .BR ldap(3),
 .BR sendmail.cf(5),
 .BR sendmail(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.  
index 3131812bb8dd21b882ad2404aa13ce142d7f0579..6003dee210d93ad9a2127bb235381aaa14e114b7 100644 (file)
@@ -1,8 +1,11 @@
-.TH RCPT500 8C "16 December 1994" "U-M LDAP LDVERSION"
+.TH RCPT500 8C "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 rcpt500 \- mail to X.500 gateway program
 .SH SYNOPSIS
-.B ETCDIR/rcpt500 [\-l] [\-h ldaphost] [\-p ldapport]
+.B LIBEXECDIR/rcpt500 [\-l] [\-h ldaphost] [\-p ldapport]
 .B [\-b searchbase] [\-a] [\-U] [\-z sizelimit] [\-u dapuser]
 .B [\-f filterfile] [\-t templatefile] [\-c rdncount]
 .SH DESCRIPTION
@@ -27,7 +30,7 @@ invoked whenever mail is sent to the address \fInamelookup\fP on your host:
 .nf
 .fi
 .ft tt
-    namelookup:        "|ETCDIR/rcpt500 -l"
+    namelookup:        "|LIBEXECDIR/rcpt500 -l"
 .ft
 .fi
 .SH OPTIONS
@@ -77,10 +80,15 @@ for your site.
 .SH FILES
 .PD 0
 .TP 20
-.B ETCDIR/rcpt500.help
+.B DATADIR/rcpt500.help
 help file
 .PD
 .SH "SEE ALSO"
 .BR ldap (3),
 .BR aliases (5),
 .BR sendmail (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.  
index 15dee333ae76e76cefcc9bdfd60e8ffa8808aa9f..3c066c2cf737a896998f8006ddb4bc619c50e590 100644 (file)
@@ -1,4 +1,7 @@
 .TH SLAPADD 8C "17 August 1999" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 slapadd \- Add entries to a SLAPD database
 .SH SYNOPSIS
index 049041d9da54f35cc97cfae8201e248474ea4223..96a24e74633f91a1658f71c18f01bcc1c9c04cb5 100644 (file)
@@ -1,4 +1,7 @@
 .TH SLAPCAT 8C "17 August 1999" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 slapcat \- SLAPD database to LDIF utility
 .SH SYNOPSIS
index 6fc43e11baf2df2b85123dde6e8fd532939128bd..1e353dd3b59aee48c0b25103aaa6e147dd610605 100644 (file)
@@ -1,4 +1,7 @@
-.TH SLAPD 8C "3 April 1999" "OpenLDAP LDVERSION"
+.TH SLAPD 8C "19 September 1999" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 slapd \- Stand-alone LDAP Daemon
 .SH SYNOPSIS
@@ -6,9 +9,7 @@ slapd \- Stand-alone LDAP Daemon
 .B [\-f slapd\-config\-file]
 .B [\-h URLs]
 .B [\-d debug\-level]
-.B [\-p port\-number]
-.B [\-P tls\-port\-number]
-.B [\-s syslog\-level] [\-l syslog\-local\-user]
+.B [\-n service\-name] [\-s syslog\-level] [\-l syslog\-local\-user]
 .B [\-u user] [\-g group]
 .B 
 .SH DESCRIPTION
@@ -72,6 +73,10 @@ at what level debugging statements should be logged to the
 .BR syslog (8)
 facility.
 .TP
+.BI \-n " service\-name"
+Specifies the service name for logging and other purposes.  Defaults
+to basename of argv[0], i.e.: "slapd".
+.TP
 .BI \-l " syslog\-local\-user"
 Selects the local user of the
 .BR syslog (8)
@@ -109,25 +114,6 @@ a DN or other optional parameters.  Hosts may be specified in either
 Internet '.' format (preferred) or by name.  Ports, if specfied,
 must be numeric.
 .TP
-.BI \-p " port\-number"
-.B slapd
-will use on the default port (389) for LDAP URLs unless this
-option is given to override the default.
-A numeric port number is expected.
-.TP
-.BI \-P " tls\-port\-number"
-.B slapd
-will use on the default port (636) for LDAPS (LDAP over TLS) URLs
-unless this option is given to override the default.  A numeric port
-number is expected.
-.TP
-.BI \-P " port\-number"
-Changes the port where 
-.B slapd
-will expect LDAP over raw TLS connections.  If this option is not given,
-the default port for this purpose (636) will be used.  A numeric port
-number is expected.
-.TP
 .BI \-u " user"
 .B slapd
 will run slapd with the specified user name or id, and that user's
@@ -172,8 +158,7 @@ on voluminous debugging which will be printed on standard error, type:
 .LP
 "The SLAPD and SLURPD Administrator's Guide"
 .SH BUGS
-When using the LDBM database backend, the Modify RDN operation does not
-update the attribute values in the entry that are affected by the change.
+See http://www.openldap.org/its/
 .SH ACKNOWLEDGEMENTS
 .B     OpenLDAP
 is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
index 51c8c14b0dc71c74a6a8efee553d2f3ececfd492..2b8fea8b5d6e867526d7e4af2f59bfe8ce6ebc79 100644 (file)
@@ -1,4 +1,7 @@
 .TH SLURPD 8C "22 September 1998" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 slurpd \- Standalone LDAP Update Replication Daemon
 .SH SYNOPSIS
diff --git a/doc/rfc/rfc1488.txt b/doc/rfc/rfc1488.txt
deleted file mode 100644 (file)
index ecafe75..0000000
+++ /dev/null
@@ -1,619 +0,0 @@
-
-
-
-
-
-
-Network Working Group                                         T. Howes
-Request for Comments: 1488                      University of Michigan
-                                                              S. Kille
-                                                      ISODE Consortium
-                                                              W. Yeong
-                                     Performance Systems International
-                                                            C. Robbins
-                                                            NeXor Ltd.
-                                                             July 1993
-
-
-     The X.500 String Representation of Standard Attribute Syntaxes
-
-Status of this Memo
-
-   This RFC specifies an IAB standards track protocol for the Internet
-   community, and requests discussion and suggestions for improvements.
-   Please refer to the current edition of the "IAB Official Protocol
-   Standards" for the standardization state and status of this protocol.
-   Distribution of this memo is unlimited.
-
-Abstract
-
-   The Lightweight Directory Access Protocol (LDAP) [9] requires that
-   the contents of AttributeValue fields in protocol elements be octet
-   strings.  This document defines the requirements that must be
-   satisfied by encoding rules used to render Directory attribute
-   syntaxes into a form suitable for use in the LDAP, then goes on to
-   define the encoding rules for the standard set of attribute syntaxes
-   defined in [1,2] and [3].
-
-1.  Attribute Syntax Encoding Requirements
-
-   This section defines general requirements for lightweight directory
-   protocol attribute syntax encodings. All documents defining attribute
-   syntax encodings for use by the lightweight directory protocols are
-   expected to conform to these requirements.
-
-   The encoding rules defined for a given attribute syntax must produce
-   octet strings.  To the greatest extent possible, encoded octet
-   strings should be usable in their native encoded form for display
-   purposes. In particular, encoding rules for attribute syntaxes
-   defining non-binary values should produce strings that can be
-   displayed with little or no translation by clients implementing the
-   lightweight directory protocols.
-
-
-
-
-
-
-Howes, Kille, Yeong & Robbins                                   [Page 1]
-\f
-RFC 1488                 X.500 Syntax Encoding                 July 1993
-
-
-2.  Standard Attribute Syntax Encodings
-
-   For the purposes of defining the encoding rules for the standard
-   attribute syntaxes, the following auxiliary BNF definitions will be
-   used:
-
-     <a> ::= 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' |
-             'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' |
-             's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | 'A' |
-             'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' |
-             'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' |
-             'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z'
-
-     <d> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
-
-     <hex-digit> ::= <d> | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' |
-                      'A' | 'B' | 'C' | 'D' | 'E' | 'F'
-
-     <k> ::= <a> | <d> | '-'
-
-     <p> ::= <a> | <d> | ''' | '(' | ')' | '+' | ',' | '-' | '.' |
-             '/' | ':' | '?' | ' '
-
-     <CRLF> ::= The ASCII newline character with hexadecimal value 0x0A
-
-     <letterstring> ::= <a> | <a> <letterstring>
-
-     <numericstring> ::= <d> | <d> <numericstring>
-
-     <keystring> ::= <a> | <a> <anhstring>
-
-     <anhstring> ::= <k> | <k> <anhstring>
-
-     <printablestring> ::= <p> | <p> <printablestring>
-
-     <space> ::= ' ' | ' ' <space>
-
-2.1.  Undefined
-
-   Values of type Undefined are encoded as if they were values of type
-   Octet String.
-
-2.2.  Case Ignore String
-
-   A string of type caseIgnoreStringSyntax is encoded as the string
-   value itself.
-
-
-
-
-
-Howes, Kille, Yeong & Robbins                                   [Page 2]
-\f
-RFC 1488                 X.500 Syntax Encoding                 July 1993
-
-
-2.3.  Case Exact String
-
-   The encoding of a string of type caseExactStringSyntax is the string
-   value itself.
-
-2.4.  Printable String
-
-   The encoding of a string of type printableStringSyntax is the string
-   value itself.
-
-2.5.  Numeric String
-
-   The encoding of a string of type numericStringSyntax is the string
-   value itself.
-
-2.6.  Octet String
-
-   The encoding of a string of type octetStringSyntax is the string
-   value itself.
-
-2.7.  Case Ignore IA5 String
-
-   The encoding of a string of type caseIgnoreIA5String is the string
-   value itself.
-
-2.8.  IA5 String
-
-   The encoding of a string of type iA5StringSyntax is the string value
-   itself.
-
-2.9.  T61 String
-
-   The encoding of a string of type t61StringSyntax is the string value
-   itself.
-
-2.10.  Case Ignore List
-
-   Values of type caseIgnoreListSyntax are encoded according to the
-   following BNF:
-
-     <caseignorelist> ::= <caseignorestring> |
-                          <caseignorestring> '$' <caseignorelist>
-
-     <caseignorestring> ::= a string encoded according to the rules
-                             for Case Ignore String as above.
-
-
-
-
-
-
-Howes, Kille, Yeong & Robbins                                   [Page 3]
-\f
-RFC 1488                 X.500 Syntax Encoding                 July 1993
-
-
-2.11.  Case Exact List
-
-   Values of type caseExactListSyntax are encoded according to the
-   following BNF:
-
-     <caseexactlist> ::= <caseexactstring> |
-                          <caseexactstring> '$' <caseexactlist>
-
-     <caseexactstring> ::= a string encoded according to the rules for
-                            Case Exact String as above.
-
-2.12.  Distinguished Name
-
-   Values of type distinguishedNameSyntax are encoded to have the
-   representation defined in [5].
-
-2.13.  Boolean
-
-   Values of type booleanSyntax are encoded according to the following
-   BNF:
-
-     <boolean> ::= "TRUE" | "FALSE"
-
-   Boolean values have an encoding of "TRUE" if they are logically true,
-   and have an encoding of "FALSE" otherwise.
-
-2.14.  Integer
-
-   Values of type integerSyntax are encoded as the decimal
-   representation of their values, with each decimal digit represented
-   by the its character equivalent. So the digit 1 is represented by the
-   character
-
-2.15.  Object Identifier
-
-   Values of type objectIdentifierSyntax are encoded according to the
-   following BNF:
-
-     <oid> ::= <descr> | <descr> '.' <numericoid> | <numericoid>
-
-     <descr> ::= <keystring>
-
-     <numericoid> ::= <numericstring> | <numericstring> '.' <numericoid>
-
-   In the above BNF, <descr> is the syntactic representation of an
-   object descriptor. When encoding values of type
-   objectIdentifierSyntax, the first encoding option should be used in
-   preference to the second, which should be used in preference to the
-
-
-
-Howes, Kille, Yeong & Robbins                                   [Page 4]
-\f
-RFC 1488                 X.500 Syntax Encoding                 July 1993
-
-
-   third wherever possible. That is, in encoding object identifiers,
-   object descriptors (where assigned and known by the implementation)
-   should be used in preference to numeric oids to the greatest extent
-   possible. For example, in encoding the object identifier representing
-   an organizationName, the descriptor "organizationName" is preferable
-   to "ds.4.10", which is in turn preferable to the string "2.5.4.10".
-
-2.16.  Telephone Number
-
-   Values of type telephoneNumberSyntax are encoded as if they were
-   Printable String types.
-
-2.17.  Telex Number
-
-   Values of type telexNumberSyntax are encoded according to the
-   following BNF:
-
-     <telex-number> ::= <actual-number> '$' <country> '$' <answerback>
-
-     <actual-number> ::= <printablestring>
-
-     <country> ::= <printablestring>
-
-     <answerback> ::= <printablestring>
-
-   In the above, <actual-number> is the syntactic representation of the
-   number portion of the TELEX number being encoded, <country> is the
-   TELEX country code, and <answerback> is the answerback code of a
-   TELEX terminal.
-
-2.18.  Teletex Terminal Identifier
-
-   Values of type teletexTerminalIdentifier are encoded according to the
-   following BNF:
-
-     <teletex-id> ::= <printablestring> 0*( '$' <printablestring>)
-
-   In the above, the first <printablestring> is the encoding of the
-   first portion of the teletex terminal identifier to be encoded, and
-   the subsequent 0 or more <printablestrings> are subsequent portions
-   of the teletex terminal identifier.
-
-2.19.  Facsimile Telephone Number
-
-   Values of type FacsimileTelephoneNumber are encoded according to the
-   following BNF:
-
- <fax-number> ::= <printablestring> [ '$' <faxparameters> ]
-
-
-
-Howes, Kille, Yeong & Robbins                                   [Page 5]
-\f
-RFC 1488                 X.500 Syntax Encoding                 July 1993
-
-
- <faxparameters> ::= <faxparm> | <faxparm> '$' <faxparameters>
-
- <faxparm> ::= 'twoDimensional' | 'fineResolution' | 'unlimitedLength' |
-               'b4Length' | 'a3Width' | 'b4Width' | 'uncompressed'
-
-   In the above, the first <printablestring> is the actual fax number,
-   and the <faxparm> tokens represent fax parameters.
-
-2.20.  Presentation Address
-
-   Values of type PresentationAddress are encoded to have the
-   representation described in [6].
-
-2.21.  UTC Time
-
-   Values of type uTCTimeSyntax are encoded as if they were Printable
-   Strings with the strings containing a UTCTime value.
-
-2.22.  Guide (search guide)
-
-   Values of type Guide, such as values of the searchGuide attribute,
-   are encoded according to the following BNF:
-
-     <guide-value> ::= [ <object-class> '#' ] <criteria>
-
-     <object-class> ::= an encoded value of type objectIdentifierSyntax
-
-     <criteria> ::= <criteria-item> | <criteria-set> | '!' <criteria>
-
-     <criteria-set> ::= [ '(' ] <criteria> '&' <criteria-set> [ ')' ] |
-                        [ '(' ] <criteria> '|' <criteria-set> [ ')' ]
-
-     <criteria-item> ::= [ '(' ] <attributetype> '$' <match-type> [ ')' ]
-
-     <match-type> ::= "EQ" | "SUBSTR" | "GE" | "LE" | "APPROX"
-
-2.23.  Postal Address
-
-Values of type PostalAddress are encoded according to the following BNF:
-
-     <postal-address> ::= <t61string> | <t61string> '$' <postal-address>
-
-   In the above, each <t61string> component of a postal address value is
-   encoded as a value of type t61StringSyntax.
-
-
-
-
-
-
-
-Howes, Kille, Yeong & Robbins                                   [Page 6]
-\f
-RFC 1488                 X.500 Syntax Encoding                 July 1993
-
-
-2.24.  User Password
-
-   Values of type userPasswordSyntax are encoded as if they were of type
-   octetStringSyntax.
-
-2.25.  User Certificate
-
-   Values of type userCertificate are encoded according to the following
-   BNF:
-
- <certificate> ::= <signature> '#' <issuer> '#' <validity> '#' <subject>
-                   '#' <public-key-info>
-
- <signature> ::= <algorithm-id>
-
- <issuer> ::= an encoded Distinguished Name
-
- <validity> ::= <not-before-time> '#' <not-after-time>
-
- <not-before-time> ::= <utc-time>
-
- <not-after-time> ::= <utc-time>
-
- <algorithm-parameters> ::=  <null> | <integervalue> |
-                             '{ASN}' <hex-string>
-
- <subject> ::= an encoded Distinguished Name
-
- <public-key-info> ::= <algorithm-id> '#' <encrypted-value>
-
- <encrypted-value> ::= <hex-string> | <hex-string> '-' <d>
-
- <algorithm-id> ::= <oid> '#' <algorithm-parameters>
-
- <utc-time> ::= an encoded UTCTime value
-
- <hex-string> ::= <hex-digit> | <hex-digit> <hex-string>
-
-2.26.  CA Certificate
-
-   Values of type cACertificate are encoded as if the values were of
-   type userCertificate.
-
-2.27.  Authority Revocation List
-
-   Values of type authorityRevocationList are encoded according to the
-   following BNF:
-
-
-
-
-Howes, Kille, Yeong & Robbins                                   [Page 7]
-\f
-RFC 1488                 X.500 Syntax Encoding                 July 1993
-
-
-     <certificate-list> ::= <signature> '#' <issuer> '#'
-                            <utc-time> [ '#' <revoked-certificates> ]
-
-     <revoked-certificates> ::= <algorithm> '#' <encrypted-value>
-                                [ '#' 0*(<revoked-certificate>) '#']
-
-     <revoked-certificates> ::= <subject> '#' <algorithm> '#'
-                                <serial> '#' <utc-time>
-
-   The syntactic components <algorithm>, <issuer>, <encrypted-value>,
-   <utc-time>, <subject> and <serial> have the same definitions as in
-   the BNF for the userCertificate attribute syntax.
-
-2.28.  Certificate Revocation List
-
-   Values of type certificateRevocationList are encoded as if the values
-   were of type authorityRevocationList.
-
-2.29.  Cross Certificate Pair
-
-   Values of type crossCertificatePair are encoded according to the
-   following BNF:
-
-     <certificate-pair> ::= <certificate> '|' <certificate>
-
-   The syntactic component <certificate> has the same definition as in
-   the BNF for the userCertificate attribute syntax.
-
-2.30.  Delivery Method
-
-   Values of type deliveryMethod are encoded according to the following
-   BNF:
-
-     <delivery-value> ::= <pdm> | <pdm> '$' <delivery-value>
-
-     <pdm> ::= 'any' | 'mhs' | 'physical' | 'telex' | 'teletex' |
-               'g3fax' | 'g4fax' | 'ia5' | 'videotex' | 'telephone'
-
-2.31.  Other Mailbox
-
-   Values of the type otherMailboxSyntax are encoded according to the
-   following BNF:
-
-     <otherMailbox> ::= <mailbox-type> '$' <mailbox>
-
-     <mailbox-type> ::= an encoded Printable String
-
-     <mailbox> ::= an encoded IA5 String
-
-
-
-Howes, Kille, Yeong & Robbins                                   [Page 8]
-\f
-RFC 1488                 X.500 Syntax Encoding                 July 1993
-
-
-   In the above, <mailbox-type> represents the type of mail system in
-   which the mailbox resides, for example "Internet" or "MCIMail"; and
-   <mailbox> is the actual mailbox in the mail system defined by
-   <mailbox-type>.
-
-2.32.  Mail Preference
-
-   Values of type mailPreferenceOption are encoded according to the
-   following BNF:
-
- <mail-preference> ::= "NO-LISTS" | "ANY-LIST" | "PROFESSIONAL-LISTS"
-
-2.33.  MHS OR Address
-
-   Values of type MHS OR Address are encoded as strings, according to
-   the format defined in [10].
-
-2.34.  Photo
-
-   Values of type Photo are encoded as if they were octet strings
-   containing JPEG images in the JPEG File Interchange Format (JFIF), as
-   described in [8].
-
-2.35.  Fax
-
-   Values of type Fax are encoded as if they were octet strings
-   containing Group 3 Fax images as defined in [7].
-
-3.  Acknowledgements
-
-   Many of the attribute syntax encodings defined in this document are
-   adapted from those used in the QUIPU X.500 implementation. The
-   contribu- tions of the authors of the QUIPU implementation in the
-   specification of the QUIPU syntaxes [4] are gratefully acknowledged.
-
-4.  Bibliography
-
-   [1] The Directory: Selected Attribute Syntaxes.  CCITT,
-       Recommendation X.520.
-
-   [2] Information Processing Systems -- Open Systems Interconnection --
-       The Directory: Selected Attribute Syntaxes.
-
-   [3] Barker, P., and S. Kille, "The COSINE and Internet X.500 Schema",
-       RFC 1274, University College London, November 1991.
-
-   [4] The ISO Development Environment: User's Manual -- Volume 5:
-       QUIPU.  Colin Robbins, Stephen E. Kille.
-
-
-
-Howes, Kille, Yeong & Robbins                                   [Page 9]
-\f
-RFC 1488                 X.500 Syntax Encoding                 July 1993
-
-
-   [5] Kille, S., "A String Representation of Distinguished Names", RFC
-       1485, July 1993.
-
-   [6] Kille, S., "A String Representation for Presentation Addresses",
-       RFC 1278, University College London, November 1991.
-
-   [7] Terminal Equipment and Protocols for Telematic Services -
-       Standardization of Group 3 facsimile apparatus for document
-       transmission.  CCITT, Recommendation T.4.
-
-   [8] JPEG File Interchange Format (Version 1.02).  Eric Hamilton, C-
-       Cube Microsystems, Milpitas, CA, September 1, 1992.
-
-   [9] Yeong, W., Howes, T., and S. Kille, "Lightweight Directory Access
-       Protocol", RFC 1487, Performance Systems International,
-       University of Michigan, ISODE Consortium, July 1993.
-
-  [10] Kille, S., "Mapping between X.400(1988)/ISO 10021 and RFC 822",
-       RFC 1327, University College London, May 1992.
-
-5.  Security Considerations
-
-   Security issues are not discussed in this memo.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Howes, Kille, Yeong & Robbins                                  [Page 10]
-\f
-RFC 1488                 X.500 Syntax Encoding                 July 1993
-
-
-6.  Authors' Addresses
-
-   Tim Howes
-   University of Michigan
-   ITD Research Systems
-   535 W William St.
-   Ann Arbor, MI 48103-4943
-   USA
-
-   Phone: +1 313 747-4454
-   EMail: tim@umich.edu
-
-
-   Steve Kille
-   ISODE Consortium
-   PO Box 505
-   London
-   SW11 1DX
-   UK
-
-   Phone: +44-71-223-4062
-   EMail: S.Kille@isode.com
-
-
-   Wengyik Yeong
-   PSI, Inc.
-   510 Huntmar Park Drive
-   Herndon, VA 22070
-   USA
-
-   Phone: +1 703-450-8001
-   EMail: yeongw@psilink.com
-
-
-   Colin Robbins
-   NeXor Ltd
-   University Park
-   Nottingham
-   NG7 2RD
-   UK
-
-
-
-
-
-
-
-
-
-
-
-Howes, Kille, Yeong & Robbins                                  [Page 11]
-\f
\ No newline at end of file
diff --git a/doc/rfc/rfc1558.txt b/doc/rfc/rfc1558.txt
deleted file mode 100644 (file)
index 1bb5bd9..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-
-
-
-
-
-
-Network Working Group                                           T. Howes
-Request for Comments: 1558                        University of Michigan
-Category: Informational                                    December 1993
-
-
-             A String Representation of LDAP Search Filters
-
-Status of this Memo
-
-   This memo provides information for the Internet community.  This memo
-   does not specify an Internet standard of any kind.  Distribution of
-   this memo is unlimited.
-
-Abstract
-
-   The Lightweight Directory Access Protocol (LDAP) [1] defines a
-   network representation of a search filter transmitted to an LDAP
-   server.  Some applications may find it useful to have a common way of
-   representing these search filters in a human-readable form.  This
-   document defines a human-readable string format for representing LDAP
-   search filters.
-
-1.  LDAP Search Filter Definition
-
-   An LDAP search filter is defined in [1] as follows:
-
-     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
-     }
-
-     SubstringFilter ::= SEQUENCE {
-             type    AttributeType,
-             SEQUENCE OF CHOICE {
-                     initial        [0] LDAPString,
-                     any            [1] LDAPString,
-                     final          [2] LDAPString
-             }
-     }
-
-
-
-
-
-Howes                                                           [Page 1]
-\f
-RFC 1558             Representation of LDAP Filters        December 1993
-
-
-     AttributeValueAssertion ::= SEQUENCE
-             attributeType   AttributeType,
-             attributeValue  AttributeValue
-     }
-
-     AttributeType ::= LDAPString
-
-     AttributeValue ::= OCTET STRING
-
-     LDAPString ::= OCTET STRING
-
-   where the LDAPString above is limited to the IA5 character set.  The
-   AttributeType is a string representation of the attribute object
-   identifier in dotted OID format (e.g., "2.5.4.10"), or the shorter
-   string name of the attribute (e.g., "organizationName", or "o").  The
-   AttributeValue OCTET STRING has the form defined in [2].  The Filter
-   is encoded for transmission over a network using the Basic Encoding
-   Rules defined in [3], with simplifications described in [1].
-
-2.  String Search Filter Definition
-
-   The string representation of an LDAP search filter is defined by the
-   following BNF.  It uses a prefix format.
-
-     <filter> ::= '(' <filtercomp> ')'
-     <filtercomp> ::= <and> | <or> | <not> | <item>
-     <and> ::= '&' <filterlist>
-     <or> ::= '|' <filterlist>
-     <not> ::= '!' <filter>
-     <filterlist> ::= <filter> | <filter> <filterlist>
-     <item> ::= <simple> | <present> | <substring>
-     <simple> ::= <attr> <filtertype> <value>
-     <filtertype> ::= <equal> | <approx> | <greater> | <less>
-     <equal> ::= '='
-     <approx> ::= '~='
-     <greater> ::= '>='
-     <less> ::= '<='
-     <present> ::= <attr> '=*'
-     <substring> ::= <attr> '=' <initial> <any> <final>
-     <initial> ::= NULL | <value>
-     <any> ::= '*' <starval>
-     <starval> ::= NULL | <value> '*' <starval>
-     <final> ::= NULL | <value>
-
-   <attr> is a string representing an AttributeType, and has the format
-   defined in [1].  <value> is a string representing an AttributeValue,
-   or part of one, and has the form defined in [2].  If a <value> must
-   contain one of the characters '*' or '(' or ')', these characters
-
-
-
-Howes                                                           [Page 2]
-\f
-RFC 1558             Representation of LDAP Filters        December 1993
-
-
-   should be escaped by preceding them with the backslash '\' character.
-
-3.  Examples
-
-   This section gives a few examples of search filters written using
-   this notation.
-
-     (cn=Babs Jensen)
-     (!(cn=Tim Howes))
-     (&(objectClass=Person)(|(sn=Jensen)(cn=Babs J*)))
-     (o=univ*of*mich*)
-
-4.  Security Considerations
-
-   Security issues are not discussed in this memo.
-
-5.  References
-
-   [1] Yeong, W., Howes, T., and S. Kille, "Lightweight Directory Access
-       Protocol", RFC 1487, Performance Systems International,
-       University of Michigan, ISODE Consortium, July 1993.
-
-   [2] Howes, T., Kille, S., Yeong, W., and C. Robbins, "The String
-       Representation of Standard Attribute Syntaxes", RFC 1488,
-       University of Michigan, ISODE Consortium, Performance Systems
-       International, NeXor Ltd., July 1993.
-
-   [3] "Specification of Basic Encoding Rules for Abstract Syntax
-       Notation One (ASN.1)", CCITT Recommendation X.209, 1988.
-
-6.  Author's Address
-
-       Tim Howes
-       University of Michigan
-       ITD Research Systems
-       535 W William St.
-       Ann Arbor, MI 48103-4943
-       USA
-
-       Phone: +1 313 747-4454
-       EMail: tim@umich.edu
-
-
-
-
-
-
-
-
-
-
-Howes                                                           [Page 3]
-\f
\ No newline at end of file
diff --git a/doc/rfc/rfc2119.txt b/doc/rfc/rfc2119.txt
new file mode 100644 (file)
index 0000000..e31fae4
--- /dev/null
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+Network Working Group                                         S. Bradner
+Request for Comments: 2119                            Harvard University
+BCP: 14                                                       March 1997
+Category: Best Current Practice
+
+
+        Key words for use in RFCs to Indicate Requirement Levels
+
+Status of this Memo
+
+   This document specifies an Internet Best Current Practices for the
+   Internet Community, and requests discussion and suggestions for
+   improvements.  Distribution of this memo is unlimited.
+
+Abstract
+
+   In many standards track documents several words are used to signify
+   the requirements in the specification.  These words are often
+   capitalized.  This document defines these words as they should be
+   interpreted in IETF documents.  Authors who follow these guidelines
+   should incorporate this phrase near the beginning of their document:
+
+      The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
+      NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and
+      "OPTIONAL" in this document are to be interpreted as described in
+      RFC 2119.
+
+   Note that the force of these words is modified by the requirement
+   level of the document in which they are used.
+
+1. MUST   This word, or the terms "REQUIRED" or "SHALL", mean that the
+   definition is an absolute requirement of the specification.
+
+2. MUST NOT   This phrase, or the phrase "SHALL NOT", mean that the
+   definition is an absolute prohibition of the specification.
+
+3. SHOULD   This word, or the adjective "RECOMMENDED", mean that there
+   may exist valid reasons in particular circumstances to ignore a
+   particular item, but the full implications must be understood and
+   carefully weighed before choosing a different course.
+
+4. SHOULD NOT   This phrase, or the phrase "NOT RECOMMENDED" mean that
+   there may exist valid reasons in particular circumstances when the
+   particular behavior is acceptable or even useful, but the full
+   implications should be understood and the case carefully weighed
+   before implementing any behavior described with this label.
+
+
+
+
+
+Bradner                  Best Current Practice                  [Page 1]
+\f
+RFC 2119                     RFC Key Words                    March 1997
+
+
+5. MAY   This word, or the adjective "OPTIONAL", mean that an item is
+   truly optional.  One vendor may choose to include the item because a
+   particular marketplace requires it or because the vendor feels that
+   it enhances the product while another vendor may omit the same item.
+   An implementation which does not include a particular option MUST be
+   prepared to interoperate with another implementation which does
+   include the option, though perhaps with reduced functionality. In the
+   same vein an implementation which does include a particular option
+   MUST be prepared to interoperate with another implementation which
+   does not include the option (except, of course, for the feature the
+   option provides.)
+
+6. Guidance in the use of these Imperatives
+
+   Imperatives of the type defined in this memo must be used with care
+   and sparingly.  In particular, they MUST only be used where it is
+   actually required for interoperation or to limit behavior which has
+   potential for causing harm (e.g., limiting retransmisssions)  For
+   example, they must not be used to try to impose a particular method
+   on implementors where the method is not required for
+   interoperability.
+
+7. Security Considerations
+
+   These terms are frequently used to specify behavior with security
+   implications.  The effects on security of not implementing a MUST or
+   SHOULD, or doing something the specification says MUST NOT or SHOULD
+   NOT be done may be very subtle. Document authors should take the time
+   to elaborate the security implications of not following
+   recommendations or requirements as most implementors will not have
+   had the benefit of the experience and discussion that produced the
+   specification.
+
+8. Acknowledgments
+
+   The definitions of these terms are an amalgam of definitions taken
+   from a number of RFCs.  In addition, suggestions have been
+   incorporated from a number of people including Robert Ullmann, Thomas
+   Narten, Neal McBurnett, and Robert Elz.
+
+
+
+
+
+
+
+
+
+
+
+
+Bradner                  Best Current Practice                  [Page 2]
+\f
+RFC 2119                     RFC Key Words                    March 1997
+
+
+9. Author's Address
+
+      Scott Bradner
+      Harvard University
+      1350 Mass. Ave.
+      Cambridge, MA 02138
+
+      phone - +1 617 495 3864
+
+      email - sob@harvard.edu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Bradner                  Best Current Practice                  [Page 3]
+\f
diff --git a/doc/rfc/rfc2222.txt b/doc/rfc/rfc2222.txt
new file mode 100644 (file)
index 0000000..2b0a2ab
--- /dev/null
@@ -0,0 +1,899 @@
+
+
+
+
+
+
+Network Working Group                                           J. Myers
+Request for Comments: 2222                       Netscape Communications
+Category: Standards Track                                   October 1997
+
+
+            Simple Authentication and Security Layer (SASL)
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (1997).  All Rights Reserved.
+
+Table of Contents
+
+   1.    Abstract ..............................................    2
+   2.    Organization of this Document .........................    2
+   2.1.  How to Read This Document .............................    2
+   2.2.  Conventions Used in this Document .....................    2
+   2.3.  Examples ..............................................    3
+   3.    Introduction and Overview .............................    3
+   4.    Profiling requirements ................................    4
+   5.    Specific issues .......................................    5
+   5.1.  Client sends data first ...............................    5
+   5.2.  Server returns success with additional data ...........    5
+   5.3.  Multiple authentications ..............................    5
+   6.    Registration procedures ...............................    6
+   6.1.  Comments on SASL mechanism registrations ..............    6
+   6.2.  Location of Registered SASL Mechanism List ............    6
+   6.3.  Change Control ........................................    7
+   6.4.  Registration Template .................................    7
+   7.    Mechanism definitions .................................    8
+   7.1.  Kerberos version 4 mechanism ..........................    8
+   7.2.  GSSAPI mechanism ......................................    9
+   7.2.1 Client side of authentication protocol exchange .......    9
+   7.2.2 Server side of authentication protocol exchange .......   10
+   7.2.3 Security layer ........................................   11
+   7.3.  S/Key mechanism .......................................   11
+   7.4.  External mechanism ....................................   12
+   8.    References ............................................   13
+   9.    Security Considerations ...............................   13
+   10.   Author's Address ......................................   14
+
+
+
+Myers                       Standards Track                     [Page 1]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+   Appendix A. Relation of SASL to Transport Security ..........   15
+   Full Copyright Statement ....................................   16
+
+1.    Abstract
+
+   This document describes a method for adding authentication support to
+   connection-based protocols.  To use this specification, a protocol
+   includes a command for identifying and authenticating a user to a
+   server and for optionally negotiating protection of subsequent
+   protocol interactions.  If its use is negotiated, a security layer is
+   inserted between the protocol and the connection.  This document
+   describes how a protocol specifies such a command, defines several
+   mechanisms for use by the command, and defines the protocol used for
+   carrying a negotiated security layer over the connection.
+
+2.    Organization of this Document
+
+2.1.  How to Read This Document
+
+   This document is written to serve two different audiences, protocol
+   designers using this specification to support authentication in their
+   protocol, and implementors of clients or servers for those protocols
+   using this specification.
+
+   The sections "Introduction and Overview", "Profiling requirements",
+   and "Security Considerations" cover issues that protocol designers
+   need to understand and address in profiling this specification for
+   use in a specific protocol.
+
+   Implementors of a protocol using this specification need the
+   protocol-specific profiling information in addition to the
+   information in this document.
+
+2.2.  Conventions Used in this Document
+
+   In examples, "C:" and "S:" indicate lines sent by the client and
+   server respectively.
+
+   The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY"
+   in this document are to be interpreted as defined in "Key words for
+   use in RFCs to Indicate Requirement Levels" [RFC 2119].
+
+
+
+
+
+
+
+
+
+
+Myers                       Standards Track                     [Page 2]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+2.3.  Examples
+
+   Examples in this document are for the IMAP profile [RFC 2060] of this
+   specification.  The base64 encoding of challenges and responses, as
+   well as the "+ " preceding the responses are part of the IMAP4
+   profile, not part of the SASL specification itself.
+
+3.    Introduction and Overview
+
+   The Simple Authentication and Security Layer (SASL) is a method for
+   adding authentication support to connection-based protocols.  To use
+   this specification, a protocol includes a command for identifying and
+   authenticating a user to a server and for optionally negotiating a
+   security layer for subsequent protocol interactions.
+
+   The command has a required argument identifying a SASL mechanism.
+   SASL mechanisms are named by strings, from 1 to 20 characters in
+   length, consisting of upper-case letters, digits, hyphens, and/or
+   underscores.  SASL mechanism names must be registered with the IANA.
+   Procedures for registering new SASL mechanisms are given in the
+   section "Registration procedures"
+
+   If a server supports the requested mechanism, it initiates an
+   authentication protocol exchange.  This consists of a series of
+   server challenges and client responses that are specific to the
+   requested mechanism.  The challenges and responses are defined by the
+   mechanisms as binary tokens of arbitrary length.  The protocol's
+   profile then specifies how these binary tokens are then encoded for
+   transfer over the connection.
+
+   After receiving the authentication command or any client response, a
+   server may issue a challenge, indicate failure, or indicate
+   completion.  The protocol's profile specifies how the server
+   indicates which of the above it is doing.
+
+   After receiving a challenge, a client may issue a response or abort
+   the exchange.  The protocol's profile specifies how the client
+   indicates which of the above it is doing.
+
+   During the authentication protocol exchange, the mechanism performs
+   authentication, transmits an authorization identity (frequently known
+   as a userid) from the client to server, and negotiates the use of a
+   mechanism-specific security layer.  If the use of a security layer is
+   agreed upon, then the mechanism must also define or negotiate the
+   maximum cipher-text buffer size that each side is able to receive.
+
+
+
+
+
+
+Myers                       Standards Track                     [Page 3]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+   The transmitted authorization identity may be different than the
+   identity in the client's authentication credentials.  This permits
+   agents such as proxy servers to authenticate using their own
+   credentials, yet request the access privileges of the identity for
+   which they are proxying.  With any mechanism, transmitting an
+   authorization identity of the empty string directs the server to
+   derive an authorization identity from the client's authentication
+   credentials.
+
+   If use of a security layer is negotiated, it is applied to all
+   subsequent data sent over the connection.  The security layer takes
+   effect immediately following the last response of the authentication
+   exchange for data sent by the client and the completion indication
+   for data sent by the server.  Once the security layer is in effect,
+   the protocol stream is processed by the security layer into buffers
+   of cipher-text.  Each buffer is transferred over the connection as a
+   stream of octets prepended with a four octet field in network byte
+   order that represents the length of the following buffer.  The length
+   of the cipher-text buffer must be no larger than the maximum size
+   that was defined or negotiated by the other side.
+
+4.    Profiling requirements
+
+   In order to use this specification, a protocol definition must supply
+   the following information:
+
+   1. A service name, to be selected from the IANA registry of "service"
+      elements for the GSSAPI host-based service name form [RFC 2078].
+
+   2. A definition of the command to initiate the authentication
+      protocol exchange.  This command must have as a parameter the
+      mechanism name being selected by the client.
+
+      The command SHOULD have an optional parameter giving an initial
+      response.  This optional parameter allows the client to avoid a
+      round trip when using a mechanism which is defined to have the
+      client send data first.  When this initial response is sent by the
+      client and the selected mechanism is defined to have the server
+      start with an initial challenge, the command fails.  See section
+      5.1 of this document for further information.
+
+   3. A definition of the method by which the authentication protocol
+      exchange is carried out, including how the challenges and
+      responses are encoded, how the server indicates completion or
+      failure of the exchange, how the client aborts an exchange, and
+      how the exchange method interacts with any line length limits in
+      the protocol.
+
+
+
+
+Myers                       Standards Track                     [Page 4]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+   4. Identification of the octet where any negotiated security layer
+      starts to take effect, in both directions.
+
+   5. A specification of how the authorization identity passed from the
+      client to the server is to be interpreted.
+
+5.    Specific issues
+
+5.1.  Client sends data first
+
+   Some mechanisms specify that the first data sent in the
+   authentication protocol exchange is from the client to the server.
+
+   If a protocol's profile permits the command which initiates an
+   authentication protocol exchange to contain an initial client
+   response, this parameter SHOULD be used with such mechanisms.
+
+   If the initial client response parameter is not given, or if a
+   protocol's profile does not permit the command which initiates an
+   authentication protocol exchange to contain an initial client
+   response, then the server issues a challenge with no data.  The
+   client's response to this challenge is then used as the initial
+   client response.  (The server then proceeds to send the next
+   challenge, indicates completion, or indicates failure.)
+
+5.2.  Server returns success with additional data
+
+   Some mechanisms may specify that server challenge data be sent to the
+   client along with an indication of successful completion of the
+   exchange.  This data would, for example, authenticate the server to
+   the client.
+
+   If a protocol's profile does not permit this server challenge to be
+   returned with a success indication, then the server issues the server
+   challenge without an indication of successful completion.  The client
+   then responds with no data.  After receiving this empty response, the
+   server then indicates successful completion.
+
+5.3.  Multiple authentications
+
+   Unless otherwise stated by the protocol's profile, only one
+   successful SASL negotiation may occur in a protocol session.  In this
+   case, once an authentication protocol exchange has successfully
+   completed, further attempts to initiate an authentication protocol
+   exchange fail.
+
+
+
+
+
+
+Myers                       Standards Track                     [Page 5]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+   In the case that a profile explicitly permits multiple successful
+   SASL negotiations to occur, then in no case may multiple security
+   layers be simultaneously in effect.  If a security layer is in effect
+   and a subsequent SASL negotiation selects no security layer, the
+   original security layer remains in effect.  If a security layer is in
+   effect and a subsequent SASL negotiation selects a second security
+   layer, then the second security layer replaces the first.
+
+6.    Registration procedures
+
+   Registration of a SASL mechanism is done by filling in the template
+   in section 6.4 and sending it in to iana@isi.edu.  IANA has the right
+   to reject obviously bogus registrations, but will perform no review
+   of clams made in the registration form.
+
+   There is no naming convention for SASL mechanisms; any name that
+   conforms to the syntax of a SASL mechanism name can be registered.
+
+   While the registration procedures do not require it, authors of SASL
+   mechanisms are encouraged to seek community review and comment
+   whenever that is feasible.  Authors may seek community review by
+   posting a specification of their proposed mechanism as an internet-
+   draft.  SASL mechanisms intended for widespread use should be
+   standardized through the normal IETF process, when appropriate.
+
+6.1.  Comments on SASL mechanism registrations
+
+   Comments on registered SASL mechanisms should first be sent to the
+   "owner" of the mechanism.  Submitters of comments may, after a
+   reasonable attempt to contact the owner, request IANA to attach their
+   comment to the SASL mechanism registration itself.  If IANA approves
+   of this the comment will be made accessible in conjunction with the
+   SASL mechanism registration itself.
+
+6.2.  Location of Registered SASL Mechanism List
+
+   SASL mechanism registrations will be posted in the anonymous FTP
+   directory "ftp://ftp.isi.edu/in-notes/iana/assignments/sasl-
+   mechanisms/" and all registered SASL mechanisms will be listed in the
+   periodically issued "Assigned Numbers" RFC [currently STD 2, RFC
+   1700].  The SASL mechanism description and other supporting material
+   may also be published as an Informational RFC by sending it to "rfc-
+   editor@isi.edu" (please follow the instructions to RFC authors [RFC
+   2223]).
+
+
+
+
+
+
+
+Myers                       Standards Track                     [Page 6]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+6.3.  Change Control
+
+   Once a SASL mechanism registration has been published by IANA, the
+   author may request a change to its definition.  The change request
+   follows the same procedure as the registration request.
+
+   The owner of a SASL mechanism may pass responsibility for the SASL
+   mechanism to another person or agency by informing IANA; this can be
+   done without discussion or review.
+
+   The IESG may reassign responsibility for a SASL mechanism. The most
+   common case of this will be to enable changes to be made to
+   mechanisms where the author of the registration has died, moved out
+   of contact or is otherwise unable to make changes that are important
+   to the community.
+
+   SASL mechanism registrations may not be deleted; mechanisms which are
+   no longer believed appropriate for use can be declared OBSOLETE by a
+   change to their "intended use" field; such SASL mechanisms will be
+   clearly marked in the lists published by IANA.
+
+   The IESG is considered to be the owner of all SASL mechanisms which
+   are on the IETF standards track.
+
+6.4.  Registration Template
+
+   To: iana@iana.org
+   Subject: Registration of SASL mechanism X
+
+   SASL mechanism name:
+
+   Security considerations:
+
+   Published specification (optional, recommended):
+
+   Person & email address to contact for further information:
+
+   Intended usage:
+
+   (One of COMMON, LIMITED USE or OBSOLETE)
+
+   Author/Change controller:
+
+   (Any other information that the author deems interesting may be
+   added below this line.)
+
+
+
+
+
+
+Myers                       Standards Track                     [Page 7]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+7.    Mechanism definitions
+
+   The following mechanisms are hereby defined.
+
+7.1.  Kerberos version 4 mechanism
+
+   The mechanism name associated with Kerberos version 4 is
+   "KERBEROS_V4".
+
+   The first challenge consists of a random 32-bit number in network
+   byte order.  The client responds with a Kerberos ticket and an
+   authenticator for the principal "service.hostname@realm", where
+   "service" is the service name specified in the protocol's profile,
+   "hostname" is the first component of the host name of the server with
+   all letters in lower case, and where "realm" is the Kerberos realm of
+   the server.  The encrypted checksum field included within the
+   Kerberos authenticator contains the server provided challenge in
+   network byte order.
+
+   Upon decrypting and verifying the ticket and authenticator, the
+   server verifies that the contained checksum field equals the original
+   server provided random 32-bit number.  Should the verification be
+   successful, the server must add one to the checksum and construct 8
+   octets of data, with the first four octets containing the incremented
+   checksum in network byte order, the fifth octet containing a bit-mask
+   specifying the security layers supported by the server, and the sixth
+   through eighth octets containing, in network byte order, the maximum
+   cipher-text buffer size the server is able to receive.  The server
+   must encrypt using DES ECB mode the 8 octets of data in the session
+   key and issue that encrypted data in a second challenge.  The client
+   considers the server authenticated if the first four octets of the
+   un-encrypted data is equal to one plus the checksum it previously
+   sent.
+
+   The client must construct data with the first four octets containing
+   the original server-issued checksum in network byte order, the fifth
+   octet containing the bit-mask specifying the selected security layer,
+   the sixth through eighth octets containing in network byte order the
+   maximum cipher-text buffer size the client is able to receive, and
+   the following octets containing the authorization identity.  The
+   client must then append from one to eight zero-valued octets so that
+   the length of the data is a multiple of eight octets. The client must
+   then encrypt using DES PCBC mode the data with the session key and
+   respond with the encrypted data.  The server decrypts the data and
+   verifies the contained checksum.  The server must verify that the
+   principal identified in the Kerberos ticket is authorized to connect
+   as that authorization identity.  After this verification, the
+   authentication process is complete.
+
+
+
+Myers                       Standards Track                     [Page 8]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+   The security layers and their corresponding bit-masks are as follows:
+
+      1 No security layer
+      2 Integrity (krb_mk_safe) protection
+      4 Privacy (krb_mk_priv) protection
+
+   Other bit-masks may be defined in the future; bits which are not
+   understood must be negotiated off.
+
+   EXAMPLE: The following are two Kerberos version 4 login scenarios to
+   the IMAP4 protocol (note that the line breaks in the sample
+   authenticators are for editorial clarity and are not in real
+   authenticators)
+
+     S: * OK IMAP4 Server
+     C: A001 AUTHENTICATE KERBEROS_V4
+     S: + AmFYig==
+     C: BAcAQU5EUkVXLkNNVS5FRFUAOCAsho84kLN3/IJmrMG+25a4DT
+        +nZImJjnTNHJUtxAA+o0KPKfHEcAFs9a3CL5Oebe/ydHJUwYFd
+        WwuQ1MWiy6IesKvjL5rL9WjXUb9MwT9bpObYLGOKi1Qh
+     S: + or//EoAADZI=
+     C: DiAF5A4gA+oOIALuBkAAmw==
+     S: A001 OK Kerberos V4 authentication successful
+
+
+     S: * OK IMAP4 Server
+     C: A001 AUTHENTICATE KERBEROS_V4
+     S: + gcfgCA==
+     C: BAcAQU5EUkVXLkNNVS5FRFUAOCAsho84kLN3/IJmrMG+25a4DT
+        +nZImJjnTNHJUtxAA+o0KPKfHEcAFs9a3CL5Oebe/ydHJUwYFd
+        WwuQ1MWiy6IesKvjL5rL9WjXUb9MwT9bpObYLGOKi1Qh
+     S: A001 NO Kerberos V4 authentication failed
+
+7.2.  GSSAPI mechanism
+
+   The mechanism name associated with all mechanisms employing the
+   GSSAPI [RFC 2078] is "GSSAPI".
+
+7.2.1 Client side of authentication protocol exchange
+
+   The client calls GSS_Init_sec_context, passing in 0 for
+   input_context_handle (initially) and a targ_name equal to output_name
+   from GSS_Import_Name called with input_name_type of
+   GSS_C_NT_HOSTBASED_SERVICE and input_name_string of
+   "service@hostname" where "service" is the service name specified in
+   the protocol's profile, and "hostname" is the fully qualified host
+   name of the server.  The client then responds with the resulting
+   output_token.  If GSS_Init_sec_context returns GSS_S_CONTINUE_NEEDED,
+
+
+
+Myers                       Standards Track                     [Page 9]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+   then the client should expect the server to issue a token in a
+   subsequent challenge.  The client must pass the token to another call
+   to GSS_Init_sec_context, repeating the actions in this paragraph.
+
+   When GSS_Init_sec_context returns GSS_S_COMPLETE, the client takes
+   the following actions: If the last call to GSS_Init_sec_context
+   returned an output_token, then the client responds with the
+   output_token, otherwise the client responds with no data.  The client
+   should then expect the server to issue a token in a subsequent
+   challenge.  The client passes this token to GSS_Unwrap and interprets
+   the first octet of resulting cleartext as a bit-mask specifying the
+   security layers supported by the server and the second through fourth
+   octets as the maximum size output_message to send to the server.  The
+   client then constructs data, with the first octet containing the
+   bit-mask specifying the selected security layer, the second through
+   fourth octets containing in network byte order the maximum size
+   output_message the client is able to receive, and the remaining
+   octets containing the authorization identity.  The client passes the
+   data to GSS_Wrap with conf_flag set to FALSE, and responds with the
+   generated output_message.  The client can then consider the server
+   authenticated.
+
+7.2.2 Server side of authentication protocol exchange
+
+   The server passes the initial client response to
+   GSS_Accept_sec_context as input_token, setting input_context_handle
+   to 0 (initially).  If GSS_Accept_sec_context returns
+   GSS_S_CONTINUE_NEEDED, the server returns the generated output_token
+   to the client in challenge and passes the resulting response to
+   another call to GSS_Accept_sec_context, repeating the actions in this
+   paragraph.
+
+   When GSS_Accept_sec_context returns GSS_S_COMPLETE, the client takes
+   the following actions: If the last call to GSS_Accept_sec_context
+   returned an output_token, the server returns it to the client in a
+   challenge and expects a reply from the client with no data.  Whether
+   or not an output_token was returned (and after receipt of any
+   response from the client to such an output_token), the server then
+   constructs 4 octets of data, with the first octet containing a bit-
+   mask specifying the security layers supported by the server and the
+   second through fourth octets containing in network byte order the
+   maximum size output_token the server is able to receive.  The server
+   must then pass the plaintext to GSS_Wrap with conf_flag set to FALSE
+   and issue the generated output_message to the client in a challenge.
+   The server must then pass the resulting response to GSS_Unwrap and
+   interpret the first octet of resulting cleartext as the bit-mask for
+   the selected security layer, the second through fourth octets as the
+   maximum size output_message to send to the client, and the remaining
+
+
+
+Myers                       Standards Track                    [Page 10]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+   octets as the authorization identity.  The server must verify that
+   the src_name is authorized to authenticate as the authorization
+   identity.  After these verifications, the authentication process is
+   complete.
+
+7.2.3 Security layer
+
+   The security layers and their corresponding bit-masks are as follows:
+
+     1 No security layer
+     2 Integrity protection.
+       Sender calls GSS_Wrap with conf_flag set to FALSE
+     4 Privacy protection.
+       Sender calls GSS_Wrap with conf_flag set to TRUE
+
+   Other bit-masks may be defined in the future; bits which are not
+   understood must be negotiated off.
+
+7.3.  S/Key mechanism
+
+   The mechanism name associated with S/Key [RFC 1760] using the MD4
+   digest algorithm is "SKEY".
+
+   The client sends an initial response with the authorization identity.
+
+   The server then issues a challenge which contains the decimal
+   sequence number followed by a single space and the seed string for
+   the indicated authorization identity.  The client responds with the
+   one-time-password, as either a 64-bit value in network byte order or
+   encoded in the "six English words" format.
+
+   The server must verify the one-time-password.  After this
+   verification, the authentication process is complete.
+
+   S/Key authentication does not provide for any security layers.
+
+   EXAMPLE: The following are two S/Key login scenarios in the IMAP4
+   protocol.
+
+     S: * OK IMAP4 Server
+     C: A001 AUTHENTICATE SKEY
+     S: +
+     C: bW9yZ2Fu
+     S: + OTUgUWE1ODMwOA==
+     C: Rk9VUiBNQU5OIFNPT04gRklSIFZBUlkgTUFTSA==
+     S: A001 OK S/Key authentication successful
+
+
+
+
+
+Myers                       Standards Track                    [Page 11]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+     S: * OK IMAP4 Server
+     C: A001 AUTHENTICATE SKEY
+     S: +
+     C: c21pdGg=
+     S: + OTUgUWE1ODMwOA==
+     C: BsAY3g4gBNo=
+     S: A001 NO S/Key authentication failed
+
+   The following is an S/Key login scenario in an IMAP4-like protocol
+   which has an optional "initial response" argument to the AUTHENTICATE
+   command.
+
+     S: * OK IMAP4-Like Server
+     C: A001 AUTHENTICATE SKEY bW9yZ2Fu
+     S: + OTUgUWE1ODMwOA==
+     C: Rk9VUiBNQU5OIFNPT04gRklSIFZBUlkgTUFTSA==
+     S: A001 OK S/Key authentication successful
+
+7.4.  External mechanism
+
+   The mechanism name associated with external authentication is
+   "EXTERNAL".
+
+   The client sends an initial response with the authorization identity.
+
+   The server uses information, external to SASL, to determine whether
+   the client is authorized to authenticate as the authorization
+   identity.  If the client is so authorized, the server indicates
+   successful completion of the authentication exchange; otherwise the
+   server indicates failure.
+
+   The system providing this external information may be, for example,
+   IPsec or TLS.
+
+   If the client sends the empty string as the authorization identity
+   (thus requesting the authorization identity be derived from the
+   client's authentication credentials), the authorization identity is
+   to be derived from authentication credentials which exist in the
+   system which is providing the external authentication.
+
+
+
+
+
+
+
+
+
+
+
+
+Myers                       Standards Track                    [Page 12]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+8.    References
+
+   [RFC 2060] Crispin, M., "Internet Message Access Protocol - Version
+              4rev1", RFC 2060, December 1996.
+
+   [RFC 2078] Linn, J., "Generic Security Service Application Program
+              Interface, Version 2", RFC 2078, January 1997.
+
+   [RFC 2119] Bradner, S., "Key words for use in RFCs to Indicate
+              Requirement Levels", RFC 2119, March 1997.
+
+   [RFC 2223] Postel, J., and J. Reynolds, "Instructions to RFC
+              Authors", RFC 2223, October 1997.
+
+   [RFC 1760] Haller, N., "The S/Key One-Time Password System", RFC
+              1760, February 1995.
+
+   [RFC 1700] Reynolds, J., and J. Postel, "Assigned Numbers", STD 2,
+              RFC 1700, October 1994.
+
+9.    Security Considerations
+
+   Security issues are discussed throughout this memo.
+
+   The mechanisms that support integrity protection are designed such
+   that the negotiation of the security layer and authorization identity
+   is integrity protected.  When the client selects a security layer
+   with at least integrity protection, this protects against an active
+   attacker hijacking the connection and modifying the authentication
+   exchange to negotiate a plaintext connection.
+
+   When a server or client supports multiple authentication mechanisms,
+   each of which has a different security strength, it is possible for
+   an active attacker to cause a party to use the least secure mechanism
+   supported.  To protect against this sort of attack, a client or
+   server which supports mechanisms of different strengths should have a
+   configurable minimum strength that it will use.  It is not sufficient
+   for this minimum strength check to only be on the server, since an
+   active attacker can change which mechanisms the client sees as being
+   supported, causing the client to send authentication credentials for
+   its weakest supported mechanism.
+
+
+
+
+
+
+
+
+
+
+Myers                       Standards Track                    [Page 13]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+   The client's selection of a SASL mechanism is done in the clear and
+   may be modified by an active attacker.  It is important for any new
+   SASL mechanisms to be designed such that an active attacker cannot
+   obtain an authentication with weaker security properties by modifying
+   the SASL mechanism name and/or the challenges and responses.
+
+   Any protocol interactions prior to authentication are performed in
+   the clear and may be modified by an active attacker.  In the case
+   where a client selects integrity protection, it is important that any
+   security-sensitive protocol negotiations be performed after
+   authentication is complete.  Protocols should be designed such that
+   negotiations performed prior to authentication should be either
+   ignored or revalidated once authentication is complete.
+
+10.   Author's Address
+
+   John G. Myers
+   Netscape Communications
+   501 E. Middlefield Road
+   Mail Stop MV-029
+   Mountain View, CA 94043-4042
+
+   EMail: jgmyers@netscape.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Myers                       Standards Track                    [Page 14]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+Appendix A. Relation of SASL to Transport Security
+
+   Questions have been raised about the relationship between SASL and
+   various services (such as IPsec and TLS) which provide a secured
+   connection.
+
+   Two of the key features of SASL are:
+
+   1. The separation of the authorization identity from the identity in
+      the client's credentials.  This permits agents such as proxy
+      servers to authenticate using their own credentials, yet request
+      the access privileges of the identity for which they are proxying.
+
+   2. Upon successful completion of an authentication exchange, the
+      server knows the authorization identity the client wishes to use.
+      This allows servers to move to a "user is authenticated" state in
+      the protocol.
+
+   These features are extremely important to some application protocols,
+   yet Transport Security services do not always provide them.  To
+   define SASL mechanisms based on these services would be a very messy
+   task, as the framing of these services would be redundant with the
+   framing of SASL and some method of providing these important SASL
+   features would have to be devised.
+
+   Sometimes it is desired to enable within an existing connection the
+   use of a security service which does not fit the SASL model.  (TLS is
+   an example of such a service.)  This can be done by adding a command,
+   for example "STARTTLS", to the protocol.  Such a command is outside
+   the scope of SASL, and should be different from the command which
+   starts a SASL authentication protocol exchange.
+
+   In certain situations, it is reasonable to use SASL underneath one of
+   these Transport Security services.  The transport service would
+   secure the connection, either service would authenticate the client,
+   and SASL would negotiate the authorization identity.  The SASL
+   negotiation would be what moves the protocol from "unauthenticated"
+   to "authenticated" state.  The "EXTERNAL" SASL mechanism is
+   explicitly intended to handle the case where the transport service
+   secures the connection and authenticates the client and SASL
+   negotiates the authorization identity.
+
+   When using SASL underneath a sufficiently strong Transport Security
+   service, a SASL security layer would most likely be redundant.  The
+   client and server would thus probably want to negotiate off the use
+   of a SASL security layer.
+
+
+
+
+
+Myers                       Standards Track                    [Page 15]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+Full Copyright Statement
+
+   Copyright (C) The Internet Society (1997).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implmentation may be prepared, copied, published
+   andand distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Myers                       Standards Track                    [Page 16]
+\f
diff --git a/doc/rfc/rfc2649.txt b/doc/rfc/rfc2649.txt
new file mode 100644 (file)
index 0000000..fb5f38e
--- /dev/null
@@ -0,0 +1,563 @@
+
+
+
+
+
+
+Network Working Group                                       B. Greenblatt
+Request for Comments: 2649                                     P. Richard
+Category: Experimental                                        August 1999
+
+
+      An LDAP Control and Schema for Holding Operation Signatures
+
+Status of this Memo
+
+   This memo defines an Experimental Protocol for the Internet
+   community.  It does not specify an Internet standard of any kind.
+   Discussion and suggestions for improvement are requested.
+   Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (1999).  All Rights Reserved.
+
+Abstract
+
+   In many environments clients require the ability to validiate the
+   source and integrity of information provided by the directory.  This
+   document describes an LDAP message control which allows for the
+   retrieval of digitally signed information. This document defines an
+   LDAP v3 based mechanism for signing directory operations in order to
+   create a secure journal of changes that have been made to each
+   directory entry.  Both client and server based signatures are
+   supported.  An object class for subsequent retrieval are "journal
+   entries" is also defined.  This document specifies LDAP v3 controls
+   that enable this functionality.  It also defines an LDAP v3 schema
+   that allows for subsequent browsing of the journal information.
+
+Table of Contents
+
+   1. Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   2
+   1.1 Audit Trail Mechanism  . . . . . . . . . . . . . . . . . . .   2
+   1.2. Handling the Delete Operation . . . . . . . . . . . . . . .   5
+   2. Signed Results Mechanism  . . . . . . . . . . . . . . . . . .   6
+   3. Security Considerations and Other Notes   . . . . . . . . . .   7
+   4. References  . . . . . . . . . . . . . . . . . . . . . . . . .   8
+   5. Authors' Addresses  . . . . . . . . . . . . . . . . . . . . .   9
+   6. Full Copyright Statement  . . . . . . . . . . . . . . . . . .  10
+
+
+
+
+
+
+
+
+
+Greenblatt & Richard          Experimental                      [Page 1]
+\f
+RFC 2649                LDAP Control and Schema              August 1999
+
+
+1.  Introduction
+
+   In many environments clients require the ability to validiate the
+   source and integrity of information provided by the directory.  This
+   document describes an LDAP message control which allows for the
+   retrieval of digitally signed information.  The perspective of this
+   document is that the origin of the information that is stored in LDAP
+   v3 accessible directories is the LDAP v3 client that creates the
+   information.  The source and integrity of the information is
+   guaranteed by allowing for the digital signing of the operations that
+   make changes to entries in the directory.  The source and integrity
+   of an individual LDAP connection can be guaranteed by making use of
+   an underlying session layer that provides such services, such as TLS.
+   Note that the integrity of an individual connection does not, in and
+   of itself guarantee the integrity of the data that comes across the
+   connection.  This is due to the fact that the LDAP server is only
+   capable of providing information that it has stored.  In distributed
+   and replicated environments, the fact that an entry has been
+   successfully retrieved from a server may not be completely
+   reassuring, if the entry in question was replicated from an untrusted
+   domain.
+
+   By making use of public key technology, and creating digitally signed
+   transactions that are created by the LDAP v3 client as entries are
+   created and modified, a complete journal of the history of the entry
+   is available.  Since each entry in the journal has been digitally
+   signed with the private key of the creator, or modifier of the entry,
+   the source and integrity of the directory entry can be validated by
+   verifying the signature of each entry in the journal.  Note that not
+   all of the journal entries will have been signed by the same user.
+
+1.1.  Audit Trail Mechanism
+
+   Signed directory operations is a straightforward application of
+   S/MIME technology that also leverages the extensible framework that
+   is provided by LDAP version 3.  LDAP version 3 is defined in [4], and
+   S/MIME is defined in [2].  The security used in S/MIME is based in
+   the definitions in [1].  The basic idea is that the submitter of an
+   LDAP operation that changes the directory information includes an
+   LDAP version 3 control that includes either a signature of the
+   operation, or a request that the LDAP server sign the operation on
+   the behalf of the LDAP client.  The result of the operation (in
+   addition to the change of the directory information), is additional
+   information that is attached to directory objects, that includes the
+   audit trail of signed operations.  The LDAP control is (OID =
+   1.2.840.113549.6.0.0):
+
+
+
+
+
+Greenblatt & Richard          Experimental                      [Page 2]
+\f
+RFC 2649                LDAP Control and Schema              August 1999
+
+
+      SignedOperation ::= CHOICE {
+           signbyServer   NULL,
+           signatureIncluded   OCTET STRING
+       }
+
+   If the SignatureIncluded CHOICE is used, then the OCTET string is
+   just an S/MIME message of the multipart/signed variety, that is
+   composed of a single piece, that is the signature of the directory
+   operation.  Multipart/signed MIME objects are defined in [3].  If the
+   SignbyServer CHOICE us used, then the LDAP server creates the
+   signature on behalf of the client, using its own identity and not the
+   identity of the client, in order to produce the audit trail entry.
+   In either case the successful result of processing the control is the
+   creation of additional information in the directory entry that is
+   being modified or created. The signature of the LDAP operation is
+   computed on the LDAPMessage prior to the inclusion of the
+   SignedOperation control. The procedure is as follows:
+
+      - Build LDAPMessage without the SignedOperation control
+      - Compute signature on the above LDAPMessage
+      - Create new LDAPMessage that includes the old MessageID,
+        protocolOp and any control fields from the previous LDAPMessage,
+        plus  the computed signature formatted as an S/MIME message.
+
+   No control is defined for the server to return in the LDAPResult as
+   defined in [4].  The LDAP server MAY attempt to parse and verify the
+   signature included in the SignedOperation control, but is not
+   required to.  The server can accept the signed operation without
+   verifying the signature.  Signature verification can be quite a
+   lengthy operation, requiring complex certificate chain traversals.
+   This allows a more timely creation of the audit trail by the server.
+   Any LDAP client browsing the directory that retrieves the 'Changes'
+   (defined in the following paragraphs) attributes, should verify the
+   signature of each value according to the local signature verification
+   policies.  Even if the LDAP server verifies the signature contained
+   in the singed operation, the LDAP client has no way of knowing what
+   policies were followed by the server in order to verify the
+   signature.
+
+   If the LDAP server is unable to verify the signature and wishes to
+   return an error then the error code unwillingToPerform(53) should be
+   returned, and the entire LDAP operation fails.  In this situation, an
+   appropriate message (e.g. "Unable to verify signature") MAY be
+   included in the errorMessage of the LDAPResult.  The SignedOperation
+   Control MAY be marked CRITICAL, and if it is CRITICAL then if the
+   LDAP Server performs the LDAP operation, then must include the
+   signature in the signedAuditTrail information.
+
+
+
+
+Greenblatt & Richard          Experimental                      [Page 3]
+\f
+RFC 2649                LDAP Control and Schema              August 1999
+
+
+      The schema definition for the signedAuditTrail information is:
+
+      ( 1.2.840.113549.6.1.0
+      NAME 'signedAuditTrail'
+      SUP top
+      AUXILIARY
+      MUST (
+      Changes
+      )
+         )
+
+      The format of the Changes attribute is:
+
+      ( 1.2.840.113549.6.2.0
+      NAME 'Changes'
+      DESC 'a set of changes applied to an entry'
+      SYNTAX 'Binary' )
+
+      The actual format of the Changes attribute is:
+
+      Changes ::= SEQUENCE {
+           sequenceNumber [0] INTEGER (0 .. maxInt),
+           signedOperation [1] OCTET STRING }
+
+   The SignedOperation attribute is a multipart/signed S/MIME message.
+   Part 1 of the message is the directory operation, and part 2 is the
+   signature.  Sequence number 0 (if present) always indicates the
+   starting point directory object as represented by the definitions in
+   "A MIME Content-Type for Directory Information", as defined in [5].
+   Subsequent sequence numbers indicate the sequence of changes that
+   have been made to this directory object.  Note that the sequence of
+   the changes can be verified due to the fact that the signed directory
+   object will have a timestamp as part of the signature object, and
+   that the sequence numbering as part of the change attribute should be
+   considered to be an unverified aid to the LDAP client.  Sequence
+   numbers are meaningful only within the context of a single directory
+   entry, and LDAP servers are not expected to maintain these sequence
+   numbers across all entries in the directory.
+
+   Some LDAP servers will only allow operations that include the
+   SignedOperation control.  This is indicated by the inclusion of a
+   'signedDirectoryOperationSupport' attribute in the rootDSE.  This
+   attribute is defined as:
+
+
+
+
+
+
+
+
+Greenblatt & Richard          Experimental                      [Page 4]
+\f
+RFC 2649                LDAP Control and Schema              August 1999
+
+
+      1.2.840.113549.6.2.2
+      NAME 'signedDirectoryOperationSupport'
+      DESC 'how many of the LDAP operations must be signed'
+      SYNTAX 'Integer' SINGLE-VALUE )
+
+   The 'signedDirectoryOperationSupport' attribute above may have one of
+   the values, '0', '1' or '2' with the following meanings:
+
+      - '0' Directory Operations may be signed
+      - '1' Directory Operations must always be signed
+      - '2' Directory Operations must never be signed
+
+   Some LDAP servers will desire that the audit trail be continuous, and
+   not contain any gaps that would result from unsigned operations.
+   Such server will include a signature on each LDAP operation that
+   changes a directory entry, even when the LDAP client does not include
+   a signed-Operation control.
+
+1.2.  Handling the Delete Operation
+
+   The LDAP Delete operation represents an interesting case for Signed
+   Directory Operations.  This is due to the case that subsequent to the
+   successful completion of the Delete Operation, the object that would
+   have held the latest 'Changes' attribute no longer exists.  In order
+   to handle this situation, a new object class is defined to represent
+   a directory object that has been deleted.
+
+      ( 1.2.840.113549.6.1.2
+      NAME 'zombieObject'
+      SUP top
+      STRUCTURAL
+      MUST (
+      Cn $ Changes $ OriginalObject
+      )
+         )
+
+      The format of the OriginalObject attribute is:
+
+      ( 1.2.840.113549.6.2.1
+      NAME OriginalObject
+      DESC 'The LDAP URL of an object that has been deleted from the
+      directory' SYNTAX 'Binary' )
+
+   The OriginalObject attribute contains the URL of the object that was
+   deleted from the directory.  It is formatted in accordance with RFC
+   2255.  Directory servers that comply with this specification SHOULD
+   create a zombieObject when performing the delete Operation that
+   contains a SignedOperation LDAPControl.  The Cn attribute of the
+
+
+
+Greenblatt & Richard          Experimental                      [Page 5]
+\f
+RFC 2649                LDAP Control and Schema              August 1999
+
+
+   zombieObject is synthesized by the LDAP server, and may or may not be
+   related to the original name of the directory entry that was deleted.
+   All changes attributes that were attached to the original entry are
+   copied over to the zombieObject.  In addition the LDAP Server MUST
+   attach the signature of the Delete operation as the last successful
+   change that was made to the entry.
+
+2.  Signed Results Mechanism
+
+   A control is also defined that allows the LDAP v3 client to request
+   that the server sign the results that it returns.  It is intended
+   that this control is primarily used in concert with the LDAPSearch
+   operation.  This control MAY be marked as CRITICAL.  If it is marked
+   as CRITICAL and the LDAP Server supports this operation, then all
+   search results MUST be returned with a signature as attached in the
+   SignedResult control if it is willing to sign results for this user.
+   If the server supports this control but does not wish to sign the
+   results for this user then the error code unwillingToPerform(53)
+   should be returned, and the LDAP search will have failed.  In this
+   situation, an appropriate message (e.g. "Unwilling to sign results
+   for you!") MUST be included in the errorMessage of the LDAPResult.
+   If the LDAPSigType has the value FALSE then the client is requesting
+   that the server not sign this operation.  This may be done in
+   situations where servers are configured to always sign their
+   operations.
+
+   The LDAP control to include in the LDAP request is (OID =
+   1.2.840.113549.6.0.1):
+
+      DemandSignedResult ::=  LDAPSigType
+
+      LDAPSigType ::= BOOLEAN
+
+   In response to a DemandSignedResult control, the LDAP v3 server will
+   return a SignedResult control in addition to the normal result as
+   defined by the operation (assuming that the server understands the
+   con- trol, and is willing to perform it).  The SignedResult control
+   MUST NOT be marked CRITICAL.  Some LDAP v3 servers may be configured
+   to sign all of their operations.  In this situation the server always
+   returns a SignedResult control, unless instructed otherwise by the
+   DemandSigne-dResult Control.  Since the SignedResult control is not
+   marked critical, the LDAP client is allowed to ignore it.  The
+   signature field below includes the signature of the enitre LDAPResult
+   formatted as an S/MIME pkcs-7/signature object, as defined in [2].
+
+
+
+
+
+
+
+Greenblatt & Richard          Experimental                      [Page 6]
+\f
+RFC 2649                LDAP Control and Schema              August 1999
+
+
+   The procedure for creating the signature of the signedResult control
+   is the same as the procedure for the creation of the signedOperation
+   control.  The LDAP control in the LDAP response is (OID =
+   1.2.840.113549.6.0.2):
+
+      SignedResult ::= CHOICE {
+           signature     OCTET STRING }
+
+3.  Security Considerations and Other Notes
+
+      The base OIDs are:
+
+      rsadsiLdap ::= {1 2 840 113549 6}
+      rsadsiLdapControls ::=  {1 2 840 113549 6 0}
+      rsadsiLdapObjectClasses ::= {1 2 840 113549 6 1}
+      rsadsiLdapAttributes ::= {1 2 840 113549 6 2}
+
+
+      The complete ASN.1 module for this specification is:
+
+      SIGNEDOPERATIONS DEFINITIONS ::=
+      BEGIN
+
+      SignedOperation ::= CHOICE {
+           signbyServer   NULL,
+           signatureIncluded   OCTET STRING
+       }
+
+      Changes ::= SEQUENCE {
+           sequenceNumber [0] INTEGER (0 .. maxInt),
+           signedOperation [1] OCTET STRING }
+
+      DemandSignedResult ::=  LDAPSigType
+
+      LDAPSigType ::= BOOLEAN
+
+      SignedResult ::= CHOICE {
+           signature     OCTET STRING }
+
+
+      END
+
+
+
+
+
+
+
+
+
+
+Greenblatt & Richard          Experimental                      [Page 7]
+\f
+RFC 2649                LDAP Control and Schema              August 1999
+
+
+   If any of the controls in this specification are supported by an LDAP
+   v3 server then that server MUST make available its certificate (if
+   any) in the userCertificate attribute of its rootDSE object.  The
+   UserCertificate attribute is defined in [6], and contains the public
+   key of the server that is used in the creation of the various
+   signatures defined in this specification.
+
+   It is not the intention of this specification to provide a mechanism
+   that guarantees the origin and integrity of LDAP v3 operations.  Such
+   a service is best provided by the use of an underlying protocol such
+   as TLS [8].  TLS defines additional features such as encryption and
+   compression.  This specification does not define support for
+   encrypted operations.
+
+   This memo proposes protocol elements for transmission and storage of
+   the digital signatures of LDAP operations.  Though the LDAP server
+   may have verified the operation signatures prior to their storage and
+   subsequent retrieval, it is prudent for LDAP clients to verify the
+   signatures contained in the chained attribute upon their retrieval.
+   The issuing Certification Authorities of the signer's certificate
+   should also be consulted in order to determine if the signer's
+   private key has been compromised or the certificate has been
+   otherwise revoked.  Security considerations are discussed throughout
+   this memo.
+
+4.  References
+
+   [1] Kaliski, B., "PKCS 7: Cryptographic Message Syntax Version 1-5",
+       RFC 2315, March 1998.
+
+   [2] Dusse, S., Hoffman, P., Ramsdell, B., Lundblade, L. and L.
+       Repka., "S/MIME Version 2 Message Specification", RFC 2311, March
+       1998.
+
+   [3] Galvin, J., Murphy, S., Crocker, S. and N. Freed, "Security
+       Multiparts for MIME: Multipart/Signed and Multipart/Encrypted",
+       RFC 1847, October 1995.
+
+   [4] Wahl, M., Howes, T. and S. Kille, "Lightweight Directory Access
+       Protocol (v3)", RFC 2251, December 1997.
+
+   [5] Howes, T., Smith, M. and F. Dawson, "A MIME Content-Type for
+       Directory Information", RFC 2425, September 1998.
+
+   [6] Wahl, M., "A Summary of the X.500(96) User Schema for use with
+       LDAPv3", RFC 2256, December 1997.
+
+
+
+
+
+Greenblatt & Richard          Experimental                      [Page 8]
+\f
+RFC 2649                LDAP Control and Schema              August 1999
+
+
+   [7] Howes, T. and M. Smith, "The LDAP URL Format", RFC 2255, December
+       1997.
+
+   [8] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0", RFC
+       2246, January 1999.
+
+5.  Authors' Addresses
+
+   Bruce Greenblatt
+   San Jose, CA 95119
+   USA
+
+   Phone: +1-408-224-5349
+   EMail: bgreenblatt@directory-applications.com
+
+
+   Pat Richard
+   Xcert Software, Inc.
+   Suite 1001 - 701 W. Georgia
+   Vancouver, BC
+   CANADA V6G 1C9
+
+   EMail: patr@xcert.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Greenblatt & Richard          Experimental                      [Page 9]
+\f
+RFC 2649                LDAP Control and Schema              August 1999
+
+
+6.  Full Copyright Statement
+
+   Copyright (C) The Internet Society (1999).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Greenblatt & Richard          Experimental                     [Page 10]
+\f
diff --git a/doc/rfc/rfc2657.txt b/doc/rfc/rfc2657.txt
new file mode 100644 (file)
index 0000000..d23a877
--- /dev/null
@@ -0,0 +1,675 @@
+
+
+
+
+
+
+Network Working Group                                        R. Hedberg
+Request for Comment: 2657                                     Catalogix
+Category: Experimental                                      August 1999
+
+
+                    LDAPv2 Client vs. the Index Mesh
+
+Status of this Memo
+
+   This memo defines an Experimental Protocol for the Internet
+   community.  It does not specify an Internet standard of any kind.
+   Discussion and suggestions for improvement are requested.
+   Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (1999).  All Rights Reserved.
+
+Abstract
+
+   LDAPv2 clients as implemented according to RFC 1777 [1] have no
+   notion on referral.  The integration between such a client and an
+   Index Mesh, as defined by the Common Indexing Protocol [2], heavily
+   depends on referrals and therefore needs to be handled in a special
+   way.  This document defines one possible way of doing this.
+
+1. Background
+
+   During the development of the Common Indexing Protocol (CIP), one of
+   the underlying assumptions was that the interaction between clients
+   and the Index Mesh Servers [1] would heavily depend on the passing of
+   referrals.  Protocols like LDAPv2 [2] that lack this functionality
+   need to compensate for it by some means.  The way chosen in this memo
+   is to add more intelligence into the client. There are two reasons
+   behind this decision.  First, this is not a major enhancement that is
+   needed and secondly, that the intelligence when dealing with the
+   Index Mesh, with or the knowledge about referrals, eventually has to
+   go into the client.
+
+2. The clients view of the Index Mesh
+
+   If a LDAPv2 client is going to be able to interact with the Index
+   Mesh, the Mesh has to appear as something that is understandable to
+   the client.  Basically, this consists of representing the index
+   servers and their contained indexes in a defined directory
+   information tree (DIT) [3,4] structure and a set of object classes
+   and attribute types that have been proven to be useful in this
+   context.
+
+
+
+Hedberg                       Experimental                      [Page 1]
+\f
+RFC 2657                 LDAPv2 vs. Index Mesh               August 1999
+
+
+2.1 The CIP Object Classes
+
+   Object class descriptions are written according to the BNF defined in
+   [5].
+
+2.1.1 cIPIndex
+
+   The cIPIndex objectClass, if present in a entry, allows it to hold
+   one indexvalue and information connected to this value.
+
+   ( 1.2.752.17.3.9
+     NAME 'cIPIndex'
+     SUP 'top'
+     STRUCTURAL
+     MUST ( extendedDSI $ idx )
+     MAY ( indexOCAT )
+   )
+
+2.1.2 cIPDataSet
+
+   The cIPDataSet objectClass, if present in a entry, allows it to hold
+   information concerning one DataSet.
+
+   ( 1.2.752.17.3.10
+     NAME 'cIPDataSet'
+     SUP 'top'
+     STRUCTURAL
+     MUST ( dSI $ searchBase )
+     MAY ( indexOCAT $ description $ indexType $
+           accessPoint $ protocolVersion $ polledBy $
+           updateIntervall $ securityOption $
+           supplierURI $ consumerURI $ baseURI $
+           attributeNamespace $ consistencyBase
+      )
+   )
+
+2.2 The CIP attributeTypes
+
+   The attributes idx, indexOCAT, extendedDSI, description,
+   cIPIndexType, baseURI, dSI are used by a client accessing the index
+   server.  The other attributes (accesspoint, protocolVersion,
+   polledBy, updateIntervall, consumerURI, supplierURI and
+   securityOption, attributeNamespace, consistencyBase) are all for
+   usage in server to server interactions.
+
+
+
+
+
+
+
+Hedberg                       Experimental                      [Page 2]
+\f
+RFC 2657                 LDAPv2 vs. Index Mesh               August 1999
+
+
+2.2.1 idx
+
+   The index value, normally used as part of the RDN.
+
+   ( 1.2.752.17.1.20
+     NAME 'idx'
+     EQUALITY caseIgnoreIA5Match
+     SYNTAX IA5String
+     SINGLE-VALUE
+      )
+
+2.2.2 dSI
+
+   DataSet Identifier, a unique identifier for one particular set of
+   information.  This should be an OID, but stored in a stringformat.
+
+   ( 1.2.752.17.1.21
+     NAME 'dSI'
+     EQUALITY caseIgnoreIA5Match
+     SYNTAX IA5String
+   )
+
+2.2.3 indexOCAT
+
+   Describes the type of data that is stored in this entry, by using
+   objectcClasses and attributeTypes. The information is stored as a
+   objectClass name followed by a space and then an attributeType name.
+   A typical example when dealing with whitepages information would be
+   "person cn".
+
+   ( 1.2.752.17.1.28
+     NAME 'indexOCAT'
+     EQUALITY caseIgnoreIA5Match
+     SYNTAX IA5String
+   )
+
+2.2.5 supplierURI
+
+   A URI describing which protocols, hostnames and ports should be used
+   by an indexserver to interact with servers carrying indexinformation
+   representing this dataSet.
+
+     ( 1.2.752.17.1.22
+      NAME 'supplierURI'
+      EQUALITY caseIgnoreIA5Match
+      SYNTAX IA5String
+   )
+
+
+
+
+Hedberg                       Experimental                      [Page 3]
+\f
+RFC 2657                 LDAPv2 vs. Index Mesh               August 1999
+
+
+2.2.6 baseURI
+
+   The attribute value for this attribute is a LDAP URI. One can
+   envisage other URI syntaxes, if the client knows about more access
+   protocols besides LDAP, and the interaction between the client and
+   the server can not use referrals for some reason.
+
+   ( 1.2.752.17.1.26
+     NAME 'baseURI'
+     EQUALITY caseExactIA5Match
+     SYNTAX IA5String
+   )
+
+2.2.7 protocolVersion
+
+   At present, the Common Indexing Protocol version should be 3.
+
+   ( 1.2.752.17.1.27
+     NAME 'protocolVersion'
+     EQUALITY numericStringMatch
+     SYNTAX numericString
+   )
+
+2.2.8 cIPIndexType
+
+   The type of index Object that is used to pass around index
+   information.
+
+   ( 1.2.752.17.1.29
+     NAME 'cIPIndexType'
+     EQUALITY caseIgnoreIA5Match
+     SYNTAX IA5String
+   )
+
+2.2.10 polledBy
+
+   The Distinguished Name of Index servers that polls data from this
+   indexserver.
+
+   ( 1.2.752.17.1.30
+     NAME 'polledBy'
+     EQUALITY distinguishedNameMatch
+     SYNTAX DN
+   )
+
+
+
+
+
+
+
+Hedberg                       Experimental                      [Page 4]
+\f
+RFC 2657                 LDAPv2 vs. Index Mesh               August 1999
+
+
+2.2.11 updateIntervall
+
+   The maximum duration in seconds between the generation of two updates
+   by the supplier server.
+
+   ( 1.2.752.17.1.31
+     Name 'updateIntervall'
+     EQUALITY numericStringMatch
+     SYNTAX numericString
+     SINGLE-VALUE
+   )
+
+2.2.12 securityOption
+
+   Whether and how the supplier server should sign and encrypt the
+   update before sending it to the consumer server.
+
+   ( 1.2.752.17.1.32
+     NAME 'securityOption'
+     EQUALITY caseIgnoreIA5Match
+     SYNTAX IA5String
+     SINGLE-VALUE
+   )
+
+2.2.13 extendedDSI
+
+   DataSet Identifier possibly followed by a space and a taglist, the
+   later as specified by [6].
+
+   ( 1.2.752.17.1.33
+     NAME 'extendedDSI'
+     EQUALITY caseIgnoreIA5Match
+     SYNTAX IA5String
+        )
+
+2.2.14 consumerURI
+
+   A URI describing which means a server can accept indexinformation.
+   An example being a mailto URI for MIME email based index transport.
+
+   ( 1.2.752.17.1.34
+     NAME 'consumerURI'
+     EQUALITY caseExactIA5Match
+     SYNTAX IA5String
+   )
+
+
+
+
+
+
+Hedberg                       Experimental                      [Page 5]
+\f
+RFC 2657                 LDAPv2 vs. Index Mesh               August 1999
+
+
+2.2.15 attributeNamespace
+
+   Any consumer supplier pair has to agree on what attribute that should
+   be used and also possibly the meaning of the attributenames. The
+   value of this attribute should, for example, be a URI pointing to a
+   document wherein the agreement is described.
+
+   ( 1.2.752.17.1.35 NAME 'attributeNamespace' EQUALITY
+     caseExactIA5Match SYNTAX IA5String
+   )
+
+2.2.16 consistencyBase
+
+   This attribute is specifically used by consumer supplier pairs that
+   use the tagged index object [6].
+
+   ( 1.2.752.17.1.36
+     NAME 'consistencyBase'
+     EQUALITY caseExactIA5Match
+     SYNTAX IA5String
+   )
+
+3. The interaction between a client and the Index Mesh
+
+   A client interaction with the Index Mesh consists of a couple of
+   rather well defined actions. The first being to find a suitable index
+   to start with, then to transverse the Index Mesh and finally to query
+   the servers holding the original data.  Note when reading this text
+   that what is discussed here is the client's perception of the DIT,
+   how it is in fact implemented is not discussed.
+
+3.1 Finding a Index Mesh
+
+   This approach depends on the fact that every index server partaking
+   in an Index Mesh is represented in the DIT by a entry of the type
+   cIPDataSet, and has a distinguished name (DN) which most significant
+   relative distinguished name (RDN) has the attributetype dSI.
+   Therefore, finding a suitable indexserver to start the search from is
+   a matter of searching the DIT at a suitable place for objects with
+   the objectClass cIPIndexObject.  Every found entry can then be
+   evaluated by looking at the description value as well as the
+   indexOCAT value. The description string should be a human readable
+   and understandable text that describes what the index server is
+   indexing. An example of such a string could be, "This index covers
+   all employees at Swedish Universities and University Colleges that
+   has an email account". The indexOCAT attribute supplies information
+   about which kind of entries and which attributes within these entries
+   that the index information has emanated from.  For example, if the
+
+
+
+Hedberg                       Experimental                      [Page 6]
+\f
+RFC 2657                 LDAPv2 vs. Index Mesh               August 1999
+
+
+   indexOCAT attribute value is "person cn", one can deduce that this is
+   an index over persons and not over roles, and that it is the
+   attribute commonName that is indexed.
+
+3.2 Searching the mesh
+
+   Each index server has its information represented in the DIT as a
+   very flat tree. In fact, it is only one level deep.
+
+
+                            0 Indexservers cIPDataSet
+                           /|\
+                          / | \
+                         /  |  \
+                        0       0
+      cIPDataSet entries     cIPIndex entries
+      one for each DataSet   one for each index value
+      that this server has   that this indexserver
+      gathered indexes from. has.
+
+   A search then consists of a set of searches.  The first being the
+   search for the index entries that contains an indexvalue that matches
+   what the user is looking for, and the second a search based on the
+   DSI information in the extendedDSI attribute values returned from the
+   first search.  In the case of the the cIPIndexType being tagged-
+   index, the taglists should be compared to find which DSI it might be
+   useful to pose further queries to.
+
+   When doing these types of searches, the client should be aware of the
+   fact that the index values disregarding their origin (attributeTypes)
+   always are stored in the index server as values of the idx attribute.
+
+   The object of the second search is to get information on the
+   different DataSet involved, and should normally be performed as a
+   read. Since the DataSet information probably will remain quite stable
+   over time, this information lends itself very well to caching.  If at
+   this stage there is more than one DataSet involved, the User
+   interface might use the description value to aid the user in choosing
+   which one to proceed with.  The content of the searchBase value of
+   the DataSet tells the client whether it represents another index
+   server (the most significant part of the dn is a dSI attribute) or if
+   it is a end server.
+
+
+
+
+
+
+
+
+
+Hedberg                       Experimental                      [Page 7]
+\f
+RFC 2657                 LDAPv2 vs. Index Mesh               August 1999
+
+
+3.3 Querying the end server
+
+   When finally reaching the end server/servers that probably has the
+   sought for information, the information in the indexOCAT attribute
+   can be used to produce an appropriate filter.  If a search for "Rol*"
+   in an index having an indexOCAT attribute value of "person cn"
+   returns an idx entry with the idx value of "Roland", then an
+   appropriate filter to use might be "&(|(cn=* roland *)(cn=roland
+   *)(cn=* roland))(objectclass=person)".  A complete example of a
+   search process is given in Appendix A.
+
+4. Security Considerations
+
+   Since this memo deals with client behavior, it does not add anything
+   that either enhances or diminishes the security features that exists
+   in LDAPv2.
+
+5. Internationalization
+
+   As with security, this memo neither enhances or diminishes the
+   handling of internationalization in LDAPv2.
+
+6. References
+
+   [1] Yeong, W., Howes, T. and S. Kille, "Lightweight Directory Access
+       Protocol", RFC 1777, March 1995.
+
+   [2] Allen, J. and M. Mealling "The Architecture of the Common
+       Indexing Protocol (CIP)", RFC 2651, August 1999.
+
+   [3] The Directory: Overview of Concepts, Models and Service. CCITT
+       Recommendation X.500, 1988.
+
+   [4] Information Processing Systems -- Open Systems Interconnection --
+       The Directory: Overview of Concepts, Models and Service. ISO/IEC
+       JTC 1/SC21; International Standard 9594-1, 1988.
+
+   [5] Wahl, M., Coulbeck, A., Howes, T. and S. Kille, "Lightweight
+       Directory Access Protocol (v3): Attribute Syntax Definitions",
+       RFC 2252, December 1997.
+
+   [6] Hedberg, R., Greenblatt, B., Moats, R. and M. Wahl, "A Tagged
+       Index Object for use in the Common Indexing Protocol", RFC 2654,
+       August 1999.
+
+
+
+
+
+
+
+Hedberg                       Experimental                      [Page 8]
+\f
+RFC 2657                 LDAPv2 vs. Index Mesh               August 1999
+
+
+7. Author's Address
+
+   Roland Hedberg
+   Catalogix
+   Dalsveien 53
+   0387 Oslo, Norway
+
+   Phone: +47 23 08 29 96
+   EMail: roland@catalogix.ac.se
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hedberg                       Experimental                      [Page 9]
+\f
+RFC 2657                 LDAPv2 vs. Index Mesh               August 1999
+
+
+Appendix A - Sample Session
+
+   Below is a sample of a session between a LDAPv2 client and an index
+   server mesh as specified in this memo.
+
+   The original question of the session is to find the email address of
+   a person by the name, "Roland Hedberg", who is working at "Umea
+   University" in Sweden.
+
+   Step 1.
+
+   A singlelevel search with the baseaddress "c=SE" and the filter
+   "(objectclass=cipDataset)" was issued.
+
+   The following results were received:
+
+   DN: dSI=1.2.752.17.5.0,c=SE
+   dsi= 1.2.752.17.5.0
+   description= "index over employees with emailaddresses within Swedish
+   higher education"
+   indexOCAT= "cn person"
+   cIPIndexType= "x-tagged-index-1" ;
+   searchBase= "dsi=1.2.752.17.5.0,c=SE"
+   protocolVersion = 3
+
+   DN: dSI=1.2.752.23.1.3,c=SE
+   dsi= 1.2.752.23.1.3
+   description= "index over Swedish lawyers"
+   indexOCAT= "cn person"
+   cIPIndexType= "x-tagged-index-1" ;
+   searchBase= "dsi=1.2.752.23.1.3,c=SE"
+   protocolVersion = 3
+
+   Step 2.
+
+   Since the first index seemed to cover the interesting population, a
+   single level search with the baseaddress "dsi=1.2.752.17.5.0,c=SE"
+   and the filter "(|(idx=roland)(idx=hedberg))" was issued.
+
+   The following results were received:
+
+   DN: idx=Roland,dSI=1.2.752.17.5.0,c=SE
+   idx= Roland
+   extendedDSI= 1.2.752.17.5.10 1,473,612,879,1024
+   extendedDSI= 1.2.752.17.5.14 35,78,150,200
+   extendedDSI= 1.2.752.17.5.16 187,2031,3167,5284,6034-6040
+   extendedDSI= 1.2.752.17.5.17 17
+
+
+
+
+Hedberg                       Experimental                     [Page 10]
+\f
+RFC 2657                 LDAPv2 vs. Index Mesh               August 1999
+
+
+   DN: idx=Hedberg,dSI=1.2.752.17.5.0,c=SE
+   idx= Hedberg
+   extendedDSI= 1.2.752.17.5.8  24,548-552,1066
+   extendedDSI= 1.2.752.17.5.10 473,512,636,777,1350
+   extendedDSI= 1.2.752.17.5.14 84,112,143,200
+   extendedDSI= 1.2.752.17.5.15 1890-1912
+   extendedDSI= 1.2.752.17.5.17 44
+
+   A comparison between the two sets of extendedDSIs shows that two
+   datasets 1.2.752.17.5.10 and 1.2.752.17.5.14 contains persons named
+   "Roland" and "Hedberg". Therefore, the next step would be to see what
+   the datasets represent.  A comparison like this should normally not
+   be left to the user.
+
+   Step. 3
+
+   Two baselevel searches, one for
+   "dsi=1.2.752.17.5.10,dsi=1.2.752.17.5.0,c=SE" and the other for
+   "dsi=1.2.752.17.5.14,dsi=1.2.752.17.5.0,c=SE" with the filter
+   "(objectclass=cipdataset)" were issued.
+
+   The following results were received:
+
+   DN: dSI=1.2.752.17.5.10,dSI=1.2.752.17.5.0,c=SE
+   dsi= 1.2.752.17.5.10
+   description= "Employees at Umea University,Sweden"
+   indexOCAT= "person cn"
+   searchBase= "o=Umea Universitet,c=SE"
+
+   respectively
+
+   DN: dSI=1.2.752.17.5.14,dSI=1.2.752.17.5.0,c=SE
+   dsi= 1.2.752.17.5.14
+   description= "Employees at Lund University,Sweden"
+   indexOCAT= "person cn"
+   searchBase= "o=Lunds Universitet,c=SE"
+
+   Step 4
+
+   Based on the descriptions for the two datasets, "1.2.752.17.5.10" was
+   chosen as the best to proceed with.  From the searchbase attribute
+   value, it was clear that this was a base server.  The query now has
+   to be somewhat modified.  One possibility would be to issue a query
+   with the baseobject "o=Umea Universitet,c=SE" and the filter
+   "(&(cn=Roland Hedberg)(objectclass=person))"
+
+
+
+
+
+
+Hedberg                       Experimental                     [Page 11]
+\f
+RFC 2657                 LDAPv2 vs. Index Mesh               August 1999
+
+
+Full Copyright Statement
+
+   Copyright (C) The Internet Society (1999).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hedberg                       Experimental                     [Page 12]
+\f
diff --git a/doc/rfc/rfc2696.txt b/doc/rfc/rfc2696.txt
new file mode 100644 (file)
index 0000000..4ccc4c1
--- /dev/null
@@ -0,0 +1,395 @@
+
+
+
+
+
+
+Network Working Group                                        C. Weider
+Request for Comments: 2696                                   A. Herron
+Category: Informational                                     A. Anantha
+                                                             Microsoft
+                                                              T. Howes
+                                                              Netscape
+                                                        September 1999
+
+
+      LDAP Control Extension for Simple Paged Results Manipulation
+
+Status of this Memo
+
+   This memo provides information for the Internet community.  It does
+   not specify an Internet standard of any kind.  Distribution of this
+   memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (1999).  All Rights Reserved.
+
+1. Abstract
+
+   This document describes an LDAPv3 control extension for simple paging
+   of search results. This control extension allows a client to control
+   the rate at which an LDAP server returns the results of an LDAP
+   search operation. This control may be useful when the LDAP client has
+   limited resources and may not be able to process the entire result
+   set from a given LDAP query, or when the LDAP client is connected
+   over a low-bandwidth connection. Other operations on the result set
+   are not defined in this extension. This extension is not designed to
+   provide more sophisticated result set management.
+
+   The key words "MUST", "SHOULD", and "MAY" used in this document are
+   to be interpreted as described in [bradner97].
+
+2. The Control
+
+   This control is included in the searchRequest and searchResultDone
+   messages as part of the controls field of the LDAPMessage, as defined
+   in Section 4.1.12 of [LDAPv3]. The structure of this control is as
+   follows:
+
+
+
+
+
+
+
+
+
+Weider, et al.               Informational                      [Page 1]
+\f
+RFC 2696       LDAP Control Ext. for Simple Paged Results September 1999
+
+
+pagedResultsControl ::= SEQUENCE {
+        controlType     1.2.840.113556.1.4.319,
+        criticality     BOOLEAN DEFAULT FALSE,
+        controlValue    searchControlValue
+}
+
+The searchControlValue is an OCTET STRING wrapping the BER-encoded
+version of the following SEQUENCE:
+
+realSearchControlValue ::= SEQUENCE {
+        size            INTEGER (0..maxInt),
+                                -- requested page size from client
+                                -- result set size estimate from server
+        cookie          OCTET STRING
+}
+
+3. Client-Server Interaction
+
+   An LDAP client application that needs to control the rate at which
+   results are returned MAY specify on the searchRequest a
+   pagedResultsControl with size set to the desired page size and cookie
+   set to the zero-length string. The page size specified MAY be greater
+   than zero and less than the sizeLimit value specified in the
+   searchRequest.
+
+   If the page size is greater than or equal to the sizeLimit value, the
+   server should ignore the control as the request can be satisfied in a
+   single page. If the server does not support this control, the server
+   MUST return an error of unsupportedCriticalExtension if the client
+   requested it as critical, otherwise the server SHOULD ignore the
+   control. The remainder of this section assumes the server does not
+   ignore the client's pagedResultsControl.
+
+   Each time the server returns a set of results to the client when
+   processing a search request containing the pagedResultsControl, the
+   server includes the pagedResultsControl control in the
+   searchResultDone message. In the control returned to the client, the
+   size MAY be set to the server's estimate of the total number of
+   entries in the entire result set. Servers that cannot provide such an
+   estimate MAY set this size to zero (0).  The cookie MUST be set to an
+   empty value if there are no more entries to return (i.e., the page of
+   search results returned was the last), or, if there are more entries
+   to return, to an octet string of the server's choosing,used to resume
+   the search.
+
+   The client MUST consider the cookie to be an opaque structure and
+   make no assumptions about its internal organization or value. When
+   the client wants to retrieve more entries for the result set, it MUST
+
+
+
+Weider, et al.               Informational                      [Page 2]
+\f
+RFC 2696       LDAP Control Ext. for Simple Paged Results September 1999
+
+
+   send to the server a searchRequest with all values identical to the
+   initial request with the exception of the messageID, the cookie, and
+   optionally a modified pageSize. The cookie MUST be the octet string
+   on the last searchResultDone response returned by the server.
+   Returning cookies from previous searchResultDone responses besides
+   the last one is undefined, as the server implementation may restrict
+   cookies from being reused.
+
+   The server will then return the next set of results from the whole
+   result set. This interaction will continue until the client has
+   retrieved all the results, in which case the cookie in the
+   searchResultDone field will be empty, or until the client abandons
+   the search sequence as described below. Once the paged search
+   sequence has been completed, the cookie is no longer valid and MUST
+   NOT be used.
+
+   A sequence of paged search requests is abandoned by the client
+   sending a search request containing a pagedResultsControl with the
+   size set to zero (0) and the cookie set to the last cookie returned
+   by the server.  A client MAY use the LDAP Abandon operation to
+   abandon one paged search request in progress, but this is discouraged
+   as it MAY invalidate the client's cookie.
+
+   If, for any reason, the server cannot resume a paged search operation
+   for a client, then it SHOULD return the appropriate error in a
+   searchResultDone entry. If this occurs, both client and server should
+   assume the paged result set is closed and no longer resumable.
+
+   A client may have any number of outstanding search requests pending,
+   any of which may have used the pagedResultsControl.  A server
+   implementation which requires a limit on the number of outstanding
+   paged search requests from a given client MAY either return
+   unwillingToPerform when the client attempts to create a new paged
+   search request, or age out an older result set.  If the server
+   implementation ages out an older paged search request, it SHOULD
+   return "unwilling to perform" if the client attempts to resume the
+   paged search that was aged out.
+
+   A client may safely assume that all entries that satisfy a given
+   search query are returned once and only once during the set of paged
+   search requests/responses necessary to enumerate the entire result
+   set, unless the result set for that query has changed since the
+   searchRequest starting the request/response sequence was processed.
+   In that case, the client may receive a given entry multiple times
+   and/or may not receive all entries matching the given search
+   criteria.
+
+
+
+
+
+Weider, et al.               Informational                      [Page 3]
+\f
+RFC 2696       LDAP Control Ext. for Simple Paged Results September 1999
+
+
+4. Example
+
+   The following example illustrates the client-server interaction
+   between a client doing a search requesting a page size limit of 3.
+   The entire result set returned by the server contains 5 entries.
+
+   Lines beginning with "C:" indicate requests sent from client to
+   server. Lines beginning with "S:" indicate responses sent from server
+   to client. Lines beginning with "--" are comments to help explain the
+   example.
+
+   -- Client sends a search request asking for paged results
+   -- with a page size of 3.
+   C: SearchRequest + pagedResultsControl(3,"")
+   -- Server responds with three entries plus an indication
+   -- of 5 total entries in the search result and an opaque
+   -- cooking to be used by the client when retrieving subsequent
+   -- pages.
+   S: SearchResultEntry
+   S: SearchResultEntry
+   S: SearchResultEntry
+   S: SearchResultDone + pagedResultsControl(5, "opaque")
+   -- Client sends an identical search request (except for
+   -- message id), returning the opaque cooking, asking for
+   -- the next page.
+   C: SearchRequest + PagedResultsControl(3, "opaque")
+   -- Server responds with two entries plus an indication
+   -- that there are no more entries (null cookie).
+   S: SearchResultEntry
+   S: SearchResultEntry
+   S: SearchResultDone + pagedResultsControl(5,"")
+
+5. Relationship to X.500
+
+   For LDAP servers providing a front end to X.500 (93) directories, the
+   paged results control defined in this document may be mapped directly
+   onto the X.500 (93) PagedResultsRequest defined in X.511 [x500]. The
+   size parameter may be mapped onto pageSize.  The cookie parameter may
+   be mapped onto queryReference.  The sortKeys and reverse fields in
+   the X.500 PagedResultsRequest are excluded.
+
+
+
+
+
+
+
+
+
+
+
+Weider, et al.               Informational                      [Page 4]
+\f
+RFC 2696       LDAP Control Ext. for Simple Paged Results September 1999
+
+
+6. Security Considerations
+
+   Server implementors should consider the resources used when clients
+   send searches with the simple paged control, to ensure that a
+   client's misuse of this control does not lock out other legitimate
+   operations.
+
+   Servers implementations may enforce an overriding sizelimit, to
+   prevent the retrieval of large portions of a publically-accessible
+   directory.
+
+   Clients can, using this control, determine how many entries match a
+   particular filter, before the entries are returned to the client.
+   This may require special processing in servers which perform access
+   control checks on entries to determine whether the existence of the
+   entry can be disclosed to the client.
+
+7. References
+
+   [LDAPv3]    Wahl, M., Howes, T. and S. Kille, "Lightweight Directory
+               Access Protocol (v3)", RFC 2251, December 1997.
+
+   [Bradner97] Bradner, S., "Key Words for use in RFCs to Indicate
+               Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Weider, et al.               Informational                      [Page 5]
+\f
+RFC 2696       LDAP Control Ext. for Simple Paged Results September 1999
+
+
+8. Authors' Addresses
+
+   Chris Weider
+   Microsoft Corp.
+   1 Microsoft Way
+   Redmond, WA 98052
+   USA
+
+   Phone: +1 425 882-8080
+   EMail: cweider@microsoft.com
+
+
+   Andy Herron
+   Microsoft Corp.
+   1 Microsoft Way
+   Redmond, WA 98052
+   USA
+
+   Phone: +1 425 882-8080
+   EMail: andyhe@microsoft.com
+
+
+   Anoop Anantha
+   Microsoft Corp.
+   1 Microsoft Way
+   Redmond, WA 98052
+   USA
+
+   Phone: +1 425 882-8080
+   EMail: anoopa@microsoft.com
+
+
+   Tim Howes
+   Netscape Communications Corp.
+   501 E. Middlefield Road
+   Mountain View, CA 94043
+   USA
+
+   Phone: +1 415 937-2600
+   EMail: howes@netscape.com
+
+
+
+
+
+
+
+
+
+
+
+Weider, et al.               Informational                      [Page 6]
+\f
+RFC 2696       LDAP Control Ext. for Simple Paged Results September 1999
+
+
+9.  Full Copyright Statement
+
+   Copyright (C) The Internet Society (1999).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Weider, et al.               Informational                      [Page 7]
+\f
diff --git a/doc/rfc/rfc2713.txt b/doc/rfc/rfc2713.txt
new file mode 100644 (file)
index 0000000..ca88d30
--- /dev/null
@@ -0,0 +1,1179 @@
+
+
+
+
+
+
+Network Working Group                                            V. Ryan
+Request for Comments: 2713                                   S. Seligman
+Category: Informational                                           R. Lee
+                                                  Sun Microsystems, Inc.
+                                                            October 1999
+
+
+     Schema for Representing Java(tm) Objects in an LDAP Directory
+
+Status of this Memo
+
+   This memo provides information for the Internet community.  It does
+   not specify an Internet standard of any kind.  Distribution of this
+   memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (1999).  All Rights Reserved.
+
+Abstract
+
+   This document defines the schema for representing Java(tm) objects in
+   an LDAP directory [LDAPv3].  It defines schema elements to represent
+   a Java serialized object [Serial], a Java marshalled object [RMI], a
+   Java remote object [RMI], and a JNDI reference [JNDI].
+
+1. Introduction
+
+   This document assumes that the reader has a general knowledge of the
+   Java programming language [Java].  For brevity we use the term "Java
+   object" in place of "object in the Java programming language"
+   throughout this text.
+
+   Traditionally, LDAP directories have been used to store data. Users
+   and programmers think of the directory as a hierarchy of directory
+   entries, each containing a set of attributes.  You look up an entry
+   from the directory and extract the attribute(s) of interest.  For
+   example, you can look up a person's telephone number from the
+   directory.  Alternatively, you can search the directory for entries
+   with a particular set of attributes.  For example, you can search for
+   all persons in the directory with the surname "Smith".
+
+   For applications written in the Java programming language, a kind of
+   data that is typically shared are Java objects themselves.  For such
+   applications, it makes sense to be able to use the directory as a
+   repository for Java objects.  The directory provides a centrally
+   administered, and possibly replicated, service for use by Java
+   applications distributed across the network.
+
+
+
+Ryan, et al.                 Informational                      [Page 1]
+\f
+RFC 2713                Schema for Java Objects             October 1999
+
+
+   For example, an application server might use the directory for
+   "registering" objects representing the services that it manages, so
+   that a client can later search the directory to locate those services
+   as it needs.
+
+   The motivation for this document is to define a common way for
+   applications to store and retrieve Java objects from the directory.
+   Using this common schema, any Java application that needs to read or
+   store Java objects in the directory can do so in an interoperable
+   way.
+
+2 Representation of Java Objects
+
+   This document defines schema elements to represent three types of
+   Java objects:  a Java serialized object, a Java marshalled object,
+   and a JNDI reference. A Java remote object is stored as either a Java
+   marshalled object or a JNDI reference.
+
+2.1 Common Representations
+
+   A Java object is stored in the LDAP directory by using the object
+   class javaObject. This is the base class from which other Java object
+   related classes derive: javaSerializedObject, javaMarshalledObject,
+   and javaNamingReference.  javaObject is an abstract object class,
+   which means that a javaObject cannot exist by itself in the
+   directory; only auxiliary or structural subclasses of it can exist in
+   the directory.
+
+   The object class javaContainer represents a directory entry dedicated
+   to storing a Java object. It is a structural object class.  In cases
+   where a subclass of javaObject is mixed in with another structural
+   object class, javaContainer is not required.
+
+   The definitions for the object classes javaObject and javaContainer
+   are presented in Section 4.
+
+   The javaObject class has one mandatory attribute (javaClassName) and
+   four optional attributes (javaClassNames, javaCodebase, javaDoc,
+   description).  javaClassName is a single valued attribute that is
+   used to store the fully qualified name of the object's Java class
+   (for example, "java.lang.String").  This may be the object's most
+   derived class's name, but does not have to be; that of a superclass
+   or interface in some cases might be most appropriate.  This attribute
+   is intended for storing the name of the object's "distinguished"
+   class, that is, the class or interface with which the object should
+   be identified.
+
+
+
+
+
+Ryan, et al.                 Informational                      [Page 2]
+\f
+RFC 2713                Schema for Java Objects             October 1999
+
+
+   javaClassNames is a multivalued attribute that is used to store the
+   fully qualified names of the object's Java classes and interfaces
+   (for example, "java.lang.Byte"). Like all multivalued attributes, the
+   javaClassNames attribute's values are unordered and so no one value
+   is more "distinguished" than the others. This attribute is intended
+   for storing an object's class and interface names and those of its
+   ancestor classes and interfaces, although the list of values does not
+   have to be complete.  If the javaClassNames attribute is present, it
+   should include the value of javaClassName.
+
+   For example, suppose an object is stored in the directory with a
+   javaClassName attribute of "java.io.FilePermission", and a
+   javaClassNames attribute of {"java.security.Permission",
+   "java.io.FilePermission", "java.security.Guard",
+   "java.io.Serializable"}. An application searching a directory for
+   Java objects might use javaClassName to produce a summary of the
+   names and types of Java objects in that directory.  Another
+   application might use the javaClassNames attribute to find, for
+   example, all java.security.Permission objects.
+
+   javaCodebase is a multivalued attribute that is used to store the
+   location(s) of the object's class definition.  javaDoc is used to
+   store a pointer (URL) to the Java documentation for the class.
+   description is used to store a textual description of a Java object
+   and is defined in [v3Schema]. The definitions of these attributes are
+   presented in Section 3.
+
+2.2 Serialized Objects
+
+   To "serialize" an object means to convert its state into a byte
+   stream in such a way that the byte stream can be converted back into
+   a copy of the object.  A Java object is "serializable" if its class
+   or any of its superclasses implements either the java.io.Serializable
+   interface or its subinterface java.io.Externalizable.
+   "Deserialization" is the process of converting the serialized form of
+   an object back into a copy of the object.  When an object is
+   serialized, the entire tree of objects rooted at the object is also
+   serialized. When it is deserialized, the tree is reconstructed. For
+   example, suppose a serializable Book object contains (a serializable
+   field of) an array of Page objects.  When a Book object is
+   serialized, so is the array of Page objects.
+
+   The Java platform specifies a default algorithm by which serializable
+   objects are serialized. A Java class can also override this default
+   serialization with its own algorithm.  [Serial] describes object
+   serialization in detail.
+
+
+
+
+
+Ryan, et al.                 Informational                      [Page 3]
+\f
+RFC 2713                Schema for Java Objects             October 1999
+
+
+   When an object is serialized, information that identifies its class
+   is recorded in the serialized stream. However, the class's definition
+   ("class file") itself is not recorded. It is the responsibility of
+   the system that is deserializing the object to determine the
+   mechanism to use for locating and loading the associated class
+   definitions. For example, the Java application might include in its
+   classpath a JAR file containing the class definitions of the
+   serialized object, or load the class definitions using information
+   from the directory, as explained below.
+
+2.2.1 Representation in the Directory
+
+   A serialized object is represented in the directory by the attributes
+   javaClassName, javaClassNames, javaCodebase, and javaSerializedData,
+   as defined in Section 3.  The mandatory attribute,
+   javaSerializedData, contains the serialized form of the object.
+   Although the serialized form already contains the class name, the
+   mandatory javaClassName attribute also records the class name of the
+   serialized object so that applications can determined class
+   information without having to first deserialize the object.  The
+   optional javaClassNames attribute is used to record additional class
+   information about the serialized object.  The optional javaCodebase
+   attribute is used to record the locations of the class definitions
+   needed to deserialize the serialized object.
+
+   A directory entry that contains a serialized object is represented by
+   the object class javaSerializedObject, which is a subclass of
+   javaObject.  javaSerializedObject is an auxiliary object class, which
+   means that it needs to be mixed in with a structural object class.
+   javaSerializedObject's definition is given in Section 4.
+
+2.3 Marshalled Objects
+
+   To "marshal" an object means to record its state and codebase(s) in
+   such a way that when the marshalled object is "unmarshalled," a copy
+   of the original object is obtained, possibly by automatically loading
+   the class definitions of the object.  You can marshal any object that
+   is serializable or remote (that is, implements the java.rmi.Remote
+   interface).  Marshalling is like serialization, except marshalling
+   also records codebases. Marshalling is different from serialization
+   in that marshalling treats remote objects specially. If an object is
+   a java.rmi.Remote object, marshalling records the remote object's
+   "stub" (see Section 2.5), instead of the remote object itself.  Like
+   serialization, when an object is marshalled, the entire tree of
+   objects rooted at the object is marshalled. When it is unmarshalled,
+   the tree is reconstructed.
+
+
+
+
+
+Ryan, et al.                 Informational                      [Page 4]
+\f
+RFC 2713                Schema for Java Objects             October 1999
+
+
+   A "marshalled" object is the represented by the
+   java.rmi.MarshalledObject class. Here's an example of how to create
+   MarshalledObjects for serializable and remote objects:
+
+       java.io.Serializable sobj = ...;
+       java.rmi.MarshalledObject mobj1 =
+           new java.rmi.MarshalledObject(sobj);
+
+       java.rmi.Remote robj = ...;
+       java.rmi.MarshalledObject mobj2 =
+           new java.rmi.MarshalledObject(robj);
+
+   Then, to retrieve the original objects from the MarshalledObjects, do
+   as follows:
+
+       java.io.Serializable sobj = (java.io.Serializable) mobj1.get();
+       java.io.Remote rstub = (java.io.Remote) mobj2.get();
+
+   MarshalledObject is available only on the Java 2 Platform, Standard
+   Edition, v1.2, and higher releases.
+
+2.3.1 Representation in the Directory
+
+   A marshalled object is represented in the directory by the attributes
+   javaClassName, javaClassNames, and javaSerializedData, as defined in
+   Section 3.  The mandatory attribute, javaSerializedData, contains the
+   serialized form of the marshalled object (that is, the serialized
+   form of a MarshalledObject instance).  The mandatory javaClassName
+   attribute records the distinguished class name of the object before
+   it has been marshalled.  The optional javaClassNames attribute is
+   used to record additional class information about the object before
+   it has been marshalled.
+
+   A directory entry that contains a marshalled object is represented by
+   the object class javaMarshalledObject, which is a subclass of
+   javaObject.  javaMarshalledObject is an auxiliary object class, which
+   means that it needs to be mixed in with a structural object class.
+   javaMarshalledObject's definition is given in Section 4.
+
+   As evident in this description, a javaMarshalledObject differs from a
+   javaSerializedObject only in the interpretation of the javaClassName
+   and javaClassNames attributes.
+
+
+
+
+
+
+
+
+
+Ryan, et al.                 Informational                      [Page 5]
+\f
+RFC 2713                Schema for Java Objects             October 1999
+
+
+2.4 JNDI References
+
+   Java Naming and Directory Interface(tm) (JNDI) is a directory access
+   API specified in the Java programming language [JNDI].  It provides
+   an object-oriented view of the directory, allowing Java objects to be
+   added to and retrieved from the directory without requiring the
+   client to manage data representation issues.
+
+   JNDI defines the notion of a "reference" for use when an object
+   cannot be stored in the directory directly, or when it is
+   inappropriate or undesirable to do so.  An object with an associated
+   reference is stored in the directory indirectly, by storing its
+   reference instead.
+
+2.4.1 Contents of a Reference
+
+   A JNDI reference is a Java object of class javax.naming.Reference.
+   It consists of class information about the object being referenced
+   and an ordered list of addresses.  An address is a Java object of
+   class javax.naming.RefAddr.  Each address contains information on how
+   to construct the object.
+
+   A common use for JNDI references is to represent connections to a
+   network service such as a database, directory, or file system.  Each
+   address may then identify a "communications endpoint" for that
+   service, containing information on how to contact the service.
+   Multiple addresses may arise for various reasons, such as replication
+   or the object offering interfaces over more than one communication
+   mechanism.
+
+   A reference also contains information to assist in the creation of an
+   instance of the object to which the reference refers.  It contains
+   the Java class name of that object, and the class name and location
+   of the object factory to be used to create the object.  The
+   procedures for creating an object given its reference and the reverse
+   are described in [JNDI].
+
+2.4.2 Representation in the Directory
+
+   A JNDI reference is stored in the directory by using the attributes
+   javaClassName, javaClassNames, javaCodebase, javaReferenceAddress,
+   and javaFactory, defined in Section 3.  These attributes store
+   information corresponding to the contents of a reference described
+   above.  javaReferenceAddress is a multivalued optional attribute for
+   storing reference addresses.  javaFactory is the optional attribute
+   for storing the object factory's fully qualified class name.  The
+   mandatory javaClassName attribute is used to store the name of the
+   distinguished class of the object.  The optional javaClassNames
+
+
+
+Ryan, et al.                 Informational                      [Page 6]
+\f
+RFC 2713                Schema for Java Objects             October 1999
+
+
+   attribute is used to record additional class and interface names.
+   The optional javaCodebase attribute is used to store the locations of
+   the object factory's and the object's class definitions.
+
+   A directory entry containing a JNDI reference is represented by the
+   object class javaNamingReference, which is a subclass of javaObject.
+   javaNamingReference is an auxiliary object class, which means that it
+   needs to be mixed in with a structural object class.
+   javaNamingReference's definition is given in Section 4.
+
+2.5 Remote Objects
+
+   The Java Remote Method Invocation (RMI) system [RMI] is a mechanism
+   that enables an object on one Java virtual machine to invoke methods
+   on an object in another Java virtual machine. Any object whose
+   methods can be invoked in this way must implement the java.rmi.Remote
+   interface.  When such an object is invoked, its arguments are
+   marshalled and sent from the local virtual machine to the remote one,
+   where the arguments are unmarshalled and used.  When the method
+   terminates, the results are marshalled from the remote machine and
+   sent to the caller's virtual machine.
+
+   To make a remote object accessible to other virtual machines, a
+   program typically registers it with the RMI registry.  The program
+   supplies to the RMI registry the string name of the remote object and
+   the remote object itself.  When a program wants to access a remote
+   object, it supplies the object's string name to the RMI registry on
+   the same machine as the remote object.  The RMI registry returns to
+   the caller a reference (called "stub") to the remote object.  When
+   the program receives the stub for the remote object, it can invoke
+   methods on the remote object (through the stub).  A program can also
+   obtain references to remote objects as a result of remote calls to
+   other remote objects or from other naming services.  For example, the
+   program can look up a reference to a remote object from an LDAP
+   server that supports the schema defined in this document.
+
+   The string name accepted by the RMI registry has the syntax
+   "rmi://hostname:port/remoteObjectName", where "hostname" and "port"
+   identify the machine and port on which the RMI registry is running,
+   respectively, and "remoteObjectName" is the string name of the remote
+   object.  "hostname", "port", and the prefix, "rmi:", are optional. If
+   "hostname" is not specified, it defaults to the local host.  If
+   "port" is not specified, it defaults to 1099.  If "remoteObjectName"
+   is not specified, then the object being named is the RMI registry
+   itself.  See [RMI] for details.
+
+
+
+
+
+
+Ryan, et al.                 Informational                      [Page 7]
+\f
+RFC 2713                Schema for Java Objects             October 1999
+
+
+   RMI can be supported using different protocols: the Java Remote
+   Method Protocol (JRMP) and the Internet Inter-ORB Protocol (IIOP).
+   The JRMP is a specialized protocol designed for RMI; the IIOP is the
+   standard protocol for communication between CORBA objects [CORBA].
+   RMI over IIOP allows Java remote objects to communicate with CORBA
+   objects which might be written in a non-Java programming language
+   [RMI-IIOP].
+
+2.5.1 Representation in the Directory
+
+   Remote objects that use the IIOP are represented in the directory as
+   CORBA object references [CORBA-LDAP].  Remote objects that use the
+   JRMP are represented in the directory in one of two ways: as a
+   marshalled object, or as a JNDI reference.
+
+   A marshalled object records the codebases of the remote object's stub
+   and any serializable or remote objects that it references, and
+   replaces remote objects with their stubs.  To store a Remote object
+   as a marshalled object (java.rmi.MarshalledObject), you first create
+   a java.rmi.MarshalledObject instance for it.
+
+       java.rmi.Remote robj = ...;
+       java.rmi.MarshalledObject mobj =
+           new java.rmi.MarshalledObject(robj);
+
+   You can then store the MarshalledObject instance as a
+   javaMarshalledObject.  The javaClassName attribute should contain the
+   fully qualified name of the distinguished class of the remote object.
+   The javaClassNames attribute should contain the names of the classes
+   and interfaces of the remote object.  To read the remote object back
+   from the directory, first deserialize the contents of the
+   javaSerializedData to get a MarshalledObject (mobj), then retrieve it
+   from the MarshalledObject as follows:
+
+       java.rmi.Remote robj = (java.rmi.Remote)mobj.get();
+
+   This returns the remote stub, which you can then use to invoke remote
+   methods.
+
+   MarshalledObject is available only on the Java 2 Platform, Standard
+   Edition, v1.2 and higher releases. Therefore, a remote object stored
+   as a MarshalledObject can only be read by clients using the the Java
+   2 Platform, Standard Edition, v1.2 or higher releases.
+
+
+
+
+
+
+
+
+Ryan, et al.                 Informational                      [Page 8]
+\f
+RFC 2713                Schema for Java Objects             October 1999
+
+
+   To store a remote object as a JNDI reference, you first create a
+   javax.naming.Reference object instance for it using the remote
+   object's string name as it has been, or will be, recorded with the
+   RMI registry, with the additional restriction that the "rmi:" prefix
+   must be present. Here's an example:
+
+       javax.naming.Reference ref = new javax.naming.Reference(
+         obj.getClass().getName(),
+         new javax.naming.StringRefAddr("URL",
+             "rmi://rserver/AppRemoteObjectX"));
+
+   You then store the javax.naming.Reference instance as a
+   javaNamingReference.  The advantage of using a JNDI reference is that
+   this can be done without a reference to the remote object. In fact,
+   the remote object does not have to exist at the time that this
+   recording in the directory is made.  The remote object needs to exist
+   and be bound with the RMI registry when the object is looked up from
+   the directory.
+
+2.6  Serialized Objects Vs. Marshalled Objects Vs. References
+
+   The object classes defined in this document store different aspects
+   of the Java objects.
+
+   A javaSerializedObject or a serializable object stored as a
+   javaMarshalledObject represents the object itself, while a
+   javaNamingReference or a remote object stored as a
+   javaMarshalledObject represents a "pointer" to the object.
+
+   When storing a serializable object in the directory, you have a
+   choice of storing it as a javaSerializedObject or a
+   javaMarshalledObject.  The javaSerializedObject object class provides
+   the basic way in which to store serializable objects. When you create
+   an LDAP entry using the javaSerializableObject object class, you must
+   explicitly set the javaCodebase attribute if you want readers of that
+   entry to know where to load the class definitions of the object. When
+   you create an LDAP entry using the javaMarshalledObject object class,
+   you use the MarshalledObject class.  The MarshalledObject class uses
+   the RMI infrastructure available on the Java platform to automate how
+   codebase information is gathered and recorded, thus freeing you from
+   having to set the javaCodebase attribute. On the other hand, the
+   javaCodebase attribute is human-readable and can be updated easily by
+   using text-based tools without having to change other parts of the
+   entry.  This allows you, for instance, to move the class definitions
+   to another location and then update the javaCodebase attribute to
+   reflect the move without having to update the serialized object
+   itself.
+
+
+
+
+Ryan, et al.                 Informational                      [Page 9]
+\f
+RFC 2713                Schema for Java Objects             October 1999
+
+
+   A javaNamingReference provides a way of recording address information
+   about an object which itself is not directly stored in the directory.
+   A remote object stored as a javaMarshalledObject also records address
+   information (the object's "stub") of an object which itself is not
+   directory stored in the directory.  In other words, you can think of
+   these as compact representations of the information required to
+   access the object.
+
+   A javaNamingReference typically consists of a small number of human-
+   readable strings.  Standard text-based tools for directory
+   administration may therefore be used to add, read, or modify
+   reference entries -- if so desired -- quite easily.  Serialized and
+   marshalled objects are not intended to be read or manipulated
+   directly by humans.
+
+3 Attribute Type Definitions
+
+   The following attribute types are defined in this document:
+
+       javaClassName
+       javaClassNames
+       javaCodebase
+       javaSerializedData
+       javaFactory
+       javaReferenceAddress
+       javaDoc
+
+3.1 javaClassName
+
+   This attribute stores the fully qualified name of the Java object's
+   "distinguished" class or interface (for example, "java.lang.String").
+   It is a single-valued attribute. This attribute's syntax is '
+   Directory String' and its case is significant.
+
+       ( 1.3.6.1.4.1.42.2.27.4.1.6
+         NAME 'javaClassName'
+         DESC 'Fully qualified name of distinguished Java class or
+               interface'
+         EQUALITY caseExactMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+         SINGLE-VALUE
+       )
+
+
+
+
+
+
+
+
+
+Ryan, et al.                 Informational                     [Page 10]
+\f
+RFC 2713                Schema for Java Objects             October 1999
+
+
+3.2 javaCodebase
+
+   This attribute stores the Java class definition's locations.  It
+   specifies the locations from which to load the class definition for
+   the class specified by the javaClassName attribute.  Each value of
+   the attribute contains an ordered list of URLs, separated by spaces.
+   For example, a value of "url1 url2 url3" means that the three
+   (possibly interdependent) URLs (url1, url2, and url3) form the
+   codebase for loading in the Java class definition.
+
+   If the javaCodebase attribute contains more than one value, each
+   value is an independent codebase. That is, there is no relationship
+   between the URLs in one value and those in another; each value can be
+   viewed as an alternate source for loading the Java class definition.
+   See [Java] for information regarding class loading.
+
+   This attribute's syntax is 'IA5 String' and its case is significant.
+
+       ( 1.3.6.1.4.1.42.2.27.4.1.7
+         NAME 'javaCodebase'
+         DESC 'URL(s) specifying the location of class definition'
+         EQUALITY caseExactIA5Match
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       )
+
+3.3 javaClassNames
+
+   This attribute stores the Java object's fully qualified class or
+   interface names (for example, "java.lang.String").  It is a
+   multivalued attribute. When more than one value is present, each is
+   the name of a class or interface, or ancestor class or interface, of
+   this object.
+
+   This attribute's syntax is 'Directory String' and its case is
+   significant.
+
+       ( 1.3.6.1.4.1.42.2.27.4.1.13
+         NAME 'javaClassNames'
+         DESC 'Fully qualified Java class or interface name'
+         EQUALITY caseExactMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+       )
+
+
+
+
+
+
+
+
+
+Ryan, et al.                 Informational                     [Page 11]
+\f
+RFC 2713                Schema for Java Objects             October 1999
+
+
+3.4 javaSerializedData
+
+   This attribute stores the serialized form of a Java object.  The
+   serialized form is described in [Serial].
+
+   This attribute's syntax is 'Octet String'.
+
+       ( 1.3.6.1.4.1.42.2.27.4.1.8
+         NAME 'javaSerializedData
+         DESC 'Serialized form of a Java object'
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
+         SINGLE-VALUE
+       )
+
+3.5 javaFactory
+
+   This attribute stores the fully qualified class name of the object
+   factory (for example, "com.wiz.jndi.WizObjectFactory") that can be
+   used to create an instance of the object identified by the
+   javaClassName attribute.
+
+   This attribute's syntax is 'Directory String' and its case is
+   significant.
+
+       ( 1.3.6.1.4.1.42.2.27.4.1.10
+         NAME 'javaFactory'
+         DESC 'Fully qualified Java class name of a JNDI object factory'
+         EQUALITY caseExactMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+         SINGLE-VALUE
+       )
+
+3.6 javaReferenceAddress
+
+   This attribute represents the sequence of addresses of a JNDI
+   reference.  Each of its values represents one address, a Java object
+   of type javax.naming.RefAddr.  Its value is a concatenation of the
+   address type and address contents, preceded by a sequence number (the
+   order of addresses in a JNDI reference is significant).  For example:
+
+       #0#TypeA#ValA
+       #1#TypeB#ValB
+       #2#TypeC##rO0ABXNyABpq...
+
+   In more detail, the value is encoded as follows:
+
+
+
+
+
+
+Ryan, et al.                 Informational                     [Page 12]
+\f
+RFC 2713                Schema for Java Objects             October 1999
+
+
+   The delimiter is the first character of the value.  For readability
+   the character '#' is recommended when it is not otherwise used
+   anywhere in the value, but any character may be used subject to
+   restrictions given below.
+
+   The first delimiter is followed by the sequence number.  The sequence
+   number of an address is its position in the JNDI reference, with the
+   first address being numbered 0.  It is represented by its shortest
+   string form, in decimal notation.
+
+   The sequence number is followed by a delimiter, then by the address
+   type, and then by another delimiter.  If the address is of Java class
+   javax.naming.StringRefAddr, then this delimiter is followed by the
+   value of the address contents (which is a string).  Otherwise, this
+   delimiter is followed immediately by another delimiter, and then by
+   the Base64 encoding of the serialized form of the entire address.
+
+   The delimiter may be any character other than a digit or a character
+   contained in the address type.  In addition, if the address contents
+   is a string, the delimiter may not be the first character of that
+   string.
+
+   This attribute's syntax is 'Directory String' and its case is
+   significant.  It can contain multiple values.
+
+       ( 1.3.6.1.4.1.42.2.27.4.1.11
+         NAME 'javaReferenceAddress'
+         DESC 'Addresses associated with a JNDI Reference'
+         EQUALITY caseExactMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+       )
+
+3.7 javaDoc
+
+   This attribute stores a pointer to the Java documentation for the
+   class.  It's value is a URL. For example, the following URL points to
+   the specification of the java.lang.String class:
+   http://java.sun.com/products/jdk/1.2/docs/api/java/lang/String.html
+
+   This attribute's syntax is 'IA5 String' and its case is significant.
+
+       ( 1.3.6.1.4.1.42.2.27.4.1.12
+         NAME 'javaDoc'
+         DESC 'The Java documentation for the class'
+         EQUALITY caseExactIA5Match
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       )
+
+
+
+
+Ryan, et al.                 Informational                     [Page 13]
+\f
+RFC 2713                Schema for Java Objects             October 1999
+
+
+4 Object Class Definitions
+
+   The following object classes are defined in this document:
+
+       javaContainer
+       javaObject
+       javaSerializedObject
+       javaMarshalledObject
+       javaNamingReference
+
+4.1 javaContainer
+
+   This structural object class represents a container for a Java
+   object.
+
+       ( 1.3.6.1.4.1.42.2.27.4.2.1
+         NAME 'javaContainer'
+         DESC 'Container for a Java object'
+         SUP top
+         STRUCTURAL
+         MUST ( cn )
+       )
+
+4.2 javaObject
+
+   This abstract object class represents a Java object.  A javaObject
+   cannot exist in the directory; only auxiliary or structural
+   subclasses of it can exist in the directory.
+
+       ( 1.3.6.1.4.1.42.2.27.4.2.4
+         NAME 'javaObject'
+         DESC 'Java object representation'
+         SUP top
+         ABSTRACT
+         MUST ( javaClassName )
+         MAY ( javaClassNames $
+               javaCodebase $
+               javaDoc $
+               description )
+       )
+
+
+
+
+
+
+
+
+
+
+
+Ryan, et al.                 Informational                     [Page 14]
+\f
+RFC 2713                Schema for Java Objects             October 1999
+
+
+4.3 javaSerializedObject
+
+   This auxiliary object class represents a Java serialized object.  It
+   must be mixed in with a structural object class.
+
+       ( 1.3.6.1.4.1.42.2.27.4.2.5
+         NAME 'javaSerializedObject'
+         DESC 'Java serialized object'
+         SUP javaObject
+         AUXILIARY
+         MUST ( javaSerializedData )
+       )
+
+4.4 javaMarshalledObject
+
+   This auxiliary object class represents a Java marshalled object.  It
+   must be mixed in with a structural object class.
+
+       ( 1.3.6.1.4.1.42.2.27.4.2.8
+         NAME 'javaMarshalledObject'
+         DESC 'Java marshalled object'
+         SUP javaObject
+         AUXILIARY
+         MUST ( javaSerializedData )
+       )
+
+4.5 javaNamingReference
+
+   This auxiliary object class represents a JNDI reference.  It must be
+   mixed in with a structural object class.
+
+       ( 1.3.6.1.4.1.42.2.27.4.2.7
+         NAME 'javaNamingReference'
+         DESC 'JNDI reference'
+         SUP javaObject
+         AUXILIARY
+         MAY ( javaReferenceAddress $
+               javaFactory )
+       )
+
+
+
+
+
+
+
+
+
+
+
+
+Ryan, et al.                 Informational                     [Page 15]
+\f
+RFC 2713                Schema for Java Objects             October 1999
+
+
+5. Security Considerations
+
+   Serializing an object and storing it into the directory enables (a
+   copy of) the object to be examined and used outside the environment
+   in which it was originally created.  The directory entry containing
+   the serialized object could be read and modified within the
+   constraints imposed by the access control mechanisms of the
+   directory.  If an object contains sensitive information or
+   information that could be misused outside of the context in which it
+   was created, the object should not be stored in the directory.  For
+   more details on security issues relating to serialization in general,
+   see [Serial].
+
+6. Acknowledgements
+
+   We would like to thank Joseph Fialli, Peter Jones, Roger Riggs, Bob
+   Scheifler, and Ann Wollrath of Sun Microsystems for their comments
+   and suggestions.
+
+7. References
+
+   [CORBA]      The Object Management Group, "Common Object Request
+                Broker Architecture Specification 2.0,"
+                http://www.omg.org
+
+   [CORBA-LDAP] Ryan, V., Lee, R. and S. Seligman, "Schema for
+                Representing CORBA Object References in an LDAP
+                Directory", RFC 2714, October 1999.
+
+   [Java]       Ken Arnold and James Gosling, "The Java(tm) Programming
+                Language," Second Edition, ISBN 0-201-31006-6.
+
+   [JNDI]       Java Software, Sun Microsystems, Inc., "The Java(tm)
+                Naming and Directory Interface (tm) Specification,"
+                February 1998.  http://java.sun.com/products/jndi/
+
+   [LDAPv3]     Wahl, M., Howes, T. and  S. Kille, "Lightweight
+                Directory Access Protocol (v3)", RFC 2251, December
+                1997.
+
+   [RMI]        Java Software, Sun Microsystems, Inc., "Remote Method
+                Invocation," November 1998.
+                http://java.sun.com/products/jdk/1.2/docs/guide/rmi
+
+
+
+
+
+
+
+
+Ryan, et al.                 Informational                     [Page 16]
+\f
+RFC 2713                Schema for Java Objects             October 1999
+
+
+   [RMI-IIOP]   IBM and Java Software, Sun Microsystems, Inc., "RMI over
+                IIOP", June 1999.
+                http://java.sun.com/products/rmi-iiop/
+
+   [Serial]     Java Software, Sun Microsystems, Inc., "Object
+                Serialization Specification," November 1998.
+                http://java.sun.com/products/jdk/1.2/docs/guide/
+                serialization
+
+   [v3Schema]   Wahl, M., "A Summary of the X.500(96) User Schema for
+                use with LDAPv3", RFC 2256, December 1997.
+
+8. Authors' Addresses
+
+   Vincent Ryan
+   Sun Microsystems, Inc.
+   Mail Stop EDUB03
+   901 San Antonio Road
+   Palo Alto, CA 94303
+   USA
+
+   Phone: +353 1 819 9151
+   EMail: vincent.ryan@ireland.sun.com
+
+
+   Scott Seligman
+   Sun Microsystems, Inc.
+   Mail Stop UCUP02-209
+   901 San Antonio Road
+   Palo Alto, CA 94303
+   USA
+
+   Phone: +1 408 863 3222
+   EMail: scott.seligman@eng.sun.com
+
+
+   Rosanna Lee
+   Sun Microsystems, Inc.
+   Mail Stop UCUP02-206
+   901 San Antonio Road
+   Palo Alto, CA 94303
+   USA
+
+   Phone: +1 408 863 3221
+   EMail: rosanna.lee@eng.sun.com
+
+
+
+
+
+
+Ryan, et al.                 Informational                     [Page 17]
+\f
+RFC 2713                Schema for Java Objects             October 1999
+
+
+Appendix - LDAP Schema
+
+  -- Attribute types --
+
+  ( 1.3.6.1.4.1.42.2.27.4.1.6
+    NAME 'javaClassName'
+    DESC 'Fully qualified name of distinguished Java class or interface'
+    EQUALITY caseExactMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+    SINGLE-VALUE
+  )
+
+  ( 1.3.6.1.4.1.42.2.27.4.1.7
+    NAME 'javaCodebase'
+    DESC 'URL(s) specifying the location of class definition'
+    EQUALITY caseExactIA5Match
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  )
+
+  ( 1.3.6.1.4.1.42.2.27.4.1.8
+    NAME 'javaSerializedData'
+    DESC 'Serialized form of a Java object'
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
+    SINGLE-VALUE
+  )
+
+  ( 1.3.6.1.4.1.42.2.27.4.1.10
+    NAME 'javaFactory'
+    DESC 'Fully qualified Java class name of a JNDI object factory'
+    EQUALITY caseExactMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+    SINGLE-VALUE
+  )
+
+  ( 1.3.6.1.4.1.42.2.27.4.1.11
+    NAME 'javaReferenceAddress'
+    DESC 'Addresses associated with a JNDI Reference'
+    EQUALITY caseExactMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+  )
+
+  ( 1.3.6.1.4.1.42.2.27.4.1.12
+    NAME 'javaDoc'
+    DESC 'The Java documentation for the class'
+    EQUALITY caseExactIA5Match
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  )
+
+
+
+
+Ryan, et al.                 Informational                     [Page 18]
+\f
+RFC 2713                Schema for Java Objects             October 1999
+
+
+  ( 1.3.6.1.4.1.42.2.27.4.1.13
+    NAME 'javaClassNames'
+    DESC 'Fully qualified Java class or interface name'
+    EQUALITY caseExactMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+  )
+
+  -- from RFC-2256 --
+
+  ( 2.5.4.13
+    NAME 'description'
+    EQUALITY caseIgnoreMatch
+    SUBSTR caseIgnoreSubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024}
+  )
+
+  -- Object classes --
+
+  ( 1.3.6.1.4.1.42.2.27.4.2.1
+    NAME 'javaContainer'
+    DESC 'Container for a Java object'
+    SUP top
+    STRUCTURAL
+    MUST ( cn )
+  )
+
+  ( 1.3.6.1.4.1.42.2.27.4.2.4
+    NAME 'javaObject'
+    DESC 'Java object representation'
+    SUP top
+    ABSTRACT
+    MUST ( javaClassName )
+    MAY ( javaClassNames $ javaCodebase $ javaDoc $ description )
+  )
+
+  ( 1.3.6.1.4.1.42.2.27.4.2.5
+    NAME 'javaSerializedObject'
+    DESC 'Java serialized object'
+    SUP javaObject
+    AUXILIARY
+    MUST ( javaSerializedData )
+  )
+
+
+
+
+
+
+
+
+
+Ryan, et al.                 Informational                     [Page 19]
+\f
+RFC 2713                Schema for Java Objects             October 1999
+
+
+  ( 1.3.6.1.4.1.42.2.27.4.2.7
+    NAME 'javaNamingReference'
+    DESC 'JNDI reference'
+    SUP javaObject
+    AUXILIARY
+    MAY ( javaReferenceAddress $ javaFactory )
+  )
+
+  ( 1.3.6.1.4.1.42.2.27.4.2.8
+    NAME 'javaMarshalledObject'
+    DESC 'Java marshalled object'
+    SUP javaObject
+    AUXILIARY
+    MUST ( javaSerializedData )
+  )
+
+  -- Matching rule from ISO X.520 --
+
+  ( 2.5.13.5
+    NAME 'caseExactMatch'
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+  )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Ryan, et al.                 Informational                     [Page 20]
+\f
+RFC 2713                Schema for Java Objects             October 1999
+
+
+Full Copyright Statement
+
+   Copyright (C) The Internet Society (1999).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Ryan, et al.                 Informational                     [Page 21]
+\f
diff --git a/doc/rfc/rfc2714.txt b/doc/rfc/rfc2714.txt
new file mode 100644 (file)
index 0000000..172ff30
--- /dev/null
@@ -0,0 +1,563 @@
+
+
+
+
+
+
+Network Working Group                                            V. Ryan
+Request for Comments: 2714                                        R. Lee
+Category: Informational                                      S. Seligman
+                                                  Sun Microsystems, Inc.
+                                                            October 1999
+
+
+  Schema for Representing CORBA Object References in an LDAP Directory
+
+Status of this Memo
+
+   This memo provides information for the Internet community.  It does
+   not specify an Internet standard of any kind.  Distribution of this
+   memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (1999).  All Rights Reserved.
+
+Abstract
+
+   CORBA [CORBA] is the Common Object Request Broker Architecture
+   defined by the Object Management Group. This document defines the
+   schema for representing CORBA object references in an LDAP directory
+   [LDAPv3].
+
+1. Introduction
+
+   This document assumes that the reader has a general understanding of
+   CORBA.
+
+   Traditionally, LDAP directories have been used to store data. Users
+   and programmers think of the directory as a hierarchy of directory
+   entries, each containing a set of attributes.  You look up an entry
+   from the directory and extract the attribute(s) of interest.  For
+   example, you can look up a person's telephone number from the
+   directory.  Alternatively, you can search the directory for entries
+   with a particular set of attributes.  For example, you can search for
+   all persons in the directory with the surname "Smith".
+
+   CORBA applications require access to CORBA objects. Traditionally,
+   CORBA applications have used the COS Naming service for storage and
+   retrieval of CORBA object references. When deployed in environments
+   with a directory, CORBA applications should be able to use the
+   directory as a repository for CORBA object references. The directory
+   provides a centrally administered, and possibly replicated, service
+   for use by CORBA applications distributed across the network.
+
+
+
+
+Ryan, et al.                 Informational                      [Page 1]
+\f
+RFC 2714           Schema for CORBA Object References       October 1999
+
+
+   For example, an application server may use the directory for
+   "registering" CORBA objects representing the services that it
+   manages, so that a client can later search the directory to locate
+   those services as it needs.
+
+   The motivation for this document is to define a common way for
+   applications to store and retrieve CORBA object references from the
+   directory.  Using this common schema, any CORBA application that
+   needs to read or store CORBA object references in the directory can
+   do so in an interoperable way.
+
+   Note that this schema is defined for storing CORBA "object
+   references," not CORBA objects in general. There might be other ways
+   to store CORBA objects in an LDAP directory but they are not covered
+   by this schema.
+
+2. Representation of CORBA Object References
+
+   This document defines schema elements to represent a CORBA object
+   reference in LDAP directory. Applications in possession of a
+   reference to an object can invoke calls on that object.  Such a
+   reference is termed an "interoperable object reference," or IOR.
+   Access to CORBA objects by using IORs is achieved transparently to
+   the application, by means of the General Inter-ORB Protocol.
+
+   A CORBA object reference is represented in the directory by the
+   object class corbaObjectReference. corbaObjectReference is a subclass
+   of the abstract corbaObject object class. corbaObjectReference is an
+   auxiliary object class, which means that it needs to be mixed in with
+   a structural object class.
+
+   The object class corbaContainer is used in a directory entry which
+   represents a CORBA object or object reference. It is a structural
+   object class, and when representing an object reference, the
+   corbaObjectReference object class would also need to be present in
+   the entry.  corbaContainer is not required when a subclass of
+   corbaObject (such as corbaObjectReference) is mixed in with another
+   structural object class.
+
+   The definitions for the object classes corbaObject,
+   corbaObjectReference, and corbaContainer are presented in Section 4.
+
+   The corbaObject class has two optional attributes: corbaRepositoryId
+   and description.  corbaRepositoryId is a multivalued attribute that
+   is used to store the repository ids of the interfaces implemented by
+   a CORBA object.  description is used to store a textual description
+   of a CORBA object.
+
+
+
+
+Ryan, et al.                 Informational                      [Page 2]
+\f
+RFC 2714           Schema for CORBA Object References       October 1999
+
+
+   The corbaObjectReference class has one mandatory attribute: corbaIor.
+   corbaIor is used to store the object's stringified IOR.
+
+   corbaIor and corbaRepositoryId are defined in Section 3; description
+   is defined in [v3Schema].
+
+3. Attribute Type Definitions
+
+   The following attribute types are defined in this document:
+
+       corbaIor
+       corbaRepositoryId
+
+3.1 corbaIor
+
+   This attribute stores the string representation of the interoperable
+   object reference (IOR) for a CORBA object. An IOR is an opaque handle
+   for the object which contains the information necessary to locate the
+   object, even if the object is in another ORB.
+
+   This attribute's syntax is 'IA5 String' and its case is
+   insignificant.
+
+   ( 1.3.6.1.4.1.42.2.27.4.1.14
+    NAME 'corbaIor'
+    DESC 'Stringified interoperable object reference of a CORBA object'
+    EQUALITY caseIgnoreIA5Match
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    SINGLE-VALUE
+   )
+
+3.2 corbaRepositoryId
+
+   Each CORBA interface has a unique "repository id" (also called "type
+   id") that identifies the interface.  A CORBA object has one or more
+   repository ids, one for each interface that it implements.
+
+   The format of a repository id can be any string, but the OMG
+   specifies four standard formats:
+
+      a. IDL-style
+
+       IDL:Prefix/ModuleName/InterfaceName:VersionNumber
+
+
+
+
+
+
+
+
+Ryan, et al.                 Informational                      [Page 3]
+\f
+RFC 2714           Schema for CORBA Object References       October 1999
+
+
+   For example, the repository id for the "NamingContext" in OMG's COS
+   Naming module is:  "IDL:omg.org/CosNaming/NamingContext:1.0".
+
+      b. RMI-style
+
+       RMI:ClassName:HashCode[:SUID]
+
+   This format is used by RMI-IIOP remote objects [RMI-IIOP].
+   "ClassName" is the fully qualified name of the class (for example,
+   "java.lang.String"). "HashCode" is the object's hash code (that is,
+   that obtained by invoking the "hashCode()" method).  "SUID" is the
+   "stream unique identifier", which is a 64-bit number that uniquely
+   identifies the serialization version of the class; SUID is optional
+   in the repository id.
+
+      c. DCE-style
+
+       DCE:UUID
+
+   This format is used for DCE/CORBA interoperability [CORBA-DCE].
+   "UUID" represents a DCE UUID.
+
+      d. "local"
+
+   This format is defined by the local Object Request Broker (ORB).
+
+   The corbaRepositoryId attribute is a multivalued attribute; each
+   value records a single repository id of an interface implemented by
+   the CORBA object.  This attribute need not contain a complete list of
+   the interfaces implemented by the CORBA object.
+
+   This attribute's syntax is 'Directory String' and its case is
+   significant.  The values of this attribute are encoded using UTF-8.
+   Some values may require translation from their native representation
+   in order to be correctly encoded using UTF-8.
+
+   ( 1.3.6.1.4.1.42.2.27.4.1.15
+    NAME 'corbaRepositoryId'
+    DESC 'Repository ids of interfaces implemented by a CORBA object'
+    EQUALITY caseExactMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+   )
+
+
+
+
+
+
+
+
+
+Ryan, et al.                 Informational                      [Page 4]
+\f
+RFC 2714           Schema for CORBA Object References       October 1999
+
+
+4. Object Class Definitions
+
+   The following object classes are defined in this document:
+
+       corbaContainer
+       corbaObject
+       corbaObjectReference
+
+4.1 corbaContainer
+
+   This structural object class represents a container for a CORBA
+   object.
+
+   ( 1.3.6.1.4.1.42.2.27.4.2.10
+    NAME 'corbaContainer'
+    DESC 'Container for a CORBA object'
+    SUP top
+    STRUCTURAL
+    MUST ( cn )
+   )
+
+4.2 corbaObject
+
+   This abstract object class is the root class for representing a CORBA
+   object.
+
+   ( 1.3.6.1.4.1.42.2.27.4.2.9
+    NAME 'corbaObject'
+    DESC 'CORBA object representation'
+    SUP top
+    ABSTRACT
+    MAY ( corbaRepositoryId $ description )
+   )
+
+4.3 corbaObjectReference
+
+   This auxiliary object class represents a CORBA object reference.  It
+   must be mixed in with a structural object class.
+
+   ( 1.3.6.1.4.1.42.2.27.4.2.11
+    NAME 'corbaObjectReference'
+    DESC 'CORBA interoperable object reference'
+    SUP corbaObject
+    AUXILIARY
+    MUST ( corbaIor )
+   )
+
+
+
+
+
+Ryan, et al.                 Informational                      [Page 5]
+\f
+RFC 2714           Schema for CORBA Object References       October 1999
+
+
+5. Security Considerations
+
+   Obtaining a reference to an object and storing it in the directory
+   may make a handle to the object available to a wider audience.  This
+   may have security implications.
+
+6. Acknowledgements
+
+   We would like to thank Sanjeev Krishnan of Sun Microsystems, Simon
+   Nash of IBM, and Jeffrey Spirn of Oracle for their comments and
+   suggestions.
+
+7. References
+
+   [CORBA]     The Object Management Group, "Common Object Request
+               Broker Architecture Specification 2.2",
+               http://www.omg.org
+
+   [CORBA-DCE] Distributed Systems Technology Center and Digital
+               Equipment Corporation, "DCE/CORBA Interworking
+               Specification", May 1998.
+               http://www.omg.org/library/schedule/
+               DCE_CORBA_Interworking_RFP.html
+
+   [LDAPv3]    Wahl, M., Howes, T. and S. Kille, "Lightweight Directory
+               Access Protocol (v3)", RFC 2251, December 1997.
+
+   [RMI-IIOP]  IBM and Java Software, Sun Microsystems, Inc., "RMI over
+               IIOP", June 1999.  http://java.sun.com/products/rmi-
+               iiop/index.html
+
+   [v3Schema]  Wahl, M., "A Summary of the X.500(96) User Schema for use
+               with LDAPv3", RFC 2256, December 1997.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Ryan, et al.                 Informational                      [Page 6]
+\f
+RFC 2714           Schema for CORBA Object References       October 1999
+
+
+8. Authors' Addresses
+
+   Vincent Ryan
+   Sun Microsystems, Inc.
+   Mail Stop EDUB03
+   901 San Antonio Road
+   Palo Alto, CA 94303
+   USA
+
+   Phone: +353 1 819 9151
+   EMail: vincent.ryan@ireland.sun.com
+
+
+   Rosanna Lee
+   Sun Microsystems, Inc.
+   Mail Stop UCUP02-206
+   901 San Antonio Road
+   Palo Alto, CA 94303
+   USA
+
+   Phone: +1 408 863 3221
+   EMail: rosanna.lee@eng.sun.com
+
+
+   Scott Seligman
+   Sun Microsystems, Inc.
+   Mail Stop UCUP02-209
+   901 San Antonio Road
+   Palo Alto, CA 94303
+   USA
+
+   Phone: +1 408 863 3222
+   EMail: scott.seligman@eng.sun.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Ryan, et al.                 Informational                      [Page 7]
+\f
+RFC 2714           Schema for CORBA Object References       October 1999
+
+
+9. Appendix  - LDAP Schema
+
+   -- Attribute types --
+
+   ( 1.3.6.1.4.1.42.2.27.4.1.14
+    NAME 'corbaIor'
+    DESC 'Stringified interoperable object reference of a CORBA object'
+    EQUALITY caseIgnoreIA5Match
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+    SINGLE-VALUE
+   )
+
+   ( 1.3.6.1.4.1.42.2.27.4.1.15
+    NAME 'corbaRepositoryId'
+    DESC 'Repository ids of interfaces implemented by a CORBA object'
+    EQUALITY caseExactMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+   )
+
+   -- from RFC-2256 --
+
+   ( 2.5.4.13
+    NAME 'description'
+    EQUALITY caseIgnoreMatch
+    SUBSTR caseIgnoreSubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024}
+   )
+
+   -- Object classes --
+
+   ( 1.3.6.1.4.1.42.2.27.4.2.9
+    NAME 'corbaObject'
+    DESC 'CORBA object representation'
+    SUP top
+    ABSTRACT
+    MAY ( corbaRepositoryId $ description )
+   )
+
+   ( 1.3.6.1.4.1.42.2.27.4.2.10
+    NAME 'corbaContainer'
+    DESC 'Container for a CORBA object'
+    SUP top
+    STRUCTURAL
+    MUST ( cn )
+   )
+
+
+
+
+
+
+Ryan, et al.                 Informational                      [Page 8]
+\f
+RFC 2714           Schema for CORBA Object References       October 1999
+
+
+   ( 1.3.6.1.4.1.42.2.27.4.2.11
+    NAME 'corbaObjectReference'
+    DESC 'CORBA interoperable object reference'
+    SUP corbaObject
+    AUXILIARY
+    MUST ( corbaIor )
+   )
+
+   -- Matching rule from ISO X.520 --
+
+   ( 2.5.13.5
+    NAME 'caseExactMatch'
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+   )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Ryan, et al.                 Informational                      [Page 9]
+\f
+RFC 2714           Schema for CORBA Object References       October 1999
+
+
+10.  Full Copyright Statement
+
+   Copyright (C) The Internet Society (1999).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Ryan, et al.                 Informational                     [Page 10]
+\f
diff --git a/doc/rfc/rfc2798.txt b/doc/rfc/rfc2798.txt
new file mode 100644 (file)
index 0000000..3ad08a2
--- /dev/null
@@ -0,0 +1,1123 @@
+
+
+
+
+
+
+Network Working Group                                          M. Smith
+Request for Comments: 2798                      Netscape Communications
+Category: Informational                                      April 2000
+
+
+           Definition of the inetOrgPerson LDAP Object Class
+
+Status of this Memo
+
+   This memo provides information for the Internet community.  It does
+   not specify an Internet standard of any kind.  Distribution of this
+   memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2000).  All Rights Reserved.
+
+Abstract
+
+   While the X.500 standards define many useful attribute types [X520]
+   and object classes [X521], they do not define a person object class
+   that meets the requirements found in today's Internet and Intranet
+   directory service deployments.  We define a new object class called
+   inetOrgPerson for use in LDAP and X.500 directory services that
+   extends the X.521 standard organizationalPerson class to meet these
+   needs.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Smith                        Informational                      [Page 1]
+\f
+RFC 2798          The LDAP inetOrgPerson Object Class         April 2000
+
+
+Table of Contents
+
+   1.     Background and Intended Usage...............................2
+   2.     New Attribute Types Used in the inetOrgPerson Object Class..3
+   2.1.      Vehicle license or registration plate....................3
+   2.2.      Department number........................................3
+   2.3.      Display Name.............................................4
+   2.4.      Employee Number..........................................4
+   2.5.      Employee Type............................................4
+   2.6.      JPEG Photograph..........................................5
+   2.7.      Preferred Language.......................................5
+   2.8.      User S/MIME Certificate..................................5
+   2.9.      User PKCS #12............................................6
+   3.     Definition of the inetOrgPerson Object Class................6
+   4.     Example of an inetOrgPerson Entry...........................7
+   5.     Security Considerations.....................................8
+   6.     Acknowledgments.............................................8
+   7.     Bibliography................................................8
+   8.     Author's Address............................................9
+   9.     Appendix A - inetOrgPerson Schema Summary..................10
+   9.1.     Attribute Types..........................................10
+   9.1.1.      New attribute types that are defined in this document.10
+   9.1.2.      Attribute types from RFC 2256.........................12
+   9.1.3.      Attribute types from RFC 1274.........................15
+   9.1.4.      Attribute type from RFC 2079..........................16
+   9.2.     Syntaxes.................................................17
+   9.2.1.      Syntaxes from RFC 2252................................17
+   9.2.2.      Syntaxes from RFC 2256................................17
+   9.3.     Matching Rules...........................................17
+   9.3.1.      Matching rules from RFC 2252..........................17
+   9.3.2.      Matching rule from RFC 2256...........................18
+   9.3.3.      Additional matching rules from X.520..................18
+   9.3.4.      Matching rules not defined in any referenced document.19
+   10.    Full Copyright Statement...................................20
+
+1.  Background and Intended Usage
+
+   The inetOrgPerson object class is a general purpose object class that
+   holds attributes about people.  The attributes it holds were chosen
+   to accommodate information requirements found in typical Internet and
+   Intranet directory service deployments.  The inetOrgPerson object
+   class is designed to be used within directory services based on the
+   LDAP [RFC2251] and the X.500 family of protocols, and it should be
+   useful in other contexts as well.  There is no requirement for
+   directory services implementors to use the inetOrgPerson object
+   class; it is simply presented as well-documented class that
+   implementors can choose to use if they find it useful.
+
+
+
+
+Smith                        Informational                      [Page 2]
+\f
+RFC 2798          The LDAP inetOrgPerson Object Class         April 2000
+
+
+   The attribute type and object class definitions in this document are
+   written using the BNF form of AttributeTypeDescription and
+   ObjectClassDescription given in [RFC2252].  In some cases lines have
+   been folded for readability.
+
+   Attributes that are referenced but not defined in this document are
+   included in one of the following documents:
+
+      The COSINE and Internet X.500 Schema [RFC1274]
+
+      Definition of an X.500 Attribute Type and an Object Class to Hold
+      Uniform Resource Identifiers (URIs) [RFC2079]
+
+      A Summary of the X.500(96) User Schema for use with LDAPv3
+      [RFC2256]
+
+   See Appendix A for a summary of the attribute types, associated
+   syntaxes, and matching rules used in this document.
+
+2.  New Attribute Types Used in the inetOrgPerson Object Class
+
+2.1.  Vehicle license or registration plate.
+
+   This multivalued field is used to record the values of the license or
+   registration plate associated with an individual.
+
+    ( 2.16.840.1.113730.3.1.1 NAME 'carLicense'
+      DESC 'vehicle license or registration plate'
+      EQUALITY caseIgnoreMatch
+      SUBSTR caseIgnoreSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+2.2.  Department number
+
+   Code for department to which a person belongs.  This can also be
+   strictly numeric (e.g., 1234) or alphanumeric (e.g., ABC/123).
+
+    ( 2.16.840.1.113730.3.1.2
+      NAME 'departmentNumber'
+      DESC 'identifies a department within an organization'
+      EQUALITY caseIgnoreMatch
+      SUBSTR caseIgnoreSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+
+
+
+
+
+
+Smith                        Informational                      [Page 3]
+\f
+RFC 2798          The LDAP inetOrgPerson Object Class         April 2000
+
+
+2.3.  Display Name
+
+   When displaying an entry, especially within a one-line summary list,
+   it is useful to be able to identify a name to be used.  Since other
+   attribute types such as 'cn' are multivalued, an additional attribute
+   type is needed.  Display name is defined for this purpose.
+
+  ( 2.16.840.1.113730.3.1.241
+    NAME 'displayName'
+    DESC 'preferred name of a person to be used when displaying entries'
+    EQUALITY caseIgnoreMatch
+    SUBSTR caseIgnoreSubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+    SINGLE-VALUE )
+
+2.4.  Employee Number
+
+   Numeric or alphanumeric identifier assigned to a person, typically
+   based on order of hire or association with an organization.  Single
+   valued.
+
+    ( 2.16.840.1.113730.3.1.3
+      NAME 'employeeNumber'
+      DESC 'numerically identifies an employee within an organization'
+      EQUALITY caseIgnoreMatch
+      SUBSTR caseIgnoreSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+      SINGLE-VALUE )
+
+2.5.  Employee Type
+
+   Used to identify the employer to employee relationship.  Typical
+   values used will be "Contractor", "Employee", "Intern", "Temp",
+   "External", and "Unknown" but any value may be used.
+
+    ( 2.16.840.1.113730.3.1.4
+      NAME 'employeeType'
+      DESC 'type of employment for a person'
+      EQUALITY caseIgnoreMatch
+      SUBSTR caseIgnoreSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+
+
+
+
+
+
+
+
+Smith                        Informational                      [Page 4]
+\f
+RFC 2798          The LDAP inetOrgPerson Object Class         April 2000
+
+
+2.6.  JPEG Photograph
+
+   Used to store one or more images of a person using the JPEG File
+   Interchange Format [JFIF].
+
+    ( 0.9.2342.19200300.100.1.60
+      NAME 'jpegPhoto'
+      DESC 'a JPEG image'
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.28 )
+
+   Note that the jpegPhoto attribute type was defined for use in the
+   Internet X.500 pilots but no referencable definition for it could be
+   located.
+
+2.7.  Preferred Language
+
+   Used to indicate an individual's preferred written or spoken
+   language.  This is useful for international correspondence or human-
+   computer interaction.  Values for this attribute type MUST conform to
+   the definition of the Accept-Language header field defined in
+   [RFC2068] with one exception:  the sequence "Accept-Language" ":"
+   should be omitted.  This is a single valued attribute type.
+
+    ( 2.16.840.1.113730.3.1.39
+      NAME 'preferredLanguage'
+      DESC 'preferred written or spoken language for a person'
+      EQUALITY caseIgnoreMatch
+      SUBSTR caseIgnoreSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+      SINGLE-VALUE )
+   )
+
+2.8.  User S/MIME Certificate
+
+   A PKCS#7 [RFC2315] SignedData, where the content that is signed is
+   ignored by consumers of userSMIMECertificate values.  It is
+   recommended that values have a `contentType' of data with an absent
+   `content' field.  Values of this attribute contain a person's entire
+   certificate chain and an smimeCapabilities field [RFC2633] that at a
+   minimum describes their SMIME algorithm capabilities.  Values for
+   this attribute are to be stored and requested in binary form, as
+   'userSMIMECertificate;binary'.  If available, this attribute is
+   preferred over the userCertificate attribute for S/MIME applications.
+
+    ( 2.16.840.1.113730.3.1.40
+      NAME 'userSMIMECertificate'
+      DESC 'PKCS#7 SignedData used to support S/MIME'
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 )
+
+
+
+Smith                        Informational                      [Page 5]
+\f
+RFC 2798          The LDAP inetOrgPerson Object Class         April 2000
+
+
+2.9.  User PKCS #12
+
+   PKCS #12 [PKCS12] provides a format for exchange of personal identity
+   information.  When such information is stored in a directory service,
+   the userPKCS12 attribute should be used. This attribute is to be
+   stored and requested in binary form, as 'userPKCS12;binary'.  The
+   attribute values are PFX PDUs stored as binary data.
+
+( 2.16.840.1.113730.3.1.216
+  NAME 'userPKCS12'
+  DESC 'PKCS #12 PFX PDU for exchange of personal identity information'
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 )
+
+3.  Definition of the inetOrgPerson Object Class
+
+   The inetOrgPerson represents people who are associated with an
+   organization in some way.  It is a structural class and is derived
+   from the organizationalPerson class which is defined in X.521 [X521].
+
+( 2.16.840.1.113730.3.2.2
+    NAME 'inetOrgPerson'
+    SUP organizationalPerson
+    STRUCTURAL
+    MAY (
+        audio $ businessCategory $ carLicense $ departmentNumber $
+        displayName $ employeeNumber $ employeeType $ givenName $
+        homePhone $ homePostalAddress $ initials $ jpegPhoto $
+        labeledURI $ mail $ manager $ mobile $ o $ pager $
+        photo $ roomNumber $ secretary $ uid $ userCertificate $
+        x500uniqueIdentifier $ preferredLanguage $
+        userSMIMECertificate $ userPKCS12
+    )
+)
+
+   For reference, we list the following additional attribute types that
+   are part of the inetOrgPerson object class.  These attribute types
+   are inherited from organizationalPerson (which in turn is derived
+   from the person object class):
+
+
+
+
+
+
+
+
+
+
+
+
+
+Smith                        Informational                      [Page 6]
+\f
+RFC 2798          The LDAP inetOrgPerson Object Class         April 2000
+
+
+    MUST (
+        cn $ objectClass $ sn
+    )
+    MAY (
+        description $ destinationIndicator $ facsimileTelephoneNumber $
+        internationaliSDNNumber $ l $ ou $ physicalDeliveryOfficeName $
+        postalAddress $ postalCode $ postOfficeBox $
+        preferredDeliveryMethod $ registeredAddress $ seeAlso $
+        st $ street $ telephoneNumber $ teletexTerminalIdentifier $
+        telexNumber $ title $ userPassword $ x121Address
+    )
+
+4.  Example of an inetOrgPerson Entry
+
+   The following example is expressed using the LDIF notation defined in
+   [LDIF].
+
+   version: 1
+   dn: cn=Barbara Jensen,ou=Product Development,dc=siroe,dc=com
+   objectClass: top
+   objectClass: person
+   objectClass: organizationalPerson
+   objectClass: inetOrgPerson
+   cn: Barbara Jensen
+   cn: Babs Jensen
+   displayName: Babs Jensen
+   sn: Jensen
+   givenName: Barbara
+   initials: BJJ
+   title: manager, product development
+   uid: bjensen
+   mail: bjensen@siroe.com
+   telephoneNumber: +1 408 555 1862
+   facsimileTelephoneNumber: +1 408 555 1992
+   mobile: +1 408 555 1941
+   roomNumber: 0209
+   carLicense: 6ABC246
+   o: Siroe
+   ou: Product Development
+   departmentNumber: 2604
+   employeeNumber: 42
+   employeeType: full time
+   preferredLanguage: fr, en-gb;q=0.8, en;q=0.7
+   labeledURI: http://www.siroe.com/users/bjensen My Home Page
+
+
+
+
+
+
+
+Smith                        Informational                      [Page 7]
+\f
+RFC 2798          The LDAP inetOrgPerson Object Class         April 2000
+
+
+5.  Security Considerations
+
+   Attributes of directory entries are used to provide descriptive
+   information about the real-world objects they represent, which can be
+   people, organizations or devices.  Most countries have privacy laws
+   regarding the publication of information about people.
+
+   Transfer of cleartext passwords are strongly discouraged where the
+   underlying transport service cannot guarantee confidentiality and may
+   result in disclosure of the password to unauthorized parties.
+
+6.  Acknowledgments
+
+   The Netscape Directory Server team created the inetOrgPerson object
+   class based on experience and customer requirements.  Anil Bhavnani
+   and John Kristian in particular deserve credit for all of the early
+   design work.
+
+   Many members of the Internet community, in particular those in the
+   IETF ASID and LDAPEXT groups, also contributed to the design of this
+   object class.
+
+7.  Bibliography
+
+   [JFIF]    E. Hamilton, "JPEG File Interchange Format (Version 1.02)",
+             C-Cube Microsystems, Milpitas, CA, September 1, 1992.
+
+   [LDIF]    G. Good, "The LDAP Data Interchange Format (LDIF) -
+             Technical Specification", Work in Progress.
+
+   [PKCS12]  "PKCS #12: Personal Information Exchange Standard", Version
+             1.0 Draft, 30 April 1997.
+
+   [RFC1274] Barker, P. and S. Kille, "The COSINE and Internet X.500
+             Schema", RFC 1274, November 1991.
+
+   [RFC1847] Galvin, J., Murphy, S., Crocker, S. and N. Freed, "Security
+             Multiparts for MIME:  Multipart/Signed and
+             Multipart/Encrypted", RFC 1847, October 1995.
+
+   [RFC2068] Fielding, R., Gettys, J., Mogul, J., Frystyk, H. and T.
+             Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC
+             2068, January 1997.
+
+   [RFC2079] Smith, M., "Definition of an X.500 Attribute Type and an
+             Object Class to Hold Uniform Resource Identifiers (URIs)",
+             RFC 2079, January 1997.
+
+
+
+
+Smith                        Informational                      [Page 8]
+\f
+RFC 2798          The LDAP inetOrgPerson Object Class         April 2000
+
+
+   [RFC2251] Wahl, M., Howes, T. and S. Kille, "Lightweight Directory
+             Access Protocol (v3)", RFC 2251, December 1997.
+
+   [RFC2252] Wahl, M., Coulbeck, A., Howes, T., Kille, S., Yeong, W. and
+             C. Robbins, "Lightweight Directory Access Protocol (v3):
+             Attribute Syntax Definitions", RFC 2252, December 1997.
+
+   [RFC2256] Wahl, M., "A Summary of the X.500(96) User Schema for use
+             with LDAPv3", RFC 2256, December 1997.
+
+   [RFC2315] Kaliski, B., "PKCS #7: Cryptographic Message Syntax Version
+             1.5", RFC 2315, March 1998.
+
+   [RFC2633] Ramsdell, B., "S/MIME Version 3 Message Specification", RFC
+             2633, June 1999.
+
+   [X520]    ITU-T Rec. X.520, "The Directory: Selected Attribute
+             Types", 1996.
+
+   [X521]    ITU-T Rec. X.521, "The Directory: Selected Object Classes",
+             1996.
+
+8.  Author's Address
+
+   Mark Smith
+   Netscape Communications Corp.
+   501 E. Middlefield Rd., Mailstop MV068
+   Mountain View, CA 94043, USA
+
+   Phone:  +1 650 937-3477
+   EMail:  mcs@netscape.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Smith                        Informational                      [Page 9]
+\f
+RFC 2798          The LDAP inetOrgPerson Object Class         April 2000
+
+
+9.  Appendix A - inetOrgPerson Schema Summary
+
+   This appendix provides definitions of all the attribute types
+   included in the inetOrgPerson object class along with their
+   associated syntaxes and matching rules.
+
+9.1.  Attribute Types
+
+9.1.1.  New attribute types that are defined in this document
+
+  ( 2.16.840.1.113730.3.1.1 NAME 'carLicense'
+    DESC 'vehicle license or registration plate'
+    EQUALITY caseIgnoreMatch
+    SUBSTR caseIgnoreSubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+  ( 2.16.840.1.113730.3.1.2
+    NAME 'departmentNumber'
+    DESC 'identifies a department within an organization'
+    EQUALITY caseIgnoreMatch
+    SUBSTR caseIgnoreSubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+  ( 2.16.840.1.113730.3.1.241
+    NAME 'displayName'
+    DESC 'preferred name of a person to be used when displaying entries'
+    EQUALITY caseIgnoreMatch
+    SUBSTR caseIgnoreSubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+    SINGLE-VALUE )
+
+  ( 2.16.840.1.113730.3.1.3
+    NAME 'employeeNumber'
+    DESC 'numerically identifies an employee within an organization'
+    EQUALITY caseIgnoreMatch
+    SUBSTR caseIgnoreSubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+    SINGLE-VALUE )
+
+  ( 2.16.840.1.113730.3.1.4
+    NAME 'employeeType'
+    DESC 'type of employment for a person'
+    EQUALITY caseIgnoreMatch
+    SUBSTR caseIgnoreSubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+
+
+
+
+Smith                        Informational                     [Page 10]
+\f
+RFC 2798          The LDAP inetOrgPerson Object Class         April 2000
+
+
+  ( 0.9.2342.19200300.100.1.60
+    NAME 'jpegPhoto'
+    DESC 'a JPEG image'
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.28 )
+  Note: The jpegPhoto attribute type was defined for use in the
+    Internet X.500 pilots but no referencable definition for it
+    could be located.
+
+  ( 2.16.840.1.113730.3.1.39
+    NAME 'preferredLanguage'
+    DESC 'preferred written or spoken language for a person'
+    EQUALITY caseIgnoreMatch
+    SUBSTR caseIgnoreSubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+    SINGLE-VALUE )
+
+  ( 2.16.840.1.113730.3.1.40
+    NAME 'userSMIMECertificate'
+    DESC 'signed message used to support S/MIME'
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 )
+
+  ( 2.16.840.1.113730.3.1.216
+    NAME 'userPKCS12'
+    DESC 'PKCS #12 PFX PDU for exchange of personal identity information'
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 )
+
+9.1.2.  Attribute types from RFC 2256
+
+   Note that the original definitions of these types can be found in
+   X.520.
+
+    ( 2.5.4.15
+      NAME 'businessCategory'
+      EQUALITY caseIgnoreMatch
+      SUBSTR caseIgnoreSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
+
+    ( 2.5.4.3
+      NAME 'cn'
+      SUP name )
+
+    ( 2.5.4.13
+      NAME 'description'
+      EQUALITY caseIgnoreMatch
+      SUBSTR caseIgnoreSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024} )
+
+
+
+
+
+Smith                        Informational                     [Page 11]
+\f
+RFC 2798          The LDAP inetOrgPerson Object Class         April 2000
+
+
+    ( 2.5.4.27
+      NAME 'destinationIndicator'
+      EQUALITY caseIgnoreMatch
+      SUBSTR caseIgnoreSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{128} )
+
+    ( 2.5.4.23
+      NAME 'facsimileTelephoneNumber'
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.22 )
+
+    ( 2.5.4.42
+      NAME 'givenName'
+      SUP name )
+
+    ( 2.5.4.43
+      NAME 'initials'
+      SUP name )
+
+    ( 2.5.4.25
+      NAME 'internationaliSDNNumber'
+      EQUALITY numericStringMatch
+      SUBSTR numericStringSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{16} )
+
+    ( 2.5.4.7
+      NAME 'l'
+      SUP name )
+
+    ( 2.5.4.0
+      NAME 'objectClass'
+      EQUALITY objectIdentifierMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )
+
+    ( 2.5.4.10
+      NAME 'o'
+      SUP name )
+
+    ( 2.5.4.11
+      NAME 'ou'
+      SUP name )
+
+    ( 2.5.4.19
+      NAME 'physicalDeliveryOfficeName'
+      EQUALITY caseIgnoreMatch
+      SUBSTR caseIgnoreSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
+
+
+
+
+
+Smith                        Informational                     [Page 12]
+\f
+RFC 2798          The LDAP inetOrgPerson Object Class         April 2000
+
+
+    ( 2.5.4.18
+      NAME 'postOfficeBox'
+      EQUALITY caseIgnoreMatch
+      SUBSTR caseIgnoreSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{40} )
+
+    ( 2.5.4.16
+      NAME 'postalAddress'
+      EQUALITY caseIgnoreListMatch
+      SUBSTR caseIgnoreListSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )
+
+    ( 2.5.4.17
+      NAME 'postalCode'
+      EQUALITY caseIgnoreMatch
+      SUBSTR caseIgnoreSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{40} )
+
+    ( 2.5.4.28
+      NAME 'preferredDeliveryMethod'
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.14
+      SINGLE-VALUE )
+
+    ( 2.5.4.26
+      NAME 'registeredAddress'
+      SUP postalAddress
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )
+
+    ( 2.5.4.34
+      NAME 'seeAlso'
+      SUP distinguishedName )
+
+    ( 2.5.4.4
+      NAME 'sn'
+      SUP name )
+
+    ( 2.5.4.8
+      NAME 'st'
+      SUP name )
+
+    ( 2.5.4.9
+      NAME 'street'
+      EQUALITY caseIgnoreMatch
+      SUBSTR caseIgnoreSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
+
+
+
+
+
+
+Smith                        Informational                     [Page 13]
+\f
+RFC 2798          The LDAP inetOrgPerson Object Class         April 2000
+
+
+    ( 2.5.4.20
+      NAME 'telephoneNumber'
+      EQUALITY telephoneNumberMatch
+      SUBSTR telephoneNumberSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{32} )
+
+    ( 2.5.4.22
+      NAME 'teletexTerminalIdentifier'
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.51 )
+
+    ( 2.5.4.21
+      NAME 'telexNumber'
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.52 )
+
+    ( 2.5.4.12
+      NAME 'title'
+      SUP name )
+
+    ( 2.5.4.36
+      NAME 'userCertificate'
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 )
+
+    ( 2.5.4.35
+      NAME 'userPassword'
+      EQUALITY octetStringMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} )
+
+    ( 2.5.4.24
+      NAME 'x121Address'
+      EQUALITY numericStringMatch
+      SUBSTR numericStringSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{15} )
+
+    ( 2.5.4.45
+      NAME 'x500UniqueIdentifier'
+      EQUALITY bitStringMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )
+
+   Some attribute types included in inetOrgPerson are derived from the
+   'name' and 'distinguishedName' attribute supertypes:
+
+    ( 2.5.4.41
+      NAME 'name'
+      EQUALITY caseIgnoreMatch
+      SUBSTR caseIgnoreSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
+
+
+
+
+
+Smith                        Informational                     [Page 14]
+\f
+RFC 2798          The LDAP inetOrgPerson Object Class         April 2000
+
+
+    ( 2.5.4.49
+      NAME 'distinguishedName'
+      EQUALITY distinguishedNameMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+9.1.3.  Attribute types from RFC 1274
+
+    ( 0.9.2342.19200300.100.1.55
+      NAME 'audio'
+      EQUALITY octetStringMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{250000} )
+    Note: The syntax used here for the audio attribute type is Octet
+      String. RFC 1274 uses a syntax called audio which is not defined
+      in RFC 1274.
+
+    ( 0.9.2342.19200300.100.1.20
+      NAME 'homePhone'
+      EQUALITY telephoneNumberMatch
+      SUBSTR telephoneNumberSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )
+    Note: RFC 1274 uses the longer name 'homeTelephoneNumber'.
+
+    ( 0.9.2342.19200300.100.1.39
+      NAME 'homePostalAddress'
+      EQUALITY caseIgnoreListMatch
+      SUBSTR caseIgnoreListSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )
+
+    ( 0.9.2342.19200300.100.1.3
+      NAME 'mail'
+      EQUALITY caseIgnoreIA5Match
+      SUBSTR caseIgnoreIA5SubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+    Note: RFC 1274 uses the longer name 'rfc822Mailbox' and syntax OID
+      of 0.9.2342.19200300.100.3.5.  All recent LDAP documents and most
+      deployed LDAP implementations refer to this attribute as 'mail'
+      and define the IA5 String syntax using using the OID
+      1.3.6.1.4.1.1466.115.121.1.26, as is done here.
+
+    ( 0.9.2342.19200300.100.1.10
+      NAME 'manager'
+      EQUALITY distinguishedNameMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+
+
+
+
+
+
+
+Smith                        Informational                     [Page 15]
+\f
+RFC 2798          The LDAP inetOrgPerson Object Class         April 2000
+
+
+    ( 0.9.2342.19200300.100.1.41
+      NAME 'mobile'
+      EQUALITY telephoneNumberMatch
+      SUBSTR telephoneNumberSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )
+    Note: RFC 1274 uses the longer name 'mobileTelephoneNumber'.
+
+    ( 0.9.2342.19200300.100.1.42
+      NAME 'pager'
+      EQUALITY telephoneNumberMatch
+      SUBSTR telephoneNumberSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )
+    Note: RFC 1274 uses the longer name 'pagerTelephoneNumber'.
+
+    ( 0.9.2342.19200300.100.1.7
+      NAME 'photo' )
+    Note: Photo attribute values are encoded in G3 fax format with an
+      ASN.1 wrapper. Please refer to RFC 1274 section 9.3.7 for
+      detailed syntax information for this attribute.
+
+    ( 0.9.2342.19200300.100.1.6
+      NAME 'roomNumber'
+      EQUALITY caseIgnoreMatch
+      SUBSTR caseIgnoreSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+    ( 0.9.2342.19200300.100.1.21
+      NAME 'secretary'
+      EQUALITY distinguishedNameMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+    ( 0.9.2342.19200300.100.1.1
+      NAME 'uid'
+      EQUALITY caseIgnoreMatch
+      SUBSTR caseIgnoreSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+    Note: RFC 1274 uses the longer name 'userid'.
+
+9.1.4.  Attribute type from RFC 2079
+
+    ( 1.3.6.1.4.1.250.1.57
+      NAME 'labeledURI'
+      EQUALITY caseExactMatch
+      SUBSTR caseExactSubstringsMatch
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+
+
+
+
+Smith                        Informational                     [Page 16]
+\f
+RFC 2798          The LDAP inetOrgPerson Object Class         April 2000
+
+
+9.2.  Syntaxes
+
+9.2.1.  Syntaxes from RFC 2252
+
+    ( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' )
+
+    ( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )
+
+    ( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' )
+
+    ( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'DN' )
+
+    ( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )
+
+    ( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )
+
+    ( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )
+
+    ( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' )
+
+    ( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )
+
+    ( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )
+
+    ( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )
+
+    ( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )
+
+    ( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )
+
+9.2.2.  Syntaxes from RFC 2256
+
+    ( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )
+
+    ( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )
+
+    ( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )
+
+    ( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )
+
+9.3.  Matching Rules
+
+9.3.1.  Matching rules from RFC 2252
+
+   Note that the original definition of many of these matching rules can
+   be found in X.520.
+
+
+
+
+
+Smith                        Informational                     [Page 17]
+\f
+RFC 2798          The LDAP inetOrgPerson Object Class         April 2000
+
+
+    ( 2.5.13.16 NAME 'bitStringMatch'
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )
+
+    ( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match'
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+    ( 2.5.13.11 NAME 'caseIgnoreListMatch'
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )
+
+    ( 2.5.13.2 NAME 'caseIgnoreMatch'
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+    ( 2.5.13.1 NAME 'distinguishedNameMatch'
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+    ( 2.5.13.8 NAME 'numericStringMatch'
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )
+
+    ( 2.5.13.0 NAME 'objectIdentifierMatch'
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )
+
+    ( 2.5.13.20 NAME 'telephoneNumberMatch'
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )
+
+9.3.2.  Matching rule from RFC 2256
+
+   Note that the original definition of this matching rule can be found
+   in X.520.
+
+    ( 2.5.13.17 NAME 'octetStringMatch'
+      SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
+
+9.3.3.  Additional matching rules from X.520
+
+   caseExactMatch
+
+       ( 2.5.13.5 NAME 'caseExactMatch'
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+   This rule determines whether a presented string exactly matches an
+   attribute value of syntax DirectoryString.  It is identical to
+   caseIgnoreMatch except that case is not ignored.  Multiple adjoining
+   whitespace characters are treated the same as an individual space,
+   and leading and trailing whitespace is ignored.
+
+
+
+
+
+
+
+Smith                        Informational                     [Page 18]
+\f
+RFC 2798          The LDAP inetOrgPerson Object Class         April 2000
+
+
+   caseExactSubstringsMatch
+
+       ( 2.5.13.7 NAME 'caseExactSubstringsMatch'
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )
+
+   This rules determines whether the initial, any and final substring
+   elements in a presented value are present in an attribute value of
+   syntax DirectoryString.  It is identical to caseIgnoreSubstringsMatch
+   except that case is not ignored.
+
+   caseIgnoreListSubstringsMatch
+
+       ( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch'
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )
+
+   This rule compares a presented substring with an attribute value
+   which is a sequence of DirectoryStrings, but where the case of
+   letters is not significant for comparison purposes.  A presented
+   value matches a stored value if and only if the presented value
+   matches the string formed by concatenating the strings of the stored
+   value.  Matching is done according to the caseIgnoreSubstringsMatch
+   rule except that none of the initial, final, or any values of the
+   presented value match a substring of the concatenated string which
+   spans more than one of the strings of the stored value.
+
+9.3.4.  Matching rules not defined in any referenced document
+
+   caseIgnoreIA5SubstringsMatch
+
+       ( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch'
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )
+
+   This rules determines whether the initial, any and final substring
+   elements in a presented value are present in an attribute value of
+   syntax IA5 String without regard to the case of the letters in the
+   strings.  It is expected that this matching rule will be added to an
+   update of RFC 2252.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Smith                        Informational                     [Page 19]
+\f
+RFC 2798          The LDAP inetOrgPerson Object Class         April 2000
+
+
+10.  Full Copyright Statement
+
+   Copyright (C) The Internet Society (2000).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Smith                        Informational                     [Page 20]
+\f
diff --git a/doc/rfc/rfc2829.txt b/doc/rfc/rfc2829.txt
new file mode 100644 (file)
index 0000000..343e153
--- /dev/null
@@ -0,0 +1,899 @@
+
+
+
+
+
+
+Network Working Group                                            M. Wahl
+Request for Comments: 2829                        Sun Microsystems, Inc.
+Category: Standards Track                                  H. Alvestrand
+                                                             EDB Maxware
+                                                               J. Hodges
+                                                             Oblix, Inc.
+                                                               R. Morgan
+                                                University of Washington
+                                                                May 2000
+
+
+                    Authentication Methods for LDAP
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2000).  All Rights Reserved.
+
+Abstract
+
+   This document specifies particular combinations of security
+   mechanisms which are required and recommended in LDAP [1]
+   implementations.
+
+1. Introduction
+
+   LDAP version 3 is a powerful access protocol for directories.
+
+   It offers means of searching, fetching and manipulating directory
+   content, and ways to access a rich set of security functions.
+
+   In order to function for the best of the Internet, it is vital that
+   these security functions be interoperable; therefore there has to be
+   a minimum subset of security functions that is common to all
+   implementations that claim LDAPv3 conformance.
+
+   Basic threats to an LDAP directory service include:
+
+      (1)   Unauthorized access to data via data-fetching operations,
+
+
+
+
+
+Wahl, et al.                Standards Track                     [Page 1]
+\f
+RFC 2829            Authentication Methods for LDAP             May 2000
+
+
+      (2)   Unauthorized access to reusable client authentication
+            information by monitoring others' access,
+
+      (3)   Unauthorized access to data by monitoring others' access,
+
+      (4)   Unauthorized modification of data,
+
+      (5)   Unauthorized modification of configuration,
+
+      (6)   Unauthorized or excessive use of resources (denial of
+            service), and
+
+      (7)   Spoofing of directory: Tricking a client into believing that
+            information came from the directory when in fact it did not,
+            either by modifying data in transit or misdirecting the
+            client's connection.
+
+   Threats (1), (4), (5) and (6) are due to hostile clients.  Threats
+   (2), (3) and (7) are due to hostile agents on the path between client
+   and server, or posing as a server.
+
+   The LDAP protocol suite can be protected with the following security
+   mechanisms:
+
+      (1)   Client authentication by means of the SASL [2] mechanism
+            set, possibly backed by the TLS credentials exchange
+            mechanism,
+
+      (2)   Client authorization by means of access control based on the
+            requestor's authenticated identity,
+
+      (3)   Data integrity protection by means of the TLS protocol or
+            data-integrity SASL mechanisms,
+
+      (4)   Protection against snooping by means of the TLS protocol or
+            data-encrypting SASL mechanisms,
+
+      (5)   Resource limitation by means of administrative limits on
+            service controls, and
+
+      (6)   Server authentication by means of the TLS protocol or SASL
+            mechanism.
+
+   At the moment, imposition of access controls is done by means outside
+   the scope of the LDAP protocol.
+
+   In this document, the term "user" represents any application which is
+   an LDAP client using the directory to retrieve or store information.
+
+
+
+Wahl, et al.                Standards Track                     [Page 2]
+\f
+RFC 2829            Authentication Methods for LDAP             May 2000
+
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and "OPTIONAL" in this
+   document are to be interpreted as described in RFC 2119 [3].
+
+2.  Example deployment scenarios
+
+   The following scenarios are typical for LDAP directories on the
+   Internet, and have different security requirements. (In the
+   following, "sensitive" means data that will cause real damage to the
+   owner if revealed; there may be data that is protected but not
+   sensitive).  This is not intended to be a comprehensive list, other
+   scenarios are possible, especially on physically protected networks.
+
+      (1)   A read-only directory, containing no sensitive data,
+            accessible to "anyone", and TCP connection hijacking or IP
+            spoofing is not a problem.  This directory requires no
+            security functions except administrative service limits.
+
+      (2)   A read-only directory containing no sensitive data; read
+            access is granted based on identity.  TCP connection
+            hijacking is not currently a problem. This scenario requires
+            a secure authentication function.
+
+      (3)   A read-only directory containing no sensitive data; and the
+            client needs to ensure that the directory data is
+            authenticated by the server and not modified while being
+            returned from the server.
+
+      (4)   A read-write directory, containing no sensitive data; read
+            access is available to "anyone", update access to properly
+            authorized persons.  TCP connection hijacking is not
+            currently a problem.  This scenario requires a secure
+            authentication function.
+
+      (5)   A directory containing sensitive data.  This scenario
+            requires session confidentiality protection AND secure
+            authentication.
+
+3.  Authentication and Authorization:  Definitions and Concepts
+
+   This section defines basic terms, concepts, and interrelationships
+   regarding authentication, authorization, credentials, and identity.
+   These concepts are used in describing how various security approaches
+   are utilized in client authentication and authorization.
+
+
+
+
+
+
+
+Wahl, et al.                Standards Track                     [Page 3]
+\f
+RFC 2829            Authentication Methods for LDAP             May 2000
+
+
+3.1.  Access Control Policy
+
+   An access control policy is a set of rules defining the protection of
+   resources, generally in terms of the capabilities of persons or other
+   entities accessing those resources.  A common expression of an access
+   control policy is an access control list.  Security objects and
+   mechanisms, such as those described here, enable the expression of
+   access control policies and their enforcement.  Access control
+   policies are typically expressed in terms of access control
+   attributes as described below.
+
+3.2.  Access Control Factors
+
+   A request, when it is being processed by a server, may be associated
+   with a wide variety of security-related factors (section 4.2 of [1]).
+   The server uses these factors to determine whether and how to process
+   the request.  These are called access control factors (ACFs).  They
+   might include source IP address, encryption strength, the type of
+   operation being requested, time of day, etc.  Some factors may be
+   specific to the request itself, others may be associated with the
+   connection via which the request is transmitted, others (e.g. time of
+   day) may be "environmental".
+
+   Access control policies are expressed in terms of access control
+   factors.  E.g., a request having ACFs i,j,k can perform operation Y
+   on resource Z. The set of ACFs that a server makes available for such
+   expressions is implementation-specific.
+
+3.3.  Authentication, Credentials, Identity
+
+   Authentication credentials are the evidence supplied by one party to
+   another, asserting the identity of the supplying party (e.g. a user)
+   who is attempting to establish an association with the other party
+   (typically a server).  Authentication is the process of generating,
+   transmitting, and verifying these credentials and thus the identity
+   they assert.  An authentication identity is the name presented in a
+   credential.
+
+   There are many forms of authentication credentials -- the form used
+   depends upon the particular authentication mechanism negotiated by
+   the parties.  For example: X.509 certificates, Kerberos tickets,
+   simple identity and password pairs.  Note that an authentication
+   mechanism may constrain the form of authentication identities used
+   with it.
+
+
+
+
+
+
+
+Wahl, et al.                Standards Track                     [Page 4]
+\f
+RFC 2829            Authentication Methods for LDAP             May 2000
+
+
+3.4.  Authorization Identity
+
+   An authorization identity is one kind of access control factor.  It
+   is the name of the user or other entity that requests that operations
+   be performed.  Access control policies are often expressed in terms
+   of authorization identities; e.g., entity X can perform operation Y
+   on resource Z.
+
+   The authorization identity bound to an association is often exactly
+   the same as the authentication identity presented by the client, but
+   it may be different.  SASL allows clients to specify an authorization
+   identity distinct from the authentication identity asserted by the
+   client's credentials.  This permits agents such as proxy servers to
+   authenticate using their own credentials, yet request the access
+   privileges of the identity for which they are proxying [2].  Also,
+   the form of authentication identity supplied by a service like TLS
+   may not correspond to the authorization identities used to express a
+   server's access control  policy, requiring a server-specific mapping
+   to be done.  The method by which a server composes and validates an
+   authorization identity from the authentication credentials supplied
+   by a client is implementation-specific.
+
+4. Required security mechanisms
+
+   It is clear that allowing any implementation, faced with the above
+   requirements, to pick and choose among the possible alternatives is
+   not a strategy that is likely to lead to interoperability. In the
+   absence of mandates, clients will be written that do not support any
+   security function supported by the server, or worse, support only
+   mechanisms like cleartext passwords that provide clearly inadequate
+   security.
+
+   Active intermediary attacks are the most difficult for an attacker to
+   perform, and for an implementation to protect against.  Methods that
+   protect only against hostile client and passive eavesdropping attacks
+   are useful in situations where the cost of protection against active
+   intermediary attacks is not justified based on the perceived risk of
+   active intermediary attacks.
+
+   Given the presence of the Directory, there is a strong desire to see
+   mechanisms where identities take the form of a Distinguished Name and
+   authentication data can be stored in the directory; this means that
+   either this data is useless for faking authentication (like the Unix
+   "/etc/passwd" file format used to be), or its content is never passed
+   across the wire unprotected - that is, it's either updated outside
+   the protocol or it is only updated in sessions well protected against
+   snooping.  It is also desirable to allow authentication methods to
+
+
+
+
+Wahl, et al.                Standards Track                     [Page 5]
+\f
+RFC 2829            Authentication Methods for LDAP             May 2000
+
+
+   carry authorization identities based on existing forms of user
+   identities for backwards compatibility with non-LDAP-based
+   authentication services.
+
+   Therefore, the following implementation conformance requirements are
+   in place:
+
+      (1)   For a read-only, public directory, anonymous authentication,
+            described in section 5, can be used.
+
+      (2)   Implementations providing password-based authenticated
+            access MUST support authentication using the DIGEST-MD5 SASL
+            mechanism [4], as described in section 6.1.  This provides
+            client authentication with protection against passive
+            eavesdropping attacks, but does not provide protection
+            against active intermediary attacks.
+
+      (3)   For a directory needing session protection and
+            authentication, the Start TLS extended operation [5], and
+            either the simple authentication choice or the SASL EXTERNAL
+            mechanism, are to be used together.  Implementations SHOULD
+            support authentication with a password as described in
+            section 6.2, and SHOULD support authentication with a
+            certificate as described in section 7.1.  Together, these
+            can provide integrity and disclosure protection of
+            transmitted data, and authentication of client and server,
+            including protection against active intermediary attacks.
+
+   If TLS is negotiated, the client MUST discard all information about
+   the server fetched prior to the TLS negotiation.  In particular, the
+   value of supportedSASLMechanisms MAY be different after TLS has been
+   negotiated (specifically, the EXTERNAL mechanism or the proposed
+   PLAIN mechanism are likely to only be listed after a TLS negotiation
+   has been performed).
+
+   If a SASL security layer is negotiated, the client MUST discard all
+   information about the server fetched prior to SASL.  In particular,
+   if the client is configured to support multiple SASL mechanisms, it
+   SHOULD fetch supportedSASLMechanisms both before and after the SASL
+   security layer is negotiated and verify that the value has not
+   changed after the SASL security layer was negotiated.  This detects
+   active attacks which remove supported SASL mechanisms from the
+   supportedSASLMechanisms list, and allows the client to ensure that it
+   is using the best mechanism supported by both client and server
+   (additionally, this is a SHOULD to allow for environments where the
+   supported SASL mechanisms list is provided to the client through a
+   different trusted source, e.g. as part of a digitally signed object).
+
+
+
+
+Wahl, et al.                Standards Track                     [Page 6]
+\f
+RFC 2829            Authentication Methods for LDAP             May 2000
+
+
+5. Anonymous authentication
+
+   Directory operations which modify entries or access protected
+   attributes or entries generally require client authentication.
+   Clients which do not intend to perform any of these operations
+   typically use anonymous authentication.
+
+   LDAP implementations MUST support anonymous authentication, as
+   defined in section 5.1.
+
+   LDAP implementations MAY support anonymous authentication with TLS,
+   as defined in section 5.2.
+
+   While there MAY be access control restrictions to prevent access to
+   directory entries, an LDAP server SHOULD allow an anonymously-bound
+   client to retrieve the supportedSASLMechanisms attribute of the root
+   DSE.
+
+   An LDAP server MAY use other information about the client provided by
+   the lower layers or external means to grant or deny access even to
+   anonymously authenticated clients.
+
+5.1. Anonymous authentication procedure
+
+   An LDAP client which has not successfully completed a bind operation
+   on a connection is anonymously authenticated.
+
+   An LDAP client MAY also specify anonymous authentication in a bind
+   request by using a zero-length OCTET STRING with the simple
+   authentication choice.
+
+5.2. Anonymous authentication and TLS
+
+   An LDAP client MAY use the Start TLS operation [5] to negotiate the
+   use of TLS security [6].  If the client has not bound beforehand,
+   then until the client uses the EXTERNAL SASL mechanism to negotiate
+   the recognition of the client's certificate, the client is
+   anonymously authenticated.
+
+   Recommendations on TLS ciphersuites are given in section 10.
+
+   An LDAP server which requests that clients provide their certificate
+   during TLS negotiation MAY use a local security policy to determine
+   whether to successfully complete TLS negotiation if the client did
+   not present a certificate which could be validated.
+
+
+
+
+
+
+Wahl, et al.                Standards Track                     [Page 7]
+\f
+RFC 2829            Authentication Methods for LDAP             May 2000
+
+
+6. Password-based authentication
+
+   LDAP implementations MUST support authentication with a password
+   using the DIGEST-MD5 SASL mechanism for password protection, as
+   defined in section 6.1.
+
+   LDAP implementations SHOULD support authentication with the "simple"
+   password choice when the connection is protected against
+   eavesdropping using TLS, as defined in section 6.2.
+
+6.1. Digest authentication
+
+   An LDAP client MAY determine whether the server supports this
+   mechanism by performing a search request on the root DSE, requesting
+   the supportedSASLMechanisms attribute, and checking whether the
+   string "DIGEST-MD5" is present as a value of this attribute.
+
+   In the first stage of authentication, when the client is performing
+   an "initial authentication" as defined in section 2.1 of [4], the
+   client sends a bind request in which the version number is 3, the
+   authentication choice is sasl, the sasl mechanism name is "DIGEST-
+   MD5", and the credentials are absent.  The client then waits for a
+   response from the server to this request.
+
+   The server will respond with a bind response in which the resultCode
+   is saslBindInProgress, and the serverSaslCreds field is present.  The
+   contents of this field is a string defined by "digest-challenge" in
+   section 2.1.1 of [4].  The server SHOULD include a realm indication
+   and MUST indicate support for UTF-8.
+
+   The client will send a bind request with a distinct message id, in
+   which the version number is 3, the authentication choice is sasl, the
+   sasl mechanism name is "DIGEST-MD5", and the credentials contain the
+   string defined by "digest-response" in section 2.1.2 of [4].  The
+   serv-type is "ldap".
+
+   The server will respond with a bind response in which the resultCode
+   is either success, or an error indication.  If the authentication is
+   successful and the server does not support subsequent authentication,
+   then the credentials field is absent.  If the authentication is
+   successful and the server supports subsequent authentication, then
+   the credentials field contains the string defined by "response-auth"
+   in section 2.1.3 of [4].   Support for subsequent authentication is
+   OPTIONAL in clients and servers.
+
+
+
+
+
+
+
+Wahl, et al.                Standards Track                     [Page 8]
+\f
+RFC 2829            Authentication Methods for LDAP             May 2000
+
+
+6.2. "simple" authentication choice under TLS encryption
+
+   A user who has a directory entry containing a userPassword attribute
+   MAY authenticate to the directory by performing a simple password
+   bind sequence following the negotiation of a TLS ciphersuite
+   providing connection confidentiality [6].
+
+   The client will use the Start TLS operation [5] to negotiate the use
+   of TLS security [6] on the connection to the LDAP server.  The client
+   need not have bound to the directory beforehand.
+
+   For this authentication procedure to be successful, the client and
+   server MUST negotiate a ciphersuite which contains a bulk encryption
+   algorithm of appropriate strength.  Recommendations on cipher suites
+   are given in section 10.
+
+   Following the successful completion of TLS negotiation, the client
+   MUST send an LDAP bind request with the version number of 3, the name
+   field containing the name of the user's entry, and the "simple"
+   authentication choice, containing a password.
+
+   The server will, for each value of the userPassword attribute in the
+   named user's entry, compare these for case-sensitive equality with
+   the client's presented password.  If there is a match, then the
+   server will respond with resultCode success, otherwise the server
+   will respond with resultCode invalidCredentials.
+
+6.3. Other authentication choices with TLS
+
+   It is also possible, following the negotiation of TLS, to perform a
+   SASL authentication which does not involve the exchange of plaintext
+   reusable passwords.  In this case the client and server need not
+   negotiate a ciphersuite which provides confidentiality if the only
+   service required is data integrity.
+
+7. Certificate-based authentication
+
+   LDAP implementations SHOULD support authentication via a client
+   certificate in TLS, as defined in section 7.1.
+
+7.1. Certificate-based authentication with TLS
+
+   A user who has a public/private key pair in which the public key has
+   been signed by a Certification Authority may use this key pair to
+   authenticate to the directory server if the user's certificate is
+   requested by the server.  The user's certificate subject field SHOULD
+   be the name of the user's directory entry, and the Certification
+   Authority must be sufficiently trusted by the directory server to
+
+
+
+Wahl, et al.                Standards Track                     [Page 9]
+\f
+RFC 2829            Authentication Methods for LDAP             May 2000
+
+
+   have issued the certificate in order that the server can process the
+   certificate.  The means by which servers validate certificate paths
+   is outside the scope of this document.
+
+   A server MAY support mappings for certificates in which the subject
+   field name is different from the name of the user's directory entry.
+   A server which supports mappings of names MUST be capable of being
+   configured to support certificates for which no mapping is required.
+
+   The client will use the Start TLS operation [5] to negotiate the use
+   of TLS security [6] on the connection to the LDAP server.  The client
+   need not have bound to the directory beforehand.
+
+   In the TLS negotiation, the server MUST request a certificate.  The
+   client will provide its certificate to the server, and MUST perform a
+   private key-based encryption, proving it has the private key
+   associated with the certificate.
+
+   As deployments will require protection of sensitive data in transit,
+   the client and server MUST negotiate a ciphersuite which contains a
+   bulk encryption algorithm of appropriate strength.  Recommendations
+   of cipher suites are given in section 10.
+
+   The server MUST verify that the client's certificate is valid. The
+   server will normally check that the certificate is issued by a known
+   CA, and that none of the certificates on the client's certificate
+   chain are invalid or revoked.  There are several procedures by which
+   the server can perform these checks.
+
+   Following the successful completion of TLS negotiation, the client
+   will send an LDAP bind request with the SASL "EXTERNAL" mechanism.
+
+8. Other mechanisms
+
+   The LDAP "simple" authentication choice is not suitable for
+   authentication on the Internet where there is no network or transport
+   layer confidentiality.
+
+   As LDAP includes native anonymous and plaintext authentication
+   methods, the "ANONYMOUS" and "PLAIN" SASL mechanisms are not used
+   with LDAP.  If an authorization identity of a form different from a
+   DN is requested by the client, a mechanism that protects the password
+   in transit SHOULD be used.
+
+   The following SASL-based mechanisms are not considered in this
+   document: KERBEROS_V4, GSSAPI and SKEY.
+
+
+
+
+
+Wahl, et al.                Standards Track                    [Page 10]
+\f
+RFC 2829            Authentication Methods for LDAP             May 2000
+
+
+   The "EXTERNAL" SASL mechanism can be used to request the LDAP server
+   make use of security credentials exchanged by a lower layer. If a TLS
+   session has not been established between the client and server prior
+   to making the SASL EXTERNAL Bind request and there is no other
+   external source of authentication credentials (e.g.  IP-level
+   security [8]), or if, during the process of establishing the TLS
+   session, the server did not request the client's authentication
+   credentials, the SASL EXTERNAL bind MUST fail with a result code of
+   inappropriateAuthentication.  Any client authentication and
+   authorization state of the LDAP association is lost, so the LDAP
+   association is in an anonymous state after the failure.
+
+9. Authorization Identity
+
+   The authorization identity is carried as part of the SASL credentials
+   field in the LDAP Bind request and response.
+
+   When the "EXTERNAL" mechanism is being negotiated, if the credentials
+   field is present, it contains an authorization identity of the
+   authzId form described below.
+
+   Other mechanisms define the location of the authorization identity in
+   the credentials field.
+
+   The authorization identity is a string in the UTF-8 character set,
+   corresponding to the following ABNF [7]:
+
+   ; Specific predefined authorization (authz) id schemes are
+   ; defined below -- new schemes may be defined in the future.
+
+   authzId    = dnAuthzId / uAuthzId
+
+   ; distinguished-name-based authz id.
+   dnAuthzId  = "dn:" dn
+   dn         = utf8string    ; with syntax defined in RFC 2253
+
+   ; unspecified userid, UTF-8 encoded.
+   uAuthzId   = "u:" userid
+   userid     = utf8string    ; syntax unspecified
+
+   A utf8string is defined to be the UTF-8 encoding of one or more ISO
+   10646 characters.
+
+   All servers which support the storage of authentication credentials,
+   such as passwords or certificates, in the directory MUST support the
+   dnAuthzId choice.
+
+
+
+
+
+Wahl, et al.                Standards Track                    [Page 11]
+\f
+RFC 2829            Authentication Methods for LDAP             May 2000
+
+
+   The uAuthzId choice allows for compatibility with client applications
+   which wish to authenticate to a local directory but do not know their
+   own Distinguished Name or have a directory entry.  The format of the
+   string is defined as only a sequence of UTF-8 encoded ISO 10646
+   characters, and further interpretation is subject to prior agreement
+   between the client and server.
+
+   For example, the userid could identify a user of a specific directory
+   service, or be a login name or the local-part of an RFC 822 email
+   address. In general a uAuthzId MUST NOT be assumed to be globally
+   unique.
+
+   Additional authorization identity schemes MAY be defined in future
+   versions of this document.
+
+10. TLS Ciphersuites
+
+   The following ciphersuites defined in [6] MUST NOT be used for
+   confidentiality protection of passwords or data:
+
+         TLS_NULL_WITH_NULL_NULL
+         TLS_RSA_WITH_NULL_MD5
+         TLS_RSA_WITH_NULL_SHA
+
+   The following ciphersuites defined in [6] can be cracked easily (less
+   than a week of CPU time on a standard CPU in 1997).  The client and
+   server SHOULD carefully consider the value of the password or data
+   being protected before using these ciphersuites:
+
+         TLS_RSA_EXPORT_WITH_RC4_40_MD5
+         TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5
+         TLS_RSA_EXPORT_WITH_DES40_CBC_SHA
+         TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA
+         TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA
+         TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
+         TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
+         TLS_DH_anon_EXPORT_WITH_RC4_40_MD5
+         TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA
+
+   The following ciphersuites are vulnerable to man-in-the-middle
+   attacks, and SHOULD NOT be used to protect passwords or sensitive
+   data, unless the network configuration is such that the danger of a
+   man-in-the-middle attack is tolerable:
+
+
+
+
+
+
+
+
+Wahl, et al.                Standards Track                    [Page 12]
+\f
+RFC 2829            Authentication Methods for LDAP             May 2000
+
+
+         TLS_DH_anon_EXPORT_WITH_RC4_40_MD5
+         TLS_DH_anon_WITH_RC4_128_MD5
+         TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA
+         TLS_DH_anon_WITH_DES_CBC_SHA
+         TLS_DH_anon_WITH_3DES_EDE_CBC_SHA
+
+   A client or server that supports TLS MUST support at least
+   TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA.
+
+11. SASL service name for LDAP
+
+   For use with SASL [2], a protocol must specify a service name to be
+   used with various SASL mechanisms, such as GSSAPI.  For LDAP, the
+   service name is "ldap", which has been registered with the IANA as a
+   GSSAPI service name.
+
+12. Security Considerations
+
+   Security issues are discussed throughout this memo; the
+   (unsurprising) conclusion is that mandatory security is important,
+   and that session encryption is required when snooping is a problem.
+
+   Servers are encouraged to prevent modifications by anonymous users.
+   Servers may also wish to minimize denial of service attacks by timing
+   out idle connections, and returning the unwillingToPerform result
+   code rather than performing computationally expensive operations
+   requested by unauthorized clients.
+
+   A connection on which the client has not performed the Start TLS
+   operation or negotiated a suitable SASL mechanism for connection
+   integrity and encryption services is subject to man-in-the-middle
+   attacks to view and modify information in transit.
+
+   Additional security considerations relating to the EXTERNAL mechanism
+   to negotiate TLS can be found in [2], [5] and [6].
+
+13. Acknowledgements
+
+   This document is a product of the LDAPEXT Working Group of the IETF.
+   The contributions of its members is greatly appreciated.
+
+
+
+
+
+
+
+
+
+
+
+Wahl, et al.                Standards Track                    [Page 13]
+\f
+RFC 2829            Authentication Methods for LDAP             May 2000
+
+
+14. Bibliography
+
+   [1] Wahl, M., Howes, T. and S. Kille, "Lightweight Directory Access
+       Protocol (v3)", RFC 2251, December 1997.
+
+   [2] Myers, J., "Simple Authentication and Security Layer (SASL)", RFC
+       2222, October 1997.
+
+   [3] Bradner, S., "Key words for use in RFCs to Indicate Requirement
+       Levels", BCP 14, RFC 2119, March 1997.
+
+   [4] Leach, P. and C. Newman, "Using Digest Authentication as a SASL
+       Mechanism", RFC 2831, May 2000.
+
+   [5] Hodges, J., Morgan, R. and M. Wahl, "Lightweight Directory Access
+       Protocol (v3): Extension for Transport Layer Security", RFC 2830,
+       May 2000.
+
+   [6] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0", RFC
+       2246, January 1999.
+
+   [7] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax
+       Specifications: ABNF", RFC 2234, November 1997.
+
+   [8] Kent, S. and R. Atkinson, "Security Architecture for the Internet
+       Protocol", RFC 2401, November 1998.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Wahl, et al.                Standards Track                    [Page 14]
+\f
+RFC 2829            Authentication Methods for LDAP             May 2000
+
+
+15. Authors' Addresses
+
+   Mark Wahl
+   Sun Microsystems, Inc.
+   8911 Capital of Texas Hwy #4140
+   Austin TX 78759
+   USA
+
+   EMail: M.Wahl@innosoft.com
+
+
+   Harald Tveit Alvestrand
+   EDB Maxware
+   Pirsenteret
+   N-7462 Trondheim, Norway
+
+   Phone: +47 73 54 57 97
+   EMail: Harald@Alvestrand.no
+
+
+   Jeff Hodges
+   Oblix, Inc.
+   18922 Forge Drive
+   Cupertino, CA 95014
+   USA
+
+   Phone: +1-408-861-6656
+   EMail: JHodges@oblix.com
+
+
+   RL "Bob" Morgan
+   Computing and Communications
+   University of Washington
+   Seattle, WA 98105
+   USA
+
+   Phone: +1-206-221-3307
+   EMail: rlmorgan@washington.edu
+
+
+
+
+
+
+
+
+
+
+
+
+
+Wahl, et al.                Standards Track                    [Page 15]
+\f
+RFC 2829            Authentication Methods for LDAP             May 2000
+
+
+16.  Full Copyright Statement
+
+   Copyright (C) The Internet Society (2000).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Wahl, et al.                Standards Track                    [Page 16]
+\f
diff --git a/doc/rfc/rfc2830.txt b/doc/rfc/rfc2830.txt
new file mode 100644 (file)
index 0000000..7801c7d
--- /dev/null
@@ -0,0 +1,675 @@
+
+
+
+
+
+
+Network Working Group                                          J. Hodges
+Request for Comments: 2830                                    Oblix Inc.
+Category: Standards Track                                      R. Morgan
+                                                      Univ of Washington
+                                                                 M. Wahl
+                                                  Sun Microsystems, Inc.
+                                                                May 2000
+
+
+              Lightweight Directory Access Protocol (v3):
+                 Extension for Transport Layer Security
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2000).  All Rights Reserved.
+
+Abstract
+
+   This document defines the "Start Transport Layer Security (TLS)
+   Operation" for LDAP [LDAPv3, TLS]. This operation provides for TLS
+   establishment in an LDAP association and is defined in terms of an
+   LDAP extended request.
+
+1.  Conventions Used in this Document
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and "OPTIONAL" in this
+   document are to be interpreted as described in [ReqsKeywords].
+
+2.  The Start TLS Request
+
+   This section describes the Start TLS extended request and extended
+   response themselves: how to form the request, the form of the
+   response, and enumerates the various result codes the client MUST be
+   prepared to handle.
+
+   The section following this one then describes how to sequence an
+   overall Start TLS Operation.
+
+
+
+
+
+Hodges, et al.              Standards Track                     [Page 1]
+\f
+RFC 2830     LDAPv3: Extension for Transport Layer Security     May 2000
+
+
+2.1.  Requesting TLS Establishment
+
+   A client may perform a Start TLS operation by transmitting an LDAP
+   PDU containing an ExtendedRequest [LDAPv3] specifying the OID for the
+   Start TLS operation:
+
+     1.3.6.1.4.1.1466.20037
+
+   An LDAP ExtendedRequest is defined as follows:
+
+     ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
+             requestName             [0] LDAPOID,
+             requestValue            [1] OCTET STRING OPTIONAL }
+
+   A Start TLS extended request is formed by setting the requestName
+   field to the OID string given above.  The requestValue field is
+   absent.  The client MUST NOT send any PDUs on this connection
+   following this request until it receives a Start TLS extended
+   response.
+
+   When a Start TLS extended request is made, the server MUST return an
+   LDAP PDU containing a Start TLS extended response.  An LDAP
+   ExtendedResponse is defined as follows:
+
+     ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
+             COMPONENTS OF LDAPResult,
+             responseName     [10] LDAPOID OPTIONAL,
+             response         [11] OCTET STRING OPTIONAL }
+
+   A Start TLS extended response MUST contain a responseName field which
+   MUST be set to the same string as that in the responseName field
+   present in the Start TLS extended request. The response field is
+   absent. The server MUST set the resultCode field to either success or
+   one of the other values outlined in section 2.3.
+
+2.2.  "Success" Response
+
+   If the ExtendedResponse contains a resultCode of success, this
+   indicates that the server is willing and able to negotiate TLS. Refer
+   to section 3, below, for details.
+
+2.3.  Response other than "success"
+
+   If the ExtendedResponse contains a resultCode other than success,
+   this indicates that the server is unwilling or unable to negotiate
+   TLS.
+
+
+
+
+
+Hodges, et al.              Standards Track                     [Page 2]
+\f
+RFC 2830     LDAPv3: Extension for Transport Layer Security     May 2000
+
+
+   If the Start TLS extended request was not successful, the resultCode
+   will be one of:
+
+   operationsError  (operations sequencing incorrect; e.g. TLS already
+                    established)
+
+   protocolError    (TLS not supported or incorrect PDU structure)
+
+   referral         (this server doesn't do TLS, try this one)
+
+   unavailable      (e.g. some major problem with TLS, or server is
+                    shutting down)
+
+   The server MUST return operationsError if the client violates any of
+   the Start TLS extended operation sequencing requirements described in
+   section 3, below.
+
+   If the server does not support TLS (whether by design or by current
+   configuration), it MUST set the resultCode to protocolError (see
+   section 4.1.1 of [LDAPv3]), or to referral. The server MUST include
+   an actual referral value in the LDAP Result if it returns a
+   resultCode of referral. The client's current session is unaffected if
+   the server does not support TLS. The client MAY proceed with any LDAP
+   operation, or it MAY close the connection.
+
+   The server MUST return unavailable if it supports TLS but cannot
+   establish a TLS connection for some reason, e.g. the certificate
+   server not responding, it cannot contact its TLS implementation, or
+   if the server is in process of shutting down. The client MAY retry
+   the StartTLS operation, or it MAY proceed with any other LDAP
+   operation, or it MAY close the connection.
+
+3.  Sequencing of the Start TLS Operation
+
+   This section describes the overall procedures clients and servers
+   MUST follow for TLS establishment. These procedures take into
+   consideration various aspects of the overall security of the LDAP
+   association including discovery of resultant security level and
+   assertion of the client's authorization identity.
+
+   Note that the precise effects, on a client's authorization identity,
+   of establishing TLS on an LDAP association are described in detail in
+   section 5.
+
+
+
+
+
+
+
+
+Hodges, et al.              Standards Track                     [Page 3]
+\f
+RFC 2830     LDAPv3: Extension for Transport Layer Security     May 2000
+
+
+3.1.  Requesting to Start TLS on an LDAP Association
+
+   The client MAY send the Start TLS extended request at any time after
+   establishing an LDAP association, except that in the following cases
+   the client MUST NOT send a Start TLS extended request:
+
+     - if TLS is currently established on the connection, or
+     - during a multi-stage SASL negotiation, or
+     - if there are any LDAP operations outstanding on the connection.
+
+   The result of violating any of these requirements is a resultCode of
+   operationsError, as described above in section 2.3.
+
+   The client MAY have already performed a Bind operation when it sends
+   a Start TLS request, or the client might have not yet bound.
+
+   If the client did not establish a TLS connection before sending any
+   other requests, and the server requires the client to establish a TLS
+   connection before performing a particular request, the server MUST
+   reject that request with a confidentialityRequired or
+   strongAuthRequired result. The client MAY send a Start TLS extended
+   request, or it MAY choose to close the connection.
+
+3.2.  Starting TLS
+
+   The server will return an extended response with the resultCode of
+   success if it is willing and able to negotiate TLS.  It will return
+   other resultCodes, documented above, if it is unable.
+
+   In the successful case, the client, which has ceased to transfer LDAP
+   requests on the connection, MUST either begin a TLS negotiation or
+   close the connection. The client will send PDUs in the TLS Record
+   Protocol directly over the underlying transport connection to the
+   server to initiate TLS negotiation [TLS].
+
+3.3.  TLS Version Negotiation
+
+   Negotiating the version of TLS or SSL to be used is a part of the TLS
+   Handshake Protocol, as documented in [TLS]. Please refer to that
+   document for details.
+
+3.4.  Discovery of Resultant Security Level
+
+   After a TLS connection is established on an LDAP association, both
+   parties MUST individually decide whether or not to continue based on
+   the privacy level achieved. Ascertaining the TLS connection's privacy
+   level is implementation dependent, and accomplished by communicating
+   with one's respective local TLS implementation.
+
+
+
+Hodges, et al.              Standards Track                     [Page 4]
+\f
+RFC 2830     LDAPv3: Extension for Transport Layer Security     May 2000
+
+
+   If the client or server decides that the level of authentication or
+   privacy is not high enough for it to continue, it SHOULD gracefully
+   close the TLS connection immediately after the TLS negotiation has
+   completed (see sections 4.1 and 5.2, below).
+
+   The client MAY attempt to Start TLS again, or MAY send an unbind
+   request, or send any other LDAP request.
+
+3.5.  Assertion of Client's Authorization Identity
+
+   The client MAY, upon receipt of a Start TLS extended response
+   indicating success, assert that a specific authorization identity be
+   utilized in determining the client's authorization status. The client
+   accomplishes this via an LDAP Bind request specifying a SASL
+   mechanism of "EXTERNAL" [SASL]. See section 5.1.2, below.
+
+3.6.  Server Identity Check
+
+   The client MUST check its understanding of the server's hostname
+   against the server's identity as presented in the server's
+   Certificate message, in order to prevent man-in-the-middle attacks.
+
+   Matching is performed according to these rules:
+
+   - The client MUST use the server hostname it used to open the LDAP
+     connection as the value to compare against the server name as
+     expressed in the server's certificate.  The client MUST NOT use the
+     server's canonical DNS name or any other derived form of name.
+
+   - If a subjectAltName extension of type dNSName is present in the
+     certificate, it SHOULD be used as the source of the server's
+     identity.
+
+   - Matching is case-insensitive.
+
+   - The "*" wildcard character is allowed.  If present, it applies only
+     to the left-most name component.
+
+   E.g. *.bar.com would match a.bar.com, b.bar.com, etc. but not
+   bar.com.  If more than one identity of a given type is present in the
+   certificate (e.g. more than one dNSName name), a match in any one of
+   the set is considered acceptable.
+
+   If the hostname does not match the dNSName-based identity in the
+   certificate per the above check, user-oriented clients SHOULD either
+   notify the user (clients MAY give the user the opportunity to
+
+
+
+
+
+Hodges, et al.              Standards Track                     [Page 5]
+\f
+RFC 2830     LDAPv3: Extension for Transport Layer Security     May 2000
+
+
+   continue with the connection in any case) or terminate the connection
+   and indicate that the server's identity is suspect. Automated clients
+   SHOULD close the connection, returning and/or logging an error
+   indicating that the server's identity is suspect.
+
+   Beyond the server identity checks described in this section, clients
+   SHOULD be prepared to do further checking to ensure that the server
+   is authorized to provide the service it is observed to provide. The
+   client MAY need to make use of local policy information.
+
+3.7.  Refresh of Server Capabilities Information
+
+   The client MUST refresh any cached server capabilities information
+   (e.g. from the server's root DSE; see section 3.4 of [LDAPv3]) upon
+   TLS session establishment. This is necessary to protect against
+   active-intermediary attacks which may have altered any server
+   capabilities information retrieved prior to TLS establishment. The
+   server MAY advertise different capabilities after TLS establishment.
+
+4.  Closing a TLS Connection
+
+4.1.  Graceful Closure
+
+   Either the client or server MAY terminate the TLS connection on an
+   LDAP association by sending a TLS closure alert. This will leave the
+   LDAP association intact.
+
+   Before closing a TLS connection, the client MUST either wait for any
+   outstanding LDAP operations to complete, or explicitly abandon them
+   [LDAPv3].
+
+   After the initiator of a close has sent a closure alert, it MUST
+   discard any TLS messages until it has received an alert from the
+   other party.  It will cease to send TLS Record Protocol PDUs, and
+   following the receipt of the alert, MAY send and receive LDAP PDUs.
+
+   The other party, if it receives a closure alert, MUST immediately
+   transmit a TLS closure alert.  It will subsequently cease to send TLS
+   Record Protocol PDUs, and MAY send and receive LDAP PDUs.
+
+4.2.  Abrupt Closure
+
+   Either the client or server MAY abruptly close the entire LDAP
+   association and any TLS connection established on it by dropping the
+   underlying TCP connection. A server MAY beforehand send the client a
+   Notice of Disconnection [LDAPv3] in this case.
+
+
+
+
+
+Hodges, et al.              Standards Track                     [Page 6]
+\f
+RFC 2830     LDAPv3: Extension for Transport Layer Security     May 2000
+
+
+5.  Effects of TLS on a Client's Authorization Identity
+
+   This section describes the effects on a client's authorization
+   identity brought about by establishing TLS on an LDAP association.
+   The default effects are described first, and next the facilities for
+   client assertion of authorization identity are discussed including
+   error conditions. Lastly, the effects of closing the TLS connection
+   are described.
+
+   Authorization identities and related concepts are defined in
+   [AuthMeth].
+
+5.1.  TLS Connection Establishment Effects
+
+5.1.1.  Default Effects
+
+   Upon establishment of the TLS connection onto the LDAP association,
+   any previously established authentication and authorization
+   identities MUST remain in force, including anonymous state. This
+   holds even in the case where the server requests client
+   authentication via TLS -- e.g. requests the client to supply its
+   certificate during TLS negotiation (see [TLS]).
+
+5.1.2.  Client Assertion of Authorization Identity
+
+   A client MAY either implicitly request that its LDAP authorization
+   identity be derived from its authenticated TLS credentials or it MAY
+   explicitly provide an authorization identity and assert that it be
+   used in combination with its authenticated TLS credentials. The
+   former is known as an implicit assertion, and the latter as an
+   explicit assertion.
+
+5.1.2.1.  Implicit Assertion
+
+   An implicit authorization identity assertion is accomplished after
+   TLS establishment by invoking a Bind request of the SASL form using
+   the "EXTERNAL" mechanism name [SASL, LDAPv3] that SHALL NOT include
+   the optional credentials octet string (found within the
+   SaslCredentials sequence in the Bind Request). The server will derive
+   the client's authorization identity from the authentication identity
+   supplied in the client's TLS credentials (typically a public key
+   certificate) according to local policy. The underlying mechanics of
+   how this is accomplished are implementation specific.
+
+
+
+
+
+
+
+
+Hodges, et al.              Standards Track                     [Page 7]
+\f
+RFC 2830     LDAPv3: Extension for Transport Layer Security     May 2000
+
+
+5.1.2.2.  Explicit Assertion
+
+   An explicit authorization identity assertion is accomplished after
+   TLS establishment by invoking a Bind request of the SASL form using
+   the "EXTERNAL" mechanism name [SASL, LDAPv3] that SHALL include the
+   credentials octet string. This string MUST be constructed as
+   documented in section 9 of [AuthMeth].
+
+5.1.2.3.  Error Conditions
+
+   For either form of assertion, the server MUST verify that the
+   client's authentication identity as supplied in its TLS credentials
+   is permitted to be mapped to the asserted authorization identity. The
+   server MUST reject the Bind operation with an invalidCredentials
+   resultCode in the Bind response if the client is not so authorized.
+
+   Additionally, with either form of assertion, if a TLS session has not
+   been established between the client and server prior to making the
+   SASL EXTERNAL Bind request and there is no other external source of
+   authentication credentials (e.g.  IP-level security [IPSEC]), or if,
+   during the process of establishing the TLS session, the server did
+   not request the client's authentication credentials, the SASL
+   EXTERNAL bind MUST fail with a result code of
+   inappropriateAuthentication.
+
+   After the above Bind operation failures, any client authentication
+   and authorization state of the LDAP association is lost, so the LDAP
+   association is in an anonymous state after the failure.  TLS
+   connection state is unaffected, though a server MAY end the TLS
+   connection, via a TLS close_notify message, based on the Bind failure
+   (as it MAY at any time).
+
+5.2.  TLS Connection Closure Effects
+
+   Closure of the TLS connection MUST cause the LDAP association to move
+   to an anonymous authentication and authorization state regardless of
+   the state established over TLS and regardless of the authentication
+   and authorization state prior to TLS connection establishment.
+
+6.  Security Considerations
+
+   The goals of using the TLS protocol with LDAP are to ensure
+   connection confidentiality and integrity, and to optionally provide
+   for authentication. TLS expressly provides these capabilities, as
+   described in [TLS].
+
+
+
+
+
+
+Hodges, et al.              Standards Track                     [Page 8]
+\f
+RFC 2830     LDAPv3: Extension for Transport Layer Security     May 2000
+
+
+   All security gained via use of the Start TLS operation is gained by
+   the use of TLS itself. The Start TLS operation, on its own, does not
+   provide any additional security.
+
+   The use of TLS does not provide or ensure for confidentiality and/or
+   non-repudiation of the data housed by an LDAP-based directory server.
+   Nor does it secure the data from inspection by the server
+   administrators.  Once established, TLS only provides for and ensures
+   confidentiality and integrity of the operations and data in transit
+   over the LDAP association, and only if the implementations on the
+   client and server support and negotiate it.
+
+   The level of security provided though the use of TLS depends directly
+   on both the quality of the TLS implementation used and the style of
+   usage of that implementation. Additionally, an active-intermediary
+   attacker can remove the Start TLS extended operation from the
+   supportedExtension attribute of the root DSE. Therefore, both parties
+   SHOULD independently ascertain and consent to the security level
+   achieved once TLS is established and before beginning use of the TLS
+   connection. For example, the security level of the TLS connection
+   might have been negotiated down to plaintext.
+
+   Clients SHOULD either warn the user when the security level achieved
+   does not provide confidentiality and/or integrity protection, or be
+   configurable to refuse to proceed without an acceptable level of
+   security.
+
+   Client and server implementors SHOULD take measures to ensure proper
+   protection of credentials and other confidential data where such
+   measures are not otherwise provided by the TLS implementation.
+
+   Server implementors SHOULD allow for server administrators to elect
+   whether and when connection confidentiality and/or integrity is
+   required, as well as elect whether and when client authentication via
+   TLS is required.
+
+7.  Acknowledgements
+
+   The authors thank Tim Howes, Paul Hoffman, John Kristian, Shirish
+   Rai, Jonathan Trostle, Harald Alvestrand, and Marcus Leech for their
+   contributions to this document.
+
+
+
+
+
+
+
+
+
+
+Hodges, et al.              Standards Track                     [Page 9]
+\f
+RFC 2830     LDAPv3: Extension for Transport Layer Security     May 2000
+
+
+8.  References
+
+   [AuthMeth]     Wahl, M., Alvestrand, H., Hodges, J. and R. Morgan,
+                  "Authentication Methods for LDAP", RFC 2829, May 2000.
+
+   [IPSEC]        Kent, S. and R. Atkinson, "Security Architecture for
+                  the Internet Protocol", RFC 2401, November 1998.
+
+   [LDAPv3]       Wahl, M., Kille S. and T. Howes, "Lightweight
+                  Directory Access Protocol (v3)", RFC 2251, December
+                  1997.
+
+   [ReqsKeywords] Bradner, S., "Key Words for use in RFCs to Indicate
+                  Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+   [SASL]         Myers, J., "Simple Authentication and Security Layer
+                  (SASL)", RFC 2222, October 1997.
+
+   [TLS]          Dierks, T. and C. Allen. "The TLS Protocol Version
+                  1.0", RFC 2246, January 1999.
+
+9.  Authors' Addresses
+
+   Jeff Hodges
+   Oblix, Inc.
+   18922 Forge Drive
+   Cupertino, CA 95014
+   USA
+
+   Phone: +1-408-861-6656
+   EMail: JHodges@oblix.com
+
+   RL "Bob" Morgan
+   Computing and Communications
+   University of Washington
+   Seattle, WA
+   USA
+
+   Phone: +1-206-221-3307
+   EMail: rlmorgan@washington.edu
+
+   Mark Wahl
+   Sun Microsystems, Inc.
+   8911 Capital of Texas Hwy #4140
+   Austin TX 78759
+   USA
+
+   EMail: M.Wahl@innosoft.com
+
+
+
+Hodges, et al.              Standards Track                    [Page 10]
+\f
+RFC 2830     LDAPv3: Extension for Transport Layer Security     May 2000
+
+
+10.  Intellectual Property Rights Notices
+
+   The IETF takes no position regarding the validity or scope of any
+   intellectual property or other rights that might be claimed to
+   pertain to the implementation or use of the technology described in
+   this document or the extent to which any license under such rights
+   might or might not be available; neither does it represent that it
+   has made any effort to identify any such rights.  Information on the
+   IETF's procedures with respect to rights in standards-track and
+   standards-related documentation can be found in BCP-11.  Copies of
+   claims of rights made available for publication and any assurances of
+   licenses to be made available, or the result of an attempt made to
+   obtain a general license or permission for the use of such
+   proprietary rights by implementors or users of this specification can
+   be obtained from the IETF Secretariat.
+
+   The IETF invites any interested party to bring to its attention any
+   copyrights, patents or patent applications, or other proprietary
+   rights which may cover technology that may be required to practice
+   this standard.  Please address the information to the IETF Executive
+   Director.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hodges, et al.              Standards Track                    [Page 11]
+\f
+RFC 2830     LDAPv3: Extension for Transport Layer Security     May 2000
+
+
+11.  Full Copyright Statement
+
+   Copyright (C) The Internet Society (2000).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hodges, et al.              Standards Track                    [Page 12]
+\f
diff --git a/doc/rfc/rfc2831.txt b/doc/rfc/rfc2831.txt
new file mode 100644 (file)
index 0000000..c1a54c4
--- /dev/null
@@ -0,0 +1,1515 @@
+
+
+
+
+
+
+Network Working Group                                           P. Leach
+Request for Comments: 2831                                     Microsoft
+Category: Standards Track                                      C. Newman
+                                                                Innosoft
+                                                                May 2000
+
+
+            Using Digest Authentication as a SASL Mechanism
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2000).  All Rights Reserved.
+
+Abstract
+
+   This specification defines how HTTP Digest Authentication [Digest]
+   can be used as a SASL [RFC 2222] mechanism for any protocol that has
+   a SASL profile. It is intended both as an improvement over CRAM-MD5
+   [RFC 2195] and as a convenient way to support a single authentication
+   mechanism for web, mail, LDAP, and other protocols.
+
+Table of Contents
+
+   1 INTRODUCTION.....................................................2
+    1.1 CONVENTIONS AND NOTATION......................................2
+    1.2 REQUIREMENTS..................................................3
+   2 AUTHENTICATION...................................................3
+    2.1 INITIAL AUTHENTICATION........................................3
+     2.1.1 Step One...................................................3
+     2.1.2 Step Two...................................................6
+     2.1.3 Step Three................................................12
+    2.2 SUBSEQUENT AUTHENTICATION....................................12
+     2.2.1 Step one..................................................13
+     2.2.2 Step Two..................................................13
+    2.3 INTEGRITY PROTECTION.........................................13
+    2.4 CONFIDENTIALITY PROTECTION...................................14
+   3 SECURITY CONSIDERATIONS.........................................15
+    3.1 AUTHENTICATION OF CLIENTS USING DIGEST AUTHENTICATION........15
+    3.2 COMPARISON OF DIGEST WITH PLAINTEXT PASSWORDS................16
+    3.3 REPLAY ATTACKS...............................................16
+
+
+
+Leach & Newman              Standards Track                     [Page 1]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+    3.4 ONLINE DICTIONARY ATTACKS....................................16
+    3.5 OFFLINE DICTIONARY ATTACKS...................................16
+    3.6 MAN IN THE MIDDLE............................................17
+    3.7 CHOSEN PLAINTEXT ATTACKS.....................................17
+    3.8 SPOOFING BY COUNTERFEIT SERVERS..............................17
+    3.9 STORING PASSWORDS............................................17
+    3.10 MULTIPLE REALMS.............................................18
+    3.11 SUMMARY.....................................................18
+   4 EXAMPLE.........................................................18
+   5 REFERENCES......................................................20
+   6 AUTHORS' ADDRESSES..............................................21
+   7 ABNF............................................................21
+    7.1 AUGMENTED BNF................................................21
+    7.2 BASIC RULES..................................................23
+   8 SAMPLE CODE.....................................................25
+   9 FULL COPYRIGHT STATEMENT........................................27
+
+1  Introduction
+
+   This specification describes the use of HTTP Digest Access
+   Authentication as a SASL mechanism. The authentication type
+   associated with the Digest SASL mechanism is "DIGEST-MD5".
+
+   This specification is intended to be upward compatible with the
+   "md5-sess" algorithm of HTTP/1.1 Digest Access Authentication
+   specified in [Digest]. The only difference in the "md5-sess"
+   algorithm is that some directives not needed in a SASL mechanism have
+   had their values defaulted.
+
+   There is one new feature for use as a SASL mechanism: integrity
+   protection on application protocol messages after an authentication
+   exchange.
+
+   Also, compared to CRAM-MD5, DIGEST-MD5 prevents chosen plaintext
+   attacks, and permits the use of third party authentication servers,
+   mutual authentication, and optimized reauthentication if a client has
+   recently authenticated to a server.
+
+1.1  Conventions and Notation
+
+   This specification uses the same ABNF notation and lexical
+   conventions as HTTP/1.1 specification; see appendix A.
+
+   Let { a, b, ... } be the concatenation of the octet strings a, b, ...
+
+   Let H(s) be the 16 octet MD5 hash [RFC 1321] of the octet string s.
+
+
+
+
+
+Leach & Newman              Standards Track                     [Page 2]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   Let KD(k, s) be H({k, ":", s}), i.e., the 16 octet hash of the string
+   k, a colon and the string s.
+
+   Let HEX(n) be the representation of the 16 octet MD5 hash n as a
+   string of 32 hex digits (with alphabetic characters always in lower
+   case, since MD5 is case sensitive).
+
+   Let HMAC(k, s) be the 16 octet HMAC-MD5 [RFC 2104] of the octet
+   string s using the octet string k as a key.
+
+   The value of a quoted string constant as an octet string does not
+   include any terminating null character.
+
+1.2  Requirements
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+   document are to be interpreted as described in RFC 2119 [RFC 2119].
+
+   An implementation is not compliant if it fails to satisfy one or more
+   of the MUST level requirements for the protocols it implements. An
+   implementation that satisfies all the MUST level and all the SHOULD
+   level requirements for its protocols is said to be "unconditionally
+   compliant"; one that satisfies all the MUST level requirements but
+   not all the SHOULD level requirements for its protocols is said to be
+   "conditionally compliant."
+
+2  Authentication
+
+   The following sections describe how to use Digest as a SASL
+   authentication mechanism.
+
+2.1  Initial Authentication
+
+   If the client has not recently authenticated to the server, then it
+   must perform "initial authentication", as defined in this section. If
+   it has recently authenticated, then a more efficient form is
+   available, defined in the next section.
+
+2.1.1  Step One
+
+   The server starts by sending a challenge. The data encoded in the
+   challenge contains a string formatted according to the rules for a
+   "digest-challenge" defined as follows:
+
+
+
+
+
+
+
+Leach & Newman              Standards Track                     [Page 3]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   digest-challenge  =
+         1#( realm | nonce | qop-options | stale | maxbuf | charset
+               algorithm | cipher-opts | auth-param )
+
+        realm             = "realm" "=" <"> realm-value <">
+        realm-value       = qdstr-val
+        nonce             = "nonce" "=" <"> nonce-value <">
+        nonce-value       = qdstr-val
+        qop-options       = "qop" "=" <"> qop-list <">
+        qop-list          = 1#qop-value
+        qop-value         = "auth" | "auth-int" | "auth-conf" |
+                             token
+        stale             = "stale" "=" "true"
+        maxbuf            = "maxbuf" "=" maxbuf-value
+        maxbuf-value      = 1*DIGIT
+        charset           = "charset" "=" "utf-8"
+        algorithm         = "algorithm" "=" "md5-sess"
+        cipher-opts       = "cipher" "=" <"> 1#cipher-value <">
+        cipher-value      = "3des" | "des" | "rc4-40" | "rc4" |
+                            "rc4-56" | token
+        auth-param        = token "=" ( token | quoted-string )
+
+   The meanings of the values of the directives used above are as
+   follows:
+
+   realm
+      Mechanistically, a string which can enable users to know which
+      username and password to use, in case they might have different
+      ones for different servers. Conceptually, it is the name of a
+      collection of accounts that might include the user's account. This
+      string should contain at least the name of the host performing the
+      authentication and might additionally indicate the collection of
+      users who might have access. An example might be
+      "registered_users@gotham.news.example.com".  This directive is
+      optional; if not present, the client SHOULD solicit it from the
+      user or be able to compute a default; a plausible default might be
+      the realm supplied by the user when they logged in to the client
+      system. Multiple realm directives are allowed, in which case the
+      user or client must choose one as the realm for which to supply to
+      username and password.
+
+   nonce
+      A server-specified data string which MUST be different each time a
+      digest-challenge is sent as part of initial authentication.  It is
+      recommended that this string be base64 or hexadecimal data. Note
+      that since the string is passed as a quoted string, the
+      double-quote character is not allowed unless escaped (see section
+      7.2). The contents of the nonce are implementation dependent. The
+
+
+
+Leach & Newman              Standards Track                     [Page 4]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+      security of the implementation depends on a good choice. It is
+      RECOMMENDED that it contain at least 64 bits of entropy. The nonce
+      is opaque to the client. This directive is required and MUST
+      appear exactly once; if not present, or if multiple instances are
+      present, the client should abort the authentication exchange.
+
+   qop-options
+      A quoted string of one or more tokens indicating the "quality of
+      protection" values supported by the server.  The value "auth"
+      indicates authentication; the value "auth-int" indicates
+      authentication with integrity protection; the value "auth-conf"
+      indicates authentication with integrity protection and encryption.
+      This directive is optional; if not present it defaults to "auth".
+      The client MUST ignore unrecognized options; if the client
+      recognizes no option, it should abort the authentication exchange.
+
+   stale
+      The "stale" directive is not used in initial authentication. See
+      the next section for its use in subsequent authentications. This
+      directive may appear at most once; if multiple instances are
+      present, the client should abort the authentication exchange.
+
+   maxbuf
+      A number indicating the size of the largest buffer the server is
+      able to receive when using "auth-int" or "auth-conf". If this
+      directive is missing, the default value is 65536. This directive
+      may appear at most once; if multiple instances are present, the
+      client should abort the authentication exchange.
+
+   charset
+      This directive, if present, specifies that the server supports
+      UTF-8 encoding for the username and password. If not present, the
+      username and password must be encoded in ISO 8859-1 (of which
+      US-ASCII is a subset). The directive is needed for backwards
+      compatibility with HTTP Digest, which only supports ISO 8859-1.
+      This directive may appear at most once; if multiple instances are
+      present, the client should abort the authentication exchange.
+
+   algorithm
+      This directive is required for backwards compatibility with HTTP
+      Digest., which supports other algorithms. . This directive is
+      required and MUST appear exactly once; if not present, or if
+      multiple instances are present, the client should abort the
+      authentication exchange.
+
+
+
+
+
+
+
+Leach & Newman              Standards Track                     [Page 5]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   cipher-opts
+      A list of ciphers that the server supports. This directive must be
+      present exactly once if "auth-conf" is offered in the
+      "qop-options" directive, in which case the "3des" and "des" modes
+      are mandatory-to-implement. The client MUST ignore unrecognized
+      options; if the client recognizes no option, it should abort the
+      authentication exchange.
+
+      des
+         the Data Encryption Standard (DES) cipher [FIPS] in cipher
+         block chaining (CBC) mode with a 56 bit key.
+
+      3des
+         the "triple DES" cipher in CBC mode with EDE with the same key
+         for each E stage (aka "two keys mode") for a total key length
+         of 112 bits.
+
+      rc4, rc4-40, rc4-56
+         the RC4 cipher with a 128 bit, 40 bit, and 56 bit key,
+         respectively.
+
+   auth-param This construct allows for future extensions; it may appear
+      more than once. The client MUST ignore any unrecognized
+      directives.
+
+   For use as a SASL mechanism, note that the following changes are made
+   to "digest-challenge" from HTTP: the following Digest options (called
+   "directives" in HTTP terminology) are unused (i.e., MUST NOT be sent,
+   and MUST be ignored if received):
+
+    opaque
+    domain
+
+   The size of a digest-challenge MUST be less than 2048 bytes.
+
+2.1.2  Step Two
+
+   The client makes note of the "digest-challenge" and then responds
+   with a string formatted and computed according to the rules for a
+   "digest-response" defined as follows:
+
+
+
+
+
+
+
+
+
+
+
+Leach & Newman              Standards Track                     [Page 6]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   digest-response  = 1#( username | realm | nonce | cnonce |
+                          nonce-count | qop | digest-uri | response |
+                          maxbuf | charset | cipher | authzid |
+                          auth-param )
+
+       username         = "username" "=" <"> username-value <">
+       username-value   = qdstr-val
+       cnonce           = "cnonce" "=" <"> cnonce-value <">
+       cnonce-value     = qdstr-val
+       nonce-count      = "nc" "=" nc-value
+       nc-value         = 8LHEX
+       qop              = "qop" "=" qop-value
+       digest-uri       = "digest-uri" "=" <"> digest-uri-value <">
+       digest-uri-value  = serv-type "/" host [ "/" serv-name ]
+       serv-type        = 1*ALPHA
+       host             = 1*( ALPHA | DIGIT | "-" | "." )
+       serv-name        = host
+       response         = "response" "=" response-value
+       response-value   = 32LHEX
+       LHEX             = "0" | "1" | "2" | "3" |
+                          "4" | "5" | "6" | "7" |
+                          "8" | "9" | "a" | "b" |
+                          "c" | "d" | "e" | "f"
+       cipher           = "cipher" "=" cipher-value
+       authzid          = "authzid" "=" <"> authzid-value <">
+       authzid-value    = qdstr-val
+
+
+   username
+      The user's name in the specified realm, encoded according to the
+      value of the "charset" directive. This directive is required and
+      MUST be present exactly once; otherwise, authentication fails.
+
+   realm
+      The realm containing the user's account. This directive is
+      required if the server provided any realms in the
+      "digest-challenge", in which case it may appear exactly once and
+      its value SHOULD be one of those realms. If the directive is
+      missing, "realm-value" will set to the empty string when computing
+      A1 (see below for details).
+
+   nonce
+      The server-specified data string received in the preceding
+      digest-challenge. This directive is required and MUST be present
+      exactly once; otherwise, authentication fails.
+
+
+
+
+
+
+Leach & Newman              Standards Track                     [Page 7]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   cnonce
+      A client-specified data string which MUST be different each time a
+      digest-response is sent as part of initial authentication. The
+      cnonce-value is an opaque quoted string value provided by the
+      client and used by both client and server to avoid chosen
+      plaintext attacks, and to provide mutual authentication. The
+      security of the implementation depends on a good choice. It is
+      RECOMMENDED that it contain at least 64 bits of entropy. This
+      directive is required and MUST be present exactly once; otherwise,
+      authentication fails.
+
+   nonce-count
+      The nc-value is the hexadecimal count of the number of requests
+      (including the current request) that the client has sent with the
+      nonce value in this request.  For example, in the first request
+      sent in response to a given nonce value, the client sends
+      "nc=00000001". The purpose of this directive is to allow the
+      server to detect request replays by maintaining its own copy of
+      this count - if the same nc-value is seen twice, then the request
+      is a replay.   See the description below of the construction of
+      the response value. This directive may appear at most once; if
+      multiple instances are present, the client should abort the
+      authentication exchange.
+
+   qop
+      Indicates what "quality of protection" the client accepted. If
+      present, it may appear exactly once and  its value MUST be one of
+      the alternatives in qop-options. If not present, it defaults to
+      "auth". These values affect the computation of the response. Note
+      that this is a single token, not a quoted list of alternatives.
+
+   serv-type
+      Indicates the type of service, such as "www" for web service,
+      "ftp" for FTP service, "smtp" for mail delivery service, etc. The
+      service name as defined in the SASL profile for the protocol see
+      section 4 of [RFC 2222], registered in the IANA registry of
+      "service" elements for the GSSAPI host-based service name form
+      [RFC 2078].
+
+   host
+      The DNS host name or IP address for the service requested.  The
+      DNS host name must be the fully-qualified canonical name of the
+      host. The DNS host name is the preferred form; see notes on server
+      processing of the digest-uri.
+
+
+
+
+
+
+
+Leach & Newman              Standards Track                     [Page 8]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   serv-name
+      Indicates the name of the service if it is replicated. The service
+      is considered to be replicated if the client's service-location
+      process involves resolution using standard DNS lookup operations,
+      and if these operations involve DNS records (such as SRV, or MX)
+      which resolve one DNS name into a set of other DNS names. In this
+      case, the initial name used by the client is the "serv-name", and
+      the final name is the "host" component. For example, the incoming
+      mail service for "example.com" may be replicated through the use
+      of MX records stored in the DNS, one of which points at an SMTP
+      server called "mail3.example.com"; it's "serv-name" would be
+      "example.com", it's "host" would be "mail3.example.com". If the
+      service is not replicated, or the serv-name is identical to the
+      host, then the serv-name component MUST be omitted.
+
+   digest-uri
+      Indicates the principal name of the service with which the client
+      wishes to connect, formed from the serv-type, host, and serv-name.
+      For example, the FTP service on "ftp.example.com" would have a
+      "digest-uri" value of "ftp/ftp.example.com"; the SMTP server from
+      the example above would have a "digest-uri" value of
+      "smtp/mail3.example.com/example.com".
+
+   Servers SHOULD check that the supplied value is correct. This will
+   detect accidental connection to the incorrect server. It is also so
+   that clients will be trained to provide values that will work with
+   implementations that use a shared back-end authentication service
+   that can provide server authentication.
+
+   The serv-type component should match the service being offered. The
+   host component should match one of the host names of the host on
+   which the service is running, or it's IP address. Servers SHOULD NOT
+   normally support the IP address form, because server authentication
+   by IP address is not very useful; they should only do so if the DNS
+   is unavailable or unreliable. The serv-name component should match
+   one of the service's configured service names.
+
+   This directive may appear at most once; if multiple instances are
+   present, the client should abort the authentication exchange.
+
+   Note: In the HTTP use of Digest authentication, the digest-uri is the
+   URI (usually a URL) of the resource requested -- hence the name of
+   the directive.
+
+   response
+      A string of 32 hex digits computed as defined below, which proves
+      that the user knows a password. This directive is required and
+      MUST be present exactly once; otherwise, authentication fails.
+
+
+
+Leach & Newman              Standards Track                     [Page 9]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   maxbuf
+      A number indicating the size of the largest buffer the client is
+      able to receive. If this directive is missing, the default value
+      is 65536. This directive may appear at most once; if multiple
+      instances are present, the server should abort the authentication
+      exchange.
+
+   charset
+      This directive, if present, specifies that the client has used
+      UTF-8 encoding for the username and password. If not present, the
+      username and password must be encoded in ISO 8859-1 (of which
+      US-ASCII is a subset). The client should send this directive only
+      if the server has indicated it supports UTF-8. The directive is
+      needed for backwards compatibility with HTTP Digest, which only
+      supports ISO 8859-1.
+
+   LHEX
+      32 hex digits, where the alphabetic characters MUST be lower case,
+      because MD5 is not case insensitive.
+
+   cipher
+      The cipher chosen by the client. This directive MUST appear
+      exactly once if "auth-conf" is negotiated; if required and not
+      present, authentication fails.
+
+   authzid
+      The "authorization ID" as per RFC 2222, encoded in UTF-8. This
+      directive is optional. If present, and the authenticating user has
+      sufficient privilege, and the server supports it, then after
+      authentication the server will use this identity for making all
+      accesses and access checks. If the client specifies it, and the
+      server does not support it, then the response-value will be
+      incorrect, and authentication will fail.
+
+   The size of a digest-response MUST be less than 4096 bytes.
+
+2.1.2.1   Response-value
+
+   The definition of "response-value" above indicates the encoding for
+   its value -- 32 lower case hex characters. The following definitions
+   show how the value is computed.
+
+   Although qop-value and components of digest-uri-value may be
+   case-insensitive, the case which the client supplies in step two is
+   preserved for the purpose of computing and verifying the
+   response-value.
+
+      response-value  =
+
+
+
+Leach & Newman              Standards Track                    [Page 10]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+         HEX( KD ( HEX(H(A1)),
+                 { nonce-value, ":" nc-value, ":",
+                   cnonce-value, ":", qop-value, ":", HEX(H(A2)) }))
+
+   If authzid is specified, then A1 is
+
+
+      A1 = { H( { username-value, ":", realm-value, ":", passwd } ),
+           ":", nonce-value, ":", cnonce-value, ":", authzid-value }
+
+   If authzid is not specified, then A1 is
+
+
+      A1 = { H( { username-value, ":", realm-value, ":", passwd } ),
+           ":", nonce-value, ":", cnonce-value }
+
+   where
+
+         passwd   = *OCTET
+
+   The "username-value", "realm-value" and "passwd" are encoded
+   according to the value of the "charset" directive. If "charset=UTF-8"
+   is present, and all the characters of either "username-value" or
+   "passwd" are in the ISO 8859-1 character set, then it must be
+   converted to ISO 8859-1 before being hashed. This is so that
+   authentication databases that store the hashed username, realm and
+   password (which is common) can be shared compatibly with HTTP, which
+   specifies ISO 8859-1. A sample implementation of this conversion is
+   in section 8.
+
+   If the "qop" directive's value is "auth", then A2 is:
+
+      A2       = { "AUTHENTICATE:", digest-uri-value }
+
+   If the "qop" value is "auth-int" or "auth-conf" then A2 is:
+
+      A2       = { "AUTHENTICATE:", digest-uri-value,
+               ":00000000000000000000000000000000" }
+
+   Note that "AUTHENTICATE:" must be in upper case, and the second
+   string constant is a string with a colon followed by 32 zeros.
+
+   These apparently strange values of A2 are for compatibility with
+   HTTP; they were arrived at by setting "Method" to "AUTHENTICATE" and
+   the hash of the entity body to zero in the HTTP digest calculation of
+   A2.
+
+   Also, in the HTTP usage of Digest, several directives in the
+
+
+
+Leach & Newman              Standards Track                    [Page 11]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   "digest-challenge" sent by the server have to be returned by the
+   client in the "digest-response". These are:
+
+    opaque
+    algorithm
+
+   These directives are not needed when Digest is used as a SASL
+   mechanism (i.e., MUST NOT be sent, and MUST be ignored if received).
+
+2.1.3  Step Three
+
+   The server receives and validates the "digest-response". The server
+   checks that the nonce-count is "00000001". If it supports subsequent
+   authentication (see section 2.2), it saves the value of the nonce and
+   the nonce-count. It sends a message formatted as follows:
+
+    response-auth = "rspauth" "=" response-value
+
+   where response-value is calculated as above, using the values sent in
+   step two, except that if qop is "auth", then A2 is
+
+       A2 = { ":", digest-uri-value }
+
+   And if qop is "auth-int" or "auth-conf" then A2 is
+
+       A2 = { ":", digest-uri-value, ":00000000000000000000000000000000" }
+
+   Compared to its use in HTTP, the following Digest directives in the
+   "digest-response" are unused:
+
+       nextnonce
+       qop
+       cnonce
+       nonce-count
+
+2.2  Subsequent Authentication
+
+   If the client has previously authenticated to the server, and
+   remembers the values of username, realm, nonce, nonce-count, cnonce,
+   and qop that it used in that authentication, and the SASL profile for
+   a protocol permits an initial client response, then it MAY perform
+   "subsequent authentication", as defined in this section.
+
+
+
+
+
+
+
+
+
+Leach & Newman              Standards Track                    [Page 12]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+2.2.1  Step one
+
+   The client uses the values from the previous authentication and sends
+   an initial response with a string formatted and computed according to
+   the rules for a "digest-response", as defined above, but with a
+   nonce-count one greater than used in the last "digest-response".
+
+2.2.2  Step Two
+
+   The server receives the "digest-response". If the server does not
+   support subsequent authentication, then it sends a
+   "digest-challenge", and authentication proceeds as in initial
+   authentication. If the server has no saved nonce and nonce-count from
+   a previous authentication, then it sends a "digest-challenge", and
+   authentication proceeds as in initial authentication. Otherwise, the
+   server validates the "digest-response", checks that the nonce-count
+   is one greater than that used in the previous authentication using
+   that nonce, and saves the new value of nonce-count.
+
+   If the response is invalid, then the server sends a
+   "digest-challenge", and authentication proceeds as in initial
+   authentication (and should be configurable to log an authentication
+   failure in some sort of security audit log, since the failure may be
+   a symptom of an attack). The nonce-count MUST NOT be incremented in
+   this case: to do so would allow a denial of service attack by sending
+   an out-of-order nonce-count.
+
+   If the response is valid, the server MAY choose to deem that
+   authentication has succeeded. However, if it has been too long since
+   the previous authentication, or for any other reason, the server MAY
+   send a new "digest-challenge" with a new value for nonce. The
+   challenge MAY contain a "stale" directive with value "true", which
+   says that the client may respond to the challenge using the password
+   it used in the previous response; otherwise, the client must solicit
+   the password anew from the user. This permits the server to make sure
+   that the user has presented their password recently. (The directive
+   name refers to the previous nonce being stale, not to the last use of
+   the password.) Except for the handling of "stale", after sending the
+   "digest-challenge" authentication proceeds as in the case of initial
+   authentication.
+
+2.3   Integrity Protection
+
+   If the server offered "qop=auth-int" and the client responded
+   "qop=auth-int", then subsequent messages, up to but not including the
+   next subsequent authentication, between the client and the server
+
+
+
+
+
+Leach & Newman              Standards Track                    [Page 13]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   MUST be integrity protected. Using as a base session key the value of
+   H(A1) as defined above the client and server calculate a pair of
+   message integrity keys as follows.
+
+   The key for integrity protecting messages from client to server is:
+
+   Kic = MD5({H(A1),
+   "Digest session key to client-to-server signing key magic constant"})
+
+   The key for integrity protecting messages from server to client is:
+
+   Kis = MD5({H(A1),
+   "Digest session key to server-to-client signing key magic constant"})
+
+   where MD5 is as specified in [RFC 1321]. If message integrity is
+   negotiated, a MAC block for each message is appended to the message.
+   The MAC block is 16 bytes: the first 10 bytes of the HMAC-MD5 [RFC
+   2104] of the message, a 2-byte message type number in network byte
+   order with value 1, and the 4-byte sequence number in network byte
+   order. The message type is to allow for future extensions such as
+   rekeying.
+
+   MAC(Ki, SeqNum, msg) = (HMAC(Ki, {SeqNum, msg})[0..9], 0x0001,
+   SeqNum)
+
+   where Ki is Kic for messages sent by the client and Kis for those
+   sent by the server. The sequence number is initialized to zero, and
+   incremented by one for each message sent.
+
+   Upon receipt, MAC(Ki, SeqNum, msg) is computed and compared with the
+   received value; the message is discarded if they differ.
+
+2.4   Confidentiality Protection
+
+   If the server sent a "cipher-opts" directive and the client responded
+   with a "cipher" directive, then subsequent messages between the
+   client and the server MUST be confidentiality protected. Using as a
+   base session key the value of H(A1) as defined above the client and
+   server calculate a pair of message integrity keys as follows.
+
+   The key for confidentiality protecting messages from client to server
+   is:
+
+   Kcc = MD5({H(A1)[0..n],
+   "Digest H(A1) to client-to-server sealing key magic constant"})
+
+   The key for confidentiality protecting messages from server to client
+   is:
+
+
+
+Leach & Newman              Standards Track                    [Page 14]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   Kcs = MD5({H(A1)[0..n],
+   "Digest H(A1) to server-to-client sealing key magic constant"})
+
+   where MD5 is as specified in [RFC 1321]. For cipher "rc4-40" n is 5;
+   for "rc4-56" n is 7; for the rest n is 16. The key for the "rc-*"
+   ciphers is all 16 bytes of Kcc or Kcs; the key for "des" is the first
+   7 bytes; the key for "3des" is the first 14 bytes. The IV for "des"
+   and "3des" is the last 8 bytes of Kcc or Kcs.
+
+   If message confidentiality is negotiated, each message is encrypted
+   with the chosen cipher and a MAC block is appended to the message.
+
+   The MAC block is a variable length padding prefix followed by 16
+   bytes formatted as follows: the first 10 bytes of the HMAC-MD5 [RFC
+   2104] of the message, a 2-byte message type number in network byte
+   order with value 1, and the 4-byte sequence number in network byte
+   order. If the blocksize of the chosen cipher is not 1 byte, the
+   padding prefix is one or more octets each containing the number of
+   padding bytes, such that total length of the encrypted part of the
+   message is a multiple of the blocksize. The padding and first 10
+   bytes of the MAC block are encrypted along with the message.
+
+   SEAL(Ki, Kc, SeqNum, msg) =
+         {CIPHER(Kc, {msg, pad, HMAC(Ki, {SeqNum, msg})[0..9])}), 0x0001,
+          SeqNum}
+
+   where CIPHER is the chosen cipher, Ki and Kc are Kic and Kcc for
+   messages sent by the client and Kis and Kcs for those sent by the
+   server. The sequence number is initialized to zero, and incremented
+   by one for each message sent.
+
+   Upon receipt, the message is decrypted, HMAC(Ki, {SeqNum, msg}) is
+   computed and compared with the received value; the message is
+   discarded if they differ.
+
+3  Security Considerations
+
+3.1   Authentication of Clients using Digest Authentication
+
+   Digest Authentication does not provide a strong authentication
+   mechanism, when compared to public key based mechanisms, for example.
+   However, since it prevents chosen plaintext attacks, it is stronger
+   than (e.g.) CRAM-MD5, which has been proposed for use with LDAP [10],
+   POP and IMAP (see RFC 2195 [9]).   It is intended to replace the much
+   weaker and even more dangerous use of plaintext passwords; however,
+   since it is still a password based mechanism it avoids some of the
+   potential deployabilty issues with public-key, OTP or similar
+   mechanisms.
+
+
+
+Leach & Newman              Standards Track                    [Page 15]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   Digest Authentication offers no confidentiality protection beyond
+   protecting the actual password. All of the rest of the challenge and
+   response are available to an eavesdropper, including the user's name
+   and authentication realm.
+
+3.2   Comparison of Digest with Plaintext Passwords
+
+   The greatest threat to the type of transactions for which these
+   protocols are used is network snooping. This kind of transaction
+   might involve, for example, online access to a mail service whose use
+   is restricted to paying subscribers. With plaintext password
+   authentication an eavesdropper can obtain the password of the user.
+   This not only permits him to access anything in the database, but,
+   often worse, will permit access to anything else the user protects
+   with the same password.
+
+3.3   Replay Attacks
+
+   Replay attacks are defeated if the client or the server chooses a
+   fresh nonce for each authentication, as this specification requires.
+
+3.4  Online dictionary attacks
+
+   If the attacker can eavesdrop, then it can test any overheard
+   nonce/response pairs against a (potentially very large) list of
+   common words. Such a list is usually much smaller than the total
+   number of possible passwords. The cost of computing the response for
+   each password on the list is paid once for each challenge.
+
+   The server can mitigate this attack by not allowing users to select
+   passwords that are in a dictionary.
+
+3.5  Offline dictionary attacks
+
+   If the attacker can choose the challenge, then it can precompute the
+   possible responses to that challenge for a list of common words. Such
+   a list is usually much smaller than the total number of possible
+   passwords. The cost of computing the response for each password on
+   the list is paid just once.
+
+   Offline dictionary attacks are defeated if the client chooses a fresh
+   nonce for each authentication, as this specification requires.
+
+
+
+
+
+
+
+
+
+Leach & Newman              Standards Track                    [Page 16]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+3.6  Man in the Middle
+
+   Digest authentication is vulnerable to "man in the middle" (MITM)
+   attacks. Clearly, a MITM would present all the problems of
+   eavesdropping. But it also offers some additional opportunities to
+   the attacker.
+
+   A possible man-in-the-middle attack would be to substitute a weaker
+   qop scheme for the one(s) sent by the server; the server will not be
+   able to detect this attack. For this reason, the client should always
+   use the strongest scheme that it understands from the choices
+   offered, and should never choose a scheme that does not meet its
+   minimum requirements.
+
+3.7  Chosen plaintext attacks
+
+   A chosen plaintext attack is where a MITM or a malicious server can
+   arbitrarily choose the challenge that the client will use to compute
+   the response. The ability to choose the challenge is known to make
+   cryptanalysis much easier [8].
+
+   However, Digest does not permit the attack to choose the challenge as
+   long as the client chooses a fresh nonce for each authentication, as
+   this specification requires.
+
+3.8  Spoofing by Counterfeit Servers
+
+   If a user can be led to believe that she is connecting to a host
+   containing information protected by a password she knows, when in
+   fact she is connecting to a hostile server, then the hostile server
+   can obtain challenge/response pairs where it was able to partly
+   choose the challenge. There is no known way that this can be
+   exploited.
+
+3.9  Storing passwords
+
+   Digest authentication requires that the authenticating agent (usually
+   the server) store some data derived from the user's name and password
+   in a "password file" associated with a given realm. Normally this
+   might contain pairs consisting of username and H({ username-value,
+   ":", realm-value, ":", passwd }), which is adequate to compute H(A1)
+   as described above without directly exposing the user's password.
+
+   The security implications of this are that if this password file is
+   compromised, then an attacker gains immediate access to documents on
+   the server using this realm. Unlike, say a standard UNIX password
+   file, this information need not be decrypted in order to access
+   documents in the server realm associated with this file. On the other
+
+
+
+Leach & Newman              Standards Track                    [Page 17]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   hand, decryption, or more likely a brute force attack, would be
+   necessary to obtain the user's password. This is the reason that the
+   realm is part of the digested data stored in the password file. It
+   means that if one Digest authentication password file is compromised,
+   it does not automatically compromise others with the same username
+   and password (though it does expose them to brute force attack).
+
+   There are two important security consequences of this. First the
+   password file must be protected as if it contained plaintext
+   passwords, because for the purpose of accessing documents in its
+   realm, it effectively does.
+
+   A second consequence of this is that the realm string should be
+   unique among all realms that any single user is likely to use. In
+   particular a realm string should include the name of the host doing
+   the authentication.
+
+3.10  Multiple realms
+
+   Use of multiple realms may mean both that compromise of a the
+   security database for a single realm does not compromise all
+   security, and that there are more things to protect in order to keep
+   the whole system secure.
+
+3.11  Summary
+
+   By modern cryptographic standards Digest Authentication is weak,
+   compared to (say) public key based mechanisms. But for a large range
+   of purposes it is valuable as a replacement for plaintext passwords.
+   Its strength may vary depending on the implementation.
+
+4  Example
+
+   This example shows the use of the Digest SASL mechanism with the
+   IMAP4 AUTHENTICATE command [RFC 2060].
+
+   In this example, "C:" and "S:" represent a line sent by the client or
+   server respectively including a CRLF at the end.  Linebreaks and
+   indentation within a "C:" or "S:" are editorial and not part of the
+   protocol. The password in this example was "secret".  Note that the
+   base64 encoding of the challenges and responses is part of the IMAP4
+   AUTHENTICATE command, not part of the Digest specification itself.
+
+    S: * OK elwood.innosoft.com PMDF IMAP4rev1 V6.0-9
+    C: c CAPABILITY
+    S: * CAPABILITY IMAP4 IMAP4rev1 ACL LITERAL+ NAMESPACE QUOTA
+                UIDPLUS AUTH=CRAM-MD5 AUTH=DIGEST-MD5 AUTH=PLAIN
+    S: c OK Completed
+
+
+
+Leach & Newman              Standards Track                    [Page 18]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+    C: a AUTHENTICATE DIGEST-MD5
+    S: + cmVhbG09ImVsd29vZC5pbm5vc29mdC5jb20iLG5vbmNlPSJPQTZNRzl0
+         RVFHbTJoaCIscW9wPSJhdXRoIixhbGdvcml0aG09bWQ1LXNlc3MsY2hh
+         cnNldD11dGYtOA==
+    C: Y2hhcnNldD11dGYtOCx1c2VybmFtZT0iY2hyaXMiLHJlYWxtPSJlbHdvb2
+       QuaW5ub3NvZnQuY29tIixub25jZT0iT0E2TUc5dEVRR20yaGgiLG5jPTAw
+       MDAwMDAxLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLGRpZ2VzdC11cmk9Im
+       ltYXAvZWx3b29kLmlubm9zb2Z0LmNvbSIscmVzcG9uc2U9ZDM4OGRhZDkw
+       ZDRiYmQ3NjBhMTUyMzIxZjIxNDNhZjcscW9wPWF1dGg=
+    S: + cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZA==
+    C:
+    S: a OK User logged in
+    ---
+
+    The base64-decoded version of the SASL exchange is:
+
+    S: realm="elwood.innosoft.com",nonce="OA6MG9tEQGm2hh",qop="auth",
+       algorithm=md5-sess,charset=utf-8
+    C: charset=utf-8,username="chris",realm="elwood.innosoft.com",
+       nonce="OA6MG9tEQGm2hh",nc=00000001,cnonce="OA6MHXh6VqTrRk",
+       digest-uri="imap/elwood.innosoft.com",
+       response=d388dad90d4bbd760a152321f2143af7,qop=auth
+    S: rspauth=ea40f60335c427b5527b84dbabcdfffd
+
+    The password in this example was "secret".
+
+   This example shows the use of the Digest SASL mechanism with the
+   ACAP, using the same notational conventions and password as in the
+   previous example. Note that ACAP does not base64 encode and uses
+   fewer round trips that IMAP4.
+
+    S: * ACAP (IMPLEMENTATION "Test ACAP server") (SASL "CRAM-MD5"
+               "DIGEST-MD5" "PLAIN")
+    C: a AUTHENTICATE "DIGEST-MD5"
+    S: + {94}
+    S: realm="elwood.innosoft.com",nonce="OA9BSXrbuRhWay",qop="auth",
+       algorithm=md5-sess,charset=utf-8
+    C: {206}
+    C: charset=utf-8,username="chris",realm="elwood.innosoft.com",
+       nonce="OA9BSXrbuRhWay",nc=00000001,cnonce="OA9BSuZWMSpW8m",
+       digest-uri="acap/elwood.innosoft.com",
+       response=6084c6db3fede7352c551284490fd0fc,qop=auth
+    S: a OK (SASL {40}
+    S: rspauth=2f0b3d7c3c2e486600ef710726aa2eae) "AUTHENTICATE
+    Completed"
+    ---
+
+
+
+
+
+Leach & Newman              Standards Track                    [Page 19]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   The server uses the values of all the directives, plus knowledge of
+   the users password (or the hash of the user's name, server's realm
+   and the user's password) to verify the computations above. If they
+   check, then the user has authenticated.
+
+5   References
+
+   [Digest]   Franks, J., et al., "HTTP Authentication: Basic and Digest
+              Access Authentication", RFC 2617, June 1999.
+
+   [ISO-8859] ISO-8859. International Standard--Information Processing--
+              8-bit Single-Byte Coded Graphic Character Sets --
+              Part 1: Latin alphabet No. 1, ISO-8859-1:1987.
+              Part 2: Latin alphabet No. 2, ISO-8859-2, 1987.
+              Part 3: Latin alphabet No. 3, ISO-8859-3, 1988.
+              Part 4: Latin alphabet No. 4, ISO-8859-4, 1988.
+              Part 5: Latin/Cyrillic alphabet, ISO-8859-5, 1988.
+              Part 6: Latin/Arabic alphabet, ISO-8859-6, 1987.
+              Part 7: Latin/Greek alphabet, ISO-8859-7, 1987.
+              Part 8: Latin/Hebrew alphabet, ISO-8859-8, 1988.
+              Part 9: Latin alphabet No. 5, ISO-8859-9, 1990.
+
+   [RFC 822]  Crocker, D., "Standard for The Format of ARPA Internet
+              Text Messages," STD 11, RFC 822, August 1982.
+
+   [RFC 1321] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321,
+              April 1992.
+
+   [RFC 2047] Moore, K., "MIME (Multipurpose Internet Mail Extensions)
+              Part Three: Message Header Extensions for Non-ASCII Text",
+              RFC 2047, November 1996.
+
+   [RFC 2052] Gulbrandsen, A. and P. Vixie, "A DNS RR for specifying the
+              location of services (DNS SRV)", RFC 2052, October 1996.
+
+   [RFC 2060] Crispin, M., "Internet Message Access Protocol - Version
+              4rev1", RFC 2060, December 1996.
+
+   [RFC 2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC:  Keyed-
+              Hashing for  Message Authentication", RFC 2104, February
+              1997.
+
+   [RFC 2195] Klensin, J., Catoe, R. and P. Krumviede, "IMAP/POP
+              AUTHorize Extension for Simple Challenge/Response", RFC
+              2195, September 1997.
+
+
+
+
+
+
+Leach & Newman              Standards Track                    [Page 20]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   [RFC 2119] Bradner, S., "Key words for use in RFCs to Indicate
+              Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+   [RFC 2222] Myers, J., "Simple Authentication and Security Layer
+              (SASL)", RFC 2222, October 1997.
+
+   [USASCII]  US-ASCII. Coded Character Set - 7-Bit American Standard
+              Code for Information Interchange. Standard ANSI X3.4-1986,
+              ANSI, 1986.
+
+6  Authors' Addresses
+
+   Paul Leach
+   Microsoft
+   1 Microsoft Way
+   Redmond, WA  98052
+
+   EMail: paulle@microsoft.com
+
+
+   Chris Newman
+   Innosoft International, Inc.
+   1050 Lakes Drive
+   West Covina, CA 91790 USA
+
+   EMail: chris.newman@innosoft.com
+
+7  ABNF
+
+   What follows is the definition of the notation as is used in the
+   HTTP/1.1 specification (RFC 2616) and the HTTP authentication
+   specification (RFC 2617); it is reproduced here for ease of
+   reference. Since it is intended that a single Digest implementation
+   can support both HTTP and SASL-based protocols, the same notation is
+   used in both to facilitate comparison and prevention of unwanted
+   differences. Since it is cut-and-paste from the HTTP specifications,
+   not all productions may be used in this specification. It is also not
+   quite legal ABNF; again, the errors were copied from the HTTP
+   specifications.
+
+7.1   Augmented BNF
+
+   All of the mechanisms specified in this document are described in
+   both prose and an augmented Backus-Naur Form (BNF) similar to that
+   used by RFC 822 [RFC 822]. Implementers will need to be familiar with
+   the notation in order to understand this specification.
+
+
+
+
+
+Leach & Newman              Standards Track                    [Page 21]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   The augmented BNF includes the following constructs:
+
+   name = definition
+      The name of a rule is simply the name itself (without any
+      enclosing "<" and ">") and is separated from its definition by the
+      equal "=" character. White space is only significant in that
+      indentation of continuation lines is used to indicate a rule
+      definition that spans more than one line. Certain basic rules are
+      in uppercase, such as SP, LWS, HT, CRLF, DIGIT, ALPHA, etc. Angle
+      brackets are used within definitions whenever their presence will
+      facilitate discerning the use of rule names.
+
+   "literal"
+      Quotation marks surround literal text. Unless stated otherwise,
+      the text is case-insensitive.
+
+   rule1 | rule2
+      Elements separated by a bar ("|") are alternatives, e.g., "yes |
+      no" will accept yes or no.
+
+   (rule1 rule2)
+      Elements enclosed in parentheses are treated as a single element.
+      Thus, "(elem (foo | bar) elem)" allows the token sequences
+      "elem foo elem" and "elem bar elem".
+
+   *rule
+      The character "*" preceding an element indicates repetition. The
+      full form is "<n>*<m>element" indicating at least <n> and at most
+      <m> occurrences of element. Default values are 0 and infinity so
+      that "*(element)" allows any number, including zero; "1*element"
+      requires at least one; and "1*2element" allows one or two.
+
+   [rule]
+      Square brackets enclose optional elements; "[foo bar]" is
+      equivalent to "*1(foo bar)".
+
+   N rule
+      Specific repetition: "<n>(element)" is equivalent to
+      "<n>*<n>(element)"; that is, exactly <n> occurrences of (element).
+      Thus 2DIGIT is a 2-digit number, and 3ALPHA is a string of three
+      alphabetic characters.
+
+   #rule
+      A construct "#" is defined, similar to "*", for defining lists of
+      elements. The full form is "<n>#<m>element" indicating at least
+      <n> and at most <m> elements, each separated by one or more commas
+      (",") and OPTIONAL linear white space (LWS). This makes the usual
+      form of lists very easy; a rule such as
+
+
+
+Leach & Newman              Standards Track                    [Page 22]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+        ( *LWS element *( *LWS "," *LWS element ))
+      can be shown as
+        1#element
+      Wherever this construct is used, null elements are allowed, but do
+      not contribute to the count of elements present. That is,
+      "(element), , (element) " is permitted, but counts as only two
+      elements.  Therefore, where at least one element is required, at
+      least one non-null element MUST be present. Default values are 0
+      and infinity so that "#element" allows any number, including zero;
+      "1#element" requires at least one; and "1#2element" allows one or
+      two.
+
+   ; comment
+      A semi-colon, set off some distance to the right of rule text,
+      starts a comment that continues to the end of line. This is a
+      simple way of including useful notes in parallel with the
+      specifications.
+
+   implied *LWS
+      The grammar described by this specification is word-based. Except
+      where noted otherwise, linear white space (LWS) can be included
+      between any two adjacent words (token or quoted-string), and
+      between adjacent words and separators, without changing the
+      interpretation of a field. At least one delimiter (LWS and/or
+      separators) MUST exist between any two tokens (for the definition
+      of "token" below), since they would otherwise be interpreted as a
+      single token.
+
+7.2   Basic Rules
+
+   The following rules are used throughout this specification to
+   describe basic parsing constructs. The US-ASCII coded character set
+   is defined by ANSI X3.4-1986 [USASCII].
+
+       OCTET          = <any 8-bit sequence of data>
+       CHAR           = <any US-ASCII character (octets 0 - 127)>
+       UPALPHA        = <any US-ASCII uppercase letter "A".."Z">
+       LOALPHA        = <any US-ASCII lowercase letter "a".."z">
+       ALPHA          = UPALPHA | LOALPHA
+       DIGIT          = <any US-ASCII digit "0".."9">
+       CTL            = <any US-ASCII control character
+                        (octets 0 - 31) and DEL (127)>
+       CR             = <US-ASCII CR, carriage return (13)>
+       LF             = <US-ASCII LF, linefeed (10)>
+       SP             = <US-ASCII SP, space (32)>
+       HT             = <US-ASCII HT, horizontal-tab (9)>
+       <">            = <US-ASCII double-quote mark (34)>
+       CRLF           = CR LF
+
+
+
+Leach & Newman              Standards Track                    [Page 23]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+
+   All linear white space, including folding, has the same semantics as
+   SP. A recipient MAY replace any linear white space with a single SP
+   before interpreting the field value or forwarding the message
+   downstream.
+
+       LWS            = [CRLF] 1*( SP | HT )
+
+   The TEXT rule is only used for descriptive field contents and values
+   that are not intended to be interpreted by the message parser. Words
+   of *TEXT MAY contain characters from character sets other than
+   ISO-8859-1 [ISO 8859] only when encoded according to the rules of RFC
+   2047 [RFC 2047].
+
+       TEXT           = <any OCTET except CTLs,
+                        but including LWS>
+
+   A CRLF is allowed in the definition of TEXT only as part of a header
+   field continuation. It is expected that the folding LWS will be
+   replaced with a single SP before interpretation of the TEXT value.
+
+   Hexadecimal numeric characters are used in several protocol elements.
+
+       HEX            = "A" | "B" | "C" | "D" | "E" | "F"
+                      | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT
+
+   Many HTTP/1.1 header field values consist of words separated by LWS
+   or special characters. These special characters MUST be in a quoted
+   string to be used within a parameter value.
+
+       token          = 1*<any CHAR except CTLs or separators>
+       separators     = "(" | ")" | "<" | ">" | "@"
+                      | "," | ";" | ":" | "\" | <">
+                      | "/" | "[" | "]" | "?" | "="
+                      | "{" | "}" | SP | HT
+
+   A string of text is parsed as a single word if it is quoted using
+   double-quote marks.
+
+      quoted-string  = ( <"> qdstr-val <"> )
+      qdstr-val      = *( qdtext | quoted-pair )
+      qdtext         = <any TEXT except <">>
+
+   Note that LWS is NOT implicit between the double-quote marks (<">)
+   surrounding a qdstr-val and the qdstr-val; any LWS will be considered
+   part of the qdstr-val.  This is also the case for quotation marks
+   surrounding any other construct.
+
+
+
+
+Leach & Newman              Standards Track                    [Page 24]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   The backslash character ("\") MAY be used as a single-character
+   quoting mechanism only within qdstr-val and comment constructs.
+
+       quoted-pair    = "\" CHAR
+
+   The value of this construct is CHAR. Note that an effect of this rule
+   is that backslash must be quoted.
+
+8  Sample Code
+
+   The sample implementation in [Digest] also applies to DIGEST-MD5.
+
+   The following code implements the conversion from UTF-8 to 8859-1 if
+   necessary.
+
+    /* if the string is entirely in the 8859-1 subset of UTF-8, then
+     * translate to 8859-1 prior to MD5
+     */
+    void MD5_UTF8_8859_1(MD5_CTX *ctx, const unsigned char *base,
+        int len)
+    {
+        const unsigned char *scan, *end;
+        unsigned char cbuf;
+
+        end = base + len;
+        for (scan = base; scan < end; ++scan) {
+            if (*scan > 0xC3) break; /* abort if outside 8859-1 */
+            if (*scan >= 0xC0 && *scan <= 0xC3) {
+                if (++scan == end || *scan < 0x80 || *scan > 0xBF)
+                    break;
+            }
+        }
+        /* if we found a character outside 8859-1, don't alter string
+         */
+        if (scan < end) {
+            MD5Update(ctx, base, len);
+            return;
+        }
+
+        /* convert to 8859-1 prior to applying hash
+         */
+        do {
+            for (scan = base; scan < end && *scan < 0xC0; ++scan)
+                ;
+            if (scan != base) MD5Update(ctx, base, scan - base);
+            if (scan + 1 >= end) break;
+            cbuf = ((scan[0] & 0x3) << 6) | (scan[1] & 0x3f);
+            MD5Update(ctx, &cbuf, 1);
+
+
+
+Leach & Newman              Standards Track                    [Page 25]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+            base = scan + 2;
+        } while (base < end);
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Leach & Newman              Standards Track                    [Page 26]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+9  Full Copyright Statement
+
+   Copyright (C) The Internet Society (2000).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Leach & Newman              Standards Track                    [Page 27]
+\f
index a3342c6a58aef038fcbe656e961cf9dfab196cc0..fd255d6cda4e1375eda38ab113c607adbe89c1b9 100644 (file)
@@ -1,5 +1,5 @@
 # $OpenLDAP$
-## Copyright 1998 The OpenLDAP Foundation, All Rights Reserved.
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
 ## COPYING RESTRICTIONS APPLY, See COPYRIGHT file
 ##
 ## include Makefile.in for OpenLDAP
@@ -7,15 +7,12 @@
 all-local: ldap_config.h FORCE
 
 install-local: FORCE
-               -$(MKDIR) -p $(includedir)
-               $(INSTALL) $(INSTALLFLAGS) -m 644 $(srcdir)/lber.h $(includedir)
-               $(INSTALL) $(INSTALLFLAGS) -m 644 lber_types.h $(includedir)
-               $(INSTALL) $(INSTALLFLAGS) -m 644 $(srcdir)/ldap.h $(includedir)
-               $(INSTALL) $(INSTALLFLAGS) -m 644 $(srcdir)/ldap_cdefs.h $(includedir)
-               $(INSTALL) $(INSTALLFLAGS) -m 644 ldap_features.h $(includedir)
-               $(INSTALL) $(INSTALLFLAGS) -m 644 $(srcdir)/ldap_schema.h $(includedir)
-               $(INSTALL) $(INSTALLFLAGS) -m 644 $(srcdir)/disptmpl.h $(includedir)
-               $(INSTALL) $(INSTALLFLAGS) -m 644 $(srcdir)/srchpref.h $(includedir)
+       -$(MKDIR) $(DESTDIR)$(includedir)
+       for header in $(srcdir)/lber.h lber_types.h $(srcdir)/ldap.h \
+         $(srcdir)/ldap_cdefs.h ldap_features.h $(srcdir)/ldap_schema.h \
+         $(srcdir)/disptmpl.h $(srcdir)/srchpref.h; do \
+               $(INSTALL) $(INSTALLFLAGS) -m 644 $$header $(DESTDIR)$(includedir); \
+       done
 
 clean-local: FORCE 
        $(RM) ldap_config.h
index 3d04de6179f9c7841df9e3aaeca6aece0cf23145..3f143363d74f4ad7c873aae63cd92dd1fdc1fc32 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic alloca.h */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
index 6c3a44ed77639592160cbcba9b31de29ec738482..986bf7854827000b2eed3cac82a0f719e6109985 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic assert.h */
 /* $OpenLDAP$ */
 /*
- * Copyright 1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1999-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
@@ -31,8 +31,8 @@
  * create a replacement and hope it works
  */
 
-LDAP_F(void) ber_pvt_assert LDAP_P((
-       const char *file, int line, const char *test ));
+LIBLBER_F (void) ber_pvt_assert LDAP_P(( const char *file, int line,
+                                        const char *test ));
 
 /* Can't use LDAP_STRING(test), that'd expand to "test" */
 #if defined(__STDC__) || defined(__cplusplus)
index 160f0bbc8e1b729a509909690465f8f31dc8a5ab..712ed8b9297271e988e5d0524379db560fd6a450 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic bytes.h */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 
 /* cross compilers should define both AC_INT{2,4}_TYPE in CPPFLAGS */
 
-#if !defined( AC_INT4_TYPE ) || !defined( AC_INT2_TYPE )
+#if !defined( AC_INT4_TYPE ) 
        /* use autoconf defines to provide sized typedefs */
 #      if SIZEOF_LONG == 4
 #              define AC_INT4_TYPE long
 #      elif SIZEOF_INT == 4
 #              define AC_INT4_TYPE int
+#      elif SIZEOF_SHORT == 4
+#              define AC_INT4_TYPE short
 #      else
 #              error "AC_INT4_TYPE?"
 #      endif
+#endif
+
+typedef AC_INT4_TYPE ac_int4;
+typedef signed AC_INT4_TYPE ac_sint4;
+typedef unsigned AC_INT4_TYPE ac_uint4;
 
+#if !defined( AC_INT2_TYPE ) 
 #      if SIZEOF_SHORT == 2
 #              define AC_INT2_TYPE short
 #      elif SIZEOF_INT == 2
 #              define AC_INT2_TYPE int
+#      elif SIZEOF_LONG == 2
+#              define AC_INT2_TYPE long
 #      else
-#              error "AC_INT2_TYPE?"
+/* not used, no error */
+/* #   error "AC_INT2_TYPE?" */
 #      endif
 #endif
     
-typedef AC_INT4_TYPE ac_int4;
-typedef signed AC_INT4_TYPE ac_sint4;
-typedef unsigned AC_INT4_TYPE ac_uint4;
-
+#if defined( AC_INT2_TYPE ) 
 typedef AC_INT2_TYPE ac_int2;
 typedef signed AC_INT2_TYPE ac_sint2;
 typedef unsigned AC_INT2_TYPE ac_uint2;
+#endif
 
 #ifndef BYTE_ORDER
 /* cross compilers should define BYTE_ORDER in CPPFLAGS */
diff --git a/include/ac/crypt.h b/include/ac/crypt.h
new file mode 100644 (file)
index 0000000..c87c7bd
--- /dev/null
@@ -0,0 +1,25 @@
+/* Generic crypt.h */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted only
+ * as authorized by the OpenLDAP Public License.  A copy of this
+ * license is available at http://www.OpenLDAP.org/license.html or
+ * in file LICENSE in the top-level directory of the distribution.
+ */
+
+#ifndef _AC_CRYPT_H
+#define _AC_CRYPT_H
+
+#include <ac/unistd.h>
+
+/* crypt() may be defined in a separate include file */
+#if HAVE_CRYPT_H
+#      include <crypt.h>
+#else
+       extern char *(crypt)();
+#endif
+
+#endif /* _AC_CRYPT_H */
index cfdcd924d79bde724c0da5be3fa87943ceea0d9c..dac50552d9c5290476ed499ee73f7ef6f3905e9e 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic ctype.h */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
index 53f189a5186e91a6c914182d50255f6aa64d1ed4..7942375854bea46e96662d528a6beee219cd5faa 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic dirent.h */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
index 3d26e5e4641a0834abc6dc79009b246799661812..e04c228856d60cdea042e9c1516cab148af41450 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic errno.h */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
@@ -25,8 +25,8 @@
 #      define          sys_errlist     ((char **)0)
 #elif DECL_SYS_ERRLIST 
        /* have sys_errlist but need declaration */
-       extern int      sys_nerr;
-       extern char     *sys_errlist[];
+       LIBC_F (int)      sys_nerr;
+       LIBC_F (char)    *sys_errlist[];
 #endif
 
 #ifdef HAVE_STRERROR
@@ -36,6 +36,4 @@
        ((err) > -1 && (err) < sys_nerr ? sys_errlist[(err)] : "unknown")
 #endif
 
-extern char* strerror_r();
-    
 #endif /* _AC_ERRNO_H */
index a5ffa7abd802dadc1eda1e9e3b57e84c92b8a21f..2227977182f0cf86b3cff986d6e27df754ddce8a 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic krb.h */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
  * in file LICENSE in the top-level directory of the distribution.
  */
 
+/* Kerberos IV */
+
 #ifndef _AC_KRB_H
 #define _AC_KRB_H
 
-#if defined( HAVE_KERBEROS )
+#if defined( HAVE_KRB4 )
 
 #if defined( HAVE_KERBEROSIV_KRB_H )
 #include <kerberosIV/krb.h>
@@ -27,5 +29,5 @@
 #include <des.h>
 #endif
 
-#endif /* HAVE_KERBEROS */
+#endif /* HAVE_KRB4 */
 #endif /* _AC_KRB_H */
diff --git a/include/ac/krb5.h b/include/ac/krb5.h
new file mode 100644 (file)
index 0000000..33d9b73
--- /dev/null
@@ -0,0 +1,22 @@
+/* Generic krb.h */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted only
+ * as authorized by the OpenLDAP Public License.  A copy of this
+ * license is available at http://www.OpenLDAP.org/license.html or
+ * in file LICENSE in the top-level directory of the distribution.
+ */
+
+/* Kerberos V */
+
+#ifndef _AC_KRB5_H
+#define _AC_KRB5_H
+
+#if defined( HAVE_KRB5 )
+#include <krb5.h>
+#endif /* HAVE_KRB5 */
+
+#endif /* _AC_KRB5_H */
diff --git a/include/ac/param.h b/include/ac/param.h
new file mode 100644 (file)
index 0000000..ab2970c
--- /dev/null
@@ -0,0 +1,26 @@
+/* Generic param.h */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1999-2000 The OpenLDAP Foundation, Redwood City, California, USA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted only
+ * as authorized by the OpenLDAP Public License.  A copy of this
+ * license is available at http://www.OpenLDAP.org/license.html or
+ * in file LICENSE in the top-level directory of the distribution.
+ */
+
+#ifndef _AC_PARAM_H
+#define _AC_PARAM_H
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifndef MAXPATHLEN
+#      ifdef _MAX_PATH
+#              define MAXPATHLEN       _MAX_PATH
+#      endif
+#endif
+
+#endif /* _AC_PARAM_H */
index 897f7f5fd13023017fe4e9851f5bf4b4c9cd448f..a9a25f1809b62ccd04e3251f88d06f8e8ba43dd8 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic Regex */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
index 5bf1d2f49634a3ac13a43816d58f5eadef73426f..910dc96b151cd8f45af9adc6e179333d7d2f542e 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic setproctitle.h */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 #      include <libutil.h>
 #else
        /* use lutil version */
-       LDAP_F(void) (setproctitle) LDAP_P((const char *fmt, ...)) \
+       LIBLUTIL_F (void) (setproctitle) LDAP_P((const char *fmt, ...)) \
                                    LDAP_GCCATTR((format(printf, 1, 2)));
-       LDAP_F(int) Argc;
-       LDAP_F(char) **Argv;
+       LIBLUTIL_F (int) Argc;
+       LIBLUTIL_F (char) **Argv;
 #endif
 
 #endif /* LDAP_PROCTITLE */
index 73f5d480920375a10e45b7a14b4acf44e4c6a95c..4b7a9d120e298b799e9eedf38f487dce36ce9d66 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic signal.h */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 #undef LDAP_SIGUSR1
 #undef LDAP_SIGUSR2
 
-#      ifndef HAVE_LINUX_THREADS
+#      if defined(WINNT) || defined(_WINNT) || defined(_WIN32)
+#              define LDAP_SIGUSR1     SIGILL
+#              define LDAP_SIGUSR2     SIGTERM
+
+#      elif !defined(HAVE_LINUX_THREADS)
 #              define LDAP_SIGUSR1     SIGUSR1
 #              define LDAP_SIGUSR2     SIGUSR2
 
index fc1d533b6f6365bf62c7138e6d61c2748934e6ca..5a141e0f0c5bca9fceef524da46df1235edae62e 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic socket.h */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
 
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
 #endif
@@ -86,9 +90,9 @@
 #undef sock_errno
 #undef sock_errstr
 #define        sock_errno()    WSAGetLastError()
-#define        sock_errstr(e)  WSAGetErrorString(e)
+#define        sock_errstr(e)  ber_pvt_wsa_err2string(e)
 
-extern char* WSAGetErrorString LDAP_P((int));
+LIBLBER_F (char *) ber_pvt_wsa_err2string LDAP_P((int));
 
 #elif MACOS
 #      define tcp_close( s )           tcpclose( s )
@@ -110,6 +114,11 @@ extern char* WSAGetErrorString LDAP_P((int));
 #elif HAVE_CLOSESOCKET
 #      define tcp_close( s )           closesocket( s )
 
+#      ifdef __BEOS__
+#              define tcp_read( s, buf, len )  recv( s, buf, len, 0 )
+#              define tcp_write( s, buf, len ) send( s, buf, len, 0 )
+#      endif
+
 #else
 #      define tcp_close( s )           close( s )
 #      define tcp_read( s, buf, len)   read( s, buf, len )
@@ -139,31 +148,19 @@ extern char* WSAGetErrorString LDAP_P((int));
 #if !defined( HAVE_INET_ATON ) && !defined( inet_aton )
 #define inet_aton ldap_pvt_inet_aton
 struct in_addr;
-int ldap_pvt_inet_aton LDAP_P(( const char *, struct in_addr * ));
+LIBLDAP_F (int) ldap_pvt_inet_aton LDAP_P(( const char *, struct in_addr * ));
 #endif
 
 #if    defined(__WIN32) && defined(_ALPHA)
 /* NT on Alpha is hosed. */
-#define AC_HTONL( l ) \
-        ((((l)&0xff)<<24) + (((l)&0xff00)<<8) + \
-         (((l)&0xff0000)>>8) + (((l)&0xff000000)>>24))
-#define AC_NTOHL(l) AC_HTONL(l)
-
-#elif defined(__alpha) && !defined(VMS)
-/*
- * htonl and ntohl on the DEC Alpha under OSF 1 seem to only swap the
- * lower-order 32-bits of a (64-bit) long, so we define correct versions
- * here.
- */ 
-#define AC_HTONL( l )  (((long)htonl( (l) & 0x00000000FFFFFFFF )) << 32 \
-       | htonl( ( (l) & 0xFFFFFFFF00000000 ) >> 32 ))
-
-#define AC_NTOHL( l ) (((long)ntohl( (l) & 0x00000000FFFFFFFF )) << 32 \
-       | ntohl( ( (l) & 0xFFFFFFFF00000000 ) >> 32 ))
+#      define AC_HTONL( l ) \
+        ((((l)&0xffU)<<24) + (((l)&0xff00U)<<8) + \
+         (((l)&0xff0000U)>>8) + (((l)&0xff000000U)>>24))
+#      define AC_NTOHL(l) AC_HTONL(l)
 
 #else
-#define AC_HTONL( l ) htonl( l )
-#define AC_NTOHL( l ) ntohl( l )
+#      define AC_HTONL( l ) htonl( l )
+#      define AC_NTOHL( l ) ntohl( l )
 #endif
 
 /* htons()/ntohs() may be broken much like htonl()/ntohl() */
index c7b2d46c87f8f9438d7475fd47b149db908ef5cf..4d4223fd545d41923d62be778e35230791b87fb8 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic stdarg.h */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
index e8037ed496019940a72cb8899bd1a4a0f279ba1f..0537904dd6a8b156986e88c1f963df19f5b07288 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic stdlib.h */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
index 980511d3d0d5b63ac15190d0ac090ae7ae5f360c..bb1c10b836598cfa772eab64194b52da5c95c892 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic string.h */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 #endif
 
 /* use ldap_pvt_strtok instead of strtok or strtok_r! */
-LDAP_F(char *) ldap_pvt_strtok LDAP_P((
-       char *str, const char *delim, char **pos ));
-
-LDAP_F(char *) ldap_pvt_strdup LDAP_P((
-       const char * s ));
+LIBLDAP_F(char *) ldap_pvt_strtok LDAP_P(( char *str, const char *delim,
+                                          char **pos ));
 
 #ifndef HAVE_STRDUP
        /* strdup() is missing, declare our own version */
 #      undef strdup
-#      define strdup(s) ldap_pvt_strdup(s)
+#      define strdup(s) ber_strdup(s)
 #else
        /* some systems fail to declare strdup */
-       extern char *(strdup)();
+       LIBC_F(char *) (strdup)();
 #endif
 
 /*
  * some systems fail to declare strcasecmp() and strncasecmp()
  * we need them declared so we can obtain pointers to them
  */
-extern int (strcasecmp)();
-extern int (strncasecmp)();
+
+/* In Mingw32, strcasecmp is not in the C library, so we don't LIBC_F it */
+int (strcasecmp)();
+int (strncasecmp)();
 
 #ifndef SAFEMEMCPY
 #      if defined( HAVE_MEMMOVE )
index 8d5df5ffdf88ed5065b74365f7ff4e6d84966b63..ede4da70aa1a23b19171a6939c321d1567fdd3c3 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic sysexits */
 /* $OpenLDAP$ */
 /*
- * Copyright 1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1999-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
index 4015fd96a81d7aca653f79cf58edca6d7b215b59..2602a407cf662661d5c5994e8340798975214709 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic syslog.h */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
index 5b548a499464992ab6a9d87e71d4da076afdfebd..c1e15494a6e4dd82670f5b0da0d23ce88e0e7040 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic termios.h */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
index 9f8d3038687f250dbbb2602eebf32c4b5529fd37..b61b9f374ca3a4ba570e2bcce58562bc985289ec 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic time.h */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
index 7c2fdfc533630d9877911bb1585718c954e42431..b7710dcd75b8e43e164c4f9d2ff60e7e9fb84863 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic unistd.h */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 #      include <unistd.h>
 #endif
 
-/* crypt() may be defined in a separate include file */
-#if HAVE_CRYPT_H
-#      include <crypt.h>
-#else
-       extern char *(crypt)();
+#if HAVE_PROCESS_H
+#      include <process.h>
 #endif
 
-#ifndef HAVE_GETPASS
-LDAP_F(char*)(getpass) LDAP_P((const char *getpass));
+/* note: callers of crypt(3) should include <ac/crypt.h> */
+
+#if defined(HAVE_GETPASSPHRASE)
+LIBC_F(char*)(getpassphrase)();
+
+#elif defined(HAVE_GETPASS)
+#define getpassphrase(p) getpass(p)
+LIBC_F(char*)(getpass)();
+
 #else
-LDAP_F(char*)(getpass)();
+#define NEED_GETPASSPHRASE 1
+#define getpassphrase(p) lutil_getpass(p)
+LIBLUTIL_F(char*)(lutil_getpass) LDAP_P((const char *getpass));
 #endif
 
 /* getopt() defines may be in separate include file */
@@ -44,17 +50,13 @@ LDAP_F(char*)(getpass)();
 
 #else
        /* assume we need to declare these externs */
-       extern char *optarg;
-       extern int optind, opterr, optopt;
+       LIBC_F (char *) optarg;
+       LIBC_F (int) optind, opterr, optopt;
 #endif
 
 #ifndef HAVE_TEMPNAM
-       LDAP_F(char *)(tempnam) LDAP_P((
-               const char *tmpdir,
-               const char *prefix));
-#endif
-#ifndef HAVE_MKTEMP
-       LDAP_F(char *)(mktemp) LDAP_P((char *));
+       LIBLUTIL_F(char *)(tempnam) LDAP_P(( const char *tmpdir,
+                                            const char *prefix));
 #endif
 
 /* use lutil file locking */
index 12bb7d4a6a0381228bbcd645e05a0a2240869aee..6ec659b3aca50bb026a6e0865a7ee6c70d329d38 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic wait.h */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
index ae3b44ab65f2da2656bf0d193c8fff89a2682d3b..7ecb3affe55f79536eb2e3a0fe85d2f6689559a6 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
@@ -61,39 +61,39 @@ typedef int         (*AVL_CMP) LDAP_P((const void*, const void*));
 typedef int            (*AVL_DUP) LDAP_P((void*, void*));
 typedef void   (*AVL_FREE) LDAP_P((void*));
 
-LDAP_F( int )
+LIBAVL_F( int )
 avl_free LDAP_P(( Avlnode *root, AVL_FREE dfree ));
 
-LDAP_F( int )
+LIBAVL_F( int )
 avl_insert LDAP_P((Avlnode **, void*, AVL_CMP, AVL_DUP));
 
-LDAP_F( void* )
+LIBAVL_F( void* )
 avl_delete LDAP_P((Avlnode **, void*, AVL_CMP));
 
-LDAP_F( void* )
+LIBAVL_F( void* )
 avl_find LDAP_P((Avlnode *, const void*, AVL_CMP));
 
-LDAP_F( void* )
+LIBAVL_F( void* )
 avl_find_lin LDAP_P((Avlnode *, const void*, AVL_CMP));
 
 #ifdef AVL_NONREENTRANT
-LDAP_F( void* )
+LIBAVL_F( void* )
 avl_getfirst LDAP_P((Avlnode *));
 
-LDAP_F( void* )
+LIBAVL_F( void* )
 avl_getnext LDAP_P((void));
 #endif
 
-LDAP_F( int )
+LIBAVL_F( int )
 avl_dup_error LDAP_P((void*, void*));
 
-LDAP_F( int )
+LIBAVL_F( int )
 avl_dup_ok LDAP_P((void*, void*));
 
-LDAP_F( int )
+LIBAVL_F( int )
 avl_apply LDAP_P((Avlnode *, AVL_APPLY, void*, int, int));
 
-LDAP_F( int )
+LIBAVL_F( int )
 avl_prefixapply LDAP_P((Avlnode *, void*, AVL_CMP, void*, AVL_CMP, void*, int));
 
 /* apply traversal types */
index ba6f4bd98258bd8c761c26c213be256eb041ae73..c99ddb240baaa2e5ba99cdaa213f452feef1f0d8 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
@@ -225,88 +225,88 @@ struct ldap_disptmpl {
 typedef int (*ldap_writeptype) LDAP_P((
        void *writeparm, char *p, ber_len_t len ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_init_templates LDAP_P(( char *file, struct ldap_disptmpl **tmpllistp ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_init_templates_buf LDAP_P(( char *buf,
        ber_len_t buflen,
        struct ldap_disptmpl **tmpllistp ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_free_templates LDAP_P(( struct ldap_disptmpl *tmpllist ));
 
-LDAP_F( struct ldap_disptmpl * )
+LIBLDAP_F( struct ldap_disptmpl * )
 ldap_first_disptmpl LDAP_P(( struct ldap_disptmpl *tmpllist ));
 
-LDAP_F( struct ldap_disptmpl * )
+LIBLDAP_F( struct ldap_disptmpl * )
 ldap_next_disptmpl LDAP_P(( struct ldap_disptmpl *tmpllist,
        struct ldap_disptmpl *tmpl ));
 
-LDAP_F( struct ldap_disptmpl * )
+LIBLDAP_F( struct ldap_disptmpl * )
 ldap_name2template LDAP_P(( char *name,
        struct ldap_disptmpl *tmpllist ));
 
-LDAP_F( struct ldap_disptmpl * )
+LIBLDAP_F( struct ldap_disptmpl * )
 ldap_oc2template LDAP_P(( char **oclist,
        struct ldap_disptmpl *tmpllist ));
 
-LDAP_F( char ** )
+LIBLDAP_F( char ** )
 ldap_tmplattrs LDAP_P(( struct ldap_disptmpl *tmpl,
        char **includeattrs,
        int exclude,
        unsigned long syntaxmask ));
 
-LDAP_F( struct ldap_tmplitem * )
+LIBLDAP_F( struct ldap_tmplitem * )
 ldap_first_tmplrow LDAP_P(( struct ldap_disptmpl *tmpl ));
 
-LDAP_F( struct ldap_tmplitem * )
+LIBLDAP_F( struct ldap_tmplitem * )
 ldap_next_tmplrow LDAP_P(( struct ldap_disptmpl *tmpl,
        struct ldap_tmplitem *row ));
 
-LDAP_F( struct ldap_tmplitem * )
+LIBLDAP_F( struct ldap_tmplitem * )
 ldap_first_tmplcol LDAP_P(( struct ldap_disptmpl *tmpl,
        struct ldap_tmplitem *row ));
 
-LDAP_F( struct ldap_tmplitem * )
+LIBLDAP_F( struct ldap_tmplitem * )
 ldap_next_tmplcol LDAP_P(( struct ldap_disptmpl *tmpl,
        struct ldap_tmplitem *row,
        struct ldap_tmplitem *col ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_entry2text LDAP_P(( LDAP *ld,
        char *buf, LDAPMessage *entry,
        struct ldap_disptmpl *tmpl, char **defattrs, char ***defvals,
        ldap_writeptype writeproc, void *writeparm, char *eol, int rdncount,
        unsigned long opts ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_vals2text LDAP_P(( LDAP *ld,
        char *buf, char **vals, char *label, int labelwidth,
        unsigned long syntaxid, ldap_writeptype writeproc, void *writeparm,
        char *eol, int rdncount ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_entry2text_search LDAP_P(( LDAP *ld,
        char *dn, char *base, LDAPMessage *entry,
        struct ldap_disptmpl *tmpllist, char **defattrs, char ***defvals,
        ldap_writeptype writeproc, void *writeparm, char *eol, int rdncount,
        unsigned long opts ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_entry2html LDAP_P(( LDAP *ld,
        char *buf, LDAPMessage *entry,
        struct ldap_disptmpl *tmpl, char **defattrs, char ***defvals,
        ldap_writeptype writeproc, void *writeparm, char *eol, int rdncount,
        unsigned long opts, char *urlprefix, char *base ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_vals2html LDAP_P(( LDAP *ld,
        char *buf, char **vals, char *label, int labelwidth,
        unsigned long syntaxid, ldap_writeptype writeproc, void *writeparm,
        char *eol, int rdncount, char *urlprefix ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_entry2html_search LDAP_P(( LDAP
        *ld, char *dn, char *base, LDAPMessage *entry,
        struct ldap_disptmpl *tmpllist, char **defattrs, char ***defvals,
index 14b2a2f5b028c8b077c68f23f5abad3129d106db..ca23e4b7764077b599136a024475636d163423df 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 
 LDAP_BEGIN_DECL
 
-extern char *optarg;
-extern int optind, opterr, optopt;
+/* change symbols to avoid clashing */
+#define optarg lutil_optarg
+#define optind lutil_optind
+#define opterr lutil_opterr
+#define optopt lutil_optopt
+#define getopt lutil_getopt
 
-LDAP_F( int )
-getopt LDAP_P((
-       int,
-       char * const [],
-       const char *));
+LIBLUTIL_F (char *) optarg;
+LIBLUTIL_F (int) optind, opterr, optopt;
+
+LIBLUTIL_F (int) getopt LDAP_P(( int, char * const [], const char *));
 
 LDAP_END_DECL
 
index 229e97e55c7046a83f7825075b2c60850a095d59..13551e37a6862f8b1e8e34005556fc19543e3713 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 #ifndef _LBER_H
 #define _LBER_H
 
-#include <ldap_cdefs.h>
 #include <lber_types.h>
 
 LDAP_BEGIN_DECL
 
-/* boolean, enumerations, and integers */
-typedef LBER_INT_T ber_int_t;
-
-/* signed and unsigned versions */
-typedef signed LBER_INT_T ber_sint_t;
-typedef unsigned LBER_INT_T ber_uint_t;
-
-/* tags */
-typedef LBER_TAG_T ber_tag_t;
-
-/* "socket" descriptors */
-typedef LBER_SOCKET_T ber_socket_t;
-
-/* lengths */
-typedef unsigned LBER_LEN_T ber_len_t;
-
-/* signed lengths */
-typedef LBER_LEN_T ber_slen_t;
-
-
 /* Overview of LBER tag construction
  *
  *     Bits
@@ -66,62 +45,65 @@ typedef LBER_LEN_T ber_slen_t;
  */
 
 /* BER classes and mask */
-#define LBER_CLASS_UNIVERSAL   (ber_tag_t) 0x00U
-#define LBER_CLASS_APPLICATION (ber_tag_t) 0x40U
-#define LBER_CLASS_CONTEXT     (ber_tag_t) 0x80U
-#define LBER_CLASS_PRIVATE     (ber_tag_t) 0xc0U
-#define LBER_CLASS_MASK                (ber_tag_t) 0xc0U
+#define LBER_CLASS_UNIVERSAL   ((ber_tag_t) 0x00U)
+#define LBER_CLASS_APPLICATION ((ber_tag_t) 0x40U)
+#define LBER_CLASS_CONTEXT             ((ber_tag_t) 0x80U)
+#define LBER_CLASS_PRIVATE             ((ber_tag_t) 0xc0U)
+#define LBER_CLASS_MASK                        ((ber_tag_t) 0xc0U)
 
 /* BER encoding type and mask */
-#define LBER_PRIMITIVE         (ber_tag_t) 0x00U
-#define LBER_CONSTRUCTED       (ber_tag_t) 0x20U
-#define LBER_ENCODING_MASK     (ber_tag_t) 0x20U
+#define LBER_PRIMITIVE                 ((ber_tag_t) 0x00U)
+#define LBER_CONSTRUCTED               ((ber_tag_t) 0x20U)
+#define LBER_ENCODING_MASK             ((ber_tag_t) 0x20U)
 
-#define LBER_BIG_TAG_MASK      (ber_tag_t) 0x1fU
-#define LBER_MORE_TAG_MASK     (ber_tag_t) 0x80U
+#define LBER_BIG_TAG_MASK              ((ber_tag_t) 0x1fU)
+#define LBER_MORE_TAG_MASK             ((ber_tag_t) 0x80U)
 
 /*
  * Note that LBER_ERROR and LBER_DEFAULT are values that can never appear
  * as valid BER tags, and so it is safe to use them to report errors.  In
  * fact, any tag for which the following is true is invalid:
  */
-#define LBER_INVALID(t)     (((t) & 0x080) && (((t) & (ber_tag_t) ~ 0x0FF))
-#define LBER_ERROR                     ((ber_tag_t) ~ 0x0)
-#define LBER_DEFAULT           ((ber_tag_t) ~ 0x0)
+#define LBER_INVALID(t)     (((t) & (ber_tag_t) 0x080UL) \
+       && (((t) & (ber_tag_t) ~ 0x0FF))
+
+#define LBER_ERROR                     ((ber_tag_t) -1)
+#define LBER_DEFAULT           ((ber_tag_t) -1)
 
 /* general BER types we know about */
-#define LBER_BOOLEAN           (ber_tag_t) 0x01UL
-#define LBER_INTEGER           (ber_tag_t) 0x02UL
-#define LBER_BITSTRING         (ber_tag_t) 0x03UL
-#define LBER_OCTETSTRING       (ber_tag_t) 0x04UL
-#define LBER_NULL                      (ber_tag_t) 0x05UL
-#define LBER_ENUMERATED                (ber_tag_t) 0x0aUL
-#define LBER_SEQUENCE          (ber_tag_t) 0x30UL      /* constructed */
-#define LBER_SET                       (ber_tag_t) 0x31UL      /* constructed */
-
-#define OLD_LBER_SEQUENCE      (ber_tag_t) 0x10UL      /* w/o constructed bit - broken */
-#define OLD_LBER_SET           (ber_tag_t) 0x11UL      /* w/o constructed bit - broken */
-
-typedef int (*BERTranslateProc) LDAP_P((
-       char **bufp,
-       ber_len_t *buflenp,
-       int free_input ));
+#define LBER_BOOLEAN           ((ber_tag_t) 0x01UL)
+#define LBER_INTEGER           ((ber_tag_t) 0x02UL)
+#define LBER_BITSTRING         ((ber_tag_t) 0x03UL)
+#define LBER_OCTETSTRING       ((ber_tag_t) 0x04UL)
+#define LBER_NULL                      ((ber_tag_t) 0x05UL)
+#define LBER_ENUMERATED                ((ber_tag_t) 0x0aUL)
+#define LBER_SEQUENCE          ((ber_tag_t) 0x30UL)    /* constructed */
+#define LBER_SET                       ((ber_tag_t) 0x31UL)    /* constructed */
 
 /* LBER BerElement options */
 #define LBER_USE_DER           0x01
 #define LBER_USE_INDEFINITE_LEN        0x02
-#define LBER_TRANSLATE_STRINGS 0x04
 
 /* get/set options for BerElement */
-#define LBER_OPT_BER_OPTIONS   0x01
-#define LBER_OPT_BER_DEBUG             0x02
+#define LBER_OPT_BER_OPTIONS                   0x01
+#define LBER_OPT_BER_DEBUG                             0x02
+#define LBER_OPT_BER_REMAINING_BYTES   0x03
+#define LBER_OPT_BER_TOTAL_BYTES               0x04
+#define LBER_OPT_BER_BYTES_TO_WRITE            0x05
 
 #define LBER_OPT_DEBUG_LEVEL   LBER_OPT_BER_DEBUG
+#define LBER_OPT_REMAINING_BYTES       LBER_OPT_BER_REMAINING_BYTES
+#define LBER_OPT_TOTAL_BYTES           LBER_OPT_BER_TOTAL_BYTES
+#define LBER_OPT_BYTES_TO_WRITE                LBER_OPT_BER_BYTES_TO_WRITE
 
 #define LBER_OPT_LOG_PRINT_FN  0x8001
 #define LBER_OPT_MEMORY_FNS            0x8002
+#define LBER_OPT_ERROR_FN              0x8003
+#define LBER_OPT_LOG_PRINT_FILE                0x8004
+
+typedef int* (*BER_ERRNO_FN) LDAP_P(( void ));
 
-typedef void (*BER_LOG_PRINT_FN) LDAP_P(( char *buf ));
+typedef void (*BER_LOG_PRINT_FN) LDAP_P(( LDAP_CONST char *buf ));
 
 typedef void* (*BER_MEMALLOC_FN)       LDAP_P(( ber_len_t size ));
 typedef void* (*BER_MEMCALLOC_FN)      LDAP_P(( ber_len_t n, ber_len_t size ));
@@ -135,11 +117,26 @@ typedef struct lber_memory_fns {
        BER_MEMFREE_FN bmf_free;
 } BerMemoryFunctions;
 
-/* LBER Sockbuf options */ 
-#define LBER_TO_FILE           0x01    /* to a file referenced by sb_fd   */
-#define LBER_TO_FILE_ONLY      0x02    /* only write to file, not network */
-#define LBER_MAX_INCOMING_SIZE 0x04    /* impose limit on incoming stuff  */
-#define LBER_NO_READ_AHEAD     0x08    /* read only as much as requested  */
+/* LBER Sockbuf_IO options */ 
+#define LBER_SB_OPT_GET_FD             1
+#define LBER_SB_OPT_SET_FD             2
+#define LBER_SB_OPT_HAS_IO             3
+#define LBER_SB_OPT_SET_NONBLOCK       4
+#define LBER_SB_OPT_UDP_GET_SRC                5
+#define LBER_SB_OPT_UDP_SET_DST                6
+#define LBER_SB_OPT_GET_SSL            7
+#define LBER_SB_OPT_DATA_READY         8
+#define LBER_SB_OPT_SET_READAHEAD      9
+#define LBER_SB_OPT_DRAIN              10
+#define LBER_SB_OPT_NEEDS_READ         11
+#define LBER_SB_OPT_NEEDS_WRITE                12
+/* Largest option used by the library */
+#define LBER_SB_OPT_OPT_MAX            12
+
+/* LBER IO operations stacking levels */
+#define LBER_SBIOD_LEVEL_PROVIDER      10
+#define LBER_SBIOD_LEVEL_TRANSPORT     20
+#define LBER_SBIOD_LEVEL_APPLICATION   30
 
 /* get/set options for Sockbuf */
 #define LBER_OPT_SOCKBUF_DESC          0x1000
@@ -150,37 +147,76 @@ typedef struct lber_memory_fns {
 #define LBER_OPT_ON            ((void *) 1)
 #define LBER_OPT_OFF   ((void *) 0)
 
-#define LBER_OPT_SUCCESS       0
+#define LBER_OPT_SUCCESS       (0)
 #define LBER_OPT_ERROR         (-1)
 
 typedef struct berelement BerElement;
 typedef struct sockbuf Sockbuf;
 typedef struct seqorset Seqorset;
 
+typedef struct sockbuf_io Sockbuf_IO;
+
+/* Structure for LBER IO operarion descriptor */
+typedef struct sockbuf_io_desc {
+       int                     sbiod_level;
+       Sockbuf                 *sbiod_sb;
+       Sockbuf_IO              *sbiod_io;
+       void                    *sbiod_pvt;
+       struct sockbuf_io_desc  *sbiod_next;
+} Sockbuf_IO_Desc;
+
+/* Structure for LBER IO operation functions */
+struct sockbuf_io {
+       int (*sbi_setup)( Sockbuf_IO_Desc *sbiod, void *arg );
+       int (*sbi_remove)( Sockbuf_IO_Desc *sbiod );
+       int (*sbi_ctrl)( Sockbuf_IO_Desc *sbiod, int opt, void *arg);
+       
+       ber_slen_t (*sbi_read)( Sockbuf_IO_Desc *sbiod, void *buf,
+               ber_len_t len );
+       ber_slen_t (*sbi_write)( Sockbuf_IO_Desc *sbiod, void *buf,
+               ber_len_t len );
+       
+       int (*sbi_close)( Sockbuf_IO_Desc *sbiod );
+};
+
+/* Helper macros for LBER IO functions */
+#define LBER_SBIOD_READ_NEXT( sbiod, buf, len ) \
+       ( (sbiod)->sbiod_next->sbiod_io->sbi_read( (sbiod)->sbiod_next, \
+               buf, len ) )
+#define LBER_SBIOD_WRITE_NEXT( sbiod, buf, len ) \
+       ( (sbiod)->sbiod_next->sbiod_io->sbi_write( (sbiod)->sbiod_next, \
+               buf, len ) )
+#define LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg ) \
+       ( (sbiod)->sbiod_next ? \
+               ( (sbiod)->sbiod_next->sbiod_io->sbi_ctrl( \
+               (sbiod)->sbiod_next, opt, arg ) ) : 0 )
+
 /* structure for returning a sequence of octet strings + length */
 typedef struct berval {
        ber_len_t       bv_len;
        char            *bv_val;
 } BerValue;
 
+/* this should be moved to lber-int.h */
+
 /*
  * in bprint.c:
  */
-LDAP_F( void )
-ber_print_error LDAP_P((
+LIBLBER_F( void )
+ber_error_print LDAP_P((
        LDAP_CONST char *data ));
 
-LDAP_F( void )
+LIBLBER_F( void )
 ber_bprint LDAP_P((
        LDAP_CONST char *data, ber_len_t len ));
 
-LDAP_F( void )
+LIBLBER_F( void )
 ber_dump LDAP_P((
-       LDAP_CONST BerElement *ber, int inout ));
+       BerElement *ber, int inout ));
 
-LDAP_F( void )
+LIBLBER_F( void )
 ber_sos_dump LDAP_P((
-       LDAP_CONST Seqorset *sos ));
+       Seqorset *sos ));
 
 
 /*
@@ -191,80 +227,79 @@ typedef int (*BERDecodeCallback) LDAP_P((
        void *data,
        int mode ));
 
-LDAP_F( ber_tag_t )
+LIBLBER_F( ber_tag_t )
 ber_get_tag LDAP_P((
        BerElement *ber ));
 
-LDAP_F( ber_tag_t )
+LIBLBER_F( ber_tag_t )
 ber_skip_tag LDAP_P((
        BerElement *ber,
        ber_len_t *len ));
 
-LDAP_F( ber_tag_t )
+LIBLBER_F( ber_tag_t )
 ber_peek_tag LDAP_P((
-       LDAP_CONST BerElement *ber,
+       BerElement *ber,
        ber_len_t *len ));
 
-LDAP_F( ber_tag_t )
+LIBLBER_F( ber_tag_t )
 ber_get_int LDAP_P((
        BerElement *ber,
        ber_int_t *num ));
 
-LDAP_F( ber_tag_t )
+LIBLBER_F( ber_tag_t )
+ber_get_enum LDAP_P((
+       BerElement *ber,
+       ber_int_t *num ));
+
+LIBLBER_F( ber_tag_t )
 ber_get_stringb LDAP_P((
        BerElement *ber,
        char *buf,
        ber_len_t *len ));
 
-LDAP_F( ber_tag_t )
+LIBLBER_F( ber_tag_t )
 ber_get_stringa LDAP_P((
        BerElement *ber,
        char **buf ));
 
-LDAP_F( ber_tag_t )
+LIBLBER_F( ber_tag_t )
 ber_get_stringal LDAP_P((
        BerElement *ber,
        struct berval **bv ));
 
-LDAP_F( ber_tag_t )
+LIBLBER_F( ber_tag_t )
 ber_get_bitstringa LDAP_P((
        BerElement *ber,
        char **buf,
        ber_len_t *len ));
 
-LDAP_F( ber_tag_t )
+LIBLBER_F( ber_tag_t )
 ber_get_null LDAP_P((
        BerElement *ber ));
 
-LDAP_F( ber_tag_t )
+LIBLBER_F( ber_tag_t )
 ber_get_boolean LDAP_P((
        BerElement *ber,
        ber_int_t *boolval ));
 
-LDAP_F( ber_tag_t )
+LIBLBER_F( ber_tag_t )
 ber_first_element LDAP_P((
        BerElement *ber,
        ber_len_t *len,
        char **last ));
 
-LDAP_F( ber_tag_t )
+LIBLBER_F( ber_tag_t )
 ber_next_element LDAP_P((
        BerElement *ber,
        ber_len_t *len,
-       char *last ));
+       LDAP_CONST char *last ));
 
-LDAP_F( ber_tag_t )
+LIBLBER_F( ber_tag_t )
 ber_scanf LDAP_P((                                                               
        BerElement *ber,
        LDAP_CONST char *fmt,
        ... ));
 
-LDAP_F( void )
-ber_set_string_translators LDAP_P((
-       BerElement *ber,
-       BERTranslateProc encode_proc,
-       BERTranslateProc decode_proc ));
-
 /*
  * in encode.c
  */
@@ -272,74 +307,74 @@ typedef int (*BEREncodeCallback) LDAP_P((
        BerElement *ber,
        void *data ));
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_put_enum LDAP_P((
        BerElement *ber,
        ber_int_t num,
        ber_tag_t tag ));
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_put_int LDAP_P((
        BerElement *ber,
        ber_int_t num,
        ber_tag_t tag ));
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_put_ostring LDAP_P((
        BerElement *ber,
        LDAP_CONST char *str,
        ber_len_t len,
        ber_tag_t tag ));
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_put_berval LDAP_P((
        BerElement *ber,
        LDAP_CONST struct berval *bv,
        ber_tag_t tag ));
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_put_string LDAP_P((
        BerElement *ber,
        LDAP_CONST char *str,
        ber_tag_t tag ));
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_put_bitstring LDAP_P((
        BerElement *ber,
        LDAP_CONST char *str,
        ber_len_t bitlen,
        ber_tag_t tag ));
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_put_null LDAP_P((
        BerElement *ber,
        ber_tag_t tag ));
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_put_boolean LDAP_P((
        BerElement *ber,
        ber_int_t boolval,
        ber_tag_t tag ));
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_start_seq LDAP_P((
        BerElement *ber,
        ber_tag_t tag ));
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_start_set LDAP_P((
        BerElement *ber,
        ber_tag_t tag ));
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_put_seq LDAP_P((
        BerElement *ber ));
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_put_set LDAP_P((
        BerElement *ber ));
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_printf LDAP_P((
        BerElement *ber,
        LDAP_CONST char *fmt,
@@ -350,80 +385,80 @@ ber_printf LDAP_P((
  * in io.c:
  */
 
-LDAP_F( ber_slen_t )
+LIBLBER_F( ber_slen_t )
 ber_read LDAP_P((
        BerElement *ber,
        char *buf,
        ber_len_t len ));
 
-LDAP_F( ber_slen_t )
+LIBLBER_F( ber_slen_t )
 ber_write LDAP_P((
        BerElement *ber,
        LDAP_CONST char *buf,
        ber_len_t len,
        int nosos ));
 
-LDAP_F( void )
+LIBLBER_F( void )
 ber_free LDAP_P((
        BerElement *ber,
        int freebuf ));
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_flush LDAP_P((
        Sockbuf *sb,
        BerElement *ber,
        int freeit ));
 
-LDAP_F( BerElement * )
+LIBLBER_F( BerElement * )
 ber_alloc LDAP_P(( void )); /* DEPRECATED */
 
-LDAP_F( BerElement * )
+LIBLBER_F( BerElement * )
 der_alloc LDAP_P(( void )); /* DEPRECATED */
 
-LDAP_F( BerElement * )
+LIBLBER_F( BerElement * )
 ber_alloc_t LDAP_P((
        int beroptions ));
 
-LDAP_F( BerElement * )
+LIBLBER_F( BerElement * )
 ber_dup LDAP_P((
-       LDAP_CONST BerElement *ber ));
+       BerElement *ber ));
 
-LDAP_F( ber_tag_t )
+LIBLBER_F( ber_tag_t )
 ber_get_next LDAP_P((
        Sockbuf *sb,
        ber_len_t *len,
        BerElement *ber ));
 
-LDAP_F( void )
+LIBLBER_F( void )
 ber_init_w_nullc LDAP_P((
        BerElement *ber,
        int options ));
 
-LDAP_F( void )
+LIBLBER_F( void )
 ber_reset LDAP_P((
        BerElement *ber,
        int was_writing ));
 
-LDAP_F( BerElement * )
+LIBLBER_F( BerElement * )
 ber_init LDAP_P((
        struct berval *bv ));
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_flatten LDAP_P((
-       LDAP_CONST BerElement *ber,
+       BerElement *ber,
        struct berval **bvPtr ));
 
 /*
  * LBER ber accessor functions
  */
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_get_option LDAP_P((
-       LDAP_CONST void *item,
+       void *item,
        int option,
        void *outvalue));
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_set_option LDAP_P((
        void *item,
        int option,
@@ -433,58 +468,103 @@ ber_set_option LDAP_P((
  * LBER sockbuf.c
  */
 
-LDAP_F( Sockbuf * )
-ber_sockbuf_alloc( void );
+LIBLBER_F( Sockbuf *  )
+ber_sockbuf_alloc LDAP_P((
+       void ));
 
-LDAP_F( Sockbuf *  )
-ber_sockbuf_alloc_fd(
-       ber_socket_t fd );
+LIBLBER_F( void )
+ber_sockbuf_free LDAP_P((
+       Sockbuf *sb ));
 
-LDAP_F( void )
-ber_sockbuf_free(
-       Sockbuf *sb );
+LIBLBER_F( int )
+ber_sockbuf_add_io LDAP_P((
+       Sockbuf *sb,
+       Sockbuf_IO *sbio,
+       int layer,
+       void *arg ));
+
+LIBLBER_F( int )
+ber_sockbuf_remove_io LDAP_P((
+       Sockbuf *sb,
+       Sockbuf_IO *sbio,
+       int layer ));
+
+LIBLBER_F( int )
+ber_sockbuf_ctrl LDAP_P((
+       Sockbuf *sb,
+       int opt,
+       void *arg ));
+
+LIBLBER_F( Sockbuf_IO ) ber_sockbuf_io_tcp;
+LIBLBER_F( Sockbuf_IO ) ber_sockbuf_io_udp;
+LIBLBER_F( Sockbuf_IO ) ber_sockbuf_io_readahead;
+LIBLBER_F( Sockbuf_IO ) ber_sockbuf_io_fd;
+LIBLBER_F( Sockbuf_IO ) ber_sockbuf_io_debug;
 
 /*
  * LBER memory.c
  */
-LDAP_F( void * )
+LIBLBER_F( void * )
 ber_memalloc LDAP_P((
        ber_len_t s ));
 
-LDAP_F( void * )
+LIBLBER_F( void * )
 ber_memrealloc LDAP_P((
        void* p,
        ber_len_t s ));
 
-LDAP_F( void * )
+LIBLBER_F( void * )
 ber_memcalloc LDAP_P((
        ber_len_t n,
        ber_len_t s ));
 
-LDAP_F( void )
+LIBLBER_F( void )
 ber_memfree LDAP_P((
        void* p ));
 
-LDAP_F( void )
+LIBLBER_F( void )
 ber_memvfree LDAP_P((
        void** vector ));
 
-LDAP_F( void )
+LIBLBER_F( void )
 ber_bvfree LDAP_P((
        struct berval *bv ));
 
-LDAP_F( void )
+LIBLBER_F( void )
 ber_bvecfree LDAP_P((
        struct berval **bv ));
 
-LDAP_F( struct berval * )
+LIBLBER_F( int )
+ber_bvecadd LDAP_P((
+       struct berval ***bvec,
+       struct berval *bv ));
+
+LIBLBER_F( struct berval * )
 ber_bvdup LDAP_P((
        LDAP_CONST struct berval *bv ));
 
-LDAP_F( char * )
+LIBLBER_F( struct berval * )
+ber_bvstr LDAP_P((
+       LDAP_CONST char * ));
+
+LIBLBER_F( struct berval * )
+ber_bvstrdup LDAP_P((
+       LDAP_CONST char * ));
+
+LIBLBER_F( char * )
 ber_strdup LDAP_P((
        LDAP_CONST char * ));
 
+/*
+ * error.c
+ */
+LIBLBER_F( int * ) ber_errno_addr LDAP_P((void));
+#define ber_errno (*(ber_errno_addr)())
+
+#define LBER_ERROR_NONE                0
+#define LBER_ERROR_PARAM       0x1
+#define LBER_ERROR_MEMORY      0x2
+
 LDAP_END_DECL
 
 #endif /* _LBER_H */
index 7e26591ceab2ff34c16fe90078d6d2a10c96806f..e314205f4781fb096aff0f1516ea97357b3f0b0b 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 
 LDAP_BEGIN_DECL
 
+typedef struct sockbuf_buf {
+       ber_len_t               buf_size;
+       ber_len_t               buf_ptr;
+       ber_len_t               buf_end;
+       char                    *buf_base;
+} Sockbuf_Buf;
+
 /*
  * bprint.c
  */
-LDAP_F( BER_LOG_PRINT_FN ) ber_pvt_log_print;
+LIBLBER_F( BER_LOG_PRINT_FN ) ber_pvt_log_print;
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_pvt_log_printf LDAP_P((
        int errlvl,
        int loglvl,
        const char *fmt,
        ... )) LDAP_GCCATTR((format(printf, 3, 4)));
 
+/*
+ * sockbuf.c
+ */
+LIBLBER_F( ber_slen_t )
+ber_pvt_sb_do_write LDAP_P(( Sockbuf_IO_Desc *sbiod, Sockbuf_Buf *buf_out ));
+
+LIBLBER_F( void )
+ber_pvt_sb_buf_init LDAP_P(( Sockbuf_Buf *buf ));
+
+LIBLBER_F( void )
+ber_pvt_sb_buf_destroy LDAP_P(( Sockbuf_Buf *buf ));
+
+LIBLBER_F( int )
+ber_pvt_sb_grow_buffer LDAP_P(( Sockbuf_Buf *buf, ber_len_t minsize ));
+
+LIBLBER_F( ber_len_t )
+ber_pvt_sb_copy_out LDAP_P(( Sockbuf_Buf *sbb, char *buf, ber_len_t len ));
+
+LIBLBER_F( int )
+ber_pvt_socket_set_nonblock LDAP_P(( ber_socket_t sd, int nb ));
+
 LDAP_END_DECL
 
 #endif
index 6abba8f722d0246d33ef4b53edd609e5cdee8937..46adad9e5cc7524d1f57b8fee57d0fa1a99cc981 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 #ifndef _LBER_TYPES_H
 #define _LBER_TYPES_H
 
-/* LBER boolean, enum, integers - 32 bits or larger*/
+#include <ldap_cdefs.h>
+
+LDAP_BEGIN_DECL
+
+/* LBER boolean, enum, integers (32 bits or larger) */
 #undef LBER_INT_T
 
-/* LBER tags - 32 bits or larger */
+/* LBER tags (32 bits or larger) */
 #undef LBER_TAG_T
 
 /* LBER socket descriptor */
 #undef LBER_SOCKET_T
 
-/* LBER lengths - 32 bits or larger*/
+/* LBER lengths (32 bits or larger) */
 #undef LBER_LEN_T
 
+/* ------------------------------------------------------------ */
+
+/* booleans, enumerations, and integers */
+typedef LBER_INT_T ber_int_t;
+
+/* signed and unsigned versions */
+typedef signed LBER_INT_T ber_sint_t;
+typedef unsigned LBER_INT_T ber_uint_t;
+
+/* tags */
+typedef unsigned LBER_TAG_T ber_tag_t;
+
+/* "socket" descriptors */
+typedef LBER_SOCKET_T ber_socket_t;
+
+/* lengths */
+typedef unsigned LBER_LEN_T ber_len_t;
+
+/* signed lengths */
+typedef signed LBER_LEN_T ber_slen_t;
+
+LDAP_END_DECL
+
 #endif /* _LBER_TYPES_H */
index 884188edcfbe14ccb656605f1b59281e6768ec8f..9b04d5c76eef771f06697b6bdbb51f8c2908fbeb 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
  */
 
 /*
- * LBER types for Windows NT
+ * LBER types for Windows NT (and Win32)
+ * copied by setup.mak to lber_types.h (when confingure is not used).
  */
 
-#ifndef _LBER_TYPES_H_NT
-#define _LBER_TYPES_H_NT
+#ifndef _LBER_TYPES_H
+#define _LBER_TYPES_H
+
+#include <ldap_cdefs.h>
+
+LDAP_BEGIN_DECL
 
 /*
  * NT types:
  *
  *     bitsof(short) == 2
  *     bitsof(int)     == 4
- *     bitsof(long) == 4
+ *     bitsof(long) == 4       (or larger)
  *
  *  typedef unsigned int size_t;
  *     typedef unsigned int SOCKET;
 #define LBER_SOCKET_T  unsigned int
 
 /* LBER lengths - 32 bits or larger*/
-#define LBER_LEN_T             int
+#define LBER_LEN_T             long
+
+/* ------------------------------------------------------------ */
+
+/* booleans, enumerations, and integers */
+typedef LBER_INT_T ber_int_t;
+
+/* signed and unsigned versions */
+typedef signed LBER_INT_T ber_sint_t;
+typedef unsigned LBER_INT_T ber_uint_t;
+
+/* tags */
+typedef unsigned LBER_TAG_T ber_tag_t;
+
+/* "socket" descriptors */
+typedef LBER_SOCKET_T ber_socket_t;
+
+/* lengths */
+typedef unsigned LBER_LEN_T ber_len_t;
+
+/* signed lengths */
+typedef signed LBER_LEN_T ber_slen_t;
+
+LDAP_END_DECL
 
-#endif /* _LBER_TYPES_H_NT */
+#endif /* _LBER_TYPES_H */
index 8dbbd1b1ef673e7bf66171cdc3b50bd004d8ebfa..460d3811778e28d9a7311cab75ddb76ea2f921c2 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
@@ -23,9 +23,7 @@
 #ifndef _LDAP_H
 #define _LDAP_H
 
-#include <ldap_cdefs.h>
-
-/* draft spec requires ldap.h include lber declarations */
+/* pull in lber */
 #include <lber.h>
 
 LDAP_BEGIN_DECL
@@ -43,10 +41,10 @@ LDAP_BEGIN_DECL
  * As such, the number will be above the old RFC but below 
  * whatever number does finally get assigned
  */
-#define LDAP_API_VERSION       2003
+#define LDAP_API_VERSION       2004
 #define LDAP_VENDOR_NAME       "OpenLDAP"
 /* We'll eventually release as 200 */
-#define LDAP_VENDOR_VERSION    192
+#define LDAP_VENDOR_VERSION    19905
 
 /* OpenLDAP API Features */
 #define LDAP_API_FEATURE_X_OPENLDAP LDAP_VENDOR_VERSION
@@ -73,7 +71,7 @@ LDAP_BEGIN_DECL
 #define LDAP_ROOT_DSE                          ""
 #define LDAP_NO_ATTRS                          "1.1"
 #define LDAP_ALL_USER_ATTRIBUTES       "*"
-#define LDAP_ALL_OPERATIONAL_ATTRIBUTES        "+"
+#define LDAP_ALL_OPERATIONAL_ATTRIBUTES        "+" /* OpenLDAP extension */
 
 /*
  * LDAP_OPTions defined by draft-ldapext-ldap-c-api-02
@@ -82,7 +80,7 @@ LDAP_BEGIN_DECL
  * 0x4000 - 0x7fff reserved for private and experimental options
  */
 #define LDAP_OPT_API_INFO                      0x0000
-#define LDAP_OPT_DESC                          0x0001
+#define LDAP_OPT_DESC                          0x0001 /* deprecated */
 #define LDAP_OPT_DEREF                         0x0002
 #define LDAP_OPT_SIZELIMIT                     0x0003
 #define LDAP_OPT_TIMELIMIT                     0x0004
@@ -100,22 +98,21 @@ LDAP_BEGIN_DECL
 #define LDAP_OPT_HOST_NAME                     0x0030
 #define        LDAP_OPT_ERROR_NUMBER           0x0031
 #define LDAP_OPT_ERROR_STRING          0x0032
+#define LDAP_OPT_MATCHED_DN                    0x0033
 
-/* 0x33 - 0x0fff not defined by current draft */
+/* 0x34 - 0x0fff not defined by current draft */
 
-/* extended options - none */
+#define LDAP_OPT_PRIVATE_EXTENSION_BASE 0x4000  /* to 0x7FFF inclusive */
 
 /* private and experimental options */
-#define LDAP_OPT_DNS                           0x4001  /* use DN & DNS */
-
 /* OpenLDAP specific options */
 #define LDAP_OPT_DEBUG_LEVEL           0x5001  /* debug level */
 #define LDAP_OPT_TIMEOUT                       0x5002  /* default timeout */
 #define LDAP_OPT_REFHOPLIMIT           0x5003  /* ref hop limit */
-#define LDAP_OPT_MATCHED_DN                    0x5004  /* should have been in draft */
 #define LDAP_OPT_NETWORK_TIMEOUT        0x5005  /* socket level timeout */
+#define LDAP_OPT_URI                           0x5006
 
-/* TLS options */
+/* OpenLDAP TLS options */
 #define LDAP_OPT_X_TLS_CACERTFILE      0x6001
 #define LDAP_OPT_X_TLS_CACERTDIR       0x6002
 #define LDAP_OPT_X_TLS_CERT            0x6003
@@ -132,6 +129,11 @@ LDAP_BEGIN_DECL
 #define LDAP_OPT_X_TLS_ALLOW           3
 #define LDAP_OPT_X_TLS_TRY             4
 
+/* OpenLDAP SASL options */
+#define LDAP_OPT_X_SASL_MINSSF         0x6100
+#define LDAP_OPT_X_SASL_MAXSSF         0x6101
+#define LDAP_OPT_X_SASL_ACTSSF         0x6102
+
 /* on/off values */
 #define LDAP_OPT_ON            ((void *) 1)
 #define LDAP_OPT_OFF   ((void *) 0)
@@ -165,16 +167,30 @@ typedef struct ldapcontrol {
 /* LDAP Controls */
        /* chase referrals controls */
 #define LDAP_CONTROL_REFERRALS "1.2.840.113666.1.4.616"
-#define LDAP_CHASE_SUBORDINATE_REFERRALS       0x0020
-#define LDAP_CHASE_EXTERNAL_REFERRALS  0x0040
+#define LDAP_CHASE_SUBORDINATE_REFERRALS       0x0020U
+#define LDAP_CHASE_EXTERNAL_REFERRALS  0x0040U
+
+#define LDAP_CONTROL_MANAGEDSAIT "2.16.840.1.113730.3.4.2"
 
-#define LDAP_CONTROL_MANAGEDSAIT "2.16.840.1.113730.3.2.6"
+/* Experimental Controls */
+
+#define LDAP_CONTROL_SORTREQUEST    "1.2.840.113556.1.4.473"
+#define LDAP_CONTROL_SORTRESPONSE      "1.2.840.113556.1.4.474"
+#define LDAP_CONTROL_VLVREQUEST        "2.16.840.1.113730.3.4.9"
+#define LDAP_CONTROL_VLVRESPONSE    "2.16.840.1.113730.3.4.10"
 
 /* LDAP Unsolicited Notifications */
-#define        LDAP_NOTICE_DISCONNECT  "1.3.6.1.4.1.1466.20036"
+#define        LDAP_NOTICE_OF_DISCONNECTION    "1.3.6.1.4.1.1466.20036"
+#define LDAP_NOTICE_DISCONNECT LDAP_NOTICE_OF_DISCONNECTION
 
 /* LDAP Extended Operations */
+#define LDAP_EXOP_START_TLS "1.3.6.1.4.1.1466.20037"
 
+#define LDAP_EXOP_X_MODIFY_PASSWD "1.3.6.1.4.1.4203.666.6.1"
+#define LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID       ((ber_tag_t) 0x80U)
+#define LDAP_TAG_EXOP_X_MODIFY_PASSWD_OLD      ((ber_tag_t) 0x81U)
+#define LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW      ((ber_tag_t) 0x82U)
+#define LDAP_TAG_EXOP_X_MODIFY_PASSWD_GEN      ((ber_tag_t) 0x80U)
 
 /* 
  * specific LDAP instantiations of BER types we know about
@@ -198,115 +214,100 @@ typedef struct ldapcontrol {
  */
 
 /* general stuff */
-#define LDAP_TAG_MESSAGE       (ber_tag_t) 0x30U       /* constructed + 16 */
-#define LDAP_TAG_MSGID         (ber_tag_t) 0x02U       /* integer */
-#define LDAP_TAG_LDAPDN                (ber_tag_t) 0x04U       /* octect string */
-#define LDAP_TAG_LDAPCRED      (ber_tag_t) 0x04U       /* octect string */
-#define LDAP_TAG_CONTROLS      (ber_tag_t) 0xa0U       /* context specific + constructed + 0 */
-#define LDAP_TAG_REFERRAL      (ber_tag_t) 0xa3U       /* context specific + constructed + 3 */
-
-#define LDAP_TAG_NEWSUPERIOR   (ber_tag_t) 0x80U       /* context-specific + primitive + 0 */
-
-#define LDAP_TAG_EXOP_REQ_OID   (ber_tag_t) 0x80U      /* context specific + primitive */
-#define LDAP_TAG_EXOP_REQ_VALUE (ber_tag_t) 0x81U      /* context specific + primitive */
-#define LDAP_TAG_EXOP_RES_OID   (ber_tag_t) 0x8aU      /* context specific + primitive */
-#define LDAP_TAG_EXOP_RES_VALUE (ber_tag_t) 0x8bU      /* context specific + primitive */
+#define LDAP_TAG_MESSAGE       ((ber_tag_t) 0x30U)     /* constructed + 16 */
+#define LDAP_TAG_MSGID         ((ber_tag_t) 0x02U)     /* integer */
+#define LDAP_TAG_LDAPDN                ((ber_tag_t) 0x04U)     /* octect string */
+#define LDAP_TAG_LDAPCRED      ((ber_tag_t) 0x04U)     /* octect string */
+#define LDAP_TAG_CONTROLS      ((ber_tag_t) 0xa0U)     /* context specific + constructed + 0 */
+#define LDAP_TAG_REFERRAL      ((ber_tag_t) 0xa3U)     /* context specific + constructed + 3 */
 
-#define LDAP_TAG_SASL_RES_CREDS        (ber_tag_t) 0x87U       /* context specific + primitive */
+#define LDAP_TAG_NEWSUPERIOR   ((ber_tag_t) 0x80U)     /* context-specific + primitive + 0 */
 
+#define LDAP_TAG_EXOP_REQ_OID   ((ber_tag_t) 0x80U)    /* context specific + primitive */
+#define LDAP_TAG_EXOP_REQ_VALUE ((ber_tag_t) 0x81U)    /* context specific + primitive */
+#define LDAP_TAG_EXOP_RES_OID   ((ber_tag_t) 0x8aU)    /* context specific + primitive */
+#define LDAP_TAG_EXOP_RES_VALUE ((ber_tag_t) 0x8bU)    /* context specific + primitive */
 
+#define LDAP_TAG_SASL_RES_CREDS        ((ber_tag_t) 0x87U)     /* context specific + primitive */
 
 
 /* possible operations a client can invoke */
-#define LDAP_REQ_BIND                  (ber_tag_t) 0x60U       /* application + constructed */
-#define LDAP_REQ_UNBIND                        (ber_tag_t) 0x42U       /* application + primitive   */
-#define LDAP_REQ_SEARCH                        (ber_tag_t) 0x63U       /* application + constructed */
-#define LDAP_REQ_MODIFY                        (ber_tag_t) 0x66U       /* application + constructed */
-#define LDAP_REQ_ADD                   (ber_tag_t) 0x68U       /* application + constructed */
-#define LDAP_REQ_DELETE                        (ber_tag_t) 0x4aU       /* application + primitive   */
-#define LDAP_REQ_MODRDN                        (ber_tag_t) 0x6cU       /* application + constructed */
+#define LDAP_REQ_BIND                  ((ber_tag_t) 0x60U)     /* application + constructed */
+#define LDAP_REQ_UNBIND                        ((ber_tag_t) 0x42U)     /* application + primitive   */
+#define LDAP_REQ_SEARCH                        ((ber_tag_t) 0x63U)     /* application + constructed */
+#define LDAP_REQ_MODIFY                        ((ber_tag_t) 0x66U)     /* application + constructed */
+#define LDAP_REQ_ADD                   ((ber_tag_t) 0x68U)     /* application + constructed */
+#define LDAP_REQ_DELETE                        ((ber_tag_t) 0x4aU)     /* application + primitive   */
+#define LDAP_REQ_MODRDN                        ((ber_tag_t) 0x6cU)     /* application + constructed */
 #define LDAP_REQ_MODDN                 LDAP_REQ_MODRDN 
 #define LDAP_REQ_RENAME                        LDAP_REQ_MODRDN 
-#define LDAP_REQ_COMPARE               (ber_tag_t) 0x6eU       /* application + constructed */
-#define LDAP_REQ_ABANDON               (ber_tag_t) 0x50U       /* application + primitive   */
-#define LDAP_REQ_EXTENDED              (ber_tag_t) 0x77U       /* application + constructed */
+#define LDAP_REQ_COMPARE               ((ber_tag_t) 0x6eU)     /* application + constructed */
+#define LDAP_REQ_ABANDON               ((ber_tag_t) 0x50U)     /* application + primitive   */
+#define LDAP_REQ_EXTENDED              ((ber_tag_t) 0x77U)     /* application + constructed */
 
 /* possible result types a server can return */
-#define LDAP_RES_BIND                  (ber_tag_t) 0x61U       /* application + constructed */
-#define LDAP_RES_SEARCH_ENTRY          (ber_tag_t) 0x64U       /* application + constructed */
-#define LDAP_RES_SEARCH_REFERENCE      (ber_tag_t) 0x73U       /* V3: application + constructed */
-#define LDAP_RES_SEARCH_RESULT         (ber_tag_t) 0x65U       /* application + constructed */
-#define LDAP_RES_MODIFY                        (ber_tag_t) 0x67U       /* application + constructed */
-#define LDAP_RES_ADD                   (ber_tag_t) 0x69U       /* application + constructed */
-#define LDAP_RES_DELETE                        (ber_tag_t) 0x6bU       /* application + constructed */
-#define LDAP_RES_MODRDN                        (ber_tag_t) 0x6dU       /* application + constructed */
+#define LDAP_RES_BIND                  ((ber_tag_t) 0x61U)     /* application + constructed */
+#define LDAP_RES_SEARCH_ENTRY          ((ber_tag_t) 0x64U)     /* application + constructed */
+#define LDAP_RES_SEARCH_REFERENCE      ((ber_tag_t) 0x73U)     /* V3: application + constructed */
+#define LDAP_RES_SEARCH_RESULT         ((ber_tag_t) 0x65U)     /* application + constructed */
+#define LDAP_RES_MODIFY                        ((ber_tag_t) 0x67U)     /* application + constructed */
+#define LDAP_RES_ADD                   ((ber_tag_t) 0x69U)     /* application + constructed */
+#define LDAP_RES_DELETE                        ((ber_tag_t) 0x6bU)     /* application + constructed */
+#define LDAP_RES_MODRDN                        ((ber_tag_t) 0x6dU)     /* application + constructed */
 #define LDAP_RES_MODDN                 LDAP_RES_MODRDN /* application + constructed */
 #define LDAP_RES_RENAME                        LDAP_RES_MODRDN /* application + constructed */
-#define LDAP_RES_COMPARE               (ber_tag_t) 0x6fU       /* application + constructed */
-#define LDAP_RES_EXTENDED              (ber_tag_t) 0x78U       /* V3: application + constructed */
-#define LDAP_RES_ANY                   ((ber_tag_t)(~0))
+#define LDAP_RES_COMPARE               ((ber_tag_t) 0x6fU)     /* application + constructed */
+#define LDAP_RES_EXTENDED              ((ber_tag_t) 0x78U)     /* V3: application + constructed */
+#define LDAP_RES_EXTENDED_PARTIAL      ((ber_tag_t) 0x79U)     /* V3+: application + constructed */
+
+#define LDAP_RES_ANY                   ((ber_tag_t)(-1))
+#define LDAP_RES_UNSOLICITED   ((ber_tag_t)(0))
 
 
 /* sasl methods */
 #define LDAP_SASL_SIMPLE                       NULL
 
 /* authentication methods available */
-#define LDAP_AUTH_NONE         (ber_tag_t) 0x00U       /* no authentication              */
-#define LDAP_AUTH_SIMPLE       (ber_tag_t) 0x80U       /* context specific + primitive   */
-#define LDAP_AUTH_SASL         (ber_tag_t) 0xa3U       /* context specific + primitive   */
-#define LDAP_AUTH_KRBV4                (ber_tag_t) 0xffU       /* means do both of the following */
-#define LDAP_AUTH_KRBV41       (ber_tag_t) 0x81U       /* context specific + primitive   */
-#define LDAP_AUTH_KRBV42       (ber_tag_t) 0x82U       /* context specific + primitive   */
+#define LDAP_AUTH_NONE         ((ber_tag_t) 0x00U)     /* no authentication              */
+#define LDAP_AUTH_SIMPLE       ((ber_tag_t) 0x80U)     /* context specific + primitive   */
+#define LDAP_AUTH_SASL         ((ber_tag_t) 0xa3U)     /* context specific + primitive   */
+#define LDAP_AUTH_KRBV4                ((ber_tag_t) 0xffU)     /* means do both of the following */
+#define LDAP_AUTH_KRBV41       ((ber_tag_t) 0x81U)     /* context specific + primitive   */
+#define LDAP_AUTH_KRBV42       ((ber_tag_t) 0x82U)     /* context specific + primitive   */
 
 
 /* filter types */
-#define LDAP_FILTER_AND                (ber_tag_t) 0xa0U       /* context specific + constructed */
-#define LDAP_FILTER_OR         (ber_tag_t) 0xa1U       /* context specific + constructed */
-#define LDAP_FILTER_NOT                (ber_tag_t) 0xa2U       /* context specific + constructed */
-#define LDAP_FILTER_EQUALITY   (ber_tag_t) 0xa3U       /* context specific + constructed */
-#define LDAP_FILTER_SUBSTRINGS (ber_tag_t) 0xa4U       /* context specific + constructed */
-#define LDAP_FILTER_GE         (ber_tag_t) 0xa5U       /* context specific + constructed */
-#define LDAP_FILTER_LE         (ber_tag_t) 0xa6U       /* context specific + constructed */
-#define LDAP_FILTER_PRESENT    (ber_tag_t) 0x87U       /* context specific + primitive   */
-#define LDAP_FILTER_APPROX     (ber_tag_t) 0xa8U       /* context specific + constructed */
-#define LDAP_FILTER_EXT                (ber_tag_t) 0xa9U       /* context specific + constructed */
+#define LDAP_FILTER_AND                ((ber_tag_t) 0xa0U)     /* context specific + constructed */
+#define LDAP_FILTER_OR         ((ber_tag_t) 0xa1U)     /* context specific + constructed */
+#define LDAP_FILTER_NOT                ((ber_tag_t) 0xa2U)     /* context specific + constructed */
+#define LDAP_FILTER_EQUALITY   ((ber_tag_t) 0xa3U)     /* context specific + constructed */
+#define LDAP_FILTER_SUBSTRINGS ((ber_tag_t) 0xa4U)     /* context specific + constructed */
+#define LDAP_FILTER_GE         ((ber_tag_t) 0xa5U)     /* context specific + constructed */
+#define LDAP_FILTER_LE         ((ber_tag_t) 0xa6U)     /* context specific + constructed */
+#define LDAP_FILTER_PRESENT    ((ber_tag_t) 0x87U)     /* context specific + primitive   */
+#define LDAP_FILTER_APPROX     ((ber_tag_t) 0xa8U)     /* context specific + constructed */
+#define LDAP_FILTER_EXT                ((ber_tag_t) 0xa9U)     /* context specific + constructed */
 
 /* extended filter component types */
-#define LDAP_FILTER_EXT_OID    (ber_tag_t) 0x81U       /* context specific */
-#define LDAP_FILTER_EXT_TYPE   (ber_tag_t) 0x82U       /* context specific */
-#define LDAP_FILTER_EXT_VALUE  (ber_tag_t) 0x83U       /* context specific */
-#define LDAP_FILTER_EXT_DNATTRS        (ber_tag_t) 0x84U       /* context specific */
+#define LDAP_FILTER_EXT_OID    ((ber_tag_t) 0x81U)     /* context specific */
+#define LDAP_FILTER_EXT_TYPE   ((ber_tag_t) 0x82U)     /* context specific */
+#define LDAP_FILTER_EXT_VALUE  ((ber_tag_t) 0x83U)     /* context specific */
+#define LDAP_FILTER_EXT_DNATTRS        ((ber_tag_t) 0x84U)     /* context specific */
 
 /* substring filter component types */
-#define LDAP_SUBSTRING_INITIAL (ber_tag_t) 0x80U       /* context specific */
-#define LDAP_SUBSTRING_ANY     (ber_tag_t) 0x81U       /* context specific */
-#define LDAP_SUBSTRING_FINAL   (ber_tag_t) 0x82U       /* context specific */
+#define LDAP_SUBSTRING_INITIAL ((ber_tag_t) 0x80U)     /* context specific */
+#define LDAP_SUBSTRING_ANY     ((ber_tag_t) 0x81U)     /* context specific */
+#define LDAP_SUBSTRING_FINAL   ((ber_tag_t) 0x82U)     /* context specific */
 
 /* search scopes */
-#define LDAP_SCOPE_BASE                (ber_int_t) 0x0000
-#define LDAP_SCOPE_ONELEVEL    (ber_int_t) 0x0001
-#define LDAP_SCOPE_SUBTREE     (ber_int_t) 0x0002
+#define LDAP_SCOPE_BASE                ((ber_int_t) 0x0000)
+#define LDAP_SCOPE_ONELEVEL    ((ber_int_t) 0x0001)
+#define LDAP_SCOPE_SUBTREE     ((ber_int_t) 0x0002)
 
-/* for modifications */
-typedef struct ldapmod {
-       int             mod_op;
-#define LDAP_MOD_ADD           (ber_int_t) 0x0000
-#define LDAP_MOD_DELETE                (ber_int_t) 0x0001
-#define LDAP_MOD_REPLACE       (ber_int_t) 0x0002
-#define LDAP_MOD_BVALUES       (ber_int_t) 0x0080
-/* IMPORTANT: do not use code 0x1000 (or above),
- * it is used internally by the backends!
- * (see ldap/servers/slapd/slap.h)
- * JCG 05/1999 (gomez@engr.sgi.com)
- */
-       char            *mod_type;
-       union mod_vals_u {
-               char            **modv_strvals;
-               struct berval   **modv_bvals;
-       } mod_vals;
-#define mod_values     mod_vals.modv_strvals
-#define mod_bvalues    mod_vals.modv_bvals
-} LDAPMod;
+/* substring filter component types */
+#define LDAP_SUBSTRING_INITIAL ((ber_tag_t) 0x80U)     /* context specific */
+#define LDAP_SUBSTRING_ANY     ((ber_tag_t) 0x81U)     /* context specific */
+#define LDAP_SUBSTRING_FINAL   ((ber_tag_t) 0x82U)     /* context specific */
 
 /* 
  * possible error codes we can return
@@ -404,6 +405,28 @@ typedef struct ldapmod {
 
 typedef struct ldapmsg LDAPMessage;
 
+/* for modifications */
+typedef struct ldapmod {
+       int             mod_op;
+
+#define LDAP_MOD_ADD           ((ber_int_t) 0x0000)
+#define LDAP_MOD_DELETE                ((ber_int_t) 0x0001)
+#define LDAP_MOD_REPLACE       ((ber_int_t) 0x0002)
+#define LDAP_MOD_BVALUES       ((ber_int_t) 0x0080)
+/* IMPORTANT: do not use code 0x1000 (or above),
+ * it is used internally by the backends!
+ * (see ldap/servers/slapd/slap.h)
+ */
+
+       char            *mod_type;
+       union mod_vals_u {
+               char            **modv_strvals;
+               struct berval   **modv_bvals;
+       } mod_vals;
+#define mod_values     mod_vals.modv_strvals
+#define mod_bvalues    mod_vals.modv_bvals
+} LDAPMod;
+
 /*
  * structures for ldap getfilter routines
  */
@@ -411,8 +434,8 @@ typedef struct ldapmsg LDAPMessage;
 typedef struct ldap_filt_info {
        char                    *lfi_filter;
        char                    *lfi_desc;
-       int                     lfi_scope;      /* LDAP_SCOPE_BASE, etc */
-       int                     lfi_isexact;    /* exact match filter? */
+       int                     lfi_scope;
+       int                     lfi_isexact;
        struct ldap_filt_info   *lfi_next;
 } LDAPFiltInfo;
 
@@ -441,9 +464,10 @@ typedef struct ldap_filt_desc {
 
 
 /*
- * structure representing an ldap connection
+ * structure representing an ldap session which can
+ * encompass connections to multiple servers (in the
+ * face of referrals).
  */
-
 typedef struct ldap LDAP;
 
 #define LDAP_DEREF_NEVER       0x00
@@ -471,21 +495,22 @@ typedef struct ldap_friendly {
  * types for ldap URL handling
  */
 typedef struct ldap_url_desc {
-       int             lud_ldaps;
+    struct ldap_url_desc *lud_next;
+    char       *lud_scheme;
     char       *lud_host;
     int                lud_port;
     char       *lud_dn;
     char       **lud_attrs;
     int                lud_scope;
     char       *lud_filter;
-       char    **lud_exts;
+    char       **lud_exts;
 } LDAPURLDesc;
 
 #define LDAP_URL_SUCCESS               0x00    /* Success */
 #define LDAP_URL_ERR_MEM               0x01    /* can't allocate memory space */
 #define LDAP_URL_ERR_PARAM             0x02    /* parameter is bad */
 
-#define LDAP_URL_ERR_NOTLDAP   0x03    /* URL doesn't begin with "ldap[s]://" */
+#define LDAP_URL_ERR_BADSCHEME 0x03    /* URL doesn't begin with "ldap[si]://" */
 #define LDAP_URL_ERR_BADENCLOSURE 0x04 /* URL is missing trailing ">" */
 #define LDAP_URL_ERR_BADURL            0x05    /* URL is bad */
 #define LDAP_URL_ERR_BADHOST   0x06    /* host port is bad */
@@ -496,42 +521,67 @@ typedef struct ldap_url_desc {
 
 /*
  * The API draft spec says we should declare (or cause to be declared)
- * 'struct timeval'.   We don't.  See LDAPext discussions.
+ * 'struct timeval'.   We don't.  See IETF LDAPext discussions.
  */
 struct timeval;
 
 /*
  * in options.c:
  */
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_get_option LDAP_P((
-       LDAP_CONST LDAP *ld,
+       LDAP *ld,
        int option,
        void *outvalue));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_set_option LDAP_P((
        LDAP *ld,
        int option,
        LDAP_CONST void *invalue));
 
+/* V3 REBIND Function Callback Prototype */
+typedef int (LDAP_REBIND_PROC) LDAP_P((
+       LDAP *ld, LDAP_CONST char *url, int request, ber_int_t msgid ));
+
+LIBLDAP_F( int )
+ldap_set_rebind_proc LDAP_P((
+       LDAP *ld,
+       LDAP_REBIND_PROC *ldap_proc));
 
 /*
  * in controls.c:
  */
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_control_free LDAP_P((
        LDAPControl *ctrl ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_controls_free LDAP_P((
        LDAPControl **ctrls ));
 
-  
+/*
+ * in dnssrv.c:
+ */
+LIBLDAP_F( int )
+ldap_domain2dn LDAP_P((
+       LDAP_CONST char* domain,
+       char** dn ));
+
+LIBLDAP_F( int )
+ldap_dn2domain LDAP_P((
+       LDAP_CONST char* dn,
+       char** domain ));
+
+LIBLDAP_F( int )
+ldap_domain2hostlist LDAP_P((
+       LDAP_CONST char *domain,
+       char** hostlist ));
+
 /*
  * in extended.c:
  */
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_extended_operation LDAP_P((
        LDAP                    *ld,
        LDAP_CONST char *reqoid,
@@ -540,7 +590,7 @@ ldap_extended_operation LDAP_P((
        LDAPControl             **clientctrls,
        int                             *msgidp ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_extended_operation_s LDAP_P((
        LDAP                    *ld,
        LDAP_CONST char *reqoid,
@@ -550,7 +600,7 @@ ldap_extended_operation_s LDAP_P((
        char                    **retoidp,
        struct berval   **retdatap ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_parse_extended_result LDAP_P((
        LDAP                    *ld,
        LDAPMessage             *res,
@@ -561,12 +611,12 @@ ldap_parse_extended_result LDAP_P((
 /*
  * in abandon.c:
  */
-LDAP_F( int )
-ldap_abandon LDAP_P((
+LIBLDAP_F( int )
+ldap_abandon LDAP_P((  /* deprecated */
        LDAP *ld,
        int msgid ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_abandon_ext LDAP_P((
        LDAP                    *ld,
        int                             msgid,
@@ -577,7 +627,7 @@ ldap_abandon_ext LDAP_P((
 /*
  * in add.c:
  */
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_add_ext LDAP_P((
        LDAP                    *ld,
        LDAP_CONST char *dn,
@@ -586,7 +636,7 @@ ldap_add_ext LDAP_P((
        LDAPControl             **clientctrls,
        int                     *msgidp ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_add_ext_s LDAP_P((
        LDAP                    *ld,
        LDAP_CONST char *dn,
@@ -594,14 +644,14 @@ ldap_add_ext_s LDAP_P((
        LDAPControl             **serverctrls,
        LDAPControl             **clientctrls ));
 
-LDAP_F( int )
-ldap_add LDAP_P((
+LIBLDAP_F( int )
+ldap_add LDAP_P((      /* deprecated */
        LDAP *ld,
        LDAP_CONST char *dn,
        LDAPMod **attrs ));
 
-LDAP_F( int )
-ldap_add_s LDAP_P((
+LIBLDAP_F( int )
+ldap_add_s LDAP_P((    /* deprecated */
        LDAP *ld,
        LDAP_CONST char *dn,
        LDAPMod **attrs ));
@@ -610,7 +660,7 @@ ldap_add_s LDAP_P((
 /*
  * in sasl.c:
  */
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_sasl_bind LDAP_P((
        LDAP                    *ld,
        LDAP_CONST char *dn,
@@ -620,7 +670,18 @@ ldap_sasl_bind LDAP_P((
        LDAPControl             **clientctrls,
        int                             *msgidp ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
+ldap_negotiated_sasl_bind_s LDAP_P((
+       LDAP *ld,
+       LDAP_CONST char *dn, /* usually NULL */
+       LDAP_CONST char *authenticationId, 
+       LDAP_CONST char *authorizationId, /* usually NULL */
+       LDAP_CONST char *saslMechanism,
+       struct berval *passPhrase,
+       LDAPControl **serverControls,
+       LDAPControl **clientControls ));
+
+LIBLDAP_F( int )
 ldap_sasl_bind_s LDAP_P((
        LDAP                    *ld,
        LDAP_CONST char *dn,
@@ -630,7 +691,7 @@ ldap_sasl_bind_s LDAP_P((
        LDAPControl             **clientctrls,
        struct berval   **servercredp ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_parse_sasl_bind_result LDAP_P((
        LDAP                    *ld,
        LDAPMessage             *res,
@@ -641,41 +702,30 @@ ldap_parse_sasl_bind_result LDAP_P((
  * in bind.c:
  *     (deprecated)
  */
-LDAP_F( int )
-ldap_bind LDAP_P((
+LIBLDAP_F( int )
+ldap_bind LDAP_P((     /* deprecated */
        LDAP *ld,
        LDAP_CONST char *who,
        LDAP_CONST char *passwd,
        int authmethod ));
 
-LDAP_F( int )
-ldap_bind_s LDAP_P((
+LIBLDAP_F( int )
+ldap_bind_s LDAP_P((   /* deprecated */
        LDAP *ld,
        LDAP_CONST char *who,
        LDAP_CONST char *cred,
        int authmethod ));
 
-LDAP_F( void )
-ldap_set_rebind_proc LDAP_P((
-       LDAP *ld,
-       int (*rebindproc) LDAP_P((
-               LDAP *ld,
-               char **dnp,
-               char **passwdp,
-               int *authmethodp,
-               int freeit ))));
-
-
 /*
  * in sbind.c:
  */
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_simple_bind LDAP_P((
        LDAP *ld,
        LDAP_CONST char *who,
        LDAP_CONST char *passwd ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_simple_bind_s LDAP_P((
        LDAP *ld,
        LDAP_CONST char *who,
@@ -686,28 +736,28 @@ ldap_simple_bind_s LDAP_P((
  * in kbind.c:
  *     (deprecated)
  */
-LDAP_F( int )
-ldap_kerberos_bind_s LDAP_P((
+LIBLDAP_F( int )
+ldap_kerberos_bind_s LDAP_P((  /* deprecated */
        LDAP *ld,
        LDAP_CONST char *who ));
 
-LDAP_F( int )
-ldap_kerberos_bind1 LDAP_P((
+LIBLDAP_F( int )
+ldap_kerberos_bind1 LDAP_P((   /* deprecated */
        LDAP *ld,
        LDAP_CONST char *who ));
 
-LDAP_F( int )
-ldap_kerberos_bind1_s LDAP_P((
+LIBLDAP_F( int )
+ldap_kerberos_bind1_s LDAP_P(( /* deprecated */
        LDAP *ld,
        LDAP_CONST char *who ));
 
-LDAP_F( int )
-ldap_kerberos_bind2 LDAP_P((
+LIBLDAP_F( int )
+ldap_kerberos_bind2 LDAP_P((   /* deprecated */
        LDAP *ld,
        LDAP_CONST char *who ));
 
-LDAP_F( int )
-ldap_kerberos_bind2_s LDAP_P((
+LIBLDAP_F( int )
+ldap_kerberos_bind2_s LDAP_P(( /* deprecated */
        LDAP *ld,
        LDAP_CONST char *who ));
 
@@ -715,32 +765,32 @@ ldap_kerberos_bind2_s LDAP_P((
  * in cache.c
  * (deprecated)
  */
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_enable_cache LDAP_P(( LDAP *ld, long timeout, ber_len_t maxmem ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_disable_cache LDAP_P(( LDAP *ld ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_set_cache_options LDAP_P(( LDAP *ld, unsigned long opts ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_destroy_cache LDAP_P(( LDAP *ld ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_flush_cache LDAP_P(( LDAP *ld ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_uncache_entry LDAP_P(( LDAP *ld, LDAP_CONST char *dn ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_uncache_request LDAP_P(( LDAP *ld, int msgid ));
 
 
 /*
  * in compare.c:
  */
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_compare_ext LDAP_P((
        LDAP                    *ld,
        LDAP_CONST char *dn,
@@ -750,7 +800,7 @@ ldap_compare_ext LDAP_P((
        LDAPControl             **clientctrls,
        int                     *msgidp ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_compare_ext_s LDAP_P((
        LDAP                    *ld,
        LDAP_CONST char *dn,
@@ -759,15 +809,15 @@ ldap_compare_ext_s LDAP_P((
        LDAPControl             **serverctrls,
        LDAPControl             **clientctrls ));
 
-LDAP_F( int )
-ldap_compare LDAP_P((
+LIBLDAP_F( int )
+ldap_compare LDAP_P((  /* deprecated */
        LDAP *ld,
        LDAP_CONST char *dn,
        LDAP_CONST char *attr,
        LDAP_CONST char *value ));
 
-LDAP_F( int )
-ldap_compare_s LDAP_P((
+LIBLDAP_F( int )
+ldap_compare_s LDAP_P((        /* deprecated */
        LDAP *ld,
        LDAP_CONST char *dn,
        LDAP_CONST char *attr,
@@ -777,7 +827,7 @@ ldap_compare_s LDAP_P((
 /*
  * in delete.c:
  */
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_delete_ext LDAP_P((
        LDAP                    *ld,
        LDAP_CONST char *dn,
@@ -785,20 +835,20 @@ ldap_delete_ext LDAP_P((
        LDAPControl             **clientctrls,
        int                     *msgidp ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_delete_ext_s LDAP_P((
        LDAP                    *ld,
        LDAP_CONST char *dn,
        LDAPControl             **serverctrls,
        LDAPControl             **clientctrls ));
 
-LDAP_F( int )
-ldap_delete LDAP_P((
+LIBLDAP_F( int )
+ldap_delete LDAP_P((   /* deprecated */
        LDAP *ld,
        LDAP_CONST char *dn ));
 
-LDAP_F( int )
-ldap_delete_s LDAP_P((
+LIBLDAP_F( int )
+ldap_delete_s LDAP_P(( /* deprecated */
        LDAP *ld,
        LDAP_CONST char *dn ));
 
@@ -806,7 +856,7 @@ ldap_delete_s LDAP_P((
 /*
  * in error.c:
  */
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_parse_result LDAP_P((
        LDAP                    *ld,
        LDAPMessage             *res,
@@ -817,17 +867,17 @@ ldap_parse_result LDAP_P((
        LDAPControl             ***serverctrls,
        int                             freeit ));
 
-LDAP_F( char *)
+LIBLDAP_F( char *)
 ldap_err2string LDAP_P((
        int err ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_result2error LDAP_P((     /* deprecated */
        LDAP *ld,
        LDAPMessage *r,
        int freeit ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_perror LDAP_P((   /* deprecated */
        LDAP *ld,
        LDAP_CONST char *s ));
@@ -836,7 +886,7 @@ ldap_perror LDAP_P((        /* deprecated */
 /*
  * in modify.c:
  */
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_modify_ext LDAP_P((
        LDAP                    *ld,
        LDAP_CONST char *dn,
@@ -845,7 +895,7 @@ ldap_modify_ext LDAP_P((
        LDAPControl             **clientctrls,
        int                     *msgidp ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_modify_ext_s LDAP_P((
        LDAP                    *ld,
        LDAP_CONST char *dn,
@@ -853,14 +903,14 @@ ldap_modify_ext_s LDAP_P((
        LDAPControl             **serverctrls,
        LDAPControl             **clientctrls ));
 
-LDAP_F( int )
-ldap_modify LDAP_P((
+LIBLDAP_F( int )
+ldap_modify LDAP_P((   /* deprecated */
        LDAP *ld,
        LDAP_CONST char *dn,
        LDAPMod **mods ));
 
-LDAP_F( int )
-ldap_modify_s LDAP_P((
+LIBLDAP_F( int )
+ldap_modify_s LDAP_P(( /* deprecated */
        LDAP *ld,
        LDAP_CONST char *dn,
        LDAPMod **mods ));
@@ -869,28 +919,28 @@ ldap_modify_s LDAP_P((
 /*
  * in modrdn.c:
  */
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_rename LDAP_P((
        LDAP *ld,
        LDAP_CONST char *dn,
        LDAP_CONST char *newrdn,
-       int deleteoldrdn,
        LDAP_CONST char *newSuperior,
+       int deleteoldrdn,
        LDAPControl **sctrls,
        LDAPControl **cctrls,
        int *msgidp ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_rename_s LDAP_P((
        LDAP *ld,
        LDAP_CONST char *dn,
        LDAP_CONST char *newrdn,
-       int deleteoldrdn,
        LDAP_CONST char *newSuperior,
+       int deleteoldrdn,
        LDAPControl **sctrls,
        LDAPControl **cctrls ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_rename_ext LDAP_P((
        LDAP                    *ld,
        LDAP_CONST char *dn,
@@ -901,7 +951,7 @@ ldap_rename_ext LDAP_P((
        LDAPControl             **clientctrls,
        int                     *msgidp ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_rename_ext_s LDAP_P((
        LDAP                    *ld,
        LDAP_CONST char *dn,
@@ -911,43 +961,43 @@ ldap_rename_ext_s LDAP_P((
        LDAPControl             **serverctrls,
        LDAPControl             **clientctrls ));
 
-LDAP_F( int )
-ldap_rename2 LDAP_P((
+LIBLDAP_F( int )
+ldap_rename2 LDAP_P((  /* deprecated */
        LDAP *ld,
        LDAP_CONST char *dn,
        LDAP_CONST char *newrdn,
-       int deleteoldrdn,
-       LDAP_CONST char *newSuperior ));
+       LDAP_CONST char *newSuperior,
+       int deleteoldrdn ));
 
-LDAP_F( int )
-ldap_rename2_s LDAP_P((
+LIBLDAP_F( int )
+ldap_rename2_s LDAP_P((        /* deprecated */
        LDAP *ld,
        LDAP_CONST char *dn,
        LDAP_CONST char *newrdn,
-       int deleteoldrdn,
-       LDAP_CONST char *newSuperior));
+       LDAP_CONST char *newSuperior,
+       int deleteoldrdn ));
 
-LDAP_F( int )
-ldap_modrdn LDAP_P((
+LIBLDAP_F( int )
+ldap_modrdn LDAP_P((   /* deprecated */
        LDAP *ld,
        LDAP_CONST char *dn,
        LDAP_CONST char *newrdn ));
 
-LDAP_F( int )
-ldap_modrdn_s LDAP_P((
+LIBLDAP_F( int )
+ldap_modrdn_s LDAP_P(( /* deprecated */
        LDAP *ld,
        LDAP_CONST char *dn,
        LDAP_CONST char *newrdn ));
 
-LDAP_F( int )
-ldap_modrdn2 LDAP_P((
+LIBLDAP_F( int )
+ldap_modrdn2 LDAP_P((  /* deprecated */
        LDAP *ld,
        LDAP_CONST char *dn,
        LDAP_CONST char *newrdn,
        int deleteoldrdn ));
 
-LDAP_F( int )
-ldap_modrdn2_s LDAP_P((
+LIBLDAP_F( int )
+ldap_modrdn2_s LDAP_P((        /* deprecated */
        LDAP *ld,
        LDAP_CONST char *dn,
        LDAP_CONST char *newrdn,
@@ -957,31 +1007,45 @@ ldap_modrdn2_s LDAP_P((
 /*
  * in open.c:
  */
-LDAP_F( LDAP *)
-ldap_open LDAP_P((
+LIBLDAP_F( LDAP *)
+ldap_open LDAP_P((     /* deprecated */
        LDAP_CONST char *host,
        int port ));
 
-LDAP_F( LDAP *)
+LIBLDAP_F( LDAP *)
 ldap_init LDAP_P((
        LDAP_CONST char *host,
        int port ));
 
+LIBLDAP_F( int )
+ldap_create LDAP_P(( 
+       LDAP **ldp ));
+
+LIBLDAP_F( int )
+ldap_initialize LDAP_P((
+       LDAP **ldp,
+       LDAP_CONST char *url ));
+
+LIBLDAP_F( int )
+ldap_start_tls LDAP_P((
+       LDAP *ld,
+       LDAPControl **serverctrls,
+       LDAPControl **clientctrls ));
 
 /*
  * in messages.c:
  */
-LDAP_F( LDAPMessage *)
+LIBLDAP_F( LDAPMessage *)
 ldap_first_message LDAP_P((
        LDAP *ld,
        LDAPMessage *chain ));
 
-LDAP_F( LDAPMessage *)
+LIBLDAP_F( LDAPMessage *)
 ldap_next_message LDAP_P((
        LDAP *ld,
        LDAPMessage *msg ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_count_messages LDAP_P((
        LDAP *ld,
        LDAPMessage *chain ));
@@ -990,22 +1054,22 @@ ldap_count_messages LDAP_P((
 /*
  * in references.c:
  */
-LDAP_F( LDAPMessage *)
+LIBLDAP_F( LDAPMessage *)
 ldap_first_reference LDAP_P((
        LDAP *ld,
        LDAPMessage *chain ));
 
-LDAP_F( LDAPMessage *)
+LIBLDAP_F( LDAPMessage *)
 ldap_next_reference LDAP_P((
        LDAP *ld,
        LDAPMessage *ref ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_count_references LDAP_P((
        LDAP *ld,
        LDAPMessage *chain ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_parse_reference LDAP_P((
        LDAP                    *ld,
        LDAPMessage             *ref,
@@ -1017,22 +1081,22 @@ ldap_parse_reference LDAP_P((
 /*
  * in getentry.c:
  */
-LDAP_F( LDAPMessage *)
+LIBLDAP_F( LDAPMessage *)
 ldap_first_entry LDAP_P((
        LDAP *ld,
        LDAPMessage *chain ));
 
-LDAP_F( LDAPMessage *)
+LIBLDAP_F( LDAPMessage *)
 ldap_next_entry LDAP_P((
        LDAP *ld,
        LDAPMessage *entry ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_count_entries LDAP_P((
        LDAP *ld,
        LDAPMessage *chain ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_get_entry_controls LDAP_P((
        LDAP                    *ld,
        LDAPMessage             *entry,
@@ -1042,12 +1106,12 @@ ldap_get_entry_controls LDAP_P((
 /*
  * in addentry.c
  */
-LDAP_F( LDAPMessage *)
+LIBLDAP_F( LDAPMessage *)
 ldap_delete_result_entry LDAP_P((
        LDAPMessage **list,
        LDAPMessage *e ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_add_result_entry LDAP_P((
        LDAPMessage **list,
        LDAPMessage *e ));
@@ -1056,56 +1120,53 @@ ldap_add_result_entry LDAP_P((
 /*
  * in getdn.c
  */
-LDAP_F( char * )
+LIBLDAP_F( char * )
 ldap_get_dn LDAP_P((
        LDAP *ld,
        LDAPMessage *entry ));
 
-LDAP_F( char * )
+LIBLDAP_F( char * )
 ldap_dn2ufn LDAP_P((
        LDAP_CONST char *dn ));
 
-LDAP_F( char ** )
+LIBLDAP_F( char ** )
 ldap_explode_dn LDAP_P((
        LDAP_CONST char *dn,
        int notypes ));
 
-LDAP_F( char ** )
+LIBLDAP_F( char ** )
 ldap_explode_rdn LDAP_P((
        LDAP_CONST char *rdn,
        int notypes ));
 
-LDAP_F( char * )
+LIBLDAP_F( char * )
 ldap_parent_dn LDAP_P((
        LDAP_CONST char *dn ));
 
-LDAP_F( char * )
+LIBLDAP_F( char * )
 ldap_relative_dn LDAP_P((
        LDAP_CONST char *dn ));
 
-LDAP_F( char * )
+LIBLDAP_F( char * )
 ldap_normalize_dn LDAP_P((
        LDAP_CONST char *dn ));
 
-LDAP_F( char ** )
-ldap_explode_dns LDAP_P(( /* deprecated */
-       LDAP_CONST char *dn ));
-
-LDAP_F( int )
-ldap_is_dns_dn LDAP_P((        /* deprecated */
-       LDAP_CONST char *dn ));
+LIBLDAP_F( char * )
+ldap_dn2dcedn LDAP_P(( LDAP_CONST char *dn )); /* deprecated */
 
+LIBLDAP_F( char * )
+ldap_dcedn2dn LDAP_P(( LDAP_CONST char *dce ));        /* deprecated */
 
 /*
  * in getattr.c
  */
-LDAP_F( char *)
+LIBLDAP_F( char *)
 ldap_first_attribute LDAP_P((                                                                   
        LDAP *ld,
        LDAPMessage *entry,
        BerElement **ber ));
 
-LDAP_F( char *)
+LIBLDAP_F( char *)
 ldap_next_attribute LDAP_P((
        LDAP *ld,
        LDAPMessage *entry,
@@ -1115,38 +1176,38 @@ ldap_next_attribute LDAP_P((
 /*
  * in getvalues.c
  */
-LDAP_F( char **)
+LIBLDAP_F( char **)
 ldap_get_values LDAP_P((
        LDAP *ld,
        LDAPMessage *entry,
        LDAP_CONST char *target ));
 
-LDAP_F( struct berval **)
+LIBLDAP_F( struct berval **)
 ldap_get_values_len LDAP_P((
        LDAP *ld,
        LDAPMessage *entry,
        LDAP_CONST char *target ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_count_values LDAP_P((
        char **vals ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_count_values_len LDAP_P((
        struct berval **vals ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_value_free LDAP_P((
        char **vals ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_value_free_len LDAP_P((
        struct berval **vals ));
 
 /*
  * in result.c:
  */
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_result LDAP_P((
        LDAP *ld,
        int msgid,
@@ -1154,19 +1215,19 @@ ldap_result LDAP_P((
        struct timeval *timeout,
        LDAPMessage **result ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_msgtype LDAP_P((
        LDAPMessage *lm ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_msgid   LDAP_P((
        LDAPMessage *lm ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_msgfree LDAP_P((
        LDAPMessage *lm ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_msgdelete LDAP_P((
        LDAP *ld,
        int msgid ));
@@ -1175,7 +1236,7 @@ ldap_msgdelete LDAP_P((
 /*
  * in search.c:
  */
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_search_ext LDAP_P((
        LDAP                    *ld,
        LDAP_CONST char *base,
@@ -1189,7 +1250,7 @@ ldap_search_ext LDAP_P((
        int                             sizelimit,
        int                             *msgidp ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_search_ext_s LDAP_P((
        LDAP                    *ld,
        LDAP_CONST char *base,
@@ -1203,8 +1264,8 @@ ldap_search_ext_s LDAP_P((
        int                             sizelimit,
        LDAPMessage             **res ));
 
-LDAP_F( int )
-ldap_search LDAP_P((
+LIBLDAP_F( int )
+ldap_search LDAP_P((   /* deprecated */
        LDAP *ld,
        LDAP_CONST char *base,
        int scope,
@@ -1212,8 +1273,8 @@ ldap_search LDAP_P((
        char **attrs,
        int attrsonly ));
 
-LDAP_F( int )
-ldap_search_s LDAP_P((
+LIBLDAP_F( int )
+ldap_search_s LDAP_P(( /* deprecated */
        LDAP *ld,
        LDAP_CONST char *base,
        int scope,
@@ -1222,8 +1283,8 @@ ldap_search_s LDAP_P((
        int attrsonly,
        LDAPMessage **res ));
 
-LDAP_F( int )
-ldap_search_st LDAP_P((                                                         
+LIBLDAP_F( int )
+ldap_search_st LDAP_P((        /* deprecated */
        LDAP *ld,
        LDAP_CONST char *base,
        int scope,
@@ -1235,10 +1296,11 @@ ldap_search_st LDAP_P((
 
 
 /*
- * in ufn.c
+ * in ufn.c                                                    
+ *     (deprecated)
  */
-LDAP_F( int )
-ldap_ufn_search_c LDAP_P((
+LIBLDAP_F( int )
+ldap_ufn_search_c LDAP_P(( /* deprecated */
        LDAP *ld,
        LDAP_CONST char *ufn,
        char **attrs,
@@ -1247,8 +1309,8 @@ ldap_ufn_search_c LDAP_P((
        int (*cancelproc)( void *cl ),
        void *cancelparm ));
 
-LDAP_F( int )
-ldap_ufn_search_ct LDAP_P((
+LIBLDAP_F( int )
+ldap_ufn_search_ct LDAP_P(( /* deprecated */
        LDAP *ld,
        LDAP_CONST char *ufn,
        char **attrs,
@@ -1260,47 +1322,47 @@ ldap_ufn_search_ct LDAP_P((
        char *tag2,
        char *tag3 ));
 
-LDAP_F( int )
-ldap_ufn_search_s LDAP_P((
+LIBLDAP_F( int )
+ldap_ufn_search_s LDAP_P(( /* deprecated */
        LDAP *ld,
        LDAP_CONST char *ufn,
        char **attrs,
        int attrsonly,
        LDAPMessage **res ));
 
-LDAP_F( LDAPFiltDesc *)
-ldap_ufn_setfilter LDAP_P((
+LIBLDAP_F( LDAPFiltDesc *)
+ldap_ufn_setfilter LDAP_P(( /* deprecated */
        LDAP *ld,
        LDAP_CONST char *fname ));
 
-LDAP_F( void )
-ldap_ufn_setprefix LDAP_P((
+LIBLDAP_F( void )
+ldap_ufn_setprefix LDAP_P(( /* deprecated */
        LDAP *ld,
        LDAP_CONST char *prefix ));
 
-LDAP_F( int )
-ldap_ufn_timeout LDAP_P((
+LIBLDAP_F( int )
+ldap_ufn_timeout LDAP_P(( /* deprecated */
        void *tvparam ));
 
 
 /*
  * in unbind.c
  */
-LDAP_F( int )
-ldap_unbind LDAP_P((
+LIBLDAP_F( int )
+ldap_unbind LDAP_P(( /* deprecated */
        LDAP *ld ));
 
-LDAP_F( int )
-ldap_unbind_s LDAP_P((
+LIBLDAP_F( int )
+ldap_unbind_s LDAP_P(( /* deprecated */
        LDAP *ld ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_unbind_ext LDAP_P((
        LDAP                    *ld,
        LDAPControl             **serverctrls,
        LDAPControl             **clientctrls));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_unbind_ext_s LDAP_P((
        LDAP                    *ld,
        LDAPControl             **serverctrls,
@@ -1308,34 +1370,35 @@ ldap_unbind_ext_s LDAP_P((
 
 /*
  * in getfilter.c
+ *     (deprecated)
  */
-LDAP_F( LDAPFiltDesc *)
-ldap_init_getfilter LDAP_P((
+LIBLDAP_F( LDAPFiltDesc *)
+ldap_init_getfilter LDAP_P(( /* deprecated */
        LDAP_CONST char *fname ));
 
-LDAP_F( LDAPFiltDesc *)
-ldap_init_getfilter_buf LDAP_P((
+LIBLDAP_F( LDAPFiltDesc *)
+ldap_init_getfilter_buf LDAP_P(( /* deprecated */
        /* LDAP_CONST */ char *buf,
        ber_len_t buflen ));
 
-LDAP_F( LDAPFiltInfo *)
-ldap_getfirstfilter LDAP_P((
+LIBLDAP_F( LDAPFiltInfo *)
+ldap_getfirstfilter LDAP_P(( /* deprecated */
        LDAPFiltDesc *lfdp,
        /* LDAP_CONST */ char *tagpat,
        /* LDAP_CONST */ char *value ));
 
-LDAP_F( LDAPFiltInfo *)
-ldap_getnextfilter LDAP_P((
+LIBLDAP_F( LDAPFiltInfo *)
+ldap_getnextfilter LDAP_P(( /* deprecated */
        LDAPFiltDesc *lfdp ));
 
-LDAP_F( void )
-ldap_setfilteraffixes LDAP_P((
+LIBLDAP_F( void )
+ldap_setfilteraffixes LDAP_P(( /* deprecated */
        LDAPFiltDesc *lfdp,
        LDAP_CONST char *prefix,
        LDAP_CONST char *suffix ));
 
-LDAP_F( void )
-ldap_build_filter LDAP_P((
+LIBLDAP_F( void )
+ldap_build_filter LDAP_P(( /* deprecated */
        char *buf,
        ber_len_t buflen,
        LDAP_CONST char *pattern,
@@ -1350,37 +1413,37 @@ ldap_build_filter LDAP_P((
  * in free.c
  */
 
-LDAP_F( void * )
+LIBLDAP_F( void * )
 ldap_memalloc LDAP_P((
        ber_len_t s ));
 
-LDAP_F( void * )
+LIBLDAP_F( void * )
 ldap_memrealloc LDAP_P((
        void* p,
        ber_len_t s ));
 
-LDAP_F( void * )
+LIBLDAP_F( void * )
 ldap_memcalloc LDAP_P((
        ber_len_t n,
        ber_len_t s ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_memfree LDAP_P((
        void* p ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_memvfree LDAP_P((
        void** v ));
 
-LDAP_F( char * )
+LIBLDAP_F( char * )
 ldap_strdup LDAP_P((
        LDAP_CONST char * ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_getfilter_free LDAP_P((
        LDAPFiltDesc *lfdp ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_mods_free LDAP_P((
        LDAPMod **mods,
        int freemods ));
@@ -1388,32 +1451,35 @@ ldap_mods_free LDAP_P((
 
 /*
  * in friendly.c
+ *     (deprecated)
  */
-LDAP_F( char * )
-ldap_friendly_name LDAP_P((
+LIBLDAP_F( char * )
+ldap_friendly_name LDAP_P(( /* deprecated */
        LDAP_CONST char *filename,
        /* LDAP_CONST */ char *uname,
        LDAPFriendlyMap **map ));
 
-LDAP_F( void )
-ldap_free_friendlymap LDAP_P((
+LIBLDAP_F( void )
+ldap_free_friendlymap LDAP_P(( /* deprecated */
        LDAPFriendlyMap **map ));
 
 
 /*
  * in cldap.c
+ *     (deprecated)
  */
-LDAP_F( LDAP * )
-cldap_open LDAP_P((
+LIBLDAP_F( LDAP * )
+cldap_open LDAP_P((    /* deprecated */
        LDAP_CONST char *host,
        int port ));
 
-LDAP_F( void )
-cldap_close LDAP_P((
+LIBLDAP_F( void )
+cldap_close LDAP_P((   /* deprecated */
        LDAP *ld ));
 
-LDAP_F( int )
-cldap_search_s LDAP_P(( LDAP *ld,
+LIBLDAP_F( int )
+cldap_search_s LDAP_P(( /* deprecated */
+       LDAP *ld,
        LDAP_CONST char *base,
        int scope,
        LDAP_CONST char *filter,
@@ -1422,8 +1488,8 @@ cldap_search_s LDAP_P(( LDAP *ld,
        LDAPMessage **res,
        char *logdn ));
 
-LDAP_F( void )
-cldap_setretryinfo LDAP_P((
+LIBLDAP_F( void )
+cldap_setretryinfo LDAP_P(( /* deprecated */
        LDAP *ld,
        int tries,
        int timeout ));
@@ -1432,19 +1498,27 @@ cldap_setretryinfo LDAP_P((
 /*
  * in sort.c
  */
-LDAP_F( int )
+typedef int (LDAP_SORT_AD_CMP_PROC) LDAP_P((
+       LDAP_CONST char *left,
+       LDAP_CONST char *right ));
+
+typedef int (LDAP_SORT_AV_CMP_PROC) LDAP_P((
+       LDAP_CONST void *left,
+       LDAP_CONST void *right ));
+
+LIBLDAP_F( int )
 ldap_sort_entries LDAP_P(( LDAP *ld,
        LDAPMessage **chain,
        LDAP_CONST char *attr,
-       int (*cmp) (LDAP_CONST char *, LDAP_CONST char *) ));
+       LDAP_SORT_AD_CMP_PROC *cmp ));
 
-LDAP_F( int )
+LIBLDAP_F( int )       /* deprecated */
 ldap_sort_values LDAP_P((
        LDAP *ld,
        char **vals,
-       int (*cmp) (LDAP_CONST void *, LDAP_CONST void *) ));
+       LDAP_SORT_AV_CMP_PROC *cmp ));
 
-LDAP_F( int )
+LIBLDAP_F( int ) /* deprecated */
 ldap_sort_strcasecmp LDAP_P((
        LDAP_CONST void *a,
        LDAP_CONST void *b ));
@@ -1455,37 +1529,41 @@ ldap_sort_strcasecmp LDAP_P((
  *
  * need _ext varients
  */
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_is_ldap_url LDAP_P((
        LDAP_CONST char *url ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_is_ldaps_url LDAP_P((
        LDAP_CONST char *url ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
+ldap_is_ldapi_url LDAP_P((
+       LDAP_CONST char *url ));
+
+LIBLDAP_F( int )
 ldap_url_parse LDAP_P((
        LDAP_CONST char *url,
        LDAPURLDesc **ludpp ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_free_urldesc LDAP_P((
        LDAPURLDesc *ludp ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_url_search LDAP_P((
        LDAP *ld,
        LDAP_CONST char *url,
        int attrsonly ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_url_search_s LDAP_P((
        LDAP *ld,
        LDAP_CONST char *url,
        int attrsonly,
        LDAPMessage **res ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_url_search_st LDAP_P((
        LDAP *ld,
        LDAP_CONST char *url,
@@ -1493,49 +1571,75 @@ ldap_url_search_st LDAP_P((
        struct timeval *timeout,
        LDAPMessage **res ));
 
-
+/* 
+ * in sortctrl.c  
+ */
 /*
- * in charset.c
- *     DEPRECATED
+ * structure for a sort-key 
  */
-LDAP_F( void )
-ldap_set_string_translators LDAP_P((
-       LDAP *ld,
-       BERTranslateProc encode_proc,
-       BERTranslateProc decode_proc ));
-
-LDAP_F( int )
-ldap_translate_from_t61 LDAP_P((
-       LDAP *ld,
-       char **bufp,
-       ber_len_t *lenp,
-       int free_input ));
+typedef struct ldapsortkey {
+       char *  attributeType;
+       char *  orderingRule;
+       int     reverseOrder;
+} LDAPSortKey;
+
+LIBLDAP_F( int )
+ldap_create_sort_keylist LDAP_P((
+       LDAPSortKey ***sortKeyList,
+       char        *keyString ));
+
+LIBLDAP_F( void )
+ldap_free_sort_keylist LDAP_P((
+       LDAPSortKey **sortkeylist ));
+
+LIBLDAP_F( int )
+ldap_create_sort_control LDAP_P((      
+       LDAP *ld, 
+       LDAPSortKey **keyList,
+       int ctl_iscritical,
+       LDAPControl **ctrlp ));
+
+LIBLDAP_F( int )
+ldap_parse_sort_control LDAP_P((
+       LDAP           *ld, 
+       LDAPControl    **ctrlp,  
+       unsigned long  *result,
+       char           **attribute ));
 
-LDAP_F( int )
-ldap_translate_to_t61 LDAP_P((
-       LDAP *ld,
-       char **bufp,
-       ber_len_t *lenp,
-       int free_input ));
 
-LDAP_F( void )
-ldap_enable_translation LDAP_P((
-       LDAP *ld,
-       LDAPMessage *entry,
-       int enable ));
+/* 
+ * in vlvctrl.c  
+ */
 
-LDAP_F( int )
-ldap_t61_to_8859 LDAP_P((
-       char **bufp,
-       ber_len_t *buflenp,
-       int free_input ));
+/*
+ * structure for virtul 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;
+    struct berval  *ldvlv_attrvalue;
+    struct berval  *ldvlv_context;
+    void           *ldvlv_extradata;
+} LDAPVLVInfo;
+
+LIBLDAP_F( int ) 
+ldap_create_vlv_control LDAP_P((
+       LDAP *ld, 
+       LDAPVLVInfo *ldvlistp,
+       LDAPControl **ctrlp ));
+
+LIBLDAP_F( int )
+ldap_parse_vlv_control LDAP_P(( 
+       LDAP          *ld, 
+       LDAPControl   **ctrls,
+       unsigned long *target_posp, 
+       unsigned long *list_countp, 
+       struct berval **contextp,
+       int           *errcodep ));
 
-LDAP_F( int )
-ldap_8859_to_t61 LDAP_P((
-       char **bufp,
-       ber_len_t *buflenp,
-       int free_input ));
 
 LDAP_END_DECL
-
 #endif /* _LDAP_H */
index dc5722d82e38a6d34405e96875d0198e84f1ecb6..c4e78b4cc2023d3b785a54e6d838779014b1f090 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 
 #endif /* no prototypes */
 
-#if _WIN32 && _DLL
-#      define LDAP_F_IMPORT    extern __declspec( dllimport )
-#      define LDAP_F_EXPORT    extern __declspec( dllexport )
-#else
-#      define LDAP_F_IMPORT    extern
-#      define LDAP_F_EXPORT    extern
-#endif
-
 #if (__GNUC__) * 1000 + (__GNUC_MINOR__) >= 2006
 #      define LDAP_GCCATTR(attrs)      __attribute__(attrs)
 #else
 #endif
 
 
-#endif /* _LDAP_CDEFS_H */
+/* Support for NT dynamic libraries. */
+
+/*
+ * C library. Mingw32 links with the C run-time library by default,
+ * so the explicit definition of CSTATIC will keep dllimport from
+ * being defined.
+ */
+#if (defined(__MINGW32__) && !defined(CSTATIC) || \
+     defined(_WIN32) && defined(_DLL))
+#      define LIBC_F(type)     extern __declspec(dllimport) type
+#else
+#      define LIBC_F(type)     extern type
+#endif
 
-/* purposely allow these to be redefined */
-#ifndef LDAP_F_PRE
-#      define LDAP_F_PRE       LDAP_F_IMPORT
+/* AVL library */
+#if defined(LIBAVL_DECL) && defined(_WIN32)
+#      define LIBAVL_F(type)   extern __declspec(LIBAVL_DECL) type
+#else
+#      define LIBAVL_F(type)   extern type
 #endif
-#ifndef LDAP_F_POST
-#      define LDAP_F_POST      /* no post */
+
+/* LBER library */
+#if defined(LIBLBER_DECL) && defined(_WIN32)
+#      define LIBLBER_F(type)  extern __declspec(LIBLBER_DECL) type
+#else
+#      define LIBLBER_F(type)  extern type
 #endif
-#ifndef LDAP_F
-#define LDAP_F(type)   LDAP_F_PRE type LDAP_F_POST
+
+/* LDAP library */
+#if defined(LIBLDAP_DECL) && defined(_WIN32)
+#      define LIBLDAP_F(type)  extern __declspec(LIBLDAP_DECL) type
+#else
+#      define LIBLDAP_F(type)  extern type
 #endif
 
+/* LDBM library */
+#if defined(LIBLDBM_DECL) && defined(_WIN32)
+#      define LIBLDBM_F(type)  extern __declspec(LIBLDBM_DECL) type
+#else
+#      define LIBLDBM_F(type)  extern type
+#endif
+
+/* LDIF library */
+#if defined(LIBLDIF_DECL) && defined(_WIN32)
+#      define LIBLDIF_F(type)  extern __declspec(LIBLDIF_DECL) type
+#else
+#      define LIBLDIF_F(type)  extern type
+#endif
+
+/* LUTIL library */
+#if defined(LIBLUTIL_DECL) && defined(_WIN32)
+#      define LIBLUTIL_F(type) extern __declspec(LIBLUTIL_DECL) type
+#else
+#      define LIBLUTIL_F(type) extern type
+#endif
+
+/* SLAPD (as a module exporting symbols) */
+#if defined(LIBSLAPD_DECL) && defined(_WIN32)
+#      define LIBSLAPD_F(type) extern __declspec(LIBSLAPD_DECL) type
+#else
+#      define LIBSLAPD_F(type) extern type
+#endif
+
+#endif /* _LDAP_CDEFS_H */
index a7d0f01cb9b1330ddd29b910572041b98009d8fe..63b604f6ea62f9478d80eb0dfcd9067006a44d65 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 
 /* directory separator */
 #ifndef LDAP_DIRSEP
+#ifndef _WIN32
 #define LDAP_DIRSEP "/"
+#else
+#define LDAP_DIRSEP "\\"
+#endif
 #endif
 
 /* directories */
index ce3597a76b481507b65c169d9bd18c22385dea1e..cee39be0b44282a265e58b528ab18df66b85264e 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
@@ -10,7 +10,7 @@
  */
 
 /*
- * This file works in confunction with OpenLDAP configure system.
+ * This file works in confunction with OpenLDAP setup.mak system.
  * If you do no like the values below, adjust your configure options.
  */
 
index 0b27fff34ea53a2b5136861f5c92ba0d88289bc8..14ee2137d190c7417f7b452df858ce07de6ee195 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
@@ -22,7 +22,7 @@
 
 /*
  * This file controls defaults for OpenLDAP package.
- * You should not change any of these settings.
+ * You probably do not need to edit the defaults provided by this file.
  */
 
 #ifndef _LDAP_DEFAULTS_H
 #define LDAP_ENV_PREFIX "LDAP"
 
 
-/*********************************************************************
- *                                                                   *
- * You probably do not need to edit anything below this point        *
- *                                                                   *
- *********************************************************************/
-
 /*
  * SHARED DEFINITIONS - other things you can change
  */
@@ -208,14 +202,16 @@ Please try again later.\r\n"
        /* 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          4000
+#define SLAPD_LDBM_MIN_MAXIDS          (8192-4)
 
-/* the following DNs must be normalized and in uppercase! */
+/* the following DNs must be normalized! */
+       /* dn of the special "schema" entry */
+#define SLAPD_SCHEMA_DN                        "cn=Schema"
+#if 0
        /* dn of the special "monitor" entry */
-#define SLAPD_MONITOR_DN               "CN=MONITOR"
+#define SLAPD_MONITOR_DN               "cn=Monitor"
        /* dn of the special "config" entry */
-#define SLAPD_CONFIG_DN                        "CN=CONFIG"
-       /* dn of the special "schema" entry */
-#define SLAPD_SCHEMA_DN                        "CN=SCHEMA"
+#define SLAPD_CONFIG_DN                        "cn=Config"
+#endif
 
 #endif /* _LDAP_CONFIG_H */
index 62c3b5a167fe1a033bc0d4c675110a41f4b6ca79..1722986246db9c3572b54556c96c5377bbc4b5e8 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 /* is threadsafe version of -lldap (ie: -lldap_r) *available* or not */
 #undef LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE
 
-/* LDAP v2 DNS */
-#undef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
+/* LDAP v2 Kerberos Bind */
+#undef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
 
 /* LDAP v2 Referrals */
 #undef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
 
+/* LDAP Server Side Sort. */
+#define LDAP_API_FEATURE_SERVER_SIDE_SORT 1000
+
+/* LDAP Virtual List View. */ 
+#define LDAP_API_FEATURE_VIRTUAL_LIST_VIEW 1000
+
 #endif /* LDAP_FEATURES */
index 29cd0a5314f6437b97ba14a3d4b85e36e15a9ed0..746e7d9f3e15c3ea30336fdd5e5b80a7b9ed0c5a 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 /* is threadsafe version of -lldap (ie: -lldap_r) *available* or not */
 #define LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE LDAP_VENDOR_VERSION
 
-/* LDAP v2 DNS */
-/* #undef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS */
-
 /* LDAP v2 Referrals */
 #define LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS LDAP_VENDOR_VERSION
 
+/* LDAP Server Side Sort. */
+#define LDAP_API_FEATURE_SERVER_SIDE_SORT 1000
+
+/* LDAP Virtual List View. Version = 1000 + draft revision.
+ * VLV requires Server Side Sort control.
+ */
+#define LDAP_API_FEATURE_VIRTUAL_LIST_VIEW 1000
+
 #endif /* LDAP_FEATURES */
diff --git a/include/ldap_int_thread.h b/include/ldap_int_thread.h
new file mode 100644 (file)
index 0000000..f89afb5
--- /dev/null
@@ -0,0 +1,201 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted only
+ * as authorized by the OpenLDAP Public License.  A copy of this
+ * license is available at http://www.OpenLDAP.org/license.html or
+ * in file LICENSE in the top-level directory of the distribution.
+ */
+/* ldap_int_thread.h - ldap internal thread wrappers header file */
+
+#ifndef _LDAP_INT_THREAD_H
+#define _LDAP_INT_THREAD_H
+
+#if defined( HAVE_PTHREADS )
+/**********************************
+ *                                *
+ * definitions for POSIX Threads  *
+ *                                *
+ **********************************/
+
+#include <pthread.h>
+#ifdef HAVE_SCHED_H
+#include <sched.h>
+#endif
+
+LDAP_BEGIN_DECL
+
+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;
+
+#if defined( _POSIX_REENTRANT_FUNCTIONS ) || \
+       defined( _POSIX_THREAD_SAFE_FUNCTIONS ) || \
+       defined( _POSIX_THREADSAFE_FUNCTIONS )
+#define HAVE_REENTRANT_FUNCTIONS 1
+#endif
+
+#if defined( HAVE_PTHREAD_GETCONCURRENCY ) || \
+       defined( HAVE_THR_GETCONCURRENCY )
+#define LDAP_THREAD_HAVE_GETCONCURRENCY 1
+#endif
+
+#if defined( HAVE_PTHREAD_SETCONCURRENCY ) || \
+       defined( HAVE_THR_SETCONCURRENCY )
+#define LDAP_THREAD_HAVE_SETCONCURRENCY 1
+#endif
+
+#if 0 && defined( HAVE_PTHREAD_RWLOCK_DESTROY )
+#define LDAP_THREAD_HAVE_RDWR 1
+typedef pthread_rwlock_t ldap_pvt_thread_rdwr_t;
+#endif
+
+LDAP_END_DECL
+
+#elif defined ( HAVE_MACH_CTHREADS )
+/**********************************
+ *                                *
+ * definitions for Mach CThreads  *
+ *                                *
+ **********************************/
+
+#include <mach/cthreads.h>
+
+LDAP_BEGIN_DECL
+
+typedef cthread_t              ldap_int_thread_t;
+typedef struct mutex           ldap_int_thread_mutex_t;
+typedef struct condition       ldap_int_thread_cond_t;
+
+LDAP_END_DECL
+
+#elif defined( HAVE_GNU_PTH )
+/***********************************
+ *                                 *
+ * thread definitions for GNU Pth  *
+ *                                 *
+ ***********************************/
+
+#define PTH_SYSCALL_SOFT 1
+#include <pth.h>
+
+LDAP_BEGIN_DECL
+
+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;
+
+#if 0
+#define LDAP_THREAD_HAVE_RDWR 1
+typedef pth_rwlock_t ldap_pvt_thread_rdwr_t;
+#endif
+
+LDAP_END_DECL
+
+#elif defined( HAVE_THR )
+/********************************************
+ *                                          *
+ * thread definitions for Solaris LWP (THR) *
+ *                                          *
+ ********************************************/
+
+#include <thread.h>
+#include <synch.h>
+
+LDAP_BEGIN_DECL
+
+typedef thread_t               ldap_int_thread_t;
+typedef mutex_t                        ldap_int_thread_mutex_t;
+typedef cond_t                 ldap_int_thread_cond_t;
+
+#define HAVE_REENTRANT_FUNCTIONS 1
+
+#ifdef HAVE_THR_GETCONCURRENCY
+#define LDAP_THREAD_HAVE_GETCONCURRENCY 1
+#endif
+#ifdef HAVE_THR_SETCONCURRENCY
+#define LDAP_THREAD_HAVE_SETCONCURRENCY 1
+#endif
+
+LDAP_END_DECL
+
+#elif defined( HAVE_LWP )
+/*************************************
+ *                                   *
+ * thread definitions for SunOS LWP  *
+ *                                   *
+ *************************************/
+
+#include <lwp/lwp.h>
+#include <lwp/stackdep.h>
+#define LDAP_THREAD_HAVE_SLEEP 1
+
+LDAP_BEGIN_DECL
+
+typedef thread_t               ldap_int_thread_t;
+typedef mon_t                  ldap_int_thread_mutex_t;
+struct ldap_int_thread_lwp_cv {
+       int             lcv_created;
+       cv_t            lcv_cv;
+};
+typedef struct ldap_int_thread_lwp_cv ldap_int_thread_cond_t;
+
+#define HAVE_REENTRANT_FUNCTIONS 1
+
+LDAP_END_DECL
+
+#elif defined(HAVE_NT_THREADS)
+
+#include <process.h>
+#include <windows.h>
+
+LDAP_BEGIN_DECL
+
+typedef unsigned long  ldap_int_thread_t;
+typedef HANDLE ldap_int_thread_mutex_t;
+typedef HANDLE ldap_int_thread_cond_t;
+
+LDAP_END_DECL
+
+#else
+
+/***********************************
+ *                                 *
+ * thread definitions for no       *
+ * underlying library support      *
+ *                                 *
+ ***********************************/
+
+#ifndef NO_THREADS
+#define NO_THREADS 1
+#endif
+
+LDAP_BEGIN_DECL
+
+typedef int                    ldap_int_thread_t;
+typedef int                    ldap_int_thread_mutex_t;
+typedef int                    ldap_int_thread_cond_t;
+
+#define LDAP_THREAD_HAVE_TPOOL 1
+typedef int                    ldap_int_thread_pool_t;
+
+LDAP_END_DECL
+
+#endif /* no threads support */
+
+LDAP_BEGIN_DECL
+
+LIBLDAP_F(int) ldap_int_thread_initialize LDAP_P(( void ));
+LIBLDAP_F(int) ldap_int_thread_destroy LDAP_P(( void ));
+LIBLDAP_F(int) ldap_int_thread_pool_startup ( void );
+LIBLDAP_F(int) ldap_int_thread_pool_shutdown ( void );
+
+#ifndef LDAP_THREAD_HAVE_TPOOL
+typedef struct ldap_int_thread_pool_s * ldap_int_thread_pool_t;
+#endif
+
+LDAP_END_DECL
+
+#endif /* _LDAP_INT_THREAD_H */
index dfb2e7a9cdc78d171a87805eed297686644f8836..1ba0b42d68106911eb8f9ad3e8376be60bc80023 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
@@ -47,6 +47,10 @@ LDAP_BEGIN_DECL
 /* debugging stuff */
 #ifdef LDAP_DEBUG
 
+/*
+ * 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 */
@@ -74,7 +78,7 @@ extern int    ldap_syslog_level;
 #define Debug( level, fmt, arg1, arg2, arg3 )
 #endif /* LDAP_DEBUG */
 
-LDAP_F(void) lutil_debug LDAP_P((
+LIBLUTIL_F(void) lutil_debug LDAP_P((
        int debug, int level,
        const char* fmt, ... )) LDAP_GCCATTR((format(printf, 3, 4)));
 
index 2b20ed49298e7e524d89ed76cd2ef7c784d18c17..7107c9b8ec0b9e5ffa3847d13fe4d9b6c7b5eda9 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 
 LDAP_BEGIN_DECL
 
+#define LDAP_PROTO_TCP 1
+#define LDAP_PROTO_UDP 2
+#define LDAP_PROTO_IPC 3
+
+LIBLDAP_F ( int )
+ldap_pvt_url_scheme2proto LDAP_P((
+       const char * ));
+LIBLDAP_F ( int )
+ldap_pvt_url_scheme2tls LDAP_P((
+       const char * ));
+
+
+LIBLDAP_F ( int )
+ldap_pvt_domain2dn LDAP_P((
+       LDAP_CONST char *domain,
+       char **dn ));
+
 struct hostent;        /* avoid pulling in <netdb.h> */
 
-LDAP_F( char * )
+LIBLDAP_F( char * )
 ldap_pvt_ctime LDAP_P((
        const time_t *tp,
        char *buf ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_gethostbyname_a LDAP_P((
        const char *name, 
        struct hostent *resbuf,
@@ -36,7 +53,7 @@ ldap_pvt_gethostbyname_a LDAP_P((
        struct hostent **result,
        int *herrno_ptr ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_gethostbyaddr_a LDAP_P((
        const char *addr,
        int len,
@@ -49,35 +66,35 @@ ldap_pvt_gethostbyaddr_a LDAP_P((
 
 /* charray.c */
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_charray_add LDAP_P((
     char       ***a,
     char       *s ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_charray_merge LDAP_P((
     char       ***a,
     char       **s ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_charray_free LDAP_P(( char **a ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_charray_inlist LDAP_P((
     char       **a,
     char       *s ));
 
-LDAP_F( char ** )
+LIBLDAP_F( char ** )
 ldap_charray_dup LDAP_P(( char **a ));
 
-LDAP_F( char ** )
+LIBLDAP_F( char ** )
 ldap_str2charray LDAP_P((
-       char *str,
-       char *brkstr ));
+       const char *str,
+       const char *brkstr ));
 
 /* url.c */
-void ldap_pvt_hex_unescape LDAP_P(( char *s ));
-int ldap_pvt_unhex( int c );
+LIBLDAP_F (void) ldap_pvt_hex_unescape LDAP_P(( char *s ));
+LIBLDAP_F (int) ldap_pvt_unhex( int c );
 
 /* these macros assume 'x' is an ASCII x */
 #define LDAP_DNSEPARATOR(c)    ((c) == ',' || (c) == ';')
@@ -100,20 +117,114 @@ int ldap_pvt_unhex( int c );
 
 #define LDAP_NEEDSESCAPE(c)    ((c) == '\\' || (c) == '"')
 
+#ifdef HAVE_CYRUS_SASL
+/* sasl.c */
+
+#include <sasl.h>
+#include <ldap.h> 
+
+LIBLDAP_F (int) ldap_pvt_sasl_init LDAP_P(( void )); /* clientside init */
+LIBLDAP_F (int) ldap_pvt_sasl_install LDAP_P(( Sockbuf *, void * ));
+LIBLDAP_F (int) ldap_pvt_sasl_bind LDAP_P(( LDAP *, LDAP_CONST char *,
+       LDAP_CONST char *, LDAP_CONST sasl_callback_t *, LDAPControl **,
+       LDAPControl ** ));
+LIBLDAP_F (int) ldap_pvt_sasl_get_option LDAP_P(( LDAP *ld, int option,
+       void *arg ));
+LIBLDAP_F (int) ldap_pvt_sasl_set_option LDAP_P(( LDAP *ld, int option,
+       void *arg ));
+#endif /* HAVE_CYRUS_SASL */
+
 /* search.c */
-LDAP_F( char * )
-ldap_pvt_find_wildcard LDAP_P((        char *s ));
+LIBLDAP_F( char * )
+ldap_pvt_find_wildcard LDAP_P((        const char *s ));
 
-LDAP_F( ber_slen_t )
+LIBLDAP_F( ber_slen_t )
 ldap_pvt_filter_value_unescape LDAP_P(( char *filter ));
 
 /* string.c */
-LDAP_F( char * )
+LIBLDAP_F( char * )
 ldap_pvt_str2upper LDAP_P(( char *str ));
 
-LDAP_F( char * )
+LIBLDAP_F( char * )
 ldap_pvt_str2lower LDAP_P(( char *str ));
 
+/* tls.c */
+struct ldapoptions;
+struct ldap;
+
+LIBLDAP_F (int) ldap_pvt_tls_init LDAP_P(( void ));
+LIBLDAP_F (int) ldap_pvt_tls_config LDAP_P(( struct ldapoptions *lo, int option, const char *arg ));
+LIBLDAP_F (int) ldap_pvt_tls_connect LDAP_P(( struct ldap *ld, Sockbuf *sb, void *ctx_arg ));
+LIBLDAP_F (int) ldap_pvt_tls_accept LDAP_P(( Sockbuf *sb, void *ctx_arg ));
+LIBLDAP_F (int) ldap_pvt_tls_get_option LDAP_P(( struct ldapoptions *lo, int option, void *arg ));
+LIBLDAP_F (int) ldap_pvt_tls_set_option LDAP_P(( struct ldapoptions *lo, int option, void *arg ));
+LIBLDAP_F (void *) ldap_pvt_tls_sb_handle LDAP_P(( Sockbuf *sb ));
+LIBLDAP_F (void *) ldap_pvt_tls_get_handle LDAP_P(( struct ldap *ld ));
+LIBLDAP_F (int) ldap_pvt_tls_inplace LDAP_P(( Sockbuf *sb ));
+LIBLDAP_F (int) ldap_pvt_tls_start LDAP_P(( struct ldap *ld, Sockbuf *sb, void *ctx_arg ));
+
+/*  
+ * UTF-8 (in utf-8.c)
+ */
+
+typedef ber_int_t ldap_ucs4_t;
+typedef short ldap_ucs2_t;
+typedef ldap_ucs2_t ldap_unicode_t;
+
+/* returns the number of bytes in the UTF-8 string */
+LIBLDAP_F (ber_len_t) ldap_utf8_bytes( const char * );
+/* returns the number of UTF-8 characters in the string */
+LIBLDAP_F (ber_len_t) ldap_utf8_chars( const char * );
+/* returns the length (in bytes) of the UTF-8 character */
+LIBLDAP_F (int) ldap_utf8_offset( const char * );
+/* returns the length (in bytes) indicated by the UTF-8 character */
+LIBLDAP_F (int) ldap_utf8_charlen( const char * );
+/* copies a UTF-8 character and returning number of bytes copied */
+LIBLDAP_F (int) ldap_utf8_copy( char *, const char *);
+
+/* returns pointer of next UTF-8 character in string */
+LIBLDAP_F (char*) ldap_utf8_next( const char * );
+/* returns pointer of previous UTF-8 character in string */
+LIBLDAP_F (char*) ldap_utf8_prev( const char * );
+
+/* primitive ctype routines -- not aware of non-ascii characters */
+LIBLDAP_F (int) ldap_utf8_isascii( const char * );
+LIBLDAP_F (int) ldap_utf8_isalpha( const char * );
+LIBLDAP_F (int) ldap_utf8_isalnum( const char * );
+LIBLDAP_F (int) ldap_utf8_isdigit( const char * );
+LIBLDAP_F (int) ldap_utf8_isxdigit( const char * );
+LIBLDAP_F (int) ldap_utf8_isspace( const char * );
+
+/* span characters not in set, return bytes spanned */
+LIBLDAP_F (ber_len_t) ldap_utf8_strcspn( const char* str, const char *set);
+/* span characters in set, return bytes spanned */
+LIBLDAP_F (ber_len_t) ldap_utf8_strspn( const char* str, const char *set);
+/* return first occurance of character in string */
+LIBLDAP_F (char *) ldap_utf8_strchr( const char* str, const char *chr);
+/* return first character of set in string */
+LIBLDAP_F (char *) ldap_utf8_strpbrk( const char* str, const char *set);
+/* reentrant tokenizer */
+LIBLDAP_F (char*) ldap_utf8_strtok( char* sp, const char* sep, char **last);
+
+/* Optimizations */
+#define LDAP_UTF8_ISASCII(p) ( * (const unsigned char *) (p) < 0x100 )
+#define LDAP_UTF8_CHARLEN(p) ( LDAP_UTF8_ISASCII(p) \
+       ? 1 : ldap_utf8_charlen((p)) )
+#define LDAP_UTF8_OFFSET(p) ( LDAP_UTF8_ISASCII(p) \
+       ? 1 : ldap_utf8_offset((p)) )
+
+#define LDAP_UTF8_COPY(d,s) (  LDAP_UTF8_ISASCII(s) \
+       ? (*(d) = *(s), 1) : ldap_utf8_copy((d),(s)) )
+
+#define LDAP_UTF8_NEXT(p) (    LDAP_UTF8_ISASCII(p) \
+       ? (char *)(p)+1 : ldap_utf8_next((p)) )
+
+#define LDAP_UTF8_INCR(p) ((p) = LDAP_UTF8_NEXT(p))
+
+/* For symmetry */
+#define LDAP_UTF8_PREV(p) (ldap_utf8_prev((p)))
+#define LDAP_UTF8_DECR(p) ((p)=LDAP_UTF8_PREV((p)))
+
 LDAP_END_DECL
 
 #endif
index a006a2ef6637d24e5ea83c0630bef17a956fdfcb..23df121b1ec3c7cce02babb9ac6f510eb2cda324 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 #define _LDAP_PVT_THREAD_H
 
 #include "ldap_cdefs.h"
-
-#if defined( HAVE_PTHREADS )
-/**********************************
- *                                *
- * definitions for POSIX Threads  *
- *                                *
- **********************************/
-
-#include <pthread.h>
-#ifdef HAVE_SCHED_H
-#include <sched.h>
-#endif
-
-LDAP_BEGIN_DECL
-
-typedef pthread_t              ldap_pvt_thread_t;
-typedef pthread_mutex_t                ldap_pvt_thread_mutex_t;
-typedef pthread_cond_t         ldap_pvt_thread_cond_t;
-
-#if defined( _POSIX_REENTRANT_FUNCTIONS ) || \
-       defined( _POSIX_THREAD_SAFE_FUNCTIONS ) || \
-       defined( _POSIX_THREADSAFE_FUNCTIONS )
-#define HAVE_REENTRANT_FUNCTIONS 1
-#endif
-
-#if defined( HAVE_PTHREAD_GETCONCURRENCY ) || \
-       defined( HAVE_THR_GETCONCURRENCY )
-#define HAVE_GETCONCURRENCY 1
-#endif
-
-#if defined( HAVE_PTHREAD_SETCONCURRENCY ) || \
-       defined( HAVE_THR_SETCONCURRENCY )
-#define HAVE_SETCONCURRENCY 1
-#endif
-
-LDAP_END_DECL
-
-#elif defined ( HAVE_MACH_CTHREADS )
-/**********************************
- *                                *
- * definitions for Mach CThreads  *
- *                                *
- **********************************/
-
-#include <mach/cthreads.h>
-
-LDAP_BEGIN_DECL
-
-typedef cthread_t              ldap_pvt_thread_t;
-typedef struct mutex           ldap_pvt_thread_mutex_t;
-typedef struct condition       ldap_pvt_thread_cond_t;
-
-LDAP_END_DECL
-
-#elif defined( HAVE_GNU_PTH )
-/***********************************
- *                                 *
- * thread definitions for GNU Pth  *
- *                                 *
- ***********************************/
-
-#include <pth.h>
-
-LDAP_BEGIN_DECL
-
-typedef pth_t          ldap_pvt_thread_t;
-typedef pth_mutex_t    ldap_pvt_thread_mutex_t;
-typedef pth_cond_t     ldap_pvt_thread_cond_t;
-
-LDAP_END_DECL
-
-
-#elif defined( HAVE_THR )
-/********************************************
- *                                          *
- * thread definitions for Solaris LWP (THR) *
- *                                          *
- ********************************************/
-
-#include <thread.h>
-#include <synch.h>
-
-LDAP_BEGIN_DECL
-
-typedef thread_t               ldap_pvt_thread_t;
-typedef mutex_t                        ldap_pvt_thread_mutex_t;
-typedef cond_t                 ldap_pvt_thread_cond_t;
-
-#define HAVE_REENTRANT_FUNCTIONS 1
-
-#ifdef HAVE_THR_GETCONCURRENCY
-#define HAVE_GETCONCURRENCY 1
-#endif
-#ifdef HAVE_THR_SETCONCURRENCY
-#define HAVE_SETCONCURRENCY 1
-#endif
-
-LDAP_END_DECL
-
-#elif defined( HAVE_LWP )
-/*************************************
- *                                   *
- * thread definitions for SunOS LWP  *
- *                                   *
- *************************************/
-
-#include <lwp/lwp.h>
-#include <lwp/stackdep.h>
+#include "ldap_int_thread.h"
 
 LDAP_BEGIN_DECL
 
-typedef thread_t               ldap_pvt_thread_t;
-typedef mon_t                  ldap_pvt_thread_mutex_t;
-struct ldap_pvt_thread_lwp_cv {
-       int             lcv_created;
-       cv_t            lcv_cv;
-};
-typedef struct ldap_pvt_thread_lwp_cv ldap_pvt_thread_cond_t;
-
-#define HAVE_REENTRANT_FUNCTIONS 1
-
-LDAP_END_DECL
-
-#elif HAVE_NT_THREADS
-
-LDAP_BEGIN_DECL
-
-#define WIN32_LEAN_AND_MEAN
-#include <process.h>
-#include <windows.h>
-
-typedef unsigned long  ldap_pvt_thread_t;
-typedef HANDLE ldap_pvt_thread_mutex_t;
-typedef HANDLE ldap_pvt_thread_cond_t;
-
-LDAP_END_DECL
-
-#else
-
-/***********************************
- *                                 *
- * thread definitions for no       *
- * underlying library support      *
- *                                 *
- ***********************************/
-
-LDAP_BEGIN_DECL
+typedef ldap_int_thread_t ldap_pvt_thread_t;
+typedef ldap_int_thread_mutex_t ldap_pvt_thread_mutex_t;
+typedef ldap_int_thread_cond_t ldap_pvt_thread_cond_t;
 
-#ifndef NO_THREADS
-#define NO_THREADS 1
-#endif
-
-typedef int                    ldap_pvt_thread_t;
-typedef int                    ldap_pvt_thread_mutex_t;
-typedef int                    ldap_pvt_thread_cond_t;
-
-LDAP_END_DECL
-
-#endif /* no threads support */
-
-LDAP_BEGIN_DECL
-
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_initialize LDAP_P(( void ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_destroy LDAP_P(( void ));
 
-LDAP_F( unsigned int )
+LIBLDAP_F( unsigned int )
 ldap_pvt_thread_sleep LDAP_P(( unsigned int s ));
 
-#ifdef HAVE_GETCONCURRENCY
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_get_concurrency LDAP_P(( void ));
-#endif
 
-#ifdef HAVE_SETCONCURRENCY
-#      ifndef LDAP_THREAD_CONCURRENCY
-       /* three concurrent threads should be enough */
-#      define LDAP_THREAD_CONCURRENCY  3
-#      endif
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_set_concurrency LDAP_P(( int ));
-#endif
 
 #define LDAP_PVT_THREAD_CREATE_JOINABLE 0
 #define LDAP_PVT_THREAD_CREATE_DETACHED 1
 
-LDAP_F( int ) 
+LIBLDAP_F( int ) 
 ldap_pvt_thread_create LDAP_P((
        ldap_pvt_thread_t * thread, 
        int     detach,
        void *(*start_routine)( void * ), 
        void *arg));
 
-LDAP_F( void ) 
+LIBLDAP_F( void ) 
 ldap_pvt_thread_exit LDAP_P(( void *retval ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_join LDAP_P(( ldap_pvt_thread_t thread, void **status ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_kill LDAP_P(( ldap_pvt_thread_t thread, int signo ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_yield LDAP_P(( void ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_cond_init LDAP_P(( ldap_pvt_thread_cond_t *cond ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_cond_destroy LDAP_P(( ldap_pvt_thread_cond_t *cond ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_cond_signal LDAP_P(( ldap_pvt_thread_cond_t *cond ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_cond_broadcast LDAP_P(( ldap_pvt_thread_cond_t *cond ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_cond_wait LDAP_P((
        ldap_pvt_thread_cond_t *cond, 
        ldap_pvt_thread_mutex_t *mutex ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_mutex_init LDAP_P(( ldap_pvt_thread_mutex_t *mutex ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_mutex_destroy LDAP_P(( ldap_pvt_thread_mutex_t *mutex ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_mutex_lock LDAP_P(( ldap_pvt_thread_mutex_t *mutex ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_mutex_trylock LDAP_P(( ldap_pvt_thread_mutex_t *mutex ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_mutex_unlock LDAP_P(( ldap_pvt_thread_mutex_t *mutex ));
 
-typedef struct ldap_pvt_thread_rdwr_var {
-       ldap_pvt_thread_mutex_t ltrw_mutex;     
-       ldap_pvt_thread_cond_t ltrw_read;       /* wait for read */
-       ldap_pvt_thread_cond_t ltrw_write;      /* wait for write */
-       int ltrw_valid;
-#define LDAP_PVT_THREAD_RDWR_VALID 0x0bad
-       int ltrw_r_active;
-       int ltrw_w_active;
-       int ltrw_r_wait;
-       int ltrw_w_wait;
-} ldap_pvt_thread_rdwr_t;
-
-LDAP_F( int )
+#ifndef LDAP_THREAD_HAVE_RDWR
+typedef struct ldap_int_thread_rdwr_s * ldap_pvt_thread_rdwr_t;
+#endif
+
+LIBLDAP_F( int )
 ldap_pvt_thread_rdwr_init LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_rdwr_destroy LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_rdwr_rlock LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_rdwr_rtrylock LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_rdwr_runlock LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_rdwr_wlock LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_rdwr_wtrylock LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_rdwr_wunlock LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
 
 #ifdef LDAP_DEBUG
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_rdwr_readers LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_rdwr_writers LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_pvt_thread_rdwr_active LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
 #endif /* LDAP_DEBUG */
 
 #define LDAP_PVT_THREAD_EINVAL EINVAL
 #define LDAP_PVT_THREAD_EBUSY EINVAL
 
+typedef ldap_int_thread_pool_t ldap_pvt_thread_pool_t;
+
+LIBLDAP_F( int )
+ldap_pvt_thread_pool_init LDAP_P((
+       ldap_pvt_thread_pool_t *pool_out,
+       int max_concurrency,
+       int max_pending ));
+
+LIBLDAP_F( int )
+ldap_pvt_thread_pool_submit LDAP_P((
+       ldap_pvt_thread_pool_t *pool,
+       void *(*start_routine)( void * ),
+       void *arg ));
+
+LIBLDAP_F( int )
+ldap_pvt_thread_pool_backload LDAP_P((
+       ldap_pvt_thread_pool_t *pool ));
+
+LIBLDAP_F( int )
+ldap_pvt_thread_pool_destroy LDAP_P((
+       ldap_pvt_thread_pool_t *pool,
+       int run_pending ));
+
+
 LDAP_END_DECL
 
 #endif /* _LDAP_THREAD_H */
index c0c21bc88da4628f8368c64f783ea7c3be551b92..ec29616445569f1d2d3d1e58eec3d5db2bf9ad8b 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1999-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
@@ -33,9 +33,16 @@ LDAP_BEGIN_DECL
 #define LDAP_SCHERR_DUPOPT             9
 #define LDAP_SCHERR_EMPTY              10
 
+typedef struct ldap_schema_extension_item {
+       char *lsei_name;
+       char **lsei_values;
+} LDAP_SCHEMA_EXTENSION_ITEM;
+
 typedef struct ldap_syntax {
        char *syn_oid;          /* REQUIRED */
+       char **syn_names;       /* OPTIONAL */
        char *syn_desc;         /* OPTIONAL */
+       LDAP_SCHEMA_EXTENSION_ITEM **syn_extensions; /* OPTIONAL */
 } LDAP_SYNTAX;
 
 typedef struct ldap_matchingrule {
@@ -44,6 +51,7 @@ typedef struct ldap_matchingrule {
        char *mr_desc;          /* OPTIONAL */
        int  mr_obsolete;       /* OPTIONAL */
        char *mr_syntax_oid;    /* REQUIRED */
+       LDAP_SCHEMA_EXTENSION_ITEM **mr_extensions; /* OPTIONAL */
 } LDAP_MATCHING_RULE;
 
 typedef struct ldap_attributetype {
@@ -62,6 +70,7 @@ typedef struct ldap_attributetype {
        int  at_no_user_mod;    /* 0=no, 1=yes */
        int  at_usage;          /* 0=userApplications, 1=directoryOperation,
                                   2=distributedOperation, 3=dSAOperation */
+       LDAP_SCHEMA_EXTENSION_ITEM **at_extensions; /* OPTIONAL */
 } LDAP_ATTRIBUTE_TYPE;
 
 typedef struct ldap_objectclass {
@@ -73,6 +82,7 @@ typedef struct ldap_objectclass {
        int  oc_kind;           /* 0=ABSTRACT, 1=STRUCTURAL, 2=AUXILIARY */
        char **oc_at_oids_must; /* OPTIONAL */
        char **oc_at_oids_may;  /* OPTIONAL */
+       LDAP_SCHEMA_EXTENSION_ITEM **oc_extensions; /* OPTIONAL */
 } LDAP_OBJECT_CLASS;
 
 #define LDAP_SCHEMA_NO                         0
@@ -87,79 +97,93 @@ typedef struct ldap_objectclass {
 #define LDAP_SCHEMA_STRUCTURAL                 1
 #define LDAP_SCHEMA_AUXILIARY                  2
 
-LDAP_F( LDAP_CONST char * )
+/*
+ * Flags that control how liberal the parsing routines are.
+ */
+#define LDAP_SCHEMA_ALLOW_NONE         0x00 /* Strict parsing               */
+#define LDAP_SCHEMA_ALLOW_NO_OID       0x01 /* Allow missing oid            */
+#define LDAP_SCHEMA_ALLOW_QUOTED       0x02 /* Allow bogus extra quotes     */
+#define LDAP_SCHEMA_ALLOW_DESCR                0x04 /* Allow descr instead of OID   */
+#define LDAP_SCHEMA_ALLOW_DESCR_PREFIX 0x08 /* Allow descr as OID prefix    */
+#define LDAP_SCHEMA_ALLOW_ALL          0x0f /* Be very liberal in parsing   */
+
+LIBLDAP_F( LDAP_CONST char * )
 ldap_syntax2name LDAP_P((
        LDAP_SYNTAX * syn ));
 
-LDAP_F( LDAP_CONST char * )
+LIBLDAP_F( LDAP_CONST char * )
 ldap_matchingrule2name LDAP_P((
        LDAP_MATCHING_RULE * mr ));
 
-LDAP_F( LDAP_CONST char * )
+LIBLDAP_F( LDAP_CONST char * )
 ldap_attributetype2name LDAP_P((
        LDAP_ATTRIBUTE_TYPE * at ));
 
-LDAP_F( LDAP_CONST char * )
+LIBLDAP_F( LDAP_CONST char * )
 ldap_objectclass2name LDAP_P((
        LDAP_OBJECT_CLASS * oc ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_syntax_free LDAP_P((
        LDAP_SYNTAX * syn ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_matchingrule_free LDAP_P((
        LDAP_MATCHING_RULE * mr ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_attributetype_free LDAP_P((
        LDAP_ATTRIBUTE_TYPE * at ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_objectclass_free LDAP_P((
        LDAP_OBJECT_CLASS * oc ));
 
-LDAP_F( LDAP_OBJECT_CLASS * )
+LIBLDAP_F( LDAP_OBJECT_CLASS * )
 ldap_str2objectclass LDAP_P((
        LDAP_CONST char * s,
        int * code,
-       LDAP_CONST char ** errp ));
+       LDAP_CONST char ** errp,
+       LDAP_CONST int flags ));
 
-LDAP_F( LDAP_ATTRIBUTE_TYPE * )
+LIBLDAP_F( LDAP_ATTRIBUTE_TYPE * )
 ldap_str2attributetype LDAP_P((
        LDAP_CONST char * s,
        int * code,
-       LDAP_CONST char ** errp ));
+       LDAP_CONST char ** errp,
+       LDAP_CONST int flags ));
 
-LDAP_F( LDAP_SYNTAX * )
+LIBLDAP_F( LDAP_SYNTAX * )
 ldap_str2syntax LDAP_P((
        LDAP_CONST char * s,
        int * code,
-       LDAP_CONST char ** errp ));
+       LDAP_CONST char ** errp,
+       LDAP_CONST int flags ));
 
-LDAP_F( LDAP_MATCHING_RULE * )
+LIBLDAP_F( LDAP_MATCHING_RULE * )
 ldap_str2matchingrule LDAP_P((
        LDAP_CONST char * s,
        int * code,
-       LDAP_CONST char ** errp ));
+       LDAP_CONST char ** errp,
+       LDAP_CONST int flags ));
 
-LDAP_F( char *)
+LIBLDAP_F( char *)
 ldap_objectclass2str LDAP_P((
        LDAP_CONST LDAP_OBJECT_CLASS * oc ));
 
-LDAP_F( char *)
+LIBLDAP_F( char *)
 ldap_attributetype2str LDAP_P((
        LDAP_CONST LDAP_ATTRIBUTE_TYPE * at ));
 
-LDAP_F( char *)
+LIBLDAP_F( char *)
 ldap_syntax2str LDAP_P((
        LDAP_CONST LDAP_SYNTAX * syn ));
 
-LDAP_F( char *)
+LIBLDAP_F( char *)
 ldap_matchingrule2str LDAP_P((
        LDAP_CONST LDAP_MATCHING_RULE * mr ));
 
-LDAP_F( char *)
+LIBLDAP_F( char *)
 ldap_scherr2str LDAP_P((
        int code )) LDAP_GCCATTR((const));
 
index 9fd65730e39fb3908163b5df94ae23715f775146..3da50df682ed453c4c4528daf3ebc3e21d249e18 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 
 #include <ldap_cdefs.h>
 
-#ifdef LDBM_USE_DBBTREE
+#if defined( LDBM_USE_DBBTREE ) || defined( LDBM_USE_DBHASH )
 
 /*****************************************************************
  *                                                               *
- * use berkeley db btree package                                 *
+ * use berkeley db btree or hash package                         *
  *                                                               *
  *****************************************************************/
-
 #include <sys/types.h>
 #include <limits.h>
 #include <fcntl.h>
 #      else
 #              include <db.h>
 #      endif
-#      ifdef HAVE_BERKELEY_DB2
-#              define R_NOOVERWRITE DB_NOOVERWRITE
-#              define DEFAULT_DB_PAGE_SIZE 1024
-#      endif
 #endif
 
-
-LDAP_BEGIN_DECL
-
-typedef DBT    Datum;
-#define dsize  size
-#define dptr   data
-
-typedef DB     *LDBM;
-
-
-#define DB_TYPE                DB_BTREE
-
-/* for ldbm_open */
-#ifdef HAVE_BERKELEY_DB2
-typedef DBC    LDBMCursor;
-#      define LDBM_READER      DB_RDONLY
-#      define LDBM_WRITER      0x00000      /* hopefully */
-#      define LDBM_WRCREAT     (DB_NOMMAP|DB_CREATE|DB_THREAD)
-#      define LDBM_NEWDB       (DB_TRUNCATE|DB_CREATE|DB_THREAD)
-#else
-typedef int LDBMCursor;
-#      define LDBM_READER      O_RDONLY
-#      define LDBM_WRITER      O_RDWR
-#      define LDBM_WRCREAT     (O_RDWR|O_CREAT)
-#      define LDBM_NEWDB       (O_RDWR|O_TRUNC|O_CREAT)
+#ifndef DB_VERSION_MAJOR
+#  define DB_VERSION_MAJOR 1
+#endif
+#ifndef DB_VERSION_MINOR
+#  define DB_VERSION_MINOR 85
 #endif
 
-LDAP_END_DECL
-
-#  define LDBM_FAST    0
-
-#define LDBM_SUFFIX    ".dbb"
-#define LDBM_ORDERED   1
-
-/* for ldbm_insert */
-#define LDBM_INSERT    R_NOOVERWRITE
-#define LDBM_REPLACE   0
-#define LDBM_SYNC      0x80000000
-
-#elif defined( LDBM_USE_DBHASH )
-
-/*****************************************************************
- *                                                               *
- * use berkeley db hash package                                  *
- *                                                               *
- *****************************************************************/
-
-#include <sys/types.h>
-#include <limits.h>
-#include <fcntl.h>
-
-#ifdef HAVE_DB_185_H
-#      include <db_185.h>
-#else
-#      ifdef HAVE_DB1_DB_H
-#              include <db1/db.h>
-#      else
-#              include <db.h>
-#      endif
-#      ifdef LDBM_USE_DB2
-#              define R_NOOVERWRITE DB_NOOVERWRITE
-#              define DEFAULT_DB_PAGE_SIZE 1024
+#if DB_VERSION_MAJOR >= 2
+#      define R_NOOVERWRITE DB_NOOVERWRITE
+#      ifndef DEFAULT_DB_PAGE_SIZE
+#              define DEFAULT_DB_PAGE_SIZE 4096
 #      endif
 #endif
 
+
 LDAP_BEGIN_DECL
 
 typedef DBT    Datum;
@@ -114,32 +59,49 @@ typedef DBT        Datum;
 
 typedef DB     *LDBM;
 
-#define DB_TYPE                DB_HASH
 
 /* for ldbm_open */
-#ifdef LDBM_USE_DB2
+#if DB_VERSION_MAJOR >= 2
 typedef DBC    LDBMCursor;
+
 #      define LDBM_READER      DB_RDONLY
 #      define LDBM_WRITER      0x00000      /* hopefully */
+# if defined( HAVE_BERKELEY_DB_THREAD )
 #      define LDBM_WRCREAT     (DB_NOMMAP|DB_CREATE|DB_THREAD)
 #      define LDBM_NEWDB       (DB_TRUNCATE|DB_CREATE|DB_THREAD)
+# else
+#      define LDBM_WRCREAT     (DB_NOMMAP|DB_CREATE)
+#      define LDBM_NEWDB       (DB_TRUNCATE|DB_CREATE)
+# endif
+
 #else
-typedef int LDBMCursor;
+typedef void LDBMCursor;
 #      define LDBM_READER      O_RDONLY
 #      define LDBM_WRITER      O_RDWR
 #      define LDBM_WRCREAT     (O_RDWR|O_CREAT)
 #      define LDBM_NEWDB       (O_RDWR|O_TRUNC|O_CREAT)
-#      define LDBM_FAST        0
 #endif
 
 LDAP_END_DECL
 
-#define LDBM_SUFFIX    ".dbh"
+/* for ldbm_open */
+#define LDBM_NOSYNC    0
+#define LDBM_SYNC      0
+#define LDBM_LOCKING   0
+#define LDBM_NOLOCKING 0
 
 /* for ldbm_insert */
 #define LDBM_INSERT    R_NOOVERWRITE
 #define LDBM_REPLACE   0
-#define LDBM_SYNC      0x80000000
+
+#ifdef LDBM_USE_DBBTREE
+#      define LDBM_ORDERED     1
+#      define LDBM_SUFFIX      ".dbb"
+#      define DB_TYPE          DB_BTREE
+#else
+#      define LDBM_SUFFIX      ".dbh"
+#      define DB_TYPE          DB_HASH
+#endif
 
 #elif defined( HAVE_GDBM )
 
@@ -154,7 +116,7 @@ LDAP_END_DECL
 LDAP_BEGIN_DECL
 
 typedef datum          Datum;
-typedef int LDBMCursor;
+typedef Datum LDBMCursor;
 typedef GDBM_FILE      LDBM;
 
 extern gdbm_error      gdbm_errno;
@@ -166,14 +128,31 @@ LDAP_END_DECL
 #define LDBM_WRITER    GDBM_WRITER
 #define LDBM_WRCREAT   GDBM_WRCREAT
 #define LDBM_NEWDB     GDBM_NEWDB
-#define LDBM_FAST      GDBM_FAST
+
+#ifdef GDBM_FAST
+#define LDBM_NOSYNC    GDBM_FAST
+#else
+#define LDBM_NOSYNC    0
+#endif
+
+#ifdef GDBM_SYNC
+#define LDBM_SYNC      GDBM_SYNC
+#else
+#define LDBM_SYNC      0
+#endif
+
+#define LDBM_LOCKING   0
+#ifdef GDBM_NOLOCK
+#define LDBM_NOLOCKING GDBM_NOLOCK
+#else
+#define LDBM_NOLOCKING 0
+#endif
 
 #define LDBM_SUFFIX    ".gdbm"
 
 /* for ldbm_insert */
 #define LDBM_INSERT    GDBM_INSERT
 #define LDBM_REPLACE   GDBM_REPLACE
-#define LDBM_SYNC      0x80000000
 
 #elif defined( HAVE_MDBM )
 
@@ -202,15 +181,17 @@ LDAP_END_DECL
 #define LDBM_WRITER    O_RDWR
 #define LDBM_WRCREAT   (O_RDWR|O_CREAT)
 #define LDBM_NEWDB     (O_RDWR|O_TRUNC|O_CREAT)
-#define LDBM_FAST      0
+
+#define LDBM_SYNC      0
+#define LDBM_NOSYNC    0
+#define LDBM_LOCKING   0
+#define LDBM_NOLOCKING 0
 
 #define LDBM_SUFFIX    ".mdbm"
 
 /* for ldbm_insert */
 #define LDBM_INSERT    MDBM_INSERT
 #define LDBM_REPLACE   MDBM_REPLACE
-#define LDBM_SYNC      0x80000000
-
 
 #elif defined( HAVE_NDBM )
 
@@ -239,42 +220,45 @@ LDAP_END_DECL
 #define LDBM_WRITER    O_WRONLY
 #define LDBM_WRCREAT   (O_RDWR|O_CREAT)
 #define LDBM_NEWDB     (O_RDWR|O_TRUNC|O_CREAT)
-#define LDBM_FAST      0
+
+#define LDBM_NOSYNC    0
+#define LDBM_SYNC      0
+#define LDBM_NOLOCK    0
+#define LDBM_SYNC      0
 
 #define LDBM_SUFFIX    ".ndbm"
 
 /* for ldbm_insert */
 #define LDBM_INSERT    DBM_INSERT
 #define LDBM_REPLACE   DBM_REPLACE
-#define LDBM_SYNC      0
 
 #endif
 
 LDAP_BEGIN_DECL
 
-int ldbm_initialize( void );
-int ldbm_shutdown( void );
+LIBLDBM_F (int) ldbm_initialize( void );
+LIBLDBM_F (int) ldbm_shutdown( void );
 
-int    ldbm_errno( LDBM ldbm );
-LDBM   ldbm_open( char *name, int rw, int mode, int dbcachesize );
-void   ldbm_close( LDBM ldbm );
-void   ldbm_sync( LDBM ldbm );
-void   ldbm_datum_free( LDBM ldbm, Datum data );
-Datum  ldbm_datum_dup( LDBM ldbm, Datum data );
-Datum  ldbm_fetch( LDBM ldbm, Datum key );
-int    ldbm_store( LDBM ldbm, Datum key, Datum data, int flags );
-int    ldbm_delete( LDBM ldbm, Datum key );
+LIBLDBM_F (int) ldbm_errno( LDBM ldbm );
+LIBLDBM_F (LDBM) ldbm_open( char *name, int rw, int mode, int dbcachesize );
+LIBLDBM_F (void) ldbm_close( LDBM ldbm );
+LIBLDBM_F (void) ldbm_sync( LDBM ldbm );
+LIBLDBM_F (void) ldbm_datum_free( LDBM ldbm, Datum data );
+LIBLDBM_F (Datum) ldbm_datum_dup( LDBM ldbm, Datum data );
+LIBLDBM_F (Datum) ldbm_fetch( LDBM ldbm, Datum key );
+LIBLDBM_F (int) ldbm_store( LDBM ldbm, Datum key, Datum data, int flags );
+LIBLDBM_F (int) ldbm_delete( LDBM ldbm, Datum key );
 
-Datum  ldbm_firstkey( LDBM ldbm, LDBMCursor **cursor );
-Datum  ldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *cursor );
+LIBLDBM_F (Datum) ldbm_firstkey( LDBM ldbm, LDBMCursor **cursor );
+LIBLDBM_F (Datum) ldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *cursor );
 
 /* initialization of Datum structures */
-#ifdef HAVE_BERKELEY_DB2
-       void   *ldbm_malloc( size_t size );
-#   define ldbm_datum_init(d) ((void)memset(&(d), 0, sizeof(Datum)))
+#if defined( HAVE_BERKELEY_DB ) && (DB_VERSION_MAJOR >= 2)
+       LIBLDBM_F (void *) ldbm_malloc( size_t size );
+#   define ldbm_datum_init(d) ((void)memset(&(d), '\0', sizeof(Datum)))
 #else
 #   define ldbm_datum_init(d) ((void)0)
-#endif  /* HAVE_BERKELEY_DB2 */
+#endif  /* HAVE_BERKELEY_DB */
 
 LDAP_END_DECL
 
index a50bbf063442a73d8dde65ac32455a0d881fd2f0..2d0ee1de9db496bd62a247612474daf78da65b39 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
@@ -27,7 +27,8 @@
 
 LDAP_BEGIN_DECL
 
-extern int ldif_debug;
+/* This is NOT a bogus extern declaration (unlike ldap_debug) */
+LIBLDIF_F (int) ldif_debug;
 
 #define LDIF_LINE_WIDTH      76      /* maximum length of LDIF lines */
 
@@ -48,23 +49,23 @@ extern int ldif_debug;
     ((nlen) + 4 + LDIF_BASE64_LEN(vlen) \
     + ((LDIF_BASE64_LEN(vlen) + (nlen) + 3) / LDIF_LINE_WIDTH * 2 ))
 
-LDAP_F( int )
+LIBLDIF_F( int )
 ldif_parse_line LDAP_P((
        LDAP_CONST char *line,
        char **name,
        char **value,
        ber_len_t *vlen ));
 
-LDAP_F( int )
+LIBLDIF_F( int )
 ldif_fetch_url LDAP_P((
        LDAP_CONST char *line,
        char **value,
        ber_len_t *vlen ));
 
-LDAP_F( char * )
+LIBLDIF_F( char * )
 ldif_getline LDAP_P(( char **next ));
 
-LDAP_F( int )
+LIBLDIF_F( int )
 ldif_read_record LDAP_P((
        FILE *fp,
        int *lineno,
@@ -82,7 +83,7 @@ ldif_read_record LDAP_P((
 #define LDIF_PUT_URL           0x0020  /* url */
 #define LDIF_PUT_SEP           0x0040  /* separator */
 
-LDAP_F( void )
+LIBLDIF_F( void )
 ldif_sput LDAP_P((
        char **out,
        int type,
@@ -90,14 +91,14 @@ ldif_sput LDAP_P((
        LDAP_CONST char *val,
        ber_len_t vlen ));
 
-LDAP_F( char * )
+LIBLDIF_F( char * )
 ldif_put LDAP_P((
        int type,
        LDAP_CONST char *name,
        LDAP_CONST char *val,
        ber_len_t vlen ));
 
-LDAP_F( int )
+LIBLDIF_F( int )
 ldif_is_not_printable LDAP_P((
        LDAP_CONST char *val,
        ber_len_t vlen ));
index 05d6279f947eddf8bb2c1c209ecebbd291f31988..398f50f2a860a8d854590646baca6e155f7cd7d4 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 
 LDAP_BEGIN_DECL
 
+/* n octets encode into ceiling(n/3) * 4 bytes */
+/* Avoid floating point math by through extra padding */
+
+#define LUTIL_BASE64_ENCODE_LEN(n)     ((n)/3 * 4 + 4)
+#define LUTIL_BASE64_DECODE_LEN(n)     ((n)/4 * 3)
+
 /* ISC Base64 Routines */
 /* base64.c */
 
-LDAP_F( int )
+LIBLUTIL_F( int )
 lutil_b64_ntop LDAP_P((
        unsigned char const *,
        size_t,
        char *,
        size_t));
 
-LDAP_F( int )
+LIBLUTIL_F( int )
 lutil_b64_pton LDAP_P((
        char const *,
        unsigned char *,
        size_t));
 
 /* detach.c */
-LDAP_F( void )
+LIBLUTIL_F( void )
 lutil_detach LDAP_P((
        int debug,
        int do_close));
 
+/* entropy.c */
+LIBLUTIL_F( int )
+lutil_entropy LDAP_P((
+       char *buf,
+       ber_len_t nbytes ));
+
 /* passwd.c */
-LDAP_F( int )
+struct berval; /* avoid pulling in lber.h */
+
+LIBLUTIL_F( int )
+lutil_authpasswd LDAP_P((
+       const struct berval *passwd,    /* stored password */
+       const struct berval *cred,      /* user supplied value */
+       const char **methods ));
+
+LIBLUTIL_F( int )
+lutil_authpasswd_hash LDAP_P((
+       const struct berval *cred,
+       struct berval **passwd, /* password to store */
+       struct berval **salt,   /* salt to store */
+       const char *method ));
+
+#if defined( SLAPD_SPASSWD ) && defined( HAVE_CYRUS_SASL )
+       /* cheat to avoid pulling in <sasl.h> */
+LIBLUTIL_F( struct sasl_conn * ) lutil_passwd_sasl_conn;
+#endif
+
+LIBLUTIL_F( int )
 lutil_passwd LDAP_P((
-       const char *cred,
-       const char *passwd,
+       const struct berval *passwd,    /* stored password */
+       const struct berval *cred,      /* user supplied value */
        const char **methods ));
 
+LIBLUTIL_F( struct berval * )
+lutil_passwd_generate LDAP_P(( ber_len_t ));
+
+LIBLUTIL_F( struct berval * )
+lutil_passwd_hash LDAP_P((
+       const struct berval *passwd,
+       const char *method ));
+
+LIBLUTIL_F( int )
+lutil_passwd_scheme LDAP_P((
+       const char *scheme ));
+
 /* utils.c */
-LDAP_F( char* )
+LIBLUTIL_F( char* )
 lutil_progname LDAP_P((
        const char* name,
        int argc,
        char *argv[] ));
 
 /* sockpair.c */
-LDAP_F( int )
+LIBLUTIL_F( int )
 lutil_pair( LBER_SOCKET_T sd[2] );
 
 LDAP_END_DECL
index 728b445cbffc5a6de64142f82db66d4350a8a8a0..3afb7bd335419534eb501183b44f8e28b8bfd67f 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 
 LDAP_BEGIN_DECL
 
-LDAP_F( int )
+LIBLUTIL_F( int )
 lutil_lockf LDAP_P(( int fd ));
 
-LDAP_F( int )
+LIBLUTIL_F( int )
 lutil_unlockf LDAP_P(( int fd ));
 
 LDAP_END_DECL
index 6a140c9753558bda521cb3a6da5fc6b4f41df6ae..7148abc0abbac1c112d8eac1db835d95f3170951 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 #ifndef _LUTIL_MD5_H_
 #define _LUTIL_MD5_H_
 
-#include <ldap_cdefs.h>
-#include <ac/bytes.h>
+#include <lber_types.h>
 
 LDAP_BEGIN_DECL
 
-/* Unlike previous versions of this code, uint32 need not be exactly
+/* Unlike previous versions of this code, ber_int_t need not be exactly
    32 bits, merely 32 bits or more.  Choosing a data type which is 32
    bits instead of 64 is not important; speed is considerably more
    important.  ANSI guarantees that "unsigned long" will be big enough,
    and always using it seems to have few disadvantages.  */
 
-#ifndef LDAP_UINT32
-#define LDAP_UINT32 1
-typedef ac_uint4 uint32;
-#endif
+#define LUTIL_MD5_BYTES 16
 
 struct lutil_MD5Context {
-       uint32 buf[4];
-       uint32 bits[2];
+       ber_uint_t buf[4];
+       ber_uint_t bits[2];
        unsigned char in[64];
 };
 
-LDAP_F( void )
+LIBLUTIL_F( void )
 lutil_MD5Init LDAP_P((
        struct lutil_MD5Context *context));
 
-LDAP_F( void )
+LIBLUTIL_F( void )
 lutil_MD5Update LDAP_P((
        struct lutil_MD5Context *context,
        unsigned char const *buf,
-       unsigned len));
+       ber_len_t len));
 
-LDAP_F( void )
+LIBLUTIL_F( void )
 lutil_MD5Final LDAP_P((
        unsigned char digest[16],
        struct lutil_MD5Context *context));
 
-LDAP_F( void )
+LIBLUTIL_F( void )
 lutil_MD5Transform LDAP_P((
-       uint32 buf[4],
+       ber_uint_t buf[4],
        const unsigned char in[64]));
 
 /*
index 07f82fb8eb0af06d8e8dd78b38e5cdaea47d1d71..cb3e67c2b1d16f0a5a60fc0c480282fbb80b8a37 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
@@ -24,11 +24,10 @@ LDAP_BEGIN_DECL
  * SHA-1 in C
  * By Steve Reid <steve@edmweb.com>
  */
+#define LUTIL_SHA1_BYTES 20
 
-#ifndef LDAP_UINT32
-#define LDAP_UINT32 1
+/* This code assumes char are 8-bits and uint32 are 32-bits */
 typedef ac_uint4 uint32;
-#endif
 
 typedef struct {
     uint32 state[5];
@@ -36,31 +35,31 @@ typedef struct {
     unsigned char buffer[64];
 } lutil_SHA1_CTX;
   
-LDAP_F( void )
+LIBLUTIL_F( void )
 lutil_SHA1Transform
        LDAP_P((uint32 state[5], const unsigned char buffer[64]));
 
-LDAP_F( void  )
+LIBLUTIL_F( void  )
 lutil_SHA1Init
        LDAP_P((lutil_SHA1_CTX *context));
 
-LDAP_F( void  )
+LIBLUTIL_F( void  )
 lutil_SHA1Update
        LDAP_P((lutil_SHA1_CTX *context, const unsigned char *data, uint32 len));
 
-LDAP_F( void  )
+LIBLUTIL_F( void  )
 lutil_SHA1Final
        LDAP_P((unsigned char digest[20], lutil_SHA1_CTX *context));
 
-LDAP_F( char * )
+LIBLUTIL_F( char * )
 lutil_SHA1End
        LDAP_P((lutil_SHA1_CTX *, char *));
 
-LDAP_F( char * )
+LIBLUTIL_F( char * )
 lutil_SHA1File
        LDAP_P((char *, char *));
 
-LDAP_F( char * )
+LIBLUTIL_F( char * )
 lutil_SHA1Data
        LDAP_P((const unsigned char *, size_t, char *));
 
index 3464300ce20038b07d8ef1ca508a9cc5db9c5253..55786a172a227b6aeaab5591fad0c893fc3c839e 100644 (file)
@@ -1,6 +1,6 @@
 /* include/portable.h.in.  Generated automatically from configure.in by autoheader.  */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 
 /* end of preamble */
 
+#if !defined(SLAPD_SCHEMA_COMPAT) && !defined(SLAPD_SCHEMA_NOT_COMPAT)
+       /* define SLAPD_SCHEMA_COMPAT if you want old schema codes */
+#define SLAPD_SCHEMA_NOT_COMPAT 1
+#endif
+
+
 /* Define if on AIX 3.
    System headers sometimes define this.
    We just want to avoid a redefinition error message.  */
 /* Define to empty if the keyword does not work.  */
 #undef const
 
-/* Define to the type of elements in the array set by `getgroups'.
-   Usually this is either `int' or `gid_t'.  */
-#undef GETGROUPS_T
-
 /* Define to `int' if <sys/types.h> doesn't define.  */
 #undef gid_t
 
 /* Define if on MINIX.  */
 #undef _MINIX
 
-/* Define to `int' if <sys/types.h> doesn't define.  */
-#undef mode_t
-
-/* Define to `long' if <sys/types.h> doesn't define.  */
-#undef off_t
-
-/* Define to `int' if <sys/types.h> doesn't define.  */
-#undef pid_t
-
 /* Define if the system does not provide POSIX.1 features except
    with this defined.  */
 #undef _POSIX_1_SOURCE
@@ -77,9 +70,6 @@
 /* Define to the type of arg5 for select(). */
 #undef SELECT_TYPE_ARG5
 
-/* Define to `unsigned' if <sys/types.h> doesn't define.  */
-#undef size_t
-
 /* Define if you have the ANSI C header files.  */
 #undef STDC_HEADERS
 
 /*
  LDAP_API_FEATURE_X_OPENLDAP_REENTRANT
  LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE
- LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
+ LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
  LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
 */
 
  LBER_TAG_T
 */
 
-/* The number of bytes in a int.  */
-#undef SIZEOF_INT
-
-/* The number of bytes in a long.  */
-#undef SIZEOF_LONG
-
-/* The number of bytes in a short.  */
-#undef SIZEOF_SHORT
-
 /* Define if you have the bcopy function.  */
 #undef HAVE_BCOPY
 
+/* Define if you have the chroot function.  */
+#undef HAVE_CHROOT
+
 /* Define if you have the closesocket function.  */
 #undef HAVE_CLOSESOCKET
 
 /* Define if you have the flock function.  */
 #undef HAVE_FLOCK
 
+/* Define if you have the getaddrinfo function.  */
+#undef HAVE_GETADDRINFO
+
 /* Define if you have the getdtablesize function.  */
 #undef HAVE_GETDTABLESIZE
 
 /* Define if you have the getpass function.  */
 #undef HAVE_GETPASS
 
+/* Define if you have the getpassphrase function.  */
+#undef HAVE_GETPASSPHRASE
+
 /* Define if you have the getpwnam function.  */
 #undef HAVE_GETPWNAM
 
 /* Define if you have the pthread_kill function.  */
 #undef HAVE_PTHREAD_KILL
 
+/* Define if you have the pthread_rwlock_destroy function.  */
+#undef HAVE_PTHREAD_RWLOCK_DESTROY
+
 /* Define if you have the pthread_setconcurrency function.  */
 #undef HAVE_PTHREAD_SETCONCURRENCY
 
 /* Define if you have the <assert.h> header file.  */
 #undef HAVE_ASSERT_H
 
+/* Define if you have the <conio.h> header file.  */
+#undef HAVE_CONIO_H
+
 /* Define if you have the <crypt.h> header file.  */
 #undef HAVE_CRYPT_H
 
 /* Define if you have the <db.h> header file.  */
 #undef HAVE_DB_H
 
-/* Define if you have the <db1/db.h> header file.  */
-#undef HAVE_DB1_DB_H
-
 /* Define if you have the <db_185.h> header file.  */
 #undef HAVE_DB_185_H
 
 /* Define if you have the <des.h> header file.  */
 #undef HAVE_DES_H
 
+/* Define if you have the <direct.h> header file.  */
+#undef HAVE_DIRECT_H
+
 /* Define if you have the <dirent.h> header file.  */
 #undef HAVE_DIRENT_H
 
-/* Define if you have the <dmalloc.h> header file.  */
-#undef HAVE_DMALLOC_H
-
 /* Define if you have the <errno.h> header file.  */
 #undef HAVE_ERRNO_H
 
 /* Define if you have the <grp.h> header file.  */
 #undef HAVE_GRP_H
 
+/* Define if you have the <heim_err.h> header file.  */
+#undef HAVE_HEIM_ERR_H
+
+/* Define if you have the <io.h> header file.  */
+#undef HAVE_IO_H
+
 /* Define if you have the <kerberosIV/des.h> header file.  */
 #undef HAVE_KERBEROSIV_DES_H
 
 /* Define if you have the <kerberosIV/krb.h> header file.  */
 #undef HAVE_KERBEROSIV_KRB_H
 
+/* Define if you have the <krb-archaeology.h> header file.  */
+#undef HAVE_KRB_ARCHAEOLOGY_H
+
 /* Define if you have the <krb.h> header file.  */
 #undef HAVE_KRB_H
 
+/* Define if you have the <krb5.h> header file.  */
+#undef HAVE_KRB5_H
+
 /* Define if you have the <libutil.h> header file.  */
 #undef HAVE_LIBUTIL_H
 
 /* Define if you have the <memory.h> header file.  */
 #undef HAVE_MEMORY_H
 
+/* Define if you have the <minix/config.h> header file.  */
+#undef HAVE_MINIX_CONFIG_H
+
 /* Define if you have the <ncurses.h> header file.  */
 #undef HAVE_NCURSES_H
 
 /* Define if you have the <openssl/ssl.h> header file.  */
 #undef HAVE_OPENSSL_SSL_H
 
+/* Define if you have the <process.h> header file.  */
+#undef HAVE_PROCESS_H
+
 /* Define if you have the <psap.h> header file.  */
 #undef HAVE_PSAP_H
 
 /* Define if you have the <resolv.h> header file.  */
 #undef HAVE_RESOLV_H
 
+/* Define if you have the <sasl.h> header file.  */
+#undef HAVE_SASL_H
+
 /* Define if you have the <sched.h> header file.  */
 #undef HAVE_SCHED_H
 
 /* Define if you have the <sys/types.h> header file.  */
 #undef HAVE_SYS_TYPES_H
 
+/* Define if you have the <sys/un.h> header file.  */
+#undef HAVE_SYS_UN_H
+
 /* Define if you have the <sysexits.h> header file.  */
 #undef HAVE_SYSEXITS_H
 
 /* Define if you have the <syslog.h> header file.  */
 #undef HAVE_SYSLOG_H
 
-/* Define if you have the <tcl.h> header file.  */
-#undef HAVE_TCL_H
-
 /* Define if you have the <tcpd.h> header file.  */
 #undef HAVE_TCPD_H
 
 /* Define if you have the <unistd.h> header file.  */
 #undef HAVE_UNISTD_H
 
+/* Define if you have the <winsock.h> header file.  */
+#undef HAVE_WINSOCK_H
+
 /* Define if you have the V3 library (-lV3).  */
 #undef HAVE_LIBV3
 
 /* Define if you have the bind library (-lbind).  */
 #undef HAVE_LIBBIND
 
-/* Define if you have the dmalloc library (-ldmalloc).  */
-#undef HAVE_LIBDMALLOC
-
 /* Define if you have the gen library (-lgen).  */
 #undef HAVE_LIBGEN
 
 /* Define if you have the inet library (-linet).  */
 #undef HAVE_LIBINET
 
-/* Define if you have the ltdl library (-lltdl).  */
-#undef HAVE_LIBLTDL
-
 /* Define if you have the net library (-lnet).  */
 #undef HAVE_LIBNET
 
 /* defined to be the EXE extension */
 #undef EXEEXT
 
+/* define if you have AIX security lib */
+#undef HAVE_AIX_SECURITY
+
+/* define if you have libtool -ltdl */
+#undef HAVE_LIBLTDL
+
 /* define if system uses EBCDIC instead of ASCII */
 #undef HAVE_EBCDIC
 
 /* define if you have POSIX termios */
 #undef HAVE_POSIX_TERMIOS
 
-/* define if you have res_search() */
-#undef HAVE_RES_SEARCH
+/* define if you have winsock */
+#undef HAVE_WINSOCK
+
+/* define if you have res_query() */
+#undef HAVE_RES_QUERY
+
+/* define if you have HEIMDAL Kerberos */
+#undef HAVE_HEIMDAL_KERBEROS
+
+/* define if you have Kerberos V */
+#undef HAVE_KRB5
+
+/* define if you have Kerberos V with IV support */
+#undef HAVE_KRB425
+
+/* define if you have Kerberos IV */
+#undef HAVE_KRB4
 
 /* define if you have Kerberos des_debug */
 #undef HAVE_DES_DEBUG
 
+/* define if you have Kerberos IV */
+#undef HAVE_KRB4
+
+/* define if you have Kth Kerberos */
+#undef HAVE_KTH_KERBEROS
+
 /* define if you have Kerberos */
 #undef HAVE_KERBEROS
 
 /* set to the number of arguments gethostbyaddr_r() expects */
 #undef GETHOSTBYADDR_R_NARGS
 
+/* if you have NT Threads */
+#undef HAVE_NT_THREADS
+
+/* if you have NT Service Manager */
+#undef HAVE_NT_SERVICE_MANAGER
+
+/* if you have NT Event Log */
+#undef HAVE_NT_EVENT_LOG
+
 /* define if pthreads API compatible with final spec */
 #undef HAVE_PTHREADS_FINAL
 
 /* define if you have (or want) no threads */
 #undef NO_THREADS
 
-/* define if Berkeley DBv2 is available */
-#undef HAVE_BERKELEY_DB2
+/* define if Berkeley DB has DB_THREAD support */
+#undef HAVE_BERKELEY_DB_THREAD
 
-/* define this to use DBHASH w/ LDBM backend */
-#undef LDBM_USE_DBHASH
-
-/* define this to use DBBTREE w/ LDBM backend */
-#undef LDBM_USE_DBBTREE
-
-/* define if Berkeley DB is available */
+/* define this if Berkeley DB is available */
 #undef HAVE_BERKELEY_DB
 
 /* define this to use DBHASH w/ LDBM backend */
 /* define if you have Cyrus SASL */
 #undef HAVE_CYRUS_SASL
 
+/* set to urandom device */
+#undef URANDOM_DEVICE
+
 /* define if you actually have FreeBSD fetch(3) */
 #undef HAVE_FETCH
 
 /* define if setproctitle(3) is available */
 #undef HAVE_SETPROCTITLE
 
+/* Define to `int' if <sys/types.h> does not define. */
+#undef mode_t
+
+/* Define to `long' if <sys/types.h> does not define. */
+#undef off_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
 /* Define if system has ptrdiff_t type */
 #undef HAVE_PTRDIFF_T
 
-/* define to atomic type if sig_atomic_t is not available */
-#undef sig_atomic_t
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define to `signed int' if <sys/types.h> does not define. */
+#undef ssize_t
+
+/* Define to `char *' if <sys/types.h> does not define. */
+#undef caddr_t
 
 /* define to int if socklen_t is not available */
 #undef socklen_t
 
+/* define to atomic type if sig_atomic_t is not available */
+#undef sig_atomic_t
+
 /* define if struct passwd has pw_gecos */
 #undef HAVE_PW_GECOS
 
 /* define if cross compiling */
 #undef CROSS_COMPILING
 
+/* The number of bytes in type short */
+#undef SIZEOF_SHORT
+
+/* The number of bytes in type int */
+#undef SIZEOF_INT
+
+/* The number of bytes in type long */
+#undef SIZEOF_LONG
+
 /* define to you inet_aton(3) is available */
 #undef HAVE_INET_ATON
 
+/* if you have spawnlp() */
+#undef HAVE_SPAWNLP
+
+/* define to snprintf routine */
+#undef snprintf
+
+/* define to vsnprintf routine */
+#undef vsnprintf
+
 /* define if sys_errlist is not declared in stdio.h or errno.h */
 #undef DECL_SYS_ERRLIST
 
 /* define to support CLDAP */
 #undef LDAP_CONNECTIONLESS
 
-/* define to support crypt(3) passwords */
-#undef SLAPD_CRYPT
+/* define to support PF_UNIX */
+#undef LDAP_PF_UNIX
+
+/* define to support PF_INET6 */
+#undef LDAP_PF_INET6
 
 /* define to support cleartext passwords */
 #undef SLAPD_CLEARTEXT
 
+/* define to support crypt(3) passwords */
+#undef SLAPD_CRYPT
+
+/* define to support Kerberos passwords */
+#undef SLAPD_KPASSWD
+
+/* define to support SASL passwords */
+#undef SLAPD_SPASSWD
+
 /* define to support multimaster replication */
 #undef SLAPD_MULTIMASTER
 
 /* define to support per-object ACIs */
 #undef SLAPD_ACI_ENABLED
 
-/* define to support discrete rights in ACIs */
-#undef SLAPD_ACI_DISCRETE_RIGHTS
-
 /* define to support modules */
 #undef SLAPD_MODULES
 
-/* define to support BDB2 backend */
-#undef SLAPD_BDB2
+/* define to support DNS SRV backend */
+#undef SLAPD_DNSSRV
 
-/* define to support dynamic BDB2 backend */
-#undef SLAPD_BDB2_DYNAMIC
+/* define to support dynamic DNS SRV backend */
+#undef SLAPD_DNSSRV_DYNAMIC
 
 /* define to support LDAP backend */
 #undef SLAPD_LDAP
 /* define to support dynamic PASSWD backend */
 #undef SLAPD_PASSWD_DYNAMIC
 
-/* define to support PERL backend */
-#undef SLAPD_PERL
-
-/* define to support dynamic PERL backend */
-#undef SLAPD_PERL_DYNAMIC
-
 /* define to support SHELL backend */
 #undef SLAPD_SHELL
 
 /* define to support dynamic SHELL backend */
 #undef SLAPD_SHELL_DYNAMIC
 
-/* define to support TCL backend */
-#undef SLAPD_TCL
-
-/* define to support dynamic TCL backend */
-#undef SLAPD_TCL_DYNAMIC
 
 /* begin of postamble */
 
+#ifdef _WIN32
+       /* don't suck in all of the win32 api */
+#      define WIN32_LEAN_AND_MEAN 1
+#endif
+
 #ifndef __NEED_PROTOTYPES
 /* force LDAP_P to always include prototypes */
 #define __NEED_PROTOTYPES 1
index af077ef6f25a9d72376f92f614d462ff30ed4a60..080089649ffd351ec1ae162701e594286364b1a2 100644 (file)
@@ -2,7 +2,7 @@
 /* include/portable.h.nt -- manually updated of MS NT (MS VC5) */
 /* synced with portable.h.in 1.24 */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 
 /* end of preamble */
 
+/* comment this out if you don't have Cyrus SASL */
+#define HAVE_CYRUS_SASL 1
+
 /* --------------------------------------------------- */
 /* begin of MSVC5 specific entries */
 
 #define OPENLDAP_PACKAGE "OpenLDAP"
 #define OPENLDAP_VERSION "-devel"
 #define EXEEXT ".exe"
-#define LDAP_DIRSEP "\\"
 
 /* don't suck in all of the win32 api */
 #define WIN32_LEAN_AND_MEAN
 
-#ifdef _WINNT
-/* WindowsNT specific features */
+#if defined(_WIN32) && !defined(_WINNT) && !defined(_WIN95)
+#define _WINNT
+#endif
+
+#if defined( _MT ) && defined( _WINNT )
+#define HAVE_NT_THREADS 1
+#else
+#define NO_THREADS 1
+#endif
+
+#ifdef HAVE_NT_THREADS
+/* enable WINNT specific features only if we have NT THREADS */
 #define HAVE_NT_SERVICE_MANAGER 1
 #define HAVE_NT_EVENT_LOG 1
-
-#elif _WIN95
-/* Windows95 specific features */
 #endif
 
 #if defined( _DEBUG ) && !defined( LDAP_DEBUG )
@@ -49,7 +58,6 @@
 
 #define strcasecmp     stricmp
 #define strncasecmp    strnicmp
-#define strdup         _strdup
 
 #define        snprintf        _snprintf
 #define vsnprintf      _vsnprintf
 /* define type for caddr_t */
 typedef char * caddr_t;
 
-#define ssize_t signed int
-
-#define LOG_DEBUG 0
-#define openlog( a, b )
-#define closelog()
-
-#define FD_SETSIZE 1024
-
-/* we have NT threads */
-#ifdef _MT
-#define HAVE_NT_THREADS 1
-#else
-#define NO_THREADS 1
-#endif
+/* define type for ssize_t */
+typedef signed int ssize_t;
 
 /* we have spawnlp instead of fork/execlp */
 #define HAVE_SPAWNLP 1
@@ -94,8 +90,8 @@ typedef char * caddr_t;
 /* we have <process.h> */
 #define HAVE_PROCESS_H 1
 
-#define LDAP_SIGUSR1   SIGILL
-#define LDAP_SIGUSR2   SIGTERM
+/* we have <wincrypt.h> */
+#define HAVE_WINCRYPT_H 1
 
 #define MAXPATHLEN _MAX_PATH
 
@@ -210,10 +206,7 @@ typedef char * caddr_t;
 #define HAVE_SYS_ERRLIST 1 
 
 /* define if you have berkeley db */
-/* #undef HAVE_BERKELEY_DB */
-
-/* define if you have berkeley db2 */
-#define HAVE_BERKELEY_DB2 1
+#define HAVE_BERKELEY_DB 1
 
 /* define if you have crypt */
 /* #undef HAVE_CRYPT */
@@ -266,9 +259,6 @@ typedef char * caddr_t;
 /* define this for ACL Group support */
 #define SLAPD_ACLGROUPS 1
 
-/* define this to use SLAPD Berkeley DB2 backend */
-/* #define SLAPD_BDB2 1 */
-
 /* define this for ClearText password support */
 #define SLAPD_CLEARTEXT 1
 
@@ -281,6 +271,9 @@ typedef char * caddr_t;
 /* define this to use SLAPD LDBM backend */
 #define SLAPD_LDBM 1
 
+/* define this to use SLAPD SQL backend */
+/* #undef SLAPD_SQL */
+
 /* define this to use SLAPD passwd backend */
 /* #undef SLAPD_PASSWD */
 
@@ -296,9 +289,6 @@ typedef char * caddr_t;
 /* define this for per-object ACIs */
 /* #undef SLAPD_ACI_ENABLED */
 
-/* define this for discrete rights in ACIs */
-/* #undef SLAPD_ACI_DISCRETE_RIGHTS */
-
 /* define this to use SLAPD shell backend */
 /* #undef SLAPD_SHELL */
 
@@ -403,12 +393,12 @@ typedef char * caddr_t;
 /* Define if you have the sigset function.  */
 /* #undef HAVE_SIGSET */
 
-/* Define if you have the snprintf function.  */
-/* #undef HAVE_SNPRINTF */
-
 /* Define if you have the socket function.  */
 #define HAVE_SOCKET 1
 
+/* Define if you have the snprintf function.  */
+#define HAVE_SNPRINTF 1
+
 /* Define if you have the strdup function.  */
 #define HAVE_STRDUP 1
 
@@ -446,7 +436,7 @@ typedef char * caddr_t;
 /* #undef HAVE_SYSCONF */
 
 /* Define if you have the tempnam function.  */
-/* #undef HAVE_TEMPNAM */
+#define HAVE_TEMPNAM 1
 
 /* Define if you have the thr_getconcurrency function.  */
 /* #undef HAVE_THR_GETCONCURRENCY */
@@ -527,7 +517,7 @@ typedef char * caddr_t;
 #define HAVE_MALLOC_H 1
 
 /* Define if you have the <memory.h> header file.  */
-/* #define HAVE_MEMORY_H */
+#define HAVE_MEMORY_H 1
 
 /* Define if you have the <ncurses.h> header file.  */
 /* #undef HAVE_NCURSES_H */
index 2114f7205e36a637fcdc69acfe3f16561d329819..299f29cdeb54e1a3c67ddd2f39c5159f80f2c527 100644 (file)
@@ -4,7 +4,7 @@
 
 # TARGTYPE "Win32 (x86) External Target" 0x0106
 
-CFG=setup - Win32 Debug
+CFG=setup - Win32 DLL Debug
 !MESSAGE This is not a valid makefile. To build this project using NMAKE,
 !MESSAGE use the Export Makefile command and run
 !MESSAGE 
@@ -13,12 +13,17 @@ CFG=setup - Win32 Debug
 !MESSAGE You can specify a configuration when running NMAKE
 !MESSAGE by defining the macro CFG on the command line. For example:
 !MESSAGE 
-!MESSAGE NMAKE /f "setup.mak" CFG="setup - Win32 Debug"
+!MESSAGE NMAKE /f "setup.mak" CFG="setup - Win32 DLL Debug"
 !MESSAGE 
 !MESSAGE Possible choices for configuration are:
 !MESSAGE 
 !MESSAGE "setup - Win32 Release" (based on "Win32 (x86) External Target")
 !MESSAGE "setup - Win32 Debug" (based on "Win32 (x86) External Target")
+!MESSAGE "setup - Win32 Single Debug" (based on "Win32 (x86) External Target")
+!MESSAGE "setup - Win32 Single Release" (based on\
+ "Win32 (x86) External Target")
+!MESSAGE "setup - Win32 DLL Debug" (based on "Win32 (x86) External Target")
+!MESSAGE "setup - Win32 DLL Release" (based on "Win32 (x86) External Target")
 !MESSAGE 
 
 # Begin Project
@@ -63,17 +68,105 @@ CFG=setup - Win32 Debug
 # PROP Bsc_Name "setup.bsc"
 # PROP Target_Dir ""
 
+!ELSEIF  "$(CFG)" == "setup - Win32 Single Debug"
+
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "setup___"
+# PROP BASE Intermediate_Dir "setup___"
+# PROP BASE Cmd_Line "NMAKE /f setup.mak"
+# PROP BASE Rebuild_Opt "/a"
+# PROP BASE Target_File "setup.txt"
+# PROP BASE Bsc_Name "setup.bsc"
+# PROP BASE Target_Dir ""
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "setup___"
+# PROP Intermediate_Dir "setup___"
+# PROP Cmd_Line "NMAKE /f setup.mak"
+# PROP Rebuild_Opt "/a"
+# PROP Target_File "setup.txt"
+# PROP Bsc_Name "setup.bsc"
+# PROP Target_Dir ""
+
+!ELSEIF  "$(CFG)" == "setup - Win32 Single Release"
+
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "setup__0"
+# PROP BASE Intermediate_Dir "setup__0"
+# PROP BASE Cmd_Line "NMAKE /f setup.mak"
+# PROP BASE Rebuild_Opt "/a"
+# PROP BASE Target_File "setup.txt"
+# PROP BASE Bsc_Name "setup.bsc"
+# PROP BASE Target_Dir ""
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "setup__0"
+# PROP Intermediate_Dir "setup__0"
+# PROP Cmd_Line "NMAKE /f setup.mak"
+# PROP Rebuild_Opt "/a"
+# PROP Target_File "setup.txt"
+# PROP Bsc_Name "setup.bsc"
+# PROP Target_Dir ""
+
+!ELSEIF  "$(CFG)" == "setup - Win32 DLL Debug"
+
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "setup__1"
+# PROP BASE Intermediate_Dir "setup__1"
+# PROP BASE Cmd_Line "NMAKE /f setup.mak"
+# PROP BASE Rebuild_Opt "/a"
+# PROP BASE Target_File "setup.txt"
+# PROP BASE Bsc_Name "setup.bsc"
+# PROP BASE Target_Dir ""
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "setup__1"
+# PROP Intermediate_Dir "setup__1"
+# PROP Cmd_Line "NMAKE /f setup.mak"
+# PROP Rebuild_Opt "/a"
+# PROP Target_File "setup.txt"
+# PROP Bsc_Name "setup.bsc"
+# PROP Target_Dir ""
+
+!ELSEIF  "$(CFG)" == "setup - Win32 DLL Release"
+
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "setup__2"
+# PROP BASE Intermediate_Dir "setup__2"
+# PROP BASE Cmd_Line "NMAKE /f setup.mak"
+# PROP BASE Rebuild_Opt "/a"
+# PROP BASE Target_File "setup.txt"
+# PROP BASE Bsc_Name "setup.bsc"
+# PROP BASE Target_Dir ""
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "setup__2"
+# PROP Intermediate_Dir "setup__2"
+# PROP Cmd_Line "NMAKE /f setup.mak"
+# PROP Rebuild_Opt "/a"
+# PROP Target_File "setup.txt"
+# PROP Bsc_Name "setup.bsc"
+# PROP Target_Dir ""
+
 !ENDIF 
 
 # Begin Target
 
 # Name "setup - Win32 Release"
 # Name "setup - Win32 Debug"
+# Name "setup - Win32 Single Debug"
+# Name "setup - Win32 Single Release"
+# Name "setup - Win32 DLL Debug"
+# Name "setup - Win32 DLL Release"
 
 !IF  "$(CFG)" == "setup - Win32 Release"
 
 !ELSEIF  "$(CFG)" == "setup - Win32 Debug"
 
+!ELSEIF  "$(CFG)" == "setup - Win32 Single Debug"
+
+!ELSEIF  "$(CFG)" == "setup - Win32 Single Release"
+
+!ELSEIF  "$(CFG)" == "setup - Win32 DLL Debug"
+
+!ELSEIF  "$(CFG)" == "setup - Win32 DLL Release"
+
 !ENDIF 
 
 # Begin Source File
index 9e3b1c3a53f4b2580f621e4b2401507db1767286..a24056e9edb692d26d55fd9454b98f218a065407 100644 (file)
@@ -1,6 +1,6 @@
 # $OpenLDAP$
 #
-# Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+# Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 #
 
index e3523b005175e6379329c9360cc55f80e419f42d..4731597f055d2902c2d6129bafbe4b2a9142e943 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
@@ -78,22 +78,22 @@ struct ldap_searchobj {
 #define LDAP_SEARCHPREF_ERR_FILE       4
 
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_init_searchprefs LDAP_P(( char *file,
        struct ldap_searchobj **solistp ));
 
-LDAP_F( int )
+LIBLDAP_F( int )
 ldap_init_searchprefs_buf LDAP_P(( char *buf,
        ber_len_t buflen,
        struct ldap_searchobj **solistp ));
 
-LDAP_F( void )
+LIBLDAP_F( void )
 ldap_free_searchprefs LDAP_P(( struct ldap_searchobj *solist ));
 
-LDAP_F( struct ldap_searchobj * )
+LIBLDAP_F( struct ldap_searchobj * )
 ldap_first_searchobj LDAP_P(( struct ldap_searchobj *solist ));
 
-LDAP_F( struct ldap_searchobj * )
+LIBLDAP_F( struct ldap_searchobj * )
 ldap_next_searchobj LDAP_P(( struct ldap_searchobj *sollist,
        struct ldap_searchobj *so ));
 
index 48551549800880a8a1fbf41c3e7e856d945cfbec..578415657e9b3050b52938fbca58573ba74434b2 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
index d911128bea44eefefcfb8934547097f51521fc94..46d260a0f568acc3a8d48530d02079189efbded4 100644 (file)
@@ -1,8 +1,10 @@
 # $OpenLDAP$
-## Copyright 1998 The OpenLDAP Foundation, All Rights Reserved.
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
 ## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 ##
 ## Libraries Makefile for OpenLDAP
 
-SUBDIRS= liblutil libldif liblber libldap libavl libldbm libldap_r
+SUBDIRS= liblutil libldif \
+       liblber libldap libldap_r \
+       libavl libldbm liblunicode
 
index 92af71fa0d317f3c5c14add81725789c3751fb37..e641c50c319bef3fd5cd9d676b828b5e5d95b12a 100644 (file)
@@ -1,4 +1,6 @@
 # $OpenLDAP$
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 ##
 ## LIBAVL
 ##
index eb30049ef44aae764f7299d5aa1680fc2f0bcecf..63a543f8e4fb82f048d2387a887031dfa8119c18 100644 (file)
@@ -1,7 +1,7 @@
 /* avl.c - routines to implement an avl tree */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
diff --git a/libraries/libavl/libavl.dsp b/libraries/libavl/libavl.dsp
new file mode 100644 (file)
index 0000000..c1077b5
--- /dev/null
@@ -0,0 +1,137 @@
+# Microsoft Developer Studio Project File - Name="libavl" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=libavl - Win32 Single Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "libavl.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "libavl.mak" CFG="libavl - Win32 Single Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "libavl - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "libavl - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE "libavl - Win32 Single Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE "libavl - Win32 Single Release" (based on\
+ "Win32 (x86) Static Library")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+
+!IF  "$(CFG)" == "libavl - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\libavl"
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF  "$(CFG)" == "libavl - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\libavl"
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF  "$(CFG)" == "libavl - Win32 Single Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "libavl__"
+# PROP BASE Intermediate_Dir "libavl__"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\libavl"
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF  "$(CFG)" == "libavl - Win32 Single Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "libavl_0"
+# PROP BASE Intermediate_Dir "libavl_0"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\libavl"
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ENDIF 
+
+# Begin Target
+
+# Name "libavl - Win32 Release"
+# Name "libavl - Win32 Debug"
+# Name "libavl - Win32 Single Debug"
+# Name "libavl - Win32 Single Release"
+# Begin Source File
+
+SOURCE=.\avl.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\avl.h
+# End Source File
+# End Target
+# End Project
index 94540c304d60d8e7303fce95355dbcb113276818..de948d8bcd48193942f8e7bffeaa6cd9d3867b33 100644 (file)
@@ -1,5 +1,9 @@
 /* testavl.c - Test Tim Howes AVL code */
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 
 #include "portable.h"
 
diff --git a/libraries/libavl/testavl.dsp b/libraries/libavl/testavl.dsp
new file mode 100644 (file)
index 0000000..ecc7045
--- /dev/null
@@ -0,0 +1,143 @@
+# Microsoft Developer Studio Project File - Name="testavl" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=testavl - Win32 Single Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "testavl.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "testavl.mak" CFG="testavl - Win32 Single Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "testavl - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "testavl - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "testavl - Win32 Single Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "testavl - Win32 Single Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "testavl - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\testavl"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 /nologo /subsystem:console /machine:I386 /libpath:"..\..\Release"
+
+!ELSEIF  "$(CFG)" == "testavl - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "testavl_"
+# PROP BASE Intermediate_Dir "testavl_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\testavl"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Debug"
+
+!ELSEIF  "$(CFG)" == "testavl - Win32 Single Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "testavl_"
+# PROP BASE Intermediate_Dir "testavl_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\testavl"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\SDebug"
+
+!ELSEIF  "$(CFG)" == "testavl - Win32 Single Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "testavl0"
+# PROP BASE Intermediate_Dir "testavl0"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\testavl"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 /nologo /subsystem:console /machine:I386 /libpath:"..\..\SRelease"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "testavl - Win32 Release"
+# Name "testavl - Win32 Debug"
+# Name "testavl - Win32 Single Debug"
+# Name "testavl - Win32 Single Release"
+# Begin Source File
+
+SOURCE=.\testavl.c
+# End Source File
+# End Target
+# End Project
index 4808224b228b3829a58a5a6c8a124be7a26b589a..0c687d843de72f4753f905e37eee9d1f8d95d240 100644 (file)
@@ -1,5 +1,5 @@
 # $OpenLDAP$
-## Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
 ## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 ##
 ## LIBLBER
@@ -8,10 +8,13 @@
 LIBRARY = liblber.la
 XLIBRARY = ../liblber.a
 
+NT_SRCS = nt_err.c
+NT_OBJS = nt_err.lo
+
 SRCS= assert.c decode.c encode.c io.c bprint.c \
-       memory.c options.c sockbuf.c
+       memory.c options.c sockbuf.c $(@PLAT@_SRCS)
 OBJS= assert.lo decode.lo encode.lo io.lo bprint.lo \
-       memory.lo options.lo sockbuf.lo
+       memory.lo options.lo sockbuf.lo $(@PLAT@_OBJS)
 XSRCS= version.c
 
 PROGRAMS= dtest etest idtest
@@ -22,6 +25,17 @@ LDAP_LIBDIR= ../../libraries
 XLIBS = -llber
 XXLIBS = 
 
+LINKAGE = @LT_LIB_LINKAGE@
+
+NT_DYN_TEST_DEFS = -DLIBLBER_DECL=dllimport
+
+# Extras for building the library
+EXTRA_DEFS = $(@PLAT@_@LIB_LINKAGE@_LIB_DEFS)
+EXTRA_LIBS =
+
+# Only the test programs will pick up these defs.
+CPPFLAGS = $(@PLAT@_@LIB_LINKAGE@_TEST_DEFS)
+
 dtest:    $(LIBRARY) dtest.o
        $(LTLINK) $(LDFLAGS) -o $@ dtest.o $(LIBS)
 etest:  $(LIBRARY) etest.o
@@ -30,6 +44,6 @@ idtest:  $(LIBRARY) idtest.o
        $(LTLINK) $(LDFLAGS) -o $@ idtest.o $(LIBS)
 
 install-local: FORCE
-       -$(MKDIR) $(libdir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 644 $(LIBRARY) $(libdir)
+       -$(MKDIR) $(DESTDIR)$(libdir)
+       $(LTINSTALL) $(INSTALLFLAGS) -m 644 $(LIBRARY) $(DESTDIR)$(libdir)
 
index 50b70dd53b1a0cfba52da14ee357ef7d60d375bd..c0530ad6ee4f9661071535f1ad1682d951b33a1a 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1999-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
index eb8808563cb793b781ae7a11edf8cddc14d71d9f..e7569dc3775de084f05a866b72d5adf486f3ebcf 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 #include <ac/stdarg.h>
 #include <ac/string.h>
 
-#undef LDAP_F_PRE
-#define LDAP_F_PRE LDAP_F_EXPORT
-
 #include "lber-int.h"
 
+/*
+ * We don't just set ber_pvt_err_file to stderr here, because in NT,
+ * stderr is a symbol imported from a DLL. As such, the compiler
+ * doesn't recognize the symbol as having a constant address. Thus
+ * we set ber_pvt_err_file to stderr later, when it first gets
+ * referenced.
+ */
+FILE *ber_pvt_err_file;
+
+/*
+ * ber errno
+ */
+BER_ERRNO_FN ber_int_errno_fn;
+
+int * ber_errno_addr(void)
+{
+       static int ber_int_errno = LBER_ERROR_NONE;
+
+       if( ber_int_errno_fn ) {
+               return (*ber_int_errno_fn)();
+       }
+
+       return &ber_int_errno;
+}
+
 /*
  * Print stuff
  */
-static void
-ber_error_print( char *data )
+void ber_error_print( LDAP_CONST char *data )
 {
        assert( data != NULL );
 
-       fputs( data, stderr );
-       fflush( stderr );
+       if (!ber_pvt_err_file) ber_pvt_err_file = stderr;
+
+       fputs( data, ber_pvt_err_file );
+
+       /* Print to both streams */
+       if (ber_pvt_err_file != stderr) {
+               fputs( data, stderr );
+               fflush( stderr );
+       }
+
+       fflush( ber_pvt_err_file );
 }
 
 BER_LOG_PRINT_FN ber_pvt_log_print = ber_error_print;
@@ -114,7 +144,7 @@ ber_bprint(
 
        assert( data != NULL );
 
-    memset( out, 0, BPLEN );
+    memset( out, '\0', BPLEN );
     for ( ;; ) {
        if ( len < 1 ) {
            sprintf( buf, "\t%s\n", ( i == 0 ) ? "(end)" : out );
@@ -141,7 +171,7 @@ ber_bprint(
                char data[128 + BPLEN];
            sprintf( data, "\t%s\n", out );
                (*ber_pvt_log_print)(data);
-           memset( out, 0, BPLEN );
+           memset( out, '\0', BPLEN );
            i = 0;
            continue;
        }
@@ -153,7 +183,7 @@ int
 ber_log_dump(
        int errlvl,
        int loglvl,
-       const BerElement *ber,
+       BerElement *ber,
        int inout )
 {
        assert( ber != NULL );
@@ -169,7 +199,7 @@ ber_log_dump(
 
 void
 ber_dump(
-       LDAP_CONST BerElement *ber,
+       BerElement *ber,
        int inout )
 {
        char buf[132];
@@ -201,7 +231,7 @@ int
 ber_log_sos_dump(
        int errlvl,
        int loglvl,
-       const Seqorset *sos )
+       Seqorset *sos )
 {
        assert( sos != NULL );
 
@@ -215,7 +245,7 @@ ber_log_sos_dump(
 
 void
 ber_sos_dump(
-       LDAP_CONST Seqorset *sos )
+       Seqorset *sos )
 {
        char buf[132];
 
index e2c204d7937e0abc55a836512e6ce0370b27ac41..99ff60b90883ae10763d4d3fd6904e36b1a49228 100644 (file)
@@ -1,7 +1,7 @@
 /* decode.c - ber input decoding routines */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* Portions
@@ -26,9 +26,6 @@
 #include <ac/string.h>
 #include <ac/socket.h>
 
-#undef LDAP_F_PRE
-#define LDAP_F_PRE LDAP_F_EXPORT
-
 #include "lber-int.h"
 
 static ber_len_t ber_getnint LDAP_P((
@@ -42,7 +39,6 @@ ber_get_tag( BerElement *ber )
 {
        unsigned char   xbyte;
        ber_tag_t       tag;
-       char            *tagp;
        unsigned int    i;
 
        assert( ber != NULL );
@@ -51,16 +47,17 @@ ber_get_tag( BerElement *ber )
        if ( ber_read( ber, (char *) &xbyte, 1 ) != 1 )
                return( LBER_DEFAULT );
 
+       tag = xbyte;
+
        if ( (xbyte & LBER_BIG_TAG_MASK) != LBER_BIG_TAG_MASK )
-               return( (ber_tag_t) xbyte );
+               return tag;
 
-       tagp = (char *) &tag;
-       tagp[0] = xbyte;
        for ( i = 1; i < sizeof(ber_tag_t); i++ ) {
                if ( ber_read( ber, (char *) &xbyte, 1 ) != 1 )
                        return( LBER_DEFAULT );
 
-               tagp[i] = xbyte;
+               tag <<= 8;
+               tag |= 0x00ffUL & (ber_tag_t) xbyte;
 
                if ( ! (xbyte & LBER_MORE_TAG_MASK) )
                        break;
@@ -70,8 +67,7 @@ ber_get_tag( BerElement *ber )
        if ( i == sizeof(ber_tag_t) )
                return( LBER_DEFAULT );
 
-       /* want leading, not trailing 0's */
-       return( tag >> (sizeof(ber_tag_t) - i - 1) );
+       return tag;
 }
 
 ber_tag_t
@@ -79,9 +75,8 @@ ber_skip_tag( BerElement *ber, ber_len_t *len )
 {
        ber_tag_t       tag;
        unsigned char   lc;
-       ber_len_t       noctets;
-       int             diff;
-       ber_len_t       netlen;
+       ber_len_t       i, noctets;
+       unsigned char netlen[sizeof(ber_len_t)];
 
        assert( ber != NULL );
        assert( len != NULL );
@@ -97,6 +92,8 @@ ber_skip_tag( BerElement *ber, ber_len_t *len )
         *      2) primitive encodings used whenever possible
         */
 
+       *len = 0;
+
        /*
         * First, we read the tag.
         */
@@ -111,18 +108,25 @@ ber_skip_tag( BerElement *ber, ber_len_t *len )
         * greater than what we can hold in a ber_len_t.
         */
 
-       *len = netlen = 0;
        if ( ber_read( ber, (char *) &lc, 1 ) != 1 )
                return( LBER_DEFAULT );
+
        if ( lc & 0x80U ) {
                noctets = (lc & 0x7fU);
-               if ( noctets > sizeof(ber_len_t) )
+
+               if ( noctets > sizeof(ber_len_t) ) {
                        return( LBER_DEFAULT );
-               diff = sizeof(ber_len_t) - noctets;
-               if ( (unsigned) ber_read( ber, (char *) &netlen + diff, noctets )
-                   != noctets )
+               }
+
+               if( (unsigned) ber_read( ber, netlen, noctets ) != noctets ) {
                        return( LBER_DEFAULT );
-               *len = LBER_LEN_NTOH( netlen );
+               }
+
+               for( i = 0; i < noctets; i++ ) {
+                       *len <<= 8;
+                       *len |= netlen[i];
+               }
+
        } else {
                *len = lc;
        }
@@ -132,7 +136,7 @@ ber_skip_tag( BerElement *ber, ber_len_t *len )
 
 ber_tag_t
 ber_peek_tag(
-       LDAP_CONST BerElement *ber_in,
+       BerElement *ber_in,
        ber_len_t *len )
 {
        ber_tag_t       tag;
@@ -141,6 +145,8 @@ ber_peek_tag(
        assert( ber_in != NULL );
        assert( BER_VALID( ber_in ) );
 
+       *len = 0;
+
        ber = ber_dup( ber_in );
 
        if( ber == NULL ) {
@@ -222,6 +228,14 @@ ber_get_int(
                return( tag );
 }
 
+ber_tag_t
+ber_get_enum(
+       BerElement *ber,
+       ber_int_t *num )
+{
+       return ber_get_int( ber, num );
+}
+
 ber_tag_t
 ber_get_stringb(
        BerElement *ber,
@@ -231,10 +245,6 @@ ber_get_stringb(
        ber_len_t       datalen;
        ber_tag_t       tag;
 
-#ifdef STR_TRANSLATION
-       char            *transbuf;
-#endif /* STR_TRANSLATION */
-
        assert( ber != NULL );
        assert( BER_VALID( ber ) );
 
@@ -248,25 +258,6 @@ ber_get_stringb(
 
        buf[datalen] = '\0';
 
-#ifdef STR_TRANSLATION
-       if ( datalen > 0 && ( ber->ber_options & LBER_TRANSLATE_STRINGS ) != 0
-           && ber->ber_decode_translate_proc ) {
-               transbuf = buf;
-               ++datalen;
-               if ( (*(ber->ber_decode_translate_proc))( &transbuf, &datalen,
-                   0 ) != 0 ) {
-                       return( LBER_DEFAULT );
-               }
-               if ( datalen > *len ) {
-                       LBER_FREE( transbuf );
-                       return( LBER_DEFAULT );
-               }
-               SAFEMEMCPY( buf, transbuf, datalen );
-               LBER_FREE( transbuf );
-               --datalen;
-       }
-#endif /* STR_TRANSLATION */
-
        *len = datalen;
        return( tag );
 }
@@ -297,19 +288,6 @@ ber_get_stringa( BerElement *ber, char **buf )
        }
        (*buf)[datalen] = '\0';
 
-#ifdef STR_TRANSLATION
-       if ( datalen > 0 && ( ber->ber_options & LBER_TRANSLATE_STRINGS ) != 0
-           && ber->ber_decode_translate_proc ) {
-               ++datalen;
-               if ( (*(ber->ber_decode_translate_proc))( buf, &datalen, 1 )
-                   != 0 ) {
-                       LBER_FREE( *buf );
-                       *buf = NULL;
-                       return( LBER_DEFAULT );
-               }
-       }
-#endif /* STR_TRANSLATION */
-
        return( tag );
 }
 
@@ -346,20 +324,6 @@ ber_get_stringal( BerElement *ber, struct berval **bv )
        ((*bv)->bv_val)[len] = '\0';
        (*bv)->bv_len = len;
 
-#ifdef STR_TRANSLATION
-       if ( len > 0 && ( ber->ber_options & LBER_TRANSLATE_STRINGS ) != 0
-           && ber->ber_decode_translate_proc ) {
-               ++len;
-               if ( (*(ber->ber_decode_translate_proc))( &((*bv)->bv_val),
-                   &len, 1 ) != 0 ) {
-                       ber_bvfree( *bv );
-                       *bv = NULL;
-                       return( LBER_DEFAULT );
-               }
-               (*bv)->bv_len = len - 1;
-       }
-#endif /* STR_TRANSLATION */
-
        return( tag );
 }
 
@@ -470,7 +434,7 @@ ber_tag_t
 ber_next_element(
        BerElement *ber,
        ber_len_t *len,
-       char *last )
+       LDAP_CONST char *last )
 {
        assert( ber != NULL );
        assert( len != NULL );
@@ -764,17 +728,3 @@ ber_scanf ( BerElement *ber,
 
        return( rc );
 }
-
-
-#ifdef STR_TRANSLATION
-void
-ber_set_string_translators( BerElement *ber, BERTranslateProc encode_proc,
-       BERTranslateProc decode_proc )
-{
-       assert( ber != NULL );
-       assert( BER_VALID( ber ) );
-
-    ber->ber_encode_translate_proc = encode_proc;
-    ber->ber_decode_translate_proc = decode_proc;
-}
-#endif /* STR_TRANSLATION */
index 749958b1ee708640bb02095eb34f3fd68242d251..633d42ed7edaaf8ffa3652fbc46af920dee91132 100644 (file)
@@ -1,7 +1,7 @@
 /* dtest.c - lber decoding test program */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* Portions
@@ -47,6 +47,7 @@ main( int argc, char **argv )
 
        BerElement      *ber;
        Sockbuf         *sb;
+       int             fd;
 
        /* enable debugging */
        int ival = -1;
@@ -62,7 +63,10 @@ main( int argc, char **argv )
        cshow( stdout );
 #endif
 
-       sb = ber_sockbuf_alloc_fd( fileno(stdin) );
+       sb = ber_sockbuf_alloc();
+       fd = fileno( stdin );
+       ber_sockbuf_add_io( sb, &ber_sockbuf_io_fd, LBER_SBIOD_LEVEL_PROVIDER,
+               (void *)&fd );
 
        if( (ber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
                perror( "ber_alloc_t" );
diff --git a/libraries/liblber/dtest.dsp b/libraries/liblber/dtest.dsp
new file mode 100644 (file)
index 0000000..ad00d2c
--- /dev/null
@@ -0,0 +1,200 @@
+# Microsoft Developer Studio Project File - Name="dtest" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=dtest - Win32 DLL Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "dtest.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "dtest.mak" CFG="dtest - Win32 DLL Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "dtest - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "dtest - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "dtest - Win32 Single Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "dtest - Win32 Single Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "dtest - Win32 DLL Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "dtest - Win32 DLL Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "dtest - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\dtest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\Release"
+
+!ELSEIF  "$(CFG)" == "dtest - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "dtest___"
+# PROP BASE Intermediate_Dir "dtest___"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\dtest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Debug"
+
+!ELSEIF  "$(CFG)" == "dtest - Win32 Single Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "dtest___"
+# PROP BASE Intermediate_Dir "dtest___"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\dtest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 olber32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\Debug"
+# ADD LINK32 ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\SDebug"
+
+!ELSEIF  "$(CFG)" == "dtest - Win32 Single Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "dtest__0"
+# PROP BASE Intermediate_Dir "dtest__0"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\dtest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 olber32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\Release"
+# ADD LINK32 ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\SRelease"
+
+!ELSEIF  "$(CFG)" == "dtest - Win32 DLL Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "dtest___"
+# PROP BASE Intermediate_Dir "dtest___"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\DLLDebug"
+# PROP Intermediate_Dir "..\..\DLLDebug\dtest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Debug"
+# ADD LINK32 ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Debug"
+
+!ELSEIF  "$(CFG)" == "dtest - Win32 DLL Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "dtest__0"
+# PROP BASE Intermediate_Dir "dtest__0"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "dtest__0"
+# PROP Intermediate_Dir "dtest__0"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\Release"
+# ADD LINK32 ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\Release"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "dtest - Win32 Release"
+# Name "dtest - Win32 Debug"
+# Name "dtest - Win32 Single Debug"
+# Name "dtest - Win32 Single Release"
+# Name "dtest - Win32 DLL Debug"
+# Name "dtest - Win32 DLL Release"
+# Begin Source File
+
+SOURCE=.\dtest.c
+# End Source File
+# End Target
+# End Project
index ef515a3369718935030921256c877f41d5a7fea5..68f321d8bed4d1d9fa1e7c3dd9d8ad36657cb0f3 100644 (file)
@@ -1,7 +1,7 @@
 /* encode.c - ber output encoding routines */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* Portions
@@ -26,9 +26,6 @@
 #include <ac/socket.h>
 #include <ac/string.h>
 
-#undef LDAP_F_PRE
-#define LDAP_F_PRE LDAP_F_EXPORT
-
 #include "lber-int.h"
 
 static int ber_put_len LDAP_P((
@@ -73,17 +70,21 @@ ber_put_tag(
 {
        int rc;
        ber_len_t       taglen;
-       ber_tag_t       ntag;
+       ber_len_t       i;
+       unsigned char nettag[sizeof(ber_tag_t)];
 
        assert( ber != NULL );
        assert( BER_VALID( ber ) );
 
        taglen = ber_calc_taglen( tag );
 
-       ntag = LBER_TAG_HTON( tag );
+       for( i=0; i<taglen; i++ ) {
+               nettag[(sizeof(ber_tag_t)-1) - i] = (unsigned char)(tag & 0xffU);
+               tag >>= 8;
+       }
 
        rc = ber_write( ber,
-               ((char *) &ntag) + sizeof(ber_tag_t) - taglen,
+               &nettag[sizeof(ber_tag_t) - taglen],
            taglen, nosos );
 
        return rc;
@@ -118,10 +119,11 @@ ber_calc_lenlen( ber_len_t len )
 static int
 ber_put_len( BerElement *ber, ber_len_t len, int nosos )
 {
-       int             i;
+       int rc;
+       int             i,j;
        char            lenlen;
        ber_len_t       mask;
-       ber_len_t       netlen;
+       unsigned char netlen[sizeof(ber_len_t)];
 
        assert( ber != NULL );
        assert( BER_VALID( ber ) );
@@ -151,19 +153,24 @@ ber_put_len( BerElement *ber, ber_len_t len, int nosos )
        lenlen = (unsigned char) ++i;
        if ( lenlen > 4 )
                return( -1 );
+
        lenlen |= 0x80UL;
 
        /* write the length of the length */
        if ( ber_write( ber, &lenlen, 1, nosos ) != 1 )
                return( -1 );
 
+       for( j=0; j<i; j++) {
+               netlen[(sizeof(ber_len_t)-1) - j] = (unsigned char)(len & 0xffU);
+               len >>= 8;
+       }
+
        /* write the length itself */
-       netlen = LBER_LEN_HTON( len );
-       if ( ber_write( ber, (char *) &netlen + (sizeof(ber_len_t) - i), i, nosos )
-           != i )
-               return( -1 );
+       rc = ber_write( ber,
+               &netlen[sizeof(ber_len_t)-i],
+               i, nosos );
 
-       return( i + 1 );
+       return rc == i ?  i+1 : -1;
 }
 
 static int
@@ -172,9 +179,11 @@ ber_put_int_or_enum(
        ber_int_t num,
        ber_tag_t tag )
 {
-       int     i, sign;
+       int rc;
+       int     i, j, sign;
        ber_len_t       len, lenlen, taglen;
-       ber_uint_t      unum, netnum, mask;
+       ber_uint_t      unum, mask;
+       unsigned char netnum[sizeof(ber_uint_t)];
 
        assert( ber != NULL );
        assert( BER_VALID( ber ) );
@@ -216,13 +225,18 @@ ber_put_int_or_enum(
        if ( (lenlen = ber_put_len( ber, len, 0 )) == -1 )
                return( -1 );
        i++;
-       netnum = LBER_INT_HTON( unum );
-       if ( ber_write( ber, (char *) &netnum + (sizeof(ber_int_t) - i), i, 0 )
-          != i )
-               return( -1 );
+
+       for( j=0; j<i; j++ ) {
+               netnum[(sizeof(ber_int_t)-1) - j] = (unsigned char)(unum & 0xffU);
+               unum >>= 8;
+       }
+
+       rc = ber_write( ber,
+               &netnum[sizeof(ber_int_t) - i],
+               i, 0 );
 
        /* length of tag + length + contents */
-       return( taglen + lenlen + i );
+       return rc == i ? taglen + lenlen + i : -1;
 }
 
 int
@@ -264,9 +278,6 @@ ber_put_ostring(
 {
        ber_len_t       taglen, lenlen;
        int rc;
-#ifdef STR_TRANSLATION
-       int     free_str;
-#endif /* STR_TRANSLATION */
 
        assert( ber != NULL );
        assert( str != NULL );
@@ -279,19 +290,6 @@ ber_put_ostring(
        if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 )
                return( -1 );
 
-#ifdef STR_TRANSLATION
-       if ( len > 0 && ( ber->ber_options & LBER_TRANSLATE_STRINGS ) != 0 &&
-           ber->ber_encode_translate_proc ) {
-               if ( (*(ber->ber_encode_translate_proc))( &str, &len, 0 )
-                   != 0 ) {
-                       return( -1 );
-               }
-               free_str = 1;
-       } else {
-               free_str = 0;
-       }
-#endif /* STR_TRANSLATION */
-
        if ( (lenlen = ber_put_len( ber, len, 0 )) == -1 ||
                (ber_len_t) ber_write( ber, str, len, 0 ) != len ) {
                rc = -1;
@@ -300,12 +298,6 @@ ber_put_ostring(
                rc = taglen + lenlen + len;
        }
 
-#ifdef STR_TRANSLATION
-       if ( free_str ) {
-               LBER_FREE( str );
-       }
-#endif /* STR_TRANSLATION */
-
        return( rc );
 }
 
@@ -402,8 +394,8 @@ ber_put_boolean(
        ber_tag_t tag )
 {
        ber_len_t               taglen;
-       unsigned char   trueval = 0xFFU;
-       unsigned char   falseval = 0x00U;
+       unsigned char   trueval = (unsigned char) -1;
+       unsigned char   falseval = 0;
 
        assert( ber != NULL );
        assert( BER_VALID( ber ) );
@@ -484,7 +476,9 @@ ber_start_set( BerElement *ber, ber_tag_t tag )
 static int
 ber_put_seqorset( BerElement *ber )
 {
-       ber_len_t       len, netlen;
+       int rc;
+       ber_len_t       len;
+       unsigned char netlen[sizeof(ber_len_t)];
        ber_len_t       taglen, lenlen;
        unsigned char   ltag = 0x80U + FOUR_BYTE_LEN - 1;
        Seqorset        *next;
@@ -502,16 +496,27 @@ ber_put_seqorset( BerElement *ber )
         */
 
        len = (*sos)->sos_clen;
-       netlen = LBER_LEN_HTON( len );
+
        if ( sizeof(ber_len_t) > 4 && len > 0xffffffffUL )
                return( -1 );
 
        if ( ber->ber_options & LBER_USE_DER ) {
                lenlen = ber_calc_lenlen( len );
+
        } else {
                lenlen = FOUR_BYTE_LEN;
        }
 
+       if( lenlen > 1 ) {
+               ber_len_t i;
+               for( i=0; i < lenlen-1; i++ ) {
+                       netlen[(sizeof(ber_len_t)-1) - i] = 
+                               (unsigned char)((len >> i*8) & 0xffU);
+               }
+       } else {
+               netlen[sizeof(ber_len_t)-1] = (unsigned char)(len & 0x7fU);
+       }
+
        if ( (next = (*sos)->sos_next) == NULL ) {
                /* write the tag */
                if ( (taglen = ber_put_tag( ber, (*sos)->sos_tag, 1 )) == -1 )
@@ -539,21 +544,48 @@ ber_put_seqorset( BerElement *ber )
                                return( -1 );
 
                        /* the length itself */
-                       if ( ber_write( ber, (char *) (&netlen + 1)
-                           - (FOUR_BYTE_LEN - 1), FOUR_BYTE_LEN - 1, 1 )
-                           != FOUR_BYTE_LEN - 1 )
+                       rc  = ber_write( ber,
+                               &netlen[sizeof(ber_len_t) - (FOUR_BYTE_LEN-1)],
+                               FOUR_BYTE_LEN-1, 1 );
+
+                       if( rc != FOUR_BYTE_LEN - 1 ) {
                                return( -1 );
+                       }
                }
                /* The ber_ptr is at the set/seq start - move it to the end */
                (*sos)->sos_ber->ber_ptr += len;
+
        } else {
-               ber_tag_t       ntag;
+               ber_len_t i;
+               unsigned char nettag[sizeof(ber_tag_t)];
+               ber_tag_t tmptag = (*sos)->sos_tag;
+
+               if( ber->ber_sos->sos_ptr > ber->ber_end ) {
+                       /* The sos_ptr exceeds the end of the BerElement
+                        * this can happen, for example, when the sos_ptr
+                        * is near the end and no data was written for the
+                        * 'V'.  We must realloc the BerElement to ensure
+                        * we don't overwrite the buffer when writing
+                        * the tag and length fields.
+                        */
+                       ber_len_t ext = ber->ber_sos->sos_ptr - ber->ber_end;
+
+                       if( ber_realloc( ber,  ext ) != 0 ) {
+                               return -1;
+                       }
+               }
 
                /* the tag */
-               taglen = ber_calc_taglen( (*sos)->sos_tag );
-               ntag = LBER_TAG_HTON( (*sos)->sos_tag );
-               SAFEMEMCPY( (*sos)->sos_first, (char *) &ntag +
-                   sizeof(ber_tag_t) - taglen, taglen );
+               taglen = ber_calc_taglen( tmptag );
+
+               for( i = 0; i < taglen; i++ ) {
+                       nettag[(sizeof(ber_tag_t)-1) - i] = (unsigned char)(tmptag & 0xffU);
+                       tmptag >>= 8;
+               }
+
+               SAFEMEMCPY( (*sos)->sos_first,
+                       &nettag[sizeof(ber_tag_t) - taglen],
+                       taglen );
 
                if ( ber->ber_options & LBER_USE_DER ) {
                        ltag = (lenlen == 1)
@@ -568,9 +600,8 @@ ber_put_seqorset( BerElement *ber )
                        if (lenlen > 1) {
                                /* Write the length itself */
                                SAFEMEMCPY( (*sos)->sos_first + 2,
-                                   (char *)&netlen + sizeof(ber_len_t) -
-                                   (lenlen - 1),
-                                   lenlen - 1 );
+                                   &netlen[sizeof(ber_len_t) - (lenlen - 1)],
+                                       lenlen - 1 );
                        }
                        if (lenlen != FOUR_BYTE_LEN) {
                                /*
@@ -585,8 +616,8 @@ ber_put_seqorset( BerElement *ber )
                } else {
                        /* the length itself */
                        SAFEMEMCPY( (*sos)->sos_first + taglen + 1,
-                           (char *) &netlen + sizeof(ber_len_t) -
-                           (FOUR_BYTE_LEN - 1), FOUR_BYTE_LEN - 1 );
+                           &netlen[sizeof(ber_len_t) - (FOUR_BYTE_LEN - 1)],
+                               FOUR_BYTE_LEN - 1 );
                }
 
                next->sos_clen += (taglen + lenlen + len);
@@ -685,6 +716,7 @@ ber_printf( BerElement *ber, LDAP_CONST char *fmt, ... )
                        break;
 
                case 'B':       /* bit string */
+               case 'X':       /* bit string (deprecated) */
                        s = va_arg( ap, char * );
                        len = va_arg( ap, int );        /* in bits */
                        rc = ber_put_bitstring( ber, s, len, ber->ber_tag );
index 9d235b8554e3cc534843d7942f8847616d39d1e6..01c10e99071c2a7ef43d51e90d817b82afc28d2d 100644 (file)
@@ -1,7 +1,7 @@
 /* test.c - lber encoding test program */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* Portions
@@ -75,7 +75,9 @@ main( int argc, char **argv )
        fd = fileno(stdout);
 #endif
 
-       sb = ber_sockbuf_alloc_fd( fd );
+       sb = ber_sockbuf_alloc();
+       ber_sockbuf_add_io( sb, &ber_sockbuf_io_fd, LBER_SBIOD_LEVEL_PROVIDER,
+               (void *)&fd );
 
        if( sb == NULL ) {
                perror( "ber_sockbuf_alloc_fd" );
diff --git a/libraries/liblber/etest.dsp b/libraries/liblber/etest.dsp
new file mode 100644 (file)
index 0000000..69e94a2
--- /dev/null
@@ -0,0 +1,145 @@
+# Microsoft Developer Studio Project File - Name="etest" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=etest - Win32 Single Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "etest.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "etest.mak" CFG="etest - Win32 Single Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "etest - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "etest - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "etest - Win32 Single Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "etest - Win32 Single Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "etest - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\etest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\Release"
+
+!ELSEIF  "$(CFG)" == "etest - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "etest___"
+# PROP BASE Intermediate_Dir "etest___"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\etest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Debug"
+
+!ELSEIF  "$(CFG)" == "etest - Win32 Single Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "etest___"
+# PROP BASE Intermediate_Dir "etest___"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\etest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 olber32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\Debug"
+# ADD LINK32 ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\SDebug"
+
+!ELSEIF  "$(CFG)" == "etest - Win32 Single Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "etest__0"
+# PROP BASE Intermediate_Dir "etest__0"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\etest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 olber32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\Release"
+# ADD LINK32 ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\SRelease"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "etest - Win32 Release"
+# Name "etest - Win32 Debug"
+# Name "etest - Win32 Single Debug"
+# Name "etest - Win32 Single Release"
+# Begin Source File
+
+SOURCE=.\etest.c
+# End Source File
+# End Target
+# End Project
index 2bc6822971bb27e95d6713facf7c6df12ceaac79..51863c2d30d6526268f4e93316945fd0d011803e 100644 (file)
@@ -1,7 +1,7 @@
 /* idtest.c - ber decoding test program using isode libraries */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* Portions
index 830c16e5f01f66cdb4b45b36379c9ae0f2b828c0..859b70c13726b03a809acf1f8b8d3e07e1445ed5 100644 (file)
@@ -1,7 +1,7 @@
 /* io.c - ber general i/o routines */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* Portions
@@ -32,9 +32,6 @@
 #include <io.h>
 #endif
 
-#undef LDAP_F_PRE
-#define LDAP_F_PRE LDAP_F_EXPORT
-
 #include "lber-int.h"
 
 static ber_slen_t BerRead LDAP_P((
@@ -42,10 +39,6 @@ static ber_slen_t BerRead LDAP_P((
        char *buf,
        ber_len_t len ));
 
-static int ber_realloc LDAP_P((
-       BerElement *ber,
-       ber_len_t len ));
-
 #define EXBUFSIZ       1024
 
 /* probably far too large... */
@@ -71,7 +64,7 @@ BerRead(
        assert( SOCKBUF_VALID( sb ) );
 
        while ( len > 0 ) {
-               if ( (c = ber_pvt_sb_read( sb, buf, len )) <= 0 ) {
+               if ( (c = ber_int_sb_read( sb, buf, len )) <= 0 ) {
                        if ( nread > 0 )
                                break;
                        return( c );
@@ -140,7 +133,7 @@ ber_write(
        }
 }
 
-static int
+int
 ber_realloc( BerElement *ber, ber_len_t len )
 {
        ber_len_t       need, have, total;
@@ -202,10 +195,18 @@ ber_free( BerElement *ber, int freebuf )
 
        assert( BER_VALID( ber ) );
 
-       if ( freebuf && ber->ber_buf != NULL )
+       if ( freebuf ) {
+               Seqorset *s, *next;
                LBER_FREE( ber->ber_buf );
 
+               for( s = ber->ber_sos ; s != NULL ; s = next ) {
+                       next = s->sos_next;
+                       LBER_FREE( s );
+               }
+       }
+
        ber->ber_buf = NULL;
+       ber->ber_sos = NULL;
        ber->ber_valid = LBER_UNINITIALIZED;
 
        LBER_FREE( (char *) ber );
@@ -220,7 +221,7 @@ ber_flush( Sockbuf *sb, BerElement *ber, int freeit )
        assert( sb != NULL );
        assert( ber != NULL );
 
-       assert( SOCKBUF_VALID( ber ) );
+       assert( SOCKBUF_VALID( sb ) );
        assert( BER_VALID( ber ) );
 
        if ( ber->ber_rwptr == NULL ) {
@@ -231,26 +232,15 @@ ber_flush( Sockbuf *sb, BerElement *ber, int freeit )
        if ( sb->sb_debug ) {
                ber_log_printf( LDAP_DEBUG_ANY, sb->sb_debug,
                        "ber_flush: %ld bytes to sd %ld%s\n", towrite,
-                   (long) sb->sb_sd, ber->ber_rwptr != ber->ber_buf ? " (re-flush)"
-                   : "" );
+                   (long) sb->sb_fd, ber->ber_rwptr != ber->ber_buf ?
+                   " (re-flush)" : "" );
                ber_log_bprint( LDAP_DEBUG_PACKETS, sb->sb_debug,
                        ber->ber_rwptr, towrite );
        }
 
-#if HAVE_WRITE
-       if ( sb->sb_options & (LBER_TO_FILE | LBER_TO_FILE_ONLY) ) {
-               rc = write( sb->sb_fd, ber->ber_rwptr, towrite );
-               if ( sb->sb_options & LBER_TO_FILE_ONLY ) {
-                       if ( freeit )
-                               ber_free( ber, 1 );
-                       return( (int)rc );
-               }
-       }
-#endif
-       
        nwritten = 0;
        do {
-               rc = ber_pvt_sb_write( sb, ber->ber_rwptr, towrite );
+               rc = ber_int_sb_write( sb, ber->ber_rwptr, towrite );
                if (rc<=0) {
                        return -1;
                }
@@ -299,7 +289,7 @@ der_alloc( void )   /* deprecated */
 }
 
 BerElement *
-ber_dup( LDAP_CONST BerElement *ber )
+ber_dup( BerElement *ber )
 {
        BerElement      *new;
 
@@ -376,7 +366,7 @@ ber_init( struct berval *bv )
 ** the returned berval.
 */
 int ber_flatten(
-       LDAP_CONST BerElement *ber,
+       BerElement *ber,
        struct berval **bvPtr)
 {
        struct berval *bv;
@@ -445,7 +435,7 @@ get_tag( Sockbuf *sb )
        assert( sb != NULL );
        assert( SOCKBUF_VALID( sb ) );
 
-       if ( ber_pvt_sb_read( sb, (char *) &xbyte, 1 ) != 1 )
+       if ( ber_int_sb_read( sb, (char *) &xbyte, 1 ) != 1 )
                return( LBER_DEFAULT );
 
        if ( (xbyte & LBER_BIG_TAG_MASK) != LBER_BIG_TAG_MASK )
@@ -454,7 +444,7 @@ get_tag( Sockbuf *sb )
        tagp = (char *) &tag;
        tagp[0] = xbyte;
        for ( i = 1; i < sizeof(ber_tag_t); i++ ) {
-               if ( ber_pvt_sb_read( sb, (char *) &xbyte, 1 ) != 1 )
+               if ( ber_int_sb_read( sb, (char *) &xbyte, 1 ) != 1 )
                        return( LBER_DEFAULT );
 
                tagp[i] = xbyte;
@@ -474,7 +464,7 @@ get_tag( Sockbuf *sb )
 
 /*
  * A rewrite of ber_get_next that can safely be called multiple times 
- * for the same packet. It will simply continue were it stopped until
+ * for the same packet. It will simply continue where it stopped until
  * a full packet is read.
  */
 
@@ -515,12 +505,13 @@ ber_get_next(
                ber->ber_tag = 0;
        }
 
-#define PTR_IN_VAR( ptr, var )\
-(((ptr)>=(char *) &(var)) && ((ptr)< (char *) &(var)+sizeof(var)))
+#undef PTR_IN_VAR
+#define PTR_IN_VAR( ptr, var ) \
+       (((ptr)>=(char *) &(var)) && ((ptr)< (char *) &(var)+sizeof(var)))
        
        if (PTR_IN_VAR(ber->ber_rwptr, ber->ber_tag)) {
                if (ber->ber_rwptr == (char *) &ber->ber_tag) {
-                       if (ber_pvt_sb_read( sb, ber->ber_rwptr, 1)<=0)
+                       if (ber_int_sb_read( sb, ber->ber_rwptr, 1)<=0)
                                return LBER_DEFAULT;
                        if ((ber->ber_rwptr[0] & LBER_BIG_TAG_MASK)
                                != LBER_BIG_TAG_MASK) {
@@ -532,7 +523,7 @@ ber_get_next(
                }
                do {
                        /* reading the tag... */
-                       if (ber_pvt_sb_read( sb, ber->ber_rwptr, 1)<=0)
+                       if (ber_int_sb_read( sb, ber->ber_rwptr, 1)<=0)
                                return LBER_DEFAULT;
                        if (! (ber->ber_rwptr[0] & LBER_MORE_TAG_MASK) ) {
                                ber->ber_tag>>=sizeof(ber->ber_tag) -
@@ -540,14 +531,15 @@ ber_get_next(
                                ber->ber_rwptr = (char *) &ber->ber_usertag;
                                goto get_lenbyte;
                        }
-               } while (PTR_IN_VAR(ber->ber_rwptr,ber->ber_tag));
+               } while( PTR_IN_VAR(ber->ber_rwptr, ber->ber_tag ));
                errno = ERANGE; /* this is a serious error. */
                return LBER_DEFAULT;
        }
+
 get_lenbyte:
        if (ber->ber_rwptr==(char *) &ber->ber_usertag) {
                unsigned char c;
-               if (ber_pvt_sb_read( sb, (char *) &c, 1)<=0)
+               if (ber_int_sb_read( sb, (char *) &c, 1)<=0)
                        return LBER_DEFAULT;
                if (c & 0x80U) {
                        int len = c & 0x7fU;
@@ -563,29 +555,29 @@ get_lenbyte:
                        goto fill_buffer;
                }
        }
+
        if (PTR_IN_VAR(ber->ber_rwptr, ber->ber_len)) {
+               unsigned char netlen[sizeof(ber_len_t)];
+
                ber_slen_t res;
                ber_slen_t to_go;
                to_go = (char *) &ber->ber_len + sizeof( ber->ber_len ) -
                        ber->ber_rwptr;
                assert( to_go > 0 );
-               res = ber_pvt_sb_read( sb, ber->ber_rwptr, to_go );
-               if (res <=0)
+               res = BerRead( sb, netlen, to_go );
+               if (res <= 0) {
                        return LBER_DEFAULT;
+               }
                ber->ber_rwptr += res;
-               if (res==to_go) {
-                       /* convert length. */
-                       ber->ber_len = LBER_LEN_NTOH( ber->ber_len );
-                       goto fill_buffer;
-               } else {
-#if defined( EWOULDBLOCK )
-                       errno = EWOULDBLOCK;
-#elif defined( EAGAIN )
-                       errno = EAGAIN;
-#endif                 
-                       return LBER_DEFAULT;
+
+               /* convert length. */
+               ber->ber_len = 0;
+               for( to_go = 0; to_go < res ; to_go++ ) {
+                       ber->ber_len <<= 8;
+                       ber->ber_len |= netlen[to_go];
                }
        }
+
 fill_buffer:   
        /* now fill the buffer. */
        if (ber->ber_buf==NULL) {
@@ -600,6 +592,7 @@ fill_buffer:
                ber->ber_ptr = ber->ber_buf;
                ber->ber_end = ber->ber_buf + ber->ber_len;
        }
+
        if ((ber->ber_rwptr>=ber->ber_buf) && (ber->ber_rwptr<ber->ber_end)) {
                ber_slen_t res;
                ber_slen_t to_go;
@@ -607,7 +600,7 @@ fill_buffer:
                to_go = ber->ber_end - ber->ber_rwptr;
                assert( to_go > 0 );
                
-               res = ber_pvt_sb_read( sb, ber->ber_rwptr, to_go );
+               res = ber_int_sb_read( sb, ber->ber_rwptr, to_go );
                if (res<=0)
                        return LBER_DEFAULT;
                ber->ber_rwptr+=res;
index 7d080349f58dccf4689ebeb3523a081e011570fa..136ea0c024e30df54b60978073325492cf770fa4 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* Portions
 
 LDAP_BEGIN_DECL
 
-/* these have to match lber types settings */
-#define LBER_INT_HTON(i)       AC_HTONL(i)
-#define LBER_INT_NTOH(i)       AC_NTOHL(i)
-#define LBER_LEN_HTON(l)       AC_HTONL(l)
-#define LBER_LEN_NTOH(l)       AC_NTOHL(l)
-#define LBER_TAG_HTON(t)       AC_HTONL(t)
-#define LBER_TAG_NTOH(t)       AC_NTOHL(t)
-
+LIBLBER_F (BER_ERRNO_FN) ber_int_errno_fn;
 
 struct lber_options {
        short lbo_valid;
+       unsigned short          lbo_options;
+       int                     lbo_debug;
+};
+
 #define LBER_UNINITIALIZED             0x0
 #define LBER_INITIALIZED               0x1
 #define LBER_VALID_BERELEMENT  0x2
 #define LBER_VALID_SOCKBUF             0x3
 
-       unsigned short lbo_options;
-       int lbo_debug;
-};
-
-extern struct lber_options ber_int_options;
+LIBLBER_F (struct lber_options) ber_int_options;
 #define ber_int_debug ber_int_options.lbo_debug
 
 struct berelement {
@@ -64,111 +57,24 @@ struct berelement {
 
        struct seqorset *ber_sos;
        char            *ber_rwptr;
-       BERTranslateProc ber_encode_translate_proc;
-       BERTranslateProc ber_decode_translate_proc;
 };
 #define BER_VALID(ber) ((ber)->ber_valid==LBER_VALID_BERELEMENT)
 
-
 #define ber_pvt_ber_bytes(ber)         ((ber)->ber_ptr - (ber)->ber_buf)
 #define ber_pvt_ber_remaining(ber)     ((ber)->ber_end - (ber)->ber_ptr)
 
-struct sockbuf;
-
-struct sockbuf_io {
-       int     (*sbi_setup)( struct sockbuf * sb, void *arg );
-       int     (*sbi_remove)( struct sockbuf *sb );
-       
-       ber_slen_t      (*sbi_read)( struct sockbuf *sb, void *buf, ber_len_t len );
-       ber_slen_t      (*sbi_write)( struct sockbuf *sb, void *buf, ber_len_t len );
-       int     (*sbi_close)( struct sockbuf *sb );
-};
-
-struct sockbuf_sec {
-       int     (*sbs_setup)( struct sockbuf * sb, void *arg );
-       int     (*sbs_remove)( struct sockbuf *sb );
-   
-       long    (*sbs_protect)( struct sockbuf *sb, char *in, long *ilen,
-                               char *out, long olen );
-       long    (*sbs_release)( struct sockbuf *sb, char *in, long ilen,
-                              char *out0, long olen0, char *out1, long olen1 );
-};
-
-struct sockbuf_buf {
-       ber_len_t       buf_size;
-       ber_len_t       buf_ptr;
-       ber_len_t       buf_end;
-       char    *buf_base;
-};
-
-typedef struct sockbuf_io Sockbuf_IO;
-typedef struct sockbuf_sec Sockbuf_Sec;
-typedef struct sockbuf_buf Sockbuf_Buf;
-
-extern Sockbuf_IO ber_pvt_sb_io_tcp;
-extern Sockbuf_IO ber_pvt_sb_io_udp;
-
-
 struct sockbuf {
        struct lber_options sb_opts;
+       Sockbuf_IO_Desc         *sb_iod;                /* I/O functions */
 #define        sb_valid                sb_opts.lbo_valid
 #define        sb_options              sb_opts.lbo_options
 #define        sb_debug                sb_opts.lbo_debug
-
-       int             sb_non_block:1; 
-       int             sb_read_ahead:1;
-   
-       int             sb_buf_ready:1;
-       int             sb_trans_ready:1;
-       int             sb_sec_ready:1;
-      
-       /* these bits indicate if the transport layer 
-        * needs to read or write 
-        */
+       ber_socket_t            sb_fd;
        int             sb_trans_needs_read:1;
        int             sb_trans_needs_write:1;
-
-       int             sb_fd;
-   
-       void            *sb_iodata;     /* transport-layer data pointer */
-       Sockbuf_IO      *sb_io;         /* I/O functions */
-   
-#ifdef LDAP_SASL
-       void            *sb_sdata;      /* security-layer data pointer */
-       Sockbuf_Sec     *sb_sec;
-#endif 
-
-       ber_socket_t    sb_sd;
-
-#ifdef DEADWOOD
-       long            sb_max_incoming;
-#endif
-       Sockbuf_Buf     sb_buf;
-#ifdef LDAP_SASL   
-       Sockbuf_Buf     sb_sec_buf_in;
-       Sockbuf_Buf     sb_sec_buf_out;
-       ber_len_t       sb_sec_prev_len;
-#endif   
 };
-#define SOCKBUF_VALID(ber)     ((sb)->sb_valid==LBER_VALID_SOCKBUF)
-
-/* these should be internal ie: ber_int_* */
-#define        ber_pvt_sb_get_desc( sb ) ((sb)->sb_sd)
-#define ber_pvt_sb_set_desc( sb, val ) ((sb)->sb_sd =(val))
-
-#define ber_pvt_sb_in_use( sb ) ((sb)->sb_sd != AC_SOCKET_INVALID)
 
-#ifdef USE_SASL
-#define ber_pvt_sb_data_ready( sb ) \
-(((sb)->sb_buf_ready) || ((sb)->sb_trans_ready) || ((sb)->sb_sec_ready))
-#else
-#define ber_pvt_sb_data_ready( sb ) \
-(((sb)->sb_buf_ready) || ((sb)->sb_trans_ready))
-#endif
-#define ber_pvt_sb_needs_read( sb ) \
-((sb)->sb_trans_needs_read)
-#define ber_pvt_sb_needs_write( sb ) \
-((sb)->sb_trans_needs_write)
+#define SOCKBUF_VALID( sb )    ( (sb)->sb_valid == LBER_VALID_SOCKBUF )
 
 #define READBUFSIZ     8192
 
@@ -182,35 +88,42 @@ struct seqorset {
 };
 
 
+/*
+ * io.c
+ */
+int ber_realloc LDAP_P((
+       BerElement *ber,
+       ber_len_t len ));
+
 /*
  * bprint.c
  */
 #define ber_log_printf ber_pvt_log_printf
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_log_bprint LDAP_P((
        int errlvl,
        int loglvl,
        const char *data,
        ber_len_t len ));
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_log_dump LDAP_P((
        int errlvl,
        int loglvl,
-       const BerElement *ber,
+       BerElement *ber,
        int inout ));
 
-LDAP_F( int )
+LIBLBER_F( int )
 ber_log_sos_dump LDAP_P((
        int errlvl,
        int loglvl,
-       const Seqorset *sos ));
+       Seqorset *sos ));
 
 
 /* memory.c */
        /* simple macros to realloc for now */
-extern BerMemoryFunctions*             ber_int_memory_fns;
+LIBLBER_F (BerMemoryFunctions *)       ber_int_memory_fns;
 
 #ifdef CSRIMALLOC
 #define LBER_INT_MALLOC                malloc
@@ -245,50 +158,21 @@ extern BerMemoryFunctions*                ber_int_memory_fns;
 
 /* sockbuf.c */
 
-/* these should be ber_int*() functions */
-
-LDAP_F( int )
-ber_pvt_sb_init LDAP_P(( Sockbuf *sb ));
-
-LDAP_F(        int )
-ber_pvt_sb_destroy LDAP_P(( Sockbuf *sb ));
-
-#ifdef USE_SASL
-LDAP_F( int )
-ber_pvt_sb_set_sec LDAP_P(( Sockbuf *sb, Sockbuf_Sec *sec, void *arg ));
-
-LDAP_F( int )
-ber_pvt_sb_clear_sec LDAP_P(( Sockbuf *sb ));
-#endif
-
-LDAP_F(        int )
-ber_pvt_sb_set_io LDAP_P(( Sockbuf *sb, Sockbuf_IO *layer, void *arg ));
-
-LDAP_F(        int )
-ber_pvt_sb_clear_io LDAP_P(( Sockbuf *sb ));
-
-LDAP_F(        int )
-ber_pvt_sb_close LDAP_P((Sockbuf *sb ));
-
-LDAP_F( int )
-ber_pvt_sb_set_nonblock LDAP_P(( Sockbuf *sb, int nb ));
-
-LDAP_F( int )
-ber_pvt_sb_set_readahead LDAP_P(( Sockbuf *sb, int rh ));
+LIBLBER_F(     int )
+ber_int_sb_init LDAP_P(( Sockbuf *sb ));
 
-LDAP_F( ber_slen_t )
-ber_pvt_sb_read LDAP_P(( Sockbuf *sb, void *buf, ber_len_t len ));
+LIBLBER_F( int )
+ber_int_sb_close LDAP_P(( Sockbuf *sb ));
 
-LDAP_F( ber_slen_t )
-ber_pvt_sb_write LDAP_P(( Sockbuf *sb, void *buf, ber_len_t len ));
+LIBLBER_F(     int )
+ber_int_sb_destroy LDAP_P(( Sockbuf *sb ));
 
-LDAP_F(        int )
-ber_pvt_sb_udp_set_dst LDAP_P((Sockbuf *sb, void *addr ));
+LIBLBER_F( ber_slen_t )
+ber_int_sb_read LDAP_P(( Sockbuf *sb, void *buf, ber_len_t len ));
 
-LDAP_F(        void * )
-ber_pvt_sb_udp_get_src LDAP_P((Sockbuf *sb ));
+LIBLBER_F( ber_slen_t )
+ber_int_sb_write LDAP_P(( Sockbuf *sb, void *buf, ber_len_t len ));
 
-LDAP_F( int )
-ber_pvt_socket_set_nonblock LDAP_P(( ber_socket_t sd, int nb ));
+LDAP_END_DECL
 
 #endif /* _LBER_INT_H */
diff --git a/libraries/liblber/liblber.dsp b/libraries/liblber/liblber.dsp
new file mode 100644 (file)
index 0000000..e02e1f3
--- /dev/null
@@ -0,0 +1,225 @@
+# Microsoft Developer Studio Project File - Name="liblber" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=liblber - Win32 DLL Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "liblber.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "liblber.mak" CFG="liblber - Win32 DLL Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "liblber - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "liblber - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE "liblber - Win32 Single Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE "liblber - Win32 Single Release" (based on\
+ "Win32 (x86) Static Library")
+!MESSAGE "liblber - Win32 DLL Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE "liblber - Win32 DLL Release" (based on "Win32 (x86) Static Library")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+
+!IF  "$(CFG)" == "liblber - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\liblber"
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_WINDOWS" /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\..\Release\olber32.lib"
+
+!ELSEIF  "$(CFG)" == "liblber - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\liblber"
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\..\Debug\olber32.lib"
+
+!ELSEIF  "$(CFG)" == "liblber - Win32 Single Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "liblber_"
+# PROP BASE Intermediate_Dir "liblber_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Sdebug"
+# PROP Intermediate_Dir "..\..\SDebug\liblber"
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
+# ADD CPP /nologo /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo /out:"..\Debug\olber32.lib"
+# ADD LIB32 /nologo /out:"..\..\SDebug\olber32.lib"
+
+!ELSEIF  "$(CFG)" == "liblber - Win32 Single Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "liblber0"
+# PROP BASE Intermediate_Dir "liblber0"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\liblber"
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_WINDOWS" /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo /out:"..\Release\olber32.lib"
+# ADD LIB32 /nologo /out:"..\..\SRelease\olber32.lib"
+
+!ELSEIF  "$(CFG)" == "liblber - Win32 DLL Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "liblber_"
+# PROP BASE Intermediate_Dir "liblber_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\DLLDebug"
+# PROP Intermediate_Dir "..\..\DLLDebug\liblber"
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo /out:"..\..\Debug\olber32.lib"
+# ADD LIB32 /nologo /out:"..\..\DLLDebug\olber32.lib"
+
+!ELSEIF  "$(CFG)" == "liblber - Win32 DLL Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "liblber0"
+# PROP BASE Intermediate_Dir "liblber0"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "liblber0"
+# PROP Intermediate_Dir "liblber0"
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_WINDOWS" /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo /out:"..\..\Release\olber32.lib"
+# ADD LIB32 /nologo /out:"..\..\Release\olber32.lib"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "liblber - Win32 Release"
+# Name "liblber - Win32 Debug"
+# Name "liblber - Win32 Single Debug"
+# Name "liblber - Win32 Single Release"
+# Name "liblber - Win32 DLL Debug"
+# Name "liblber - Win32 DLL Release"
+# Begin Source File
+
+SOURCE=.\bprint.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\decode.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\encode.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\io.c
+# End Source File
+# Begin Source File
+
+SOURCE=".\lber-int.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\lber.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\lber_pvt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\lber_types.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\memory.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\nt_err.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\options.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\sockbuf.c
+# End Source File
+# End Target
+# End Project
index 604e8ccc940cc49b0e442ced1cea018b599f27d5..3b4be421ba7bed8a55a5eb0b544de0e1a2e28a62 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 #include "portable.h"
@@ -8,12 +8,20 @@
 #include <ac/stdlib.h>
 #include <ac/string.h>
 
-#undef LDAP_F_PRE
-#define LDAP_F_PRE LDAP_F_EXPORT
-
 #include "lber-int.h"
 
 #if 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.
+ *
+ * The code behind this macro is subject to change as needed to
+ * support this testing.
+ */
+
 struct ber_mem_hdr {
        union bmu_align_u {
                ber_len_t       bmu_len_t;
@@ -30,13 +38,14 @@ struct ber_mem_hdr {
 #define bm_junk        ber_align.bmu_len_t
 #define bm_data        ber_align.bmu_char[1]
 };
-#define BER_MEM_JUNK 0xddeeddeeU
+#define BER_MEM_JUNK 0xdeaddadaU
 static const struct ber_mem_hdr ber_int_mem_hdr = { BER_MEM_JUNK };
 #define BER_MEM_BADADDR        ((void *) &ber_int_mem_hdr.bm_data)
 #define BER_MEM_VALID(p)       do { \
                assert( (p) != BER_MEM_BADADDR );       \
                assert( (p) != (void *) &ber_int_mem_hdr );     \
        } while(0)
+
 #else
 #define BER_MEM_VALID(p)       /* no-op */
 #endif
@@ -83,7 +92,6 @@ ber_memfree( void *p )
 
        assert( ber_int_memory_fns->bmf_free );
 
-               
        (*ber_int_memory_fns->bmf_free)( p );
 }
 
@@ -112,6 +120,7 @@ ber_memvfree( void **vec )
 void *
 ber_memalloc( ber_len_t s )
 {
+       void *new;
     ber_int_options.lbo_valid = LBER_INITIALIZED;
 
 #ifdef LDAP_MEMORY_DEBUG
@@ -131,21 +140,26 @@ ber_memalloc( ber_len_t s )
                mh->bm_junk = BER_MEM_JUNK;
 
                BER_MEM_VALID( &mh[1] );
-               return &mh[1];
+               new = &mh[1];
 #else
-               return malloc( s );
+               new = malloc( s );
 #endif
+       } else {
+               new = (*ber_int_memory_fns->bmf_malloc)( s );
        }
 
-       assert( ber_int_memory_fns->bmf_malloc );
+       if( new == NULL ) {
+               ber_errno = LBER_ERROR_MEMORY;
+       }
 
-       return (*ber_int_memory_fns->bmf_malloc)( s );
+       return new;
 }
 
 
 void *
 ber_memcalloc( ber_len_t n, ber_len_t s )
 {
+       void *new;
     ber_int_options.lbo_valid = LBER_INITIALIZED;
 
 #ifdef LDAP_MEMORY_DEBUG
@@ -164,21 +178,27 @@ ber_memcalloc( ber_len_t n, ber_len_t s )
                mh->bm_junk = BER_MEM_JUNK;
 
                BER_MEM_VALID( &mh[1] );
-               return &mh[1];
+               new = &mh[1];
 #else
-               return calloc( n, s );
+               new = calloc( n, s );
 #endif
+
+       } else {
+               new = (*ber_int_memory_fns->bmf_calloc)( n, s );
        }
 
-       assert( ber_int_memory_fns->bmf_calloc );
+       if( new == NULL ) {
+               ber_errno = LBER_ERROR_MEMORY;
+       }
 
-       return (*ber_int_memory_fns->bmf_calloc)( n, s );
+       return new;
 }
 
 
 void *
 ber_memrealloc( void* p, ber_len_t s )
 {
+       void *new = NULL;
     ber_int_options.lbo_valid = LBER_INITIALIZED;
 
        /* realloc(NULL,s) -> malloc(s) */
@@ -202,22 +222,26 @@ ber_memrealloc( void* p, ber_len_t s )
 
                p = realloc( mh, s + sizeof(struct ber_mem_hdr) );
 
-               if( p == NULL ) return NULL;
+               if( p != NULL ) {
+                       mh = p;
 
-               mh = p;
-
-               assert( mh->bm_junk == BER_MEM_JUNK );
+                       assert( mh->bm_junk == BER_MEM_JUNK );
 
-               BER_MEM_VALID( &mh[1] );
-               return &mh[1];
+                       BER_MEM_VALID( &mh[1] );
+                       new = &mh[1];
+               }
 #else
-               return realloc( p, s );
+               new = realloc( p, s );
 #endif
+       } else {
+               new = (*ber_int_memory_fns->bmf_realloc)( p, s );
        }
 
-       assert( ber_int_memory_fns->bmf_realloc );
+       if( new == NULL ) {
+               ber_errno = LBER_ERROR_MEMORY;
+       }
 
-       return (*ber_int_memory_fns->bmf_realloc)( p, s );
+       return new;
 }
 
 
@@ -258,6 +282,57 @@ ber_bvecfree( struct berval **bv )
        LBER_FREE( (char *) bv );
 }
 
+int
+ber_bvecadd( struct berval ***bvec, struct berval *bv )
+{
+       ber_len_t i;
+       struct berval **new;
+
+       ber_int_options.lbo_valid = LBER_INITIALIZED;
+
+       if( bvec == NULL ) {
+               if( bv == NULL ) {
+                       /* nothing to add */
+                       return 0;
+               }
+
+               *bvec = ber_memalloc( 2 * sizeof(struct berval *) );
+
+               if( *bvec == NULL ) {
+                       return -1;
+               }
+
+               (*bvec)[0] = bv;
+               (*bvec)[1] = NULL;
+
+               return 1;
+       }
+
+       BER_MEM_VALID( bvec );
+
+       /* count entries */
+       for ( i = 0; bvec[i] != NULL; i++ ) {
+               /* EMPTY */;
+       }
+
+       if( bv == NULL ) {
+               return i;
+       }
+
+       new = ber_memrealloc( *bvec, (i+2) * sizeof(struct berval *));
+
+       if( new == NULL ) {
+               return -1;
+       }
+
+       *bvec = new;
+
+       (*bvec)[i++] = bv;
+       (*bvec)[i] = NULL;
+
+       return i;
+}
+
 
 struct berval *
 ber_bvdup(
@@ -268,10 +343,12 @@ ber_bvdup(
        ber_int_options.lbo_valid = LBER_INITIALIZED;
 
        if( bv == NULL ) {
+               ber_errno = LBER_ERROR_PARAM;
                return NULL;
        }
 
        if(( new = LBER_MALLOC( sizeof(struct berval) )) == NULL ) {
+               ber_errno = LBER_ERROR_MEMORY;
                return NULL;
        }
 
@@ -282,6 +359,7 @@ ber_bvdup(
        }
 
        if(( new->bv_val = LBER_MALLOC( bv->bv_len + 1 )) == NULL ) {
+               ber_errno = LBER_ERROR_MEMORY;
                LBER_FREE( new );
                return NULL;
        }
@@ -293,6 +371,66 @@ ber_bvdup(
        return( new );
 }
 
+struct berval *
+ber_bvstr(
+       LDAP_CONST char *s )
+{
+       struct berval *new;
+
+       ber_int_options.lbo_valid = LBER_INITIALIZED;
+
+       if( s == NULL ) {
+               ber_errno = LBER_ERROR_PARAM;
+               return NULL;
+       }
+
+       if(( new = LBER_MALLOC( sizeof(struct berval) )) == NULL ) {
+               ber_errno = LBER_ERROR_MEMORY;
+               return NULL;
+       }
+
+       if ( *s == '\0' ) {
+               new->bv_val = NULL;
+               new->bv_len = 0;
+               return new;
+       }
+
+       new->bv_val = (char *) s;
+       new->bv_len = strlen( s );
+
+       return( new );
+}
+
+struct berval *
+ber_bvstrdup(
+       LDAP_CONST char *s )
+{
+       struct berval *new;
+       char *p;
+
+       ber_int_options.lbo_valid = LBER_INITIALIZED;
+
+       if( s == NULL ) {
+               ber_errno = LBER_ERROR_PARAM;
+               return NULL;
+       }
+
+       p = LBER_STRDUP( s );
+
+       if( p == NULL ) {
+               ber_errno = LBER_ERROR_MEMORY;
+               return NULL;
+       }
+
+       new = ber_bvstr( p );
+
+       if( new == NULL || *p == '\0' ) {
+               LBER_FREE( p );
+       }
+
+       return( new );
+}
+
 char *
 ber_strdup( LDAP_CONST char *s )
 {
@@ -306,12 +444,14 @@ ber_strdup( LDAP_CONST char *s )
 #endif
 
        if( s == NULL ) {
+               ber_errno = LBER_ERROR_PARAM;
                return( NULL );
        }
 
        len = strlen( s ) + 1;
 
        if ( (p = LBER_MALLOC( len )) == NULL ) {
+               ber_errno = LBER_ERROR_MEMORY;
                return( NULL );
        }
 
diff --git a/libraries/liblber/nt_err.c b/libraries/liblber/nt_err.c
new file mode 100644 (file)
index 0000000..45de02c
--- /dev/null
@@ -0,0 +1,88 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+#include "portable.h"
+
+#ifdef HAVE_WINSOCK2
+#include <winsock2.h>
+#elif HAVE_WINSOCK
+#include <winsock.h>
+#endif /* HAVE_WINSOCK(2) */
+
+#undef __RETSTR
+#define __RETSTR( x ) case x: return #x;
+
+char *ber_pvt_wsa_err2string( int err )
+{
+       switch( err )
+       {
+               __RETSTR( WSAEINTR )
+               __RETSTR( WSAEBADF )
+               __RETSTR( WSAEACCES )
+               __RETSTR( WSAEFAULT )
+               __RETSTR( WSAEINVAL )
+               __RETSTR( WSAEMFILE )
+               __RETSTR( WSAEWOULDBLOCK )
+               __RETSTR( WSAEINPROGRESS )
+               __RETSTR( WSAEALREADY )
+               __RETSTR( WSAENOTSOCK )
+               __RETSTR( WSAEDESTADDRREQ )
+               __RETSTR( WSAEMSGSIZE )
+               __RETSTR( WSAEPROTOTYPE )
+               __RETSTR( WSAENOPROTOOPT )
+               __RETSTR( WSAEPROTONOSUPPORT )
+               __RETSTR( WSAESOCKTNOSUPPORT )
+               __RETSTR( WSAEOPNOTSUPP )
+               __RETSTR( WSAEPFNOSUPPORT )
+               __RETSTR( WSAEAFNOSUPPORT )
+               __RETSTR( WSAEADDRINUSE )
+               __RETSTR( WSAEADDRNOTAVAIL )
+               __RETSTR( WSAENETDOWN )
+               __RETSTR( WSAENETUNREACH )
+               __RETSTR( WSAENETRESET )
+               __RETSTR( WSAECONNABORTED )
+               __RETSTR( WSAECONNRESET )
+               __RETSTR( WSAENOBUFS )
+               __RETSTR( WSAEISCONN )
+               __RETSTR( WSAENOTCONN )
+               __RETSTR( WSAESHUTDOWN )
+               __RETSTR( WSAETOOMANYREFS )
+               __RETSTR( WSAETIMEDOUT )
+               __RETSTR( WSAECONNREFUSED )
+               __RETSTR( WSAELOOP )
+               __RETSTR( WSAENAMETOOLONG )
+               __RETSTR( WSAEHOSTDOWN )
+               __RETSTR( WSAEHOSTUNREACH )
+               __RETSTR( WSAENOTEMPTY )
+               __RETSTR( WSAEPROCLIM )
+               __RETSTR( WSAEUSERS )
+               __RETSTR( WSAEDQUOT )
+               __RETSTR( WSAESTALE )
+               __RETSTR( WSAEREMOTE )
+               __RETSTR( WSASYSNOTREADY )
+               __RETSTR( WSAVERNOTSUPPORTED )
+               __RETSTR( WSANOTINITIALISED )
+               __RETSTR( WSAEDISCON )
+
+#ifdef HAVE_WINSOCK2
+               __RETSTR( WSAENOMORE )
+               __RETSTR( WSAECANCELLED )
+               __RETSTR( WSAEINVALIDPROCTABLE )
+               __RETSTR( WSAEINVALIDPROVIDER )
+               __RETSTR( WSASYSCALLFAILURE )
+               __RETSTR( WSASERVICE_NOT_FOUND )
+               __RETSTR( WSATYPE_NOT_FOUND )
+               __RETSTR( WSA_E_NO_MORE )
+               __RETSTR( WSA_E_CANCELLED )
+               __RETSTR( WSAEREFUSED )
+#endif // HAVE_WINSOCK2        
+
+               __RETSTR( WSAHOST_NOT_FOUND )
+               __RETSTR( WSATRY_AGAIN )
+               __RETSTR( WSANO_RECOVERY )
+               __RETSTR( WSANO_DATA )
+       }
+       return "unknown WSA error";
+}
\ No newline at end of file
index 4ffea28b1deef204b75b22240f8b675e931275b5..dc61707dfd73d42b75259aa5f33695c8f12ead67 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 #include "portable.h"
@@ -8,17 +8,16 @@
 #include <ac/stdlib.h>
 #include <ac/string.h>
 
-#undef LDAP_F_PRE
-#define LDAP_F_PRE LDAP_F_EXPORT
-
 #include "lber-int.h"
 
+extern void * ber_pvt_err_file;        /* bprint.c */
+
 struct lber_options ber_int_options = {
        LBER_UNINITIALIZED, 0, 0 };
 
 int
 ber_get_option(
-       LDAP_CONST void *item,
+       void    *item,
        int             option,
        void    *outvalue)
 {
@@ -29,6 +28,7 @@ ber_get_option(
 
        if(outvalue == NULL) {
                /* no place to get to */
+               ber_errno = LBER_ERROR_PARAM;
                return LBER_OPT_ERROR;
        }
 
@@ -38,6 +38,7 @@ ber_get_option(
                        return LBER_OPT_SUCCESS;
                }
 
+               ber_errno = LBER_ERROR_PARAM;
                return LBER_OPT_ERROR;
        }
 
@@ -55,8 +56,21 @@ ber_get_option(
                * (int *) outvalue = ber->ber_debug;
                return LBER_OPT_SUCCESS;
 
+       case LBER_OPT_BER_REMAINING_BYTES:
+               *((ber_len_t *) outvalue) = ber->ber_end - ber->ber_ptr;
+               return LBER_OPT_SUCCESS;
+
+       case LBER_OPT_BER_TOTAL_BYTES:
+               *((ber_len_t *) outvalue) = ber->ber_end - ber->ber_buf;
+               return LBER_OPT_SUCCESS;
+
+       case LBER_OPT_BER_BYTES_TO_WRITE:
+               *((ber_len_t *) outvalue) = ber->ber_ptr - ber->ber_buf;
+               return LBER_OPT_SUCCESS;
+
        default:
                /* bad param */
+               ber_errno = LBER_ERROR_PARAM;
                break;
        }
 
@@ -84,6 +98,7 @@ ber_set_option(
                if(!( f->bmf_malloc && f->bmf_calloc
                        && f->bmf_realloc && f->bmf_free ))
                {
+                       ber_errno = LBER_ERROR_PARAM;
                        return LBER_OPT_ERROR;
                }
 
@@ -91,6 +106,7 @@ ber_set_option(
                        (*(f->bmf_malloc))(sizeof(BerMemoryFunctions));
 
                if ( ber_int_memory_fns == NULL ) {
+                       ber_errno = LBER_ERROR_MEMORY;
                        return LBER_OPT_ERROR;
                }
 
@@ -104,6 +120,7 @@ ber_set_option(
 
        if(invalue == NULL) {
                /* no place to set from */
+               ber_errno = LBER_ERROR_PARAM;
                return LBER_OPT_ERROR;
        }
 
@@ -115,8 +132,12 @@ ber_set_option(
                } else if(option == LBER_OPT_LOG_PRINT_FN) {
                        ber_pvt_log_print = (BER_LOG_PRINT_FN) invalue;
                        return LBER_OPT_SUCCESS;
+               } else if(option == LBER_OPT_LOG_PRINT_FILE) {
+                       ber_pvt_err_file = (void *) invalue;
+                       return LBER_OPT_SUCCESS;
                }
 
+               ber_errno = LBER_ERROR_PARAM;
                return LBER_OPT_ERROR;
        }
 
@@ -134,8 +155,21 @@ ber_set_option(
                ber->ber_debug = * (const int *) invalue;
                return LBER_OPT_SUCCESS;
 
+       case LBER_OPT_BER_REMAINING_BYTES:
+               ber->ber_end = &ber->ber_ptr[* (const ber_len_t *) invalue];
+               return LBER_OPT_SUCCESS;
+
+       case LBER_OPT_BER_TOTAL_BYTES:
+               ber->ber_end = &ber->ber_buf[* (const ber_len_t *) invalue];
+               return LBER_OPT_SUCCESS;
+
+       case LBER_OPT_BER_BYTES_TO_WRITE:
+               ber->ber_ptr = &ber->ber_buf[* (const ber_len_t *) invalue];
+               return LBER_OPT_SUCCESS;
+
        default:
                /* bad param */
+               ber_errno = LBER_ERROR_PARAM;
                break;
        }
 
index 30bceb6bedcb4197e4b79c478a7d8478aa2a6eff..e3ddbcd44a8833bcb0db1c830ef52797629e5fdf 100644 (file)
@@ -1,7 +1,7 @@
 /* sockbuf.c - i/o routines with support for adding i/o layers. */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 #include <sys/ioctl.h>
 #endif
 
-#undef LDAP_F_PRE
-#define LDAP_F_PRE LDAP_F_EXPORT
-
 #include "lber-int.h"
 
-#ifdef LDAP_TEST
-#undef TEST_PARTIAL_READ
-#undef TEST_PARTIAL_WRITE
-#endif
-
-#define MAX_BUF_SIZE   65535
-#define MIN_BUF_SIZE   4096
+#define MIN_BUFF_SIZE          4096
+#define MAX_BUFF_SIZE          65536
+#define DEFAULT_READAHEAD      16384
 
-#define sockbuf_io_write( sb, buf, len ) \
-((sb)->sb_io->sbi_write( (sb), (buf), (len) ))
-
-#define sockbuf_io_read( sb, buf, len ) \
-((sb)->sb_io->sbi_read( (sb), (buf), (len) ))
+Sockbuf *
+ber_sockbuf_alloc( void )
+{
+       Sockbuf                 *sb;
 
-static ber_slen_t have_no_read( Sockbuf *sb, void *buf, ber_len_t len );
-static ber_slen_t have_no_write( Sockbuf *sb, void *buf, ber_len_t len );
-static int have_no_close( Sockbuf *sb );
+       ber_int_options.lbo_valid = LBER_INITIALIZED;
 
-static Sockbuf_IO sb_IO_None=
-{
-       NULL,   /* sbi_setup */
-       NULL,   /* sbi_release */
-       have_no_read,   /* sbi_read */
-       have_no_write,  /* sbi_write */
-       have_no_close   /* sbi_close */
-};
+       sb = LBER_CALLOC( 1, sizeof( Sockbuf ) );
 
-static void
-update_status( Sockbuf *sb )
-{
-       assert( sb != NULL );
-       assert( SOCKBUF_VALID( sb ) );
+       if( sb == NULL )
+               return NULL;
 
-   sb->sb_buf_ready = (sb->sb_buf.buf_ptr < sb->sb_buf.buf_end);
-#ifdef USE_SASL   
-   sb->sb_sec_ready = ((sb->sb_sec_buf_in.buf_end!=0) &&
-                      (sb->sb_sec_buf_in.buf_ptr >= 
-                       sb->sb_sec_buf_in.buf_end));
-#endif   
+       ber_int_sb_init( sb );
+       return sb;
 }
 
-#ifdef LDAP_DEBUG
-static int 
-status_is_ok( Sockbuf *sb )
+void
+ber_sockbuf_free( Sockbuf *sb )
 {
-       int obr;
-#ifdef USE_SASL
-       int osr;
-#endif
-
        assert( sb != NULL );
        assert( SOCKBUF_VALID( sb ) );
 
-       obr = sb->sb_buf_ready;
-#ifdef USE_SASL
-       osr = sb->sb_sec_ready;
-#endif
-
-   update_status(sb);
-   if (obr!=sb->sb_buf_ready)
-     return 0;
-
-#ifdef USE_SASL
-   if (osr!=sb->sb_sec_ready)
-     return 0;
-#endif
-
-   return 1;
+       ber_int_sb_close( sb );
+       ber_int_sb_destroy( sb );
+       LBER_FREE( sb );
 }
-#endif
 
-#ifdef USE_SASL
-static ber_len_t
-packet_length( Sockbuf *sb, const char *buf )
+/* Return values: -1: error, 0: no operation performed or the answer is false,
+ * 1: successful operation or the answer is true
+ */
+int
+ber_sockbuf_ctrl( Sockbuf *sb, int opt, void *arg )
 {
-   ber_len_t size;
+       Sockbuf_IO_Desc         *p;
+       int                     ret = 0;
+       char                    buf[4096];
 
-   assert( buf != NULL );
+       assert( sb != NULL );
 
-   size = (((ber_len_t)buf[0])<<24)|
-     (((ber_len_t)buf[1])<<16)|
-     (((ber_len_t)buf[2])<<8)|
-     (((ber_len_t)buf[3]));
-   
-   if ( size > MAX_BUF_SIZE ) {
-      /* somebody is trying to mess me up. */
-      ber_log_printf( LDAP_DEBUG_SASL, sb->sb_debug,
-                     "SASL: received packet length of %lu bytes\n",
-                     (unsigned long) size );      
-      size = 16; /* this should lead to an error. */
+       switch ( opt ) {
+               case LBER_SB_OPT_HAS_IO:
+                       p = sb->sb_iod;
+   
+                       while ( p && p->sbiod_io != (Sockbuf_IO *)arg )
+                               p = p->sbiod_next;
+   
+                       if ( p )
+                               ret = 1;
+                       break;
+               case LBER_SB_OPT_GET_FD:
+                       if ( arg != NULL )
+                               *((int *)arg) = sb->sb_fd;
+                       ret = ( sb->sb_fd == AC_SOCKET_INVALID ? -1 : 1);
+                       break;
+               case LBER_SB_OPT_SET_FD:
+                       sb->sb_fd = *((int *)arg);
+                       ret = 1;
+                       break;
+               case LBER_SB_OPT_SET_NONBLOCK:
+                       ret = ber_pvt_socket_set_nonblock( sb->sb_fd, arg != NULL)
+                               ? -1 : 1;
+                       break;
+               case LBER_SB_OPT_DRAIN:
+                       /* Drain the data source to enable possible errors (e.g.
+                        * TLS) to be propagated to the upper layers
+                        */
+                       do {
+                               ret = ber_int_sb_read( sb, buf, sizeof( buf ) );
+                       } while ( ret == sizeof( buf ) );
+
+                       ret = 1;
+                       break;
+               case LBER_SB_OPT_NEEDS_READ:
+                       ret = ( sb->sb_trans_needs_read ? 1 : 0 );
+                       break;
+               case LBER_SB_OPT_NEEDS_WRITE:
+                       ret = ( sb->sb_trans_needs_write ? 1 : 0 );
+                       break;
+               default:
+                       ret = sb->sb_iod->sbiod_io->sbi_ctrl( sb->sb_iod,
+                               opt, arg );
+                       break;
    }
-   
-   return size + 4; /* include the size !!! */
-}
-#endif
-
-static int
-grow_buffer( Sockbuf_Buf * buf, ber_len_t minsize )
-{
-   ber_len_t pw;;
-   
-   assert( buf != NULL );
 
-   for( pw=MIN_BUF_SIZE; pw<minsize; pw<<=1 ) {
-      if (pw > MAX_BUF_SIZE) {
-        /* this could mean that somebody is trying to crash us. */
-        return -1;
-      }
-   }
-   minsize = pw;
-
-   if (buf->buf_size<minsize) {
-      if ((buf->buf_base==NULL) || ((buf->buf_end==0) && (buf->buf_ptr==0))) {
-        /* empty buffer */
-        if (buf->buf_base!=NULL)
-          LBER_FREE( buf->buf_base );
-        assert( buf->buf_ptr==0 );
-        assert( buf->buf_end==0 );
-        buf->buf_base = LBER_MALLOC( minsize );
-        if (buf->buf_base==NULL)
-          return -1;
-      } else {
-        char *nb;
-        nb = LBER_REALLOC( buf->buf_base, minsize );
-        if (nb==NULL)
-          return -1;
-        buf->buf_base = nb;
-      }
-      buf->buf_size = minsize;
-   }
-   return 0;
+       return ret;
 }
 
-#ifdef USE_SASL
-static ber_slen_t
-sockbuf_sec_release( Sockbuf *sb, char *buf, ber_len_t len )
+int
+ber_sockbuf_add_io( Sockbuf *sb, Sockbuf_IO *sbio, int layer, void *arg )
 {
-   /* when this is called:
-    *  sb->sb_sec_buf_in.buf_base  points to a packet.
-    *  sb->sb_sec_buf_in.buf_ptr   contains the total bytes read.
-    *  sb->sb_sec_end.buf_end   contains the packet length.
-    * 
-    *  sb->sb_buf.buf_ptr == sb->sb_buf.buf_end == 0;
-    */
-   long rlen;
-   long total;
-   char *ptr;
-   char *end;
-   long size;
+       Sockbuf_IO_Desc         *d, *p, **q;
    
-    assert( buf != NULL );
        assert( sb != NULL );
        assert( SOCKBUF_VALID( sb ) );
-
-   assert( sb->sb_sec );
-   assert( sb->sb_sec->sbs_release );
-   assert( sb->sb_sec_buf_in.sb_ptr >= sb->sb_sec_buf_in.sb_end );
-   
-   assert( sb->sb_buf.sb_ptr == 0 );
-   assert( sb->sb_buf.sb_end == 0 );
-
-   assert( status_is_ok(sb) );
    
-   total = 0;
+       if ( sbio == NULL )
+               return -1;
    
-   ptr = sb->sb_sec_buf_in.buf_base;
-   end = ptr+ sb->sb_sec_buf_in.buf_ptr;
-   size = sb->sb_sec_buf_in.buf_end;
+       q = &sb->sb_iod;
+       p = *q;
+       while ( p && p->sbiod_level > layer ) {
+               q = &p->sbiod_next;
+               p = *q;
+       }
    
-   sb->sb_sec_ready = 1;
+       d = LBER_MALLOC( sizeof( *d ) );
+       if ( d == NULL )
+               return -1;
    
-   for(;(ptr+size<=end);) {
-      for(;;) {
-        rlen = sb->sb_sec->sbs_release( sb, ptr, size,
-                                       buf, len, 
-                                       sb->sb_buf.buf_base,
-                                       sb->sb_buf.buf_size );
-        if (rlen==0) {
-           /* this means a security violation. */
-           return total; /* total ? total : 0 */
-        }
-        if (rlen<0) {
-           /* this means that the buffer isn't big enough. */
-           if (grow_buffer( &(sb->sb_buf), -rlen )<0)
-             /* memory violation. */
-             return total; /* total ? total : 0 */
-           continue;
-        }
-        /* if (rlen>0) */
-        break;
-      }
-      total+=rlen;
-      
-      /* move to the next packet... */
-      ptr+=size;
+       d->sbiod_level = layer;
+       d->sbiod_sb = sb;
+       d->sbiod_io = sbio;
+       memset( &d->sbiod_pvt, '\0', sizeof( d->sbiod_pvt ) );
+       d->sbiod_next = p;
+       *q = d;
       
-      if (ptr+4<=end)
-       size = packet_length( sb, ptr ); 
-      /* size is always at least 4, so the loop condition is always OK !!*/
-      assert( size>=4 );
+       if ( sbio->sbi_setup != NULL && ( sbio->sbi_setup( d, arg ) < 0 ) )
+               return -1;
       
-      if (rlen<len) {
-        len-=rlen;
-        buf+=rlen;
-      } else {
-        sb->sb_buf_ready = (sb->sb_buf.buf_end = rlen - len) ? 1 : 0;
-        break;
-      }
+       return 0;
    }
    
-   if (ptr+size>end)
-     sb->sb_sec_ready = 0;
-   /* clean up the mess. */
-   if (ptr<end) {
-      /* copy back to beginning of buffer. */
-      SAFEMEMCPY( sb->sb_sec_buf_in.buf_base, ptr, end-ptr );
-      sb->sb_sec_buf_in.buf_ptr = 0;
-      sb->sb_sec_buf_in.buf_end -= (ptr - sb->sb_sec_buf_in.buf_base);
-   }
-   assert( status_is_ok(sb) );
-   return total;
-}
-
-static long
-sockbuf_sec_protect( Sockbuf *sb, char *buf, long len )
+int
+ber_sockbuf_remove_io( Sockbuf *sb, Sockbuf_IO *sbio, int layer )
 {
-   long ret;
-   long blen;
-   long total;
-   
-   assert( buf != NULL );
+       Sockbuf_IO_Desc         *p, **q;
 
    assert( sb != NULL );
        assert( SOCKBUF_VALID( sb ) );
-
-   assert( sb->sb_sec_out.buf_end == 0 );
-   assert( sb->sb_sec_out.buf_ptr == 0 );
-   
-   assert( sb->sb_sec );
-   assert( sb->sb_sec->sbs_protect );
    
-   assert( status_is_ok(sb) );
-   
-   total = 0;
-   for(;(len);) {
-      for(;;) {
-        blen = len;
-        ret = sb->sb_sec->sbs_protect( sb, buf, &blen, 
-                                      sb->sb_sec_out.buf_base+
-                                      sb->sb_sec_out.buf_end, 
-                                      sb->sb_sec_out.buf_size -
-                                      sb->sb_sec_out.buf_end );
-        if (ret==0)
-          /* protection error ? */
-          return total;
-        if (ret<0) {
-           if (grow_buffer( &(sb->sb_sec_out),-ret-sb->sb_sec_out.buf_end )<0)
-             /* memory error */
-             return total;
-           continue;
-        }
-        /* else if (ret>0) */
+       if ( sb->sb_iod == NULL )
+               return -1;
+   
+       q = &sb->sb_iod;
+       while ( *q != NULL ) {
+               p = *q;
+               if ( layer == p->sbiod_level && p->sbiod_io == sbio ) {
+                       if ( p->sbiod_io->sbi_remove != NULL &&
+                                       p->sbiod_io->sbi_remove( p ) < 0 )
+                               return -1;
+                       *q = p->sbiod_next;
+                       LBER_FREE( p );
         break;
-      }
-      sb->sb_sec_out.buf_end += ret;
-      len -= blen;
-      total += blen;
    }
-   assert( status_is_ok(sb) );
-   return total;
+               q = &p->sbiod_next;
 }
-#endif
-
-static ber_len_t 
-sockbuf_copy_out( Sockbuf *sb, char **buf, ber_len_t len )
-{
-   ber_len_t blen = (sb->sb_buf.buf_end - sb->sb_buf.buf_ptr );
 
-   assert( buf != NULL );
-
-   assert( sb != NULL );
-       assert( SOCKBUF_VALID( sb ) );
-   assert( status_is_ok(sb) );
-
-   if (blen) {
-      ber_len_t rlen = (blen<len) ? blen : len;
-      memcpy( *buf, sb->sb_buf.buf_base + sb->sb_buf.buf_ptr, rlen );
-      sb->sb_buf.buf_ptr+=rlen;
-      *buf+=rlen;
-      len -= rlen;
-      if (sb->sb_buf.buf_ptr >= sb->sb_buf.buf_end) {
-        sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0;
-        sb->sb_buf_ready = 0;
-      } else {
-        sb->sb_buf_ready = 1;
-      }
-   }
-   assert( status_is_ok(sb) );
-   return len;
+       return 0;
 }
 
-Sockbuf *ber_sockbuf_alloc( void )
+void
+ber_pvt_sb_buf_init( Sockbuf_Buf *buf )
 {
-       Sockbuf *sb;
-
-       ber_int_options.lbo_valid = LBER_INITIALIZED;
-
-       sb = LBER_CALLOC(1, sizeof(Sockbuf));
-
-       if( sb == NULL ) return NULL;
-
-       ber_pvt_sb_init( sb );
-       return sb;
+       buf->buf_base = NULL;
+       buf->buf_ptr = 0;
+       buf->buf_end = 0;
+       buf->buf_size = 0;
 }
 
-Sockbuf *ber_sockbuf_alloc_fd( ber_socket_t fd )
+void
+ber_pvt_sb_buf_destroy( Sockbuf_Buf *buf )
 {
-       Sockbuf *sb = ber_sockbuf_alloc();
-
-       if( sb == NULL ) return NULL;
-
-       ber_pvt_sb_set_desc( sb, fd );
-       ber_pvt_sb_set_io( sb, &ber_pvt_sb_io_tcp, NULL );
-       return sb;
-}
+       assert( buf != NULL);
 
-void ber_sockbuf_free( Sockbuf *sb )
-{
-       assert(sb != NULL);
-       assert( SOCKBUF_VALID( sb ) );
-       ber_pvt_sb_destroy( sb );
-       LBER_FREE(sb);
+       if (buf->buf_base)
+               LBER_FREE( buf->buf_base );
+       ber_pvt_sb_buf_init( buf );
 }
 
-ber_slen_t 
-ber_pvt_sb_read( Sockbuf *sb, void *buf_arg, ber_len_t len )
+int
+ber_pvt_sb_grow_buffer( Sockbuf_Buf *buf, ber_len_t minsize )
 {
-   char *buf;
-   ber_slen_t ret;
+       ber_len_t               pw;
+       char                    *p;
    
-   assert( buf_arg != NULL );
-   assert( sb != NULL );
-   assert( SOCKBUF_VALID( sb ) );
-   assert( status_is_ok(sb) );
-
-   /* slapd might have problems with this */
-   assert( ber_pvt_sb_in_use( sb ) );
+       assert( buf != NULL );
 
-#ifdef TEST_PARTIAL_READ
-   if ((rand() & 3)==1) { /* 1 out of 4 */
-      errno = EWOULDBLOCK;
+       for ( pw = MIN_BUFF_SIZE; pw < minsize; pw <<= 1 ) {
+               if (pw > MAX_BUFF_SIZE)
       return -1;
    }
 
-   if( len > 0 )
-          len = (rand() % len)+1;
-#endif   
-   
-   buf = (char *) buf_arg;
-
-   if (sb->sb_buf.buf_ptr!=sb->sb_buf.buf_end) {
-      len = sockbuf_copy_out( sb, &buf, len );
-      if (len==0) {
-        return (buf - (char *) buf_arg);
-      }
+       if ( buf->buf_size < pw ) {
+               p = LBER_REALLOC( buf->buf_base, pw );
+               if ( p == NULL )
+                       return -1;
+               buf->buf_base = p;
+               buf->buf_size = pw;
    }
-
-#ifdef USE_SASL
-   if (sb->sb_sec) {
-      ber_slen_t max;
-      assert( sb->sb_sec->sbs_release );
-      assert( sb->sb_sec_buf_in.buf_base );
-      if (sb->sb_read_ahead) {
-        max = sb->sb_sec_buf_in.buf_size - sb->sb_sec_buf_in.buf_ptr;
-      } else {
-        max = sb->sb_sec_buf_in.buf_end - sb->sb_sec_buf_in.buf_ptr;
-        if (max<=0) {
-           /* special situation. This means that we need to read the first
-            * four bytes for the packet length.
-            */
-           max += 4;
-        }
-      }
-      for(;;) {
-        /* read from stream into sb_sec_buf_in */
-        for(;;) {
-           ret = sockbuf_io_read( sb, sb->sb_sec_buf_in.buf_base +
-                                 sb->sb_sec_buf_in.buf_ptr, max );
-#ifdef EINTR
-           if ((ret<0) && (errno==EINTR))
-             continue;
-#endif
-           break;
-        }
-        if (ret<=0) {
-           /* read error. return */
-           goto do_return;
-        }
-        sb->sb_sec_buf_in.buf_ptr += ret;
-        
-        if (sb->sb_sec_buf_in.buf_ptr < sb->sb_sec_buf_in.buf_end) {
-           /* did not finish a packet. give up. */
-           goto do_return;
-        }
-           
-        if (sb->sb_sec_buf_in.buf_end == 0) {
-           /* Were trying to read the first four bytes... */
-           if (sb->sb_sec_buf_in.buf_ptr < 4) {
-              /* did not read enough for packet length. give up. */
-              goto do_return;
-           }
-           /* calculate the packet length. */
-           sb->sb_sec_buf_in.buf_end = 
-              packet_length(sb, sb->sb_sec_buf_in.buf_base );
-           if ((sb->sb_sec_buf_in.buf_end > sb->sb_sec_buf_in.buf_size) &&
-               (grow_buffer( &(sb->sb_sec_buf_in), sb->sb_sec_buf_in.buf_end)<0)) {
-              /* buffer has to be to big. exit with error. */
-              ret = -1;
-              goto do_return;
-           }
-           if (sb->sb_sec_buf_in.buf_ptr >= sb->sb_sec_buf_in.buf_end) {
-              /* finished packet. decode it. */
-              goto decode_packet;
-           }
-           /* did not finish packet yet. try again ? */
-           if (sb->sb_read_ahead) {
-              /* we were trying to read the max anyway. forget it */
-              goto do_return;
-           }
-        }
-decode_packet:
-        /* we read enough for at least 1 packet */
-        ret = sockbuf_sec_release( sb, buf, len );
-        if (ret<=0) {
-           /* something went wrong... */
-           goto do_return;
-        }
-        buf+=ret;
-        len-=ret;
-        /* we are finished !!! */
-        if ((len==0) || (ret!=max))
-          goto do_return;
-      }
-   } else {
-#endif
-      if (sb->sb_read_ahead) {
-        ber_slen_t max;
-        max = sb->sb_buf.buf_size - sb->sb_buf.buf_end;
-        if (max> (ber_slen_t) len) {
-           for(;;) {
-              ret = sockbuf_io_read( sb, 
-                                    sb->sb_buf.buf_base +
-                                    sb->sb_buf.buf_end,
-                                    max );
-#ifdef EINTR          
-              if ((ret<0) && (errno==EINTR))
-                continue;
-#endif
-              break;
-           }
-           if (ret<=0) {
-              /* some error occured */
-              goto do_return;
-           }
-           sb->sb_buf.buf_end += ret;
-           /* move out the data... */
-           len = sockbuf_copy_out( sb, &buf, len );
-           goto do_return;
-        }
-      }
-      /* no read_ahead, just try to put the data in the buf. */
-      for(;;) {
-        ret = sockbuf_io_read( sb, buf, len );
-#ifdef EINTR    
-        if ((ret<0) && (errno==EINTR))
-          continue;
-#endif
-        break;
-      }
-      if (ret>0) {
-        buf+=ret;
-        len-=ret;
-      }
-      /* we might as well return, since there is nothing to do... */
-#ifdef USE_SASL            
-   }
-#endif
-do_return:
-   assert( status_is_ok(sb) );
-   if ((ret<=0) && (buf==buf_arg)) {
-      /* there was an error. */
-      return ret;
-   }
-   return (buf - ((char *) buf_arg));
+       return 0;
 }
 
-#ifdef USE_SASL
-long sockbuf_do_write( Sockbuf *sb )
+ber_len_t
+ber_pvt_sb_copy_out( Sockbuf_Buf *sbb, char *buf, ber_len_t len )
 {
-   long to_go;
-   ber_slen_t   ret;
+       ber_len_t               max;
 
-   assert( sb != NULL );
-       assert( SOCKBUF_VALID( sb ) );
-
-   to_go = sb->sb_sec_out.buf_end - sb->sb_sec_out.buf_ptr;
-   assert( to_go > 0 );
-   /* there is something left of the last time... */
-   for(;;) {
-      ret = sockbuf_io_write( sb, sb->sb_sec_out.buf_base+
-                            sb->sb_sec_out.buf_ptr, to_go );
-#ifdef EINTR
-      if ((ret<0) && (errno==EINTR))
-       continue;
-#endif
-      break;
+       assert( buf != NULL );
+       assert( sbb != NULL );
+       assert( sbb->buf_size > 0 );
+
+       max = sbb->buf_end - sbb->buf_ptr;
+       max = ( max < len) ? max : len;
+       if ( max ) {
+               memcpy( buf, sbb->buf_base + sbb->buf_ptr, max );
+               sbb->buf_ptr += max;
+               if ( sbb->buf_ptr >= sbb->buf_end )
+                       sbb->buf_ptr = sbb->buf_end = 0;
    }
-   if (ret<=0) /* error */
-     return ret;
-   sb->sb_sec_out.buf_ptr += ret;
-   if (ret<to_go) /* not enough data, so pretend no data was sent. */
-     return -1;
-   return ret;
+       return max;
 }
-#endif
 
-ber_slen_t ber_pvt_sb_write( Sockbuf *sb, void *buf, ber_len_t len_arg )
+ber_slen_t
+ber_pvt_sb_do_write( Sockbuf_IO_Desc *sbiod, Sockbuf_Buf *buf_out )
 {
+       ber_len_t               to_go;
    ber_slen_t ret;
-   ber_len_t len = len_arg;
-
-       assert( buf != NULL );
-       assert( sb != NULL );
-       assert( SOCKBUF_VALID( sb ) );
-   assert( status_is_ok(sb) );
-
-   /* slapd might have problems with this */
-   assert( ber_pvt_sb_in_use( sb ) );
 
-#ifdef TEST_PARTIAL_WRITE
-   if ((rand() & 3)==1) { /* 1 out of 4 */
-      errno = EWOULDBLOCK;
-      return -1;
-   }
+       assert( sbiod != NULL );
+       assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
 
-   len_arg = (rand() % len_arg)+1;
-   len = len_arg;
-#endif   
+       to_go = buf_out->buf_end - buf_out->buf_ptr;
+       assert( to_go > 0 );
    
-#ifdef USE_SASL
-   if (sb->sb_sec) {
-      assert( sb->sb_sec_prev_len <= len );
-      if (sb->sb_sec_prev_len) {
-        ret = sockbuf_do_write( sb );
-        if (ret<=0)
-          return ret;
-        /* finished. */
-        len -= sb->sb_sec_prev_len;
-        sb->sb_sec_prev_len = 0;
-        sb->sb_sec_out.buf_end = sb->sb_sec_out.buf_ptr = 0;
-      }
-      /* now protect the next packet. */
-      ret = sockbuf_sec_protect( sb, buf, len );
-      if (ret<=0)
-       return ret;
-      ret = sockbuf_do_write( sb );
-      if (ret<=0) {
-        sb->sb_sec_prev_len = len;
-        return ret;
-      }
-      return len_arg;
-   } else {
-#endif
       for(;;) {
-        ret = sockbuf_io_write( sb, buf, len );
+               ret = LBER_SBIOD_WRITE_NEXT( sbiod, buf_out->buf_base +
+                       buf_out->buf_ptr, to_go );
 #ifdef EINTR
         if ((ret<0) && (errno==EINTR))
           continue;
 #endif
         break;
       }
-#ifdef USE_SASL      
-   }
-#endif
 
+       if ( ret <= 0 )
    return ret;
-}
-     
-int ber_pvt_sb_close( Sockbuf *sb )
-{
-   int ret;
-
-   assert( sb != NULL );
-   assert( SOCKBUF_VALID( sb ) );
-   assert( sb->sb_io );
-   assert( sb->sb_io->sbi_close );
-   assert( status_is_ok(sb) );
-   assert( ber_pvt_sb_in_use( sb ) );
    
-   ret = sb->sb_io->sbi_close( sb );
-   ber_pvt_sb_set_desc( sb, -1 );
-
+       buf_out->buf_ptr += ret;
+       if (buf_out->buf_ptr == buf_out->buf_end)
+               buf_out->buf_end = buf_out->buf_ptr = 0;
+       if ( (ber_len_t)ret < to_go )
+               /* not enough data, so pretend no data was sent. */
+               return -1;
    return ret;
 }
 
-int ber_pvt_sb_set_readahead( Sockbuf *sb, int rh )
-{
-   assert( sb != NULL );
-   assert( SOCKBUF_VALID( sb ) );
-   assert( status_is_ok(sb) );
-   sb->sb_read_ahead = (rh!=0);
-   return 0;
-}
-
-int ber_pvt_socket_set_nonblock( ber_socket_t sd, int nb )
+int
+ber_pvt_socket_set_nonblock( ber_socket_t sd, int nb )
 {
 #if HAVE_FCNTL
-       int flags = fcntl(ber_pvt_sb_get_desc(sb), F_GETFL);
-       if( nb ) {
+       int flags = fcntl( sd, F_GETFL);
+       if( nb )
                flags |= O_NONBLOCK;
-       } else {
+       else
                flags &= ~O_NONBLOCK;
-       }
-       return fcntl( ber_pvt_sb_get_desc(sb), F_SETFL, flags );
+       return fcntl( sd, F_SETFL, flags );
                
 #elif defined( FIONBIO )
        ioctl_t status = nb ? 1 : 0;
@@ -663,201 +296,100 @@ int ber_pvt_socket_set_nonblock( ber_socket_t sd, int nb )
 #endif
 }
 
-#define USE_NONBLOCK
-#ifdef USE_NONBLOCK
-int ber_pvt_sb_set_nonblock( Sockbuf *sb, int nb )
-{
-   assert( sb != NULL );
-   assert( SOCKBUF_VALID( sb ) );
-   assert( status_is_ok(sb) );
-   if (nb) {
-      sb->sb_non_block = 1;
-#if 0      
-      sb->sb_read_ahead = 1;
-#endif
-   } else {
-      sb->sb_non_block = 0;
-#if 0
-      sb->sb_read_ahead = 0;
-#endif
-   }
-       if (ber_pvt_sb_in_use(sb)) {
-               return ber_pvt_socket_set_nonblock(
-                       ber_pvt_sb_get_desc(sb), nb );
-       }
-       return 0;
-}
-#endif
-        
-#define sockbuf_buf_init( bb ) do { \
-               Sockbuf_Buf *sbb = (bb); \
-               sbb->buf_base = NULL; \
-               sbb->buf_ptr = 0; \
-               sbb->buf_end = 0; \
-               sbb->buf_size = 0; \
-       } while(0)
-
-static int 
-sockbuf_buf_destroy( Sockbuf_Buf *buf )
-{
-       assert( buf != NULL);
-
-   if (buf->buf_base)
-     LBER_FREE( buf->buf_base );
-   sockbuf_buf_init( buf );
-   return 0;
-}
-
-int ber_pvt_sb_init( Sockbuf *sb )
+int
+ber_int_sb_init( Sockbuf *sb )
 {
        assert( sb != NULL);
 
-       ber_int_options.lbo_valid = LBER_INITIALIZED;
-
    sb->sb_valid=LBER_VALID_SOCKBUF;
    sb->sb_options = 0;
-   sb->sb_debug = 0;
-   sb->sb_trans_ready = 0;
-   sb->sb_buf_ready = 0;
-#ifdef USE_SASL   
-   sb->sb_sec_ready = 0;
-#endif   
-   sb->sb_read_ahead = 1; /* test */
-   sb->sb_non_block = 0;
+       sb->sb_debug = ber_int_debug;
+       sb->sb_fd = AC_SOCKET_INVALID;
+       sb->sb_iod = NULL;
    sb->sb_trans_needs_read = 0;
    sb->sb_trans_needs_write = 0;
-   sb->sb_fd = -1;
-   sb->sb_iodata = NULL;
-   sb->sb_io = &sb_IO_None;
-   sb->sb_sd = -1;
-#ifdef DEADWOOD   
-   sb->sb_max_incoming = 0;
-#endif   
-   sockbuf_buf_init( &(sb->sb_buf) );
-#ifdef USE_SASL
-   sockbuf_buf_init( &(sb->sb_sec_buf_in) );
-   sockbuf_buf_init( &(sb->sb_sec_buf_out) );
-   sb->sb_sdata = NULL;
-   sb->sb_sec = NULL;
-   sb->sb_sec_prev_len = 0;
-#endif 
    
    assert( SOCKBUF_VALID( sb ) );
    return 0;
 }
    
-int ber_pvt_sb_destroy( Sockbuf *sb )
+int
+ber_int_sb_close( Sockbuf *sb )
 {
-       assert( sb != NULL);
-       assert( SOCKBUF_VALID(sb) );
-#ifdef USE_SASL
-   ber_pvt_sb_clear_sec(sb);
-   sockbuf_buf_destroy( &(sb->sb_sec_buf_in) );
-   sockbuf_buf_destroy( &(sb->sb_sec_buf_out) );
-#endif
-   ber_pvt_sb_clear_io(sb);
-   sockbuf_buf_destroy( &(sb->sb_buf) );
-   return ber_pvt_sb_init( sb );
-}
+       Sockbuf_IO_Desc         *p;
 
-#ifdef USE_SASL
-int ber_pvt_sb_set_sec( Sockbuf *sb, Sockbuf_Sec * sec, void *arg )
-{
-   int len;
        assert( sb != NULL);
-       assert( SOCKBUF_VALID( *sb ) );
-   if ((sb->sb_sec) || (sec==NULL))
-     return -1;
-   
-   sb->sb_sec = sec;
    
-   if ((sec->sbs_setup) && (sec->sbs_setup( sb, arg)<0)) {
+       p = sb->sb_iod;
+       while ( p ) {
+               if ( p->sbiod_io->sbi_close &&
+                               p->sbiod_io->sbi_close( p ) < 0 )
       return -1;
+               p = p->sbiod_next;
    }
    
-   len = sb->sb_buf.buf_end - sb->sb_buf.buf_ptr;
+       sb->sb_fd = AC_SOCKET_INVALID;
    
-   if (len>0) {
-      /* move this to the security layer. */
-      if (grow_buffer( &(sb->sb_sec_buf_in), len )<0)
-       return -1;
-      memcpy( sb->sb_sec_buf_in.buf_base, 
-            sb->sb_buf.buf_base + sb->sb_buf.buf_ptr, len );
-      sb->sb_sec_buf_in.buf_ptr = len;
-      sb->sb_sec_buf_in.buf_end = (len>4) ? packet_length( sb, sb->sb_sec_buf_in ) : 0;
-      sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0;
-   }
-   update_status( sb );
    return 0;
 }
 
-int ber_pvt_sb_clear_sec( Sockbuf *sb )
+int
+ber_int_sb_destroy( Sockbuf *sb )
 {
+       Sockbuf_IO_Desc         *p;
+
        assert( sb != NULL);
        assert( SOCKBUF_VALID( sb ) );
-
-   if (sb->sb_buf.buf_ptr!=0)
-     return -1;
-   if (sb->sb_sec==NULL)
-     return -1;
-   if ((sb->sb_sec->sbs_remove) && (sb->sb_sec->sbs_remove(sb)<0)) 
-     return -1;
    
-   sb->sb_sec = NULL;
-   if (sb->sb_sec_buf_in.buf_ptr!=0) {
-      if (grow_buffer( &(sb->sb_buf), 
-                     sb->sb_buf.buf_end + sb->sb_sec_buf_in.buf_ptr)<0)
-       return -1;
-      memcpy( sb->sb_buf.buf_base + sb->sb_buf.buf_end,
-             sb->sb_sec_buf_in.buf_base, sb->sb_sec_buf_in.buf_ptr );
-      sb->sb_buf.buf_end += sb->sb_sec_buf_in.buf_ptr;
-      sb->sb_buf_ready = 1;
-   }
-   sockbuf_buf_destroy( &(sb->sb_sec_buf_in) );
-   assert( sb->sb_sec_buf.buf_end==0 );
-   sockbuf_buf_destroy( &(sb->sb_sec_buf_out) );
-   
-   sb->sb_sec_ready = 0;
-   
-   return 0;
+       while ( sb->sb_iod ) {
+               p = sb->sb_iod->sbiod_next;
+               ber_sockbuf_remove_io( sb, sb->sb_iod->sbiod_io,
+                       sb->sb_iod->sbiod_level );
+               sb->sb_iod = p;
+}
+       return ber_int_sb_init( sb );
 }
-#endif
 
-int ber_pvt_sb_set_io( Sockbuf *sb, Sockbuf_IO *trans, void *arg )
+ber_slen_t
+ber_int_sb_read( Sockbuf *sb, void *buf, ber_len_t len )
 {
+       ber_slen_t              ret;
+
+       assert( buf != NULL );
        assert( sb != NULL);
+       assert( sb->sb_iod != NULL );
        assert( SOCKBUF_VALID( sb ) );
-   assert( sb->sb_io == &sb_IO_None );
 
-   if (trans==NULL)
-     return -1;
-   
-   sb->sb_io = trans;
-   
-   if ((trans->sbi_setup) && (trans->sbi_setup( sb, arg)<0))
-     return -1;
-   
-   return 0;
+       for (;;) {
+               ret = sb->sb_iod->sbiod_io->sbi_read( sb->sb_iod, buf, len );
+#ifdef EINTR   
+               if ( ( ret < 0 ) && ( errno == EINTR ) )
+                       continue;
+#endif
+               break;
+}
+       return ret;
 }
 
-int ber_pvt_sb_clear_io( Sockbuf *sb )
+ber_slen_t
+ber_int_sb_write( Sockbuf *sb, void *buf, ber_len_t len )
 {
+       ber_slen_t              ret;
+
+       assert( buf != NULL );
        assert( sb != NULL);
+       assert( sb->sb_iod != NULL );
        assert( SOCKBUF_VALID( sb ) );
 
-   if (sb->sb_io==&sb_IO_None)
-     return -1;
-   
-   if ((sb->sb_io->sbi_remove) && (sb->sb_io->sbi_remove( sb )<0))
-     return -1;
-
-   sb->sb_io = &sb_IO_None;
-   
-   sb->sb_trans_ready = 0;
-   sb->sb_trans_needs_read = 0;
-   sb->sb_trans_needs_write = 0;
-
-   return 0;
+       for (;;) {
+               ret = sb->sb_iod->sbiod_io->sbi_write( sb->sb_iod, buf, len );
+#ifdef EINTR   
+               if ( ( ret < 0 ) && ( errno == EINTR ) )
+                       continue;
+#endif
+               break;
+}
+       return ret;
 }
 
 /*
@@ -865,16 +397,16 @@ int ber_pvt_sb_clear_io( Sockbuf *sb )
  */
 
 static ber_slen_t
-stream_read( Sockbuf *sb, void *buf, ber_len_t len )
+sb_stream_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
 {
-       assert( sb != NULL);
-       assert( SOCKBUF_VALID( sb ) );
+       assert( sbiod != NULL);
+       assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
 
 #if defined(MACOS)
 /*
  * MacTCP/OpenTransport
  */
-   return tcpread( ber_pvt_sb_get_desc(sb), 0, (unsigned char *)buf, 
+       return tcpread( sbiod->sbiod_sb->sb_fd, 0, (unsigned char *)buf,
                   len, NULL );
 
 #elif defined( HAVE_PCNFS ) || \
@@ -890,36 +422,44 @@ stream_read( Sockbuf *sb, void *buf, ber_len_t len )
  */
    {
    int rc;
-   rc = recv( ber_pvt_sb_get_desc(sb), buf, len, 0 );
+
+               rc = recv( sbiod->sbiod_sb->sb_fd, buf, len, 0 );
+
 #ifdef HAVE_WINSOCK
-   if ( rc < 0 ) errno = WSAGetLastError();
+   if ( rc < 0 )
+   {
+     int err;
+
+     err = WSAGetLastError();
+     errno = err;
+   }
 #endif
+
    return rc;
    }
 #elif defined( HAVE_NCSA )
 /*
  * NCSA Telnet TCP/IP stack (under DOS)
  */
-   return nread( ber_pvt_sb_get_desc(sb), buf, len );
+       return nread( sbiod->sbiod_sb->sb_fd, buf, len );
 
 #else
-   return read( ber_pvt_sb_get_desc(sb), buf, len );
+       return read( sbiod->sbiod_sb->sb_fd, buf, len );
 #endif
 }
 
 static ber_slen_t
-stream_write( Sockbuf *sb, void *buf, ber_len_t len )
+sb_stream_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
 {
-       assert( sb != NULL);
-       assert( SOCKBUF_VALID( sb ) );
+       assert( sbiod != NULL);
+       assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
 
 #if defined(MACOS) 
 /*
  * MacTCP/OpenTransport
  */
 #define MAX_WRITE      65535
-   return tcpwrite( ber_pvt_sb_get_desc(sb),
-                   (unsigned char *)(buf), 
+       return tcpwrite( sbiod->sbiod_sb->sb_fd, (unsigned char *)buf,
                    (len<MAX_WRITE)? len : MAX_WRITE );
 
 #elif defined( HAVE_PCNFS) \
@@ -936,44 +476,68 @@ stream_write( Sockbuf *sb, void *buf, ber_len_t len )
 
    {
    int rc;
-   rc = send( ber_pvt_sb_get_desc(sb), buf, len, 0 );
+       
+               rc = send( sbiod->sbiod_sb->sb_fd, buf, len, 0 );
 #ifdef HAVE_WINSOCK
-   if ( rc < 0 ) errno = WSAGetLastError();
+   if ( rc < 0 )
+   {
+     int err;
+               
+     err = WSAGetLastError();
+     errno = err;
+   }
 #endif
    return rc;
    }
 
 #elif defined(HAVE_NCSA)
-   return netwrite( ber_pvt_sb_get_desc(sb), buf, len );
+       return netwrite( sbiod->sbiod_sb->sb_fd, buf, len );
 
 #elif defined(VMS)
 /*
  * VMS -- each write must be 64K or smaller
  */
 #define MAX_WRITE 65535
-   return write( ber_pvt_sb_get_desc(sb), buf, 
+       return write( sbiod->sbiod_sb->sb_fd, buf,
                 (len<MAX_WRITE)? len : MAX_WRITE);
 #else
-   return write( ber_pvt_sb_get_desc(sb), buf, len );
+       return write( sbiod->sbiod_sb->sb_fd, buf, len );
 #endif   
 }   
    
 static int 
-stream_close( Sockbuf *sb )
+sb_stream_close( Sockbuf_IO_Desc *sbiod )
 {
-       assert( sb != NULL);
-       assert( SOCKBUF_VALID( sb ) );
-   tcp_close( ber_pvt_sb_get_desc( sb ) );
+       assert( sbiod != NULL );
+       assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
+       tcp_close( sbiod->sbiod_sb->sb_fd );
    return 0;
 }
 
-Sockbuf_IO ber_pvt_sb_io_tcp=
+/* The argument is a pointer to the socket descriptor */
+static int
+sb_stream_setup( Sockbuf_IO_Desc *sbiod, void *arg ) {
+       assert( sbiod != NULL );
+
+       if ( arg != NULL )
+               sbiod->sbiod_sb->sb_fd = *((int *)arg);
+       return 0;
+}
+
+static int
+sb_stream_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg ) {
+       /* This is an end IO descriptor */
+       return 0;
+}
+
+Sockbuf_IO ber_sockbuf_io_tcp =
 {
-       NULL,   /* sbi_setup */
-       NULL,   /* sbi_release */
-       stream_read,    /* sbi_read */
-       stream_write,   /* sbi_write */
-       stream_close,   /* sbi_close */
+       sb_stream_setup,        /* sbi_setup */
+       NULL,                   /* sbi_remove */
+       sb_stream_ctrl,         /* sbi_ctrl */
+       sb_stream_read,         /* sbi_read */
+       sb_stream_write,        /* sbi_write */
+       sb_stream_close         /* sbi_close */
 };
 
 /*
@@ -987,53 +551,52 @@ struct dgram_data
 };
 
 static int 
-dgram_setup( Sockbuf *sb, void *arg )
+sb_dgram_setup( Sockbuf_IO_Desc *sbiod, void *arg )
 {
-       assert( sb != NULL);
-       assert( SOCKBUF_VALID( sb ) );
+       struct dgram_data       *p;
+
+       assert( sbiod != NULL);
+       assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
 
-   sb->sb_iodata = LBER_MALLOC( sizeof( struct dgram_data ) );
-   if (sb->sb_iodata==NULL)
+       p = LBER_MALLOC( sizeof( *p ) );
+       if ( p == NULL )
      return -1;
-   sb->sb_read_ahead = 1; /* important since udp is packet based. */
+       memset( p, '\0', sizeof( *p ) );
+       sbiod->sbiod_pvt = (void *)p;
+       if ( arg != NULL )
+               sbiod->sbiod_sb->sb_fd = *((int *)arg);
    return 0;
 }
 
 static int 
-dgram_release( Sockbuf *sb )
+sb_dgram_release( Sockbuf_IO_Desc *sbiod )
 {
-       assert( sb != NULL);
-       assert( SOCKBUF_VALID( sb ) );
+       assert( sbiod != NULL);
+       assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
 
-   LBER_FREE( sb->sb_iodata );
+       LBER_FREE( sbiod->sbiod_pvt );
+       sbiod->sbiod_pvt = NULL;
    return 0;
 }
 
 static ber_slen_t
-dgram_read( Sockbuf *sb, void *buf, ber_len_t len )
+sb_dgram_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
 {
 #ifdef LDAP_CONNECTIONLESS
    ber_slen_t rc;
    socklen_t  addrlen;
-   struct dgram_data *dd;
+       struct dgram_data       *p;
    
-       assert( sb != NULL );
-       assert( SOCKBUF_VALID( sb ) );
+       assert( sbiod != NULL );
+       assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
        assert( buf != NULL );
 
-   dd = (struct dgram_data *)(sb->sb_iodata);
+       p = (struct dgram_data *)sbiod->sbiod_pvt;
    
    addrlen = sizeof( struct sockaddr );
-   rc=recvfrom( ber_pvt_sb_get_desc(sb), buf, len, 0, &(dd->src), &addrlen );
+       rc = recvfrom( sbiod->sbiod_sb->sb_fd, buf, len, 0, &p->src,
+               &addrlen );
    
-   if ( sb->sb_debug ) {
-      ber_log_printf( LDAP_DEBUG_ANY, sb->sb_debug,
-                     "dgram_read udp_read %ld bytes\n",
-                     (long) rc );
-      if ( rc > 0 )
-       ber_log_bprint( LDAP_DEBUG_PACKETS, sb->sb_debug,
-                       buf, rc );
-   }
    return rc;
 # else /* LDAP_CONNECTIONLESS */
    return -1;
@@ -1041,30 +604,30 @@ dgram_read( Sockbuf *sb, void *buf, ber_len_t len )
 }
 
 static ber_slen_t 
-dgram_write( Sockbuf *sb, void *buf, ber_len_t len )
+sb_dgram_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
 {
 #ifdef LDAP_CONNECTIONLESS
    ber_slen_t rc;
-   struct dgram_data *dd;
+       struct dgram_data       *p;
    
-       assert( sb != NULL );
-       assert( SOCKBUF_VALID( sb ) );
+       assert( sbiod != NULL );
+       assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
        assert( buf != NULL );
 
-   dd = (struct dgram_data *)(sb->sb_iodata);
+       p = (struct dgram_data *)sbiod->sbiod_pvt;
    
-   rc=sendto( ber_pvt_sb_get_desc(sb), buf, len, 0, &(dd->dst),
+       rc = sendto( sbiod->sbiod_sb->sb_fd, buf, len, 0, &p->dst,
             sizeof( struct sockaddr ) );
 
    if ( rc <= 0 )
-       return( -1 );
+               return -1;
    
    /* fake error if write was not atomic */
    if (rc < len) {
 # ifdef EMSGSIZE
       errno = EMSGSIZE;
 # endif
-      return( -1 );
+               return -1;
    }
    return rc;
 #else
@@ -1073,84 +636,325 @@ dgram_write( Sockbuf *sb, void *buf, ber_len_t len )
 }
 
 static int 
-dgram_close( Sockbuf *sb )
+sb_dgram_close( Sockbuf_IO_Desc *sbiod )
 {
-       assert( sb != NULL );
-       assert( SOCKBUF_VALID( sb ) );
+       assert( sbiod != NULL );
+       assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
+
+       tcp_close( sbiod->sbiod_sb->sb_fd );
+       return 0;
+}
+
+static int
+sb_dgram_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
+{
+       struct dgram_data       *p;
+
+       assert( sbiod != NULL );
+       assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
+
+       p = (struct dgram_data *)sbiod->sbiod_pvt;
 
-       tcp_close( ber_pvt_sb_get_desc(sb) );
+       if ( opt == LBER_SB_OPT_UDP_SET_DST ) {
+               memcpy( &p->dst, arg, sizeof( struct sockaddr ) );
+               return 1;
+       }
+       else if ( opt == LBER_SB_OPT_UDP_GET_SRC ) {
+               *(( struct sockaddr **)arg) = &p->src;
+               return 1;
+       }
+       /* This is an end IO descriptor */
        return 0;
 }
 
-Sockbuf_IO ber_pvt_sb_io_udp=
+Sockbuf_IO ber_sockbuf_io_udp =
 {
-       dgram_setup,    /* sbi_setup */
-       dgram_release,  /* sbi_release */
-       dgram_read,     /* sbi_read */
-       dgram_write,    /* sbi_write */
-       dgram_close,    /* sbi_close */
+       sb_dgram_setup,         /* sbi_setup */
+       sb_dgram_release,       /* sbi_release */
+       sb_dgram_ctrl,          /* sbi_ctrl */
+       sb_dgram_read,          /* sbi_read */
+       sb_dgram_write,         /* sbi_write */
+       sb_dgram_close          /* sbi_close */
 };
 
-int ber_pvt_sb_udp_set_dst(Sockbuf *sb, void *addr )
+/*
+ * Support for readahead (UDP needs it)
+ */
+
+static int
+sb_rdahead_setup( Sockbuf_IO_Desc *sbiod, void *arg )
 {
-   struct dgram_data *dd;
-       assert( sb != NULL );
-       assert( SOCKBUF_VALID( sb ) );
-   assert( sb->sb_io == &ber_pvt_sb_io_udp );
-   dd = (struct dgram_data *) (sb->sb_iodata);
-   memcpy( &(dd->dst), addr, sizeof( struct sockaddr ) );
+       Sockbuf_Buf             *p;
+
+       assert( sbiod != NULL );
+
+       p = LBER_MALLOC( sizeof( *p ) );
+       if ( p == NULL )
+               return -1;
+       ber_pvt_sb_buf_init( p );
+       if ( arg == NULL )
+               ber_pvt_sb_grow_buffer( p, DEFAULT_READAHEAD );
+       else
+               ber_pvt_sb_grow_buffer( p, *((int *)arg) );
+       sbiod->sbiod_pvt = p;
    return 0;
 }
 
-void *ber_pvt_sb_udp_get_src( Sockbuf *sb )
+static int
+sb_rdahead_remove( Sockbuf_IO_Desc *sbiod )
 {
-   struct dgram_data *dd;
+       Sockbuf_Buf             *p;
 
-       assert( sb != NULL );
-       assert( SOCKBUF_VALID( sb ) );
-   assert( sb->sb_io == &ber_pvt_sb_io_udp );
-   dd = (struct dgram_data *) (sb->sb_iodata);
-   return &(dd->src);
+       assert( sbiod != NULL );
+
+       p = (Sockbuf_Buf *)sbiod->sbiod_pvt;
+
+       if ( p->buf_ptr != p->buf_end )
+               return -1;
+
+       ber_pvt_sb_buf_destroy( (Sockbuf_Buf *)(sbiod->sbiod_pvt) );
+       LBER_FREE( sbiod->sbiod_pvt );
+       sbiod->sbiod_pvt = NULL;
+
+       return 0;
 }
 
+static ber_slen_t
+sb_rdahead_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
+{
+       Sockbuf_Buf             *p;
+       ber_slen_t              bufptr = 0, ret, max;
+
+       assert( sbiod != NULL );
+       assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
+       assert( sbiod->sbiod_next != NULL );
+
+       p = (Sockbuf_Buf *)sbiod->sbiod_pvt;
+
+       assert( p->buf_size > 0 );
+
+       /* Are there anything left in the buffer? */
+       ret = ber_pvt_sb_copy_out( p, buf, len );
+       bufptr += ret;
+       len -= ret;
+
+       if ( len == 0 )
+               return bufptr;
+
+       max = p->buf_size - p->buf_end;
+       ret = 0;
+       while ( max > 0 ) {
+               ret = LBER_SBIOD_READ_NEXT( sbiod, p->buf_base + p->buf_end,
+                       max );
+#ifdef EINTR   
+               if ( ( ret < 0 ) && ( errno == EINTR ) )
+                       continue;
+#endif
+               break;
+}
+
+       if ( ret < 0 )
+               return ( bufptr ? bufptr : ret );
+
+       p->buf_end += ret;
+       bufptr += ber_pvt_sb_copy_out( p, (char *) buf + bufptr, len );
+       return bufptr;
+}
+
+static ber_slen_t
+sb_rdahead_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
+{
+       assert( sbiod != NULL );
+       assert( sbiod->sbiod_next != NULL );
+
+       return LBER_SBIOD_WRITE_NEXT( sbiod, buf, len );
+}
+
+static int
+sb_rdahead_close( Sockbuf_IO_Desc *sbiod )
+{
+       assert( sbiod != NULL );
+
+       /* Just erase the buffer */
+       ber_pvt_sb_buf_destroy((Sockbuf_Buf *)sbiod->sbiod_pvt);
+       return 0;
+}
+
+static int
+sb_rdahead_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
+{
+       Sockbuf_Buf             *p;
+
+       p = (Sockbuf_Buf *)sbiod->sbiod_pvt;
+
+       if ( opt == LBER_SB_OPT_DATA_READY ) {
+               if ( p->buf_ptr != p->buf_end )
+                       return 1;
+       }
+       else if ( opt == LBER_SB_OPT_SET_READAHEAD ) {
+               if ( p->buf_size >= *((ber_len_t *)arg) )
+                       return 0;
+               return ( ber_pvt_sb_grow_buffer( p, *((int *)arg) ) ?
+                       -1 : 1 );
+       }
+
+       return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
+}
+
+Sockbuf_IO ber_sockbuf_io_readahead =
+{
+       sb_rdahead_setup,       /* sbi_setup */
+       sb_rdahead_remove,      /* sbi_remove */
+       sb_rdahead_ctrl,        /* sbi_ctrl */
+       sb_rdahead_read,        /* sbi_read */
+       sb_rdahead_write,       /* sbi_write */
+       sb_rdahead_close        /* sbi_close */
+};
+
 /*
- * debug routines.
- * 
- * BUGS:
- * These routines should really call abort, but at the moment that would
- * break the servers.
+ * Support for simple file IO
  */
 
 static ber_slen_t
-have_no_read( Sockbuf *sb, void *buf, ber_len_t len )
+sb_fd_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
 {
-       assert( sb != NULL );
-       assert( SOCKBUF_VALID( sb ) );
+       assert( sbiod != NULL);
+       assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
 
-   ber_log_printf( LDAP_DEBUG_ANY, ber_int_debug,
-                  "warning: reading from uninitialized sockbuf\n");
-   errno =  EBADF;
-   return -1;
+       return read( sbiod->sbiod_sb->sb_fd, buf, len );
 }
 
 static ber_slen_t
-have_no_write( Sockbuf *sb, void *buf, ber_len_t len )
+sb_fd_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
 {
-       assert( sb != NULL );
-       assert( SOCKBUF_VALID( sb ) );
+       assert( sbiod != NULL);
+       assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
 
-   ber_log_printf( LDAP_DEBUG_ANY, ber_int_debug,
-                  "warning: writing to uninitialized sockbuf\n");
-   errno =  EBADF;
-   return -1;
+       return write( sbiod->sbiod_sb->sb_fd, buf, len );
 }
 
 static int 
-have_no_close( Sockbuf *sb )
+sb_fd_close( Sockbuf_IO_Desc *sbiod )
 {   
-       assert( sb != NULL );
-       assert( SOCKBUF_VALID( sb ) );
+       assert( sbiod != NULL );
+       assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
+
+       close( sbiod->sbiod_sb->sb_fd );
+       return 0;
+}
+
+/* The argument is a pointer to the file descriptor */
+static int
+sb_fd_setup( Sockbuf_IO_Desc *sbiod, void *arg ) {
+       assert( sbiod != NULL );
+
+       if ( arg != NULL )
+               sbiod->sbiod_sb->sb_fd = *((int *)arg);
+       return 0;
+}
+
+static int
+sb_fd_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg ) {
+       /* This is an end IO descriptor */
+       return 0;
+}
+
+Sockbuf_IO ber_sockbuf_io_fd =
+{
+       sb_fd_setup,            /* sbi_setup */
+       NULL,                   /* sbi_remove */
+       sb_fd_ctrl,             /* sbi_ctrl */
+       sb_fd_read,             /* sbi_read */
+       sb_fd_write,            /* sbi_write */
+       sb_fd_close             /* sbi_close */
+};
+
+/*
+ * Debugging layer
+ */
 
-   assert( 0 );
+static int
+sb_debug_setup( Sockbuf_IO_Desc *sbiod, void *arg )
+{
+       assert( sbiod != NULL );
+       
+       if ( arg == NULL )
+               arg = "sockbuf_";
+
+       sbiod->sbiod_pvt = LBER_MALLOC( strlen( arg ) + 1 );
+       if ( sbiod->sbiod_pvt == NULL )
    return -1;
+       strcpy( (char *)sbiod->sbiod_pvt, (char *)arg );
+       return 0;
+}
+
+static int
+sb_debug_remove( Sockbuf_IO_Desc *sbiod )
+{
+       assert( sbiod != NULL );
+       assert( sbiod->sbiod_pvt != NULL );
+
+       LBER_FREE( sbiod->sbiod_pvt );
+       sbiod->sbiod_pvt = NULL;
+       return 0;
+}
+
+static int
+sb_debug_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
+{
+       return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
+}
+
+static ber_slen_t
+sb_debug_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
+{
+       ber_slen_t              ret;
+
+       ret = LBER_SBIOD_READ_NEXT( sbiod, buf, len );
+       if ( ret < 0 ) {
+               ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
+                       "%sread: want=%ld error=%s\n", (char *)sbiod->sbiod_pvt,
+                       (long)len, strerror( errno ) );
+       }
+       else {
+               ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
+                       "%sread: want=%ld, got=%ld\n", (char *)sbiod->sbiod_pvt,
+                       (long)len, (long)ret );
+               ber_log_bprint( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
+                       (const char *)buf, ret );
+       }
+       return ret;
 }
+
+static ber_slen_t
+sb_debug_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
+{
+       ber_slen_t              ret;
+
+       ret = LBER_SBIOD_WRITE_NEXT( sbiod, buf, len );
+       if ( ret < 0 ) {
+               ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
+                       "%swrite: want=%ld error=%s\n",
+                       (char *)sbiod->sbiod_pvt, (long)len,
+                       strerror( errno ) );
+       }
+       else {
+               ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
+                       "%swrite: want=%ld, written=%ld\n",
+                       (char *)sbiod->sbiod_pvt, (long)len, (long)ret );
+               ber_log_bprint( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
+                       (const char *)buf, ret );
+       }
+       return ret;
+}
+
+Sockbuf_IO ber_sockbuf_io_debug =
+{
+       sb_debug_setup,         /* sbi_setup */
+       sb_debug_remove,        /* sbi_remove */
+       sb_debug_ctrl,          /* sbi_ctrl */
+       sb_debug_read,          /* sbi_read */
+       sb_debug_write,         /* sbi_write */
+       NULL                    /* sbi_close */
+};
+
index 1ee85ec934ca6569c50e67f477bd3faa4b6f97f0..0ae884ddb1da73139533edf2b2a3f6c373f8cf49 100644 (file)
@@ -1,5 +1,5 @@
 # $OpenLDAP$
-## Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
 ## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 ##
 ## Makefile.in for LDAP -lldap
@@ -15,25 +15,45 @@ SRCS        = bind.c open.c result.c error.c compare.c search.c \
        getfilter.c sasl.c sbind.c kbind.c unbind.c friendly.c cldap.c \
        free.c disptmpl.c srchpref.c dsparse.c tmplout.c sort.c \
        getdn.c getentry.c getattr.c getvalues.c addentry.c \
-       request.c getdxbyname.c os-ip.c url.c charset.c \
+       request.c os-ip.c url.c sortctrl.c vlvctrl.c \
        init.c options.c print.c string.c util-int.c schema.c \
-       charray.c digest.c tls.c dn.c
+       charray.c tls.c dn.c os-local.c dnssrv.c \
+       utf-8.c
 OBJS   = bind.lo open.lo result.lo error.lo compare.lo search.lo \
        controls.lo messages.lo references.lo extended.lo \
        modify.lo add.lo modrdn.lo delete.lo abandon.lo ufn.lo cache.lo \
        getfilter.lo sasl.lo sbind.lo kbind.lo unbind.lo friendly.lo cldap.lo \
        free.lo disptmpl.lo srchpref.lo dsparse.lo tmplout.lo sort.lo \
        getdn.lo getentry.lo getattr.lo getvalues.lo addentry.lo \
-       request.lo getdxbyname.lo os-ip.lo url.lo charset.lo \
+       request.lo os-ip.lo url.lo sortctrl.lo vlvctrl.lo \
        init.lo options.lo print.lo string.lo util-int.lo schema.lo \
-       charray.lo digest.lo tls.lo dn.lo
+       charray.lo tls.lo dn.lo os-local.lo dnssrv.lo \
+       utf-8.lo
 
 LDAP_INCDIR= ../../include       
 LDAP_LIBDIR= ../../libraries
 
-XLIBS = -lldap -llber
+XLIBS = -lldap -llber -llutil
 XXLIBS = $(SECURITY_LIBS) $(TLS_LIBS)
 
+LINKAGE = @LT_LIB_LINKAGE@
+
+NT_DYN_LIB_LIBS  = -llber -llutil $(AC_LIBS)
+NT_DYN_LIB_DEFS  = -DLIBLBER_DECL=dllimport
+NT_DYN_TEST_DEFS = -DLIBLBER_DECL=dllimport -DLIBLDAP_DECL=dllimport
+
+NT_XXLIBS = $(SECURITY_LIBS)
+
+UNIX_DYN_LIB_LIBS  = -llber $(AC_LIBS)
+UNIX_XXLIBS = $(SECURITY_LIBS)
+
+# Extras for building the library
+EXTRA_DEFS = $(@PLAT@_@LIB_LINKAGE@_LIB_DEFS)
+EXTRA_LIBS = $(@PLAT@_@LIB_LINKAGE@_LIB_LIBS) $(@PLAT@_XXLIBS)
+
+# Only the test programs will pick up these defs.
+CPPFLAGS = $(@PLAT@_@LIB_LINKAGE@_TEST_DEFS)
+
 apitest:       $(LIBRARY) apitest.o $(LDAP_LIBLBER_DEPEND)
        $(LTLINK) $(LDFLAGS) -o $@ apitest.o $(LIBS)
 ltest: $(LIBRARY) test.o $(LDAP_LIBLBER_DEPEND)
@@ -44,20 +64,20 @@ ttest:      $(LIBRARY) tmpltest.o $(LDAP_LIBLBER_DEPEND)
 CFFILES=ldap.conf ldapfilter.conf ldaptemplates.conf ldapsearchprefs.conf
 
 install-local: $(CFFILES) FORCE
-       -$(MKDIR) $(libdir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 644 $(LIBRARY) $(libdir)
-       -$(MKDIR) $(sysconfdir)
+       -$(MKDIR) $(DESTDIR)$(libdir)
+       $(LTINSTALL) $(INSTALLFLAGS) -m 644 $(LIBRARY) $(DESTDIR)$(libdir)
+       -$(MKDIR) $(DESTDIR)$(sysconfdir)
        @for i in $(CFFILES); do \
-               if test ! -f $(sysconfdir)/$$i; then \
+               if test ! -f $(DESTDIR)$(sysconfdir)/$$i; then \
                        echo "installing $$i in $(sysconfdir)"; \
-                       echo "$(INSTALL) $(INSTALLFLAGS) -m 644 $(srcdir)/$$i $(sysconfdir)/$$i"; \
-                       $(INSTALL) $(INSTALLFLAGS) -m 644 $(srcdir)/$$i $(sysconfdir)/$$i; \
+                       echo "$(INSTALL) $(INSTALLFLAGS) -m 644  $(srcdir)/$$i $(DESTDIR)$(sysconfdir)/$$i"; \
+                       $(INSTALL) $(INSTALLFLAGS) -m 644 $(srcdir)/$$i $(DESTDIR)$(sysconfdir)/$$i; \
                else \
                        echo "PRESERVING EXISTING CONFIGURATION FILE $(sysconfdir)/$$i" ; \
                fi; \
-               $(INSTALL) $(INSTALLFLAGS) -m 644 $(srcdir)/$$i $(sysconfdir)/$$i.default; \
+               $(INSTALL) $(INSTALLFLAGS) -m 644 $(srcdir)/$$i $(DESTDIR)$(sysconfdir)/$$i.default; \
        done
-       -$(MKDIR) $(datadir)
-       -$(MV) $(datadir)/ldapfriendly $(datadir)/ldapfriendly-
-       $(INSTALL) $(INSTALLFLAGS) -m 644 $(srcdir)/ldapfriendly $(datadir)/ldapfriendly
+       -$(MKDIR) $(DESTDIR)$(datadir)
+       -$(MV) $(DESTDIR)$(datadir)/ldapfriendly $(DESTDIR)$(datadir)/ldapfriendly-
+       $(INSTALL) $(INSTALLFLAGS) -m 644 $(srcdir)/ldapfriendly $(DESTDIR)$(datadir)/ldapfriendly
 
index 0541dd93cc6e34934c65d02f0bbd62bf756de469..3ce621f7aa3685d11dc1149512b56d40897cec89 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
@@ -180,7 +180,7 @@ do_abandon(
                                if ( lr != NULL ) {
                                        sb = lr->lr_conn->lconn_sb;
                                } else {
-                                       sb = &ld->ld_sb;
+                                       sb = ld->ld_sb;
                                }
 
                                if ( ber_flush( sb, ber, 1 ) != 0 ) {
index aa69653572ba4ce2a34f4846c182b829bf0eae13..34f61e8c8f25d14680a464b3a093729a862a483e 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
index 1249157f0d3546f8efec0ca55d71c78a91309fdb..4ee6870222cb51e07129fdf0f5f359cda5e47e14 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
index b14f563d4bfdf62671a2efa8d811193ba9a19f60..0fe1de5ee5eb347e5d414a351e2e6bc1d7ae3265 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
diff --git a/libraries/libldap/apitest.dsp b/libraries/libldap/apitest.dsp
new file mode 100644 (file)
index 0000000..b191770
--- /dev/null
@@ -0,0 +1,145 @@
+# Microsoft Developer Studio Project File - Name="apitest" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=apitest - Win32 Single Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "apitest.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "apitest.mak" CFG="apitest - Win32 Single Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "apitest - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "apitest - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "apitest - Win32 Single Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "apitest - Win32 Single Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "apitest - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\apitest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 oldap32.lib olber32.lib sasl.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\Release"
+
+!ELSEIF  "$(CFG)" == "apitest - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "apitest_"
+# PROP BASE Intermediate_Dir "apitest_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\apitest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 oldap32.lib olber32.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Debug"
+
+!ELSEIF  "$(CFG)" == "apitest - Win32 Single Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "apitest_"
+# PROP BASE Intermediate_Dir "apitest_"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\apitest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 oldap32.lib olber32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\Debug"
+# ADD LINK32 oldap32.lib olber32.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\SDebug"
+
+!ELSEIF  "$(CFG)" == "apitest - Win32 Single Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "apitest0"
+# PROP BASE Intermediate_Dir "apitest0"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\apitest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 oldap32.lib olber32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\Release"
+# ADD LINK32 oldap32.lib olber32.lib sasl.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\SRelease"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "apitest - Win32 Release"
+# Name "apitest - Win32 Debug"
+# Name "apitest - Win32 Single Debug"
+# Name "apitest - Win32 Single Release"
+# Begin Source File
+
+SOURCE=.\apitest.c
+# End Source File
+# End Target
+# End Project
index b9579f2b4a9c7b6530c0cbb9e74e9e9ea7d21dd7..f985b3b0d937f50deaf4d881896e7bb11b0215ce 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
@@ -16,7 +16,7 @@
  *             name            DistinguishedName,       -- who
  *             authentication  CHOICE {
  *                     simple          [0] OCTET STRING -- passwd
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
  *                     krbv42ldap      [1] OCTET STRING
  *                     krbv42dsa       [2] OCTET STRING
 #endif
@@ -66,7 +66,7 @@ ldap_bind( LDAP *ld, LDAP_CONST char *dn, LDAP_CONST char *passwd, int authmetho
        case LDAP_AUTH_SIMPLE:
                return( ldap_simple_bind( ld, dn, passwd ) );
 
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
        case LDAP_AUTH_KRBV41:
                return( ldap_kerberos_bind1( ld, dn ) );
 
@@ -111,7 +111,7 @@ ldap_bind_s(
        case LDAP_AUTH_SIMPLE:
                return( ldap_simple_bind_s( ld, dn, passwd ) );
 
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
        case LDAP_AUTH_KRBV4:
                return( ldap_kerberos_bind_s( ld, dn ) );
 
@@ -130,14 +130,3 @@ ldap_bind_s(
                return( ld->ld_errno = LDAP_AUTH_UNKNOWN );
        }
 }
-
-
-void
-ldap_set_rebind_proc( LDAP *ld, int (*rebindproc)( LDAP *ld, char **dnp,
-       char **passwdp, int *authmethodp, int freeit ))
-{
-       assert( ld != NULL );
-       assert( LDAP_VALID( ld ) );
-
-       ld->ld_rebindproc = rebindproc;
-}
index 0e01394a90202358455bb247f6c1b4c71ef90444..93e0e3108389ce400bafe7efcfb8c457ba4e12a1 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
@@ -44,7 +44,7 @@ ldap_enable_cache( LDAP *ld, long timeout, ber_len_t maxmem )
                        ld->ld_errno = LDAP_NO_MEMORY;
                        return( -1 );
                }
-               (void) memset( ld->ld_cache, 0, sizeof( LDAPCache ));
+               (void) memset( ld->ld_cache, '\0', sizeof( LDAPCache ));
                ld->ld_cache->lc_memused = sizeof( LDAPCache );
        }
 
@@ -387,6 +387,7 @@ ldap_check_cache( LDAP *ld, ber_tag_t msgtype, BerElement *request )
                return( -1 );
        }
 
+       reqber.ber_valid = LBER_VALID_BERELEMENT;
        reqber.ber_buf = reqber.ber_ptr = request->ber_buf;
        reqber.ber_end = request->ber_ptr;
 
index 6be31524278042e45666f77ed1dec6f84ca0ca09..744ab07b7397c8966f213297ee1781e0ae220173 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* charray.c - routines for dealing with char * arrays */
@@ -165,22 +165,22 @@ ldap_charray_dup( char **a )
 }
 
 char **
-ldap_str2charray( char *str, char *brkstr )
+ldap_str2charray( const char *str_in, const char *brkstr )
 {
        char    **res;
-       char    *s;
+       char    *str, *s;
        char    *lasts;
        int     i;
 
        /* protect the input string from strtok */
-       str = LDAP_STRDUP( str );
+       str = LDAP_STRDUP( str_in );
        if( str == NULL ) {
                return NULL;
        }
 
        i = 1;
        for ( s = str; *s; s++ ) {
-               if ( strchr( brkstr, *s ) != NULL ) {
+               if ( ldap_utf8_strchr( brkstr, s ) != NULL ) {
                        i++;
                }
        }
@@ -194,9 +194,9 @@ ldap_str2charray( char *str, char *brkstr )
 
        i = 0;
 
-       for ( s = ldap_pvt_strtok( str, brkstr, &lasts );
+       for ( s = ldap_utf8_strtok( str, brkstr, &lasts );
                s != NULL;
-               s = ldap_pvt_strtok( NULL, brkstr, &lasts ) )
+               s = ldap_utf8_strtok( NULL, brkstr, &lasts ) )
        {
                res[i] = LDAP_STRDUP( s );
 
diff --git a/libraries/libldap/charset.c b/libraries/libldap/charset.c
deleted file mode 100644 (file)
index 7d85f5a..0000000
+++ /dev/null
@@ -1,1806 +0,0 @@
-/* $OpenLDAP$ */
-/*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
- */
-/*  Portions
- *  Copyright (c) 1995 Regents of the University of Michigan.
- *  All rights reserved.
- *
- *  charset.c
- */
-
-#include "portable.h"
-
-#ifdef STR_TRANSLATION
-
-#include <stdio.h>
-
-#include <ac/stdlib.h>
-
-#include <ac/socket.h>
-#include <ac/string.h>
-#include <ac/time.h>
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-#include "ldap-int.h"
-
-
-void
-ldap_set_string_translators( LDAP *ld, BERTranslateProc encode_proc,
-       BERTranslateProc decode_proc )
-{
-       ld->ld_lber_encode_translate_proc = encode_proc;
-       ld->ld_lber_decode_translate_proc = decode_proc;
-}
-
-
-void
-ldap_enable_translation( LDAP *ld, LDAPMessage *entry, int enable )
-{
-       unsigned short  *optionsp;
-
-       optionsp = ( entry == NULL ) ? &ld->ld_lberoptions :
-           &entry->lm_ber->ber_options;
-               
-       if ( enable ) {
-               *optionsp |= LBER_TRANSLATE_STRINGS;
-       } else {
-               *optionsp &= ~LBER_TRANSLATE_STRINGS;
-       }
-}
-
-
-int
-ldap_translate_from_t61( LDAP *ld, char **bufp, ber_len_t *lenp,
-    int free_input )
-{
-       if ( ld->ld_lber_decode_translate_proc == 0 ) {
-               return( LDAP_SUCCESS );
-       }
-           
-       return( (*ld->ld_lber_decode_translate_proc)( bufp, lenp, free_input ));
-}
-
-
-int
-ldap_translate_to_t61( LDAP *ld, char **bufp, ber_len_t *lenp,
-    int free_input )
-{
-       if ( ld->ld_lber_encode_translate_proc == 0 ) {
-               return( LDAP_SUCCESS );
-       }
-           
-       return( (*ld->ld_lber_encode_translate_proc)( bufp, lenp, free_input ));
-}
-
-
-/*
- ** Character translation routine notes:
- *
- * On entry:  bufp points to a "string" to be converted (not necessarily
- *  zero-terminated) and buflenp points to the length of the buffer.
- *
- * On exit:  bufp should point to a malloc'd result.  If free_input is
- *  non-zero then the original bufp will be freed.  *buflenp should be
- *  set to the new length.  Zero bytes in the input buffer must be left
- *  as zero bytes.
- *
- * Return values: any ldap error code (LDAP_SUCCESS if all goes well).
- */
-
-
-#ifdef LDAP_CHARSET_8859
-
-#if LDAP_CHARSET_8859 == 88591
-#define ISO_8859 1
-#elif LDAP_CHARSET_8859 == 88592
-#define ISO_8859 2
-#elif LDAP_CHARSET_8859 == 88593
-#define ISO_8859 3
-#elif LDAP_CHARSET_8859 == 88594
-#define ISO_8859 4
-#elif LDAP_CHARSET_8859 == 88595
-#define ISO_8859 5
-#elif LDAP_CHARSET_8859 == 88596
-#define ISO_8859 6
-#elif LDAP_CHARSET_8859 == 88597
-#define ISO_8859 7
-#elif LDAP_CHARSET_8859 == 88598
-#define ISO_8859 8
-#elif LDAP_CHARSET_8859 == 88599
-#define ISO_8859 9
-#elif LDAP_CHARSET_8859 == 885910
-#define ISO_8859 10
-#else
-#define ISO_8859 0
-#endif
-
-/*
- * the following ISO_8859 to/afrom T.61 character set translation code is
- * based on the code found in Enrique Silvestre Mora's iso-t61.c, found
- * as part of this package:
- *   ftp://pereiii.uji.es/pub/uji-ftp/unix/ldap/iso-t61.translation.tar.Z
- * Enrique is now (10/95) at this address: enrique.silvestre@uv.es
- *
- * changes made by mcs@umich.edu 12 October 1995:
- *   Change calling conventions of iso8859_t61() and t61_iso8859() to
- *     match libldap conventions; rename to ldap_8859_to_t61() and
- *     ldap_t61_to_8859().
- *   Change conversion routines to deal with non-zero terminated strings.
- *   ANSI-ize functions and include prototypes.
- */
-
-/* iso-t61.c - ISO-T61 translation routines (version: 0.2.1, July-1994) */
-/*
- * Copyright (c) 1994 Enrique Silvestre Mora, Universitat Jaume I, Spain.
- * 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 Universitat Jaume I. 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.
-*/
-
-
-#include <stdio.h>
-#include <ac/stdlib.h>
-#include <ac/string.h>
-
-/* Character set used: ISO 8859-1, ISO 8859-2, ISO 8859-3, ... */
-/* #define  ISO_8859      1 */
-
-#ifndef ISO_8859
-#  define ISO_8859     0
-#endif
-
-typedef unsigned char  Byte;
-typedef struct { Byte  a, b; } Couple;
-
-/* Prototypes without LDAP_P():
- * 'Byte' in definition incompatible with unprototyped declaration. */
-static Byte *c_to_hh   ( Byte *o, Byte c );
-static Byte *c_to_cc   ( Byte *o, const Couple *cc, Byte c );
-static int   hh_to_c   ( const Byte *h );
-static Byte *cc_to_t61 ( Byte *o, const Byte *s );
-
-/*
-   Character choosed as base in diacritics alone: NO-BREAK SPACE.
-   (The standard say it must be a blank space, 0x20.)
-*/
-#define  ALONE  0xA0
-
-static const Couple diacritic[16] = {
-#if (ISO_8859 == 1) || (ISO_8859 == 9)
-       {0,0},       {'`',0},     {0xb4,0},    {'^',0},
-       {'~',0},     {0xaf,0},    {'(',ALONE}, {'.',ALONE},
-       {0xa8,0},    {0,0},       {'0',ALONE}, {0xb8,0},
-       {0,0},       {'"',ALONE}, {';',ALONE}, {'<',ALONE},
-#elif (ISO_8859 == 2)
-       {0,0},       {'`',0},     {0xb4,0},    {'^',0},
-       {'~',0},     {'-',ALONE}, {0xa2,0},    {0xff,0},
-       {0xa8,0},    {0,0},       {'0',ALONE}, {0xb8,0},
-       {0,0},       {0xbd,0},    {0xb2,0},    {0xb7,0}
-#elif (ISO_8859 == 3)
-       {0,0},       {'`',0},     {0xb4,0},    {'^',0},
-       {'~',0},     {'-',ALONE}, {0xa2,0},    {0xff,0},
-       {0xa8,0},    {0,0},       {'0',ALONE}, {0xb8,0},
-       {0,0},       {'"',ALONE}, {';',ALONE}, {'<',ALONE}
-#elif (ISO_8859 == 4)
-       {0,0},       {'`',0},     {0xb4,0},    {'^',0},
-       {'~',0},     {0xaf,0},    {'(',ALONE}, {0xff,0},
-       {0xa8,0},    {0,0},       {'0',ALONE}, {0xb8,0},
-       {0,0},       {'"',ALONE}, {0xb2,0},    {0xb7,0}
-#else
-       {0,0},       {'`',0},     {'\'',ALONE}, {'^',0},
-       {'~',0},     {'-',ALONE}, {'(',ALONE},  {'.',ALONE},
-       {':',ALONE}, {0,0},       {'0',ALONE},  {',',ALONE},
-       {0,0},       {'"',ALONE}, {';',ALONE},  {'<',ALONE}
-#endif
-};
-
-/*
-   --- T.61 (T.51) letters with diacritics: conversion to ISO 8859-n -----
-       A,   C,   D,   E,   G,   H,   I,   J,   K,
-       L,   N,   O,   R,   S,   T,   U,   W,   Y,   Z.
-   -----------------------------------------------------------------------
-*/
-static const int letter_w_diacritic[16][38] = {
-#if (ISO_8859 == 1)
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0xc0,0,   0,   0xc8,0,   0,   0xcc,0,   0,
-       0,   0,   0xd2,0,   0,   0,   0xd9,0,   0,   0,
-       0xe0,0,   0,   0xe8,0,   0,   0xec,0,   0,
-       0,   0,   0xf2,0,   0,   0,   0xf9,0,   0,   0,
-       0xc1,-1,  0,   0xc9,0,   0,   0xcd,0,   0,
-       -1,  -1,  0xd3,-1,  -1,  0,   0xda,0,   0xdd,-1,
-       0xe1,-1,  0,   0xe9,0,   0,   0xed,0,   0,
-       -1,  -1,  0xf3,-1,  -1,  0,   0xfa,0,   0xfd,-1,
-       0xc2,-1,  0,   0xca,-1,  -1,  0xce,-1,  0,
-       0,   0,   0xd4,0,   -1,  0,   0xdb,-1,  -1,  0,
-       0xe2,-1,  0,   0xea,-1,  -1,  0xee,-1,  0,
-       0,   0,   0xf4,0,   -1,  0,   0xfb,-1,  -1,  0,
-       0xc3,0,   0,   0,   0,   0,   -1,  0,   0,
-       0,   0xd1,0xd5,0,   0,   0,   -1,  0,   0,   0,
-       0xe3,0,   0,   0,   0,   0,   -1,  0,   0,
-       0,   0xf1,0xf5,0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   0,   -1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   0,   -1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0,   -1,  0,   -1,  -1,  0,   -1,  0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   -1,
-       0,   -1,  0,   -1,  -1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   -1,
-       0xc4,0,   0,   0xcb,0,   0,   0xcf,0,   0,
-       0,   0,   0xd6,0,   0,   0,   0xdc,0,   -1,  0,
-       0xe4,0,   0,   0xeb,0,   0,   0xef,0,   0,
-       0,   0,   0xf6,0,   0,   0,   0xfc,0,   0xff,0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0xc5,0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0xe5,0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0,   0xc7,0,   0,   -1,  0,   0,   0,   -1,
-       -1,  -1,  0,   -1,  -1,  -1,  0,   0,   0,   0,
-       0,   0xe7,0,   0,   -1,  0,   0,   0,   -1,
-       -1,  -1,  0,   -1,  -1,  -1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0,   -1,  -1,  -1,  0,   0,   0,   0,   0,
-       -1,  -1,  0,   -1,  -1,  -1,  0,   0,   0,   -1,
-       0,   -1,  -1,  -1,  0,   0,   0,   0,   0,
-       -1,  -1,  0,   -1,  -1,  -1,  0,   0,   0,   -1
-#elif (ISO_8859 == 2)
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       0xc1,0xc6,0,   0xc9,0,   0,   0xcd,0,   0,
-       0xc5,0xd1,0xd3,0xc0,0xa6,0,   0xda,0,   0xdd,0xac,
-       0xe1,0xe6,0,   0xe9,0,   0,   0xed,0,   0,
-       0xe5,0xf1,0xf3,0xe0,0xb6,0,   0xfa,0,   0xfd,0xbc,
-       0xc2,-1,  0,   -1,  -1,  -1,  0xce,-1,  0,
-       0,   0,   0xd4,0,   -1,  0,   -1,  -1,  -1,  0,
-       0xe2,-1,  0,   -1,  -1,  -1,  0xee,-1,  0,
-       0,   0,   0xf4,0,   -1,  0,   -1,  -1,  -1,  0,
-       -1,  0,   0,   0,   0,   0,   -1,  0,   0,
-       0,   -1,  -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   0,   0,   0,   -1,  0,   0,
-       0,   -1,  -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       0xc3,0,   0,   0,   -1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0xe3,0,   0,   0,   -1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0,   -1,  0,   -1,  -1,  0,   -1,  0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0xaf,
-       0,   -1,  0,   -1,  -1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0xbf,
-       0xc4,0,   0,   0xcb,0,   0,   -1,  0,   0,
-       0,   0,   0xd6,0,   0,   0,   0xdc,0,   -1,  0,
-       0xe4,0,   0,   0xeb,0,   0,   -1,  0,   0,
-       0,   0,   0xf6,0,   0,   0,   0xfc,0,   -1,  0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       -1,  0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0xd9,0,   0,   0,
-       -1,  0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0xf9,0,   0,   0,
-       0,   0xc7,0,   0,   -1,  0,   0,   0,   -1,
-       -1,  -1,  0,   -1,  0xaa,0xde,0,   0,   0,   0,
-       0,   0xe7,0,   0,   -1,  0,   0,   0,   -1,
-       -1,  -1,  0,   -1,  0xba,0xfe,0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0xd5,0,   0,   0,   0xdb,0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0xf5,0,   0,   0,   0xfb,0,   0,   0,
-       0xa1,0,   0,   0xca,0,   0,   -1,  0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0xb1,0,   0,   0xea,0,   0,   -1,  0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0,   0xc8,0xcf,0xcc,0,   0,   0,   0,   0,
-       0xa5,0xd2,0,   0xd8,0xa9,0xab,0,   0,   0,   0xae,
-       0,   0xe8,0xef,0xec,0,   0,   0,   0,   0,
-       0xb5,0xf2,0,   0xf8,0xb9,0xbb,0,   0,   0,   0xbe
-#elif (ISO_8859 == 3)
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0xc0,0,   0,   0xc8,0,   0,   0xcc,0,   0,
-       0,   0,   0xd2,0,   0,   0,   0xd9,0,   0,   0,
-       0xe0,0,   0,   0xe8,0,   0,   0xec,0,   0,
-       0,   0,   0xf2,0,   0,   0,   0xf9,0,   0,   0,
-       0xc1,-1,  0,   0xc9,0,   0,   0xcd,0,   0,
-       -1,  -1,  0xd3,-1,  -1,  0,   0xda,0,   -1,  -1,
-       0xe1,-1,  0,   0xe9,0,   0,   0xed,0,   0,
-       -1,  -1,  0xf3,-1,  -1,  0,   0xfa,0,   -1,  -1,
-       0xc2,0xc6,0,   0xca,0xd8,0xa6,0xce,0xac,0,
-       0,   0,   0xd4,0,   0xde,0,   0xdb,-1,  -1,  0,
-       0xe2,0xe6,0,   0xea,0xf8,0xb6,0xee,0xbc,0,
-       0,   0,   0xf4,0,   0xfe,0,   0xfb,-1,  -1,  0,
-       -1,  0,   0,   0,   0,   0,   -1,  0,   0,
-       0,   0xd1,-1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   0,   0,   0,   -1,  0,   0,
-       0,   0xf1,-1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   0,   0xab,0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0xdd,0,   0,   0,
-       -1,  0,   0,   0,   0xbb,0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0xfd,0,   0,   0,
-       0,   0xc5,0,   -1,  0xd5,0,   0xa9,0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0xaf,
-       0,   0xe5,0,   -1,  0xf5,0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0xbf,
-       0xc4,0,   0,   0xcb,0,   0,   0xcf,0,   0,
-       0,   0,   0xd6,0,   0,   0,   0xdc,0,   -1,  0,
-       0xe4,0,   0,   0xeb,0,   0,   0xef,0,   0,
-       0,   0,   0xf6,0,   0,   0,   0xfc,0,   -1,  0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       -1,  0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0,   0xc7,0,   0,   -1,  0,   0,   0,   -1,
-       -1,  -1,  0,   -1,  0xaa,-1,  0,   0,   0,   0,
-       0,   0xe7,0,   0,   -1,  0,   0,   0,   -1,
-       -1,  -1,  0,   -1,  0xba,-1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0,   -1,  -1,  -1,  0,   0,   0,   0,   0,
-       -1,  -1,  0,   -1,  -1,  -1,  0,   0,   0,   -1,
-       0,   -1,  -1,  -1,  0,   0,   0,   0,   0,
-       -1,  -1,  0,   -1,  -1,  -1,  0,   0,   0,   -1
-#elif (ISO_8859 == 4)
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       0xc1,-1,  0,   0xc9,0,   0,   0xcd,0,   0,
-       -1,  -1,  -1,  -1,  -1,  0,   0xda,0,   -1,  -1,
-       0xe1,-1,  0,   0xe9,0,   0,   0xed,0,   0,
-       -1,  -1,  -1,  -1,  -1,  0,   0xfa,0,   -1,  -1,
-       0xc2,-1,  0,   -1,  -1,  -1,  0xce,-1,  0,
-       0,   0,   0xd4,0,   -1,  0,   0xdb,-1,  -1,  0,
-       0xe2,-1,  0,   -1,  -1,  -1,  0xee,-1,  0,
-       0,   0,   0xf4,0,   -1,  0,   0xfb,-1,  -1,  0,
-       0xc3,0,   0,   0,   0,   0,   0xa5,0,   0,
-       0,   -1,  0xd5,0,   0,   0,   0xdd,0,   0,   0,
-       0xe3,0,   0,   0,   0,   0,   0xb5,0,   0,
-       0,   -1,  0xf5,0,   0,   0,   0xfd,0,   0,   0,
-       0xc0,0,   0,   0xaa,0,   0,   0xcf,0,   0,
-       0,   0,   0xd2,0,   0,   0,   0xde,0,   0,   0,
-       0xe0,0,   0,   0xba,0,   0,   0xef,0,   0,
-       0,   0,   0xf2,0,   0,   0,   0xfe,0,   0,   0,
-       -1,  0,   0,   0,   -1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   0,   -1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0,   -1,  0,   0xcc,-1,  0,   -1,  0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   -1,
-       0,   -1,  0,   0xec,-1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   -1,
-       0xc4,0,   0,   0xcb,0,   0,   -1,  0,   0,
-       0,   0,   0xd6,0,   0,   0,   0xdc,0,   -1,  0,
-       0xe4,0,   0,   0xeb,0,   0,   -1,  0,   0,
-       0,   0,   0xf6,0,   0,   0,   0xfc,0,   -1,  0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0xc5,0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0xe5,0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0,   -1,  0,   0,   0xab,0,   0,   0,   0xd3,
-       0xa6,0xd1,0,   0xa3,-1,  -1,  0,   0,   0,   0,
-       0,   -1,  0,   0,   0xbb,0,   0,   0,   0xf3,
-       0xb6,0xf1,0,   0xb3,-1,  -1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       0xa1,0,   0,   0xca,0,   0,   0xc7,0,   0,
-       0,   0,   0,   0,   0,   0,   0xd9,0,   0,   0,
-       0xb1,0,   0,   0xea,0,   0,   0xe7,0,   0,
-       0,   0,   0,   0,   0,   0,   0xf9,0,   0,   0,
-       0,   0xc8,-1,  -1,  0,   0,   0,   0,   0,
-       -1,  -1,  0,   -1,  0xa9,-1,  0,   0,   0,   0xae,
-       0,   0xe8,-1,  -1,  0,   0,   0,   0,   0,
-       -1,  -1,  0,   -1,  0xb9,-1,  0,   0,   0,   0xbe
-#elif (ISO_8859 == 9)
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0xc0,0,   0,   0xc8,0,   0,   0xcc,0,   0,
-       0,   0,   0xd2,0,   0,   0,   0xd9,0,   0,   0,
-       0xe0,0,   0,   0xe8,0,   0,   -1,  0,   0,
-       0,   0,   0xf2,0,   0,   0,   0xf9,0,   0,   0,
-       0xc1,-1,  0,   0xc9,0,   0,   0xcd,0,   0,
-       -1,  -1,  0xd3,-1,  -1,  0,   0xda,0,   -1,  -1,
-       0xe1,-1,  0,   0xe9,0,   0,   0xed,0,   0,
-       -1,  -1,  0xf3,-1,  -1,  0,   0xfa,0,   -1,  -1,
-       0xc2,-1,  0,   0xca,-1,  -1,  0xce,-1,  0,
-       0,   0,   0xd4,0,   -1,  0,   0xdb,-1,  -1,  0,
-       0xe2,-1,  0,   -1,  -1,  -1,  0xee,-1,  0,
-       0,   0,   0xf4,0,   -1,  0,   0xfb,-1,  -1,  0,
-       0xc3,0,   0,   0,   0,   0,   -1,  0,   0,
-       0,   0xd1,0xd5,0,   0,   0,   -1,  0,   0,   0,
-       0xe3,0,   0,   0,   0,   0,   -1,  0,   0,
-       0,   0xf1,0xf5,0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   0xef,0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   0,   0xd0,0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   0,   0xf0,0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0,   -1,  0,   -1,  -1,  0,   0xdd,0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   -1,
-       0,   -1,  0,   0xec,-1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   -1,
-       0xc4,0,   0,   0xcb,0,   0,   0xcf,0,   0,
-       0,   0,   0xd6,0,   0,   0,   0xdc,0,   -1,  0,
-       0xe4,0,   0,   0xeb,0,   0,   -1,  0,   0,
-       0,   0,   0xf6,0,   0,   0,   0xfc,0,   0xff,0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0xc5,0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0xe5,0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0,   0xc7,0,   0,   -1,  0,   0,   0,   -1,
-       -1,  -1,  0,   -1,  0xde,-1,  0,   0,   0,   0,
-       0,   0xe7,0,   0,   -1,  0,   0,   0,   -1,
-       -1,  -1,  0,   -1,  0xfe,-1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   0xea,0,   0,   -1,  0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0,   -1,  -1,  -1,  0,   0,   0,   0,   0,
-       -1,  -1,  0,   -1,  -1,  -1,  0,   0,   0,   -1,
-       0,   -1,  -1,  -1,  0,   0,   0,   0,   0,
-       -1,  -1,  0,   -1,  -1,  -1,  0,   0,   0,   -1
-#elif (ISO_8859 == 10)
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       0xc1,-1,  0,   0xc9,0,   0,   0xcd,0,   0,
-       -1,  -1,  0xd3,-1,  -1,  0,   0xda,0,   0xdd,-1,
-       0xe1,-1,  0,   0xe9,0,   0,   0xed,0,   0,
-       -1,  -1,  0xf3,-1,  -1,  0,   0xfa,0,   0xfd,-1,
-       0xc2,-1,  0,   -1,  -1,  -1,  0xce,-1,  0,
-       0,   0,   0xd4,0,   -1,  0,   0xdb,-1,  -1,  0,
-       0xe2,-1,  0,   -1,  -1,  -1,  0xee,-1,  0,
-       0,   0,   0xf4,0,   -1,  0,   0xfb,-1,  -1,  0,
-       0xc3,0,   0,   0,   0,   0,   0xa5,0,   0,
-       0,   -1,  0xd5,0,   0,   0,   0xd7,0,   0,   0,
-       0xe3,0,   0,   0,   0,   0,   0xb5,0,   0,
-       0,   -1,  0xf5,0,   0,   0,   0xf7,0,   0,   0,
-       0xc0,0,   0,   0xa2,0,   0,   0xa4,0,   0,
-       0,   0,   0xd2,0,   0,   0,   0xae,0,   0,   0,
-       0xe0,0,   0,   0xb2,0,   0,   0xb4,0,   0,
-       0,   0,   0xf2,0,   0,   0,   0xbe,0,   0,   0,
-       -1,  0,   0,   0,   -1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   0,   -1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0,   -1,  0,   0xcc,-1,  0,   -1,  0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   -1,
-       0,   -1,  0,   0xec,-1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   -1,
-       0xc4,0,   0,   0xcb,0,   0,   0xcf,0,   0,
-       0,   0,   0xd6,0,   0,   0,   0xdc,0,   -1,  0,
-       0xe4,0,   0,   0xeb,0,   0,   0xef,0,   0,
-       0,   0,   0xf6,0,   0,   0,   0xfc,0,   -1,  0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0xc5,0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0xe5,0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0,   -1,  0,   0,   0xa3,0,   0,   0,   0xa6,
-       0xa8,0xd1,0,   -1,  -1,  -1,  0,   0,   0,   0,
-       0,   -1,  0,   0,   0xb3,0,   0,   0,   0xb6,
-       0xb8,0xf1,0,   -1,  -1,  -1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       0xa1,0,   0,   0xca,0,   0,   0xc7,0,   0,
-       0,   0,   0,   0,   0,   0,   0xd9,0,   0,   0,
-       0xb1,0,   0,   0xea,0,   0,   0xe7,0,   0,
-       0,   0,   0,   0,   0,   0,   0xf9,0,   0,   0,
-       0,   0xc8,-1,  -1,  0,   0,   0,   0,   0,
-       -1,  -1,  0,   -1,  0xaa,-1,  0,   0,   0,   0xac,
-       0,   0xe8,-1,  -1,  0,   0,   0,   0,   0,
-       -1,  -1,  0,   -1,  0xba,-1,  0,   0,   0,   0xbc
-#else
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  -1,  0,   -1,  0,   0,   -1,  0,   0,
-       -1,  -1,  -1,  -1,  -1,  0,   -1,  0,   -1,  -1,
-       -1,  -1,  0,   -1,  0,   0,   -1,  0,   0,
-       -1,  -1,  -1,  -1,  -1,  0,   -1,  0,   -1,  -1,
-       -1,  -1,  0,   -1,  -1,  -1,  -1,  -1,  0,
-       0,   0,   -1,  0,   -1,  0,   -1,  -1,  -1,  0,
-       -1,  -1,  0,   -1,  -1,  -1,  -1,  -1,  0,
-       0,   0,   -1,  0,   -1,  0,   -1,  -1,  -1,  0,
-       -1,  0,   0,   0,   0,   0,   -1,  0,   0,
-       0,   -1,  -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   0,   0,   0,   -1,  0,   0,
-       0,   -1,  -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   0,   -1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   0,   -1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0,   -1,  0,   -1,  -1,  0,   -1,  0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   -1,
-       0,   -1,  0,   -1,  -1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   -1,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   -1,  0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   -1,  0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       -1,  0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0,   -1,  0,   0,   -1,  0,   0,   0,   -1,
-       -1,  -1,  0,   -1,  -1,  -1,  0,   0,   0,   0,
-       0,   -1,  0,   0,   -1,  0,   0,   0,   -1,
-       -1,  -1,  0,   -1,  -1,  -1,  0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       0,   0,   0,   0,   0,   0,   0,   0,   0,
-       0,   0,   -1,  0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       -1,  0,   0,   -1,  0,   0,   -1,  0,   0,
-       0,   0,   0,   0,   0,   0,   -1,  0,   0,   0,
-       0,   -1,  -1,  -1,  0,   0,   0,   0,   0,
-       -1,  -1,  0,   -1,  -1,  -1,  0,   0,   0,   -1,
-       0,   -1,  -1,  -1,  0,   0,   0,   0,   0,
-       -1,  -1,  0,   -1,  -1,  -1,  0,   0,   0,   -1
-#endif
-};
-
-/*
---- T.61 characters [0xA0 .. 0xBF] -----------------
-*/
-static const Couple trans_t61a_iso8859[32] = {
-#if (ISO_8859 == 1) || (ISO_8859 == 9)
-       {'N','S'}, {0xa1,0},  {0xa2,0},  {0xa3,0},
-       {'D','O'}, {0xa5,0},  {'C','u'}, {0xa7,0},
-       {0xa4,0},  {'\'','6'},{'"','6'}, {0xab,0},
-       {'<','-'}, {'-','!'}, {'-','>'}, {'-','v'},
-       {0xb0,0},  {0xb1,0},  {0xb2,0},  {0xb3,0},
-       {0xd7,0},  {0xb5,0},  {0xb6,0},  {0xb7,0},
-       {0xf7,0},  {'\'','9'},{'"','9'}, {0xbb,0},
-       {0xbc,0},  {0xbd,0},  {0xbe,0},  {0xbf,0}
-#elif (ISO_8859 == 2) || (ISO_8859 == 4)
-       {'N','S'}, {'!','I'}, {'C','t'}, {'P','d'},
-       {'D','O'}, {'Y','e'}, {'C','u'}, {0xa7,0},
-       {0xa4,0},  {'\'','6'},{'"','6'}, {'<','<'},
-       {'<','-'}, {'-','!'}, {'-','>'}, {'-','v'},
-       {0xb0,0},  {'+','-'}, {'2','S'}, {'3','S'},
-       {0xd7,0},  {'M','y'}, {'P','I'}, {'.','M'},
-       {0xf7,0},  {'\'','9'},{'"','9'}, {'>','>'},
-       {'1','4'}, {'1','2'}, {'3','4'}, {'?','I'},
-#elif (ISO_8859 == 3)
-       {'N','S'}, {'!','I'}, {'C','t'}, {0xa3,0},
-       {'D','O'}, {'Y','e'}, {'C','u'}, {0xa7,0},
-       {0xa4,0},  {'\'','6'},{'"','6'}, {'<','<'},
-       {'<','-'}, {'-','!'}, {'-','>'}, {'-','v'},
-       {0xb0,0},  {'+','-'}, {0xb2,0},  {0xb3,0},
-       {0xd7,0},  {0xb5,0},  {'P','I'}, {0xb7,0},
-       {0xf7,0},  {'\'','9'},{'"','9'}, {'>','>'},
-       {'1','4'}, {0xbd,0},  {'3','4'}, {'?','I'}
-#elif (ISO_8859 == 10)
-       {'N','S'}, {'!','I'}, {'C','t'}, {'P','d'},
-       {'D','O'}, {'Y','e'}, {'C','u'}, {0xa7,0},
-       {'C','u'}, {'\'','6'},{'"','6'}, {'<','<'},
-       {'<','-'}, {'-','!'}, {'-','>'}, {'-','v'},
-       {0xb0,0},  {'+','-'}, {'2','S'}, {'3','S'},
-       {'*','X'}, {'M','y'}, {'P','I'}, {0xb7,0},
-       {'-',':'}, {'\'','9'},{'"','9'}, {'>','>'},
-       {'1','4'}, {'1','2'}, {'3','4'}, {'?','I'}
-#else
-       {'N','S'}, {'!','I'}, {'C','t'}, {'P','d'},
-       {'D','O'}, {'Y','e'}, {'C','u'}, {'S','E'},
-       {'X','O'}, {'\'','6'},{'"','6'}, {'<','<'},
-       {'<','-'}, {'-','!'}, {'-','>'}, {'-','v'},
-       {'D','G'}, {'+','-'}, {'2','S'}, {'3','S'},
-       {'*','X'}, {'M','y'}, {'P','I'}, {'.','M'},
-       {'-',':'}, {'\'','9'},{'"','9'}, {'>','>'},
-       {'1','4'}, {'1','2'}, {'3','4'}, {'?','I'}
-#endif
-};
-
-/*
---- T.61 characters [0xE0 .. 0xFF] -----------------
-*/
-static const Couple trans_t61b_iso8859[48] = {
-#if (ISO_8859 == 1)
-       {'-','M'}, {0xb9,0},  {0xae,0},  {0xa9,0},
-       {'T','M'}, {'M','8'}, {0xac,0},  {0xa6,0},
-       {0,0},     {0,0},     {0,0},     {0,0},
-       {'1','8'}, {'3','8'}, {'5','8'}, {'7','8'},
-       {'O','m'}, {0xc6,0},  {0xd0,0},  {0xaa,0},
-       {'H','/'}, {0,0},     {'I','J'}, {'L','.'},
-       {'L','/'}, {0xd8,0},  {'O','E'}, {0xba,0},
-       {0xde,0},  {'T','/'}, {'N','G'}, {'\'','n'},
-       {'k','k'}, {0xe6,0},  {'d','/'}, {0xf0,0},
-       {'h','/'}, {'i','.'}, {'i','j'}, {'l','.'},
-       {'l','/'}, {0xf8,0},  {'o','e'}, {0xdf,0},
-       {0xfe,0},  {'t','/'}, {'n','g'}, {'-','-'}
-#elif (ISO_8859 == 2)
-       {'-','M'}, {'1','S'}, {'R','g'}, {'C','o'},
-       {'T','M'}, {'M','8'}, {'N','O'}, {'B','B'},
-       {0,0},     {0,0},     {0,0},     {0,0},
-       {'1','8'}, {'3','8'}, {'5','8'}, {'7','8'},
-       {'O','m'}, {'A','E'}, {0xd0,0},  {'-','a'},
-       {'H','/'}, {0,0},     {'I','J'}, {'L','.'},
-       {0xa3,0},  {'O','/'}, {'O','E'}, {'-','o'},
-       {'T','H'}, {'T','/'}, {'N','G'}, {'\'','n'},
-       {'k','k'}, {'a','e'}, {0xf0,0},  {'d','-'},
-       {'h','/'}, {'i','.'}, {'i','j'}, {'l','.'},
-       {0xb3,0},  {'o','/'}, {'o','e'}, {0xdf,0},
-       {'t','h'}, {'t','/'}, {'n','g'}, {'-','-'}
-#elif (ISO_8859 == 3)
-       {'-','M'}, {'1','S'}, {'R','g'}, {'C','o'},
-       {'T','M'}, {'M','8'}, {'N','O'}, {'B','B'},
-       {0,0},     {0,0},     {0,0},     {0,0},
-       {'1','8'}, {'3','8'}, {'5','8'}, {'7','8'},
-       {'O','m'}, {'A','E'}, {'D','/'}, {'-','a'},
-       {0xa1,0},  {0,0},     {'I','J'}, {'L','.'},
-       {'L','/'}, {'O','/'}, {'O','E'}, {'-','o'},
-       {'T','H'}, {'T','/'}, {'N','G'}, {'\'','n'},
-       {'k','k'}, {'a','e'}, {'d','/'}, {'d','-'},
-       {0xb1,0},  {0xb9,0},  {'i','j'}, {'l','.'},
-       {'l','/'}, {'o','/'}, {'o','e'}, {0xdf,0},
-       {'t','h'}, {'t','/'}, {'n','g'}, {'-','-'}
-#elif (ISO_8859 == 4)
-       {'-','M'}, {'1','S'}, {'R','g'}, {'C','o'},
-       {'T','M'}, {'M','8'}, {'N','O'}, {'B','B'},
-       {0,0},     {0,0},     {0,0},     {0,0},
-       {'1','8'}, {'3','8'}, {'5','8'}, {'7','8'},
-       {'O','m'}, {0xc6,0},  {0xd0,0},  {'-','a'},
-       {'H','/'}, {0,0},     {'I','J'}, {'L','.'},
-       {'L','/'}, {0xd8,0},  {'O','E'}, {'-','o'},
-       {'T','H'}, {0xac,0},  {0xbd,0},  {'\'','n'},
-       {0xa2,0},  {0xe6,0},  {0xf0,0},  {'d','-'},
-       {'h','/'}, {'i','.'}, {'i','j'}, {'l','.'},
-       {'l','/'}, {0xf8,0},  {'o','e'}, {0xdf,0},
-       {'t','h'}, {0xbc,0},  {0xbf,0},  {'-','-'}
-#elif (ISO_8859 == 9)
-       {'-','M'}, {0xb9,0},  {0xae,0},  {0xa9,0},
-       {'T','M'}, {'M','8'}, {0xac,0},  {0xa6,0},
-       {0,0},     {0,0},     {0,0},     {0,0},
-       {'1','8'}, {'3','8'}, {'5','8'}, {'7','8'},
-       {'O','m'}, {0xc6,0},  {'D','/'}, {0xaa,0},
-       {'H','/'}, {0,0},     {'I','J'}, {'L','.'},
-       {'L','/'}, {0xd8,0},  {'O','E'}, {0xba,0},
-       {'T','H'}, {'T','/'}, {'N','G'}, {'\'','n'},
-       {'k','k'}, {0xe6,0},  {'d','/'}, {'d','-'},
-       {'h','/'}, {0xfd,0},  {'i','j'}, {'l','.'},
-       {'l','/'}, {0xf8,0},  {'o','e'}, {0xdf,0},
-       {'t','h'}, {'t','/'}, {'n','g'}, {'-','-'}
-#elif (ISO_8859 == 10)
-       {0xbd,0},  {'1','S'}, {'R','g'}, {'C','o'},
-       {'T','M'}, {'M','8'}, {'N','O'}, {'B','B'},
-       {0,0},     {0,0},     {0,0},     {0,0},
-       {'1','8'}, {'3','8'}, {'5','8'}, {'7','8'},
-       {'O','m'}, {0xc6,0},  {0xa9,0},  {'-','a'},
-       {'H','/'}, {0,0},     {'I','J'}, {'L','.'},
-       {'L','/'}, {0xd8,0},  {'O','E'}, {'-','o'},
-       {0xde,0},  {0xab,0},  {0xaf,0},  {'\'','n'},
-       {0xff,0},  {0xe6,0},  {0xb9,0},  {0xf0,0},
-       {'h','/'}, {'i','.'}, {'i','j'}, {'l','.'},
-       {'l','/'}, {0xf8,0},  {'o','e'}, {0xdf,0},
-       {0xfe,0},  {0xbb,0},  {0xbf,0},  {'-','-'}
-#else
-       {'-','M'}, {'1','S'}, {'R','g'}, {'C','o'},
-       {'T','M'}, {'M','8'}, {'N','O'}, {'B','B'},
-       {0,0},     {0,0},     {0,0},     {0,0},
-       {'1','8'}, {'3','8'}, {'5','8'}, {'7','8'},
-       {'O','m'}, {'A','E'}, {'D','/'}, {'-','a'},
-       {'H','/'}, {0,0},     {'I','J'}, {'L','.'},
-       {'L','/'}, {'O','/'}, {'O','E'}, {'-','o'},
-       {'T','H'}, {'T','/'}, {'N','G'}, {'\'','n'},
-       {'k','k'}, {'a','e'}, {'d','/'}, {'d','-'},
-       {'h','/'}, {'i','.'}, {'i','j'}, {'l','.'},
-       {'l','/'}, {'o','/'}, {'o','e'}, {'s','s'},
-       {'t','h'}, {'t','-'}, {'n','g'}, {'-','-'}
-#endif
-};
-
-/*
---- ISO 8859-n characters <0xA0 .. 0xFF> -------------------
-*/
-#if (ISO_8859 == 1)
-static const Couple trans_iso8859_t61[96] = {
-       {0xa0,0},     {0xa1,0},     {0xa2,0},     {0xa3,0},
-       {0xa8,0},     {0xa5,0},     {0xd7,0},     {0xa7,0},
-       {0xc8,ALONE}, {0xd3,0},     {0xe3,0},     {0xab,0},
-       {0xd6,0},     {0xff,0},     {0xd2,0},     {0xc5,ALONE},
-       {0xb0,0},     {0xb1,0},     {0xb2,0},     {0xb3,0},
-       {0xc2,ALONE}, {0xb5,0},     {0xb6,0},     {0xb7,0},
-       {0xcb,ALONE}, {0xd1,0},     {0xeb,0},     {0xbb,0},
-       {0xbc,0},     {0xbd,0},     {0xbe,0},     {0xbf,0},
-       {0xc1,'A'},   {0xc2,'A'},   {0xc3,'A'},   {0xc4,'A'},
-       {0xc8,'A'},   {0xca,'A'},   {0xe1,0},     {0xcb,'C'},
-       {0xc1,'E'},   {0xc2,'E'},   {0xc3,'E'},   {0xc8,'E'},
-       {0xc1,'I'},   {0xc2,'I'},   {0xc3,'I'},   {0xc8,'I'},
-       {0xe2,0},     {0xc4,'N'},   {0xc1,'O'},   {0xc2,'O'},
-       {0xc3,'O'},   {0xc4,'O'},   {0xc8,'O'},   {0xb4,0},
-       {0xe9,0},     {0xc1,'U'},   {0xc2,'U'},   {0xc3,'U'},
-       {0xc8,'U'},   {0xc2,'Y'},   {0xec,0},     {0xfb,0},
-       {0xc1,'a'},   {0xc2,'a'},   {0xc3,'a'},   {0xc4,'a'},
-       {0xc8,'a'},   {0xca,'a'},   {0xf1,0},     {0xcb,'c'},
-       {0xc1,'e'},   {0xc2,'e'},   {0xc3,'e'},   {0xc8,'e'},
-       {0xc1,'i'},   {0xc2,'i'},   {0xc3,'i'},   {0xc8,'i'},
-       {0xf3,0},     {0xc4,'n'},   {0xc1,'o'},   {0xc2,'o'},
-       {0xc3,'o'},   {0xc4,'o'},   {0xc8,'o'},   {0xb8,0},
-       {0xf9,0},     {0xc1,'u'},   {0xc2,'u'},   {0xc3,'u'},
-       {0xc8,'u'},   {0xc2,'y'},   {0xfc,0},     {0xc8,'y'}
-};
-#elif (ISO_8859 == 2)
-static const Couple trans_iso8859_t61[96] = {
-       {0xa0,0},     {0xce,'A'},   {0xc6,ALONE}, {0xe8,0},
-       {0xa8,0},     {0xcf,'L'},   {0xc2,'S'},   {0xa7,0},
-       {0xc8,ALONE}, {0xcf,'S'},   {0xcb,'S'},   {0xcf,'T'},
-       {0xc2,'Z'},   {0xff,0},     {0xcf,'Z'},   {0xc7,'Z'},
-       {0xb0,0},     {0xce,'a'},   {0xce,ALONE}, {0xf8,0},
-       {0xc2,ALONE}, {0xcf,'l'},   {0xc2,'s'},   {0xcf,ALONE},
-       {0xcb,ALONE}, {0xcf,'s'},   {0xcb,'s'},   {0xcf,'t'},
-       {0xc2,'z'},   {0xcd,ALONE}, {0xcf,'z'},   {0xc7,'z'},
-       {0xc2,'R'},   {0xc2,'A'},   {0xc3,'A'},   {0xc6,'A'},
-       {0xc8,'A'},   {0xc2,'L'},   {0xc2,'C'},   {0xcb,'C'},
-       {0xcf,'C'},   {0xc2,'E'},   {0xce,'E'},   {0xc8,'E'},
-       {0xcf,'E'},   {0xc2,'I'},   {0xc3,'I'},   {0xcf,'D'},
-       {0xe2,0},     {0xc2,'N'},   {0xcf,'N'},   {0xc2,'O'},
-       {0xc3,'O'},   {0xcd,'O'},   {0xc8,'O'},   {0xb4,0},
-       {0xcf,'R'},   {0xca,'U'},   {0xc2,'U'},   {0xcd,'U'},
-       {0xc8,'U'},   {0xc2,'Y'},   {0xcb,'T'},   {0xfb,0},
-       {0xc2,'r'},   {0xc2,'a'},   {0xc3,'a'},   {0xc6,'a'},
-       {0xc8,'a'},   {0xc2,'l'},   {0xc2,'c'},   {0xcb,'c'},
-       {0xcf,'c'},   {0xc2,'e'},   {0xce,'e'},   {0xc8,'e'},
-       {0xcf,'e'},   {0xc2,'i'},   {0xc3,'i'},   {0xcf,'d'},
-       {0xf2,0},     {0xc2,'n'},   {0xcf,'n'},   {0xc2,'o'},
-       {0xc3,'o'},   {0xcd,'o'},   {0xc8,'o'},   {0xb8,0},
-       {0xcf,'r'},   {0xca,'u'},   {0xc2,'u'},   {0xcd,'u'},
-       {0xc8,'u'},   {0xc2,'y'},   {0xcb,'t'},   {0xc7,ALONE}
-};
-#elif (ISO_8859 == 3)
-static const Couple trans_iso8859_t61[96] = {
-       {0xa0,0},     {0xe4,0},     {0xc6,ALONE}, {0xa3,0},
-       {0xa8,0},     {0,0},        {0xc3,'H'},   {0xa7,0},
-       {0xc8,ALONE}, {0xc7,'I'},   {0xcb,'S'},   {0xc6,'G'},
-       {0xc3,'J'},   {0xff,0},     {0,0},        {0xc7,'Z'},
-       {0xb0,0},     {0xf4,0},     {0xb2,0},     {0xb3,0},
-       {0xc2,ALONE}, {0xb5,0},     {0xc3,'h'},   {0xb7,0},
-       {0xcb,ALONE}, {0xf5,0},     {0xcb,'s'},   {0xc6,'g'},
-       {0xc3,'j'},   {0xbd,0},     {0,0},        {0xc7,'z'},
-       {0xc1,'A'},   {0xc2,'A'},   {0xc3,'A'},   {0,0},
-       {0xc8,'A'},   {0xc7,'C'},   {0xc3,'C'},   {0xcb,'C'},
-       {0xc1,'E'},   {0xc2,'E'},   {0xc3,'E'},   {0xc8,'E'},
-       {0xc1,'I'},   {0xc2,'I'},   {0xc3,'I'},   {0xc8,'I'},
-       {0,0},        {0xc4,'N'},   {0xc1,'O'},   {0xc2,'O'},
-       {0xc3,'O'},   {0xc7,'G'},   {0xc8,'O'},   {0xb4,0},
-       {0xc3,'G'},   {0xc1,'U'},   {0xc2,'U'},   {0xc3,'U'},
-       {0xc8,'U'},   {0xc6,'U'},   {0xc3,'S'},   {0xfb,0},
-       {0xc1,'a'},   {0xc2,'a'},   {0xc3,'a'},   {0,0},
-       {0xc8,'a'},   {0xc7,'c'},   {0xc3,'c'},   {0xcb,'c'},
-       {0xc1,'e'},   {0xc2,'e'},   {0xc3,'e'},   {0xc8,'e'},
-       {0xc1,'i'},   {0xc2,'i'},   {0xc3,'i'},   {0xc8,'i'},
-       {0,0},        {0xc4,'n'},   {0xc1,'o'},   {0xc2,'o'},
-       {0xc3,'o'},   {0xc7,'g'},   {0xc8,'o'},   {0xb8,0},
-       {0xc3,'g'},   {0xc1,'u'},   {0xc2,'u'},   {0xc3,'u'},
-       {0xc8,'u'},   {0xc6,'u'},   {0xc3,'s'},   {0xc7,ALONE}
-};
-#elif (ISO_8859 == 4)
-static const Couple trans_iso8859_t61[96] = {
-       {0xa0,0},     {0xce,'A'},   {0xf0,0},     {0xcb,'R'},
-       {0xa8,0},     {0xc4,'I'},   {0xcb,'L'},   {0xa7,0},
-       {0xc8,ALONE}, {0xcf,'S'},   {0xc5,'E'},   {0xcb,'G'},
-       {0xed,0},     {0xff,0},     {0xcf,'Z'},   {0xc5,ALONE},
-       {0xb0,0},     {0xce,'a'},   {0xce,ALONE}, {0xcb,'r'},
-       {0xc2,ALONE}, {0xc4,'i'},   {0xcb,'l'},   {0xcf,ALONE},
-       {0xcb,ALONE}, {0xcf,'s'},   {0xc5,'e'},   {0xcb,'g'},
-       {0xfd,0},     {0xee,0},     {0xcf,'z'},   {0xfe,0},
-       {0xc5,'A'},   {0xc2,'A'},   {0xc3,'A'},   {0xc4,'A'},
-       {0xc8,'A'},   {0xca,'A'},   {0xe1,0},     {0xce,'I'},
-       {0xcf,'C'},   {0xc2,'E'},   {0xce,'E'},   {0xc8,'E'},
-       {0xc7,'E'},   {0xc2,'I'},   {0xc3,'I'},   {0xc5,'I'},
-       {0xe2,0},     {0xcb,'N'},   {0xc5,'O'},   {0xcb,'K'},
-       {0xc3,'O'},   {0xc4,'O'},   {0xc8,'O'},   {0xb4,0},
-       {0xe9,0},     {0xce,'U'},   {0xc2,'U'},   {0xc3,'U'},
-       {0xc8,'U'},   {0xc4,'U'},   {0xc5,'U'},   {0xfb,0},
-       {0xc5,'a'},   {0xc2,'a'},   {0xc3,'a'},   {0xc4,'a'},
-       {0xc8,'a'},   {0xca,'a'},   {0xf1,0},     {0xce,'i'},
-       {0xcf,'c'},   {0xc2,'e'},   {0xce,'e'},   {0xc8,'e'},
-       {0xc7,'e'},   {0xc2,'i'},   {0xc3,'i'},   {0xc5,'i'},
-       {0xf2,0},     {0xcb,'n'},   {0xc5,'o'},   {0xcb,'k'},
-       {0xc3,'o'},   {0xc4,'o'},   {0xc8,'o'},   {0xb8,0},
-       {0xf9,0},     {0xce,'u'},   {0xc2,'u'},   {0xc3,'u'},
-       {0xc8,'u'},   {0xc4,'u'},   {0xc5,'u'},   {0xc7,ALONE}
-};
-#elif (ISO_8859 == 9)
-static const Couple trans_iso8859_t61[96] = {
-       {0xa0,0},     {0xa1,0},     {0xa2,0},     {0xa3,0},
-       {0xa8,0},     {0xa5,0},     {0xd7,0},     {0xa7,0},
-       {0xc8,ALONE}, {0xd3,0},     {0xe3,0},     {0xab,0},
-       {0xd6,0},     {0xff,0},     {0xd2,0},     {0xc5,ALONE},
-       {0xb0,0},     {0xb1,0},     {0xb2,0},     {0xb3,0},
-       {0xc2,ALONE}, {0xb5,0},     {0xb6,0},     {0xb7,0},
-       {0xcb,ALONE}, {0xd1,0},     {0xeb,0},     {0xbb,0},
-       {0xbc,0},     {0xbd,0},     {0xbe,0},     {0xbf,0},
-       {0xc1,'A'},   {0xc2,'A'},   {0xc3,'A'},   {0xc4,'A'},
-       {0xc8,'A'},   {0xca,'A'},   {0xe1,0},     {0xcb,'C'},
-       {0xc1,'E'},   {0xc2,'E'},   {0xc3,'E'},   {0xc8,'E'},
-       {0xc1,'I'},   {0xc2,'I'},   {0xc3,'I'},   {0xc8,'I'},
-       {0xc6,'G'},   {0xc4,'N'},   {0xc1,'O'},   {0xc2,'O'},
-       {0xc3,'O'},   {0xc4,'O'},   {0xc8,'O'},   {0xb4,0},
-       {0xe9,0},     {0xc1,'U'},   {0xc2,'U'},   {0xc3,'U'},
-       {0xc8,'U'},   {0xc7,'I'},   {0xcb,'S'},   {0xfb,0},
-       {0xc1,'a'},   {0xc2,'a'},   {0xc3,'a'},   {0xc4,'a'},
-       {0xc8,'a'},   {0xca,'a'},   {0xf1,0},     {0xcb,'c'},
-       {0xc1,'e'},   {0xc2,'e'},   {0xce,'e'},   {0xc8,'e'},
-       {0xc7,'e'},   {0xc2,'i'},   {0xc3,'i'},   {0xc5,'i'},
-       {0xc6,'g'},   {0xc4,'n'},   {0xc1,'o'},   {0xc2,'o'},
-       {0xc3,'o'},   {0xc4,'o'},   {0xc8,'o'},   {0xb8,0},
-       {0xf9,0},     {0xc1,'u'},   {0xc2,'u'},   {0xc3,'u'},
-       {0xc8,'u'},   {0xf5,0},     {0xcb,'s'},   {0xc8,'y'}
-};
-#elif (ISO_8859 == 10)
-static const Couple trans_iso8859_t61[96] = {
-       {0xa0,0},     {0xce,'A'},   {0xc5,'E'},   {0xcb,'G'},
-       {0xc5,'I'},   {0xc4,'I'},   {0xcb,'K'},   {0xa7,0},
-       {0xcb,'L'},   {0xe2,0},     {0xcf,'S'},   {0xed,0},
-       {0xcf,'Z'},   {0xff,0},     {0xc5,'U'},   {0xee,0},
-       {0xb0,0},     {0xce,'a'},   {0xc5,'e'},   {0xcb,'g'},
-       {0xc5,'i'},   {0xc4,'i'},   {0xcb,'k'},   {0xb7,0},
-       {0xcb,'l'},   {0xf2,0},     {0xcf,'s'},   {0xfd,0},
-       {0xcf,'z'},   {0xd0,0},     {0xc5,'u'},   {0xfe,0},
-       {0xc5,'A'},   {0xc2,'A'},   {0xc3,'A'},   {0xc4,'A'},
-       {0xc8,'A'},   {0xca,'A'},   {0xe1,0},     {0xce,'I'},
-       {0xcf,'C'},   {0xc2,'E'},   {0xce,'E'},   {0xc8,'E'},
-       {0xc7,'E'},   {0xc2,'I'},   {0xc3,'I'},   {0xc8,'I'},
-       {0,0},        {0xcb,'N'},   {0xc5,'O'},   {0xc2,'O'},
-       {0xc3,'O'},   {0xc4,'O'},   {0xc8,'O'},   {0xc4,'U'},
-       {0xe9,0},     {0xce,'U'},   {0xc2,'U'},   {0xc3,'U'},
-       {0xc8,'U'},   {0xc2,'Y'},   {0xec,0},     {0xfb,0},
-       {0xc5,'a'},   {0xc2,'a'},   {0xc3,'a'},   {0xc4,'a'},
-       {0xc8,'a'},   {0xca,'a'},   {0xf1,0},     {0xce,'i'},
-       {0xcf,'c'},   {0xc2,'e'},   {0xce,'e'},   {0xc8,'e'},
-       {0xc7,'e'},   {0xc2,'i'},   {0xc3,'i'},   {0xc8,'i'},
-       {0xf3,0},     {0xcb,'n'},   {0xc5,'o'},   {0xc2,'o'},
-       {0xc3,'o'},   {0xc4,'o'},   {0xc8,'o'},   {0xc4,'u'},
-       {0xf9,0},     {0xce,'u'},   {0xc2,'u'},   {0xc3,'u'},
-       {0xc8,'u'},   {0xc2,'y'},   {0xfc,0},     {0xf0,0}
-};
-#endif
-
-
-static Byte *
-c_to_hh( Byte *o, Byte c )
-{
-  Byte n;
-
-  *o++ = '{'; *o++ = 'x';
-  n = c >> 4;
-  *o++ = ((n < 0xA) ? '0' : 'A' - 0xA) + n;
-  n = c & 0x0F;
-  *o++ = ((n < 0xA) ? '0' : 'A' - 0xA) + n;
-  *o++ = '}';
-  return o;
-}
-
-
-static Byte *
-c_to_cc( Byte *o, const Couple *cc, Byte c )
-{
-  if ( (*cc).a != 0 ) {
-    if ( (*cc).b == 0 )
-      *o++ = (*cc).a;
-    else {
-      *o++ = '{';
-      *o++ = (*cc).a;
-      *o++ = (*cc).b;
-      *o++ = '}';
-    }
-    return o;
-  }
-  else
-    return c_to_hh( o, c );
-}
-
-/* --- routine to convert from T.61 to ISO 8859-n --- */
-
-int
-ldap_t61_to_8859( char **bufp, ber_len_t *buflenp, int free_input )
-{
-  Byte         *s, *oo, *o;
-  unsigned int  n;
-  int           c;
-  ber_len_t len;
-
-  Debug( LDAP_DEBUG_TRACE, "ldap_t61_to_8859 input length: %ld\n",
-       *buflenp, 0, 0 );
-
-  len = *buflenp;
-  s = (Byte *) *bufp;
-
-  if ( (o = oo = (Byte *)LDAP_MALLOC( 2 * len + 64 )) == NULL ) {
-        return( 1 );
-  }
-
-  while ( (char *)s - *(char **)bufp < len ) {
-    switch ( *s >> 4 ) {
-
-    case 0xA: case 0xB:
-      o = c_to_cc( o, &trans_t61a_iso8859[ *s - 0xA0 ], *s );
-      s++;
-      break;
-
-    case 0xD: case 0xE: case 0xF:
-      o = c_to_cc( o, &trans_t61b_iso8859[ *s - 0xD0 ], *s );
-      s++;
-      break;
-
-    case 0xC:
-      if ( (*s == 0xC0) || (*s == 0xC9) || (*s == 0xCC) ) {
-        o = c_to_hh( o, *s++ );
-        break;
-      }
-
-      n = (*s++) - 0xC0;
-      switch ( *s ) {
-
-      case 'A':  c = letter_w_diacritic[n][0]; break;
-      case 'C':  c = letter_w_diacritic[n][1]; break;
-      case 'D':  c = letter_w_diacritic[n][2]; break;
-      case 'E':  c = letter_w_diacritic[n][3]; break;
-      case 'G':  c = letter_w_diacritic[n][4]; break;
-      case 'H':  c = letter_w_diacritic[n][5]; break;
-      case 'I':  c = letter_w_diacritic[n][6]; break;
-      case 'J':  c = letter_w_diacritic[n][7]; break;
-      case 'K':  c = letter_w_diacritic[n][8]; break;
-      case 'L':  c = letter_w_diacritic[n][9]; break;
-      case 'N':  c = letter_w_diacritic[n][10]; break;
-      case 'O':  c = letter_w_diacritic[n][11]; break;
-      case 'R':  c = letter_w_diacritic[n][12]; break;
-      case 'S':  c = letter_w_diacritic[n][13]; break;
-      case 'T':  c = letter_w_diacritic[n][14]; break;
-      case 'U':  c = letter_w_diacritic[n][15]; break;
-      case 'W':  c = letter_w_diacritic[n][16]; break;
-      case 'Y':  c = letter_w_diacritic[n][17]; break;
-      case 'Z':  c = letter_w_diacritic[n][18]; break;
-
-      case 'a':  c = letter_w_diacritic[n][19]; break;
-      case 'c':  c = letter_w_diacritic[n][20]; break;
-      case 'd':  c = letter_w_diacritic[n][21]; break;
-      case 'e':  c = letter_w_diacritic[n][22]; break;
-      case 'g':  c = letter_w_diacritic[n][23]; break;
-      case 'h':  c = letter_w_diacritic[n][24]; break;
-      case 'i':  c = letter_w_diacritic[n][25]; break;
-      case 'j':  c = letter_w_diacritic[n][26]; break;
-      case 'k':  c = letter_w_diacritic[n][27]; break;
-      case 'l':  c = letter_w_diacritic[n][28]; break;
-      case 'n':  c = letter_w_diacritic[n][29]; break;
-      case 'o':  c = letter_w_diacritic[n][30]; break;
-      case 'r':  c = letter_w_diacritic[n][31]; break;
-      case 's':  c = letter_w_diacritic[n][32]; break;
-      case 't':  c = letter_w_diacritic[n][33]; break;
-      case 'u':  c = letter_w_diacritic[n][34]; break;
-      case 'w':  c = letter_w_diacritic[n][35]; break;
-      case 'y':  c = letter_w_diacritic[n][36]; break;
-      case 'z':  c = letter_w_diacritic[n][37]; break;
-
-      case ALONE:  c = (( !diacritic[n].b ) ? diacritic[n].a : -1);
-                   break;
-
-      default:   c = 0;
-      }
-
-      if ( c > 0 ) {
-        *o++ = c;  s++;
-      } else {
-        *o++ = '{';
-        if ( c == -1 ) {
-          *o++ = ( ( *s == ALONE ) ? ' ' : *s );
-          s++;
-        } else {
-          *o++ = '"';
-        }
-        *o++ = diacritic[n].a;
-        *o++ = '}';
-      }
-      break;
-
-#if (ISO_8859 == 0)
-    case 0x8: case 0x9:
-      *o++ = 0x1B; /* <ESC> */
-      *o++ = *s++ - 0x40;
-      break;
-#endif
-
-      default:
-        *o++ = *s++;
-    }
-  }
-
-  len = o - oo;
-  o = oo;
-
-  if ( (oo = (Byte *)LDAP_REALLOC( o, len )) == NULL ) {
-    LDAP_FREE( o );
-    return( 1 );
-  }
-
-  if ( free_input ) {
-    LDAP_FREE( *bufp );
-  }
-  *bufp = (char *) oo;
-  *buflenp = len;
-  return( 0 );
-}
-
-
-static int
-hh_to_c( const Byte *h )
-{
-  Byte c;
-
-  if ( (*h >= '0') && (*h <= '9') )      c = *h++ - '0';
-  else if ( (*h >= 'A') && (*h <= 'F') ) c = *h++ - 'A' + 10;
-  else if ( (*h >= 'a') && (*h <= 'f') ) c = *h++ - 'a' + 10;
-  else return -1;
-
-  c <<= 4;
-
-  if ( (*h >= '0') && (*h <= '9') )      c |= *h - '0';
-  else if ( (*h >= 'A') && (*h <= 'F') ) c |= *h - 'A' + 10;
-  else if ( (*h >= 'a') && (*h <= 'f') ) c |= *h - 'a' + 10;
-  else return -1;
-
-  return c;
-}
-
-
-static Byte *
-cc_to_t61( Byte *o, const Byte *s )
-{
-  int n, c = 0;
-
-  switch ( *(s + 1) ) {
-
-  case '`':  c = -1;   break;    /* <grave-accent> */
-
-  case '!':
-    switch ( *s ) {
-    case '!':  c = 0x7C;  break;  /* <vertical-line> */
-    case '(':  c = 0x7B;  break;  /* <left-curly-bracket> */
-    case '-':  c = 0xAD;  break;  /* <upwards-arrow> */
-    default:   c = -1;            /* <grave-accent> */
-    }
-    break;
-
-#if (ISO_8859 == 1) || (ISO_8859 == 2) || (ISO_8859 == 3) || \
-    (ISO_8859 == 4) || (ISO_8859 == 9)
-  case 0xB4:
-#endif
-  case '\'': c = -2;  break;    /* <acute-accent> */
-
-  case '^':  c = -3;  break;    /* <circumflex-acent> */
-
-  case '>':
-    switch ( *s ) {
-    case ')':  c = 0x5D;  break;  /* <right-square-bracket> */
-    case '>':  c = 0xBB;  break;  /* <right-angle-quotation> */
-    case '-':  c = 0xAE;  break;  /* <rightwards-arrow> */
-    default:   c = -3;            /* <circumflex-acent> */
-    }
-    break;
-
-  case '~':
-  case '?':  c = -4;  break;        /* <tilde> */
-
-#if (ISO_8859 == 1) || (ISO_8859 == 4) || (ISO_8859 == 9)
-  case 0xAF:  c = -5;  break;       /* <macron> */
-#endif
-
-  case '-':
-    switch ( *s ) {
-    case '-':  c = 0xFF; break; /* <soft-hyphen> */
-    case '<':  c = 0xAC; break; /* <leftwards arrow> */
-    case '+':  c = 0xB1; break; /* <plus-minus> */
-    case 'd':  c = 0xF3; break; /* <eth> */
-    default:   c = -5;          /* <macron> */
-    }
-    break;
-
-#if (ISO_8859 == 2) || (ISO_8859 == 3)
-  case 0xA2:  c = -6;  break;            /* <breve> */
-#endif
-
-  case '(':
-    if ( *s == '<' ) c = 0x5B;  /* <left-square-bracket> */
-    else             c = -6;    /* <breve> */
-    break;
-
-#if (ISO_8859 == 2) || (ISO_8859 == 3) || (ISO_8859 == 4)
-  case 0xFF:  c = -7;  break;    /* <dot-accent> */
-#endif
-
-  case '.':
-    switch ( *s ) {
-    case 'i':  c = 0xF5; break; /* <dotless-i> */
-    case 'L':  c = 0xE7; break; /* <L-middle-dot> */
-    case 'l':  c = 0xF7; break; /* <l-middle-dot> */
-    default:   c = -7;          /* <dot-accent> */
-    }
-    break;
-
-#if (ISO_8859 == 1) || (ISO_8859 == 2) || (ISO_8859 == 3) || \
-    (ISO_8859 == 4) || (ISO_8859 == 9)
-  case 0xA8:  c = -8; break; /* <diaeresis> */
-#endif
-
-  case ':':
-    if ( *s == '-')  c = 0xB8; /* <division-sign> */
-    else             c = -8;   /* <diaeresis> */
-    break;
-
-#if (ISO_8859 == 1) || (ISO_8859 == 2) || (ISO_8859 == 3) || \
-    (ISO_8859 == 4) || (ISO_8859 == 9) || (ISO_8859 == 10)
-  case 0xB0:
-#endif
-  case '0':  c = -10;  break;  /* <ring-above> */
-
-#if (ISO_8859 == 1) || (ISO_8859 == 2) || (ISO_8859 == 3) || \
-    (ISO_8859 == 4) || (ISO_8859 == 9)
-  case 0xB8:
-#endif
-  case ',':  c = -11; break; /* <cedilla> */
-
-#if (ISO_8859 == 2)
-  case 0xBD:
-#endif
-  case '"':  c = -13; break; /* <double-acute-accent> */
-
-#if (ISO_8859 == 2) || (ISO_8859 == 4)
-  case 0xB2:
-#endif
-  case ';':  c = -14; break; /* <ogonek> */
-
-#if (ISO_8859 == 2) || (ISO_8859 == 4)
-  case 0xB7:  c = -15;  break;  /* <caron> */
-#endif
-
-  case ')':
-    if ( *s == '!' )  c = 0x7D;  /* <left-curly-bracket> */
-    break;
-
-  case '<':
-    if ( *s == '<' )  c = 0xAB;  /* <left-angle-quotation> */
-    else              c = -15;   /* <caron> */
-    break;
-
-  case '/':
-    switch ( *s ) {
-    case '/':  c = 0x5C; break; /* <reverse-solidus> */
-    case 'D':  c = 0xE2; break; /* <D-stroke> */
-    case 'd':  c = 0xF2; break; /* <d-stroke> */
-    case 'H':  c = 0xE4; break; /* <H-stroke> */
-    case 'h':  c = 0xF4; break; /* <h-stroke> */
-    case 'L':  c = 0xE8; break; /* <L-stroke> */
-    case 'l':  c = 0xF8; break; /* <l-stroke> */
-    case 'O':  c = 0xE9; break; /* <O-stroke> */
-    case 'o':  c = 0xF9; break; /* <o-stroke> */
-    case 'T':  c = 0xED; break; /* <T-stroke> */
-    case 't':  c = 0xFD; break; /* <t-stroke> */
-    }
-    break;
-
-  case '2':
-    if ( *s == '1' )  c = 0xBD;    /* <one-half> */
-    break;
-
-  case '4':
-    switch ( *s ) {
-    case '1':  c = 0xBC; break; /* <one-quarter> */
-    case '3':  c = 0xBE; break; /* <three-quarters> */
-    }
-    break;
-
-  case '6':
-    switch ( *s ) {
-    case '\'': c = 0xA9; break; /* <left-single-quotation> */
-    case '"':  c = 0xAA; break; /* <left-double-quotation> */
-    }
-    break;
-
-  case '8':
-    switch ( *s ) {
-    case '1':  c = 0xDC; break; /* <one-eighth> */
-    case '3':  c = 0xDD; break; /* <three-eighths> */
-    case '5':  c = 0xDE; break; /* <five-eighths> */
-    case '7':  c = 0xDF; break; /* <seven-eighths> */
-    case 'M':  c = 0xD5; break; /* <eighth-note> */
-    }
-    break;
-
-  case '9':
-    switch ( *s ) {
-    case '\'': c = 0xB9; break; /* <right-single-quotation> */
-    case '"':  c = 0xBA; break; /* <right-double-quotation> */
-    }
-    break;
-
-  case 'A':
-    if ( *s == 'A' )  c = -10;  /* <ring-above> + <A> */
-    break;
-
-  case 'a':
-    switch ( *s ) {
-    case '-':  c = 0xE3; break; /* <femenine-ordinal-a> */
-    case 'a':  c = -10;  break; /* <ring-above> + <a> */
-    }
-    break;
-
-  case 'B':
-    if ( *s == 'B' )  c = 0xD7; /* <broken-bar> */
-    break;
-
-  case 'b':
-    if ( *s == 'N' )  c = 0xA6;  /* <number-sign> */
-    break;
-
-  case 'd':
-    if ( *s == 'P' )  c = 0xA3;  /* <pound-sign> */
-    break;
-
-  case 'E':
-    switch ( *s ) {
-    case 'S':  c = 0xA7; break; /* <section-sign> */
-    case 'A':  c = 0xE1; break; /* <AE> */
-    case 'O':  c = 0xEA; break; /* <OE> */
-    }
-    break;
-
-  case 'e':
-    switch ( *s ) {
-    case 'a':  c = 0xF1; break; /* <ae> */
-    case 'o':  c = 0xFA; break; /* <oe> */
-    case 'Y':  c = 0xA5;  break;  /* <yen-sign> */
-    }
-    break;
-
-  case 'G':
-    switch ( *s ) {
-    case 'D':  c = 0xB0; break; /* <degree-sign> */
-    case 'N':  c = 0xEE; break; /* <Eng> */
-    }
-    break;
-
-  case 'g':
-    switch ( *s ) {
-    case 'R':  c = 0xD2; break;  /* <registered-sign> */
-    case 'n':  c = 0xFE; break; /* <eng> */
-    }
-    break;
-
-  case 'H':
-    if ( *s == 'T' )  c = 0xEC;  /* <Thorn> */
-    break;
-
-  case 'h':
-    if ( *s == 't' )  c = 0xFC; /* <thorn> */
-    break;
-
-  case 'I':
-    switch ( *s ) {
-    case 'P':  c = 0xB6; break;  /* <pilcrow-sign> */
-    case '!':  c = 0xA1; break; /* <inverted-exclamation> */
-    case '?':  c = 0xBF; break; /* <inverted-question> */
-    }
-    break;
-
-  case 'J':
-    if ( *s == 'I' )  c = 0xE6; /* <IJ> */
-    break;
-
-  case 'j':
-    if ( *s == 'i' )  c = 0xF6;  /* <ij> */
-    break;
-
-  case 'k':
-    if ( *s == 'k' )  c = 0xF0; /* <kra> */
-    break;
-
-  case 'M':
-    switch ( *s ) {
-    case '.':  c = 0xB7; break; /* <middle-dot> */
-    case '-':  c = 0xD0; break; /* <em-dash> */
-    case 'T':  c = 0xD4; break; /* <trade-mark-sign> */
-    }
-    break;
-
-  case 'm':
-    switch ( *s ) {
-    case '\'':                  /* <macron> RFC 1345 */
-    case ' ':  c = -5;   break; /* <macron> */
-    case 'O':  c = 0xE0; break; /* <Ohm sign> */
-    }
-    break;
-
-  case 'n':
-    if ( *s == '\'' )  c = 0xEF; /* <n-preceded-by-apostrophe> */
-    break;
-
-  case 'O':
-    switch ( *s ) {
-    case 'D':  c = 0xA4; break; /* <dollar-sign> */
-    case 'N':  c = 0xD6; break; /* <not-sign> */
-    }
-    break;
-
-  case 'o':
-    switch ( *s ) {
-    case 'C':  c = 0xD3; break; /* <copyright-sign> */
-    case '-':  c = 0xEB; break; /* <masculine-ordinal-o> */
-    }
-    break;
-
-  case 'S':
-    switch ( *s ) {
-    case '1':  c = 0xD1; break; /* <superscript-1> */
-    case '2':  c = 0xB2; break; /* <superscript-2> */
-    case '3':  c = 0xB3; break; /* <superscript-3> */
-    case 'N':  c = 0xA0; break; /* <no-break-space> */
-    }
-    break;
-
-  case 's':
-    if ( *s == 's' )  c = 0xFB; /* <sharp-s> */
-    break;
-
-  case 't':
-    if ( *s == 'C' )  c = 0xA2; /* <cent-sign> */
-    break;
-
-  case 'u':
-    if ( *s == 'C' )  c = 0xA8; /* <currency-sign> */
-    break;
-
-  case 'v':
-    if ( *s == '-' )  c = 0xAF; /* <downwards-arrow> */
-    break;
-
-  case 'X':
-    if ( *s == '*' )  c = 0xB4; /* <multiplication-sign> */
-    break;
-
-  case 'y':
-    if ( *s == 'M' )  c = 0xB5; /* <micro-sign> */
-    break;
-  }
-
-  if ( c > 0 ) {
-    *o++ = c;
-    return o;
-  } else if ( !c )
-    return NULL;
-
-  /* else: c < 0 */
-  n = -c;
-  switch ( *s ) {
-
-  case 'A':  c = letter_w_diacritic[n][0]; break;
-  case 'C':  c = letter_w_diacritic[n][1]; break;
-  case 'D':  c = letter_w_diacritic[n][2]; break;
-  case 'E':  c = letter_w_diacritic[n][3]; break;
-  case 'G':  c = letter_w_diacritic[n][4]; break;
-  case 'H':  c = letter_w_diacritic[n][5]; break;
-  case 'I':  c = letter_w_diacritic[n][6]; break;
-  case 'J':  c = letter_w_diacritic[n][7]; break;
-  case 'K':  c = letter_w_diacritic[n][8]; break;
-  case 'L':  c = letter_w_diacritic[n][9]; break;
-  case 'N':  c = letter_w_diacritic[n][10]; break;
-  case 'O':  c = letter_w_diacritic[n][11]; break;
-  case 'R':  c = letter_w_diacritic[n][12]; break;
-  case 'S':  c = letter_w_diacritic[n][13]; break;
-  case 'T':  c = letter_w_diacritic[n][14]; break;
-  case 'U':  c = letter_w_diacritic[n][15]; break;
-  case 'W':  c = letter_w_diacritic[n][16]; break;
-  case 'Y':  c = letter_w_diacritic[n][17]; break;
-  case 'Z':  c = letter_w_diacritic[n][18]; break;
-
-  case 'a':  c = letter_w_diacritic[n][19]; break;
-  case 'c':  c = letter_w_diacritic[n][20]; break;
-  case 'd':  c = letter_w_diacritic[n][21]; break;
-  case 'e':  c = letter_w_diacritic[n][22]; break;
-  case 'g':  c = letter_w_diacritic[n][23]; break;
-  case 'h':  c = letter_w_diacritic[n][24]; break;
-  case 'i':  c = letter_w_diacritic[n][25]; break;
-  case 'j':  c = letter_w_diacritic[n][26]; break;
-  case 'k':  c = letter_w_diacritic[n][27]; break;
-  case 'l':  c = letter_w_diacritic[n][28]; break;
-  case 'n':  c = letter_w_diacritic[n][29]; break;
-  case 'o':  c = letter_w_diacritic[n][30]; break;
-  case 'r':  c = letter_w_diacritic[n][31]; break;
-  case 's':  c = letter_w_diacritic[n][32]; break;
-  case 't':  c = letter_w_diacritic[n][33]; break;
-  case 'u':  c = letter_w_diacritic[n][34]; break;
-  case 'w':  c = letter_w_diacritic[n][35]; break;
-  case 'y':  c = letter_w_diacritic[n][36]; break;
-  case 'z':  c = letter_w_diacritic[n][37]; break;
-
-  case '\'':
-  case ' ':  c = -1; break;
-
-  default:   c = 0;
-  }
-
-  if ( !c )
-    return NULL;
-
-  *o++ = n + 0xC0;
-  *o++ = ( ( (*s == ' ') || (*s == '\'') ) ? ALONE : *s );
-  return o;
-}
-
-
-/* --- routine to convert from ISO 8859-n to T.61 --- */
-
-int
-ldap_8859_to_t61( char **bufp, ber_len_t *buflenp, int free_input )
-{
-  Byte         *s, *oo, *o, *aux;
-  int          c;
-  ber_len_t len; 
-  const Couple *cc;
-
-  Debug( LDAP_DEBUG_TRACE, "ldap_8859_to_t61 input length: %ld\n",
-       *buflenp, 0, 0 );
-
-  len = *buflenp;
-  s = (Byte *) *bufp;
-
-  if ( (o = oo = (Byte *)LDAP_MALLOC( 2 * len + 64 )) == NULL ) {
-        return( 1 );
-  }
-
-  while ( (char *)s - *(char **)bufp < len ) {
-    switch( *s >> 5 ) {
-
-    case 2:
-      switch ( *s ) {
-
-      case '^':  *o++ = 0xC3; *o++ = ALONE; s++; break;
-
-      case '\\':
-        s++;
-        if ( (c = hh_to_c( s )) != -1 ) {
-          *o++ = c;
-          s += 2;
-        } else
-          *o++ = '\\';
-        break;
-
-      default:  *o++ = *s++;
-      }
-      break;
-
-    case 3:
-      switch ( *s ) {
-
-      case '`':  *o++ = 0xC1; *o++ = ALONE; s++; break;
-      case '~':  *o++ = 0xC4; *o++ = ALONE; s++; break;
-
-      case '{':
-        s++;
-        if ( *(s + 2) == '}' ) {
-          if ( (aux = cc_to_t61( o, s )) != NULL ) {
-            o = aux;
-            s += 3;
-          } else {
-            *o++ = '{';
-          }
-        } else if ( (*(s + 3) == '}') && ( (*s == 'x') || (*s == 'X') ) &&
-                    ( (c = hh_to_c( s + 1 )) != -1 ) ) {
-          *o++ = c;
-          s += 4;
-        } else {
-          *o++ = '{';
-        }
-        break;
-
-      default:
-        *o++ = *s++;
-      }
-      break;
-
-#if (ISO_8859 == 0)
-    case 4: case 5: case 6: case 7:
-      s++;
-      break;
-#else
-    case 5: case 6: case 7:
-# if (ISO_8859 == 1) || (ISO_8859 == 2) || (ISO_8859 == 3) || \
-     (ISO_8859 == 4) || (ISO_8859 == 9) || (ISO_8859 == 10)
-      if ( (*(cc = &trans_iso8859_t61[ *s - 0xA0 ])).a ) {
-       *o++ = (*cc).a;
-       if ( (*cc).b )  *o++ = (*cc).b;
-      }
-# endif
-      s++;
-      break;
-#endif
-
-    default:
-      *o++ = *s++;
-    }
-  }
-
-  len = o - oo;
-  o = oo;
-
-  if ( (oo = (Byte *)LDAP_REALLOC( o, len )) == NULL ) {
-    LDAP_FREE( o );
-    return( 1 );
-  }
-
-  if ( free_input ) {
-    LDAP_FREE( *bufp );
-  }
-  *bufp = (char *) oo;
-  *buflenp = len;
-  return( 0 );
-}
-
-
-#ifdef NOT_NEEDED_IN_LIBLDAP   /* mcs@umich.edu 12 Oct 1995 */
-/* --- routine to convert "escaped" (\hh) characters to 8bits --- */
-
-void convert_escaped_to_8bit( s )
-char   *s;
-{
-  char *o = s;
-  int  c;
-
-  while ( *s ) {
-    if ( *s == '\\' ) {
-      if ( (c = hh_to_c( (Byte *) ++s )) != -1 ) {
-       *o++ = c;
-       s += 2;
-      } else
-        *o++ = '\\';
-    } else
-      *o++ = *s++;
-  }
-  *o = '\0';
-}
-
-/* --- routine to convert 8bits characters to the "escaped" (\hh) form --- */
-
-char *convert_8bit_to_escaped( s )
-const Byte  *s;
-{
-  Byte *o, *oo;
-  Byte n;
-
-  if ( (o = oo = (Byte *)LDAP_MALLOC( 2 * strlen( s ) + 64 )) == NULL ) {
-        return( NULL );
-  }
-
-  while ( *s ) {
-    if ( *s < 0x80 )
-      *o++ = *s++;
-    else {
-      *o++ = '\\';
-      n = *s >> 4;
-      *o++ = ((n < 0xA) ? '0' : 'A' - 0xA) + n;
-      n = *s++ & 0x0F;
-      *o++ = ((n < 0xA) ? '0' : 'A' - 0xA) + n;
-    }
-  }
-  *o = '\0';
-
-  o = oo;
-
-  if ( (oo = (Byte *)LDAP_REALLOC( o, strlen( o ) + 1 )) == NULL ) {
-    LDAP_FREE( o );
-    return( NULL );
-  }
-
-  return( (char *)oo );
-}
-
-/* --- routine to convert from T.61 to printable characters --- */
-
-/*
-   printable characters [RFC 1488]: 'A'..'Z', 'a'..'z', '0'..'9',
-       '\'', '(', ')', '+', ',', '-', '.', '/', ':', '?, ' '.
-
-   that conversion is language dependent.
-*/
-
-static const Couple last_t61_printabled[32] = {
-       {0,0},     {'A','E'}, {'D',0},   {0,0},
-       {'H',0},   {0,0},     {'I','J'}, {'L',0},
-       {'L',0},   {'O',0},   {'O','E'}, {0,0},
-       {'T','H'}, {'T',0},   {'N','G'}, {'n',0},
-       {'k',0},   {'a','e'}, {'d',0},   {'d',0},
-       {'h',0},   {'i',0},   {'i','j'}, {'l',0},
-       {'l',0},   {'o',0},   {'o','e'}, {'s','s'},
-       {'t','h'}, {'t',0},   {'n','g'}, {0,0}
-};
-
-char *t61_printable( s )
-Byte  *s;
-{
-  Byte   *o, *oo;
-  Byte   n;
-  const Couple *cc;
-
-  if ( (o = oo = (Byte *)LDAP_MALLOC( 2 * strlen( s ) + 64 )) == NULL ) {
-        return( NULL );
-  }
-
-  while ( *s ) {
-    if ( ( (*s >= 'A') && (*s <= 'Z') ) ||
-         ( (*s >= 'a') && (*s <= 'z') ) ||
-         ( (*s >= '0') && (*s <= '9') ) ||
-         ( (*s >= '\'') && (*s <= ')') ) ||
-         ( (*s >= '+') && (*s <= '/') ) ||
-         ( *s == '?' ) || ( *s == ' ' ) )
-      *o++ = *s++;
-    else {
-      if ( *s >= 0xE0 ) {
-       if ( (*(cc = &last_t61_printabled[ *s - 0xE0 ])).a ) {
-          *o++ = (*cc).a;
-          if ( (*cc).b )  *o++ = (*cc).b;
-        }
-      }
-      else if ( (*s >> 4) == 0xC ) {
-        switch ( *s ) {
-       case 0xCA:                      /* ring */
-         switch ( *(s + 1) ) {
-         case 'A':  *o++ = 'A'; *o++ = 'A'; s++; break; /* Swedish */
-         case 'a':  *o++ = 'a'; *o++ = 'a'; s++; break; /* Swedish */
-         }
-         break;
-
-       case 0xC8:                      /* diaeresis */
-         switch ( *(s + 1) ) {
-         case 'Y':  *o++ = 'I'; *o++ = 'J'; s++; break; /* Dutch */
-         case 'y':  *o++ = 'i'; *o++ = 'j'; s++; break; /* Dutch */
-          }
-         break;
-        }
-      }
-      s++;
-    }
-  }
-  *o = '\0';
-
-  o = oo;
-
-  if ( (oo = (Byte *)LDAP_REALLOC( o, strlen( o ) + 1 )) == NULL ) {
-    LDAP_FREE( o );
-    return( NULL );
-  }
-
-  return( (char *)oo );
-}
-#endif /* NOT_NEEDED_IN_LIBLDAP */     /* mcs@umich.edu 12 Oct 1995 */
-
-#endif /* LDAP_CHARSET_8859 */
-#endif /* STR_TRANSLATION */
index de6208136b3d5f89b6d1c0df4b3b531a6239c800..50839df1fa848831157e0b505c201c0eefe4db57 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
@@ -94,10 +94,20 @@ cldap_open( LDAP_CONST char *host, int port )
     ld->ld_cldapnaddr = 0;
     ld->ld_cldapaddrs = NULL;
 
-    if (ber_pvt_sb_set_io( &(ld->ld_sb), &ber_pvt_sb_io_udp, NULL )<0) {
+    if ( ber_sockbuf_add_io( ld->ld_sb, &ber_sockbuf_io_udp,
+           LBER_SBIOD_LEVEL_PROVIDER, (void *)&s ) < 0 ) {
        ldap_ld_free(ld, 1, NULL, NULL );
+       tcp_close( s );
        return NULL;
     }
+    if ( ber_sockbuf_add_io( ld->ld_sb, &ber_sockbuf_io_readahead,
+           LBER_SBIOD_LEVEL_PROVIDER, NULL ) < 0 ) {
+       ldap_ld_free( ld, 1, NULL, NULL );
+       return NULL;
+    }
+#ifdef LDAP_DEBUG
+    ber_sockbuf_add_io( ld->ld_sb, &ber_sockbuf_io_debug, INT_MAX, NULL );
+#endif
        
     ld->ld_version = LDAP_VERSION2;
 
@@ -129,9 +139,9 @@ cldap_open( LDAP_CONST char *host, int port )
                }
 
                for ( i = 0; hp->h_addr_list[ i ] != 0; ++i ) {
-                   SAFEMEMCPY( (char *)&sock.sin_addr.s_addr,
+                   SAFEMEMCPY( (char *)&sock.sin_addr,
                            (char *)hp->h_addr_list[ i ],
-                           sizeof(sock.sin_addr.s_addr));
+                           sizeof(sock.sin_addr));
                    if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) {
                        ldap_ld_free( ld, 1, NULL, NULL );
                        LDAP_FREE( host_dup );
@@ -162,13 +172,14 @@ cldap_open( LDAP_CONST char *host, int port )
     }
 
     if ( ld->ld_cldapaddrs == NULL
-           || ( ld->ld_defconn = ldap_new_connection( ld, NULL, 1,0,0 )) == NULL
+           || ( ld->ld_defconn = ldap_new_connection( ld, NULL, 1,0,NULL )) == NULL
            ) {
        ldap_ld_free( ld, 0, NULL, NULL );
        DO_RETURN( NULL );
     }
 
-    ber_pvt_sb_udp_set_dst( &ld->ld_sb, ld->ld_cldapaddrs[0] );
+    ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_UDP_SET_DST,
+       ld->ld_cldapaddrs[0] );
 
     cldap_setretryinfo( ld, 0, 0 );
 
@@ -216,7 +227,7 @@ cldap_search_s( LDAP *ld,
 
     *res = NULL;
 
-    (void) memset( &cri, 0, sizeof( cri ));
+    (void) memset( &cri, '\0', sizeof( cri ));
 
     if ( logdn != NULL ) {
        ld->ld_cldapdn = logdn;
@@ -229,8 +240,8 @@ cldap_search_s( LDAP *ld,
                --ld->ld_msgid; /* use same id as before */
        }
            
-       ber_pvt_sb_udp_set_dst( &(ld->ld_sb), 
-                       ld->ld_cldapaddrs[ cri.cri_useaddr ] );
+       ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_UDP_SET_DST,
+           (void *)ld->ld_cldapaddrs[cri.cri_useaddr] );
 
        Debug( LDAP_DEBUG_TRACE, "cldap_search_s try %d (to %s)\n",
            cri.cri_try, inet_ntoa( ((struct sockaddr_in *)
@@ -287,7 +298,6 @@ static int
 cldap_result( LDAP *ld, int msgid, LDAPMessage **res,
        struct cldap_retinfo *crip, const char *base )
 {
-    Sockbuf            *sb = &ld->ld_sb;
     BerElement         ber;
     char               *logdn;
     int                        ret, fromaddr, i;
@@ -365,7 +375,7 @@ cldap_result( LDAP *ld, int msgid, LDAPMessage **res,
             * got a result: determine which server it came from
             * decode into ldap message chain
             */
-           src = (struct sockaddr_in *) ber_pvt_sb_udp_get_src( sb );
+           ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_UDP_GET_SRC, (void *)&src );
                
            for ( fromaddr = 0; fromaddr < ld->ld_cldapnaddr; ++fromaddr ) {
                    if ( memcmp( &((struct sockaddr_in *)
@@ -401,7 +411,8 @@ cldap_result( LDAP *ld, int msgid, LDAPMessage **res,
            if ( i == fromaddr ) {
                continue;
            }
-           ber_pvt_sb_udp_set_dst( sb, ld->ld_cldapaddrs[i] );
+           ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_UDP_SET_DST,
+               (void *)ld->ld_cldapaddrs[i] );
 
            Debug( LDAP_DEBUG_TRACE, "cldap_result abandoning id %d (to %s)\n",
                msgid, inet_ntoa( ((struct sockaddr_in *)
index e7ddcc70aac449274a05c298b224a0d1595cf632..9cfa56963a09172a59e83db618d23024aec5d74c 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
@@ -68,7 +68,7 @@ ldap_compare_ext(
 
        if ( ber_printf( ber, "{it{s{sO}}", /* '}' */
                ++ld->ld_msgid,
-               LDAP_REQ_COMPARE, dn, attr, &bvalue ) == -1 )
+               LDAP_REQ_COMPARE, dn, attr, bvalue ) == -1 )
        {
                ld->ld_errno = LDAP_ENCODING_ERROR;
                ber_free( ber, 1 );
index cc07664c90681f2e62808926cc96ea9c56cd1180..34f49f534326f6324d972416e779d653189e33b3 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -151,7 +151,7 @@ int ldap_int_get_controls(
                return LDAP_NO_MEMORY;
        }
 
-       ctrls[nctrls] = NULL;
+       *ctrls[nctrls] = NULL;
 
        for( tag = ber_first_element( ber, &len, &opaque );
                tag != LBER_ERROR;
@@ -226,7 +226,9 @@ int ldap_int_get_controls(
 void
 ldap_control_free( LDAPControl *c )
 {
+#ifdef LDAP_MEMORY_DEBUG
        assert( c != NULL );
+#endif
 
        if ( c != NULL ) {
                if( c->ldctl_oid != NULL) {
@@ -247,7 +249,9 @@ ldap_control_free( LDAPControl *c )
 void
 ldap_controls_free( LDAPControl **controls )
 {
+#ifdef LDAP_MEMORY_DEBUG
        assert( controls != NULL );
+#endif
 
        if ( controls != NULL ) {
                int i;
@@ -357,3 +361,81 @@ ldap_control_dup( const LDAPControl *c )
        new->ldctl_iscritical = c->ldctl_iscritical;
        return new;
 }
+
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/* Adapted for inclusion into OpenLDAP by Kurt D. Zeilenga */
+/*---
+ * This notice applies to changes, created by or for Novell, Inc.,
+ * to preexisting works for which notices appear elsewhere in this file.
+ *
+ * Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
+ *
+ * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.
+ * USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO VERSION
+ * 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS AVAILABLE AT
+ * HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE" IN THE
+ * TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION OF THIS
+ * WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP PUBLIC
+ * LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT THE
+ * PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY. 
+ *---
+ * Modification to OpenLDAP source by Novell, Inc.
+ * June 2000 sfs  Added control utilities
+ */
+/*---
+   ldap_int_create_control
+   
+   Internal function to create an LDAP control from the encoded BerElement.
+
+   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.
+---*/
+
+LIBLDAP_F( int )
+ldap_int_create_control(
+       const char *requestOID,
+       BerElement *ber,
+       int iscritical,
+       LDAPControl **ctrlp )
+{
+       LDAPControl *ctrl;
+       struct berval *bvalp;
+
+       if ( requestOID == NULL || ber == NULL || ctrlp == NULL ) {
+               return LDAP_PARAM_ERROR;
+       }
+
+       if ( ber_flatten( ber, &bvalp ) == LBER_ERROR ) {
+               return LDAP_NO_MEMORY;
+       }
+
+       ctrl = (LDAPControl *) LBER_MALLOC( sizeof(LDAPControl) );
+       if ( ctrl == NULL ) {
+               ber_bvfree( bvalp );
+               return LDAP_NO_MEMORY;
+       }
+
+       ctrl->ldctl_value = *bvalp;
+       LDAP_FREE( bvalp );
+
+       ctrl->ldctl_oid = LDAP_STRDUP( requestOID );
+       ctrl->ldctl_iscritical = iscritical;
+
+       if ( ctrl->ldctl_oid == NULL ) {
+               LBER_FREE( ctrl );
+               return LDAP_NO_MEMORY;
+       }
+
+       *ctrlp = ctrl;
+       return LDAP_SUCCESS;
+}
index 6d463e17f6ef8c540e909609502cc6e71711d896..e750ecb9d8f143a69d42cd1975ce8e1dd26dfd3f 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
diff --git a/libraries/libldap/digest.c b/libraries/libldap/digest.c
deleted file mode 100644 (file)
index 69aa80c..0000000
+++ /dev/null
@@ -1,382 +0,0 @@
-/* $OpenLDAP$ */
-/*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
- */
-/* digest.c:
- *     DIGEST-MD5 routines
- */
-
-#include "portable.h"
-
-#ifdef DIGEST_MD5
-
-#include <ac/ctype.h>
-#include <ac/string.h>
-#include <ac/time.h>
-
-#include "ldap-int.h"
-#include "ldap_pvt.h"
-
-#define TK_NOENDQUOTE  -2
-#define TK_OUTOFMEM    -1
-
-#define TK_EOS         0
-#define TK_UNEXPCHAR   1
-#define TK_BAREWORD    2
-#define        TK_COMMA        3
-#define        TK_EQUALS       4
-#define TK_QDSTRING    5
-
-struct token {
-       int type;
-       char *sval;
-};
-
-static int
-get_token(const char ** sp, char ** token_val)
-{
-       int kind;
-       const char * p;
-       const char * q;
-       char * res;
-
-       *token_val = NULL;
-
-       if( (**sp) != '\0' || iscntrl(**sp) || !isascii(**sp) ) {
-               (*sp)++;
-               return TK_UNEXPCHAR;
-       }
-
-       switch (**sp) {
-       case '\0':
-               kind = TK_EOS;
-               (*sp)++;
-               break;
-
-       case ',':
-               kind = TK_COMMA;
-               (*sp)++;
-               break;
-
-       case '=':
-               kind = TK_EQUALS;
-               (*sp)++;
-               break;
-
-       case '\"':
-               kind = TK_QDSTRING;
-               (*sp)++;
-               
-               for (p = *sp;
-                       **sp != '\"' && **sp != '\0' && isascii(**sp);
-                       (*sp)++ )
-               {
-                       if(**sp == '\\') {
-                               (*sp)++;
-                               if( **sp == '\0' ) break;
-                       }
-               }
-
-               if ( **sp == '\"' ) {
-                       q = *sp;
-                       res = LDAP_MALLOC(q-p+1);
-                       if ( !res ) {
-                               kind = TK_OUTOFMEM;
-                       } else {
-                               strncpy(res,p,q-p);
-                               res[q-p] = '\0';
-                               *token_val = res;
-                       }
-                       (*sp)++;
-
-               } else {
-                       kind = TK_NOENDQUOTE;
-               }
-
-               break;
-
-       default:
-               kind = TK_BAREWORD;
-               p = *sp;
-               while ( isascii(**sp) &&
-                       !iscntrl(**sp) &&
-                       !isspace(**sp) && 
-                       **sp != '(' &&
-                       **sp != ')' &&
-                       **sp != '<' &&
-                       **sp != '>' &&
-                       **sp != '@' &&
-                       **sp != ',' &&
-                       **sp != ';' &&
-                       **sp != ':' &&
-                       **sp != '\\'&&
-                       **sp != '\"'&&
-                       **sp != '/' &&
-                       **sp != '[' &&
-                       **sp != ']' &&
-                       **sp != '?' &&
-                       **sp != '=' &&
-                       **sp != '{' &&
-                       **sp != '}' &&
-                       **sp != '\0' )
-                       (*sp)++;
-               q = *sp;
-               res = LDAP_MALLOC(q-p+1);
-               if ( !res ) {
-                       kind = TK_OUTOFMEM;
-               } else {
-                       strncpy(res,p,q-p);
-                       res[q-p] = '\0';
-                       *token_val = res;
-               }
-       }
-       
-       return kind;
-}
-
-struct kv {
-       char *key;
-       char *value;
-};
-
-static void kv_destory( struct kv **kv )
-{
-       int i;
-
-       if( kv == NULL ) return;
-
-       for( i=0; kv[i] != NULL; i++ ) {
-               if( kv[i]->key != NULL ) {
-                       LDAP_FREE( kv[i]->key );
-               }
-
-               if( kv[i]->value != NULL ) {
-                       LDAP_FREE( kv[i]->value );
-               }
-
-               LDAP_FREE( kv[i] );
-       }
-
-       LDAP_FREE( kv );
-}
-
-static int kv_add( struct kv ***kvs, const struct kv *kv )
-{
-       int n;
-       struct kv **tmp_kvs;
-       struct kv *tmp_kv;
-
-       assert( kvs != NULL );
-       assert( kv != NULL );
-
-       tmp_kv = LDAP_MALLOC( sizeof(struct kv) );
-
-       if( tmp_kv == NULL ) {
-               return -1;
-       }
-
-       *tmp_kv = *kv;
-
-       if( *kvs == NULL ) {
-               tmp_kvs = LDAP_MALLOC( 2 * sizeof(struct kv *) );
-               n = 0;
-
-       } else {
-               for( n=0; (*kvs)[n] != NULL; n++ ) {
-                       /* EMPTY */ ;
-               }
-
-               tmp_kvs = LDAP_REALLOC( kvs, (n+2) * sizeof(struct kv *) );
-       }
-
-       if( tmp_kvs == NULL ) {
-               LDAP_FREE( tmp_kv );
-               return -1;
-       }
-
-       *kvs = tmp_kvs;
-       kvs[n] = tmp_kvs;
-       kvs[n+1] = NULL;
-
-       return 0;
-}
-
-#define ST_ERROR -1
-#define ST_DONE 0
-#define ST_KEY 1
-#define ST_EQUALS 2
-#define ST_VALUE 3
-#define ST_SEP 4
-
-static int
-parse_key_value(
-       struct kv ***kvsp,
-       const char *str )
-{
-       int rc = 0;
-       int kind, state;
-       const char *ss = str;
-       char *sval;
-
-       struct kv **kvs = NULL;
-       struct kv kv;
-
-       assert( kvsp != NULL );
-       assert( str != NULL );
-
-       kv.key = NULL;
-       kv.value = NULL;
-
-       state = ST_KEY;
-
-       while( state > ST_DONE ) {
-               kind = get_token( &ss, &sval );
-               switch( kind ) {
-               case TK_EOS:
-                       state = ( state == ST_SEP )
-                               ? ST_DONE : ST_ERROR;
-                       break;
-
-               case TK_BAREWORD:
-                       if( state == ST_KEY ) {
-                               state = ST_EQUALS;
-
-                               assert( kv.key == NULL );
-                               assert( kv.value == NULL );
-                               kv.key = sval;
-
-                       } else if ( state == ST_VALUE ) {
-                               state = ST_SEP;
-
-                               assert( kv.key != NULL );
-                               assert( kv.value == NULL );
-                               kv.value = sval;
-
-                       } else {
-                               state = ST_ERROR;
-                       }
-                       break;
-
-               case TK_COMMA:
-                       state = ( state == ST_SEP )
-                               ? ST_KEY : ST_ERROR;
-                       break;
-
-               case TK_EQUALS:
-                       state = ( state == ST_EQUALS )
-                               ? ST_VALUE : ST_ERROR;
-                       break;
-
-               case TK_QDSTRING:
-                       if( state == ST_VALUE ) {
-                               state = ST_SEP;
-
-                               assert( kv.key != NULL );
-                               assert( kv.value == NULL );
-                               kv.value = sval;
-
-                       } else {
-                               state = ST_ERROR;
-                       }
-                       break;
-
-               default:
-                       state = ST_ERROR;
-               }
-
-               if( state == ST_SEP ) {
-                       /* add kv to return */
-                       if( kv_add( &kvs, &kv ) != 0 ) {
-                               state = ST_ERROR;
-                               kind = TK_OUTOFMEM;
-
-                       } else {
-                               kv.key = NULL;
-                               kv.value = NULL;
-                       }
-               }
-       }
-
-       if( state == ST_ERROR ) {
-               if( kv.key != NULL ) LDAP_FREE(kv.key);
-               if( kv.value != NULL ) LDAP_FREE( kv.value );
-
-               kv_destory( kvs );
-               kvs = NULL;
-
-               rc = ( kind == TK_OUTOFMEM ) ? -1 : 1 ;
-       }
-
-       *kvsp = kvs;
-       return rc;
-}
-
-static int
-parse_value_list(
-       char ***valuesp,
-       const char* str )
-{
-       int rc = 0;
-       char **values = NULL;
-
-       int kind, state;
-       const char *ss = str;
-       char *sval;
-
-       assert( valuesp != NULL );
-       assert( str != NULL );
-
-       state = ST_VALUE;
-
-       while( state > ST_DONE ) {
-               kind = get_token( &ss, &sval );
-               switch( kind ) {
-               case TK_EOS:
-                       state = ( state == ST_SEP )
-                               ? ST_DONE : ST_ERROR;
-                       break;
-
-               case TK_BAREWORD:
-                       if( state == ST_VALUE ) {
-                               state = ST_SEP;
-
-                       } else {
-                               state = ST_ERROR;
-                       }
-                       break;
-
-               case TK_COMMA:
-                       state = ( state == ST_SEP )
-                               ? ST_VALUE : ST_ERROR;
-                       break;
-
-               default:
-                       state = ST_ERROR;
-               }
-
-               if( state == ST_SEP ) {
-                       if( ldap_charray_add( &values, sval ) != 0 ) {
-                               state = ST_ERROR;
-                               kind = TK_OUTOFMEM;
-                       }
-
-                       LDAP_FREE( sval );
-                       sval = NULL;
-               }
-       }
-
-       if( state == ST_ERROR ) {
-               if( sval != NULL ) LDAP_FREE( sval );
-
-               LDAP_VFREE( values );
-               values = NULL;
-
-               rc = ( kind == TK_OUTOFMEM ) ? -1 : 1 ;
-       }
-
-       *valuesp = values;
-       return rc;
-}
-
-#endif
index 40c2b7734337a160d659089fc0d1fd1e1103f268..82dcfe8f3d9a8303fefda3834b6ce562d01313a5 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
@@ -149,13 +149,13 @@ ldap_init_templates_buf( char *buf, ber_len_t buflen,
 
     *tmpllistp = prevtmpl = NULL;
 
-    if ( next_line_tokens( &buf, &buflen, &toks ) != 2 ||
+    if ( ldap_int_next_line_tokens( &buf, &buflen, &toks ) != 2 ||
            strcasecmp( toks[ 0 ], "version" ) != 0 ) {
-       free_strarray( toks );
+       LDAP_VFREE( toks );
        return( LDAP_TMPL_ERR_SYNTAX );
     }
     version = atoi( toks[ 1 ] );
-    free_strarray( toks );
+    LDAP_VFREE( toks );
     if ( version != LDAP_TEMPLATE_VERSION ) {
        return( LDAP_TMPL_ERR_VERSION );
     }
@@ -226,7 +226,7 @@ free_disptmpl( struct ldap_disptmpl *tmpl )
 
            for ( ocp = tmpl->dt_oclist; ocp != NULL; ocp = nextocp ) {
                nextocp = ocp->oc_next;
-               free_strarray( ocp->oc_objclasses );
+               LDAP_VFREE( ocp->oc_objclasses );
                LDAP_FREE( ocp );
            }
        }
@@ -260,7 +260,7 @@ free_disptmpl( struct ldap_disptmpl *tmpl )
                        LDAP_FREE( colp->ti_label );
                    }
                    if ( colp->ti_args != NULL ) {
-                       free_strarray( colp->ti_args );
+                       LDAP_VFREE( colp->ti_args );
                    }
                    LDAP_FREE( colp );
                }
@@ -457,14 +457,14 @@ read_next_tmpl( char **bufp, ber_len_t *blenp, struct ldap_disptmpl **tmplp,
     /*
      * template name comes first
      */
-    if (( tokcnt = next_line_tokens( bufp, blenp, &toks )) != 1 ) {
-       free_strarray( toks );
+    if (( tokcnt = ldap_int_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
+       LDAP_VFREE( toks );
        return( tokcnt == 0 ? 0 : LDAP_TMPL_ERR_SYNTAX );
     }
 
     if (( tmpl = (struct ldap_disptmpl *)LDAP_CALLOC( 1,
            sizeof( struct ldap_disptmpl ))) == NULL ) {
-       free_strarray( toks );
+       LDAP_VFREE( toks );
        return(  LDAP_TMPL_ERR_MEM );
     }
     tmpl->dt_name = toks[ 0 ];
@@ -473,8 +473,8 @@ read_next_tmpl( char **bufp, ber_len_t *blenp, struct ldap_disptmpl **tmplp,
     /*
      * template plural name comes next
      */
-    if (( tokcnt = next_line_tokens( bufp, blenp, &toks )) != 1 ) {
-       free_strarray( toks );
+    if (( tokcnt = ldap_int_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
+       LDAP_VFREE( toks );
        free_disptmpl( tmpl );
        return( LDAP_TMPL_ERR_SYNTAX );
     }
@@ -484,8 +484,8 @@ read_next_tmpl( char **bufp, ber_len_t *blenp, struct ldap_disptmpl **tmplp,
     /*
      * template icon name is next
      */
-    if (( tokcnt = next_line_tokens( bufp, blenp, &toks )) != 1 ) {
-       free_strarray( toks );
+    if (( tokcnt = ldap_int_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
+       LDAP_VFREE( toks );
        free_disptmpl( tmpl );
        return( LDAP_TMPL_ERR_SYNTAX );
     }
@@ -495,8 +495,8 @@ read_next_tmpl( char **bufp, ber_len_t *blenp, struct ldap_disptmpl **tmplp,
     /*
      * template options come next
      */
-    if (( tokcnt = next_line_tokens( bufp, blenp, &toks )) < 1 ) {
-       free_strarray( toks );
+    if (( tokcnt = ldap_int_next_line_tokens( bufp, blenp, &toks )) < 1 ) {
+       LDAP_VFREE( toks );
        free_disptmpl( tmpl );
        return( LDAP_TMPL_ERR_SYNTAX );
     }
@@ -507,15 +507,15 @@ read_next_tmpl( char **bufp, ber_len_t *blenp, struct ldap_disptmpl **tmplp,
            }
        }
     }
-    free_strarray( toks );
+    LDAP_VFREE( toks );
 
     /*
      * object class list is next
      */
-    while (( tokcnt = next_line_tokens( bufp, blenp, &toks )) > 0 ) {
+    while (( tokcnt = ldap_int_next_line_tokens( bufp, blenp, &toks )) > 0 ) {
        if (( ocp = (struct ldap_oclist *)LDAP_CALLOC( 1,
                sizeof( struct ldap_oclist ))) == NULL ) {
-           free_strarray( toks );
+           LDAP_VFREE( toks );
            free_disptmpl( tmpl );
            return( LDAP_TMPL_ERR_MEM );
        }
@@ -535,8 +535,8 @@ read_next_tmpl( char **bufp, ber_len_t *blenp, struct ldap_disptmpl **tmplp,
     /*
      * read name of attribute to authenticate as
      */
-    if (( tokcnt = next_line_tokens( bufp, blenp, &toks )) != 1 ) {
-       free_strarray( toks );
+    if (( tokcnt = ldap_int_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
+       LDAP_VFREE( toks );
        free_disptmpl( tmpl );
        return( LDAP_TMPL_ERR_SYNTAX );
     }
@@ -550,8 +550,8 @@ read_next_tmpl( char **bufp, ber_len_t *blenp, struct ldap_disptmpl **tmplp,
     /*
      * read default attribute to use for RDN
      */
-    if (( tokcnt = next_line_tokens( bufp, blenp, &toks )) != 1 ) {
-       free_strarray( toks );
+    if (( tokcnt = ldap_int_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
+       LDAP_VFREE( toks );
        free_disptmpl( tmpl );
        return( LDAP_TMPL_ERR_SYNTAX );
     }
@@ -561,8 +561,8 @@ read_next_tmpl( char **bufp, ber_len_t *blenp, struct ldap_disptmpl **tmplp,
     /*
      * read default location for new entries
      */
-    if (( tokcnt = next_line_tokens( bufp, blenp, &toks )) != 1 ) {
-       free_strarray( toks );
+    if (( tokcnt = ldap_int_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
+       LDAP_VFREE( toks );
        free_disptmpl( tmpl );
        return( LDAP_TMPL_ERR_SYNTAX );
     }
@@ -576,7 +576,7 @@ read_next_tmpl( char **bufp, ber_len_t *blenp, struct ldap_disptmpl **tmplp,
     /*
      * read list of rules used to define default values for new entries
      */
-    while (( tokcnt = next_line_tokens( bufp, blenp, &toks )) > 0 ) {
+    while (( tokcnt = ldap_int_next_line_tokens( bufp, blenp, &toks )) > 0 ) {
        if ( strcasecmp( ADDEF_CONSTANT, toks[ 0 ] ) == 0 ) {
            adsource = LDAP_ADSRC_CONSTANTVALUE;
        } else if ( strcasecmp( ADDEF_ADDERSDN, toks[ 0 ] ) == 0 ) {
@@ -587,14 +587,14 @@ read_next_tmpl( char **bufp, ber_len_t *blenp, struct ldap_disptmpl **tmplp,
        if ( adsource == 0 || tokcnt < 2 ||
                ( adsource == LDAP_ADSRC_CONSTANTVALUE && tokcnt != 3 ) ||
                ( adsource == LDAP_ADSRC_ADDERSDN && tokcnt != 2 )) {
-           free_strarray( toks );
+           LDAP_VFREE( toks );
            free_disptmpl( tmpl );
            return( LDAP_TMPL_ERR_SYNTAX );
        }
                
        if (( adp = (struct ldap_adddeflist *)LDAP_CALLOC( 1,
                sizeof( struct ldap_adddeflist ))) == NULL ) {
-           free_strarray( toks );
+           LDAP_VFREE( toks );
            free_disptmpl( tmpl );
            return( LDAP_TMPL_ERR_MEM );
        }
@@ -618,17 +618,17 @@ read_next_tmpl( char **bufp, ber_len_t *blenp, struct ldap_disptmpl **tmplp,
      * item list is next
      */
     samerow = 0;
-    while (( tokcnt = next_line_tokens( bufp, blenp, &toks )) > 0 ) {
+    while (( tokcnt = ldap_int_next_line_tokens( bufp, blenp, &toks )) > 0 ) {
        if ( strcasecmp( toks[ 0 ], "item" ) == 0 ) {
            if ( tokcnt < 4 ) {
-               free_strarray( toks );
+               LDAP_VFREE( toks );
                free_disptmpl( tmpl );
                return( LDAP_TMPL_ERR_SYNTAX );
            }
 
            if (( ip = (struct ldap_tmplitem *)LDAP_CALLOC( 1,
                    sizeof( struct ldap_tmplitem ))) == NULL ) {
-               free_strarray( toks );
+               LDAP_VFREE( toks );
                free_disptmpl( tmpl );
                return( LDAP_TMPL_ERR_MEM );
            }
@@ -644,7 +644,7 @@ read_next_tmpl( char **bufp, ber_len_t *blenp, struct ldap_disptmpl **tmplp,
                    }
                }
                if ( itemoptions[ i ] == NULL ) {
-                   free_strarray( toks );
+                   LDAP_VFREE( toks );
                    free_disptmpl( tmpl );
                    return( LDAP_TMPL_ERR_SYNTAX );
                }
@@ -657,7 +657,7 @@ read_next_tmpl( char **bufp, ber_len_t *blenp, struct ldap_disptmpl **tmplp,
                }
            }
            if ( itemtypes[ i ] == NULL ) {
-               free_strarray( toks );
+               LDAP_VFREE( toks );
                free_disptmpl( tmpl );
                return( LDAP_TMPL_ERR_SYNTAX );
            }
@@ -698,10 +698,10 @@ read_next_tmpl( char **bufp, ber_len_t *blenp, struct ldap_disptmpl **tmplp,
            previp = ip;
            samerow = 0;
        } else if ( strcasecmp( toks[ 0 ], "samerow" ) == 0 ) {
-           free_strarray( toks );
+           LDAP_VFREE( toks );
            samerow = 1;
        } else {
-           free_strarray( toks );
+           LDAP_VFREE( toks );
            free_disptmpl( tmpl );
            return( LDAP_TMPL_ERR_SYNTAX );
        }
index fc1c6ead88df0b2702f6cae2d12be5cc36ca13aa..d0ba92f886f5752d06d12fcb594465b0412ccd3a 100644 (file)
@@ -1,7 +1,7 @@
 /* dn.c - routines for dealing with distinguished names */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -217,25 +217,7 @@ ldap_dn_parent(
        }
 
        /*
-        * no =, assume it is a dns name, like blah@some.domain.name
-        * if the blah@ part is there, return some.domain.name.  if
-        * it's just some.domain.name, return domain.name.
-        */
-       if ( strchr( dn, '=' ) == NULL ) {
-               if ( (s = strchr( dn, '@' )) == NULL ) {
-                       if ( (s = strchr( dn, '.' )) == NULL ) {
-                               return( NULL );
-                       }
-               }
-               if ( *(s + 1) == '\0' ) {
-                       return( NULL );
-               } else {
-                       return( LDAP_STRDUP( &s[1] ) );
-               }
-       }
-
-       /*
-        * else assume it is an X.500-style name, which looks like
+        * assume it is an X.500-style name, which looks like
         * foo=bar,sha=baz,...
         */
 
@@ -288,25 +270,8 @@ char * ldap_dn_rdn(
                return NULL;
        }
 
-#ifdef DNS_DN
-       /*
-        * no =, assume it is a dns name, like blah@some.domain.name
-        * if the blah@ part is there, return some.domain.name.  if
-        * it's just some.domain.name, return domain.name.
-        */
-       if ( strchr( rdn, '=' ) == NULL ) {
-               if ( (s = strchr( rdn, '@' )) == NULL ) {
-                       if ( (s = strchr( rdn, '.' )) == NULL ) {
-                               return( rdn );
-                       }
-               }
-               *s = '\0';
-               return( rdn );
-       }
-#endif
-
        /*
-        * else assume it is an X.500-style name, which looks like
+        * assume it is an X.500-style name, which looks like
         * foo=bar,sha=baz,...
         */
 
diff --git a/libraries/libldap/dnssrv.c b/libraries/libldap/dnssrv.c
new file mode 100644 (file)
index 0000000..ae96301
--- /dev/null
@@ -0,0 +1,307 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+/*
+ * locate LDAP servers using DNS SRV records.
+ * Location code based on MIT Kerberos KDC location code.
+ */
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/stdlib.h>
+
+#include <ac/param.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/time.h>
+
+#include "ldap-int.h"
+
+#ifdef HAVE_ARPA_NAMESER_H
+#include <arpa/nameser.h>
+#endif
+#ifdef HAVE_RESOLV_H
+#include <resolv.h>
+#endif
+
+/* Sometimes this is not defined. */
+#ifndef T_SRV
+#define T_SRV            33
+#endif                         /* T_SRV */
+
+int ldap_dn2domain(
+       LDAP_CONST char *dn_in,
+       char **domainp)
+{
+       int i;
+       char *domain = NULL;
+       char **dn;
+
+       if( dn_in == NULL || domainp == NULL ) {
+               return -1;
+       }
+
+       dn = ldap_explode_dn( dn_in, 0 );
+
+       if( dn == NULL ) {
+               return -2;
+       }
+
+       for( i=0; dn[i] != NULL; i++ ) {
+               char ** rdn = ldap_explode_rdn( dn[i], 0 );
+
+               if( rdn == NULL || *rdn == NULL ) {
+                       LDAP_FREE( rdn );
+                       LDAP_FREE( domain );
+                       LDAP_VFREE( dn );
+                       return -3;
+               }
+
+
+               if( rdn[1] == NULL ) {
+                       /*
+                        * single-valued RDN
+                        */
+                       char *dc;
+
+#define LDAP_DC "dc="
+#define LDAP_DCOID "0.9.2342.19200300.100.1.25="
+
+                       if( strncasecmp( rdn[0],
+                               LDAP_DC, sizeof(LDAP_DC)-1 ) == 0 )
+                       {
+                               dc = &rdn[0][sizeof(LDAP_DC)-1];
+
+                       } else if( strncmp( rdn[0],
+                               LDAP_DCOID, sizeof(LDAP_DCOID)-1 ) == 0 )
+                       {
+                               dc = &rdn[0][sizeof(LDAP_DCOID)-1];
+
+                       } else {
+                               dc = NULL;
+                       }
+
+                       if( dc != NULL ) {
+                               char *ndomain;
+
+                               if( *dc == '\0' ) {
+                                       /* dc value is empty! */
+                                       LDAP_FREE( rdn );
+                                       LDAP_FREE( domain );
+                                       LDAP_VFREE( dn );
+                                       LDAP_VFREE( rdn );
+                                       return -4;
+                               }
+
+                               ndomain = LDAP_REALLOC( domain,
+                                       ( domain == NULL ? 0 : strlen(domain) )
+                                       + strlen(dc) + sizeof(".") );
+
+                               if( ndomain == NULL ) {
+                                       LDAP_FREE( rdn );
+                                       LDAP_FREE( domain );
+                                       LDAP_VFREE( dn );
+                                       LDAP_VFREE( rdn );
+                                       return -5;
+                               }
+
+                               if( domain == NULL ) {
+                                       ndomain[0] = '\0';
+                               } else {
+                                       strcat( ndomain, "." );
+                               }
+
+                               strcat( ndomain, dc );
+
+                               domain = ndomain;
+                               continue;
+                       }
+               }
+
+               /*
+                * multi-valued RDN or fall thru
+                */
+
+               LDAP_VFREE( rdn );
+               LDAP_FREE( domain );
+               domain = NULL;
+       } 
+
+       if( domain != NULL &&  *domain == '\0' ) {
+               LDAP_FREE( domain );
+               domain = NULL;
+       }
+
+       *domainp = domain;
+       return 0;
+}
+
+int ldap_domain2dn(
+       LDAP_CONST char *domain_in,
+       char **dnp)
+{
+    char *domain, *s, *tok_r, *dn;
+    size_t loc;
+
+    if (domain_in == NULL || dnp == NULL) {
+       return LDAP_NO_MEMORY;
+    }
+    domain = LDAP_STRDUP(domain_in);
+    if (domain == NULL) {
+       return LDAP_NO_MEMORY;
+    }
+    dn = NULL;
+    loc = 0;
+
+    for (s = ldap_pvt_strtok(domain, ".", &tok_r);
+        s != NULL;
+        s = ldap_pvt_strtok(NULL, ".", &tok_r)) {
+       size_t len = strlen(s);
+
+       dn = (char *) LDAP_REALLOC(dn, loc + sizeof(",dc=") + len );
+       if (dn == NULL) {
+           LDAP_FREE(domain);
+           return LDAP_NO_MEMORY;
+       }
+       if (loc > 0) {
+           /* not first time. */
+           strcpy(dn + loc, ",");
+           loc++;
+       }
+       strcpy(dn + loc, "dc=");
+       loc += sizeof("dc=")-1;
+
+       strcpy(dn + loc, s);
+       loc += len;
+    }
+
+    LDAP_FREE(domain);
+
+    *dnp = dn;
+
+    return LDAP_SUCCESS;
+}
+
+/*
+ * Lookup and return LDAP servers for domain (using the DNS
+ * SRV record _ldap._tcp.domain).
+ */
+int ldap_domain2hostlist(
+       LDAP_CONST char *domain,
+       char **list )
+{
+#ifdef HAVE_RES_QUERY
+    char *request;
+    char *dn;
+    char *hostlist = NULL;
+    int rc, len, cur = 0;
+    unsigned char reply[1024];
+
+       if( domain == NULL || *domain == '\0' ) {
+               return LDAP_PARAM_ERROR;
+       }
+
+       if( list == NULL ) {
+               return LDAP_PARAM_ERROR;
+       }
+
+    request = LDAP_MALLOC(strlen(domain) + sizeof("_ldap._tcp."));
+    if (request == NULL) {
+       rc = LDAP_NO_MEMORY;
+       goto out;
+    }
+    sprintf(request, "_ldap._tcp.%s", domain);
+
+#ifdef LDAP_R_COMPILE
+    ldap_pvt_thread_mutex_lock(&ldap_int_resolv_mutex);
+#endif
+
+    rc = LDAP_UNAVAILABLE;
+    len = res_query(request, C_IN, T_SRV, reply, sizeof(reply));
+    if (len >= 0) {
+       unsigned char *p;
+       char host[1024];
+       int status;
+       u_short port;
+       /* int priority, weight; */
+
+       /* Parse out query */
+       p = reply;
+       p += sizeof(HEADER);
+       status = dn_expand(reply, reply + len, p, host, sizeof(host));
+       if (status < 0) {
+           goto out;
+       }
+       p += status;
+       p += 4;
+
+       while (p < reply + len) {
+           int type, class, ttl, size;
+           status = dn_expand(reply, reply + len, p, host, sizeof(host));
+           if (status < 0) {
+               goto out;
+           }
+           p += status;
+           type = (p[0] << 8) | p[1];
+           p += 2;
+           class = (p[0] << 8) | p[1];
+           p += 2;
+           ttl = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+           p += 4;
+           size = (p[0] << 8) | p[1];
+           p += 2;
+           if (type == T_SRV) {
+               int buflen;
+               status = dn_expand(reply, reply + len, p + 6, host, sizeof(host));
+               if (status < 0) {
+                   goto out;
+               }
+               /* ignore priority and weight for now */
+               /* priority = (p[0] << 8) | p[1]; */
+               /* weight = (p[2] << 8) | p[3]; */
+               port = (p[4] << 8) | p[5];
+
+               buflen = strlen(host) + sizeof(":65355");
+               hostlist = (char *) LDAP_REALLOC(hostlist, cur + buflen);
+               if (hostlist == NULL) {
+                   rc = LDAP_NO_MEMORY;
+                   goto out;
+               }
+               if (cur > 0) {
+                   /* not first time around */
+                   hostlist[cur++] = ' ';
+               }
+               cur += sprintf(&hostlist[cur], "%s:%hd", host, port);
+           }
+           p += size;
+       }
+    }
+    if (hostlist == NULL) {
+       /* No LDAP servers found in DNS. */
+       rc = LDAP_UNAVAILABLE;
+       goto out;
+    }
+
+    rc = LDAP_SUCCESS;
+       *list = hostlist;
+
+  out:
+#ifdef LDAP_R_COMPILE
+    ldap_pvt_thread_mutex_unlock(&ldap_int_resolv_mutex);
+#endif
+
+    if (request != NULL) {
+       LDAP_FREE(request);
+    }
+    if (rc != LDAP_SUCCESS && hostlist != NULL) {
+       LDAP_FREE(hostlist);
+    }
+    return rc;
+#else
+    return LDAP_NOT_SUPPORTED;
+#endif /* HAVE_RES_QUERY */
+}
index 336025db559ded4e89ec37e2353909720434816c..8ec7116fd9f2af43b18bb7d7d116c27cc3742ef0 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
@@ -39,9 +39,8 @@ static int next_line LDAP_P(( char **bufp, ber_len_t *blenp, char **linep ));
 static char *next_token LDAP_P(( char ** sp ));
 
 
-
 int
-next_line_tokens( char **bufp, ber_len_t *blenp, char ***toksp )
+ldap_int_next_line_tokens( char **bufp, ber_len_t *blenp, char ***toksp )
 {
     char       *p, *line, *token, **toks;
     int                rc, tokcnt;
@@ -72,7 +71,7 @@ next_line_tokens( char **bufp, ber_len_t *blenp, char ***toksp )
 
     if ( tokcnt == 1 && strcasecmp( toks[ 0 ], "END" ) == 0 ) {
        tokcnt = 0;
-       free_strarray( toks );
+       LDAP_VFREE( toks );
        toks = NULL;
     }
 
@@ -195,17 +194,3 @@ next_token( char **sp )
 
     return( LDAP_STRDUP( tokstart ));
 }
-
-
-void
-free_strarray( char **sap )
-{
-    int                i;
-
-    if ( sap != NULL ) {
-       for ( i = 0; sap[ i ] != NULL; ++i ) {
-           LBER_FREE( sap[ i ] );
-       }
-       LBER_FREE( (char *)sap );
-    }
-}
index ff15bfe4620da3609bd89dfb66250366d9ea2a03..34cac4600b233b2ca194d62a893c20b14dd45bc1 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -50,7 +50,7 @@ static const struct ldaperror ldap_errlist[] = {
        {LDAP_NO_SUCH_OBJECT,                   "No such object" },
        {LDAP_ALIAS_PROBLEM,                    "Alias problem" },
        {LDAP_INVALID_DN_SYNTAX,                "Invalid DN syntax" },
-       {LDAP_IS_LEAF,                                  "Object is a leaf" },
+       {LDAP_IS_LEAF,                                  "Entry is a leaf" },
        {LDAP_ALIAS_DEREF_PROBLEM,              "Alias dereferencing problem" },
 
        {LDAP_INAPPROPRIATE_AUTH,               "Inappropriate authentication" },
@@ -71,6 +71,8 @@ static const struct ldaperror ldap_errlist[] = {
        {LDAP_AFFECTS_MULTIPLE_DSAS,    "Operation affects multiple DSAs" },
 
        {LDAP_OTHER,                                    "Unknown error" },
+
+       /* API ResultCodes */
        {LDAP_SERVER_DOWN,                              "Can't contact LDAP server" },
        {LDAP_LOCAL_ERROR,                              "Local error" },
        {LDAP_ENCODING_ERROR,                   "Encoding error" },
@@ -160,6 +162,7 @@ ldap_perror( LDAP *ld, LDAP_CONST char *str )
        fflush( stderr );
 }
 
+/* deprecated */
 int
 ldap_result2error( LDAP *ld, LDAPMessage *r, int freeit )
 {
@@ -168,7 +171,7 @@ ldap_result2error( LDAP *ld, LDAPMessage *r, int freeit )
        rc = ldap_parse_result( ld, r, &err,
                NULL, NULL, NULL, NULL, freeit );
 
-       return rc != LDAP_SUCCESS ? err : rc;
+       return err != LDAP_SUCCESS ? err : rc;
 }
 
 /*
@@ -206,9 +209,7 @@ ldap_parse_result(
        int                             freeit )
 {
        LDAPMessage     *lm;
-       ber_int_t errcode;
-       char* matcheddn;
-       char* errmsg;
+       ber_int_t errcode = LDAP_SUCCESS;
 
        int rc;
        ber_tag_t tag;
@@ -224,6 +225,7 @@ ldap_parse_result(
                return LDAP_PARAM_ERROR;
        }
 
+       if(errcodep != NULL) *errcodep = LDAP_SUCCESS;
        if(matcheddnp != NULL) *matcheddnp = NULL;
        if(errmsgp != NULL) *errmsgp = NULL;
        if(referralsp != NULL) *referralsp = NULL;
@@ -244,10 +246,6 @@ ldap_parse_result(
                return ld->ld_errno;
        }
 
-       errcode = LDAP_SUCCESS;
-       matcheddn = NULL;
-       errmsg = NULL;
-
        if ( ld->ld_error ) {
                LDAP_FREE( ld->ld_error );
                ld->ld_error = NULL;
@@ -263,11 +261,11 @@ ldap_parse_result(
 
        if ( ld->ld_version < LDAP_VERSION2 ) {
                tag = ber_scanf( ber, "{ia}",
-                       &errcode, &ld->ld_error );
+                       &ld->ld_errno, &ld->ld_error );
        } else {
                ber_len_t len;
                tag = ber_scanf( ber, "{iaa" /*}*/,
-                       &errcode, &ld->ld_matched, &ld->ld_error );
+                       &ld->ld_errno, &ld->ld_matched, &ld->ld_error );
 
                if( tag != LBER_ERROR ) {
                        /* peek for referrals */
@@ -321,7 +319,7 @@ ldap_parse_result(
        }
 
        if ( tag == LBER_ERROR ) {
-               errcode = LDAP_DECODING_ERROR;
+               ld->ld_errno = errcode = LDAP_DECODING_ERROR;
        }
 
        if( ber != NULL ) {
@@ -329,10 +327,10 @@ ldap_parse_result(
        }
 
        /* return */
+       if( errcodep != NULL ) {
+               *errcodep = ld->ld_errno;
+       }
        if ( errcode == LDAP_SUCCESS ) {
-               if( errcodep != NULL ) {
-                       *errcodep = ld->ld_errno;
-               }
                if( matcheddnp != NULL ) {
                        *matcheddnp = LDAP_STRDUP( ld->ld_matched );
                }
@@ -357,6 +355,5 @@ ldap_parse_result(
                ldap_msgfree( r );
        }
 
-       ld->ld_errno = errcode;
-       return( ld->ld_errno );
+       return( errcode );
 }
index e284b485fdd63e31d3d13dcf7ea911e839cd7aba..f42afd281aaba1e3856b81ac6635ecf346905371 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -181,7 +181,7 @@ ldap_parse_extended_result (
                return ld->ld_errno;
        }
 
-       if( res->lm_msgtype == LDAP_RES_EXTENDED ) {
+       if( res->lm_msgtype != LDAP_RES_EXTENDED ) {
                ld->ld_errno = LDAP_PARAM_ERROR;
                return ld->ld_errno;
        }
@@ -189,8 +189,6 @@ ldap_parse_extended_result (
        if( retoidp != NULL ) *retoidp = NULL;
        if( retdatap != NULL ) *retdatap = NULL;
 
-       ber = ber_dup( res->lm_ber );
-
        if ( ld->ld_error ) {
                LDAP_FREE( ld->ld_error );
                ld->ld_error = NULL;
@@ -201,8 +199,15 @@ ldap_parse_extended_result (
                ld->ld_matched = NULL;
        }
 
+       ber = ber_dup( res->lm_ber );
+
+       if ( ber == NULL ) {
+               ld->ld_errno = LDAP_NO_MEMORY;
+               return ld->ld_errno;
+       }
+
        rc = ber_scanf( ber, "{iaa" /*}*/, &errcode,
-               &ld->ld_matched, &ld->ld_matched );
+               &ld->ld_matched, &ld->ld_error );
 
        if( rc == LBER_ERROR ) {
                ld->ld_errno = LDAP_DECODING_ERROR;
@@ -217,11 +222,13 @@ ldap_parse_extended_result (
 
        if( tag == LDAP_TAG_REFERRAL ) {
                /* skip over referral */
-               tag = ber_scanf( ber, "x" );
-
-               if( tag != LBER_ERROR ) {
-                       tag = ber_peek_tag( ber, &len );
+               if( ber_scanf( ber, "x" ) == LBER_ERROR ) {
+                       ld->ld_errno = LDAP_DECODING_ERROR;
+                       ber_free( ber, 0 );
+                       return ld->ld_errno;
                }
+
+               tag = ber_peek_tag( ber, &len );
        }
 
        if( tag == LDAP_TAG_EXOP_RES_OID ) {
@@ -237,7 +244,7 @@ ldap_parse_extended_result (
 
        if( tag == LDAP_TAG_EXOP_RES_VALUE ) {
                /* we have a resdata */
-               if( ber_scanf( ber, "O", &resoid ) == LBER_ERROR ) {
+               if( ber_scanf( ber, "O", &resdata ) == LBER_ERROR ) {
                        ld->ld_errno = LDAP_DECODING_ERROR;
                        ber_free( ber, 0 );
                        if( resoid != NULL ) LDAP_FREE( resoid );
@@ -245,6 +252,8 @@ ldap_parse_extended_result (
                }
        }
 
+       ber_free( ber, 0 );
+
        if( retoidp != NULL ) {
                *retoidp = resoid;
        } else {
index 120e1605b0cf5fa7e54f90eb070ec7e590ade7e8..e20ffbd24dbaa30ed0027936656aad9aa1599bb2 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
index ec37982a70b27393d3b424ee481d843452822e12..3078fee69335b0f69063480bc5d9d1995db871ef 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
index 079db4b9f3beddc2ac6fa22a23201e00e8fb2124..9a511ee2eae23d2571b4ede57c0d55268e44edca 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
index 0110e298e719649340db1af1513c6c3e8072fc37..0d8b488e19ac18c35e24fba7a0161fb22cd04322 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
 
 #include "ldap-int.h"
 
-static char **explode_name( const char *name, int notypes, int is_dn );
+#define NAME_TYPE_LDAP_RDN     0
+#define NAME_TYPE_LDAP_DN      1
+#define NAME_TYPE_DCE_DN       2
+
+static char **explode_name( const char *name, int notypes, int is_type );
 
 char *
 ldap_get_dn( LDAP *ld, LDAPMessage *entry )
@@ -59,28 +63,26 @@ ldap_dn2ufn( LDAP_CONST char *dn )
                return NULL;
        }
 
-       if ( ldap_is_dns_dn( dn ) ||
-               ( p = strchr( dn, '=' ) ) == NULL )
-       {
+       if ( ( p = ldap_utf8_strpbrk( dn, "=" ) ) == NULL ) {
                return( LDAP_STRDUP( dn ) );
        }
-
-
        ufn = LDAP_STRDUP( ++p );
 
+       if( ufn == NULL ) return NULL;
+
 #define INQUOTE                1
 #define OUTQUOTE       2
        state = OUTQUOTE;
-       for ( p = ufn, r = ufn; *p; p++ ) {
+       for ( p = ufn, r = ufn; *p; LDAP_UTF8_INCR(p) ) {
                switch ( *p ) {
                case '\\':
-                       if ( *++p == '\0' )
-                               p--;
-                       else {
+                       if ( p[1] != '\0' ) {
                                *r++ = '\\';
-                               *r++ = *p;
+                               LDAP_UTF8_COPY(r,++p);
+                               LDAP_UTF8_INCR(r);
                        }
                        break;
+
                case '"':
                        if ( state == INQUOTE )
                                state = OUTQUOTE;
@@ -88,6 +90,7 @@ ldap_dn2ufn( LDAP_CONST char *dn )
                                state = INQUOTE;
                        *r++ = *p;
                        break;
+
                case ';':
                case ',':
                        if ( state == OUTQUOTE )
@@ -95,17 +98,22 @@ ldap_dn2ufn( LDAP_CONST char *dn )
                        else
                                *r++ = *p;
                        break;
+
                case '=':
-                       if ( state == INQUOTE )
+                       if ( state == INQUOTE ) {
                                *r++ = *p;
-                       else {
+                       else {
                                char    *rsave = r;
 
-                               *r-- = '\0';
-                               while ( !isspace( (unsigned char) *r )
+                               *r = '\0';
+                               LDAP_UTF8_DECR( r );
+
+                               while ( !ldap_utf8_isspace( r )
                                        && *r != ';' && *r != ',' && r > ufn )
-                                       r--;
-                               r++;
+                               {
+                                       LDAP_UTF8_DECR( r );
+                               }
+                               LDAP_UTF8_INCR( r );
 
                                if ( strcasecmp( r, "c" )
                                    && strcasecmp( r, "o" )
@@ -118,8 +126,10 @@ ldap_dn2ufn( LDAP_CONST char *dn )
                                }
                        }
                        break;
+
                default:
-                       *r++ = *p;
+                       LDAP_UTF8_COPY(r, p);
+                       LDAP_UTF8_INCR(r);
                        break;
                }
        }
@@ -129,84 +139,134 @@ ldap_dn2ufn( LDAP_CONST char *dn )
 }
 
 char **
-ldap_explode_dns( LDAP_CONST char *dn_in )
+ldap_explode_dn( LDAP_CONST char *dn, int notypes )
 {
-       char    *s;
-       char    **rdns;
-       char    *tok_r;
-       char    *dn;
+       Debug( LDAP_DEBUG_TRACE, "ldap_explode_dn\n", 0, 0, 0 );
 
-       int ncomps;
-       int maxcomps = 8;
+       return explode_name( dn, notypes, NAME_TYPE_LDAP_DN );
+}
 
-       if ( (dn = LDAP_STRDUP( dn_in )) == NULL ) {
-               return( NULL );
-       }
+char **
+ldap_explode_rdn( LDAP_CONST char *rdn, int notypes )
+{
+       Debug( LDAP_DEBUG_TRACE, "ldap_explode_rdn\n", 0, 0, 0 );
+       return explode_name( rdn, notypes, NAME_TYPE_LDAP_RDN );
+}
 
-       if ( (rdns = (char **) LDAP_MALLOC( maxcomps * sizeof(char *) )) == NULL ) {
-               LDAP_FREE( dn );
-               return( NULL );
+char *
+ldap_dn2dcedn( LDAP_CONST char *dn )
+{
+       char *dce, *q, **rdns, **p;
+       int len = 0;
+
+       Debug( LDAP_DEBUG_TRACE, "ldap_dn2dcedn\n", 0, 0, 0 );
+
+       rdns = explode_name( dn, 0, NAME_TYPE_LDAP_DN );
+       if ( rdns == NULL ) {
+               return NULL;
+       }
+       
+       for ( p = rdns; *p != NULL; p++ ) {
+               len += strlen( *p ) + 1;
        }
 
-       ncomps = 0;
-       for ( s = ldap_pvt_strtok( dn, "@.", &tok_r ); s != NULL; 
-             s = ldap_pvt_strtok( NULL, "@.", &tok_r ) )
-       {
-               if ( ncomps == maxcomps ) {
-                       maxcomps *= 2;
-                       if ( (rdns = (char **) LDAP_REALLOC( rdns, maxcomps *
-                           sizeof(char *) )) == NULL )
-                       {
-                               LDAP_FREE( dn );
-                               return NULL;
-                       }
-               }
-               rdns[ncomps++] = LDAP_STRDUP( s );
+       q = dce = LDAP_MALLOC( len + 1 );
+       if ( dce == NULL ) {
+               return NULL;
        }
-       LDAP_FREE(dn);
 
-       rdns[ncomps] = NULL;
+       p--; /* get back past NULL */
 
-       /* trim rdns */
-       rdns = (char **) LDAP_REALLOC( rdns, (ncomps+1) * sizeof(char*) );
-       return( rdns );
+       for ( ; p != rdns; p-- ) {
+               strcpy( q, "/" );
+               q++;
+               strcpy( q, *p );
+               q += strlen( *p );
+       }
+
+       strcpy( q, "/" );
+       q++;
+       strcpy( q, *p );
+       
+       return dce;
 }
 
-char **
-ldap_explode_dn( LDAP_CONST char *dn, int notypes )
+char *
+ldap_dcedn2dn( LDAP_CONST char *dce )
 {
-       Debug( LDAP_DEBUG_TRACE, "ldap_explode_dn\n", 0, 0, 0 );
+       char *dn, *q, **rdns, **p;
+       int len;
+
+       Debug( LDAP_DEBUG_TRACE, "ldap_dcedn2dn\n", 0, 0, 0 );
+
+       rdns = explode_name( dce, 0, NAME_TYPE_DCE_DN );
+       if ( rdns == NULL ) {
+               return NULL;
+       }
+
+       len = 0;
 
-       if ( ldap_is_dns_dn( dn ) ) {
-               return( ldap_explode_dns( dn ) );
+       for ( p = rdns; *p != NULL; p++ ) {
+               len += strlen( *p ) + 1;
        }
-       return explode_name( dn, notypes, 1 );
-}
 
-char **
-ldap_explode_rdn( LDAP_CONST char *rdn, int notypes )
-{
-       Debug( LDAP_DEBUG_TRACE, "ldap_explode_rdn\n", 0, 0, 0 );
-       return explode_name( rdn, notypes, 0 );
+       q = dn = LDAP_MALLOC( len );
+       if ( dn == NULL ) {
+               return NULL;
+       }
+
+       p--;
+
+       for ( ; p != rdns; p-- ) {
+               strcpy( q, *p );
+               q += strlen( *p );
+               strcpy( q, "," );
+               q++;
+       }
+
+       if ( *dce == '/' ) {
+               /* the name was fully qualified, thus the most-significant
+                * RDN was empty. trash the last comma */
+               q--;
+               *q = '\0';
+       } else {
+               /* the name was relative. copy the most significant RDN */
+               strcpy( q, *p );
+       }
+
+       return dn;
 }
 
 static char **
-explode_name( const char *name, int notypes, int is_dn )
+explode_name( const char *name, int notypes, int is_type )
 {
-       const char *p, *q;
+       const char *p, *q, *rdn;
        char **parts = NULL;
-       int     state, count = 0, endquote, len;
+       int     offset, state, have_equals, count = 0, endquote, len;
 
-       p = name-1;
+       /* safe guard */
+       if(name == NULL) name = "";
+
+       /* skip leading whitespace */
+       while( ldap_utf8_isspace( name )) {
+               LDAP_UTF8_INCR( name );
+       }
+
+       p = rdn = name;
+       offset = 0;
        state = OUTQUOTE;
+       have_equals=0;
 
        do {
+               /* step forward */
+               p += offset;
+               offset = 1;
 
-               ++p;
                switch ( *p ) {
                case '\\':
-                       if ( *++p == '\0' )
-                               p--;
+                       if ( p[1] != '\0' ) {
+                               offset = LDAP_UTF8_OFFSET(++p);
+                       }
                        break;
                case '"':
                        if ( state == INQUOTE )
@@ -214,19 +274,28 @@ explode_name( const char *name, int notypes, int is_dn )
                        else
                                state = INQUOTE;
                        break;
+               case '=':
+                       if( state == OUTQUOTE ) have_equals++;
+                       break;
                case '+':
-                       if (!is_dn)
+                       if (is_type == NAME_TYPE_LDAP_RDN)
+                               goto end_part;
+                       break;
+               case '/':
+                       if (is_type == NAME_TYPE_DCE_DN)
                                goto end_part;
                        break;
                case ';':
                case ',':
-                       if (!is_dn)
-                               break;
-                       goto end_part;
+                       if (is_type == NAME_TYPE_LDAP_DN)
+                               goto end_part;
+                       break;
                case '\0':
                end_part:
                        if ( state == OUTQUOTE ) {
                                ++count;
+                               have_equals=0;
+
                                if ( parts == NULL ) {
                                        if (( parts = (char **)LDAP_MALLOC( 8
                                                 * sizeof( char *))) == NULL )
@@ -237,31 +306,45 @@ explode_name( const char *name, int notypes, int is_dn )
                                                == NULL )
                                                return( NULL );
                                }
+
                                parts[ count ] = NULL;
                                endquote = 0;
+
                                if ( notypes ) {
-                                       for ( q = name;
-                                           q < p && *q != '='; ++q ) {
-                                               ;
+                                       for ( q = rdn; q < p && *q != '='; ++q ) {
+                                               /* EMPTY */;
                                        }
+
                                        if ( q < p ) {
-                                               name = ++q;
+                                               rdn = ++q;
                                        }
-                                       if ( *name == '"' ) {
-                                               ++name;
+
+                                       if ( *rdn == '"' ) {
+                                               ++rdn;
                                        }
                                        
-                                       if ( *(p-1) == '"' ) {
+                                       if ( p[-1] == '"' ) {
                                                endquote = 1;
                                                --p;
                                        }
                                }
 
-                               len = p - name;
+                               len = p - rdn;
+
                                if (( parts[ count-1 ] = (char *)LDAP_CALLOC( 1,
-                                   len + 1 )) != NULL ) {
-                                       SAFEMEMCPY( parts[ count-1 ], name,
-                                           len );
+                                   len + 1 )) != NULL )
+                               {
+                                       SAFEMEMCPY( parts[ count-1 ], rdn, len );
+
+                                       if( !endquote ) {
+                                               /* skip trailing spaces */
+                                               while( len > 0 && ldap_utf8_isspace(
+                                                       &parts[count-1][len-1] ) )
+                                               {
+                                                       --len;
+                                               }
+                                       }
+
                                        parts[ count-1 ][ len ] = '\0';
                                }
 
@@ -273,24 +356,12 @@ explode_name( const char *name, int notypes, int is_dn )
                                if ( endquote == 1 )
                                        p++;
 
-                               name = *p ? p + 1 : p;
-                               while ( isascii( *name ) && isspace( *name ) )
-                                       ++name;
-                       }
-                       break;
+                               rdn = *p ? &p[1] : p;
+                               while ( ldap_utf8_isspace( rdn ) )
+                                       ++rdn;
+                       } break;
                }
        } while ( *p );
 
        return( parts );
 }
-
-
-int
-ldap_is_dns_dn( LDAP_CONST char *dn )
-{
-       return( dn[ 0 ] != '\0'
-               && strchr( dn, '=' ) == NULL
-               && strchr( dn, ',' ) == NULL
-               && strchr( dn, ';' ) == NULL );
-}
-
diff --git a/libraries/libldap/getdxbyname.c b/libraries/libldap/getdxbyname.c
deleted file mode 100644 (file)
index 602721a..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-/* $OpenLDAP$ */
-/*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
- */
-/*  Portions
- *  Copyright (c) 1995 Regents of the University of Michigan.
- *  All rights reserved.
- *
- * ldap_getdxbyname - retrieve DX records from the DNS (from TXT records for now)
- */
-
-#include "portable.h"
-
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
-
-#include <stdio.h>
-#include <ac/stdlib.h>
-
-#include <ac/ctype.h>
-#include <ac/socket.h>
-#include <ac/string.h>
-#include <ac/time.h>
-
-#include "ldap-int.h"
-
-static char ** decode_answer LDAP_P(( unsigned char *answer, ber_len_t len ));
-
-#define MAX_TO_SORT    32
-
-
-/*
- * ldap_getdxbyname - lookup DNS DX records for domain and return an ordered
- *     array.
- */
-char **
-ldap_getdxbyname( const char *domain )
-{
-    unsigned char      buf[ PACKETSZ ];
-    char               **dxs;
-    int                        rc;
-
-    Debug( LDAP_DEBUG_TRACE, "ldap_getdxbyname( %s )\n", domain, 0, 0 );
-
-    memset( buf, 0, sizeof( buf ));
-
-    if (( rc = res_search( domain, C_IN, T_TXT, buf, sizeof( buf ))) < 0
-               || ( dxs = decode_answer( buf, rc )) == NULL ) {
-       /*
-        * punt:  return list conisting of the original domain name only
-        */
-       if (( dxs = (char **)LDAP_MALLOC( 2 * sizeof( char * ))) == NULL ||
-               ( dxs[ 0 ] = LDAP_STRDUP( domain )) == NULL ) {
-           if ( dxs != NULL ) {
-               LDAP_FREE( dxs );
-           }
-           dxs = NULL;
-       } else {
-           dxs[ 1 ] = NULL;
-       }
-    }
-
-    return( dxs );
-}
-
-
-static char **
-decode_answer( unsigned char *answer, ber_len_t len )
-{
-    HEADER             *hp;
-    char               buf[ 256 ], **dxs;
-    unsigned char      *eom, *p;
-    int                        ancount, err, rc, type, class, dx_count, rr_len;
-    int                        dx_pref[ MAX_TO_SORT ];
-
-#ifdef LDAP_DEBUG
-#ifdef notdef
-    if ( ldap_debug & LDAP_DEBUG_PACKETS ) {
-               __p_query( answer );
-    }
-#endif
-#endif /* LDAP_DEBUG */
-
-    dxs = NULL;
-    hp = (HEADER *)answer;
-    eom = answer + len;
-
-    if ( ntohs( hp->qdcount ) != 1 ) {
-       h_errno = NO_RECOVERY;
-       return( NULL );
-    }
-
-    ancount = ntohs( hp->ancount );
-    if ( ancount < 1 ) {
-       h_errno = NO_DATA;
-       return( NULL );
-    }
-
-    /*
-     * skip over the query
-     */
-    p = answer + HFIXEDSZ;
-    if (( rc = dn_expand( answer, eom, p, buf, sizeof( buf ))) < 0 ) {
-       h_errno = NO_RECOVERY;
-       return( NULL );
-    }
-    p += ( rc + QFIXEDSZ );
-
-    /*
-     * pull out the answers we are interested in
-     */
-    err = dx_count = 0;
-    while ( ancount > 0 && err == 0 && p < eom ) {
-       if (( rc = dn_expand( answer, eom, p, buf, sizeof( buf ))) < 0 ) {
-           err = NO_RECOVERY;
-           continue;
-       }
-       p += rc;        /* skip over name */
-       type = _getshort( p );
-       p += INT16SZ;
-       class = _getshort( p );
-       p += INT16SZ;
-       p += INT32SZ;           /* skip over TTL */
-       rr_len = _getshort( p );
-       p += INT16SZ;
-       if ( class == C_IN && type == T_TXT ) {
-           int         pref, txt_len;
-           char        *q, *r;
-
-           q = (char *)p;
-           while ( q < (char *)p + rr_len && err == 0 ) {
-               if ( *q >= 3 && strncasecmp( q + 1, "dx:", 3 ) == 0 ) {
-                   txt_len = *q - 3;
-                   r = q + 4;
-                   while ( isspace( (unsigned char) *r )) { 
-                       ++r;
-                       --txt_len;
-                   }
-                   pref = 0;
-                   while ( isdigit( (unsigned char) *r )) {
-                       pref *= 10;
-                       pref += ( *r - '0' );
-                       ++r;
-                       --txt_len;
-                   }
-                   if ( dx_count < MAX_TO_SORT - 1 ) {
-                       dx_pref[ dx_count ] = pref;
-                   }
-                   while ( isspace( (unsigned char) *r )) { 
-                       ++r;
-                       --txt_len;
-                   }
-                       dxs = (char **)LDAP_REALLOC( dxs,
-                               ( dx_count + 2 ) * sizeof( char * ));
-                   if ( dxs == NULL || ( dxs[ dx_count ] =
-                               (char *)LDAP_CALLOC( 1, txt_len + 1 )) == NULL ) {
-                       err = NO_RECOVERY;
-                       continue;
-                   }
-                   memcpy( dxs[ dx_count ], r, txt_len );
-                   dxs[ ++dx_count ] = NULL;
-               }
-               q += ( *q + 1 );        /* move past last TXT record */
-           }
-       }
-       p += rr_len;
-    }
-
-    if ( err == 0 ) {
-       if ( dx_count == 0 ) {
-           err = NO_DATA;
-       } else {
-           /*
-            * sort records based on associated preference value
-            */
-           int         i, j, sort_count, tmp_pref;
-           char        *tmp_dx;
-
-           sort_count = ( dx_count < MAX_TO_SORT ) ? dx_count : MAX_TO_SORT;
-           for ( i = 0; i < sort_count; ++i ) {
-               for ( j = i + 1; j < sort_count; ++j ) {
-                   if ( dx_pref[ i ] > dx_pref[ j ] ) {
-                       tmp_pref = dx_pref[ i ];
-                       dx_pref[ i ] = dx_pref[ j ];
-                       dx_pref[ j ] = tmp_pref;
-                       tmp_dx = dxs[ i ];
-                       dxs[ i ] = dxs[ j ];
-                       dxs[ j ] = tmp_dx;
-                   }
-               }
-           }
-       }
-    }
-
-    h_errno = err;
-    return( dxs );
-}
-
-#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_DNS */
index 09721f1d8e991fcc90b570db2c8e03db53f89270..2cf17681d8cb2f18fe724e7c5fe601e13f1b3658 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
index efafeb5067658b1e2ff937a6fd4cb163a5a13542..2d8b89c8a8d68672e17d8bc39e2c817f556153f0 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
@@ -102,7 +102,7 @@ ldap_init_getfilter_buf( char *buf, ber_len_t buflen )
     fip = NULL;
     tag = NULL;
 
-    while ( buflen > 0 && ( tokcnt = next_line_tokens( &buf, &buflen, &tok ))
+    while ( buflen > 0 && ( tokcnt = ldap_int_next_line_tokens( &buf, &buflen, &tok ))
            > 0 ) {
 
        switch( tokcnt ) {
@@ -131,7 +131,7 @@ ldap_init_getfilter_buf( char *buf, ber_len_t buflen )
                        nextflp->lfl_pattern, error );
                errno = EINVAL;
 #endif /* LDAP_LIBUI */
-               free_strarray( tok );
+               LDAP_VFREE( tok );
                return( NULL );
            }
                regfree(&re);
@@ -157,7 +157,7 @@ ldap_init_getfilter_buf( char *buf, ber_len_t buflen )
                if (( nextfip = (LDAPFiltInfo *)LDAP_CALLOC( 1,
                        sizeof( LDAPFiltInfo ))) == NULL ) {
                    ldap_getfilter_free( lfdp );
-                   free_strarray( tok );
+                   LDAP_VFREE( tok );
                    return( NULL );
                }
                if ( fip == NULL ) {    /* first one */
@@ -177,7 +177,7 @@ ldap_init_getfilter_buf( char *buf, ber_len_t buflen )
                    } else if ( strcasecmp( tok[ 2 ], "base" ) == 0 ) {
                        nextfip->lfi_scope = LDAP_SCOPE_BASE;
                    } else {
-                       free_strarray( tok );
+                       LDAP_VFREE( tok );
                        ldap_getfilter_free( lfdp );
                        errno = EINVAL;
                        return( NULL );
@@ -194,7 +194,7 @@ ldap_init_getfilter_buf( char *buf, ber_len_t buflen )
            break;
 
        default:
-           free_strarray( tok );
+           LDAP_VFREE( tok );
            ldap_getfilter_free( lfdp );
            errno = EINVAL;
            return( NULL );
index a5d5f0ee9d0caa5bab5d01959c600284671ae38b..0fb1e2511f81c4a98fe5b253a427a0e18b4847e8 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
index 69ffdec8efc49d5796ceb017b7457c10d7e25271..03fee191de20c21244f775bea2e579ae8ebfb1e8 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 #include "portable.h"
 #include <ac/ctype.h>
 #include <ac/time.h>
 
+#include <limits.h>
+
 #include "ldap-int.h"
 #include "ldap_defaults.h"
 
 struct ldapoptions ldap_int_global_options =
        { LDAP_UNINITIALIZED, LDAP_DEBUG_NONE };  
 
-#undef gopts
-#define gopts ldap_int_global_options
-
 #define ATTR_NONE      0
 #define ATTR_BOOL      1
 #define ATTR_INT       2
 #define ATTR_KV                3
 #define ATTR_STRING    4
 #define ATTR_TLS       5
+#define ATTR_URIS      6
 
 struct ol_keyvalue {
        const char *            key;
@@ -43,57 +43,77 @@ static const struct ol_keyvalue deref_kv[] = {
 };
 
 static const struct ol_attribute {
+       int                     useronly;
        int                     type;
        const char *    name;
        const void *    data;
        size_t          offset;
 } attrs[] = {
-       {ATTR_KV,               "DEREF",        deref_kv, /* or &deref_kv[0] */
+       {0, ATTR_KV,            "DEREF",        deref_kv, /* or &deref_kv[0] */
                offsetof(struct ldapoptions, ldo_deref)},
-       {ATTR_INT,              "SIZELIMIT",    NULL,
+       {0, ATTR_INT,           "SIZELIMIT",    NULL,
                offsetof(struct ldapoptions, ldo_sizelimit)},
-       {ATTR_INT,              "TIMELIMIT",    NULL,
+       {0, ATTR_INT,           "TIMELIMIT",    NULL,
                offsetof(struct ldapoptions, ldo_timelimit)},
-       {ATTR_STRING,   "BASE",                 NULL,
+       {1, ATTR_STRING,        "BINDDN",               NULL,
+               offsetof(struct ldapoptions, ldo_defbinddn)},
+       {0, ATTR_STRING,        "BASE",                 NULL,
                offsetof(struct ldapoptions, ldo_defbase)},
-       {ATTR_STRING,   "HOST",                 NULL,
-               offsetof(struct ldapoptions, ldo_defhost)},
-       {ATTR_INT,              "PORT",                 NULL,
+       {0, ATTR_INT,           "PORT",                 NULL,
                offsetof(struct ldapoptions, ldo_defport)},
-       {ATTR_BOOL,             "REFERRALS",    NULL,   LDAP_BOOL_REFERRALS},
-       {ATTR_BOOL,             "RESTART",              NULL,   LDAP_BOOL_RESTART},
-       {ATTR_BOOL,             "DNS",                  NULL,   LDAP_BOOL_DNS},
-       {ATTR_BOOL,             "TLS",                  NULL,   LDAP_OPT_X_TLS},
-       {ATTR_TLS,              "TLS_CERT",             NULL,   LDAP_OPT_X_TLS_CERTFILE},
-       {ATTR_TLS,              "TLS_KEY",              NULL,   LDAP_OPT_X_TLS_KEYFILE},
-       {ATTR_TLS,              "TLS_CACERT",   NULL,   LDAP_OPT_X_TLS_CACERTFILE},
-       {ATTR_TLS,              "TLS_CACERTDIR",NULL,   LDAP_OPT_X_TLS_CACERTDIR},
-       {ATTR_TLS,              "TLS_REQCERT",  NULL,   LDAP_OPT_X_TLS_REQUIRE_CERT},
-       {ATTR_NONE,             NULL,           NULL,   0}
+       /* **** keep this around for backward compatibility */
+       {0, ATTR_URIS,          "HOST",                 NULL,   1},
+       /* **** */
+       {0, ATTR_URIS,          "URI",                  NULL,   0},
+       {0, ATTR_BOOL,          "REFERRALS",    NULL,   LDAP_BOOL_REFERRALS},
+       {0, ATTR_BOOL,          "RESTART",              NULL,   LDAP_BOOL_RESTART},
+       {0, ATTR_TLS,           "TLS",                  NULL,   LDAP_OPT_X_TLS},
+       {0, ATTR_TLS,           "TLS_CERT",             NULL,   LDAP_OPT_X_TLS_CERTFILE},
+       {0, ATTR_TLS,           "TLS_KEY",              NULL,   LDAP_OPT_X_TLS_KEYFILE},
+       {0, ATTR_TLS,           "TLS_CACERT",   NULL,   LDAP_OPT_X_TLS_CACERTFILE},
+       {0, ATTR_TLS,           "TLS_CACERTDIR",NULL,   LDAP_OPT_X_TLS_CACERTDIR},
+       {0, ATTR_TLS,           "TLS_REQCERT",  NULL,   LDAP_OPT_X_TLS_REQUIRE_CERT},
+#ifdef HAVE_CYRUS_SASL
+       {0, ATTR_INT,           "SASL_MINSSF",  NULL,
+               offsetof(struct ldapoptions, ldo_sasl_minssf)},
+       {0, ATTR_INT,           "SASL_MAXSSF",  NULL,
+               offsetof(struct ldapoptions, ldo_sasl_maxssf)},
+#endif
+       {0, ATTR_NONE,          NULL,           NULL,   0}
 };
 
 #define MAX_LDAP_ATTR_LEN  sizeof("TLS_CACERTDIR")
 #define MAX_LDAP_ENV_PREFIX_LEN 8
 
-static void openldap_ldap_init_w_conf(const char *file)
+static void openldap_ldap_init_w_conf(
+       const char *file, int userconf )
 {
        char linebuf[128];
        FILE *fp;
        int i;
        char *cmd, *opt;
        char *start, *end;
+       struct ldapoptions *gopts;
+
+       if ((gopts = LDAP_INT_GLOBAL_OPT()) == NULL) {
+               return;                 /* Could not allocate mem for global options */
+       }
 
        if (file == NULL) {
                /* no file name */
                return;
        }
 
+       Debug(LDAP_DEBUG_TRACE, "ldap_init: trying %s\n", file, 0, 0);
+
        fp = fopen(file, "r");
        if(fp == NULL) {
                /* could not open file */
                return;
        }
 
+       Debug(LDAP_DEBUG_TRACE, "ldap_init: using %s\n", file, 0, 0);
+
        while((start = fgets(linebuf, sizeof(linebuf), fp)) != NULL) {
                /* skip lines starting with '#' */
                if(*start == '#') continue;
@@ -126,13 +146,17 @@ static void openldap_ldap_init_w_conf(const char *file)
 
                *start++ = '\0';
 
-               /* we must have some non-whitespace to skip */
+               /* we must have some whitespace to skip */
                while(isspace((unsigned char)*start)) start++;
                opt = start;
 
                for(i=0; attrs[i].type != ATTR_NONE; i++) {
                        void *p;
 
+                       if( !userconf && attrs[i].useronly ) {
+                               continue;
+                       }
+
                        if(strcasecmp(cmd, attrs[i].name) != 0) {
                                continue;
                        }
@@ -143,16 +167,16 @@ static void openldap_ldap_init_w_conf(const char *file)
                                        || (strcasecmp(opt, "yes") == 0)
                                        || (strcasecmp(opt, "true") == 0))
                                {
-                                       LDAP_BOOL_SET(&gopts, attrs[i].offset);
+                                       LDAP_BOOL_SET(gopts, attrs[i].offset);
 
                                } else {
-                                       LDAP_BOOL_CLR(&gopts, attrs[i].offset);
+                                       LDAP_BOOL_CLR(gopts, attrs[i].offset);
                                }
 
                                break;
 
                        case ATTR_INT:
-                               p = &((char *) &gopts)[attrs[i].offset];
+                               p = &((char *) gopts)[attrs[i].offset];
                                * (int*) p = atoi(opt);
                                break;
 
@@ -164,7 +188,7 @@ static void openldap_ldap_init_w_conf(const char *file)
                                                kv++) {
 
                                                if(strcasecmp(opt, kv->key) == 0) {
-                                                       p = &((char *) &gopts)[attrs[i].offset];
+                                                       p = &((char *) gopts)[attrs[i].offset];
                                                        * (int*) p = kv->value;
                                                        break;
                                                }
@@ -172,26 +196,39 @@ static void openldap_ldap_init_w_conf(const char *file)
                                } break;
 
                        case ATTR_STRING:
-                               p = &((char *) &gopts)[attrs[i].offset];
+                               p = &((char *) gopts)[attrs[i].offset];
                                if (* (char**) p != NULL) LDAP_FREE(* (char**) p);
                                * (char**) p = LDAP_STRDUP(opt);
                                break;
                        case ATTR_TLS:
 #ifdef HAVE_TLS
-                               ldap_pvt_tls_config( &gopts, attrs[i].offset, opt );
+                               ldap_pvt_tls_config( gopts, attrs[i].offset, opt );
 #endif
                                break;
+                       case ATTR_URIS:
+                               if (attrs[i].offset == 0) {
+                                       ldap_set_option( NULL, LDAP_OPT_URI, opt );
+                               } else {
+                                       ldap_set_option( NULL, LDAP_OPT_HOST_NAME, opt );
+                               }
+                               break;
                        }
+                       break;
                }
        }
 
        fclose(fp);
 }
 
+static void openldap_ldap_init_w_sysconf(const char *file)
+{
+       openldap_ldap_init_w_conf( file, 0 );
+}
+
 static void openldap_ldap_init_w_userconf(const char *file)
 {
        char *home;
-       char *path;
+       char *path = NULL;
 
        if (file == NULL) {
                /* no file name */
@@ -201,9 +238,12 @@ static void openldap_ldap_init_w_userconf(const char *file)
        home = getenv("HOME");
 
        if (home != NULL) {
+               Debug(LDAP_DEBUG_TRACE, "ldap_init: HOME env is %s\n",
+                     home, 0, 0);
                path = LDAP_MALLOC(strlen(home) + strlen(file) + 3);
        } else {
-               path = LDAP_MALLOC(strlen(file) + 3);
+               Debug(LDAP_DEBUG_TRACE, "ldap_init: HOME env is NULL\n",
+                     0, 0, 0);
        }
 
        if(home != NULL && path != NULL) {
@@ -211,11 +251,11 @@ static void openldap_ldap_init_w_userconf(const char *file)
 
                /* try ~/file */
                sprintf(path, "%s/%s", home, file);
-               openldap_ldap_init_w_conf(path);
+               openldap_ldap_init_w_conf(path, 1);
 
                /* try ~/.file */
                sprintf(path, "%s/.%s", home, file);
-               openldap_ldap_init_w_conf(path);
+               openldap_ldap_init_w_conf(path, 1);
        }
 
        if(path != NULL) {
@@ -223,10 +263,12 @@ static void openldap_ldap_init_w_userconf(const char *file)
        }
 
        /* try file */
-       openldap_ldap_init_w_conf(file);
+       openldap_ldap_init_w_conf(file, 1);
 }
 
-static void openldap_ldap_init_w_env(const char *prefix)
+static void openldap_ldap_init_w_env(
+               struct ldapoptions *gopts,
+               const char *prefix)
 {
        char buf[MAX_LDAP_ATTR_LEN+MAX_LDAP_ENV_PREFIX_LEN];
        int len;
@@ -256,15 +298,15 @@ static void openldap_ldap_init_w_env(const char *prefix)
                                || (strcasecmp(value, "yes") == 0)
                                || (strcasecmp(value, "true") == 0))
                        {
-                               LDAP_BOOL_SET(&gopts, attrs[i].offset);
+                               LDAP_BOOL_SET(gopts, attrs[i].offset);
 
                        } else {
-                               LDAP_BOOL_CLR(&gopts, attrs[i].offset);
+                               LDAP_BOOL_CLR(gopts, attrs[i].offset);
                        }
                        break;
 
                case ATTR_INT:
-                       p = &((char *) &gopts)[attrs[i].offset];
+                       p = &((char *) gopts)[attrs[i].offset];
                        * (int*) p = atoi(value);
                        break;
 
@@ -276,7 +318,7 @@ static void openldap_ldap_init_w_env(const char *prefix)
                                        kv++) {
 
                                        if(strcasecmp(value, kv->key) == 0) {
-                                               p = &((char *) &gopts)[attrs[i].offset];
+                                               p = &((char *) gopts)[attrs[i].offset];
                                                * (int*) p = kv->value;
                                                break;
                                        }
@@ -284,7 +326,7 @@ static void openldap_ldap_init_w_env(const char *prefix)
                        } break;
 
                case ATTR_STRING:
-                       p = &((char *) &gopts)[attrs[i].offset];
+                       p = &((char *) gopts)[attrs[i].offset];
                        if (* (char**) p != NULL) LDAP_FREE(* (char**) p);
                        if (*value == '\0') {
                                * (char**) p = NULL;
@@ -294,75 +336,117 @@ static void openldap_ldap_init_w_env(const char *prefix)
                        break;
                case ATTR_TLS:
 #ifdef HAVE_TLS
-                       ldap_pvt_tls_config( attrs[i].offset, value );
+                       ldap_pvt_tls_config( gopts, attrs[i].offset, value );
 #endif                         
                        break;
+               case ATTR_URIS:
+                       if (attrs[i].offset == 0) {
+                               ldap_set_option( NULL, LDAP_OPT_URI, value );
+                       } else {
+                               ldap_set_option( NULL, LDAP_OPT_HOST_NAME, value );
+                       }
+                       break;
                }
        }
 }
 
-void ldap_int_initialize( void )
+/* 
+ * Initialize the global options structure with default values.
+ */
+void ldap_int_initialize_global_options( struct ldapoptions *gopts, int *dbglvl )
 {
-       if ( gopts.ldo_valid == LDAP_INITIALIZED ) {
-               return;
-       }
+       if (dbglvl)
+           gopts->ldo_debug = *dbglvl;
+       else
+               gopts->ldo_debug = 0;
 
-       ldap_int_utils_init();
+       gopts->ldo_version   = LDAP_VERSION2;
+       gopts->ldo_deref     = LDAP_DEREF_NEVER;
+       gopts->ldo_timelimit = LDAP_NO_LIMIT;
+       gopts->ldo_sizelimit = LDAP_NO_LIMIT;
 
-#ifdef HAVE_TLS
-       ldap_pvt_tls_init();
-#endif
+       gopts->ldo_tm_api = (struct timeval *)NULL;
+       gopts->ldo_tm_net = (struct timeval *)NULL;
 
-       if ( ldap_int_tblsize == 0 )
-               ldap_int_ip_init();
+       /* ldo_defludp is leaked, we should have an at_exit() handler
+        * to free this and whatever else needs to cleaned up. 
+        */
+       ldap_url_parselist(&gopts->ldo_defludp, "ldap://localhost/");
+       gopts->ldo_defport = LDAP_PORT;
+
+       gopts->ldo_refhoplimit = LDAP_DEFAULT_REFHOPLIMIT;
+       gopts->ldo_rebindproc = NULL;
 
-       gopts.ldo_debug = 0;
+       LDAP_BOOL_ZERO(gopts);
 
-       gopts.ldo_version =     LDAP_VERSION2;
-       gopts.ldo_deref =       LDAP_DEREF_NEVER;
-       gopts.ldo_timelimit = LDAP_NO_LIMIT;
-       gopts.ldo_sizelimit = LDAP_NO_LIMIT;
+       LDAP_BOOL_SET(gopts, LDAP_BOOL_REFERRALS);
 
-       gopts.ldo_tm_api = (struct timeval *)NULL;
-       gopts.ldo_tm_net = (struct timeval *)NULL;
+#ifdef HAVE_TLS
+       gopts->ldo_tls_ctx = NULL;
+#endif
+#ifdef HAVE_CYRUS_SASL
+       gopts->ldo_sasl_minssf = 0;
+       gopts->ldo_sasl_maxssf = INT_MAX;
+#endif
 
-       gopts.ldo_defhost = LDAP_STRDUP("localhost");
-       gopts.ldo_defport = LDAP_PORT;
+       gopts->ldo_valid = LDAP_INITIALIZED;
 
-       gopts.ldo_refhoplimit = LDAP_DEFAULT_REFHOPLIMIT;
+       return;
+}
 
-       LDAP_BOOL_ZERO(&gopts);
+void ldap_int_initialize( struct ldapoptions *gopts, int *dbglvl )
+{
+       if ( gopts->ldo_valid == LDAP_INITIALIZED ) {
+               return;
+       }
 
-       LDAP_BOOL_SET(&gopts, LDAP_BOOL_REFERRALS);
+       ldap_int_utils_init();
 
 #ifdef HAVE_TLS
-       gopts.ldo_tls_ctx = NULL;
+       ldap_pvt_tls_init();
 #endif
 
-       gopts.ldo_valid = LDAP_INITIALIZED;
+#ifdef HAVE_CYRUS_SASL
+       ldap_pvt_sasl_init();
+#endif
+
+       if ( ldap_int_tblsize == 0 )
+               ldap_int_ip_init();
+
+       ldap_int_initialize_global_options(gopts, NULL);
 
        if( getenv("LDAPNOINIT") != NULL ) {
                return;
        }
 
-       openldap_ldap_init_w_conf(LDAP_CONF_FILE);
+       openldap_ldap_init_w_sysconf(LDAP_CONF_FILE);
        openldap_ldap_init_w_userconf(LDAP_USERRC_FILE);
 
        {
                char *altfile = getenv(LDAP_ENV_PREFIX "CONF");
 
                if( altfile != NULL ) {
-                       openldap_ldap_init_w_conf( altfile );
+                       Debug(LDAP_DEBUG_TRACE, "ldap_init: %s env is %s\n",
+                             LDAP_ENV_PREFIX "CONF", altfile, 0);
+                       openldap_ldap_init_w_sysconf( altfile );
                }
+               else
+                       Debug(LDAP_DEBUG_TRACE, "ldap_init: %s env is NULL\n",
+                             LDAP_ENV_PREFIX "CONF", 0, 0);
        }
 
        {
                char *altfile = getenv(LDAP_ENV_PREFIX "RC");
 
                if( altfile != NULL ) {
+                       Debug(LDAP_DEBUG_TRACE, "ldap_init: %s env is %s\n",
+                             LDAP_ENV_PREFIX "RC", altfile, 0);
                        openldap_ldap_init_w_userconf( altfile );
                }
+               else
+                       Debug(LDAP_DEBUG_TRACE, "ldap_init: %s env is NULL\n",
+                             LDAP_ENV_PREFIX "RC", 0, 0);
        }
 
-       openldap_ldap_init_w_env(NULL);
+       openldap_ldap_init_w_env(gopts, NULL);
 }
index 731a8b5fc6c25c5b43df0c5efc47a78bf71e3f10..fd6d59ab7fd1ae011cc374bbf8ba6e6387860490 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
@@ -16,7 +16,7 @@
  *             name            DistinguishedName,       -- who
  *             authentication  CHOICE {
  *                     simple          [0] OCTET STRING -- passwd
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
  *                     krbv42ldap      [1] OCTET STRING
  *                     krbv42dsa       [2] OCTET STRING
 #endif
@@ -33,7 +33,7 @@
 
 #include "portable.h"
 
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
 
 #include <stdio.h>
 #include <ac/stdlib.h>
@@ -63,9 +63,6 @@ ldap_kerberos_bind1( LDAP *ld, LDAP_CONST char *dn )
        char            *cred;
        int             rc;
        ber_len_t credlen;
-#ifdef STR_TRANSLATION
-       int             str_translation_on;
-#endif /* STR_TRANSLATION */
 
        Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind1\n", 0, 0, 0 );
 
@@ -83,23 +80,10 @@ ldap_kerberos_bind1( LDAP *ld, LDAP_CONST char *dn )
                return( -1 );
        }
 
-#ifdef STR_TRANSLATION
-       if (( str_translation_on = (( ber->ber_options &
-           LBER_TRANSLATE_STRINGS ) != 0 ))) { /* turn translation off */
-               ber->ber_options &= ~LBER_TRANSLATE_STRINGS;
-       }
-#endif /* STR_TRANSLATION */
-
        /* fill it in */
        rc = ber_printf( ber, "{it{isto}}", ++ld->ld_msgid, LDAP_REQ_BIND,
            ld->ld_version, dn, LDAP_AUTH_KRBV41, cred, credlen );
 
-#ifdef STR_TRANSLATION
-       if ( str_translation_on ) {     /* restore translation */
-               ber->ber_options |= LBER_TRANSLATE_STRINGS;
-       }
-#endif /* STR_TRANSLATION */
-
        if ( rc == -1 ) {
                LDAP_FREE( cred );
                ber_free( ber, 1 );
@@ -157,9 +141,6 @@ ldap_kerberos_bind2( LDAP *ld, LDAP_CONST char *dn )
        char            *cred;
        int             rc;
        ber_len_t credlen;
-#ifdef STR_TRANSLATION
-       int             str_translation_on;
-#endif /* STR_TRANSLATION */
 
        Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind2\n", 0, 0, 0 );
 
@@ -177,24 +158,11 @@ ldap_kerberos_bind2( LDAP *ld, LDAP_CONST char *dn )
                return( -1 );
        }
 
-#ifdef STR_TRANSLATION
-       if (( str_translation_on = (( ber->ber_options &
-           LBER_TRANSLATE_STRINGS ) != 0 ))) { /* turn translation off */
-               ber->ber_options &= ~LBER_TRANSLATE_STRINGS;
-       }
-#endif /* STR_TRANSLATION */
-
        /* fill it in */
        rc = ber_printf( ber, "{it{isto}}", ++ld->ld_msgid, LDAP_REQ_BIND,
            ld->ld_version, dn, LDAP_AUTH_KRBV42, cred, credlen );
 
 
-#ifdef STR_TRANSLATION
-       if ( str_translation_on ) {     /* restore translation */
-               ber->ber_options |= LBER_TRANSLATE_STRINGS;
-       }
-#endif /* STR_TRANSLATION */
-
        LDAP_FREE( cred );
 
        if ( rc == -1 ) {
@@ -269,10 +237,17 @@ ldap_get_kerberosv4_credentials(
                fprintf( stderr, "krb_get_tf_realm failed (%s)\n",
                    krb_err_txt[err] );
 #endif /* LDAP_LIBUI */
-               ld->ld_errno = LDAP_INVALID_CREDENTIALS;
+               ld->ld_errno = LDAP_AUTH_UNKNOWN;
                return( NULL );
        }
 
+       if ( ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, NULL ) == -1 ) {
+               /* not connected yet */
+               int rc = ldap_open_defconn( ld );
+
+               if( rc < 0 ) return NULL;
+       }
+
        krbinstance = ld->ld_defconn->lconn_krbinstance;
 
        if ( (err = krb_mk_req( &ktxt, service, krbinstance, realm, 0 ))
@@ -280,7 +255,7 @@ ldap_get_kerberosv4_credentials(
 #ifdef LDAP_LIBUI
                fprintf( stderr, "krb_mk_req failed (%s)\n", krb_err_txt[err] );
 #endif /* LDAP_LIBUI */
-               ld->ld_errno = LDAP_INVALID_CREDENTIALS;
+               ld->ld_errno = LDAP_AUTH_UNKNOWN;
                return( NULL );
        }
 
@@ -296,4 +271,4 @@ ldap_get_kerberosv4_credentials(
 }
 
 #endif /* !AUTHMAN */
-#endif /* HAVE_KERBEROS */
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
index ab446da5a979dacc96cdb5281d0c52201a55f3d5..36993c8afdc30e9da5893f27bb2904c4724e154d 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
 
 #include "../liblber/lber-int.h"
 
-#define ldap_debug     (ldap_int_global_options.ldo_debug)
+/* 
+ * Support needed if the library is running in the kernel
+ */
+#if LDAP_INT_IN_KERNEL
+       /* 
+        * Platform specific function to return a pointer to the
+        * process-specific global options. 
+        *
+        * This function should perform the following functions:
+        *  Allocate and initialize a global options struct on a per process basis
+        *  Use callers process identifier to return its global options struct
+        *  Note: Deallocate structure when the process exits
+        */
+#      define LDAP_INT_GLOBAL_OPT() ldap_int_global_opt()
+   struct ldapoptions *ldap_int_global_opt(void);
+#else
+#      define LDAP_INT_GLOBAL_OPT() (&ldap_int_global_options)
+#endif
+
+#define ldap_debug     ((LDAP_INT_GLOBAL_OPT())->ldo_debug)
+
+#include "ldap_log.h"
+
 #undef Debug
 #define Debug( level, fmt, arg1, arg2, arg3 ) \
        ldap_log_printf( NULL, (level), (fmt), (arg1), (arg2), (arg3) )
 
-#include "ldap_log.h"
-
 #include "ldap.h"
 
 #include "ldap_pvt.h"
@@ -36,6 +56,10 @@ LDAP_BEGIN_DECL
 #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 LDAPI_URL_PREFIX       "ldapi://"
+#define LDAPI_URL_PREFIX_LEN   (sizeof(LDAPI_URL_PREFIX)-1)
+#define LDAPIS_URL_PREFIX      "ldapis://"
+#define LDAPIS_URL_PREFIX_LEN  (sizeof(LDAPIS_URL_PREFIX)-1)
 #define LDAP_URL_URLCOLON              "URL:"
 #define LDAP_URL_URLCOLON_LEN  (sizeof(LDAP_URL_URLCOLON)-1)
 #define NULLLDAPURLDESC ((LDAPURLDesc *)NULL)
@@ -45,16 +69,11 @@ LDAP_BEGIN_DECL
 #define LDAP_LDAP_REF_STR      LDAP_URL_PREFIX
 #define LDAP_LDAP_REF_STR_LEN  (sizeof(LDAP_LDAP_REF_STR)-1)
 
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
-#define LDAP_DX_REF_STR                "dx://"
-#define LDAP_DX_REF_STR_LEN    (sizeof(LDAP_DX_REF_STR)-1)
-#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_DNS */
 
 #define LDAP_DEFAULT_REFHOPLIMIT 5
 
 #define LDAP_BOOL_REFERRALS            0
 #define LDAP_BOOL_RESTART              1
-#define LDAP_BOOL_DNS                  2
 #define LDAP_BOOL_TLS                  3
 
 #define LDAP_BOOLEANS  unsigned long
@@ -95,14 +114,15 @@ struct ldapoptions {
        struct timeval          *ldo_tm_api;
        struct timeval          *ldo_tm_net;
 
-       ber_int_t               ldo_version;    /* version to connect at */
+       ber_int_t               ldo_version;
        ber_int_t               ldo_deref;
        ber_int_t               ldo_timelimit;
        ber_int_t               ldo_sizelimit;
 
+       LDAPURLDesc *ldo_defludp;
        int             ldo_defport;
        char*   ldo_defbase;
-       char*   ldo_defhost;
+       char*   ldo_defbinddn;  /* simple bind dn */
 
 #ifdef LDAP_CONNECTIONLESS
        int             ldo_cldaptries; /* connectionless search retry count */
@@ -114,11 +134,18 @@ struct ldapoptions {
        /* LDAPv3 server and client controls */
        LDAPControl     **ldo_sctrls;
        LDAPControl **ldo_cctrls;
+       /* LDAPV3 rebind callback function
+       */
+       LDAP_REBIND_PROC                *ldo_rebindproc;
 
 #ifdef HAVE_TLS
        /* tls context */
        void            *ldo_tls_ctx;
        int             ldo_tls_mode;
+#endif
+#ifdef HAVE_CYRUS_SASL
+       sasl_ssf_t      ldo_sasl_minssf;
+       sasl_ssf_t      ldo_sasl_maxssf;
 #endif
        LDAP_BOOLEANS ldo_booleans;     /* boolean options */
 };
@@ -131,6 +158,7 @@ typedef struct ldap_server {
        char                    *lsrv_host;
        char                    *lsrv_dn;       /* if NULL, use default */
        int                     lsrv_port;
+/*     int                     lsrv_protocol; */
        struct ldap_server      *lsrv_next;
 } LDAPServer;
 
@@ -142,11 +170,13 @@ typedef struct ldap_conn {
        Sockbuf                 *lconn_sb;
        int                     lconn_refcnt;
        time_t          lconn_lastused; /* time */
+       int                     lconn_rebind_inprogress;        /* set if rebind in progress */
+       char            ***lconn_rebind_queue;          /* used if rebind in progress */
        int                     lconn_status;
 #define LDAP_CONNST_NEEDSOCKET         1
 #define LDAP_CONNST_CONNECTING         2
 #define LDAP_CONNST_CONNECTED          3
-       LDAPServer              *lconn_server;
+       LDAPURLDesc             *lconn_server;
        char                    *lconn_krbinstance;
        struct ldap_conn        *lconn_next;
        BerElement              *lconn_ber;/* ber receiving on this conn. */
@@ -159,6 +189,7 @@ typedef struct ldap_conn {
 typedef struct ldapreq {
        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
@@ -194,6 +225,15 @@ typedef struct ldapcache {
 #define LDAP_CACHE_OPT_CACHEALLERRS    0x00000002
 }  LDAPCache;
 
+/*
+ * structure containing referral request info for rebind procedure
+ */
+typedef struct ldapreqinfo {
+       ber_len_t       ri_msgid;
+       int                     ri_request;
+       char            *ri_url;
+} LDAPreqinfo;
+
 /*
  * handy macro for checking if handle is connectionless
  */
@@ -205,7 +245,7 @@ typedef struct ldapcache {
  */
 
 struct ldap {
-       Sockbuf         ld_sb;          /* socket descriptor & buffer */
+       Sockbuf         *ld_sb;         /* socket descriptor & buffer */
 
        struct ldapoptions ld_options;
 
@@ -216,6 +256,7 @@ struct ldap {
 #define ld_timelimit   ld_options.ldo_timelimit
 #define ld_sizelimit   ld_options.ldo_sizelimit
 
+#define ld_defbinddn   ld_options.ldo_defbinddn
 #define ld_defbase             ld_options.ldo_defbase
 #define ld_defhost             ld_options.ldo_defhost
 #define ld_defport             ld_options.ldo_defport
@@ -226,8 +267,9 @@ struct ldap {
 
 #define ld_sctrls              ld_options.ldo_sctrls
 #define ld_cctrls              ld_options.ldo_cctrls
+#define ld_rebindproc  ld_options.ldo_rebindproc
 
-       ber_int_t               ld_version;             /* version connected at */
+#define ld_version             ld_options.ldo_version  
        char    *ld_host;
        int             ld_port;
 
@@ -255,25 +297,29 @@ struct ldap {
        void            **ld_cldapaddrs;/* addresses to send request to */
 
        /* do not mess with the rest though */
-       BERTranslateProc ld_lber_encode_translate_proc;
-       BERTranslateProc ld_lber_decode_translate_proc;
 
        LDAPConn        *ld_defconn;    /* default connection */
        LDAPConn        *ld_conns;      /* list of server connections */
        void            *ld_selectinfo; /* platform specifics for select */
-       int             (*ld_rebindproc)( struct ldap *ld, char **dnp,
-                               char **passwdp, int *authmethodp, int freeit );
-                               /* routine to get info needed for re-bind */
+#ifdef HAVE_CYRUS_SASL
+       sasl_conn_t             *ld_sasl_context;
+#endif /* HAVE_CYRUS_SASL */
 };
 #define LDAP_VALID(ld) ( (ld)->ld_valid == LDAP_VALID_SESSION )
 
+#if defined(HAVE_RES_QUERY) && defined(LDAP_R_COMPILE)
+#include <ldap_pvt_thread.h>
+extern ldap_pvt_thread_mutex_t ldap_int_resolv_mutex;
+#endif /* HAVE_RES_QUERY && LDAP_R_COMPILE */
+
 /*
  * in init.c
  */
 
-extern struct ldapoptions ldap_int_global_options;
-void ldap_int_initialize LDAP_P((void));
-
+LIBLDAP_F ( struct ldapoptions ) ldap_int_global_options;
+LIBLDAP_F ( void ) ldap_int_initialize LDAP_P((struct ldapoptions *, int *));
+LIBLDAP_F ( void ) ldap_int_initialize_global_options LDAP_P((
+       struct ldapoptions *, int *));
 
 /* memory.c */
        /* simple macros to realloc for now */
@@ -294,125 +340,129 @@ void ldap_int_initialize LDAP_P((void));
 /*
  * in unit-int.c
  */
-void ldap_int_utils_init LDAP_P(( void ));
+LIBLDAP_F (void) ldap_int_utils_init LDAP_P(( void ));
 
 
 /*
  * in print.c
  */
-int ldap_log_printf LDAP_P((LDAP *ld, int level, const char *fmt, ...))
-                    LDAP_GCCATTR((format(printf, 3, 4)));
+LIBLDAP_F (int) ldap_log_printf LDAP_P((LDAP *ld, int level, const char *fmt, ...)) LDAP_GCCATTR((format(printf, 3, 4)));
 
 /*
  * in cache.c
  */
-void ldap_add_request_to_cache LDAP_P(( LDAP *ld, ber_tag_t msgtype,
+LIBLDAP_F (void) ldap_add_request_to_cache LDAP_P(( LDAP *ld, ber_tag_t msgtype,
         BerElement *request ));
-void ldap_add_result_to_cache LDAP_P(( LDAP *ld, LDAPMessage *result ));
-int ldap_check_cache LDAP_P(( LDAP *ld, ber_tag_t msgtype, BerElement *request ));
+LIBLDAP_F (void) ldap_add_result_to_cache LDAP_P(( LDAP *ld, LDAPMessage *result ));
+LIBLDAP_F (int) ldap_check_cache LDAP_P(( LDAP *ld, ber_tag_t msgtype, BerElement *request ));
 
 /*
  * in controls.c
  */
-LDAPControl *ldap_control_dup LDAP_P((
+LIBLDAP_F (LDAPControl *) ldap_control_dup LDAP_P((
        const LDAPControl *ctrl ));
 
-LDAPControl **ldap_controls_dup LDAP_P((
+LIBLDAP_F (LDAPControl **) ldap_controls_dup LDAP_P((
        LDAPControl *const *ctrls ));
 
-int ldap_int_get_controls LDAP_P((
+LIBLDAP_F (int) ldap_int_get_controls LDAP_P((
        BerElement *be,
        LDAPControl ***ctrlsp));
 
-int ldap_int_put_controls LDAP_P((
+LIBLDAP_F (int) ldap_int_put_controls LDAP_P((
        LDAP *ld,
        LDAPControl *const *ctrls,
        BerElement *ber ));
 
+LIBLDAP_F( int ) 
+ldap_int_create_control LDAP_P(( 
+       const char *requestOID, 
+       BerElement *ber, 
+       int iscritical,
+       LDAPControl **ctrlp ));
+
 /*
  * in dsparse.c
  */
-int next_line_tokens LDAP_P(( char **bufp, ber_len_t *blenp, char ***toksp ));
-void free_strarray LDAP_P(( char **sap ));
+LIBLDAP_F (int) ldap_int_next_line_tokens LDAP_P(( char **bufp, ber_len_t *blenp, char ***toksp ));
 
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
 /*
  * in kerberos.c
  */
-char *ldap_get_kerberosv4_credentials LDAP_P((
+LIBLDAP_F (char *) ldap_get_kerberosv4_credentials LDAP_P((
        LDAP *ld,
        LDAP_CONST char *who,
        LDAP_CONST char *service,
        ber_len_t *len ));
 
-#endif /* HAVE_KERBEROS */
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
 
 
 /*
  * in open.c
  */
-int open_ldap_connection( LDAP *ld, Sockbuf *sb, const char *host, int defport,
-       char **krbinstancep, int async );
-
+LIBLDAP_F (int) ldap_open_defconn( LDAP *ld );
+LIBLDAP_F (int) open_ldap_connection( LDAP *ld, Sockbuf *sb, LDAPURLDesc *srvlist, char **krbinstancep, int async );
 
 /*
  * in os-ip.c
  */
-extern int ldap_int_tblsize;
-int ldap_int_timeval_dup( struct timeval **dest, const struct timeval *tm );
-int ldap_connect_to_host( LDAP *ld, Sockbuf *sb, const char *host,
-       unsigned long address, int port, int async );
-
-void ldap_close_connection( Sockbuf *sb );
-
-#ifdef HAVE_KERBEROS
-char *ldap_host_connected_to( Sockbuf *sb );
-#endif /* HAVE_KERBEROS */
-
-void ldap_int_ip_init( void );
-int do_ldap_select( LDAP *ld, struct timeval *timeout );
-void *ldap_new_select_info( void );
-void ldap_free_select_info( void *sip );
-void ldap_mark_select_write( LDAP *ld, Sockbuf *sb );
-void ldap_mark_select_read( LDAP *ld, Sockbuf *sb );
-void ldap_mark_select_clear( LDAP *ld, Sockbuf *sb );
-int ldap_is_read_ready( LDAP *ld, Sockbuf *sb );
-int ldap_is_write_ready( LDAP *ld, Sockbuf *sb );
+LIBLDAP_F (int) ldap_int_tblsize;
+LIBLDAP_F (int) ldap_int_timeval_dup( struct timeval **dest, const struct timeval *tm );
+LIBLDAP_F (int) ldap_connect_to_host( LDAP *ld, Sockbuf *sb, const char *host, unsigned long address, int port, int async );
+
+#if defined(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND) || defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
+LIBLDAP_F (char *) ldap_host_connected_to( Sockbuf *sb );
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
+
+LIBLDAP_F (void) ldap_int_ip_init( void );
+LIBLDAP_F (int) do_ldap_select( LDAP *ld, struct timeval *timeout );
+LIBLDAP_F (void *) ldap_new_select_info( void );
+LIBLDAP_F (void) ldap_free_select_info( void *sip );
+LIBLDAP_F (void) ldap_mark_select_write( LDAP *ld, Sockbuf *sb );
+LIBLDAP_F (void) ldap_mark_select_read( LDAP *ld, Sockbuf *sb );
+LIBLDAP_F (void) ldap_mark_select_clear( LDAP *ld, Sockbuf *sb );
+LIBLDAP_F (int) ldap_is_read_ready( LDAP *ld, Sockbuf *sb );
+LIBLDAP_F (int) ldap_is_write_ready( LDAP *ld, Sockbuf *sb );
 
+/*
+ * in os-local.c
+ */
+#ifdef LDAP_PF_UNIX 
+LIBLDAP_F (int) ldap_connect_to_path( LDAP *ld, Sockbuf *sb, const char *path, int async );
+#endif /* LDAP_PF_UNIX */
 
 /*
  * in request.c
  */
-ber_int_t ldap_send_initial_request( LDAP *ld, ber_tag_t msgtype,
+LIBLDAP_F (ber_int_t) ldap_send_initial_request( LDAP *ld, ber_tag_t msgtype,
        const char *dn, BerElement *ber );
-BerElement *ldap_alloc_ber_with_options( LDAP *ld );
-void ldap_set_ber_options( LDAP *ld, BerElement *ber );
-
-int ldap_send_server_request( LDAP *ld, BerElement *ber, ber_int_t msgid,
-       LDAPRequest *parentreq, LDAPServer *srvlist, LDAPConn *lc,
-       int bind );
-LDAPConn *ldap_new_connection( LDAP *ld, LDAPServer **srvlistp, int use_ldsb,
-       int connect, int bind );
-LDAPRequest *ldap_find_request_by_msgid( LDAP *ld, ber_int_t msgid );
-void ldap_free_request( LDAP *ld, LDAPRequest *lr );
-void ldap_free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind );
-void ldap_dump_connection( LDAP *ld, LDAPConn *lconns, int all );
-void ldap_dump_requests_and_responses( LDAP *ld );
-
-int ldap_chase_referrals( LDAP *ld, LDAPRequest *lr, char **errstrp, int *hadrefp );
-int ldap_append_referral( LDAP *ld, char **referralsp, char *s );
+LIBLDAP_F (BerElement *) ldap_alloc_ber_with_options( LDAP *ld );
+LIBLDAP_F (void) ldap_set_ber_options( LDAP *ld, BerElement *ber );
+
+LIBLDAP_F (int) ldap_send_server_request( LDAP *ld, BerElement *ber, ber_int_t msgid, LDAPRequest *parentreq, LDAPURLDesc *srvlist, LDAPConn *lc, LDAPreqinfo *bind );
+LIBLDAP_F (LDAPConn *) ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb, int connect, LDAPreqinfo *bind );
+LIBLDAP_F (LDAPRequest *) ldap_find_request_by_msgid( LDAP *ld, ber_int_t msgid );
+LIBLDAP_F (void) ldap_free_request( LDAP *ld, LDAPRequest *lr );
+LIBLDAP_F (void) ldap_free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind );
+LIBLDAP_F (void) ldap_dump_connection( LDAP *ld, LDAPConn *lconns, int all );
+LIBLDAP_F (void) ldap_dump_requests_and_responses( LDAP *ld );
+LIBLDAP_F (int) ldap_chase_referrals( LDAP *ld, LDAPRequest *lr, char **errstrp, int *hadrefp );
+LIBLDAP_F (int) ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, char **referralsp, int *hadrefp );
+LIBLDAP_F (int) ldap_append_referral( LDAP *ld, char **referralsp, char *s );
 
 /*
  * in result.c:
  */
 #ifdef LDAP_CONNECTIONLESS
-int cldap_getmsg( LDAP *ld, struct timeval *timeout, BerElement *ber );
+LIBLDAP_F (int) cldap_getmsg( LDAP *ld, struct timeval *timeout, BerElement *ber );
 #endif
 
 /*
  * in search.c
  */
-BerElement *ldap_build_search_req LDAP_P((
+LIBLDAP_F (BerElement *) ldap_build_search_req LDAP_P((
        LDAP *ld,
        const char *base,
        ber_int_t scope,
@@ -432,40 +482,44 @@ BerElement *ldap_build_search_req LDAP_P((
 /*
  * in unbind.c
  */
-int ldap_ld_free LDAP_P((
+LIBLDAP_F (int) ldap_ld_free LDAP_P((
        LDAP *ld,
        int close,
        LDAPControl **sctrls,
        LDAPControl **cctrls ));
 
-int ldap_send_unbind LDAP_P((
+LIBLDAP_F (int) ldap_send_unbind LDAP_P((
        LDAP *ld,
        Sockbuf *sb,
        LDAPControl **sctrls,
        LDAPControl **cctrls ));
 
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
 /*
- * in getdxbyname.c
+ * in url.c
  */
-char **ldap_getdxbyname( const char *domain );
-#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_DNS */
+LIBLDAP_F (LDAPURLDesc *) ldap_url_dup LDAP_P((
+       LDAPURLDesc *ludp ));
+
+LIBLDAP_F (LDAPURLDesc *) ldap_url_duplist LDAP_P((
+       LDAPURLDesc *ludlist ));
+
+LIBLDAP_F (int) ldap_url_parselist LDAP_P((
+       LDAPURLDesc **ludlist,
+       const char *url ));
+
+LIBLDAP_F (int) ldap_url_parsehosts LDAP_P((
+       LDAPURLDesc **ludlist,
+       const char *hosts ));
+
+LIBLDAP_F (char *) ldap_url_list2hosts LDAP_P((
+       LDAPURLDesc *ludlist ));
+
+LIBLDAP_F (char *) ldap_url_list2urls LDAP_P((
+       LDAPURLDesc *ludlist ));
+
+LIBLDAP_F (void) ldap_free_urllist LDAP_P((
+       LDAPURLDesc *ludlist ));
 
-#if defined( STR_TRANSLATION ) && defined( LDAP_DEFAULT_CHARSET )
-/*
- * in charset.c
- *
- * added-in this stuff so that libldap.a would build, i.e. refs to 
- * these routines from open.c would resolve. 
- * hodges@stanford.edu 5-Feb-96
- */
-#if LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET
-extern 
-int ldap_t61_to_8859( char **bufp, ber_len_t *buflenp, int free_input );
-extern 
-int ldap_8859_to_t61( char **bufp, ber_len_t *buflenp, int free_input );
-#endif /* LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET */
-#endif /* STR_TRANSLATION && LDAP_DEFAULT_CHARSET */
 
 LDAP_END_DECL
 
index 48692feb92c049470ae9f838ad2245ca59fae4a3..5a9f03affcf45bd2f6d8879464b9b10f2c59d19e 100644 (file)
@@ -38,9 +38,10 @@ CPP=cl.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\Release"
-# PROP Intermediate_Dir "Release\libldap"
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\libldap"
 # PROP Target_Dir ""
+RSC=rc.exe
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
 # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_WINDOWS" /YX /FD /c
 BSC32=bscmake.exe
@@ -48,7 +49,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LIB32=link.exe -lib
 # ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\Release\oldap32.lib"
+# ADD LIB32 /nologo /out:"..\..\Release\oldap32.lib"
 
 !ELSEIF  "$(CFG)" == "libldap - Win32 Debug"
 
@@ -59,9 +60,10 @@ LIB32=link.exe -lib
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\Debug"
-# PROP Intermediate_Dir "Debug\libldap"
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\libldap"
 # PROP Target_Dir ""
+RSC=rc.exe
 # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
 # ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
 BSC32=bscmake.exe
@@ -69,7 +71,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LIB32=link.exe -lib
 # ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\Debug\oldap32.lib"
+# ADD LIB32 /nologo /out:"..\..\Debug\oldap32.lib"
 
 !ELSEIF  "$(CFG)" == "libldap - Win32 Single Debug"
 
@@ -80,9 +82,10 @@ LIB32=link.exe -lib
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\SDebug"
-# PROP Intermediate_Dir "SDebug\libldap"
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\libldap"
 # PROP Target_Dir ""
+RSC=rc.exe
 # ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
 # ADD CPP /nologo /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
 BSC32=bscmake.exe
@@ -90,7 +93,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LIB32=link.exe -lib
 # ADD BASE LIB32 /nologo /out:"..\Debug\oldap32.lib"
-# ADD LIB32 /nologo /out:"..\SDebug\oldap32.lib"
+# ADD LIB32 /nologo /out:"..\..\SDebug\oldap32.lib"
 
 !ELSEIF  "$(CFG)" == "libldap - Win32 Single Release"
 
@@ -101,9 +104,10 @@ LIB32=link.exe -lib
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\SRelease"
-# PROP Intermediate_Dir "SRelease\libldap"
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\libldap"
 # PROP Target_Dir ""
+RSC=rc.exe
 # ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
 # ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_WINDOWS" /YX /FD /c
 BSC32=bscmake.exe
@@ -111,7 +115,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LIB32=link.exe -lib
 # ADD BASE LIB32 /nologo /out:"..\Release\oldap32.lib"
-# ADD LIB32 /nologo /out:"..\SRelease\oldap32.lib"
+# ADD LIB32 /nologo /out:"..\..\SRelease\oldap32.lib"
 
 !ENDIF 
 
@@ -147,10 +151,6 @@ SOURCE=.\charray.c
 # End Source File
 # Begin Source File
 
-SOURCE=.\charset.c
-# End Source File
-# Begin Source File
-
 SOURCE=.\cldap.c
 # End Source File
 # Begin Source File
@@ -167,10 +167,6 @@ SOURCE=.\delete.c
 # End Source File
 # Begin Source File
 
-SOURCE=.\digest.c
-# End Source File
-# Begin Source File
-
 SOURCE=.\disptmpl.c
 # End Source File
 # Begin Source File
@@ -183,6 +179,10 @@ SOURCE=.\dn.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\dnssrv.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\dsparse.c
 # End Source File
 # Begin Source File
@@ -211,10 +211,6 @@ SOURCE=.\getdn.c
 # End Source File
 # Begin Source File
 
-SOURCE=.\getdxbyname.c
-# End Source File
-# Begin Source File
-
 SOURCE=.\getentry.c
 # End Source File
 # Begin Source File
@@ -335,6 +331,10 @@ SOURCE=.\sort.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\sortctrl.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\srchpref.c
 # End Source File
 # Begin Source File
@@ -347,6 +347,10 @@ SOURCE=.\string.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\tls.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\ufn.c
 # End Source File
 # Begin Source File
@@ -359,7 +363,15 @@ SOURCE=.\url.c
 # End Source File
 # Begin Source File
 
+SOURCE=".\utf-8.c"
+# End Source File
+# Begin Source File
+
 SOURCE=".\util-int.c"
 # End Source File
+# Begin Source File
+
+SOURCE=.\vlvctrl.c
+# End Source File
 # End Target
 # End Project
diff --git a/libraries/libldap/ltest.dsp b/libraries/libldap/ltest.dsp
new file mode 100644 (file)
index 0000000..16e6f14
--- /dev/null
@@ -0,0 +1,143 @@
+# Microsoft Developer Studio Project File - Name="ltest" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=ltest - Win32 Single Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "ltest.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "ltest.mak" CFG="ltest - Win32 Single Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "ltest - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "ltest - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "ltest - Win32 Single Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ltest - Win32 Single Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "ltest - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\ltest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 libsasl.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\Release"
+
+!ELSEIF  "$(CFG)" == "ltest - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "ltest___"
+# PROP BASE Intermediate_Dir "ltest___"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\ltest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 libsasl.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Debug"
+
+!ELSEIF  "$(CFG)" == "ltest - Win32 Single Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ltest___"
+# PROP BASE Intermediate_Dir "ltest___"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\ltest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 oldap32.lib olber32.lib olutil32.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\Release"
+# ADD LINK32 libsasl.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\SRelease"
+
+!ELSEIF  "$(CFG)" == "ltest - Win32 Single Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "ltest__0"
+# PROP BASE Intermediate_Dir "ltest__0"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\ltest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 oldap32.lib olber32.lib olutil32.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\Debug"
+# ADD LINK32 libsasl.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\SDebug"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "ltest - Win32 Release"
+# Name "ltest - Win32 Debug"
+# Name "ltest - Win32 Single Release"
+# Name "ltest - Win32 Single Debug"
+# Begin Source File
+
+SOURCE=.\test.c
+# End Source File
+# End Target
+# End Project
index 57e331daeb093cc1426eda758298b0fa6e70c79a..57cd4dbd43a411d8598d611c19426ccd465e3240 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
index a758fc160798fe3e844da0a38f52060ce0604df7..83a4b67a3e55c5bced91c8a5a0e66035fafe5f8c 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
index 209ec4315ad3814b6f1d3a125aad70c58edb488f..29108a3f38d12ae98343a644aec956d95fe09f53 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
@@ -59,8 +59,8 @@ ldap_rename(
        LDAP *ld,
        LDAP_CONST char *dn,
        LDAP_CONST char *newrdn,
-       int deleteoldrdn,
        LDAP_CONST char *newSuperior,
+       int deleteoldrdn,
        LDAPControl **sctrls,
        LDAPControl **cctrls,
        int *msgidp )
@@ -141,16 +141,16 @@ ldap_rename2(
        LDAP *ld,
        LDAP_CONST char *dn,
        LDAP_CONST char *newrdn,
-       int deleteoldrdn,
-       LDAP_CONST char *newSuperior )
+       LDAP_CONST char *newSuperior,
+       int deleteoldrdn )
 {
        int msgid;
        int rc;
 
        Debug( LDAP_DEBUG_TRACE, "ldap_rename2\n", 0, 0, 0 );
 
-       rc = ldap_rename( ld, dn, newrdn, deleteoldrdn, newSuperior,
-               NULL, NULL, &msgid );
+       rc = ldap_rename( ld, dn, newrdn, newSuperior,
+               deleteoldrdn, NULL, NULL, &msgid );
 
        return rc == LDAP_SUCCESS ? msgid : -1;
 }
@@ -173,13 +173,13 @@ ldap_modrdn2( LDAP *ld,
        LDAP_CONST char *newrdn,
        int deleteoldrdn )
 {
-       return ldap_rename2( ld, dn, newrdn, deleteoldrdn, NULL );
+       return ldap_rename2( ld, dn, newrdn, NULL, deleteoldrdn );
 }
 
 int
 ldap_modrdn( LDAP *ld, LDAP_CONST char *dn, LDAP_CONST char *newrdn )
 {
-       return( ldap_rename2( ld, dn, newrdn, 1, NULL ) );
+       return( ldap_rename2( ld, dn, newrdn, NULL, 1 ) );
 }
 
 
@@ -188,8 +188,8 @@ ldap_rename_s(
        LDAP *ld,
        LDAP_CONST char *dn,
        LDAP_CONST char *newrdn,
-       int deleteoldrdn,
        LDAP_CONST char *newSuperior,
+       int deleteoldrdn,
        LDAPControl **sctrls,
        LDAPControl **cctrls )
 {
@@ -197,8 +197,8 @@ ldap_rename_s(
        int msgid;
        LDAPMessage *res;
 
-       rc = ldap_rename( ld, dn, newrdn, deleteoldrdn,
-               newSuperior, sctrls, cctrls, &msgid );
+       rc = ldap_rename( ld, dn, newrdn, newSuperior,
+               deleteoldrdn, sctrls, cctrls, &msgid );
 
        if( rc != LDAP_SUCCESS ) {
                return rc;
@@ -218,21 +218,22 @@ ldap_rename2_s(
        LDAP *ld,
        LDAP_CONST char *dn,
        LDAP_CONST char *newrdn,
-       int deleteoldrdn,
-       LDAP_CONST char *newSuperior )
+       LDAP_CONST char *newSuperior,
+       int deleteoldrdn )
 {
-       return ldap_rename_s( ld, dn, newrdn, deleteoldrdn, newSuperior, NULL, NULL );
+       return ldap_rename_s( ld, dn, newrdn, newSuperior,
+               deleteoldrdn, NULL, NULL );
 }
 
 int
 ldap_modrdn2_s( LDAP *ld, LDAP_CONST char *dn, LDAP_CONST char *newrdn, int deleteoldrdn )
 {
-       return ldap_rename_s( ld, dn, newrdn, deleteoldrdn, NULL, NULL, NULL );
+       return ldap_rename_s( ld, dn, newrdn, NULL, deleteoldrdn, NULL, NULL );
 }
 
 int
 ldap_modrdn_s( LDAP *ld, LDAP_CONST char *dn, LDAP_CONST char *newrdn )
 {
-       return ldap_rename_s( ld, dn, newrdn, 1, NULL, NULL, NULL );
+       return ldap_rename_s( ld, dn, newrdn, NULL, 1, NULL, NULL );
 }
 
index e8785387f5507c4cb7b6f3328e1953b70d51ef4e..938739d7ebabb6b839ad737e960697c3db364287 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
 #include "portable.h"
 
 #include <stdio.h>
+#include <limits.h>
 
 #include <ac/stdlib.h>
 
+#include <ac/param.h>
 #include <ac/socket.h>
 #include <ac/string.h>
 #include <ac/time.h>
 
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
 #include "ldap-int.h"
 
+int ldap_open_defconn( LDAP *ld )
+{
+       if (( ld->ld_defconn = ldap_new_connection( ld, ld->ld_options.ldo_defludp, 1,1,NULL )) == NULL )
+       {
+               ld->ld_errno = LDAP_SERVER_DOWN;
+               return -1;
+       }
+
+       ++ld->ld_defconn->lconn_refcnt; /* so it never gets closed/freed */
+
+       return 0;
+}
 
 /*
  * ldap_open - initialize and connect to an ldap server.  A magic cookie to
@@ -40,8 +50,8 @@
 LDAP *
 ldap_open( LDAP_CONST char *host, int port )
 {
+       int rc;
        LDAP            *ld;
-       LDAPServer      *srv;
 
        Debug( LDAP_DEBUG_TRACE, "ldap_open\n", 0, 0, 0 );
 
@@ -49,22 +59,12 @@ ldap_open( LDAP_CONST char *host, int port )
                return( NULL );
        }
 
-       if (( srv = (LDAPServer *)LDAP_CALLOC( 1, sizeof( LDAPServer ))) ==
-           NULL || ( ld->ld_defhost != NULL && ( srv->lsrv_host =
-           LDAP_STRDUP( ld->ld_defhost )) == NULL )) {
-               if(srv != NULL) LDAP_FREE( (char*) srv );
-               ldap_ld_free( ld, 0, NULL, NULL );
-               return( NULL );
-       }
-       srv->lsrv_port = ld->ld_defport;
+       rc = ldap_open_defconn( ld );
 
-       if (( ld->ld_defconn = ldap_new_connection( ld, &srv, 1,1,0 )) == NULL ) {
-               if ( ld->ld_defhost != NULL ) LDAP_FREE( srv->lsrv_host );
-               LDAP_FREE( (char *)srv );
+       if( rc < 0 ) {
                ldap_ld_free( ld, 0, NULL, NULL );
                return( NULL );
        }
-       ++ld->ld_defconn->lconn_refcnt; /* so it never gets closed/freed */
 
        Debug( LDAP_DEBUG_TRACE, "ldap_open successful, ld_host is %s\n",
                ( ld->ld_host == NULL ) ? "(null)" : ld->ld_host, 0, 0 );
@@ -73,22 +73,22 @@ ldap_open( LDAP_CONST char *host, int port )
 }
 
 
-/*
- * ldap_init - initialize the LDAP library.  A magic cookie to be used for
- * future communication is returned on success, NULL on failure.
- * "host" may be a space-separated list of hosts or IP addresses
- *
- * Example:
- *     LDAP    *ld;
- *     ld = ldap_open( host, port );
- */
-LDAP *
-ldap_init( LDAP_CONST char *defhost, int defport )
+
+int
+ldap_create( LDAP **ldp )
 {
        LDAP                    *ld;
+       struct ldapoptions      *gopts;
 
-       if( ldap_int_global_options.ldo_valid != LDAP_INITIALIZED ) {
-               ldap_int_initialize();
+       *ldp = NULL;
+       /* Get pointer to global option structure */
+       if ( (gopts = LDAP_INT_GLOBAL_OPT()) == NULL) {
+               return LDAP_NO_MEMORY;
+       }
+
+       /* Initialize the global options, if not already done. */
+       if( gopts->ldo_valid != LDAP_INITIALIZED ) {
+               ldap_int_initialize(gopts, NULL);
        }
 
        Debug( LDAP_DEBUG_TRACE, "ldap_init\n", 0, 0, 0 );
@@ -96,15 +96,12 @@ ldap_init( LDAP_CONST char *defhost, int defport )
 #ifdef HAVE_WINSOCK2
 {      WORD wVersionRequested;
        WSADATA wsaData;
-       int err;
  
        wVersionRequested = MAKEWORD( 2, 0 );
-       err = WSAStartup( wVersionRequested, &wsaData );
-       if ( err != 0 ) {
+       if ( WSAStartup( wVersionRequested, &wsaData ) != 0 ) {
                /* Tell the user that we couldn't find a usable */
                /* WinSock DLL.                                  */
-               return NULL;
+               return LDAP_LOCAL_ERROR;
        }
  
        /* Confirm that the WinSock DLL supports 2.0.*/
@@ -119,164 +116,235 @@ ldap_init( LDAP_CONST char *defhost, int defport )
            /* Tell the user that we couldn't find a usable */
            /* WinSock DLL.                                  */
            WSACleanup( );
-           return NULL
+           return LDAP_LOCAL_ERROR
        }
 }      /* The WinSock DLL is acceptable. Proceed. */
 
 #elif HAVE_WINSOCK
 {      WSADATA wsaData;
        if ( WSAStartup( 0x0101, &wsaData ) != 0 ) {
-           return( NULL );
+           return LDAP_LOCAL_ERROR;
        }
 }
 #endif
 
        if ( (ld = (LDAP *) LDAP_CALLOC( 1, sizeof(LDAP) )) == NULL ) {
            WSACleanup( );
-               return( NULL );
+               return( LDAP_NO_MEMORY );
        }
    
        /* copy the global options */
-       memcpy(&ld->ld_options, &ldap_int_global_options,
-               sizeof(ld->ld_options));
+       memcpy(&ld->ld_options, gopts, sizeof(ld->ld_options));
 
        ld->ld_valid = LDAP_VALID_SESSION;
 
        /* but not pointers to malloc'ed items */
-       ld->ld_options.ldo_defbase = NULL;
-       ld->ld_options.ldo_defhost = NULL;
+       ld->ld_options.ldo_defludp = NULL;
        ld->ld_options.ldo_sctrls = NULL;
        ld->ld_options.ldo_cctrls = NULL;
 
-       if ( defhost != NULL ) {
-               ld->ld_options.ldo_defhost = LDAP_STRDUP( defhost );
-       } else {
-               ld->ld_options.ldo_defhost = LDAP_STRDUP(
-                       ldap_int_global_options.ldo_defhost);
-       }
+       ld->ld_options.ldo_defludp = ldap_url_duplist(gopts->ldo_defludp);
 
-       if ( ld->ld_options.ldo_defhost == NULL ) {
+       if ( ld->ld_options.ldo_defludp == NULL ) {
                LDAP_FREE( (char*)ld );
            WSACleanup( );
-               return( NULL );
-       }
-
-       if ( ldap_int_global_options.ldo_defbase != NULL ) {
-               ld->ld_options.ldo_defbase = LDAP_STRDUP(
-                       ldap_int_global_options.ldo_defbase);
+               return LDAP_NO_MEMORY;
        }
 
        if (( ld->ld_selectinfo = ldap_new_select_info()) == NULL ) {
-               LDAP_FREE( (char*) ld->ld_options.ldo_defhost );
-               if ( ld->ld_options.ldo_defbase == NULL ) {
-                       LDAP_FREE( (char*) ld->ld_options.ldo_defbase );
-               }
+               ldap_free_urllist( ld->ld_options.ldo_defludp );
                LDAP_FREE( (char*) ld );
            WSACleanup( );
-               return( NULL );
+               return LDAP_NO_MEMORY;
        }
 
-       if(defport != 0) {
-               ld->ld_defport = defport;
+       ld->ld_lberoptions = LBER_USE_DER;
+
+       ld->ld_sb = ber_sockbuf_alloc( );
+       if ( ld->ld_sb == NULL ) {
+               ldap_free_urllist( ld->ld_options.ldo_defludp );
+               LDAP_FREE( (char*) ld );
+               WSACleanup( );
+               return LDAP_NO_MEMORY;
        }
 
-       ld->ld_lberoptions = LBER_USE_DER;
+       *ldp = ld;
+       return LDAP_SUCCESS;
+}
 
-#if defined( STR_TRANSLATION ) && defined( LDAP_DEFAULT_CHARSET )
-       ld->ld_lberoptions |= LBER_TRANSLATE_STRINGS;
-#if LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET
-       ldap_set_string_translators( ld, ldap_8859_to_t61, ldap_t61_to_8859 );
-#endif /* LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET */
-#endif /* STR_TRANSLATION && LDAP_DEFAULT_CHARSET */
+/*
+ * ldap_init - initialize the LDAP library.  A magic cookie to be used for
+ * future communication is returned on success, NULL on failure.
+ * "host" may be a space-separated list of hosts or IP addresses
+ *
+ * Example:
+ *     LDAP    *ld;
+ *     ld = ldap_open( host, port );
+ */
+LDAP *
+ldap_init( LDAP_CONST char *defhost, int defport )
+{
+       LDAP *ld;
+       int rc;
+
+       rc = ldap_create(&ld);
+       if ( rc != LDAP_SUCCESS )
+               return NULL;
 
-       /* we'll assume we're talking version 2 for now */
-       ld->ld_version = LDAP_VERSION2;
+       if (defport != 0)
+               ld->ld_options.ldo_defport = defport;
 
-       ber_pvt_sb_init( &(ld->ld_sb) );
+       if (defhost != NULL) {
+               rc = ldap_set_option(ld, LDAP_OPT_HOST_NAME, defhost);
+               if ( rc != LDAP_SUCCESS ) {
+                       ldap_ld_free(ld, 1, NULL, NULL);
+                       return NULL;
+               }
+       }
 
        return( ld );
 }
 
 
 int
-open_ldap_connection( LDAP *ld, Sockbuf *sb, const char *host, int defport,
+ldap_initialize( LDAP **ldp, LDAP_CONST char *url )
+{
+       int rc;
+       LDAP *ld;
+
+       *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;
+               }
+       }
+
+       *ldp = ld;
+       return LDAP_SUCCESS;
+}
+
+int
+ldap_start_tls ( LDAP *ld,
+                               LDAPControl **serverctrls,
+                               LDAPControl **clientctrls )
+{
+#ifdef HAVE_TLS
+       LDAPConn *lc;
+       int rc;
+       char *rspoid = NULL;
+       struct berval *rspdata = NULL;
+
+       if (ld->ld_conns == NULL) {
+               rc = ldap_open_defconn( ld );
+               if (rc != LDAP_SUCCESS)
+                       return(rc);
+       }
+
+       for (lc = ld->ld_conns; lc != NULL; lc = lc->lconn_next) {
+               if (ldap_pvt_tls_inplace(lc->lconn_sb) != 0)
+                       return LDAP_OPERATIONS_ERROR;
+               rc = ldap_extended_operation_s(ld, LDAP_EXOP_START_TLS,
+                                                       NULL, serverctrls, clientctrls, &rspoid, &rspdata);
+               if (rc != LDAP_SUCCESS)
+                       return rc;
+               if (rspoid != NULL)
+                       LDAP_FREE(rspoid);
+               if (rspdata != NULL)
+                       ber_bvfree(rspdata);
+               rc = ldap_pvt_tls_start( ld, lc->lconn_sb, ld->ld_options.ldo_tls_ctx );
+               if (rc != LDAP_SUCCESS)
+                       return rc;
+       }
+       return LDAP_SUCCESS;
+#else
+       return LDAP_NOT_SUPPORTED;
+#endif
+}
+
+int
+open_ldap_connection( LDAP *ld, Sockbuf *sb, LDAPURLDesc *srv,
        char **krbinstancep, int async )
 {
-       int                     rc = -1;
-       int                             port;
-       const char              *p, *q;
-       char                    *r, *curhost, hostname[ 2*MAXHOSTNAMELEN ];
+       int rc = -1;
+       int port;
+       long addr;
 
        Debug( LDAP_DEBUG_TRACE, "open_ldap_connection\n", 0, 0, 0 );
 
-       defport = htons( (short) defport );
-
-       if ( host != NULL ) {
-               for ( p = host; p != NULL && *p != '\0'; p = q ) {
-                       if (( q = strchr( p, ' ' )) != NULL ) {
-                               strncpy( hostname, p, q - p );
-                               hostname[ q - p ] = '\0';
-                               curhost = hostname;
-                               while ( *q == ' ' ) {
-                                   ++q;
-                               }
-                       } else {
-                               curhost = (char *) p;   /* avoid copy if possible */
-                               q = NULL;
-                       }
-
-                       if (( r = strchr( curhost, ':' )) != NULL ) {
-                           if ( curhost != hostname ) {
-                               strcpy( hostname, curhost );    /* now copy */
-                               r = hostname + ( r - curhost );
-                               curhost = hostname;
-                           }
-                           *r++ = '\0';
-                           port = htons( (short) atoi( r ) );
-                       } else {
-                           port = defport;   
-                       }
-
-                       if (( rc = ldap_connect_to_host( ld, sb, curhost, 0L,
-                           port, async )) != -1 ) {
-                               break;
-                       }
-               }
-       } else {
-               rc = ldap_connect_to_host( ld, sb, 0, htonl( INADDR_LOOPBACK ),
-                   defport, async );
+       port = srv->lud_port;
+       if (port == 0)
+               port = ld->ld_options.ldo_defport;
+       port = htons( (short) port );
+
+       addr = 0;
+       if ( srv->lud_host == NULL || *srv->lud_host == 0 )
+               addr = htonl( INADDR_LOOPBACK );
+
+       switch ( ldap_pvt_url_scheme2proto( srv->lud_scheme ) ) {
+               case LDAP_PROTO_TCP:
+                       rc = ldap_connect_to_host( ld, sb, srv->lud_host,
+                               addr, port, async );
+                       if ( rc == -1 )
+                               return rc;
+                       ber_sockbuf_add_io( sb, &ber_sockbuf_io_tcp,
+                               LBER_SBIOD_LEVEL_PROVIDER, NULL );
+                       break;
+               case LDAP_PROTO_UDP:
+                       rc = ldap_connect_to_host( ld, sb, srv->lud_host,
+                               addr, port, async );
+                       if ( rc == -1 )
+                               return rc;
+                       ber_sockbuf_add_io( sb, &ber_sockbuf_io_udp,
+                               LBER_SBIOD_LEVEL_PROVIDER, NULL );
+                       break;
+               case LDAP_PROTO_IPC:
+#ifdef LDAP_PF_UNIX
+                       /* only IPC mechanism supported is PF_UNIX */
+                       rc = ldap_connect_to_path( ld, sb, srv->lud_host,
+                               async );
+                       if ( rc == -1 )
+                               return rc;
+                       ber_sockbuf_add_io( sb, &ber_sockbuf_io_fd,
+                               LBER_SBIOD_LEVEL_PROVIDER, NULL );
+                       break;
+#endif /* LDAP_PF_UNIX */
+               default:
+                       return -1;
+                       break;
        }
 
-       if ( rc == -1 ) {
-               return( rc );
-       }
-   
-       ber_pvt_sb_set_io( sb, &ber_pvt_sb_io_tcp, NULL );
+       ber_sockbuf_add_io( sb, &ber_sockbuf_io_readahead,
+               LBER_SBIOD_LEVEL_PROVIDER, NULL );
+#ifdef LDAP_DEBUG
+       ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug, INT_MAX, NULL );
+#endif
 
 #ifdef HAVE_TLS
-       if ( ld->ld_options.ldo_tls_mode == LDAP_OPT_X_TLS_HARD ) {
-               /*
-                * Fortunately, the lib uses blocking io...
-                */
-               if ( ldap_pvt_tls_connect( sb, ld->ld_options.ldo_tls_ctx ) < 
-                    0 ) {
-                       return -1;
-               }
-               /* FIXME: hostname of server must be compared with name in
-                * certificate....
-                */
+       if (ld->ld_options.ldo_tls_mode == LDAP_OPT_X_TLS_HARD ||
+               strcmp( srv->lud_scheme, "ldaps" ) == 0 )
+       {
+               rc = ldap_pvt_tls_start( ld, sb, ld->ld_options.ldo_tls_ctx );
+               if (rc != LDAP_SUCCESS)
+                       return rc;
        }
 #endif
+
        if ( krbinstancep != NULL ) {
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
                char *c;
                if (( *krbinstancep = ldap_host_connected_to( sb )) != NULL &&
                    ( c = strchr( *krbinstancep, '.' )) != NULL ) {
                        *c = '\0';
                }
-#else /* HAVE_KERBEROS */
-               krbinstancep = NULL;
-#endif /* HAVE_KERBEROS */
+#else /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
+               *krbinstancep = NULL;
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
        }
 
        return( 0 );
index 12edf629fcfc1852df3c05b2d292bae35fbe0429..879c70f3a897eddc6c0277b7dad37c2c06689db6 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -16,6 +16,8 @@
 
 #include "ldap-int.h"
 
+#define LDAP_OPT_REBIND_PROC 0x4e814d
+
 static const LDAPAPIFeatureInfo features[] = {
 #ifdef LDAP_API_FEATURE_X_OPENLDAP
        {       /* OpenLDAP Extensions API Feature */
@@ -61,13 +63,6 @@ static const LDAPAPIFeatureInfo features[] = {
                LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE
        },
 #endif
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
-       {       /* DNS */
-               LDAP_FEATURE_INFO_VERSION,
-               "X_OPENLDAP_V2_DNS",
-               LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
-       },
-#endif
 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
        {       /* V2 Referrals */
                LDAP_FEATURE_INFO_VERSION,
@@ -80,20 +75,23 @@ static const LDAPAPIFeatureInfo features[] = {
 
 int
 ldap_get_option(
-       LDAP_CONST LDAP *ld,
+       LDAP    *ld,
        int             option,
        void    *outvalue)
 {
-       LDAP_CONST struct ldapoptions *lo;
+       struct ldapoptions *lo;
 
-       if( ldap_int_global_options.ldo_valid != LDAP_INITIALIZED ) {
-               ldap_int_initialize();
+       /* Get pointer to global option structure */
+       lo = LDAP_INT_GLOBAL_OPT();   
+       if (NULL == lo) {
+               return LDAP_NO_MEMORY;
        }
 
-       if(ld == NULL) {
-               lo = &ldap_int_global_options;
+       if( lo->ldo_valid != LDAP_INITIALIZED ) {
+               ldap_int_initialize(lo, NULL);
+       }
 
-       } else {
+       if(ld != NULL) {
                assert( LDAP_VALID( ld ) );
 
                if( !LDAP_VALID( ld ) ) {
@@ -149,12 +147,12 @@ ldap_get_option(
                } break;
 
        case LDAP_OPT_DESC:
-               if(ld == NULL) {
+               if( ld == NULL || ld->ld_sb == NULL ) {
                        /* bad param */
                        break;
                } 
 
-               * (ber_socket_t *) outvalue = ber_pvt_sb_get_desc( &(ld->ld_sb) );
+               ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, outvalue );
                return LDAP_OPT_SUCCESS;
 
        case LDAP_OPT_TIMEOUT:
@@ -193,16 +191,8 @@ ldap_get_option(
                * (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_RESTART);
                return LDAP_OPT_SUCCESS;
 
-       case LDAP_OPT_DNS:      /* LDAPv2 */
-               * (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_DNS);
-               return LDAP_OPT_SUCCESS;
-
        case LDAP_OPT_PROTOCOL_VERSION:
-               if ((ld != NULL) && ld->ld_version) {
-                       * (int *) outvalue = ld->ld_version;
-               } else { 
-                       * (int *) outvalue = lo->ldo_version;
-               }
+               * (int *) outvalue = lo->ldo_version;
                return LDAP_OPT_SUCCESS;
 
        case LDAP_OPT_SERVER_CONTROLS:
@@ -218,7 +208,11 @@ ldap_get_option(
                return LDAP_OPT_SUCCESS;
 
        case LDAP_OPT_HOST_NAME:
-               * (char **) outvalue = LDAP_STRDUP(lo->ldo_defhost);
+               * (char **) outvalue = ldap_url_list2hosts(lo->ldo_defludp);
+               return LDAP_OPT_SUCCESS;
+
+       case LDAP_OPT_URI:
+               * (char **) outvalue = ldap_url_list2urls(lo->ldo_defludp);
                return LDAP_OPT_SUCCESS;
 
        case LDAP_OPT_ERROR_NUMBER:
@@ -287,7 +281,11 @@ ldap_get_option(
 
        default:
 #ifdef HAVE_TLS
-               if ( ldap_pvt_tls_get_option(lo, option, outvalue ) == 0 )
+               if ( ldap_pvt_tls_get_option((struct ldapoptions *)lo, option, outvalue ) == 0 )
+                       return LDAP_OPT_SUCCESS;
+#endif
+#ifdef HAVE_CYRUS_SASL
+               if ( ldap_pvt_sasl_get_option(ld, option, outvalue ) == 0 )
                        return LDAP_OPT_SUCCESS;
 #endif
                /* bad param */
@@ -304,15 +302,27 @@ ldap_set_option(
        LDAP_CONST void *invalue)
 {
        struct ldapoptions *lo;
+       int *dbglvl = NULL;
 
-       if( ldap_int_global_options.ldo_valid != LDAP_INITIALIZED ) {
-               ldap_int_initialize();
+       /* Get pointer to global option structure */
+       lo = LDAP_INT_GLOBAL_OPT();
+       if (lo == NULL) {
+               return LDAP_NO_MEMORY;
        }
 
-       if(ld == NULL) {
-               lo = &ldap_int_global_options;
+       /*
+        * The architecture to turn on debugging has a chicken and egg
+        * problem. Thus, we introduce a fix here.
+        */
+
+       if (option == LDAP_OPT_DEBUG_LEVEL)
+           dbglvl = (int *) invalue;
+
+       if( lo->ldo_valid != LDAP_INITIALIZED ) {
+               ldap_int_initialize(lo, dbglvl);
+       }
 
-       } else {
+       if(ld != NULL) {
                assert( LDAP_VALID( ld ) );
 
                if( !LDAP_VALID( ld ) ) {
@@ -407,6 +417,11 @@ ldap_set_option(
                                return LDAP_OPT_ERROR;
                        }
                } return LDAP_OPT_SUCCESS;
+
+       /* Only accessed from inside this function by ldap_set_rebind_proc() */
+       case LDAP_OPT_REBIND_PROC: {
+                       lo->ldo_rebindproc = (LDAP_REBIND_PROC *)invalue;               
+               } return LDAP_OPT_SUCCESS;
        }
 
        if(invalue == NULL) {
@@ -440,39 +455,77 @@ ldap_set_option(
                                /* not supported */
                                break;
                        }
-                       ld->ld_version = vers;
+                       lo->ldo_version = vers;
                } return LDAP_OPT_SUCCESS;
 
 
        case LDAP_OPT_HOST_NAME: {
                        const char *host = (const char *) invalue;
+                       LDAPURLDesc *ludlist = NULL;
+                       int rc = LDAP_OPT_SUCCESS;
+
+                       if(host != NULL) {
+                               rc = ldap_url_parsehosts(&ludlist, host);
+
+                       } else if(ld == NULL) {
+                               /*
+                                * must want global default returned
+                                * to initial condition.
+                                */
+                               rc = ldap_url_parselist(&ludlist, "ldap://localhost/");
 
-                       if(lo->ldo_defhost != NULL) {
-                               LDAP_FREE(lo->ldo_defhost);
-                               lo->ldo_defhost = NULL;
+                       } else {
+                               /*
+                                * must want the session default
+                                *   updated to the current global default
+                                */
+                               ludlist = ldap_url_duplist(
+                                       ldap_int_global_options.ldo_defludp);
+                               if (ludlist == NULL)
+                                       rc = LDAP_NO_MEMORY;
                        }
 
-                       if(host != NULL) {
-                               lo->ldo_defhost = LDAP_STRDUP(host);
-                               return LDAP_OPT_SUCCESS;
+                       if (rc == LDAP_OPT_SUCCESS) {
+                               if (lo->ldo_defludp != NULL)
+                                       ldap_free_urllist(lo->ldo_defludp);
+                               lo->ldo_defludp = ludlist;
                        }
+                       return rc;
+               }
 
-                       if(ld == NULL) {
+       case LDAP_OPT_URI: {
+                       const char *urls = (const char *) invalue;
+                       LDAPURLDesc *ludlist = NULL;
+                       int rc = LDAP_OPT_SUCCESS;
+
+                       if(urls != NULL) {
+                               rc = ldap_url_parselist(&ludlist, urls);
+
+                       } else if(ld == NULL) {
                                /*
                                 * must want global default returned
                                 * to initial condition.
                                 */
-                               lo->ldo_defhost = LDAP_STRDUP("localhost");
+                               rc = ldap_url_parselist(&ludlist, "ldap://localhost/");
 
                        } else {
                                /*
                                 * must want the session default
                                 *   updated to the current global default
                                 */
-                               lo->ldo_defhost = LDAP_STRDUP(
-                                       ldap_int_global_options.ldo_defhost);
+                               ludlist = ldap_url_duplist(
+                                       ldap_int_global_options.ldo_defludp);
+                               if (ludlist == NULL)
+                                       rc = LDAP_NO_MEMORY;
                        }
-               } return LDAP_OPT_SUCCESS;
+
+                       if (rc == LDAP_OPT_SUCCESS) {
+                               if (lo->ldo_defludp != NULL)
+                                       ldap_free_urllist(lo->ldo_defludp);
+                               lo->ldo_defludp = ludlist;
+                       }
+                       return rc;
+               }
 
        case LDAP_OPT_ERROR_NUMBER: {
                        int err = * (const int *) invalue;
@@ -525,11 +578,21 @@ ldap_set_option(
 
        default:
 #ifdef HAVE_TLS
-               if ( ldap_pvt_tls_set_option( lo, option, invalue ) == 0 )
-                       return LDAP_OPT_SUCCESS;
+               if ( ldap_pvt_tls_set_option( lo, option, (void *)invalue ) == 0 )
+               return LDAP_OPT_SUCCESS;
+#endif
+#ifdef HAVE_CYRUS_SASL
+               if ( ldap_pvt_sasl_set_option( ld, option, (void *)invalue ) == 0 )
+                       return LDAP_OPT_SUCCESS;
 #endif
                /* bad param */
                break;
        }
        return LDAP_OPT_ERROR;
 }
+
+LIBLDAP_F(int)
+ldap_set_rebind_proc( LDAP *ld, LDAP_REBIND_PROC *rebind_proc)
+{
+       return( ldap_set_option( ld, LDAP_OPT_REBIND_PROC, (void *)rebind_proc));
+}
index 2eb1c02eff228ad67b32453ea7679677b77770d7..c1c75e894ba527b0b879eb2917330abf92fa9a3e 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
@@ -46,7 +46,7 @@ int ldap_int_tblsize = 0;
 
 #define osip_debug(ld,fmt,arg1,arg2,arg3) \
 do { \
-       ldap_log_printf(ld, LDAP_DEBUG_TRACE, fmt, arg1, arg2, arg3); \
+       ldap_log_printf(NULL, LDAP_DEBUG_TRACE, fmt, arg1, arg2, arg3); \
 } while(0)
 
 static void
@@ -67,7 +67,7 @@ ldap_int_timeval_dup( struct timeval **dest, const struct timeval *src )
                return 0;
        }
 
-       new = (struct timeval *) malloc(sizeof(struct timeval));
+       new = (struct timeval *) LDAP_MALLOC(sizeof(struct timeval));
 
        if( new == NULL ) {
                *dest = NULL;
@@ -117,8 +117,13 @@ ldap_pvt_prepare_socket(LDAP *ld, int fd)
 #ifdef TCP_NODELAY
 {
        int dummy = 1;
-       if ( setsockopt( fd, IPPROTO_TCP, TCP_NODELAY, (char*) &dummy, sizeof(dummy) ) == -1 )
-               return -1;
+       if ( setsockopt( fd, IPPROTO_TCP, TCP_NODELAY,
+               (char*) &dummy, sizeof(dummy) ) == AC_SOCKET_ERROR )
+       {
+               osip_debug(ld, "ldap_prepare_socket: "
+                       "setsockopt(%d, TCP_NODELAY) failed (ignored).\n",
+                       fd, 0, 0);
+       }
 }
 #endif
        return 0;
@@ -127,10 +132,10 @@ ldap_pvt_prepare_socket(LDAP *ld, int fd)
 #undef TRACE
 #define TRACE do { \
        osip_debug(ld, \
-               "ldap_is_socket_ready: errror on socket %d: errno: %d (%s)\n", \
+               "ldap_is_socket_ready: error on socket %d: errno: %d (%s)\n", \
                s, \
                errno, \
-               strerror(errno) ); \
+               sock_errstr(errno) ); \
 } while( 0 )
 
 /*
@@ -182,6 +187,9 @@ ldap_pvt_connect(LDAP *ld, ber_socket_t s, struct sockaddr_in *sin, int async)
 {
        struct timeval  tv, *opt_tv=NULL;
        fd_set          wfds, *z=NULL;
+#ifdef HAVE_WINSOCK
+       fd_set          efds;
+#endif
 
        if ( (opt_tv = ld->ld_options.ldo_tm_net) != NULL ) {
                tv.tv_usec = opt_tv->tv_usec;
@@ -216,9 +224,30 @@ ldap_pvt_connect(LDAP *ld, ber_socket_t s, struct sockaddr_in *sin, int async)
        FD_ZERO(&wfds);
        FD_SET(s, &wfds );
 
-       if ( select(ldap_int_tblsize, z, &wfds, z, opt_tv ? &tv : NULL) == -1)
+#ifdef HAVE_WINSOCK
+       FD_ZERO(&efds);
+       FD_SET(s, &efds );
+#endif
+
+       if ( select(ldap_int_tblsize, z, &wfds,
+#ifdef HAVE_WINSOCK
+                   &efds,
+#else
+                   z,
+#endif
+                   opt_tv ? &tv : NULL) == -1)
                return ( -1 );
 
+#ifdef HAVE_WINSOCK
+       /* This means the connection failed */
+       if (FD_ISSET(s, &efds))
+       {
+           ldap_pvt_set_errno(WSAECONNREFUSED);
+           osip_debug(ld, "ldap_pvt_connect: error on socket %d: "
+                      "errno: %d (%s)\n", s, errno, sock_errstr(errno));
+           return -1;
+       }
+#endif
        if ( FD_ISSET(s, &wfds) ) {
                if ( ldap_pvt_is_socket_ready(ld, s) == -1 )
                        return ( -1 );
@@ -295,12 +324,12 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb, const char *host,
                        break;
                }
 
-               (void)memset((char *)&sin, 0, sizeof(struct sockaddr_in));
+               (void)memset((char *)&sin, '\0', sizeof(struct sockaddr_in));
                sin.sin_family = AF_INET;
                sin.sin_port = port;
-               p = (char *)&sin.sin_addr.s_addr;
+               p = (char *)&sin.sin_addr;
                q = use_hp ? (char *)hp->h_addr_list[i] : (char *)&address;
-               SAFEMEMCPY(p, q, sizeof(p) );
+               SAFEMEMCPY(p, q, sizeof(sin.sin_addr) );
 
                osip_debug(ld, "ldap_connect_to_host: Trying %s:%d\n", 
                                inet_ntoa(sin.sin_addr),ntohs(sin.sin_port),0);
@@ -308,7 +337,7 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb, const char *host,
                rc = ldap_pvt_connect(ld, s, &sin, async);
    
                if ( (rc == 0) || (rc == -2) ) {
-                       ber_pvt_sb_set_desc( sb, s );
+                       ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_FD, &s );
                        break;
                }
 
@@ -321,19 +350,11 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb, const char *host,
        return rc;
 }
 
-void
-ldap_close_connection( Sockbuf *sb )
-{
-       ber_pvt_sb_close( sb );
-}
-
-
-#if defined( HAVE_KERBEROS ) || defined( HAVE_TLS )
+#if defined( LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND ) || defined( HAVE_TLS ) || defined( HAVE_CYRUS_SASL )
 char *
 ldap_host_connected_to( Sockbuf *sb )
 {
        struct hostent          *hp;
-       char                    *p;
        socklen_t               len;
        struct sockaddr_in      sin;
 
@@ -341,12 +362,14 @@ ldap_host_connected_to( Sockbuf *sb )
        struct hostent          he_buf;
         int                    local_h_errno;
        char                    *ha_buf=NULL;
+       ber_socket_t            sd;
 #define DO_RETURN(x) if (ha_buf) LDAP_FREE(ha_buf); return (x);
    
-       (void)memset( (char *)&sin, 0, sizeof( struct sockaddr_in ));
+       (void)memset( (char *)&sin, '\0', sizeof( struct sockaddr_in ));
        len = sizeof( sin );
 
-       if ( getpeername( ber_pvt_sb_get_desc(sb), (struct sockaddr *)&sin, &len ) == -1 ) {
+       ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
+       if ( getpeername( sd, (struct sockaddr *)&sin, &len ) == -1 ) {
                return( NULL );
        }
 
@@ -370,7 +393,7 @@ ldap_host_connected_to( Sockbuf *sb )
 }
 #undef DO_RETURN   
    
-#endif /* HAVE_KERBEROS || HAVE_TLS */
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND || HAVE_TLS */
 
 
 /* for UNIX */
@@ -386,11 +409,13 @@ void
 ldap_mark_select_write( LDAP *ld, Sockbuf *sb )
 {
        struct selectinfo       *sip;
+       ber_socket_t            sd;
 
        sip = (struct selectinfo *)ld->ld_selectinfo;
        
-       if ( !FD_ISSET( ber_pvt_sb_get_desc(sb), &sip->si_writefds )) {
-               FD_SET( (u_int) sb->sb_sd, &sip->si_writefds );
+       ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
+       if ( !FD_ISSET( sd, &sip->si_writefds )) {
+               FD_SET( sd, &sip->si_writefds );
        }
 }
 
@@ -399,11 +424,13 @@ void
 ldap_mark_select_read( LDAP *ld, Sockbuf *sb )
 {
        struct selectinfo       *sip;
+       ber_socket_t            sd;
 
        sip = (struct selectinfo *)ld->ld_selectinfo;
 
-       if ( !FD_ISSET( ber_pvt_sb_get_desc(sb), &sip->si_readfds )) {
-               FD_SET( (u_int) sb->sb_sd, &sip->si_readfds );
+       ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
+       if ( !FD_ISSET( sd, &sip->si_readfds )) {
+               FD_SET( sd, &sip->si_readfds );
        }
 }
 
@@ -412,11 +439,13 @@ void
 ldap_mark_select_clear( LDAP *ld, Sockbuf *sb )
 {
        struct selectinfo       *sip;
+       ber_socket_t            sd;
 
        sip = (struct selectinfo *)ld->ld_selectinfo;
 
-       FD_CLR( (u_int) ber_pvt_sb_get_desc(sb), &sip->si_writefds );
-       FD_CLR( (u_int) ber_pvt_sb_get_desc(sb), &sip->si_readfds );
+       ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
+       FD_CLR( sd, &sip->si_writefds );
+       FD_CLR( sd, &sip->si_readfds );
 }
 
 
@@ -424,10 +453,12 @@ int
 ldap_is_write_ready( LDAP *ld, Sockbuf *sb )
 {
        struct selectinfo       *sip;
+       ber_socket_t            sd;
 
        sip = (struct selectinfo *)ld->ld_selectinfo;
 
-       return( FD_ISSET( ber_pvt_sb_get_desc(sb), &sip->si_use_writefds ));
+       ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
+       return( FD_ISSET( sd, &sip->si_use_writefds ));
 }
 
 
@@ -435,10 +466,12 @@ int
 ldap_is_read_ready( LDAP *ld, Sockbuf *sb )
 {
        struct selectinfo       *sip;
+       ber_socket_t            sd;
 
        sip = (struct selectinfo *)ld->ld_selectinfo;
 
-       return( FD_ISSET( ber_pvt_sb_get_desc(sb), &sip->si_use_readfds ));
+       ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
+       return( FD_ISSET( sd, &sip->si_use_readfds ));
 }
 
 
diff --git a/libraries/libldap/os-local.c b/libraries/libldap/os-local.c
new file mode 100644 (file)
index 0000000..6d45b25
--- /dev/null
@@ -0,0 +1,219 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*  Portions
+ *  Copyright (c) 1995 Regents of the University of Michigan.
+ *  All rights reserved.
+ *  Copyright (c) 1999 PADL Software Pty Ltd.
+ *  os-ip.c -- platform-specific domain socket code
+ */
+
+
+#include "portable.h"
+
+#ifdef LDAP_PF_UNIX
+
+#include <stdio.h>
+
+#include <ac/stdlib.h>
+
+#include <ac/errno.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/time.h>
+#include <ac/unistd.h>
+
+/* XXX non-portable */
+#include <sys/stat.h>
+
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif /* HAVE_IO_H */
+
+#include "ldap-int.h"
+
+/* int ldap_int_tblsize = 0; */
+
+#define oslocal_debug(ld,fmt,arg1,arg2,arg3) \
+do { \
+       ldap_log_printf(ld, LDAP_DEBUG_TRACE, fmt, arg1, arg2, arg3); \
+} while(0)
+
+static void
+ldap_pvt_set_errno(int err)
+{
+       errno = err;
+}
+
+static int
+ldap_pvt_ndelay_on(LDAP *ld, int fd)
+{
+       oslocal_debug(ld, "ldap_ndelay_on: %d\n",fd,0,0);
+       return ber_pvt_socket_set_nonblock( fd, 1 );
+}
+   
+static int
+ldap_pvt_ndelay_off(LDAP *ld, int fd)
+{
+       oslocal_debug(ld, "ldap_ndelay_off: %d\n",fd,0,0);
+       return ber_pvt_socket_set_nonblock( fd, 0 );
+}
+
+static ber_socket_t
+ldap_pvt_socket(LDAP *ld)
+{
+       ber_socket_t s = socket(AF_UNIX, SOCK_STREAM, 0);
+       oslocal_debug(ld, "ldap_new_socket: %d\n",s,0,0);
+       return ( s );
+}
+
+static int
+ldap_pvt_close_socket(LDAP *ld, int s)
+{
+       oslocal_debug(ld, "ldap_close_socket: %d\n",s,0,0);
+       return tcp_close(s);
+}
+
+#undef TRACE
+#define TRACE do { \
+       oslocal_debug(ld, \
+               "ldap_is_socket_ready: errror on socket %d: errno: %d (%s)\n", \
+               s, \
+               errno, \
+               strerror(errno) ); \
+} while( 0 )
+
+/*
+ * check the socket for errors after select returned.
+ */
+static int
+ldap_pvt_is_socket_ready(LDAP *ld, int s)
+{
+       oslocal_debug(ld, "ldap_is_sock_ready: %d\n",s,0,0);
+
+#if defined( notyet ) /* && defined( SO_ERROR ) */
+{
+       int so_errno;
+       int dummy = sizeof(so_errno);
+       if ( getsockopt( s, SOL_SOCKET, SO_ERROR, &so_errno, &dummy ) == -1 ) {
+               return -1;
+       }
+       if ( so_errno ) {
+               ldap_pvt_set_errno(so_errno);
+               TRACE;
+               return -1;
+       }
+       return 0;
+}
+#else
+{
+       /* error slippery */
+       struct sockaddr_un sun;
+       char ch;
+       int dummy = sizeof(sun);
+       if ( getpeername( s, (struct sockaddr *) &sun, &dummy ) == -1 ) {
+               /* XXX: needs to be replace with ber_stream_read() */
+               read(s, &ch, 1);
+               TRACE;
+               return -1;
+       }
+       return 0;
+}
+#endif
+       return -1;
+}
+#undef TRACE
+
+static int
+ldap_pvt_connect(LDAP *ld, ber_socket_t s, struct sockaddr_un *sun, int async)
+{
+       struct timeval  tv, *opt_tv=NULL;
+       fd_set          wfds, *z=NULL;
+
+       if ( (opt_tv = ld->ld_options.ldo_tm_net) != NULL ) {
+               tv.tv_usec = opt_tv->tv_usec;
+               tv.tv_sec = opt_tv->tv_sec;
+       }
+
+       oslocal_debug(ld, "ldap_connect_timeout: fd: %d tm: %ld async: %d\n",
+                       s, opt_tv ? tv.tv_sec : -1L, async);
+
+       if ( ldap_pvt_ndelay_on(ld, s) == -1 )
+               return ( -1 );
+
+       if ( connect(s, (struct sockaddr *) sun, sizeof(struct sockaddr_un)) == 0 )
+       {
+               if ( ldap_pvt_ndelay_off(ld, s) == -1 )
+                       return ( -1 );
+               return ( 0 );
+       }
+
+       if ( errno != EINPROGRESS && errno != EWOULDBLOCK ) {
+               return ( -1 );
+       }
+       
+#ifdef notyet
+       if ( async ) return ( -2 );
+#endif
+
+       FD_ZERO(&wfds);
+       FD_SET(s, &wfds );
+
+       if ( select(ldap_int_tblsize, z, &wfds, z, opt_tv ? &tv : NULL) == -1)
+               return ( -1 );
+
+       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 );
+               return ( 0 );
+       }
+       oslocal_debug(ld, "ldap_connect_timeout: timed out\n",0,0,0);
+       ldap_pvt_set_errno( ETIMEDOUT );
+       return ( -1 );
+}
+
+int
+ldap_connect_to_path(LDAP *ld, Sockbuf *sb, const char *path, int async)
+{
+       struct sockaddr_un      server;
+       ber_socket_t            s = AC_SOCKET_INVALID;
+       int                     rc, i, len;
+       char                    *ha_buf=NULL, *p, *q;
+
+       oslocal_debug(ld, "ldap_connect_to_path\n",0,0,0);
+
+       if ( (s = ldap_pvt_socket( ld )) == -1 ) {
+               return -1;
+       }
+
+       if ( path == NULL || path[0] == '\0' ) {
+               path = "/tmp/.ldap-sock";
+       } else {
+               if ( strlen(path) > (sizeof( server.sun_path ) - 1) ) {
+                       ldap_pvt_set_errno( ENAMETOOLONG );
+                       return -1;
+               }
+       }
+
+       oslocal_debug(ld, "ldap_connect_to_path: Trying %s\n", path, 0, 0);
+
+       memset( &server, '\0', sizeof(server) );
+       server.sun_family = AF_UNIX;
+       strcpy( server.sun_path, path );
+
+       rc = ldap_pvt_connect(ld, s, &server, async);
+
+       if (rc == 0) {
+               ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_FD, (void *)&s );
+       } else {
+               ldap_pvt_close_socket(ld, s);
+       }
+       return rc;
+}
+#else
+static int dummy;
+#endif /* LDAP_PF_UNIX */
index a6616c53ecad68ce0b66fe8a60b5e5a04ea24c8d..02b95bcc05f98712db79f49754636c01f092042c 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -26,7 +26,7 @@ static int ldap_log_check( LDAP *ld, int loglvl )
        if(ld == NULL) {
                errlvl = ldap_debug;
        } else {
-               errlvl = ld->ld_errno;
+               errlvl = ld->ld_debug;
        }
 
        return errlvl & loglvl ? 1 : 0;
index 371919db10de2318b04555649645fc194570e6fe..c42f652057cc9ce4ceb773ac92964bcf19df2c95 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
@@ -132,7 +132,7 @@ free_and_return:
                *referralsp = refs;
 
        } else {
-               ldap_value_free( refs );
+               LDAP_VFREE( refs );
        }
 
        if( freeit ) {
index 07da8e9bcec79d63a8c3a8c9dc862afc6082c72f..cb645b18a7dc9a3ab4529ace7461a31e74ac09df 100644 (file)
@@ -1,12 +1,29 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
  *  Copyright (c) 1995 Regents of the University of Michigan.
  *  All rights reserved.
+ */
+/*---
+ * This notice applies to changes, created by or for Novell, Inc.,
+ * to preexisting works for which notices appear elsewhere in this file.
+ *
+ * Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
  *
+ * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.
+ * USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO VERSION
+ * 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS AVAILABLE AT
+ * HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE" IN THE
+ * TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION OF THIS
+ * WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP PUBLIC
+ * LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT THE
+ * PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY. 
+ *---
+ * Modification to OpenLDAP source by Novell, Inc.
+ * April 2000 sfs  Added code to chase V3 referrals
  *  request.c - sending of ldap requests; handling of referrals
  */
 
 #include "ldap-int.h"
 #include "lber.h"
 
-static LDAPConn *find_connection LDAP_P(( LDAP *ld, LDAPServer *srv, int any ));
+static LDAPConn *find_connection LDAP_P(( LDAP *ld, LDAPURLDesc *srv, int any ));
 static void use_connection LDAP_P(( LDAP *ld, LDAPConn *lc ));
-static void free_servers LDAP_P(( LDAPServer *srvlist ));
 
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
-static LDAPServer *dn2servers LDAP_P(( LDAP *ld, const char *dn ));
-#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_DNS */
 
 static BerElement *re_encode_request LDAP_P((
        LDAP *ld,
        BerElement *origber,
     ber_int_t msgid,
-       char **dnp ));
+       char **dnp,
+       int      *type));
 
 
 BerElement *
@@ -47,10 +61,6 @@ ldap_alloc_ber_with_options( LDAP *ld )
 
     if (( ber = ber_alloc_t( ld->ld_lberoptions )) == NULL ) {
                ld->ld_errno = LDAP_NO_MEMORY;
-#ifdef STR_TRANSLATION
-       } else {
-               ldap_set_ber_options( ld, ber );
-#endif /* STR_TRANSLATION */
        }
 
        return( ber );
@@ -61,13 +71,6 @@ void
 ldap_set_ber_options( LDAP *ld, BerElement *ber )
 {
        ber->ber_options = ld->ld_lberoptions;
-#ifdef STR_TRANSLATION
-       if (( ld->ld_lberoptions & LBER_TRANSLATE_STRINGS ) != 0 ) {
-               ber_set_string_translators( ber,
-                   ld->ld_lber_encode_translate_proc,
-                   ld->ld_lber_decode_translate_proc );
-       }
-#endif /* STR_TRANSLATION */
 }
 
 
@@ -78,67 +81,25 @@ ldap_send_initial_request(
        const char *dn,
        BerElement *ber )
 {
-       LDAPServer      *servers, *srv;
+       LDAPURLDesc     *servers;
+       int rc;
 
        Debug( LDAP_DEBUG_TRACE, "ldap_send_initial_request\n", 0, 0, 0 );
 
-       if ( ! ber_pvt_sb_in_use(&ld->ld_sb ) ) {
+       if ( ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, NULL ) == -1 ) {
                /* not connected yet */
+               int rc = ldap_open_defconn( ld );
 
-               if (( srv = (LDAPServer *)LDAP_CALLOC( 1, sizeof( LDAPServer ))) ==
-                   NULL || ( ld->ld_defhost != NULL && ( srv->lsrv_host =
-                   LDAP_STRDUP( ld->ld_defhost )) == NULL ))
-               {
-                       if (srv != NULL) LDAP_FREE( srv );
+               if( rc < 0 ) {
                        ber_free( ber, 1 );
-                       ld->ld_errno = LDAP_NO_MEMORY;
                        return( -1 );
                }
 
-               srv->lsrv_port = ld->ld_defport;
-
-               if (( ld->ld_defconn = ldap_new_connection( ld, &srv, 1,1,0 ))
-                       == NULL )
-               {
-                       if ( ld->ld_defhost != NULL ) LDAP_FREE( srv->lsrv_host );
-                       LDAP_FREE( (char *)srv );
-                       ber_free( ber, 1 );
-                       ld->ld_errno = LDAP_SERVER_DOWN;
-                       return( -1 );
-               }
-               ++ld->ld_defconn->lconn_refcnt; /* so it never gets closed/freed */
-
                Debug( LDAP_DEBUG_TRACE,
                        "ldap_delayed_open successful, ld_host is %s\n",
                        ( ld->ld_host == NULL ) ? "(null)" : ld->ld_host, 0, 0 );
        }
 
-
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
-       if ( LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_DNS )
-               && ldap_is_dns_dn( dn ) )
-       {
-               if (( servers = dn2servers( ld, dn )) == NULL ) {
-                       ber_free( ber, 1 );
-                       return( -1 );
-               }
-
-#ifdef LDAP_DEBUG
-               if ( ldap_debug & LDAP_DEBUG_TRACE ) {
-                       LDAPServer      *srv;
-
-                       for ( srv = servers; srv != NULL;
-                           srv = srv->lsrv_next ) {
-                               fprintf( stderr,
-                                   "LDAP server %s:  dn %s, port %d\n",
-                                   srv->lsrv_host, ( srv->lsrv_dn == NULL ) ?
-                                   "(default)" : srv->lsrv_dn,
-                                   srv->lsrv_port );
-                       }
-               }
-#endif /* LDAP_DEBUG */
-       } else
-#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_DNS */
        {
                /*
                 * use of DNS is turned off or this is an X.500 DN...
@@ -147,8 +108,11 @@ ldap_send_initial_request(
                servers = NULL;
        }       
 
-       return( ldap_send_server_request( ld, ber, ld->ld_msgid, NULL, servers,
-           NULL, 0 ));
+       rc = ldap_send_server_request( ld, ber, ld->ld_msgid, NULL,
+                                                                       servers, NULL, NULL );
+       if (servers)
+               ldap_free_urllist(servers);
+       return(rc);
 }
 
 
@@ -159,9 +123,9 @@ ldap_send_server_request(
        BerElement *ber,
        ber_int_t msgid,
        LDAPRequest *parentreq,
-       LDAPServer *srvlist,
+       LDAPURLDesc *srvlist,
        LDAPConn *lc,
-       int bind )
+       LDAPreqinfo *bind )
 {
        LDAPRequest     *lr;
        int incparent;
@@ -177,14 +141,13 @@ ldap_send_server_request(
                } else {
                        if (( lc = find_connection( ld, srvlist, 1 )) ==
                            NULL ) {
-                               if ( bind && (parentreq != NULL) ) {
+                               if ( (bind != NULL) && (parentreq != NULL) ) {
                                        /* Remember the bind in the parent */
                                        incparent = 1;
                                        ++parentreq->lr_outrefcnt;
                                }
-                               lc = ldap_new_connection( ld, &srvlist, 0, 1, bind );
+                               lc = ldap_new_connection( ld, srvlist, 0, 1, bind );
                        }
-                       free_servers( srvlist );
                }
        }
 
@@ -267,15 +230,15 @@ ldap_send_server_request(
        return( msgid );
 }
 
-
 LDAPConn *
-ldap_new_connection( LDAP *ld, LDAPServer **srvlistp, int use_ldsb,
-       int connect, int bind )
+ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb,
+       int connect, LDAPreqinfo *bind )
 {
        LDAPConn        *lc;
-       LDAPServer      *prevsrv, *srv;
+       LDAPURLDesc     *srv;
        Sockbuf         *sb;
 
+       Debug( LDAP_DEBUG_TRACE, "ldap_new_connection\n", 0, 0, 0 );
        /*
         * make a new LDAP server connection
         * XXX open connection synchronously for now
@@ -289,35 +252,27 @@ ldap_new_connection( LDAP *ld, LDAPServer **srvlistp, int use_ldsb,
                return( NULL );
        }
 
-       lc->lconn_sb = ( use_ldsb ) ? &ld->ld_sb : sb;
+       lc->lconn_sb = ( use_ldsb ) ? ld->ld_sb : sb;
 
        if ( connect ) {
-               prevsrv = NULL;
-
-               for ( srv = *srvlistp; srv != NULL; srv = srv->lsrv_next ) {
+               for ( srv = srvlist; srv != NULL; srv = srv->lud_next ) {
                        if ( open_ldap_connection( ld, lc->lconn_sb,
-                           srv->lsrv_host, srv->lsrv_port,
-                           &lc->lconn_krbinstance, 0 ) != -1 ) {
+                                       srv, &lc->lconn_krbinstance, 0 ) != -1 )
+                       {
                                break;
                        }
-                       prevsrv = srv;
                }
 
                if ( srv == NULL ) {
-                   if ( !use_ldsb ) {
-                       ber_sockbuf_free( lc->lconn_sb );
-                   }
+                       if ( !use_ldsb ) {
+                               ber_sockbuf_free( lc->lconn_sb );
+                       }
                    LDAP_FREE( (char *)lc );
                    ld->ld_errno = LDAP_SERVER_DOWN;
                    return( NULL );
                }
 
-               if ( prevsrv == NULL ) {
-                   *srvlistp = srv->lsrv_next;
-               } else {
-                   prevsrv->lsrv_next = srv->lsrv_next;
-               }
-               lc->lconn_server = srv;
+               lc->lconn_server = ldap_url_dup(srv);
        }
 
        lc->lconn_status = LDAP_CONNST_CONNECTED;
@@ -328,71 +283,79 @@ ldap_new_connection( LDAP *ld, LDAPServer **srvlistp, int use_ldsb,
         * XXX for now, we always do a synchronous bind.  This will have
         * to change in the long run...
         */
-       if ( bind ) {
-               int             err, freepasswd, authmethod;
-               char            *binddn, *passwd;
+       if ( bind != NULL) {
+               int             err = 0;
                LDAPConn        *savedefconn;
 
-               freepasswd = err = 0;
-
-               if ( ld->ld_rebindproc == 0 ) {
-                       binddn = passwd = "";
-                       authmethod = LDAP_AUTH_SIMPLE;
-               } else {
-                       if (( err = (*ld->ld_rebindproc)( ld, &binddn, &passwd,
-                           &authmethod, 0 )) == LDAP_SUCCESS ) {
-                               freepasswd = 1;
+               /* Set flag to prevent additional referrals from being processed on this
+                * connection until the bind has completed
+                */
+               lc->lconn_rebind_inprogress = 1;
+               /* V3 rebind function */
+               if ( ld->ld_rebindproc != NULL) {
+                       LDAPURLDesc     *srvfunc;
+                       if( ( srvfunc = ldap_url_dup( srvlist)) == NULL) {
+                               ld->ld_errno = LDAP_NO_MEMORY;
+                               err = -1;
                        } else {
-                               ld->ld_errno = err;
+                               savedefconn = ld->ld_defconn;
+                               ++lc->lconn_refcnt;     /* avoid premature free */
+                               ld->ld_defconn = lc;
+
+                               Debug( LDAP_DEBUG_TRACE, "Call application rebindproc\n", 0, 0, 0);
+                               err = (*ld->ld_rebindproc)( ld, bind->ri_url, bind->ri_request, bind->ri_msgid);
+
+                               ld->ld_defconn = savedefconn;
+                               --lc->lconn_refcnt;
+
+                               if( err != 0) {
                                err = -1;
+                                       ldap_free_connection( ld, lc, 1, 0 );
+                                       lc = NULL;
                        }
+                               ldap_free_urldesc( srvfunc);
                }
-
-
-               if ( err == 0 ) {
+               } else {
                        savedefconn = ld->ld_defconn;
-                       ld->ld_defconn = lc;
                        ++lc->lconn_refcnt;     /* avoid premature free */
+                       ld->ld_defconn = lc;
 
-                       if ( ldap_bind_s( ld, binddn, passwd, authmethod ) !=
-                           LDAP_SUCCESS ) {
+                       Debug( LDAP_DEBUG_TRACE, "anonymous rebind via ldap_bind_s\n", 0, 0, 0);
+                       if ( ldap_bind_s( ld, "", "", LDAP_AUTH_SIMPLE ) != LDAP_SUCCESS ) {
                                err = -1;
                        }
-                       --lc->lconn_refcnt;
                        ld->ld_defconn = savedefconn;
-               }
-
-               if ( freepasswd ) {
-                       (*ld->ld_rebindproc)( ld, &binddn, &passwd,
-                               &authmethod, 1 );
-               }
+                       --lc->lconn_refcnt;
 
                if ( err != 0 ) {
                        ldap_free_connection( ld, lc, 1, 0 );
                        lc = NULL;
                }
        }
+               if( lc != NULL)
+                       lc->lconn_rebind_inprogress = 0;
+       }
 
        return( lc );
 }
 
 
 static LDAPConn *
-find_connection( LDAP *ld, LDAPServer *srv, int any )
+find_connection( LDAP *ld, LDAPURLDesc *srv, int any )
 /*
  * return an existing connection (if any) to the server srv
  * if "any" is non-zero, check for any server in the "srv" chain
  */
 {
        LDAPConn        *lc;
-       LDAPServer      *ls;
+       LDAPURLDesc     *ls;
 
        for ( lc = ld->ld_conns; lc != NULL; lc = lc->lconn_next ) {
-               for ( ls = srv; ls != NULL; ls = ls->lsrv_next ) {
-                       if ( lc->lconn_server->lsrv_host != NULL &&
-                           ls->lsrv_host != NULL && strcasecmp(
-                           ls->lsrv_host, lc->lconn_server->lsrv_host ) == 0
-                           && ls->lsrv_port == lc->lconn_server->lsrv_port ) {
+               for ( ls = srv; ls != NULL; ls = ls->lud_next ) {
+                       if ( lc->lconn_server->lud_host != NULL &&
+                           ls->lud_host != NULL && strcasecmp(
+                           ls->lud_host, lc->lconn_server->lud_host ) == 0
+                           && ls->lud_port == lc->lconn_server->lud_port ) {
                                return( lc );
                        }
                        if ( !any ) {
@@ -427,12 +390,12 @@ ldap_free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind )
                        if ( unbind ) {
                                ldap_send_unbind( ld, lc->lconn_sb, NULL, NULL );
                        }
-                       ldap_close_connection( lc->lconn_sb );
-                       ber_pvt_sb_destroy( lc->lconn_sb );
-                       if( lc->lconn_ber != NULL ) {
-                               ber_free( lc->lconn_ber, 1 );
-                       }
                }
+
+               if( lc->lconn_ber != NULL ) {
+                       ber_free( lc->lconn_ber, 1 );
+               }
+
                prevlc = NULL;
                for ( tmplc = ld->ld_conns; tmplc != NULL;
                    tmplc = tmplc->lconn_next ) {
@@ -446,13 +409,20 @@ ldap_free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind )
                        }
                        prevlc = tmplc;
                }
-               free_servers( lc->lconn_server );
+               ldap_free_urllist( lc->lconn_server );
                if ( lc->lconn_krbinstance != NULL ) {
                        LDAP_FREE( lc->lconn_krbinstance );
                }
-               if ( lc->lconn_sb != &ld->ld_sb ) {
+               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++) {
+                               LDAP_VFREE(lc->lconn_rebind_queue[i]);
+                       }
+                       LDAP_FREE( lc->lconn_rebind_queue);
+               }
                LDAP_FREE( lc );
                Debug( LDAP_DEBUG_TRACE, "ldap_free_connection: actually freed\n",
                    0, 0, 0 );
@@ -475,17 +445,33 @@ ldap_dump_connection( LDAP *ld, LDAPConn *lconns, int all )
        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->lsrv_host == NULL ) ? "(null)"
-                           : lc->lconn_server->lsrv_host,
-                           lc->lconn_server->lsrv_port, ( lc->lconn_sb ==
-                           &ld->ld_sb ) ? "  (default)" : "" );
+                           ( 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\n",
+               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]);
+                                       }
+                               }
+                       } else {
+                               fprintf( stderr, "    queue is empty\n");
+                       }
+               }
+               fprintf(stderr, "\n");
                if ( !all ) {
                        break;
                }
@@ -505,11 +491,12 @@ ldap_dump_requests_and_responses( LDAP *ld )
        }
        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_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" :
-               "Writing" );
+               ( lr->lr_status == LDAP_REQST_WRITING) ? "Writing" :
+               ( lr->lr_status == LDAP_REQST_COMPLETED ? "Request Completed" : "Invalid Status"));
            fprintf( stderr, "   outstanding referrals %d, parent count %d\n",
                    lr->lr_outrefcnt, lr->lr_parentcnt );
        }
@@ -578,25 +565,202 @@ ldap_free_request( LDAP *ld, LDAPRequest *lr )
        LDAP_FREE( lr );
 }
 
-
-static void
-free_servers( LDAPServer *srvlist )
+/*
+ * Chase v3 referrals
+ *
+ * Parameters:
+ *  (IN) ld = LDAP connection handle
+ *  (IN) lr = LDAP Request structure
+ *  (IN) refs = array of pointers to referral strings that we will chase
+ *              The array will be free'd by this function when no longer needed
+ *  (OUT) errstrp = Place to return a string of referrals which could not be followed
+ *  (OUT) hadrefp = 1 if sucessfully followed referral
+ *
+ * Return value - number of referrals followed
+ */
+LIBLDAP_F(int)
+ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, char **errstrp, int *hadrefp )
 {
-    LDAPServer *nextsrv;
+       char            *unfollowed;
+       int                      unfollowedcnt = 0;
+       LDAPRequest     *origreq;
+       LDAPURLDesc     *srv = NULL;
+       BerElement      *ber;
+       char            **refarray = NULL;
+       LDAPConn        *lc;
+       int                      rc, count, i, j;
+       LDAPreqinfo  rinfo;
+
+       ld->ld_errno = LDAP_SUCCESS;    /* optimistic */
+       *hadrefp = 0;
+
+       Debug( LDAP_DEBUG_TRACE, "ldap_chase_v3referrals\n", 0, 0, 0 );
+
+       unfollowed = NULL;
+       rc = count = 0;
 
-    while ( srvlist != NULL ) {
-       nextsrv = srvlist->lsrv_next;
-       if ( srvlist->lsrv_dn != NULL ) {
-               LDAP_FREE( srvlist->lsrv_dn );
+       /* If no referrals in array, return */
+       if ( (refs == NULL) || ( (refs)[0] == NULL) ) {
+               rc = 0;
+               goto done;
        }
-       if ( srvlist->lsrv_host != NULL ) {
-               LDAP_FREE( srvlist->lsrv_host );
+
+       /* Check for hop limit exceeded */
+       if ( lr->lr_parentcnt >= ld->ld_refhoplimit ) {
+               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;
+               goto done;
        }
-       LDAP_FREE( srvlist );
-       srvlist = nextsrv;
-    }
-}
 
+       /* find original request */
+       for ( origreq = lr; origreq->lr_parent != NULL; origreq = origreq->lr_parent ) {
+               ;
+       }
+
+       refarray = refs;
+       refs = NULL;
+       /* parse out & follow referrals */
+       for( i=0; refarray[i] != NULL; i++) {
+               /* Parse the referral URL */
+               if (( rc = ldap_url_parse( refarray[i], &srv)) != LDAP_SUCCESS) {
+                       ld->ld_errno = rc;
+                       rc = -1;
+                       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 ) {
+                       if( lc->lconn_rebind_inprogress) {
+                               /* We are already chasing a referral or search reference and a
+                                * bind on that connection is in progress.  We must queue
+                                * referrals on that connection, so we don't get a request
+                                * going out before the bind operation completes. This happens
+                                * if two search references come in one behind the other
+                                * for the same server with different contexts.
+                                */
+                               Debug( LDAP_DEBUG_TRACE, "ldap_chase_v3referrals: queue referral \"%s\"\n",
+                                       refarray[i], 0, 0);
+                               if( lc->lconn_rebind_queue == NULL ) {
+                                       /* Create a referral list */
+                                       if( (lc->lconn_rebind_queue = (char ***)LDAP_MALLOC( sizeof(void *) * 2)) == NULL) {
+                                               ld->ld_errno = LDAP_NO_MEMORY;
+                                               rc = -1;
+                                               goto done;
+                                       }
+                                       lc->lconn_rebind_queue[0] = refarray;
+                                       lc->lconn_rebind_queue[1] = NULL;
+                                       refarray = NULL;
+                               } else {
+                                       /* Count how many referral arrays we already have */
+                                       for( j = 0; lc->lconn_rebind_queue[j] != NULL; j++) {
+                                               ;
+                                       }
+                                       /* Add the new referral to the list */
+                                       if( (lc->lconn_rebind_queue = (char ***)LDAP_REALLOC(
+                                                       lc->lconn_rebind_queue, sizeof(void *) * (j + 2))) == NULL) {
+                                               ld->ld_errno = LDAP_NO_MEMORY;
+                                               rc = -1;
+                                               goto done;
+                                       }
+                                       lc->lconn_rebind_queue[j] = refarray;
+                                       lc->lconn_rebind_queue[j+1] = NULL;
+                                       refarray = NULL;
+                               }
+                               /* We have queued the referral/reference, now just return */
+                               rc = 0;
+                               *hadrefp = 1;
+                               count = 1; /* Pretend we already followed referral */
+                               goto done;
+                       }
+               } 
+               /* Re-encode the request with the new starting point of the search.
+                * Note: In the future we also need to replace the filter if one
+                * was provided with the search reference
+                */
+               if (( ber = re_encode_request( ld, origreq->lr_ber,
+                           ++ld->ld_msgid, &srv->lud_dn, &rinfo.ri_request )) == NULL ) {
+                       ld->ld_errno = LDAP_ENCODING_ERROR;
+                       rc = -1;
+                       goto done;
+               }
+
+               Debug( LDAP_DEBUG_TRACE, "ldap_chase_v3referral: msgid %d, url \"%s\"\n",
+                       lr->lr_msgid, refarray[i], 0);
+
+               /* Send the new request to the server - may require a bind */
+               rinfo.ri_msgid = origreq->lr_origid;
+               rinfo.ri_url = refarray[i];
+               if ( (rc = ldap_send_server_request( ld, ber, ld->ld_msgid,
+                       origreq, srv, NULL, &rinfo )) < 0 ) {
+                       /* Failure, try next referral in the list */
+                       Debug( LDAP_DEBUG_ANY, "Unable to chase referral \"%s\" (%s)\n", 
+                               refarray[i], ldap_err2string( ld->ld_errno ), 0);
+                       unfollowedcnt += ldap_append_referral( ld, &unfollowed, refarray[i]);
+                       ldap_free_urllist(srv);
+                       srv = NULL;
+               } else {
+                       /* Success, no need to try this referral list further */
+                       rc = 0;
+                       ++count;
+                       *hadrefp = 1;
+
+                       /* check if there is a queue of referrals that came in during bind */
+                       if( lc == NULL) {
+                               if (( lc = find_connection( ld, srv, 1 )) == NULL ) {
+                                       ld->ld_errno = LDAP_OPERATIONS_ERROR;
+                                       rc = -1;
+                                       goto done;
+                               }
+                       }
+
+                       if( lc->lconn_rebind_queue != NULL) {
+                               /* Release resources of previous list */
+                               LDAP_VFREE(refarray);
+                               refarray = NULL;
+                               ldap_free_urllist(srv);
+                               srv = NULL;
+
+                               /* Pull entries off end of queue so list always null terminated */
+                               for( j = 0; lc->lconn_rebind_queue[j] != NULL; j++) {
+                                       ;
+                               }
+                               refarray = lc->lconn_rebind_queue[j-1];
+                               lc->lconn_rebind_queue[j-1] = NULL;
+                               /* we pulled off last entry from queue, free queue */
+                               if ( j == 1 ) {
+                                       LDAP_FREE( lc->lconn_rebind_queue);
+                                       lc->lconn_rebind_queue = NULL;
+                               }
+                               /* restart the loop the with new referral list */
+                               i = -1;
+                               continue;
+                       }
+                       break; /* referral followed, break out of for loop */
+               }
+       } /* end for loop */
+done:
+       LDAP_VFREE(refarray);
+       ldap_free_urllist(srv);
+       LDAP_FREE( *errstrp );
+       
+       if( rc == 0) {
+               *errstrp = NULL;
+               LDAP_FREE( unfollowed );
+               return count;
+       } else {
+               ld->ld_errno = LDAP_REFERRAL;
+               *errstrp = unfollowed;
+               return rc;
+       }
+}
 
 /*
  * XXX merging of errors in this routine needs to be improved
@@ -605,13 +769,11 @@ int
 ldap_chase_referrals( LDAP *ld, LDAPRequest *lr, char **errstrp, int *hadrefp )
 {
        int             rc, count, len, newdn;
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
-       int             ldapref;
-#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_DNS */
        char            *p, *ports, *ref, *tmpref, *refdn, *unfollowed;
        LDAPRequest     *origreq;
-       LDAPServer      *srv;
+       LDAPURLDesc     *srv;
        BerElement      *ber;
+       LDAPreqinfo  rinfo;
 
        Debug( LDAP_DEBUG_TRACE, "ldap_chase_referrals\n", 0, 0, 0 );
 
@@ -655,9 +817,6 @@ ldap_chase_referrals( LDAP *ld, LDAPRequest *lr, char **errstrp, int *hadrefp )
 
        /* parse out & follow referrals */
        for ( ref = p; rc == 0 && ref != NULL; ref = p ) {
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
-               ldapref = 0;
-#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_DNS */
 
                if (( p = strchr( ref, '\n' )) != NULL ) {
                        *p++ = '\0';
@@ -665,22 +824,16 @@ ldap_chase_referrals( LDAP *ld, LDAPRequest *lr, char **errstrp, int *hadrefp )
                        p = NULL;
                }
 
+               ldap_pvt_hex_unescape( ref );
                len = strlen( ref );
+
+               /* FIXME: we should use the URL Parser */
+
                if ( len > LDAP_LDAP_REF_STR_LEN && strncasecmp( ref,
                    LDAP_LDAP_REF_STR, LDAP_LDAP_REF_STR_LEN ) == 0 ) {
                        Debug( LDAP_DEBUG_TRACE,
                            "chasing LDAP referral: <%s>\n", ref, 0, 0 );
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
-                       ldapref = 1;
-#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_DNS */
                        tmpref = ref + LDAP_LDAP_REF_STR_LEN;
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
-               } else if ( len > LDAP_DX_REF_STR_LEN && strncasecmp( ref,
-                   LDAP_DX_REF_STR, LDAP_DX_REF_STR_LEN ) == 0 ) {
-                       Debug( LDAP_DEBUG_TRACE,
-                           "chasing DX referral: <%s>\n", ref, 0, 0 );
-                       tmpref = ref + LDAP_DX_REF_STR_LEN;
-#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_DNS */
                } else {
                        Debug( LDAP_DEBUG_TRACE,
                            "ignoring unknown referral <%s>\n", ref, 0, 0 );
@@ -689,50 +842,55 @@ ldap_chase_referrals( LDAP *ld, LDAPRequest *lr, char **errstrp, int *hadrefp )
                        continue;
                }
 
+               /* copy the complete referral for rebind process */
+               rinfo.ri_url = LDAP_STRDUP( ref );
+
                *hadrefp = 1;
+
                if (( refdn = strchr( tmpref, '/' )) != NULL ) {
                        *refdn++ = '\0';
-                       newdn = 1;
+                       newdn = refdn[0] != '?' && refdn[0] != '\0';
+                       if( !newdn ) refdn = NULL;
                } else {
                        newdn = 0;
                }
 
                if (( ber = re_encode_request( ld, origreq->lr_ber,
-                   ++ld->ld_msgid, &refdn )) == NULL ) {
+                   ++ld->ld_msgid, &refdn, &rinfo.ri_request )) == NULL ) {
                        return( -1 );
                }
 
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
-               if ( ldapref ) {
-#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_DNS */
-                       if (( srv = (LDAPServer *)LDAP_CALLOC( 1,
-                           sizeof( LDAPServer ))) == NULL ) {
+                       if (( srv = (LDAPURLDesc *)LDAP_CALLOC( 1,
+                           sizeof( LDAPURLDesc ))) == NULL ) {
                                ber_free( ber, 1 );
                                ld->ld_errno = LDAP_NO_MEMORY;
                                return( -1 );
                        }
 
-                       if (( srv->lsrv_host = LDAP_STRDUP( tmpref )) == NULL ) {
+                       if (( srv->lud_scheme = LDAP_STRDUP("ldap")) == NULL ) {
                                LDAP_FREE( (char *)srv );
                                ber_free( ber, 1 );
                                ld->ld_errno = LDAP_NO_MEMORY;
                                return( -1 );
                        }
 
-                       if (( ports = strchr( srv->lsrv_host, ':' )) != NULL ) {
+                       if (( srv->lud_host = LDAP_STRDUP( tmpref )) == NULL ) {
+                               LDAP_FREE( (char *)srv );
+                               ber_free( ber, 1 );
+                               ld->ld_errno = LDAP_NO_MEMORY;
+                               return( -1 );
+                       }
+
+                       if (( ports = strchr( srv->lud_host, ':' )) != NULL ) {
                                *ports++ = '\0';
-                               srv->lsrv_port = atoi( ports );
+                               srv->lud_port = atoi( ports );
                        } else {
-                               srv->lsrv_port = ldap_int_global_options.ldo_defport;
+                               srv->lud_port = (LDAP_INT_GLOBAL_OPT())->ldo_defport;
                        }
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
-               } else {
-                       srv = dn2servers( ld, tmpref );
-               }
-#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_DNS */
 
+               rinfo.ri_msgid = origreq->lr_origid;
                if ( srv != NULL && ldap_send_server_request( ld, ber, ld->ld_msgid,
-                   lr, srv, NULL, 1 ) >= 0 ) {
+                   lr, srv, NULL, &rinfo ) >= 0 ) {
                        ++count;
                } else {
                        Debug( LDAP_DEBUG_ANY,
@@ -740,6 +898,10 @@ ldap_chase_referrals( LDAP *ld, LDAPRequest *lr, char **errstrp, int *hadrefp )
                            ldap_err2string( ld->ld_errno ), 0, 0 );
                        rc = ldap_append_referral( ld, &unfollowed, ref );
                }
+               LDAP_FREE( rinfo.ri_url);
+
+               if (srv != NULL)
+                       ldap_free_urllist(srv);
 
                if ( !newdn && refdn != NULL ) {
                        LDAP_FREE( refdn );
@@ -786,13 +948,12 @@ ldap_append_referral( LDAP *ld, char **referralsp, char *s )
 
 
 static BerElement *
-re_encode_request( LDAP *ld, BerElement *origber, ber_int_t msgid, char **dnp )
+re_encode_request( LDAP *ld, BerElement *origber, ber_int_t msgid, char **dnp, int *type )
 {
 /*
  * XXX this routine knows way too much about how the lber library works!
  */
        ber_int_t       along;
-       ber_len_t       len;
        ber_tag_t       tag;
        ber_int_t       ver;
        int             rc;
@@ -806,31 +967,34 @@ re_encode_request( LDAP *ld, BerElement *origber, ber_int_t msgid, char **dnp )
        tmpber = *origber;
 
        /*
-        * all LDAP requests are sequences that start with a message id,
-        * followed by a sequence that is tagged with the operation code
+        * all LDAP requests are sequences that start with a message id.
+        * For all except delete, this is followed by a sequence that is
+        * tagged with the operation code.  For delete, the provided DN
+        * is not wrapped by a sequence.
         */
-       if ( ber_scanf( &tmpber, "{i", /*}*/ &along ) != LDAP_TAG_MSGID ||
-           ( tag = ber_skip_tag( &tmpber, &len )) == LBER_DEFAULT ) {
-                ld->ld_errno = LDAP_DECODING_ERROR;
+       rc = ber_scanf( &tmpber, "{it", /*}*/ &along, &tag );
+
+       if ( rc == LBER_ERROR ) {
+               ld->ld_errno = LDAP_DECODING_ERROR;
                return( NULL );
        }
 
-        if (( ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
-                return( NULL );
-        }
+       assert( tag != 0);
+       if ( tag == LDAP_REQ_BIND ) {
+               /* bind requests have a version number before the DN & other stuff */
+               rc = ber_scanf( &tmpber, "{ia" /*}*/, &ver, &orig_dn );
 
-       /* bind requests have a version number before the DN & other stuff */
-       if ( tag == LDAP_REQ_BIND && ber_get_int( &tmpber, &ver ) ==
-           LBER_DEFAULT ) {
-                ld->ld_errno = LDAP_DECODING_ERROR;
-               ber_free( ber, 1 );
-               return( NULL );
+       } else if ( tag == LDAP_REQ_DELETE ) {
+               /* delete requests don't have a DN wrapping sequence */
+               rc = ber_scanf( &tmpber, "a", &orig_dn );
+
+       } else {
+               rc = ber_scanf( &tmpber, "{a" /*}*/, &orig_dn );
        }
 
-       /* the rest of the request is the DN followed by other stuff */
-       if ( ber_get_stringa( &tmpber, &orig_dn ) == LBER_DEFAULT ) {
-               ber_free( ber, 1 );
-               return( NULL );
+       if( rc == LBER_ERROR ) {
+               ld->ld_errno = LDAP_DECODING_ERROR;
+               return NULL;
        }
 
        if ( *dnp == NULL ) {
@@ -839,20 +1003,29 @@ re_encode_request( LDAP *ld, BerElement *origber, ber_int_t msgid, char **dnp )
                LDAP_FREE( orig_dn );
        }
 
+       if (( ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
+               return( NULL );
+       }
+
        if ( tag == LDAP_REQ_BIND ) {
                rc = ber_printf( ber, "{it{is" /*}}*/, msgid, tag, ver, *dnp );
+       } else if ( tag == LDAP_REQ_DELETE ) {
+               rc = ber_printf( ber, "{its}", msgid, tag, *dnp );
        } else {
                rc = ber_printf( ber, "{it{s" /*}}*/, msgid, tag, *dnp );
        }
 
        if ( rc == -1 ) {
+               ld->ld_errno = LDAP_ENCODING_ERROR;
                ber_free( ber, 1 );
                return( NULL );
        }
 
-       if ( ber_write( ber, tmpber.ber_ptr, ( tmpber.ber_end -
-           tmpber.ber_ptr ), 0 ) != ( tmpber.ber_end - tmpber.ber_ptr ) ||
-           ber_printf( ber, /*{{*/ "}}" ) == -1 ) {
+       if ( tag != LDAP_REQ_DELETE && (
+               ber_write(ber, tmpber.ber_ptr, ( tmpber.ber_end - tmpber.ber_ptr ), 0)
+               != ( tmpber.ber_end - tmpber.ber_ptr ) ||
+           ber_printf( ber, /*{{*/ "}}" ) == -1 ) )
+       {
                ld->ld_errno = LDAP_ENCODING_ERROR;
                ber_free( ber, 1 );
                return( NULL );
@@ -866,6 +1039,7 @@ re_encode_request( LDAP *ld, BerElement *origber, ber_int_t msgid, char **dnp )
        }
 #endif /* LDAP_DEBUG */
 
+       *type = tag;    /* return request type */
        return( ber );
 }
 
@@ -876,6 +1050,9 @@ ldap_find_request_by_msgid( LDAP *ld, ber_int_t msgid )
        LDAPRequest     *lr;
 
        for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
+               if( lr->lr_status == LDAP_REQST_COMPLETED ) {
+                       continue;       /* Skip completed requests */
+               }
                if ( msgid == lr->lr_msgid ) {
                        break;
                }
@@ -885,86 +1062,3 @@ ldap_find_request_by_msgid( LDAP *ld, ber_int_t msgid )
 }
 
 
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
-static LDAPServer *
-dn2servers( LDAP *ld, const char *dn ) /* dn can also be a domain.... */
-{
-       char            *p, *host, *server_dn, **dxs;
-       const char *domain;
-       int             i, port;
-       LDAPServer      *srvlist, *prevsrv, *srv;
-
-       if (( domain = strrchr( dn, '@' )) != NULL ) {
-               ++domain;
-       } else {
-               domain = dn;
-       }
-
-       if (( dxs = ldap_getdxbyname( domain )) == NULL ) {
-               ld->ld_errno = LDAP_NO_MEMORY;
-               return( NULL );
-       }
-
-       srvlist = NULL;
-
-       for ( i = 0; dxs[ i ] != NULL; ++i ) {
-               port = ldap_int_global_options.ldo_defport;
-               server_dn = NULL;
-               if ( strchr( dxs[ i ], ':' ) == NULL ) {
-                       host = dxs[ i ];
-               } else if ( strlen( dxs[ i ] ) >= 7 &&
-                   strncmp( dxs[ i ], "ldap://", 7 ) == 0 ) {
-                       host = dxs[ i ] + 7;
-                       if (( p = strchr( host, ':' )) == NULL ) {
-                               p = host;
-                       } else {
-                               *p++ = '\0';
-                               port = atoi( p );
-                       }
-                       if (( p = strchr( p, '/' )) != NULL ) {
-                               server_dn = ++p;
-                               if ( *server_dn == '\0' ) {
-                                       server_dn = NULL;
-                               }
-                       }
-               } else {
-                       host = NULL;
-               }
-
-               if ( host != NULL ) {   /* found a server we can use */
-                       if (( srv = (LDAPServer *)LDAP_CALLOC( 1,
-                           sizeof( LDAPServer ))) == NULL ) {
-                               free_servers( srvlist );
-                               srvlist = NULL;
-                               break;          /* exit loop & return */
-                       }
-
-                       /* add to end of list of servers */
-                       if ( srvlist == NULL ) {
-                               srvlist = srv;
-                       } else {
-                               prevsrv->lsrv_next = srv;
-                       }
-                       prevsrv = srv;
-                       
-                       /* copy in info. */
-                       if (( srv->lsrv_host = LDAP_STRDUP( host )) == NULL ||
-                           ( server_dn != NULL && ( srv->lsrv_dn =
-                           LDAP_STRDUP( server_dn )) == NULL )) {
-                               free_servers( srvlist );
-                               srvlist = NULL;
-                               break;          /* exit loop & return */
-                       }
-                       srv->lsrv_port = port;
-               }
-       }
-
-       ldap_value_free( dxs );
-
-       if ( srvlist == NULL ) {
-               ld->ld_errno = LDAP_SERVER_DOWN;
-       }
-
-       return( srvlist );
-}
-#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_DNS */
index a47e0577e97b557058ea13bbcf557a01f6b94564..475effc9d5c062caa9b4e015e625a0eb752f01c3 100644 (file)
@@ -1,11 +1,29 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
  *  Copyright (c) 1990 Regents of the University of Michigan.
  *  All rights reserved.
+ */
+/*---
+ * This notice applies to changes, created by or for Novell, Inc.,
+ * to preexisting works for which notices appear elsewhere in this file.
+ *
+ * Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
+ *
+ * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.
+ * USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO VERSION
+ * 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS AVAILABLE AT
+ * HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE" IN THE
+ * TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION OF THIS
+ * WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP PUBLIC
+ * LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT THE
+ * PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY. 
+ *---
+ * Modification to OpenLDAP source by Novell, Inc.
+ * April 2000 sfs Add code to process V3 referrals and search results
  *
  *  result.c - wait for an ldap result
  */
@@ -114,7 +132,7 @@ ldap_result(
                if ( msgid == LDAP_RES_ANY || lm->lm_msgid == msgid ) {
                        LDAPMessage     *tmp;
 
-                       if ( all == 0
+                       if ( all == LDAP_MSG_ONE
                            || (lm->lm_msgtype != LDAP_RES_SEARCH_RESULT
                            && lm->lm_msgtype != LDAP_RES_SEARCH_REFERENCE      /* LDAPv3 */
                            && lm->lm_msgtype != LDAP_RES_SEARCH_ENTRY) )
@@ -138,14 +156,17 @@ ldap_result(
        }
 
        if ( lastlm == NULL ) {
-               ld->ld_responses = (all == 0 && lm->lm_chain != NULL
+               ld->ld_responses = (all == LDAP_MSG_ONE && lm->lm_chain != NULL
                    ? lm->lm_chain : lm->lm_next);
        } else {
-               lastlm->lm_next = (all == 0 && lm->lm_chain != NULL
+               lastlm->lm_next = (all == LDAP_MSG_ONE && lm->lm_chain != NULL
                    ? lm->lm_chain : lm->lm_next);
        }
-       if ( all == 0 )
+       if ( all == LDAP_MSG_ONE && lm->lm_chain != NULL )
+       {
+               lm->lm_chain->lm_next = lm->lm_next;
                lm->lm_chain = NULL;
+       }
        lm->lm_next = NULL;
 
        *result = lm;
@@ -197,7 +218,8 @@ wait4msg(
                }
 #endif /* LDAP_DEBUG */
                for ( lc = ld->ld_conns; lc != NULL; lc = lc->lconn_next ) {
-                       if ( ber_pvt_sb_data_ready(lc->lconn_sb) ) {
+                       if ( ber_sockbuf_ctrl( lc->lconn_sb,
+                                       LBER_SB_OPT_DATA_READY, NULL ) ) {
                                rc = try_read1msg( ld, msgid, all, lc->lconn_sb,
                                    lc, result );
                                break;
@@ -276,10 +298,15 @@ try_read1msg(
        ber_tag_t       tag;
        ber_len_t       len;
        int             foundit = 0;
-       LDAPRequest     *lr;
+       LDAPRequest     *lr, *tmplr;
        BerElement      tmpber;
        int             rc, refer_cnt, hadref, simple_request;
        ber_int_t       lderr;
+       /*
+        * v3ref = flag for V3 referral / search reference
+        * 0 = not a ref, 1 = sucessfully chased ref, -1 = pass ref to application
+        */
+       int     v3ref;
 
        assert( ld != NULL );
        assert( lc != NULL );
@@ -335,6 +362,7 @@ try_read1msg(
        /* if it's been abandoned, toss it */
        if ( ldap_abandoned( ld, id ) ) {
                ber_free( ber, 1 );
+               Debug( LDAP_DEBUG_ANY, "abandoned\n", 0, 0, 0);
                return( -2 );   /* continue looking */
        }
 
@@ -353,10 +381,10 @@ try_read1msg(
                return( -1 );
        }
 
-       Debug( LDAP_DEBUG_TRACE, "ldap_read: %s msgid %ld, original id %ld\n",
+       Debug( LDAP_DEBUG_TRACE, "ldap_read: message type %s msgid %ld, original id %ld\n",
            ( tag == LDAP_RES_SEARCH_ENTRY ) ? "entry" : 
                ( tag == LDAP_RES_SEARCH_REFERENCE ) ? "reference" : "result",
-               (long) id, (long) lr->lr_origid );
+               (long) lr->lr_msgid, (long) lr->lr_origid );
 
        id = lr->lr_origid;
        refer_cnt = 0;
@@ -364,12 +392,96 @@ try_read1msg(
        rc = -2;        /* default is to keep looking (no response found) */
        lr->lr_res_msgtype = tag;
 
-       if ( tag != LDAP_RES_SEARCH_ENTRY ) {
+       /*
+        * This code figures out if we are going to chase a
+        * referral / search reference, or pass it back to the application
+        */
+       v3ref = 0;      /* Assume not a V3 search reference or 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) {
+                       /* This is a V3 search reference */
+                       /* Assume we do not chase the reference, but pass it to application */
+                       v3ref = -1;
+                       if( LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_REFERRALS) ||
+                                       (lr->lr_parent != NULL) )
+                       {
+                               /* Get the referral list */
+                               if ( ber_scanf( &tmpber, "{v}", &refs ) == LBER_ERROR ) {
+                                       rc = LDAP_DECODING_ERROR;
+                               } else {
+                                       /* Note: refs arrary is freed by ldap_chase_v3referrals */
+                                       refer_cnt = ldap_chase_v3referrals( ld, lr, refs,
+                                           &lr->lr_res_error, &hadref );
+                                       if ( refer_cnt > 0 ) {  /* sucessfully chased reference */
+                                               /* If haven't got end search, set chasing referrals */
+                                               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);
+                                               }
+                                               v3ref = 1;      /* We sucessfully chased the reference */
+                                       }
+                               }
+                       }
+               } else {
+                       /* Check for V3 referral */
+                       ber_len_t len;
+                       if ( ber_scanf( &tmpber, "{iaa",/*}*/ &lderr,
+                                   &lr->lr_res_matched, &lr->lr_res_error )
+                                   != LBER_ERROR ) {
+                               /* Check if V3 referral */
+                               if( ber_peek_tag( &tmpber, &len) == LDAP_TAG_REFERRAL ) {
+                                       /* We have a V3 referral, assume we cannot chase it */
+                                       v3ref = -1;
+                                       if( LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_REFERRALS)
+                                                        || (lr->lr_parent != NULL) )
+                                       {
+                                               v3ref = -1;  /* Assume referral not chased and return it to app */
+                                               /* Get the referral list */
+                                               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, id = %d\n",
+                                                                   lr->lr_msgid, 0, 0);
+                                               } else {
+                                                       /* Chase the referral 
+                                                        * Note: refs arrary is freed by ldap_chase_v3referrals
+                                                        */
+                                                       refer_cnt = ldap_chase_v3referrals( ld, lr, refs,
+                                                           &lr->lr_res_error, &hadref );
+                                                       lr->lr_status = LDAP_REQST_COMPLETED;
+                                                       Debug( LDAP_DEBUG_TRACE,
+                                                           "read1msg:  referral chased, mark request completed, id = %d\n",
+                                                           lr->lr_msgid, 0, 0);
+                                                       if( refer_cnt > 0) {
+                                                               v3ref = 1;  /* Referral successfully chased */
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /* 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) && (v3ref > -1) ) {
+               /* For a v3 search referral/reference, only come here if already chased it */
                if ( ld->ld_version >= LDAP_VERSION2 &&
                        ( lr->lr_parent != NULL ||
                        LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_REFERRALS) ) )
                {
                        tmpber = *ber;  /* struct copy */
+                       if ( v3ref == 1 ) {
+                               ; /* V3 search reference or V3 referral sucessfully chased */
+                       } else
                        if ( ber_scanf( &tmpber, "{iaa}", &lderr,
                            &lr->lr_res_matched, &lr->lr_res_error )
                            != LBER_ERROR ) {
@@ -377,6 +489,9 @@ try_read1msg(
                                        /* referrals are in error string */
                                        refer_cnt = ldap_chase_referrals( ld, lr,
                                            &lr->lr_res_error, &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);
                                }
 
                                /* save errno, message, and matched string */
@@ -405,7 +520,7 @@ Debug( LDAP_DEBUG_TRACE,
                        if ( refer_cnt < 0 ) {
                                return( -1 );   /* fatal error */
                        }
-                       lr->lr_status = LDAP_REQST_CHASINGREFS;
+                       lr->lr_res_errno = LDAP_SUCCESS; /* sucessfully chased referral */
                } else {
                        if ( lr->lr_outrefcnt <= 0 && lr->lr_parent == NULL ) {
                                /* request without any referrals */
@@ -416,6 +531,9 @@ Debug( LDAP_DEBUG_TRACE,
                                ber = NULL;
                        }
 
+                       lr->lr_status = LDAP_REQST_COMPLETED; /* declare this request done */
+                       Debug( LDAP_DEBUG_TRACE,
+                           "read1msg:  mark request completed, id = %d\n", lr->lr_msgid, 0, 0);
                        while ( lr->lr_parent != NULL ) {
                                merge_error_info( ld, lr->lr_parent, lr );
 
@@ -425,7 +543,15 @@ Debug( LDAP_DEBUG_TRACE,
                                }
                        }
 
-                       if ( lr->lr_outrefcnt <= 0 && lr->lr_parent == NULL ) {
+                       /* Check if all requests are finished, lr is now parent */
+                       for(tmplr=lr ; tmplr != NULL; tmplr=tmplr->lr_refnext) {
+                               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 && tmplr == NULL ) {
                                id = lr->lr_msgid;
                                tag = lr->lr_res_msgtype;
                                Debug( LDAP_DEBUG_ANY, "request %ld done\n",
@@ -474,9 +600,10 @@ lr->lr_res_matched ? lr->lr_res_matched : "" );
 
        /* is this the one we're looking for? */
        if ( msgid == LDAP_RES_ANY || id == msgid ) {
-               if ( all == 0
+               if ( all == LDAP_MSG_ONE
                    || (new->lm_msgtype != LDAP_RES_SEARCH_RESULT
-                   && new->lm_msgtype != LDAP_RES_SEARCH_ENTRY) ) {
+                   && new->lm_msgtype != LDAP_RES_SEARCH_ENTRY
+                   && new->lm_msgtype != LDAP_RES_SEARCH_REFERENCE) ) {
                        *result = new;
                        ld->ld_errno = LDAP_SUCCESS;
                        return( tag );
@@ -515,8 +642,9 @@ lr->lr_res_matched ? lr->lr_res_matched : "" );
            (long) new->lm_msgid, (long) new->lm_msgtype, 0 );
 
        /* part of a search response - add to end of list of entries */
-       for ( tmp = l; tmp->lm_chain != NULL &&
-           tmp->lm_chain->lm_msgtype == LDAP_RES_SEARCH_ENTRY;
+       for ( tmp = l; (tmp->lm_chain != NULL) &&
+               ((tmp->lm_chain->lm_msgtype == LDAP_RES_SEARCH_ENTRY) ||
+                (tmp->lm_chain->lm_msgtype == LDAP_RES_SEARCH_REFERENCE));
            tmp = tmp->lm_chain )
                ;       /* NULL */
        tmp->lm_chain = new;
@@ -643,7 +771,7 @@ int
 ldap_msgtype( LDAPMessage *lm )
 {
        assert( lm != NULL );
-       return ( lm == NULL ) ? lm->lm_msgtype : -1;
+       return ( lm != NULL ) ? lm->lm_msgtype : -1;
 }
 
 
@@ -652,7 +780,7 @@ ldap_msgid( LDAPMessage *lm )
 {
        assert( lm != NULL );
 
-       return ( lm == NULL ) ? lm->lm_msgid : -1;
+       return ( lm != NULL ) ? lm->lm_msgid : -1;
 }
 
 
@@ -761,14 +889,16 @@ cldap_getmsg( LDAP *ld, struct timeval *timeout, BerElement *ber )
        int     rc;
        ber_tag_t       tag;
        ber_len_t       len;
+       ber_socket_t    sd;
 
-       if ( ! ber_pvt_sb_data_ready(&ld->ld_sb) ) {
+       ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, &sd );
+       if ( sd != AC_SOCKET_INVALID ) {
                /* restored from ldap_select1() in result.c version 1.24 */
                fd_set  readfds;
                if ( ldap_int_tblsize == 0 )
                        ldap_int_ip_init();
                FD_ZERO( &readfds );
-               FD_SET( ber_pvt_sb_get_desc(&ld->ld_sb), &readfds );
+               FD_SET( sd, &readfds );
                rc = select( ldap_int_tblsize, &readfds, 0, 0, timeout );
 
                if ( rc == -1 || rc == 0 ) {
@@ -779,7 +909,7 @@ cldap_getmsg( LDAP *ld, struct timeval *timeout, BerElement *ber )
        }
 
        /* get the next message */
-       if ( (tag = ber_get_next( &ld->ld_sb, &len, ber ))
+       if ( (tag = ber_get_next( ld->ld_sb, &len, ber ))
            != LDAP_TAG_MESSAGE ) {
                ld->ld_errno = (tag == LBER_DEFAULT ? LDAP_SERVER_DOWN :
                    LDAP_LOCAL_ERROR);
index a397288c4dd119de3f7bd3d0f96d18d4588c38ce..1243454d76a92aaff48ebfa9714afb133f48c465 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -10,7 +10,7 @@
  *             name            DistinguishedName,       -- who
  *             authentication  CHOICE {
  *                     simple          [0] OCTET STRING -- passwd
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
  *                     krbv42ldap      [1] OCTET STRING
  *                     krbv42dsa       [2] OCTET STRING
 #endif
 #include <ac/socket.h>
 #include <ac/string.h>
 #include <ac/time.h>
+#include <ac/errno.h>
 
 #include "ldap-int.h"
 
 
 /*
- * ldap_sasl_bind - bind to the ldap server (and X.500).  The dn, mechanism, and
- * credentials of the entry to which to bind are supplied.  The message id
- * of the request initiated is provided upon successful (LDAP_SUCCESS) return.
+ * ldap_sasl_bind - bind to the ldap server (and X.500).
+ * The dn (usually NULL), mechanism, and credentials are provided.
+ * The message id of the request initiated is provided upon successful
+ * (LDAP_SUCCESS) return.
  *
  * Example:
- *     ldap_sasl_bind( ld, "cn=manager, o=university of michigan, c=us",
- *         "mechanism", "secret", NULL, NULL, &msgid )
+ *     ldap_sasl_bind( ld, NULL, "mechanism",
+ *             cred, NULL, NULL, &msgid )
  */
 
 int
@@ -70,15 +72,20 @@ ldap_sasl_bind(
                return ld->ld_errno;
        }
 
-       if( mechanism != LDAP_SASL_SIMPLE
-               && ld->ld_version < LDAP_VERSION3)
-       {
+       if( mechanism == LDAP_SASL_SIMPLE ) {
+               if( dn == NULL && cred != NULL ) {
+                       /* use default binddn */
+                       dn = ld->ld_defbinddn;
+               }
+
+       } else if( ld->ld_version < LDAP_VERSION3 ) {
                ld->ld_errno = LDAP_NOT_SUPPORTED;
                return ld->ld_errno;
        }
 
-       if ( dn == NULL )
+       if ( dn == NULL ) {
                dn = "";
+       }
 
        /* create a message to send */
        if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
@@ -143,16 +150,6 @@ ldap_sasl_bind(
        return LDAP_SUCCESS;
 }
 
-/*
- * ldap_sasl_bind_s - bind to the ldap server (and X.500) using simple
- * authentication.  The dn and password of the entry to which to bind are
- * supplied.  LDAP_SUCCESS is returned upon success, the ldap error code
- * otherwise.
- *
- * Example:
- *     ldap_sasl_bind_s( ld, "cn=manager, o=university of michigan, c=us",
- *         "mechanism", "secret", NULL, NULL, &servercred )
- */
 
 int
 ldap_sasl_bind_s(
@@ -195,19 +192,21 @@ ldap_sasl_bind_s(
                rc = ldap_parse_sasl_bind_result( ld, result, &scredp, 0 );
        }
 
-       if( rc != LDAP_SUCCESS ) {
+       if ( rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS ) {
                ldap_msgfree( result );
                return( rc );
        }
 
        rc = ldap_result2error( ld, result, 1 );
 
-       if( rc == LDAP_SUCCESS ) {
+       if ( rc == LDAP_SUCCESS || rc == LDAP_SASL_BIND_IN_PROGRESS ) {
                if( servercredp != NULL ) {
                        *servercredp = scredp;
+                       scredp = NULL;
                }
+       }
 
-       } else if (scredp != NULL ) {
+       if ( scredp != NULL ) {
                ber_bvfree(scredp);
        }
 
@@ -216,18 +215,18 @@ ldap_sasl_bind_s(
 
 
 /*
- * Parse BindResponse:
- *
- *   BindResponse ::= [APPLICATION 1] SEQUENCE {
- *     COMPONENTS OF LDAPResult,
- *     serverSaslCreds  [7] OCTET STRING OPTIONAL }
- *
- *   LDAPResult ::= SEQUENCE {
- *     resultCode      ENUMERATED,
- *     matchedDN       LDAPDN,
- *     errorMessage    LDAPString,
- *     referral        [3] Referral OPTIONAL }
- */
+* Parse BindResponse:
+*
+*   BindResponse ::= [APPLICATION 1] SEQUENCE {
+*     COMPONENTS OF LDAPResult,
+*     serverSaslCreds  [7] OCTET STRING OPTIONAL }
+*
+*   LDAPResult ::= SEQUENCE {
+*     resultCode      ENUMERATED,
+*     matchedDN       LDAPDN,
+*     errorMessage    LDAPString,
+*     referral        [3] Referral OPTIONAL }
+*/
 
 int
 ldap_parse_sasl_bind_result(
@@ -252,19 +251,18 @@ ldap_parse_sasl_bind_result(
                return LDAP_PARAM_ERROR;
        }
 
-       if(servercredp != NULL) {
+       if( servercredp != NULL ) {
                if( ld->ld_version < LDAP_VERSION2 ) {
                        return LDAP_NOT_SUPPORTED;
                }
                *servercredp = NULL;
        }
 
-       if( res->lm_msgtype == LDAP_RES_BIND ) {
+       if( res->lm_msgtype != LDAP_RES_BIND ) {
                ld->ld_errno = LDAP_PARAM_ERROR;
                return ld->ld_errno;
        }
 
-       errcode = LDAP_SUCCESS;
        scred = NULL;
 
        if ( ld->ld_error ) {
@@ -280,55 +278,838 @@ ldap_parse_sasl_bind_result(
 
        ber = ber_dup( res->lm_ber );
 
+       if( ber == NULL ) {
+               ld->ld_errno = LDAP_NO_MEMORY;
+               return ld->ld_errno;
+       }
+
        if ( ld->ld_version < LDAP_VERSION2 ) {
                tag = ber_scanf( ber, "{ia}",
                        &errcode, &ld->ld_error );
 
+               if( tag == LBER_ERROR ) {
+                       ber_free( ber, 0 );
+                       ld->ld_errno = LDAP_DECODING_ERROR;
+                       return ld->ld_errno;
+               }
+
        } else {
                ber_len_t len;
 
                tag = ber_scanf( ber, "{iaa" /*}*/,
                        &errcode, &ld->ld_matched, &ld->ld_error );
 
-               if( tag != LBER_ERROR ) {
-                       tag = ber_peek_tag(ber, &len);
+               if( tag == LBER_ERROR ) {
+                       ber_free( ber, 0 );
+                       ld->ld_errno = LDAP_DECODING_ERROR;
+                       return ld->ld_errno;
                }
 
+               tag = ber_peek_tag(ber, &len);
+
                if( tag == LDAP_TAG_REFERRAL ) {
                        /* skip 'em */
-                       tag = ber_scanf( ber, "x" );
-
-                       if( tag != LBER_ERROR ) {
-                               tag = ber_peek_tag(ber, &len);
+                       if( ber_scanf( ber, "x" ) == LBER_ERROR ) {
+                               ber_free( ber, 0 );
+                               ld->ld_errno = LDAP_DECODING_ERROR;
+                               return ld->ld_errno;
                        }
+
+                       tag = ber_peek_tag(ber, &len);
                }
 
-               /* need to clean out misc items */
                if( tag == LDAP_TAG_SASL_RES_CREDS ) {
-                       tag = ber_scanf( ber, "O", &scred );
+                       if( ber_scanf( ber, "O", &scred ) == LBER_ERROR ) {
+                               ber_free( ber, 0 );
+                               ld->ld_errno = LDAP_DECODING_ERROR;
+                               return ld->ld_errno;
+                       }
                }
        }
 
-       if ( tag == LBER_ERROR ) {
-               errcode = LDAP_DECODING_ERROR;
-       }
-
-       if( ber != NULL ) {
-               ber_free( ber, 0 );
-       }
+       ber_free( ber, 0 );
 
-       /* return */
-       if ( errcode == LDAP_SUCCESS && servercredp != NULL ) {
+       if ( servercredp != NULL ) {
                *servercredp = scred;
 
        } else if ( scred != NULL ) {
                ber_bvfree( scred );
        }
 
+       ld->ld_errno = errcode;
+
        if ( freeit ) {
                ldap_msgfree( res );
        }
 
-       ld->ld_errno = errcode;
        return( ld->ld_errno );
 }
+
+#ifdef HAVE_CYRUS_SASL
+/*
+* Various Cyrus SASL related stuff.
+*/
+
+#define MAX_BUFF_SIZE  65536
+#define MIN_BUFF_SIZE  4096
+
+static char *
+array2str( char **a )
+{
+       char *s, **v, *p;
+       int len = 0;
+
+       for ( v = a; *v != NULL; v++ ) {
+               len += strlen( *v ) + 1; /* for a space */
+       }
+
+       if ( len == 0 ) {
+               return NULL;
+       }
+
+       s = LDAP_MALLOC ( len ); /* last space holds \0 */
+
+       if ( s == NULL ) {
+               return NULL;    
+       }
+
+       p = s;
+       for ( v = a; *v != NULL; v++ ) {
+               int len;
+
+               if ( v != a ) {
+                       strncpy( p, " ", 1 );
+                       ++p;
+               }
+               len = strlen( *v );
+               strncpy( p, *v, len );
+               p += len;
+       }
+
+       *p = '\0';
+
+       return s;
+}
+
+int ldap_pvt_sasl_init( void )
+{
+       /* XXX not threadsafe */
+       static int sasl_initialized = 0;
+
+       if ( sasl_initialized ) {
+               return 0;
+       }
+#ifndef CSRIMALLOC
+       sasl_set_alloc( ber_memalloc, ber_memcalloc, ber_memrealloc, ber_memfree );
+#endif /* CSRIMALLOC */
+
+       if ( sasl_client_init( NULL ) == SASL_OK ) {
+               sasl_initialized = 1;
+               return 0;
+       }
+
+       return -1;
+}
+
+/*
+ * SASL encryption support for LBER Sockbufs
+ */
+
+struct sb_sasl_data {
+       sasl_conn_t             *sasl_context;
+       Sockbuf_Buf             sec_buf_in;
+       Sockbuf_Buf             buf_in;
+       Sockbuf_Buf             buf_out;
+};
+
+static int
+sb_sasl_setup( Sockbuf_IO_Desc *sbiod, void *arg )
+{
+       struct sb_sasl_data     *p;
+
+       assert( sbiod != NULL );
+
+       p = LBER_MALLOC( sizeof( *p ) );
+       if ( p == NULL )
+               return -1;
+       p->sasl_context = (sasl_conn_t *)arg;
+       ber_pvt_sb_buf_init( &p->sec_buf_in );
+       ber_pvt_sb_buf_init( &p->buf_in );
+       ber_pvt_sb_buf_init( &p->buf_out );
+       if ( ber_pvt_sb_grow_buffer( &p->sec_buf_in, MIN_BUFF_SIZE ) < 0 ) {
+               errno = ENOMEM;
+               return -1;
+       }
+
+       sbiod->sbiod_pvt = p;
+
+       return 0;
+}
+
+static int
+sb_sasl_remove( Sockbuf_IO_Desc *sbiod )
+{
+       struct sb_sasl_data     *p;
+
+       assert( sbiod != NULL );
+       
+       p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
+       ber_pvt_sb_buf_destroy( &p->sec_buf_in );
+       ber_pvt_sb_buf_destroy( &p->buf_in );
+       ber_pvt_sb_buf_destroy( &p->buf_out );
+       LBER_FREE( p );
+       sbiod->sbiod_pvt = NULL;
+       return 0;
+}
+
+static ber_len_t
+sb_sasl_pkt_length( const char *buf, int debuglevel )
+{
+       ber_len_t               size;
+       long                    tmp;
+
+       assert( buf != NULL );
+
+       tmp = *((long *)buf);
+       size = ntohl( tmp );
+   
+       if ( size > MAX_BUFF_SIZE ) {
+               /* somebody is trying to mess me up. */
+               ber_log_printf( LDAP_DEBUG_ANY, debuglevel,
+                       "sb_sasl_pkt_length: received illegal packet length "
+                       "of %lu bytes\n", (unsigned long)size );      
+               size = 16; /* this should lead to an error. */
+}
+
+       return size + 4; /* include the size !!! */
+}
+
+/* Drop a processed packet from the input buffer */
+static void
+sb_sasl_drop_packet ( Sockbuf_Buf *sec_buf_in, int debuglevel )
+{
+       ber_slen_t                      len;
+
+       len = sec_buf_in->buf_ptr - sec_buf_in->buf_end;
+       if ( len > 0 )
+               memmove( sec_buf_in->buf_base, sec_buf_in->buf_base +
+                       sec_buf_in->buf_end, len );
+   
+       if ( len >= 4 ) {
+               sec_buf_in->buf_end = sb_sasl_pkt_length( sec_buf_in->buf_base,
+                       debuglevel);
+       }
+       else {
+               sec_buf_in->buf_end = 0;
+       }
+       sec_buf_in->buf_ptr = len;
+}
+
+static ber_slen_t
+sb_sasl_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
+{
+       struct sb_sasl_data     *p;
+       ber_slen_t              ret, bufptr;
+   
+       assert( sbiod != NULL );
+       assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
+
+       p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
+
+       /* Are there anything left in the buffer? */
+       ret = ber_pvt_sb_copy_out( &p->buf_in, buf, len );
+       bufptr = ret;
+       len -= ret;
+
+       if ( len == 0 )
+               return bufptr;
+
+       ber_pvt_sb_buf_destroy( &p->buf_in );
+
+       /* Read the length of the packet */
+       while ( p->sec_buf_in.buf_ptr < 4 ) {
+               ret = LBER_SBIOD_READ_NEXT( sbiod, p->sec_buf_in.buf_base,
+                       4 - p->sec_buf_in.buf_ptr );
+#ifdef EINTR
+               if ( ( ret < 0 ) && ( errno == EINTR ) )
+                       continue;
+#endif
+               if ( ret <= 0 )
+                       return ret;
+
+               p->sec_buf_in.buf_ptr += ret;
+       }
+
+       /* The new packet always starts at p->sec_buf_in.buf_base */
+       ret = sb_sasl_pkt_length( p->sec_buf_in.buf_base,
+               sbiod->sbiod_sb->sb_debug );
+
+       /* Grow the packet buffer if neccessary */
+       if ( ( p->sec_buf_in.buf_size < ret ) && 
+                       ber_pvt_sb_grow_buffer( &p->sec_buf_in, ret ) < 0 ) {
+               errno = ENOMEM;
+               return -1;
+       }
+       p->sec_buf_in.buf_end = ret;
+
+       /* Did we read the whole encrypted packet? */
+       while ( p->sec_buf_in.buf_ptr < p->sec_buf_in.buf_end ) {
+               /* No, we have got only a part of it */
+               ret = p->sec_buf_in.buf_end - p->sec_buf_in.buf_ptr;
+
+               ret = LBER_SBIOD_READ_NEXT( sbiod, p->sec_buf_in.buf_base +
+                       p->sec_buf_in.buf_ptr, ret );
+#ifdef EINTR
+               if ( ( ret < 0 ) && ( errno == EINTR ) )
+                       continue;
+#endif
+               if ( ret <= 0 )
+                       return ret;
+
+               p->sec_buf_in.buf_ptr += ret;
+       }
+
+       /* Decode the packet */
+       ret = sasl_decode( p->sasl_context, p->sec_buf_in.buf_base,
+               p->sec_buf_in.buf_end, &p->buf_in.buf_base,
+               (unsigned *)&p->buf_in.buf_end );
+       if ( ret != SASL_OK ) {
+               ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug,
+                       "sb_sasl_read: failed to decode packet: %s\n",
+                       sasl_errstring( ret, NULL, NULL ) );
+               sb_sasl_drop_packet( &p->sec_buf_in,
+                       sbiod->sbiod_sb->sb_debug );
+               errno = EIO;
+               return -1;
+       }
+       
+       /* Drop the packet from the input buffer */
+       sb_sasl_drop_packet( &p->sec_buf_in, sbiod->sbiod_sb->sb_debug );
+
+       p->buf_in.buf_size = p->buf_in.buf_end;
+
+       bufptr += ber_pvt_sb_copy_out( &p->buf_in, (char*) buf + bufptr, len );
+
+       return bufptr;
+}
+
+static ber_slen_t
+sb_sasl_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
+{
+       struct sb_sasl_data     *p;
+       int                     ret;
+
+       assert( sbiod != NULL );
+       assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
+
+       p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
+
+       /* Are there anything left in the buffer? */
+       if ( p->buf_out.buf_ptr != p->buf_out.buf_end ) {
+               ret = ber_pvt_sb_do_write( sbiod, &p->buf_out );
+               if ( ret <= 0 )
+                       return ret;
+       }
+
+       /* now encode the next packet. */
+       ber_pvt_sb_buf_destroy( &p->buf_out );
+       ret = sasl_encode( p->sasl_context, buf, len, &p->buf_out.buf_base,
+               (unsigned *)&p->buf_out.buf_size );
+       if ( ret != SASL_OK ) {
+               ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug,
+                       "sb_sasl_write: failed to encode packet: %s\n",
+                       sasl_errstring( ret, NULL, NULL ) );
+               return -1;
+       }
+       p->buf_out.buf_end = p->buf_out.buf_size;
+
+       ret = ber_pvt_sb_do_write( sbiod, &p->buf_out );
+       if ( ret <= 0 )
+               return ret;
+       return len;
+}
+
+static int
+sb_sasl_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
+{
+       struct sb_sasl_data     *p;
+
+       p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
+
+       if ( opt == LBER_SB_OPT_DATA_READY ) {
+               if ( p->buf_in.buf_ptr != p->buf_in.buf_end )
+                       return 1;
+       }
+       
+       return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
+}
+
+Sockbuf_IO ldap_pvt_sockbuf_io_sasl =
+{
+       sb_sasl_setup,          /* sbi_setup */
+       sb_sasl_remove,         /* sbi_remove */
+       sb_sasl_ctrl,           /* sbi_ctrl */
+       sb_sasl_read,           /* sbi_read */
+       sb_sasl_write,          /* sbi_write */
+       NULL                    /* sbi_close */
+};
+
+int ldap_pvt_sasl_install( Sockbuf *sb, void *ctx_arg )
+{
+       /* don't install the stuff unless security has been negotiated */
+
+       if ( !ber_sockbuf_ctrl( sb, LBER_SB_OPT_HAS_IO,
+                       &ldap_pvt_sockbuf_io_sasl ) )
+               ber_sockbuf_add_io( sb, &ldap_pvt_sockbuf_io_sasl,
+                       LBER_SBIOD_LEVEL_APPLICATION, ctx_arg );
+
+       return LDAP_SUCCESS;
+}
+
+static int
+sasl_err2ldap( int saslerr )
+{
+       int rc;
+
+       switch (saslerr) {
+               case SASL_CONTINUE:
+                       rc = LDAP_MORE_RESULTS_TO_RETURN;
+                       break;
+               case SASL_OK:
+                       rc = LDAP_SUCCESS;
+                       break;
+               case SASL_FAIL:
+                       rc = LDAP_LOCAL_ERROR;
+                       break;
+               case SASL_NOMEM:
+                       rc = LDAP_NO_MEMORY;
+                       break;
+               case SASL_NOMECH:
+                       rc = LDAP_AUTH_UNKNOWN;
+                       break;
+               case SASL_BADAUTH:
+                       rc = LDAP_AUTH_UNKNOWN;
+                       break;
+               case SASL_NOAUTHZ:
+                       rc = LDAP_PARAM_ERROR;
+                       break;
+               case SASL_TOOWEAK:
+               case SASL_ENCRYPT:
+                       rc = LDAP_AUTH_UNKNOWN;
+                       break;
+               default:
+                       rc = LDAP_LOCAL_ERROR;
+                       break;
+       }
+
+       assert( rc == LDAP_SUCCESS || LDAP_API_ERROR( rc ) );
+       return rc;
+}
+
+int
+ldap_pvt_sasl_getmechs ( LDAP *ld, char **pmechlist )
+{
+       /* we need to query the server for supported mechs anyway */
+       LDAPMessage *res, *e;
+       char *attrs[] = { "supportedSASLMechanisms", NULL };
+       char **values, *mechlist;
+       int rc;
+
+       Debug( LDAP_DEBUG_TRACE, "ldap_pvt_sasl_getmech\n", 0, 0, 0 );
+
+       rc = ldap_search_s( ld, NULL, LDAP_SCOPE_BASE,
+               NULL, attrs, 0, &res );
+
+       if ( rc != LDAP_SUCCESS ) {
+               return ld->ld_errno;
+       }
+               
+       e = ldap_first_entry( ld, res );
+       if ( e == NULL ) {
+               if ( ld->ld_errno == LDAP_SUCCESS ) {
+                       ld->ld_errno = LDAP_UNAVAILABLE;
+               }
+               return ld->ld_errno;
+       }
+
+       values = ldap_get_values( ld, e, "supportedSASLMechanisms" );
+       if ( values == NULL ) {
+               ld->ld_errno = LDAP_NO_SUCH_ATTRIBUTE;
+               ldap_msgfree( res );
+               return ld->ld_errno;
+       }
+
+       mechlist = array2str( values );
+       if ( mechlist == NULL ) {
+               ld->ld_errno = LDAP_NO_MEMORY;
+               LDAP_VFREE( values );
+               ldap_msgfree( res );
+               return ld->ld_errno;
+       } 
+
+       LDAP_VFREE( values );
+       ldap_msgfree( res );
+
+       *pmechlist = mechlist;
+
+       return LDAP_SUCCESS;
+}
+
+int
+ldap_pvt_sasl_bind(
+       LDAP                    *ld,
+       LDAP_CONST char         *dn,
+       LDAP_CONST char         *mechs,
+       LDAP_CONST sasl_callback_t      *callbacks,
+       LDAPControl             **sctrls,
+       LDAPControl             **cctrls )
+{
+       const char *mech;
+       int                     saslrc, rc;
+       sasl_ssf_t              *ssf = NULL;
+       unsigned credlen;
+       struct berval ccred, *scred;
+       char *host;
+       sasl_interact_t *client_interact = NULL;
+       struct sockaddr_in      sin;
+       socklen_t               len;
+       sasl_security_properties_t      secprops;
+       ber_socket_t            sd;
+
+       Debug( LDAP_DEBUG_TRACE, "ldap_pvt_sasl_bind\n", 0, 0, 0 );
+
+       /* do a quick !LDAPv3 check... ldap_sasl_bind will do the rest. */
+       if (ld->ld_version < LDAP_VERSION3) {
+               ld->ld_errno = LDAP_NOT_SUPPORTED;
+               return ld->ld_errno;
+       }
+
+       ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, &sd );
+
+       if ( sd == AC_SOCKET_INVALID ) {
+               /* not connected yet */
+               int rc = ldap_open_defconn( ld );
+  
+               if( rc < 0 ) return ld->ld_errno;
+               ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, &sd );
+       }   
+
+       /* XXX this doesn't work with PF_LOCAL hosts */
+       host = ldap_host_connected_to( ld->ld_sb );
+
+       if ( host == NULL ) {
+               ld->ld_errno = LDAP_UNAVAILABLE;
+               return ld->ld_errno;
+       }
+
+       if ( ld->ld_sasl_context != NULL ) {
+               sasl_dispose( &ld->ld_sasl_context );
+       }
+
+       saslrc = sasl_client_new( "ldap", host, callbacks, SASL_SECURITY_LAYER,
+               &ld->ld_sasl_context );
+
+       LDAP_FREE( host );
+
+       if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
+               ld->ld_errno = sasl_err2ldap( saslrc );
+               sasl_dispose( &ld->ld_sasl_context );
+               return ld->ld_errno;
+       }
+
+       len = sizeof( sin );
+       if ( getpeername( sd, (struct sockaddr *)&sin, &len ) == -1 ) {
+               Debug( LDAP_DEBUG_ANY, "SASL: can't query remote IP.\n",
+                       0, 0, 0 );
+               ld->ld_errno = LDAP_OPERATIONS_ERROR;
+               return ld->ld_errno;
+       }
+       sasl_setprop( ld->ld_sasl_context, SASL_IP_REMOTE, &sin );
+
+       len = sizeof( sin );
+       if ( getsockname( sd, (struct sockaddr *)&sin, &len ) == -1 ) {
+               Debug( LDAP_DEBUG_ANY, "SASL: can't query local IP.\n",
+                       0, 0, 0 );
+               ld->ld_errno = LDAP_OPERATIONS_ERROR;
+               return ld->ld_errno;
+       }
+       sasl_setprop( ld->ld_sasl_context, SASL_IP_LOCAL, &sin );
+
+       memset( &secprops, '\0', sizeof( secprops ) );
+       secprops.min_ssf = ld->ld_options.ldo_sasl_minssf;
+       secprops.max_ssf = ld->ld_options.ldo_sasl_maxssf;
+       secprops.security_flags = SASL_SECURITY_LAYER;
+       secprops.maxbufsize = 65536;
+       sasl_setprop( ld->ld_sasl_context, SASL_SEC_PROPS, &secprops );
+
+       ccred.bv_val = NULL;
+       ccred.bv_len = 0;
+
+       saslrc = sasl_client_start( ld->ld_sasl_context,
+               mechs,
+               NULL,
+               &client_interact,
+               &ccred.bv_val,
+               &credlen,
+               &mech );
+
+       ccred.bv_len = credlen;
+
+       if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
+               ld->ld_errno = sasl_err2ldap( saslrc );
+               sasl_dispose( &ld->ld_sasl_context );
+               return ld->ld_errno;
+       }
+
+       scred = NULL;
+
+       do {
+               unsigned credlen;
+               sasl_interact_t *client_interact = NULL;
+
+               rc = ldap_sasl_bind_s( ld, dn, mech, &ccred, sctrls, cctrls, &scred );
+               if ( rc == LDAP_SUCCESS ) {
+                       break;
+               } else if ( rc != LDAP_SASL_BIND_IN_PROGRESS ) {
+                       if ( ccred.bv_val != NULL ) {
+                               LDAP_FREE( ccred.bv_val );
+                       }
+                       sasl_dispose( &ld->ld_sasl_context );
+                       return ld->ld_errno;
+               }
+
+               if ( ccred.bv_val != NULL ) {
+                       LDAP_FREE( ccred.bv_val );
+                       ccred.bv_val = NULL;
+               }
+
+               saslrc = sasl_client_step( ld->ld_sasl_context,
+                       (scred == NULL) ? NULL : scred->bv_val,
+                       (scred == NULL) ? 0 : scred->bv_len,
+                       &client_interact,
+                       &ccred.bv_val,
+                       &credlen );
+
+               ccred.bv_len = credlen;
+               ber_bvfree( scred );
+
+               if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
+                       ld->ld_errno = sasl_err2ldap( saslrc );
+                       sasl_dispose( &ld->ld_sasl_context );
+                       return ld->ld_errno;
+               }
+       } while ( rc == LDAP_SASL_BIND_IN_PROGRESS );
+
+       assert ( rc == LDAP_SUCCESS );
+
+       if ( sasl_getprop( ld->ld_sasl_context, SASL_SSF, (void **)&ssf )
+               == SASL_OK && ssf && *ssf ) {
+               ldap_pvt_sasl_install( ld->ld_sb, ld->ld_sasl_context );
+       }
+
+       return rc;
+}
+
+/* based on sample/sample-client.c */
+static int
+ldap_pvt_sasl_getsecret(sasl_conn_t *conn,
+       void *context, int id, sasl_secret_t **psecret)
+{
+       struct berval *passphrase = (struct berval *)context;
+       size_t len;           
+
+       if ( conn == NULL || psecret == NULL || id != SASL_CB_PASS ) {
+               return SASL_BADPARAM;
+       }
+
+       len = (passphrase != NULL) ? (size_t)passphrase->bv_len: 0;
+
+       *psecret = (sasl_secret_t *) LDAP_MALLOC( sizeof( sasl_secret_t ) + len );
+       if ( *psecret == NULL ) {
+               return SASL_NOMEM;
+       }
+
+       (*psecret)->len = passphrase->bv_len;
+
+       if ( passphrase != NULL ) {
+               memcpy((*psecret)->data, passphrase->bv_val, len);
+       }
+
+       return SASL_OK;
+}
+
+static int
+ldap_pvt_sasl_getsimple(void *context, int id, const char **result, int *len)
+{
+       const char *value = (const char *)context;
+
+       if ( result == NULL ) {
+               return SASL_BADPARAM;
+       }
+
+       switch ( id ) {
+               case SASL_CB_USER:
+               case SASL_CB_AUTHNAME:
+                       *result = value;
+                       if ( len )
+                               *len = value ? strlen( value ) : 0;
+                       break;
+               case SASL_CB_LANGUAGE:
+                       *result = NULL;
+                       if ( len )
+                               *len = 0;
+                       break;
+               default:
+                       return SASL_BADPARAM;
+       }
+
+       return SASL_OK;
+}
+
+int
+ldap_pvt_sasl_get_option( LDAP *ld, int option, void *arg )
+{
+       sasl_ssf_t      *ssf;
+       
+       if ( ld == NULL )
+               return -1;
+
+       switch ( option ) {
+               case LDAP_OPT_X_SASL_MINSSF:
+                       *(int *)arg = ld->ld_options.ldo_sasl_minssf;
+                       break;
+               case LDAP_OPT_X_SASL_MAXSSF:
+                       *(int *)arg = ld->ld_options.ldo_sasl_maxssf;
+                       break;
+               case LDAP_OPT_X_SASL_ACTSSF:
+                       if ( ld->ld_sasl_context == NULL ) {
+                               *(int *)arg = -1;
+                               break;
+                       }
+                       if ( sasl_getprop( ld->ld_sasl_context, SASL_SSF,
+                               (void **) &ssf ) != SASL_OK )
+                       {
+                               return -1;
+                       }
+                       *(int *)arg = *ssf;
+                       break;
+               default:
+                       return -1;
+       }
+       return 0;
+}
+
+int
+ldap_pvt_sasl_set_option( LDAP *ld, int option, void *arg )
+{
+       if ( ld == NULL )
+               return -1;
+
+       switch ( option ) {
+               case LDAP_OPT_X_SASL_MINSSF:
+                       ld->ld_options.ldo_sasl_minssf = *(int *)arg;
+                       break;
+               case LDAP_OPT_X_SASL_MAXSSF:
+                       ld->ld_options.ldo_sasl_maxssf = *(int *)arg;
+                       break;
+               case LDAP_OPT_X_SASL_ACTSSF:
+                       /* This option is read-only */
+               default:
+                       return -1;
+       }
+       return 0;
+}
+
+/*
+ * ldap_negotiated_sasl_bind_s - bind to the ldap server (and X.500)
+ * using SASL authentication.
+ *
+ * This routine attempts to authenticate the user referred by the
+ * authentication id using the provided password.  An optional
+ * authorization identity may be provided.  An DN is generally not
+ * provided [see AuthMethod].
+ *
+ * If the mechanism negotiated does not require a password, the
+ * passwd field is ignored.  [A callback mechanism should really
+ * be used].
+ * 
+ * LDAP_SUCCESS is returned upon success, the ldap error code
+ * otherwise.
+ *
+ * Examples:
+ *     ldap_negotiated_sasl_bind_s( ld, NULL,
+ *         NULL, NULL, NULL,
+ *             NULL, NULL, NULL, NULL );
+ *
+ *     ldap_negotiated_sasl_bind_s( ld, NULL,
+ *         "user@OPENLDAP.ORG", NULL, NULL,
+ *             "GSSAPI", NULL, NULL, NULL );
+ *
+ *     ldap_negotiated_sasl_bind_s( ld, NULL,
+ *         "manager", "dn:cn=user,dc=openldap,dc=org", NULL,
+ *             "DIGEST-MD5", NULL, NULL, NULL );
+ *
+ *     ldap_negotiated_sasl_bind_s( ld, NULL,
+ *         "root@OPENLDAP.ORG", "u:user@OPENLDAP.ORG", NULL,
+ *             "GSSAPI", NULL, NULL, NULL );
+ *
+ *     ldap_negotiated_sasl_bind_s( ld, NULL,
+ *         "manager", "dn:cn=user,dc=openldap,dc=org", NULL,
+ *             "DIGEST-MD5", NULL, NULL, NULL );
+ */
+int
+ldap_negotiated_sasl_bind_s(
+       LDAP *ld,
+       LDAP_CONST char *dn, /* usually NULL */
+       LDAP_CONST char *authenticationId,
+       LDAP_CONST char *authorizationId, /* commonly NULL */
+       LDAP_CONST char *saslMechanism,
+       struct berval *passPhrase,
+       LDAPControl **serverControls,
+       LDAPControl **clientControls)
+{
+       int n;
+       sasl_callback_t callbacks[4];
+       int rc;
+
+       Debug( LDAP_DEBUG_TRACE, "ldap_negotiated_sasl_bind_s\n", 0, 0, 0 );
+
+       if( saslMechanism == NULL || *saslMechanism == '\0' ) {
+               char *mechs;
+               rc = ldap_pvt_sasl_getmechs( ld, &mechs );
+
+               if( rc != LDAP_SUCCESS ) {
+                       return rc;
+               }
+
+               saslMechanism = mechs;
+       }
+
+       /* SASL Authentication Identity */
+       callbacks[n=0].id = SASL_CB_AUTHNAME;
+       callbacks[n].proc = ldap_pvt_sasl_getsimple;
+       callbacks[n].context = (void *)authenticationId;
+
+       /* SASL Authorization Identity (userid) */
+       if( authorizationId != NULL ) {
+               callbacks[++n].id = SASL_CB_USER;
+               callbacks[n].proc = ldap_pvt_sasl_getsimple;
+               callbacks[n].context = (void *)authorizationId;
+       }
+
+       callbacks[++n].id = SASL_CB_PASS;
+       callbacks[n].proc = ldap_pvt_sasl_getsecret;
+       callbacks[n].context = (void *)passPhrase;
+
+       callbacks[++n].id = SASL_CB_LIST_END;
+       callbacks[n].proc = NULL;
+       callbacks[n].context = NULL;
+
+       assert( n * sizeof(sasl_callback_t) < sizeof(callbacks) );
+
+       rc = ldap_pvt_sasl_bind(ld, dn, saslMechanism, callbacks,
+               serverControls, clientControls);
+
+       return rc;
+}
+#endif /* HAVE_CYRUS_SASL */
index 96d9a7843359397de12f257c623c5ebc8cd561a8..ffcce858884c1ad89d2f1f6a169f548f00deafe1 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
@@ -16,7 +16,7 @@
  *             name            DistinguishedName,       -- who
  *             authentication  CHOICE {
  *                     simple          [0] OCTET STRING -- passwd
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
  *                     krbv42ldap      [1] OCTET STRING
  *                     krbv42dsa       [2] OCTET STRING
 #endif
index 78fbe8a3fa25079f7ee5a5e89017a1076b53a066..cae5dfc660c2050dd091e8097809f3342a3c3c2f 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1999-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
@@ -21,7 +21,6 @@
 
 #include <ldap_schema.h>
 
-
 static LDAP_CONST char *
 choose_name( char *names[], LDAP_CONST char *fallback )
 {
@@ -212,9 +211,9 @@ print_qdescrs(safe_string *ss, char **sa)
         */
        if ( !sa[0] || ( sa[0] && sa[1] ) ) {
                print_whsp(ss);
-               print_literal(ss,"(");
+               print_literal(ss,"("/*)*/);
                print_qdescrlist(ss,sa);
-               print_literal(ss,")");
+               print_literal(ss,/*(*/")");
                return(print_whsp(ss));
        } else {
          return(print_qdescr(ss,*sa));
@@ -245,10 +244,10 @@ static int
 print_oids(safe_string *ss, char **sa)
 {
        if ( sa[0] && sa[1] ) {
-               print_literal(ss,"(");
+               print_literal(ss,"("/*)*/);
                print_oidlist(ss,sa);
                print_whsp(ss);
-               return(print_literal(ss,")"));
+               return(print_literal(ss,/*(*/")"));
        } else {
                return(print_woid(ss,*sa));
        }
@@ -268,6 +267,25 @@ print_noidlen(safe_string *ss, char *s, int l)
        return(ret);
 }
 
+static int
+print_extensions(safe_string *ss, LDAP_SCHEMA_EXTENSION_ITEM **extensions)
+{
+       LDAP_SCHEMA_EXTENSION_ITEM **ext;
+
+       if ( extensions ) {
+               print_whsp(ss);
+               for ( ext = extensions; *ext != NULL; ext++ ) {
+                       print_literal(ss, (*ext)->lsei_name);
+                       print_whsp(ss);
+                       /* Should be print_qdstrings */
+                       print_qdescrs(ss, (*ext)->lsei_values);
+                       print_whsp(ss);
+               }
+       }
+
+       return 0;
+}
+
 char *
 ldap_syntax2str( const LDAP_SYNTAX * syn )
 {
@@ -278,7 +296,7 @@ ldap_syntax2str( const LDAP_SYNTAX * syn )
        if ( !ss )
                return NULL;
 
-       print_literal(ss,"(");
+       print_literal(ss,"("/*)*/);
        print_whsp(ss);
 
        print_numericoid(ss, syn->syn_oid);
@@ -290,7 +308,10 @@ ldap_syntax2str( const LDAP_SYNTAX * syn )
        }
 
        print_whsp(ss);
-       print_literal(ss,")");
+
+       print_extensions(ss, syn->syn_extensions);
+
+       print_literal(ss,/*(*/ ")");
 
        retstring = LDAP_STRDUP(safe_string_val(ss));
        safe_string_free(ss);
@@ -307,7 +328,7 @@ ldap_matchingrule2str( const LDAP_MATCHING_RULE * mr )
        if ( !ss )
                return NULL;
 
-       print_literal(ss,"(");
+       print_literal(ss,"(" /*)*/);
        print_whsp(ss);
 
        print_numericoid(ss, mr->mr_oid);
@@ -336,7 +357,10 @@ ldap_matchingrule2str( const LDAP_MATCHING_RULE * mr )
        }
 
        print_whsp(ss);
-       print_literal(ss,")");
+
+       print_extensions(ss, mr->mr_extensions);
+
+       print_literal(ss,/*(*/")");
 
        retstring = LDAP_STRDUP(safe_string_val(ss));
        safe_string_free(ss);
@@ -353,7 +377,7 @@ ldap_objectclass2str( const LDAP_OBJECT_CLASS * oc )
        if ( !ss )
                return NULL;
 
-       print_literal(ss,"(");
+       print_literal(ss,"("/*)*/);
        print_whsp(ss);
 
        print_numericoid(ss, oc->oc_oid);
@@ -412,7 +436,10 @@ ldap_objectclass2str( const LDAP_OBJECT_CLASS * oc )
        }
 
        print_whsp(ss);
-       print_literal(ss,")");
+
+       print_extensions(ss, oc->oc_extensions);
+
+       print_literal(ss, /*(*/")");
 
        retstring = LDAP_STRDUP(safe_string_val(ss));
        safe_string_free(ss);
@@ -429,7 +456,7 @@ ldap_attributetype2str( const LDAP_ATTRIBUTE_TYPE * at )
        if ( !ss )
                return NULL;
 
-       print_literal(ss,"(");
+       print_literal(ss,"("/*)*/);
        print_whsp(ss);
 
        print_numericoid(ss, at->at_oid);
@@ -512,7 +539,10 @@ ldap_attributetype2str( const LDAP_ATTRIBUTE_TYPE * at )
        }
        
        print_whsp(ss);
-       print_literal(ss,")");
+
+       print_extensions(ss, at->at_extensions);
+
+       print_literal(ss,/*(*/")");
 
        retstring = LDAP_STRDUP(safe_string_val(ss));
        safe_string_free(ss);
@@ -649,7 +679,7 @@ parse_whsp(const char **sp)
 
 /* Parse a sequence of dot-separated decimal strings */
 static char *
-parse_numericoid(const char **sp, int *code, const int allow_quoted)
+parse_numericoid(const char **sp, int *code, const int flags)
 {
        char * res;
        const char * start = *sp;
@@ -657,7 +687,7 @@ parse_numericoid(const char **sp, int *code, const int allow_quoted)
        int quoted = 0;
 
        /* Netscape puts the SYNTAX value in quotes (incorrectly) */
-       if ( allow_quoted && **sp == '\'' ) {
+       if ( flags & LDAP_SCHEMA_ALLOW_QUOTED && **sp == '\'' ) {
                quoted = 1;
                (*sp)++;
                start++;
@@ -689,7 +719,7 @@ parse_numericoid(const char **sp, int *code, const int allow_quoted)
        }
        strncpy(res,start,len);
        res[len] = '\0';
-       if ( allow_quoted && quoted ) {
+       if ( flags & LDAP_SCHEMA_ALLOW_QUOTED && quoted ) {
                if ( **sp == '\'' ) {
                        (*sp)++;
                } else {
@@ -805,12 +835,12 @@ parse_noidlen(const char **sp, int *code, int *len, int allow_quoted)
        if ( !sval ) {
                return NULL;
        }
-       if ( **sp == '{' ) {
+       if ( **sp == '{' /*}*/ ) {
                (*sp)++;
                *len = atoi(*sp);
                while ( isdigit(**sp) )
                        (*sp)++;
-               if ( **sp != '}' ) {
+               if ( **sp != /*{*/ '}' ) {
                        *code = LDAP_SCHERR_UNEXPTOKEN;
                        LDAP_FREE(sval);
                        return NULL;
@@ -936,23 +966,73 @@ parse_oids(const char **sp, int *code, const int allow_quoted)
        }
 }
 
+static int
+add_extension(LDAP_SCHEMA_EXTENSION_ITEM ***extensions,
+             char * name, char ** values)
+{
+       int n;
+       LDAP_SCHEMA_EXTENSION_ITEM **tmp, *ext;
+
+       ext = LDAP_CALLOC(1, sizeof(LDAP_SCHEMA_EXTENSION_ITEM));
+       if ( !ext )
+               return 1;
+       ext->lsei_name = name;
+       ext->lsei_values = values;
+
+       if ( !*extensions ) {
+               *extensions =
+                 LDAP_CALLOC(2, sizeof(LDAP_SCHEMA_EXTENSION_ITEM *));
+               if ( !*extensions )
+                 return 1;
+               n = 0;
+       } else {
+               for ( n=0; (*extensions)[n] != NULL; n++ )
+                       ;
+               tmp = LDAP_REALLOC(*extensions,
+                                  (n+2)*sizeof(LDAP_SCHEMA_EXTENSION_ITEM *));
+               if ( !tmp )
+                       return 1;
+               *extensions = tmp;
+       }
+       (*extensions)[n] = ext;
+       (*extensions)[n+1] = NULL;
+       return 0;
+}
+
+static void
+free_extensions(LDAP_SCHEMA_EXTENSION_ITEM **extensions)
+{
+       LDAP_SCHEMA_EXTENSION_ITEM **ext;
+
+       if ( extensions ) {
+               for ( ext = extensions; *ext != NULL; ext++ ) {
+                       LDAP_FREE((*ext)->lsei_name);
+                       LDAP_VFREE((*ext)->lsei_values);
+                       LDAP_FREE(*ext);
+               }
+               LDAP_FREE(extensions);
+       }
+}
+
 void
 ldap_syntax_free( LDAP_SYNTAX * syn )
 {
        LDAP_FREE(syn->syn_oid);
        LDAP_FREE(syn->syn_desc);
+       free_extensions(syn->syn_extensions);
        LDAP_FREE(syn);
 }
 
 LDAP_SYNTAX *
-ldap_str2syntax( const char * s, int * code, const char ** errp )
+ldap_str2syntax( const char * s, int * code, const char ** errp, const int flags )
 {
        int kind;
        const char * ss = s;
        char * sval;
+       int seen_name = 0;
        int seen_desc = 0;
        LDAP_SYNTAX * syn;
-       char ** ssdummy;
+       char ** ext_vals;
 
        if ( !s ) {
                *code = LDAP_SCHERR_EMPTY;
@@ -1000,7 +1080,24 @@ ldap_str2syntax( const char * s, int * code, const char ** errp )
                case TK_RIGHTPAREN:
                        return syn;
                case TK_BAREWORD:
-                       if ( !strcmp(sval,"DESC") ) {
+                       if ( !strcmp(sval,"NAME") ) {
+                               LDAP_FREE(sval);
+                               if ( seen_name ) {
+                                       *code = LDAP_SCHERR_DUPOPT;
+                                       *errp = ss;
+                                       ldap_syntax_free(syn);
+                                       return(NULL);
+                               }
+                               seen_name = 1;
+                               syn->syn_names = parse_qdescrs(&ss,code);
+                               if ( !syn->syn_names ) {
+                                       if ( *code != LDAP_SCHERR_OUTOFMEM )
+                                               *code = LDAP_SCHERR_BADNAME;
+                                       *errp = ss;
+                                       ldap_syntax_free(syn);
+                                       return NULL;
+                               }
+                       } else if ( !strcmp(sval,"DESC") ) {
                                LDAP_FREE(sval);
                                if ( seen_desc ) {
                                        *code = LDAP_SCHERR_DUPOPT;
@@ -1021,11 +1118,18 @@ ldap_str2syntax( const char * s, int * code, const char ** errp )
                                syn->syn_desc = sval;
                                parse_whsp(&ss);
                        } else if ( sval[0] == 'X' && sval[1] == '-' ) {
-                               LDAP_FREE(sval);
                                /* Should be parse_qdstrings */
-                               ssdummy = parse_qdescrs(&ss, code);
-                               if ( !ssdummy ) {
+                               ext_vals = parse_qdescrs(&ss, code);
+                               if ( !ext_vals ) {
+                                       *errp = ss;
+                                       ldap_syntax_free(syn);
+                                       return NULL;
+                               }
+                               if ( add_extension(&syn->syn_extensions,
+                                                   sval, ext_vals) ) {
+                                       *code = LDAP_SCHERR_OUTOFMEM;
                                        *errp = ss;
+                                       LDAP_FREE(sval);
                                        ldap_syntax_free(syn);
                                        return NULL;
                                }
@@ -1054,22 +1158,22 @@ ldap_matchingrule_free( LDAP_MATCHING_RULE * mr )
        LDAP_VFREE(mr->mr_names);
        LDAP_FREE(mr->mr_desc);
        LDAP_FREE(mr->mr_syntax_oid);
+       free_extensions(mr->mr_extensions);
        LDAP_FREE(mr);
 }
 
 LDAP_MATCHING_RULE *
-ldap_str2matchingrule( const char * s, int * code, const char ** errp )
+ldap_str2matchingrule( const char * s, int * code, const char ** errp, const int flags )
 {
        int kind;
        const char * ss = s;
        char * sval;
-       int be_liberal = 1;     /* Future additional argument */
        int seen_name = 0;
        int seen_desc = 0;
        int seen_obsolete = 0;
        int seen_syntax = 0;
        LDAP_MATCHING_RULE * mr;
-       char ** ssdummy;
+       char ** ext_vals;
        const char * savepos;
 
        if ( !s ) {
@@ -1096,9 +1200,9 @@ ldap_str2matchingrule( const char * s, int * code, const char ** errp )
 
        parse_whsp(&ss);
        savepos = ss;
-       mr->mr_oid = parse_numericoid(&ss,code,be_liberal);
+       mr->mr_oid = parse_numericoid(&ss,code,flags);
        if ( !mr->mr_oid ) {
-               if ( be_liberal ) {
+               if ( flags & LDAP_SCHEMA_ALLOW_NO_OID ) {
                        /* Backtracking */
                        ss = savepos;
                        kind = get_token(&ss,&sval);
@@ -1197,7 +1301,7 @@ ldap_str2matchingrule( const char * s, int * code, const char ** errp )
                                seen_syntax = 1;
                                parse_whsp(&ss);
                                mr->mr_syntax_oid =
-                                       parse_numericoid(&ss,code,be_liberal);
+                                       parse_numericoid(&ss,code,flags);
                                if ( !mr->mr_syntax_oid ) {
                                        *errp = ss;
                                        ldap_matchingrule_free(mr);
@@ -1205,11 +1309,18 @@ ldap_str2matchingrule( const char * s, int * code, const char ** errp )
                                }
                                parse_whsp(&ss);
                        } else if ( sval[0] == 'X' && sval[1] == '-' ) {
-                               LDAP_FREE(sval);
                                /* Should be parse_qdstrings */
-                               ssdummy = parse_qdescrs(&ss, code);
-                               if ( !ssdummy ) {
+                               ext_vals = parse_qdescrs(&ss, code);
+                               if ( !ext_vals ) {
+                                       *errp = ss;
+                                       ldap_matchingrule_free(mr);
+                                       return NULL;
+                               }
+                               if ( add_extension(&mr->mr_extensions,
+                                                   sval, ext_vals) ) {
+                                       *code = LDAP_SCHERR_OUTOFMEM;
                                        *errp = ss;
+                                       LDAP_FREE(sval);
                                        ldap_matchingrule_free(mr);
                                        return NULL;
                                }
@@ -1242,16 +1353,16 @@ ldap_attributetype_free(LDAP_ATTRIBUTE_TYPE * at)
        LDAP_FREE(at->at_ordering_oid);
        LDAP_FREE(at->at_substr_oid);
        LDAP_FREE(at->at_syntax_oid);
+       free_extensions(at->at_extensions);
        LDAP_FREE(at);
 }
 
 LDAP_ATTRIBUTE_TYPE *
-ldap_str2attributetype( const char * s, int * code, const char ** errp )
+ldap_str2attributetype( const char * s, int * code, const char ** errp, const int flags )
 {
        int kind;
        const char * ss = s;
        char * sval;
-       int be_liberal = 1;     /* Future additional argument */
        int seen_name = 0;
        int seen_desc = 0;
        int seen_obsolete = 0;
@@ -1262,7 +1373,7 @@ ldap_str2attributetype( const char * s, int * code, const char ** errp )
        int seen_syntax = 0;
        int seen_usage = 0;
        LDAP_ATTRIBUTE_TYPE * at;
-       char ** ssdummy;
+       char ** ext_vals;
        const char * savepos;
 
        if ( !s ) {
@@ -1298,7 +1409,7 @@ ldap_str2attributetype( const char * s, int * code, const char ** errp )
        savepos = ss;
        at->at_oid = parse_numericoid(&ss,code,0);
        if ( !at->at_oid ) {
-               if ( be_liberal ) {
+               if ( flags & LDAP_SCHEMA_ALLOW_NO_OID ) {
                        /* Backtracking */
                        ss = savepos;
                        kind = get_token(&ss,&sval);
@@ -1468,7 +1579,7 @@ ldap_str2attributetype( const char * s, int * code, const char ** errp )
                                        parse_noidlen(&ss,
                                                      code,
                                                      &at->at_syntax_len,
-                                                     be_liberal);
+                                                     flags);
                                if ( !at->at_syntax_oid ) {
                                        *errp = ss;
                                        ldap_attributetype_free(at);
@@ -1545,14 +1656,21 @@ ldap_str2attributetype( const char * s, int * code, const char ** errp )
                                LDAP_FREE(sval);
                                parse_whsp(&ss);
                        } else if ( sval[0] == 'X' && sval[1] == '-' ) {
-                               LDAP_FREE(sval);
                                /* Should be parse_qdstrings */
-                               ssdummy = parse_qdescrs(&ss, code);
-                               if ( !ssdummy ) {
+                               ext_vals = parse_qdescrs(&ss, code);
+                               if ( !ext_vals ) {
                                        *errp = ss;
                                        ldap_attributetype_free(at);
                                        return NULL;
                                }
+                               if ( add_extension(&at->at_extensions,
+                                                   sval, ext_vals) ) {
+                                       *code = LDAP_SCHERR_OUTOFMEM;
+                                       *errp = ss;
+                                       LDAP_FREE(sval);
+                                       ldap_attributetype_free(at);
+                                       return NULL;
+                               }
                        } else {
                                *code = LDAP_SCHERR_UNEXPTOKEN;
                                *errp = ss;
@@ -1580,16 +1698,16 @@ ldap_objectclass_free(LDAP_OBJECT_CLASS * oc)
        LDAP_VFREE(oc->oc_sup_oids);
        LDAP_VFREE(oc->oc_at_oids_must);
        LDAP_VFREE(oc->oc_at_oids_may);
+       free_extensions(oc->oc_extensions);
        LDAP_FREE(oc);
 }
 
 LDAP_OBJECT_CLASS *
-ldap_str2objectclass( const char * s, int * code, const char ** errp )
+ldap_str2objectclass( const char * s, int * code, const char ** errp, const int flags )
 {
        int kind;
        const char * ss = s;
        char * sval;
-       int be_liberal = 1;     /* Future additional argument */
        int seen_name = 0;
        int seen_desc = 0;
        int seen_obsolete = 0;
@@ -1598,7 +1716,7 @@ ldap_str2objectclass( const char * s, int * code, const char ** errp )
        int seen_must = 0;
        int seen_may = 0;
        LDAP_OBJECT_CLASS * oc;
-       char ** ssdummy;
+       char ** ext_vals;
        const char * savepos;
 
        if ( !s ) {
@@ -1634,7 +1752,7 @@ ldap_str2objectclass( const char * s, int * code, const char ** errp )
        savepos = ss;
        oc->oc_oid = parse_numericoid(&ss,code,0);
        if ( !oc->oc_oid ) {
-               if ( be_liberal ) {
+               if ( flags & LDAP_SCHEMA_ALLOW_ALL ) {
                        /* Backtracking */
                        ss = savepos;
                        kind = get_token(&ss,&sval);
@@ -1737,7 +1855,7 @@ ldap_str2objectclass( const char * s, int * code, const char ** errp )
                                seen_sup = 1;
                                oc->oc_sup_oids = parse_oids(&ss,
                                                             code,
-                                                            be_liberal);
+                                                            flags);
                                if ( !oc->oc_sup_oids ) {
                                        *errp = ss;
                                        ldap_objectclass_free(oc);
@@ -1809,14 +1927,21 @@ ldap_str2objectclass( const char * s, int * code, const char ** errp )
                                }
                                parse_whsp(&ss);
                        } else if ( sval[0] == 'X' && sval[1] == '-' ) {
-                               LDAP_FREE(sval);
                                /* Should be parse_qdstrings */
-                               ssdummy = parse_qdescrs(&ss, code);
-                               if ( !ssdummy ) {
+                               ext_vals = parse_qdescrs(&ss, code);
+                               if ( !ext_vals ) {
                                        *errp = ss;
                                        ldap_objectclass_free(oc);
                                        return NULL;
                                }
+                               if ( add_extension(&oc->oc_extensions,
+                                                   sval, ext_vals) ) {
+                                       *code = LDAP_SCHERR_OUTOFMEM;
+                                       *errp = ss;
+                                       LDAP_FREE(sval);
+                                       ldap_objectclass_free(oc);
+                                       return NULL;
+                               }
                        } else {
                                *code = LDAP_SCHERR_UNEXPTOKEN;
                                *errp = ss;
@@ -1836,7 +1961,7 @@ ldap_str2objectclass( const char * s, int * code, const char ** errp )
 }
 
 static char *const err2text[] = {
-       "",
+       "Success",
        "Out of memory",
        "Unexpected token",
        "Missing opening parenthesis",
@@ -1852,7 +1977,7 @@ static char *const err2text[] = {
 char *
 ldap_scherr2str(int code)
 {
-       if ( code < 1 || code >= (sizeof(err2text)/sizeof(char *)) ) {
+       if ( code < 0 || code >= (sizeof(err2text)/sizeof(char *)) ) {
                return "Unknown error";
        } else {
                return err2text[code];
index f6d84d10d1041874e0b730011c892e04333cf03e..4f9984affe8076545c699cd459dc782da8e0aa4e 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
@@ -98,12 +98,21 @@ ldap_search_ext(
        Debug( LDAP_DEBUG_TRACE, "ldap_search_ext\n", 0, 0, 0 );
 
        /*
-        * if timeout is provided, use only tv_sec as timelimit.
-        * otherwise, use default.
+        * if timeout is provided, both tv_sec and tv_usec must
+        * be non-zero
         */
-       timelimit = (timeout != NULL)
-                       ?  timeout->tv_sec
-                       : -1;
+       if( timeout != NULL ) {
+               if( timeout->tv_sec == 0 && timeout->tv_usec == 0 ) {
+                       return LDAP_PARAM_ERROR;
+               }
+
+               /* timelimit must be non-zero if timeout is provided */
+               timelimit = timeout->tv_sec != 0 ? timeout->tv_sec : 1;
+
+       } else {
+               /* no timeout, no timelimit */
+               timelimit = -1;
+       }
 
        ber = ldap_build_search_req( ld, base, scope, filter, attrs,
            attrsonly, sctrls, cctrls, timelimit, sizelimit ); 
@@ -157,8 +166,16 @@ ldap_search_ext_s(
                return( rc );
        }
 
-       if ( ldap_result( ld, msgid, 1, timeout, res ) == -1 )
+       rc = ldap_result( ld, msgid, 1, timeout, res );
+
+       if( rc <= 0 ) {
+               /* error(-1) or timeout(0) */
+               return( ld->ld_errno );
+       }
+
+       if( rc == LDAP_RES_SEARCH_REFERENCE) {
                return( ld->ld_errno );
+       }
 
        return( ldap_result2error( ld, *res, 0 ) );
 }
@@ -294,7 +311,11 @@ ldap_build_search_req(
                return( NULL );
        }
 
-       filter = LDAP_STRDUP( filter_in );
+       if( filter_in != NULL ) {
+               filter = LDAP_STRDUP( filter_in );
+       } else {
+               filter = LDAP_STRDUP( "(objectclass=*)" );
+       }
        err = put_filter( ber, filter );
        LDAP_FREE( filter );
 
@@ -348,7 +369,6 @@ static int ldap_is_attr_oid ( const char *attr )
        }
 
        return digit;
-
 }
 
 static int ldap_is_attr_desc ( const char *attr )
@@ -412,12 +432,12 @@ static int hex2value( int c )
 }
 
 char *
-ldap_pvt_find_wildcard( char *s )
+ldap_pvt_find_wildcard( const char *s )
 {
        for( ; *s != '\0' ; s++ ) {
                switch( *s ) {
                case '*':       /* found wildcard */
-                       return s;
+                       return (char *) s;
 
                case '\\':
                        s++; /* skip over escape */
@@ -556,6 +576,10 @@ put_filter( BerElement *ber, char *str )
                case '(':
                        str++;
                        parens++;
+
+                       /* skip spaces */
+                       while( isspace( *str ) ) str++;
+
                        switch ( *str ) {
                        case '&':
                                Debug( LDAP_DEBUG_TRACE, "put_filter: AND\n",
index c62961b7731f6cc9367d45d88f949a6d33f4e273..5734022c58170ece106a45094a117033a02a96b6 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* Portions
@@ -40,8 +40,8 @@ static int    et_cmp LDAP_P(( const void *aa, const void *bb));
 
 int
 ldap_sort_strcasecmp(
-       const void      *a,
-       const void      *b
+       LDAP_CONST void *a,
+       LDAP_CONST void *b
 )
 {
        return( strcasecmp( *(char *const *)a, *(char *const *)b ) );
@@ -135,7 +135,7 @@ ldap_sort_entries(
                *ep = et[i].et_msg;
                ep = &(*ep)->lm_chain;
 
-               ldap_value_free( et[i].et_vals );
+               LDAP_VFREE( et[i].et_vals );
        }
        *ep = last;
        LDAP_FREE( (char *) et );
@@ -147,7 +147,7 @@ int
 ldap_sort_values(
     LDAP       *ld,
     char       **vals,
-    int                (*cmp) (const void *, const void *)
+    int                (*cmp) (LDAP_CONST void *, LDAP_CONST void *)
 )
 {
        int     nel;
diff --git a/libraries/libldap/sortctrl.c b/libraries/libldap/sortctrl.c
new file mode 100644 (file)
index 0000000..3f04a20
--- /dev/null
@@ -0,0 +1,467 @@
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/* Adapted for inclusion into OpenLDAP by Kurt D. Zeilenga */
+/*---
+ * Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
+ *
+ * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
+ * TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT
+ * TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS
+ * AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE"
+ * IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION
+ * OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP
+ * PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT
+ * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
+ *
+ *---*/
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/stdlib.h>
+#include <ac/string.h>
+#include <ac/time.h>
+#include <ac/ctype.h>
+
+#include "ldap-int.h"
+
+#define LDAP_MATCHRULE_IDENTIFIER      0x80L
+#define LDAP_REVERSEORDER_IDENTIFIER   0x81L
+#define LDAP_ATTRTYPES_IDENTIFIER      0x80L
+
+
+
+/* ---------------------------------------------------------------------------
+   countKeys
+   
+   Internal function to determine the number of keys in the string.
+   
+   keyString  (IN) String of items separated by whitespace.
+   ---------------------------------------------------------------------------*/
+
+static int countKeys(char *keyString)
+{
+       char *p = keyString;
+       int count = 0;
+
+       for (;;)
+       {
+               while (isspace(*p))              /* Skip leading whitespace */
+                       p++;
+
+               if (*p == '\0')                 /* End of string? */
+                       return count;
+
+               count++;                                /* Found start of a key */
+
+               while (!isspace(*p))    /* Skip till next space or end of string. */
+                       if (*p++ == '\0')
+                               return count;
+       }
+}
+
+
+/* ---------------------------------------------------------------------------
+   readNextKey
+   
+   Internal function to parse the next sort key in the string.
+   Allocate an LDAPSortKey structure and initialize it with
+   attribute name, reverse flag, and matching rule OID.
+
+   Each sort key in the string has the format:
+         [whitespace][-]attribute[:[OID]]
+
+   pNextKey    (IN/OUT) Points to the next key in the sortkey string to parse.
+                                               The pointer is updated to point to the next character
+                                               after the sortkey being parsed.
+                                               
+   key         (OUT)    Points to the address of an LDAPSortKey stucture
+                                               which has been allocated by this routine and
+                                               initialized with information from the next sortkey.                        
+   ---------------------------------------------------------------------------*/
+
+static int readNextKey( char **pNextKey, LDAPSortKey **key)
+{
+       char *p = *pNextKey;
+       int rev = 0;
+       char *attrStart;
+       int attrLen;
+       char *oidStart = NULL;
+       int oidLen = 0;
+
+       /* Skip leading white space. */
+       while (isspace(*p))
+               p++;
+
+       if (*p == '-')           /* Check if the reverse flag is present. */
+       {
+               rev=1;
+               p++;
+       }
+
+       /* We're now positioned at the start of the attribute. */
+       attrStart = p;
+
+       /* Get the length of the attribute until the next whitespace or ":". */
+       attrLen = strcspn(p, " \t:");
+       p += attrLen;
+
+       if (attrLen == 0)        /* If no attribute name was present, quit. */
+               return LDAP_PARAM_ERROR;
+
+       if (*p == ':')
+       {
+               oidStart = ++p;                          /* Start of the OID, after the colon */
+               oidLen = strcspn(p, " \t");      /* Get length of OID till next whitespace */
+               p += oidLen;
+       }
+
+       *pNextKey = p;           /* Update argument to point to next key */
+
+       /* Allocate an LDAPSortKey structure */
+       *key = LDAP_MALLOC(sizeof(LDAPSortKey));
+       if (*key == NULL) return LDAP_NO_MEMORY;
+
+       /* Allocate memory for the attribute and copy to it. */
+       (*key)->attributeType = LDAP_MALLOC(attrLen+1);
+       if ((*key)->attributeType == NULL) {
+               LDAP_FREE(*key);
+               return LDAP_NO_MEMORY;
+       }
+
+       strncpy((*key)->attributeType, attrStart, attrLen);
+       (*key)->attributeType[attrLen] = 0;
+
+       /* If present, allocate memory for the OID and copy to it. */
+       if (oidLen) {
+               (*key)->orderingRule = LDAP_MALLOC(oidLen+1);
+               if ((*key)->orderingRule == NULL) {
+                       LDAP_FREE((*key)->attributeType);
+                       LDAP_FREE(*key);
+                       return LDAP_NO_MEMORY;
+               }
+               strncpy((*key)->orderingRule, oidStart, oidLen);
+               (*key)->orderingRule[oidLen] = 0;
+
+       } else {
+               (*key)->orderingRule = NULL;
+       }
+
+       (*key)->reverseOrder = rev;
+
+       return LDAP_SUCCESS;
+}
+
+
+/* ---------------------------------------------------------------------------
+   ldap_create_sort_keylist
+   
+   Create an array of pointers to LDAPSortKey structures, containing the
+   information specified by the string representation of one or more
+   sort keys.
+   
+   sortKeyList    (OUT) Points to a null-terminated array of pointers to
+                                               LDAPSortKey structures allocated by this routine.
+                                               This memory SHOULD be freed by the calling program
+                                               using ldap_free_sort_keylist().
+                                               
+   keyString      (IN)  Points to a string of one or more sort keys.                      
+   
+   ---------------------------------------------------------------------------*/
+
+LIBLDAP_F(int)
+ldap_create_sort_keylist ( LDAPSortKey ***sortKeyList, char *keyString )
+{
+       int         numKeys, rc, i;
+       char        *nextKey;
+       LDAPSortKey **keyList = NULL;
+
+       if (( sortKeyList == NULL ) || ( keyString == NULL )) {
+               return LDAP_PARAM_ERROR;
+       }
+       *sortKeyList = NULL;
+
+       /* Determine the number of sort keys so we can allocate memory. */
+       if (( numKeys = countKeys(keyString)) == 0) {
+               return LDAP_PARAM_ERROR;
+       }
+
+       /* Allocate the array of pointers.  Initialize to NULL. */
+       keyList=(LDAPSortKey**)LBER_CALLOC(numKeys+1, sizeof(LDAPSortKey*));
+       if ( keyList == NULL) return LDAP_NO_MEMORY;
+
+       /* For each sort key in the string, create an LDAPSortKey structure
+          and add it to the list.
+       */
+       nextKey = keyString;              /* Points to the next key in the string */
+       for (i=0; i < numKeys; i++) {
+               rc = readNextKey(&nextKey, &keyList[i]);
+
+               if (rc != LDAP_SUCCESS) {
+                       ldap_free_sort_keylist(keyList);
+                       return rc;
+               }
+       }
+
+       *sortKeyList = keyList;
+       return LDAP_SUCCESS;
+}
+
+
+/* ---------------------------------------------------------------------------
+   ldap_free_sort_keylist
+   
+   Frees the sort key structures created by ldap_create_sort_keylist().
+   Frees the memory referenced by the LDAPSortKey structures,
+   the LDAPSortKey structures themselves, and the array of pointers
+   to the structures.
+   
+   keyList     (IN) Points to an array of pointers to LDAPSortKey structures.
+   ---------------------------------------------------------------------------*/
+
+LIBLDAP_F(void)
+ldap_free_sort_keylist ( LDAPSortKey **keyList )
+{
+       int i;
+       LDAPSortKey *nextKeyp;
+
+       if (keyList == NULL) return;
+
+       i=0;
+       while ( 0 != (nextKeyp = keyList[i++]) ) {
+               if (nextKeyp->attributeType) {
+                       LBER_FREE(nextKeyp->attributeType);
+               }
+
+               if (nextKeyp->orderingRule != NULL) {
+                       LBER_FREE(nextKeyp->orderingRule);
+               }
+
+               LBER_FREE(nextKeyp);
+       }
+
+       LBER_FREE(keyList);
+}
+
+
+/* ---------------------------------------------------------------------------
+   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 }
+   
+   ---------------------------------------------------------------------------*/
+
+LIBLDAP_F( int )
+ldap_create_sort_control (
+       LDAP *ld,
+       LDAPSortKey **keyList,
+       int isCritical,
+       LDAPControl **ctrlp )
+{
+       int         i;
+       BerElement  *ber;
+       ber_tag_t tag;
+
+
+       if ( (ld == NULL) || (keyList == NULL) || (ctrlp == NULL) ) {
+               ld->ld_errno = LDAP_PARAM_ERROR;
+               return(ld->ld_errno);
+       }
+
+       if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
+               ld->ld_errno = LDAP_NO_MEMORY;
+               return( ld->ld_errno );
+       }
+
+       tag = ber_printf(ber, "{" /*}*/);
+       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 exit;
+
+               if ((keyList[i])->orderingRule != NULL) {
+                       tag = ber_printf( ber, "ts",
+                               LDAP_MATCHRULE_IDENTIFIER,
+                               (keyList[i])->orderingRule );
+
+                       if( tag == LBER_ERROR ) goto exit;
+               }
+
+               if ((keyList[i])->reverseOrder) {
+                       tag = ber_printf(ber, "tb",
+                               LDAP_REVERSEORDER_IDENTIFIER,
+                               (keyList[i])->reverseOrder );
+
+                       if( tag == LBER_ERROR ) goto exit;
+               }
+
+               tag = ber_printf(ber, /*{*/ "}");
+               if( tag == LBER_ERROR ) goto exit;
+       }
+
+       tag = ber_printf(ber, /*{*/ "}");
+       if( tag == LBER_ERROR ) goto exit;
+
+       ld->ld_errno = ldap_int_create_control( LDAP_CONTROL_SORTREQUEST,
+               ber, isCritical, ctrlp);
+
+       ber_free(ber, 1);
+
+       return(ld->ld_errno);
+
+exit:
+       ber_free(ber, 1);
+       ld->ld_errno =  LDAP_ENCODING_ERROR;
+       return(ld->ld_errno);
+}
+
+
+/* ---------------------------------------------------------------------------
+   ldap_parse_sort_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().
+                                 
+   returnCode (OUT) This result parameter is filled in with the sort control
+                                       result code.  This parameter MUST not be NULL.
+                                 
+   attribute  (OUT) If an error occured the server may return a string
+                                       indicating the first attribute in the sortkey list
+                                       that was in error.  If a string is returned, the memory
+                                       should be freed with ldap_memfree.  If this parameter is
+                                       NULL, no string is returned.
+   
+                          
+   Ber encoding for sort control
+        
+        SortResult ::= SEQUENCE {
+               sortResult  ENUMERATED {
+                       success                   (0), -- results are sorted
+                       operationsError           (1), -- server internal failure
+                       timeLimitExceeded         (3), -- timelimit reached before
+                                                                                  -- sorting was completed
+                       strongAuthRequired        (8), -- refused to return sorted
+                                                                                  -- results via insecure
+                                                                                  -- protocol
+                       adminLimitExceeded       (11), -- too many matching entries
+                                                                                  -- for the server to sort
+                       noSuchAttribute          (16), -- unrecognized attribute
+                                                                                  -- type in sort key
+                       inappropriateMatching    (18), -- unrecognized or inappro-
+                                                                                  -- priate matching rule in
+                                                                                  -- sort key
+                       insufficientAccessRights (50), -- refused to return sorted
+                                                                                  -- results to this client
+                       busy                     (51), -- too busy to process
+                       unwillingToPerform       (53), -- unable to sort
+                       other                    (80)
+                       },
+         attributeType [0] AttributeDescription OPTIONAL }
+   ---------------------------------------------------------------------------*/
+
+LIBLDAP_F( int )
+ldap_parse_sort_control(
+       LDAP           *ld,
+       LDAPControl    **ctrls,
+       unsigned long  *returnCode,
+       char           **attribute )
+{
+       BerElement *ber;
+       LDAPControl *pControl;
+       int i;
+       ber_tag_t tag, berTag;
+       ber_len_t berLen;
+
+       if (ld == 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);
+       }
+
+       if (attribute) {
+               *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;
+       }
+
+       /* 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);
+
+       if (ber == NULL) {
+               ld->ld_errno = LDAP_NO_MEMORY;
+               return(ld->ld_errno);
+       }
+
+       /* Extract the result code from the control. */
+       tag = ber_scanf(ber, "{e" /*}*/, returnCode);
+
+       if( tag == LBER_ERROR ) {
+               ber_free(ber, 1);
+               ld->ld_errno = LDAP_DECODING_ERROR;
+               return(ld->ld_errno);
+       }
+
+       /* If caller wants the attribute name, and if it's present in the control,
+          extract the attribute name which caused the error. */
+       if (attribute && (LDAP_ATTRTYPES_IDENTIFIER == ber_peek_tag(ber, &berLen)))
+       {
+               tag = ber_scanf(ber, "ta", &berTag, attribute);
+
+               if (tag == LBER_ERROR ) {
+                       ber_free(ber, 1);
+                       ld->ld_errno = LDAP_DECODING_ERROR;
+                       return(ld->ld_errno);
+               }
+       }
+
+       ber_free(ber,1);
+
+       ld->ld_errno = LDAP_SUCCESS;
+       return(ld->ld_errno);
+}
index adfca3de1072f08e683319ff77c91aebd978b9d3..8f34f509f28c0df3ebf109136a9ef60db1e0938f 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* Portions
@@ -111,13 +111,13 @@ ldap_init_searchprefs_buf(
 
     *solistp = prevso = NULL;
 
-    if ( next_line_tokens( &buf, &buflen, &toks ) != 2 ||
+    if ( ldap_int_next_line_tokens( &buf, &buflen, &toks ) != 2 ||
            strcasecmp( toks[ 0 ], "version" ) != 0 ) {
-       free_strarray( toks );
+       LDAP_VFREE( toks );
        return( LDAP_SEARCHPREF_ERR_SYNTAX );
     }
     version = atoi( toks[ 1 ] );
-    free_strarray( toks );
+    LDAP_VFREE( toks );
     if ( version != LDAP_SEARCHPREF_VERSION &&
            version != LDAP_SEARCHPREF_VERSION_ZERO ) {
        return( LDAP_SEARCHPREF_ERR_VERSION );
@@ -250,14 +250,14 @@ read_next_searchobj(
     /*
      * Object type prompt comes first
      */
-    if (( tokcnt = next_line_tokens( bufp, blenp, &toks )) != 1 ) {
-       free_strarray( toks );
+    if (( tokcnt = ldap_int_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
+       LDAP_VFREE( toks );
        return( tokcnt == 0 ? 0 : LDAP_SEARCHPREF_ERR_SYNTAX );
     }
 
     if (( so = (struct ldap_searchobj *)LDAP_CALLOC( 1,
            sizeof( struct ldap_searchobj ))) == NULL ) {
-       free_strarray( toks );
+       LDAP_VFREE( toks );
        return(  LDAP_SEARCHPREF_ERR_MEM );
     }
     so->so_objtypeprompt = toks[ 0 ];
@@ -267,8 +267,8 @@ read_next_searchobj(
      * if this is post-version zero, options come next
      */
     if ( soversion > LDAP_SEARCHPREF_VERSION_ZERO ) {
-       if (( tokcnt = next_line_tokens( bufp, blenp, &toks )) < 1 ) {
-           free_strarray( toks );
+       if (( tokcnt = ldap_int_next_line_tokens( bufp, blenp, &toks )) < 1 ) {
+           LDAP_VFREE( toks );
            ldap_free_searchprefs( so );
            return( LDAP_SEARCHPREF_ERR_SYNTAX );
        }
@@ -279,14 +279,14 @@ read_next_searchobj(
                }
            }
        }
-       free_strarray( toks );
+       LDAP_VFREE( toks );
     }
 
     /*
      * "Fewer choices" prompt is next
      */
-    if (( tokcnt = next_line_tokens( bufp, blenp, &toks )) != 1 ) {
-       free_strarray( toks );
+    if (( tokcnt = ldap_int_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
+       LDAP_VFREE( toks );
        ldap_free_searchprefs( so );
        return( LDAP_SEARCHPREF_ERR_SYNTAX );
     }
@@ -296,8 +296,8 @@ read_next_searchobj(
     /*
      * Filter prefix for "More Choices" searching is next
      */
-    if (( tokcnt = next_line_tokens( bufp, blenp, &toks )) != 1 ) {
-       free_strarray( toks );
+    if (( tokcnt = ldap_int_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
+       LDAP_VFREE( toks );
        ldap_free_searchprefs( so );
        return( LDAP_SEARCHPREF_ERR_SYNTAX );
     }
@@ -307,8 +307,8 @@ read_next_searchobj(
     /*
      * "Fewer Choices" filter tag comes next
      */
-    if (( tokcnt = next_line_tokens( bufp, blenp, &toks )) != 1 ) {
-       free_strarray( toks );
+    if (( tokcnt = ldap_int_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
+       LDAP_VFREE( toks );
        ldap_free_searchprefs( so );
        return( LDAP_SEARCHPREF_ERR_SYNTAX );
     }
@@ -318,8 +318,8 @@ read_next_searchobj(
     /*
      * Selection (disambiguation) attribute comes next
      */
-    if (( tokcnt = next_line_tokens( bufp, blenp, &toks )) != 1 ) {
-       free_strarray( toks );
+    if (( tokcnt = ldap_int_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
+       LDAP_VFREE( toks );
        ldap_free_searchprefs( so );
        return( LDAP_SEARCHPREF_ERR_SYNTAX );
     }
@@ -329,8 +329,8 @@ read_next_searchobj(
     /*
      * Label for selection (disambiguation) attribute
      */
-    if (( tokcnt = next_line_tokens( bufp, blenp, &toks )) != 1 ) {
-       free_strarray( toks );
+    if (( tokcnt = ldap_int_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
+       LDAP_VFREE( toks );
        ldap_free_searchprefs( so );
        return( LDAP_SEARCHPREF_ERR_SYNTAX );
     }
@@ -340,8 +340,8 @@ read_next_searchobj(
     /*
      * Search scope is next
      */
-    if (( tokcnt = next_line_tokens( bufp, blenp, &toks )) != 1 ) {
-       free_strarray( toks );
+    if (( tokcnt = ldap_int_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
+       LDAP_VFREE( toks );
        ldap_free_searchprefs( so );
        return( LDAP_SEARCHPREF_ERR_SYNTAX );
     }
@@ -355,22 +355,22 @@ read_next_searchobj(
        ldap_free_searchprefs( so );
        return( LDAP_SEARCHPREF_ERR_SYNTAX );
     }
-    free_strarray( toks );
+    LDAP_VFREE( toks );
 
 
     /*
      * "More Choices" search option list comes next
      */
     sa = &( so->so_salist );
-    while (( tokcnt = next_line_tokens( bufp, blenp, &toks )) > 0 ) {
+    while (( tokcnt = ldap_int_next_line_tokens( bufp, blenp, &toks )) > 0 ) {
        if ( tokcnt < 5 ) {
-           free_strarray( toks );
+           LDAP_VFREE( toks );
            ldap_free_searchprefs( so );
            return( LDAP_SEARCHPREF_ERR_SYNTAX );
        }
        if (( *sa = ( struct ldap_searchattr * ) LDAP_CALLOC( 1,
                sizeof( struct ldap_searchattr ))) == NULL ) {
-           free_strarray( toks );
+           LDAP_VFREE( toks );
            ldap_free_searchprefs( so );
            return(  LDAP_SEARCHPREF_ERR_MEM );
        }
@@ -395,15 +395,15 @@ read_next_searchobj(
      * Match types are last
      */
     sm = &( so->so_smlist );
-    while (( tokcnt = next_line_tokens( bufp, blenp, &toks )) > 0 ) {
+    while (( tokcnt = ldap_int_next_line_tokens( bufp, blenp, &toks )) > 0 ) {
        if ( tokcnt < 2 ) {
-           free_strarray( toks );
+           LDAP_VFREE( toks );
            ldap_free_searchprefs( so );
            return( LDAP_SEARCHPREF_ERR_SYNTAX );
        }
        if (( *sm = ( struct ldap_searchmatch * ) LDAP_CALLOC( 1,
                sizeof( struct ldap_searchmatch ))) == NULL ) {
-           free_strarray( toks );
+           LDAP_VFREE( toks );
            ldap_free_searchprefs( so );
            return(  LDAP_SEARCHPREF_ERR_MEM );
        }
index cd9994ad0601a6ae96c145bd5ad84f42521e3330..df8069ccaabe80c4e9da084decf7e1db1f711032 100644 (file)
@@ -1,9 +1,14 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
+/*
+ * Locale-specific 1-byte character versions
+ * See utf-8.c for UTF-8 versions
+ */
+
 #include "portable.h"
 
 #include <ac/stdlib.h>
@@ -92,20 +97,6 @@ char *(ldap_pvt_strtok)( char *str, const char *delim, char **pos )
        return str;
 }
 
-char *
-(ldap_pvt_strdup)( const char *s )
-{
-       char    *p;
-       size_t  len = strlen( s ) + 1;
-
-       if ( (p = (char *) malloc( len )) == NULL ) {
-               return( NULL );
-       }
-
-       memcpy( p, s, len );
-       return( p );
-}
-
 char *
 ldap_pvt_str2upper( char *str )
 {
index d52859042b85d5ae88243885531cbc12a712c52a..404ffbfe29e0fb7146f63e36989d7bd431f55e19 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -229,38 +229,37 @@ get_modlist( char *prompt1, char *prompt2, char *prompt3 )
 
 
 static int
-bind_prompt( LDAP *ld, char **dnp, char **passwdp, int *authmethodp,
-       int freeit )
+bind_prompt( LDAP *ld, LDAP_CONST char *url, int request, ber_int_t msgid)
 {
        static char     dn[256], passwd[256];
+       int     authmethod;
 
-       if ( !freeit ) {
-#ifdef HAVE_KERBEROS
+       printf("rebind for request=%d msgid=%ld url=%s\n",
+               request, (long) msgid, url );
+
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
                getline( dn, sizeof(dn), stdin,
                    "re-bind method (0->simple, 1->krbv41, 2->krbv42, 3->krbv41&2)? " );
-               if (( *authmethodp = atoi( dn )) == 3 ) {
-                       *authmethodp = LDAP_AUTH_KRBV4;
+       if (( authmethod = atoi( dn )) == 3 ) {
+               authmethod = LDAP_AUTH_KRBV4;
                } else {
-                       *authmethodp |= 0x80;
+               authmethod |= 0x80;
                }
-#else /* HAVE_KERBEROS */
-               *authmethodp = LDAP_AUTH_SIMPLE;
-#endif /* HAVE_KERBEROS */
+#else /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
+       authmethod = LDAP_AUTH_SIMPLE;
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
 
                getline( dn, sizeof(dn), stdin, "re-bind dn? " );
                strcat( dn, dnsuffix );
-               *dnp = dn;
 
-               if ( *authmethodp == LDAP_AUTH_SIMPLE && dn[0] != '\0' ) {
+       if ( authmethod == LDAP_AUTH_SIMPLE && dn[0] != '\0' ) {
                        getline( passwd, sizeof(passwd), stdin,
                            "re-bind password? " );
                } else {
                        passwd[0] = '\0';
                }
-               *passwdp = passwd;
-       }
 
-       return( LDAP_SUCCESS );
+       return ldap_bind_s( ld, dn, passwd, authmethod);
 }
 
 
@@ -324,12 +323,12 @@ main( int argc, char **argv )
 
                case 't':       /* copy ber's to given file */
                        copyfname = strdup( optarg );
-                       copyoptions = LBER_TO_FILE;
+/*                     copyoptions = LBER_TO_FILE; */
                        break;
 
                case 'T':       /* only output ber's to given file */
                        copyfname = strdup( optarg );
-                       copyoptions = (LBER_TO_FILE | LBER_TO_FILE_ONLY);
+/*                     copyoptions = (LBER_TO_FILE | LBER_TO_FILE_ONLY); */
                        break;
 
                default:
@@ -365,12 +364,12 @@ main( int argc, char **argv )
        }
 
        if ( copyfname != NULL ) {
-               if ( (ld->ld_sb.sb_fd = open( copyfname, O_WRONLY | O_CREAT,
+               if ( ( ld->ld_sb->sb_fd = open( copyfname, O_WRONLY | O_CREAT,
                    0600 ))  == -1 ) {
                        perror( copyfname );
                        exit ( EXIT_FAILURE );
                }
-               ld->ld_sb.sb_options = copyoptions;
+               ld->ld_sb->sb_options = copyoptions;
        }
 
        bound = 0;
@@ -413,13 +412,13 @@ main( int argc, char **argv )
                        break;
 
                case 'b':       /* asynch bind */
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
                        getline( line, sizeof(line), stdin,
                            "method (0->simple, 1->krbv41, 2->krbv42)? " );
                        method = atoi( line ) | 0x80;
-#else /* HAVE_KERBEROS */
+#else /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
                        method = LDAP_AUTH_SIMPLE;
-#endif /* HAVE_KERBEROS */
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
                        getline( dn, sizeof(dn), stdin, "dn? " );
                        strcat( dn, dnsuffix );
 
@@ -439,7 +438,7 @@ main( int argc, char **argv )
                        break;
 
                case 'B':       /* synch bind */
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
                        getline( line, sizeof(line), stdin,
                            "method 0->simple 1->krbv41 2->krbv42 3->krb? " );
                        method = atoi( line );
@@ -447,9 +446,9 @@ main( int argc, char **argv )
                                method = LDAP_AUTH_KRBV4;
                        else
                                method = method | 0x80;
-#else /* HAVE_KERBEROS */
+#else /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
                        method = LDAP_AUTH_SIMPLE;
-#endif /* HAVE_KERBEROS */
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
                        getline( dn, sizeof(dn), stdin, "dn? " );
                        strcat( dn, dnsuffix );
 
@@ -764,33 +763,6 @@ main( int argc, char **argv )
 
                        LDAP_BOOL_ZERO(&ld->ld_options);
 
-#ifdef STR_TRANSLATION
-                       getline( line, sizeof(line), stdin,
-                               "Automatic translation of T.61 strings (0=no, 1=yes)?" );
-                       if ( atoi( line ) == 0 ) {
-                               ld->ld_lberoptions &= ~LBER_TRANSLATE_STRINGS;
-                       } else {
-                               ld->ld_lberoptions |= LBER_TRANSLATE_STRINGS;
-#ifdef LDAP_CHARSET_8859
-                               getline( line, sizeof(line), stdin,
-                                       "Translate to/from ISO-8859 (0=no, 1=yes?" );
-                               if ( atoi( line ) != 0 ) {
-                                       ldap_set_string_translators( ld,
-                                           ldap_8859_to_t61,
-                                           ldap_t61_to_8859 );
-                               }
-#endif /* LDAP_CHARSET_8859 */
-                       }
-#endif /* STR_TRANSLATION */
-
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
-                       getline( line, sizeof(line), stdin,
-                               "Use DN & DNS to determine where to send requests (0=no, 1=yes)?" );
-                       if ( atoi( line ) != 0 ) {
-                               LDAP_BOOL_SET(&ld->ld_options, LDAP_BOOL_DNS);
-                       }
-#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_DNS */
-
                        getline( line, sizeof(line), stdin,
                                "Recognize and chase referrals (0=no, 1=yes)?" );
                        if ( atoi( line ) != 0 ) {
index 0a6f47fe2281e5624f7f0d15f7d3678e34caf7e5..9e49d641976e17d49c5d9af47633c66115b3547c 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  *
  * tls.c - Handle tls/ssl using SSLeay or OpenSSL.
@@ -27,6 +27,8 @@
 
 #ifdef HAVE_OPENSSL_SSL_H
 #include <openssl/ssl.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
 #elif defined( HAVE_SSL_H )
 #include <ssl.h>
 #endif
@@ -39,30 +41,20 @@ static char *tls_opt_cacertdir = NULL;
 static int  tls_opt_require_cert = 0;
 static char *tls_opt_ciphersuite = NULL;
 
-#define HAS_TLS( sb ) ((sb)->sb_io==&tls_io)
+#define HAS_TLS( sb )  ber_sockbuf_ctrl( sb, LBER_SB_OPT_HAS_IO, \
+                               (void *)&ldap_pvt_sockbuf_io_tls )
 
-static int tls_setup( Sockbuf *sb, void *arg );
-static int tls_remove( Sockbuf *sb );
-static ber_slen_t tls_read( Sockbuf *sb, void *buf, ber_len_t len );
-static ber_slen_t tls_write( Sockbuf *sb, void *buf, ber_len_t len );
-static int tls_close( Sockbuf *sb );
-static int tls_report_error( void );
-
-static Sockbuf_IO tls_io=
-{
-   tls_setup,
-   tls_remove,
-   tls_read,
-   tls_write,
-   tls_close
-};
+static void tls_report_error( void );
 
 static void tls_info_cb( SSL *ssl, int where, int ret );
 static int tls_verify_cb( int ok, X509_STORE_CTX *ctx );
 static RSA * tls_tmp_rsa_cb( SSL *ssl, int is_export, int key_length );
-static DH * tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length );
 static STACK_OF(X509_NAME) * get_ca_list( char * bundle, char * dir );
 
+#if 0  /* Currently this is not used by anyone */
+static DH * tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length );
+#endif
+
 static SSL_CTX *tls_def_ctx = NULL;
 
 #ifdef LDAP_R_COMPILE
@@ -74,9 +66,9 @@ static ldap_pvt_thread_mutex_t        tls_mutexes[CRYPTO_NUM_LOCKS];
 static void tls_locking_cb( int mode, int type, const char *file, int line )
 {
        if ( mode & CRYPTO_LOCK ) {
-               ldap_pvt_thread_mutex_lock( tls_mutexes+type );
+               ldap_pvt_thread_mutex_lock( &tls_mutexes[type] );
        } else {
-               ldap_pvt_thread_mutex_unlock( tls_mutexes+type );
+               ldap_pvt_thread_mutex_unlock( &tls_mutexes[type] );
        }
 }
 
@@ -91,7 +83,7 @@ static void tls_init_threads( void )
        int i;
 
        for( i=0; i< CRYPTO_NUM_LOCKS ; i++ ) {
-               ldap_pvt_thread_mutex_init( tls_mutexes+i );
+               ldap_pvt_thread_mutex_init( &tls_mutexes[i] );
        }
        CRYPTO_set_locking_callback( tls_locking_cb );
        /* FIXME: the thread id should be added somehow... */
@@ -109,7 +101,8 @@ ldap_pvt_tls_init( void )
        static int tls_initialized = 0;
 
        if ( tls_initialized )
-               return -1;
+               return 0;
+       tls_initialized = 1;
 #ifdef LDAP_R_COMPILE
        tls_init_threads();
 #endif
@@ -147,25 +140,28 @@ ldap_pvt_tls_init_def_ctx( void )
                        tls_report_error();
                        goto error_exit;
                }
-               if ( !SSL_CTX_load_verify_locations( tls_def_ctx,
-                                                    tls_opt_cacertfile,
-                                                    tls_opt_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_cacertdir,0);
-                       tls_report_error();
-                       goto error_exit;
-               }
-               calist = get_ca_list( tls_opt_cacertfile, tls_opt_cacertdir );
-               if ( !calist ) {
-                       Debug( LDAP_DEBUG_ANY,
-               "TLS: could not load client CA list (file:`%s',dir:`%s').\n",
-                              tls_opt_cacertfile,tls_opt_cacertdir,0);
-                       tls_report_error();
-                       goto error_exit;
+               if (tls_opt_cacertfile != NULL || tls_opt_cacertdir != NULL) {
+                       if ( !SSL_CTX_load_verify_locations( tls_def_ctx,
+                                                            tls_opt_cacertfile,
+                                                            tls_opt_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_cacertdir,0);
+                               tls_report_error();
+                               goto error_exit;
+                       }
+                       calist = get_ca_list( tls_opt_cacertfile, tls_opt_cacertdir );
+                       if ( !calist ) {
+                               Debug( LDAP_DEBUG_ANY,
+                       "TLS: could not load client CA list (file:`%s',dir:`%s').\n",
+                                      tls_opt_cacertfile,tls_opt_cacertdir,0);
+                               tls_report_error();
+                               goto error_exit;
+                       }
+                       SSL_CTX_set_client_CA_list( tls_def_ctx, calist );
                }
-               SSL_CTX_set_client_CA_list( tls_def_ctx, calist );
                if ( tls_opt_keyfile &&
                     !SSL_CTX_use_PrivateKey_file( tls_def_ctx,
                                                   tls_opt_keyfile,
@@ -208,6 +204,10 @@ ldap_pvt_tls_init_def_ctx( void )
 #endif
        return 0;
 error_exit:
+       if ( tls_def_ctx != NULL ) {
+               SSL_CTX_free( tls_def_ctx );
+               tls_def_ctx = NULL;
+       }
 #ifdef LDAP_R_COMPILE
        ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
 #endif
@@ -230,9 +230,8 @@ get_ca_list( char * bundle, char * dir )
 }
 
 static SSL *
-alloc_handle( Sockbuf *sb, void *ctx_arg )
+alloc_handle( void *ctx_arg )
 {
-       int     err;
        SSL_CTX *ctx;
        SSL     *ssl;
 
@@ -253,18 +252,277 @@ alloc_handle( Sockbuf *sb, void *ctx_arg )
        if ( tls_opt_trace ) {
                SSL_set_info_callback( ssl, tls_info_cb );
        }
-       sb->sb_iodata = ssl;
-       SSL_set_fd( ssl, ber_pvt_sb_get_desc( sb ) );
        return ssl;
 }
 
-static void
-update_flags( Sockbuf *sb, SSL * ssl )
+static int
+update_flags( Sockbuf *sb, SSL * 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)
+       {
+           sb->sb_trans_needs_read  = 1;
+           return 1;
+       } else if (err == SSL_ERROR_WANT_WRITE)
+       {
+           sb->sb_trans_needs_write = 1;
+           return 1;
+       } else if (err == SSL_ERROR_WANT_CONNECT)
+       {
+           return 1;
+       }
+       return 0;
+}
+
+/*
+ * TLS support for LBER Sockbufs
+ */
+
+struct tls_data {
+       SSL                     *ssl;
+       Sockbuf_IO_Desc         *sbiod;
+};
+
+extern BIO_METHOD ldap_pvt_sb_bio_method;
+
+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( &ldap_pvt_sb_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;
+       }
+       
+       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;
+#ifdef WIN32
+               errno = EWOULDBLOCK;
+#endif
+       }
+       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;
+#ifdef WIN32
+               errno = EWOULDBLOCK;
+#endif
+       }
+       else
+               sbiod->sbiod_sb->sb_trans_needs_write = 0;
+       return ret;
+}
+
+Sockbuf_IO ldap_pvt_sockbuf_io_tls =
+{
+       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 */
+};
+
+static int
+sb_tls_bio_create( BIO *b ) {
+       b->init = 1;
+       b->num = 0;
+       b->ptr = NULL;
+       b->flags = 0;
+       return 1;
+}
+
+static int
+sb_tls_bio_destroy( BIO *b )
+{
+       if ( b == NULL )
+               return 0;
+
+       b->ptr = NULL;          /* sb_tls_remove() will free it */
+       b->init = 0;
+       b->flags = 0;
+       return 1;
+}
+
+static int
+sb_tls_bio_read( BIO *b, char *buf, int len )
+{
+       struct tls_data         *p;
+       int                     ret;
+               
+       if ( buf == NULL || len <= 0 )
+               return 0;
+
+       p = (struct tls_data *)b->ptr;
+
+       if ( p == NULL || p->sbiod == NULL )
+               return 0;
+
+       ret = LBER_SBIOD_READ_NEXT( p->sbiod, buf, len );
+
+       BIO_clear_retry_flags( b );
+       if ( ret < 0 && errno == EWOULDBLOCK )
+               BIO_set_retry_read( b );
+
+       return ret;
+}
+
+static int
+sb_tls_bio_write( BIO *b, char *buf, int len )
+{
+       struct tls_data         *p;
+       int                     ret;
+       
+       if ( buf == NULL || len <= 0 )
+               return 0;
+       
+       p = (struct tls_data *)b->ptr;
+
+       if ( p == NULL || p->sbiod == NULL )
+               return 0;
+
+       ret = LBER_SBIOD_WRITE_NEXT( p->sbiod, buf, len );
+
+       BIO_clear_retry_flags( b );
+       if ( ret < 0 && errno == EWOULDBLOCK )
+               BIO_set_retry_write( b );
+
+       return ret;
+}
+
+static long
+sb_tls_bio_ctrl( BIO *b, int cmd, long num, char *ptr )
+{
+       if ( cmd == BIO_CTRL_FLUSH ) {
+               /* The OpenSSL library needs this */
+               return 1;
+       }
+       return 0;
+}
+
+static int
+sb_tls_bio_gets( BIO *b, char *buf, int len )
 {
-       sb->sb_trans_needs_read  = SSL_want_read(ssl) ? 1 : 0;
-       sb->sb_trans_needs_write = SSL_want_write(ssl) ? 1 : 0;
+       return -1;
 }
 
+static int
+sb_tls_bio_puts( BIO *b, char *str )
+{
+       return sb_tls_bio_write( b, str, strlen( str ) );
+}
+       
+BIO_METHOD ldap_pvt_sb_bio_method =
+{
+       ( 100 | 0x400 ),                /* it's a source/sink BIO */
+       "sockbuf glue",
+       sb_tls_bio_write,
+       sb_tls_bio_read,
+       sb_tls_bio_puts,
+       sb_tls_bio_gets,
+       sb_tls_bio_ctrl,
+       sb_tls_bio_create,
+       sb_tls_bio_destroy
+};
+
 /*
  * 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.
@@ -279,38 +537,44 @@ update_flags( Sockbuf *sb, SSL * ssl )
  */
 
 int
-ldap_pvt_tls_connect( Sockbuf *sb, void *ctx_arg )
+ldap_pvt_tls_connect( LDAP *ld, Sockbuf *sb, void *ctx_arg )
 {
        int     err;
        SSL     *ssl;
 
        if ( HAS_TLS( sb ) ) {
-               ssl = (SSL *) sb->sb_iodata;
+               ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl );
        } else {
-               ssl = alloc_handle( sb, ctx_arg );
+               ssl = alloc_handle( ctx_arg );
                if ( ssl == NULL )
                        return -1;
-               ber_pvt_sb_clear_io( sb );
-               ber_pvt_sb_set_io( sb, &tls_io, (void *)ssl );
+#ifdef LDAP_DEBUG
+               ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug,
+                       LBER_SBIOD_LEVEL_TRANSPORT, (void *)"tls_" );
+#endif
+               ber_sockbuf_add_io( sb, &ldap_pvt_sockbuf_io_tls,
+                       LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl );
        }
 
        err = SSL_connect( ssl );
 
-       if ( err <= 0 ) {
-               if (
-#ifdef EWOULDBLOCK
-                   (errno==EWOULDBLOCK) ||
+#ifdef HAVE_WINSOCK
+       errno = WSAGetLastError();
 #endif
-#ifdef EAGAIN
-                   (errno==EAGAIN) ||
-#endif
-                   (0)) {
-                       update_flags( sb, ssl );
+       if ( err <= 0 ) {
+               if ( update_flags( sb, ssl, err ))
                        return 1;
+               if ((err = ERR_peek_error())) {
+                       char buf[256];
+                       ld->ld_error = LDAP_STRDUP(ERR_error_string(err, buf));
                }
                Debug( LDAP_DEBUG_ANY,"TLS: can't connect.\n",0,0,0);
-               ber_pvt_sb_clear_io( sb );
-               ber_pvt_sb_set_io( sb, &ber_pvt_sb_io_tcp, NULL );
+               ber_sockbuf_remove_io( sb, &ldap_pvt_sockbuf_io_tls,
+                       LBER_SBIOD_LEVEL_TRANSPORT );
+#ifdef LDAP_DEBUG
+               ber_sockbuf_remove_io( sb, &ber_sockbuf_io_debug,
+                       LBER_SBIOD_LEVEL_TRANSPORT );
+#endif
                return -1;
        }
        return 0;
@@ -327,39 +591,76 @@ ldap_pvt_tls_accept( Sockbuf *sb, void *ctx_arg )
        SSL     *ssl;
 
        if ( HAS_TLS( sb ) ) {
-               ssl = (SSL *) sb->sb_iodata;
+               ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl );
        } else {
-               ssl = alloc_handle( sb, ctx_arg );
+               ssl = alloc_handle( ctx_arg );
                if ( ssl == NULL )
                        return -1;
-               ber_pvt_sb_clear_io( sb );
-               ber_pvt_sb_set_io( sb, &tls_io, (void *)ssl );
+#ifdef LDAP_DEBUG
+               ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug,
+                       LBER_SBIOD_LEVEL_TRANSPORT, (void *)"tls_" );
+#endif
+               ber_sockbuf_add_io( sb, &ldap_pvt_sockbuf_io_tls,
+                       LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl );
        }
 
        err = SSL_accept( ssl );
 
+#ifdef HAVE_WINSOCK
+       errno = WSAGetLastError();
+#endif
        if ( err <= 0 ) {
-               if ( !SSL_want_nothing( ssl ) ) {
-                       update_flags( sb, ssl );
+               if ( update_flags( sb, ssl, err ))
                        return 1;
-               }
                Debug( LDAP_DEBUG_ANY,"TLS: can't accept.\n",0,0,0 );
                tls_report_error();
-               ber_pvt_sb_clear_io( sb );
-               ber_pvt_sb_set_io( sb, &ber_pvt_sb_io_tcp, NULL );
+               ber_sockbuf_remove_io( sb, &ldap_pvt_sockbuf_io_tls,
+                       LBER_SBIOD_LEVEL_TRANSPORT );
+#ifdef LDAP_DEBUG
+               ber_sockbuf_remove_io( sb, &ber_sockbuf_io_debug,
+                       LBER_SBIOD_LEVEL_TRANSPORT );
+#endif
                return -1;
        }
        return 0;
 }
 
+int
+ldap_pvt_tls_inplace ( Sockbuf *sb )
+{
+       if ( HAS_TLS( sb ) )
+               return(1);
+       return(0);
+}
+
+void *
+ldap_pvt_tls_sb_handle( Sockbuf *sb )
+{
+       void                    *p;
+       
+       if (HAS_TLS( sb )) {
+               ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&p );
+               return p;
+       }
+               return NULL;
+}
+
+void *
+ldap_pvt_tls_get_handle( LDAP *ld )
+{
+       return ldap_pvt_tls_sb_handle( ld->ld_sb );
+}
+
 const char *
 ldap_pvt_tls_get_peer( LDAP *ld )
 {
+    return NULL;
 }
 
 const char *
 ldap_pvt_tls_get_peer_issuer( LDAP *ld )
 {
+    return NULL;
 }
 
 int
@@ -379,21 +680,19 @@ ldap_pvt_tls_config( struct ldapoptions *lo, int option, const char *arg )
                      ( strcasecmp( arg, "true" ) == 0 ) );
                return ldap_pvt_tls_set_option( NULL, option, (void *) &i );
        case LDAP_OPT_X_TLS:
+               i = -1;
                if ( strcasecmp( arg, "never" ) == 0 )
-                       return ldap_pvt_tls_set_option( lo, option,
-                               LDAP_OPT_X_TLS_NEVER );
+                       i = LDAP_OPT_X_TLS_NEVER ;
                if ( strcasecmp( arg, "demand" ) == 0 )
-                       return ldap_pvt_tls_set_option( lo, option,
-                               LDAP_OPT_X_TLS_DEMAND );
+                       i = LDAP_OPT_X_TLS_DEMAND ;
                if ( strcasecmp( arg, "allow" ) == 0 )
-                       return ldap_pvt_tls_set_option( lo, option,
-                               LDAP_OPT_X_TLS_ALLOW );
+                       i = LDAP_OPT_X_TLS_ALLOW ;
                if ( strcasecmp( arg, "try" ) == 0 )
-                       return ldap_pvt_tls_set_option( lo, option,
-                               LDAP_OPT_X_TLS_TRY );
+                       i = LDAP_OPT_X_TLS_TRY ;
                if ( strcasecmp( arg, "hard" ) == 0 )
-                       return ldap_pvt_tls_set_option( lo, option,
-                               LDAP_OPT_X_TLS_HARD );
+                       i = LDAP_OPT_X_TLS_HARD ;
+               if (i >= 0)
+                       return ldap_pvt_tls_set_option( lo, option, &i );
                return -1;
        default:
                return -1;
@@ -409,9 +708,9 @@ ldap_pvt_tls_get_option( struct ldapoptions *lo, int option, void *arg )
                break;
        case LDAP_OPT_X_TLS_CERT:
                if ( lo == NULL )
-                       arg = (void *) tls_def_ctx;
+                       *(void **)arg = (void *) tls_def_ctx;
                else
-                       arg = lo->ldo_tls_ctx;
+                       *(void **)arg = lo->ldo_tls_ctx;
                break;
        case LDAP_OPT_X_TLS_CACERTFILE:
                *(char **)arg = tls_opt_cacertfile ?
@@ -449,21 +748,28 @@ ldap_pvt_tls_set_option( struct ldapoptions *lo, int option, void *arg )
                case LDAP_OPT_X_TLS_ALLOW:
                case LDAP_OPT_X_TLS_TRY:
                case LDAP_OPT_X_TLS_HARD:
-                       lo->ldo_tls_mode = *(int *)arg;
-                       break;
-               default:
-                       return -1;
+                       if (lo != NULL) {
+                               lo->ldo_tls_mode = *(int *)arg;
+                       }
+
+                       return 0;
                }
-               break;
+               return -1;
+
        case LDAP_OPT_X_TLS_CERT:
-               if ( lo == NULL )
+               if ( lo == NULL ) {
                        tls_def_ctx = (SSL_CTX *) arg;
-               else
+
+               } else {
                        lo->ldo_tls_ctx = arg;
-               break;
+               }
+               return 0;
        }
-       if ( lo != NULL )
+
+       if ( lo != NULL ) {
                return -1;
+       }
+
        switch( option ) {
        case LDAP_OPT_X_TLS_CACERTFILE:
                if ( tls_opt_cacertfile ) free( tls_opt_cacertfile );
@@ -494,43 +800,21 @@ ldap_pvt_tls_set_option( struct ldapoptions *lo, int option, void *arg )
        return 0;
 }
 
-static int
-tls_setup( Sockbuf *sb, void *arg )
-{
-       sb->sb_iodata = arg;
-       return 0;
-}
-
-static int
-tls_remove( Sockbuf *sb )
-{
-       SSL_free( (SSL *) sb->sb_iodata );
-       return 0;
-}
-
-static ber_slen_t
-tls_write( Sockbuf *sb, void *buf, ber_len_t sz )
-{
-       int ret = SSL_write( (SSL *)sb->sb_iodata, buf, sz );
-
-       update_flags(sb, (SSL *)sb->sb_iodata );
-       return ret;
-}
-
-static ber_slen_t
-tls_read( Sockbuf *sb, void *buf, ber_len_t sz )
+int
+ldap_pvt_tls_start ( LDAP *ld, Sockbuf *sb, void *ctx_arg )
 {
-       int ret = SSL_read( (SSL *)sb->sb_iodata, buf, sz );
+       /*
+        * Fortunately, the lib uses blocking io...
+        */
+       if ( ldap_pvt_tls_connect( ld, sb, ctx_arg ) < 0 ) {
+               return LDAP_CONNECT_ERROR;
+       }
 
-       update_flags(sb, (SSL *)sb->sb_iodata );
-       return ret;
-}
+       /* FIXME: hostname of server must be compared with name in
+        * certificate....
+        */
 
-static int
-tls_close( Sockbuf *sb )
-{
-       tcp_close( ber_pvt_sb_get_desc( sb ) );
-       return 0;
+       return LDAP_SUCCESS;
 }
 
 /* Derived from openssl/apps/s_cb.c */
@@ -603,15 +887,15 @@ tls_verify_cb( int ok, X509_STORE_CTX *ctx )
               sname ? sname : "-unknown-",
               iname ? iname : "-unknown-" );
        if ( sname )
-               free ( sname );
+               CRYPTO_free ( sname );
        if ( iname )
-               free ( iname );
+               CRYPTO_free ( iname );
 
-       return 1;
+       return ok;
 }
 
 /* Inspired by ERR_print_errors in OpenSSL */
-static int
+static void
 tls_report_error( void )
 {
         unsigned long l;
@@ -642,11 +926,13 @@ tls_tmp_rsa_cb( SSL *ssl, int is_export, int key_length )
        return tmp_rsa;
 }
 
+#if 0
 static DH *
 tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length )
 {
        return NULL;
 }
+#endif
 
 #else
 static int dummy;
index 8b480a3ef568a1da8a53c0336843c22078e7cb97..385312256f94e7663d9f9e235b8e9702573ea383 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
@@ -12,6 +12,7 @@
 
 #include <stdio.h>
 
+#include <ac/socket.h>
 #include <ac/stdlib.h>
 
 #include <ac/ctype.h>
@@ -477,11 +478,11 @@ do_entry2text_search(
 #ifdef LDAP_CONNECTIONLESS
            if ( LDAP_IS_CLDAP( ld ))
                    err = cldap_search_s( ld, dn, LDAP_SCOPE_BASE,
-                       "objectClass=*", ocattrs, 0, &ldmp, NULL );
+                       NULL, ocattrs, 0, &ldmp, NULL );
            else
 #endif /* LDAP_CONNECTIONLESS */
                    err = ldap_search_st( ld, dn, LDAP_SCOPE_BASE,
-                           "objectClass=*", ocattrs, 0, &timeout, &ldmp );
+                           NULL, ocattrs, 0, &timeout, &ldmp );
 
            if ( err == LDAP_SUCCESS ) {
                entry = ldap_first_entry( ld, ldmp );
@@ -510,11 +511,11 @@ do_entry2text_search(
 
 #ifdef LDAP_CONNECTIONLESS
     if ( LDAP_IS_CLDAP( ld ))
-       err = cldap_search_s( ld, dn, LDAP_SCOPE_BASE, "objectClass=*",
+       err = cldap_search_s( ld, dn, LDAP_SCOPE_BASE, NULL,
                fetchattrs, 0, &ldmp, NULL );
     else
 #endif /* LDAP_CONNECTIONLESS */
-       err = ldap_search_st( ld, dn, LDAP_SCOPE_BASE, "objectClass=*",
+       err = ldap_search_st( ld, dn, LDAP_SCOPE_BASE, NULL,
                fetchattrs, 0, &timeout, &ldmp );
 
     if ( freedn ) {
@@ -900,7 +901,7 @@ time2text( char *ldtimestr, int dateonly )
            return( fmterr );
        }
        
-    memset( (char *)&t, 0, sizeof( struct tm ));
+    memset( (char *)&t, '\0', sizeof( struct tm ));
 
     p = ldtimestr;
 
@@ -909,8 +910,17 @@ time2text( char *ldtimestr, int dateonly )
                /* POSIX says tm_year should be year - 1900 */
        t.tm_year = 100 * GET2BYTENUM( p ) - 1900;
                p += 2;
+               t.tm_year += GET2BYTENUM( p ); p += 2;
+
+       } else {
+               /* came without a century */
+               t.tm_year = GET2BYTENUM( p ); p += 2;
+
+               /* Y2K hack - 2 digit years < 70 are 21st century */
+               if( t.tm_year < 70 ) {
+                       t.tm_year += 100;
+               }
        }
-    t.tm_year = GET2BYTENUM( p ); p += 2;
 
     t.tm_mon = GET2BYTENUM( p ) - 1; p += 2;
     t.tm_mday = GET2BYTENUM( p ); p += 2;
index bbdae7fa1af49809de64d833c54d37982816d62b..728724690d81727837cf216eab3a281fa23ca4bc 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 #include "portable.h"
index 9d215cdec999aa45eb2333482374cbee70225c60..d5e1a5206b470e20f6260a72c6af6eeb9f136dad 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
@@ -185,7 +185,7 @@ ldap_ufn_search_ctx( LDAP *ld, char **ufncomp, int ncomp, char *prefix,
 
                        if ( err == -1 || err == LDAP_USER_CANCELLED ) {
                                if ( dns != NULL ) {
-                                       ldap_value_free( dns );
+                                       LDAP_VFREE( dns );
                                        dns = NULL;
                                }
                                return( err );
@@ -198,7 +198,7 @@ ldap_ufn_search_ctx( LDAP *ld, char **ufncomp, int ncomp, char *prefix,
                                goto tryagain;
                        } else {
                                if ( dns != NULL ) {
-                                       ldap_value_free( dns );
+                                       LDAP_VFREE( dns );
                                        dns = NULL;
                                }
                                return( err );
@@ -209,7 +209,7 @@ ldap_ufn_search_ctx( LDAP *ld, char **ufncomp, int ncomp, char *prefix,
                if ( phase == 1 )
                        phase++;
                if ( dns != NULL ) {
-                       ldap_value_free( dns );
+                       LDAP_VFREE( dns );
                        dns = NULL;
                }
        }
@@ -246,7 +246,7 @@ ldap_ufn_search_ct(
                    attrsonly, res, cancelproc, cancelparm, tag1, tag2, tag3 );
 
                if ( ldap_count_entries( ld, *res ) > 0 ) {
-                       ldap_value_free( ufncomp );
+                       LDAP_VFREE( ufncomp );
                        return( err );
                } else {
                        ldap_msgfree( *res );
@@ -255,21 +255,21 @@ ldap_ufn_search_ct(
        }
 
        if ( ld->ld_ufnprefix == NULL ) {
-               ldap_value_free( ufncomp );
+               LDAP_VFREE( ufncomp );
                return( err );
        }
 
        /* if that failed, or < 2 components, use the prefix */
        if ( (prefixcomp = ldap_explode_dn( ld->ld_ufnprefix, 0 )) == NULL ) {
-               ldap_value_free( ufncomp );
+               LDAP_VFREE( ufncomp );
                return( ld->ld_errno = LDAP_LOCAL_ERROR );
        }
        for ( pcomp = 0; prefixcomp[pcomp] != NULL; pcomp++ )
                ;       /* NULL */
        if ( (pbuf = (char *) LDAP_MALLOC( strlen( ld->ld_ufnprefix ) + 1 ))
            == NULL ) { 
-               ldap_value_free( ufncomp );
-               ldap_value_free( prefixcomp );
+               LDAP_VFREE( ufncomp );
+               LDAP_VFREE( prefixcomp );
                return( ld->ld_errno = LDAP_NO_MEMORY );
        }
 
@@ -293,8 +293,8 @@ ldap_ufn_search_ct(
                }
        }
 
-       ldap_value_free( ufncomp );
-       ldap_value_free( prefixcomp );
+       LDAP_VFREE( ufncomp );
+       LDAP_VFREE( prefixcomp );
        LDAP_FREE( pbuf );
 
        return( err );
@@ -478,7 +478,8 @@ ldap_ufn_setprefix( LDAP *ld, LDAP_CONST char *prefix )
        if ( ld->ld_ufnprefix != NULL )
                LDAP_FREE( ld->ld_ufnprefix );
 
-       ld->ld_ufnprefix = LDAP_STRDUP( prefix );
+       ld->ld_ufnprefix = prefix == NULL
+               ? NULL : LDAP_STRDUP( prefix );
 }
 
 int
index 852926f785304f7c45660f9dcbb91e8ff55d20d7..36810f3d8dd09b97673e6dcb3c5fd222e2245e82 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
@@ -37,6 +37,15 @@ ldap_unbind_ext(
        return ldap_ld_free( ld, 1, sctrls, cctrls );
 }
 
+int
+ldap_unbind_ext_s(
+       LDAP *ld,
+       LDAPControl **sctrls,
+       LDAPControl **cctrls )
+{
+       return ldap_unbind_ext( ld, sctrls, cctrls );
+}
+
 int
 ldap_unbind( LDAP *ld )
 {
@@ -124,14 +133,9 @@ ldap_ld_free(
                ld->ld_selectinfo = NULL;
        }
 
-       if ( ld->ld_options.ldo_defbase != NULL ) {
-               LDAP_FREE( ld->ld_options.ldo_defbase );
-               ld->ld_options.ldo_defbase = NULL;
-       }
-
-       if ( ld->ld_options.ldo_defhost != NULL ) {
-               LDAP_FREE( ld->ld_options.ldo_defhost );
-               ld->ld_options.ldo_defhost = NULL;
+       if ( ld->ld_options.ldo_defludp != NULL ) {
+               ldap_free_urllist( ld->ld_options.ldo_defludp );
+               ld->ld_options.ldo_defludp = NULL;
        }
 
        if ( ld->ld_options.ldo_tm_api != NULL ) {
@@ -144,7 +148,13 @@ ldap_ld_free(
                ld->ld_options.ldo_tm_net = NULL;
        }
 
-       ber_pvt_sb_destroy( &(ld->ld_sb) );   
+#ifdef HAVE_CYRUS_SASL
+       if ( ld->ld_sasl_context != NULL ) {
+               sasl_dispose( &ld->ld_sasl_context );
+       }
+#endif 
+
+       ber_sockbuf_free( ld->ld_sb );   
    
        LDAP_FREE( (char *) ld );
    
index b632c688f8da78a9b5014bf506d60ab48bef76a9..f604098c1a350bec0fd7df1996416dbe1a5fd263 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*  Portions
@@ -10,7 +10,7 @@
  *  LIBLDAP url.c -- LDAP URL (RFC 2255) related routines
  *
  *  LDAP URLs look like this:
- *    ldap[s]://host:port[/[dn[?[attributes][?[scope][?[filter][?exts]]]]]]
+ *    ldap[is]://host:port[/[dn[?[attributes][?[scope][?[filter][?exts]]]]]]
  *
  *  where:
  *   attributes is a comma separated list
 static const char* skip_url_prefix LDAP_P((
        const char *url,
        int *enclosedp,
-       int *ldaps ));
+       const char **scheme ));
 
+int ldap_pvt_url_scheme2proto( const char *scheme )
+{
+       assert( scheme );
+
+       if( scheme == NULL ) {
+               return -1;
+       }
+
+       if( strcmp("ldap", scheme) == 0 ) {
+               return LDAP_PROTO_TCP;
+       }
+
+       if( strcmp("ldapi", scheme) == 0 ) {
+               return LDAP_PROTO_IPC;
+       }
+
+       if( strcmp("ldaps", scheme) == 0 ) {
+               return LDAP_PROTO_TCP;
+       }
+
+       return -1;
+}
+
+int ldap_pvt_url_scheme2tls( const char *scheme )
+{
+       assert( scheme );
+
+       if( scheme == NULL ) {
+               return -1;
+       }
+
+       return strcmp("ldaps", scheme) == 0;
+}
 
 int
 ldap_is_ldap_url( LDAP_CONST char *url )
 {
        int     enclosed;
-       int ldaps;
+       const char * scheme;
 
        if( url == NULL ) {
                return 0;
        }
 
-       if( skip_url_prefix( url, &enclosed, &ldaps) == NULL ) {
+       if( skip_url_prefix( url, &enclosed, &scheme ) == NULL ) {
                return 0;
        }
 
-       return !ldaps;
+       return 1;
 }
 
 int
 ldap_is_ldaps_url( LDAP_CONST char *url )
 {
        int     enclosed;
-       int ldaps;
+       const char * scheme;
 
        if( url == NULL ) {
                return 0;
        }
 
-       if( skip_url_prefix( url, &enclosed, &ldaps) == NULL ) {
+       if( skip_url_prefix( url, &enclosed, &scheme ) == NULL ) {
                return 0;
        }
 
-       return ldaps;
+       return strcmp(scheme, "ldaps") == 0;
+}
+
+int
+ldap_is_ldapi_url( LDAP_CONST char *url )
+{
+       int     enclosed;
+       const char * scheme;
+
+       if( url == NULL ) {
+               return 0;
+       }
+
+       if( skip_url_prefix( url, &enclosed, &scheme ) == NULL ) {
+               return 0;
+       }
+
+       return strcmp(scheme, "ldapi") == 0;
 }
 
 static const char*
 skip_url_prefix(
        const char *url,
        int *enclosedp,
-       int *ldaps )
+       const char **scheme )
 {
 /*
  * return non-zero if this looks like a LDAP URL; zero if not
@@ -113,7 +163,7 @@ skip_url_prefix(
        if ( strncasecmp( p, LDAP_URL_PREFIX, LDAP_URL_PREFIX_LEN ) == 0 ) {
                /* skip over "ldap://" prefix and return success */
                p += LDAP_URL_PREFIX_LEN;
-               *ldaps = 0;
+               *scheme = "ldap";
                return( p );
        }
 
@@ -121,7 +171,15 @@ skip_url_prefix(
        if ( strncasecmp( p, LDAPS_URL_PREFIX, LDAPS_URL_PREFIX_LEN ) == 0 ) {
                /* skip over "ldaps://" prefix and return success */
                p += LDAPS_URL_PREFIX_LEN;
-               *ldaps = 1;
+               *scheme = "ldaps";
+               return( p );
+       }
+
+       /* check for "ldapi://" prefix */
+       if ( strncasecmp( p, LDAPI_URL_PREFIX, LDAPI_URL_PREFIX_LEN ) == 0 ) {
+               /* skip over "ldapi://" prefix and return success */
+               p += LDAPI_URL_PREFIX_LEN;
+               *scheme = "ldapi";
                return( p );
        }
 
@@ -160,7 +218,8 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp )
 
        LDAPURLDesc     *ludp;
        char    *p, *q;
-       int             i, enclosed, ldaps;
+       int             i, enclosed;
+       const char *scheme = NULL;
        const char *url_tmp;
        char *url;
 
@@ -168,19 +227,29 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp )
                return LDAP_URL_ERR_PARAM;
        }
 
+#ifndef LDAP_INT_IN_KERNEL
+       /* Global options may not be created yet
+        * We can't test if the global options are initialized
+        * because a call to LDAP_INT_GLOBAL_OPT() will try to allocate
+        * the options and cause infinite recursion
+        */
        Debug( LDAP_DEBUG_TRACE, "ldap_url_parse(%s)\n", url_in, 0, 0 );
+#endif
 
        *ludpp = NULL;  /* pessimistic */
 
-       url_tmp = skip_url_prefix( url_in, &enclosed, &ldaps );
+       url_tmp = skip_url_prefix( url_in, &enclosed, &scheme );
 
        if ( url_tmp == NULL ) {
-               return LDAP_URL_ERR_NOTLDAP;
+               return LDAP_URL_ERR_BADSCHEME;
        }
 
+       assert( scheme );
+
        /* make working copy of the remainder of the URL */
-       if (( url = LDAP_STRDUP( url_tmp )) == NULL ) {
-               return( LDAP_URL_ERR_MEM );
+       url = LDAP_STRDUP( url_tmp );
+       if ( url == NULL ) {
+               return LDAP_URL_ERR_MEM;
        }
 
        if ( enclosed ) {
@@ -202,17 +271,18 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp )
                return LDAP_URL_ERR_MEM;
        }
 
+       ludp->lud_next = NULL;
        ludp->lud_host = NULL;
        ludp->lud_port = 0;
-    ludp->lud_dn = NULL;
-    ludp->lud_attrs = NULL;
-    ludp->lud_filter = NULL;
-       ludp->lud_ldaps = ldaps;
+       ludp->lud_dn = NULL;
+       ludp->lud_attrs = NULL;
+       ludp->lud_filter = NULL;
        ludp->lud_scope = LDAP_SCOPE_BASE;
+       ludp->lud_filter = NULL;
 
-       ludp->lud_filter = LDAP_STRDUP("(objectClass=*)");
+       ludp->lud_scheme = LDAP_STRDUP( scheme );
 
-       if( ludp->lud_filter == NULL ) {
+       if ( ludp->lud_scheme == NULL ) {
                LDAP_FREE( url );
                ldap_free_urldesc( ludp );
                return LDAP_URL_ERR_MEM;
@@ -226,7 +296,9 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp )
                *p++ = '\0';
        }
 
-       if (( q = strchr( url, ':' )) != NULL ) {
+       q = strchr( url, ':' );
+
+       if ( q != NULL ) {
                *q++ = '\0';
                ldap_pvt_hex_unescape( q );
 
@@ -248,6 +320,36 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp )
                return LDAP_URL_ERR_MEM;
        }
 
+       /*
+        * Kludge.  ldap://111.222.333.444:389??cn=abc,o=company
+        *
+        * On early Novell releases, search references/referrals were returned
+        * in this format, i.e., the dn was kind of in the scope position,
+        * but the required slash is missing. The whole thing is illegal syntax,
+        * 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++;            
+               /* ? 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( "" );
+                       }
+
+                       if( ludp->lud_dn == NULL ) {
+                               LDAP_FREE( url );
+                               ldap_free_urldesc( ludp );
+                               return LDAP_URL_ERR_MEM;
+                       }
+               }
+       }
+
        if( p == NULL ) {
                LDAP_FREE( url );
                *ludpp = ludp;
@@ -414,6 +516,268 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp )
        return LDAP_URL_SUCCESS;
 }
 
+LDAPURLDesc *
+ldap_url_dup ( LDAPURLDesc *ludp )
+{
+       LDAPURLDesc *dest;
+
+       if ( ludp == NULL ) {
+               return NULL;
+       }
+
+       dest = LDAP_MALLOC( sizeof(LDAPURLDesc) );
+       if (dest == NULL)
+               return NULL;
+       
+       *dest = *ludp;
+       dest->lud_scheme = NULL;
+       dest->lud_host = NULL;
+       dest->lud_dn = NULL;
+       dest->lud_filter = NULL;
+       dest->lud_attrs = NULL;
+       dest->lud_exts = NULL;
+       dest->lud_next = NULL;
+
+       if ( ludp->lud_scheme != NULL ) {
+               dest->lud_scheme = LDAP_STRDUP( ludp->lud_scheme );
+               if (dest->lud_scheme == NULL) {
+                       ldap_free_urldesc(dest);
+                       return NULL;
+               }
+       }
+
+       if ( ludp->lud_host != NULL ) {
+               dest->lud_host = LDAP_STRDUP( ludp->lud_host );
+               if (dest->lud_host == NULL) {
+                       ldap_free_urldesc(dest);
+                       return NULL;
+               }
+       }
+
+       if ( ludp->lud_dn != NULL ) {
+               dest->lud_dn = LDAP_STRDUP( ludp->lud_dn );
+               if (dest->lud_dn == NULL) {
+                       ldap_free_urldesc(dest);
+                       return NULL;
+               }
+       }
+
+       if ( ludp->lud_filter != NULL ) {
+               dest->lud_filter = LDAP_STRDUP( ludp->lud_filter );
+               if (dest->lud_filter == NULL) {
+                       ldap_free_urldesc(dest);
+                       return NULL;
+               }
+       }
+
+       if ( ludp->lud_attrs != NULL ) {
+               dest->lud_attrs = ldap_charray_dup( ludp->lud_attrs );
+               if (dest->lud_attrs == NULL) {
+                       ldap_free_urldesc(dest);
+                       return NULL;
+               }
+       }
+
+       if ( ludp->lud_exts != NULL ) {
+               dest->lud_exts = ldap_charray_dup( ludp->lud_exts );
+               if (dest->lud_exts == NULL) {
+                       ldap_free_urldesc(dest);
+                       return NULL;
+               }
+       }
+
+       return dest;
+}
+
+LDAPURLDesc *
+ldap_url_duplist (LDAPURLDesc *ludlist)
+{
+       LDAPURLDesc *dest, *tail, *ludp, *newludp;
+
+       dest = NULL;
+       tail = NULL;
+       for (ludp = ludlist; ludp != NULL; ludp = ludp->lud_next) {
+               newludp = ldap_url_dup(ludp);
+               if (newludp == NULL) {
+                       ldap_free_urllist(dest);
+                       return NULL;
+               }
+               if (tail == NULL)
+                       dest = newludp;
+               else
+                       tail->lud_next = newludp;
+               tail = newludp;
+       }
+       return dest;
+}
+
+int
+ldap_url_parselist (LDAPURLDesc **ludlist, const char *url )
+{
+       int i, rc;
+       LDAPURLDesc *ludp;
+       char **urls;
+
+       *ludlist = NULL;
+
+       if (url == NULL)
+               return LDAP_PARAM_ERROR;
+
+       urls = ldap_str2charray((char *)url, ", ");
+       if (urls == NULL)
+               return LDAP_NO_MEMORY;
+
+       /* count the URLs... */
+       for (i = 0; urls[i] != NULL; i++) ;
+       /* ...and put them in the "stack" backward */
+       while (--i >= 0) {
+               rc = ldap_url_parse( urls[i], &ludp );
+               if ( rc != 0 ) {
+                       ldap_charray_free(urls);
+                       ldap_free_urllist(*ludlist);
+                       *ludlist = NULL;
+                       return rc;
+               }
+               ludp->lud_next = *ludlist;
+               *ludlist = ludp;
+       }
+       ldap_charray_free(urls);
+       return LDAP_SUCCESS;
+}
+
+int
+ldap_url_parsehosts (LDAPURLDesc **ludlist, const char *hosts )
+{
+       int i;
+       LDAPURLDesc *ludp;
+       char **specs, *p;
+
+       *ludlist = NULL;
+
+       if (hosts == NULL)
+               return LDAP_PARAM_ERROR;
+
+       specs = ldap_str2charray((char *)hosts, ", ");
+       if (specs == NULL)
+               return LDAP_NO_MEMORY;
+
+       /* count the URLs... */
+       for (i = 0; specs[i] != NULL; i++) /* EMPTY */;
+
+       /* ...and put them in the "stack" backward */
+       while (--i >= 0) {
+               ludp = LDAP_CALLOC( 1, sizeof(LDAPURLDesc) );
+               if (ludp == NULL) {
+                       ldap_charray_free(specs);
+                       ldap_free_urllist(*ludlist);
+                       *ludlist = NULL;
+                       return LDAP_NO_MEMORY;
+               }
+               ludp->lud_host = specs[i];
+               specs[i] = NULL;
+               p = strchr(ludp->lud_host, ':');
+               if (p != NULL) {
+                       *p++ = 0;
+                       ldap_pvt_hex_unescape(p);
+                       ludp->lud_port = atoi(p);
+               }
+               ldap_pvt_hex_unescape(ludp->lud_host);
+               ludp->lud_scheme = LDAP_STRDUP("ldap");
+               ludp->lud_next = *ludlist;
+               *ludlist = ludp;
+       }
+
+       /* this should be an array of NULLs now */
+       ldap_charray_free(specs);
+       return LDAP_SUCCESS;
+}
+
+char *
+ldap_url_list2hosts (LDAPURLDesc *ludlist)
+{
+       LDAPURLDesc *ludp;
+       int size;
+       char *s, *p, buf[32];   /* big enough to hold a long decimal # (overkill) */
+
+       if (ludlist == NULL)
+               return NULL;
+
+       /* figure out how big the string is */
+       size = 1;       /* nul-term */
+       for (ludp = ludlist; ludp != NULL; ludp = ludp->lud_next) {
+               size += strlen(ludp->lud_host) + 1;             /* host and space */
+               if (ludp->lud_port != 0)
+                       size += sprintf(buf, ":%d", ludp->lud_port);
+       }
+       s = LDAP_MALLOC(size);
+       if (s == NULL)
+               return NULL;
+
+       p = s;
+       for (ludp = ludlist; ludp != NULL; ludp = ludp->lud_next) {
+               strcpy(p, ludp->lud_host);
+               p += strlen(ludp->lud_host);
+               if (ludp->lud_port != 0)
+                       p += sprintf(p, ":%d", ludp->lud_port);
+               *p++ = ' ';
+       }
+       if (p != s)
+               p--;    /* nuke that extra space */
+       *p = 0;
+       return s;
+}
+
+char *
+ldap_url_list2urls(
+       LDAPURLDesc *ludlist )
+{
+       LDAPURLDesc *ludp;
+       int size;
+       char *s, *p, buf[32];   /* big enough to hold a long decimal # (overkill) */
+
+       if (ludlist == NULL)
+               return NULL;
+
+       /* figure out how big the string is */
+       size = 1;       /* nul-term */
+       for (ludp = ludlist; ludp != NULL; ludp = ludp->lud_next) {
+               size += strlen(ludp->lud_scheme) + strlen(ludp->lud_host);
+               size += sizeof(":/// ");
+
+               if (ludp->lud_port != 0) {
+                       size += sprintf(buf, ":%d", ludp->lud_port);
+               }
+       }
+
+       s = LDAP_MALLOC(size);
+       if (s == NULL) {
+               return NULL;
+       }
+
+       p = s;
+       for (ludp = ludlist; ludp != NULL; ludp = ludp->lud_next) {
+               p += sprintf(p, "%s://%s", ludp->lud_scheme, ludp->lud_host);
+               if (ludp->lud_port != 0)
+                       p += sprintf(p, ":%d", ludp->lud_port);
+               *p++ = '/';
+               *p++ = ' ';
+       }
+       if (p != s)
+               p--;    /* nuke that extra space */
+       *p = 0;
+       return s;
+}
+
+void
+ldap_free_urllist( LDAPURLDesc *ludlist )
+{
+       LDAPURLDesc *ludp, *next;
+
+       for (ludp = ludlist; ludp != NULL; ludp = next) {
+               next = ludp->lud_next;
+               ldap_free_urldesc(ludp);
+       }
+}
 
 void
 ldap_free_urldesc( LDAPURLDesc *ludp )
@@ -422,6 +786,10 @@ ldap_free_urldesc( LDAPURLDesc *ludp )
                return;
        }
        
+       if ( ludp->lud_scheme != NULL ) {
+               LDAP_FREE( ludp->lud_scheme );
+       }
+
        if ( ludp->lud_host != NULL ) {
                LDAP_FREE( ludp->lud_host );
        }
@@ -453,7 +821,7 @@ ldap_url_search( LDAP *ld, LDAP_CONST char *url, int attrsonly )
        int             err;
        LDAPURLDesc     *ludp;
        BerElement      *ber;
-       LDAPServer      *srv = NULL;
+       LDAPreqinfo  bind;
 
        if ( ldap_url_parse( url, &ludp ) != 0 ) {
                ld->ld_errno = LDAP_PARAM_ERROR;
@@ -465,38 +833,19 @@ ldap_url_search( LDAP *ld, LDAP_CONST char *url, int attrsonly )
                -1, -1 );
 
        if ( ber == NULL ) {
-               return( -1 );
-       }
-
-       err = 0;
-
-       if ( ludp->lud_host != NULL || ludp->lud_port != 0 ) {
-               if (( srv = (LDAPServer *)LDAP_CALLOC( 1, sizeof( LDAPServer )))
-                   == NULL || ( srv->lsrv_host = LDAP_STRDUP( ludp->lud_host ==
-                   NULL ? ld->ld_defhost : ludp->lud_host )) == NULL ) {
-                       if ( srv != NULL ) {
-                               LDAP_FREE( srv );
-                       }
-                       ld->ld_errno = LDAP_NO_MEMORY;
-                       err = -1;
-               } else {
-                       if ( ludp->lud_port == 0 ) {
-                               srv->lsrv_port = ldap_int_global_options.ldo_defport;
-                       } else {
-                               srv->lsrv_port = ludp->lud_port;
-                       }
-               }
-       }
-
-       if ( err != 0 ) {
-               ber_free( ber, 1 );
+               err = -1;
        } else {
-               err = ldap_send_server_request( ld, ber, ld->ld_msgid, NULL, srv,
-                   NULL, 1 );
+               bind.ri_request = LDAP_REQ_SEARCH;
+               bind.ri_msgid = ld->ld_msgid;
+               bind.ri_url = (char *)url;
+               err = ldap_send_server_request(
+                                       ld, ber, ld->ld_msgid, NULL,
+                                       (ludp->lud_host != NULL || ludp->lud_port != 0)
+                                               ? ludp : NULL,
+                                       NULL, &bind );
        }
 
        ldap_free_urldesc( ludp );
-
        return( err );
 }
 
@@ -547,9 +896,9 @@ void
 ldap_pvt_hex_unescape( char *s )
 {
 /*
- * Remove URL hex escapes from s... done in place.  The basic concept for
- * this routine is borrowed from the WWW library HTUnEscape() routine.
- */
+* Remove URL hex escapes from s... done in place.  The basic concept for
+* this routine is borrowed from the WWW library HTUnEscape() routine.
+*/
        char    *p;
 
        for ( p = s; *s != '\0'; ++s ) {
diff --git a/libraries/libldap/utf-8.c b/libraries/libldap/utf-8.c
new file mode 100644 (file)
index 0000000..0d12f01
--- /dev/null
@@ -0,0 +1,461 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+/*
+ * Basic UTF-8 routines
+ *
+ * These routines are "dumb".  Though they understand UTF-8,
+ * they don't grok Unicode.  That is, they can push bits,
+ * but don't have a clue what the bits represent.  That's
+ * good enough for use with the LDAP Client SDK.
+ *
+ * These routines are not optimized.
+ */
+
+#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_defaults.h"
+
+#undef ISASCII
+#define ISASCII(uc)    ((uc) < 0x100)
+#undef UCS4_INVALID
+#define UCS4_INVALID   0x80000000U
+
+/*
+ * Basic UTF-8 routines
+ */
+
+/*
+ * return the number of bytes required to hold the
+ * NULL-terminated UTF-8 string NOT INCLUDING the
+ * termination.
+ */
+ber_len_t ldap_utf8_bytes( const char * p )
+{
+       ber_len_t bytes;
+
+       for( bytes=0; p[bytes]; bytes++ ) {
+               /* EMPTY */ ;
+       }
+
+       return bytes;
+}
+
+ber_len_t ldap_utf8_chars( const char * p )
+{
+       /* could be optimized and could check for invalid sequences */
+       ber_len_t chars=0;
+
+       for( ; *p ; LDAP_UTF8_INCR(p) ) {
+               chars++;
+       };
+
+       return chars;
+}
+
+/* return offset to next character */
+int ldap_utf8_offset( const char * p )
+{
+       return LDAP_UTF8_NEXT(p) - p;
+}
+
+/*
+ * Returns length indicated by first byte.
+ *
+ * This function should use a table lookup.
+ */
+int ldap_utf8_charlen( const char * p )
+{
+       unsigned c = * (const unsigned char *) p;
+
+       if ((c & 0xfe ) == 0xfc) {
+               return 6;
+       }
+
+       if ((c & 0xfc ) == 0xf8) {
+               return 5;
+       }
+
+       if ((c & 0xf8 ) == 0xf0) {
+               return 4;
+       }
+
+       if ((c & 0xf0 ) == 0xe0) {
+               return 3;
+       }
+
+       if ((c & 0xe0 ) == 0xc0) {
+               return 2;
+       }
+
+       if ((c & 0x80 ) == 0x80) {
+               /* INVALID */
+               return 0;
+       }
+
+       return 1;
+}
+
+/* conv UTF-8 to UCS-4, useful for comparisons */
+ldap_ucs4_t ldap_utf8_to_ucs4( const char * p )
+{
+    const unsigned char *c = p;
+    ldap_ucs4_t ch;
+       int len, i;
+       static unsigned char mask[] = {
+               0, 0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01 };
+
+       len = LDAP_UTF8_CHARLEN(p);
+
+       if( len == 0 ) return UCS4_INVALID;
+
+       ch = c[0] & mask[len];
+
+       for(i=1; i < len; i++) {
+               if ((c[i] & 0xc0) != 0x80) {
+                       return UCS4_INVALID;
+               }
+
+               ch <<= 6;
+               ch |= c[i] & 0x3f;
+       }
+
+       return ch;
+}
+
+/* conv UCS-4 to UTF-8, not used */
+int ldap_ucs4_to_utf8( ldap_ucs4_t c, char *buf )
+{
+       int len=0;
+       unsigned char* p = buf;
+       if(buf == NULL) return 0;
+
+       if ( c < 0 ) {
+               /* not a valid Unicode character */
+
+       } else if( c < 0x80 ) {
+               p[len++] = c;
+
+       } else if( c < 0x800 ) {
+               p[len++] = 0xc0 | ( c >> 6 );
+               p[len++] = 0x80 | ( c & 0x3f );
+
+       } else if( c < 0x10000 ) {
+               p[len++] = 0xe0 | ( c >> 12 );
+               p[len++] = 0x80 | ( (c >> 6) & 0x3f );
+               p[len++] = 0x80 | ( c & 0x3f );
+
+       } else if( c < 0x200000 ) {
+               p[len++] = 0xf0 | ( c >> 18 );
+               p[len++] = 0x80 | ( (c >> 12) & 0x3f );
+               p[len++] = 0x80 | ( (c >> 6) & 0x3f );
+               p[len++] = 0x80 | ( c & 0x3f );
+
+       } else if( c < 0x400000 ) {
+               p[len++] = 0xf8 | ( c >> 24 );
+               p[len++] = 0x80 | ( (c >> 18) & 0x3f );
+               p[len++] = 0x80 | ( (c >> 12) & 0x3f );
+               p[len++] = 0x80 | ( (c >> 6) & 0x3f );
+               p[len++] = 0x80 | ( c & 0x3f );
+
+       } else /* if( c < 0x80000000 ) */ {
+               p[len++] = 0xfc | ( c >> 30 );
+               p[len++] = 0x80 | ( (c >> 24) & 0x3f );
+               p[len++] = 0x80 | ( (c >> 18) & 0x3f );
+               p[len++] = 0x80 | ( (c >> 12) & 0x3f );
+               p[len++] = 0x80 | ( (c >> 6) & 0x3f );
+               p[len++] = 0x80 | ( c & 0x3f );
+       }
+
+       buf[len] = '\0';
+       return len;
+}
+
+/*
+ * Advance to the next UTF-8 character
+ *
+ * Ignores length of multibyte character, instead rely on
+ * continuation markers to find start of next character.
+ * This allows for "resyncing" of when invalid characters
+ * are provided provided the start of the next character
+ * is appears within the 6 bytes examined.
+ */
+char* ldap_utf8_next( const char * p )
+{
+       int i;
+       const unsigned char *u = p;
+
+       if( LDAP_UTF8_ISASCII(u) ) {
+               return (char *) &p[1];
+       }
+
+       for( i=1; i<6; i++ ) {
+               if ( ( u[i] & 0xc0 ) != 0x80 ) {
+                       return (char *) &p[i];
+               }
+       }
+
+       return (char *) &p[i];
+}
+
+/*
+ * Advance to the previous UTF-8 character
+ *
+ * Ignores length of multibyte character, instead rely on
+ * continuation markers to find start of next character.
+ * This allows for "resyncing" of when invalid characters
+ * are provided provided the start of the next character
+ * is appears within the 6 bytes examined.
+ */
+char* ldap_utf8_prev( const char * p )
+{
+       int i;
+       const unsigned char *u = p;
+
+       for( i=-1; i>-6 ; i-- ) {
+               if ( ( u[i] & 0xc0 ) != 0x80 ) {
+                       return (char *) &p[i];
+               }
+       }
+
+       return (char *) &p[i];
+}
+
+/*
+ * Copy one UTF-8 character from src to dst returning
+ * number of bytes copied.
+ *
+ * Ignores length of multibyte character, instead rely on
+ * continuation markers to find start of next character.
+ * This allows for "resyncing" of when invalid characters
+ * are provided provided the start of the next character
+ * is appears within the 6 bytes examined.
+ */
+int ldap_utf8_copy( char* dst, const char *src )
+{
+       int i;
+       const unsigned char *u = src;
+
+       dst[0] = src[0];
+
+       if( LDAP_UTF8_ISASCII(u) ) {
+               return 1;
+       }
+
+       for( i=1; i<6; i++ ) {
+               if ( ( u[i] & 0xc0 ) != 0x80 ) {
+                       return i; 
+               }
+               dst[i] = src[i];
+       }
+
+       return i;
+}
+
+/*
+ * UTF-8 ctype routines
+ * Only deals with characters < 0x100 (ie: US-ASCII)
+ */
+
+int ldap_utf8_isascii( const char * p )
+{
+       unsigned c = * (const unsigned char *) p;
+       return ISASCII(c);
+}
+
+int ldap_utf8_isdigit( const char * p )
+{
+       unsigned c = * (const unsigned char *) p;
+
+       if(!ISASCII(c)) return 0;
+
+       return c >= '0' && c <= '9';
+}
+
+int ldap_utf8_isxdigit( const char * p )
+{
+       unsigned c = * (const unsigned char *) p;
+
+       if(!ISASCII(c)) return 0;
+
+       return ( c >= '0' && c <= '9' )
+               || ( c >= 'A' && c <= 'F' )
+               || ( c >= 'a' && c <= 'f' );
+}
+
+int ldap_utf8_isspace( const char * p )
+{
+       unsigned c = * (const unsigned char *) p;
+
+       if(!ISASCII(c)) return 0;
+
+       switch(c) {
+       case ' ':
+       case '\t':
+       case '\n':
+       case '\r':
+       case '\v':
+       case '\f':
+               return 1;
+       }
+
+       return 0;
+}
+
+#ifndef UTF8_ALPHA_CTYPE
+/*
+ * These are not needed by the C SDK and are
+ * not "good enough" for general use.
+ */
+int ldap_utf8_isalpha( const char * p )
+{
+       unsigned c = * (const unsigned char *) p;
+
+       if(!ISASCII(c)) return 0;
+
+       return ( c >= 'A' && c <= 'Z' )
+               || ( c >= 'a' && c <= 'z' );
+}
+
+int ldap_utf8_isalnum( const char * p )
+{
+       unsigned c = * (const unsigned char *) p;
+
+       if(!ISASCII(c)) return 0;
+
+       return ( c >= '0' && c <= '9' )
+               || ( c >= 'A' && c <= 'Z' )
+               || ( c >= 'a' && c <= 'z' );
+}
+
+int ldap_utf8_islower( const char * p )
+{
+       unsigned c = * (const unsigned char *) p;
+
+       if(!ISASCII(c)) return 0;
+
+       return ( c >= 'a' && c <= 'z' );
+}
+
+int ldap_utf8_isupper( const char * p )
+{
+       unsigned c = * (const unsigned char *) p;
+
+       if(!ISASCII(c)) return 0;
+
+       return ( c >= 'A' && c <= 'Z' );
+}
+#endif
+
+
+/*
+ * UTF-8 string routines
+ */
+
+/* like strchr() */
+char * (ldap_utf8_strchr)( const char *str, const char *chr )
+{
+       for( ; *str != '\0'; LDAP_UTF8_INCR(str) ) {
+               if( ldap_utf8_to_ucs4( str ) == ldap_utf8_to_ucs4( chr ) ) {
+                       return (char *) str;
+               } 
+       }
+
+       return NULL;
+}
+
+/* like strcspn() but returns number of bytes, not characters */
+ber_len_t (ldap_utf8_strcspn)( const char *str, const char *set )
+{
+       const char *cstr;
+       const char *cset;
+
+       for( cstr = str; *cstr != '\0'; LDAP_UTF8_INCR(cstr) ) {
+               for( cset = set; *cset != '\0'; LDAP_UTF8_INCR(cset) ) {
+                       if( ldap_utf8_to_ucs4( cstr ) == ldap_utf8_to_ucs4( cset ) ) {
+                               return cstr - str;
+                       } 
+               }
+       }
+
+       return cstr - str;
+}
+
+/* like strspn() but returns number of bytes, not characters */
+ber_len_t (ldap_utf8_strspn)( const char *str, const char *set )
+{
+       const char *cstr;
+       const char *cset;
+
+       for( cstr = str; *cstr != '\0'; LDAP_UTF8_INCR(cstr) ) {
+
+               for( cset = set; ; LDAP_UTF8_INCR(cset) ) {
+                       if( *cset == '\0' ) {
+                               return cstr - str;
+                       }
+
+                       if( ldap_utf8_to_ucs4( cstr ) == ldap_utf8_to_ucs4( cset ) ) {
+                               break;
+                       } 
+               }
+       }
+
+       return cstr - str;
+}
+
+/* like strpbrk(), replaces strchr() as well */
+char *(ldap_utf8_strpbrk)( const char *str, const char *set )
+{
+       for( ; *str != '\0'; LDAP_UTF8_INCR(str) ) {
+               const char *cset;
+
+               for( cset = set; *cset != '\0'; LDAP_UTF8_INCR(cset) ) {
+                       if( ldap_utf8_to_ucs4( str ) == ldap_utf8_to_ucs4( cset ) ) {
+                               return (char *) str;
+                       } 
+               }
+       }
+
+       return NULL;
+}
+
+/* like strtok_r(), not strtok() */
+char *(ldap_utf8_strtok)(char *str, const char *sep, char **last)
+{
+       char *begin;
+       char *end;
+
+       if( last == NULL ) return NULL;
+
+       begin = str ? str : *last;
+
+       begin += ldap_utf8_strspn( begin, sep );
+
+       if( *begin == '\0' ) {
+               *last = NULL;
+               return NULL;
+       }
+
+       end = &begin[ ldap_utf8_strcspn( begin, sep ) ];
+
+       if( *end != '\0' ) {
+               char *next = LDAP_UTF8_NEXT( end );
+               *end = '\0';
+               end = next;
+       }
+
+       *last = end;
+       return begin;
+}
index a3128e6e17b14c284e5f0c5de311ff788afa1495..b0484034a5f6bfc26d6c351e08facf0ea03ad97b 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
 # ifndef USE_CTIME_R
        static ldap_pvt_thread_mutex_t ldap_int_ctime_mutex;
 # endif
-# ifndef HAVE_GETHOSTBYNAME_R
-       static ldap_pvt_thread_mutex_t ldap_int_gethostbyname_mutex;
+# if !defined( HAVE_GETHOSTBYNAME_R ) || !defined( HAVE_GETHOSTBYADDR_R )
+       static ldap_pvt_thread_mutex_t ldap_int_gethostby_mutex;
 # endif
-# ifndef HAVE_GETHOSTBYADDR_R
-       static ldap_pvt_thread_mutex_t ldap_int_gethostbyaddr_mutex;
+# ifdef HAVE_RES_QUERY
+       ldap_pvt_thread_mutex_t ldap_int_resolv_mutex;
 # endif
 #endif /* LDAP_R_COMPILE */
 
@@ -143,7 +143,7 @@ int ldap_pvt_gethostbyname_a(
        struct hostent *he;
        int     retval;
        
-       ldap_pvt_thread_mutex_lock( &ldap_int_gethostbyname_mutex );
+       ldap_pvt_thread_mutex_lock( &ldap_int_gethostby_mutex );
        
        he = gethostbyname( name );
        
@@ -158,7 +158,7 @@ int ldap_pvt_gethostbyname_a(
                retval = 0;
        }
        
-       ldap_pvt_thread_mutex_unlock( &ldap_int_gethostbyname_mutex );
+       ldap_pvt_thread_mutex_unlock( &ldap_int_gethostby_mutex );
        
        return retval;
 #else  
@@ -222,7 +222,7 @@ int ldap_pvt_gethostbyaddr_a(
        struct hostent *he;
        int     retval;
        
-       ldap_pvt_thread_mutex_lock( &ldap_int_gethostbyaddr_mutex );
+       ldap_pvt_thread_mutex_lock( &ldap_int_gethostby_mutex );
        
        he = gethostbyaddr( addr, len, type );
        
@@ -237,7 +237,7 @@ int ldap_pvt_gethostbyaddr_a(
                retval = 0;
        }
        
-       ldap_pvt_thread_mutex_unlock( &ldap_int_gethostbyaddr_mutex );
+       ldap_pvt_thread_mutex_unlock( &ldap_int_gethostby_mutex );
        
        return retval;   
 #else /* gethostbyaddr() */
@@ -266,12 +266,12 @@ void ldap_int_utils_init( void )
        ldap_pvt_thread_mutex_init( &ldap_int_ctime_mutex );
 #endif
 
-#if !defined( HAVE_GETHOSTBYNAME_R )
-       ldap_pvt_thread_mutex_init( &ldap_int_gethostbyname_mutex );
+#if !defined( HAVE_GETHOSTBYNAME_R ) || !defined( HAVE_GETHOSTBYADDR_R )
+       ldap_pvt_thread_mutex_init( &ldap_int_gethostby_mutex );
 #endif
 
-#if !defined( HAVE_GETHOSTBYADDR_R )
-       ldap_pvt_thread_mutex_init( &ldap_int_gethostbyaddr_mutex );
+#ifdef HAVE_RES_QUERY
+       ldap_pvt_thread_mutex_init( &ldap_int_resolv_mutex );
 #endif
 
        /* call other module init functions here... */
@@ -314,24 +314,28 @@ static int copy_hostent( struct hostent *res, char **buf, struct hostent * src )
        char    **tp;
        char    *tbuf;
        int     name_len;
-       int     n_alias;
-       int     total_alias_len;
-       int     n_addr;
+       int     n_alias=0;
+       int     total_alias_len=0;
+       int     n_addr=0;
        int     total_addr_len;
        int     total_len;
          
        /* calculate the size needed for the buffer */
        name_len = strlen( src->h_name ) + 1;
        
-       for( n_alias=total_alias_len=0, p=src->h_aliases; (*p) ; p++ ) {
-               total_alias_len += strlen( *p ) + 1;
-               n_alias++; 
+       if( src->h_aliases != NULL ) {
+               for( p = src->h_aliases; (*p) != NULL; p++ ) {
+                       total_alias_len += strlen( *p ) + 1;
+                       n_alias++; 
+               }
        }
 
-       for( n_addr=0, p=src->h_addr_list; (*p) ; p++ ) {
-               n_addr++;
+       if( src->h_addr_list != NULL ) {
+               for( p = src->h_addr_list; (*p) != NULL; p++ ) {
+                       n_addr++;
+               }
+               total_addr_len = n_addr * src->h_length;
        }
-       total_addr_len = n_addr * src->h_length;
        
        total_len = (n_alias + n_addr + 2) * sizeof( char * ) +
                total_addr_len + total_alias_len + name_len;
@@ -345,11 +349,15 @@ static int copy_hostent( struct hostent *res, char **buf, struct hostent * src )
                res->h_name = tbuf; tbuf+=name_len;
                /* now the aliases */
                res->h_aliases = tp;
-               tbuf = cpy_aliases( &tp, tbuf, src->h_aliases );
+               if ( src->h_aliases != NULL ) {
+                       tbuf = cpy_aliases( &tp, tbuf, src->h_aliases );
+               }
                *tp++=NULL;
                /* finally the addresses */
                res->h_addr_list = tp;
-               tbuf = cpy_addresses( &tp, tbuf, src->h_addr_list, src->h_length );
+               if ( src->h_addr_list != NULL ) {
+                       tbuf = cpy_addresses( &tp, tbuf, src->h_addr_list, src->h_length );
+               }
                *tp++=NULL;
                return 0;
        }
diff --git a/libraries/libldap/vlvctrl.c b/libraries/libldap/vlvctrl.c
new file mode 100644 (file)
index 0000000..04b5526
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/* Adapted for inclusion into OpenLDAP by Kurt D. Zeilenga */
+/*---
+ * Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
+ *
+ * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
+ * TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT
+ * TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS
+ * AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE"
+ * IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION
+ * OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP
+ * PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT
+ * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
+ *---*/
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/stdlib.h>
+#include <ac/string.h>
+#include <ac/time.h>
+#include <ac/ctype.h>
+
+#include "ldap-int.h"
+
+#define LDAP_VLVBYINDEX_IDENTIFIER     0xa0L
+#define LDAP_VLVBYVALUE_IDENTIFIER     0x81L
+#define LDAP_VLVCONTEXT_IDENTIFIER     0x04L
+
+
+/*---
+   ldap_create_vlv_control
+   
+   Create and encode the Virtual List View control.
+
+   ld        (IN)  An LDAP session handle, as obtained from a call to
+                                  ldap_init().
+   
+   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.
+
+ ---*/
+
+LIBLDAP_F( int )
+ldap_create_vlv_control( LDAP *ld,
+                                                LDAPVLVInfo *vlvinfop,
+                                                LDAPControl **ctrlp )
+{
+       ber_tag_t tag;
+       BerElement *ber;
+
+       if ( (ld==NULL) || (vlvinfop==NULL) || (ctrlp == NULL) ) {
+               ld->ld_errno =  LDAP_PARAM_ERROR;
+               return(ld->ld_errno);
+       }
+
+       if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
+               ld->ld_errno = LDAP_NO_MEMORY;
+               return(LDAP_NO_MEMORY);
+       }
+
+       tag = ber_printf(ber, "{ii" /*}*/,
+               vlvinfop->ldvlv_before_count,
+               vlvinfop->ldvlv_after_count);
+       if( tag == LBER_ERROR ) goto exit;
+
+       if (vlvinfop->ldvlv_attrvalue == NULL) {
+               tag = ber_printf(ber, "t{ii}",
+                       LDAP_VLVBYINDEX_IDENTIFIER,
+                       vlvinfop->ldvlv_offset,
+                       vlvinfop->ldvlv_count);
+               if( tag == LBER_ERROR ) goto exit;
+
+       } else {
+               tag = ber_printf(ber, "tO",
+                       LDAP_VLVBYVALUE_IDENTIFIER,
+                       vlvinfop->ldvlv_attrvalue);
+               if( tag == LBER_ERROR ) goto exit;
+       }
+
+       if (vlvinfop->ldvlv_context) {
+               tag = ber_printf(ber, "tO",
+                       LDAP_VLVCONTEXT_IDENTIFIER,
+                       vlvinfop->ldvlv_context);
+               if( tag == LBER_ERROR ) goto exit;
+       }
+
+       tag = ber_printf(ber, /*{*/ "}"); 
+       if( tag == LBER_ERROR ) goto exit;
+
+       ld->ld_errno = ldap_int_create_control(
+               LDAP_CONTROL_VLVREQUEST, ber, 1, ctrlp);
+
+       ber_free(ber, 1);
+       return(ld->ld_errno);
+
+exit:
+       ber_free(ber, 1);
+       ld->ld_errno = LDAP_ENCODING_ERROR;
+       return(ld->ld_errno);
+}
+
+
+/*---
+   ldap_parse_vlv_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().
+   
+   target_posp (OUT)  This result parameter is filled in with the list
+                                          index of the target entry.  If this parameter is
+                                          NULL, the target position is not returned.
+   
+   list_countp  (OUT)  This result parameter is filled in with the server's
+                                          estimate of the size of the list.  If this parameter
+                                          is NULL, the size is not returned.
+   
+   contextp     (OUT)  This result parameter is filled in with the address
+                                          of a struct berval that contains the server-
+                                          generated context identifier if one was returned by
+                                          the server.  If the server did not return a context
+                                          identifier, this parameter will be set to NULL, even
+                                          if an error occured.
+                                          The returned context SHOULD be used in the next call
+                                          to create a VLV sort control.  The struct berval
+                                          returned SHOULD be disposed of by calling ber_bvfree()
+                                          when it is no longer needed.  If NULL is passed for
+                                          contextp, the context identifier is not returned.
+   
+   errcodep     (OUT)  This result parameter is filled in with the VLV
+                                          result code.  If this parameter is NULL, the result
+                                          code is not returned.  
+   
+   
+   Ber encoding
+   
+   VirtualListViewResponse ::= SEQUENCE {
+               targetPosition    INTEGER (0 .. maxInt),
+               contentCount     INTEGER (0 .. maxInt),
+               virtualListViewResult ENUMERATED {
+               success (0),
+               operatonsError (1),
+               unwillingToPerform (53),
+               insufficientAccessRights (50),
+               busy (51),
+               timeLimitExceeded (3),
+               adminLimitExceeded (11),
+               sortControlMissing (60),
+               offsetRangeError (61),
+               other (80) },
+               contextID     OCTET STRING OPTIONAL }
+   
+---*/
+
+LIBLDAP_F( int )
+ldap_parse_vlv_control(
+       LDAP           *ld,
+       LDAPControl    **ctrls,
+       unsigned long  *target_posp,
+       unsigned long  *list_countp,
+       struct berval  **contextp,
+       int            *errcodep )
+{
+       BerElement  *ber;
+       LDAPControl *pControl;
+       int i;
+       unsigned long pos, count, err;
+       ber_tag_t tag, berTag;
+       ber_len_t berLen;
+
+       if (contextp) {
+               *contextp = NULL;        /* Make sure we return a NULL if error occurs. */
+       }
+
+       if (ld == 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);
+       }
+
+       /* 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;
+       }
+
+       /* 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);
+
+       if (ber == NULL) {
+               ld->ld_errno = LDAP_NO_MEMORY;
+               return(ld->ld_errno);
+       }
+
+       /* Extract the data returned in the control. */
+       tag = ber_scanf(ber, "{iie" /*}*/, &pos, &count, &err);
+
+       if( tag == LBER_ERROR) {
+               ber_free(ber, 1);
+               ld->ld_errno = LDAP_DECODING_ERROR;
+               return(ld->ld_errno);
+       }
+
+
+       /* Since the context is the last item encoded, if caller doesn't want
+          it returned, don't decode it. */
+       if (contextp) {
+               if (LDAP_VLVCONTEXT_IDENTIFIER == ber_peek_tag(ber, &berLen)) {
+                       tag = ber_scanf(ber, "tO", &berTag, contextp);
+
+                       if( tag == LBER_ERROR) {
+                               ber_free(ber, 1);
+                               ld->ld_errno = LDAP_DECODING_ERROR;
+                               return(ld->ld_errno);
+                       }
+               }
+       }
+
+       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;
+       }
+
+       ld->ld_errno = LDAP_SUCCESS;
+       return(ld->ld_errno);
+}
index fba054ecb0ee7536afd0441c958ff3a3e9acbef3..a95fec2275269ed26a2d00bbc0f448a503104fe5 100644 (file)
@@ -1,4 +1,6 @@
 # $OpenLDAP$
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 ##
 ## Makefile.in for LDAP -lldap
 ##
@@ -14,31 +16,53 @@ XXSRCS      = apitest.c test.c tmpltest.c extended.c \
        getfilter.c sasl.c sbind.c kbind.c unbind.c friendly.c cldap.c \
        free.c disptmpl.c srchpref.c dsparse.c tmplout.c sort.c \
        getdn.c getentry.c getattr.c getvalues.c addentry.c \
-       request.c getdxbyname.c os-ip.c url.c charset.c \
+       request.c os-ip.c url.c sortctrl.c vlvctrl.c \
        init.c options.c print.c string.c util-int.c schema.c \
-       charray.c digest.c tls.c dn.c
-SRCS   = thr_posix.c thr_cthreads.c thr_thr.c thr_lwp.c thr_nt.c \
-       thr_pth.c thr_sleep.c thr_stub.c rdwr.c
-OBJS   = extended.lo \
+       charray.c tls.c dn.c os-local.c dnssrv.c \
+       utf-8.c
+SRCS   = threads.c rdwr.c tpool.c \
+       thr_posix.c thr_cthreads.c thr_thr.c thr_lwp.c thr_nt.c \
+       thr_pth.c thr_stub.c
+OBJS   = threads.lo rdwr.lo tpool.lo  \
+       thr_posix.lo thr_cthreads.lo thr_thr.lo thr_lwp.lo thr_nt.lo \
+       thr_pth.lo thr_stub.lo \
+       extended.lo \
        bind.lo controls.lo open.lo result.lo error.lo compare.lo search.lo \
        modify.lo add.lo modrdn.lo delete.lo abandon.lo ufn.lo cache.lo \
        getfilter.lo sasl.lo sbind.lo kbind.lo unbind.lo friendly.lo cldap.lo \
        free.lo disptmpl.lo srchpref.lo dsparse.lo tmplout.lo sort.lo \
        getdn.lo getentry.lo getattr.lo getvalues.lo addentry.lo \
-       request.lo getdxbyname.lo os-ip.lo url.lo charset.lo \
+       request.lo os-ip.lo url.lo sortctrl.lo vlvctrl.lo \
        init.lo options.lo print.lo string.lo util-int.lo schema.lo \
-       thr_posix.lo thr_cthreads.lo thr_thr.lo thr_lwp.lo thr_nt.lo \
-       thr_pth.lo thr_sleep.lo thr_stub.lo rdwr.lo \
-       charray.lo digest.lo tls.lo dn.lo
+       charray.lo tls.lo dn.lo os-local.lo dnssrv.lo \
+       utf-8.lo
 
 LDAP_INCDIR= ../../include       
 LDAP_LIBDIR= ../../libraries
 
 XDEFS = -DLDAP_R_COMPILE -I$(XXDIR)
-XLIBS = -lldap_r -llber
+XLIBS = -lldap_r -llber -llutil
 XXLIBS = $(SECURITY_LIBS) $(LUTIL_LIBS)
 XXXLIBS = $(LTHREAD_LIBS)
 
+LINKAGE = @LT_LIB_LINKAGE@
+
+NT_DYN_LIB_LIBS  = -llber -llutil $(AC_LIBS)
+NT_DYN_LIB_DEFS  = -DLIBLBER_DECL=dllimport
+NT_DYN_TEST_DEFS = -DLIBLBER_DECL=dllimport -DLIBLDAP_DECL=dllimport
+
+NT_XXLIBS = $(SECURITY_LIBS)
+
+UNIX_DYN_LIB_LIBS  = -llber $(AC_LIBS)
+UNIX_XXLIBS = $(SECURITY_LIBS)
+
+# Extras for building the library
+EXTRA_DEFS = $(@PLAT@_@LIB_LINKAGE@_LIB_DEFS)
+EXTRA_LIBS = $(@PLAT@_@LIB_LINKAGE@_LIB_LIBS) $(@PLAT@_XXLIBS)
+
+# Only the test programs will pick up these defs.
+CPPFLAGS = $(@PLAT@_@LIB_LINKAGE@_TEST_DEFS)
+
 .links :
        @for i in $(XXSRCS); do \
                $(RM) $$i ; \
@@ -61,5 +85,5 @@ ttest:        $(LIBRARY) tmpltest.o $(LDAP_LIBLBER_DEPEND)
        $(LTLINK) $(LDFLAGS) -o $@ tmpltest.o $(LIBS)
 
 install-local: $(CFFILES) FORCE
-       -$(MKDIR) $(libdir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 644 $(LIBRARY) $(libdir)
+       -$(MKDIR) $(DESTDIR)$(libdir)
+       $(LTINSTALL) $(INSTALLFLAGS) -m 644 $(LIBRARY) $(DESTDIR)$(libdir)
diff --git a/libraries/libldap_r/apitest_r.dsp b/libraries/libldap_r/apitest_r.dsp
new file mode 100644 (file)
index 0000000..3dbf186
--- /dev/null
@@ -0,0 +1,146 @@
+# Microsoft Developer Studio Project File - Name="apitest_r" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=apitest_r - Win32 Single Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "apitest_r.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "apitest_r.mak" CFG="apitest_r - Win32 Single Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "apitest_r - Win32 Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "apitest_r - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "apitest_r - Win32 Single Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "apitest_r - Win32 Single Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "apitest_r - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\apitest_r"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 sasl.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\Release"
+
+!ELSEIF  "$(CFG)" == "apitest_r - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "apitest_r_"
+# PROP BASE Intermediate_Dir "apitest_r_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\apitest_r"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Debug"
+
+!ELSEIF  "$(CFG)" == "apitest_r - Win32 Single Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "apitest_r_"
+# PROP BASE Intermediate_Dir "apitest_r_"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\apitest_r"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 oldap_r.lib olber32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\Debug"
+# ADD LINK32 libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\SDebug"
+
+!ELSEIF  "$(CFG)" == "apitest_r - Win32 Single Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "apitest_r0"
+# PROP BASE Intermediate_Dir "apitest_r0"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\apitest_r"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 oldap_r.lib olber32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\Release"
+# ADD LINK32 sasl.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\SRelease"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "apitest_r - Win32 Release"
+# Name "apitest_r - Win32 Debug"
+# Name "apitest_r - Win32 Single Debug"
+# Name "apitest_r - Win32 Single Release"
+# Begin Source File
+
+SOURCE=..\libldap\apitest.c
+# End Source File
+# End Target
+# End Project
diff --git a/libraries/libldap_r/libldap_r.dsp b/libraries/libldap_r/libldap_r.dsp
new file mode 100644 (file)
index 0000000..86e5329
--- /dev/null
@@ -0,0 +1,374 @@
+# Microsoft Developer Studio Project File - Name="libldap_r" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=libldap_r - Win32 Single Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "libldap_r.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "libldap_r.mak" CFG="libldap_r - Win32 Single Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "libldap_r - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "libldap_r - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE "libldap_r - Win32 Single Debug" (based on\
+ "Win32 (x86) Static Library")
+!MESSAGE "libldap_r - Win32 Single Release" (based on\
+ "Win32 (x86) Static Library")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+
+!IF  "$(CFG)" == "libldap_r - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\libldap_r"
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "LDAP_R_COMPILE" /D "WIN32" /D "_WINDOWS" /D _WIN32_WINNT=0x0400 /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\..\Release\oldap_r.lib"
+
+!ELSEIF  "$(CFG)" == "libldap_r - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\libldap_r"
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "_DEBUG" /D "LDAP_R_COMPILE" /D "WIN32" /D "_WINDOWS" /D _WIN32_WINNT=0x0400 /FR /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\..\Debug\oldap_r.lib"
+
+!ELSEIF  "$(CFG)" == "libldap_r - Win32 Single Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "libldap_"
+# PROP BASE Intermediate_Dir "libldap_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\libldap_r"
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "_DEBUG" /D "LDAP_R_COMPILE" /D "WIN32" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /Z7 /Od /I "..\..\include" /D "_DEBUG" /D "LDAP_R_COMPILE" /D "WIN32" /D "_WINDOWS" /FR /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo /out:"..\Debug\oldap_r.lib"
+# ADD LIB32 /nologo /out:"..\..\SDebug\oldap_r.lib"
+
+!ELSEIF  "$(CFG)" == "libldap_r - Win32 Single Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "libldap0"
+# PROP BASE Intermediate_Dir "libldap0"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\libldap_r"
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "LDAP_R_COMPILE" /D "WIN32" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "LDAP_R_COMPILE" /D "WIN32" /D "_WINDOWS" /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo /out:"..\Release\oldap_r.lib"
+# ADD LIB32 /nologo /out:"..\..\SRelease\oldap_r.lib"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "libldap_r - Win32 Release"
+# Name "libldap_r - Win32 Debug"
+# Name "libldap_r - Win32 Single Debug"
+# Name "libldap_r - Win32 Single Release"
+# Begin Source File
+
+SOURCE=..\libldap\abandon.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\add.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\addentry.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\bind.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\cache.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\charray.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\cldap.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\compare.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\controls.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\delete.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\disptmpl.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\disptmpl.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\dnssrv.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\dsparse.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\error.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\extended.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\free.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\friendly.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\getattr.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\getdn.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\getentry.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\getfilter.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\getvalues.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\init.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\kbind.c
+# End Source File
+# Begin Source File
+
+SOURCE="..\libldap\ldap-int.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ldap.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ldap_cdefs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ldap_features.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ldap_log.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ldap_pvt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ldap_pvt_thread.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\modify.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\modrdn.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\open.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\options.c
+# End Source File
+# Begin Source File
+
+SOURCE="..\libldap\os-ip.c"
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\print.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\rdwr.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\request.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\result.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\sasl.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\sbind.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\schema.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\search.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\sort.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\sortctrl.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\srchpref.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\srchpref.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\string.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\thr_nt.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\thr_sleep.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\thr_stub.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\threads.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\tls.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\ufn.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\unbind.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\url.c
+# End Source File
+# Begin Source File
+
+SOURCE="..\libldap\utf-8.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\libldap\util-int.c"
+# End Source File
+# Begin Source File
+
+SOURCE=..\libldap\vlvctrl.c
+# End Source File
+# End Target
+# End Project
diff --git a/libraries/libldap_r/ltest_r.dsp b/libraries/libldap_r/ltest_r.dsp
new file mode 100644 (file)
index 0000000..6e5711b
--- /dev/null
@@ -0,0 +1,143 @@
+# Microsoft Developer Studio Project File - Name="ltest_r" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=ltest_r - Win32 Single Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "ltest_r.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "ltest_r.mak" CFG="ltest_r - Win32 Single Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "ltest_r - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "ltest_r - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "ltest_r - Win32 Single Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ltest_r - Win32 Single Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "ltest_r - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\ltest_r"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 oldap32.lib olber32.lib olutil32.lib libsasl.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\Release"
+
+!ELSEIF  "$(CFG)" == "ltest_r - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "ltest_r___"
+# PROP BASE Intermediate_Dir "ltest_r___"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\ltest_r"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 oldap32.lib olber32.lib olutil32.lib libsasl.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Debug"
+
+!ELSEIF  "$(CFG)" == "ltest_r - Win32 Single Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "ltest_r_"
+# PROP BASE Intermediate_Dir "ltest_r_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\ltest_r"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 oldap32.lib olber32.lib olutil32.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\Debug"
+# ADD LINK32 oldap32.lib olber32.lib olutil32.lib libsasl.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\SDebug"
+
+!ELSEIF  "$(CFG)" == "ltest_r - Win32 Single Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ltest_r0"
+# PROP BASE Intermediate_Dir "ltest_r0"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\ltest_r"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 oldap32.lib olber32.lib olutil32.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\Release"
+# ADD LINK32 oldap32.lib olber32.lib olutil32.lib libsasl.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\SRelease"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "ltest_r - Win32 Release"
+# Name "ltest_r - Win32 Debug"
+# Name "ltest_r - Win32 Single Debug"
+# Name "ltest_r - Win32 Single Release"
+# Begin Source File
+
+SOURCE=..\libldap\test.c
+# End Source File
+# End Target
+# End Project
index ab31f426aee40fd67b7a792fa787ddfbfe71190f..6a43f66a187c8be0940092db612632227c1c1711 100644 (file)
@@ -7,13 +7,10 @@
 **
 ** Does not support cancellation nor does any status checking.
 */
-
-/********************************************************
- * Adapted from:
+/* Adapted from publically available examples for:
  *     "Programming with Posix Threads"
- *             by David R Butenhof
- *             Addison-Wesley 
- ********************************************************
+ *             by David R Butenhof, Addison-Wesley 
+ *             http://cseng.aw.com/bookpage.taf?ISBN=0-201-63392-2
  */
 
 #include "portable.h"
 
 #include <ac/errno.h>
 #include <ac/string.h>
+#include <ac/time.h>
 
+#include "ldap-int.h"
 #include "ldap_pvt_thread.h"
 
+/*
+ * implementations that provide their own compatible 
+ * reader/writer locks define LDAP_THREAD_HAVE_RDWR
+ * in ldap_pvt_thread.h
+ */
+#ifndef LDAP_THREAD_HAVE_RDWR
+
+struct ldap_int_thread_rdwr_s {
+       ldap_pvt_thread_mutex_t ltrw_mutex;
+       ldap_pvt_thread_cond_t ltrw_read;       /* wait for read */
+       ldap_pvt_thread_cond_t ltrw_write;      /* wait for write */
+       int ltrw_valid;
+#define LDAP_PVT_THREAD_RDWR_VALID 0x0bad
+       int ltrw_r_active;
+       int ltrw_w_active;
+       int ltrw_r_wait;
+       int ltrw_w_wait;
+};
+
 int 
-ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw )
+ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rwlock )
 {
-       assert( rw != NULL );
+       struct ldap_int_thread_rdwr_s *rw;
+
+       assert( rwlock != NULL );
 
-       memset( rw, 0, sizeof(ldap_pvt_thread_rdwr_t) );
+       rw = (struct ldap_int_thread_rdwr_s *) LDAP_CALLOC( 1,
+               sizeof( struct ldap_int_thread_rdwr_s ) );
 
        /* we should check return results */
        ldap_pvt_thread_mutex_init( &rw->ltrw_mutex );
@@ -38,12 +59,19 @@ ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw )
        ldap_pvt_thread_cond_init( &rw->ltrw_write );
 
        rw->ltrw_valid = LDAP_PVT_THREAD_RDWR_VALID;
+
+       *rwlock = rw;
        return 0;
 }
 
 int 
-ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rw )
+ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rwlock )
 {
+       struct ldap_int_thread_rdwr_s *rw;
+
+       assert( rwlock != NULL );
+       rw = *rwlock;
+
        assert( rw != NULL );
        assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
 
@@ -53,7 +81,7 @@ ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rw )
        ldap_pvt_thread_mutex_lock( &rw->ltrw_mutex );
 
        /* active threads? */
-       if( rw->ltrw_r_active > 0 || rw->ltrw_w_active > 1) {
+       if( rw->ltrw_r_active > 0 || rw->ltrw_w_active > 0) {
                ldap_pvt_thread_mutex_unlock( &rw->ltrw_mutex );
                return LDAP_PVT_THREAD_EBUSY;
        }
@@ -72,11 +100,18 @@ ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rw )
        ldap_pvt_thread_cond_destroy( &rw->ltrw_read );
        ldap_pvt_thread_cond_destroy( &rw->ltrw_write );
 
+       LDAP_FREE(rw);
+       *rwlock = NULL;
        return 0;
 }
 
-int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rw )
+int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rwlock )
 {
+       struct ldap_int_thread_rdwr_s *rw;
+
+       assert( rwlock != NULL );
+       rw = *rwlock;
+
        assert( rw != NULL );
        assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
 
@@ -85,7 +120,7 @@ int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rw )
 
        ldap_pvt_thread_mutex_lock( &rw->ltrw_mutex );
 
-       if( rw->ltrw_w_active > 1 ) {
+       if( rw->ltrw_w_active > 0 ) {
                /* writer is active */
 
                rw->ltrw_r_wait++;
@@ -93,7 +128,7 @@ int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rw )
                do {
                        ldap_pvt_thread_cond_wait(
                                &rw->ltrw_read, &rw->ltrw_mutex );
-               } while( rw->ltrw_w_active > 1 );
+               } while( rw->ltrw_w_active > 0 );
 
                rw->ltrw_r_wait--;
        }
@@ -105,8 +140,13 @@ int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rw )
        return 0;
 }
 
-int ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rw )
+int ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rwlock )
 {
+       struct ldap_int_thread_rdwr_s *rw;
+
+       assert( rwlock != NULL );
+       rw = *rwlock;
+
        assert( rw != NULL );
        assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
 
@@ -115,7 +155,7 @@ int ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rw )
 
        ldap_pvt_thread_mutex_lock( &rw->ltrw_mutex );
 
-       if( rw->ltrw_w_active > 1) {
+       if( rw->ltrw_w_active > 0) {
                ldap_pvt_thread_mutex_unlock( &rw->ltrw_mutex );
                return LDAP_PVT_THREAD_EBUSY;
        }
@@ -127,8 +167,13 @@ int ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rw )
        return 0;
 }
 
-int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rw )
+int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rwlock )
 {
+       struct ldap_int_thread_rdwr_s *rw;
+
+       assert( rwlock != NULL );
+       rw = *rwlock;
+
        assert( rw != NULL );
        assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
 
@@ -148,8 +193,13 @@ int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rw )
        return 0;
 }
 
-int ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rw )
+int ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rwlock )
 {
+       struct ldap_int_thread_rdwr_s *rw;
+
+       assert( rwlock != NULL );
+       rw = *rwlock;
+
        assert( rw != NULL );
        assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
 
@@ -176,8 +226,13 @@ int ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rw )
        return 0;
 }
 
-int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rw )
+int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rwlock )
 {
+       struct ldap_int_thread_rdwr_s *rw;
+
+       assert( rwlock != NULL );
+       rw = *rwlock;
+
        assert( rw != NULL );
        assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
 
@@ -198,8 +253,13 @@ int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rw )
        return 0;
 }
 
-int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rw )
+int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rwlock )
 {
+       struct ldap_int_thread_rdwr_s *rw;
+
+       assert( rwlock != NULL );
+       rw = *rwlock;
+
        assert( rw != NULL );
        assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
 
@@ -222,7 +282,7 @@ int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rw )
        return 0;
 }
 
-#ifdef LDAP_DEBUG
+#ifdef LDAP_RDWR_DEBUG
 
 /* just for testing, 
  * return 0 if false, suitable for assert(ldap_pvt_thread_rdwr_Xchk(rdwr))
@@ -234,24 +294,39 @@ int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rw )
  * a lock are caught.
  */
 
-int ldap_pvt_thread_rdwr_readers(ldap_pvt_thread_rdwr_t *rw)
+int ldap_pvt_thread_rdwr_readers(ldap_pvt_thread_rdwr_t *rwlock)
 {
+       struct ldap_int_thread_rdwr_s *rw;
+
+       assert( rwlock != NULL );
+       rw = *rwlock;
+
        assert( rw != NULL );
        assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
 
        return( rw->ltrw_r_active );
 }
 
-int ldap_pvt_thread_rdwr_writers(ldap_pvt_thread_rdwr_t *rw)
+int ldap_pvt_thread_rdwr_writers(ldap_pvt_thread_rdwr_t *rwlock)
 {
+       struct ldap_int_thread_rdwr_s *rw;
+
+       assert( rwlock != NULL );
+       rw = *rwlock;
+
        assert( rw != NULL );
        assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
 
        return( rw->ltrw_w_active );
 }
 
-int ldap_pvt_thread_rdwr_active(ldap_pvt_thread_rdwr_t *rw)
+int ldap_pvt_thread_rdwr_active(ldap_pvt_thread_rdwr_t *rwlock)
 {
+       struct ldap_int_thread_rdwr_s *rw;
+
+       assert( rwlock != NULL );
+       rw = *rwlock;
+
        assert( rw != NULL );
        assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
 
@@ -260,3 +335,5 @@ int ldap_pvt_thread_rdwr_active(ldap_pvt_thread_rdwr_t *rw)
 }
 
 #endif /* LDAP_DEBUG */
+
+#endif /* LDAP_THREAD_HAVE_RDWR */
index 8d3949aa989aba76efaf07bf3df019538b2bcd0f..8e9049c7b1927d489abf5600a63996b8feed8ad2 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
  ***********************************************************************/
 
 int
-ldap_pvt_thread_initialize( void )
+ldap_int_thread_initialize( void )
 {
        return 0;
 }
 
 int
-ldap_pvt_thread_destroy( void )
+ldap_int_thread_destroy( void )
 {
        return 0;
 }
index 3c1dff33890ee2700612f7547fc325e9f779bccd..69ddd72f00c16a3a603e4ac9406bfd6fef534d2b 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
@@ -47,7 +47,7 @@
  * Initialize LWP by spinning of a schedular
  */
 int
-ldap_pvt_thread_initialize( void )
+ldap_int_thread_initialize( void )
 {
        thread_t                tid;
        stkalign_t              *stack;
@@ -62,7 +62,7 @@ ldap_pvt_thread_initialize( void )
 }
 
 int
-ldap_pvt_thread_destroy( void )
+ldap_int_thread_destroy( void )
 {
        /* need to destory lwp_scheduler thread and clean up private
                variables */
@@ -76,7 +76,7 @@ struct stackinfo {
 
 static struct stackinfo        *stacks;
 
-static stkalign_t * ldap_pvt_thread_get_stack( int *stacknop )
+static stkalign_t * ldap_int_thread_get_stack( int *stacknop )
 {
        int     i;
 
@@ -122,7 +122,7 @@ static stkalign_t * ldap_pvt_thread_get_stack( int *stacknop )
 }
 
 static void
-ldap_pvt_thread_free_stack( int        stackno )
+ldap_int_thread_free_stack( int        stackno )
 {
        if ( stackno < 0 || stackno > MAX_THREADS ) {
                Debug( LDAP_DEBUG_ANY, "free_stack of bogus stack %d\n",
@@ -137,7 +137,7 @@ lwp_create_stack( void *(*func)(), void *arg, int stackno )
 {
        (*func)( arg );
 
-       ldap_pvt_thread_free_stack( stackno );
+       ldap_int_thread_free_stack( stackno );
 }
 
 int 
@@ -149,7 +149,7 @@ ldap_pvt_thread_create( ldap_pvt_thread_t * thread,
        stkalign_t      *stack;
        int             stackno;
 
-       if ( (stack = ldap_pvt_thread_get_stack( &stackno )) == NULL ) {
+       if ( (stack = ldap_int_thread_get_stack( &stackno )) == NULL ) {
                return( -1 );
        }
        return( lwp_create( thread, lwp_create_stack, MINPRIO, 0, 
@@ -308,7 +308,7 @@ ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
 
 int 
 ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, 
-                     ldap_pvt_thread_mutex_t *mutex )
+       ldap_int_thread_mutex_t *mutex )
 {
        if ( ! cond->lcv_created ) {
                cv_create( &cond->lcv_cv, *mutex );
index 20cca306eaf8c9a2100b431a227180e6167b65a3..935bf4bd1396f8b9a7f9816eb1219314b6608cdf 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 #include "ldap_pvt_thread.h"
 
 int
-ldap_pvt_thread_initialize( void )
+ldap_int_thread_initialize( void )
 {
        return 0;
 }
 
 int
-ldap_pvt_thread_destroy( void )
+ldap_int_thread_destroy( void )
 {
        return 0;
 }
@@ -93,18 +93,18 @@ ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
 
 int 
 ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, 
-                         ldap_pvt_thread_mutex_t *mutex )
+       ldap_pvt_thread_mutex_t *mutex )
 {
        ReleaseMutex( *mutex );
-       WaitForSingleObject( *cond, INFINITE );
+       SignalObjectAndWait( *mutex, *cond, INFINITE, FALSE );
        WaitForSingleObject( *mutex, INFINITE );
        return( 0 );
 }
 
 int
-ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cv )
+ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond )
 {
-       SetEvent( *cv );
+       SetEvent( *cond );
        return( 0 );
 }
 
index c44bee48c315ff463008ef9177c3b2b500db6dc7..95d30f1b4b4d186471073954d73ee010ae9c2a90 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 
 
 #if HAVE_PTHREADS_D4
-#  define LDAP_PVT_THREAD_ATTR_DEFAULT         pthread_attr_default
-#  define LDAP_PVT_THREAD_CONDATTR_DEFAULT     pthread_condattr_default
-#  define LDAP_PVT_THREAD_MUTEXATTR_DEFAULT    pthread_mutexattr_default
+#  define LDAP_INT_THREAD_ATTR_DEFAULT         pthread_attr_default
+#  define LDAP_INT_THREAD_CONDATTR_DEFAULT     pthread_condattr_default
+#  define LDAP_INT_THREAD_MUTEXATTR_DEFAULT    pthread_mutexattr_default
 #else
-#  define LDAP_PVT_THREAD_ATTR_DEFAULT         NULL
-#  define LDAP_PVT_THREAD_CONDATTR_DEFAULT     NULL
-#  define LDAP_PVT_THREAD_MUTEXATTR_DEFAULT    NULL
+#  define LDAP_INT_THREAD_ATTR_DEFAULT         NULL
+#  define LDAP_INT_THREAD_CONDATTR_DEFAULT     NULL
+#  define LDAP_INT_THREAD_MUTEXATTR_DEFAULT    NULL
 #endif
 
 
 int
-ldap_pvt_thread_initialize( void )
+ldap_int_thread_initialize( void )
 {
-#if defined( LDAP_THREAD_CONCURRENCY ) && HAVE_PTHREAD_SETCONCURRENCY
-       ldap_pvt_thread_set_concurrency( LDAP_THREAD_CONCURRENCY );
-#endif
        return 0;
 }
 
 int
-ldap_pvt_thread_destroy( void )
+ldap_int_thread_destroy( void )
 {
        return 0;
 }
@@ -81,8 +78,19 @@ ldap_pvt_thread_create( ldap_pvt_thread_t * thread,
        void *(*start_routine)( void * ),
        void *arg)
 {
-       int rtn = pthread_create( thread, LDAP_PVT_THREAD_ATTR_DEFAULT,
+       int rtn;
+#if defined(HAVE_PTHREADS_FINAL) && defined(PTHREAD_CREATE_UNDETACHED)
+       pthread_attr_t attr;
+
+       pthread_attr_init(&attr);
+       if (!detach)
+               pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_UNDETACHED);
+
+       rtn = pthread_create( thread, &attr, start_routine, arg );
+#else
+       rtn = pthread_create( thread, LDAP_INT_THREAD_ATTR_DEFAULT,
                                  start_routine, arg );
+#endif
 
        if( detach ) {
 #ifdef HAVE_PTHREADS_FINAL
@@ -149,7 +157,7 @@ ldap_pvt_thread_yield( void )
 int 
 ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond )
 {
-       return pthread_cond_init( cond, LDAP_PVT_THREAD_CONDATTR_DEFAULT );
+       return pthread_cond_init( cond, LDAP_INT_THREAD_CONDATTR_DEFAULT );
 }
 
 int 
@@ -180,7 +188,7 @@ ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond,
 int 
 ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex )
 {
-       return pthread_mutex_init( mutex, LDAP_PVT_THREAD_MUTEXATTR_DEFAULT );
+       return pthread_mutex_init( mutex, LDAP_INT_THREAD_MUTEXATTR_DEFAULT );
 }
 
 int 
@@ -195,11 +203,63 @@ ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
        return pthread_mutex_lock( mutex );
 }
 
+int 
+ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex )
+{
+       return pthread_mutex_trylock( mutex );
+}
+
 int 
 ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
 {
        return pthread_mutex_unlock( mutex );
 }
 
+#ifdef LDAP_THREAD_HAVE_RDWR
+#ifdef HAVE_PTHREAD_RWLOCK_DESTROY
+int 
+ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw )
+{
+       return pthread_rwlock_init( rw, NULL );
+}
+
+int 
+ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rw )
+{
+       return pthread_rwlock_destroy( rw );
+}
+
+int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rw )
+{
+       return pthread_rwlock_rdlock( rw );
+}
+
+int ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rw )
+{
+       return pthread_rwlock_tryrdlock( rw );
+}
+
+int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rw )
+{
+       return pthread_rwlock_unlock( rw );
+}
+
+int ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rw )
+{
+       return pthread_rwlock_wrlock( rw );
+}
+
+int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rw )
+{
+       return pthread_rwlock_trywrlock( rw );
+}
+
+int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rw )
+{
+       return pthread_rwlock_unlock( rw );
+}
+
+#endif /* HAVE_PTHREAD_RDLOCK_DESTROY */
+#endif /* LDAP_THREAD_HAVE_RDWR */
 #endif /* HAVE_PTHREADS */
 
index 132644cff070372ea6fe7202910288b107fee2a2..15fcac75a8c3889436123b6ee74248cf690fe952 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 static pth_attr_t detach_attr;
 
 int
-ldap_pvt_thread_initialize( void )
+ldap_int_thread_initialize( void )
 {
+       if( !pth_init() ) {
+               return -1;
+       }
        detach_attr = pth_attr_new();
-       pth_attr_set( detach_attr, PTH_ATTR_JOINABLE, FALSE );
-       return pth_init();
+       return pth_attr_set( detach_attr, PTH_ATTR_JOINABLE, FALSE );
 }
 
 int
-ldap_pvt_thread_destroy( void )
+ldap_int_thread_destroy( void )
 {
        pth_attr_destroy(detach_attr);
        pth_kill();
@@ -99,7 +101,7 @@ ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond )
 
 int 
 ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, 
-                         ldap_pvt_thread_mutex_t *mutex )
+       ldap_pvt_thread_mutex_t *mutex )
 {
        return( pth_cond_await( cond, mutex, NULL ) );
 }
@@ -140,4 +142,48 @@ ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex )
        return( pth_mutex_acquire( mutex, 1, NULL ) );
 }
 
+#ifdef LDAP_THREAD_HAVE_RDWR
+int 
+ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw )
+{
+       return pth_rwlock_init( rw );
+}
+
+int 
+ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rw )
+{
+       return 0;
+}
+
+int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rw )
+{
+       return pth_rwlock_acquire( rw, PTH_RWLOCK_RD, 0, NULL );
+}
+
+int ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rw )
+{
+       return pth_rwlock_acquire( rw, PTH_RWLOCK_RD, 1, NULL );
+}
+
+int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rw )
+{
+       return pth_rwlock_release( rw );
+}
+
+int ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rw )
+{
+       return pth_rwlock_acquire( rw, PTH_RWLOCK_RW, 0, NULL );
+}
+
+int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rw )
+{
+       return pth_rwlock_acquire( rw, PTH_RWLOCK_RW, 1, NULL );
+}
+
+int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rw )
+{
+       return pth_rwlock_release( rw );
+}
+
+#endif /* LDAP_THREAD_HAVE_RDWR */
 #endif /* HAVE_GNU_PTH */
diff --git a/libraries/libldap_r/thr_sleep.c b/libraries/libldap_r/thr_sleep.c
deleted file mode 100644 (file)
index fac90d0..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* $OpenLDAP$ */
-/*
- * Copyright (c) 1996 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.
- */
-
-/*
- * ldap_pvt_thread_sleep.c - allow a thread to sleep without putting
- * the whole process (e.g. pod under lwp) to sleep.
- *
- * Contains platform-specific code to allow this:
- *
- * Under non-preemptive threads packages like SunOS lwp, tsleep() adds
- * the thread to a list of sleepers.  The lwp_scheduler process takes
- * care of resuming suspended threads.
- *
- * Under a fully-preemptive threads package, like Solaris threads,
- * tsleep just calls sleep(), and there is no scheduler thread.  Life
- * is so much simpler...
- */
-
-#include "portable.h"
-
-#if !defined( HAVE_LWP )
-
-#include <stdio.h>
-#include <ac/stdlib.h>
-#include <ac/unistd.h>                 /* get sleep() */
-
-#include "ldap_pvt_thread.h"
-
-
-/*
- * Here we assume we have fully preemptive threads and that sleep()
- * does the right thing.
- */
-unsigned int
-ldap_pvt_thread_sleep(
-       unsigned int interval
-)
-{
-       sleep( interval );
-       return 0;
-}
-
-#else
-
-/* LWP implementation of sleep can be found in thr_lwp.c */
-
-#endif /* HAVE_LWP */
index 60da3cec1f001f57915b8597afd412b9d7e8c307..e473e0e557ebe2dddbf0bffe5cf4841aab27da13 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
  ***********************************************************************/
 
 int
-ldap_pvt_thread_initialize( void )
+ldap_int_thread_initialize( void )
 {
        return 0;
 }
 
 int
-ldap_pvt_thread_destroy( void )
+ldap_int_thread_destroy( void )
 {
        return 0;
 }
@@ -126,10 +126,52 @@ ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
        return 0;
 }
 
+int 
+ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex )
+{
+       return 0;
+}
+
 int 
 ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
 {
        return 0;
 }
 
+/*
+ * NO_THREADS requires a separate tpool implementation since
+ * generic ldap_pvt_thread_pool_wrapper loops forever.
+ */
+int
+ldap_pvt_thread_pool_init (
+       ldap_pvt_thread_pool_t *pool_out,
+       int max_concurrency, int max_pending )
+{
+       *pool_out = NULL;
+       return(0);
+}
+
+int
+ldap_pvt_thread_pool_submit (
+       ldap_pvt_thread_pool_t *pool,
+       void *(*start_routine)( void * ), void *arg )
+{
+       (start_routine)(arg);
+       return(0);
+}
+
+int
+ldap_pvt_thread_pool_backload (
+       ldap_pvt_thread_pool_t *pool )
+{
+       return(0);
+}
+
+int
+ldap_pvt_thread_pool_destroy (
+       ldap_pvt_thread_pool_t *pool, int run_pending )
+{
+       return(0);
+}
+
 #endif /* NO_THREADS */
index bb3b10d6b73b4df31a3de92f8dc1fde16ea29bca..ee89e2e6409185c530445e5de207a2638916d5d4 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
  *******************/
 
 int
-ldap_pvt_thread_initialize( void )
+ldap_int_thread_initialize( void )
 {
-#ifdef LDAP_THREAD_CONCURRENCY
-       thr_setconcurrency( LDAP_THREAD_CONCURRENCY );
-#endif
        return 0;
 }
 
 int
-ldap_pvt_thread_destroy( void )
+ldap_int_thread_destroy( void )
 {
        return 0;
 }
 
+#ifdef LDAP_THREAD_HAVE_SETCONCURRENCY
 int
 ldap_pvt_thread_set_concurrency(int n)
 {
        return thr_setconcurrency( n );
 }
+#endif
 
+#ifdef LDAP_THREAD_HAVE_GETCONCURRENCY
 int
 ldap_pvt_thread_get_concurrency(void)
 {
        return thr_getconcurrency();
 }
+#endif
 
 int 
 ldap_pvt_thread_create( ldap_pvt_thread_t * thread, 
@@ -107,7 +108,7 @@ ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cv )
 
 int 
 ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, 
-                         ldap_pvt_thread_mutex_t *mutex )
+       ldap_pvt_thread_mutex_t *mutex )
 {
        return( cond_wait( cond, mutex ) );
 }
diff --git a/libraries/libldap_r/threads.c b/libraries/libldap_r/threads.c
new file mode 100644 (file)
index 0000000..9f845fe
--- /dev/null
@@ -0,0 +1,87 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted only
+ * as authorized by the OpenLDAP Public License.  A copy of this
+ * license is available at http://www.OpenLDAP.org/license.html or
+ * in file LICENSE in the top-level directory of the distribution.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <ac/stdlib.h>
+#include <ac/string.h>
+
+#include "ldap_pvt_thread.h"
+
+
+/*
+ * Common LDAP thread routines
+ *     see thr_*.c for implementation specific routines
+ *     see rdwr.c for generic reader/writer lock implementation
+ *     see tpool.c for generic thread pool implementation
+ */
+
+
+int ldap_pvt_thread_initialize( void )
+{
+       int rc;
+       static int init = 0;
+
+       /* we only get one shot at this */
+       if( init++ ) return -1;
+
+       rc = ldap_int_thread_initialize();
+       if( rc ) return rc;
+
+#ifndef LDAP_THREAD_HAVE_TPOOL
+       rc = ldap_int_thread_pool_startup();
+       if( rc ) return rc;
+#endif
+
+       return 0;
+}
+
+int ldap_pvt_thread_destroy( void )
+{
+#ifndef LDAP_THREAD_HAVE_TPOOL
+       (void) ldap_int_thread_pool_shutdown();
+#endif
+       (void) ldap_int_thread_destroy();
+}
+
+#ifndef LDAP_THREAD_HAVE_GETCONCURRENCY
+int
+ldap_pvt_thread_get_concurrency ( void )
+{
+       return 1;
+}
+#endif
+
+#ifndef LDAP_THREAD_HAVE_SETCONCURRENCY
+int
+ldap_pvt_thread_set_concurrency ( int concurrency )
+{
+       return 1;
+}
+#endif
+
+#ifndef LDAP_THREAD_HAVE_SLEEP
+/*
+ * Here we assume we have fully preemptive threads and that sleep()
+ * does the right thing.
+ */
+unsigned int
+ldap_pvt_thread_sleep(
+       unsigned int interval
+)
+{
+       sleep( interval );
+       return 0;
+}
+#endif
diff --git a/libraries/libldap_r/tpool.c b/libraries/libldap_r/tpool.c
new file mode 100644 (file)
index 0000000..af0c4f7
--- /dev/null
@@ -0,0 +1,396 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted only
+ * as authorized by the OpenLDAP Public License.  A copy of this
+ * license is available at http://www.OpenLDAP.org/license.html or
+ * in file LICENSE in the top-level directory of the distribution.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <ac/stdlib.h>
+#include <ac/string.h>
+#include <ac/time.h>
+
+#include "ldap-int.h"
+#include "ldap_pvt_thread.h"
+
+#ifndef LDAP_THREAD_HAVE_TPOOL
+
+enum ldap_int_thread_pool_state {
+       LDAP_INT_THREAD_POOL_RUNNING,
+       LDAP_INT_THREAD_POOL_FINISHING,
+       LDAP_INT_THREAD_POOL_STOPPING
+};
+
+typedef struct ldap_int_thread_list_element_s {
+       struct ldap_int_thread_list_element_s *next;
+} ldap_int_thread_list_element_t, *ldap_int_thread_list_t;
+
+struct ldap_int_thread_pool_s {
+       struct ldap_int_thread_pool_s *ltp_next;
+       ldap_pvt_thread_mutex_t ltp_mutex;
+       ldap_pvt_thread_cond_t ltp_cond;
+       ldap_int_thread_list_t ltp_pending_list;
+       long ltp_state;
+       long ltp_max_count;
+       long ltp_max_pending;
+       long ltp_pending_count;
+       long ltp_active_count;
+       long ltp_open_count;
+};
+
+typedef struct ldap_int_thread_ctx_s {
+       struct ldap_int_thread_ctx_s *ltc_next;
+       void *(*ltc_start_routine)( void *);
+       void *ltc_arg;
+} ldap_int_thread_ctx_t;
+
+static ldap_int_thread_list_t ldap_int_thread_pool_list = NULL;
+static ldap_pvt_thread_mutex_t ldap_pvt_thread_pool_mutex;
+
+static void *ldap_int_thread_pool_wrapper(
+       struct ldap_int_thread_pool_s *pool );
+
+static void *ldap_int_thread_enlist( ldap_int_thread_list_t *list, void *elem );
+static void *ldap_int_thread_delist( ldap_int_thread_list_t *list, void *elem );
+static void *ldap_int_thread_onlist( ldap_int_thread_list_t *list, void *elem );
+
+int
+ldap_int_thread_pool_startup ( void )
+{
+       return ldap_pvt_thread_mutex_init(&ldap_pvt_thread_pool_mutex);
+}
+
+int
+ldap_int_thread_pool_shutdown ( void )
+{
+       while (ldap_int_thread_pool_list != NULL) {
+               struct ldap_int_thread_pool_s *pool =
+                       (struct ldap_int_thread_pool_s *) ldap_int_thread_pool_list;
+
+               ldap_pvt_thread_pool_destroy( &pool, 0);
+       }
+       ldap_pvt_thread_mutex_destroy(&ldap_pvt_thread_pool_mutex);
+       return(0);
+}
+
+int
+ldap_pvt_thread_pool_init (
+       ldap_pvt_thread_pool_t *tpool,
+       int max_concurrency,
+       int max_pending )
+{
+       int rc;
+       ldap_pvt_thread_pool_t pool;
+       ldap_pvt_thread_t thr;
+
+       *tpool = NULL;
+       pool = (ldap_pvt_thread_pool_t) LDAP_CALLOC(1,
+               sizeof(struct ldap_int_thread_pool_s));
+
+       if (pool == NULL) return(-1);
+
+       ldap_pvt_thread_mutex_init(&pool->ltp_mutex);
+       ldap_pvt_thread_cond_init(&pool->ltp_cond);
+       pool->ltp_state = LDAP_INT_THREAD_POOL_RUNNING;
+       pool->ltp_max_count = max_concurrency;
+       pool->ltp_max_pending = max_pending;
+       ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex);
+       ldap_int_thread_enlist(&ldap_int_thread_pool_list, pool);
+       ldap_pvt_thread_mutex_unlock(&ldap_pvt_thread_pool_mutex);
+
+       /* start up one thread, just so there is one */
+       pool->ltp_open_count++;
+
+       rc = ldap_pvt_thread_create( &thr, 1,
+               (void *) ldap_int_thread_pool_wrapper, pool );
+
+       if( rc != 0) {
+               /* couldn't start one?  then don't start any */
+               ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex);
+               ldap_int_thread_delist(&ldap_int_thread_pool_list, pool);
+               ldap_pvt_thread_mutex_unlock(&ldap_pvt_thread_pool_mutex);
+               ldap_pvt_thread_cond_destroy(&pool->ltp_cond);
+               ldap_pvt_thread_mutex_destroy(&pool->ltp_mutex);
+               free(pool);
+               return(-1);
+       }
+
+       *tpool = pool;
+       return(0);
+}
+
+int
+ldap_pvt_thread_pool_submit (
+       ldap_pvt_thread_pool_t *tpool,
+       void *(*start_routine)( void * ), void *arg )
+{
+       struct ldap_int_thread_pool_s *pool;
+       ldap_int_thread_ctx_t *ctx;
+       int need_thread = 0;
+       ldap_pvt_thread_t thr;
+
+       if (tpool == NULL)
+               return(-1);
+
+       pool = *tpool;
+
+       if (pool == NULL)
+               return(-1);
+
+       ctx = (ldap_int_thread_ctx_t *) LDAP_CALLOC(1,
+               sizeof(ldap_int_thread_ctx_t));
+
+       if (ctx == NULL) return(-1);
+
+       ctx->ltc_start_routine = start_routine;
+       ctx->ltc_arg = arg;
+
+       ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
+       if (pool->ltp_state != LDAP_INT_THREAD_POOL_RUNNING
+               || (pool->ltp_max_pending > 0
+                       && pool->ltp_pending_count >= pool->ltp_max_pending))
+       {
+               ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
+               free(ctx);
+               return(-1);
+       }
+       pool->ltp_pending_count++;
+       ldap_int_thread_enlist(&pool->ltp_pending_list, ctx);
+       ldap_pvt_thread_cond_signal(&pool->ltp_cond);
+       if ((pool->ltp_open_count <= 0
+                       || pool->ltp_pending_count > 1
+                       || pool->ltp_open_count == pool->ltp_active_count)
+               && (pool->ltp_max_count <= 0
+                       || pool->ltp_open_count < pool->ltp_max_count))
+       {
+               pool->ltp_open_count++;
+               need_thread = 1;
+       }
+       ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
+
+       if (need_thread) {
+               int rc = ldap_pvt_thread_create( &thr, 1,
+                       (void *)ldap_int_thread_pool_wrapper, pool );
+               if (rc != 0) {
+                       /* couldn't create thread.  back out of
+                        * ltp_open_count and check for even worse things.
+                        */
+                       ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
+                       pool->ltp_open_count--;
+                       if (pool->ltp_open_count == 0) {
+                               /* no open threads at all?!?  this will never happen
+                                * because we always leave at least one thread open.
+                                */
+                               if (ldap_int_thread_delist(&pool->ltp_pending_list, ctx)) {
+                                       /* no open threads, context not handled, so
+                                        * back out of ltp_pending_count, free the context,
+                                        * report the error.
+                                        */
+                                       pool->ltp_pending_count++;
+                                       ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
+                                       free(ctx);
+                                       return(-1);
+                               }
+                       }
+                       ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
+                       /* there is another open thread, so this
+                        * context will be handled eventually.
+                        * continue on and signal that the context
+                        * is waiting.
+                        */
+               }
+       }
+
+       return(0);
+}
+
+int
+ldap_pvt_thread_pool_backload ( ldap_pvt_thread_pool_t *tpool )
+{
+       struct ldap_int_thread_pool_s *pool;
+       int count;
+
+       if (tpool == NULL)
+               return(-1);
+
+       pool = *tpool;
+
+       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);
+}
+
+int
+ldap_pvt_thread_pool_destroy ( ldap_pvt_thread_pool_t *tpool, int run_pending )
+{
+       struct ldap_int_thread_pool_s *pool;
+       long waiting;
+       ldap_int_thread_ctx_t *ctx;
+
+       if (tpool == NULL)
+               return(-1);
+
+       pool = *tpool;
+
+       if (pool == NULL) return(-1);
+
+       ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex);
+       pool = ldap_int_thread_delist(&ldap_int_thread_pool_list, pool);
+       ldap_pvt_thread_mutex_unlock(&ldap_pvt_thread_pool_mutex);
+
+       if (pool == NULL) return(-1);
+
+       ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
+       pool->ltp_state = run_pending
+               ? LDAP_INT_THREAD_POOL_FINISHING
+               : LDAP_INT_THREAD_POOL_STOPPING;
+       waiting = pool->ltp_open_count;
+       ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
+
+       /* broadcast could be used here, but only after
+        * it is fixed in the NT thread implementation
+        */
+       while (--waiting >= 0) {
+               ldap_pvt_thread_cond_signal(&pool->ltp_cond);
+       }
+
+       do {
+               ldap_pvt_thread_yield();
+               ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
+               waiting = pool->ltp_open_count;
+               ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
+       } while (waiting > 0);
+
+       while (ctx = (ldap_int_thread_ctx_t *)ldap_int_thread_delist(
+               &pool->ltp_pending_list, NULL))
+       {
+               free(ctx);
+       }
+
+       ldap_pvt_thread_cond_destroy(&pool->ltp_cond);
+       ldap_pvt_thread_mutex_destroy(&pool->ltp_mutex);
+       free(pool);
+       return(0);
+}
+
+static void *
+ldap_int_thread_pool_wrapper ( 
+       struct ldap_int_thread_pool_s *pool )
+{
+       ldap_int_thread_ctx_t *ctx;
+
+       if (pool == NULL)
+               return NULL;
+
+       ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
+
+       while (pool->ltp_state != LDAP_INT_THREAD_POOL_STOPPING) {
+
+               ctx = ldap_int_thread_delist(&pool->ltp_pending_list, NULL);
+               if (ctx == NULL) {
+                       if (pool->ltp_state == LDAP_INT_THREAD_POOL_FINISHING)
+                               break;
+                       /* we could check an idle timer here, and let the
+                        * thread die if it has been inactive for a while.
+                        * only die if there are other open threads (i.e.,
+                        * always have at least one thread open).
+                        */
+
+                       if (pool->ltp_state == LDAP_INT_THREAD_POOL_RUNNING)
+                               ldap_pvt_thread_cond_wait(&pool->ltp_cond, &pool->ltp_mutex);
+
+                       continue;
+               }
+
+               pool->ltp_pending_count--;
+               pool->ltp_active_count++;
+               ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
+
+               (ctx->ltc_start_routine)(ctx->ltc_arg);
+               free(ctx);
+               ldap_pvt_thread_yield();
+
+               /* if we use an idle timer, here's
+                * a good place to update it
+                */
+
+               ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
+               pool->ltp_active_count--;
+       }
+
+       pool->ltp_open_count--;
+       ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
+
+       ldap_pvt_thread_exit(NULL);
+       return(NULL);
+}
+
+static void *
+ldap_int_thread_enlist( ldap_int_thread_list_t *list, void *elem )
+{
+       ldap_int_thread_list_element_t *prev;
+
+       if (elem == NULL) return(NULL);
+
+       ((ldap_int_thread_list_element_t *)elem)->next = NULL;
+       if (*list == NULL) {
+               *list = elem;
+               return(elem);
+       }
+
+       for (prev = *list ; prev->next != NULL; prev = prev->next) ;
+       prev->next = elem;
+       return(elem);
+}
+
+static void *
+ldap_int_thread_delist( ldap_int_thread_list_t *list, void *elem )
+{
+       ldap_int_thread_list_element_t *prev;
+
+       if (*list == NULL) return(NULL);
+
+       if (elem == NULL) elem = *list;
+
+       if (*list == elem) {
+               *list = ((ldap_int_thread_list_element_t *)elem)->next;
+               return(elem);
+       }
+
+       for (prev = *list ; prev->next != NULL; prev = prev->next) {
+               if (prev->next == elem) {
+                       prev->next = ((ldap_int_thread_list_element_t *)elem)->next;
+                       return(elem);
+               }
+       }
+       return(NULL);
+}
+
+static void *
+ldap_int_thread_onlist( ldap_int_thread_list_t *list, void *elem )
+{
+       ldap_int_thread_list_element_t *prev;
+
+       if (elem == NULL || *list == NULL) return(NULL);
+
+       for (prev = *list ; prev != NULL; prev = prev->next) {
+               if (prev == elem)
+                       return(elem);
+       }
+
+       return(NULL);
+}
+
+#endif /* LDAP_HAVE_THREAD_POOL */
index 7926c3673d895ff768ff5910e331a70829ed6474..a2679ab8a6059b8b294809afc953b722d1319c1f 100644 (file)
@@ -1,4 +1,6 @@
 # $OpenLDAP$
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 ##
 ## Makefile for -lldbm
 ##
@@ -11,8 +13,12 @@ OBJS         = ldbm.o
 LDAP_INCDIR= ../../include       
 LDAP_LIBDIR= ../../libraries
 
+NT_DYN_LIB_DEFS = -DLIBLDAP_DECL=dllimport
+CPPFLAGS = $(@PLAT@_@LIB_LINKAGE@_LIB_DEFS)
+
 XLIBS          = -lldbm -lavl
 XXLIBS         = $(LDBM_LIBS)
 
 testldbm:      libldbm.a testldbm.o
        $(CC) $(LDFLAGS) -o $@ testldbm.o $(LIBS)
+
index 461db8657e84964619db4b9a33a49a57c210c955..2560fd8727f568c7a80ecd9291043b89c40f386c 100644 (file)
@@ -1,7 +1,7 @@
 /* ldbm.c - ldap dbm compatibility routines */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 #include "ldbm.h"
 #include "ldap_pvt_thread.h"
 
-
 void
 ldbm_datum_free( LDBM ldbm, Datum data )
 {
        if ( data.dptr ) {
                free( data.dptr );
-               memset( &data, 0, sizeof( Datum ));
+               memset( &data, '\0', sizeof( Datum ));
                data.dptr = NULL;
        }
 }
@@ -59,32 +58,28 @@ ldbm_datum_dup( LDBM ldbm, Datum data )
 
 static int ldbm_initialized = 0;
 
-#ifndef HAVE_BERKELEY_DB2
-/* Everything but DB2 is non-reentrant */
+#ifdef HAVE_BERKELEY_DB_THREAD
+#define LDBM_LOCK      ((void)0)
+#define LDBM_UNLOCK    ((void)0)
+#else
 
+/* Only DB2 or DB3 with DB_THREAD is thread-free */
 static ldap_pvt_thread_mutex_t ldbm_big_mutex;
 #define LDBM_LOCK      (ldap_pvt_thread_mutex_lock(&ldbm_big_mutex))
 #define LDBM_UNLOCK    (ldap_pvt_thread_mutex_unlock(&ldbm_big_mutex))
 
-int ldbm_initialize( void )
-{
-       if(ldbm_initialized++) return 1;
-
-       ldap_pvt_thread_mutex_init( &ldbm_big_mutex );
+#endif
 
-       return 0;
-}
 
-int ldbm_shutdown( void )
-{
-       if( !ldbm_initialized ) return 1;
 
-       ldap_pvt_thread_mutex_destroy( &ldbm_big_mutex );
+/*******************************************************************
+ *                                                                 *
+ *  Create some special functions to initialize Berkeley DB for    *
+ *  versions greater than 2.                                       *
+ *                                                                 *
+ *******************************************************************/
+#if defined( HAVE_BERKELEY_DB ) && (DB_VERSION_MAJOR >= 2)
 
-       return 0;
-}
-
-#else
 
 void *
 ldbm_malloc( size_t size )
@@ -105,13 +100,8 @@ ldbm_db_errcall( const char *prefix, char *message )
 }
 
 /*  a dbEnv for BERKELEYv2  */
-static DB_ENV    ldbm_Env_internal;
 DB_ENV           *ldbm_Env = NULL;
 
-/* Berkeley DB 2.x is reentrant */
-#define LDBM_LOCK      ((void)0)
-#define LDBM_UNLOCK    ((void)0)
-
 int ldbm_initialize( void )
 {
        int     err;
@@ -119,23 +109,37 @@ int ldbm_initialize( void )
 
        if(ldbm_initialized++) return 1;
 
-       memset( &ldbm_Env_internal, 0, sizeof( DB_ENV ));
-       ldbm_Env = &ldbm_Env_internal;
+#if DB_VERSION_MAJOR < 3
+       ldbm_Env = calloc( 1, sizeof( DB_ENV ));
+
+       if( ldbm_Env == NULL ) return 1;
 
        ldbm_Env->db_errcall   = ldbm_db_errcall;
        ldbm_Env->db_errpfx    = "==>";
+#else
+       ldbm_Env = NULL;
+#endif
 
-       envFlags = DB_CREATE | DB_THREAD;
+       envFlags = 
+#if defined( HAVE_BERKELEY_DB_THREAD )
+               DB_THREAD |
+#endif
+               DB_CREATE;
 
-       if ( ( err = db_appinit( NULL, NULL, ldbm_Env, envFlags )) ) {
-               char  error[BUFSIZ];
+#if DB_VERSION_MAJOR >= 3
+       err = db_env_create( &ldbm_Env, 0 );
+#elif DB_VERSION_MAJOR >= 2
+       err = db_appinit( NULL, NULL, ldbm_Env, envFlags );
+#endif
+
+       if ( err ) {
+               char error[BUFSIZ];
 
                if ( err < 0 ) {
                        sprintf( error, "%ld\n", (long) err );
                } else {
                        sprintf( error, "%s\n", strerror( err ));
                }
-
 #ifdef LDAP_SYSLOG
                syslog( LOG_INFO,
                        "ldbm_initialize(): FATAL error in db_appinit() : %s\n",
@@ -144,6 +148,31 @@ int ldbm_initialize( void )
                return( 1 );
        }
 
+#if DB_VERSION_MAJOR >= 3
+       ldbm_Env->set_errcall( ldbm_Env, ldbm_db_errcall );
+       ldbm_Env->set_errpfx( ldbm_Env, "==>" );
+
+        envFlags |= DB_INIT_MPOOL;
+        err = ldbm_Env->open( ldbm_Env, NULL, NULL, envFlags, 0 );
+        if ( err != 0 )
+        {
+            char error[BUFSIZ];
+
+            if ( err < 0 ) {
+                sprintf( error, "%ld\n", (long) err );
+            } else {
+                sprintf( error, "%s\n", strerror( err ));
+            }
+#ifdef LDAP_SYSLOG
+            syslog( LOG_INFO,
+                    "ldbm_initialize(): FATAL error in db_appinit() : %s\n",
+                    error );
+#endif
+                   ldbm_Env->close( ldbm_Env, 0 );
+            return( 1 );
+       }
+#endif
+
        return 0;
 }
 
@@ -151,12 +180,37 @@ int ldbm_shutdown( void )
 {
        if( !ldbm_initialized ) return 1;
 
+#if DB_VERSION_MAJOR >= 3
+        ldbm_Env->close( ldbm_Env, 0 );
+#else
        db_appexit( ldbm_Env );
+#endif
 
        return 0;
 }
 
-#endif
+#else  /* some DB other than Berkeley V2 or greater */
+
+int ldbm_initialize( void )
+{
+       if(ldbm_initialized++) return 1;
+
+       ldap_pvt_thread_mutex_init( &ldbm_big_mutex );
+
+       return 0;
+}
+
+int ldbm_shutdown( void )
+{
+       if( !ldbm_initialized ) return 1;
+
+       ldap_pvt_thread_mutex_destroy( &ldbm_big_mutex );
+
+       return 0;
+}
+
+#endif /* ifdef HAVE_BERKELEY_DB */
+
 
 #if defined( LDBM_USE_DBHASH ) || defined( LDBM_USE_DBBTREE )
 
@@ -171,10 +225,45 @@ ldbm_open( char *name, int rw, int mode, int dbcachesize )
 {
        LDBM            ret = NULL;
 
-#ifdef HAVE_BERKELEY_DB2
+#if DB_VERSION_MAJOR >= 3
+       int err;
+       LDBM_LOCK;
+       err = db_create( &ret, ldbm_Env, 0 );
+       if ( err != 0 )
+       {
+           char error[BUFSIZ];
+
+           if ( err < 0 ) {
+               sprintf( error, "%ld\n", (long) err );
+           } else {
+               sprintf( error, "%s\n", strerror( err ));
+           }
+           (void)ret->close(ret, 0);
+           return NULL;
+       }
+
+       ret->set_pagesize( ret, DEFAULT_DB_PAGE_SIZE );
+       ret->set_malloc( ret, ldbm_malloc );
+       ret->set_cachesize( ret, 0, dbcachesize, 0 );
+       err = ret->open( ret, name, NULL, DB_TYPE, rw, mode);
+       LDBM_UNLOCK;
+       if ( err != 0 )
+       {
+           char error[BUFSIZ];
+
+           if ( err < 0 ) {
+               sprintf( error, "%ld\n", (long) err );
+           } else {
+               sprintf( error, "%s\n", strerror( err ));
+           }
+           (void)ret->close(ret, 0);
+           return NULL;
+       }
+#elif DB_VERSION_MAJOR >= 2
        DB_INFO dbinfo;
 
-       memset( &dbinfo, 0, sizeof( dbinfo ));
+       memset( &dbinfo, '\0', sizeof( dbinfo ));
 
 #if defined( DB_VERSION_MAJOR ) && defined( DB_VERSION_MINOR ) && \
     DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR == 4
@@ -225,7 +314,9 @@ void
 ldbm_close( LDBM ldbm )
 {
        LDBM_LOCK;
-#ifdef HAVE_BERKELEY_DB2
+#if DB_VERSION_MAJOR >= 3
+        ldbm->close( ldbm, 0 );
+#elif DB_VERSION_MAJOR >= 2
        (*ldbm->close)( ldbm, 0 );
 #else
        (*ldbm->close)( ldbm );
@@ -248,8 +339,15 @@ ldbm_fetch( LDBM ldbm, Datum key )
        int     rc;
 
        LDBM_LOCK;
+#if DB_VERSION_MAJOR >= 3
+        ldbm_datum_init( data );
+
+        data.flags = DB_DBT_MALLOC;
 
-#ifdef HAVE_BERKELEY_DB2
+        if ( (rc = ldbm->get( ldbm, NULL, &key, &data, 0 )) != 0 ) {
+            ldbm_datum_free( ldbm, data );
+
+#elif DB_VERSION_MAJOR >= 2
        ldbm_datum_init( data );
 
        data.flags = DB_DBT_MALLOC;
@@ -279,7 +377,21 @@ ldbm_store( LDBM ldbm, Datum key, Datum data, int flags )
 
        LDBM_LOCK;
 
-#ifdef HAVE_BERKELEY_DB2
+#if DB_VERSION_MAJOR >= 3
+        rc = ldbm->put( ldbm, NULL, &key, &data, flags & ~LDBM_SYNC );
+       if ( rc != 0 )
+       {
+           char error[BUFSIZ];
+
+           if ( rc < 0 ) {
+               sprintf( error, "%ld\n", (long) rc );
+           } else {
+               sprintf( error, "%s\n", strerror( rc ));
+           }
+       }
+        rc = (-1) * rc;
+
+#elif DB_VERSION_MAJOR >= 2
        rc = (*ldbm->put)( ldbm, NULL, &key, &data, flags & ~LDBM_SYNC );
        rc = (-1 ) * rc;
 #else
@@ -301,7 +413,10 @@ ldbm_delete( LDBM ldbm, Datum key )
 
        LDBM_LOCK;
 
-#ifdef HAVE_BERKELEY_DB2
+#if DB_VERSION_MAJOR >= 3
+       rc = ldbm->del( ldbm, NULL, &key, 0 );
+       rc = (-1 ) * rc;
+#elif DB_VERSION_MAJOR >= 2
        rc = (*ldbm->del)( ldbm, NULL, &key, 0 );
        rc = (-1 ) * rc;
 #else
@@ -319,7 +434,7 @@ ldbm_firstkey( LDBM ldbm, LDBMCursor **dbch )
 {
        Datum   key, data;
 
-#ifdef HAVE_BERKELEY_DB2
+#if DB_VERSION_MAJOR >= 2
        LDBMCursor  *dbci;
 
        ldbm_datum_init( key );
@@ -330,11 +445,12 @@ ldbm_firstkey( LDBM ldbm, LDBMCursor **dbch )
        LDBM_LOCK;
 
        /* acquire a cursor for the DB */
+# if DB_VERSION_MAJOR >= 3
+        if ( ldbm->cursor( ldbm, NULL, &dbci, 0 ) )
+# elif defined( DB_VERSION_MAJOR ) && defined( DB_VERSION_MINOR ) && \
+    (DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6)
 
-#  if defined( DB_VERSION_MAJOR ) && defined( DB_VERSION_MINOR ) && \
-    DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6
-
-       if ( (*ldbm->cursor)( ldbm, NULL, &dbci )) 
+       if ( (*ldbm->cursor)( ldbm, NULL, &dbci ))
 
 #  else
        if ( (*ldbm->cursor)( ldbm, NULL, &dbci, 0 ))
@@ -362,7 +478,7 @@ ldbm_firstkey( LDBM ldbm, LDBMCursor **dbch )
                key.dsize = 0;
        }
 
-#ifdef HAVE_BERKELEY_DB2
+#if DB_VERSION_MAJOR >= 2
        }
 #endif
 
@@ -376,7 +492,7 @@ ldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *dbcp )
 {
        Datum   data;
 
-#ifdef HAVE_BERKELEY_DB2
+#if DB_VERSION_MAJOR >= 2
        ldbm_datum_init( data );
 
        ldbm_datum_free( ldbm, key );
@@ -413,6 +529,12 @@ ldbm_errno( LDBM ldbm )
        return( errno );
 }
 
+/******************************************************************
+ *                                                                *
+ *         END Berkeley section                                   *
+ *                                                                *
+ ******************************************************************/
+
 #elif defined( HAVE_GDBM )
 
 #ifdef HAVE_ST_BLKSIZE
@@ -523,6 +645,11 @@ ldbm_firstkey( LDBM ldbm, LDBMCursor **dbcp )
        d = gdbm_firstkey( ldbm );
        LDBM_UNLOCK;
 
+       if ( d.dptr != NULL ) {
+               *dbcp = (Datum *) malloc( sizeof( Datum ) );
+               **dbcp = ldbm_datum_dup( ldbm, d );
+       }
+
        return d;
 }
 
@@ -532,9 +659,17 @@ ldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *dbcp )
        Datum d;
 
        LDBM_LOCK;
-       d = gdbm_nextkey( ldbm, key );
+       d = gdbm_nextkey( ldbm, *dbcp );
        LDBM_UNLOCK;
 
+       ldbm_datum_free( ldbm, *dbcp );
+
+       if ( d.dptr != NULL ) {
+               *dbcp = ldbm_datum_dup( ldbm, d );
+       } else {
+               free( dbcp );
+       }
+
        return d;
 }
 
diff --git a/libraries/libldbm/libldbm.dsp b/libraries/libldbm/libldbm.dsp
new file mode 100644 (file)
index 0000000..5c2a9e9
--- /dev/null
@@ -0,0 +1,137 @@
+# Microsoft Developer Studio Project File - Name="libldbm" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=libldbm - Win32 Single Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "libldbm.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "libldbm.mak" CFG="libldbm - Win32 Single Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "libldbm - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "libldbm - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE "libldbm - Win32 Single Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE "libldbm - Win32 Single Release" (based on\
+ "Win32 (x86) Static Library")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+
+!IF  "$(CFG)" == "libldbm - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\libldbm"
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\..\Release\oldbm32.lib"
+
+!ELSEIF  "$(CFG)" == "libldbm - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\libldbm"
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\..\Debug\oldbm32.lib"
+
+!ELSEIF  "$(CFG)" == "libldbm - Win32 Single Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "libldbm_"
+# PROP BASE Intermediate_Dir "libldbm_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\libldbm"
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo /out:"..\Debug\oldbm32.lib"
+# ADD LIB32 /nologo /out:"..\..\SDebug\oldbm32.lib"
+
+!ELSEIF  "$(CFG)" == "libldbm - Win32 Single Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "libldbm0"
+# PROP BASE Intermediate_Dir "libldbm0"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\libldbm"
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo /out:"..\Release\oldbm32.lib"
+# ADD LIB32 /nologo /out:"..\..\SRelease\oldbm32.lib"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "libldbm - Win32 Release"
+# Name "libldbm - Win32 Debug"
+# Name "libldbm - Win32 Single Debug"
+# Name "libldbm - Win32 Single Release"
+# Begin Source File
+
+SOURCE=.\ldbm.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ldbm.h
+# End Source File
+# End Target
+# End Project
index 020e16d816380a3583e65767ff5dfd061ab92e85..c15f30be93280355b4b9cc204cfe50a3ce0aa6de 100644 (file)
@@ -1,4 +1,6 @@
 # $OpenLDAP$
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 ##
 ## Makefile for -lldif
 ##
@@ -10,3 +12,6 @@ OBJS  = line64.o fetch.o
 LDAP_INCDIR= ../../include       
 LDAP_LIBDIR= ../../libraries
 
+NT_DYN_LIB_DEFS = -DLIBLDAP_DECL=dllimport -DLIBLBER_DECL=dllimport
+CPPFLAGS = $(@PLAT@_@LIB_LINKAGE@_LIB_DEFS)
+
index 94d08614552668a42a52c28177a3eab6c7c9e6c9..4dc179bbc5771df74bff62729cfa3b215b43595b 100644 (file)
@@ -1,7 +1,7 @@
 /* line64.c - routines for dealing with the slapd line format */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
index f72025a24141eb2c00c711bea568fe2cfe8ffd59..112f5658f1b6933f42673849998bcff1ca03892b 100644 (file)
@@ -38,9 +38,10 @@ CPP=cl.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\Release"
-# PROP Intermediate_Dir "Release\libldif"
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\libldif"
 # PROP Target_Dir ""
+RSC=rc.exe
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
 # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
 BSC32=bscmake.exe
@@ -48,7 +49,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LIB32=link.exe -lib
 # ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\Release\oldif32.lib"
+# ADD LIB32 /nologo /out:"..\..\Release\oldif32.lib"
 
 !ELSEIF  "$(CFG)" == "libldif - Win32 Debug"
 
@@ -59,9 +60,10 @@ LIB32=link.exe -lib
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\Debug"
-# PROP Intermediate_Dir "Debug\libldif"
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\libldif"
 # PROP Target_Dir ""
+RSC=rc.exe
 # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
 # ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
 BSC32=bscmake.exe
@@ -69,7 +71,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LIB32=link.exe -lib
 # ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\Debug\oldif32.lib"
+# ADD LIB32 /nologo /out:"..\..\Debug\oldif32.lib"
 
 !ELSEIF  "$(CFG)" == "libldif - Win32 Single Debug"
 
@@ -80,9 +82,10 @@ LIB32=link.exe -lib
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\SDebug"
-# PROP Intermediate_Dir "SDebug\libldif"
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\libldif"
 # PROP Target_Dir ""
+RSC=rc.exe
 # ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
 # ADD CPP /nologo /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
 BSC32=bscmake.exe
@@ -90,7 +93,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LIB32=link.exe -lib
 # ADD BASE LIB32 /nologo /out:"..\Debug\oldif32.lib"
-# ADD LIB32 /nologo /out:"..\SDebug\oldif32.lib"
+# ADD LIB32 /nologo /out:"..\..\SDebug\oldif32.lib"
 
 !ELSEIF  "$(CFG)" == "libldif - Win32 Single Release"
 
@@ -101,9 +104,10 @@ LIB32=link.exe -lib
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\SRelease"
-# PROP Intermediate_Dir "SRelease\libldif"
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\libldif"
 # PROP Target_Dir ""
+RSC=rc.exe
 # ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
 # ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
 BSC32=bscmake.exe
@@ -111,7 +115,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LIB32=link.exe -lib
 # ADD BASE LIB32 /nologo /out:"..\Release\oldif32.lib"
-# ADD LIB32 /nologo /out:"..\SRelease\oldif32.lib"
+# ADD LIB32 /nologo /out:"..\..\SRelease\oldif32.lib"
 
 !ENDIF 
 
index f2a8e995ed055f28793cb7614ffa7d2497a09084..7ee83d8e6ad56588cdb850b6359dc61b4ca5d5ac 100644 (file)
@@ -1,7 +1,7 @@
 /* line64.c - routines for dealing with the slapd line format */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -135,6 +135,13 @@ ldif_parse_line(
                s++;
        }
 
+       /* check for continued line markers that should be deleted */
+       for ( p = s, d = s; *p; p++ ) {
+               if ( *p != CONTINUED_LINE_MARKER )
+                       *d++ = *p;
+       }
+       *d = '\0';
+
        /* if no value is present, error out */
        if ( *s == '\0' ) {
                ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug,
@@ -145,13 +152,6 @@ ldif_parse_line(
                goto done;
        }
 
-       /* check for continued line markers that should be deleted */
-       for ( p = s, d = s; *p; p++ ) {
-               if ( *p != CONTINUED_LINE_MARKER )
-                       *d++ = *p;
-       }
-       *d = '\0';
-
        if ( b64 ) {
                char *byte = s;
 
@@ -223,14 +223,17 @@ done:
        }
 
        if( !url && value != NULL ) {
-               value = ber_strdup( value );
-               if( value == NULL ) {
+               p = ber_memalloc( vlen + 1 );
+               if( p == NULL ) {
                        ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug,
                                "ldif_parse_line: value malloc failed\n");
                        ber_memfree( type );
                        ber_memfree( freeme );
                        return( -1 );
                }
+               memcpy( p, value, vlen );
+               p[vlen] = '\0';
+               value = p;
        }
 
        ber_memfree( freeme );
@@ -349,6 +352,11 @@ ldif_sput(
        }
 #endif
 
+       if( vlen == 0 ) {
+               *(*out)++ = '\n';
+               return;
+       }
+
        switch( type ) {
        case LDIF_PUT_NOVALUE:
                *(*out)++ = '\n';
@@ -395,18 +403,18 @@ ldif_sput(
        *(*out)++ = ' ';
        len++;
 
-       if( vlen == 0 ) {
-               *(*out)++ = '\n';
-               return;
-       }
-
        stop = (const unsigned char *) (val + vlen);
 
        if ( type == LDIF_PUT_VALUE
                && isgraph( val[0] ) && val[0] != ':' && val[0] != '<'
                && isgraph( val[vlen-1] )
+#ifndef LDAP_BINARY_DEBUG
+               && strstr( name, ";binary" ) == NULL
+#endif
+#ifndef LDAP_PASSWD_DEBUG
                && strcasecmp( name, "userPassword" ) != 0      /* encode userPassword */
                && strcasecmp( name, "2.5.4.35" ) != 0          /* encode userPassword */
+#endif
        ) {
                int b64 = 0;
 
index 31e3aa9d8d498bc81e47bd1f792181fcd98a8a6e..87192d29705c7c87809ef8827cf5e7abaa2ad7b6 100644 (file)
@@ -1,15 +1,39 @@
 # $OpenLDAP$
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 ##
-## Makefile for -lutil
+## Makefile for -llutil
 ##
 
 LIBRARY        = liblutil.a
-SRCS   = base64.c debug.c detach.c \
-       md5.c passwd.c sha1.c getpass.c lockf.c utils.c sockpair.c
-OBJS   = base64.o debug.o detach.o \
+
+NT_SRCS = ntservice.c
+NT_OBJS = ntservice.o slapdmsg.res
+
+UNIX_SRCS = detach.c
+UNIX_OBJS = detach.o
+
+SRCS   = base64.c debug.c entropy.c \
+       md5.c passwd.c sha1.c getpass.c lockf.c utils.c sockpair.c \
+       @LIBSRCS@ $(@PLAT@_SRCS)
+
+OBJS   = base64.o debug.o entropy.o \
        md5.o passwd.o sha1.o getpass.o lockf.o utils.o sockpair.o \
-       @LIBOBJS@
+       @LIBOBJS@ $(@PLAT@_OBJS)
 
 LDAP_INCDIR= ../../include       
 LDAP_LIBDIR= ../../libraries
 
+NT_DYN_LIB_DEFS = -DLIBLDAP_DECL=dllimport
+CPPFLAGS = $(@PLAT@_@LIB_LINKAGE@_LIB_DEFS)
+
+# These rules are for a Mingw32 build, specifically.
+# It's ok for them to be here because the clean rule is harmless, and
+# slapdmsg.res won't get built unless it's declared in OBJS.
+
+slapdmsg.res: slapdmsg.rc slapdmsg.bin
+       windres $< -O coff -o $@
+
+clean-local:
+       $(RM) *.res
+
diff --git a/libraries/liblutil/authpasswd.c b/libraries/liblutil/authpasswd.c
new file mode 100644 (file)
index 0000000..1fc4d74
--- /dev/null
@@ -0,0 +1,929 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * lutil_authpassword(authpasswd, cred)
+ *
+ * Returns true if user supplied credentials (cred) matches
+ * the stored authentication password (authpasswd). 
+ *
+ * Due to the use of the crypt(3) function 
+ * this routine is NOT thread-safe.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/stdlib.h>
+#include <ac/string.h>
+
+#ifdef SLAPD_KPASSWD
+#      include <ac/krb.h>
+#      include <ac/krb5.h>
+#endif
+
+#include <ac/param.h>
+
+#include <ac/unistd.h>
+#include <ac/crypt.h>
+
+#ifdef HAVE_SHADOW_H
+#      include <shadow.h>
+#endif
+#ifdef HAVE_PWD_H
+#      include <pwd.h>
+#endif
+
+#include <lber.h>
+
+#include "lutil_md5.h"
+#include "lutil_sha1.h"
+#include "lutil.h"
+
+static const unsigned char crypt64[] =
+       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890./";
+
+struct pw_scheme;
+
+typedef int (*PASSWD_CHK_FUNC)(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd,
+       const struct berval *salt,
+       const struct berval *cred );
+
+typedef int (*PASSWD_HASH_FUNC) (
+       const struct pw_scheme *scheme,
+       const struct berval *cred,
+       const struct berval *salt,
+       struct berval **passwd_out,
+       struct berval **salt_out );
+
+/* password check routines */
+static int chk_md5(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd,
+       const struct berval *salt,
+       const struct berval *cred );
+
+static int chk_sha1(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd,
+       const struct berval *salt,
+       const struct berval *cred );
+
+static int chk_crypt(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd,
+       const struct berval *salt,
+       const struct berval *cred );
+
+static int chk_ext(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd,
+       const struct berval *salt,
+       const struct berval *cred );
+
+static int chk_ext_kerberos(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd,
+       const struct berval *cred );
+
+static int chk_ext_unix(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd,
+       const struct berval *cred );
+
+
+/* password hash routines */
+static int *hash_sha1(
+       const struct pw_scheme *scheme,
+       const struct berval *cred,
+       const struct berval *salt,
+       struct berval **passwd_out,
+       struct berval **salt_out );
+
+static int *hash_md5(
+       const struct pw_scheme *scheme,
+       const struct berval *cred,
+       const struct berval *salt,
+       struct berval **passwd_out,
+       struct berval **salt_out );
+
+static int *hash_crypt(
+       const struct pw_scheme *scheme,
+       const struct berval *cred,
+       const struct berval *salt,
+       struct berval **passwd_out,
+       struct berval **salt_out );
+
+
+struct pw_scheme {
+       struct berval name;
+       PASSWD_CHK_FUNC chk_fn;
+       PASSWD_HASH_FUNC hash_fn;
+       int saltbytes;
+};
+
+static const struct pw_scheme pw_schemes[] =
+{
+       { {sizeof("SHA1")-1, "SHA1"},   chk_sha1, 0 /* hash_sha1 */, 4 },
+       { {sizeof("MD5")-1, "MD5"},             chk_md5, 0 /* hash_md5 */, 4 },
+
+#ifdef SLAPD_CRYPT
+       { {sizeof("CRYPT")-1, "CRYPT"}, chk_crypt, hash_crypt, 2 },
+#endif
+
+#ifdef EXT_PASSWD
+       { {sizeof("EXTERNAL")-1, "EXTERNAL"}, chk_ext, NULL, 0 },
+#endif
+
+       { {0, NULL}, NULL, NULL, 0 }
+};
+
+#ifdef EXT_PASSWD
+struct ext_scheme {
+       struct berval name;
+       EXT_CHK_FUNC chk_fn;
+};
+
+static const struct ext_scheme ext_schemes[] =
+{
+       { {0, NULL}, NULL, NULL, 0 }
+};
+#endif
+
+static const struct pw_scheme *get_scheme(
+       const char *scheme )
+{
+       int i;
+
+       if( scheme == NULL || *scheme == '\0' ) return NULL;
+
+       for( i=0; pw_schemes[i].name.bv_val; i++) {
+               if( pw_schemes[i].name.bv_len == 0 ) continue;
+
+               if( strncasecmp( scheme,
+                       pw_schemes[i].name.bv_val,
+                       pw_schemes[i].name.bv_len) == 0 )
+               {
+                       return &pw_schemes[i];
+               }
+       }
+
+       return NULL;
+}
+
+int lutil_authpasswd_scheme(
+       const char *scheme )
+{
+       return get_scheme( scheme ) != NULL;
+}
+
+
+static int is_allowed_scheme( 
+       const char* scheme,
+       const char** schemes )
+{
+       int i;
+
+       if( scheme == NULL || *scheme == '\0' ) return 1;
+
+       for( i=0; schemes[i] != NULL; i++ ) {
+               if( strcasecmp( scheme, schemes[i] ) == 0 ) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+static int parse_authpasswd(
+       char **scheme,
+       struct berval *salt,
+       struct berval *passwd )
+{
+       *scheme = NULL;
+       return -1;
+}
+
+/*
+ * Return 0 if creds are good.
+ */
+int
+lutil_authpasswd(
+       const struct berval *value,     /* stored authpasswd */
+       const struct berval *cred,              /* user cred */
+       const char **schemes )
+{
+       char *scheme;
+       struct berval salt, passwd;
+       const struct pw_scheme *pws;
+       int rc = -1;
+
+       if (cred == NULL || cred->bv_len == 0 ||
+               value == NULL || value->bv_len == 0 )
+       {
+               return -1;
+       }
+
+       rc = parse_authpasswd( &scheme, &salt, &passwd );
+
+       if( rc != 0 ) return -1;
+
+       if( !is_allowed_scheme( scheme, schemes ) ) {
+               goto done;
+       }
+
+       pws = get_scheme( scheme );
+
+       if( pws == NULL || !pws->chk_fn ) {
+               goto done;
+       };
+
+       rc = (pws->chk_fn)( pws, &salt, &passwd, cred );
+
+done:
+       if( scheme != NULL ) {
+               ber_memfree( scheme );
+               ber_memfree( salt.bv_val );
+               ber_memfree( passwd.bv_val );
+       }
+
+       return rc ? -1 : 0;
+}
+
+struct berval * lutil_authpasswd_generate( ber_len_t len )
+{
+       struct berval *pw;
+
+       if( len < 1 ) return NULL;
+
+       pw = ber_memalloc( sizeof( struct berval ) );
+       if( pw == NULL ) return NULL;
+
+       pw->bv_len = len;
+       pw->bv_val = ber_memalloc( len + 1 );
+
+       if( pw->bv_val == NULL ) {
+               ber_memfree( pw );
+               return NULL;
+       }
+
+       if( lutil_entropy( pw->bv_val, pw->bv_len) < 0 ) {
+               ber_bvfree( pw );
+               return NULL; 
+       }
+
+       for( len = 0; len < pw->bv_len; len++ ) {
+               pw->bv_val[len] = crypt64[
+                       pw->bv_val[len] % (sizeof(crypt64)-1) ];
+       }
+
+       pw->bv_val[len] = '\0';
+       
+       return pw;
+}
+
+int lutil_authpasswd_hash(
+       const struct berval * cred,
+       struct berval ** passwd_out,
+       struct berval ** salt_out,
+       const char * method )
+{
+       const struct pw_scheme *sc;
+       int rc;
+
+       if( passwd_out == NULL ) return -1;
+       
+       sc = get_scheme( method );
+       if( sc == NULL || !sc->hash_fn ) return -1;
+
+       if( sc->saltbytes && salt_out != NULL ) {
+               struct berval salt;
+               salt.bv_val = ber_memalloc( sc->saltbytes );
+
+               if( salt.bv_val == NULL ) {
+                       return -1;
+               }
+               salt.bv_len = sc->saltbytes;
+
+               if( lutil_entropy( salt.bv_val, salt.bv_len ) < 0 ) {
+                       ber_memfree( salt.bv_val );
+                       return -1; 
+               }
+
+               rc = (sc->hash_fn)( sc, cred, &salt, passwd_out, NULL );
+               ber_memfree( salt.bv_val );
+
+       } else if ( sc->saltbytes ) {
+               /* wants salt, disallow */
+               return -1;
+
+       } else {
+               rc = (sc->hash_fn)( sc, cred, NULL, passwd_out, salt_out );
+       }
+
+       return rc;
+}
+
+static struct berval * base64(
+       const struct berval *value )
+{
+       int rc;
+       struct berval *b64; 
+
+       assert( value != NULL );
+
+       if( value == NULL || value->bv_len == 0 ) return NULL;
+
+       b64 = ber_memalloc( sizeof(struct berval) );
+       if( b64 == NULL ) return NULL;
+
+       b64->bv_len = LUTIL_BASE64_ENCODE_LEN( value->bv_len );
+       b64->bv_val = ber_memalloc( b64->bv_len + 1 );
+
+       if( b64->bv_val == NULL ) {
+               ber_memfree( b64 );
+               return NULL;
+       }
+
+       rc = lutil_b64_ntop(
+               value->bv_val, value->bv_len,
+               b64->bv_val, b64->bv_len );
+
+       b64->bv_val[b64->bv_len] = '\0';
+
+       if( rc < 0 ) {
+               ber_bvfree( b64 );
+               return NULL;
+       }
+
+       return b64;
+}
+
+/* PASSWORD CHECK ROUTINES */
+
+static int chk_sha1(
+       const struct pw_scheme *sc,
+       const struct berval * passwd,
+       const struct berval * salt,
+       const struct berval * cred )
+{
+       lutil_SHA1_CTX SHA1context;
+       unsigned char SHA1digest[LUTIL_SHA1_BYTES];
+       int rc;
+       unsigned char *orig_pass = NULL;
+       unsigned char *orig_salt = NULL;
+       int saltlen;
+       if( passwd == NULL || passwd->bv_len == 0 ) {
+               return 1;
+       }
+
+       /* decode base64 password */
+       orig_pass = (unsigned char *) ber_memalloc( (size_t) (
+               LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) );
+
+       if( orig_pass == NULL ) {
+               rc = -1;
+               goto done;
+       }
+
+       rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len);
+
+       if( rc < 0 ) {
+               goto done;
+       }
+
+       /* decode base64 salt */
+       if( salt != NULL && salt->bv_len > 0 ) {
+               orig_salt = (unsigned char *) ber_memalloc( (size_t) (
+                       LUTIL_BASE64_DECODE_LEN(salt->bv_len) + 1) );
+
+               if( orig_salt == NULL ) {
+                       rc = -1;
+                       goto done;
+               }
+
+               saltlen = lutil_b64_pton(passwd->bv_val, orig_salt, passwd->bv_len);
+
+               if( saltlen < 0 ) {
+                       goto done;
+               }
+       }
+
+       /* hash credentials with salt */
+       lutil_SHA1Init(&SHA1context);
+       lutil_SHA1Update(&SHA1context,
+               (const unsigned char *) cred->bv_val, cred->bv_len);
+       if( orig_salt != NULL ) {
+               lutil_SHA1Update(&SHA1context,
+                       orig_salt, saltlen );
+       }
+       lutil_SHA1Final(SHA1digest, &SHA1context);
+       /* compare */
+       rc = memcmp((char *)orig_pass, (char *)SHA1digest, sizeof(SHA1digest));
+
+done:
+       ber_memfree(orig_pass);
+       ber_memfree(orig_salt);
+       return rc;
+}
+
+static int chk_md5(
+       const struct pw_scheme *sc,
+       const struct berval * passwd,
+       const struct berval * salt,
+       const struct berval * cred )
+{
+       lutil_MD5_CTX MD5context;
+       unsigned char MD5digest[LUTIL_MD5_BYTES];
+       int rc;
+       unsigned char *orig_pass = NULL;
+       unsigned char *orig_salt = NULL;
+       int saltlen;
+       if( passwd == NULL || passwd->bv_len == 0 ) {
+               return 1;
+       }
+
+       /* decode base64 password */
+       orig_pass = (unsigned char *) ber_memalloc( (size_t) (
+               LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) );
+
+       if( orig_pass == NULL ) {
+               rc = -1;
+               goto done;
+       }
+
+       rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len);
+
+       if( rc < 0 ) {
+               goto done;
+       }
+
+       /* decode base64 salt */
+       if( salt != NULL && salt->bv_len > 0 ) {
+               orig_salt = (unsigned char *) ber_memalloc( (size_t) (
+                       LUTIL_BASE64_DECODE_LEN(salt->bv_len) + 1) );
+
+               if( orig_salt == NULL ) {
+                       rc = -1;
+                       goto done;
+               }
+
+               saltlen = lutil_b64_pton(passwd->bv_val, orig_salt, passwd->bv_len);
+
+               if( saltlen < 0 ) {
+                       goto done;
+               }
+       }
+
+       /* hash credentials with salt */
+       lutil_MD5Init(&MD5context);
+       lutil_MD5Update(&MD5context,
+               (const unsigned char *) cred->bv_val, cred->bv_len);
+       if( orig_salt != NULL ) {
+               lutil_MD5Update(&MD5context,
+                       orig_salt, saltlen );
+       }
+       lutil_MD5Final(MD5digest, &MD5context);
+       /* compare */
+       rc = memcmp((char *)orig_pass, (char *)MD5digest, sizeof(MD5digest));
+
+done:
+       ber_memfree(orig_pass);
+       ber_memfree(orig_salt);
+       return rc;
+}
+
+#ifdef SLAPD_KPASSWD
+static int chk_kerberos(
+       const struct pw_scheme *sc,
+       const struct berval * passwd,
+       const struct berval * cred,
+       const struct berval * salt )
+{
+       int i;
+       int rtn;
+
+       for( i=0; i<cred->bv_len; i++) {
+               if(cred->bv_val[i] == '\0') {
+                       return 1;       /* NUL character in password */
+               }
+       }
+
+       if( cred->bv_val[i] != '\0' ) {
+               return 1;       /* cred must behave like a string */
+       }
+
+       for( i=0; i<passwd->bv_len; i++) {
+               if(passwd->bv_val[i] == '\0') {
+                       return 1;       /* NUL character in password */
+               }
+       }
+
+       if( passwd->bv_val[i] != '\0' ) {
+               return 1;       /* passwd must behave like a string */
+       }
+
+       rtn = 1;
+
+#ifdef HAVE_KRB5 /* HAVE_HEIMDAL_KRB5 */
+       {
+/* Portions:
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska H\xf6gskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+               krb5_context context;
+               krb5_error_code ret;
+               krb5_creds creds;
+               krb5_get_init_creds_opt get_options;
+               krb5_verify_init_creds_opt verify_options;
+               krb5_principal client, server;
+#ifdef notdef
+               krb5_preauthtype pre_auth_types[] = {KRB5_PADATA_ENC_TIMESTAMP};
+#endif
+
+               ret = krb5_init_context( &context );
+               if (ret) {
+                       return 1;
+               }
+
+#ifdef notdef
+               krb5_get_init_creds_opt_set_preauth_list(&get_options,
+                       pre_auth_types, 1);
+#endif
+
+               krb5_get_init_creds_opt_init( &get_options );
+
+               krb5_verify_init_creds_opt_init( &verify_options );
+       
+               ret = krb5_parse_name( context, passwd->bv_val, &client );
+
+               if (ret) {
+                       krb5_free_context( context );
+                       return 1;
+               }
+
+               ret = krb5_get_init_creds_password( context,
+                       &creds, client, cred->bv_val, NULL,
+                       NULL, 0, NULL, &get_options );
+
+               if (ret) {
+                       krb5_free_principal( context, client );
+                       krb5_free_context( context );
+                       return 1;
+               }
+
+               {
+                       char host[MAXHOSTNAMELEN];
+
+                       if( gethostname( host, MAXHOSTNAMELEN ) != 0 ) {
+                               krb5_free_principal( context, client );
+                               krb5_free_context( context );
+                               return 1;
+                       }
+
+                       ret = krb5_sname_to_principal( context,
+                               host, "ldap", KRB5_NT_SRV_HST, &server );
+               }
+
+               if (ret) {
+                       krb5_free_principal( context, client );
+                       krb5_free_context( context );
+                       return 1;
+               }
+
+               ret = krb5_verify_init_creds( context,
+                       &creds, server, NULL, NULL, &verify_options );
+
+               krb5_free_principal( context, client );
+               krb5_free_principal( context, server );
+               krb5_free_creds_contents( context, &creds );
+               krb5_free_context( context );
+
+               rtn = !!ret;
+       }
+#elif  defined(HAVE_KRB4)
+       {
+               /* Borrowed from Heimdal kpopper */
+/* Portions:
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+               int status;
+               char lrealm[REALM_SZ];
+               char tkt[MAXHOSTNAMELEN];
+
+               status = krb_get_lrealm(lrealm,1);
+               if (status == KFAILURE) {
+                       return 1;
+               }
+
+               snprintf(tkt, sizeof(tkt), "%s_slapd.%u",
+                       TKT_ROOT, (unsigned)getpid());
+               krb_set_tkt_string (tkt);
+
+               status = krb_verify_user( passwd->bv_val, "", lrealm,
+                       cred->bv_val, 1, "ldap");
+
+               dest_tkt(); /* no point in keeping the tickets */
+
+               return status == KFAILURE;
+       }
+#endif
+
+       return rtn;
+}
+#endif /* SLAPD_KPASSWD */
+
+#ifdef SLAPD_CRYPT
+static int chk_crypt(
+       const struct pw_scheme *sc,
+       const struct berval * passwd,
+       const struct berval * cred )
+{
+       char *cr;
+       int i;
+
+       for( i=0; i<cred->bv_len; i++) {
+               if(cred->bv_val[i] == '\0') {
+                       return 1;       /* NUL character in password */
+               }
+       }
+
+       if( cred->bv_val[i] != '\0' ) {
+               return 1;       /* cred must behave like a string */
+       }
+
+       if( passwd->bv_len < 2 ) {
+               return 1;       /* passwd must be at least two characters long */
+       }
+
+       for( i=0; i<passwd->bv_len; i++) {
+               if(passwd->bv_val[i] == '\0') {
+                       return 1;       /* NUL character in password */
+               }
+       }
+
+       if( passwd->bv_val[i] != '\0' ) {
+               return 1;       /* passwd must behave like a string */
+       }
+
+       cr = crypt( cred->bv_val, passwd->bv_val );
+
+       if( cr == NULL || cr[0] == '\0' ) {
+               /* salt must have been invalid */
+               return 1;
+       }
+
+       return strcmp( passwd->bv_val, cr );
+}
+
+# if defined( HAVE_GETSPNAM ) \
+  || ( defined( HAVE_GETPWNAM ) && defined( HAVE_PW_PASSWD ) )
+static int chk_unix(
+       const struct pw_scheme *sc,
+       const struct berval * passwd,
+       const struct berval * cred )
+{
+       int i;
+       char *pw,*cr;
+
+       for( i=0; i<cred->bv_len; i++) {
+               if(cred->bv_val[i] == '\0') {
+                       return 1;       /* NUL character in password */
+               }
+       }
+       if( cred->bv_val[i] != '\0' ) {
+               return 1;       /* cred must behave like a string */
+       }
+
+       for( i=0; i<passwd->bv_len; i++) {
+               if(passwd->bv_val[i] == '\0') {
+                       return 1;       /* NUL character in password */
+               }
+       }
+
+       if( passwd->bv_val[i] != '\0' ) {
+               return 1;       /* passwd must behave like a string */
+       }
+
+#  ifdef HAVE_GETSPNAM
+       {
+               struct spwd *spwd = getspnam(passwd->bv_val);
+
+               if(spwd == NULL) {
+                       return 1;       /* not found */
+               }
+
+               pw = spwd->sp_pwdp;
+       }
+
+#  else
+       {
+               struct passwd *pwd = getpwnam(passwd->bv_val);
+
+               if(pwd == NULL) {
+                       return 1;       /* not found */
+               }
+
+               pw = pwd->pw_passwd;
+       }
+#  endif
+
+       if( pw == NULL || pw[0] == '\0' || pw[1] == '\0' ) {
+               /* password must must be at least two characters long */
+               return 1;
+       }
+
+       cr = crypt(cred->bv_val, pw);
+
+       if( cr == NULL || cr[0] == '\0' ) {
+               /* salt must have been invalid */
+               return 1;
+       }
+
+       return strcmp(pw, cr);
+
+}
+# endif
+#endif
+
+/* PASSWORD GENERATION ROUTINES */
+
+#ifdef SLAPD_GENERATE
+
+static struct berval *hash_ssha1(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd )
+{
+       lutil_SHA1_CTX  SHA1context;
+       unsigned char   SHA1digest[LUTIL_SHA1_BYTES];
+       unsigned char   saltdata[4];
+       struct berval digest;
+       struct berval salt;
+
+       digest.bv_val = SHA1digest;
+       digest.bv_len = sizeof(SHA1digest);
+       salt.bv_val = saltdata;
+       salt.bv_len = sizeof(saltdata);
+
+       if( lutil_entropy( salt.bv_val, salt.bv_len) < 0 ) {
+               return NULL; 
+       }
+
+       lutil_SHA1Init( &SHA1context );
+       lutil_SHA1Update( &SHA1context,
+               (const unsigned char *)passwd->bv_val, passwd->bv_len );
+       lutil_SHA1Update( &SHA1context,
+               (const unsigned char *)salt.bv_val, salt.bv_len );
+       lutil_SHA1Final( SHA1digest, &SHA1context );
+
+       return pw_string64( scheme, &digest, &salt);
+}
+
+static struct berval *hash_sha1(
+       const struct pw_scheme *scheme,
+       const struct berval  *passwd )
+{
+       lutil_SHA1_CTX  SHA1context;
+       unsigned char   SHA1digest[LUTIL_SHA1_BYTES];
+       struct berval digest;
+       digest.bv_val = SHA1digest;
+       digest.bv_len = sizeof(SHA1digest);
+     
+       lutil_SHA1Init( &SHA1context );
+       lutil_SHA1Update( &SHA1context,
+               (const unsigned char *)passwd->bv_val, passwd->bv_len );
+       lutil_SHA1Final( SHA1digest, &SHA1context );
+            
+       return pw_string64( scheme, &digest, NULL);
+}
+
+static struct berval *hash_smd5(
+       const struct pw_scheme *scheme,
+       const struct berval  *passwd )
+{
+       lutil_MD5_CTX   MD5context;
+       unsigned char   MD5digest[LUTIL_MD5_BYTES];
+       unsigned char   saltdata[4];
+       struct berval digest;
+       struct berval salt;
+
+       digest.bv_val = MD5digest;
+       digest.bv_len = sizeof(MD5digest);
+       salt.bv_val = saltdata;
+       salt.bv_len = sizeof(saltdata);
+
+       if( lutil_entropy( salt.bv_val, salt.bv_len) < 0 ) {
+               return NULL; 
+       }
+
+       lutil_MD5Init( &MD5context );
+       lutil_MD5Update( &MD5context,
+               (const unsigned char *) passwd->bv_val, passwd->bv_len );
+       lutil_MD5Update( &MD5context,
+               (const unsigned char *) salt.bv_val, salt.bv_len );
+       lutil_MD5Final( MD5digest, &MD5context );
+
+       return pw_string64( scheme, &digest, &salt );
+}
+
+static struct berval *hash_md5(
+       const struct pw_scheme *scheme,
+       const struct berval  *passwd )
+{
+       lutil_MD5_CTX   MD5context;
+       unsigned char   MD5digest[LUTIL_MD5_BYTES];
+
+       struct berval digest;
+
+       digest.bv_val = MD5digest;
+       digest.bv_len = sizeof(MD5digest);
+
+       lutil_MD5Init( &MD5context );
+       lutil_MD5Update( &MD5context,
+               (const unsigned char *) passwd->bv_val, passwd->bv_len );
+       lutil_MD5Final( MD5digest, &MD5context );
+
+       return pw_string64( scheme, &digest, NULL );
+;
+}
+
+#ifdef SLAPD_CRYPT
+static struct berval *hash_crypt(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd )
+{
+       struct berval hash;
+       unsigned char salt[3];
+       int i;
+
+       for( i=0; i<passwd->bv_len; i++) {
+               if(passwd->bv_val[i] == '\0') {
+                       return NULL;    /* NUL character in password */
+               }
+       }
+
+       if( passwd->bv_val[i] != '\0' ) {
+               return NULL;    /* passwd must behave like a string */
+       }
+
+       if( lutil_entropy( salt, sizeof(salt)) < 0 ) {
+               return NULL; 
+       }
+
+       salt[0] = crypt64[ salt[0] % (sizeof(crypt64)-1) ];
+       salt[1] = crypt64[ salt[1] % (sizeof(crypt64)-1) ];
+       salt[2] = '\0';
+
+       hash.bv_val = crypt( passwd->bv_val, salt );
+
+       if( hash.bv_val == NULL ) return NULL;
+
+       hash.bv_len = strlen( hash.bv_val );
+
+       if( hash.bv_len == 0 ) {
+               return NULL;
+       }
+
+       return pw_string( scheme, &hash );
+}
+#endif
+#endif
\ No newline at end of file
index d4e107b621eed0ce4d1be734de534e1a2396413d..1ebd409afb48b9fe56bdc5d344997f46b8f7695e 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
index a6fc5064d2d9d7861461bc5753b60e9658e56b02..7cf7f64dfea221b0b505152fd38617ea9245b793 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
 
 #include "ldap_log.h"
 #include "ldap_defaults.h"
+#include "lber.h"
 
 static FILE *log_file;
 
 int lutil_debug_file( FILE *file )
 {
        log_file = file;
+       ber_set_option( NULL, LBER_OPT_LOG_PRINT_FILE, file );
 
        return 0;
 }
@@ -57,9 +59,10 @@ void (lutil_debug)( int level, int debug, const char *fmt, ... )
 
                if ( log_file == NULL )
                        return;
+
+           ber_set_option( NULL, LBER_OPT_LOG_PRINT_FILE, log_file );
        }
 #endif
-
        va_start( vl, fmt );
 
 #ifdef HAVE_VSNPRINTF
index c4f2aa4478eb6db60d4ec83cb3c0b0b6fa85aa41..022c2dbd787e825e58a2de47ba124e095ec0233e 100644 (file)
@@ -72,21 +72,37 @@ lutil_detach( int debug, int do_close )
                        break;
                }
 
-               if ( do_close )
-                       for ( i = 3; i < nbits; i++ )
-                               close( i );
-
-               (void) chdir( "/" );
-
                if ( (sd = open( "/dev/null", O_RDWR )) == -1 ) {
-                       perror( "/dev/null" );
-                       exit( EXIT_FAILURE );
+                       perror("/dev/null");
                }
-               for ( i = 0;  i < 3;  i++ )
-                       if ( sd != i && isatty( i ) )
-                               (void) dup2( sd, i );
-               if ( sd > 2 )
-                       close( sd );
+
+               /* close stdin, stdout, stderr */
+               close( STDIN_FILENO );
+               close( STDOUT_FILENO );
+               close( STDERR_FILENO );
+
+               /* redirect stdin, stdout, stderr to /dev/null */
+               dup2( sd, STDIN_FILENO );
+               dup2( sd, STDOUT_FILENO );
+               dup2( sd, STDERR_FILENO );
+
+               close( sd );
+
+               if ( do_close ) {
+                       /* close everything else */
+                       for ( i = 0; i < nbits; i++ ) {
+                               if( i != STDIN_FILENO &&
+                                       i != STDOUT_FILENO && 
+                                       i != STDERR_FILENO )
+                               {
+                                       close( i );
+                               }
+                       }
+               }
+
+#ifdef CHDIR_TO_ROOT
+               (void) chdir( "/" );
+#endif
 
 #ifdef HAVE_SETSID
                (void) setsid();
diff --git a/libraries/liblutil/entropy.c b/libraries/liblutil/entropy.c
new file mode 100644 (file)
index 0000000..1759f7d
--- /dev/null
@@ -0,0 +1,151 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <ac/string.h>
+#include <ac/time.h>
+
+#ifdef HAVE_WINCRYPT_H
+#include <wincrypt.h>
+#endif
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#include <fcntl.h>
+
+#include <lutil.h>
+#include <lutil_md5.h>
+
+/*
+ * lutil_entropy() provides nbytes of entropy in buf.
+ * Quality offerred is suitable for one-time uses, such as "once" keys.
+ * Values may not be suitable for multi-time uses.
+ *
+ * Note:  Callers are encouraged to provide additional bytes of
+ * of entropy in the buf argument.  This information is used in
+ * fallback mode to improve the quality of bytes returned.
+ *
+ * This routinue should be extended to support additional sources
+ * of entropy.
+ */
+int lutil_entropy( char *buf, ber_len_t nbytes )
+{
+       if( nbytes == 0 ) return 0;
+
+#ifdef URANDOM_DEVICE
+       /* Linux and *BSD offer a urandom device */
+       {
+               int rc, fd;
+
+               fd = open( URANDOM_DEVICE, O_RDONLY );
+
+               if( fd < 0 ) return -1;
+
+               rc = read( fd, buf, nbytes );
+               close(fd);
+
+               /* should return nbytes */
+               if( rc < nbytes ) return -1;
+
+               return 0;
+       }
+#elif PROV_RSA_FULL
+       {
+               /* Not used since _WIN32_WINNT not set... */
+               HCRYPTPROV hProv = 0;
+
+               /* Get handle to user default provider */
+               if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) {
+                  return -1;
+               }
+
+               /* Generate random initialization vector */
+               if(!CryptGenRandom(hProv, (DWORD) nbytes, (BYTE *) buf)) {
+                  return -1;
+               }
+
+               /* Release provider handle */
+               if(hProv != 0) CryptReleaseContext(hProv, 0);
+
+               return 0;
+       }
+#else
+       {
+               /* based upon Phil Karn's "practical randomness" idea
+                * but implementation 100% OpenLDAP.  So don't blame Phil.
+                *
+                * Worse case is that this is a MD5 hash of a counter, if
+                * MD5 is a strong cryptographic hash, this should be fairly
+                * resistant to attack
+                */
+
+               /*
+                * the caller may need to provide external synchronization OR
+                * provide entropy (in buf) to ensure quality results as
+                * access to this counter may not be atomic.
+                */
+               static int counter = 0;
+               ber_len_t n;
+
+               struct rdata_s {
+                       int counter;
+
+                       char *buf;
+                       struct rdata_s *stack;
+
+                       pid_t   pid;
+
+#ifdef HAVE_GETTIMEOFDAY
+                       struct timeval tv;
+#else
+                       time_t  time;
+#endif
+
+                       unsigned long   junk;   /* purposely not initialized */
+               } rdata;
+
+               /* make sure rdata differs for each process */
+               rdata.pid = getpid();
+
+               /* make sure rdata differs for each program */
+               rdata.buf = buf;
+               rdata.stack = &rdata;
+
+               for( n = 0; n < nbytes; n += 16 ) {
+                       struct lutil_MD5Context ctx;
+                       char digest[16];
+
+                       /* poor resolution */
+#ifdef HAVE_GETTIMEOFDAY
+                       (void) gettimeofday( &rdata.tv, NULL );
+#else
+                       (void) time( &rdata.time );
+#endif
+
+                       /* make sure rdata differs */
+                       rdata.counter = ++counter;
+                       rdata.pid++;
+                       rdata.junk++;
+
+                       lutil_MD5Init( &ctx );
+                       lutil_MD5Update( &ctx, (char *) &rdata, sizeof( rdata ) );
+
+                       /* allow caller to provided additional entropy */
+                       lutil_MD5Update( &ctx, (char *) &buf, nbytes );
+
+                       lutil_MD5Final( digest, &ctx );
+
+                       memcpy( &buf[n], digest,
+                               nbytes - n >= 16 ? 16 : nbytes - n );
+               }
+
+               return 0;
+       }
+#endif
+       return -1;
+}
index 3b0ca476a5b59a55099101733c5eb95d4a854d4a..c85305a8eaac4451b43809a19af6afe99ef778f0 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
@@ -59,6 +59,7 @@ int getopt (int argc, char * const argv [], const char * opts)
 printf("DF_TRACE_DEBUG:        int getopt () in getopt.c\n");
 #endif
        if (sp == 1)
+       {
                if (optind >= argc || argv[optind][0] != sw
                || argv[optind][1] == eos)
                        return EOF;
@@ -67,6 +68,7 @@ printf("DF_TRACE_DEBUG:       int getopt () in getopt.c\n");
                        optind++;
                        return EOF;
                }
+       }
        c = argv[optind][sp];
        optopt = (int) c;
        if (c == arg || (cp = strchr(opts,c)) == NULL)
index ce8f6de8c800a94b7dc021b048ffb722543afe96..7da409108e4eef6b501c39321020867c5bae6dce 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
@@ -17,8 +17,6 @@
 
 #include "portable.h"
 
-#ifndef HAVE_GETPASS
-
 #include <stdio.h>
 
 #include <ac/stdlib.h>
@@ -30,6 +28,8 @@
 #include <ac/time.h>
 #include <ac/unistd.h>
 
+#ifdef NEED_GETPASSPHRASE
+
 #ifdef HAVE_FCNTL_H
 #include <fcntl.h>
 #endif
 #include "ldap_defaults.h"
 
 char *
-getpass( const char *prompt )
+lutil_getpass( const char *prompt )
 {
 #if !defined(HAVE_POSIX_TERMIOS) && !defined(HAVE_SGTTY_H)
        static char buf[256];
        int i, c;
 
+       if( prompt == NULL ) prompt = "Password: ";
+
 #ifdef DEBUG
        if (debug & D_TRACE)
                printf("->getpass(%s)\n", prompt);
 #endif
+
        printf("%s", prompt);
        i = 0;
        while ( (c = getch()) != EOF && c != '\n' && c != '\r' )
@@ -73,6 +76,8 @@ getpass( const char *prompt )
        FILE *fi;
        RETSIGTYPE (*sig)( int sig );
 
+       if( prompt == NULL ) prompt = "Password: ";
+
 #ifdef DEBUG
        if (debug & D_TRACE)
                printf("->getpass(%s)\n", prompt);
@@ -155,4 +160,4 @@ getpass( const char *prompt )
 #endif
 }
 
-#endif /* !HAVE_GETPASS */
+#endif /* !NEED_GETPASSPHRASE */
index 54800a3eca9624342415670af3cfa653dab405a3..121921e98593c07cd499d732aa478c2e6883277c 100644 (file)
@@ -39,9 +39,10 @@ CPP=cl.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\Release"
-# PROP Intermediate_Dir "Release\liblutil"
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\liblutil"
 # PROP Target_Dir ""
+RSC=rc.exe
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
 # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
 BSC32=bscmake.exe
@@ -49,7 +50,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LIB32=link.exe -lib
 # ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\Release\olutil32.lib"
+# ADD LIB32 /nologo /out:"..\..\Release\olutil32.lib"
 
 !ELSEIF  "$(CFG)" == "liblutil - Win32 Debug"
 
@@ -60,9 +61,10 @@ LIB32=link.exe -lib
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\Debug"
-# PROP Intermediate_Dir "Debug\liblutil"
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\liblutil"
 # PROP Target_Dir ""
+RSC=rc.exe
 # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
 # ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
 BSC32=bscmake.exe
@@ -70,7 +72,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LIB32=link.exe -lib
 # ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\Debug\olutil32.lib"
+# ADD LIB32 /nologo /out:"..\..\Debug\olutil32.lib"
 
 !ELSEIF  "$(CFG)" == "liblutil - Win32 Single Debug"
 
@@ -81,9 +83,10 @@ LIB32=link.exe -lib
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\SDebug"
-# PROP Intermediate_Dir "SDebug\liblutil"
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\liblutil"
 # PROP Target_Dir ""
+RSC=rc.exe
 # ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
 # ADD CPP /nologo /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
 BSC32=bscmake.exe
@@ -91,7 +94,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LIB32=link.exe -lib
 # ADD BASE LIB32 /nologo /out:"..\Debug\olutil32.lib"
-# ADD LIB32 /nologo /out:"..\SDebug\olutil32.lib"
+# ADD LIB32 /nologo /out:"..\..\SDebug\olutil32.lib"
 
 !ELSEIF  "$(CFG)" == "liblutil - Win32 Single Release"
 
@@ -102,9 +105,10 @@ LIB32=link.exe -lib
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\SRelease"
-# PROP Intermediate_Dir "SRelease\liblutil"
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\liblutil"
 # PROP Target_Dir ""
+RSC=rc.exe
 # ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
 # ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
 BSC32=bscmake.exe
@@ -112,7 +116,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LIB32=link.exe -lib
 # ADD BASE LIB32 /nologo /out:"..\Release\olutil32.lib"
-# ADD LIB32 /nologo /out:"..\SRelease\olutil32.lib"
+# ADD LIB32 /nologo /out:"..\..\SRelease\olutil32.lib"
 
 !ENDIF 
 
@@ -124,6 +128,10 @@ LIB32=link.exe -lib
 # Name "liblutil - Win32 Single Release"
 # Begin Source File
 
+SOURCE=.\authpasswd.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\base64.c
 # End Source File
 # Begin Source File
@@ -136,6 +144,10 @@ SOURCE=.\debug.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\entropy.c
+# End Source File
+# Begin Source File
+
 SOURCE="..\..\include\getopt-compat.h"
 # End Source File
 # Begin Source File
@@ -176,10 +188,6 @@ SOURCE=.\md5.c
 # End Source File
 # Begin Source File
 
-SOURCE=.\nt_err.c
-# End Source File
-# Begin Source File
-
 SOURCE=.\ntservice.c
 # End Source File
 # Begin Source File
@@ -201,7 +209,7 @@ SOURCE=.\slapdmsg.mc
 !IF  "$(CFG)" == "liblutil - Win32 Release"
 
 # Begin Custom Build - Building slapd message file
-IntDir=.\Release\liblutil
+IntDir=.\..\..\Release\liblutil
 InputPath=.\slapdmsg.mc
 
 "slapdmsg.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
@@ -214,7 +222,7 @@ InputPath=.\slapdmsg.mc
 !ELSEIF  "$(CFG)" == "liblutil - Win32 Debug"
 
 # Begin Custom Build - Building slapd message file
-IntDir=.\Debug\liblutil
+IntDir=.\..\..\Debug\liblutil
 InputPath=.\slapdmsg.mc
 
 "slapdmsg.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
@@ -227,7 +235,7 @@ InputPath=.\slapdmsg.mc
 !ELSEIF  "$(CFG)" == "liblutil - Win32 Single Debug"
 
 # Begin Custom Build - Building slapd message file
-IntDir=.\SDebug\liblutil
+IntDir=.\..\..\SDebug\liblutil
 InputPath=.\slapdmsg.mc
 
 "slapdmsg.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
@@ -240,7 +248,7 @@ InputPath=.\slapdmsg.mc
 !ELSEIF  "$(CFG)" == "liblutil - Win32 Single Release"
 
 # Begin Custom Build - Building slapd message file
-IntDir=.\SRelease\liblutil
+IntDir=.\..\..\SRelease\liblutil
 InputPath=.\slapdmsg.mc
 
 "slapdmsg.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
index a3424ba14611203bc63ec8dd3cedf4db919ee1c9..7ba5c0ea50189328ee56a4096ed7bb0d39113087 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
+ * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
@@ -79,7 +79,7 @@ int lutil_unlockf ( int fd ) {
 int lutil_lockf ( int fd ) {
        struct flock file_lock;
 
-       memset( &file_lock, 0, sizeof( file_lock ) );
+       memset( &file_lock, '\0', sizeof( file_lock ) );
        file_lock.l_type = F_WRLCK;
        file_lock.l_whence = SEEK_SET;
        file_lock.l_start = 0;
@@ -92,7 +92,7 @@ int lutil_lockf ( int fd ) {
 int lutil_unlockf ( int fd ) {
        struct flock file_lock;
 
-       memset( &file_lock, 0, sizeof( file_lock ) );
+       memset( &file_lock, '\0', sizeof( file_lock ) );
        file_lock.l_type = F_UNLCK;
        file_lock.l_whence = SEEK_SET;
        file_lock.l_start = 0;
index 6758de02409af77e40adb6296de2dcd71fac60a7..9ce509f8ffe13ab86436b802423dbd58d2bb4500 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
 #include <lutil_md5.h>
 
 /* Little-endian byte-swapping routines.  Note that these do not
-   depend on the size of datatypes such as uint32, nor do they require
+   depend on the size of datatypes such as ber_uint_t, nor do they require
    us to detect the endianness of the machine we are running on.  It
    is possible they should be macros for speed, but I would be
    surprised if they were a performance bottleneck for MD5.  */
 
-static uint32
+static ber_uint_t
 getu32( const unsigned char *addr )
 {
        return (((((unsigned long)addr[3] << 8) | addr[2]) << 8)
@@ -57,7 +57,7 @@ getu32( const unsigned char *addr )
 }
 
 static void
-putu32( uint32 data, unsigned char *addr )
+putu32( ber_uint_t data, unsigned char *addr )
 {
        addr[0] = (unsigned char)data;
        addr[1] = (unsigned char)(data >> 8);
@@ -89,15 +89,15 @@ void
 lutil_MD5Update(
     struct lutil_MD5Context    *ctx,
     const unsigned char                *buf,
-    unsigned int               len
+    ber_len_t          len
 )
 {
-       uint32 t;
+       ber_uint_t t;
 
        /* Update bitcount */
 
        t = ctx->bits[0];
-       if ((ctx->bits[0] = (t + ((uint32)len << 3)) & 0xffffffff) < t)
+       if ((ctx->bits[0] = (t + ((ber_uint_t)len << 3)) & 0xffffffff) < t)
                ctx->bits[1]++; /* Carry from low to high */
        ctx->bits[1] += len >> 29;
 
@@ -157,14 +157,14 @@ lutil_MD5Final( unsigned char *digest, struct lutil_MD5Context *ctx )
        /* Pad out to 56 mod 64 */
        if (count < 8) {
                /* Two lots of padding:  Pad the first block to 64 bytes */
-               memset(p, 0, count);
+               memset(p, '\0', count);
                lutil_MD5Transform(ctx->buf, ctx->in);
 
                /* Now fill the next block with 56 bytes */
-               memset(ctx->in, 0, 56);
+               memset(ctx->in, '\0', 56);
        } else {
                /* Pad block to 56 bytes */
-               memset(p, 0, count-8);
+               memset(p, '\0', count-8);
        }
 
        /* Append length in bits and transform */
@@ -176,7 +176,7 @@ lutil_MD5Final( unsigned char *digest, struct lutil_MD5Context *ctx )
        putu32(ctx->buf[1], digest + 4);
        putu32(ctx->buf[2], digest + 8);
        putu32(ctx->buf[3], digest + 12);
-       memset(ctx, 0, sizeof(ctx));    /* In case it's sensitive */
+       memset(ctx, '\0', sizeof(ctx)); /* In case it's sensitive */
 }
 
 #ifndef ASM_MD5
@@ -199,10 +199,10 @@ lutil_MD5Final( unsigned char *digest, struct lutil_MD5Context *ctx )
  * the data and converts bytes into longwords for this routine.
  */
 void
-lutil_MD5Transform( uint32 *buf, const unsigned char *inraw )
+lutil_MD5Transform( ber_uint_t *buf, const unsigned char *inraw )
 {
-       register uint32 a, b, c, d;
-       uint32 in[16];
+       register ber_uint_t a, b, c, d;
+       ber_uint_t in[16];
        int i;
 
        for (i = 0; i < 16; ++i)
@@ -297,7 +297,7 @@ int
 main (int  argc, char **argv )
 {
        struct lutil_MD5Context context;
-       unsigned char checksum[16];
+       unsigned char checksum[LUTIL_MD5_BYTES];
        int i;
        int j;
 
@@ -312,7 +312,7 @@ main (int  argc, char **argv )
                lutil_MD5Init (&context);
                lutil_MD5Update (&context, argv[j], strlen (argv[j]));
                lutil_MD5Final (checksum, &context);
-               for (i = 0; i < 16; i++)
+               for (i = 0; i < LUTIL_MD5_BYTES; i++)
                {
                        printf ("%02x", (unsigned int) checksum[i]);
                }
diff --git a/libraries/liblutil/nt_err.c b/libraries/liblutil/nt_err.c
deleted file mode 100644 (file)
index 6d119d2..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/* $OpenLDAP$ */
-#include "portable.h"
-
-#ifdef HAVE_WINSOCK2
-#include <winsock2.h>
-
-#define __RETSTR( x ) case x: return #x;
-
-char *WSAGetErrorString( int err )
-{
-       switch( err )
-       {
-               __RETSTR( WSAEINTR )
-               __RETSTR( WSAEBADF )
-               __RETSTR( WSAEACCES )
-               __RETSTR( WSAEFAULT )
-               __RETSTR( WSAEINVAL )
-               __RETSTR( WSAEMFILE )
-               __RETSTR( WSAEWOULDBLOCK )
-               __RETSTR( WSAEINPROGRESS )
-               __RETSTR( WSAEALREADY )
-               __RETSTR( WSAENOTSOCK )
-               __RETSTR( WSAEDESTADDRREQ )
-               __RETSTR( WSAEMSGSIZE )
-               __RETSTR( WSAEPROTOTYPE )
-               __RETSTR( WSAENOPROTOOPT )
-               __RETSTR( WSAEPROTONOSUPPORT )
-               __RETSTR( WSAESOCKTNOSUPPORT )
-               __RETSTR( WSAEOPNOTSUPP )
-               __RETSTR( WSAEPFNOSUPPORT )
-               __RETSTR( WSAEAFNOSUPPORT )
-               __RETSTR( WSAEADDRINUSE )
-               __RETSTR( WSAEADDRNOTAVAIL )
-               __RETSTR( WSAENETDOWN )
-               __RETSTR( WSAENETUNREACH )
-               __RETSTR( WSAENETRESET )
-               __RETSTR( WSAECONNABORTED )
-               __RETSTR( WSAECONNRESET )
-               __RETSTR( WSAENOBUFS )
-               __RETSTR( WSAEISCONN )
-               __RETSTR( WSAENOTCONN )
-               __RETSTR( WSAESHUTDOWN )
-               __RETSTR( WSAETOOMANYREFS )
-               __RETSTR( WSAETIMEDOUT )
-               __RETSTR( WSAECONNREFUSED )
-               __RETSTR( WSAELOOP )
-               __RETSTR( WSAENAMETOOLONG )
-               __RETSTR( WSAEHOSTDOWN )
-               __RETSTR( WSAEHOSTUNREACH )
-               __RETSTR( WSAENOTEMPTY )
-               __RETSTR( WSAEPROCLIM )
-               __RETSTR( WSAEUSERS )
-               __RETSTR( WSAEDQUOT )
-               __RETSTR( WSAESTALE )
-               __RETSTR( WSAEREMOTE )
-               __RETSTR( WSASYSNOTREADY )
-               __RETSTR( WSAVERNOTSUPPORTED )
-               __RETSTR( WSANOTINITIALISED )
-               __RETSTR( WSAEDISCON )
-               __RETSTR( WSAENOMORE )
-               __RETSTR( WSAECANCELLED )
-               __RETSTR( WSAEINVALIDPROCTABLE )
-               __RETSTR( WSAEINVALIDPROVIDER )
-               __RETSTR( WSASYSCALLFAILURE )
-               __RETSTR( WSASERVICE_NOT_FOUND )
-               __RETSTR( WSATYPE_NOT_FOUND )
-               __RETSTR( WSA_E_NO_MORE )
-               __RETSTR( WSA_E_CANCELLED )
-               __RETSTR( WSAEREFUSED )
-
-               __RETSTR( WSAHOST_NOT_FOUND )
-               __RETSTR( WSATRY_AGAIN )
-               __RETSTR( WSANO_RECOVERY )
-               __RETSTR( WSANO_DATA )
-       }
-       return "unknown";
-}
-
-char *WSAGetLastErrorString( void )
-{
-       return WSAGetErrorString( WSAGetLastError() );
-}
-
-#undef __RETSTR
-
-#endif /* HAVE_WINSOCK2 */
-
-
-char *GetErrorString( int err )
-{
-       static char msgBuf[1024];
-
-       FormatMessage(
-               FORMAT_MESSAGE_FROM_SYSTEM,
-               NULL,
-               err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-               msgBuf, 1024, NULL );
-
-       return msgBuf;
-}
-
-char *GetLastErrorString( void )
-{
-       return GetErrorString( GetLastError() );
-}
-
-
-
index e1554a5cb46bf547f7cd69105cd904487e33965c..657974ae7c9b0152e0f250c2d2e2b723b416c83e 100644 (file)
@@ -1,11 +1,18 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
-/* ntservice.c */
+
+/*
+ * NT Service manager utilities for OpenLDAP services
+ *     these should NOT be slapd specific, but are
+ */
+
 #include "portable.h"
 
+#ifdef HAVE_NT_SERVICE_MANAGER
+
 #include <ac/stdlib.h>
 #include <ac/string.h>
 
@@ -41,10 +48,10 @@ ldap_pvt_thread_t           start_status_tid,       stop_status_tid;
 
 void (*stopfunc)(int);
 
-/* in nt_err.c */
-char *GetLastErrorString( void );
+static char *GetLastErrorString( void );
 
-int srv_install(LPCTSTR lpszServiceName, LPCTSTR lpszBinaryPathName)
+int srv_install(LPCTSTR lpszServiceName, LPCTSTR lpszDisplayName,
+               LPCTSTR lpszBinaryPathName, BOOL auto_start)
 {
        HKEY            hKey;
        DWORD           dwValue, dwDisposition;
@@ -56,10 +63,10 @@ int srv_install(LPCTSTR lpszServiceName, LPCTSTR lpszBinaryPathName)
                if ((schService = CreateService( 
                                                        schSCManager, 
                                                        lpszServiceName, 
-                                                       TEXT("OpenLDAP Directory Service")
-                                                       SC_MANAGER_CREATE_SERVICE
+                                                       lpszDisplayName
+                                                       SERVICE_ALL_ACCESS
                                                        SERVICE_WIN32_OWN_PROCESS, 
-                                                       SERVICE_DEMAND_START, 
+                                                       auto_start ? SERVICE_AUTO_START : SERVICE_DEMAND_START, 
                                                        SERVICE_ERROR_NORMAL, 
                                                        lpszBinaryPathName, 
                                                        NULL, NULL, NULL, NULL, NULL)) != NULL)
@@ -76,13 +83,13 @@ int srv_install(LPCTSTR lpszServiceName, LPCTSTR lpszBinaryPathName)
                                "REG_SZ", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, 
                                &dwDisposition) != ERROR_SUCCESS)
                        {
-                               fprintf( stderr, "RegCreateKeyEx() failed. GetLastError=%d (%s)\n", GetLastError(), GetLastErrorString() );
+                               fprintf( stderr, "RegCreateKeyEx() failed. GetLastError=%lu (%s)\n", GetLastError(), GetLastErrorString() );
                                RegCloseKey(hKey);
                                return(0);
                        }
                        if ( RegSetValueEx(hKey, "EventMessageFile", 0, REG_EXPAND_SZ, lpszBinaryPathName, strlen(lpszBinaryPathName) + 1) != ERROR_SUCCESS)
                        {
-                               fprintf( stderr, "RegSetValueEx(EventMessageFile) failed. GetLastError=%d (%s)\n", GetLastError(), GetLastErrorString() );
+                               fprintf( stderr, "RegSetValueEx(EventMessageFile) failed. GetLastError=%lu (%s)\n", GetLastError(), GetLastErrorString() );
                                RegCloseKey(hKey);
                                return(0);
                        }
@@ -90,7 +97,7 @@ int srv_install(LPCTSTR lpszServiceName, LPCTSTR lpszBinaryPathName)
                        dwValue = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;
                        if ( RegSetValueEx(hKey, "TypesSupported", 0, REG_DWORD, (LPBYTE) &dwValue, sizeof(DWORD)) != ERROR_SUCCESS) 
                        {
-                               fprintf( stderr, "RegCreateKeyEx(TypesSupported) failed. GetLastError=%d (%s)\n", GetLastError(), GetLastErrorString() );
+                               fprintf( stderr, "RegCreateKeyEx(TypesSupported) failed. GetLastError=%lu (%s)\n", GetLastError(), GetLastErrorString() );
                                RegCloseKey(hKey);
                                return(0);
                        }
@@ -99,13 +106,13 @@ int srv_install(LPCTSTR lpszServiceName, LPCTSTR lpszBinaryPathName)
                }
                else
                {
-                       fprintf( stderr, "CreateService() failed. GetLastError=%d (%s)\n", GetLastError(), GetLastErrorString() );
+                       fprintf( stderr, "CreateService() failed. GetLastError=%lu (%s)\n", GetLastError(), GetLastErrorString() );
                        CloseServiceHandle(schSCManager);
                        return(0);
                }
        }
        else
-               fprintf( stderr, "OpenSCManager() failed. GetLastError=%d (%s)\n", GetLastError(), GetLastErrorString() );
+               fprintf( stderr, "OpenSCManager() failed. GetLastError=%lu (%s)\n", GetLastError(), GetLastErrorString() );
        return(0);
 }
 
@@ -125,20 +132,20 @@ int srv_remove(LPCTSTR lpszServiceName, LPCTSTR lpszBinaryPathName)
                                CloseServiceHandle(schSCManager);
                                return(1);
                        } else {
-                               fprintf( stderr, "DeleteService() failed. GetLastError=%d (%s)\n", GetLastError(), GetLastErrorString() );
+                               fprintf( stderr, "DeleteService() failed. GetLastError=%lu (%s)\n", GetLastError(), GetLastErrorString() );
                                fprintf( stderr, "The %s service has not been removed.\n", lpszBinaryPathName);
                                CloseServiceHandle(schService);
                                CloseServiceHandle(schSCManager);
                                return(0);
                        }
                } else {
-                       fprintf( stderr, "OpenService() failed. GetLastError=%d (%s)\n", GetLastError(), GetLastErrorString() );
+                       fprintf( stderr, "OpenService() failed. GetLastError=%lu (%s)\n", GetLastError(), GetLastErrorString() );
                        CloseServiceHandle(schSCManager);
                        return(0);
                }
        }
        else
-               fprintf( stderr, "OpenSCManager() failed. GetLastError=%d (%s)\n", GetLastError(), GetLastErrorString() );
+               fprintf( stderr, "OpenSCManager() failed. GetLastError=%lu (%s)\n", GetLastError(), GetLastErrorString() );
        return(0);
 }
 
@@ -291,7 +298,7 @@ void *getRegParam( char *svc, char *value )
        DWORD valLen = sizeof( vValue );
 
        if ( svc != NULL )
-               sprintf ( path, "SOFTWARE\\OpenLDAP\\%s\\Parameters", svc );
+               sprintf ( path, "SOFTWARE\\%s", svc );
        else
                strcpy (path, "SOFTWARE\\OpenLDAP\\Parameters" );
        
@@ -330,12 +337,12 @@ void LogSlapdStartedEvent( char *svc, int slap_debug, char *configfile, char *ur
 
        Inserts[i] = (char *)malloc( 20 );
        itoa( slap_debug, Inserts[i++], 10 );
-       Inserts[i++] = ldap_pvt_strdup( configfile );
-       Inserts[i++] = ldap_pvt_strdup( urls ? urls : "ldap:///" );
-       Inserts[i++] = ldap_pvt_strdup( is_NT_Service ? "svc" : "cmd" );
+       Inserts[i++] = strdup( configfile );
+       Inserts[i++] = strdup( urls ? urls : "ldap:///" );
+       Inserts[i++] = strdup( is_NT_Service ? "svc" : "cmd" );
 
        ReportEvent( hEventLog, EVENTLOG_INFORMATION_TYPE, 0,
-               MSG_SLAPD_STARTED, NULL, i, 0, Inserts, NULL );
+               MSG_SLAPD_STARTED, NULL, i, 0, (LPCSTR *) Inserts, NULL );
 
        for ( j = 0; j < i; j++ )
                ldap_memfree( Inserts[j] );
@@ -425,3 +432,22 @@ void ReportSlapdShutdownComplete(  )
                SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);
        }
 }
+
+static char *GetErrorString( int err )
+{
+       static char msgBuf[1024];
+
+       FormatMessage(
+               FORMAT_MESSAGE_FROM_SYSTEM,
+               NULL,
+               err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+               msgBuf, 1024, NULL );
+
+       return msgBuf;
+}
+
+static char *GetLastErrorString( void )
+{
+       return GetErrorString( GetLastError() );
+}
+#endif
index d350770ef94e47d5497d383776efb88618423306..becde0e6c540b5f66898a054280959c3243e3297 100644 (file)
@@ -1,13 +1,16 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
- * lutil_password(credentials, password)
+ * int lutil_passwd(
+ *     const struct berval *passwd,
+ *     const struct berval *cred,
+ *     const char **schemes )
  *
- * Returns true if user supplied credentials matches
- * the stored password. 
+ * Returns true if user supplied credentials (cred) matches
+ * the stored password (passwd)
  *
  * Due to the use of the crypt(3) function 
  * this routine is NOT thread-safe.
 
 #include "portable.h"
 
+#include <stdio.h>
 #include <ac/stdlib.h>
-
 #include <ac/string.h>
-#include <ac/unistd.h>
 
-#include "lutil_md5.h"
-#include "lutil_sha1.h"
-#include "lutil.h"
+#ifdef SLAPD_SPASSWD
+#      include <sasl.h>
+#endif
+
+#ifdef SLAPD_KPASSWD
+#      include <ac/krb.h>
+#      include <ac/krb5.h>
+#endif
+
+#include <ac/param.h>
+
+#include <ac/unistd.h>
+#include <ac/crypt.h>
 
 #ifdef HAVE_SHADOW_H
 #      include <shadow.h>
 #ifdef HAVE_PWD_H
 #      include <pwd.h>
 #endif
+#ifdef HAVE_AIX_SECURITY
+#      include <userpw.h>
+#endif
+
+#include <lber.h>
+
+#include "lutil_md5.h"
+#include "lutil_sha1.h"
+#include "lutil.h"
+
+static const unsigned char crypt64[] =
+       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890./";
+
+struct pw_scheme;
+
+typedef int (*PASSWD_CHK_FUNC)(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd,
+       const struct berval *cred );
+
+typedef struct berval * (*PASSWD_HASH_FUNC) (
+       const struct pw_scheme *scheme,
+       const struct berval *passwd );
+
+struct pw_scheme {
+       struct berval name;
+       PASSWD_CHK_FUNC chk_fn;
+       PASSWD_HASH_FUNC hash_fn;
+};
+
+/* password check routines */
+static int chk_md5(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd,
+       const struct berval *cred );
+
+static int chk_smd5(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd,
+       const struct berval *cred );
+
+static int chk_ssha1(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd,
+       const struct berval *cred );
+
+static int chk_sha1(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd,
+       const struct berval *cred );
+
+#ifdef SLAPD_SPASSWD
+static int chk_sasl(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd,
+       const struct berval *cred );
+#endif
+
+#ifdef SLAPD_KPASSWD
+static int chk_kerberos(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd,
+       const struct berval *cred );
+#endif
+
+#ifdef SLAPD_CRYPT
+static int chk_crypt(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd,
+       const struct berval *cred );
+
+#if defined( HAVE_GETPWNAM ) && defined( HAVE_PW_PASSWD )
+static int chk_unix(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd,
+       const struct berval *cred );
+#endif
+#endif
+
+
+/* password hash routines */
+static struct berval *hash_sha1(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd );
+
+static struct berval *hash_ssha1(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd );
+
+static struct berval *hash_smd5(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd );
+
+static struct berval *hash_md5(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd );
+
+#ifdef SLAPD_CRYPT
+static struct berval *hash_crypt(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd );
+#endif
+
 
-static int supported_hash(
-       const char* method,
-       const char** methods )
+static const struct pw_scheme pw_schemes[] =
+{
+       { {sizeof("{SSHA}")-1, "{SSHA}"},       chk_ssha1, hash_ssha1 },
+       { {sizeof("{SHA}")-1, "{SHA}"},         chk_sha1, hash_sha1 },
+
+       { {sizeof("{SMD5}")-1, "{SMD5}"},       chk_smd5, hash_smd5 },
+       { {sizeof("{MD5}")-1, "{MD5}"},         chk_md5, hash_md5 },
+
+#ifdef SLAPD_SPASSWD
+       { {sizeof("{SASL}")-1, "{SASL}"}, chk_sasl, NULL },
+#endif
+
+#ifdef SLAPD_KPASSWD
+       { {sizeof("{KERBEROS}")-1, "{KERBEROS}"}, chk_kerberos, NULL },
+#endif
+
+#ifdef SLAPD_CRYPT
+       { {sizeof("{CRYPT}")-1, "{CRYPT}"},     chk_crypt, hash_crypt },
+# if defined( HAVE_GETPWNAM ) && defined( HAVE_PW_PASSWD )
+       { {sizeof("{UNIX}")-1, "{UNIX}"},       chk_unix, NULL },
+# endif
+#endif
+
+#ifdef SLAPD_CLEARTEXT
+       /* psuedo scheme */
+       { {0, "{CLEARTEXT}"}, NULL, NULL },
+#endif
+
+       { {0, NULL}, NULL, NULL }
+};
+
+static const struct pw_scheme *get_scheme(
+       const char* scheme )
 {
        int i;
 
-       if(methods == NULL) {
-               return 1;
+       for( i=0; pw_schemes[i].name.bv_val; i++) {
+               if( pw_schemes[i].name.bv_len == 0 ) continue;
+
+               if( strncasecmp(scheme, pw_schemes[i].name.bv_val,
+                       pw_schemes[i].name.bv_len) == 0 )
+               {
+                       return &pw_schemes[i];
+               }
        }
 
-       for(i=0; methods[i] != NULL; i++) {
-               if(strcasecmp(method, methods[i]) == 0) {
+       return NULL;
+}
+
+int lutil_passwd_scheme(
+       const char* scheme )
+{
+       if( scheme == NULL ) {
+               return 0;
+       }
+
+       return get_scheme(scheme) != NULL;
+}
+
+
+static int is_allowed_scheme( 
+       const char* scheme,
+       const char** schemes )
+{
+       int i;
+
+       if( schemes == NULL ) return 1;
+
+       for( i=0; schemes[i] != NULL; i++ ) {
+               if( strcasecmp( scheme, schemes[i] ) == 0 ) {
                        return 1;
                }
        }
-
        return 0;
 }
 
-static const char *passwd_hash(
-       const char* passwd,
-       const char* method,
-       const char** methods )
+static struct berval *passwd_scheme(
+       const struct pw_scheme *scheme,
+       const struct berval * passwd,
+       const char** allowed )
 {
-       int len;
-
-       if( !supported_hash( method, methods ) ) {
+       if( !is_allowed_scheme( scheme->name.bv_val, allowed ) ) {
                return NULL;
        }
 
-       len = strlen(method);
+       if( passwd->bv_len >= scheme->name.bv_len ) {
+               if( strncasecmp( passwd->bv_val, scheme->name.bv_val, scheme->name.bv_len ) == 0 ) {
+                       struct berval *bv = ber_memalloc( sizeof(struct berval) );
 
-       if( strncasecmp( passwd, method, len ) == 0 ) {
-               return &passwd[len];
+                       if( bv == NULL ) return NULL;
+
+                       bv->bv_val = &passwd->bv_val[scheme->name.bv_len];
+                       bv->bv_len = passwd->bv_len - scheme->name.bv_len;
+
+                       return bv;
+               }
        }
 
        return NULL;
@@ -75,144 +252,796 @@ static const char *passwd_hash(
  */
 int
 lutil_passwd(
-       const char *cred,
-       const char *passwd,
-       const char **methods)
+       const struct berval *passwd,    /* stored passwd */
+       const struct berval *cred,              /* user cred */
+       const char **schemes )
 {
-       const char *p;
+       int i;
 
-       if (cred == NULL || passwd == NULL) {
+       if (cred == NULL || cred->bv_len == 0 ||
+               passwd == NULL || passwd->bv_len == 0 )
+       {
                return -1;
        }
 
-       if ((p = passwd_hash( passwd, "{MD5}", methods )) != NULL ) {
-               lutil_MD5_CTX MD5context;
-               unsigned char MD5digest[16];
-               char base64digest[25];  /* ceiling(sizeof(input)/3) * 4 + 1 */
+       for( i=0; pw_schemes[i].name.bv_val != NULL; i++ ) {
+               if( pw_schemes[i].chk_fn ) {
+                       struct berval *p = passwd_scheme( &pw_schemes[i],
+                               passwd, schemes );
 
-               lutil_MD5Init(&MD5context);
-               lutil_MD5Update(&MD5context,
-                              (const unsigned char *)cred, strlen(cred));
-               lutil_MD5Final(MD5digest, &MD5context);
+                       if( p != NULL ) {
+                               int rc = (pw_schemes[i].chk_fn)( &pw_schemes[i], p, cred );
 
-               if ( lutil_b64_ntop(MD5digest, sizeof(MD5digest),
-                       base64digest, sizeof(base64digest)) < 0)
-               {
-                       return ( 1 );
+                               /* only free the berval structure as the bv_val points
+                                * into passwd->bv_val
+                                */
+                               ber_memfree( p );
+                               
+                               return rc;
+                       }
                }
+       }
+
+#ifdef SLAPD_CLEARTEXT
+       if( is_allowed_scheme("{CLEARTEXT}", schemes ) ) {
+               return passwd->bv_len == cred->bv_len
+                       ? memcmp( passwd->bv_val, cred->bv_val, passwd->bv_len )
+                       : 1;
+       }
+#endif
+       return 1;
+}
 
-               return( strcmp(p, base64digest) );
+struct berval * lutil_passwd_generate( ber_len_t len )
+{
+       struct berval *pw;
 
-       } else if ((p = passwd_hash( passwd, "{SHA}", methods )) != NULL ) {
-               lutil_SHA1_CTX SHA1context;
-               unsigned char SHA1digest[20];
-               char base64digest[29];  /* ceiling(sizeof(input)/3) * 4 + 1 */
+       if( len < 1 ) return NULL;
 
-               lutil_SHA1Init(&SHA1context);
-               lutil_SHA1Update(&SHA1context,
-                               (const unsigned char *) cred, strlen(cred));
-               lutil_SHA1Final(SHA1digest, &SHA1context);
+       pw = ber_memalloc( sizeof( struct berval ) );
+       if( pw == NULL ) return NULL;
 
-               if (lutil_b64_ntop(SHA1digest, sizeof(SHA1digest),
-                       base64digest, sizeof(base64digest)) < 0)
-               {
-                       return ( 1 );
+       pw->bv_len = len;
+       pw->bv_val = ber_memalloc( len + 1 );
+
+       if( pw->bv_val == NULL ) {
+               ber_memfree( pw );
+               return NULL;
+       }
+
+       if( lutil_entropy( pw->bv_val, pw->bv_len) < 0 ) {
+               ber_bvfree( pw );
+               return NULL; 
+       }
+
+       for( len = 0; len < pw->bv_len; len++ ) {
+               pw->bv_val[len] = crypt64[
+                       pw->bv_val[len] % (sizeof(crypt64)-1) ];
+       }
+
+       pw->bv_val[len] = '\0';
+       
+       return pw;
+}
+
+struct berval * lutil_passwd_hash(
+       const struct berval * passwd,
+       const char * method )
+{
+       const struct pw_scheme *sc = get_scheme( method );
+
+       if( sc == NULL ) return NULL;
+       if( ! sc->hash_fn ) return NULL;
+
+       return (sc->hash_fn)( sc, passwd );
+}
+
+static struct berval * pw_string(
+       const struct pw_scheme *sc,
+       const struct berval *passwd )
+{
+       struct berval *pw = ber_memalloc( sizeof( struct berval ) );
+       if( pw == NULL ) return NULL;
+
+       pw->bv_len = sc->name.bv_len + passwd->bv_len;
+       pw->bv_val = ber_memalloc( pw->bv_len + 1 );
+
+       if( pw->bv_val == NULL ) {
+               ber_memfree( pw );
+               return NULL;
+       }
+
+       memcpy( pw->bv_val, sc->name.bv_val, sc->name.bv_len );
+       memcpy( &pw->bv_val[sc->name.bv_len], passwd->bv_val, passwd->bv_len );
+
+       pw->bv_val[pw->bv_len] = '\0';
+       return pw;
+}
+
+static struct berval * pw_string64(
+       const struct pw_scheme *sc,
+       const struct berval *hash,
+       const struct berval *salt )
+{
+       int rc;
+       struct berval string;
+       struct berval *b64 = ber_memalloc( sizeof(struct berval) );
+       size_t b64len;
+
+       if( b64 == NULL ) return NULL;
+
+       if( salt ) {
+               /* need to base64 combined string */
+               string.bv_len = hash->bv_len + salt->bv_len;
+               string.bv_val = ber_memalloc( string.bv_len + 1 );
+
+               if( string.bv_val == NULL ) {
+                       ber_memfree( b64 );
+                       return NULL;
                }
 
-               return( strcmp(p, base64digest) );
+               memcpy( string.bv_val, hash->bv_val,
+                       hash->bv_len );
+               memcpy( &string.bv_val[hash->bv_len], salt->bv_val,
+                       salt->bv_len );
+               string.bv_val[string.bv_len] = '\0';
+
+       } else {
+               string = *hash;
+       }
+
+       b64len = LUTIL_BASE64_ENCODE_LEN( string.bv_len ) + 1;
+       b64->bv_len = b64len + sc->name.bv_len;
+       b64->bv_val = ber_memalloc( b64->bv_len + 1 );
+
+       if( b64->bv_val == NULL ) {
+               if( salt ) ber_memfree( string.bv_val );
+               ber_memfree( b64 );
+               return NULL;
+       }
+
+       memcpy(b64->bv_val, sc->name.bv_val, sc->name.bv_len);
+
+       rc = lutil_b64_ntop(
+               string.bv_val, string.bv_len,
+               &b64->bv_val[sc->name.bv_len], b64len );
+
+       if( salt ) ber_memfree( string.bv_val );
+       
+       if( rc < 0 ) {
+               ber_bvfree( b64 );
+               return NULL;
+       }
+
+       /* recompute length */
+       b64->bv_len = sc->name.bv_len + rc;
+       assert( strlen(b64->bv_val) == b64->bv_len );
+       return b64;
+}
 
-       } else if ((p = passwd_hash( passwd, "{SSHA}", methods )) != NULL ) {
-               lutil_SHA1_CTX SHA1context;
-               unsigned char SHA1digest[20];
-               int pw_len = strlen(p);
-               int rc;
-               unsigned char *orig_pass = NULL;
+/* PASSWORD CHECK ROUTINES */
+
+static int chk_ssha1(
+       const struct pw_scheme *sc,
+       const struct berval * passwd,
+       const struct berval * cred )
+{
+       lutil_SHA1_CTX SHA1context;
+       unsigned char SHA1digest[LUTIL_SHA1_BYTES];
+       int rc;
+       unsigned char *orig_pass = NULL;
  
-               /* base64 un-encode password */
-               orig_pass = (unsigned char *)malloc((size_t)(pw_len * 0.75 + 1));
-               if ((rc = lutil_b64_pton(p, orig_pass, pw_len)) < 0)
-               {
-                       free(orig_pass);
-                       return ( 1 );
-               }
+       /* decode base64 password */
+       orig_pass = (unsigned char *) ber_memalloc( (size_t) (
+               LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) );
+
+       if( orig_pass == NULL ) return -1;
+
+       rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len);
+
+       if(rc < 0) {
+               ber_memfree(orig_pass);
+               return -1;
+       }
+       /* hash credentials with salt */
+       lutil_SHA1Init(&SHA1context);
+       lutil_SHA1Update(&SHA1context,
+               (const unsigned char *) cred->bv_val, cred->bv_len);
+       lutil_SHA1Update(&SHA1context,
+               (const unsigned char *) &orig_pass[sizeof(SHA1digest)],
+               rc - sizeof(SHA1digest));
+       lutil_SHA1Final(SHA1digest, &SHA1context);
+       /* compare */
+       rc = memcmp((char *)orig_pass, (char *)SHA1digest, sizeof(SHA1digest));
+       ber_memfree(orig_pass);
+       return rc ? 1 : 0;
+}
+
+static int chk_sha1(
+       const struct pw_scheme *sc,
+       const struct berval * passwd,
+       const struct berval * cred )
+{
+       lutil_SHA1_CTX SHA1context;
+       unsigned char SHA1digest[LUTIL_SHA1_BYTES];
+       int rc;
+       unsigned char *orig_pass = NULL;
  
-               /* hash credentials with salt */
-               lutil_SHA1Init(&SHA1context);
-               lutil_SHA1Update(&SHA1context,
-                               (const unsigned char *) cred, strlen(cred));
-               lutil_SHA1Update(&SHA1context,
-                               (const unsigned char *) orig_pass + sizeof(SHA1digest),
-                               rc - sizeof(SHA1digest));
-               lutil_SHA1Final(SHA1digest, &SHA1context);
+       /* base64 un-encode password */
+       orig_pass = (unsigned char *) ber_memalloc( (size_t) (
+               LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) );
+
+       if( orig_pass == NULL ) return -1;
+
+       rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len);
+
+       if( rc != sizeof(SHA1digest) ) {
+               ber_memfree(orig_pass);
+               return -1;
+       }
+       /* hash credentials with salt */
+       lutil_SHA1Init(&SHA1context);
+       lutil_SHA1Update(&SHA1context,
+               (const unsigned char *) cred->bv_val, cred->bv_len);
+       lutil_SHA1Final(SHA1digest, &SHA1context);
  
-               /* compare */
-               rc = memcmp((char *)orig_pass, (char *)SHA1digest, sizeof(SHA1digest));
-               free(orig_pass);
-               return(rc);
-
-       } else if ((p = passwd_hash( passwd, "{SMD5}", methods )) != NULL ) {
-               lutil_MD5_CTX MD5context;
-               unsigned char MD5digest[16];
-               int pw_len = strlen(p);
-               int rc;
-               unsigned char *orig_pass = NULL;
-
-               /* base64 un-encode password */
-               orig_pass = (unsigned char *)malloc((size_t)(pw_len * 0.75 + 1));
-               if ((rc = lutil_b64_pton(p, orig_pass, pw_len)) < 0)
+       /* compare */
+       rc = memcmp((char *)orig_pass, (char *)SHA1digest, sizeof(SHA1digest));
+       ber_memfree(orig_pass);
+       return rc ? 1 : 0;
+}
+
+static int chk_smd5(
+       const struct pw_scheme *sc,
+       const struct berval * passwd,
+       const struct berval * cred )
+{
+       lutil_MD5_CTX MD5context;
+       unsigned char MD5digest[LUTIL_MD5_BYTES];
+       int rc;
+       unsigned char *orig_pass = NULL;
+
+       /* base64 un-encode password */
+       orig_pass = (unsigned char *) ber_memalloc( (size_t) (
+               LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) );
+
+       if( orig_pass == NULL ) return -1;
+
+       rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len);
+       if ( rc < 0 ) {
+               ber_memfree(orig_pass);
+               return -1;
+       }
+
+       /* hash credentials with salt */
+       lutil_MD5Init(&MD5context);
+       lutil_MD5Update(&MD5context,
+               (const unsigned char *) cred->bv_val, cred->bv_len );
+       lutil_MD5Update(&MD5context,
+               (const unsigned char *) &orig_pass[sizeof(MD5digest)],
+               rc - sizeof(MD5digest));
+       lutil_MD5Final(MD5digest, &MD5context);
+
+       /* compare */
+       rc = memcmp((char *)orig_pass, (char *)MD5digest, sizeof(MD5digest));
+       ber_memfree(orig_pass);
+       return rc ? 1 : 0;
+}
+
+static int chk_md5(
+       const struct pw_scheme *sc,
+       const struct berval * passwd,
+       const struct berval * cred )
+{
+       lutil_MD5_CTX MD5context;
+       unsigned char MD5digest[LUTIL_MD5_BYTES];
+       int rc;
+       unsigned char *orig_pass = NULL;
+
+       /* base64 un-encode password */
+       orig_pass = (unsigned char *) ber_memalloc( (size_t) (
+               LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) );
+
+       if( orig_pass == NULL ) return -1;
+
+       rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len);
+       if ( rc != sizeof(MD5digest) ) {
+               ber_memfree(orig_pass);
+               return -1;
+       }
+
+       /* hash credentials with salt */
+       lutil_MD5Init(&MD5context);
+       lutil_MD5Update(&MD5context,
+               (const unsigned char *) cred->bv_val, cred->bv_len );
+       lutil_MD5Final(MD5digest, &MD5context);
+
+       /* compare */
+       rc = memcmp((char *)orig_pass, (char *)MD5digest, sizeof(MD5digest));
+       ber_memfree(orig_pass);
+       return rc ? 1 : 0;
+}
+
+#ifdef SLAPD_SPASSWD
+#ifdef HAVE_CYRUS_SASL
+sasl_conn_t *lutil_passwd_sasl_conn = NULL;
+#endif
+
+static int chk_sasl(
+       const struct pw_scheme *sc,
+       const struct berval * passwd,
+       const struct berval * cred )
+{
+       int i;
+       int rtn;
+
+       for( i=0; i<cred->bv_len; i++) {
+               if(cred->bv_val[i] == '\0') {
+                       return 1;       /* NUL character in password */
+               }
+       }
+
+       if( cred->bv_val[i] != '\0' ) {
+               return 1;       /* cred must behave like a string */
+       }
+
+       for( i=0; i<passwd->bv_len; i++) {
+               if(passwd->bv_val[i] == '\0') {
+                       return 1;       /* NUL character in password */
+               }
+       }
+
+       if( passwd->bv_val[i] != '\0' ) {
+               return 1;       /* passwd must behave like a string */
+       }
+
+       rtn = 1;
+
+#ifdef HAVE_CYRUS_SASL
+       if( lutil_passwd_sasl_conn != NULL ) {
+               const char *errstr = NULL;
+               int sc;
+
+               sc = sasl_checkpass( lutil_passwd_sasl_conn,
+                       passwd->bv_val, passwd->bv_len,
+                       cred->bv_val, cred->bv_len,
+                       &errstr );
+
+               rtn = ( sc != SASL_OK );
+       }
+#endif
+
+       return rtn;
+}
+#endif
+
+#ifdef SLAPD_KPASSWD
+static int chk_kerberos(
+       const struct pw_scheme *sc,
+       const struct berval * passwd,
+       const struct berval * cred )
+{
+       int i;
+       int rtn;
+
+       for( i=0; i<cred->bv_len; i++) {
+               if(cred->bv_val[i] == '\0') {
+                       return 1;       /* NUL character in password */
+               }
+       }
+
+       if( cred->bv_val[i] != '\0' ) {
+               return 1;       /* cred must behave like a string */
+       }
+
+       for( i=0; i<passwd->bv_len; i++) {
+               if(passwd->bv_val[i] == '\0') {
+                       return 1;       /* NUL character in password */
+               }
+       }
+
+       if( passwd->bv_val[i] != '\0' ) {
+               return 1;       /* passwd must behave like a string */
+       }
+
+       rtn = 1;
+
+#ifdef HAVE_KRB5 /* HAVE_HEIMDAL_KRB5 */
+       {
+/* Portions:
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska H\xf6gskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+               krb5_context context;
+               krb5_error_code ret;
+               krb5_creds creds;
+               krb5_get_init_creds_opt get_options;
+               krb5_verify_init_creds_opt verify_options;
+               krb5_principal client, server;
+#ifdef notdef
+               krb5_preauthtype pre_auth_types[] = {KRB5_PADATA_ENC_TIMESTAMP};
+#endif
+
+               ret = krb5_init_context( &context );
+               if (ret) {
+                       return 1;
+               }
+
+#ifdef notdef
+               krb5_get_init_creds_opt_set_preauth_list(&get_options,
+                       pre_auth_types, 1);
+#endif
+
+               krb5_get_init_creds_opt_init( &get_options );
+
+               krb5_verify_init_creds_opt_init( &verify_options );
+       
+               ret = krb5_parse_name( context, passwd->bv_val, &client );
+
+               if (ret) {
+                       krb5_free_context( context );
+                       return 1;
+               }
+
+               ret = krb5_get_init_creds_password( context,
+                       &creds, client, cred->bv_val, NULL,
+                       NULL, 0, NULL, &get_options );
+
+               if (ret) {
+                       krb5_free_principal( context, client );
+                       krb5_free_context( context );
+                       return 1;
+               }
+
                {
-                       free(orig_pass);
-                       return ( 1 );
+                       char host[MAXHOSTNAMELEN];
+
+                       if( gethostname( host, MAXHOSTNAMELEN ) != 0 ) {
+                               krb5_free_principal( context, client );
+                               krb5_free_context( context );
+                               return 1;
+                       }
+
+                       ret = krb5_sname_to_principal( context,
+                               host, "ldap", KRB5_NT_SRV_HST, &server );
                }
 
-               /* hash credentials with salt */
-               lutil_MD5Init(&MD5context);
-               lutil_MD5Update(&MD5context,
-                               (const unsigned char *) cred, strlen(cred));
-               lutil_MD5Update(&MD5context,
-                               (const unsigned char *) orig_pass + sizeof(MD5digest),
-                               rc - sizeof(MD5digest));
-               lutil_MD5Final(MD5digest, &MD5context);
+               if (ret) {
+                       krb5_free_principal( context, client );
+                       krb5_free_context( context );
+                       return 1;
+               }
 
-               /* compare */
-               rc = memcmp((char *)orig_pass, (char *)MD5digest, sizeof(MD5digest));
-               free(orig_pass);
-               return ( rc );
+               ret = krb5_verify_init_creds( context,
+                       &creds, server, NULL, NULL, &verify_options );
+
+               krb5_free_principal( context, client );
+               krb5_free_principal( context, server );
+               krb5_free_creds_contents( context, &creds );
+               krb5_free_context( context );
+
+               rtn = !!ret;
+       }
+#elif  defined(HAVE_KRB4)
+       {
+               /* Borrowed from Heimdal kpopper */
+/* Portions:
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+               int status;
+               char lrealm[REALM_SZ];
+               char tkt[MAXHOSTNAMELEN];
+
+               status = krb_get_lrealm(lrealm,1);
+               if (status == KFAILURE) {
+                       return 1;
+               }
+
+               snprintf(tkt, sizeof(tkt), "%s_slapd.%u",
+                       TKT_ROOT, (unsigned)getpid());
+               krb_set_tkt_string (tkt);
+
+               status = krb_verify_user( passwd->bv_val, "", lrealm,
+                       cred->bv_val, 1, "ldap");
+
+               dest_tkt(); /* no point in keeping the tickets */
+
+               return status == KFAILURE;
+       }
+#endif
+
+       return rtn;
+}
+#endif /* SLAPD_KPASSWD */
 
 #ifdef SLAPD_CRYPT
-       } else if ((p = passwd_hash( passwd, "{CRYPT}", methods )) != NULL ) {
-               return( strcmp(p, crypt(cred, p)) );
+static int chk_crypt(
+       const struct pw_scheme *sc,
+       const struct berval * passwd,
+       const struct berval * cred )
+{
+       char *cr;
+       int i;
 
-# if defined( HAVE_GETSPNAM ) \
-  || ( defined( HAVE_GETPWNAM ) && defined( HAVE_PW_PASSWD ) )
-       } else if ((p = passwd_hash( passwd, "{UNIX}", methods )) != NULL ) {
+       for( i=0; i<cred->bv_len; i++) {
+               if(cred->bv_val[i] == '\0') {
+                       return 1;       /* NUL character in password */
+               }
+       }
 
-#  ifdef HAVE_GETSPNAM
-               struct spwd *spwd = getspnam(p);
+       if( cred->bv_val[i] != '\0' ) {
+               return -1;      /* cred must behave like a string */
+       }
+
+       if( passwd->bv_len < 2 ) {
+               return -1;      /* passwd must be at least two characters long */
+       }
+
+       for( i=0; i<passwd->bv_len; i++) {
+               if(passwd->bv_val[i] == '\0') {
+                       return -1;      /* NUL character in password */
+               }
+       }
+
+       if( passwd->bv_val[i] != '\0' ) {
+               return -1;      /* passwd must behave like a string */
+       }
+
+       cr = crypt( cred->bv_val, passwd->bv_val );
+
+       if( cr == NULL || cr[0] == '\0' ) {
+               /* salt must have been invalid */
+               return -1;
+       }
+
+       return strcmp( passwd->bv_val, cr ) ? 1 : 0;
+}
+
+# if defined( HAVE_GETPWNAM ) && defined( HAVE_PW_PASSWD )
+static int chk_unix(
+       const struct pw_scheme *sc,
+       const struct berval * passwd,
+       const struct berval * cred )
+{
+       int i;
+       char *pw,*cr;
 
-               if(spwd == NULL) {
-                       return 1;       /* not found */
+       for( i=0; i<cred->bv_len; i++) {
+               if(cred->bv_val[i] == '\0') {
+                       return -1;      /* NUL character in password */
                }
+       }
+       if( cred->bv_val[i] != '\0' ) {
+               return -1;      /* cred must behave like a string */
+       }
+
+       for( i=0; i<passwd->bv_len; i++) {
+               if(passwd->bv_val[i] == '\0') {
+                       return -1;      /* NUL character in password */
+               }
+       }
+
+       if( passwd->bv_val[i] != '\0' ) {
+               return -1;      /* passwd must behave like a string */
+       }
 
-               return strcmp(spwd->sp_pwdp, crypt(cred, spwd->sp_pwdp));
-#  else
-               struct passwd *pwd = getpwnam(p);
+       {
+               struct passwd *pwd = getpwnam(passwd->bv_val);
 
                if(pwd == NULL) {
-                       return 1;       /* not found */
+                       return -1;      /* not found */
                }
 
-               return strcmp(pwd->pw_passwd, crypt(cred, pwd->pw_passwd));
+               pw = pwd->pw_passwd;
+       }
+#  ifdef HAVE_GETSPNAM
+       {
+               struct spwd *spwd = getspnam(passwd->bv_val);
+
+               if(spwd != NULL) {
+                       pw = spwd->sp_pwdp;
+               }
+       }
 #  endif
+#  ifdef HAVE_AIX_SECURITY
+       {
+               struct userpw *upw = getuserpw(passwd->bv_val);
+
+               if (upw != NULL) {
+                       pw = upw->upw_passwd;
+               }
+       }
+#  endif
+
+       if( pw == NULL || pw[0] == '\0' || pw[1] == '\0' ) {
+               /* password must must be at least two characters long */
+               return -1;
+       }
+
+       cr = crypt(cred->bv_val, pw);
+
+       if( cr == NULL || cr[0] == '\0' ) {
+               /* salt must have been invalid */
+               return -1;
+       }
+
+       return strcmp(pw, cr) ? 1 : 0;
+
+}
 # endif
 #endif
+
+/* PASSWORD GENERATION ROUTINES */
+
+static struct berval *hash_ssha1(
+       const struct pw_scheme *scheme,
+       const struct berval  *passwd )
+{
+       lutil_SHA1_CTX  SHA1context;
+       unsigned char   SHA1digest[LUTIL_SHA1_BYTES];
+       unsigned char   saltdata[4];
+       struct berval digest;
+       struct berval salt;
+
+       digest.bv_val = SHA1digest;
+       digest.bv_len = sizeof(SHA1digest);
+       salt.bv_val = saltdata;
+       salt.bv_len = sizeof(saltdata);
+
+       if( lutil_entropy( salt.bv_val, salt.bv_len) < 0 ) {
+               return NULL; 
        }
 
-#ifdef SLAPD_CLEARTEXT
-       return supported_hash("{CLEARTEXT}", methods ) &&
-               strcmp(passwd, cred) != 0;
-#else
-       return( 1 );
-#endif
+       lutil_SHA1Init( &SHA1context );
+       lutil_SHA1Update( &SHA1context,
+               (const unsigned char *)passwd->bv_val, passwd->bv_len );
+       lutil_SHA1Update( &SHA1context,
+               (const unsigned char *)salt.bv_val, salt.bv_len );
+       lutil_SHA1Final( SHA1digest, &SHA1context );
+
+       return pw_string64( scheme, &digest, &salt);
+}
+
+static struct berval *hash_sha1(
+       const struct pw_scheme *scheme,
+       const struct berval  *passwd )
+{
+       lutil_SHA1_CTX  SHA1context;
+       unsigned char   SHA1digest[LUTIL_SHA1_BYTES];
+       struct berval digest;
+       digest.bv_val = SHA1digest;
+       digest.bv_len = sizeof(SHA1digest);
+     
+       lutil_SHA1Init( &SHA1context );
+       lutil_SHA1Update( &SHA1context,
+               (const unsigned char *)passwd->bv_val, passwd->bv_len );
+       lutil_SHA1Final( SHA1digest, &SHA1context );
+            
+       return pw_string64( scheme, &digest, NULL);
+}
+
+static struct berval *hash_smd5(
+       const struct pw_scheme *scheme,
+       const struct berval  *passwd )
+{
+       lutil_MD5_CTX   MD5context;
+       unsigned char   MD5digest[LUTIL_MD5_BYTES];
+       unsigned char   saltdata[4];
+       struct berval digest;
+       struct berval salt;
+
+       digest.bv_val = MD5digest;
+       digest.bv_len = sizeof(MD5digest);
+       salt.bv_val = saltdata;
+       salt.bv_len = sizeof(saltdata);
+
+       if( lutil_entropy( salt.bv_val, salt.bv_len) < 0 ) {
+               return NULL; 
+       }
+
+       lutil_MD5Init( &MD5context );
+       lutil_MD5Update( &MD5context,
+               (const unsigned char *) passwd->bv_val, passwd->bv_len );
+       lutil_MD5Update( &MD5context,
+               (const unsigned char *) salt.bv_val, salt.bv_len );
+       lutil_MD5Final( MD5digest, &MD5context );
+
+       return pw_string64( scheme, &digest, &salt );
+}
+
+static struct berval *hash_md5(
+       const struct pw_scheme *scheme,
+       const struct berval  *passwd )
+{
+       lutil_MD5_CTX   MD5context;
+       unsigned char   MD5digest[LUTIL_MD5_BYTES];
+
+       struct berval digest;
+
+       digest.bv_val = MD5digest;
+       digest.bv_len = sizeof(MD5digest);
+
+       lutil_MD5Init( &MD5context );
+       lutil_MD5Update( &MD5context,
+               (const unsigned char *) passwd->bv_val, passwd->bv_len );
+       lutil_MD5Final( MD5digest, &MD5context );
 
+       return pw_string64( scheme, &digest, NULL );
+;
 }
+
+#ifdef SLAPD_CRYPT
+static struct berval *hash_crypt(
+       const struct pw_scheme *scheme,
+       const struct berval *passwd )
+{
+       struct berval hash;
+       unsigned char salt[3];
+       int i;
+
+       for( i=0; i<passwd->bv_len; i++) {
+               if(passwd->bv_val[i] == '\0') {
+                       return NULL;    /* NUL character in password */
+               }
+       }
+
+       if( passwd->bv_val[i] != '\0' ) {
+               return NULL;    /* passwd must behave like a string */
+       }
+
+       if( lutil_entropy( salt, sizeof(salt)) < 0 ) {
+               return NULL; 
+       }
+
+       salt[0] = crypt64[ salt[0] % (sizeof(crypt64)-1) ];
+       salt[1] = crypt64[ salt[1] % (sizeof(crypt64)-1) ];
+       salt[2] = '\0';
+
+       hash.bv_val = crypt( passwd->bv_val, salt );
+
+       if( hash.bv_val == NULL ) return NULL;
+
+       hash.bv_len = strlen( hash.bv_val );
+
+       if( hash.bv_len == 0 ) {
+               return NULL;
+       }
+
+       return pw_string( scheme, &hash );
+}
+#endif
diff --git a/libraries/liblutil/passwd.dsp b/libraries/liblutil/passwd.dsp
new file mode 100644 (file)
index 0000000..e5aa45b
--- /dev/null
@@ -0,0 +1,201 @@
+# Microsoft Developer Studio Project File - Name="passwd" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=passwd - Win32 DLL Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "passwd.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "passwd.mak" CFG="passwd - Win32 DLL Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "passwd - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "passwd - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "passwd - Win32 Single Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "passwd - Win32 Single Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "passwd - Win32 DLL Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "passwd - Win32 DLL Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "passwd - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\passwd"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\Release"
+
+!ELSEIF  "$(CFG)" == "passwd - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "passwd___"
+# PROP BASE Intermediate_Dir "passwd___"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\passwd"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Debug"
+
+!ELSEIF  "$(CFG)" == "passwd - Win32 Single Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "passwd___"
+# PROP BASE Intermediate_Dir "passwd___"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\passwd"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 olber32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\Debug"
+# ADD LINK32 ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\SDebug"
+
+!ELSEIF  "$(CFG)" == "passwd - Win32 Single Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "passwd__0"
+# PROP BASE Intermediate_Dir "passwd__0"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\passwd"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 olber32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\Release"
+# ADD LINK32 ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\SRelease"
+
+!ELSEIF  "$(CFG)" == "passwd - Win32 DLL Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "passwd___"
+# PROP BASE Intermediate_Dir "passwd___"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\DLLDebug"
+# PROP Intermediate_Dir "..\..\DLLDebug\passwd"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Debug"
+# ADD LINK32 ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Debug"
+
+!ELSEIF  "$(CFG)" == "passwd - Win32 DLL Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "passwd__0"
+# PROP BASE Intermediate_Dir "passwd__0"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "passwd__0"
+# PROP Intermediate_Dir "passwd__0"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\Release"
+# ADD LINK32 ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\Release"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "passwd - Win32 Release"
+# Name "passwd - Win32 Debug"
+# Name "passwd - Win32 Single Debug"
+# Name "passwd - Win32 Single Release"
+# Name "passwd - Win32 DLL Debug"
+# Name "passwd - Win32 DLL Release"
+# Begin Source File
+
+SOURCE=.\ptest.c
+# End Source File
+# End Target
+# End Project
diff --git a/libraries/liblutil/passwd.dsw b/libraries/liblutil/passwd.dsw
new file mode 100644 (file)
index 0000000..4746b74
--- /dev/null
@@ -0,0 +1,44 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "passwd"=.\passwd.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name liblber
+    End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "liblber"=.\liblber.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/libraries/liblutil/ptest.c b/libraries/liblutil/ptest.c
new file mode 100644 (file)
index 0000000..dc972b0
--- /dev/null
@@ -0,0 +1,105 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/stdlib.h>
+
+#include <ac/ctype.h>
+#include <ac/signal.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/time.h>
+
+#include <lber.h>
+
+#include "lutil.h"
+
+// #define SLAP_AUTHPASSWD 1
+
+/*
+ * Password Test Program
+ */
+
+char *hash[] = {
+#ifdef SLAP_AUTHPASSWD
+       "SHA1", "MD5",
+#else
+#ifdef SLAPD_CRYPT
+       "{CRYPT}",
+#endif
+       "{SSHA}", "{SMD5}",
+       "{SHA}", "{MD5}",
+       "{BOGUS}",
+#endif
+       NULL
+};
+
+static struct berval pw[] = {
+       { sizeof("secret")-1,                   "secret" },
+       { sizeof("binary\0secret")-1,   "binary\0secret" },
+       { 0, NULL }
+};
+
+int
+main( int argc, char *argv[] )
+{
+       int i, j, rc;
+       struct berval *passwd;
+#ifdef SLAP_AUTHPASSWD
+       struct berval *salt;
+#endif
+       struct berval bad;
+       bad.bv_val = "bad password";
+       bad.bv_len = sizeof("bad password")-1;
+
+       for( i= 0; hash[i]; i++ ) {
+               for( j = 0; pw[j].bv_len; j++ ) {
+#ifdef SLAP_AUTHPASSWD
+                       rc = lutil_authpasswd_hash( &pw[j],
+                               &passwd, &salt, hash[i] );
+
+                       if( rc )
+#else
+                       passwd = lutil_passwd_hash( &pw[j], hash[i] );
+
+                       if( passwd == NULL )
+#endif
+                       {
+                               printf("%s generate fail: %s (%d)\n", 
+                                       hash[i], pw[j].bv_val, pw[j].bv_len );
+                               continue;
+                       }
+
+
+#ifdef SLAP_AUTHPASSWD
+                       rc = lutil_authpasswd( &pw[j], passwd, salt, NULL );
+#else
+                       rc = lutil_passwd( passwd, &pw[j], NULL );
+#endif
+
+                       printf("%s (%d): %s (%d)\t(%d) %s\n",
+                               pw[j].bv_val, pw[j].bv_len, passwd->bv_val, passwd->bv_len,
+                               rc, rc == 0 ? "OKAY" : "BAD" );
+
+#ifdef SLAP_AUTHPASSWD
+                       rc = lutil_authpasswd( passwd, salt, &bad, NULL );
+#else
+                       rc = lutil_passwd( passwd, &bad, NULL );
+#endif
+
+                       printf("%s (%d): %s (%d)\t(%d) %s\n",
+                               bad.bv_val, bad.bv_len, passwd->bv_val, passwd->bv_len,
+                               rc, rc != 0 ? "OKAY" : "BAD" );
+               }
+
+               printf("\n");
+       }
+
+       return EXIT_SUCCESS;
+}
\ No newline at end of file
index f8c38a1a66501eb2b14b9f8f44e8ff4b1815f95f..b3e608b606f3b5b8d1db91c3c1b03c864b6fd7db 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*     Acquired from:
@@ -20,6 +20,9 @@
  *   34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
  */
 
+/*
+ * This code assumes uint32 is 32 bits and char is 8 bits
+ */
 
 #include "portable.h"
 #include <ac/string.h>
 /* include socket.h to get sys/types.h and/or winsock2.h */
 #include <ac/socket.h>
 
-#if defined(HAVE_SYS_PARAM_H)
-#include <sys/param.h>
-#endif
+#include <ac/param.h>
 
 #include "lutil_sha1.h"
 
+/* undefining this will cause pointer alignment errors */
 #define SHA1HANDSOFF           /* Copies data before messing with it. */
 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
 
@@ -67,13 +69,11 @@ lutil_SHA1Transform( uint32 *state, const unsigned char *buffer )
 {
     uint32 a, b, c, d, e;
 
-       /* Assumes u_int is 32 bits and char 8 bits.
-        * I don't know why uint32 isn't used (or what the difference is). */
 #ifdef SHA1HANDSOFF
-    u_int block[16];
+    uint32 block[16];
     (void)memcpy(block, buffer, 64);
 #else
-    u_int *block = (u_int *)buffer;
+    uint32 *block = (u_int32 *) buffer;
 #endif
 
     /* Copy context->state[] to working vars */
diff --git a/libraries/liblutil/slapdmsg.bin b/libraries/liblutil/slapdmsg.bin
new file mode 100644 (file)
index 0000000..89a6c4a
Binary files /dev/null and b/libraries/liblutil/slapdmsg.bin differ
diff --git a/libraries/liblutil/slapdmsg.h b/libraries/liblutil/slapdmsg.h
new file mode 100644 (file)
index 0000000..cb952be
--- /dev/null
@@ -0,0 +1,65 @@
+//
+// This file contains message strings for the OpenLDAP slapd service.
+//
+// This file should be compiled as follows
+//   mc -v slapdmsg.mc  -r $(IntDir)  
+//   rc /v /r  $(IntDir)\slapdmsg.rc
+// The mc (message compiler) command generates the .rc and .h files from this file. The 
+// rc (resource compiler) takes the .rc file and produces a .res file that can be linked 
+// with the final executable application. The application is then registered as a message
+// source with by creating the appropriate entries in the system registry.
+//
+//
+//  Values are 32 bit values layed out as follows:
+//
+//   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+//   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+//  +---+-+-+-----------------------+-------------------------------+
+//  |Sev|C|R|     Facility          |               Code            |
+//  +---+-+-+-----------------------+-------------------------------+
+//
+//  where
+//
+//      Sev - is the severity code
+//
+//          00 - Success
+//          01 - Informational
+//          10 - Warning
+//          11 - Error
+//
+//      C - is the Customer code flag
+//
+//      R - is a reserved bit
+//
+//      Facility - is the facility code
+//
+//      Code - is the facility's status code
+//
+//
+// Define the facility codes
+//
+
+
+//
+// Define the severity codes
+//
+
+
+//
+// MessageId: MSG_SLAPD_STARTED
+//
+// MessageText:
+//
+//  OpenLDAP SLAPD service started. debuglevel=%1, conffile=%2, urls=%3, mode=%4
+//
+#define MSG_SLAPD_STARTED                0x40000500L
+
+//
+// MessageId: MSG_SLAPD_STOPPED
+//
+// MessageText:
+//
+//  OpenLDAP SLAPD service stopped.
+//
+#define MSG_SLAPD_STOPPED                0x40000501L
+
diff --git a/libraries/liblutil/slapdmsg.rc b/libraries/liblutil/slapdmsg.rc
new file mode 100644 (file)
index 0000000..01d0d06
--- /dev/null
@@ -0,0 +1,2 @@
+LANGUAGE 0x9,0x4
+1 11 slapdmsg.bin
index 39bcde0fb09cdfed198864741aceb00c2c120a53..648009d315f7eb24c6a882d135b6ca2fdf067334 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -33,7 +33,7 @@ int lutil_pair( LBER_SOCKET_T sds[2] )
        if ( sd == AC_SOCKET_INVALID )
                return sd;
        
-       (void) memset( (void*) &si, 0, len );
+       (void) memset( (void*) &si, '\0', len );
        si.sin_family = AF_INET;
        si.sin_port = 0;
        si.sin_addr.s_addr = htonl( INADDR_LOOPBACK );
index 0f0f3704a2b7d7138fca3fce03b9d2af2d33e8f4..ad597621ab91089b4409b00fd62eae14e75c60ae 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -9,6 +9,7 @@
 #include <ac/stdlib.h>
 #include <ac/string.h>
 
+#include <lber.h>
 #include <lutil.h>
 #include <ldap_defaults.h>
 
@@ -17,11 +18,11 @@ char* lutil_progname( const char* name, int argc, char *argv[] )
        char *progname;
 
        if(argc == 0) {
-               return strdup( name );
+               return ber_strdup( name );
        }
 
        progname = strrchr ( argv[0], *LDAP_DIRSEP );
-       progname = strdup( progname ? &progname[1] : argv[0] );
+       progname = ber_strdup( progname ? &progname[1] : argv[0] );
 
        return progname;
 }
index 9cf821cda514b9e62ffc752f9bde648084067d71..f44196330a3d832fc44a179967f235f30ab74846 100644 (file)
@@ -1,5 +1,5 @@
 # $OpenLDAP$
-## Copyright 1998 The OpenLDAP Foundation, All Rights Reserved.
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
 ## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 ##
 ## servers Makefile.in for OpenLDAP
index 8752f3f40c41c2617c38bd56a4b31d51264aea6c..8d618e927b01365ad8bc47dd071334054fab5dc7 100644 (file)
@@ -5,36 +5,46 @@
 PROGRAMS=slapd
 XPROGRAMS=sslapd libbackends.a .backend
 XSRCS=version.c
+
+NT_SRCS = nt_svc.c
+NT_OBJS = nt_svc.o ../../libraries/liblutil/slapdmsg.res
+
 SRCS   = main.c daemon.c connection.c search.c filter.c add.c charray.c \
                attr.c entry.c config.c backend.c result.c operation.c \
                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 \
-               schema.c schemaparse.c monitor.c configinfo.c \
-               root_dse.c sasl.c module.c suffixalias.c
+               repl.c lock.c controls.c extended.c kerberos.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 \
+               monitor.c configinfo.c starttls.c index.c \
+               root_dse.c sasl.c module.c suffixalias.c $(@PLAT@_SRCS)
+
 OBJS   = main.o daemon.o connection.o search.o filter.o add.o charray.o \
                attr.o entry.o config.o backend.o result.o operation.o \
                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 \
-               schema.o schemaparse.o monitor.o configinfo.o \
-               root_dse.o sasl.o module.o suffixalias.o
+               repl.o lock.o controls.o extended.o kerberos.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 \
+               monitor.o configinfo.o starttls.o index.o \
+               root_dse.o sasl.o module.o suffixalias.o $(@PLAT@_OBJS)
 
 LDAP_INCDIR= ../../include
 LDAP_LIBDIR= ../../libraries
 
 SLAP_DIR=
 SLAPD_MODULES=@SLAPD_MODULES_LIST@
+
 XDEFS = $(MODULES_CPPFLAGS)
 XLDFLAGS = $(MODULES_LDFLAGS) $(SLAPD_MODULES)
 
 # $(LTHREAD_LIBS) must be last
-XLIBS = libbackends.a -lavl -lldbm -lldif -lldap_r -llber -llutil
+XLIBS = libbackends.a -lavl -lldbm -lldif -llutil -lldap_r -llber
 XXLIBS = $(LDBM_LIBS) $(SLAPD_LIBS) \
-       $(PERL_LDFLAGS) $(SECURITY_LIBS) \
-       $(LDIF_LIBS) $(LUTIL_LIBS)
+        $(SECURITY_LIBS) \
+        $(LDIF_LIBS) $(LUTIL_LIBS)
 XXXLIBS = $(LTHREAD_LIBS) $(MODULES_LIBS)
 
 BUILD_OPT = "--enable-slapd"
@@ -42,18 +52,118 @@ BUILD_SRV = @BUILD_SLAPD@
 
 all-local-srv: all-cffiles
 
-slapd: libbackends.a version.o
-       $(LTLINK) -o $@ $(OBJS) version.o $(LIBS)
+NT_DYN_DEFS  = -DLIBLBER_DECL=dllimport -DLIBLDAP_DECL=dllimport
+
+DEFINES = $(@PLAT@_@LIB_LINKAGE@_DEFS)
+
+# The tricky part about building slapd in NT is that it will export symbols
+# like a DLL. The symbols that it exports should be representative of all
+# of the static symbols that it knows about.
+
+NT_EXP = slapd.exp
+NT_IMPLIB = libslapd.a
+NT_DUMMY  = symdummy.o
+
+# Add extra def targets here
+EXTRA_DEFS =
+
+# NT needs this if libltdl is built statically. You'll have to fix the path
+# to point to where libltdl was built, then put ltdl.def in EXTRA_DEFS
+ltdl.def: ../../../libtool/libltdl/*.o
+       dlltool --export-all-symbols --output-def $@ $^
+
+DYNAMIC_DEFS = liblber.def libldap_r.def
+
+STATIC_DEFS = libavl.def libldbm.def libldif.def liblutil.def slapd.def \
+             $(EXTRA_DEFS)
+
+libavl.def: $(LDAP_LIBDIR)/libavl/*.o
+       dlltool --export-all-symbols --output-def $@ `ls $^ | grep -v test`
+
+liblber.def: $(LDAP_LIBDIR)/liblber/*.o
+       dlltool --export-all-symbols --output-def $@ `ls $^ | grep -v test`
+
+libldap_r.def: $(LDAP_LIBDIR)/libldap_r/*.o
+       dlltool --export-all-symbols --output-def $@ `ls $^ | grep -v test`
+
+libldbm.def: $(LDAP_LIBDIR)/libldbm/*.o
+       dlltool --export-all-symbols --output-def $@ `ls $^ | grep -v test`
+
+libldif.def: $(LDAP_LIBDIR)/libldif/*.o
+       dlltool --export-all-symbols --output-def $@ `ls $^ | grep -v test`
+
+liblutil.def: $(LDAP_LIBDIR)/liblutil/*.o
+       dlltool --export-all-symbols --output-def $@ `ls $^ | grep -v test`
+
+slapd.def: $(OBJS) version.o
+       dlltool --export-all-symbols --exclude-symbols main,ServiceMain@8 --output-def $@ `ls $^ | grep -v test`
+
+# We don't want to include symbols from dynamic libraries.
+all.def: $(STATIC_DEFS) $(DYNAMIC_DEFS)
+       cat $(STATIC_DEFS) | grep " @ " | sed -e 's/ @ [0-9]*//' > $@
+       if [ "@LIB_LINKAGE@" != "DYN" ] ; \
+       then \
+           cat $(DYNAMIC_DEFS) | grep " @ " | sed -e 's/ @ [0-9]*//' >> $@; \
+       fi
+       echo EXPORTS > tmp.def
+       sort $@ >> tmp.def
+       rm -f $@
+       dlltool --input-def tmp.def --output-def $@
+       rm -f tmp.def
+
+DUMMYTMP = symdummytmp.c
+
+symdummy.c: all.def $(ALL_DEFS)
+       rm -f $@
+       echo "static void never_called() {" > $(DUMMYTMP)
+       cat $< | grep " @ " | while read line; \
+       do \
+           set dummy $$line; \
+           case $$# in \
+               5) \
+                   echo "int $$2();" >> $@; \
+                   echo "$$2();" >> $(DUMMYTMP); \
+                   ;; \
+               6) \
+                   echo "extern int $$2;" >> $@; \
+                   echo "$$2 = 0;" >> $(DUMMYTMP); \
+                   ;; \
+           esac; \
+       done
+       echo "" >> $@
+       echo "}" >> $(DUMMYTMP)
+       cat $(DUMMYTMP) >> $@
+       rm -f $(DUMMYTMP)
+
+symdummy.o: symdummy.c
+       $(CC) $(CFLAGS) -c $<
+
+SLAPD_OBJS = $(OBJS) version.o symdummy.o
+
+slapd.exp: libbackends.a all.def $(SLAPD_OBJS)
+       $(LTLINK) -o slapd $(SLAPD_OBJS) $(LIBS) $(WRAP_LIBS) -Wl,--base-file,slapd.base
+       rm -f slapd.exe
+       dlltool --dllname slapd.exe --input-def all.def --base-file slapd.base --output-exp $@
+       $(LTLINK) -o slapd $(SLAPD_OBJS) $(LIBS) $(WRAP_LIBS) $@ -Wl,--base-file,slapd.base
+       rm -f slapd.exe
+       dlltool --dllname slapd.exe --input-def all.def --base-file slapd.base --output-exp $@
+
+libslapd.a: all.def
+       dlltool --dllname slapd.exe --input-def $< --output-lib $@
+
+slapd: libbackends.a version.o $(@PLAT@_EXP) $(@PLAT@_DUMMY)
+       $(LTLINK) -o $@ $(@PLAT@_EXP) $(@PLAT@_DUMMY) $(OBJS) version.o $(LIBS) $(WRAP_LIBS)
        (cd tools; $(MAKE) $(MFLAGS) all)
 
 sslapd: version.o
-       $(LTLINK) -static -o $@ $(OBJS) version.o $(LIBS)
+       $(LTLINK) -static -o $@ $(OBJS) version.o $(LIBS) $(WRAP_LIBS)
 
-.backend: FORCE
+.backend: $(@PLAT@_IMPLIB) FORCE
        @for i in back-*; do \
                if [ -d $$i ]; then \
                        echo " "; echo "  cd $$i; $(MAKE) $(MFLAGS) all"; \
                        ( cd $$i; $(MAKE) $(MFLAGS) all ); \
+                       if test $$? != 0 ; then exit 1; fi ; \
                fi; \
        done; \
        echo " "
@@ -70,7 +180,7 @@ libbackends.a: .backend
                        mv $$j $${pre}$$j; \
                  done; \
                  $(AR) ruv libbackends.a *.o 2>&1 | grep -v truncated; \
-                 $(RM) *.o __.SYMDEF; \
+                 $(RM) *.o __.SYMDEF  ________64ELEL_ ; \
                  echo "added backend library $$i"; \
                ); \
        done
@@ -81,7 +191,7 @@ libbackends.a: .backend
        fi
        @ls -l libbackends.a
 
-version.c: libbackends.a $(OBJS) $(SLAPD_LIBDEPEND) 
+version.c: $(OBJS) $(SLAPD_LIBDEPEND) 
        @-$(RM) $@
        $(MKVERSION) -s -n Versionstr slapd > $@
 
@@ -90,14 +200,20 @@ depend-local-srv: FORCE
                if [ -d $$i ]; then \
                        echo; echo "  cd $$i; $(MAKE) $(MFLAGS) depend"; \
                        ( cd $$i; $(MAKE) $(MFLAGS) depend ); \
+                       if test $$? != 0 ; then exit 1; fi ; \
                fi; \
        done
+       @echo ""
+
+clean-local:
+       rm -f *.exp *.def *.base *.a *.objs symdummy.c
 
 clean-local-srv: FORCE
        @for i in back-* shell-backends tools; do \
                if [ -d $$i ]; then \
                        echo; echo "  cd $$i; $(MAKE) $(MFLAGS) clean"; \
                        ( cd $$i; $(MAKE) $(MFLAGS) clean ); \
+                       if test $$? != 0 ; then exit 1; fi ; \
                fi; \
        done
        rm -f *.tmp all-cffiles
@@ -110,53 +226,57 @@ veryclean-local-srv: FORCE
                fi; \
        done
 
-install-local-srv: install-slapd install-conf install-tools
+install-local-srv: install-slapd install-conf install-schema install-tools
 
 install-slapd: FORCE
-       @-$(MKDIR) $(libexecdir)
-       @-$(MKDIR) $(localstatedir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 slapd $(libexecdir)
+       -$(MKDIR) $(DESTDIR)$(libexecdir)
+       -$(MKDIR) $(DESTDIR)$(localstatedir)
+       $(LTINSTALL) $(INSTALLFLAGS) -s -m 755 \
+               slapd$(EXEEXT) $(DESTDIR)$(libexecdir)
        @if [ ! -z "$(SLAPD_MODULES)" ]; then \
            for i in back-* shell-backends tools; do \
                if [ -d $$i ]; then \
                        echo; echo "  cd $$i; $(MAKE) $(MFLAGS) install"; \
                        ( cd $$i; $(MAKE) $(MFLAGS) install ); \
+                       if test $$? != 0 ; then exit 1; fi ; \
                fi; \
            done; \
        fi
 
-
-CFFILES=slapd.conf slapd.at.conf slapd.oc.conf
-
 all-cffiles: slapd
-       @for i in $(CFFILES); do \
-               tmpcf=$$i.tmp; \
-               $(SED) -e 's;%SYSCONFDIR%;$(sysconfdir);' \
-                       -e 's;%LOCALSTATEDIR%;$(localstatedir);' \
-                       $(srcdir)/$$i > $$tmpcf ; \
-       done
+       $(SED) -e 's;%SYSCONFDIR%;$(sysconfdir);' \
+               -e 's;%LOCALSTATEDIR%;$(localstatedir);' \
+               -e 's;%MODULEDIR%;$(moduledir);' \
+               $(srcdir)/slapd.conf > slapd.conf.tmp ; \
        touch all-cffiles
 
-install-conf: FORCE
-       @-$(MKDIR) $(sysconfdir)
-       @for i in $(CFFILES); do \
-               tmpcf=$$i.tmp ; \
-               if test $$i = slapd.conf ; then \
-                       mode=600 ; \
-               else \
-                       mode=644 ; \
-               fi ; \
-               if test ! -f $(sysconfdir)/$$i; then \
+install-schema: FORCE
+       @-$(MKDIR) $(DESTDIR)$(sysconfdir)/schema
+       @cd $(srcdir) ; \
+       for i in schema/*.schema ; do \
+               if test ! -f $(DESTDIR)$(sysconfdir)/$$i; then \
                        echo "installing $$i in $(sysconfdir)"; \
-                       echo "$(INSTALL) $(INSTALLFLAGS) -m $$mode $$tmpcf $(sysconfdir)/$$i"; \
-                       $(INSTALL) $(INSTALLFLAGS) -m $$mode $$tmpcf $(sysconfdir)/$$i; \
+                       echo $(INSTALL) $(INSTALLFLAGS) -m 444 $$i $(DESTDIR)$(sysconfdir)/$$i; \
+                       $(INSTALL) $(INSTALLFLAGS) -m 444 $$i $(DESTDIR)$(sysconfdir)/$$i; \
                else \
-                       echo "PRESERVING EXISTING CONFIGURATION FILE $(sysconfdir)/$$i" ; \
+                       echo "PRESERVING EXISTING SCHEMA FILE $(DESTDIR)$(sysconfdir)/$$i"; \
                fi; \
-               $(INSTALL) $(INSTALLFLAGS) -m $$mode $$tmpcf $(sysconfdir)/$$i.default ; \
+               $(INSTALL) $(INSTALLFLAGS) $$i $(DESTDIR)$(sysconfdir)/$$i.default ; \
        done
 
+install-conf: FORCE
+       @-$(MKDIR) $(DESTDIR)$(sysconfdir)
+       @-$(INSTALL) -m 700 -d $(DESTDIR)$(localstatedir)/openldap-ldbm
+       $(INSTALL) $(INSTALLFLAGS) -m 600 slapd.conf.tmp $(DESTDIR)$(sysconfdir)/slapd.conf.default
+       if test ! -f $(DESTDIR)$(sysconfdir)/$$cf; then \
+               echo "installing $$cf in $(sysconfdir)"; \
+               echo "$(INSTALL) $(INSTALLFLAGS) -m 600 slapd.conf.tmp $(DESTDIR)$(sysconfdir)/slapd.conf"; \
+               $(INSTALL) $(INSTALLFLAGS) -m 600 slapd.conf.tmp $(DESTDIR)$(sysconfdir)/slapd.conf; \
+       else \
+               echo "PRESERVING EXISTING CONFIGURATION FILE $(DESTDIR)$(sysconfdir)/slapd.conf" ; \
+       fi
+
 install-tools: FORCE
-       @-$(MKDIR) $(sbindir)
+       @-$(MKDIR) $(DESTDIR)$(sbindir)
        (cd tools; $(MAKE) $(MFLAGS) install)
 
index 3340bc70f7b69308aad7b8e45fa7737037ed5052..78c14be6ba2363a69477b730ebf8f37a9ab7596b 100644 (file)
@@ -1,7 +1,7 @@
 /* abandon.c - decode and handle an ldap abandon operation */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
index 99b42832666cfed348a92eb0fac644ac35c7320b..d93d1c3ef48353a795c210b6118ce83ec9ebd293 100644 (file)
@@ -1,7 +1,7 @@
 /* acl.c - routines to parse and check acl's */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 
 #include "slap.h"
 
+static AccessControl * acl_get(
+       AccessControl *ac, int *count,
+       Backend *be, Operation *op,
+       Entry *e,
+       AttributeDescription *desc,
+       int nmatches, regmatch_t *matches );
+
+static slap_control_t acl_mask(
+       AccessControl *ac, slap_access_mask_t *mask,
+       Backend *be, Connection *conn, Operation *op,
+       Entry *e,
+       AttributeDescription *desc,
+       struct berval *val,
+       regmatch_t *matches );
+
 #ifdef SLAPD_ACI_ENABLED
-int aci_access_allowed (struct berval *aci, char *attr, Backend *be, Entry *e,
-                                       Operation *op, int access, char *edn, regmatch_t *matches);
+static int aci_mask(
+       Backend *be,
+    Connection *conn,
+       Operation *op,
+       Entry *e,
+       AttributeDescription *desc,
+       struct berval *val,
+       struct berval *aci,
+       regmatch_t *matches,
+       slap_access_t *grant,
+       slap_access_t *deny );
 #endif
 
-static int     regex_matches(char *pat, char *str, char *buf, regmatch_t *matches);
-static void    string_expand(char *newbuf, int bufsiz, char *pattern,
-                             char *match, regmatch_t *matches);
+static int     regex_matches(
+       char *pat, char *str, char *buf, regmatch_t *matches);
+static void    string_expand(
+       char *newbuf, int bufsiz, char *pattern,
+       char *match, regmatch_t *matches);
 
 
 /*
  * access_allowed - check whether op->o_ndn is allowed the requested access
  * to entry e, attribute attr, value val.  if val is null, access to
- * the whole attribute is assumed (all values).  this routine finds
- * the applicable acl and calls acl_access_allowed() to make the
- * decision.
+ * the whole attribute is assumed (all values).
  *
- * returns     0       access NOT allowed
- *             1       access allowed
+ * This routine loops through all access controls and calls
+ * acl_mask() on each applicable access control.
+ * The loop exits when a definitive answer is reached or
+ * or no more controls remain.
+ *
+ * returns:
+ *             0       access denied
+ *             1       access granted
  */
 
 int
@@ -42,168 +72,259 @@ access_allowed(
     Connection         *conn,
     Operation          *op,
     Entry              *e,
-    char               *attr,
+       AttributeDescription    *desc,
     struct berval      *val,
-    int                        access
-)
+    slap_access_t      access )
 {
-       int                             rc;
+       int                             count;
        AccessControl   *a;
-       char            *edn;
+#ifdef LDAP_DEBUG
+       char accessmaskbuf[ACCESSMASK_MAXLEN];
+#endif
+       slap_access_mask_t mask;
+       slap_control_t control;
+
+       const char *attr = desc ? desc->ad_cname->bv_val : NULL;
 
        regmatch_t       matches[MAXREMATCHES];
-       int              i;
-       int              n;
 
-       if ( be == NULL ) {
-               return( 0 );
-       }
+       Debug( LDAP_DEBUG_ACL,
+               "=> access_allowed: %s access to \"%s\" \"%s\" requested\n",
+           access2str( access ),
+               e->e_dn, attr );
 
-       edn = e->e_ndn;
+       assert( be != NULL );
+       assert( e != NULL );
+       assert( attr != NULL );
+       assert( access > ACL_NONE );
 
-       Debug( LDAP_DEBUG_ACL, "\n=> access_allowed: entry (%s) attr (%s)\n",
-               e->e_dn, attr, 0 );
+       /* grant database root access */
+       if ( be != NULL && be_isroot( be, op->o_ndn ) ) {
+               Debug( LDAP_DEBUG_ACL,
+                   "<= root access granted\n",
+                       0, 0, 0 );
+               return 1;
+       }
 
-       /* the lastmod attributes are ignored by ACL checking */
-       if ( oc_check_no_usermod_attr( attr ) ) {
-               Debug( LDAP_DEBUG_ACL, "Operational attribute: %s access allowed\n",
+       /*
+        * no-user-modification operational attributes are ignored
+        * by ACL_WRITE checking as any found here are not provided
+        * by the user
+        */
+       if ( access >= ACL_WRITE && is_at_no_user_mod( desc->ad_type ) )
+       {
+               Debug( LDAP_DEBUG_ACL, "NoUserMod Operational attribute:"
+                       " %s access granted\n",
                        attr, 0, 0 );
-               return(1);
+               return 1;
        }
 
-       memset(matches, 0, sizeof(matches));
+       /* use backend default access if no backend acls */
+       if( be != NULL && be->be_acl == NULL ) {
+               Debug( LDAP_DEBUG_ACL,
+                       "=> access_allowed: backend default %s access %s to \"%s\"\n",
+                       access2str( access ),
+                       be->be_dfltaccess >= access ? "granted" : "denied", op->o_dn );
+
+               return be->be_dfltaccess >= access;
+
+#ifdef notdef
+       /* be is always non-NULL */
+       /* use global default access if no global acls */
+       } else if ( be == NULL && global_acl == NULL ) {
+               Debug( LDAP_DEBUG_ACL,
+                       "=> access_allowed: global default %s access %s to \"%s\"\n",
+                       access2str( access ),
+                       global_default_access >= access ? "granted" : "denied", op->o_dn );
+
+               return global_default_access >= access;
+#endif
+       }
+
+       ACL_INIT(mask);
+       memset(matches, '\0', sizeof(matches));
+       
+       control = ACL_BREAK;
+       a = NULL;
+       count = 0;
 
-       a = acl_get_applicable( be, op, e, attr, MAXREMATCHES, matches );
+       while( a = acl_get( a, &count, be, op, e, desc, MAXREMATCHES, matches ) )
+       {
+               int i;
 
-       if (a) {
                for (i = 0; i < MAXREMATCHES && matches[i].rm_so > 0; i++) {
-                       Debug( LDAP_DEBUG_ARGS, "=> match[%d]: %d %d ", 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_ARGS, "%c", edn[n], 0, 0 );
+                                       Debug( LDAP_DEBUG_ACL, "%c", e->e_ndn[n], 0, 0 );
                                }
                        }
                        Debug( LDAP_DEBUG_ARGS, "\n", 0, 0, 0 );
                }
+
+               control = acl_mask( a, &mask, be, conn, op,
+                       e, desc, val, matches );
+
+               if ( control != ACL_BREAK ) {
+                       break;
+               }
+
+               memset(matches, '\0', sizeof(matches));
        }
 
-       rc = acl_access_allowed( a, attr, be, conn, e, val, op, access, edn, matches );
+       if ( ACL_IS_INVALID( mask ) ) {
+               Debug( LDAP_DEBUG_ACL,
+                       "=> access_allowed: \"%s\" (%s) invalid!\n",
+                       e->e_dn, attr, 0 );
+               ACL_INIT( mask );
 
-       Debug( LDAP_DEBUG_ACL, "\n=> access_allowed: exit (%s) attr (%s)\n",
-               e->e_dn, attr, 0);
+       } else if ( control == ACL_BREAK ) {
+               Debug( LDAP_DEBUG_ACL,
+                       "=> access_allowed: no more rules\n", 0, 0, 0);
+               ACL_INIT( mask );
+       }
+
+       Debug( LDAP_DEBUG_ACL,
+               "=> access_allowed: %s access %s by %s\n",
+               access2str( access ),
+               ACL_GRANT(mask, access) ? "granted" : "denied",
+               accessmask2str( mask, accessmaskbuf ) );
 
-       return( rc );
+       return ACL_GRANT(mask, access);
 }
 
 /*
- * acl_get_applicable - return the acl applicable to entry e, attribute
+ * acl_get - return the acl applicable to entry e, attribute
  * attr.  the acl returned is suitable for use in subsequent calls to
  * acl_access_allowed().
  */
 
-AccessControl *
-acl_get_applicable(
+static AccessControl *
+acl_get(
+       AccessControl *a,
+       int                     *count,
     Backend            *be,
-    Operation          *op,
+    Operation  *op,
     Entry              *e,
-    char               *attr,
+       AttributeDescription *desc,
     int                        nmatch,
-    regmatch_t *matches
-)
+    regmatch_t *matches )
 {
-       int             i;
-       AccessControl   *a;
-    char               *edn;
+       const char *attr;
+       int dnlen, patlen;
 
-       Debug( LDAP_DEBUG_ACL, "\n=> acl_get: entry (%s) attr (%s)\n",
-               e->e_dn, attr, 0 );
+       assert( e != NULL );
+       assert( count != NULL );
 
-       if ( be_isroot( be, op->o_ndn ) ) {
-               Debug( LDAP_DEBUG_ACL,
-                   "<= acl_get: no acl applicable to database root\n", 0, 0,
-                   0 );
-               return( NULL );
-       }
+       attr = desc ? desc->ad_cname->bv_val : NULL;
 
-    edn = e->e_ndn;
+       if( a == NULL ) {
+               if( be == NULL ) {
+                       a = global_acl;
+               } else {
+                       a = be->be_acl;
+               }
 
-       Debug( LDAP_DEBUG_ARGS, "=> acl_get: edn %s\n", edn, 0, 0 );
+               assert( a != NULL );
 
-       /* check for a backend-specific acl that matches the entry */
-       for ( i = 1, a = be->be_acl; a != NULL; a = a->acl_next, i++ ) {
-               if (a->acl_dn_pat != NULL) {
-                       Debug( LDAP_DEBUG_TRACE, "=> dnpat: [%d] %s nsub: %d\n", 
-                               i, a->acl_dn_pat, (int) a->acl_dn_re.re_nsub);
+       } else {
+               a = a->acl_next;
+       }
 
-                       if (regexec(&a->acl_dn_re, edn, nmatch, matches, 0)) {
-                               continue;
+       dnlen = strlen(e->e_ndn);
 
-                       } else {
-                               Debug( LDAP_DEBUG_TRACE, "=> acl_get:[%d]  backend ACL match\n",
-                                       i, 0, 0);
-                       }
-               }
+       for ( ; a != NULL; a = a->acl_next ) {
+               (*count) ++;
 
-               if ( a->acl_filter != NULL ) {
-                       if ( test_filter( NULL, NULL, NULL, e, a->acl_filter ) != 0 ) {
-                               continue;
-                       }
-               }
+               if (a->acl_dn_pat != NULL) {
+                       if ( a->acl_dn_style == ACL_STYLE_REGEX ) {
+                               Debug( LDAP_DEBUG_ACL, "=> dnpat: [%d] %s nsub: %d\n", 
+                                       *count, a->acl_dn_pat, (int) a->acl_dn_re.re_nsub );
 
-        Debug( LDAP_DEBUG_ARGS, "=> acl_get: [%d] check attr %s\n", i, attr, 0);
+                               if (regexec(&a->acl_dn_re, e->e_ndn, nmatch, matches, 0))
+                                       continue;
 
-               if ( attr == NULL || a->acl_attrs == NULL ||
-                       charray_inlist( a->acl_attrs, attr ) )
-               {
-                       Debug( LDAP_DEBUG_ACL, "<= acl_get: [%d] backend acl %s attr: %s\n",
-                               i, e->e_dn, attr );
-                       return( a );
-               }
-               matches[0].rm_so = matches[0].rm_eo = -1;
-       }
+                       } else {
+                               Debug( LDAP_DEBUG_ACL, "=> dn: [%d] %s\n", 
+                                       *count, a->acl_dn_pat, 0 );
 
-       /* check for a global acl that matches the entry */
-       for ( i = 1, a = global_acl; a != NULL; a = a->acl_next, i++ ) {
-               if (a->acl_dn_pat != NULL) {
-                       Debug( LDAP_DEBUG_TRACE, "=> dn pat: [%d] %s nsub: %d\n", 
-                               i, a->acl_dn_pat, (int) a->acl_dn_re.re_nsub);
+                               patlen = strlen( a->acl_dn_pat );
+                               if ( dnlen < patlen )
+                                       continue;
 
-                       if (regexec(&a->acl_dn_re, edn, nmatch, matches, 0)) {
-                               continue;
+                               if ( a->acl_dn_style == ACL_STYLE_BASE ) {
+                                       /* base dn -- entire object DN must match */
+                                       if ( dnlen != patlen )
+                                               continue;
+
+                               } else if ( a->acl_dn_style == ACL_STYLE_ONE ) {
+                                       char *rdn;
+                                       int rdnlen = -1;
+
+                                       if ( dnlen <= patlen )
+                                               continue;
+
+                                       if ( e->e_ndn[dnlen - patlen - 1] != ',' )
+                                               continue;
+
+                                       rdn = dn_rdn( NULL, e->e_ndn );
+                                       if ( rdn != NULL ) {
+                                               rdnlen = strlen( rdn );
+                                               ch_free( rdn );
+                                       }
+                                       if ( rdnlen != dnlen - patlen - 1 )
+                                               continue;
+
+                               } else if ( a->acl_dn_style == ACL_STYLE_SUBTREE ) {
+                                       if ( dnlen > patlen && e->e_ndn[dnlen - patlen - 1] != ',' )
+                                               continue;
+
+                               } else if ( a->acl_dn_style == ACL_STYLE_CHILDREN ) {
+                                       if ( dnlen <= patlen )
+                                               continue;
+                                       if ( e->e_ndn[dnlen - patlen - 1] != ',' )
+                                               continue;
+                               }
 
-                       } else {
-                               Debug( LDAP_DEBUG_TRACE, "=> acl_get: [%d] global ACL match\n",
-                                       i, 0, 0);
+                               if ( strcmp( a->acl_dn_pat, e->e_ndn + dnlen - patlen ) != 0 )
+                                       continue;
                        }
+
+                       Debug( LDAP_DEBUG_ACL, "=> acl_get: [%d] matched\n",
+                               *count, 0, 0 );
                }
 
                if ( a->acl_filter != NULL ) {
-                       if ( test_filter( NULL, NULL, NULL, e, a->acl_filter ) != 0 ) {
+                       ber_int_t rc = test_filter( NULL, NULL, NULL, e, a->acl_filter );
+                       if ( rc != LDAP_COMPARE_TRUE ) {
                                continue;
                        }
                }
 
-               Debug( LDAP_DEBUG_ARGS, "=> acl_get: [%d] check attr\n", i, 0, 0);
+        Debug( LDAP_DEBUG_ACL, "=> acl_get: [%d] check attr %s\n",
+                       *count, attr, 0);
 
                if ( attr == NULL || a->acl_attrs == NULL ||
-                       charray_inlist( a->acl_attrs, attr ) )
+                       ad_inlist( desc, a->acl_attrs ) )
                {
-                       Debug( LDAP_DEBUG_ACL, "<= acl_get: [%d] global acl %s attr: %s\n",
-                               i, e->e_dn, attr );
-                       return( a );
+                       Debug( LDAP_DEBUG_ACL,
+                               "<= acl_get: [%d] acl %s attr: %s\n",
+                               *count, e->e_dn, attr );
+                       return a;
                }
-
                matches[0].rm_so = matches[0].rm_eo = -1;
        }
 
-       Debug( LDAP_DEBUG_ACL, "<= acl_get: no match\n", 0, 0, 0 );
+       Debug( LDAP_DEBUG_ACL, "<= acl_get: done.\n", 0, 0, 0 );
        return( NULL );
 }
 
+
 /*
- * acl_access_allowed - check whether the given acl allows dn the
+ * acl_mask - modifies mask based upon the given acl and the
  * requested access to entry e, attribute attr, value val.  if val
  * is null, access to the whole attribute is assumed (all values).
  *
@@ -211,152 +332,242 @@ acl_get_applicable(
  *             1       access allowed
  */
 
-int
-acl_access_allowed(
+static slap_control_t
+acl_mask(
     AccessControl      *a,
-    char               *attr,
+       slap_access_mask_t *mask,
     Backend            *be,
-    Connection         *conn,
+    Connection *conn,
+    Operation  *op,
     Entry              *e,
+       AttributeDescription *desc,
     struct berval      *val,
-    Operation          *op,
-    int                        access,
-       char            *edn,
        regmatch_t      *matches
 )
 {
-       int             i;
+       int             i, odnlen, patlen;
        Access  *b;
-       int             default_access;
+#ifdef LDAP_DEBUG
+       char accessmaskbuf[ACCESSMASK_MAXLEN];
+#endif
+       const char *attr = desc ? desc->ad_cname->bv_val : NULL;
 
-       Debug( LDAP_DEBUG_ACL,
-               "\n=> acl_access_allowed: %s access to entry \"%s\"\n",
-               access2str( access ), e->e_dn, 0 );
+       assert( a != NULL );
+       assert( mask != NULL );
 
        Debug( LDAP_DEBUG_ACL,
-               "\n=> acl_access_allowed: %s access to value \"%s\" by \"%s\"\n",
-           access2str( access ),
-               val ? val->bv_val : "any",
-               op->o_ndn ?  op->o_ndn : "" );
+               "=> acl_mask: access to entry \"%s\", attr \"%s\" requested\n",
+               e->e_dn, attr, 0 );
 
-       if ( be_isroot( be, op->o_ndn ) ) {
-               Debug( LDAP_DEBUG_ACL,
-                       "<= acl_access_allowed: granted to database root\n",
-                   0, 0, 0 );
-               return( 1 );
-       }
+       Debug( LDAP_DEBUG_ACL,
+               "=> acl_mask: to value \"%s\" by \"%s\", (%s) \n",
+               val ? val->bv_val : "*",
+               op->o_ndn ?  op->o_ndn : "",
+               accessmask2str( *mask, accessmaskbuf ) );
 
-       default_access = be->be_dfltaccess ? be->be_dfltaccess : global_default_access;
+       for ( i = 1, b = a->acl_access; b != NULL; b = b->a_next, i++ ) {
+               slap_access_mask_t oldmask, modmask;
 
-       if ( a == NULL ) {
-               Debug( LDAP_DEBUG_ACL,
-                   "<= acl_access_allowed: %s by default (no matching to)\n",
-                   default_access >= access ? "granted" : "denied", 0, 0 );
-               return( default_access >= access );
-       }
+               ACL_INVALIDATE( modmask );
 
-       for ( i = 1, b = a->acl_access; b != NULL; b = b->a_next, i++ ) {
                /* AND <who> clauses */
                if ( b->a_dn_pat != NULL ) {
-                       Debug( LDAP_DEBUG_TRACE, "<= check a_dn_pat: %s\n",
+                       Debug( LDAP_DEBUG_ACL, "<= check a_dn_pat: %s\n",
                                b->a_dn_pat, 0, 0);
                        /*
                         * if access applies to the entry itself, and the
                         * user is bound as somebody in the same namespace as
                         * the entry, OR the given dn matches the dn pattern
                         */
-                       if ( strcasecmp( b->a_dn_pat, "anonymous" ) == 0 ) {
+                       if ( strcmp( b->a_dn_pat, "anonymous" ) == 0 ) {
                                if (op->o_ndn != NULL && op->o_ndn[0] != '\0' ) {
                                        continue;
                                }
 
-                       } else if ( strcasecmp( b->a_dn_pat, "self" ) == 0 ) {
+                       } else if ( strcmp( b->a_dn_pat, "users" ) == 0 ) {
+                               if (op->o_ndn == NULL || op->o_ndn[0] == '\0' ) {
+                                       continue;
+                               }
+
+                       } else if ( strcmp( b->a_dn_pat, "self" ) == 0 ) {
                                if( op->o_ndn == NULL || op->o_ndn[0] == '\0' ) {
                                        continue;
                                }
                                
-                               if ( e->e_dn == NULL || strcmp( edn, op->o_ndn ) != 0 ) {
+                               if ( e->e_dn == NULL || strcmp( e->e_ndn, op->o_ndn ) != 0 ) {
                                        continue;
                                }
 
-                       } else if ( strcmp( b->a_dn_pat, ".*" ) != 0 &&
-                               !regex_matches( b->a_dn_pat, op->o_ndn, edn, matches ) )
-                       {
-                               continue;
+                       } else if ( b->a_dn_style == ACL_STYLE_REGEX ) {
+                               if ( strcmp( b->a_dn_pat, "*" ) != 0 ) {
+                                       int ret = regex_matches( b->a_dn_pat,
+                                               op->o_ndn, e->e_ndn, matches );
+
+                                       if( ret == 0 ) {
+                                               continue;
+                                       }
+                               }
+
+                       } else {
+                               if ( e->e_dn == NULL )
+                                       continue;
+
+                               patlen = strlen( b->a_dn_pat );
+                               odnlen = strlen( op->o_ndn );
+                               if ( odnlen < patlen )
+                                       continue;
+
+                               if ( b->a_dn_style == ACL_STYLE_BASE ) {
+                                       /* base dn -- entire object DN must match */
+                                       if ( odnlen != patlen )
+                                               continue;
+
+                               } else if ( b->a_dn_style == ACL_STYLE_ONE ) {
+                                       char *rdn;
+                                       int rdnlen = -1;
+
+                                       if ( odnlen <= patlen )
+                                               continue;
+
+                                       if ( op->o_ndn[odnlen - patlen - 1] != ',' )
+                                               continue;
+
+                                       rdn = dn_rdn( NULL, op->o_ndn );
+                                       if ( rdn != NULL ) {
+                                               rdnlen = strlen( rdn );
+                                               ch_free( rdn );
+                                       }
+                                       if ( rdnlen != odnlen - patlen - 1 )
+                                               continue;
+
+                               } else if ( b->a_dn_style == ACL_STYLE_SUBTREE ) {
+                                       if ( odnlen > patlen && op->o_ndn[odnlen - patlen - 1] != ',' )
+                                               continue;
+
+                               } else if ( b->a_dn_style == ACL_STYLE_CHILDREN ) {
+                                       if ( odnlen <= patlen )
+                                               continue;
+                                       if ( op->o_ndn[odnlen - patlen - 1] != ',' )
+                                               continue;
+                               }
+
+                               if ( strcmp( b->a_dn_pat, op->o_ndn + odnlen - patlen ) != 0 )
+                                       continue;
+
                        }
                }
 
                if ( b->a_sockurl_pat != NULL ) {
-                       Debug( LDAP_DEBUG_ARGS, "<= check a_sockurl_pat: %s\n",
+                       Debug( LDAP_DEBUG_ACL, "<= check a_sockurl_pat: %s\n",
                                b->a_sockurl_pat, 0, 0 );
 
-                       if ( strcmp( b->a_sockurl_pat, ".*" ) != 0 &&
-                               !regex_matches( b->a_sockurl_pat, conn->c_listener_url,
-                               edn, matches ) ) 
-                       {
-                               continue;
+                       if ( strcmp( b->a_sockurl_pat, "*" ) != 0) {
+                               if ( b->a_sockurl_style == ACL_STYLE_REGEX) {
+                                       if (!regex_matches( b->a_sockurl_pat, conn->c_listener_url,
+                                                       e->e_ndn, matches ) ) 
+                                       {
+                                               continue;
+                                       }
+                               } else {
+                                       if ( strcasecmp( b->a_sockurl_pat, conn->c_listener_url ) == 0 )
+                                               continue;
+                               }
                        }
                }
 
                if ( b->a_domain_pat != NULL ) {
-                       Debug( LDAP_DEBUG_ARGS, "<= check a_domain_pat: %s\n",
+                       Debug( LDAP_DEBUG_ACL, "<= check a_domain_pat: %s\n",
                                b->a_domain_pat, 0, 0 );
 
-                       if ( strcmp( b->a_domain_pat, ".*" ) != 0 &&
-                               !regex_matches( b->a_domain_pat, conn->c_peer_domain,
-                               edn, matches ) ) 
-                       {
-                               continue;
+                       if ( strcmp( b->a_domain_pat, "*" ) != 0) {
+                               if ( b->a_domain_style == ACL_STYLE_REGEX) {
+                                       if (!regex_matches( b->a_domain_pat, conn->c_peer_domain,
+                                                       e->e_ndn, matches ) ) 
+                                       {
+                                               continue;
+                                       }
+                               } else {
+                                       if ( strcasecmp( b->a_domain_pat, conn->c_peer_domain ) == 0 )
+                                               continue;
+                               }
                        }
                }
 
                if ( b->a_peername_pat != NULL ) {
-                       Debug( LDAP_DEBUG_ARGS, "<= check a_peername_path: %s\n",
+                       Debug( LDAP_DEBUG_ACL, "<= check a_peername_path: %s\n",
                                b->a_peername_pat, 0, 0 );
 
-                       if ( strcmp( b->a_peername_pat, ".*" ) != 0 &&
-                               !regex_matches( b->a_peername_pat, conn->c_peer_name,
-                               edn, matches ) )
-                       {
-                               continue;
+                       if ( strcmp( b->a_peername_pat, "*" ) != 0) {
+                               if ( b->a_peername_style == ACL_STYLE_REGEX) {
+                                       if (!regex_matches( b->a_peername_pat, conn->c_peer_name,
+                                                       e->e_ndn, matches ) ) 
+                                       {
+                                               continue;
+                                       }
+                               } else {
+                                       if ( strcasecmp( b->a_peername_pat, conn->c_peer_name ) == 0 )
+                                               continue;
+                               }
                        }
                }
 
                if ( b->a_sockname_pat != NULL ) {
-                       Debug( LDAP_DEBUG_ARGS, "<= check a_sockname_path: %s\n",
+                       Debug( LDAP_DEBUG_ACL, "<= check a_sockname_path: %s\n",
                                b->a_sockname_pat, 0, 0 );
 
-                       if ( strcmp( b->a_sockname_pat, ".*" ) != 0 &&
-                               !regex_matches( b->a_sockname_pat, conn->c_sock_name,
-                               edn, matches ) )
-                       {
-                               continue;
+                       if ( strcmp( b->a_sockname_pat, "*" ) != 0) {
+                               if ( b->a_sockname_style == ACL_STYLE_REGEX) {
+                                       if (!regex_matches( b->a_sockname_pat, conn->c_sock_name,
+                                                       e->e_ndn, matches ) ) 
+                                       {
+                                               continue;
+                                       }
+                               } else {
+                                       if ( strcasecmp( b->a_sockname_pat, conn->c_sock_name ) == 0 )
+                                               continue;
+                               }
                        }
                }
 
                if ( b->a_dn_at != NULL && op->o_ndn != NULL ) {
                        Attribute       *at;
                        struct berval   bv;
+                       int match;
+                       const char *text;
+                       const char *desc = b->a_dn_at->ad_cname->bv_val;
 
-                       Debug( LDAP_DEBUG_ARGS, "<= check a_dn_at: %s\n",
-                               b->a_dn_at, 0, 0);
+                       Debug( LDAP_DEBUG_ACL, "<= check a_dn_at: %s\n",
+                               desc, 0, 0);
 
                        bv.bv_val = op->o_ndn;
                        bv.bv_len = strlen( bv.bv_val );
 
-                       /* see if asker is listed in dnattr */ 
-                       if ( (at = attr_find( e->e_attrs, b->a_dn_at )) != NULL &&
-                               value_find( at->a_vals, &bv, at->a_syntax, 3 ) == 0 )
+                       /* see if asker is listed in dnattr */
+                       for( at = attrs_find( e->e_attrs, b->a_dn_at );
+                               at == NULL;
+                               at = attrs_find( e->e_attrs->a_next, b->a_dn_at ) )
                        {
-                               if ( ACL_IS_SELF(b->a_access) && 
-                                       (val == NULL || value_cmp( &bv, val, at->a_syntax, 2 )) )
+                               if( value_find( b->a_dn_at, at->a_vals, &bv ) == 0 ) {
+                                       /* found it */
+                                       match = 1;
+                                       break;
+                               }
+                       }
+
+                       if( match ) {
+                               if ( b->a_dn_self && (val == NULL
+                                       || value_match( &match, b->a_dn_at,
+                                               b->a_dn_at->ad_type->sat_equality, val, &bv, &text ) )
+                                               != LDAP_SUCCESS
+                                       || match )
                                {
                                        continue;
                                }
-
-                       /* asker not listed in dnattr - check for self access */
-                       } else if ( ! ACL_IS_SELF(b->a_access) || val == NULL ||
-                               value_cmp( &bv, val, at->a_syntax, 2 ) != 0 )
+                       } else if ( ! b->a_dn_self || val == NULL
+                               || value_match( &match, b->a_dn_at,
+                                       b->a_dn_at->ad_type->sat_equality, val, &bv, &text )
+                                       != LDAP_SUCCESS
+                               || match )
                        {
                                continue;
                        }
@@ -370,10 +581,15 @@ acl_access_allowed(
                         * the values in the attribute group
                         */
                        /* see if asker is listed in dnattr */
-                       string_expand(buf, sizeof(buf), b->a_group_pat, edn, matches);
-                       if ( dn_normalize_case(buf) == NULL ) {
-                               /* did not expand to a valid dn */
-                               continue;
+                       if ( b->a_group_style != ACL_STYLE_REGEX ) {
+                               string_expand(buf, sizeof(buf), b->a_group_pat, e->e_ndn, matches);
+                               if ( dn_normalize(buf) == NULL ) {
+                                       /* did not expand to a valid dn */
+                                       continue;
+                               }
+                       } else {
+                               strncpy( buf, b->a_group_pat, sizeof(buf) - 1 );
+                               buf[sizeof(buf) - 1] = 0;
                        }
 
                        if (backend_group(be, e, buf, op->o_ndn,
@@ -384,12 +600,13 @@ acl_access_allowed(
                }
 
 #ifdef SLAPD_ACI_ENABLED
-               if ( b->a_aci_at != NULL ) {                            
+               if ( b->a_aci_at != NULL ) {
                        Attribute       *at;
+                       slap_access_t grant, deny, tgrant, tdeny;
 
                        /* this case works different from the others above.
                         * since aci's themselves give permissions, we need
-                        * to first check b->a_access, the ACL's access level.
+                        * to first check b->a_mask, the ACL's access level.
                         */
 
                        if( op->o_ndn == NULL || op->o_ndn[0] == '\0' ) {
@@ -400,10 +617,10 @@ acl_access_allowed(
                                continue;
                        }
 
-                       /* first check if the right being requested is
-                        * higher than allowed by the ACL clause.
+                       /* first check if the right being requested
+                        * is allowed by the ACL clause.
                         */
-                       if ( ! ACL_GRANT( b->a_access, access ) ) {
+                       if ( ! ACL_GRANT( b->a_mask, *mask ) ) {
                                continue;
                        }
 
@@ -413,44 +630,115 @@ acl_access_allowed(
                                continue;
                        }
 
+                       /* start out with nothing granted, nothing denied */
+                       ACL_INIT(tgrant);
+                       ACL_INIT(tdeny);
+
                        /* the aci is an multi-valued attribute.  The
                         * rights are determined by OR'ing the individual
                         * rights given by the acis.
                         */
                        for ( i = 0; at->a_vals[i] != NULL; i++ ) {
-                               if ( aci_access_allowed( at->a_vals[i], attr, be, e, op, access, edn, matches ) ) {
-                                       Debug( LDAP_DEBUG_ACL,
-                                               "<= acl_access_allowed: matched by clause #%d access granted\n",
-                                               i, 0, 0 );
-                                       return(1);
+                               if (aci_mask( be, conn, op,
+                                       e, desc, val, at->a_vals[i],
+                                       matches, &grant, &deny ) != 0)
+                               {
+                                       tgrant |= grant;
+                                       tdeny |= deny;
                                }
                        }
-                       continue;
-               }
+
+                       /* remove anything that the ACL clause does not allow */
+                       tgrant &= b->a_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 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
+               {
+                       modmask = b->a_mask;
+               }
+
+
+               Debug( LDAP_DEBUG_ACL,
+                       "<= acl_mask: [%d] applying %s (%s)\n",
+                       i, accessmask2str( modmask, accessmaskbuf ), 
+                       b->a_type == ACL_CONTINUE
+                               ? "continue"
+                               : b->a_type == ACL_BREAK
+                                       ? "break"
+                                       : "stop" );
+
+               /* save old mask */
+               oldmask = *mask;
+
+               if( ACL_IS_ADDITIVE(modmask) ) {
+                       /* add privs */
+                       ACL_PRIV_SET( *mask, modmask );
+
+                       /* cleanup */
+                       ACL_PRIV_CLR( *mask, ~ACL_PRIV_MASK );
+
+               } else if( ACL_IS_SUBTRACTIVE(modmask) ) {
+                       /* substract privs */
+                       ACL_PRIV_CLR( *mask, modmask );
+
+                       /* cleanup */
+                       ACL_PRIV_CLR( *mask, ~ACL_PRIV_MASK );
+
+               } else {
+                       /* assign privs */
+                       *mask = modmask;
+               }
 
                Debug( LDAP_DEBUG_ACL,
-                       "<= acl_access_allowed: matched by clause #%d access %s\n",
-                       i,
-                       ACL_GRANT(b->a_access, access) ? "granted" : "denied",
-                       0 );
+                       "<= acl_mask: [%d] mask: %s\n",
+                       i, accessmask2str(*mask, accessmaskbuf), 0 );
+
+               if( b->a_type == ACL_CONTINUE ) {
+                       continue;
+
+               } else if ( b->a_type == ACL_BREAK ) {
+                       return ACL_BREAK;
 
-               return ACL_GRANT(b->a_access, access );
+               } else {
+                       return ACL_STOP;
+               }
        }
 
        Debug( LDAP_DEBUG_ACL,
-               "<= acl_access_allowed: %s by default (no matching by)\n",
-           default_access >= access ? "granted" : "denied", 0, 0 );
-
-       return( default_access >= access );
+               "<= acl_mask: no more <who> clauses, returning %s (stop)\n",
+               accessmask2str(*mask, accessmaskbuf), 0, 0 );
+       return ACL_STOP;
 }
 
 /*
  * acl_check_modlist - check access control on the given entry to see if
  * it allows the given modifications by the user associated with op.
- * returns     LDAP_SUCCESS    mods allowed ok
- *             anything else   mods not allowed - return is an error
- *                             code indicating the problem
+ * returns     1       if mods allowed ok
+ *                     0       mods not allowed
  */
 
 int
@@ -459,67 +747,97 @@ acl_check_modlist(
     Connection *conn,
     Operation  *op,
     Entry      *e,
-    LDAPModList        *mlist
+    Modifications      *mlist
 )
 {
        int             i;
-       AccessControl   *a;
-       char    *edn = e->e_ndn;
 
-       for ( ; mlist != NULL; mlist = mlist->ml_next ) {
-               regmatch_t       matches[MAXREMATCHES];
+       assert( be != NULL );
+
+       /* short circuit root database access */
+       if ( be_isroot( be, op->o_ndn ) ) {
+               Debug( LDAP_DEBUG_ACL,
+                       "<= acl_access_allowed: granted to database root\n",
+                   0, 0, 0 );
+               return 1;
+       }
+
+       /* use backend default access if no backend acls */
+       if( be != NULL && be->be_acl == NULL ) {
+               Debug( LDAP_DEBUG_ACL,
+                       "=> access_allowed: backend default %s access %s to \"%s\"\n",
+                       access2str( ACL_WRITE ),
+                       be->be_dfltaccess >= ACL_WRITE ? "granted" : "denied", op->o_dn );
+
+               return be->be_dfltaccess >= ACL_WRITE;
+
+#ifdef notdef
+       /* be is always non-NULL */
+       /* use global default access if no global acls */
+       } else if ( be == NULL && global_acl == NULL ) {
+               Debug( LDAP_DEBUG_ACL,
+                       "=> access_allowed: global default %s access %s to \"%s\"\n",
+                       access2str( ACL_WRITE ),
+                       global_default_access >= ACL_WRITE ? "granted" : "denied", op->o_dn );
+
+               return global_default_access >= ACL_WRITE;
+#endif
+       }
 
-               /* the lastmod attributes are ignored by ACL checking */
-               if ( oc_check_no_usermod_attr( mlist->ml_type ) ) {
-                       Debug( LDAP_DEBUG_ACL, "Operational attribute: %s access allowed\n",
-                               mlist->ml_type, 0, 0 );
+       for ( ; mlist != NULL; mlist = mlist->sml_next ) {
+               /*
+                * no-user-modification operational attributes are ignored
+                * by ACL_WRITE checking as any found here are not provided
+                * by the user
+                */
+               if ( is_at_no_user_mod( mlist->sml_desc->ad_type ) ) {
+                       Debug( LDAP_DEBUG_ACL, "acl: no-user-mod %s:"
+                               " modify access granted\n",
+                               mlist->sml_desc->ad_cname->bv_val, 0, 0 );
                        continue;
                }
 
-               a = acl_get_applicable( be, op, e, mlist->ml_type,
-                       MAXREMATCHES, matches );
-
-               switch ( mlist->ml_op & ~LDAP_MOD_BVALUES ) {
+               switch ( mlist->sml_op ) {
                case LDAP_MOD_REPLACE:
                case LDAP_MOD_ADD:
-                       if ( mlist->ml_bvalues == NULL ) {
+                       if ( mlist->sml_bvalues == NULL ) {
                                break;
                        }
-                       for ( i = 0; mlist->ml_bvalues[i] != NULL; i++ ) {
-                               if ( ! acl_access_allowed( a, mlist->ml_type, be, conn, e, mlist->ml_bvalues[i], 
-                                       op, ACL_WRITE, edn, matches) ) 
+                       for ( i = 0; mlist->sml_bvalues[i] != NULL; i++ ) {
+                               if ( ! access_allowed( be, conn, op, e,
+                                       mlist->sml_desc, mlist->sml_bvalues[i], ACL_WRITE ) )
                                {
-                                       return( LDAP_INSUFFICIENT_ACCESS );
+                                       return( 0 );
                                }
                        }
                        break;
 
                case LDAP_MOD_DELETE:
-                       if ( mlist->ml_bvalues == NULL ) {
-                               if ( ! acl_access_allowed( a, mlist->ml_type, be, conn, e,
-                                       NULL, op, ACL_WRITE, edn, matches) ) 
+                       if ( mlist->sml_bvalues == NULL ) {
+                               if ( ! access_allowed( be, conn, op, e,
+                                       mlist->sml_desc, NULL, ACL_WRITE ) )
                                {
-                                       return( LDAP_INSUFFICIENT_ACCESS );
+                                       return( 0 );
                                }
                                break;
                        }
-                       for ( i = 0; mlist->ml_bvalues[i] != NULL; i++ ) {
-                               if ( ! acl_access_allowed( a, mlist->ml_type, be, conn, e, mlist->ml_bvalues[i], 
-                                       op, ACL_WRITE, edn, matches) ) 
+                       for ( i = 0; mlist->sml_bvalues[i] != NULL; i++ ) {
+                               if ( ! access_allowed( be, conn, op, e,
+                                       mlist->sml_desc, mlist->sml_bvalues[i], ACL_WRITE ) )
                                {
-                                       return( LDAP_INSUFFICIENT_ACCESS );
+                                       return( 0 );
                                }
                        }
                        break;
                }
        }
 
-       return( LDAP_SUCCESS );
+       return( 1 );
 }
 
 #ifdef SLAPD_ACI_ENABLED
 static char *
-aci_bvstrdup (struct berval *bv)
+aci_bvstrdup( struct berval *bv )
 {
        char *s;
 
@@ -532,7 +850,9 @@ aci_bvstrdup (struct berval *bv)
 }
 
 static int
-aci_strbvcmp (char *s, struct berval *bv)
+aci_strbvcmp(
+       const char *s,
+       struct berval *bv )
 {
        int res, len;
 
@@ -540,15 +860,19 @@ aci_strbvcmp (char *s, struct berval *bv)
        if (res)
                return(res);
        len = strlen(s);
-       if (len > bv->bv_len)
+       if (len > (int)bv->bv_len)
                return(1);
-       if (len < bv->bv_len)
+       if (len < (int)bv->bv_len)
                return(-1);
        return(0);
 }
 
 static int
-aci_get_part (struct berval *list, int ix, char sep, struct berval *bv)
+aci_get_part(
+       struct berval *list,
+       int ix,
+       char sep,
+       struct berval *bv )
 {
        int len;
        char *p;
@@ -583,17 +907,20 @@ aci_get_part (struct berval *list, int ix, char sep, struct berval *bv)
 }
 
 static int
-aci_list_has_right (struct berval *list, int access, int action)
+aci_list_map_rights(
+       struct berval *list )
 {
        struct berval bv;
-       int i, right;
+       slap_access_t mask;
+       int i;
 
+       ACL_INIT(mask);
        for (i = 0; aci_get_part(list, i, ',', &bv) >= 0; i++) {
                if (bv.bv_len <= 0)
                        continue;
                switch (*bv.bv_val) {
                case 'c':
-                       right = ACL_COMPARE;
+                       ACL_PRIV_SET(mask, ACL_PRIV_COMPARE);
                        break;
                case 's':
                        /* **** NOTE: draft-ietf-ldapext-aci-model-0.3.txt defines
@@ -601,192 +928,228 @@ aci_list_has_right (struct berval *list, int access, int action)
                         * that the right 's' means "search".  The latter definition
                         * is used here.
                         */
-                       right = ACL_SEARCH;
+                       ACL_PRIV_SET(mask, ACL_PRIV_SEARCH);
                        break;
                case 'r':
-                       right = ACL_READ;
+                       ACL_PRIV_SET(mask, ACL_PRIV_READ);
                        break;
                case 'w':
-                       right = ACL_WRITE;
+                       ACL_PRIV_SET(mask, ACL_PRIV_WRITE);
                        break;
                case 'x':
                        /* **** NOTE: draft-ietf-ldapext-aci-model-0.3.txt does not 
                         * define any equivalent to the AUTH right, so I've just used
                         * 'x' for now.
                         */
-                       right = ACL_AUTH;
+                       ACL_PRIV_SET(mask, ACL_PRIV_AUTH);
                        break;
                default:
-                       right = 0;
                        break;
                }
-#ifdef SLAPD_ACI_DISCRETE_RIGHTS
-               if (right & access) {
-                       return(action);
-               }
-       }
-       return(!action);
-#else
-               if (action != 0) {
-                       /* check granted */
-                       if (ACL_GRANT(right, access))
-                               return(1);
-               } else {
-                       /* check denied */
-                       if (right <= access)
-                               return(1);
-               }
+
        }
-       return(0);
-#endif
+       return(mask);
 }
 
 static int
-aci_list_has_attr (struct berval *list, char *attr)
+aci_list_has_attr(
+       struct berval *list,
+       const char *attr,
+       struct berval *val )
 {
-       struct berval bv;
+       struct berval bv, left, right;
        int i;
 
        for (i = 0; aci_get_part(list, i, ',', &bv) >= 0; i++) {
-               if (aci_strbvcmp(attr, &bv) == 0) {
-                       return(1);
+               if (aci_get_part(&bv, 0, '=', &left) < 0
+                       || aci_get_part(&bv, 1, '=', &right) < 0)
+               {
+                       if (aci_strbvcmp(attr, &bv) == 0)
+                               return(1);
+               } else if (val == NULL) {
+                       if (aci_strbvcmp(attr, &left) == 0)
+                               return(1);
+               } else {
+                       if (aci_strbvcmp(attr, &left) == 0) {
+                               /* this is experimental code that implements a
+                                * simple (prefix) match of the attribute value.
+                                * the ACI draft does not provide for aci's that
+                                * apply to specific values, but it would be
+                                * nice to have.  If the <attr> part of an aci's
+                                * rights list is of the form <attr>=<value>,
+                                * that means the aci applies only to attrs with
+                                * the given value.  Furthermore, if the attr is
+                                * of the form <attr>=<value>*, then <value> is
+                                * treated as a prefix, and the aci applies to 
+                                * any value with that prefix.
+                                *
+                                * Ideally, this would allow r.e. matches.
+                                */
+                               if (aci_get_part(&right, 0, '*', &left) < 0
+                                       || right.bv_len <= left.bv_len)
+                               {
+                                       if (aci_strbvcmp(val->bv_val, &right) == 0)
+                                               return(1);
+                               } else if (val->bv_len >= left.bv_len) {
+                                       if (strncasecmp( val->bv_val, left.bv_val, left.bv_len ) == 0)
+                                               return(1);
+                               }
+                       }
                }
        }
        return(0);
 }
 
-static int
-aci_list_has_attr_right (struct berval *list, char *attr, int access, int action)
+static slap_access_t
+aci_list_get_attr_rights(
+       struct berval *list,
+       const char *attr,
+       struct berval *val )
 {
     struct berval bv;
-    int i, found;
+    slap_access_t mask;
+    int i;
 
        /* loop through each rights/attr pair, skip first part (action) */
-       found = -1;
+       ACL_INIT(mask);
        for (i = 1; aci_get_part(list, i + 1, ';', &bv) >= 0; i += 2) {
-               if (aci_list_has_attr(&bv, attr) == 0)
+               if (aci_list_has_attr(&bv, attr, val) == 0)
                        continue;
-               found = 0;
                if (aci_get_part(list, i, ';', &bv) < 0)
                        continue;
-               if (aci_list_has_right(&bv, access, action) != 0)
-                       return(1);
+               mask |= aci_list_map_rights(&bv);
        }
-       return(found);
+       return(mask);
 }
 
 static int
-aci_list_has_permission (struct berval *list, char *attr, int access)
+aci_list_get_rights(
+       struct berval *list,
+       const char *attr,
+       struct berval *val,
+       slap_access_t *grant,
+       slap_access_t *deny )
 {
     struct berval perm, actn;
-    int i, action, specific, general;
+    slap_access_t *mask;
+    int i, found;
 
        if (attr == NULL || *attr == 0 || strcasecmp(attr, "entry") == 0) {
                attr = "[entry]";
        }
 
+       found = 0;
+       ACL_INIT(*grant);
+       ACL_INIT(*deny);
        /* loop through each permissions clause */
        for (i = 0; aci_get_part(list, i, '$', &perm) >= 0; i++) {
                if (aci_get_part(&perm, 0, ';', &actn) < 0)
                        continue;
                if (aci_strbvcmp( "grant", &actn ) == 0) {
-                       action = 1;
+                       mask = grant;
                } else if (aci_strbvcmp( "deny", &actn ) == 0) {
-                       action = 0;
+                       mask = deny;
                } else {
                        continue;
                }
 
-               specific = aci_list_has_attr_right(&perm, attr, access, action);
-               if (specific >= 0)
-                       return(specific);
-
-               general = aci_list_has_attr_right(&perm, "[all]", access, action);
-               if (general >= 0)
-                       return(general);
+               found = 1;
+               *mask |= aci_list_get_attr_rights(&perm, attr, val);
+               *mask |= aci_list_get_attr_rights(&perm, "[all]", NULL);
        }
-       return(0);
+       return(found);
 }
 
 static int
 aci_group_member (
        struct berval *subj,
-       char *grpoc,
-       char *grpat,
+       const char *defgrpoc,
+       const char *defgrpat,
     Backend            *be,
     Entry              *e,
     Operation          *op,
-       char            *edn,
        regmatch_t      *matches
 )
 {
        struct berval bv;
-       char *subjdn, *grpdn;
-       int rc = 0;
+       char *subjdn, *grpdn = NULL;
+       char *grpoc;
+       char *grpat;
+       ObjectClass *grp_oc = NULL;
+       AttributeDescription *grp_ad = NULL;
+       char *text;
+       int rc;
 
        /* format of string is "group/objectClassValue/groupAttrName" */
-       if (aci_get_part(subj, 0, '/', &bv) < 0)
+       if (aci_get_part(subj, 0, '/', &bv) < 0) {
                return(0);
+       }
+
        subjdn = aci_bvstrdup(&bv);
-       if (subjdn == NULL)
+       if (subjdn == NULL) {
                return(0);
+       }
 
-       if (aci_get_part(subj, 1, '/', &bv) < 0)
-               grpoc = ch_strdup(grpoc);
-       else
+       if (aci_get_part(subj, 1, '/', &bv) < 0) {
+               grpoc = ch_strdup( defgrpoc );
+       } else {
                grpoc = aci_bvstrdup(&bv);
+       }
 
-       if (aci_get_part(subj, 2, '/', &bv) < 0)
-               grpat = ch_strdup(grpat);
-       else
+       if (aci_get_part(subj, 2, '/', &bv) < 0) {
+               grpat = ch_strdup( defgrpat );
+       } else {
                grpat = aci_bvstrdup(&bv);
+       }
+
+       rc = slap_str2ad( grpat, &grp_ad, &text );
+       if( rc != LDAP_SUCCESS ) {
+               rc = 0;
+               goto done;
+       }
+       rc = 0;
 
        grpdn = (char *)ch_malloc(1024);
-       if (grpoc != NULL && grpat != NULL && grpdn != NULL) {
-               string_expand(grpdn, 1024, subjdn, edn, matches);
-               if ( dn_normalize_case(grpdn) != NULL ) {
-                       rc = (backend_group(be, e, grpdn, op->o_ndn, grpoc, grpat) == 0);
+
+       if (grp_oc != NULL && grp_ad != NULL && grpdn != NULL) {
+               string_expand(grpdn, 1024, subjdn, e->e_ndn, matches);
+               if ( dn_normalize(grpdn) != NULL ) {
+                       rc = (backend_group(be, e, grpdn, op->o_ndn, grp_oc, grp_ad) == 0);
                }
-               ch_free(grpdn);
        }
-       if (grpat != NULL)
-               ch_free(grpat);
-       if (grpoc != NULL)
-               ch_free(grpoc);
+
+done:
+       if( grp_ad != NULL ) ad_free( grp_ad, 1 );
+       ch_free(grpdn);
+       ch_free(grpat);
+       ch_free(grpoc);
        ch_free(subjdn);
        return(rc);
 }
 
-int
-aci_access_allowed (
-    struct berval      *aci,
-    char                       *attr,
+static int
+aci_mask(
     Backend                    *be,
-    Entry                      *e,
+    Connection         *conn,
     Operation          *op,
-    int                                access,
-       char                    *edn,
-       regmatch_t              *matches
+    Entry                      *e,
+       AttributeDescription *desc,
+    struct berval      *val,
+    struct berval      *aci,
+       regmatch_t              *matches,
+       slap_access_t   *grant,
+       slap_access_t   *deny
 )
 {
     struct berval bv, perms, sdn;
     char *subjdn;
        int rc;
-
-       Debug( LDAP_DEBUG_ACL,
-               "\n=> aci_access_allowed: %s access to entry \"%s\"\n",
-               access2str( access ), e->e_dn, 0 );
-
-       Debug( LDAP_DEBUG_ACL,
-               "\n=> aci_access_allowed: %s access to attribute \"%s\" by \"%s\"\n",
-           access2str( access ),
-               attr,
-               op->o_ndn ? op->o_ndn : "" );
+       char *attr = desc->ad_cname->bv_val;
 
        /* parse an aci of the form:
                oid#scope#action;rights;attr;rights;attr$action;rights;attr;rights;attr#dnType#subjectDN
 
-          See draft-ietf-ldapext-aci-model-0.3.txt section 9.1 for
+          See draft-ietf-ldapext-aci-model-04.txt section 9.1 for
           a full description of the format for this attribute.
 
           For now, this routine only supports scope=entry.
@@ -796,6 +1159,10 @@ aci_access_allowed (
        if (aci_get_part(aci, 4, '#', NULL) < 0)
                return(0);
 
+       /* check that the aci family is supported */
+       if (aci_get_part(aci, 0, '#', &bv) < 0)
+               return(0);
+
        /* check that the scope is "entry" */
        if (aci_get_part(aci, 1, '#', &bv) < 0
                || aci_strbvcmp( "entry", &bv ) != 0)
@@ -808,7 +1175,7 @@ aci_access_allowed (
                return(0);
 
        /* check if any permissions allow desired access */
-       if (aci_list_has_permission(&perms, attr, access) == 0)
+       if (aci_list_get_rights(&perms, attr, val, grant, deny) == 0)
                return(0);
 
        /* see if we have a DN match */
@@ -817,31 +1184,67 @@ aci_access_allowed (
 
        if (aci_get_part(aci, 4, '#', &sdn) < 0)
                return(0);
+
        if (aci_strbvcmp( "access-id", &bv ) == 0) {
                subjdn = aci_bvstrdup(&sdn);
                if (subjdn == NULL)
                        return(0);
-               rc = 0;
-               if (dn_normalize_case(subjdn) != NULL)
-                       rc = (strcasecmp(op->o_ndn, subjdn) == 0);
+               rc = 1;
+               if ( dn_normalize(subjdn) != NULL )
+                       if (strcasecmp(op->o_ndn, subjdn) != 0)
+                               rc = 0;
                ch_free(subjdn);
                return(rc);
        }
 
        if (aci_strbvcmp( "self", &bv ) == 0) {
-               return(strcasecmp(op->o_ndn, edn) == 0);
-       }
+               if (strcasecmp(op->o_ndn, e->e_ndn) == 0)
+                       return(1);
 
-       if (aci_strbvcmp( "group", &bv ) == 0) {
-               return(aci_group_member(&sdn, "groupOfNames", "member", be, e, op, edn, matches));
-       }
+       } else if (aci_strbvcmp( "dnattr", &bv ) == 0) {
+               char *dnattr = aci_bvstrdup(&sdn);
+               Attribute *at;
+               AttributeDescription *ad = NULL;
+               const char *text;
+
+               rc = slap_str2ad( dnattr, &ad, &text );
+               ch_free( dnattr );
+
+               if( rc != LDAP_SUCCESS ) {
+                       return 0;
+               }
+
+               rc = 0;
+
+               bv.bv_val = op->o_ndn;
+               bv.bv_len = strlen( bv.bv_val );
+
+               for(at = attrs_find( e->e_attrs, ad );
+                       at != NULL;
+                       at = attrs_find( at->a_next, ad ) )
+               {
+                       if (value_find( ad, at->a_vals, &bv) == 0 ) {
+                               rc = 1;
+                               break;
+                       }
+               }
+
+               ad_free( ad, 1 );
+               return rc;
 
-       if (aci_strbvcmp( "role", &bv ) == 0) {
-               return(aci_group_member(&sdn, "organizationalRole", "roleOccupant", be, e, op, edn, matches));
+
+       } else if (aci_strbvcmp( "group", &bv ) == 0) {
+               if (aci_group_member(&sdn, SLAPD_GROUP_CLASS, SLAPD_GROUP_ATTR, be, e, op, matches))
+                       return(1);
+
+       } else if (aci_strbvcmp( "role", &bv ) == 0) {
+               if (aci_group_member(&sdn, SLAPD_ROLE_CLASS, SLAPD_ROLE_ATTR, be, e, op, matches))
+                       return(1);
        }
 
        return(0);
 }
+
 #endif /* SLAPD_ACI_ENABLED */
 
 static void
@@ -859,6 +1262,7 @@ string_expand(
 
        size = 0;
        newbuf[0] = '\0';
+       bufsiz--; /* leave space for lone $ */
 
        flag = 0;
        for ( dp = newbuf, sp = pat; size < bufsiz && *sp ; sp++) {
@@ -892,6 +1296,13 @@ string_expand(
                        }
                }
        }
+
+       if (flag) {
+               /* must have ended with a single $ */
+               *dp++ = '$';
+               size++;
+       }
+
        *dp = '\0';
 
        Debug( LDAP_DEBUG_TRACE, "=> string_expand: pattern:  %s\n", pat, 0, 0 );
index a1345069089da7475d18e452ab64983a2f2d8650..8d64d9aad8d9f7b4f0d16846a535acda6291122f 100644 (file)
@@ -1,7 +1,7 @@
-/* acl.c - routines to parse and check acl's */
+/* aclparse.c - routines to parse and check acl's */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 #include "slap.h"
 
 static void            split(char *line, int splitchar, char **left, char **right);
-static void            acl_append(AccessControl **l, AccessControl *a);
 static void            access_append(Access **l, Access *a);
 static void            acl_usage(void) LDAP_GCCATTR((noreturn));
+
 #ifdef LDAP_DEBUG
-static void            print_acl(AccessControl *a);
+static void            print_acl(Backend *be, AccessControl *a);
 static void            print_access(Access *b);
 #endif
 
@@ -92,9 +92,11 @@ parse_acl(
 )
 {
        int             i;
-       char            *left, *right;
+       char            *left, *right, *style;
        AccessControl   *a;
        Access  *b;
+       int rc;
+       const char *text;
 
        a = NULL;
        for ( i = 1; i < argc; i++ ) {
@@ -119,11 +121,21 @@ parse_acl(
                                }
 
                                if ( strcasecmp( argv[i], "*" ) == 0 ) {
-                                       a->acl_dn_pat = ch_strdup( ".*" );
+                                       if( a->acl_dn_pat != NULL ) {
+                                               fprintf( stderr,
+                                                       "%s: line %d: dn pattern"
+                                                       " already specified in to clause.\n",
+                                                       fname, lineno );
+                                               acl_usage();
+                                       }
+
+                                       a->acl_dn_pat = ch_strdup( "*" );
                                        continue;
                                }
 
                                split( argv[i], '=', &left, &right );
+                               split( left, '.', &left, &style );
+
                                if ( right == NULL || *right == '\0' ) {
                                        fprintf( stderr,
        "%s: line %d: missing \"=\" in (or value after) \"%s\" in to clause\n",
@@ -131,6 +143,58 @@ parse_acl(
                                        acl_usage();
                                }
 
+                               if ( strcasecmp( left, "dn" ) == 0 ) {
+                                       if( a->acl_dn_pat != NULL ) {
+                                               fprintf( stderr,
+                                                       "%s: line %d: dn pattern"
+                                                       " already specified in to clause.\n",
+                                                       fname, lineno );
+                                               acl_usage();
+                                       }
+
+                                       if ( style == NULL || *style == '\0'
+                                               || strcasecmp( style, "regex" ) == 0 )
+                                       {
+                                               a->acl_dn_style = ACL_STYLE_REGEX;
+                                               if ( strcmp(right, "*") == 0 
+                                                       || strcmp(right, ".*") == 0 
+                                                       || strcmp(right, ".*$") == 0 
+                                                       || strcmp(right, "^.*") == 0 
+                                                       || strcmp(right, "^.*$$") == 0
+                                                       || strcmp(right, ".*$$") == 0 
+                                                       || strcmp(right, "^.*$$") == 0 )
+                                               {
+                                                       a->acl_dn_pat = ch_strdup( "*" );
+
+                                               } else {
+                                                       a->acl_dn_pat = ch_strdup( right );
+                                               }
+                                       } else if ( strcasecmp( style, "base" ) == 0 ) {
+                                               a->acl_dn_style = ACL_STYLE_BASE;
+                                               a->acl_dn_pat = ch_strdup( right );
+
+                                       } else if ( strcasecmp( style, "one" ) == 0 ) {
+                                               a->acl_dn_style = ACL_STYLE_ONE;
+                                               a->acl_dn_pat = ch_strdup( right );
+
+                                       } else if ( strcasecmp( style, "subtree" ) == 0 ) {
+                                               a->acl_dn_style = ACL_STYLE_SUBTREE;
+                                               a->acl_dn_pat = ch_strdup( right );
+
+                                       } else if ( strcasecmp( style, "children" ) == 0 ) {
+                                               a->acl_dn_style = ACL_STYLE_CHILDREN;
+                                               a->acl_dn_pat = ch_strdup( right );
+
+                                       } else {
+                                               fprintf( stderr,
+       "%s: line %d: unknown dn style \"%s\" in to clause\n",
+                                                   fname, lineno, style );
+                                               acl_usage();
+                                       }
+
+                                       continue;
+                               }
+
                                if ( strcasecmp( left, "filter" ) == 0 ) {
                                        if ( (a->acl_filter = str2filter(
                                            right )) == NULL ) {
@@ -140,9 +204,6 @@ parse_acl(
                                                acl_usage();
                                        }
 
-                               } else if ( strcasecmp( left, "dn" ) == 0 ) {
-                                               a->acl_dn_pat = ch_strdup( right );
-
                                } else if ( strncasecmp( left, "attr", 4 ) == 0 ) {
                                        char    **alist;
 
@@ -158,16 +219,27 @@ parse_acl(
                                }
                        }
 
-                       if ( a->acl_dn_pat != NULL ) {
-                               int e = regcomp( &a->acl_dn_re, a->acl_dn_pat,
-                                                REG_EXTENDED | REG_ICASE );
-                               if ( e ) {
-                                       char buf[512];
-                                       regerror( e, &a->acl_dn_re, buf, sizeof(buf) );
-                                       fprintf( stderr,
-                               "%s: line %d: regular expression \"%s\" bad because of %s\n",
-                                                fname, lineno, right, buf );
-                                       acl_usage();
+                       if ( a->acl_dn_pat != NULL && strcmp(a->acl_dn_pat, "*") == 0) {
+                               free( a->acl_dn_pat );
+                               a->acl_dn_pat = NULL;
+                       }
+                       
+                       if( a->acl_dn_pat != NULL ) {
+                               if ( a->acl_dn_style != ACL_STYLE_REGEX )
+                               {
+                                       dn_normalize(a->acl_dn_pat);
+
+                               } else {
+                                       int e = regcomp( &a->acl_dn_re, a->acl_dn_pat,
+                                                        REG_EXTENDED | REG_ICASE );
+                                       if ( e ) {
+                                               char buf[512];
+                                               regerror( e, &a->acl_dn_re, buf, sizeof(buf) );
+                                               fprintf( stderr,
+                                       "%s: line %d: regular expression \"%s\" bad because of %s\n",
+                                                        fname, lineno, right, buf );
+                                               acl_usage();
+                                       }
                                }
                        }
 
@@ -179,12 +251,15 @@ parse_acl(
                                    fname, lineno );
                                acl_usage();
                        }
+
                        /*
                         * by clause consists of <who> and <access>
                         */
 
                        b = (Access *) ch_calloc( 1, sizeof(Access) );
 
+                       ACL_INVALIDATE( b->a_mask );
+
                        if ( ++i == argc ) {
                                fprintf( stderr,
                            "%s: line %d: premature eol: expecting <who>\n",
@@ -195,17 +270,91 @@ parse_acl(
                        /* get <who> */
                        for ( ; i < argc; i++ ) {
                                char *pat;
+                               slap_style_t sty = ACL_STYLE_REGEX;
+
                                split( argv[i], '=', &left, &right );
+                               split( left, '.', &left, &style );
+                               if ( style == NULL || *style == '\0'
+                                       || strcasecmp( style, "regex" ) == 0 )
+                               {
+                                       sty = ACL_STYLE_REGEX;
+                               } else if ( strcasecmp( style, "exact" ) == 0 ) {
+                                       sty = ACL_STYLE_BASE;
+                               } else if ( strcasecmp( style, "base" ) == 0 ) {
+                                       sty = ACL_STYLE_BASE;
+                               } else if ( strcasecmp( style, "one" ) == 0 ) {
+                                       sty = ACL_STYLE_ONE;
+                               } else if ( strcasecmp( style, "subtree" ) == 0 ) {
+                                       sty = ACL_STYLE_SUBTREE;
+                               } else if ( strcasecmp( style, "children" ) == 0 ) {
+                                       sty = ACL_STYLE_CHILDREN;
+                               } else {
+                                       fprintf( stderr,
+                                               "%s: line %d: unknown style \"%s\" in by clause\n",
+                                           fname, lineno, style );
+                                       acl_usage();
+                               }
 
                                if ( strcasecmp( argv[i], "*" ) == 0 ) {
-                                       pat = ch_strdup( ".*" );
+                                       pat = ch_strdup( "*" );
+
                                } else if ( strcasecmp( argv[i], "anonymous" ) == 0 ) {
                                        pat = ch_strdup( "anonymous" );
+
                                } else if ( strcasecmp( argv[i], "self" ) == 0 ) {
                                        pat = ch_strdup( "self" );
+
+                               } else if ( strcasecmp( argv[i], "users" ) == 0 ) {
+                                       pat = ch_strdup( "users" );
+
                                } else if ( strcasecmp( left, "dn" ) == 0 ) {
-                                       regtest(fname, lineno, right);
-                                       pat = ch_strdup( right );
+                                       if ( sty == ACL_STYLE_REGEX ) {
+                                               b->a_dn_style = ACL_STYLE_REGEX;
+                                               if( right == NULL ) {
+                                                       /* no '=' */
+                                                       pat = ch_strdup( "users" );
+
+                                               } else if (*right == '\0' ) {
+                                                       /* dn="" */
+                                                       pat = ch_strdup( "anonymous" );
+
+                                               } else if ( strcmp( right, "*" ) == 0 ) {
+                                                       /* dn=* */
+                                                       /* any or users?  users for now */
+                                                       pat = ch_strdup( "users" );
+
+                                               } else if ( strcmp( right, ".+" ) == 0
+                                                       || strcmp( right, "^.+" ) == 0
+                                                       || strcmp( right, ".+$" ) == 0
+                                                       || strcmp( right, "^.+$" ) == 0
+                                                       || strcmp( right, ".+$$" ) == 0
+                                                       || strcmp( right, "^.+$$" ) == 0 )
+                                               {
+                                                       pat = ch_strdup( "users" );
+
+                                               } else if ( strcmp( right, ".*" ) == 0
+                                                       || strcmp( right, "^.*" ) == 0
+                                                       || strcmp( right, ".*$" ) == 0
+                                                       || strcmp( right, "^.*$" ) == 0
+                                                       || strcmp( right, ".*$$" ) == 0
+                                                       || strcmp( right, "^.*$$" ) == 0 )
+                                               {
+                                                       pat = ch_strdup( "*" );
+
+                                               } else {
+                                                       regtest(fname, lineno, right);
+                                                       pat = ch_strdup( right );
+                                               }
+                                       } else if ( right == NULL || *right == '\0' ) {
+                                               fprintf( stderr,
+                                                       "%s: line %d: missing \"=\" in (or value after) \"%s\" in by clause\n",
+                                                   fname, lineno, left );
+                                               acl_usage();
+
+                                       } else {
+                                               pat = ch_strdup( right );
+                                       }
+
                                } else {
                                        pat = NULL;
                                }
@@ -219,21 +368,51 @@ parse_acl(
                                        }
 
                                        b->a_dn_pat = pat;
+                                       b->a_dn_style = sty;
+                                       if ( sty != ACL_STYLE_REGEX )
+                                               dn_normalize(pat);
                                        continue;
                                }
 
                                if ( strcasecmp( left, "dnattr" ) == 0 ) {
-                                       if( b->a_dn_pat != NULL ) {
+                                       if( b->a_dn_at != NULL ) {
                                                fprintf( stderr,
-                                                       "%s: line %d: dnaddr already specified.\n",
+                                                       "%s: line %d: dnattr already specified.\n",
                                                        fname, lineno );
                                                acl_usage();
                                        }
 
-                                       b->a_dn_at = ch_strdup( right );
+                                       rc = slap_str2ad( right, &b->a_dn_at, &text );
+
+                                       if( rc != LDAP_SUCCESS ) {
+                                               fprintf( stderr,
+                                                       "%s: line %d: dnattr \"%s\": %s\n",
+                                                       fname, lineno, right, text );
+                                               acl_usage();
+                                       }
+
+
+                                       if( !is_at_syntax( b->a_dn_at->ad_type,
+                                               SLAPD_DN_SYNTAX ) )
+                                       {
+                                               fprintf( stderr,
+                                                       "%s: line %d: dnattr \"%s\": "
+                                                       "inappropriate syntax: %s\n",
+                                                       fname, lineno, right,
+                                                       b->a_dn_at->ad_type->sat_syntax_oid );
+                                               acl_usage();
+                                       }
+
                                        continue;
                                }
 
+                               if (sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE) {
+                                       fprintf( stderr,
+                                               "%s: line %d: inappropriate style \"%s\" in by clause\n",
+                                           fname, lineno, style );
+                                       acl_usage();
+                               }
+
                                if ( strncasecmp( left, "group", sizeof("group")-1 ) == 0 ) {
                                        char *name = NULL;
                                        char *value = NULL;
@@ -248,28 +427,119 @@ parse_acl(
                                        /* format of string is "group/objectClassValue/groupAttrName" */
                                        if ((value = strchr(left, '/')) != NULL) {
                                                *value++ = '\0';
-                                               if (value && *value
+                                               if (*value
                                                        && (name = strchr(value, '/')) != NULL)
                                                {
                                                        *name++ = '\0';
                                                }
                                        }
 
-                                       regtest(fname, lineno, right);
-                                       b->a_group_pat = ch_strdup( right );
+                                       b->a_group_style = sty;
+                                       if (sty == ACL_STYLE_REGEX) {
+                                               regtest(fname, lineno, right);
+                                               b->a_group_pat = ch_strdup( right );
+                                       } else {
+                                               b->a_group_pat = ch_strdup( right );
+                                               dn_normalize(b->a_group_pat);
+                                       }
 
                                        if (value && *value) {
-                                               b->a_group_oc = ch_strdup(value);
+                                               b->a_group_oc = oc_find( value );
                                                *--value = '/';
+
+                                               if( b->a_group_oc == NULL ) {
+                                                       fprintf( stderr,
+                                                               "%s: line %d: group objectclass "
+                                                               "\"%s\" unknown\n",
+                                                               fname, lineno, value );
+                                                       acl_usage();
+                                               }
                                        } else {
-                                               b->a_group_oc = ch_strdup("groupOfNames");
+                                               b->a_group_oc = oc_find(SLAPD_GROUP_CLASS);
+
+                                               if( b->a_group_oc == NULL ) {
+                                                       fprintf( stderr,
+                                                               "%s: line %d: group default objectclass "
+                                                               "\"%s\" unknown\n",
+                                                               fname, lineno, SLAPD_GROUP_CLASS );
+                                                       acl_usage();
+                                               }
+                                       }
 
-                                               if (name && *name) {
-                                                       b->a_group_at = ch_strdup(name);
-                                                       *--name = '/';
+#if 0
+                                       if( is_object_subclass( b->a_group_oc,
+                                               slap_schema.si_oc_referral ) )
+                                       {
+                                               fprintf( stderr,
+                                                       "%s: line %d: group objectclass \"%s\" "
+                                                       "is subclass of referral\n",
+                                                       fname, lineno, value );
+                                               acl_usage();
+                                       }
 
-                                               } else {
-                                                       b->a_group_at = ch_strdup("member");
+                                       if( is_object_subclass( b->a_group_oc,
+                                               slap_schema.si_oc_alias ) )
+                                       {
+                                               fprintf( stderr,
+                                                       "%s: line %d: group objectclass \"%s\" "
+                                                       "is subclass of alias\n",
+                                                       fname, lineno, value );
+                                               acl_usage();
+                                       }
+#endif
+
+                                       if (name && *name) {
+                                               rc = slap_str2ad( right, &b->a_group_at, &text );
+
+                                               if( rc != LDAP_SUCCESS ) {
+                                                       fprintf( stderr,
+                                                               "%s: line %d: group \"%s\": %s\n",
+                                                               fname, lineno, right, text );
+                                                       acl_usage();
+                                               }
+                                               *--name = '/';
+                                       } else {
+                                               rc = slap_str2ad( SLAPD_GROUP_ATTR, &b->a_group_at, &text );
+
+                                               if( rc != LDAP_SUCCESS ) {
+                                                       fprintf( stderr,
+                                                               "%s: line %d: group \"%s\": %s\n",
+                                                               fname, lineno, SLAPD_GROUP_ATTR, text );
+                                                       acl_usage();
+                                               }
+                                       }
+
+                                       if( !is_at_syntax( b->a_group_at->ad_type,
+                                               SLAPD_DN_SYNTAX ) )
+                                       {
+                                               fprintf( stderr,
+                                                       "%s: line %d: group \"%s\": inappropriate syntax: %s\n",
+                                                       fname, lineno, right,
+                                                       b->a_group_at->ad_type->sat_syntax_oid );
+                                               acl_usage();
+                                       }
+
+
+                                       {
+                                               int rc;
+                                               struct berval val;
+                                               struct berval *vals[2];
+
+                                               val.bv_val = b->a_group_oc->soc_oid;
+                                               val.bv_len = strlen(val.bv_val);
+                                               vals[0] = &val;
+                                               vals[1] = NULL;
+
+
+                                               rc = oc_check_allowed( b->a_group_at->ad_type, vals );
+
+                                               if( rc != 0 ) {
+                                                       fprintf( stderr,
+                                                               "%s: line %d: group: \"%s\" not allowed by \"%s\"\n",
+                                                               fname, lineno,
+                                                               b->a_group_at->ad_cname->bv_val,
+                                                               b->a_group_oc->soc_oid );
+                                                       acl_usage();
                                                }
                                        }
                                        continue;
@@ -283,7 +553,10 @@ parse_acl(
                                                acl_usage();
                                        }
 
-                                       regtest(fname, lineno, right);
+                                       b->a_peername_style = sty;
+                                       if (sty == ACL_STYLE_REGEX) {
+                                               regtest(fname, lineno, right);
+                                       }
                                        b->a_peername_pat = ch_strdup( right );
                                        continue;
                                }
@@ -296,7 +569,10 @@ parse_acl(
                                                acl_usage();
                                        }
 
-                                       regtest(fname, lineno, right);
+                                       b->a_sockname_style = sty;
+                                       if (sty == ACL_STYLE_REGEX) {
+                                               regtest(fname, lineno, right);
+                                       }
                                        b->a_sockname_pat = ch_strdup( right );
                                        continue;
                                }
@@ -309,7 +585,10 @@ parse_acl(
                                                acl_usage();
                                        }
 
-                                       regtest(fname, lineno, right);
+                                       b->a_domain_style = sty;
+                                       if (sty == ACL_STYLE_REGEX) {
+                                               regtest(fname, lineno, right);
+                                       }
                                        b->a_domain_pat = ch_strdup( right );
                                        continue;
                                }
@@ -322,7 +601,10 @@ parse_acl(
                                                acl_usage();
                                        }
 
-                                       regtest(fname, lineno, right);
+                                       b->a_sockurl_style = sty;
+                                       if (sty == ACL_STYLE_REGEX) {
+                                               regtest(fname, lineno, right);
+                                       }
                                        b->a_sockurl_pat = ch_strdup( right );
                                        continue;
                                }
@@ -336,24 +618,127 @@ parse_acl(
                                                acl_usage();
                                        }
 
-                                       if ( right != NULL && *right != '\0' )
-                                               b->a_aci_at = ch_strdup( right );
-                                       else
-                                               b->a_aci_at = ch_strdup( SLAPD_ACI_DEFAULT_ATTR );
+                                       if ( right != NULL && *right != '\0' ) {
+                                               rc = slap_str2ad( right, &b->a_aci_at, &text );
+
+                                               if( rc != LDAP_SUCCESS ) {
+                                                       fprintf( stderr,
+                                                               "%s: line %d: aci \"%s\": %s\n",
+                                                               fname, lineno, right, text );
+                                                       acl_usage();
+                                               }
+
+                                       } else {
+                                               rc = slap_str2ad( SLAPD_ACI_ATTR, &b->a_aci_at, &text );
+
+                                               if( rc != LDAP_SUCCESS ) {
+                                                       fprintf( stderr,
+                                                               "%s: line %d: aci \"%s\": %s\n",
+                                                               fname, lineno, SLAPD_ACI_ATTR, text );
+                                                       acl_usage();
+                                               }
+                                       }
+
+                                       if( !is_at_syntax( b->a_aci_at->ad_type,
+                                               SLAPD_ACI_SYNTAX) )
+                                       {
+                                               fprintf( stderr,
+                                                       "%s: line %d: aci \"%s\": inappropriate syntax: %s\n",
+                                                       fname, lineno, right,
+                                                       b->a_aci_at->ad_type->sat_syntax_oid );
+                                               acl_usage();
+                                       }
+
                                        continue;
                                }
-#endif
+#endif /* SLAPD_ACI_ENABLED */
 
-                               /* get <access> */
-                               if ( ACL_IS_INVALID(ACL_SET(b->a_access, str2access( left ))) ) {
-                                       fprintf( stderr,
-                                       "%s: line %d: expecting <access> got \"%s\"\n",
-                                               fname, lineno, left );
-                                       acl_usage();
+                               if( right != NULL ) {
+                                       /* unsplit */
+                                       right[-1] = '=';
                                }
-                               access_append( &a->acl_access, b );
                                break;
                        }
+
+                       if( i == argc || ( strcasecmp( left, "stop" ) == 0 )) { 
+                               /* out of arguments or plain stop */
+
+                               ACL_PRIV_ASSIGN(b->a_mask, ACL_PRIV_ADDITIVE);
+                               b->a_type = ACL_STOP;
+
+                               access_append( &a->acl_access, b );
+                               continue;
+                       }
+
+                       if( strcasecmp( left, "continue" ) == 0 ) {
+                               /* plain continue */
+
+                               ACL_PRIV_ASSIGN(b->a_mask, ACL_PRIV_ADDITIVE);
+                               b->a_type = ACL_CONTINUE;
+
+                               access_append( &a->acl_access, b );
+                               continue;
+                       }
+
+                       if( strcasecmp( left, "break" ) == 0 ) {
+                               /* plain continue */
+
+                               ACL_PRIV_ASSIGN(b->a_mask, ACL_PRIV_ADDITIVE);
+                               b->a_type = ACL_BREAK;
+
+                               access_append( &a->acl_access, b );
+                               continue;
+                       }
+
+                       if ( strcasecmp( left, "by" ) == 0 ) {
+                               /* we've gone too far */
+                               --i;
+                               ACL_PRIV_ASSIGN(b->a_mask, ACL_PRIV_ADDITIVE);
+                               b->a_type = ACL_STOP;
+
+                               access_append( &a->acl_access, b );
+                               continue;
+                       }
+
+                       /* get <access> */
+                       if( strncasecmp( left, "self", 4 ) == 0 ) {
+                               b->a_dn_self = 1;
+                               ACL_PRIV_ASSIGN( b->a_mask, str2accessmask( &left[4] ) );
+
+                       } else {
+                               ACL_PRIV_ASSIGN( b->a_mask, str2accessmask( left ) );
+                       }
+
+                       if( ACL_IS_INVALID( b->a_mask ) ) {
+                               fprintf( stderr,
+                                       "%s: line %d: expecting <access> got \"%s\"\n",
+                                       fname, lineno, left );
+                               acl_usage();
+                       }
+
+                       b->a_type = ACL_STOP;
+
+                       if( ++i == argc ) {
+                               /* out of arguments or plain stop */
+                               access_append( &a->acl_access, b );
+                               continue;
+                       }
+
+                       if( strcasecmp( argv[i], "continue" ) == 0 ) {
+                               /* plain continue */
+                               b->a_type = ACL_CONTINUE;
+
+                       } else if( strcasecmp( argv[i], "break" ) == 0 ) {
+                               /* plain continue */
+                               b->a_type = ACL_BREAK;
+
+                       } else if ( strcasecmp( argv[i], "stop" ) != 0 ) {
+                               /* gone to far */
+                               i--;
+                       }
+
+                       access_append( &a->acl_access, b );
+
                } else {
                        fprintf( stderr,
                    "%s: line %d: expecting \"to\" or \"by\" got \"%s\"\n",
@@ -369,10 +754,9 @@ parse_acl(
                            fname, lineno );
 
        } else {
-
 #ifdef LDAP_DEBUG
-                if (ldap_debug & LDAP_DEBUG_ACL)
-                    print_acl(a);
+               if (ldap_debug & LDAP_DEBUG_ACL)
+                       print_acl(be, a);
 #endif
        
                if ( a->acl_access == NULL ) {
@@ -390,76 +774,175 @@ parse_acl(
 }
 
 char *
-access2str( int access )
+accessmask2str( slap_access_mask_t mask, char *buf )
 {
-       static char     buf[12];
+       int none=1;
 
-       if ( ACL_IS_SELF( access ) ) {
-               strcpy( buf, "self" );
-       } else {
-               buf[0] = '\0';
+       assert( buf != NULL );
+
+       if ( ACL_IS_INVALID( mask ) ) {
+               return "invalid";
+       }
+
+       buf[0] = '\0';
+
+       if ( ACL_IS_LEVEL( mask ) ) {
+               if ( ACL_LVL_IS_NONE(mask) ) {
+                       strcat( buf, "none" );
+
+               } else if ( ACL_LVL_IS_AUTH(mask) ) {
+                       strcat( buf, "auth" );
+
+               } else if ( ACL_LVL_IS_COMPARE(mask) ) {
+                       strcat( buf, "compare" );
+
+               } else if ( ACL_LVL_IS_SEARCH(mask) ) {
+                       strcat( buf, "search" );
+
+               } else if ( ACL_LVL_IS_READ(mask) ) {
+                       strcat( buf, "read" );
+
+               } else if ( ACL_LVL_IS_WRITE(mask) ) {
+                       strcat( buf, "write" );
+               } else {
+                       strcat( buf, "unknown" );
+               }
+               
+               strcat(buf, " (");
        }
 
-       if ( ACL_IS_NONE(access) ) {
-               strcat( buf, "none" );
-       } else if ( ACL_IS_AUTH(access) ) {
-               strcat( buf, "auth" );
-       } else if ( ACL_IS_COMPARE(access) ) {
-               strcat( buf, "compare" );
-       } else if ( ACL_IS_SEARCH(access) ) {
-               strcat( buf, "search" );
-       } else if ( ACL_IS_READ(access) ) {
-               strcat( buf, "read" );
-       } else if ( ACL_IS_WRITE(access) ) {
-               strcat( buf, "write" );
+       if( ACL_IS_ADDITIVE( mask ) ) {
+               strcat( buf, "+" );
+
+       } else if( ACL_IS_SUBTRACTIVE( mask ) ) {
+               strcat( buf, "-" );
 
        } else {
-               strcat( buf, "unknown" );
+               strcat( buf, "=" );
+       }
+
+       if ( ACL_PRIV_ISSET(mask, ACL_PRIV_WRITE) ) {
+               none = 0;
+               strcat( buf, "w" );
+       } 
+
+       if ( ACL_PRIV_ISSET(mask, ACL_PRIV_READ) ) {
+               none = 0;
+               strcat( buf, "r" );
+       } 
+
+       if ( ACL_PRIV_ISSET(mask, ACL_PRIV_SEARCH) ) {
+               none = 0;
+               strcat( buf, "s" );
+       } 
+
+       if ( ACL_PRIV_ISSET(mask, ACL_PRIV_COMPARE) ) {
+               none = 0;
+               strcat( buf, "c" );
+       } 
+
+       if ( ACL_PRIV_ISSET(mask, ACL_PRIV_AUTH) ) {
+               none = 0;
+               strcat( buf, "x" );
+       } 
+
+       if ( none && ACL_PRIV_ISSET(mask, ACL_PRIV_NONE) ) {
+               none = 0;
+               strcat( buf, "n" );
+       } 
+
+       if ( none ) {
+               strcat( buf, "0" );
        }
 
-       return( buf );
+       if ( ACL_IS_LEVEL( mask ) ) {
+               strcat(buf, ")");
+       } 
+       return buf;
 }
 
-int
-str2access( char *str )
+slap_access_mask_t
+str2accessmask( const char *str )
 {
-       int     access;
+       slap_access_mask_t      mask;
+
+       if( !isalpha(str[0]) ) {
+               int i;
+
+               if ( str[0] == '=' ) {
+                       ACL_INIT(mask);
+
+               } else if( str[0] == '+' ) {
+                       ACL_PRIV_ASSIGN(mask, ACL_PRIV_ADDITIVE);
+
+               } else if( str[0] == '-' ) {
+                       ACL_PRIV_ASSIGN(mask, ACL_PRIV_SUBSTRACTIVE);
+
+               } else {
+                       ACL_INVALIDATE(mask);
+                       return mask;
+               }
+
+               for( i=1; str[i] != '\0'; i++ ) {
+                       if( TOLOWER(str[i]) == 'w' ) {
+                               ACL_PRIV_SET(mask, ACL_PRIV_WRITE);
 
-       ACL_CLR(access);
+                       } else if( TOLOWER(str[i]) == 'r' ) {
+                               ACL_PRIV_SET(mask, ACL_PRIV_READ);
 
-       if ( strncasecmp( str, "self", 4 ) == 0 ) {
-               ACL_SET_SELF(access);
-               str += 4;
+                       } else if( TOLOWER(str[i]) == 's' ) {
+                               ACL_PRIV_SET(mask, ACL_PRIV_SEARCH);
+
+                       } else if( TOLOWER(str[i]) == 'c' ) {
+                               ACL_PRIV_SET(mask, ACL_PRIV_COMPARE);
+
+                       } else if( TOLOWER(str[i]) == 'x' ) {
+                               ACL_PRIV_SET(mask, ACL_PRIV_AUTH);
+
+                       } else if( str[i] != '0' ) {
+                               ACL_INVALIDATE(mask);
+                               return mask;
+                       }
+               }
+
+               return mask;
        }
 
        if ( strcasecmp( str, "none" ) == 0 ) {
-               ACL_SET_NONE(access);
+               ACL_LVL_ASSIGN_NONE(mask);
+
        } else if ( strcasecmp( str, "auth" ) == 0 ) {
-               ACL_SET_AUTH(access);
+               ACL_LVL_ASSIGN_AUTH(mask);
+
        } else if ( strcasecmp( str, "compare" ) == 0 ) {
-               ACL_SET_COMPARE(access);
+               ACL_LVL_ASSIGN_COMPARE(mask);
+
        } else if ( strcasecmp( str, "search" ) == 0 ) {
-               ACL_SET_SEARCH(access);
+               ACL_LVL_ASSIGN_SEARCH(mask);
+
        } else if ( strcasecmp( str, "read" ) == 0 ) {
-               ACL_SET_READ(access);
+               ACL_LVL_ASSIGN_READ(mask);
+
        } else if ( strcasecmp( str, "write" ) == 0 ) {
-               ACL_SET_WRITE(access);
+               ACL_LVL_ASSIGN_WRITE(mask);
+
        } else {
-               ACL_SET_INVALID(access);
+               ACL_INVALIDATE( mask );
        }
 
-       return( access );
+       return mask;
 }
 
 static void
 acl_usage( void )
 {
        fprintf( stderr, "\n"
-               "<access clause> ::= access to <what> [ by <who> <access> ]+ \n"
+               "<access clause> ::= access to <what> "
+                               "[ by <who> <access> <control> ]+ \n"
                "<what> ::= * | [dn=<regex>] [filter=<ldapfilter>] [attrs=<attrlist>]\n"
                "<attrlist> ::= <attr> | <attr> , <attrlist>\n"
                "<attr> ::= <attrname> | entry | children\n"
-               "<who> ::= [ * | anonymous | self | dn=<regex> ]\n"
+               "<who> ::= [ * | anonymous | users | self | dn=<regex> ]\n"
                        "\t[dnattr=<attrname>]\n"
                        "\t[group[/<objectclass>[/<attrname>]]=<regex>]\n"
                        "\t[peername=<regex>] [sockname=<regex>]\n"
@@ -467,7 +950,10 @@ acl_usage( void )
 #ifdef SLAPD_ACI_ENABLED
                        "\t[aci=<attrname>]\n"
 #endif
-               "<access> ::= [self]{none|auth|compare|search|read|write}\n"
+               "<access> ::= [self]{<level>|<priv>}\n"
+               "<level> ::= none | auth | compare | search | read | write\n"
+               "<priv> ::= {=|+|-}{w|r|s|c|x}+\n"
+               "<control> ::= [ stop | continue | break ]\n"
                );
        exit( EXIT_FAILURE );
 }
@@ -495,7 +981,7 @@ access_append( Access **l, Access *a )
        *l = a;
 }
 
-static void
+void
 acl_append( AccessControl **l, AccessControl *a )
 {
        for ( ; *l != NULL; l = &(*l)->acl_next )
@@ -504,37 +990,100 @@ acl_append( AccessControl **l, AccessControl *a )
        *l = a;
 }
 
+char *
+access2str( slap_access_t access )
+{
+       if ( access == ACL_NONE ) {
+               return "none";
+
+       } else if ( access == ACL_AUTH ) {
+               return "auth";
+
+       } else if ( access == ACL_COMPARE ) {
+               return "compare";
+
+       } else if ( access == ACL_SEARCH ) {
+               return "search";
+
+       } else if ( access == ACL_READ ) {
+               return "read";
+
+       } else if ( access == ACL_WRITE ) {
+               return "write";
+       }
+
+       return "unknown";
+}
+
+slap_access_t
+str2access( const char *str )
+{
+       if ( strcasecmp( str, "none" ) == 0 ) {
+               return ACL_NONE;
+
+       } else if ( strcasecmp( str, "auth" ) == 0 ) {
+               return ACL_AUTH;
+
+       } else if ( strcasecmp( str, "compare" ) == 0 ) {
+               return ACL_COMPARE;
+
+       } else if ( strcasecmp( str, "search" ) == 0 ) {
+               return ACL_SEARCH;
+
+       } else if ( strcasecmp( str, "read" ) == 0 ) {
+               return ACL_READ;
+
+       } else if ( strcasecmp( str, "write" ) == 0 ) {
+               return ACL_WRITE;
+       }
+
+       return( ACL_INVALID_ACCESS );
+}
+
 #ifdef LDAP_DEBUG
 
+static char *style_strings[5] = {
+                       "regex",
+                       "base",
+                       "one",
+                       "subtree",
+                       "children"
+               };
+
+
 static void
 print_access( Access *b )
 {
+       char maskbuf[ACCESSMASK_MAXLEN];
+
        fprintf( stderr, "\tby" );
 
        if ( b->a_dn_pat != NULL ) {
-               if( strcmp(b->a_dn_pat, "anonymous") == 0 ) {
-                       fprintf( stderr, " anonymous" );
-
-               } else if( strcmp(b->a_dn_pat, "self") == 0 ) {
-                       fprintf( stderr, " self" );
+               if( strcmp(b->a_dn_pat, "*") == 0
+                       || strcmp(b->a_dn_pat, "users") == 0 
+                       || strcmp(b->a_dn_pat, "anonymous") == 0 
+                       || strcmp(b->a_dn_pat, "self") == 0 )
+               {
+                       fprintf( stderr, " %s", b->a_dn_pat );
 
                } else {
-                       fprintf( stderr, " dn=%s", b->a_dn_pat );
+                       fprintf( stderr, " dn.%s=%s", style_strings[b->a_dn_style], b->a_dn_pat );
                }
        }
 
        if ( b->a_dn_at != NULL ) {
-               fprintf( stderr, " dnattr=%s", b->a_dn_at );
+               fprintf( stderr, " dnattr=%s", b->a_dn_at->ad_cname->bv_val );
        }
 
        if ( b->a_group_pat != NULL ) {
-               fprintf( stderr, " group%s", b->a_group_pat );
+               fprintf( stderr, " group=%s", b->a_group_pat );
 
                if ( b->a_group_oc ) {
-                       fprintf( stderr, " objectClass: %s", b->a_group_oc );
+                       fprintf( stderr, " objectClass: %s",
+                               b->a_group_oc->soc_oclass.oc_oid );
 
                        if ( b->a_group_at ) {
-                               fprintf( stderr, " attributeType: %s", b->a_group_at );
+                               fprintf( stderr, " attributeType: %s", b->a_group_at->ad_cname->bv_val );
                        }
                }
     }
@@ -542,6 +1091,7 @@ print_access( Access *b )
        if ( b->a_peername_pat != NULL ) {
                fprintf( stderr, " peername=%s", b->a_peername_pat );
        }
+
        if ( b->a_sockname_pat != NULL ) {
                fprintf( stderr, " sockname=%s", b->a_sockname_pat );
        }
@@ -556,35 +1106,55 @@ print_access( Access *b )
 
 #ifdef SLAPD_ACI_ENABLED
        if ( b->a_aci_at != NULL ) {
-               fprintf( stderr, " aci=%s", b->a_aci_at );
+               fprintf( stderr, " aci=%s", b->a_aci_at->ad_cname->bv_val );
        }
 #endif
 
+       fprintf( stderr, " %s%s",
+               b->a_dn_self ? "self" : "",
+               accessmask2str( b->a_mask, maskbuf ) );
+
+       if( b->a_type == ACL_BREAK ) {
+               fprintf( stderr, " break" );
+
+       } else if( b->a_type == ACL_CONTINUE ) {
+               fprintf( stderr, " continue" );
+
+       } else if( b->a_type != ACL_STOP ) {
+               fprintf( stderr, " unknown-control" );
+       }
+
        fprintf( stderr, "\n" );
 }
 
+
 static void
-print_acl( AccessControl *a )
+print_acl( Backend *be, AccessControl *a )
 {
-       int             i;
+       int             to = 0;
        Access  *b;
 
-       if ( a == NULL ) {
-               fprintf( stderr, "NULL\n" );
+       fprintf( stderr, "%s ACL: access to",
+               be == NULL ? "Global" : "Backend" );
+
+       if ( a->acl_dn_pat != NULL ) {
+               to++;
+               fprintf( stderr, " dn.%s=%s\n",
+                       style_strings[a->acl_dn_style], a->acl_dn_pat );
        }
-       fprintf( stderr, "ACL: access to" );
+
        if ( a->acl_filter != NULL ) {
-               fprintf(  stderr," filter=" );
+               to++;
+               fprintf( stderr, " filter=" );
                filter_print( a->acl_filter );
+               fprintf( stderr, "\n" );
        }
-       if ( a->acl_dn_pat != NULL ) {
-               fprintf( stderr, " dn=" );
-               fprintf( stderr, a->acl_dn_pat );
-       }
+
        if ( a->acl_attrs != NULL ) {
-               int     first = 1;
+               int     i, first = 1;
+               to++;
 
-               fprintf( stderr, "\n attrs=" );
+               fprintf( stderr, " attrs=" );
                for ( i = 0; a->acl_attrs[i] != NULL; i++ ) {
                        if ( ! first ) {
                                fprintf( stderr, "," );
@@ -592,11 +1162,17 @@ print_acl( AccessControl *a )
                        fprintf( stderr, a->acl_attrs[i] );
                        first = 0;
                }
+               fprintf(  stderr, "\n" );
        }
-       fprintf( stderr, "\n" );
+
+       if( !to ) {
+               fprintf( stderr, " *\n" );
+       }
+
        for ( b = a->acl_access; b != NULL; b = b->a_next ) {
                print_access( b );
        }
+
        fprintf( stderr, "\n" );
 }
 
diff --git a/servers/slapd/ad.c b/servers/slapd/ad.c
new file mode 100644 (file)
index 0000000..9a84425
--- /dev/null
@@ -0,0 +1,245 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/* ad.c - routines for dealing with attribute descriptions */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/ctype.h>
+#include <ac/errno.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/time.h>
+
+#include "ldap_pvt.h"
+#include "slap.h"
+
+AttributeDescription *ad_dup(
+       AttributeDescription *desc )
+{
+       AttributeDescription *ad;
+
+       if( desc == NULL ) {
+               return NULL;
+       }
+
+       ad = (AttributeDescription *) ch_malloc( sizeof(AttributeDescription) );
+
+       *ad = *desc;
+
+       if( ad->ad_cname != NULL ) {
+               ad->ad_cname = ber_bvdup( ad->ad_cname );
+       }
+
+       if( ad->ad_lang != NULL ) {
+               ad->ad_lang = ch_strdup( ad->ad_lang );
+       }
+
+       return ad;
+}
+
+void
+ad_free( AttributeDescription *ad, int freeit )
+{
+       if( ad == NULL ) return;
+
+       if( ad->ad_cname != NULL ) {
+               ber_bvfree( ad->ad_cname );
+       }
+
+       free( ad->ad_lang );
+
+       if( freeit ) free( ad );
+}
+
+static int ad_keystring(
+       struct berval *bv )
+{
+       ber_len_t i;
+
+       if( !AD_CHAR( bv->bv_val[0] ) ) {
+               return 1;
+       }
+
+       for( i=1; i<bv->bv_len; i++ ) {
+               if( !AD_CHAR( bv->bv_val[i] ) ) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+int slap_str2ad(
+       const char *str,
+       AttributeDescription **ad,
+       const char **text )
+{
+       struct berval bv;
+       bv.bv_val = (char *) str;
+       bv.bv_len = strlen( str );
+
+       return slap_bv2ad( &bv, ad, text );
+}
+
+int slap_bv2ad(
+       struct berval *bv,
+       AttributeDescription **ad,
+       const char **text )
+{
+       int rtn = LDAP_UNDEFINED_TYPE;
+       int i;
+       AttributeDescription desc;
+       char **tokens;
+
+       assert( ad != NULL );
+       assert( *ad == NULL ); /* temporary */
+
+       if( bv == NULL || bv->bv_len == 0 ) {
+               *text = "empty attribute description";
+               return rtn;
+       }
+
+       /* make sure description is IA5 */
+       if( ad_keystring( bv ) ) {
+               *text = "attribute description contains inappropriate characters";
+               return rtn;
+       }
+
+       tokens = str2charray( bv->bv_val, ";");
+
+       if( tokens == NULL || *tokens == NULL ) {
+               *text = "no attribute type";
+               goto done;
+       }
+
+       desc.ad_type = at_find( *tokens );
+
+       if( desc.ad_type == NULL ) {
+               *text = "attribute type undefined";
+               goto done;
+       }
+
+       desc.ad_flags = SLAP_DESC_NONE;
+       desc.ad_lang = NULL;
+
+       for( i=1; tokens[i] != NULL; i++ ) {
+               if( strcasecmp( tokens[i], "binary" ) == 0 ) {
+                       if( slap_ad_is_binary( &desc ) ) {
+                               *text = "option \"binary\" specified multiple times";
+                               goto done;
+                       }
+
+                       if( !slap_syntax_is_binary( desc.ad_type->sat_syntax )) {
+                               /* not stored in binary, disallow option */
+                               *text = "option \"binary\" with type not supported";
+                               goto done;
+                       }
+
+                       desc.ad_flags |= SLAP_DESC_BINARY;
+
+               } else if ( strncasecmp( tokens[i], "lang-",
+                       sizeof("lang-")-1 ) == 0 && tokens[i][sizeof("lang-")-1] )
+               {
+                       if( desc.ad_lang != NULL ) {
+                               *text = "multiple language tag options specified";
+                               goto done;
+                       }
+
+                       desc.ad_lang = tokens[i];
+
+                       /* normalize to all lower case, it's easy */
+                       ldap_pvt_str2lower( desc.ad_lang );
+
+               } else {
+                       *text = "unrecognized option";
+                       goto done;
+               }
+       }
+
+       desc.ad_cname = ch_malloc( sizeof( struct berval ) );
+
+       desc.ad_cname->bv_len = strlen( desc.ad_type->sat_cname );
+       if( slap_ad_is_binary( &desc ) ) {
+               desc.ad_cname->bv_len += sizeof("binary");
+       }
+       if( desc.ad_lang != NULL ) {
+               desc.ad_cname->bv_len += 1 + strlen( desc.ad_lang );
+       }
+
+       desc.ad_cname->bv_val = ch_malloc( desc.ad_cname->bv_len + 1 );
+
+       strcpy( desc.ad_cname->bv_val, desc.ad_type->sat_cname );
+       if( slap_ad_is_binary( &desc ) ) {
+               strcat( desc.ad_cname->bv_val, ";binary" );
+       }
+
+       if( desc.ad_lang != NULL ) {
+               strcat( desc.ad_cname->bv_val, ";" );
+               strcat( desc.ad_cname->bv_val, desc.ad_lang );
+       }
+
+       if( *ad == NULL ) {
+               *ad = ch_malloc( sizeof( AttributeDescription ) );
+       }
+
+       **ad = desc;
+
+       rtn = LDAP_SUCCESS;
+
+done:
+       charray_free( tokens );
+       return rtn;
+}
+
+int is_ad_subtype(
+       AttributeDescription *sub,
+       AttributeDescription *super
+)
+{
+       if( !is_at_subtype( sub->ad_type, super->ad_type ) ) {
+               return 0;
+       }
+
+       if( super->ad_flags && ( super->ad_flags == sub->ad_flags )) {
+               return 0;
+       }
+
+       if( super->ad_lang != NULL && ( sub->ad_lang == NULL
+               || strcasecmp( super->ad_lang, sub->ad_lang )))
+       {
+               return 0;
+       }
+
+       return 1;
+}
+
+
+int ad_inlist(
+       AttributeDescription *desc,
+       char **attrs )
+{
+       int i;
+       for( i=0; attrs[i] != NULL; i++ ) {
+               AttributeDescription *ad = NULL;
+               const char *text;
+               int rc;
+               
+               rc = slap_str2ad( attrs[i], &ad, &text );
+
+               if( rc != LDAP_SUCCESS ) continue;
+
+               rc = is_ad_subtype( desc, ad );
+
+               ad_free( ad, 1 );
+
+               if( rc ) return 1;
+       }
+
+       return 0;
+}
+
+
index 388ad9d629960ca608cca10e26f7600babd74cc6..1b7333f5cff4e4a5c55473db1d3143ffb78ea43f 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
 #include <ac/time.h>
 #include <ac/socket.h>
 
+#include "ldap_pvt.h"
 #include "slap.h"
 
-static int     add_created_attrs(Operation *op, Entry *e);
+static int slap_mods2entry(
+       Modifications *mods,
+       Entry **e,
+       const char **text );
 
 int
 do_add( Connection *conn, Operation *op )
@@ -36,17 +40,14 @@ do_add( Connection *conn, Operation *op )
        ber_tag_t       tag;
        Entry           *e;
        Backend         *be;
+       LDAPModList     *modlist = NULL;
+       LDAPModList     **modtail = &modlist;
+       Modifications *mods = NULL;
+       const char *text;
        int                     rc = LDAP_SUCCESS;
 
        Debug( LDAP_DEBUG_TRACE, "do_add\n", 0, 0, 0 );
 
-       if( op->o_bind_in_progress ) {
-               Debug( LDAP_DEBUG_ANY, "do_add: SASL bind in progress.\n", 0, 0, 0 );
-               send_ldap_result( conn, op, LDAP_SASL_BIND_IN_PROGRESS, NULL,
-                   "SASL bind in progress", NULL, NULL );
-               return LDAP_SASL_BIND_IN_PROGRESS;
-       }
-
        /*
         * Parse the add request.  It looks like this:
         *
@@ -69,7 +70,7 @@ do_add( Connection *conn, Operation *op )
 
        ndn = ch_strdup( dn );
 
-       if ( dn_normalize_case( ndn ) == NULL ) {
+       if ( dn_normalize( ndn ) == NULL ) {
                Debug( LDAP_DEBUG_ANY, "do_add: invalid dn (%s)\n", dn, 0, 0 );
                send_ldap_result( conn, op, LDAP_INVALID_DN_SYNTAX, NULL,
                    "invalid DN", NULL, NULL );
@@ -82,54 +83,64 @@ do_add( Connection *conn, Operation *op )
 
        e->e_dn = dn;
        e->e_ndn = ndn;
+       e->e_attrs = NULL;
        e->e_private = NULL;
 
        Debug( LDAP_DEBUG_ARGS, "    do_add: ndn (%s)\n", e->e_ndn, 0, 0 );
 
        /* get the attrs */
-       e->e_attrs = NULL;
        for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
-           tag = ber_next_element( ber, &len, last ) ) {
-               char            *type;
-               struct berval   **vals;
+           tag = ber_next_element( ber, &len, last ) )
+       {
+               LDAPModList *mod = (LDAPModList *) ch_malloc( sizeof(LDAPModList) );
+               mod->ml_op = LDAP_MOD_ADD;
+               mod->ml_next = NULL;
+
+               rc = ber_scanf( ber, "{a{V}}", &mod->ml_type, &mod->ml_bvalues );
 
-               if ( ber_scanf( ber, "{a{V}}", &type, &vals ) == LBER_ERROR ) {
+               if ( rc == LBER_ERROR ) {
+                       Debug( LDAP_DEBUG_ANY, "do_add: decoding error\n", 0, 0, 0 );
                        send_ldap_disconnect( conn, op,
                                LDAP_PROTOCOL_ERROR, "decoding error" );
-                       entry_free( e );
-                       return -1;
+                       rc = -1;
+                       free( mod );
+                       goto done;
                }
 
-               if ( vals == NULL ) {
-                       Debug( LDAP_DEBUG_ANY, "no values for type %s\n", type,
-                           0, 0 );
-                       send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR,
-                               NULL, "no values for type", NULL, NULL );
-                       free( type );
-                       entry_free( e );
-                       return LDAP_PROTOCOL_ERROR;
+               if ( mod->ml_bvalues == NULL ) {
+                       Debug( LDAP_DEBUG_ANY, "no values for type %s\n",
+                               mod->ml_type, 0, 0 );
+                       send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
+                               NULL, "no values for attribute type", NULL, NULL );
+                       free( mod->ml_type );
+                       free( mod );
+                       goto done;
                }
 
-               attr_merge( e, type, vals );
-
-               free( type );
-               ber_bvecfree( vals );
+               *modtail = mod;
+               modtail = &mod->ml_next;
        }
 
        if ( ber_scanf( ber, /*{*/ "}") == LBER_ERROR ) {
-               entry_free( e );
                Debug( LDAP_DEBUG_ANY, "do_add: ber_scanf failed\n", 0, 0, 0 );
                send_ldap_disconnect( conn, op,
                        LDAP_PROTOCOL_ERROR, "decoding error" );
-               return -1;
+               rc = -1;
+               goto done;
        }
 
        if( (rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) {
-               entry_free( e );
                Debug( LDAP_DEBUG_ANY, "do_add: get_ctrls failed\n", 0, 0, 0 );
-               return rc;
+               goto done;
        } 
 
+       if ( modlist == NULL )
+       {
+               send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
+                       NULL, "no attributes provided", NULL, NULL );
+               goto done;
+       }
+
        Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d ADD dn=\"%s\"\n",
            op->o_connid, op->o_opid, e->e_ndn, 0, 0 );
 
@@ -140,19 +151,26 @@ do_add( Connection *conn, Operation *op )
         */
        be = select_backend( e->e_ndn );
        if ( be == NULL ) {
-               entry_free( e );
-               send_ldap_result( conn, op, LDAP_REFERRAL, NULL,
-                   NULL, default_referral, NULL );
-               return rc;
+               send_ldap_result( conn, op, rc = LDAP_REFERRAL,
+                       NULL, NULL, default_referral, NULL );
+               goto done;
+       }
+
+       /* make sure this backend recongizes critical controls */
+       rc = backend_check_controls( be, conn, op, &text ) ;
+
+       if( rc != LDAP_SUCCESS ) {
+               send_ldap_result( conn, op, rc,
+                       NULL, text, NULL, NULL );
+               goto done;
        }
 
        if ( global_readonly || be->be_readonly ) {
                Debug( LDAP_DEBUG_ANY, "do_add: database is read-only\n",
                       0, 0, 0 );
-               entry_free( e );
-               send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
-                                 NULL, "database is read-only", NULL, NULL );
-               return LDAP_UNWILLING_TO_PERFORM;
+               send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
+                       NULL, "directory is read-only", NULL, NULL );
+               goto done;
        }
 
        /*
@@ -172,22 +190,43 @@ do_add( Connection *conn, Operation *op )
                        strcmp( be->be_update_ndn, op->o_ndn ) == 0 )
 #endif
                {
+                       int update = be->be_update_ndn != NULL;
+
+                       rc = slap_modlist2mods( modlist, update, &mods, &text );
+                       if( rc != LDAP_SUCCESS ) {
+                               send_ldap_result( conn, op, rc,
+                                       NULL, text, NULL, NULL );
+                               goto done;
+                       }
+
 #ifndef SLAPD_MULTIMASTER
                        if ( (be->be_lastmod == ON || (be->be_lastmod == UNDEFINED &&
-                               global_lastmod == ON)) && be->be_update_ndn == NULL )
+                               global_lastmod == ON)) && !update )
 #endif
                        {
-                               rc = add_created_attrs( op, e );
-
+                               Modifications **modstail;
+                               for( modstail = &mods;
+                                       *modstail != NULL;
+                                       modstail = &(*modstail)->sml_next )
+                               {
+                                       assert( (*modstail)->sml_op == LDAP_MOD_ADD );
+                                       assert( (*modstail)->sml_desc != NULL );
+                               }
+                               rc = slap_mods_opattrs( op, modstail, &text );
                                if( rc != LDAP_SUCCESS ) {
-                                       entry_free( e );
                                        send_ldap_result( conn, op, rc,
-                                               NULL, "no-user-modification attribute type",
-                                               NULL, NULL );
-                                       return rc;
+                                               NULL, text, NULL, NULL );
+                                       goto done;
                                }
                        }
 
+                       rc = slap_mods2entry( mods, &e, &text );
+                       if( rc != LDAP_SUCCESS ) {
+                               send_ldap_result( conn, op, rc,
+                                       NULL, text, NULL, NULL );
+                               goto done;
+                       }
+
                        if ( (*be->be_add)( be, conn, op, e ) == 0 ) {
 #ifdef SLAPD_MULTIMASTER
                                if (be->be_update_ndn == NULL ||
@@ -197,70 +236,71 @@ do_add( Connection *conn, Operation *op )
                                        replog( be, op, e->e_dn, e );
                                }
                                be_entry_release_w( be, e );
+                               e = NULL;
                        }
 
 #ifndef SLAPD_MULTIMASTER
                } else {
-                       entry_free( e );
                        send_ldap_result( conn, op, rc = LDAP_REFERRAL, NULL, NULL,
                                be->be_update_refs ? be->be_update_refs : default_referral, NULL );
 #endif
                }
        } else {
-           Debug( LDAP_DEBUG_ARGS, "    do_add: HHH\n", 0, 0, 0 );
-               entry_free( e );
+           Debug( LDAP_DEBUG_ARGS, "    do_add: no backend support\n", 0, 0, 0 );
                send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
-                       NULL, "Function not implemented", NULL, NULL );
+                       NULL, "operation not supported within namingContext", NULL, NULL );
+       }
+
+done:
+       if( modlist != NULL ) {
+               slap_modlist_free( modlist );
+       }
+       if( mods != NULL ) {
+               slap_mods_free( mods );
+       }
+       if( e != NULL ) {
+               entry_free( e );
        }
 
        return rc;
 }
 
-static int
-add_created_attrs( Operation *op, Entry *e )
+static int slap_mods2entry(
+       Modifications *mods,
+       Entry **e,
+       const char **text )
 {
-       char            buf[22];
-       struct berval   bv;
-       struct berval   *bvals[2];
-       Attribute       *a;
-       struct tm       *ltm;
-       time_t          currenttime;
-
-       Debug( LDAP_DEBUG_TRACE, "add_created_attrs\n", 0, 0, 0 );
-
-       bvals[0] = &bv;
-       bvals[1] = NULL;
-
-       /* return error on any attempts by the user to add these attrs */
-       for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
-               if ( oc_check_no_usermod_attr( a->a_type ) ) {
-                       return LDAP_CONSTRAINT_VIOLATION;
+       Attribute **tail = &(*e)->e_attrs;
+       assert( *tail == NULL );
+
+       for( ; mods != NULL; mods = mods->sml_next ) {
+               Attribute *attr;
+
+               assert( mods->sml_op == LDAP_MOD_ADD );
+               assert( mods->sml_desc != NULL );
+
+               attr = attr_find( (*e)->e_attrs, mods->sml_desc );
+
+               if( attr != NULL ) {
+                       *text = "attribute provided more than once";
+                       return LDAP_OPERATIONS_ERROR;
                }
-       }
 
-       if ( op->o_dn == NULL || op->o_dn[0] == '\0' ) {
-               bv.bv_val = "<anonymous>";
-               bv.bv_len = strlen( bv.bv_val );
-       } else {
-               bv.bv_val = op->o_dn;
-               bv.bv_len = strlen( bv.bv_val );
-       }
-       attr_merge( e, "creatorsname", bvals );
+               attr = ch_calloc( 1, sizeof(Attribute) );
 
-       currenttime = slap_get_time();
-       ldap_pvt_thread_mutex_lock( &gmtime_mutex );
-#ifndef LDAP_LOCALTIME
-       ltm = gmtime( &currenttime );
-       strftime( buf, sizeof(buf), "%Y%m%d%H%M%SZ", ltm );
-#else
-       ltm = localtime( &currenttime );
-       strftime( buf, sizeof(buf), "%y%m%d%H%M%SZ", ltm );
-#endif
-       ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
+               /* move ad to attr structure */
+               attr->a_desc = mods->sml_desc;
+               mods->sml_desc = NULL;
 
-       bv.bv_val = buf;
-       bv.bv_len = strlen( bv.bv_val );
-       attr_merge( e, "createtimestamp", bvals );
+               /* move values to attr structure */
+               /*      should check for duplicates */
+               attr->a_vals = mods->sml_bvalues;
+               mods->sml_bvalues = NULL;
+
+               *tail = attr;
+               tail = &attr->a_next;
+       }
 
        return LDAP_SUCCESS;
 }
+
diff --git a/servers/slapd/at.c b/servers/slapd/at.c
new file mode 100644 (file)
index 0000000..4ad381d
--- /dev/null
@@ -0,0 +1,386 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/* at.c - routines for dealing with attribute types */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/ctype.h>
+#include <ac/errno.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/time.h>
+
+#include "ldap_pvt.h"
+#include "slap.h"
+
+
+int is_at_syntax(
+       AttributeType *at,
+       const char *oid )
+{
+       for( ; at != NULL; at = at->sat_sup ) {
+               if( at->sat_syntax_oid ) {
+                       return ( strcmp( at->sat_syntax_oid, oid ) == 0 );
+               }
+       }
+
+       return 0;
+}
+
+int is_at_subtype(
+       AttributeType *sub,
+       AttributeType *sup )
+{
+       for( ; sub != NULL; sub = sub->sat_sup ) {
+               if( sub == sup ) return 1;
+       }
+
+       return 0;
+}
+
+struct aindexrec {
+       char            *air_name;
+       AttributeType   *air_at;
+};
+
+static Avlnode *attr_index = NULL;
+static AttributeType *attr_list = NULL;
+
+static int
+attr_index_cmp(
+    struct aindexrec   *air1,
+    struct aindexrec   *air2
+)
+{
+       return (strcasecmp( air1->air_name, air2->air_name ));
+}
+
+static int
+attr_index_name_cmp(
+    const char                 *type,
+    struct aindexrec   *air
+)
+{
+       return (strcasecmp( type, air->air_name ));
+}
+
+AttributeType *
+at_find(
+    const char         *name
+)
+{
+       struct aindexrec        *air;
+       char                    *tmpname;
+
+       {
+               tmpname = (char *)name;
+       }
+
+       if ( (air = (struct aindexrec *) avl_find( attr_index, tmpname,
+            (AVL_CMP) attr_index_name_cmp )) != NULL ) {
+               if ( tmpname != name )
+                       ldap_memfree( tmpname );
+               return( air->air_at );
+       }
+
+       if ( tmpname != name )
+               ldap_memfree( tmpname );
+       return( NULL );
+}
+
+int
+at_append_to_list(
+    AttributeType      *sat,
+    AttributeType      ***listp
+)
+{
+       AttributeType   **list;
+       AttributeType   **list1;
+       int             size;
+
+       list = *listp;
+       if ( !list ) {
+               size = 2;
+               list = calloc(size, sizeof(AttributeType *));
+               if ( !list ) {
+                       return -1;
+               }
+       } else {
+               size = 0;
+               list1 = *listp;
+               while ( *list1 ) {
+                       size++;
+                       list1++;
+               }
+               size += 2;
+               list1 = realloc(list, size*sizeof(AttributeType *));
+               if ( !list1 ) {
+                       return -1;
+               }
+               list = list1;
+       }
+       list[size-2] = sat;
+       list[size-1] = NULL;
+       *listp = list;
+       return 0;
+}
+
+int
+at_delete_from_list(
+    int                        pos,
+    AttributeType      ***listp
+)
+{
+       AttributeType   **list;
+       AttributeType   **list1;
+       int             i;
+       int             j;
+
+       if ( pos < 0 ) {
+               return -2;
+       }
+       list = *listp;
+       for ( i=0; list[i]; i++ )
+               ;
+       if ( pos >= i ) {
+               return -2;
+       }
+       for ( i=pos, j=pos+1; list[j]; i++, j++ ) {
+               list[i] = list[j];
+       }
+       list[i] = NULL;
+       /* Tell the runtime this can be shrinked */
+       list1 = realloc(list, (i+1)*sizeof(AttributeType **));
+       if ( !list1 ) {
+               return -1;
+       }
+       *listp = list1;
+       return 0;
+}
+
+int
+at_find_in_list(
+    AttributeType      *sat,
+    AttributeType      **list
+)
+{
+       int     i;
+
+       if ( !list ) {
+               return -1;
+       }
+       for ( i=0; list[i]; i++ ) {
+               if ( sat == list[i] ) {
+                       return i;
+               }
+       }
+       return -1;
+}
+
+static int
+at_insert(
+    AttributeType      *sat,
+    const char         **err
+)
+{
+       AttributeType           **atp;
+       struct aindexrec        *air;
+       char                    **names;
+
+       atp = &attr_list;
+       while ( *atp != NULL ) {
+               atp = &(*atp)->sat_next;
+       }
+       *atp = sat;
+
+       if ( sat->sat_oid ) {
+               air = (struct aindexrec *)
+                       ch_calloc( 1, sizeof(struct aindexrec) );
+               air->air_name = sat->sat_oid;
+               air->air_at = sat;
+               if ( avl_insert( &attr_index, (caddr_t) air,
+                                (AVL_CMP) attr_index_cmp,
+                                (AVL_DUP) avl_dup_error ) ) {
+                       *err = sat->sat_oid;
+                       ldap_memfree(air);
+                       return SLAP_SCHERR_DUP_ATTR;
+               }
+               /* FIX: temporal consistency check */
+               at_find(air->air_name);
+       }
+
+       if ( (names = sat->sat_names) ) {
+               while ( *names ) {
+                       air = (struct aindexrec *)
+                               ch_calloc( 1, sizeof(struct aindexrec) );
+                       air->air_name = ch_strdup(*names);
+                       air->air_at = sat;
+                       if ( avl_insert( &attr_index, (caddr_t) air,
+                                        (AVL_CMP) attr_index_cmp,
+                                        (AVL_DUP) avl_dup_error ) ) {
+                               *err = *names;
+                               ldap_memfree(air->air_name);
+                               ldap_memfree(air);
+                               return SLAP_SCHERR_DUP_ATTR;
+                       }
+                       /* FIX: temporal consistency check */
+                       at_find(air->air_name);
+                       names++;
+               }
+       }
+
+       return 0;
+}
+
+int
+at_add(
+    LDAP_ATTRIBUTE_TYPE        *at,
+    const char         **err
+)
+{
+       AttributeType   *sat;
+       MatchingRule    *mr;
+       Syntax          *syn;
+       int             code;
+       char                    *cname;
+
+       if ( at->at_names && at->at_names[0] ) {
+               cname = at->at_names[0];
+       } else if ( at->at_oid ) {
+               cname = at->at_oid;
+       } else {
+               cname = "";
+               return SLAP_SCHERR_ATTR_INCOMPLETE;
+       }
+       sat = (AttributeType *) ch_calloc( 1, sizeof(AttributeType) );
+       memcpy( &sat->sat_atype, at, sizeof(LDAP_ATTRIBUTE_TYPE));
+
+       sat->sat_cname = cname;
+
+       if ( at->at_sup_oid ) {
+               AttributeType *supsat = at_find(at->at_sup_oid);
+
+               if ( (supsat == NULL ) ) {
+                       *err = at->at_sup_oid;
+                       return SLAP_SCHERR_ATTR_NOT_FOUND;
+               }
+
+               sat->sat_sup = supsat;
+
+               if ( at_append_to_list(sat, &supsat->sat_subtypes) ) {
+                       *err = cname;
+                       return SLAP_SCHERR_OUTOFMEM;
+               }
+       }
+
+       /*
+        * Inherit definitions from superiors.  We only check the
+        * direct superior since that one has already inherited from
+        * its own superiorss
+        */
+       if ( sat->sat_sup ) {
+               sat->sat_syntax = sat->sat_sup->sat_syntax;
+               sat->sat_equality = sat->sat_sup->sat_equality;
+               sat->sat_ordering = sat->sat_sup->sat_ordering;
+               sat->sat_substr = sat->sat_sup->sat_substr;
+       }
+
+       if ( at->at_syntax_oid ) {
+               if ( (syn = syn_find(sat->sat_syntax_oid)) ) {
+                       sat->sat_syntax = syn;
+               } else {
+                       *err = sat->sat_syntax_oid;
+                       return SLAP_SCHERR_SYN_NOT_FOUND;
+               }
+
+
+       } else if ( sat->sat_syntax == NULL ) {
+               return SLAP_SCHERR_ATTR_INCOMPLETE;
+       }
+
+       if ( sat->sat_equality_oid ) {
+               if ( (mr = mr_find(sat->sat_equality_oid)) ) {
+                       sat->sat_equality = mr;
+               } else {
+                       *err = sat->sat_equality_oid;
+                       return SLAP_SCHERR_MR_NOT_FOUND;
+               }
+
+       }
+
+       if ( sat->sat_ordering_oid ) {
+               if ( (mr = mr_find(sat->sat_ordering_oid)) ) {
+                       sat->sat_ordering = mr;
+               } else {
+                       *err = sat->sat_ordering_oid;
+                       return SLAP_SCHERR_MR_NOT_FOUND;
+               }
+       }
+
+       if ( sat->sat_substr_oid ) {
+               if ( (mr = mr_find(sat->sat_substr_oid)) ) {
+                       sat->sat_substr = mr;
+               } else {
+                       *err = sat->sat_substr_oid;
+                       return SLAP_SCHERR_MR_NOT_FOUND;
+               }
+       }
+
+       code = at_insert(sat,err);
+       return code;
+}
+
+#ifdef LDAP_DEBUG
+static int
+at_index_printnode( struct aindexrec *air )
+{
+
+       printf("%s = %s\n",
+               air->air_name,
+               ldap_attributetype2str(&air->air_at->sat_atype) );
+       return( 0 );
+}
+
+static void
+at_index_print( void )
+{
+       printf("Printing attribute type index:\n");
+       (void) avl_apply( attr_index, (AVL_APPLY) at_index_printnode,
+               0, -1, AVL_INORDER );
+}
+#endif
+
+#if defined( SLAPD_SCHEMA_DN )
+int
+at_schema_info( Entry *e )
+{
+       struct berval   val;
+       struct berval   *vals[2];
+       AttributeType   *at;
+
+       AttributeDescription *ad_attributeTypes = slap_schema.si_ad_attributeTypes;
+
+       vals[0] = &val;
+       vals[1] = NULL;
+
+       for ( at = attr_list; at; at = at->sat_next ) {
+               val.bv_val = ldap_attributetype2str( &at->sat_atype );
+               if ( val.bv_val == NULL ) {
+                       return -1;
+               }
+               val.bv_len = strlen( val.bv_val );
+#if 0
+               Debug( LDAP_DEBUG_TRACE, "Merging at [%ld] %s\n",
+                      (long) val.bv_len, val.bv_val, 0 );
+#endif
+               attr_merge( e, ad_attributeTypes, vals );
+               ldap_memfree( val.bv_val );
+       }
+       return 0;
+}
+#endif
index 8a5f5358cb2f8d263937370fe0bdf455da94dbef..f4aa43308d64a9069d7da4523826c7349aa40c01 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* attr.c - routines for dealing with attributes */
 #include <ac/string.h>
 #include <ac/time.h>
 
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
 #include "ldap_pvt.h"
 #include "slap.h"
 
@@ -33,7 +29,7 @@ static void at_index_print( void );
 void
 attr_free( Attribute *a )
 {
-       free( a->a_type );
+       ad_free( a->a_desc, 1 );
        ber_bvecfree( a->a_vals );
        free( a );
 }
@@ -78,8 +74,7 @@ Attribute *attr_dup( Attribute *a )
                tmp->a_vals = NULL;
        }
 
-       tmp->a_type = ch_strdup( a->a_type );
-       tmp->a_syntax = a->a_syntax;
+       tmp->a_desc = ad_dup( a->a_desc );
        tmp->a_next = NULL;
 
        return tmp;
@@ -103,56 +98,7 @@ Attribute *attrs_dup( Attribute *a )
        return tmp;
 }
 
-/*
- * attr_normalize - normalize an attribute name (make it all lowercase)
- */
-
-char *
-attr_normalize( char *s )
-{
-       assert( s != NULL );
-
-       return( ldap_pvt_str2lower( s ) );
-}
-
-/*
- * attr_merge_fast - merge the given type and value with the list of
- * attributes in attrs. called from str2entry(), where we can make some
- * assumptions to make things faster.
- * returns     0       everything went ok
- *             -1      trouble
- */
-
-int
-attr_merge_fast(
-    Entry              *e,
-    char               *type,
-    struct berval      **vals,
-    int                        nvals,
-    int                        naddvals,
-    int                        *maxvals,
-    Attribute          ***a
-)
-{
-       if ( *a == NULL ) {
-               for ( *a = &e->e_attrs; **a != NULL; *a = &(**a)->a_next ) {
-                       if ( strcasecmp( (**a)->a_type, type ) == 0 ) {
-                               break;
-                       }
-               }
-       }
-
-       if ( **a == NULL ) {
-               **a = (Attribute *) ch_malloc( sizeof(Attribute) );
-               (**a)->a_type = attr_normalize( ch_strdup( type ) );
-               (**a)->a_vals = NULL;
-               (**a)->a_syntax = attr_syntax( type );
-               (**a)->a_next = NULL;
-       }
 
-       return( value_add_fast( &(**a)->a_vals, vals, nvals, naddvals,
-           maxvals ) );
-}
 
 /*
  * attr_merge - merge the given type and value with the list of
@@ -164,23 +110,22 @@ attr_merge_fast(
 int
 attr_merge(
     Entry              *e,
-    char               *type,
-    struct berval      **vals
-)
+       AttributeDescription *desc,
+    struct berval      **vals )
 {
        Attribute       **a;
 
        for ( a = &e->e_attrs; *a != NULL; a = &(*a)->a_next ) {
-               if ( strcasecmp( (*a)->a_type, type ) == 0 ) {
+               if ( ad_cmp( (*a)->a_desc, desc ) == 0 )
+               {
                        break;
                }
        }
 
        if ( *a == NULL ) {
                *a = (Attribute *) ch_malloc( sizeof(Attribute) );
-               (*a)->a_type = attr_normalize( ch_strdup( type ) );
+               (*a)->a_desc = ad_dup( desc );
                (*a)->a_vals = NULL;
-               (*a)->a_syntax = attr_syntax( type );
                (*a)->a_next = NULL;
        }
 
@@ -188,17 +133,18 @@ attr_merge(
 }
 
 /*
- * attr_find - find and return attribute type in list a
+ * attrs_find - find attribute(s) by AttributeDescription
+ * returns next attribute which is subtype of provided description.
  */
 
 Attribute *
-attr_find(
+attrs_find(
     Attribute  *a,
-    const char *type
+       AttributeDescription *desc
 )
 {
        for ( ; a != NULL; a = a->a_next ) {
-               if ( strcasecmp( a->a_type, type ) == 0 ) {
+               if ( is_ad_subtype( a->a_desc, desc ) ) {
                        return( a );
                }
        }
@@ -207,523 +153,51 @@ attr_find(
 }
 
 /*
- * attr_delete - delete the attribute type in list pointed to by attrs
- * return      0       deleted ok
- *             1       not found in list a
- *             -1      something bad happened
+ * attr_find - find attribute by type
  */
 
-int
-attr_delete(
-    Attribute  **attrs,
-    const char *type
+Attribute *
+attr_find(
+    Attribute  *a,
+       AttributeDescription *desc
 )
 {
-       Attribute       **a;
-       Attribute       *save;
-
-       for ( a = attrs; *a != NULL; a = &(*a)->a_next ) {
-               if ( strcasecmp( (*a)->a_type, type ) == 0 ) {
-                       break;
+       for ( ; a != NULL; a = a->a_next ) {
+               if ( ad_cmp( a->a_desc, desc ) == 0 )
+               {
+                       return( a );
                }
        }
 
-       if ( *a == NULL ) {
-               return( 1 );
-       }
-
-       save = *a;
-       *a = (*a)->a_next;
-       attr_free( save );
-
-       return( 0 );
-}
-
-#define DEFAULT_SYNTAX SYNTAX_CIS
-
-/*
- * attr_syntax - return the syntax of attribute type
- */
-
-int
-attr_syntax( char *type )
-{
-       AttributeType   *sat;
-
-       sat = at_find(type);
-       if ( sat ) {
-               return( sat->sat_syntax_compat );
-       }
-
-       return( DEFAULT_SYNTAX );
+       return( NULL );
 }
 
 /*
- * attr_syntax_config - process an attribute syntax config line
+ * attr_delete - delete the attribute type in list pointed to by attrs
+ * return      0       deleted ok
+ *             1       not found in list a
+ *             -1      something bad happened
  */
 
-void
-attr_syntax_config(
-    const char *fname,
-    int                lineno,
-    int                argc,
-    char       **argv
-)
-{
-       char                    *save;
-       LDAP_ATTRIBUTE_TYPE     *at;
-       int                     lasti;
-       int                     code;
-       const char              *err;
-
-       if ( argc < 2 ) {
-               Debug( LDAP_DEBUG_ANY,
-"%s: line %d: missing name in \"attribute <name>+ <syntax>\" (ignored)\n",
-                   fname, lineno, 0 );
-               return;
-       }
-
-       at = (LDAP_ATTRIBUTE_TYPE *)
-               ch_calloc( 1, sizeof(LDAP_ATTRIBUTE_TYPE) );
-
-       lasti = argc - 1;
-       if ( strcasecmp( argv[lasti], "caseignorestring" ) == 0 ||
-           strcasecmp( argv[lasti], "cis" ) == 0 ) {
-               at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.15";
-               at->at_equality_oid = "2.5.13.2";
-               at->at_ordering_oid = "2.5.13.3";
-               at->at_substr_oid = "2.5.13.4";
-       } else if ( strcasecmp( argv[lasti], "telephone" ) == 0 ||
-           strcasecmp( argv[lasti], "tel" ) == 0 ) {
-               at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.50";
-               at->at_equality_oid = "2.5.13.20";
-               at->at_substr_oid = "2.5.13.21";
-       } else if ( strcasecmp( argv[lasti], "dn" ) == 0 ) {
-               at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.12";
-               at->at_equality_oid = "2.5.13.1";
-       } else if ( strcasecmp( argv[lasti], "caseexactstring" ) == 0 ||
-           strcasecmp( argv[lasti], "ces" ) == 0 ) {
-               at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.15";
-               at->at_equality_oid = "2.5.13.5";
-               at->at_ordering_oid = "2.5.13.6";
-               at->at_substr_oid = "2.5.13.7";
-       } else if ( strcasecmp( argv[lasti], "binary" ) == 0 ||
-           strcasecmp( argv[lasti], "bin" ) == 0 ) {
-               at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.5";
-               /* There is no match for binary syntax. Really */
-       } else {
-               Debug( LDAP_DEBUG_ANY,
-           "%s: line %d: unknown syntax \"%s\" in attribute line (ignored)\n",
-                   fname, lineno, argv[lasti] );
-               Debug( LDAP_DEBUG_ANY,
-    "possible syntaxes are \"cis\", \"ces\", \"tel\", \"dn\", or \"bin\"\n",
-                   0, 0, 0 );
-               free( (AttributeType *) at );
-               return;
-       }
-
-       save = argv[lasti];
-       argv[lasti] = NULL;
-       at->at_names = charray_dup( argv );
-       argv[lasti] = save;
-
-       code = at_add( at, &err );
-       if ( code ) {
-               fprintf( stderr, "%s: line %d: %s %s\n",
-                        fname, lineno, scherr2str(code), err);
-               exit( EXIT_FAILURE );
-       }
-       ldap_memfree(at);
-}
-
-int
-at_fake_if_needed(
-    char       *name
-)
-{
-       char *argv[3];
-
-       if ( at_find( name ) ) {
-               return 0;
-       } else {
-               argv[0] = name;
-               argv[1] = "cis";
-               argv[2] = NULL;
-               attr_syntax_config( "implicit", 0, 2, argv );
-               return 0;
-       }
-}
-
-struct aindexrec {
-       char            *air_name;
-       AttributeType   *air_at;
-};
-
-static Avlnode *attr_index = NULL;
-static AttributeType *attr_list = NULL;
-
-static int
-attr_index_cmp(
-    struct aindexrec   *air1,
-    struct aindexrec   *air2
-)
-{
-       return (strcasecmp( air1->air_name, air2->air_name ));
-}
-
-static int
-attr_index_name_cmp(
-    char               *type,
-    struct aindexrec   *air
-)
-{
-       return (strcasecmp( type, air->air_name ));
-}
-
-AttributeType *
-at_find(
-    const char         *name
-)
-{
-       struct aindexrec        *air = NULL;
-
-       if ( (air = (struct aindexrec *) avl_find( attr_index, name,
-            (AVL_CMP) attr_index_name_cmp )) != NULL ) {
-               return( air->air_at );
-       }
-       return( NULL );
-}
-
-int
-at_append_to_list(
-    AttributeType      *sat,
-    AttributeType      ***listp
-)
-{
-       AttributeType   **list;
-       AttributeType   **list1;
-       int             size;
-
-       list = *listp;
-       if ( !list ) {
-               size = 2;
-               list = calloc(size, sizeof(AttributeType *));
-               if ( !list ) {
-                       return -1;
-               }
-       } else {
-               size = 0;
-               list1 = *listp;
-               while ( *list1 ) {
-                       size++;
-                       list1++;
-               }
-               size += 2;
-               list1 = realloc(list, size*sizeof(AttributeType *));
-               if ( !list1 ) {
-                       return -1;
-               }
-               list = list1;
-       }
-       list[size-2] = sat;
-       list[size-1] = NULL;
-       *listp = list;
-       return 0;
-}
-
-int
-at_delete_from_list(
-    int                        pos,
-    AttributeType      ***listp
-)
-{
-       AttributeType   **list;
-       AttributeType   **list1;
-       int             i;
-       int             j;
-
-       if ( pos < 0 ) {
-               return -2;
-       }
-       list = *listp;
-       for ( i=0; list[i]; i++ )
-               ;
-       if ( pos >= i ) {
-               return -2;
-       }
-       for ( i=pos, j=pos+1; list[j]; i++, j++ ) {
-               list[i] = list[j];
-       }
-       list[i] = NULL;
-       /* Tell the runtime this can be shrinked */
-       list1 = realloc(list, (i+1)*sizeof(AttributeType **));
-       if ( !list1 ) {
-               return -1;
-       }
-       *listp = list1;
-       return 0;
-}
-
-int
-at_find_in_list(
-    AttributeType      *sat,
-    AttributeType      **list
-)
-{
-       int     i;
-
-       if ( !list ) {
-               return -1;
-       }
-       for ( i=0; list[i]; i++ ) {
-               if ( sat == list[i] ) {
-                       return i;
-               }
-       }
-       return -1;
-}
-
-static int
-at_insert(
-    AttributeType      *sat,
-    const char         **err
-)
-{
-       AttributeType           **atp;
-       struct aindexrec        *air;
-       char                    **names;
-
-       atp = &attr_list;
-       while ( *atp != NULL ) {
-               atp = &(*atp)->sat_next;
-       }
-       *atp = sat;
-
-       if ( sat->sat_oid ) {
-               air = (struct aindexrec *)
-                       ch_calloc( 1, sizeof(struct aindexrec) );
-               air->air_name = sat->sat_oid;
-               air->air_at = sat;
-               if ( avl_insert( &attr_index, (caddr_t) air,
-                                (AVL_CMP) attr_index_cmp,
-                                (AVL_DUP) avl_dup_error ) ) {
-                       *err = sat->sat_oid;
-                       ldap_memfree(air);
-                       return SLAP_SCHERR_DUP_ATTR;
-               }
-               /* FIX: temporal consistency check */
-               at_find(air->air_name);
-       }
-       if ( (names = sat->sat_names) ) {
-               while ( *names ) {
-                       air = (struct aindexrec *)
-                               ch_calloc( 1, sizeof(struct aindexrec) );
-                       air->air_name = ch_strdup(*names);
-                       air->air_at = sat;
-                       if ( avl_insert( &attr_index, (caddr_t) air,
-                                        (AVL_CMP) attr_index_cmp,
-                                        (AVL_DUP) avl_dup_error ) ) {
-                               *err = *names;
-                               ldap_memfree(air);
-                               return SLAP_SCHERR_DUP_ATTR;
-                       }
-                       /* FIX: temporal consistency check */
-                       at_find(air->air_name);
-                       names++;
-               }
-       }
-
-       return 0;
-}
-
 int
-at_add(
-    LDAP_ATTRIBUTE_TYPE        *at,
-    const char         **err
+attr_delete(
+    Attribute  **attrs,
+       AttributeDescription *desc
 )
 {
-       AttributeType   *sat;
-       AttributeType   *sat1;
-       MatchingRule    *mr;
-       Syntax          *syn;
-       int             code;
-       char            *errattr;
-
-       if ( at->at_names && at->at_names[0] ) {
-               errattr = at->at_names[0];
-       } else if ( at->at_oid ) {
-               errattr = at->at_oid;
-       } else {
-               errattr = "";
-               return SLAP_SCHERR_ATTR_INCOMPLETE;
-       }
-       sat = (AttributeType *) ch_calloc( 1, sizeof(AttributeType) );
-       memcpy( &sat->sat_atype, at, sizeof(LDAP_ATTRIBUTE_TYPE));
-       if ( at->at_sup_oid ) {
-               if ( (sat1 = at_find(at->at_sup_oid)) ) {
-                       sat->sat_sup = sat1;
-                       if ( at_append_to_list(sat, &sat1->sat_subtypes) ) {
-                               *err = errattr;
-                               return SLAP_SCHERR_OUTOFMEM;
-                       }
-               } else {
-                       *err = at->at_sup_oid;
-                       return SLAP_SCHERR_ATTR_NOT_FOUND;
-               }
-       }
-
-       if ( at->at_syntax_oid ) {
-               if ( (syn = syn_find(sat->sat_syntax_oid)) ) {
-                       sat->sat_syntax = syn;
-               } else {
-                       *err = sat->sat_syntax_oid;
-                       return SLAP_SCHERR_SYN_NOT_FOUND;
-               }
-               if ( !strcmp(at->at_syntax_oid,
-                            "1.3.6.1.4.1.1466.115.121.1.15") ) {
-                       if ( at->at_equality_oid &&
-                            !strcmp(at->at_equality_oid, "2.5.13.5") ) {
-                               sat->sat_syntax_compat = SYNTAX_CES;
-                       } else {
-                               sat->sat_syntax_compat = SYNTAX_CIS;
-                       }
-               } else if ( !strcmp(at->at_syntax_oid,
-                                   "1.3.6.1.4.1.1466.115.121.1.50") ) {
-                       sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_TEL;
-               } else if ( !strcmp(at->at_syntax_oid,
-                                   "1.3.6.1.4.1.1466.115.121.1.12") ) {
-                       sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_DN;
-               } else if ( !strcmp(at->at_syntax_oid, "1.3.6.1.4.1.1466.115.121.1.5") ) {
-                       sat->sat_syntax_compat = SYNTAX_BIN;
-               } else {
-                       sat->sat_syntax_compat = DEFAULT_SYNTAX;
-               }
-       } else {
-               sat->sat_syntax_compat = DEFAULT_SYNTAX;
-       }
-
-       if ( sat->sat_equality_oid ) {
-               if ( (mr = mr_find(sat->sat_equality_oid)) ) {
-                       sat->sat_equality = mr;
-               } else {
-                       *err = sat->sat_equality_oid;
-                       return SLAP_SCHERR_MR_NOT_FOUND;
-               }
-       }
-       if ( sat->sat_ordering_oid ) {
-               if ( (mr = mr_find(sat->sat_ordering_oid)) ) {
-                       sat->sat_ordering = mr;
-               } else {
-                       *err = sat->sat_ordering_oid;
-                       return SLAP_SCHERR_MR_NOT_FOUND;
-               }
-       }
-       if ( sat->sat_substr_oid ) {
-               if ( (mr = mr_find(sat->sat_substr_oid)) ) {
-                       sat->sat_substr = mr;
-               } else {
-                       *err = sat->sat_substr_oid;
-                       return SLAP_SCHERR_MR_NOT_FOUND;
-               }
-       }
-
-       /*
-        * Now inherit definitions from superiors.  We only check the
-        * direct superior since that one has already inherited from
-        * its own superiorss
-        */
-       if ( sat->sat_sup ) {
-               if ( !sat->sat_syntax ) {
-                       sat->sat_syntax = sat->sat_sup->sat_syntax;
-                       sat->sat_syntax_len = sat->sat_sup->sat_syntax_len;
-               }
-               if ( !sat->sat_equality ) {
-                       sat->sat_equality = sat->sat_sup->sat_equality;
-               }
-               if ( !sat->sat_ordering ) {
-                       sat->sat_ordering = sat->sat_sup->sat_ordering;
-               }
-               if ( !sat->sat_substr ) {
-                       sat->sat_substr = sat->sat_sup->sat_substr;
-               }
-       }
-       code = at_insert(sat,err);
-       return code;
-}
-
-
-char *
-at_canonical_name( char * a_type )
-{
-       AttributeType   *atp;
-
-       if ( (atp=at_find(a_type)) == NULL ) {
-
-               return a_type;
-
-       } else  if ( atp->sat_names 
-                    && atp->sat_names[0]
-                    && (*(atp->sat_names[0]) != '\0') ) {
-           
-               return atp->sat_names[0];
-
-       } else if (atp->sat_oid && (*atp->sat_oid != '\0')) {
-
-               return atp->sat_oid;
-               
-       } else {
-
-               return a_type;
-
-       }
-
-}/* char * at_canonica_name() */
-
+       Attribute       **a;
 
-#if defined( SLAPD_SCHEMA_DN )
+       for ( a = attrs; *a != NULL; a = &(*a)->a_next ) {
+               if ( ad_cmp( (*a)->a_desc, desc ) == 0 )
+               {
+                       Attribute       *save = *a;
+                       *a = (*a)->a_next;
+                       attr_free( save );
 
-int
-at_schema_info( Entry *e )
-{
-       struct berval   val;
-       struct berval   *vals[2];
-       AttributeType   *at;
-
-       vals[0] = &val;
-       vals[1] = NULL;
-
-       for ( at = attr_list; at; at = at->sat_next ) {
-               val.bv_val = ldap_attributetype2str( &at->sat_atype );
-               if ( val.bv_val ) {
-                       val.bv_len = strlen( val.bv_val );
-                       Debug( LDAP_DEBUG_TRACE, "Merging at [%ld] %s\n",
-                              (long) val.bv_len, val.bv_val, 0 );
-                       attr_merge( e, "attributeTypes", vals );
-                       ldap_memfree( val.bv_val );
-               } else {
-                       return -1;
+                       return LDAP_SUCCESS;
                }
        }
-       return 0;
-}
-#endif
-
-#ifdef LDAP_DEBUG
 
-static int
-at_index_printnode( struct aindexrec *air )
-{
-
-       printf( "%s = %s\n", air->air_name, ldap_attributetype2str(&air->air_at->sat_atype) );
-       return( 0 );
-}
-
-static void
-at_index_print( void )
-{
-       printf("Printing attribute type index:\n");
-       (void) avl_apply( attr_index, (AVL_APPLY) at_index_printnode,
-               0, -1, AVL_INORDER );
+       return LDAP_NO_SUCH_ATTRIBUTE;
 }
 
-#endif
index b3f314050abd88193ed4196eba1acfdf06485ff3..4b797978fa5324a9112e163346b73114f6f4b872 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* ava.c - routines for dealing with attribute value assertions */
 
 #include "slap.h"
 
+
+void
+ava_free(
+    AttributeAssertion *ava,
+    int        freeit
+)
+{
+       ad_free( ava->aa_desc, 1 );
+       ber_bvfree( ava->aa_value );
+       if ( freeit ) {
+               ch_free( (char *) ava );
+       }
+}
+
 int
 get_ava(
     BerElement *ber,
-    Ava                *ava
+    AttributeAssertion **ava,
+       unsigned usage,
+       const char **text
 )
 {
-       if ( ber_scanf( ber, "{ao}", &ava->ava_type, &ava->ava_value )
-           == LBER_ERROR ) {
+       int rc;
+       struct berval type, value, *nvalue;
+       AttributeAssertion *aa;
+
+       rc = ber_scanf( ber, "{oo}", &type, &value );
+
+       if( rc == LBER_ERROR ) {
                Debug( LDAP_DEBUG_ANY, "  get_ava ber_scanf\n", 0, 0, 0 );
-               return( -1 );
+               *text = "Error decoding attribute value assertion";
+               return SLAPD_DISCONNECT;
        }
-       attr_normalize( ava->ava_type );
-       value_normalize( ava->ava_value.bv_val, attr_syntax( ava->ava_type ) );
 
-       return( LDAP_SUCCESS );
-}
+       aa = ch_malloc( sizeof( AttributeAssertion ) );
+       aa->aa_desc = NULL;
+       aa->aa_value = NULL;
 
-void
-ava_free(
-    Ava        *ava,
-    int        freeit
-)
-{
-       free( (char *) ava->ava_type );
-       free( (char *) ava->ava_value.bv_val );
-       if ( freeit ) {
-               free( (char *) ava );
+       rc = slap_bv2ad( &type, &aa->aa_desc, text );
+
+       if( rc != LDAP_SUCCESS ) {
+               ch_free( type.bv_val );
+               ch_free( value.bv_val );
+               ch_free( aa );
+               return rc;
+       }
+
+       rc = value_normalize( aa->aa_desc, usage, &value, &nvalue, text );
+       ch_free( value.bv_val );
+
+       if( rc != LDAP_SUCCESS ) {
+               ch_free( type.bv_val );
+               ad_free( aa->aa_desc, 1 );
+               ch_free( aa );
+               return rc;
        }
+
+       aa->aa_value = nvalue;
+       *ava = aa;
+
+       return LDAP_SUCCESS;
 }
 
diff --git a/servers/slapd/back-bdb2/Makefile.in b/servers/slapd/back-bdb2/Makefile.in
deleted file mode 100644 (file)
index fd25b63..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-# $OpenLDAP$
-
-SRCS   = idl.c add.c search.c cache.c dbcache.c dn2id.c entry.c id2entry.c \
-               index.c id2children.c nextid.c abandon.c compare.c group.c \
-               modify.c modrdn.c delete.c init.c config.c bind.c attr.c \
-               filterindex.c unbind.c kerberos.c close.c alias.c startup.c \
-               timing.c porter.c txn.c tools.c
-OBJS   = idl.lo add.lo search.lo cache.lo dbcache.lo dn2id.lo entry.lo id2entry.lo \
-               index.lo id2children.lo nextid.lo abandon.lo compare.lo group.lo \
-               modify.lo modrdn.lo delete.lo init.lo config.lo bind.lo attr.lo \
-               filterindex.lo unbind.lo kerberos.lo close.lo alias.lo startup.lo \
-               timing.lo porter.lo txn.lo tools.lo
-
-LDAP_INCDIR= ../../../include       
-LDAP_LIBDIR= ../../../libraries
-
-BUILD_OPT = "--enable-bdb2"
-BUILD_MOD = @BUILD_BDB2@
-LINKAGE = @BUILD_BDB2_DYNAMIC@
-
-LIBBASE = back_bdb2
-
-XINCPATH = -I.. -I$(srcdir)/..
-XDEFS = $(MODULES_CPPFLAGS)
-XLDFLAGS = $(MODULES_LDFLAGS)
-
-all-local-lib: ../.backend
-
-../.backend: lib$(LIBBASE).a
-       @touch $@
-
diff --git a/servers/slapd/back-bdb2/abandon.c b/servers/slapd/back-bdb2/abandon.c
deleted file mode 100644 (file)
index a062487..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/* abandon.c - ldbm backend abandon routine */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/time.h>
-#include <ac/unistd.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-
-
-/*ARGSUSED*/
-static int
-bdb2i_back_abandon_internal(
-       BackendDB    *be,
-       Connection *c,
-       Operation  *o,
-       int        msgid )
-{
-       return 0;
-}
-
-
-int
-bdb2_back_abandon(
-       BackendDB    *be,
-       Connection *conn,
-       Operation  *op,
-       int        msgid )
-{
-       struct timeval  time1;
-       int             ret;
-
-       bdb2i_start_timing( be->bd_info, &time1 );
-
-       ret = bdb2i_back_abandon_internal( be, conn, op, msgid );
-
-       bdb2i_stop_timing( be->bd_info, time1, "ABND", conn, op );
-
-       return( ret );
-}
-
-
diff --git a/servers/slapd/back-bdb2/add.c b/servers/slapd/back-bdb2/add.c
deleted file mode 100644 (file)
index b72dc51..0000000
+++ /dev/null
@@ -1,325 +0,0 @@
-/* add.c - ldap bdb2 back-end add routine */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/socket.h>
-#include <ac/string.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-#include "proto-back-bdb2.h"
-
-static DB_LOCK         lock;
-
-
-static int
-bdb2i_back_add_internal(
-    BackendDB  *be,
-    Connection *conn,
-    Operation  *op,
-    Entry      *e
-)
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       char            *pdn;
-       Entry           *p = NULL;
-       int                     rc; 
-       struct timeval  time1;
-
-       Debug(LDAP_DEBUG_ARGS, "==> bdb2i_back_add: %s\n", e->e_dn, 0, 0);
-
-       if ( ( bdb2i_dn2id( be, e->e_ndn ) ) != NOID ) {
-               entry_free( e );
-               send_ldap_result( conn, op, LDAP_ALREADY_EXISTS,
-                       NULL, NULL, NULL, NULL );
-               return( -1 );
-       }
-
-       if ( global_schemacheck && oc_schema_check( e ) != 0 ) {
-               Debug( LDAP_DEBUG_TRACE, "entry failed schema check\n",
-                       0, 0, 0 );
-
-               entry_free( e );
-               send_ldap_result( conn, op, LDAP_OBJECT_CLASS_VIOLATION,
-                       NULL, NULL, NULL, NULL );
-               return( -1 );
-       }
-
-       /*
-        * Get the parent dn and see if the corresponding entry exists.
-        * If the parent does not exist, only allow the "root" user to
-        * add the entry.
-        */
-
-       pdn = dn_parent( be, e->e_ndn );
-
-       if( pdn != NULL && *pdn != '\0' ) {
-               Entry *matched = NULL;
-
-               assert( *pdn != '\0' );
-
-               /* get parent with writer lock */
-               if ( (p = bdb2i_dn2entry_w( be, pdn, &matched )) == NULL ) {
-                       char *matched_dn;
-                       struct berval **refs;
-
-                       if( matched != NULL ) {
-                               matched_dn = ch_strdup( matched->e_dn );
-                               refs = is_entry_referral( matched )
-                                       ? get_entry_referrals( be, conn, op, matched )
-                                       : NULL;
-
-                               bdb2i_cache_return_entry_w( &li->li_cache, matched ); 
-
-                       } else {
-                               matched_dn = NULL;
-                               refs = default_referral;
-                       }
-
-                       Debug( LDAP_DEBUG_TRACE, "parent does not exist\n",
-                               0, 0, 0 );
-
-                       send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
-                           matched_dn, NULL, NULL, NULL );
-
-                       if ( matched != NULL ) {
-                               ber_bvecfree( refs );
-                               free( matched_dn );
-                       }
-
-                       entry_free( e );
-                       free( pdn );
-                       return -1;
-               }
-
-               free(pdn);
-
-               if ( ! access_allowed( be, conn, op, p,
-                       "children", NULL, ACL_WRITE ) )
-               {
-                       /* free parent and writer lock */
-                       bdb2i_cache_return_entry_w( &li->li_cache, p ); 
-
-                       Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
-                           0, 0 );
-                       send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
-                           NULL, NULL, NULL, NULL );
-
-                       entry_free( e );
-                       return -1;
-               }
-
-
-               if ( is_entry_alias( p ) ) {
-                       /* parent is an alias, don't allow add */
-
-                       /* free parent and writer lock */
-                       bdb2i_cache_return_entry_w( &li->li_cache, p ); 
-
-                       Debug( LDAP_DEBUG_TRACE, "parent is alias\n", 0,
-                           0, 0 );
-                       send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM,
-                           NULL, NULL, NULL, NULL );
-
-                       entry_free( e );
-                       return -1;
-               }
-
-               if ( is_entry_referral( p ) ) {
-                       /* parent is an referral, don't allow add */
-                       char *matched_dn = ch_strdup( matched->e_dn );
-                       struct berval **refs = is_entry_referral( matched )
-                                       ? get_entry_referrals( be, conn, op, matched )
-                                       : NULL;
-
-                       /* free parent and writer lock */
-                       bdb2i_cache_return_entry_w( &li->li_cache, p ); 
-
-                       Debug( LDAP_DEBUG_TRACE, "parent is referral\n", 0,
-                           0, 0 );
-                       send_ldap_result( conn, op, LDAP_REFERRAL,
-                           matched_dn, NULL, refs, NULL );
-
-                       ber_bvecfree( refs );
-                       free( matched_dn );
-                       entry_free( e );
-                       return -1;
-               }
-
-       } else {
-               if(pdn != NULL) {
-                       assert( *pdn == '\0' );
-                       free(pdn);
-               }
-
-               /* no parent, must be adding entry to root */
-               if ( !be_isroot( be, op->o_ndn ) && !be_issuffix(be, "") ) {
-                       Debug( LDAP_DEBUG_TRACE, "%s add denied\n",
-                               pdn == NULL ? "suffix" : "entry at root",
-                               0, 0 );
-
-                       send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
-                           NULL, NULL, NULL, NULL );
-
-                       entry_free( e );
-                       return -1;
-               }
-       }
-
-       e->e_id = bdb2i_next_id( be );
-
-       /*
-        * Try to add the entry to the cache, assign it a new dnid.
-        */
-       bdb2i_start_timing( be->bd_info, &time1 );
-
-       rc = bdb2i_cache_add_entry_rw( &li->li_cache, e, CACHE_WRITE_LOCK );
-
-       bdb2i_stop_timing( be->bd_info, time1, "ADD-CACHE", conn, op );
-
-       if ( rc != 0 ) {
-               if( p != NULL) {
-                       /* free parent and writer lock */
-                       bdb2i_cache_return_entry_w( &li->li_cache, p ); 
-               }
-
-               Debug( LDAP_DEBUG_ANY, "cache_add_entry_lock failed\n", 0, 0,
-                   0 );
-
-               /* free the entry */
-               entry_free( e );
-
-               send_ldap_result( conn, op,
-                       rc > 0 ? LDAP_ALREADY_EXISTS : LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-
-               return( -1 );
-       }
-
-       rc = -1;
-
-       /*
-        * Add the entry to the attribute indexes, then add it to
-        * the id2entry and dn2id index.
-        */
-
-       bdb2i_start_timing( be->bd_info, &time1 );
-
-       /* attribute indexes */
-       if ( bdb2i_index_add_entry( be, e ) != 0 ) {
-               Debug( LDAP_DEBUG_TRACE, "bdb2i_index_add_entry failed\n", 0,
-                   0, 0 );
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-
-               bdb2i_stop_timing( be->bd_info, time1, "ADD-INDEX", conn, op );
-
-               goto return_results;
-       }
-
-       bdb2i_stop_timing( be->bd_info, time1, "ADD-INDEX", conn, op );
-
-       bdb2i_start_timing( be->bd_info, &time1 );
-
-       /* dn2id index */
-       if ( bdb2i_dn2id_add( be, e->e_ndn, e->e_id ) != 0 ) {
-               Debug( LDAP_DEBUG_TRACE, "bdb2i_dn2id_add failed\n", 0,
-                   0, 0 );
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-
-               bdb2i_stop_timing( be->bd_info, time1, "ADD-DN2ID", conn, op );
-
-               goto return_results;
-       }
-
-       bdb2i_stop_timing( be->bd_info, time1, "ADD-DN2ID", conn, op );
-
-       bdb2i_start_timing( be->bd_info, &time1 );
-
-       /* id2entry index */
-       if ( bdb2i_id2entry_add( be, e ) != 0 ) {
-               Debug( LDAP_DEBUG_TRACE, "bdb2i_id2entry_add failed\n", 0,
-                   0, 0 );
-               (void) bdb2i_dn2id_delete( be, e->e_ndn, e->e_id );
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-
-               bdb2i_stop_timing( be->bd_info, time1, "ADD-ID2ENTRY", conn, op );
-
-               goto return_results;
-       }
-
-       bdb2i_stop_timing( be->bd_info, time1, "ADD-ID2ENTRY", conn, op );
-
-       send_ldap_result( conn, op, LDAP_SUCCESS,
-                       NULL, NULL, NULL, NULL );
-       rc = 0;
-
-return_results:;
-       if (p != NULL) {
-               /* free parent and writer lock */
-               bdb2i_cache_return_entry_w( &li->li_cache, p ); 
-       }
-
-       if ( rc ) {
-               /* free entry and writer lock */
-               bdb2i_cache_return_entry_w( &li->li_cache, e );
-       }
-
-       return( rc );
-}
-
-
-int
-bdb2_back_add(
-    BackendDB  *be,
-    Connection *conn,
-    Operation  *op,
-    Entry      *e
-)
-{
-       struct ldbminfo *li  = (struct ldbminfo *) be->be_private;
-       struct timeval  time1;
-       int             ret;
-
-       bdb2i_start_timing( be->bd_info, &time1 );
-
-       if ( bdb2i_enter_backend_w( &lock ) != 0 ) {
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-               return( -1 );
-       }
-
-       /*  check, if a new default attribute index will be created,
-               in which case we have to open the index file BEFORE TP  */
-       switch ( slapMode & SLAP_MODE ) {
-               case SLAP_SERVER_MODE:
-               case SLAP_TOOL_MODE:
-                       bdb2i_check_default_attr_index_add( li, e );
-                       break;
-       }
-
-       ret = bdb2i_back_add_internal( be, conn, op, e );
-
-       /*  if the operation was successful, we will delay the unlock  */
-       if ( ret )
-               (void) bdb2i_leave_backend_w( lock );
-
-       bdb2i_stop_timing( be->bd_info, time1, "ADD", conn, op );
-
-       return( ret );
-}
-
-
-int
-bdb2i_release_add_lock( void )
-{
-       (void) bdb2i_leave_backend_w( lock );
-       return 0;
-}
-
-
diff --git a/servers/slapd/back-bdb2/alias.c b/servers/slapd/back-bdb2/alias.c
deleted file mode 100644 (file)
index 3de54b9..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-/* $OpenLDAP$ */
-/*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-#include <ac/socket.h>
-#include "slap.h"
-#include "back-bdb2.h"
-#include "proto-back-bdb2.h"
-
-static char* get_alias_dn(
-       Entry *e,
-       int *err,
-       char **errmsg );
-
-static char* new_superior(
-       char *dn,
-       char *oldSup,
-       char *newSup );
-
-static int dnlist_subordinate(
-       char** dnlist,
-       char *dn );
-
-Entry *bdb2i_deref_r(
-       Backend*        be,
-       Entry*          alias,
-       char*           dn,
-       int*            err,
-       Entry**         matched,
-       char**          text )
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       Entry *entry;
-       Entry *sup;
-       unsigned depth;
-       char **dnlist;
-
-       assert( ( alias != NULL && dn == NULL ) || ( alias == NULL && dn != NULL ) );
-
-       *matched = NULL;
-       *err = LDAP_SUCCESS;
-       *text = NULL;
-
-       if( alias == NULL ) {
-               dn = ch_strdup( dn );
-               entry = bdb2i_dn2entry_r( be, dn, &sup );
-
-       } else {
-               dn = ch_strdup( alias->e_ndn );
-               entry = alias;
-               sup = NULL;
-       }
-
-       dnlist = NULL;
-       charray_add( &dnlist, dn );
-
-       for( depth=0 ; ; depth++ ) {
-               if( entry != NULL ) {
-                       Entry *newe;
-                       char *aliasDN;
-
-                       /* have entry, may be an alias */
-
-                       if( !is_entry_alias( entry ) ) {
-                               /* entry is not an alias */
-                               break;
-                       }
-
-                       /* entry is alias */
-                       if( depth > be->be_max_deref_depth ) {
-                               *matched = entry;
-                               entry = NULL;
-                               *err = LDAP_ALIAS_DEREF_PROBLEM;
-                               *text = "maximum deref depth exceeded";
-                               break;
-                       }
-
-                       /* deref entry */
-                       aliasDN = get_alias_dn( entry, err, text );
-
-                       if( aliasDN == NULL ) {
-                               *matched = entry;
-                               entry = NULL;
-                               break;
-                       }
-
-                       /* check if aliasDN is a subordinate of any DN in our list */
-                       if( dnlist_subordinate( dnlist, aliasDN ) ) {
-                               *matched = entry;
-                               entry = NULL;
-                               *err = LDAP_ALIAS_PROBLEM;
-                               *text = "circular alias";
-                               break;
-                       }
-
-                       /* attempt to dereference alias */
-
-                       newe = bdb2i_dn2entry_r( be, aliasDN, &sup );
-
-                       if( newe != NULL ) {
-                               free( dn );
-                               bdb2i_cache_return_entry_r(&li->li_cache, entry );
-                               entry = newe;
-                               dn = ch_strdup( entry->e_ndn );
-                               charray_add( &dnlist, dn );
-                               continue;
-
-                       }
-                       
-                       if ( sup != NULL ) {
-                               bdb2i_cache_return_entry_r(&li->li_cache, entry );
-                               entry = NULL;
-                               continue;
-                       }
-
-                       /* no newe and no superior, we're done */
-                       break;
-
-               } else if( sup != NULL ) {
-                       /* have superior, may be an alias */
-                       Entry *newe;
-                       Entry *newSup;
-                       char *supDN;
-                       char *aliasDN;
-
-                       if( !is_entry_alias( sup ) ) {
-                               /* entry is not an alias */
-                               *matched = sup;
-                               sup = NULL;
-                               break;
-                       }
-
-                       /* entry is alias */
-                       if( depth > be->be_max_deref_depth ) {
-                               *matched = sup;
-                               entry = NULL;
-                               *err = LDAP_ALIAS_DEREF_PROBLEM;
-                               *text = "maximum deref depth exceeded";
-                               break;
-                       }
-
-                       /* deref entry */
-                       supDN = get_alias_dn( sup, err, text );
-
-                       if( supDN == NULL ) {
-                               *matched = sup;
-                               break;
-                       }
-
-                       aliasDN = new_superior( dn, sup->e_ndn, supDN );
-
-                       if( aliasDN == NULL ) {
-                               free(aliasDN);
-                               *matched = sup;
-                               *err = LDAP_ALIAS_PROBLEM;
-                               *text = "superior alias problem";
-                               break;
-                       }
-
-                       /* check if aliasDN is a subordinate of any DN in our list */
-                       if( dnlist_subordinate( dnlist, aliasDN ) ) {
-                               free(aliasDN);
-                               *matched = entry;
-                               entry = NULL;
-                               *err = LDAP_ALIAS_PROBLEM;
-                               *text = "subordinate circular alias";
-                               break;
-                       }
-
-                       /* attempt to dereference alias */
-                       newe = bdb2i_dn2entry_r( be, aliasDN, &newSup );
-
-                       if( newe != NULL ) {
-                               free(aliasDN);
-                               free( dn );
-                               bdb2i_cache_return_entry_r(&li->li_cache, sup );
-                               entry = newe;
-                               dn = ch_strdup( entry->e_ndn );
-                               charray_add( &dnlist, dn );
-                               continue;
-
-                       }
-                       
-                       if ( newSup != NULL ) {
-                               free( dn );
-                               bdb2i_cache_return_entry_r(&li->li_cache, sup );
-                               sup = newSup;
-                               dn = aliasDN;
-                               continue;
-                       }
-
-                       break;
-
-               } else {
-                       /* no newe and no superior, we're done */
-                       break;
-               }
-       }
-
-       free( dn );
-       return entry;
-}
-
-
-static char* get_alias_dn(
-       Entry *e,
-       int *err,
-       char **errmsg )
-{      
-       Attribute *a = attr_find( e->e_attrs, "aliasedobjectname" );
-
-       if( a == NULL ) {
-               /*
-                * there was an aliasedobjectname defined but no data.
-                */
-               *err = LDAP_ALIAS_PROBLEM;
-               *errmsg = "alias missing aliasedObjectName attribute";
-               return NULL;
-       }
-
-       /* 
-        * aliasedObjectName should be SINGLE-VALUED with a single value. 
-        */                     
-       if ( a->a_vals[0] == NULL || a->a_vals[0]->bv_val == NULL ) {
-               /*
-                * there was an aliasedobjectname defined but no data.
-                */
-               *err = LDAP_ALIAS_PROBLEM;
-               *errmsg = "alias missing aliasedObjectName value";
-               return NULL;
-       }
-
-       if( a->a_vals[1] != NULL ) {
-               *err = LDAP_ALIAS_PROBLEM;
-               *errmsg = "alias has multivalued aliasedObjectName";
-               return NULL;
-       }
-
-       return a->a_vals[0]->bv_val;
-}
-
-static char* new_superior(
-       char *dn,
-       char *oldSup,
-       char *newSup )
-{
-       char *newDN;
-       size_t dnlen, olen, nlen;
-       assert( dn && oldSup && newSup );
-
-       dnlen = strlen( dn );
-       olen = strlen( oldSup );
-       nlen = strlen( newSup );
-
-       newDN = ch_malloc( dnlen - olen + nlen + 1 );
-
-       memcpy( newDN, dn, dnlen - olen );
-       memcpy( &newDN[dnlen - olen], newSup, nlen );
-       newDN[dnlen - olen + nlen] = '\0';
-
-       return newDN;
-}
-
-static int dnlist_subordinate(
-       char** dnlist,
-       char *dn )
-{
-       int i;
-       assert( dnlist );
-
-       for( i = 0; dnlist[i] != NULL; i++ ) {
-               if( dn_issuffix( dnlist[i], dn ) ) {
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-
diff --git a/servers/slapd/back-bdb2/attr.c b/servers/slapd/back-bdb2/attr.c
deleted file mode 100644 (file)
index 7fa5988..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/* attr.c - backend routines for dealing with attributes */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/socket.h>
-#include <ac/string.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-
-static int
-ainfo_type_cmp(
-    char               *type,
-    struct attrinfo    *a
-)
-{
-       return( strcasecmp( type, a->ai_type ) );
-}
-
-static int
-ainfo_cmp(
-    struct attrinfo    *a,
-    struct attrinfo    *b
-)
-{
-       return( strcasecmp( a->ai_type, b->ai_type ) );
-}
-
-/*
- * Called when a duplicate "index" line is encountered.
- *
- * returns 1 => original from init code, indexmask updated
- *        2 => original not from init code, warn the user
- */
-
-static int
-ainfo_dup(
-    struct attrinfo    *a,
-    struct attrinfo    *b
-)
-{
-       /*
-        * if the duplicate definition is because we initialized the attr,
-        * just add what came from the config file. otherwise, complain.
-        */
-       if ( a->ai_indexmask & INDEX_FROMINIT ) {
-               a->ai_indexmask |= b->ai_indexmask;
-
-               return( 1 );
-       }
-
-       return( 2 );
-}
-
-void
-bdb2i_attr_masks(
-    struct ldbminfo    *li,
-    char               *type,
-    int                        *indexmask,
-    int                        *syntaxmask
-)
-{
-       struct attrinfo *a;
-
-       *indexmask = 0;
-       *syntaxmask = 0;
-       if ( (a = (struct attrinfo *) avl_find( li->li_attrs, type,
-           (AVL_CMP) ainfo_type_cmp )) == NULL ) {
-               if ( (a = (struct attrinfo *) avl_find( li->li_attrs, "default",
-                   (AVL_CMP) ainfo_type_cmp )) == NULL ) {
-                       return;
-               }
-       }
-       *indexmask = a->ai_indexmask;
-       if ( strcasecmp( a->ai_type, "default" ) == 0 ) {
-               *syntaxmask = attr_syntax( type );
-       } else {
-               *syntaxmask = a->ai_syntaxmask;
-       }
-}
-
-
-/*  BDB2 changed  */
-void
-bdb2i_attr_index_config(
-    struct ldbminfo    *li,
-    const char         *fname,
-    int                        lineno,
-    int                        argc,
-    char               **argv,
-    int                        init
-)
-{
-       int             i, j;
-       char            **attrs, **indexes;
-       struct attrinfo *a;
-
-       attrs = str2charray( argv[0], "," );
-       if ( argc > 1 ) {
-               indexes = str2charray( argv[1], "," );
-       }
-       for ( i = 0; attrs[i] != NULL; i++ ) {
-               a = (struct attrinfo *) ch_malloc( sizeof(struct attrinfo) );
-               a->ai_type = ch_strdup( attrs[i] );
-               a->ai_syntaxmask = attr_syntax( a->ai_type );
-               if ( argc == 1 ) {
-                       a->ai_indexmask = (INDEX_PRESENCE | INDEX_EQUALITY |
-                           INDEX_APPROX | INDEX_SUB);
-               } else {
-                       a->ai_indexmask = 0;
-                       for ( j = 0; indexes[j] != NULL; j++ ) {
-                               if ( strncasecmp( indexes[j], "pres", 4 )
-                                   == 0 ) {
-                                       a->ai_indexmask |= INDEX_PRESENCE;
-                               } else if ( strncasecmp( indexes[j], "eq", 2 )
-                                   == 0 ) {
-                                       a->ai_indexmask |= INDEX_EQUALITY;
-                               } else if ( strncasecmp( indexes[j], "approx",
-                                   6 ) == 0 ) {
-                                       a->ai_indexmask |= INDEX_APPROX;
-                               } else if ( strncasecmp( indexes[j], "sub", 3 )
-                                   == 0 ) {
-                                       a->ai_indexmask |= INDEX_SUB;
-                               } else if ( strncasecmp( indexes[j], "none", 4 )
-                                   == 0 ) {
-                                       if ( a->ai_indexmask != 0 ) {
-                                               fprintf( stderr,
-"%s: line %d: index type \"none\" cannot be combined with other types\n",
-                                                   fname, lineno );
-                                       }
-                                       a->ai_indexmask = 0;
-                               } else {
-                                       fprintf( stderr,
-                       "%s: line %d: unknown index type \"%s\" (ignored)\n",
-                                           fname, lineno, indexes[j] );
-                                       fprintf( stderr,
-       "valid index types are \"pres\", \"eq\", \"approx\", or \"sub\"\n" );
-                               }
-                       }
-               }
-               if ( init ) {
-                       a->ai_indexmask |= INDEX_FROMINIT;
-               } else {
-                       if ( a->ai_indexmask )
-                               bdb2i_txn_attr_config( li, a->ai_type, 0 );
-               }
-
-               switch (avl_insert( &li->li_attrs, (caddr_t) a,
-                       (AVL_CMP) ainfo_cmp, (AVL_DUP) ainfo_dup ))
-               {
-               case 1:         /* duplicate - updating init version */
-                       free( a->ai_type );
-                       free( (char *) a );
-                       break;
-
-               case 2:         /* user duplicate - ignore and warn */
-                       fprintf( stderr,
-    "%s: line %d: duplicate index definition for attr \"%s\" (ignored)\n",
-                           fname, lineno, a->ai_type );
-                       free( a->ai_type );
-                       free( (char *) a );
-                       break;
-
-               default:;       /* inserted ok */
-                       /* FALL */
-               }
-       }
-       charray_free( attrs );
-       if ( argc > 1 )
-               charray_free( indexes );
-}
diff --git a/servers/slapd/back-bdb2/back-bdb2.h b/servers/slapd/back-bdb2/back-bdb2.h
deleted file mode 100644 (file)
index 4ebc544..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/* back-bdb2.h - ldap bdb2 back-end header file */
-/* $OpenLDAP$ */
-
-#ifndef _BACK_BDB2_H_
-#define _BACK_BDB2_H_
-
-#include "ldbm.h"
-#include "db.h"
-
-LDAP_BEGIN_DECL
-
-#define DEFAULT_CACHE_SIZE     1000
-
-/*  since DEFAULT_DB_PAGE_SIZE is 1K, we have 128K,
-       which is suggested by Sleepycat  */
-#define DEFAULT_DBCACHE_SIZE (128 * DEFAULT_DB_PAGE_SIZE)
-
-#define DEFAULT_DB_DIRECTORY   "/usr/tmp"
-#define DEFAULT_DB_HOME         "/usr/tmp"
-#define DEFAULT_MODE           0600
-
-#define SUBLEN                 3
-
-#define DN_BASE_PREFIX         '='
-#define DN_ONE_PREFIX          '@'
-#define DN_SUBTREE_PREFIX      '?'
-    
-#define SLAPD_FILTER_DN_ONE                    ((ber_tag_t) -2)
-#define SLAPD_FILTER_DN_SUBTREE                ((ber_tag_t) -3)
-
-
-#define BDB2_SUFFIX     ".bdb2"
-
-
-/*
- * there is a single index for each attribute.  these prefixes ensure
- * that there is no collision among keys.
- */
-#define EQ_PREFIX      '='     /* prefix for equality keys     */
-#define APPROX_PREFIX  '~'     /* prefix for approx keys       */
-#define SUB_PREFIX     '*'     /* prefix for substring keys    */
-#define CONT_PREFIX    '\\'    /* prefix for continuation keys */
-
-/* allow 3 characters per byte + PREFIX + EOS */
-#define CONT_SIZE      ( sizeof(long)*3 + 1 + 1 )
-
-
-#define UNKNOWN_PREFIX '?'     /* prefix for unknown keys    */
-
-#define DEFAULT_BLOCKSIZE      8192
-
-/*
- * This structure represents an id block on disk and an id list
- * in core.
- *
- * The fields have the following meanings:
- *
- *     b_nmax  maximum number of ids in this block. if this is == ALLIDSBLOCK,
- *             then this block represents all ids.
- *     b_nids  current number of ids in use in this block.  if this
- *             is == INDBLOCK, then this block is an indirect block
- *             containing a list of other blocks containing actual ids.
- *             the list is terminated by an id of NOID.
- *     b_ids   a list of the actual ids themselves
- */
-
-typedef ID ID_BLOCK;
-
-#define ID_BLOCK_NMAX_OFFSET   0
-#define ID_BLOCK_NIDS_OFFSET   1
-#define ID_BLOCK_IDS_OFFSET            2
-
-/* all ID_BLOCK macros operate on a pointer to a ID_BLOCK */
-
-#define ID_BLOCK_NMAX(b)               ((b)[ID_BLOCK_NMAX_OFFSET])
-#define ID_BLOCK_NIDS(b)               ((b)[ID_BLOCK_NIDS_OFFSET])
-#define ID_BLOCK_ID(b, n)              ((b)[ID_BLOCK_IDS_OFFSET+(n)])
-
-#define ID_BLOCK_NOID(b, n)            (ID_BLOCK_ID((b),(n)) == NOID)
-
-#define ID_BLOCK_ALLIDS_VALUE  0
-#define ID_BLOCK_ALLIDS(b)             (ID_BLOCK_NMAX(b) == ID_BLOCK_ALLIDS_VALUE)
-
-#define ID_BLOCK_INDIRECT_VALUE        0
-#define ID_BLOCK_INDIRECT(b)   (ID_BLOCK_NIDS(b) == ID_BLOCK_INDIRECT_VALUE)
-
-/* for the in-core cache of entries */
-struct cache {
-       int             c_maxsize;
-       int             c_cursize;
-       Avlnode         *c_dntree;
-       Avlnode         *c_idtree;
-       Entry           *c_lruhead;     /* lru - add accessed entries here */
-       Entry           *c_lrutail;     /* lru - rem lru entries from here */
-       ldap_pvt_thread_mutex_t c_mutex;
-};
-
-#define CACHE_READ_LOCK                0
-#define CACHE_WRITE_LOCK       1
-
-/* for the cache of open index files (re-used for txn) */
-struct dbcache {
-       int                     dbc_refcnt;
-       int                     dbc_maxids;
-       int                     dbc_maxindirect;
-       long            dbc_blksize;
-       char            *dbc_name;
-       LDBM            dbc_db;
-
-       struct dbcache   *next;
-};
-
-typedef  struct dbcache  BDB2_TXN_FILES;
-typedef  struct dbcache DBCache;
-
-
-/* for the cache of attribute information (which are indexed, etc.) */
-struct attrinfo {
-       char    *ai_type;       /* type name (cn, sn, ...)      */
-       int     ai_indexmask;   /* how the attr is indexed      */
-#define INDEX_PRESENCE 0x0001
-#define INDEX_EQUALITY 0x0002
-#define INDEX_APPROX   0x0004
-#define INDEX_SUB              0x0008
-#define INDEX_UNKNOWN  0x0010
-#define INDEX_FROMINIT 0x1000
-       int     ai_syntaxmask;  /* what kind of syntax          */
-/* ...from slap.h...
-#define SYNTAX_CIS      0x01
-#define SYNTAX_CES      0x02
-#define SYNTAX_BIN      0x04
-   ... etc. ...
-*/
-};
-
-/*  TP stuff  */
-
-typedef  struct _bdb2_txn_head {
-
-       /*  log size and timer to control checkpoints  */
-       u_int32_t        txn_log;
-       u_int32_t        txn_time;
-
-       /*  a list of all DB files in use  */
-       BDB2_TXN_FILES   *dbFiles;
-
-       /*  we have five fixed files  */
-#define  BDB2_DB_DN_FILE            0
-#define  BDB2_DB_DN2ID_FILE         1
-#define  BDB2_DB_ID2ENTRY_FILE      2
-#define  BDB2_DB_ID2CHILDREN_FILE   3
-#define  BDB2_DB_OC_IDX_FILE        4
-
-       /*  a database handle for the NEXTID file
-               (must be opened like all DB files at startup
-               and closed on shutdown  */
-       LDBM             nextidFile;
-
-       /*  is the default attribute index set to non-none  */
-       int              withDefIDX;
-#define  BDB2_WITH_DEF_IDX          1
-
-       /*  a handle for the backend's environment  */
-       DB_ENV           **dbenvH;
-
-} BDB2_TXN_HEAD;
-
-
-/*  end of TP stuff  */
-
-
-/*  the private description of a backend type  */
-struct ldbtype {
-       char                    *lty_dbhome;
-       size_t                  lty_mpsize;
-       int                             lty_betiming;
-};
-
-#define with_timing(bi) (((struct ldbtype *) \
-                       (bi)->bi_private)->lty_betiming == 1)
-
-/*  The DB environment  */
-extern DB_ENV       bdb2i_dbEnv;
-
-
-/*  the private description of a database  */
-struct ldbminfo {
-       ID                      li_nextid;
-       char            *li_nextid_file;
-       int                     li_mode;
-       char                    *li_directory;
-       struct cache            li_cache;
-       Avlnode                 *li_attrs;
-       int                     li_dbcachesize;
-       int                     li_dbcachewsync;
-
-       /*  a list of all files of the database  */
-       BDB2_TXN_HEAD           li_txn_head;
-
-};
-
-
-#include "proto-back-bdb2.h"
-
-LDAP_END_DECL
-
-#endif /* _back_bdb2_h_ */
diff --git a/servers/slapd/back-bdb2/bind.c b/servers/slapd/back-bdb2/bind.c
deleted file mode 100644 (file)
index e022a55..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-/* bind.c - bdb2 backend bind and unbind routines */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/krb.h>
-#include <ac/socket.h>
-#include <ac/string.h>
-#include <ac/unistd.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-#include "proto-back-bdb2.h"
-
-#include <lutil.h>
-
-#ifdef HAVE_KERBEROS
-extern int     bdb2i_krbv4_ldap_auth();
-#endif
-
-static int
-crypted_value_find(
-       struct berval       **vals,
-       struct berval       *v,
-       int                 syntax,
-       int                 normalize,
-       struct berval           *cred
-)
-{
-       int     i;
-       for ( i = 0; vals[i] != NULL; i++ ) {
-               if ( syntax != SYNTAX_BIN ) {
-                       int result;
-
-#ifdef SLAPD_CRYPT
-                       ldap_pvt_thread_mutex_lock( &crypt_mutex );
-#endif
-
-                       result = lutil_passwd(
-                               (char*) cred->bv_val,
-                               (char*) vals[i]->bv_val,
-                               NULL );
-
-#ifdef SLAPD_CRYPT
-                       ldap_pvt_thread_mutex_unlock( &crypt_mutex );
-#endif
-
-                       return result;
-
-               } else {
-                if ( value_cmp( vals[i], v, syntax, normalize ) == 0 ) {
-                        return( 0 );
-                }
-        }
-       }
-
-       return( 1 );
-}
-
-static int
-bdb2i_back_bind_internal(
-    BackendDB          *be,
-    Connection         *conn,
-    Operation          *op,
-    char               *dn,
-    int                        method,
-       char            *mech,
-    struct berval      *cred,
-       char**  edn
-)
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       Entry           *e;
-       Attribute       *a;
-       int             rc;
-       Entry           *matched;
-#ifdef HAVE_KERBEROS
-       char            krbname[MAX_K_NAME_SZ + 1];
-       AUTH_DAT        ad;
-#endif
-
-       Debug(LDAP_DEBUG_ARGS, "==> bdb2_back_bind: dn: %s\n", dn, 0, 0);
-
-       *edn = NULL;
-
-       /* get entry with reader lock */
-       if ( (e = bdb2i_dn2entry_r( be, dn, &matched )) == NULL ) {
-               char *matched_dn = NULL;
-               struct berval **refs = NULL;
-
-               if ( matched != NULL ) {
-                       matched_dn = ch_strdup( matched->e_dn );
-                       refs = is_entry_referral( matched )
-                               ? get_entry_referrals( be, conn, op, matched )
-                               : NULL;
-                       bdb2i_cache_return_entry_r( &li->li_cache, matched );
-               } else {
-                       refs = default_referral;
-               }
-
-               /* allow noauth binds */
-               rc = 1;
-               if ( method == LDAP_AUTH_SIMPLE ) {
-                       if( cred->bv_len == 0 ) {
-                               /* SUCCESS */
-                               send_ldap_result( conn, op, LDAP_SUCCESS,
-                                       NULL, NULL, NULL, NULL );
-
-                       } else if ( be_isroot_pw( be, dn, cred ) ) {
-                               /* front end will send result */
-                               *edn = ch_strdup( be_root_dn( be ) );
-                               rc = 0;
-
-                       } else {
-                               send_ldap_result( conn, op, LDAP_REFERRAL,
-                                       matched_dn, NULL, refs, NULL );
-                       }
-
-               } else if ( method == LDAP_AUTH_SASL ) {
-                       if( mech != NULL && strcasecmp(mech,"DIGEST-MD5") == 0 ) {
-                               /* insert DIGEST calls here */
-                               send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED,
-                                       NULL, NULL, NULL, NULL );
-
-                       } else {
-                               send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED,
-                                       NULL, NULL, NULL, NULL );
-                       }
-
-               } else {
-                       send_ldap_result( conn, op, LDAP_REFERRAL,
-                               matched_dn, NULL, refs, NULL );
-                       rc = 1;
-               }
-
-               if ( matched != NULL ) {
-                       ber_bvecfree( refs );
-                       free( matched_dn );
-               }
-               return( rc );
-       }
-
-       *edn = ch_strdup( e->e_dn );
-
-       /* check for deleted */
-
-       if ( ! access_allowed( be, conn, op, e,
-               "entry", NULL, ACL_AUTH ) )
-       {
-               send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
-                       NULL, NULL, NULL, NULL );
-               rc = 1;
-               goto return_results;
-       }
-
-       if ( is_entry_alias( e ) ) {
-               /* entry is a alias, don't allow bind */
-               Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
-                       0, 0 );
-
-               send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM,
-                       NULL, NULL, NULL, NULL );
-
-               rc = 1;
-               goto return_results;
-       }
-
-
-       if ( is_entry_referral( e ) ) {
-               /* entry is a referral, don't allow bind */
-               struct berval **refs = get_entry_referrals( be,
-                       conn, op, e );
-
-               Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
-                       0, 0 );
-
-               send_ldap_result( conn, op, LDAP_REFERRAL,
-                       e->e_dn, NULL, refs, NULL );
-
-               ber_bvecfree( refs );
-
-               rc = 1;
-               goto return_results;
-       }
-
-       switch ( method ) {
-       case LDAP_AUTH_SIMPLE:
-               if ( cred->bv_len == 0 ) {
-                       send_ldap_result( conn, op, LDAP_SUCCESS,
-                               NULL, NULL, NULL, NULL );
-
-                       /* stop front end from sending result */
-                       rc = 1;
-                       goto return_results;
-               }
-
-               /* check for root dn/passwd */
-               if ( be_isroot_pw( be, dn, cred ) ) {
-                       /* front end will send result */
-                       if( *edn != NULL ) free( *edn );
-                       *edn = ch_strdup( be_root_dn( be ) );
-                       rc = 0;
-                       goto return_results;
-               }
-
-               if ( ! access_allowed( be, conn, op, e,
-                       "userpassword", NULL, ACL_AUTH ) )
-               {
-                       send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
-                               NULL, NULL, NULL, NULL);
-                       rc = 1;
-                       goto return_results;
-               }
-
-               if ( (a = attr_find( e->e_attrs, "userpassword" )) == NULL ) {
-                       send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
-                               NULL, NULL, NULL, NULL);
-
-                       /* stop front end from sending result */
-                       rc = 1;
-                       goto return_results;
-               }
-
-               if ( crypted_value_find( a->a_vals, cred, a->a_syntax, 0, cred ) != 0 )
-               {
-                       send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
-                               NULL, NULL, NULL, NULL);
-                       /* stop front end from sending result */
-                       rc = 1;
-                       goto return_results;
-               }
-               rc = 0;
-               break;
-
-#ifdef HAVE_KERBEROS
-       case LDAP_AUTH_KRBV41:
-               if ( bdb2i_krbv4_ldap_auth( be, cred, &ad ) != LDAP_SUCCESS ) {
-                       send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
-                               NULL, NULL, NULL, NULL);
-                       rc = 1;
-                       goto return_results;
-               }
-
-               if ( ! access_allowed( be, conn, op, e,
-                       "krbname", NULL, ACL_AUTH ) )
-               {
-                       send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
-                               NULL, NULL, NULL, NULL);
-                       rc = 1;
-                       goto return_results;
-               }
-
-               sprintf( krbname, "%s%s%s@%s", ad.pname, *ad.pinst ? "."
-                   : "", ad.pinst, ad.prealm );
-
-               if ( (a = attr_find( e->e_attrs, "krbname" )) == NULL ) {
-                       /*
-                        * no krbName values present:  check against DN
-                        */
-                       if ( strcasecmp( dn, krbname ) == 0 ) {
-                               rc = 0; /* XXX wild ass guess */
-                               break;
-                       }
-                       send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
-                               NULL, NULL, NULL, NULL);
-                       rc = 1;
-                       goto return_results;
-               } else {        /* look for krbName match */
-                       struct berval   krbval;
-
-                       krbval.bv_val = krbname;
-                       krbval.bv_len = strlen( krbname );
-
-                       if ( value_find( a->a_vals, &krbval, a->a_syntax, 3 ) != 0 ) {
-                               send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
-                                       NULL, NULL, NULL, NULL);
-                               rc = 1;
-                               goto return_results;
-                       }
-               }
-               rc = 0;
-               break;
-
-       case LDAP_AUTH_KRBV42:
-               send_ldap_result( conn, op, LDAP_SUCCESS,
-                       NULL, NULL, NULL, NULL );
-               /* stop front end from sending result */
-               rc = 1;
-               goto return_results;
-#endif
-
-       case LDAP_AUTH_SASL:
-               /* insert sasl code here */
-
-       default:
-               send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
-                   NULL, "auth method not supported", NULL, NULL );
-               rc = 1;
-               goto return_results;
-       }
-
-return_results:;
-       /* free entry and reader lock */
-       bdb2i_cache_return_entry_r( &li->li_cache, e );
-
-       /* front end with send result on success (rc==0) */
-       return( rc );
-}
-
-
-int
-bdb2_back_bind(
-    BackendDB          *be,
-    Connection         *conn,
-    Operation          *op,
-    char               *dn,
-    int                        method,
-       char            *mech,
-    struct berval      *cred,
-       char**  edn
-)
-{
-       DB_LOCK         lock;
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       struct timeval  time1;
-       int             ret;
-
-       bdb2i_start_timing( be->bd_info, &time1 );
-
-       if ( bdb2i_enter_backend_r( &lock ) != 0 ) {
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-               return( 1 );
-       }
-
-       ret = bdb2i_back_bind_internal( be, conn, op, dn, method, mech, cred, edn );
-
-       (void) bdb2i_leave_backend_r( lock );
-
-       bdb2i_stop_timing( be->bd_info, time1, "BIND", conn, op );
-
-       return( ret );
-}
-
-
diff --git a/servers/slapd/back-bdb2/cache.c b/servers/slapd/back-bdb2/cache.c
deleted file mode 100644 (file)
index 4c44dbc..0000000
+++ /dev/null
@@ -1,590 +0,0 @@
-/* cache.c - routines to maintain an in-core cache of entries */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/errno.h>
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-
-#include "back-bdb2.h"
-
-/* LDBM backend specific entry info -- visible only to the cache */
-struct ldbm_entry_info {
-       /*
-        * These items are specific to the LDBM backend and should
-        * be hidden.
-        */
-       int             lei_state;      /* for the cache */
-#define CACHE_ENTRY_UNDEFINED  0
-#define CACHE_ENTRY_CREATING   1
-#define CACHE_ENTRY_READY              2
-#define CACHE_ENTRY_DELETED            3
-
-       int             lei_refcnt;     /* # threads ref'ing this entry */
-       Entry   *lei_lrunext;   /* for cache lru list */
-       Entry   *lei_lruprev;
-};
-#define LEI(e) ((struct ldbm_entry_info *) ((e)->e_private))
-
-static int     cache_delete_entry_internal(struct cache *cache, Entry *e);
-#ifdef LDAP_DEBUG
-static void    lru_print(struct cache *cache);
-#endif
-
-static int
-cache_entry_private_init( Entry*e )
-{
-       assert( e->e_private == NULL );
-
-       if( e->e_private != NULL ) {
-               /* this should never happen */
-               return 1;
-       }
-
-       e->e_private = ch_calloc(1, sizeof(struct ldbm_entry_info));
-
-       return 0;
-}
-
-static int
-cache_entry_private_destroy( Entry*e )
-{
-       assert( e->e_private );
-
-       free( e->e_private );
-       e->e_private = NULL;
-       return 0;
-}
-
-void
-bdb2i_cache_return_entry_rw( struct cache *cache, Entry *e, int rw )
-{
-       /* set cache mutex */
-       ldap_pvt_thread_mutex_lock( &cache->c_mutex );
-
-       assert( e->e_private );
-
-       LEI(e)->lei_refcnt--;
-
-       if ( LEI(e)->lei_state == CACHE_ENTRY_CREATING ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "====> bdb2i_cache_return_entry_%s( %ld ): created (%d)\n",
-                       rw ? "w" : "r", e->e_id, LEI(e)->lei_refcnt );
-
-               LEI(e)->lei_state = CACHE_ENTRY_READY;
-
-       } else if ( LEI(e)->lei_state == CACHE_ENTRY_DELETED ) {
-               if( LEI(e)->lei_refcnt > 0 ) {
-                       Debug( LDAP_DEBUG_TRACE,
-                       "====> bdb2i_cache_return_entry_%s( %ld ): delete pending (%d)\n",
-                               rw ? "w" : "r", e->e_id, LEI(e)->lei_refcnt );
-
-               } else {
-                       Debug( LDAP_DEBUG_TRACE,
-                               "====> bdb2i_cache_return_entry_%s( %ld ): deleted (%d)\n",
-                               rw ? "w" : "r", e->e_id, LEI(e)->lei_refcnt );
-
-                       cache_entry_private_destroy( e );
-                       entry_free( e );
-               }
-
-       } else {
-               Debug( LDAP_DEBUG_TRACE,
-                       "====> bdb2i_cache_return_entry_%s( %ld ): returned (%d)\n",
-                       rw ? "w" : "r", e->e_id, LEI(e)->lei_refcnt);
-       }
-
-       /* free cache mutex */
-       ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
-}
-
-#define LRU_DELETE( cache, e ) { \
-       if ( LEI(e)->lei_lruprev != NULL ) { \
-               LEI(LEI(e)->lei_lruprev)->lei_lrunext = LEI(e)->lei_lrunext; \
-       } else { \
-               (cache)->c_lruhead = LEI(e)->lei_lrunext; \
-       } \
-       if ( LEI(e)->lei_lrunext != NULL ) { \
-               LEI(LEI(e)->lei_lrunext)->lei_lruprev = LEI(e)->lei_lruprev; \
-       } else { \
-               (cache)->c_lrutail = LEI(e)->lei_lruprev; \
-       } \
-}
-
-#define LRU_ADD( cache, e ) { \
-       LEI(e)->lei_lrunext = (cache)->c_lruhead; \
-       if ( LEI(e)->lei_lrunext != NULL ) { \
-               LEI(LEI(e)->lei_lrunext)->lei_lruprev = (e); \
-       } \
-       (cache)->c_lruhead = (e); \
-       LEI(e)->lei_lruprev = NULL; \
-       if ( (cache)->c_lrutail == NULL ) { \
-               (cache)->c_lrutail = (e); \
-       } \
-}
-
-/*
- * bdb2i_cache_add_entry_rw - create and lock an entry in the cache
- * returns:    0       entry has been created and locked
- *             1       entry already existed
- *             -1      something bad happened
- */
-int
-bdb2i_cache_add_entry_rw(
-    struct cache       *cache,
-    Entry              *e,
-       int             rw
-)
-{
-       int     i;
-       Entry   *ee;
-
-       /* set cache mutex */
-       ldap_pvt_thread_mutex_lock( &cache->c_mutex );
-
-       assert( e->e_private == NULL );
-
-       if( cache_entry_private_init(e) != 0 ) {
-               /* free cache mutex */
-               ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
-
-               Debug( LDAP_DEBUG_ANY,
-               "====> bdb2i_cache_add_entry( %ld ): \"%s\": private init failed!\n",
-                   e->e_id, e->e_dn, 0 );
-
-               return( -1 );
-       }
-
-       if ( avl_insert( &cache->c_dntree, (caddr_t) e,
-               (AVL_CMP) entry_dn_cmp, avl_dup_error ) != 0 )
-       {
-               Debug( LDAP_DEBUG_TRACE,
-               "====> bdb2i_cache_add_entry( %ld ): \"%s\": already in dn cache\n",
-                   e->e_id, e->e_dn, 0 );
-
-               cache_entry_private_destroy(e);
-
-               /* free cache mutex */
-               ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
-               return( 1 );
-       }
-
-       /* id tree */
-       if ( avl_insert( &cache->c_idtree, (caddr_t) e,
-               (AVL_CMP) entry_id_cmp, avl_dup_error ) != 0 )
-       {
-               Debug( LDAP_DEBUG_ANY,
-               "====> bdb2i_cache_add_entry( %ld ): \"%s\": already in id cache\n",
-                   e->e_id, e->e_dn, 0 );
-
-               /* delete from dn tree inserted above */
-               if ( avl_delete( &cache->c_dntree, (caddr_t) e,
-                       (AVL_CMP) entry_dn_cmp ) == NULL )
-               {
-                       Debug( LDAP_DEBUG_ANY, "====> can't delete from dn cache\n",
-                           0, 0, 0 );
-               }
-
-               cache_entry_private_destroy(e);
-
-               /* free cache mutex */
-               ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
-               return( -1 );
-       }
-
-       /* put the entry into 'CREATING' state */
-       /* will be marked after when entry is returned */
-       LEI(e)->lei_state = CACHE_ENTRY_CREATING;
-       LEI(e)->lei_refcnt = 1;
-
-       /* lru */
-       LRU_ADD( cache, e );
-       if ( ++cache->c_cursize > cache->c_maxsize ) {
-               /*
-                * find the lru entry not currently in use and delete it.
-                * in case a lot of entries are in use, only look at the
-                * first 10 on the tail of the list.
-                */
-               i = 0;
-               while ( cache->c_lrutail != NULL &&
-                       LEI(cache->c_lrutail)->lei_refcnt != 0 &&
-                       i < 10 )
-               {
-                       /* move this in-use entry to the front of the q */
-                       ee = cache->c_lrutail;
-                       LRU_DELETE( cache, ee );
-                       LRU_ADD( cache, ee );
-                       i++;
-               }
-
-               /*
-                * found at least one to delete - try to get back under
-                * the max cache size.
-                */
-               while ( cache->c_lrutail != NULL &&
-                       LEI(cache->c_lrutail)->lei_refcnt == 0 &&
-                       cache->c_cursize > cache->c_maxsize )
-               {
-                       e = cache->c_lrutail;
-
-                       /* delete from cache and lru q */
-                       cache_delete_entry_internal( cache, e );
-                       cache_entry_private_destroy( e );
-                       entry_free( e );
-               }
-       }
-
-       /* free cache mutex */
-       ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
-       return( 0 );
-}
-
-/*
- * cache_update_entry - update a LOCKED entry which has been deleted.
- * returns:    0       entry has been created and locked
- *             1       entry already existed
- *             -1      something bad happened
- */
-int
-bdb2i_cache_update_entry(
-    struct cache       *cache,
-    Entry              *e
-)
-{
-       int     i;
-       Entry   *ee;
-
-       /* set cache mutex */
-       ldap_pvt_thread_mutex_lock( &cache->c_mutex );
-
-       assert( e->e_private );
-
-       if ( avl_insert( &cache->c_dntree, (caddr_t) e,
-               (AVL_CMP) entry_dn_cmp, avl_dup_error ) != 0 )
-       {
-               Debug( LDAP_DEBUG_TRACE,
-               "====> bdb2i_cache_add_entry( %ld ): \"%s\": already in dn cache\n",
-                   e->e_id, e->e_dn, 0 );
-
-               /* free cache mutex */
-               ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
-               return( 1 );
-       }
-
-       /* id tree */
-       if ( avl_insert( &cache->c_idtree, (caddr_t) e,
-               (AVL_CMP) entry_id_cmp, avl_dup_error ) != 0 )
-       {
-               Debug( LDAP_DEBUG_ANY,
-               "====> bdb2i_cache_update_entry( %ld ): \"%s\": already in id cache\n",
-                   e->e_id, e->e_dn, 0 );
-
-               /* delete from dn tree inserted above */
-               if ( avl_delete( &cache->c_dntree, (caddr_t) e,
-                       (AVL_CMP) entry_dn_cmp ) == NULL )
-               {
-                       Debug( LDAP_DEBUG_ANY, "====> can't delete from dn cache\n",
-                           0, 0, 0 );
-               }
-
-               /* free cache mutex */
-               ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
-               return( -1 );
-       }
-
-       /* put the entry into 'CREATING' state */
-       /* will be marked after when entry is returned */
-       LEI(e)->lei_state = CACHE_ENTRY_CREATING;
-
-       /* lru */
-       LRU_ADD( cache, e );
-       if ( ++cache->c_cursize > cache->c_maxsize ) {
-               /*
-                * find the lru entry not currently in use and delete it.
-                * in case a lot of entries are in use, only look at the
-                * first 10 on the tail of the list.
-                */
-               i = 0;
-               while ( cache->c_lrutail != NULL &&
-                       LEI(cache->c_lrutail)->lei_refcnt != 0 &&
-                       i < 10 )
-               {
-                       /* move this in-use entry to the front of the q */
-                       ee = cache->c_lrutail;
-                       LRU_DELETE( cache, ee );
-                       LRU_ADD( cache, ee );
-                       i++;
-               }
-
-               /*
-                * found at least one to delete - try to get back under
-                * the max cache size.
-                */
-               while ( cache->c_lrutail != NULL &&
-                       LEI(cache->c_lrutail)->lei_refcnt == 0 &&
-                       cache->c_cursize > cache->c_maxsize )
-               {
-                       e = cache->c_lrutail;
-
-                       /* delete from cache and lru q */
-                       cache_delete_entry_internal( cache, e );
-                       cache_entry_private_destroy( e );
-                       entry_free( e );
-               }
-       }
-
-       /* free cache mutex */
-       ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
-       return( 0 );
-}
-
-/*
- * bdb2i_cache_find_entry_dn2id - find an entry in the cache, given dn
- */
-
-ID
-bdb2i_cache_find_entry_dn2id(
-       BackendDB               *be,
-    struct cache       *cache,
-    const char         *dn
-)
-{
-       Entry           e, *ep;
-       ID                      id;
-       int             count = 0;
-
-       e.e_dn = (char *) dn;
-       e.e_ndn = ch_strdup( dn );
-       (void) dn_normalize_case( e.e_ndn );
-
-try_again:
-       /* set cache mutex */
-       ldap_pvt_thread_mutex_lock( &cache->c_mutex );
-
-       if ( (ep = (Entry *) avl_find( cache->c_dntree, (caddr_t) &e,
-               (AVL_CMP) entry_dn_cmp )) != NULL )
-       {
-               int state;
-               count++;
-
-               /*
-                * ep now points to an unlocked entry
-                * we do not need to lock the entry if we only
-                * check the state, refcnt, LRU, and id.
-                */
-
-               assert( ep->e_private );
-
-               /* save id */
-               id = ep->e_id;
-               state = LEI(ep)->lei_state;
-
-               /*
-                * entry is deleted or not fully created yet
-                */
-               if ( state != CACHE_ENTRY_READY ) {
-                       assert(state != CACHE_ENTRY_UNDEFINED);
-
-                       /* free cache mutex */
-                       ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
-
-                       Debug(LDAP_DEBUG_TRACE,
-                       "====> bdb2i_cache_find_entry_dn2id(\"%s\"): %ld (not ready) %d\n",
-                               dn, id, state);
-
-                       ldap_pvt_thread_yield();
-                       goto try_again;
-               }
-
-               /* lru */
-               LRU_DELETE( cache, ep );
-               LRU_ADD( cache, ep );
-
-               /* free cache mutex */
-               ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
-
-               Debug(LDAP_DEBUG_TRACE,
-                       "====> bdb2i_cache_find_entry_dn2id(\"%s\"): %ld (%d tries)\n",
-                       dn, id, count);
-
-       } else {
-               /* free cache mutex */
-               ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
-
-               id = NOID;
-       }
-
-       free(e.e_ndn);
-
-       return( id );
-}
-
-/*
- * cache_find_entry_id - find an entry in the cache, given id
- */
-
-Entry *
-bdb2i_cache_find_entry_id(
-       struct cache    *cache,
-       ID                              id,
-       int                             rw
-)
-{
-       Entry   e;
-       Entry   *ep;
-       int count=0;
-
-       e.e_id = id;
-
-try_again:
-       /* set cache mutex */
-       ldap_pvt_thread_mutex_lock( &cache->c_mutex );
-
-       if ( (ep = (Entry *) avl_find( cache->c_idtree, (caddr_t) &e,
-               (AVL_CMP) entry_id_cmp )) != NULL )
-       {
-               int state;
-
-               assert( ep->e_private );
-
-               state = LEI(ep)->lei_state;
-
-               /*
-                * entry is deleted or not fully created yet
-                */
-               if ( state != CACHE_ENTRY_READY ) {
-                       ID ep_id = ep->e_id;
-
-                       assert(state != CACHE_ENTRY_UNDEFINED);
-
-                       /* free cache mutex */
-                       ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
-
-                       Debug(LDAP_DEBUG_TRACE,
-                               "====> bdb2i_cache_find_entry_id( %ld ): %ld (not ready) %d\n",
-                               id, ep_id, state);
-
-                       ldap_pvt_thread_yield();
-                       goto try_again;
-               }
-
-               /* lru */
-               LRU_DELETE( cache, ep );
-               LRU_ADD( cache, ep );
-                
-               LEI(ep)->lei_refcnt++;
-
-               /* free cache mutex */
-               ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
-
-               Debug(LDAP_DEBUG_TRACE,
-                       "====> bdb2i_cache_find_entry_id( %ld ) \"%s\" (found) (%d tries)\n",
-                       id, ep->e_dn, count);
-
-               return( ep );
-       }
-
-       /* free cache mutex */
-       ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
-
-       return( NULL );
-}
-
-/*
- * cache_delete_entry - delete the entry e from the cache.  the caller
- * should have obtained e (increasing its ref count) via a call to one
- * of the cache_find_* routines.  the caller should *not* call the
- * cache_return_entry() routine prior to calling cache_delete_entry().
- * it performs this function.
- *
- * returns:    0       e was deleted ok
- *             1       e was not in the cache
- *             -1      something bad happened
- */
-int
-bdb2i_cache_delete_entry(
-    struct cache       *cache,
-    Entry              *e
-)
-{
-       int     rc;
-
-       /* set cache mutex */
-       ldap_pvt_thread_mutex_lock( &cache->c_mutex );
-
-       assert( e->e_private );
-
-       Debug( LDAP_DEBUG_TRACE, "====> bdb2i_cache_delete_entry( %ld )\n",
-               e->e_id, 0, 0 );
-
-       rc = cache_delete_entry_internal( cache, e );
-
-       /* free cache mutex */
-       ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
-       return( rc );
-}
-
-static int
-cache_delete_entry_internal(
-    struct cache       *cache,
-    Entry              *e
-)
-{
-       int rc = 0;     /* return code */
-
-       /* dn tree */
-       if ( avl_delete( &cache->c_dntree, (caddr_t) e, (AVL_CMP) entry_dn_cmp )
-               == NULL )
-       {
-               rc = -1;
-       }
-
-       /* id tree */
-       if ( avl_delete( &cache->c_idtree, (caddr_t) e, (AVL_CMP) entry_id_cmp )
-               == NULL )
-       {
-               rc = -1;
-       }
-
-       if (rc != 0) {
-               return rc;
-       }
-
-       /* lru */
-       LRU_DELETE( cache, e );
-       cache->c_cursize--;
-
-       /*
-        * flag entry to be freed later by a call to cache_return_entry()
-        */
-       LEI(e)->lei_state = CACHE_ENTRY_DELETED;
-
-       return( 0 );
-}
-
-#ifdef LDAP_DEBUG
-
-static void
-lru_print( struct cache *cache )
-{
-       Entry   *e;
-
-       fprintf( stderr, "LRU queue (head to tail):\n" );
-       for ( e = cache->c_lruhead; e != NULL; e = LEI(e)->lei_lrunext ) {
-               fprintf( stderr, "\tdn \"%20s\" id %ld refcnt %d\n",
-                       e->e_dn, e->e_id, LEI(e)->lei_refcnt );
-       }
-       fprintf( stderr, "LRU queue (tail to head):\n" );
-       for ( e = cache->c_lrutail; e != NULL; e = LEI(e)->lei_lruprev ) {
-               fprintf( stderr, "\tdn \"%20s\" id %ld refcnt %d\n",
-                       e->e_dn, e->e_id, LEI(e)->lei_refcnt );
-       }
-}
-
-#endif
-
diff --git a/servers/slapd/back-bdb2/close.c b/servers/slapd/back-bdb2/close.c
deleted file mode 100644 (file)
index 98d68c7..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* close.c - close bdb2 backend database */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-
-static int
-bdb2i_back_db_close_internal( BackendDB *be )
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       DB_LOCK         lock;
-
-       /*  since close will probably write the NEXTID file,
-               wee need transaction control  */
-       if ( bdb2i_enter_backend_w( &lock ) != 0 ) {
-               return( -1 );
-       }
-
-       if ( li->li_nextid != NOID ) {
-               Debug( LDAP_DEBUG_TRACE, "bdb2 backend saving nextid\n", 0, 0, 0 );
-               if ( bdb2i_next_id_save( be ) < 0 ) {
-                       Debug( LDAP_DEBUG_ANY, "bdb2 backend nextid save failed!\n",
-                                       0, 0, 0 );
-               }
-       }
-
-       /*  before closing all files, leave the backend (thus commiting
-               all writes) and set a last checkpoint  */
-       (void) bdb2i_leave_backend_w( lock );
-       (void) bdb2i_set_txn_checkpoint( bdb2i_dbEnv.tx_info, 1 );
-
-       /*  close all DB files  */
-       Debug( LDAP_DEBUG_TRACE, "bdb2 backend closing DB files\n", 0, 0, 0 );
-       bdb2i_txn_close_files( be );
-       Debug( LDAP_DEBUG_TRACE, "bdb2 backend done closing DB files\n", 0, 0, 0 );
-
-       return 0;
-}
-
-
-int
-bdb2_back_db_close( BackendDB *be )
-{
-       struct timeval  time1;
-       int             ret;
-
-       bdb2i_start_timing( be->bd_info, &time1 );
-
-       ret = bdb2i_back_db_close_internal( be );
-
-       bdb2i_stop_timing( be->bd_info, time1, "CLOSE", NULL, NULL );
-
-       return( ret );
-}
-
-
diff --git a/servers/slapd/back-bdb2/compare.c b/servers/slapd/back-bdb2/compare.c
deleted file mode 100644 (file)
index 46093d6..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/* compare.c - bdb2 backend compare routine */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/socket.h>
-#include <ac/string.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-#include "proto-back-bdb2.h"
-
-static int
-bdb2i_back_compare_internal(
-    BackendDB  *be,
-    Connection *conn,
-    Operation  *op,
-    char       *dn,
-    Ava                *ava
-)
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       Entry           *matched;
-       Entry           *e;
-       Attribute       *a;
-       int             rc;
-       int             manageDSAit = get_manageDSAit( op );
-
-       /* get entry with reader lock */
-       if ( (e = bdb2i_dn2entry_r( be, dn, &matched )) == NULL ) {
-               char *matched_dn = NULL;
-               struct berval **refs = NULL;
-
-               if ( matched != NULL ) {
-                       matched_dn = ch_strdup( matched->e_dn );
-                       refs = is_entry_referral( matched )
-                               ? get_entry_referrals( be, conn, op, matched )
-                               : NULL;
-                       bdb2i_cache_return_entry_r( &li->li_cache, matched );
-               } else {
-                       refs = default_referral;
-               }
-
-               send_ldap_result( conn, op, LDAP_REFERRAL,
-                       matched_dn, NULL, refs, NULL );
-
-               if( matched != NULL ) {
-                       ber_bvecfree( refs );
-                       free( matched_dn );
-               }
-
-               return( 1 );
-       }
-
-       if (!manageDSAit && is_entry_referral( e ) ) {
-               /* entry is a referral, don't allow add */
-               struct berval **refs = get_entry_referrals( be,
-                       conn, op, e );
-
-               Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
-                       0, 0 );
-
-               send_ldap_result( conn, op, LDAP_REFERRAL,
-                       e->e_dn, NULL, refs, NULL );
-
-               ber_bvecfree( refs );
-
-               rc = 1;
-               goto return_results;
-       }
-
-       if ( ! access_allowed( be, conn, op, e,
-               ava->ava_type, &ava->ava_value, ACL_COMPARE ) )
-       {
-               send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
-                       NULL, NULL, NULL, NULL );
-               rc = 1;
-               goto return_results;
-       }
-
-       if ( (a = attr_find( e->e_attrs, ava->ava_type )) == NULL ) {
-               send_ldap_result( conn, op, LDAP_NO_SUCH_ATTRIBUTE,
-                       NULL, NULL, NULL, NULL );
-               rc = 1;
-               goto return_results;
-       }
-
-       if ( value_find( a->a_vals, &ava->ava_value, a->a_syntax, 1 ) == 0 ) 
-               send_ldap_result( conn, op, LDAP_COMPARE_TRUE,
-                       NULL, NULL, NULL, NULL );
-       else
-               send_ldap_result( conn, op, LDAP_COMPARE_FALSE,
-                       NULL, NULL, NULL, NULL );
-
-       rc = 0;
-
-return_results:;
-       bdb2i_cache_return_entry_r( &li->li_cache, e );
-       return( rc );
-}
-
-
-int
-bdb2_back_compare(
-    BackendDB  *be,
-    Connection *conn,
-    Operation  *op,
-    char       *dn,
-    Ava                *ava
-)
-{
-       DB_LOCK         lock;
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       struct timeval  time1;
-       int             ret;
-
-       bdb2i_start_timing( be->bd_info, &time1 );
-
-       if ( bdb2i_enter_backend_r( &lock ) != 0 ) {
-
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-               return( 1 );
-
-       }
-
-       ret = bdb2i_back_compare_internal( be, conn, op, dn, ava );
-       (void) bdb2i_leave_backend_r( lock );
-       bdb2i_stop_timing( be->bd_info, time1, "CMP", conn, op );
-
-       return( ret );
-}
-
-
diff --git a/servers/slapd/back-bdb2/config.c b/servers/slapd/back-bdb2/config.c
deleted file mode 100644 (file)
index 87d7392..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/* config.c - bdb2 backend configuration file routine */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/socket.h>
-#include <ac/string.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-
-static int
-bdb2i_back_config_internal(
-    BackendInfo        *bi,
-    const char         *fname,
-    int                        lineno,
-    int                        argc,
-    char               **argv
-)
-{
-       struct ldbtype  *lty = (struct ldbtype *) bi->bi_private;
-
-       if ( lty == NULL ) {
-               fprintf( stderr, "%s: line %d: ldbm backend type info is null!\n",
-                   fname, lineno );
-               return( 1 );
-       }
-
-       /* directory where DB control files live */
-       if ( strcasecmp( argv[0], "home" ) == 0 ) {
-               if ( argc < 2 ) {
-                       fprintf( stderr,
-               "%s: line %d: missing dir in \"home <dir>\" line\n",
-                           fname, lineno );
-                       return( 1 );
-               }
-               lty->lty_dbhome = ch_strdup( argv[1] );
-
-       /* size of the DB memory pool */
-       } else if ( strcasecmp( argv[0], "mpoolsize" ) == 0 ) {
-               if ( argc < 2 ) {
-                       fprintf( stderr,
-                       "%s: line %d: missing size in \"mpoolsize <size>\" line\n",
-                           fname, lineno );
-                       return( 1 );
-               }
-               lty->lty_mpsize = (size_t) atoi( argv[1] );
-               /*  we should at least have the suggested 128k  */
-               if ( lty->lty_mpsize < DEFAULT_DBCACHE_SIZE )
-                       lty->lty_mpsize = DEFAULT_DBCACHE_SIZE;
-
-       /* anything else */
-       } else {
-               fprintf( stderr,
-"%s: line %d: unknown directive \"%s\" in ldbm backend definition (ignored)\n",
-                   fname, lineno, argv[0] );
-       }
-
-       return 0;
-}
-
-
-int
-bdb2_back_config(
-    BackendInfo        *bi,
-    const char *fname,
-    int                lineno,
-    int                argc,
-    char       **argv
-)
-{
-       struct timeval  time1;
-       int             ret;
-
-       bdb2i_start_timing( bi, &time1 );
-
-       ret = bdb2i_back_config_internal( bi, fname, lineno, argc, argv );
-       bdb2i_stop_timing( bi, time1, "BE-CONFIG", NULL, NULL );
-
-       return( ret );
-}
-
-
-static int
-bdb2i_back_db_config_internal(
-    BackendDB  *be,
-    const char *fname,
-    int                lineno,
-    int                argc,
-    char       **argv
-)
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-
-       if ( li == NULL ) {
-               fprintf( stderr, "%s: line %d: ldbm database info is null!\n",
-                   fname, lineno );
-               return( 1 );
-       }
-
-       /* directory where database files live */
-       if ( strcasecmp( argv[0], "directory" ) == 0 ) {
-               if ( argc < 2 ) {
-                       fprintf( stderr,
-               "%s: line %d: missing dir in \"directory <dir>\" line\n",
-                           fname, lineno );
-                       return( 1 );
-               }
-               li->li_directory = ch_strdup( argv[1] );
-
-               li->li_nextid_file =
-                       ch_malloc( strlen(li->li_directory) + sizeof("/NEXTID") + 1 );
-
-               strcpy(li->li_nextid_file, li->li_directory);
-               strcat(li->li_nextid_file, "/NEXTID");
-
-       /* mode with which to create new database files */
-       } else if ( strcasecmp( argv[0], "mode" ) == 0 ) {
-               if ( argc < 2 ) {
-                       fprintf( stderr,
-                       "%s: line %d: missing mode in \"mode <mode>\" line\n",
-                           fname, lineno );
-                       return( 1 );
-               }
-               li->li_mode = strtol( argv[1], NULL, 0 );
-
-       /* attribute to index */
-       } else if ( strcasecmp( argv[0], "index" ) == 0 ) {
-               if ( argc < 2 ) {
-                       fprintf( stderr,
-"%s: line %d: missing attr in \"index <attr> [pres,eq,approx,sub]\" line\n",
-                           fname, lineno );
-                       return( 1 );
-               } else if ( argc > 3 ) {
-                       fprintf( stderr,
-"%s: line %d: extra junk after \"index <attr> [pres,eq,approx,sub]\" line (ignored)\n",
-                           fname, lineno );
-               }
-               bdb2i_attr_index_config( li, fname, lineno, argc - 1, &argv[1], 0 );
-
-       /* size of the cache in entries */
-       } else if ( strcasecmp( argv[0], "cachesize" ) == 0 ) {
-               if ( argc < 2 ) {
-                       fprintf( stderr,
-               "%s: line %d: missing size in \"cachesize <size>\" line\n",
-                           fname, lineno );
-                       return( 1 );
-               }
-               li->li_cache.c_maxsize = atoi( argv[1] );
-
-       /* size of each dbcache in bytes */
-       } else if ( strcasecmp( argv[0], "dbcachesize" ) == 0 ) {
-               if ( argc < 2 ) {
-                       fprintf( stderr,
-               "%s: line %d: missing size in \"dbcachesize <size>\" line\n",
-                           fname, lineno );
-                       return( 1 );
-               }
-               li->li_dbcachesize = atoi( argv[1] );
-               /*  we should at least have the suggested 128k  */
-               if ( li->li_dbcachesize < DEFAULT_DBCACHE_SIZE )
-                       li->li_dbcachesize = DEFAULT_DBCACHE_SIZE;
-
-       /* no write sync */
-       } else if ( strcasecmp( argv[0], "dbcachenowsync" ) == 0 ) {
-               li->li_dbcachewsync = 0;
-
-       /* anything else */
-       } else {
-               fprintf( stderr,
-"%s: line %d: unknown directive \"%s\" in ldbm database definition (ignored)\n",
-                   fname, lineno, argv[0] );
-       }
-
-       return 0;
-}
-
-
-int
-bdb2_back_db_config(
-    BackendDB  *be,
-    const char *fname,
-    int                lineno,
-    int                argc,
-    char       **argv
-)
-{
-       struct timeval  time1;
-       int             ret;
-
-       bdb2i_start_timing( be->bd_info, &time1 );
-
-       ret = bdb2i_back_db_config_internal( be, fname, lineno, argc, argv );
-
-       bdb2i_stop_timing( be->bd_info, time1, "DB-CONFIG", NULL, NULL );
-
-       return( ret );
-}
-
-
diff --git a/servers/slapd/back-bdb2/dbcache.c b/servers/slapd/back-bdb2/dbcache.c
deleted file mode 100644 (file)
index 6a1a0ef..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-/* ldbmcache.c - maintain a cache of open bdb2 files */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/errno.h>
-#include <ac/socket.h>
-#include <ac/string.h>
-#include <ac/time.h>
-
-#include <sys/stat.h>
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-#include "slap.h"
-#include "back-bdb2.h"
-
-struct dbcache *
-bdb2i_cache_open(
-    BackendDB  *be,
-    char       *name,
-    char       *suffix,
-    int                flags
-)
-{
-       /*  all files are open, so return handle from file cache  */
-       switch ( slapMode & SLAP_MODE ) {
-
-               case SLAP_SERVER_MODE:
-               case SLAP_TOOL_MODE:
-                       {
-                               struct  ldbminfo        *li = (struct ldbminfo *) be->be_private;
-                               char    buf[MAXPATHLEN];
-
-                               /*  use short name  */
-                               sprintf( buf, "%s%s", name, suffix );
-                               return( bdb2i_get_db_file_cache( li, buf ));
-
-                       }
-                       break;
-
-               default:
-                       /*  if not SERVER or TOOL, who else would ask?
-                               NO ONE, so return error  */
-
-                       Debug( LDAP_DEBUG_ANY,
-       "bdb2i_cache_open: database user (%d) unknown -- cannot open \"%s%s\".\n",
-                                       slapMode, name, suffix );
-                       return( NULL );
-       }
-}
-
-void
-bdb2i_cache_close( BackendDB *be, struct dbcache *db )
-{
-       /*  all files stay open until SERVER or TOOL shut down  */
-       switch ( slapMode & SLAP_MODE ) {
-               case SLAP_SERVER_MODE:
-               case SLAP_TOOL_MODE:
-                       return;
-
-               default:
-                       /*  if unknown user, complain  */
-                       Debug( LDAP_DEBUG_ANY,
-                               "bdb2i_cache_close: database user (%d) unknown -- ignored.\n",
-                               slapMode, 0, 0 );
-                       return;
-       }
-}
-
-void
-bdb2i_cache_really_close( BackendDB *be, struct dbcache *db )
-{
-       /*  all files stay open until SERVER or TOOL shut down  */
-       switch ( slapMode & SLAP_MODE ) {
-               case SLAP_SERVER_MODE:
-               case SLAP_TOOL_MODE:
-                       return;
-
-               default:
-                       /*  if unknown user, complain  */
-                       Debug( LDAP_DEBUG_ANY,
-               "bdb2i_cache_really_close: database user (%d) unknown -- ignored.\n",
-                               slapMode, 0, 0 );
-                       return;
-       }
-}
-
-void
-bdb2i_cache_flush_all( BackendDB *be )
-{
-       /*  if SERVER or TOOL, syncing is done by TP, or during shutdown  */
-       switch ( slapMode & SLAP_MODE ) {
-
-               case SLAP_SERVER_MODE:
-               case SLAP_TOOL_MODE:
-                       return;
-
-               default:
-                       /*  if unknown user, complain  */
-                       Debug( LDAP_DEBUG_ANY,
-               "bdb2i_cache_flush_all: database user (%d) unknown -- ignored.\n",
-                               slapMode, 0, 0 );
-                       return;
-       }
-}
-
-Datum
-bdb2i_cache_fetch(
-    struct dbcache     *db,
-    Datum              key
-)
-{
-       Datum   data;
-
-       ldbm_datum_init( data );
-
-       data = bdb2i_db_fetch( db->dbc_db, key );
-
-       return( data );
-}
-
-int
-bdb2i_cache_store(
-    struct dbcache     *db,
-    Datum              key,
-    Datum              data,
-    int                        flags
-)
-{
-       int     rc;
-       struct timeval  time1;
-
-#ifdef LDBM_DEBUG
-       Statslog( LDAP_DEBUG_STATS,
-               "=> bdb2i_cache_store(): key.dptr=%s, key.dsize=%d\n",
-               key.dptr, key.dsize, 0, 0, 0 );
-
-       Statslog( LDAP_DEBUG_STATS,
-               "=> bdb2i_cache_store(): key.dptr=0x%08x, data.dptr=0x%0 8x\n",
-               key.dptr, data.dptr, 0, 0, 0 );
-
-       Statslog( LDAP_DEBUG_STATS,
-               "=> bdb2i_cache_store(): data.dptr=%s, data.dsize=%d\n",
-               data.dptr, data.dsize, 0, 0, 0 );
-
-       Statslog( LDAP_DEBUG_STATS,
-               "=> bdb2i_cache_store(): flags=0x%08x\n",
-               flags, 0, 0, 0, 0 );
-#endif /* LDBM_DEBUG */
-
-       if ( slapMode & SLAP_TIMED_MODE )
-               bdb2i_uncond_start_timing( &time1 );
-
-       rc = bdb2i_db_store( db->dbc_db, key, data, flags );
-
-       if ( slapMode & SLAP_TIMED_MODE ) {
-               char buf[BUFSIZ];
-               char buf2[BUFSIZ];
-
-               *buf2 = '\0';
-               if ( !( strcasecmp( db->dbc_name, "dn.bdb2" )))
-                       sprintf( buf2, " [%s]", key.dptr );
-               sprintf( buf, "ADD-BDB2( %s%s )", db->dbc_name, buf2 );
-               bdb2i_uncond_stop_timing( time1, buf,
-                                       NULL, NULL, LDAP_DEBUG_TRACE );
-       }
-
-       return( rc );
-}
-
-int
-bdb2i_cache_delete(
-    struct dbcache     *db,
-    Datum              key
-)
-{
-       int     rc;
-
-       rc = bdb2i_db_delete( db->dbc_db, key );
-
-       return( rc );
-}
diff --git a/servers/slapd/back-bdb2/delete.c b/servers/slapd/back-bdb2/delete.c
deleted file mode 100644 (file)
index eee7b6d..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-/* delete.c - bdb2 backend delete routine */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-#include "proto-back-bdb2.h"
-
-static int
-bdb2i_back_delete_internal(
-    BackendDB  *be,
-    Connection *conn,
-    Operation  *op,
-    char       *dn
-)
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       Entry   *matched = NULL;
-       char    *pdn = NULL;
-       Entry   *e, *p = NULL;
-       int     rc = -1, manageDSAit;
-
-       Debug(LDAP_DEBUG_ARGS, "==> bdb2i_back_delete: %s\n", dn, 0, 0);
-
-       /* get entry with writer lock */
-       if ( (e = bdb2i_dn2entry_w( be, dn, &matched )) == NULL ) {
-               char *matched_dn = NULL;
-               struct berval **refs = NULL;
-
-               Debug(LDAP_DEBUG_ARGS, "<=- bdb2i_back_delete: no such object %s\n",
-                       dn, 0, 0);
-
-               if ( matched != NULL ) {
-                       matched_dn = ch_strdup( matched->e_dn );
-                       refs = is_entry_referral( matched )
-                               ? get_entry_referrals( be, conn, op, matched )
-                               : NULL;
-                       bdb2i_cache_return_entry_r( &li->li_cache, matched );
-               } else {
-                       refs = default_referral;
-               }
-
-               send_ldap_result( conn, op, LDAP_REFERRAL,
-                       matched_dn, NULL, refs, NULL );
-
-               if( matched != NULL ) {
-                       ber_bvecfree( refs );
-                       free( matched_dn );
-               }
-
-               return( -1 );
-       }
-
-       if (!manageDSAit && is_entry_referral( e ) ) {
-               /* entry is a referral, don't allow add */
-               struct berval **refs = get_entry_referrals( be,
-                       conn, op, e );
-
-               Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
-                       0, 0 );
-
-               send_ldap_result( conn, op, LDAP_REFERRAL,
-                       e->e_dn, NULL, refs, NULL );
-
-               ber_bvecfree( refs );
-               goto return_results;
-       }
-
-
-       if ( bdb2i_has_children( be, e ) ) {
-               Debug(LDAP_DEBUG_ARGS, "<=- bdb2i_back_delete: non leaf %s\n",
-                       dn, 0, 0);
-               send_ldap_result( conn, op, LDAP_NOT_ALLOWED_ON_NONLEAF,
-                       NULL, NULL, NULL, NULL );
-               goto return_results;
-       }
-
-#ifdef SLAPD_CHILD_MODIFICATION_WITH_ENTRY_ACL
-       if ( ! access_allowed( be, conn, op, e,
-               "entry", NULL, ACL_WRITE ) )
-       {
-               Debug(LDAP_DEBUG_ARGS,
-                       "<=- bdb2i_back_delete: insufficient access %s\n",
-                       dn, 0, 0);
-               send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
-                       NULL, NULL, NULL, NULL );
-               goto return_results;
-       }
-#endif
-
-       /* find parent's entry */
-       if( (pdn = dn_parent( be, e->e_ndn )) != NULL ) {
-               if( (p = bdb2i_dn2entry_w( be, pdn, &matched )) == NULL) {
-                       Debug( LDAP_DEBUG_TRACE,
-                               "<=- bdb2i_back_delete: parent does not exist\n", 0, 0, 0);
-                       send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                               NULL, NULL, NULL, NULL );
-                       goto return_results;
-               }
-
-               /* check parent for "children" acl */
-               if ( ! access_allowed( be, conn, op, p,
-                       "children", NULL, ACL_WRITE ) )
-               {
-                       Debug( LDAP_DEBUG_TRACE,
-                               "<=- bdb2i_back_delete: no access to parent\n", 0, 0, 0 );
-                       send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
-                               NULL, NULL, NULL, NULL );
-                       goto return_results;
-               }
-
-       } else {
-               /* no parent, must be root to delete */
-               if( ! be_isroot( be, op->o_ndn ) ) {
-                       Debug( LDAP_DEBUG_TRACE,
-                               "<=- bdb2i_back_delete: no parent & not root\n", 0, 0, 0);
-                       send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
-                               NULL, NULL, NULL, NULL );
-                       goto return_results;
-               }
-       }
-
-       /* delete from dn2id mapping */
-       if ( bdb2i_dn2id_delete( be, e->e_ndn, e->e_id ) != 0 ) {
-               Debug(LDAP_DEBUG_ARGS,
-                       "<=- bdb2i_back_delete: operations error %s\n",
-                       dn, 0, 0);
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-               goto return_results;
-       }
-
-       /* delete from disk and cache */
-       if ( bdb2i_id2entry_delete( be, e ) != 0 ) {
-               Debug(LDAP_DEBUG_ARGS,
-                       "<=- bdb2i_back_delete: operations error %s\n",
-                       dn, 0, 0);
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-               goto return_results;
-       }
-
-       send_ldap_result( conn, op, LDAP_SUCCESS,
-               NULL, NULL, NULL, NULL );
-       rc = 0;
-
-return_results:;
-       if ( pdn != NULL ) free(pdn);
-
-       if( p != NULL ) {
-               /* free parent and writer lock */
-               bdb2i_cache_return_entry_w( &li->li_cache, p );
-
-       }
-
-       /* free entry and writer lock */
-       bdb2i_cache_return_entry_w( &li->li_cache, e );
-
-       if ( matched != NULL ) free(matched);
-
-       return rc;
-}
-
-
-int
-bdb2_back_delete(
-    BackendDB  *be,
-    Connection *conn,
-    Operation  *op,
-    char       *dn
-)
-{
-       DB_LOCK         lock;
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       struct timeval  time1;
-       int             ret;
-
-       bdb2i_start_timing( be->bd_info, &time1 );
-
-       if ( bdb2i_enter_backend_w( &lock ) != 0 ) {
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-               return( -1 );
-       }
-
-       ret = bdb2i_back_delete_internal( be, conn, op, dn );
-       (void) bdb2i_leave_backend_w( lock );
-       bdb2i_stop_timing( be->bd_info, time1, "DEL", conn, op );
-
-       return( ret );
-}
-
-
diff --git a/servers/slapd/back-bdb2/dn2id.c b/servers/slapd/back-bdb2/dn2id.c
deleted file mode 100644 (file)
index 1d4599a..0000000
+++ /dev/null
@@ -1,307 +0,0 @@
-/* dn2id.c - routines to deal with the dn2id index */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-#include "proto-back-bdb2.h"
-
-int
-bdb2i_dn2id_add(
-    BackendDB  *be,
-    const char *dn,
-    ID         id
-)
-{
-       int             rc, flags;
-       struct dbcache  *db;
-       Datum           key, data;
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-
-       Debug( LDAP_DEBUG_TRACE, "=> bdb2i_dn2id_add( \"%s\", %ld )\n", dn, id, 0 );
-
-       if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX, LDBM_WRCREAT ))
-           == NULL ) {
-               Debug( LDAP_DEBUG_ANY, "Could not open/create dn2id%s\n",
-                   BDB2_SUFFIX, 0, 0 );
-               return( -1 );
-       }
-
-       ldbm_datum_init( key );
-       key.dsize = strlen( dn ) + 2;
-       key.dptr = ch_malloc( key.dsize );
-       sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
-
-       ldbm_datum_init( data );
-       data.dptr = (char *) &id;
-       data.dsize = sizeof(ID);
-
-       flags = LDBM_INSERT;
-       if ( li->li_dbcachewsync ) flags |= LDBM_SYNC;
-
-       rc = bdb2i_cache_store( db, key, data, flags );
-
-       free( key.dptr );
-
-       if ( rc != -1 ) {
-               char *pdn = dn_parent( NULL, dn );
-
-               if( pdn != NULL ) {
-                       ldbm_datum_init( key );
-                       key.dsize = strlen( pdn ) + 2;
-                       key.dptr = ch_malloc( key.dsize );
-                       sprintf( key.dptr, "%c%s", DN_ONE_PREFIX, pdn );
-                       rc = bdb2i_idl_insert_key( be, db, key, id );
-                       free( key.dptr );
-                       free( pdn );
-               }
-       }
-
-       if ( rc != -1 ) {
-               char **subtree = dn_subtree( NULL, dn );
-
-               if( subtree != NULL ) {
-                       int i;
-                       for( i=0; subtree[i] != NULL; i++ ) {
-                               ldbm_datum_init( key );
-                               key.dsize = strlen( subtree[i] ) + 2;
-                               key.dptr = ch_malloc( key.dsize );
-                               sprintf( key.dptr, "%c%s", DN_SUBTREE_PREFIX, subtree[i] );
-
-                               rc = bdb2i_idl_insert_key( be, db, key, id );
-
-                               free( key.dptr );
-                       }
-
-                       charray_free( subtree );
-               }
-       }
-
-       bdb2i_cache_close( be, db );
-
-       Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id_add %d\n", rc, 0, 0 );
-       return( rc );
-}
-
-ID
-bdb2i_dn2id(
-    BackendDB  *be,
-    const char *dn
-)
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       struct dbcache  *db;
-       ID              id;
-       Datum           key, data;
-
-       Debug( LDAP_DEBUG_TRACE, "=> bdb2i_dn2id( \"%s\" )\n", dn, 0, 0 );
-
-       /* first check the cache */
-       if ( (id = bdb2i_cache_find_entry_dn2id( be, &li->li_cache, dn )) != NOID ) {
-               Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id %ld (in cache)\n", id,
-                       0, 0 );
-               return( id );
-       }
-
-       if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX, LDBM_WRCREAT ))
-               == NULL ) {
-               Debug( LDAP_DEBUG_ANY, "<= bdb2i_dn2id could not open dn2id%s\n",
-                       BDB2_SUFFIX, 0, 0 );
-               return( NOID );
-       }
-
-       ldbm_datum_init( key );
-
-       key.dsize = strlen( dn ) + 2;
-       key.dptr = ch_malloc( key.dsize );
-       sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
-
-       data = bdb2i_cache_fetch( db, key );
-
-       bdb2i_cache_close( be, db );
-
-       free( key.dptr );
-
-       if ( data.dptr == NULL ) {
-               Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id NOID\n", 0, 0, 0 );
-               return( NOID );
-       }
-
-       (void) memcpy( (char *) &id, data.dptr, sizeof(ID) );
-
-       ldbm_datum_free( db->dbc_db, data );
-
-       Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id %ld\n", id, 0, 0 );
-       return( id );
-}
-
-ID_BLOCK *
-bdb2i_dn2idl(
-    BackendDB  *be,
-    const char *dn,
-       int     prefix )
-{
-       struct dbcache  *db;
-       Datum key;
-       ID_BLOCK *idl;
-
-       Debug( LDAP_DEBUG_TRACE, "=> bdb2i_dn2idl( \"%c%s\" )\n", prefix, dn, 0 );
-
-       if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX, LDBM_WRCREAT ))
-           == NULL ) {
-               Debug( LDAP_DEBUG_ANY,
-                   "<= bdb2i_dn2idl could not open dn2id%s\n", BDB2_SUFFIX,
-                   0, 0 );
-               return( NULL );
-       }
-
-       ldbm_datum_init( key );
-
-       key.dsize = strlen( dn ) + 2;
-       key.dptr = ch_malloc( key.dsize );
-       sprintf( key.dptr, "%c%s", prefix, dn );
-
-       idl = bdb2i_idl_fetch( be, db, key );
-
-       free( key.dptr );
-
-       bdb2i_cache_close( be, db );
-
-       return( idl );
-}
-
-int
-bdb2i_dn2id_delete(
-    BackendDB  *be,
-    const char *dn,
-       ID id
-)
-{
-       struct dbcache  *db;
-       Datum           key;
-       int             rc;
-
-       Debug( LDAP_DEBUG_TRACE, "=> bdb2i_dn2id_delete( \"%s\", %ld )\n",
-               dn, id, 0 );
-
-       if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX, LDBM_WRCREAT ))
-           == NULL ) {
-               Debug( LDAP_DEBUG_ANY,
-                   "<= bdb2i_dn2id_delete could not open dn2id%s\n", BDB2_SUFFIX,
-                   0, 0 );
-               return( -1 );
-       }
-
-       {
-               char *pdn = dn_parent( NULL, dn );
-
-               if( pdn != NULL ) {
-                       ldbm_datum_init( key );
-                       key.dsize = strlen( pdn ) + 2;
-                       key.dptr = ch_malloc( key.dsize );
-                       sprintf( key.dptr, "%c%s", DN_ONE_PREFIX, pdn );
-                       (void) bdb2i_idl_delete_key( be, db, key, id );
-                       free( key.dptr );
-                       free( pdn );
-               }
-       }
-
-       {
-               char **subtree = dn_subtree( NULL, dn );
-
-               if( subtree != NULL ) {
-                       int i;
-                       for( i=0; subtree[i] != NULL; i++ ) {
-                               ldbm_datum_init( key );
-                               key.dsize = strlen( subtree[i] ) + 2;
-                               key.dptr = ch_malloc( key.dsize );
-                               sprintf( key.dptr, "%c%s", DN_SUBTREE_PREFIX, subtree[i] );
-
-                               (void) bdb2i_idl_delete_key( be, db, key, id );
-
-                               free( key.dptr );
-                       }
-
-                       charray_free( subtree );
-               }
-       }
-
-       ldbm_datum_init( key );
-
-       key.dsize = strlen( dn ) + 2;
-       key.dptr = ch_malloc( key.dsize );
-       sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
-
-       rc = bdb2i_cache_delete( db, key );
-
-       free( key.dptr );
-
-       bdb2i_cache_close( be, db );
-
-       Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id_delete %d\n", rc, 0, 0 );
-       return( rc );
-}
-
-/*
- * dn2entry - look up dn in the cache/indexes and return the corresponding
- * entry.
- */
-
-Entry *
-bdb2i_dn2entry_rw(
-    BackendDB  *be,
-    const char *dn,
-    Entry      **matched,
-    int         rw
-)
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       ID              id;
-       Entry           *e = NULL;
-       char            *pdn;
-
-       Debug(LDAP_DEBUG_TRACE, "dn2entry_%s: dn: \"%s\"\n",
-               rw ? "w" : "r", dn, 0);
-
-       if( matched != NULL ) {
-               /* caller cares about match */
-               *matched = NULL;
-       }
-
-       if ( (id = bdb2i_dn2id( be, dn )) != NOID &&
-               (e = bdb2i_id2entry_rw( be, id, rw )) != NULL )
-       {
-               return( e );
-       }
-
-       if ( id != NOID ) {
-               Debug(LDAP_DEBUG_ANY,
-                       "dn2entry_%s: no entry for valid id (%ld), dn \"%s\"\n",
-                       rw ? "w" : "r", id, dn);
-               /* must have been deleted from underneath us */
-               /* treat as if NOID was found */
-       }
-
-       /* caller doesn't care about match */
-       if( matched == NULL ) return NULL;
-
-       /* entry does not exist - see how much of the dn does exist */
-       /* dn_parent checks returns NULL if dn is suffix */
-       if ( (pdn = dn_parent( be, dn )) != NULL ) {
-               /* get entry with reader lock */
-               if ( (e = bdb2i_dn2entry_r( be, pdn, matched )) != NULL ) {
-                       *matched = e;
-               }
-               free( pdn );
-       }
-
-       return( NULL );
-}
-
-
diff --git a/servers/slapd/back-bdb2/entry.c b/servers/slapd/back-bdb2/entry.c
deleted file mode 100644 (file)
index 9238b1c..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* entry.c - ldbm backend entry_release routine */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/socket.h>
-#include <ac/string.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-#include "proto-back-bdb2.h"
-
-
-int
-bdb2_back_entry_release_rw(
-       BackendDB *be,
-       Entry   *e,
-       int     rw
-)
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-
-       /* free entry and reader or writer lock */
-       bdb2i_cache_return_entry_rw( &li->li_cache, e, rw ); 
-       bdb2i_release_add_lock();
-
-       return 0;
-}
diff --git a/servers/slapd/back-bdb2/external.h b/servers/slapd/back-bdb2/external.h
deleted file mode 100644 (file)
index 9af5a84..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/* $OpenLDAP$ */
-#ifndef _BDB2_EXTERNAL_H
-#define _BDB2_EXTERNAL_H
-
-LDAP_BEGIN_DECL
-
-extern int     bdb2_back_initialize LDAP_P(( BackendInfo *bi ));
-extern int     bdb2_back_open LDAP_P(( BackendInfo *bi ));
-extern int     bdb2_back_close LDAP_P(( BackendInfo *bi ));
-extern int     bdb2_back_destroy LDAP_P(( BackendInfo *bi ));
-
-extern int     bdb2_back_config LDAP_P(( BackendInfo *bt,
-       const char *fname, int lineno, int argc, char **argv ));
-
-extern int     bdb2_back_db_init LDAP_P(( BackendDB *bd ));
-extern int     bdb2_back_db_open LDAP_P(( BackendDB *bd ));
-extern int     bdb2_back_db_close LDAP_P(( BackendDB *bd ));
-extern int     bdb2_back_db_destroy LDAP_P(( BackendDB *bd ));
-
-extern int     bdb2_back_db_config LDAP_P(( BackendDB *bd,
-       const char *fname, int lineno, int argc, char **argv ));
-
-extern int bdb2_back_bind LDAP_P(( BackendDB *bd,
-       Connection *conn, Operation *op,
-       char *dn, int method, char* mech,
-       struct berval *cred, char** edn ));
-
-extern int     bdb2_back_unbind LDAP_P(( BackendDB *bd,
-       Connection *conn, Operation *op ));
-
-extern int     bdb2_back_search LDAP_P(( BackendDB *bd,
-       Connection *conn, Operation *op,
-       char *base, int scope, int deref, int sizelimit, int timelimit,
-       Filter *filter, char *filterstr, char **attrs, int attrsonly ));
-
-extern int     bdb2_back_compare LDAP_P((BackendDB *bd,
-       Connection *conn, Operation *op,
-       char *dn, Ava   *ava ));
-
-extern int     bdb2_back_modify LDAP_P(( BackendDB *bd,
-       Connection *conn, Operation *op,
-       char *dn, LDAPModList *ml ));
-
-extern int     bdb2_back_modrdn LDAP_P(( BackendDB *bd,
-       Connection *conn, Operation *op,
-       char *dn, char*newrdn, int deleteoldrdn,
-       char *newSuperior ));
-
-extern int     bdb2_back_add LDAP_P(( BackendDB *bd,
-       Connection *conn, Operation *op, Entry *e ));
-
-extern int     bdb2_back_delete LDAP_P(( BackendDB *bd,
-       Connection *conn, Operation *op, char *dn ));
-
-extern int     bdb2_back_abandon LDAP_P(( BackendDB *bd,
-       Connection *conn, Operation *op, int msgid ));
-
-extern int     bdb2_back_group LDAP_P(( BackendDB *bd,
-       Entry *target, const char* gr_ndn, const char* op_ndn,
-       const char* objectclassValue, const char* groupattrName));
-
-/* hooks for slap tools */
-extern int bdb2_tool_entry_open LDAP_P(( BackendDB *be, int mode ));
-extern int bdb2_tool_entry_close LDAP_P(( BackendDB *be ));
-extern ID bdb2_tool_entry_first LDAP_P(( BackendDB *be ));
-extern ID bdb2_tool_entry_next LDAP_P(( BackendDB *be ));
-extern Entry* bdb2_tool_entry_get LDAP_P(( BackendDB *be, ID id ));
-extern ID bdb2_tool_entry_put LDAP_P(( BackendDB *be, Entry *e ));
-extern int bdb2_tool_index_attr LDAP_P(( BackendDB *be, char* type ));
-extern int bdb2_tool_index_change LDAP_P(( BackendDB *be, char* type,
-       struct berval **bv, ID id, int op ));
-extern int bdb2_tool_sync LDAP_P(( BackendDB *be ));
-
-LDAP_END_DECL
-
-#endif /* _BDB2_EXTERNAL_H */
-
diff --git a/servers/slapd/back-bdb2/filterindex.c b/servers/slapd/back-bdb2/filterindex.c
deleted file mode 100644 (file)
index a9f7452..0000000
+++ /dev/null
@@ -1,369 +0,0 @@
-/* filterindex.c - generate the list of candidate entries from a filter */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/socket.h>
-#include <ac/string.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-
-static ID_BLOCK        *ava_candidates( BackendDB *be, Ava *ava, int type );
-static ID_BLOCK        *presence_candidates( BackendDB *be, char *type );
-static ID_BLOCK        *approx_candidates( BackendDB *be, Ava *ava );
-static ID_BLOCK        *list_candidates( BackendDB *be, Filter *flist, int ftype );
-static ID_BLOCK        *substring_candidates( BackendDB *be, Filter *f );
-static ID_BLOCK        *substring_comp_candidates( BackendDB *be, char *type, char *val, int prepost );
-
-/*
- * test_filter - test a filter against a single entry.
- * returns     0       filter matched
- *             -1      filter did not match
- *             >0      an ldap error code
- */
-
-ID_BLOCK *
-bdb2i_filter_candidates(
-    BackendDB  *be,
-    Filter     *f
-)
-{
-       ID_BLOCK        *result, *tmp1, *tmp2;
-
-       Debug( LDAP_DEBUG_TRACE, "=> bdb2i_filter_candidates\n", 0, 0, 0 );
-
-       result = NULL;
-       switch ( f->f_choice ) {
-       case SLAPD_FILTER_DN_ONE:
-               Debug( LDAP_DEBUG_FILTER, "\tDN ONE\n", 0, 0, 0 );
-               result = bdb2i_dn2idl( be, f->f_dn, DN_SUBTREE_PREFIX );
-               break;
-
-       case SLAPD_FILTER_DN_SUBTREE:
-               Debug( LDAP_DEBUG_FILTER, "\tDN SUBTREE\n", 0, 0, 0 );
-               result = bdb2i_dn2idl( be, f->f_dn, DN_SUBTREE_PREFIX );
-               break;
-
-       case LDAP_FILTER_EQUALITY:
-               Debug( LDAP_DEBUG_FILTER, "\tEQUALITY\n", 0, 0, 0 );
-               result = ava_candidates( be, &f->f_ava, LDAP_FILTER_EQUALITY );
-               break;
-
-       case LDAP_FILTER_SUBSTRINGS:
-               Debug( LDAP_DEBUG_FILTER, "\tSUBSTRINGS\n", 0, 0, 0 );
-               result = substring_candidates( be, f );
-               break;
-
-       case LDAP_FILTER_GE:
-               Debug( LDAP_DEBUG_FILTER, "\tGE\n", 0, 0, 0 );
-               result = ava_candidates( be, &f->f_ava, LDAP_FILTER_GE );
-               break;
-
-       case LDAP_FILTER_LE:
-               Debug( LDAP_DEBUG_FILTER, "\tLE\n", 0, 0, 0 );
-               result = ava_candidates( be, &f->f_ava, LDAP_FILTER_LE );
-               break;
-
-       case LDAP_FILTER_PRESENT:
-               Debug( LDAP_DEBUG_FILTER, "\tPRESENT\n", 0, 0, 0 );
-               result = presence_candidates( be, f->f_type );
-               break;
-
-       case LDAP_FILTER_APPROX:
-               Debug( LDAP_DEBUG_FILTER, "\tAPPROX\n", 0, 0, 0 );
-               result = approx_candidates( be, &f->f_ava );
-               break;
-
-       case LDAP_FILTER_AND:
-               Debug( LDAP_DEBUG_FILTER, "\tAND\n", 0, 0, 0 );
-               result = list_candidates( be, f->f_and, LDAP_FILTER_AND );
-               break;
-
-       case LDAP_FILTER_OR:
-               Debug( LDAP_DEBUG_FILTER, "\tOR\n", 0, 0, 0 );
-               result = list_candidates( be, f->f_or, LDAP_FILTER_OR );
-               break;
-
-       case LDAP_FILTER_NOT:
-               Debug( LDAP_DEBUG_FILTER, "\tNOT\n", 0, 0, 0 );
-               tmp1 = bdb2i_idl_allids( be );
-               tmp2 = bdb2i_filter_candidates( be, f->f_not );
-               result = bdb2i_idl_notin( be, tmp1, tmp2 );
-               bdb2i_idl_free( tmp2 );
-               bdb2i_idl_free( tmp1 );
-               break;
-       }
-
-       Debug( LDAP_DEBUG_TRACE, "<= bdb2i_filter_candidates %ld\n",
-           result ? ID_BLOCK_NIDS(result) : 0, 0, 0 );
-       return( result );
-}
-
-static ID_BLOCK *
-ava_candidates(
-    BackendDB  *be,
-    Ava                *ava,
-    int                type
-)
-{
-       ID_BLOCK        *idl;
-
-       Debug( LDAP_DEBUG_TRACE, "=> ava_candidates 0x%x\n", type, 0, 0 );
-
-       switch ( type ) {
-       case LDAP_FILTER_EQUALITY:
-               idl = bdb2i_index_read( be, ava->ava_type, INDEX_EQUALITY,
-                   ava->ava_value.bv_val );
-               break;
-
-       case LDAP_FILTER_GE:
-               idl = bdb2i_idl_allids( be );
-               break;
-
-       case LDAP_FILTER_LE:
-               idl = bdb2i_idl_allids( be );
-               break;
-       }
-
-       Debug( LDAP_DEBUG_TRACE, "<= ava_candidates %ld\n",
-           idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
-       return( idl );
-}
-
-static ID_BLOCK *
-presence_candidates(
-    BackendDB  *be,
-    char       *type
-)
-{
-       ID_BLOCK        *idl;
-
-       Debug( LDAP_DEBUG_TRACE, "=> presence_candidates\n", 0, 0, 0 );
-
-       idl = bdb2i_index_read( be, type, 0, "*" );
-
-       Debug( LDAP_DEBUG_TRACE, "<= presence_candidates %ld\n",
-           idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
-       return( idl );
-}
-
-static ID_BLOCK *
-approx_candidates(
-    BackendDB  *be,
-    Ava                *ava
-)
-{
-       char    *w, *c;
-       ID_BLOCK        *idl, *tmp;
-
-       Debug( LDAP_DEBUG_TRACE, "=> approx_candidates\n", 0, 0, 0 );
-
-       idl = NULL;
-       for ( w = first_word( ava->ava_value.bv_val ); w != NULL;
-           w = next_word( w ) ) {
-               c = phonetic( w );
-               if ( (tmp = bdb2i_index_read( be, ava->ava_type, INDEX_APPROX, c ))
-                   == NULL ) {
-                       free( c );
-                       bdb2i_idl_free( idl );
-                       Debug( LDAP_DEBUG_TRACE, "<= approx_candidates NULL\n",
-                           0, 0, 0 );
-                       return( NULL );
-               }
-               free( c );
-
-               if ( idl == NULL ) {
-                       idl = tmp;
-               } else {
-                       idl = bdb2i_idl_intersection( be, idl, tmp );
-               }
-       }
-
-       Debug( LDAP_DEBUG_TRACE, "<= approx_candidates %ld\n",
-           idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
-       return( idl );
-}
-
-static ID_BLOCK *
-list_candidates(
-    BackendDB  *be,
-    Filter     *flist,
-    int                ftype
-)
-{
-       ID_BLOCK        *idl, *tmp, *tmp2;
-       Filter  *f;
-
-       Debug( LDAP_DEBUG_TRACE, "=> list_candidates 0x%x\n", ftype, 0, 0 );
-
-       idl = NULL;
-       for ( f = flist; f != NULL; f = f->f_next ) {
-               if ( (tmp = bdb2i_filter_candidates( be, f )) == NULL &&
-                   ftype == LDAP_FILTER_AND ) {
-                               Debug( LDAP_DEBUG_TRACE,
-                                   "<= list_candidates NULL\n", 0, 0, 0 );
-                               bdb2i_idl_free( idl );
-                               return( NULL );
-               }
-
-               tmp2 = idl;
-               if ( idl == NULL ) {
-                       idl = tmp;
-               } else if ( ftype == LDAP_FILTER_AND ) {
-                       idl = bdb2i_idl_intersection( be, idl, tmp );
-                       bdb2i_idl_free( tmp );
-                       bdb2i_idl_free( tmp2 );
-               } else {
-                       idl = bdb2i_idl_union( be, idl, tmp );
-                       bdb2i_idl_free( tmp );
-                       bdb2i_idl_free( tmp2 );
-               }
-       }
-
-       Debug( LDAP_DEBUG_TRACE, "<= list_candidates %ld\n",
-           idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
-       return( idl );
-}
-
-static ID_BLOCK *
-substring_candidates(
-    BackendDB  *be,
-    Filter     *f
-)
-{
-       int     i;
-       ID_BLOCK        *idl, *tmp, *tmp2;
-
-       Debug( LDAP_DEBUG_TRACE, "=> substring_candidates\n", 0, 0, 0 );
-
-       idl = NULL;
-
-       /* initial */
-       if ( f->f_sub_initial != NULL ) {
-               if ( (int) strlen( f->f_sub_initial ) < SUBLEN - 1 ) {
-                       idl = bdb2i_idl_allids( be );
-               } else if ( (idl = substring_comp_candidates( be, f->f_sub_type,
-                   f->f_sub_initial, '^' )) == NULL ) {
-                       return( NULL );
-               }
-       }
-
-       /* final */
-       if ( f->f_sub_final != NULL ) {
-               if ( (int) strlen( f->f_sub_final ) < SUBLEN - 1 ) {
-                       tmp = bdb2i_idl_allids( be );
-               } else if ( (tmp = substring_comp_candidates( be, f->f_sub_type,
-                   f->f_sub_final, '$' )) == NULL ) {
-                       bdb2i_idl_free( idl );
-                       return( NULL );
-               }
-
-               if ( idl == NULL ) {
-                       idl = tmp;
-               } else {
-                       tmp2 = idl;
-                       idl = bdb2i_idl_intersection( be, idl, tmp );
-                       bdb2i_idl_free( tmp );
-                       bdb2i_idl_free( tmp2 );
-               }
-       }
-
-       for ( i = 0; f->f_sub_any != NULL && f->f_sub_any[i] != NULL; i++ ) {
-               if ( (int) strlen( f->f_sub_any[i] ) < SUBLEN ) {
-                       tmp = bdb2i_idl_allids( be );
-               } else if ( (tmp = substring_comp_candidates( be, f->f_sub_type,
-                   f->f_sub_any[i], 0 )) == NULL ) {
-                       bdb2i_idl_free( idl );
-                       return( NULL );
-               }
-
-               if ( idl == NULL ) {
-                       idl = tmp;
-               } else {
-                       tmp2 = idl;
-                       idl = bdb2i_idl_intersection( be, idl, tmp );
-                       bdb2i_idl_free( tmp );
-                       bdb2i_idl_free( tmp2 );
-               }
-       }
-
-       Debug( LDAP_DEBUG_TRACE, "<= substring_candidates %ld\n",
-           idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
-       return( idl );
-}
-
-static ID_BLOCK *
-substring_comp_candidates(
-    BackendDB  *be,
-    char       *type,
-    char       *val,
-    int                prepost
-)
-{
-       int     i, len;
-       ID_BLOCK        *idl, *tmp, *tmp2;
-       char    *p;
-       char    buf[SUBLEN + 1];
-
-       Debug( LDAP_DEBUG_TRACE, "=> substring_comp_candidates\n", 0, 0, 0 );
-
-       len = strlen( val );
-       idl = NULL;
-
-       /* prepend ^ for initial substring */
-       if ( prepost == '^' ) {
-               buf[0] = '^';
-               for ( i = 0; i < SUBLEN - 1; i++ ) {
-                       buf[i + 1] = val[i];
-               }
-               buf[SUBLEN] = '\0';
-
-               if ( (idl = bdb2i_index_read( be, type, INDEX_SUB, buf )) == NULL ) {
-                       return( NULL );
-               }
-       } else if ( prepost == '$' ) {
-               p = val + len - SUBLEN + 1;
-               for ( i = 0; i < SUBLEN - 1; i++ ) {
-                       buf[i] = p[i];
-               }
-               buf[SUBLEN - 1] = '$';
-               buf[SUBLEN] = '\0';
-
-               if ( (idl = bdb2i_index_read( be, type, INDEX_SUB, buf )) == NULL ) {
-                       return( NULL );
-               }
-       }
-
-       for ( p = val; p < (val + len - SUBLEN + 1); p++ ) {
-               for ( i = 0; i < SUBLEN; i++ ) {
-                       buf[i] = p[i];
-               }
-               buf[SUBLEN] = '\0';
-
-               if ( (tmp = bdb2i_index_read( be, type, INDEX_SUB, buf )) == NULL ) {
-                       bdb2i_idl_free( idl );
-                       return( NULL );
-               }
-
-               if ( idl == NULL ) {
-                       idl = tmp;
-               } else {
-                       tmp2 = idl;
-                       idl = bdb2i_idl_intersection( be, idl, tmp );
-                       bdb2i_idl_free( tmp );
-                       bdb2i_idl_free( tmp2 );
-               }
-
-               /* break if no candidates */
-               if( idl == NULL ) {
-                       break;
-               }
-       }
-
-       Debug( LDAP_DEBUG_TRACE, "<= substring_comp_candidates %ld\n",
-           idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
-       return( idl );
-}
diff --git a/servers/slapd/back-bdb2/group.c b/servers/slapd/back-bdb2/group.c
deleted file mode 100644 (file)
index 4bc4fc9..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/* group.c - bdb2 backend acl group routine */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/socket.h>
-#include <ac/string.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-#include "proto-back-bdb2.h"
-
-
-/* return 0 IFF op_dn is a value in member attribute
- * of entry with gr_dn AND that entry has an objectClass
- * value of groupOfNames
- */
-static int
-bdb2i_back_group_internal(
-       BackendDB       *be,
-       Entry   *target,
-       const char      *gr_ndn,
-       const char      *op_ndn,
-       const char      *objectclassValue,
-       const char      *groupattrName
-)
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;    
-       Entry *e;
-       int rc = 1;
-       Attribute *attr;
-       struct berval bv;
-
-       Debug( LDAP_DEBUG_ARGS,
-               "=> bdb2i_back_group: gr dn: \"%s\"\n",
-               gr_ndn, 0, 0 ); 
-       Debug( LDAP_DEBUG_ARGS,
-               "=> bdb2i_back_group: op dn: \"%s\"\n",
-               op_ndn, 0, 0 ); 
-       Debug( LDAP_DEBUG_ARGS,
-               "=> bdb2i_back_group: objectClass: \"%s\" attrName: \"%s\"\n", 
-               objectclassValue, groupattrName, 0 ); 
-
-       Debug( LDAP_DEBUG_ARGS,
-               "=> bdb2i_back_group: tr dn: \"%s\"\n",
-               target->e_ndn, 0, 0 ); 
-
-       if (strcmp(target->e_ndn, gr_ndn) == 0) {
-               /* we already have a LOCKED copy of the entry */
-               e = target;
-               Debug( LDAP_DEBUG_ARGS,
-                       "=> bdb2i_back_group: target is group: \"%s\"\n",
-                       gr_ndn, 0, 0 ); 
-
-       } else {
-               /* can we find group entry with reader lock */
-               if ((e = bdb2i_dn2entry_r(be, gr_ndn, NULL )) == NULL) {
-                       Debug( LDAP_DEBUG_ACL,
-                               "=> bdb2i_back_group: cannot find group: \"%s\"\n",
-                                       gr_ndn, 0, 0 ); 
-                       return( 1 );
-               }
-
-               Debug( LDAP_DEBUG_ACL,
-                       "=> bdb2i_back_group: found group: \"%s\"\n",
-                       gr_ndn, 0, 0 ); 
-       }
-
-       /* find it's objectClass and member attribute values
-        * make sure this is a group entry
-        * finally test if we can find op_dn in the member attribute value list
-        */
-        
-       rc = 1;
-
-       if ((attr = attr_find(e->e_attrs, "objectclass")) == NULL)  {
-               Debug( LDAP_DEBUG_ACL,
-                       "<= bdb2i_back_group: failed to find objectClass\n", 0, 0, 0 ); 
-               goto return_results;
-       }
-
-       bv.bv_val = "ALIAS";
-       bv.bv_len = sizeof("ALIAS")-1;
-
-       if (value_find(attr->a_vals, &bv, attr->a_syntax, 1) != 0) {
-               Debug( LDAP_DEBUG_ACL,
-                       "<= bdb2i_back_group: group is an alias\n", 0, 0, 0 ); 
-               goto return_results;
-       }
-
-       bv.bv_val = "REFERRAL";
-       bv.bv_len = sizeof("REFERRAL")-1;
-
-       if (value_find(attr->a_vals, &bv, attr->a_syntax, 1) != 0) {
-               Debug( LDAP_DEBUG_ACL,
-                       "<= bdb2i_back_group: group is a referral\n", 0, 0, 0 ); 
-               goto return_results;
-       }
-
-       bv.bv_val = (char *) objectclassValue;
-       bv.bv_len = strlen( bv.bv_val );
-
-       if (value_find(attr->a_vals, &bv, attr->a_syntax, 1) != 0) {
-               Debug( LDAP_DEBUG_ACL,
-                       "<= bdb2i_back_group: failed to find %s in objectClass\n",
-                       objectclassValue, 0, 0 ); 
-               goto return_results;
-       }
-
-       if ((attr = attr_find(e->e_attrs, groupattrName)) == NULL) {
-               Debug( LDAP_DEBUG_ACL,
-                       "<= bdb2i_back_group: failed to find %s\n",
-                       groupattrName, 0, 0 ); 
-               goto return_results;
-       }
-
-       Debug( LDAP_DEBUG_ACL,
-               "<= bdb2i_back_group: found objectClass %s and %s\n",
-               objectclassValue, groupattrName, 0 ); 
-
-
-       bv.bv_val = (char *) op_ndn;
-       bv.bv_len = strlen( op_ndn );         
-
-       if (value_find( attr->a_vals, &bv, attr->a_syntax, 1) != 0 ) {
-               Debug( LDAP_DEBUG_ACL,
-                       "<= bdb2i_back_group: \"%s\" not in \"%s\": %s\n", 
-                       op_ndn, gr_ndn, groupattrName ); 
-               goto return_results;
-       }
-
-       Debug( LDAP_DEBUG_ACL,
-               "<= bdb2i_back_group: \"%s\" is in \"%s\": %s\n", 
-               op_ndn, gr_ndn, groupattrName ); 
-       rc = 0;
-
-return_results:
-       if( target != e ) {
-               /* free entry and reader lock */
-               bdb2i_cache_return_entry_r( &li->li_cache, e );                 
-       }
-
-       Debug( LDAP_DEBUG_ARGS, "bdb2i_back_group: rc: %d\n", rc, 0, 0 ); 
-       return(rc);
-}
-
-
-int
-bdb2_back_group(
-       BackendDB       *be,
-       Entry   *target,
-       const char      *gr_ndn,
-       const char      *op_ndn,
-       const char      *objectclassValue,
-       const char      *groupattrName
-)
-{
-       DB_LOCK         lock;
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       struct timeval  time1;
-       int             ret;
-
-       bdb2i_start_timing( be->bd_info, &time1 );
-
-       if ( bdb2i_enter_backend_r( &lock ) != 0 ) {
-
-               return( 1 );
-
-       }
-
-       ret = bdb2i_back_group_internal( be, target, gr_ndn, op_ndn,
-                                       objectclassValue, groupattrName );
-
-       (void) bdb2i_leave_backend_r( lock );
-       bdb2i_stop_timing( be->bd_info, time1, "GRP", NULL, NULL );
-
-       return( ret );
-}
-
-
diff --git a/servers/slapd/back-bdb2/id2children.c b/servers/slapd/back-bdb2/id2children.c
deleted file mode 100644 (file)
index 8db5c18..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/* id2children.c - routines to deal with the id2children index */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-
-int
-bdb2i_has_children(
-    BackendDB  *be,
-    Entry      *p
-)
-{
-       struct dbcache  *db;
-       Datum           key;
-       int             rc = 0;
-       ID_BLOCK                *idl;
-
-       ldbm_datum_init( key );
-
-       Debug( LDAP_DEBUG_TRACE, "=> bdb2i_has_children( %ld )\n", p->e_id , 0, 0 );
-
-       if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX,
-           LDBM_WRCREAT )) == NULL ) {
-               Debug( LDAP_DEBUG_ANY,
-                   "<= bdb2i_has_children: could not open \"dn2id" BDB2_SUFFIX "\"\n",
-                   0, 0, 0 );
-               return( 0 );
-       }
-
-       key.dsize = strlen( p->e_ndn ) + 2;
-       key.dptr = ch_malloc( key.dsize );
-       sprintf( key.dptr, "%c%s", DN_ONE_PREFIX, p->e_ndn );
-
-       idl = bdb2i_idl_fetch( be, db, key );
-
-       free( key.dptr );
-
-       bdb2i_cache_close( be, db );
-
-       if( idl != NULL ) {
-               bdb2i_idl_free( idl );
-               rc = 1;
-       }
-
-       Debug( LDAP_DEBUG_TRACE, "<= bdb2i_has_children( %ld ): %s\n",
-                                       p->e_id, rc ? "yes" : "no", 0 );
-       return( rc );
-}
diff --git a/servers/slapd/back-bdb2/id2entry.c b/servers/slapd/back-bdb2/id2entry.c
deleted file mode 100644 (file)
index 1a151fb..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/* id2entry.c - routines to deal with the id2entry index */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-
-/*
- * This routine adds (or updates) an entry on disk.
- * The cache should already be updated.
- */
-
-int
-bdb2i_id2entry_add( BackendDB *be, Entry *e )
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       struct dbcache  *db;
-       Datum           key, data;
-       int             len, rc, flags;
-
-       ldbm_datum_init( key );
-       ldbm_datum_init( data );
-
-       Debug( LDAP_DEBUG_TRACE, "=> bdb2i_id2entry_add( %ld, \"%s\" )\n", e->e_id,
-           e->e_dn, 0 );
-
-       if ( (db = bdb2i_cache_open( be, "id2entry", BDB2_SUFFIX, LDBM_WRCREAT ))
-           == NULL ) {
-               Debug( LDAP_DEBUG_ANY, "Could not open/create id2entry%s\n",
-                   BDB2_SUFFIX, 0, 0 );
-               return( -1 );
-       }
-
-       key.dptr = (char *) &e->e_id;
-       key.dsize = sizeof(ID);
-
-       ldap_pvt_thread_mutex_lock( &entry2str_mutex );
-       data.dptr = entry2str( e, &len );
-       data.dsize = len + 1;
-
-       /* store it */
-       flags = LDBM_REPLACE;
-       if ( li->li_dbcachewsync ) flags |= LDBM_SYNC;
-       rc = bdb2i_cache_store( db, key, data, flags );
-
-       ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
-
-       bdb2i_cache_close( be, db );
-
-       Debug( LDAP_DEBUG_TRACE, "<= bdb2i_id2entry_add %d\n", rc, 0, 0 );
-
-       return( rc );
-}
-
-int
-bdb2i_id2entry_delete( BackendDB *be, Entry *e )
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       struct dbcache  *db;
-       Datum           key;
-       int             rc;
-
-       Debug(LDAP_DEBUG_TRACE, "=> bdb2i_id2entry_delete( %ld, \"%s\" )\n", e->e_id,
-           e->e_dn, 0 );
-
-#ifdef notdef
-#ifdef LDAP_DEBUG
-       /* check for writer lock */
-       assert(ldap_pvt_thread_rdwr_writers(&e->e_rdwr) == 1);
-#endif
-#endif
-
-       ldbm_datum_init( key );
-
-       if ( (db = bdb2i_cache_open( be, "id2entry", BDB2_SUFFIX, LDBM_WRCREAT ))
-               == NULL ) {
-               Debug( LDAP_DEBUG_ANY, "Could not open/create id2entry%s\n",
-                   BDB2_SUFFIX, 0, 0 );
-               return( -1 );
-       }
-
-       if ( bdb2i_cache_delete_entry( &li->li_cache, e ) != 0 ) {
-               Debug(LDAP_DEBUG_ANY, "could not delete %ld (%s) from cache\n",
-                   e->e_id, e->e_dn, 0 );
-       }
-
-       key.dptr = (char *) &e->e_id;
-       key.dsize = sizeof(ID);
-
-       rc = bdb2i_cache_delete( db, key );
-
-       bdb2i_cache_close( be, db );
-
-       Debug( LDAP_DEBUG_TRACE, "<= bdb2i_id2entry_delete %d\n", rc, 0, 0 );
-       return( rc );
-}
-
-/* returns entry with reader/writer lock */
-Entry *
-bdb2i_id2entry_rw( BackendDB *be, ID id, int rw )
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       struct dbcache  *db;
-       Datum           key, data;
-       Entry           *e;
-
-       ldbm_datum_init( key );
-       ldbm_datum_init( data );
-
-       Debug( LDAP_DEBUG_TRACE, "=> bdb2i_id2entry_%s( %ld )\n",
-               rw ? "w" : "r", id, 0 );
-
-       if ( (e = bdb2i_cache_find_entry_id( &li->li_cache, id, rw )) != NULL ) {
-               Debug( LDAP_DEBUG_TRACE, "<= bdb2i_id2entry_%s( %ld ) 0x%lx (cache)\n",
-                       rw ? "w" : "r", id, (unsigned long)e );
-               return( e );
-       }
-
-       if ( (db = bdb2i_cache_open( be, "id2entry", BDB2_SUFFIX, LDBM_WRCREAT ))
-               == NULL ) {
-               Debug( LDAP_DEBUG_ANY, "Could not open id2entry%s\n",
-                   BDB2_SUFFIX, 0, 0 );
-               return( NULL );
-       }
-
-       key.dptr = (char *) &id;
-       key.dsize = sizeof(ID);
-
-       data = bdb2i_cache_fetch( db, key );
-
-       if ( data.dptr == NULL ) {
-               Debug( LDAP_DEBUG_TRACE, "<= bdb2i_id2entry_%s( %ld ) not found\n",
-                       rw ? "w" : "r", id, 0 );
-               bdb2i_cache_close( be, db );
-               return( NULL );
-       }
-
-       e = str2entry( data.dptr );
-
-       ldbm_datum_free( db->dbc_db, data );
-       bdb2i_cache_close( be, db );
-
-       if ( e == NULL ) {
-               Debug( LDAP_DEBUG_TRACE, "<= bdb2i_id2entry_%s( %ld )  (failed)\n",
-                       rw ? "w" : "r", id, 0 );
-               return( NULL );
-       }
-
-       e->e_id = id; 
-
-       if ( bdb2i_cache_add_entry_rw( &li->li_cache, e, rw ) != 0 ) {
-               entry_free( e );
-
-               /* see if it got added underneath us */
-               if((e = bdb2i_cache_find_entry_id( &li->li_cache, id, rw )) != NULL ) {
-                       Debug( LDAP_DEBUG_TRACE,
-                               "<= bdb2i_id2entry_%s( %ld ) 0x%lx (cache)\n",
-                               rw ? "w" : "r", id, (unsigned long)e );
-                       return( e );
-               }
-
-               Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb2i_id2entry_%s( %ld ) (cache add failed)\n",
-                       rw ? "w" : "r", id, 0 );
-               return( NULL );
-       }
-
-       Debug( LDAP_DEBUG_TRACE, "<= bdb2i_id2entry_%s( %ld ) 0x%lx (disk)\n",
-               rw ? "w" : "r", id, (unsigned long) e );
-
-       return( e );
-}
-
-
diff --git a/servers/slapd/back-bdb2/idl.c b/servers/slapd/back-bdb2/idl.c
deleted file mode 100644 (file)
index c062642..0000000
+++ /dev/null
@@ -1,1050 +0,0 @@
-/* idl.c - ldap id list handling routines */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-
-static ID_BLOCK* idl_dup( ID_BLOCK *idl );
-
-/* Allocate an ID_BLOCK with room for nids ids */
-ID_BLOCK *
-bdb2i_idl_alloc( unsigned int nids )
-{
-       ID_BLOCK        *new;
-
-       /* nmax + nids + space for the ids */
-       new = (ID_BLOCK *) ch_calloc( (ID_BLOCK_IDS_OFFSET + nids), sizeof(ID) );
-       ID_BLOCK_NMAX(new) = nids;
-       ID_BLOCK_NIDS(new) = 0;
-
-       return( new );
-}
-
-
-/* Allocate an empty ALLIDS ID_BLOCK */
-ID_BLOCK       *
-bdb2i_idl_allids( BackendDB *be )
-{
-       ID_BLOCK        *idl;
-
-       idl = bdb2i_idl_alloc( 0 );
-       ID_BLOCK_NMAX(idl) = ID_BLOCK_ALLIDS_VALUE;
-       ID_BLOCK_NIDS(idl) = bdb2i_next_id_get( be );
-
-       return( idl );
-}
-
-
-/* Free an ID_BLOCK */
-void
-bdb2i_idl_free( ID_BLOCK *idl )
-{
-       if ( idl == NULL ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "bdb2i_idl_free: called with NULL pointer\n",
-                       0, 0, 0 );
-               return;
-       }
-
-       free( (char *) idl );
-}
-
-
-/* Fetch an single ID_BLOCK from the cache */
-static ID_BLOCK *
-idl_fetch_one(
-    BackendDB          *be,
-    struct dbcache     *db,
-    Datum              key
-)
-{
-       Datum   data;
-       ID_BLOCK        *idl;
-
-       ldbm_datum_init( data );
-
-       /* Debug( LDAP_DEBUG_TRACE, "=> idl_fetch_one\n", 0, 0, 0 ); */
-
-       data = bdb2i_cache_fetch( db, key );
-
-       if( data.dptr == NULL ) {
-               return NULL;
-       }
-
-       idl = idl_dup( (ID_BLOCK *) data.dptr);
-       ldbm_datum_free( db->dbc_db, data );
-
-       return( idl );
-}
-
-
-/* Fetch a set of ID_BLOCKs from the cache
- *     if not INDIRECT
- *             if block return is an ALLIDS block,
- *                     return an new ALLIDS block
- *             otherwise
- *                     return block
- *     construct super block from all blocks referenced by INDIRECT block
- *     return super block
- */
-ID_BLOCK *
-bdb2i_idl_fetch(
-    BackendDB          *be,
-    struct dbcache     *db,
-    Datum              key
-)
-{
-       Datum   data;
-       ID_BLOCK        *idl;
-       ID_BLOCK        **tmp;
-       char    *kstr;
-       int     i, nids;
-
-       idl = idl_fetch_one( be, db, key );
-
-       if ( idl == NULL ) { 
-               return NULL;
-       }
-
-       if ( ID_BLOCK_ALLIDS(idl) ) {
-               /* all ids block */
-               /* make sure we have the current value of highest id */
-               bdb2i_idl_free( idl );
-               idl = bdb2i_idl_allids( be );
-
-               return( idl );
-       }
-
-       if ( ! ID_BLOCK_INDIRECT( idl ) ) {
-               /* regular block */
-               return( idl );
-       }
-
-       /*
-        * this is an indirect block which points to other blocks.
-        * we need to read in all the blocks it points to and construct
-        * a big id list containing all the ids, which we will return.
-        */
-
-       /* count the number of blocks & allocate space for pointers to them */
-       for ( i = 0; !ID_BLOCK_NOID(idl, i); i++ )
-               ;       /* NULL */
-       tmp = (ID_BLOCK **) ch_malloc( (i + 1) * sizeof(ID_BLOCK *) );
-
-       /* read in all the blocks */
-       kstr = (char *) ch_malloc( key.dsize + CONT_SIZE );
-       nids = 0;
-       for ( i = 0; !ID_BLOCK_NOID(idl, i); i++ ) {
-               ldbm_datum_init( data );
-
-               sprintf( kstr, "%c%ld%s", CONT_PREFIX,
-                       ID_BLOCK_ID(idl, i), key.dptr );
-               data.dptr = kstr;
-               data.dsize = strlen( kstr ) + 1;
-
-               if ( (tmp[i] = idl_fetch_one( be, db, data )) == NULL ) {
-                       Debug( LDAP_DEBUG_ANY,
-                           "bdb2i_idl_fetch of (%s) returns NULL\n", data.dptr, 0, 0 );
-                       continue;
-               }
-
-               nids += ID_BLOCK_NIDS(tmp[i]);
-       }
-       tmp[i] = NULL;
-       free( kstr );
-       bdb2i_idl_free( idl );
-
-       /* allocate space for the big block */
-       idl = bdb2i_idl_alloc( nids );
-       ID_BLOCK_NIDS(idl) = nids;
-       nids = 0;
-
-       /* copy in all the ids from the component blocks */
-       for ( i = 0; tmp[i] != NULL; i++ ) {
-               if ( tmp[i] == NULL ) {
-                       continue;
-               }
-
-               SAFEMEMCPY(
-                       (char *) &ID_BLOCK_ID(idl, nids),
-                       (char *) &ID_BLOCK_ID(tmp[i], 0),
-                   ID_BLOCK_NIDS(tmp[i]) * sizeof(ID) );
-               nids += ID_BLOCK_NIDS(tmp[i]);
-
-               bdb2i_idl_free( tmp[i] );
-       }
-       free( (char *) tmp );
-
-       Debug( LDAP_DEBUG_TRACE, "<= bdb2i_idl_fetch %ld ids (%ld max)\n",
-              ID_BLOCK_NIDS(idl), ID_BLOCK_NMAX(idl), 0 );
-       return( idl );
-}
-
-
-/* store a single block */
-static int
-idl_store(
-    BackendDB          *be,
-    struct dbcache     *db,
-    Datum              key, 
-    ID_BLOCK           *idl
-)
-{
-       int     rc, flags;
-       Datum   data;
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-
-       ldbm_datum_init( data );
-
-       /* Debug( LDAP_DEBUG_TRACE, "=> idl_store\n", 0, 0, 0 ); */
-
-       data.dptr = (char *) idl;
-       data.dsize = (ID_BLOCK_IDS_OFFSET + ID_BLOCK_NMAX(idl)) * sizeof(ID);
-       
-#ifdef LDBM_DEBUG
-       Statslog( LDAP_DEBUG_STATS, "<= idl_store(): rc=%d\n",
-               rc, 0, 0, 0, 0 );
-#endif
-
-       flags = LDBM_REPLACE;
-       if( li->li_dbcachewsync ) flags |= LDBM_SYNC;
-       rc = bdb2i_cache_store( db, key, data, flags );
-
-       /* Debug( LDAP_DEBUG_TRACE, "<= idl_store %d\n", rc, 0, 0 ); */
-       return( rc );
-}
-
-
-/* split the block at id
- *    locate ID greater than or equal to id.
- */
-static void
-idl_split_block(
-    ID_BLOCK   *b,
-    ID         id,
-    ID_BLOCK   **right,
-    ID_BLOCK   **left
-)
-{
-       unsigned int    nr, nl;
-
-       /* find where to split the block *//* XXX linear search XXX */
-       for ( nr = 0; nr < ID_BLOCK_NIDS(b) && id > ID_BLOCK_ID(b, nr); nr++ )
-               ;       /* NULL */
-
-       nl = ID_BLOCK_NIDS(b) - nr;
-
-       *right = bdb2i_idl_alloc( nr == 0 ? 1 : nr );
-       *left = bdb2i_idl_alloc( nl + (nr == 0 ? 0 : 1));
-
-       /*
-        * everything before the id being inserted in the first block
-        * unless there is nothing, in which case the id being inserted
-        * goes there.
-        */
-       if ( nr == 0 ) {
-               ID_BLOCK_NIDS(*right) = 1;
-               ID_BLOCK_ID(*right, 0) = id;
-       } else {
-               SAFEMEMCPY(
-                       (char *) &ID_BLOCK_ID(*right, 0),
-                       (char *) &ID_BLOCK_ID(b, 0),
-                       nr * sizeof(ID) );
-               ID_BLOCK_NIDS(*right) = nr;
-               ID_BLOCK_ID(*left, 0) = id;
-       }
-
-       /* the id being inserted & everything after in the second block */
-       SAFEMEMCPY(
-               (char *) &ID_BLOCK_ID(*left, (nr == 0 ? 0 : 1)),
-           (char *) &ID_BLOCK_ID(b, nr),
-               nl * sizeof(ID) );
-       ID_BLOCK_NIDS(*left) = nl + (nr == 0 ? 0 : 1);
-}
-
-
-/*
- * idl_change_first - called when an indirect block's first key has
- * changed, meaning it needs to be stored under a new key, and the
- * header block pointing to it needs updating.
- */
-static int
-idl_change_first(
-    BackendDB          *be,
-    struct dbcache     *db,
-    Datum              hkey,           /* header block key     */
-    ID_BLOCK           *h,             /* header block         */
-    int                        pos,            /* pos in h to update   */
-    Datum              bkey,           /* data block key       */
-    ID_BLOCK           *b              /* data block           */
-)
-{
-       int     rc;
-
-       /* Debug( LDAP_DEBUG_TRACE, "=> idl_change_first\n", 0, 0, 0 ); */
-
-       /* delete old key block */
-       if ( (rc = bdb2i_cache_delete( db, bkey )) != 0 ) {
-               Debug( LDAP_DEBUG_ANY,
-                   "bdb2i_db_delete of (%s) returns %d\n", bkey.dptr, rc,
-                   0 );
-               return( rc );
-       }
-
-       /* write block with new key */
-       sprintf( bkey.dptr, "%c%ld%s", CONT_PREFIX,
-                       ID_BLOCK_ID(b, 0), hkey.dptr );
-       bkey.dsize = strlen( bkey.dptr ) + 1;
-       if ( (rc = idl_store( be, db, bkey, b )) != 0 ) {
-               Debug( LDAP_DEBUG_ANY,
-                   "idl_store of (%s) returns %d\n", bkey.dptr, rc, 0 );
-               return( rc );
-       }
-
-       /* update + write indirect header block */
-       ID_BLOCK_ID(h, pos) = ID_BLOCK_ID(b, 0);
-       if ( (rc = idl_store( be, db, hkey, h )) != 0 ) {
-               Debug( LDAP_DEBUG_ANY,
-                   "idl_store of (%s) returns %d\n", hkey.dptr, rc, 0 );
-               return( rc );
-       }
-
-       return( 0 );
-}
-
-
-int
-bdb2i_idl_insert_key(
-    BackendDB          *be,
-    struct dbcache     *db,
-    Datum              key,
-    ID                 id
-)
-{
-       int     i, j, first, rc;
-       ID_BLOCK        *idl, *tmp, *tmp2, *tmp3;
-       char    *kstr;
-       Datum   k2;
-
-       ldbm_datum_init( k2 );
-
-       if ( (idl = idl_fetch_one( be, db, key )) == NULL ) {
-#ifdef LDBM_DEBUG
-               Statslog( LDAP_DEBUG_STATS, "=> bdb2i_idl_insert_key(): no key yet\n",
-                       0, 0, 0, 0, 0 );
-#endif
-
-               idl = bdb2i_idl_alloc( 1 );
-               ID_BLOCK_ID(idl, ID_BLOCK_NIDS(idl)++) = id;
-               rc = idl_store( be, db, key, idl );
-
-               bdb2i_idl_free( idl );
-               return( rc );
-       }
-
-       if ( ID_BLOCK_ALLIDS( idl ) ) {
-               /* ALLIDS */
-               bdb2i_idl_free( idl );
-               return 0;
-       }
-
-       if ( ! ID_BLOCK_INDIRECT( idl ) ) {
-               /* regular block */
-               switch ( bdb2i_idl_insert( &idl, id, db->dbc_maxids ) ) {
-               case 0:         /* id inserted - store the updated block */
-               case 1:
-                       rc = idl_store( be, db, key, idl );
-                       break;
-
-               case 2:         /* id already there - nothing to do */
-                       rc = 0;
-                       break;
-
-               case 3:         /* id not inserted - block must be split */
-                       /* check threshold for marking this an all-id block */
-                       if ( db->dbc_maxindirect < 2 ) {
-                               bdb2i_idl_free( idl );
-                               idl = bdb2i_idl_allids( be );
-                               rc = idl_store( be, db, key, idl );
-                               break;
-                       }
-
-                       idl_split_block( idl, id, &tmp, &tmp2 );
-                       bdb2i_idl_free( idl );
-
-                       /* create the header indirect block */
-                       idl = bdb2i_idl_alloc( 3 );
-                       ID_BLOCK_NMAX(idl) = 3;
-                       ID_BLOCK_NIDS(idl) = ID_BLOCK_INDIRECT_VALUE;
-                       ID_BLOCK_ID(idl, 0) = ID_BLOCK_ID(tmp, 0);
-                       ID_BLOCK_ID(idl, 1) = ID_BLOCK_ID(tmp2, 0);
-                       ID_BLOCK_ID(idl, 2) = NOID;
-
-                       /* store it */
-                       rc = idl_store( be, db, key, idl );
-
-                       /* store the first id block */
-                       kstr = (char *) ch_malloc( key.dsize + CONT_SIZE );
-                       sprintf( kstr, "%c%ld%s", CONT_PREFIX,
-                           ID_BLOCK_ID(tmp, 0), key.dptr );
-                       k2.dptr = kstr;
-                       k2.dsize = strlen( kstr ) + 1;
-                       rc = idl_store( be, db, k2, tmp );
-
-                       /* store the second id block */
-                       sprintf( kstr, "%c%ld%s", CONT_PREFIX,
-                           ID_BLOCK_ID(tmp2, 0), key.dptr );
-                       k2.dptr = kstr;
-                       k2.dsize = strlen( kstr ) + 1;
-                       rc = idl_store( be, db, k2, tmp2 );
-
-                       free( kstr );
-                       bdb2i_idl_free( tmp );
-                       bdb2i_idl_free( tmp2 );
-                       break;
-               }
-
-               bdb2i_idl_free( idl );
-               return( rc );
-       }
-
-       /*
-        * this is an indirect block which points to other blocks.
-        * we need to read in the block into which the id should be
-        * inserted, then insert the id and store the block.  we might
-        * have to split the block if it is full, which means we also
-        * need to write a new "header" block.
-        */
-
-       /* select the block to try inserting into *//* XXX linear search XXX */
-       for ( i = 0; !ID_BLOCK_NOID(idl, i) && id > ID_BLOCK_ID(idl, i); i++ )
-               ;       /* NULL */
-       if ( i != 0 ) {
-               i--;
-               first = 0;
-       } else {
-               first = 1;
-       }
-
-       /* get the block */
-       kstr = (char *) ch_malloc( key.dsize + CONT_SIZE );
-       sprintf( kstr, "%c%ld%s", CONT_PREFIX,
-               ID_BLOCK_ID(idl, i), key.dptr );
-       k2.dptr = kstr;
-       k2.dsize = strlen( kstr ) + 1;
-       if ( (tmp = idl_fetch_one( be, db, k2 )) == NULL ) {
-               Debug( LDAP_DEBUG_ANY, "nonexistent continuation block (%s)\n",
-                   k2.dptr, 0, 0 );
-               free( kstr );
-               bdb2i_idl_free( idl );
-               return( -1 );
-       }
-
-       /* insert the id */
-       switch ( bdb2i_idl_insert( &tmp, id, db->dbc_maxids ) ) {
-       case 0:         /* id inserted ok */
-               if ( (rc = idl_store( be, db, k2, tmp )) != 0 ) {
-                       Debug( LDAP_DEBUG_ANY,
-                           "idl_store of (%s) returns %d\n", k2.dptr, rc, 0 );
-               }
-               break;
-
-       case 1:         /* id inserted - first id in block has changed */
-               /*
-                * key for this block has changed, so we have to
-                * write the block under the new key, delete the
-                * old key block + update and write the indirect
-                * header block.
-                */
-
-               rc = idl_change_first( be, db, key, idl, i, k2, tmp );
-               break;
-
-       case 2:         /* id not inserted - already there, do nothing */
-               rc = 0;
-               break;
-
-       case 3:         /* id not inserted - block is full */
-               /*
-                * first, see if it will fit in the next block,
-                * without splitting, unless we're trying to insert
-                * into the beginning of the first block.
-                */
-
-               /* is there a next block? */
-               if ( !first && !ID_BLOCK_NOID(idl, i + 1) ) {
-                       /* read it in */
-                       sprintf( kstr, "%c%ld%s", CONT_PREFIX,
-                           ID_BLOCK_ID(idl, i + 1), key.dptr );
-                       k2.dptr = kstr;
-                       k2.dsize = strlen( kstr ) + 1;
-                       if ( (tmp2 = idl_fetch_one( be, db, k2 )) == NULL ) {
-                               Debug( LDAP_DEBUG_ANY,
-                                   "idl_fetch_one (%s) returns NULL\n",
-                                   k2.dptr, 0, 0 );
-                               /* split the original block */
-                               goto split;
-                       }
-
-                       switch ( (rc = bdb2i_idl_insert( &tmp2, id,
-                           db->dbc_maxids )) ) {
-                       case 1:         /* id inserted first in block */
-                               rc = idl_change_first( be, db, key, idl,
-                                   i + 1, k2, tmp2 );
-                               /* FALL */
-
-                       case 2:         /* id already there - how? */
-                       case 0:         /* id inserted */
-                               if ( rc == 2 ) {
-                                       Debug( LDAP_DEBUG_ANY,
-                                           "id %ld already in next block\n",
-                                           id, 0, 0 );
-                               }
-                               free( kstr );
-                               bdb2i_idl_free( tmp );
-                               bdb2i_idl_free( tmp2 );
-                               bdb2i_idl_free( idl );
-                               return( 0 );
-
-                       case 3:         /* split the original block */
-                               break;
-                       }
-
-                       bdb2i_idl_free( tmp2 );
-               }
-
-split:
-               /*
-                * must split the block, write both new blocks + update
-                * and write the indirect header block.
-                */
-
-               rc = 0; /* optimistic */
-
-
-               /* count how many indirect blocks *//* XXX linear count XXX */
-               for ( j = 0; !ID_BLOCK_NOID(idl, j); j++ )
-                       ;       /* NULL */
-
-               /* check it against all-id thresholed */
-               if ( j + 1 > db->dbc_maxindirect ) {
-                       /*
-                        * we've passed the all-id threshold, meaning
-                        * that this set of blocks should be replaced
-                        * by a single "all-id" block.  our job: delete
-                        * all the indirect blocks, and replace the header
-                        * block by an all-id block.
-                        */
-
-                       /* delete all indirect blocks */
-                       for ( j = 0; !ID_BLOCK_NOID(idl, j); j++ ) {
-                               sprintf( kstr, "%c%ld%s", CONT_PREFIX,
-                                   ID_BLOCK_ID(idl, j), key.dptr );
-                               k2.dptr = kstr;
-                               k2.dsize = strlen( kstr ) + 1;
-
-                               rc = bdb2i_cache_delete( db, k2 );
-                       }
-
-                       /* store allid block in place of header block */
-                       bdb2i_idl_free( idl );
-                       idl = bdb2i_idl_allids( be );
-                       rc = idl_store( be, db, key, idl );
-
-                       free( kstr );
-                       bdb2i_idl_free( idl );
-                       bdb2i_idl_free( tmp );
-                       return( rc );
-               }
-
-               idl_split_block( tmp, id, &tmp2, &tmp3 );
-               bdb2i_idl_free( tmp );
-
-               /* create a new updated indirect header block */
-               tmp = bdb2i_idl_alloc( ID_BLOCK_NMAX(idl) + 1 );
-               ID_BLOCK_NIDS(tmp) = ID_BLOCK_INDIRECT_VALUE;
-               /* everything up to the split block */
-               SAFEMEMCPY(
-                       (char *) &ID_BLOCK_ID(tmp, 0),
-                       (char *) &ID_BLOCK_ID(idl, 0),
-                   i * sizeof(ID) );
-               /* the two new blocks */
-               ID_BLOCK_ID(tmp, i) = ID_BLOCK_ID(tmp2, 0);
-               ID_BLOCK_ID(tmp, i + 1) = ID_BLOCK_ID(tmp3, 0);
-               /* everything after the split block */
-               SAFEMEMCPY(
-                       (char *) &ID_BLOCK_ID(tmp, i + 2),
-                       (char *) &ID_BLOCK_ID(idl, i + 1),
-                   (ID_BLOCK_NMAX(idl) - i - 1) * sizeof(ID) );
-
-               /* store the header block */
-               rc = idl_store( be, db, key, tmp );
-
-               /* store the first id block */
-               sprintf( kstr, "%c%ld%s", CONT_PREFIX,
-                   ID_BLOCK_ID(tmp2, 0), key.dptr );
-               k2.dptr = kstr;
-               k2.dsize = strlen( kstr ) + 1;
-               rc = idl_store( be, db, k2, tmp2 );
-
-               /* store the second id block */
-               sprintf( kstr, "%c%ld%s", CONT_PREFIX,
-                   ID_BLOCK_ID(tmp3, 0), key.dptr );
-               k2.dptr = kstr;
-               k2.dsize = strlen( kstr ) + 1;
-               rc = idl_store( be, db, k2, tmp3 );
-
-               bdb2i_idl_free( tmp2 );
-               bdb2i_idl_free( tmp3 );
-               break;
-       }
-
-       free( kstr );
-       bdb2i_idl_free( tmp );
-       bdb2i_idl_free( idl );
-       return( rc );
-}
-
-
-/*
- * bdb2i_idl_insert - insert an id into an id list.
- *
- * returns
- *             0       id inserted
- *             1       id inserted, first id in block has changed
- *             2       id not inserted, already there
- *             3       id not inserted, block must be split
- */
-int
-bdb2i_idl_insert( ID_BLOCK **idl, ID id, unsigned int maxids )
-{
-       unsigned int    i;
-
-       if ( ID_BLOCK_ALLIDS( *idl ) ) {
-               return( 2 );    /* already there */
-       }
-
-       /* is it already there? *//* XXX linear search XXX */
-       for ( i = 0; i < ID_BLOCK_NIDS(*idl) && id > ID_BLOCK_ID(*idl, i); i++ ) {
-               ;       /* NULL */
-       }
-       if ( i < ID_BLOCK_NIDS(*idl) && ID_BLOCK_ID(*idl, i) == id ) {
-               return( 2 );    /* already there */
-       }
-
-       /* do we need to make room for it? */
-       if ( ID_BLOCK_NIDS(*idl) == ID_BLOCK_NMAX(*idl) ) {
-               /* make room or indicate block needs splitting */
-               if ( ID_BLOCK_NMAX(*idl) >= maxids ) {
-                       return( 3 );    /* block needs splitting */
-               }
-
-               ID_BLOCK_NMAX(*idl) *= 2;
-               if ( ID_BLOCK_NMAX(*idl) > maxids ) {
-                       ID_BLOCK_NMAX(*idl) = maxids;
-               }
-               *idl = (ID_BLOCK *) ch_realloc( (char *) *idl,
-                   (ID_BLOCK_NMAX(*idl) + ID_BLOCK_IDS_OFFSET) * sizeof(ID) );
-       }
-
-       /* make a slot for the new id */
-       SAFEMEMCPY( &ID_BLOCK_ID(*idl, i+1), &ID_BLOCK_ID(*idl, i),
-                   (ID_BLOCK_NIDS(*idl) - i) * sizeof(ID) );
-
-       ID_BLOCK_ID(*idl, i) = id;
-       ID_BLOCK_NIDS(*idl)++;
-       (void) memset(
-               (char *) &ID_BLOCK_ID((*idl), ID_BLOCK_NIDS(*idl)),
-               '\0',
-           (ID_BLOCK_NMAX(*idl) - ID_BLOCK_NIDS(*idl)) * sizeof(ID) );
-
-       return( i == 0 ? 1 : 0 );       /* inserted - first id changed or not */
-}
-
-
-int
-bdb2i_idl_delete_key (
-       BackendDB         *be,
-       struct dbcache  *db,
-       Datum           key,
-       ID              id
-)
-{
-       Datum  data;
-       ID_BLOCK *idl, *tmp;
-       unsigned i;
-       int j, nids;
-       char    *kstr;
-
-       if ( (idl = idl_fetch_one( be, db, key ) ) == NULL )
-       {
-               /* It wasn't found.  Hmm... */
-               return -1;
-       }
-
-       if ( ID_BLOCK_ALLIDS( idl ) ) {
-               bdb2i_idl_free( idl );
-               return 0;
-       }
-
-       if ( ! ID_BLOCK_INDIRECT( idl ) ) {
-               for ( i=0; i < ID_BLOCK_NIDS(idl); i++ ) {
-                       if ( ID_BLOCK_ID(idl, i) == id ) {
-                               if( --ID_BLOCK_NIDS(idl) == 0 ) {
-                                       bdb2i_cache_delete( db, key );
-
-                               } else {
-                                       SAFEMEMCPY (
-                                               &ID_BLOCK_ID(idl, i),
-                                               &ID_BLOCK_ID(idl, i+1),
-                                               (ID_BLOCK_NIDS(idl)-i) * sizeof(ID) );
-
-                                       ID_BLOCK_ID(idl, ID_BLOCK_NIDS(idl)) = NOID;
-
-                                       idl_store( be, db, key, idl );
-                               }
-
-                               bdb2i_idl_free( idl );
-                               return 0;
-                       }
-                       /*  We didn't find the ID.  Hmmm... */
-               }
-               bdb2i_idl_free( idl );
-               return -1;
-       }
-       
-       /* We have to go through an indirect block and find the ID
-          in the list of IDL's
-          */
-       for ( nids = 0; !ID_BLOCK_NOID(idl, nids); nids++ )
-               ;       /* NULL */
-       kstr = (char *) ch_malloc( key.dsize + CONT_SIZE );
-       for ( j = 0; !ID_BLOCK_NOID(idl, j); j++ )
-       {
-               ldbm_datum_init( data );
-               sprintf( kstr, "%c%ld%s", CONT_PREFIX, ID_BLOCK_ID(idl, j), key.dptr );
-               data.dptr = kstr;
-               data.dsize = strlen( kstr ) + 1;
-
-               if ( (tmp = idl_fetch_one( be, db, data )) == NULL ) {
-                       Debug( LDAP_DEBUG_ANY,
-                           "bdb2i_idl_fetch of (%s) returns NULL\n", data.dptr, 0, 0 );
-                       continue;
-               }
-               /*
-                  Now try to find the ID in tmp
-               */
-               for ( i=0; i < ID_BLOCK_NIDS(tmp); i++ )
-               {
-                       if ( ID_BLOCK_ID(tmp, i) == id )
-                       {
-                               SAFEMEMCPY(
-                                       &ID_BLOCK_ID(tmp, i),
-                                       &ID_BLOCK_ID(tmp, i+1),
-                                       (ID_BLOCK_NIDS(tmp)-(i+1)) * sizeof(ID));
-                               ID_BLOCK_ID(tmp, ID_BLOCK_NIDS(tmp)-1 ) = NOID;
-                               ID_BLOCK_NIDS(tmp)--;
-
-                               if ( ID_BLOCK_NIDS(tmp) ) {
-                                       idl_store ( be, db, data, tmp );
-
-                               } else {
-                                       bdb2i_cache_delete( db, data );
-                                       SAFEMEMCPY(
-                                               &ID_BLOCK_ID(idl, j),
-                                               &ID_BLOCK_ID(idl, j+1),
-                                               (nids-(j+1)) * sizeof(ID));
-                                       ID_BLOCK_ID(idl, nids-1) = NOID;
-                                       nids--;
-                                       if ( ! nids )
-                                               bdb2i_cache_delete( db, key );
-                                       else
-                                               idl_store( be, db, key, idl );
-                               }
-                               bdb2i_idl_free( tmp );
-                               free( kstr );
-                               bdb2i_idl_free( idl );
-                               return 0;
-                       }
-               }
-               bdb2i_idl_free( tmp );
-       }
-       free( kstr );
-       bdb2i_idl_free( idl );
-       return -1;
-}
-
-
-/* return a duplicate of a single ID_BLOCK */
-static ID_BLOCK *
-idl_dup( ID_BLOCK *idl )
-{
-       ID_BLOCK        *new;
-
-       if ( idl == NULL ) {
-               return( NULL );
-       }
-
-       new = bdb2i_idl_alloc( ID_BLOCK_NMAX(idl) );
-       SAFEMEMCPY(
-               (char *) new,
-               (char *) idl,
-               (ID_BLOCK_NMAX(idl) + ID_BLOCK_IDS_OFFSET) * sizeof(ID) );
-
-       return( new );
-}
-
-
-/* return the smaller ID_BLOCK */
-static ID_BLOCK *
-idl_min( ID_BLOCK *a, ID_BLOCK *b )
-{
-       return( ID_BLOCK_NIDS(a) > ID_BLOCK_NIDS(b) ? b : a );
-}
-
-
-/*
- * bdb2i_idl_intersection - return a intersection b
- */
-ID_BLOCK *
-bdb2i_idl_intersection(
-    BackendDB  *be,
-    ID_BLOCK   *a,
-    ID_BLOCK   *b
-)
-{
-       unsigned int    ai, bi, ni;
-       ID_BLOCK                *n;
-
-       if ( a == NULL || b == NULL ) {
-               return( NULL );
-       }
-       if ( ID_BLOCK_ALLIDS( a ) ) {
-               return( idl_dup( b ) );
-       }
-       if ( ID_BLOCK_ALLIDS( b ) ) {
-               return( idl_dup( a ) );
-       }
-
-       n = idl_dup( idl_min( a, b ) );
-
-       for ( ni = 0, ai = 0, bi = 0; ai < ID_BLOCK_NIDS(a); ai++ ) {
-               for ( ;
-                       bi < ID_BLOCK_NIDS(b) && ID_BLOCK_ID(b, bi) < ID_BLOCK_ID(a, ai);
-                       bi++ )
-               {
-                       ;       /* NULL */
-               }
-
-               if ( bi == ID_BLOCK_NIDS(b) ) {
-                       break;
-               }
-
-               if ( ID_BLOCK_ID(b, bi) == ID_BLOCK_ID(a, ai) ) {
-                       ID_BLOCK_ID(n, ni++) = ID_BLOCK_ID(a, ai);
-               }
-       }
-
-       if ( ni == 0 ) {
-               bdb2i_idl_free( n );
-               return( NULL );
-       }
-       ID_BLOCK_NIDS(n) = ni;
-
-       return( n );
-}
-
-
-/*
- * bdb2i_idl_union - return a union b
- */
-ID_BLOCK *
-bdb2i_idl_union(
-    BackendDB  *be,
-    ID_BLOCK   *a,
-    ID_BLOCK   *b
-)
-{
-       unsigned int    ai, bi, ni;
-       ID_BLOCK                *n;
-
-       if ( a == NULL ) {
-               return( idl_dup( b ) );
-       }
-       if ( b == NULL ) {
-               return( idl_dup( a ) );
-       }
-       if ( ID_BLOCK_ALLIDS( a ) || ID_BLOCK_ALLIDS( b ) ) {
-               return( bdb2i_idl_allids( be ) );
-       }
-
-       if ( ID_BLOCK_NIDS(b) < ID_BLOCK_NIDS(a) ) {
-               n = a;
-               a = b;
-               b = n;
-       }
-
-       n = bdb2i_idl_alloc( ID_BLOCK_NIDS(a) + ID_BLOCK_NIDS(b) );
-
-       for ( ni = 0, ai = 0, bi = 0;
-               ai < ID_BLOCK_NIDS(a) && bi < ID_BLOCK_NIDS(b);
-               )
-       {
-               if ( ID_BLOCK_ID(a, ai) < ID_BLOCK_ID(b, bi) ) {
-                       ID_BLOCK_ID(n, ni++) = ID_BLOCK_ID(a, ai++);
-
-               } else if ( ID_BLOCK_ID(b, bi) < ID_BLOCK_ID(a, ai) ) {
-                       ID_BLOCK_ID(n, ni++) = ID_BLOCK_ID(b, bi++);
-
-               } else {
-                       ID_BLOCK_ID(n, ni++) = ID_BLOCK_ID(a, ai);
-                       ai++, bi++;
-               }
-       }
-
-       for ( ; ai < ID_BLOCK_NIDS(a); ai++ ) {
-               ID_BLOCK_ID(n, ni++) = ID_BLOCK_ID(a, ai);
-       }
-       for ( ; bi < ID_BLOCK_NIDS(b); bi++ ) {
-               ID_BLOCK_ID(n, ni++) = ID_BLOCK_ID(b, bi);
-       }
-       ID_BLOCK_NIDS(n) = ni;
-
-       return( n );
-}
-
-
-/*
- * bdb2i_idl_notin - return a intersection ~b (or a minus b)
- */
-ID_BLOCK *
-bdb2i_idl_notin(
-    BackendDB  *be,
-    ID_BLOCK   *a,
-    ID_BLOCK   *b
-)
-{
-       unsigned int    ni, ai, bi;
-       ID_BLOCK                *n;
-
-       if ( a == NULL ) {
-               return( NULL );
-       }
-       if ( b == NULL || ID_BLOCK_ALLIDS( b )) {
-               return( idl_dup( a ) );
-       }
-
-       if ( ID_BLOCK_ALLIDS( a ) ) {
-               n = bdb2i_idl_alloc( SLAPD_LDBM_MIN_MAXIDS );
-               ni = 0;
-
-               for ( ai = 1, bi = 0;
-                       ai < ID_BLOCK_NIDS(a) && ni < ID_BLOCK_NMAX(n) && bi < ID_BLOCK_NMAX(b);
-                       ai++ )
-               {
-                       if ( ID_BLOCK_ID(b, bi) == ai ) {
-                               bi++;
-                       } else {
-                               ID_BLOCK_ID(n, ni++) = ai;
-                       }
-               }
-
-               for ( ; ai < ID_BLOCK_NIDS(a) && ni < ID_BLOCK_NMAX(n); ai++ ) {
-                       ID_BLOCK_ID(n, ni++) = ai;
-               }
-
-               if ( ni == ID_BLOCK_NMAX(n) ) {
-                       bdb2i_idl_free( n );
-                       return( bdb2i_idl_allids( be ) );
-               } else {
-                       ID_BLOCK_NIDS(n) = ni;
-                       return( n );
-               }
-       }
-
-       n = idl_dup( a );
-
-       ni = 0;
-       for ( ai = 0, bi = 0; ai < ID_BLOCK_NIDS(a); ai++ ) {
-               for ( ;
-                       bi < ID_BLOCK_NIDS(b) && ID_BLOCK_ID(b, bi) < ID_BLOCK_ID(a, ai);
-                   bi++ )
-               {
-                       ;       /* NULL */
-               }
-
-               if ( bi == ID_BLOCK_NIDS(b) ) {
-                       break;
-               }
-
-               if ( ID_BLOCK_ID(b, bi) != ID_BLOCK_ID(a, ai) ) {
-                       ID_BLOCK_ID(n, ni++) = ID_BLOCK_ID(a, ai);
-               }
-       }
-
-       for ( ; ai < ID_BLOCK_NIDS(a); ai++ ) {
-               ID_BLOCK_ID(n, ni++) = ID_BLOCK_ID(a, ai);
-       }
-       ID_BLOCK_NIDS(n) = ni;
-
-       return( n );
-}
-
-
-/*     return the first ID in the block
- *     if ALLIDS block
- *             NIDS > 1 return 1
- *             otherwise return NOID 
- *     otherwise return first ID
- *
- *  cursor is set to 1
- */         
-ID
-bdb2i_idl_firstid( ID_BLOCK *idl, ID *cursor )
-{
-       *cursor = 1;
-
-       if ( idl == NULL || ID_BLOCK_NIDS(idl) == 0 ) {
-               return( NOID );
-       }
-
-       if ( ID_BLOCK_ALLIDS( idl ) ) { 
-               return( ID_BLOCK_NIDS(idl) > 1 ? 1 : NOID );
-       }
-
-       return( ID_BLOCK_ID(idl, 0) );
-}
-
-
-/*     return next ID after id
- *     if ALLIDS block, cursor is id
- *             increment id
- *             if id < NIDS return id
- *             otherwise NOID.
- *     otherwise cursor is index into block
- *             if index < nids
- *                     return id at index then increment
- */ 
-ID
-bdb2i_idl_nextid( ID_BLOCK *idl, ID *cursor )
-{
-       if ( ID_BLOCK_ALLIDS( idl ) ) {
-               if( ++(*cursor) < ID_BLOCK_NIDS(idl) ) {
-                       return *cursor;
-               } else {
-                       return NOID;
-               }
-       }
-
-       if ( *cursor < ID_BLOCK_NIDS(idl) ) {
-               return ID_BLOCK_ID(idl, (*cursor)++);
-       }
-       return NOID;
-}
diff --git a/servers/slapd/back-bdb2/index.c b/servers/slapd/back-bdb2/index.c
deleted file mode 100644 (file)
index 6ef1ca2..0000000
+++ /dev/null
@@ -1,379 +0,0 @@
-/* index.c - routines for dealing with attribute indexes */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-
-static int     add_value(BackendDB *be, struct dbcache *db, char *type, int indextype, char *val, ID id);
-static int     index2prefix(int indextype);
-
-int
-bdb2i_index_add_entry(
-    BackendDB  *be,
-    Entry      *e
-)
-{
-       Attribute       *ap;
-       struct berval   bv;
-       struct berval   *bvals[2];
-
-       Debug( LDAP_DEBUG_TRACE, "=> index_add( %ld, \"%s\" )\n", e->e_id,
-           e->e_dn, 0 );
-
-       /*
-        * dn index entry - make it look like an attribute so it works
-        * with bdb2i_index_add_values() call
-        */
-
-       bv.bv_val = ch_strdup( e->e_ndn );
-       bv.bv_len = strlen( bv.bv_val );
-       bvals[0] = &bv;
-       bvals[1] = NULL;
-
-       /* add the dn to the indexes */
-       {
-               char *dn = ch_strdup( "dn" );
-               bdb2i_index_add_values( be, dn, bvals, e->e_id );
-               free( dn );
-       }
-
-       free( bv.bv_val );
-
-       /* add each attribute to the indexes */
-       for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) {
-               bdb2i_index_add_values( be, ap->a_type, ap->a_vals, e->e_id );
-       }
-
-       Debug( LDAP_DEBUG_TRACE, "<= index_add( %ld, \"%s\" ) 0\n", e->e_id,
-           e->e_ndn, 0 );
-       return( 0 );
-}
-
-int
-bdb2i_index_add_mods(
-    BackendDB  *be,
-    LDAPModList        *ml,
-    ID         id
-)
-{
-       int     rc;
-
-       for ( ; ml != NULL; ml = ml->ml_next ) {
-               LDAPMod *mod = &ml->ml_mod;
-
-               switch ( mod->mod_op & ~LDAP_MOD_BVALUES ) {
-               case LDAP_MOD_ADD:
-               case LDAP_MOD_REPLACE:
-                       rc = bdb2i_index_add_values( be, mod->mod_type,
-                           mod->mod_bvalues, id );
-                       break;
-               case LDAP_MOD_SOFTADD:
-               case LDAP_MOD_DELETE:
-                       rc = 0;
-                       break;
-               }
-
-               if ( rc != 0 ) {
-                       return( rc );
-               }
-       }
-
-       return( 0 );
-}
-
-ID_BLOCK *
-bdb2i_index_read(
-    BackendDB  *be,
-    char       *type,
-    int                indextype,
-    char       *val
-)
-{
-       struct dbcache  *db;
-       Datum           key;
-       ID_BLOCK                *idl;
-       int             indexmask, syntax;
-       char            prefix;
-       char            *realval, *tmpval;
-       char            buf[BUFSIZ];
-
-       char            *at_cn;
-
-       ldbm_datum_init( key );
-
-       prefix = index2prefix( indextype );
-       Debug( LDAP_DEBUG_TRACE, "=> bdb2i_index_read( \"%c%s\" -> \"%s\" )\n",
-           prefix, type, val );
-
-       bdb2i_attr_masks( be->be_private, type, &indexmask, &syntax );
-       if ( ! (indextype & indexmask) ) {
-               idl =  bdb2i_idl_allids( be );
-               Debug( LDAP_DEBUG_TRACE,
-                   "<= bdb2i_index_read %ld candidates (allids - not indexed)\n",
-                   idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
-               return( idl );
-       }
-
-       attr_normalize( type );
-       at_cn = at_canonical_name(type);
-
-       if ( (db = bdb2i_cache_open( be, at_cn, BDB2_SUFFIX, LDBM_WRCREAT ))
-           == NULL ) {
-               Debug( LDAP_DEBUG_ANY,
-                   "<= bdb2i_index_read NULL (could not open %s%s)\n", at_cn,
-                   BDB2_SUFFIX, 0 );
-               return( NULL );
-       }
-
-       realval = val;
-       tmpval = NULL;
-       if ( prefix != UNKNOWN_PREFIX ) {
-        unsigned int   len = strlen( val );
-
-        if ( (len + 2) < sizeof(buf) ) {
-                       realval = buf;
-               } else {
-                       /* value + prefix + null */
-                       tmpval = (char *) ch_malloc( len + 2 );
-                       realval = tmpval;
-               }
-
-        realval[0] = prefix;
-        strcpy( &realval[1], val );
-       }
-
-       key.dptr = realval;
-       key.dsize = strlen( realval ) + 1;
-
-       idl = bdb2i_idl_fetch( be, db, key );
-    if ( tmpval != NULL ) {
-        free( tmpval );
-    }
-
-       bdb2i_cache_close( be, db );
-
-       Debug( LDAP_DEBUG_TRACE, "<= bdb2i_index_read %ld candidates\n",
-           idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
-       return( idl );
-}
-
-static int
-add_value(
-    BackendDB          *be,
-    struct dbcache     *db,
-    char               *type,
-    int                        indextype,
-    char               *val,
-    ID                 id
-)
-{
-       int     rc;
-       Datum   key;
-       char    *tmpval = NULL;
-       char    *realval = val;
-       char    buf[BUFSIZ];
-
-       char    prefix = index2prefix( indextype );
-
-       ldbm_datum_init( key );
-
-       Debug( LDAP_DEBUG_TRACE, "=> add_value( \"%c%s\" )\n", prefix, val, 0 );
-
-       if ( prefix != UNKNOWN_PREFIX ) {
-        unsigned int     len = strlen( val );
-
-        if ( (len + 2) < sizeof(buf) ) {
-                       realval = buf;
-               } else {
-                       /* value + prefix + null */
-                       tmpval = (char *) ch_malloc( len + 2 );
-                       realval = tmpval;
-               }
-        realval[0] = prefix;
-        strcpy( &realval[1], val );
-       }
-
-       key.dptr = realval;
-       key.dsize = strlen( realval ) + 1;
-
-       rc = bdb2i_idl_insert_key( be, db, key, id );
-
-       if ( tmpval != NULL ) {
-               free( tmpval );
-       }
-
-       ldap_pvt_thread_yield();
-
-       /* Debug( LDAP_DEBUG_TRACE, "<= add_value %d\n", rc, 0, 0 ); */
-       return( rc );
-}
-
-int
-bdb2i_index_add_values(
-    BackendDB          *be,
-    char               *type,
-    struct berval      **vals,
-    ID                 id
-)
-{
-       char            *val, *p, *code, *w;
-       unsigned        i, j, len;
-       int             indexmask, syntax;
-       char            buf[SUBLEN + 1];
-       char            vbuf[BUFSIZ];
-       char            *bigbuf;
-       struct dbcache  *db;
-
-       char            *at_cn;
-
-       if( vals == NULL ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "=> bdb2i_index_add_values( \"%s\", NULL, %ld )\n",
-                       type, id, 0 );
-               return 0;
-       }
-
-       Debug( LDAP_DEBUG_TRACE, "=> bdb2i_index_add_values( \"%s\", %ld )\n",
-               type, id, 0 );
-       attr_normalize( type );
-       bdb2i_attr_masks( be->be_private, type, &indexmask, &syntax );
-       if ( indexmask == 0 ) {
-               return( 0 );
-       }
-       at_cn = at_canonical_name(type);
-
-       if ( (db = bdb2i_cache_open( be, at_cn, BDB2_SUFFIX, LDBM_WRCREAT ))
-           == NULL ) {
-               Debug( LDAP_DEBUG_ANY,
-                   "<= bdb2i_index_add_values -1 (could not open/create %s%s)\n",
-                   at_cn, BDB2_SUFFIX, 0 );
-               return( -1 );
-       }
-
-       for ( i = 0; vals[i] != NULL; i++ ) {
-               /*
-                * presence index entry
-                */
-               if ( indexmask & INDEX_PRESENCE ) {
-                       add_value( be, db, at_cn, INDEX_PRESENCE, "*", id );
-               }
-
-               Debug( LDAP_DEBUG_TRACE, "*** bdb2i_index_add_values syntax 0x%x syntax bin 0x%x\n",
-                   syntax, SYNTAX_BIN, 0 );
-               if ( syntax & SYNTAX_BIN ) {
-                       bdb2i_cache_close( be, db );
-                       return( 0 );
-               }
-
-               bigbuf = NULL;
-               len = vals[i]->bv_len;
-
-               /* value + null */
-               if ( len + 2 > sizeof(vbuf) ) {
-                       bigbuf = (char *) ch_malloc( len + 1 );
-                       val = bigbuf;
-               } else {
-                       val = vbuf;
-               }
-               (void) memcpy( val, vals[i]->bv_val, len );
-               val[len] = '\0';
-
-               value_normalize( val, syntax );
-
-               /* value_normalize could change the length of val */
-               len = strlen( val );
-
-               /*
-                * equality index entry
-                */
-               if ( indexmask & INDEX_EQUALITY ) {
-                       add_value( be, db, at_cn, INDEX_EQUALITY, val, id );
-               }
-
-               /*
-                * approximate index entry
-                */
-               if ( indexmask & INDEX_APPROX ) {
-                       for ( w = first_word( val ); w != NULL;
-                           w = next_word( w ) ) {
-                               if ( (code = phonetic( w )) != NULL ) {
-                                       add_value( be, db, at_cn, INDEX_APPROX,
-                                           code, id );
-                                       free( code );
-                               }
-                       }
-               }
-
-               /*
-                * substrings index entry
-                */
-               if ( indexmask & INDEX_SUB ) {
-                       /* leading and trailing */
-                       if ( len > SUBLEN - 2 ) {
-                               buf[0] = '^';
-                               for ( j = 0; j < SUBLEN - 1; j++ ) {
-                                       buf[j + 1] = val[j];
-                               }
-                               buf[SUBLEN] = '\0';
-
-                               add_value( be, db, at_cn, INDEX_SUB, buf, id );
-
-                               p = val + len - SUBLEN + 1;
-                               for ( j = 0; j < SUBLEN - 1; j++ ) {
-                                       buf[j] = p[j];
-                               }
-                               buf[SUBLEN - 1] = '$';
-                               buf[SUBLEN] = '\0';
-
-                               add_value( be, db, at_cn, INDEX_SUB, buf, id );
-                       }
-
-                       /* any */
-                       for ( p = val; p < (val + len - SUBLEN + 1); p++ ) {
-                               for ( j = 0; j < SUBLEN; j++ ) {
-                                       buf[j] = p[j];
-                               }
-                               buf[SUBLEN] = '\0';
-
-                               add_value( be, db, at_cn, INDEX_SUB, buf, id );
-                       }
-               }
-
-               if ( bigbuf != NULL ) {
-                       free( bigbuf );
-               }
-       }
-       bdb2i_cache_close( be, db );
-
-       return( 0 );
-}
-
-static int
-index2prefix( int indextype )
-{
-       int     prefix;
-
-       switch ( indextype ) {
-       case INDEX_EQUALITY:
-               prefix = EQ_PREFIX;
-               break;
-       case INDEX_APPROX:
-               prefix = APPROX_PREFIX;
-               break;
-       case INDEX_SUB:
-               prefix = SUB_PREFIX;
-               break;
-       default:
-               prefix = UNKNOWN_PREFIX;
-               break;
-       }
-
-       return( prefix );
-}
diff --git a/servers/slapd/back-bdb2/init.c b/servers/slapd/back-bdb2/init.c
deleted file mode 100644 (file)
index 0eb5080..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-/* init.c - initialize bdb2 backend */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-
-#ifdef SLAPD_BDB2_DYNAMIC
-
-int back_bdb2_LTX_init_module(int argc, char *argv[]) {
-    BackendInfo bi;
-
-    memset( &bi, 0, sizeof(bi) );
-    bi.bi_type = "bdb2";
-    bi.bi_init = bdb2_back_initialize;
-
-    backend_add(&bi);
-    return 0;
-}
-
-#endif /* SLAPD_BDB2_DYNAMIC */
-
-static int
-bdb2i_back_init_private(
-    BackendInfo        *bi
-)
-{
-       struct ldbtype  *bt;
-
-       /*  allocate backend-type-specific stuff */
-       bt = (struct ldbtype *) ch_calloc( 1, sizeof(struct ldbtype) );
-
-       bt->lty_dbhome = DEFAULT_DB_HOME;
-       bt->lty_mpsize = DEFAULT_DBCACHE_SIZE;
-
-       if ( slapMode & SLAP_TIMED_MODE )
-               bt->lty_betiming = 1;
-
-       bi->bi_private = bt;
-
-       return 0;
-}
-
-
-int
-bdb2_back_initialize(
-    BackendInfo        *bi
-)
-{
-       int  ret;
-
-       bi->bi_open = bdb2_back_open;
-       bi->bi_config = bdb2_back_config;
-       bi->bi_close = bdb2_back_close;
-       bi->bi_destroy = bdb2_back_destroy;
-
-       bi->bi_db_init = bdb2_back_db_init;
-       bi->bi_db_config = bdb2_back_db_config;
-       bi->bi_db_open = bdb2_back_db_open;
-       bi->bi_db_close = bdb2_back_db_close;
-       bi->bi_db_destroy = bdb2_back_db_destroy;
-
-       bi->bi_op_bind = bdb2_back_bind;
-       bi->bi_op_unbind = bdb2_back_unbind;
-       bi->bi_op_search = bdb2_back_search;
-       bi->bi_op_compare = bdb2_back_compare;
-       bi->bi_op_modify = bdb2_back_modify;
-       bi->bi_op_modrdn = bdb2_back_modrdn;
-       bi->bi_op_add = bdb2_back_add;
-       bi->bi_op_delete = bdb2_back_delete;
-       bi->bi_op_abandon = bdb2_back_abandon;
-
-       bi->bi_entry_release_rw = bdb2_back_entry_release_rw;
-       bi->bi_acl_group = bdb2_back_group;
-
-       /*
-        * hooks for slap tools
-        */
-       bi->bi_tool_entry_open = bdb2_tool_entry_open;
-       bi->bi_tool_entry_close = bdb2_tool_entry_close;
-       bi->bi_tool_entry_first = bdb2_tool_entry_first;
-       bi->bi_tool_entry_next = bdb2_tool_entry_next;
-       bi->bi_tool_entry_get = bdb2_tool_entry_get;
-       bi->bi_tool_entry_put = bdb2_tool_entry_put;
-       bi->bi_tool_index_attr = bdb2_tool_index_attr;
-       bi->bi_tool_index_change = bdb2_tool_index_change;
-       bi->bi_tool_sync = bdb2_tool_sync;
-
-       bi->bi_connection_init = 0;
-       bi->bi_connection_destroy = 0;
-
-       ret = bdb2i_back_init_private( bi );
-
-       Debug( LDAP_DEBUG_TRACE, "bdb2_back_initialize: done (%d).\n", ret, 0, 0 );
-
-       return( ret );
-}
-
-int
-bdb2_back_destroy(
-    BackendInfo        *bi
-)
-{
-       return 0;
-}
-
-int
-bdb2_back_open(
-    BackendInfo        *bi
-)
-{
-       static int initialized = 0;
-       int rc;
-
-       if ( initialized++ ) {
-
-               Debug( LDAP_DEBUG_TRACE,
-                               "bdb2_back_open: backend already initialized.\n", 0, 0, 0 );
-               return 0;
-
-       }
-
-       /* initialize the underlying database system */
-       rc = bdb2i_back_startup( bi );
-
-       return rc;
-}
-
-int
-bdb2_back_close(
-    BackendInfo        *bi
-)
-{
-       int  rc;
-
-       /* close the underlying database system */
-       rc = bdb2i_back_shutdown( bi );
-
-       return rc;
-}
-
-/*  BDB2 changed  */
-static int
-bdb2i_back_db_init_internal(
-    BackendDB  *be
-)
-{
-       struct ldbminfo *li;
-       char            *argv[ 4 ];
-
-       /* allocate backend-database-specific stuff */
-       li = (struct ldbminfo *) ch_calloc( 1, sizeof(struct ldbminfo) );
-
-       /* arrange to read nextid later (on first request for it) */
-       li->li_nextid = NOID;
-#if    SLAPD_NEXTID_CHUNK > 1
-       li->li_nextid_wrote = NOID;
-#endif
-
-       /* default cache size */
-       li->li_cache.c_maxsize = DEFAULT_CACHE_SIZE;
-
-       /* default database cache size */
-       li->li_dbcachesize = DEFAULT_DBCACHE_SIZE;
-
-       /* default cache mode is sync on write */
-       li->li_dbcachewsync = 1;
-
-       /* default file creation mode */
-       li->li_mode = DEFAULT_MODE;
-
-       /* default database directory */
-       li->li_directory = DEFAULT_DB_DIRECTORY;
-
-       argv[ 0 ] = "objectclass";
-       argv[ 1 ] = "pres,eq";
-       argv[ 2 ] = NULL;
-       bdb2i_attr_index_config( li, "ldbm objectclass initialization",
-               0, 2, argv, 1 );
-
-       /*  initialize the cache mutex */
-       ldap_pvt_thread_mutex_init( &li->li_cache.c_mutex );
-
-       /*  initialize the TP file head  */
-       if ( bdb2i_txn_head_init( &li->li_txn_head ) != 0 )
-               return 1;
-
-       be->be_private = li;
-
-       return 0;
-}
-
-
-int
-bdb2_back_db_init(
-    BackendDB  *be
-)
-{
-       struct timeval  time1;
-       int             ret;
-
-       bdb2i_start_timing( be->bd_info, &time1 );
-
-       ret = bdb2i_back_db_init_internal( be );
-       bdb2i_stop_timing( be->bd_info, time1, "DB-INIT", NULL, NULL );
-
-       return( ret );
-}
-
-
-int
-bdb2_back_db_open(
-    BackendDB  *be
-)
-{
-       int  rc;
-
-       rc = bdb2_back_db_startup( be );
-
-       return( rc );
-}
-
-int
-bdb2_back_db_destroy(
-    BackendDB  *be
-)
-{
-       /* should free/destroy every in be_private */
-       free( be->be_private );
-       be->be_private = NULL;
-       return 0;
-}
-
-
diff --git a/servers/slapd/back-bdb2/kerberos.c b/servers/slapd/back-bdb2/kerberos.c
deleted file mode 100644 (file)
index 61a9db0..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/* kerberos.c - bdb2 backend kerberos bind routines */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#ifdef HAVE_KERBEROS
-
-#include <stdio.h>
-
-#include <ac/krb.h>
-#include <ac/socket.h>
-#include <ac/string.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-
-#define LDAP_KRB_PRINCIPAL     "ldapserver"
-
-extern char            *ldap_srvtab;
-extern Attribute       *attr_find();
-
-bdb2i_krbv4_ldap_auth(
-    BackendDB          *be,
-    struct berval      *cred,
-    AUTH_DAT           *ad
-)
-{
-       KTEXT_ST        k;
-       KTEXT           ktxt = &k;
-       char            instance[INST_SZ];
-       int             err;
-
-       Debug( LDAP_DEBUG_TRACE, "=> kerberosv4_ldap_auth\n", 0, 0, 0 );
-
-       SAFEMEMCPY( ktxt->dat, cred->bv_val, cred->bv_len );
-       ktxt->length = cred->bv_len;
-
-       strcpy( instance, "*" );
-       if ( (err = krb_rd_req( ktxt, LDAP_KRB_PRINCIPAL, instance, 0L, ad,
-           ldap_srvtab )) != KSUCCESS ) {
-               Debug( LDAP_DEBUG_ANY, "krb_rd_req failed (%s)\n",
-                   krb_err_txt[err], 0, 0 );
-               return( LDAP_INVALID_CREDENTIALS );
-       }
-
-       return( LDAP_SUCCESS );
-}
-
-#endif /* kerberos */
diff --git a/servers/slapd/back-bdb2/modify.c b/servers/slapd/back-bdb2/modify.c
deleted file mode 100644 (file)
index 817d3ba..0000000
+++ /dev/null
@@ -1,323 +0,0 @@
-/* modify.c - bdb2 backend modify routine */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-#include "proto-back-bdb2.h"
-
-int
-bdb2i_back_modify_internal(
-    BackendDB  *be,
-    Connection *conn,
-    Operation  *op,
-    char       *dn,
-    LDAPModList        *modlist,
-    Entry       *e
-)
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       LDAPModList     *ml;
-       int             err;
-
-       Debug(LDAP_DEBUG_ARGS, "bdb2i_back_modify:\n", 0, 0, 0);
-
-       if ( (err = acl_check_modlist( be, conn, op, e, modlist )) != LDAP_SUCCESS ) {
-               send_ldap_result( conn, op, err,
-                       NULL, NULL, NULL, NULL );
-               goto error_return;
-       }
-
-       for ( ml = modlist; ml != NULL; ml = ml->ml_next ) {
-               LDAPMod *mod = &ml->ml_mod;
-
-               switch ( mod->mod_op & ~LDAP_MOD_BVALUES ) {
-               case LDAP_MOD_ADD:
-                       err = bdb2i_add_values( e, mod, op->o_ndn );
-                       break;
-
-               case LDAP_MOD_DELETE:
-                       err = bdb2i_delete_values( e, mod, op->o_ndn );
-                       break;
-
-               case LDAP_MOD_REPLACE:
-                       err = bdb2i_replace_values( e, mod, op->o_ndn );
-                       break;
-               
-               case LDAP_MOD_SOFTADD:
-                       /* Avoid problems in index_add_mods()
-                        * We need to add index if necessary.
-                        */
-                       mod->mod_op = LDAP_MOD_ADD;
-                       if ( (err = bdb2i_add_values( e, mod, op->o_ndn ))
-                               ==  LDAP_TYPE_OR_VALUE_EXISTS ) {
-                               err = LDAP_SUCCESS;
-                               mod->mod_op = LDAP_MOD_SOFTADD;
-                       }
-                       break;
-               }
-
-               if ( err != LDAP_SUCCESS ) {
-                       /* unlock entry, delete from cache */
-                       send_ldap_result( conn, op, err,
-                               NULL, NULL, NULL, NULL );
-                       goto error_return;
-               }
-       }
-
-       /* check that the entry still obeys the schema */
-       if ( global_schemacheck && oc_schema_check( e ) != 0 ) {
-               Debug( LDAP_DEBUG_ANY, "entry failed schema check\n", 0, 0, 0 );
-               send_ldap_result( conn, op, LDAP_OBJECT_CLASS_VIOLATION,
-                       NULL, NULL, NULL, NULL );
-               goto error_return;
-       }
-
-       /* check for abandon */
-       ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
-       if ( op->o_abandon ) {
-               ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
-               goto error_return;
-       }
-       ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
-
-       /* modify indexes */
-       if ( bdb2i_index_add_mods( be, modlist, e->e_id ) != 0 ) {
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-               goto error_return;
-       }
-
-       /* check for abandon */
-       ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
-       if ( op->o_abandon ) {
-               ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
-               goto error_return;
-       }
-       ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
-
-       /* change the entry itself */
-       if ( bdb2i_id2entry_add( be, e ) != 0 ) {
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-               goto error_return;
-       }
-
-       send_ldap_result( conn, op, LDAP_SUCCESS,
-               NULL, NULL, NULL, NULL );
-       return( 0 );
-
-error_return:;
-       return( -1 );
-}
-
-
-int
-bdb2_back_modify(
-    BackendDB  *be,
-    Connection *conn,
-    Operation  *op,
-    char       *dn,
-    LDAPModList        *modlist
-)
-{
-       DB_LOCK         lock;
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       struct timeval  time1;
-       int             ret, manageDSAit;
-       Entry           *matched;
-       Entry           *e;
-
-       bdb2i_start_timing( be->bd_info, &time1 );
-
-       if ( bdb2i_enter_backend_w( &lock ) != 0 ) {
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-               return( -1 );
-       }
-
-       /*  check, if a new default attribute index will be created,
-               in which case we have to open the index file BEFORE TP  */
-       switch ( slapMode & SLAP_MODE ) {
-               case SLAP_SERVER_MODE:
-               case SLAP_TOOL_MODE:
-                       bdb2i_check_default_attr_index_mod( li, modlist );
-                       break;
-       }
-
-       if ( (e = bdb2i_dn2entry_w( be, dn, &matched )) == NULL ) {
-               char *matched_dn = NULL;
-               struct berval **refs = NULL;
-
-               if ( matched != NULL ) {
-                       matched_dn = ch_strdup( matched->e_dn );
-                       refs = is_entry_referral( matched )
-                               ? get_entry_referrals( be, conn, op, matched )
-                               : NULL;
-                       bdb2i_cache_return_entry_r( &li->li_cache, matched );
-               } else {
-                       refs = default_referral;
-               }
-
-               send_ldap_result( conn, op, LDAP_REFERRAL,
-                       matched_dn, NULL, refs, NULL );
-
-               if( matched != NULL ) {
-                       ber_bvecfree( refs );
-                       free( matched_dn );
-               }
-
-               ret = -1;
-               goto done;
-       }
-
-       if (!manageDSAit && is_entry_referral( e ) ) {
-               /* entry is a referral, don't allow add */
-               struct berval **refs = get_entry_referrals( be,
-                       conn, op, e );
-
-               Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
-                       0, 0 );
-
-               send_ldap_result( conn, op, LDAP_REFERRAL,
-                       e->e_dn, NULL, refs, NULL );
-
-               bdb2i_cache_return_entry_w( &li->li_cache, e );
-
-               ber_bvecfree( refs );
-
-               ret = -1;
-               goto done;
-       }
-
-       ret = bdb2i_back_modify_internal( be, conn, op, dn, modlist, e );
-       bdb2i_cache_return_entry_w( &li->li_cache, e );
-
-done:
-       (void) bdb2i_leave_backend_w( lock );
-       bdb2i_stop_timing( be->bd_info, time1, "MOD", conn, op );
-
-       return( ret );
-}
-
-
-int
-bdb2i_add_values(
-    Entry      *e,
-    LDAPMod    *mod,
-    char       *dn
-)
-{
-       int             i;
-       Attribute       *a;
-
-       /* check if the values we're adding already exist */
-       if ( (a = attr_find( e->e_attrs, mod->mod_type )) != NULL ) {
-               for ( i = 0; mod->mod_bvalues[i] != NULL; i++ ) {
-                       if ( value_find( a->a_vals, mod->mod_bvalues[i],
-                           a->a_syntax, 3 ) == 0 ) {
-                               return( LDAP_TYPE_OR_VALUE_EXISTS );
-                       }
-               }
-       }
-
-       /* no - add them */
-       if( attr_merge( e, mod->mod_type, mod->mod_bvalues ) != 0 ) {
-               return( LDAP_CONSTRAINT_VIOLATION );
-       }
-
-       return( LDAP_SUCCESS );
-}
-
-int
-bdb2i_delete_values(
-    Entry      *e,
-    LDAPMod    *mod,
-    char       *dn
-)
-{
-       int             i, j, k, found;
-       Attribute       *a;
-
-       /* delete the entire attribute */
-       if ( mod->mod_bvalues == NULL ) {
-               Debug( LDAP_DEBUG_ARGS, "removing entire attribute %s\n",
-                   mod->mod_type, 0, 0 );
-               return( attr_delete( &e->e_attrs, mod->mod_type ) ?
-                   LDAP_NO_SUCH_ATTRIBUTE : LDAP_SUCCESS );
-       }
-
-       /* delete specific values - find the attribute first */
-       if ( (a = attr_find( e->e_attrs, mod->mod_type )) == NULL ) {
-               Debug( LDAP_DEBUG_ARGS, "could not find attribute %s\n",
-                   mod->mod_type, 0, 0 );
-               return( LDAP_NO_SUCH_ATTRIBUTE );
-       }
-
-       /* find each value to delete */
-       for ( i = 0; mod->mod_bvalues[i] != NULL; i++ ) {
-               found = 0;
-               for ( j = 0; a->a_vals[j] != NULL; j++ ) {
-                       if ( value_cmp( mod->mod_bvalues[i], a->a_vals[j],
-                           a->a_syntax, 3 ) != 0 ) {
-                               continue;
-                       }
-                       found = 1;
-
-                       /* found a matching value - delete it */
-                       ber_bvfree( a->a_vals[j] );
-                       for ( k = j + 1; a->a_vals[k] != NULL; k++ ) {
-                               a->a_vals[k - 1] = a->a_vals[k];
-                       }
-                       a->a_vals[k - 1] = NULL;
-
-                       /* delete the entire attribute, if no values remain */
-                       if ( a->a_vals[0] == NULL) {
-                               Debug( LDAP_DEBUG_ARGS,
-                                       "removing entire attribute %s\n",
-                                       mod->mod_type, 0, 0 );
-                               if ( attr_delete( &e->e_attrs, mod->mod_type ) ) {
-                                       return LDAP_NO_SUCH_ATTRIBUTE;
-                               }
-                       }
-
-                       break;
-               }
-
-               /* looked through them all w/o finding it */
-               if ( ! found ) {
-                       Debug( LDAP_DEBUG_ARGS,
-                           "could not find value for attr %s\n",
-                           mod->mod_type, 0, 0 );
-                       return( LDAP_NO_SUCH_ATTRIBUTE );
-               }
-       }
-
-       return( LDAP_SUCCESS );
-}
-
-int
-bdb2i_replace_values(
-    Entry      *e,
-    LDAPMod    *mod,
-    char       *dn
-)
-{
-       (void) attr_delete( &e->e_attrs, mod->mod_type );
-
-       if ( mod->mod_bvalues != NULL &&
-               attr_merge( e, mod->mod_type, mod->mod_bvalues ) != 0 )
-       {
-               return( LDAP_CONSTRAINT_VIOLATION );
-       }
-
-       return( LDAP_SUCCESS );
-}
diff --git a/servers/slapd/back-bdb2/modrdn.c b/servers/slapd/back-bdb2/modrdn.c
deleted file mode 100644 (file)
index 47c260f..0000000
+++ /dev/null
@@ -1,510 +0,0 @@
-/* modrdn.c - bdb2 backend modrdn routine */
-/* $OpenLDAP$ */
-
-/*
- * LDAP v3 newSuperior support.
- *
- * Copyright 1999, Juan C. Gomez, All rights reserved.
- * This software is not subject to any license of Silicon Graphics 
- * Inc. or Purdue University.
- *
- * Redistribution and use in source and binary forms are permitted
- * without restriction or fee of any kind as long as this notice
- * is preserved.
- *
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-#include "proto-back-bdb2.h"
-
-static int
-bdb2i_back_modrdn_internal(
-    BackendDB  *be,
-    Connection *conn,
-    Operation  *op,
-    char       *dn,
-    char       *newrdn,
-    int                deleteoldrdn,
-    char       *newSuperior
-)
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       Entry           *matched = NULL;
-       char            *p_dn = NULL, *p_ndn = NULL;
-       char            *new_dn = NULL, *new_ndn = NULL;
-       char            sep[2];
-       Entry           *e, *p = NULL;
-       int                     rc = -1, manageDSAit;
-       /* Added to support LDAP v2 correctly (deleteoldrdn thing) */
-       char            *new_rdn_val = NULL;    /* Val of new rdn */
-       char            *new_rdn_type = NULL;   /* Type of new rdn */
-       char            *old_rdn = NULL;        /* Old rdn's attr type & val */
-       char            *old_rdn_type = NULL;   /* Type of old rdn attr. */
-       char            *old_rdn_val = NULL;    /* Old rdn attribute value */
-       struct berval   add_bv;                 /* Stores new rdn att */
-       struct berval   *add_bvals[2];          /* Stores new rdn att */
-       struct berval   del_bv;                 /* Stores old rdn att */
-       struct berval   *del_bvals[2];          /* Stores old rdn att */
-       LDAPModList     mod[2];                 /* Used to delete old rdn */
-       /* Added to support newSuperior */ 
-       Entry           *np = NULL;     /* newSuperior Entry */
-       char            *np_dn = NULL;  /* newSuperior dn */
-       char            *np_ndn = NULL; /* newSuperior ndn */
-       char            *new_parent_dn = NULL;  /* np_dn, p_dn, or NULL */
-
-       Debug( LDAP_DEBUG_TRACE, "==>ldbm_back_modrdn(newSuperior=%s)\n",
-              (newSuperior ? newSuperior : "NULL"),
-              0, 0 );
-
-       /* get entry with writer lock */
-       if ( (e = bdb2i_dn2entry_w( be, dn, &matched )) == NULL ) {
-               char *matched_dn = NULL;
-               struct berval **refs = NULL;
-
-               if ( matched != NULL ) {
-                       matched_dn = ch_strdup( matched->e_dn );
-                       refs = is_entry_referral( matched )
-                               ? get_entry_referrals( be, conn, op, matched )
-                               : NULL;
-                       bdb2i_cache_return_entry_r( &li->li_cache, matched );
-               } else {
-                       refs = default_referral;
-               }
-
-               send_ldap_result( conn, op, LDAP_REFERRAL,
-                       matched_dn, NULL, refs, NULL );
-
-               if( matched != NULL ) {
-                       ber_bvecfree( refs );
-                       free( matched_dn );
-               }
-
-               return( -1 );
-       }
-
-       if (!manageDSAit && is_entry_referral( e ) ) {
-               /* entry is a referral, don't allow add */
-               struct berval **refs = get_entry_referrals( be,
-                       conn, op, e );
-
-               Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
-                       0, 0 );
-
-               send_ldap_result( conn, op, LDAP_REFERRAL,
-                       e->e_dn, NULL, refs, NULL );
-
-               ber_bvecfree( refs );
-
-               goto return_results;
-       }
-
-#ifdef SLAPD_CHILD_MODIFICATION_WITH_ENTRY_ACL
-               /* check parent for "children" acl */
-       if ( ! access_allowed( be, conn, op, e,
-               "entry", NULL, ACL_WRITE ) )
-       {
-               Debug( LDAP_DEBUG_TRACE, "no access to entry\n", 0,
-                       0, 0 );
-               send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
-                       NULL, NULL, NULL, NULL );
-               goto return_results;
-       }
-#endif
-
-       if ( (p_ndn = dn_parent( be, e->e_ndn )) != NULL ) {
-               /* parent + rdn + separator(s) + null */
-               if( (p = bdb2i_dn2entry_w( be, p_ndn, &matched )) == NULL) {
-                       Debug( LDAP_DEBUG_TRACE, "parent does not exist\n",
-                               0, 0, 0);
-                       send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                               NULL, NULL, NULL, NULL );
-                       goto return_results;
-               }
-
-               /* check parent for "children" acl */
-               if ( ! access_allowed( be, conn, op, p,
-                       "children", NULL, ACL_WRITE ) )
-               {
-                       Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
-                               0, 0 );
-                       send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
-                               NULL, NULL, NULL, NULL );
-                       goto return_results;
-               }
-
-               p_dn = dn_parent( be, e->e_dn );
-
-               Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: parent dn=%s\n",
-                      p_dn, 0, 0 );
-
-
-       } else {
-               /* no parent, modrdn entry directly under root */
-               if( ! be_isroot( be, op->o_ndn ) ) {
-                       Debug( LDAP_DEBUG_TRACE, "no parent & not root\n",
-                               0, 0, 0);
-                       send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
-                               NULL, NULL, NULL, NULL );
-                       goto return_results;
-               }
-
-               Debug( LDAP_DEBUG_TRACE,
-                      "ldbm_back_modrdn: no parent!, working on root\n",
-                      0, 0, 0 );
-
-       }
-
-       new_parent_dn = p_dn;   /* New Parent unless newSuperior given */
-
-       if ( (np_dn = newSuperior) != NULL) {
-
-
-               Debug( LDAP_DEBUG_TRACE, 
-                      "ldbm_back_modrdn: new parent requested...\n",
-                      0, 0, 0 );
-
-               np_ndn = ch_strdup( np_dn );
-               (void) dn_normalize_case( np_ndn );
-
-               /* newSuperior == oldParent?, if so ==> ERROR */
-
-               /* newSuperior == entry being moved?, if so ==> ERROR */
-
-               /* Get Entry with dn=newSuperior. Does newSuperior exist? */
-
-               if( (np = bdb2i_dn2entry_w( be, np_ndn, &matched )) == NULL) {
-
-                       Debug( LDAP_DEBUG_TRACE,
-                              "ldbm_back_modrdn: newSup(ndn=%s) not here!\n",
-                              np_ndn, 0, 0);
-                       send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                               NULL, NULL, NULL, NULL );
-                       goto return_results;
-               }
-
-               Debug( LDAP_DEBUG_TRACE,
-                      "ldbm_back_modrdn: wr to new parent OK np=%p, id=%d\n",
-                      np, np->e_id, 0 );
-           
-               /* check newSuperior for "children" acl */
-               if ( !access_allowed( be, conn, op, np, "children", NULL,
-                                     ACL_WRITE ) )
-               {
-                       Debug( LDAP_DEBUG_TRACE,
-                              "ldbm_back_modrdn: no wr to newSup children\n",
-                              0, 0, 0 );
-                       send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
-                               NULL, NULL, NULL, NULL );
-                       goto return_results;
-               }
-
-               Debug( LDAP_DEBUG_TRACE,
-                      "ldbm_back_modrdn: wr to new parent's children OK\n",
-                      0, 0 , 0 );
-
-
-               new_parent_dn = np_dn;
-
-       }
-       
-       /* Build target dn and make sure target entry doesn't exist already. */
-
-       build_new_dn( &new_dn, e->e_dn, new_parent_dn, newrdn ); 
-
-
-       new_ndn = ch_strdup( new_dn );
-       (void) dn_normalize_case( new_ndn );
-
-       Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: new ndn=%s\n",
-              new_ndn, 0, 0 );
-
-       /* check for abandon */
-       ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
-       if ( op->o_abandon ) {
-               ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
-               goto return_results;
-       }
-       ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
-
-       if ( (bdb2i_dn2id ( be, new_ndn ) ) != NOID ) {
-               send_ldap_result( conn, op, LDAP_ALREADY_EXISTS,
-                       NULL, NULL, NULL, NULL );
-               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_type = rdn_attr_type( newrdn )) == NULL ) {
-           
-               Debug( LDAP_DEBUG_TRACE,
-                      "ldbm_back_modrdn: can't figure out type of newrdn\n",
-                      0, 0, 0 );
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-               goto return_results;            
-
-       }
-
-       if ( (new_rdn_val = rdn_attr_value( newrdn )) == NULL ) {
-           
-               Debug( LDAP_DEBUG_TRACE,
-                      "ldbm_back_modrdn: can't figure out val of newrdn\n",
-                      0, 0, 0 );
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-               goto return_results;            
-
-       }
-
-       Debug( LDAP_DEBUG_TRACE,
-              "ldbm_back_modrdn: new_rdn_val=%s, new_rdn_type=%s\n",
-              new_rdn_val, new_rdn_type, 0 );
-
-       /* Retrieve the old rdn from the entry's dn */
-
-       if ( (old_rdn = dn_rdn( be, dn )) == NULL ) {
-
-               Debug( LDAP_DEBUG_TRACE,
-                      "ldbm_back_modrdn: can't figure out old_rdn from dn\n",
-                      0, 0, 0 );
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-               goto return_results;            
-
-       }
-
-       if ( (old_rdn_type = rdn_attr_type( old_rdn )) == NULL ) {
-           
-               Debug( LDAP_DEBUG_TRACE,
-                      "ldbm_back_modrdn: can't figure out the old_rdn type\n",
-                      0, 0, 0 );
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-               goto return_results;            
-               
-       }
-       
-       if ( strcasecmp( old_rdn_type, new_rdn_type ) != 0 ) {
-
-           /* Not a big deal but we may say something */
-           Debug( LDAP_DEBUG_TRACE,
-                  "ldbm_back_modrdn: old_rdn_type=%s, new_rdn_type=%s!\n",
-                  old_rdn_type, new_rdn_type, 0 );
-           
-       }               
-
-#ifdef DNS_DN
-       if ( dn_type( old_rdn ) == DN_X500 ) {
-#endif
-
-               Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: DN_X500\n",
-                      0, 0, 0 );
-
-               /* Add new attribute value to the entry.
-                */
-
-               add_bvals[0] = &add_bv;         /* Array of bervals */
-               add_bvals[1] = NULL;
-
-               add_bv.bv_val = new_rdn_val;
-               add_bv.bv_len = strlen(new_rdn_val);
-               
-               mod[0].ml_type = new_rdn_type;  
-               mod[0].ml_bvalues = add_bvals;
-               mod[0].ml_op = LDAP_MOD_SOFTADD;
-               mod[0].ml_next = NULL;
-               
-               Debug( LDAP_DEBUG_TRACE,
-                      "ldbm_back_modrdn: adding new rdn attr val =%s\n",
-                      new_rdn_val, 0, 0 );
-               
-               /* Remove old rdn value if required */
-
-               if (deleteoldrdn) {
-
-                       del_bvals[0] = &del_bv;         /* Array of bervals */
-                       del_bvals[1] = NULL;
-                       /* Get value of old rdn */
-       
-                       if ((old_rdn_val = rdn_attr_value( old_rdn ))
-                           == NULL) {
-                           
-                               Debug( LDAP_DEBUG_TRACE,
-                                      "ldbm_back_modrdn: can't figure out old_rdn_val from old_rdn\n",
-                                      0, 0, 0 );
-                               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                                       NULL, NULL, NULL, NULL );
-                               goto return_results;            
-
-
-                       }
-
-                       /* Remove old value of rdn as an attribute. */
-                   
-                       del_bv.bv_val = old_rdn_val;
-                       del_bv.bv_len = strlen(old_rdn_val);
-                       
-                       mod[0].ml_next = &mod[1];
-                       mod[1].ml_type = old_rdn_type;  
-                       mod[1].ml_bvalues = del_bvals;
-                       mod[1].ml_op = LDAP_MOD_DELETE;
-                       mod[1].ml_next = NULL;
-
-
-                       Debug( LDAP_DEBUG_TRACE,
-                              "ldbm_back_modrdn: removing old_rdn_val=%s\n",
-                              old_rdn_val, 0, 0 );
-               
-               }/* if (deleteoldrdn) */
-
-#ifdef DNS_DN
-       } else {
-           
-
-               Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: DNS DN\n",
-                      0, 0, 0 );
-               /* XXXV3: not sure of what to do here */
-               Debug( LDAP_DEBUG_TRACE,
-                      "ldbm_back_modrdn: not fully implemented...\n",
-                      0, 0, 0 );  
-
-       }
-#endif
-
-       /* check for abandon */
-       ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
-       if ( op->o_abandon ) {
-               ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
-               goto return_results;
-       }
-       ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
-
-       /* delete old one */
-       if ( bdb2i_dn2id_delete( be, e->e_ndn, e->e_id ) != 0 ) {
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-               goto return_results;
-       }
-
-       (void) bdb2i_cache_delete_entry( &li->li_cache, e );
-
-       free( e->e_dn );
-       free( e->e_ndn );
-       e->e_dn = new_dn;
-       e->e_ndn = new_ndn;
-       new_dn = NULL;
-       new_ndn = NULL;
-
-       /* add new one */
-       if ( bdb2i_dn2id_add( be,  e->e_ndn, e->e_id ) != 0 ) {
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-               goto return_results;
-       }
-
-       /* modify memory copy of entry */
-       if ( bdb2i_back_modify_internal( be, conn, op, dn, &mod[0], e )
-            != 0 ) {
-           
-               goto return_results;
-                       
-       }
-       
-       (void) bdb2i_cache_update_entry( &li->li_cache, e );
-
-       /* NOTE: after this you must not free new_dn or new_ndn!
-        * They are used by cache.
-        */
-
-       /* id2entry index */
-       if ( bdb2i_id2entry_add( be, e ) != 0 ) {
-               entry_free( e );
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-               goto return_results;
-       }
-
-       send_ldap_result( conn, op, LDAP_SUCCESS,
-               NULL, NULL, NULL, NULL );
-       rc = 0;
-
-return_results:
-       if( new_dn != NULL ) free( new_dn );
-       if( new_ndn != NULL ) free( new_ndn );
-
-       /* NOTE:
-        * new_dn and new_ndn are not deallocated because they are used by
-        * the cache entry.
-        */
-       if( p_dn != NULL ) free( p_dn );
-       if( p_ndn != NULL ) free( p_ndn );
-
-       /* LDAP v2 supporting correct attribute handling. */
-       if( new_rdn_type != NULL ) free(new_rdn_type);
-       if( new_rdn_val != NULL ) free(new_rdn_val);
-       if( old_rdn != NULL ) free(old_rdn);
-       if( old_rdn_type != NULL ) free(old_rdn_type);
-       if( old_rdn_val != NULL ) free(old_rdn_val);
-
-       /* LDAP v3 Support */
-       if ( np_dn != NULL ) free( np_dn );
-       if ( np_ndn != NULL ) free( np_ndn );
-
-       if( p != NULL ) {
-               /* free parent and writer lock */
-               bdb2i_cache_return_entry_w( &li->li_cache, p );
-
-       }
-
-       /* free entry and writer lock */
-       bdb2i_cache_return_entry_w( &li->li_cache, e );
-       return( rc );
-}
-
-
-int
-bdb2_back_modrdn(
-    BackendDB  *be,
-    Connection *conn,
-    Operation  *op,
-    char       *dn,
-    char       *newrdn,
-    int                deleteoldrdn,
-    char       *newSuperior
-)
-{
-       DB_LOCK         lock;
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       struct timeval  time1;
-       int             ret;
-
-       bdb2i_start_timing( be->bd_info, &time1 );
-
-       if ( bdb2i_enter_backend_w( &lock ) != 0 ) {
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-               return( -1 );
-
-       }
-
-       ret = bdb2i_back_modrdn_internal( be, conn, op, dn,
-                                       newrdn, deleteoldrdn,
-                                       newSuperior );
-
-       (void) bdb2i_leave_backend_w( lock );
-       bdb2i_stop_timing( be->bd_info, time1, "MODRDN", conn, op );
-
-       return( ret );
-}
-
-
diff --git a/servers/slapd/back-bdb2/nextid.c b/servers/slapd/back-bdb2/nextid.c
deleted file mode 100644 (file)
index c00c67d..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/* id.c - keep track of the next id to be given out */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/socket.h>
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-#include "slap.h"
-#include "back-bdb2.h"
-
-/*  reading and writing NEXTID is handled in txn.c  */
-#define next_id_read(be)  bdb2i_get_nextid( (be) )
-#define next_id_write(be,id)  bdb2i_put_nextid( (be), (id) )
-
-
-int
-bdb2i_next_id_save( BackendDB *be )
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       ID id = bdb2i_next_id_get( be );
-       int rc;
-
-       rc = next_id_write( be, id );
-
-       return rc;
-}
-
-ID
-bdb2i_next_id( BackendDB *be )
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       ID              id;
-
-       /* first time in here since startup - try to read the nexid */
-       if ( li->li_nextid == NOID ) {
-               li->li_nextid = next_id_read( be );
-
-               if ( li->li_nextid == NOID ) {
-                       li->li_nextid = 1;
-               }
-       }
-
-       id = li->li_nextid++;
-
-       (void) next_id_write( be, li->li_nextid );
-
-       return( id );
-}
-
-ID
-bdb2i_next_id_get( BackendDB *be )
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       ID              id;
-
-       /* first time in here since startup - try to read the nexid */
-       if ( li->li_nextid == NOID ) {
-               li->li_nextid = next_id_read( be );
-
-               if ( li->li_nextid == NOID ) {
-                       li->li_nextid = 1;
-               }
-       }
-
-       id = li->li_nextid;
-
-       return( id );
-}
diff --git a/servers/slapd/back-bdb2/porter.c b/servers/slapd/back-bdb2/porter.c
deleted file mode 100644 (file)
index 55f87a6..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/* porter.c - port functions of the bdb2 backend */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/errno.h>
-
-#include <ac/string.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-
-#define  PORTER_OBJ   "bdb2_backend"
-
-
-int
-bdb2i_enter_backend_rw( DB_LOCK *lock, int writer )
-{
-       u_int32_t      locker;
-       db_lockmode_t  lock_type;
-       DBT            lock_dbt;
-       int            ret = 0;
-
-       switch ( slapMode & SLAP_MODE ) {
-
-               case SLAP_SERVER_MODE:
-               case SLAP_TOOL_MODE:
-                       if ( ( ret = lock_id( bdb2i_dbEnv.lk_info, &locker )) != 0 ) {
-
-                               Debug( LDAP_DEBUG_ANY,
-                                       "bdb2i_enter_backend(): unable to get locker id -- %s\n",
-                                       strerror( ret ), 0, 0 );
-                               return( ret );
-
-                       }
-
-                       lock_type     = writer ? DB_LOCK_WRITE : DB_LOCK_READ;
-                       lock_dbt.data = PORTER_OBJ;
-                       lock_dbt.size = strlen( PORTER_OBJ );
-
-                       switch ( ( ret = lock_get( bdb2i_dbEnv.lk_info, locker, 0,
-                                                               &lock_dbt, lock_type, lock ))) {
-
-                               case 0:
-                                       Debug( LDAP_DEBUG_TRACE,
-                                               "bdb2i_enter_backend() -- %s lock granted\n",
-                                               writer ? "write" : "read", 0, 0 );
-                                       break;
-
-                               case DB_LOCK_NOTGRANTED:
-                                       Debug( LDAP_DEBUG_ANY,
-                                               "bdb2i_enter_backend() -- %s lock NOT granted\n",
-                                               writer ? "write" : "read", 0, 0 );
-                                       break;
-
-                               case DB_LOCK_DEADLOCK:
-                                       Debug( LDAP_DEBUG_ANY,
-                                               "bdb2i_enter_backend() -- %s lock returned DEADLOCK\n",
-                                               writer ? "write" : "read", 0, 0 );
-                                       break;
-
-                               default: 
-                                       ret = errno;
-                                       Debug( LDAP_DEBUG_ANY,
-                                               "bdb2i_enter_backend() -- %s lock returned ERROR: %s\n",
-                                               writer ? "write" : "read", strerror( ret ), 0 );
-                                       break;
-
-                       }
-                       break;
-       }
-
-       /*  if we are a writer and we have the backend lock,
-               start transaction control  */
-       if ( writer && ( ret == 0 )) {
-
-               ret = bdb2i_start_transction( bdb2i_dbEnv.tx_info );
-
-       }
-
-       return( ret );
-}
-
-
-int
-bdb2i_leave_backend_rw( DB_LOCK lock, int writer )
-{
-       /*  since one or more error can occure,
-               we must have several return codes that are or'ed at the end  */
-       int   ret_transaction = 0;
-       int   ret_lock        = 0;
-
-       /*  if we are a writer, finish the transaction  */
-       if ( writer ) {
-
-               ret_transaction = bdb2i_finish_transaction();
-
-       }
-
-       /*  check whether checkpointing is needed  */
-       ret_transaction |= bdb2i_set_txn_checkpoint( bdb2i_dbEnv.tx_info, 0 );
-
-       /*  now release the lock  */
-       switch ( slapMode & SLAP_MODE ) {
-
-               case SLAP_SERVER_MODE:
-               case SLAP_TOOL_MODE:
-                       switch( ( ret_lock = lock_put( bdb2i_dbEnv.lk_info, lock ))) {
-
-                               case 0:
-                                       Debug( LDAP_DEBUG_TRACE,
-                                               "bdb2i_leave_backend() -- %s lock released\n",
-                                               writer ? "write" : "read", 0, 0 );
-                                       break;
-
-                               case DB_LOCK_NOTHELD:
-                                       Debug( LDAP_DEBUG_ANY,
-                                               "bdb2i_leave_backend() -- %s lock NOT held\n",
-                                               writer ? "write" : "read", 0, 0 );
-                                       break;
-
-                               case DB_LOCK_DEADLOCK:
-                                       Debug( LDAP_DEBUG_ANY,
-                                               "bdb2i_leave_backend() -- %s lock returned DEADLOCK\n",
-                                               writer ? "write" : "read", 0, 0 );
-                                       break;
-
-                               default:
-                                       ret_lock = errno;
-                                       Debug( LDAP_DEBUG_ANY,
-                                               "bdb2i_leave_backend() -- %s lock returned ERROR: %s\n",
-                                               writer ? "write" : "read", strerror( ret_lock ), 0 );
-                                       break;
-                       
-                       }
-                       break;
-       }
-
-       return( ret_transaction | ret_lock );
-}
-
-
diff --git a/servers/slapd/back-bdb2/proto-back-bdb2.h b/servers/slapd/back-bdb2/proto-back-bdb2.h
deleted file mode 100644 (file)
index befba8b..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-/* $OpenLDAP$ */
-#ifndef _PROTO_BACK_BDB2
-#define _PROTO_BACK_BDB2
-
-#include <ldap_cdefs.h>
-
-#include <ac/time.h>           /* Needed in add.c compare.c struct timeval */
-
-#include "external.h"
-
-LDAP_BEGIN_DECL
-
-/*
- * add.c
- */
-int bdb2i_release_add_lock LDAP_P(());
-
-/*
- * alias.c
- */
-
-Entry * bdb2i_deref_r LDAP_P((
-       Backend *be,
-       Entry *e,
-       char *dn,
-       int *err,
-       Entry **matched,
-       char **text ));
-
-#define deref_entry_r( be, e, err, matched, text ) \
-       bdb2i_deref_r( be, e, NULL, err, matched, text )
-#define deref_dn_r( be, dn, err, matched, text ) \
-       bdb2i_deref_r( be, NULL, dn, err, matched, text )
-
-/*
- * attr.c
- */
-
-void bdb2i_attr_masks LDAP_P(( struct ldbminfo *li, char *type, int *indexmask,
- int *syntaxmask ));
-void bdb2i_attr_index_config LDAP_P(( struct ldbminfo *li,
- const char *fname,
- int lineno, int argc, char **argv, int init ));
-
-/*
- * cache.c
- */
-
-int bdb2i_cache_add_entry_rw LDAP_P(( struct cache *cache, Entry *e, int rw ));
-int bdb2i_cache_update_entry LDAP_P(( struct cache *cache, Entry *e ));
-void bdb2i_cache_return_entry_rw LDAP_P(( struct cache *cache, Entry *e,
- int rw ));
-#define bdb2i_cache_return_entry_r(c, e) bdb2i_cache_return_entry_rw((c), (e), 0)
-#define bdb2i_cache_return_entry_w(c, e) bdb2i_cache_return_entry_rw((c), (e), 1)
-
-ID bdb2i_cache_find_entry_dn2id LDAP_P(( BackendDB *be, struct cache *cache,
- const char *dn ));
-Entry * bdb2i_cache_find_entry_id LDAP_P(( struct cache *cache, ID id, int rw ));
-int bdb2i_cache_delete_entry LDAP_P(( struct cache *cache, Entry *e ));
-
-/*
- * dbcache.c
- */
-
-struct dbcache * bdb2i_cache_open LDAP_P(( BackendDB *be, char *name, char *suffix,
- int flags ));
-void bdb2i_cache_close LDAP_P(( BackendDB *be, struct dbcache *db ));
-void bdb2i_cache_really_close LDAP_P(( BackendDB *be, struct dbcache *db ));
-void bdb2i_cache_flush_all LDAP_P(( BackendDB *be ));
-Datum bdb2i_cache_fetch LDAP_P(( struct dbcache *db, Datum key ));
-int bdb2i_cache_store LDAP_P(( struct dbcache *db, Datum key, Datum data, int flags ));
-int bdb2i_cache_delete LDAP_P(( struct dbcache *db, Datum key ));
-
-/*
- * dn2id.c
- */
-
-int bdb2i_dn2id_add LDAP_P(( BackendDB *be, const char *dn, ID id ));
-ID bdb2i_dn2id LDAP_P(( BackendDB *be, const char *dn ));
-int bdb2i_dn2id_delete LDAP_P(( BackendDB *be, const char *dn, ID id ));
-
-ID_BLOCK *
-bdb2i_dn2idl LDAP_P((
-    BackendDB  *be,
-    const char *dn,
-       int     prefix ));
-
-Entry * bdb2i_dn2entry_rw LDAP_P((
-       BackendDB *be,
-       const char *dn,
-       Entry **matched,
-       int rw ));
-
-#define bdb2i_dn2entry_r(be, dn, m) bdb2i_dn2entry_rw((be), (dn), (m), 0)
-#define bdb2i_dn2entry_w(be, dn, m) bdb2i_dn2entry_rw((be), (dn), (m), 1)
-
-/*
- * entry.c
- */
-int bdb2_back_entry_release_rw LDAP_P(( BackendDB *be, Entry *e, int rw ));
-
-/*
- * filterindex.c
- */
-
-ID_BLOCK * bdb2i_filter_candidates LDAP_P(( BackendDB *be, Filter *f ));
-
-/*
- * id2children.c
- */
-
-int bdb2i_has_children LDAP_P(( BackendDB *be, Entry *p ));
-
-/*
- * id2entry.c
- */
-
-int bdb2i_id2entry_add LDAP_P(( BackendDB *be, Entry *e ));
-int bdb2i_id2entry_delete LDAP_P(( BackendDB *be, Entry *e ));
-
-Entry * bdb2i_id2entry_rw LDAP_P(( BackendDB *be, ID id, int rw )); 
-#define bdb2i_id2entry_r(be, id)  bdb2i_id2entry_rw((be), (id), 0)
-#define bdb2i_id2entry_w(be, id)  bdb2i_id2entry_rw((be), (id), 1)
-
-/*
- * idl.c
- */
-
-ID_BLOCK * bdb2i_idl_alloc LDAP_P(( unsigned int nids ));
-ID_BLOCK * bdb2i_idl_allids LDAP_P(( BackendDB *be ));
-void bdb2i_idl_free LDAP_P(( ID_BLOCK *idl ));
-ID_BLOCK * bdb2i_idl_fetch LDAP_P(( BackendDB *be, struct dbcache *db, Datum key ));
-int bdb2i_idl_insert_key LDAP_P(( BackendDB *be, struct dbcache *db, Datum key, ID id ));
-int bdb2i_idl_insert LDAP_P(( ID_BLOCK **idl, ID id, unsigned int maxids ));
-int bdb2i_idl_delete_key LDAP_P(( BackendDB *be, struct dbcache *db, Datum key, ID id ));
-ID_BLOCK * bdb2i_idl_intersection LDAP_P(( BackendDB *be, ID_BLOCK *a, ID_BLOCK *b ));
-ID_BLOCK * bdb2i_idl_union LDAP_P(( BackendDB *be, ID_BLOCK *a, ID_BLOCK *b ));
-ID_BLOCK * bdb2i_idl_notin LDAP_P(( BackendDB *be, ID_BLOCK *a, ID_BLOCK *b ));
-ID bdb2i_idl_firstid LDAP_P(( ID_BLOCK *idl, ID *cursor ));
-ID bdb2i_idl_nextid LDAP_P(( ID_BLOCK *idl, ID *cursor ));
-
-/*
- * index.c
- */
-
-int bdb2i_index_add_entry LDAP_P(( BackendDB *be, Entry *e ));
-int bdb2i_index_add_mods LDAP_P(( BackendDB *be, LDAPModList *ml, ID id ));
-ID_BLOCK * bdb2i_index_read LDAP_P(( BackendDB *be, char *type, int indextype, char *val ));
-int bdb2i_index_add_values LDAP_P(( BackendDB *be, char *type, struct berval **vals, ID  id ));
-
-/*
- * kerberos.c
- */
-
-#ifdef HAVE_KERBEROS
-/* bdb2i_krbv4_ldap_auth LDAP_P(( BackendDB *be, struct berval *cred, AUTH_DAT *ad )); */
-#endif
-
-/*
- * modify.c
- * These prototypes are placed here because they are used by modify and
- * modify rdn which are implemented in different files. 
- *
- * We need bdb2i_back_modify_internal here because of LDAP modrdn & modify use 
- * it. If we do not add this, there would be a bunch of code replication 
- * here and there and of course the likelihood of bugs increases.
- * Juan C. Gomez (gomez@engr.sgi.com) 05/18/99
- *
- */
-
-int bdb2i_add_values LDAP_P(( Entry *e, LDAPMod *mod, char *dn ));
-int bdb2i_delete_values LDAP_P(( Entry *e, LDAPMod *mod, char *dn ));
-int bdb2i_replace_values LDAP_P(( Entry *e, LDAPMod *mod, char *dn ));
-int bdb2i_back_modify_internal LDAP_P((Backend *be, Connection *conn, Operation *op,
-                                char *dn, LDAPModList *mods, Entry *e));
-/*
- * nextid.c
- */
-
-ID bdb2i_next_id LDAP_P(( BackendDB *be ));
-void bdb2i_next_id_return LDAP_P(( BackendDB *be, ID id ));
-ID bdb2i_next_id_get LDAP_P(( BackendDB *be ));
-int bdb2i_next_id_save LDAP_P(( BackendDB *be ));
-
-/*
- *  startup.c
- */
-
-int bdb2i_back_startup     LDAP_P(( BackendInfo *bi ));
-int bdb2i_back_shutdown    LDAP_P(( BackendInfo *bi ));
-int bdb2i_back_db_startup  LDAP_P(( BackendDB *be ));
-int bdb2i_back_db_shutdown LDAP_P(( BackendDB *be ));
-
-/*
- *  timing.c
- */
-
-void bdb2i_uncond_start_timing LDAP_P(( struct timeval *time1 ));
-#define bdb2i_start_timing(bi,time1)  if ( with_timing( bi )) bdb2i_uncond_start_timing( (time1) )
-void bdb2i_uncond_stop_timing LDAP_P(( struct timeval time1,
-  char *func, Connection *conn, Operation *op, int level ));
-#define bdb2i_stop_timing(bi,time1,func,conn,op)  if ( with_timing( bi )) bdb2i_uncond_stop_timing( (time1), (func), (conn), (op), LDAP_DEBUG_ANY )
-
-/*
- * porter.c
- */
-
-int bdb2i_enter_backend_rw  LDAP_P(( DB_LOCK *lock, int writer ));
-#define bdb2i_enter_backend_r(lock)  bdb2i_enter_backend_rw((lock), 0 )
-#define bdb2i_enter_backend_w(lock)  bdb2i_enter_backend_rw((lock), 1 )
-int bdb2i_leave_backend_rw LDAP_P(( DB_LOCK lock, int writer ));
-#define bdb2i_leave_backend_r(lock)  bdb2i_leave_backend_rw((lock), 0 )
-#define bdb2i_leave_backend_w(lock)  bdb2i_leave_backend_rw((lock), 1 )
-
-/*
- *  txn.c
- */
-
-int bdb2i_txn_head_init  LDAP_P(( BDB2_TXN_HEAD *head ));
-void bdb2i_txn_attr_config LDAP_P((
- struct ldbminfo  *li,
- char *attr,
- int open ));
-int bdb2i_txn_open_files LDAP_P(( BackendDB *be ));
-void bdb2i_txn_close_files LDAP_P(( BackendDB *be ));
-BDB2_TXN_FILES *bdb2i_get_db_file_cache LDAP_P((
- struct ldbminfo *li,
- char *name ));
-int bdb2i_check_additional_attr_index LDAP_P(( struct ldbminfo *li ));
-void bdb2i_check_default_attr_index_add LDAP_P((
- struct ldbminfo *li,
- Entry *e ));
-void bdb2i_check_default_attr_index_mod LDAP_P((
- struct ldbminfo *li,
- LDAPModList *modlist ));
-ID bdb2i_get_nextid  LDAP_P(( BackendDB *be ));
-int bdb2i_put_nextid LDAP_P(( BackendDB *be, ID id ));
-LDBM bdb2i_db_open LDAP_P(( char *name, int type, int rw, int mode,
- int dbcachesize ));
-int bdb2i_db_store   LDAP_P(( LDBM ldbm, Datum key, Datum data, int flags ));
-int bdb2i_db_delete  LDAP_P(( LDBM ldbm, Datum key ));
-Datum bdb2i_db_fetch LDAP_P(( LDBM ldbm, Datum key ));
-Datum bdb2i_db_firstkey LDAP_P(( LDBM ldbm, DBC **dbch ));
-Datum bdb2i_db_nextkey  LDAP_P(( LDBM ldbm, Datum key, DBC *dbcp ));
-int bdb2i_start_transction   LDAP_P(( DB_TXNMGR *txmgr ));
-int bdb2i_finish_transaction LDAP_P(( ));
-int bdb2i_set_txn_checkpoint LDAP_P(( DB_TXNMGR *txmgr, int forced ));
-
-
-LDAP_END_DECL
-#endif
diff --git a/servers/slapd/back-bdb2/search.c b/servers/slapd/back-bdb2/search.c
deleted file mode 100644 (file)
index 4bec697..0000000
+++ /dev/null
@@ -1,482 +0,0 @@
-/* search.c - bdb2 backend search function */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-#include <ac/time.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-#include "proto-back-bdb2.h"
-
-static ID_BLOCK *base_candidate(
-       Backend *be, Entry *e );
-
-static ID_BLOCK *search_candidates(
-       Backend *be, Entry *e, Filter *filter,
-       int scope, int deref, int manageDSAit );
-
-static int
-bdb2i_back_search_internal(
-    BackendDB  *be,
-    Connection *conn,
-    Operation  *op,
-    char       *base,
-    int                scope,
-    int                deref,
-    int                slimit,
-    int                tlimit,
-    Filter     *filter,
-    char       *filterstr,
-    char       **attrs,
-    int                attrsonly
-)
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       int             rc, err;
-       char *text;
-       time_t          stoptime;
-       ID_BLOCK                *candidates;
-       ID              id, cursor;
-       Entry           *e;
-       struct berval **v2refs = NULL;
-       Entry   *matched = NULL;
-       char    *realbase = NULL;
-       int             nentries = 0;
-       int             manageDSAit = get_manageDSAit( op );
-
-       Debug(LDAP_DEBUG_TRACE, "=> bdb2_back_search\n", 0, 0, 0);
-
-       /* get entry with reader lock */
-       if ( deref & LDAP_DEREF_FINDING ) {
-               e = deref_dn_r( be, base, &err, &matched, &text );
-
-       } else {
-               e = bdb2i_dn2entry_r( be, base, &matched );
-               err = e != NULL ? LDAP_SUCCESS : LDAP_REFERRAL;
-               text = NULL;
-       }
-
-       if ( e == NULL ) {
-               char *matched_dn = NULL;
-               struct berval **refs = NULL;
-
-               if ( matched != NULL ) {
-                       matched_dn = ch_strdup( matched->e_dn );
-
-                       refs = is_entry_referral( matched )
-                               ? get_entry_referrals( be, conn, op, matched )
-                               : NULL;
-
-                       bdb2i_cache_return_entry_r( &li->li_cache, matched );
-               } else {
-                       refs = default_referral;
-               }
-
-               send_ldap_result( conn, op, err,
-                       matched_dn, text, refs, NULL );
-
-               if( matched != NULL ) {
-                       ber_bvecfree( refs );
-                       free( matched_dn );
-               }
-
-               return 1;
-       }
-
-       if (!manageDSAit && is_entry_referral( e ) ) {
-               /* entry is a referral, don't allow add */
-               char *matched_dn = ch_strdup( e->e_dn );
-               struct berval **refs = get_entry_referrals( be,
-                       conn, op, e );
-
-               bdb2i_cache_return_entry_r( &li->li_cache, e );
-
-               Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
-                   0, 0 );
-
-               send_ldap_result( conn, op, LDAP_REFERRAL,
-                   matched_dn, NULL, refs, NULL );
-
-               ber_bvecfree( refs );
-               free( matched_dn );
-
-               return 1;
-       }
-
-       if ( tlimit == 0 && be_isroot( be, op->o_ndn ) ) {
-               tlimit = -1;    /* allow root to set no limit */
-       } else {
-               tlimit = (tlimit > be->be_timelimit || tlimit < 1) ?
-                   be->be_timelimit : tlimit;
-               stoptime = op->o_time + tlimit;
-       }
-
-       if ( slimit == 0 && be_isroot( be, op->o_ndn ) ) {
-               slimit = -1;    /* allow root to set no limit */
-       } else {
-               slimit = (slimit > be->be_sizelimit || slimit < 1) ?
-                   be->be_sizelimit : slimit;
-       }
-
-       if ( scope == LDAP_SCOPE_BASE) {
-               candidates = base_candidate( be, e );
-
-       } else {
-               candidates = search_candidates( be, e, filter,
-                   scope, deref, manageDSAit );
-       }
-
-       /* need normalized dn below */
-       realbase = ch_strdup( e->e_ndn );
-       bdb2i_cache_return_entry_r( &li->li_cache, e );
-
-       if ( candidates == NULL ) {
-               /* no candidates */
-               Debug( LDAP_DEBUG_TRACE, "no candidates\n", 0,
-                   0, 0 );
-
-               send_search_result( conn, op,
-                       LDAP_SUCCESS,
-                       NULL, NULL, NULL, NULL, 0 );
-
-               rc = 1;
-               goto done;
-       }
-
-       for ( id = bdb2i_idl_firstid( candidates, &cursor ); id != NOID;
-           id = bdb2i_idl_nextid( candidates, &cursor ) )
-       {
-               int             scopeok = 0;
-
-               /* check for abandon */
-               ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
-
-               if ( op->o_abandon ) {
-                       ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
-                       rc = 0;
-                       goto done;
-               }
-
-               ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
-
-               /* check time limit */
-               if ( tlimit != -1 && slap_get_time() > stoptime ) {
-                       send_search_result( conn, op, LDAP_TIMELIMIT_EXCEEDED,
-                               NULL, NULL, v2refs, NULL, nentries );
-                       rc = 0;
-                       goto done;
-               }
-
-               /* get the entry with reader lock */
-               e = bdb2i_id2entry_r( be, id );
-
-               if ( e == NULL ) {
-                       Debug( LDAP_DEBUG_ARGS, "search: candidate %ld not found\n",
-                               id, 0, 0 );
-
-                       goto loop_continue;
-               }
-
-               if ( deref & LDAP_DEREF_SEARCHING && is_entry_alias( e ) ) {
-                       Entry *matched;
-                       int err;
-                       char *text;
-                       
-                       e = deref_entry_r( be, e, &err, &matched, &text );
-
-                       if( e == NULL ) {
-                               e = matched;
-                               goto loop_continue;
-                       }
-
-                       if( e->e_id == id ) {
-                               /* circular loop */
-                               goto loop_continue;
-                       }
-
-                       /* need to skip alias which deref into scope */
-                       if( scope & LDAP_SCOPE_ONELEVEL ) {
-                               char *pdn = dn_parent( NULL, e->e_ndn );
-                               if ( pdn != NULL ) {
-                                       if( strcmp( pdn, realbase ) ) {
-                                               free( pdn );
-                                               goto loop_continue;
-                                       }
-                                       free(pdn);
-                               }
-
-                       } else if ( dn_issuffix( e->e_ndn, realbase ) ) {
-                               /* alias is within scope */
-                               Debug( LDAP_DEBUG_ARGS, "search: \"%s\" in subtree\n",
-                                       e->e_dn, 0, 0 );
-                               goto loop_continue;
-                       }
-
-                       scopeok = 1;
-               }
-
-               /*
-                * if it's a referral, add it to the list of referrals. only do
-                * this for non-base searches, and don't check the filter
-                * explicitly here since it's only a candidate anyway.
-                */
-               if ( !manageDSAit && scope != LDAP_SCOPE_BASE &&
-                       is_entry_referral( e ) )
-               {
-                       struct berval **refs = get_entry_referrals(
-                               be, conn, op, e );
-
-                       send_search_reference( be, conn, op,
-                               e, refs, scope, NULL, &v2refs );
-
-                       ber_bvecfree( refs );
-
-                       goto loop_continue;
-               }
-
-               /* if it matches the filter and scope, send it */
-               if ( test_filter( be, conn, op, e, filter ) == 0 ) {
-                       char    *dn;
-
-                       /* check scope */
-                       if ( !scopeok && scope == LDAP_SCOPE_ONELEVEL ) {
-                               if ( (dn = dn_parent( be, e->e_ndn )) != NULL ) {
-                                       (void) dn_normalize_case( dn );
-                                       scopeok = (dn == realbase)
-                                               ? 1
-                                               : (strcmp( dn, realbase ) ? 0 : 1 );
-                                       free( dn );
-
-                               } else {
-                                       scopeok = (realbase == NULL || *realbase == '\0');
-                               }
-
-                       } else if ( !scopeok && scope == LDAP_SCOPE_SUBTREE ) {
-                               dn = ch_strdup( e->e_ndn );
-                               scopeok = dn_issuffix( dn, realbase );
-                               free( dn );
-
-                       } else {
-                               scopeok = 1;
-                       }
-
-                       if ( scopeok ) {
-                               /* check size limit */
-                               if ( --slimit == -1 ) {
-                                       bdb2i_cache_return_entry_r( &li->li_cache, e );
-                                       send_search_result( conn, op,
-                                               LDAP_SIZELIMIT_EXCEEDED, NULL, NULL,
-                                               v2refs, NULL, nentries );
-                                       rc = 0;
-                                       goto done;
-                               }
-
-                               if (e) {
-                                       switch ( send_search_entry( be, conn, op, e,
-                                               attrs, attrsonly, NULL ) ) {
-                                       case 0:         /* entry sent ok */
-                                               nentries++;
-                                               break;
-                                       case 1:         /* entry not sent */
-                                               break;
-                                       case -1:        /* connection closed */
-                                               bdb2i_cache_return_entry_r( &li->li_cache, e );
-                                               rc = 0;
-                                               goto done;
-                                       }
-                               }
-                       } else {
-                               Debug( LDAP_DEBUG_TRACE, "candidate %ld scope not okay\n",
-                                       id, 0, 0 );
-                       }
-               } else {
-                       Debug( LDAP_DEBUG_TRACE, "candidate %ld does match filter\n",
-                               id, 0, 0 );
-               }
-
-loop_continue:
-               if( e != NULL ) {
-                       /* free reader lock */
-                       bdb2i_cache_return_entry_r( &li->li_cache, e );
-               }
-
-               ldap_pvt_thread_yield();
-       }
-       send_search_result( conn, op,
-               v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
-               NULL, NULL, v2refs, NULL, nentries );
-
-       rc = 0;
-
-done:
-       bdb2i_idl_free( candidates );
-
-       ber_bvecfree( v2refs );
-       if( realbase ) free( realbase );
-
-       return rc;
-}
-
-
-int
-bdb2_back_search(
-    BackendDB  *be,
-    Connection *conn,
-    Operation  *op,
-    char       *base,
-    int                scope,
-    int                deref,
-    int                slimit,
-    int                tlimit,
-    Filter     *filter,
-    char       *filterstr,
-    char       **attrs,
-    int                attrsonly
-)
-{
-       DB_LOCK         lock;
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       struct timeval  time1;
-       int             ret;
-
-       bdb2i_start_timing( be->bd_info, &time1 );
-
-       if ( bdb2i_enter_backend_r( &lock ) != 0 ) {
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-               return( -1 );
-
-       }
-
-       ret = bdb2i_back_search_internal( be, conn, op, base, scope, deref,
-                                       slimit, tlimit, filter, filterstr, attrs, attrsonly );
-
-       (void) bdb2i_leave_backend_r( lock );
-       bdb2i_stop_timing( be->bd_info, time1, "SRCH", conn, op );
-
-       return( ret );
-}
-
-
-static ID_BLOCK *
-base_candidate(
-    Backend    *be,
-       Entry   *e
-)
-{
-       ID_BLOCK                *idl;
-
-       Debug(LDAP_DEBUG_TRACE, "base_candidates: base: \"%s\"\n",
-               e->e_dn, 0, 0);
-
-       idl = bdb2i_idl_alloc( 1 );
-       bdb2i_idl_insert( &idl, e->e_id, 1 );
-
-       return( idl );
-}
-
-static ID_BLOCK *
-search_candidates(
-    Backend    *be,
-    Entry      *e,
-    Filter     *filter,
-    int                scope,
-       int             deref,
-       int             manageDSAit
-)
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       ID_BLOCK                *candidates;
-       Filter          *f, *rf, *af, *lf;
-
-       Debug(LDAP_DEBUG_TRACE, "search_candidates: base=\"%s\" s=%d d=%d\n",
-               e->e_ndn, scope, deref );
-
-       f = NULL;
-
-       if( !manageDSAit ) {
-               /* match referrals */
-               rf = (Filter *) ch_malloc( sizeof(Filter) );
-               rf->f_next = NULL;
-               rf->f_choice = LDAP_FILTER_OR;
-               rf->f_or = (Filter *) ch_malloc( sizeof(Filter) );
-               rf->f_or->f_choice = LDAP_FILTER_EQUALITY;
-               rf->f_or->f_avtype = ch_strdup( "objectclass" );
-               rf->f_or->f_avvalue.bv_val = ch_strdup( "REFERRAL" );
-               rf->f_or->f_avvalue.bv_len = sizeof("REFERRAL")-1;
-               rf->f_or->f_next = filter;
-               f = rf;
-       } else {
-               rf = NULL;
-               f = filter;
-       }
-
-       if( deref & LDAP_DEREF_SEARCHING ) {
-               /* match aliases */
-               af = (Filter *) ch_malloc( sizeof(Filter) );
-               af->f_next = NULL;
-               af->f_choice = LDAP_FILTER_OR;
-               af->f_or = (Filter *) ch_malloc( sizeof(Filter) );
-               af->f_or->f_choice = LDAP_FILTER_EQUALITY;
-               af->f_or->f_avtype = ch_strdup( "objectclass" );
-               af->f_or->f_avvalue.bv_val = ch_strdup( "ALIAS" );
-               af->f_or->f_avvalue.bv_len = sizeof("ALIAS")-1;
-               af->f_or->f_next = f;
-               f = af;
-       } else {
-               af = NULL;
-       }
-
-       if ( scope == LDAP_SCOPE_SUBTREE ) {
-               lf = (Filter *) ch_malloc( sizeof(Filter) );
-               lf->f_next = NULL;
-               lf->f_choice = LDAP_FILTER_AND;
-               lf->f_and = (Filter *) ch_malloc( sizeof(Filter) );
-
-               lf->f_and->f_choice = SLAPD_FILTER_DN_SUBTREE;
-               lf->f_and->f_dn = e->e_ndn;
-
-               lf->f_and->f_next = f;
-               f = lf;
-
-       } else if ( scope == LDAP_SCOPE_ONELEVEL ) {
-               lf = (Filter *) ch_malloc( sizeof(Filter) );
-               lf->f_next = NULL;
-               lf->f_choice = LDAP_FILTER_AND;
-               lf->f_and = (Filter *) ch_malloc( sizeof(Filter) );
-
-               lf->f_and->f_choice = SLAPD_FILTER_DN_ONE;
-               lf->f_and->f_dn = e->e_ndn;
-
-               lf->f_and->f_next = f;
-               f = lf;
-
-       } else {
-               lf = NULL;
-       }
-
-       candidates = bdb2i_filter_candidates( be, f );
-
-       /* free up filter additions we allocated above */
-       if( lf != NULL ) {
-               free( lf->f_and );
-               free( lf );
-       }
-
-       if( af != NULL ) {
-               af->f_or->f_next = NULL;
-               filter_free( af );
-       }
-
-       if( rf != NULL ) {
-               rf->f_or->f_next = NULL;
-               filter_free( rf );
-       }
-
-       return( candidates );
-}
diff --git a/servers/slapd/back-bdb2/startup.c b/servers/slapd/back-bdb2/startup.c
deleted file mode 100644 (file)
index 3bf3b09..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-/* startup.c - startup/shutdown bdb2 backend */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-#include <ac/unistd.h>
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#ifdef HAVE_DIRECT_H
-#include <direct.h>
-#endif
-
-#include "slap.h"
-#include "back-bdb2.h"
-
-#include "db.h"
-
-static void remove_old_locks( char *home );
-
-
-static void
-bdb2i_db_errcall( const char *prefix, char *message )
-{
-       Debug( LDAP_DEBUG_ANY, "bdb2_db_errcall(): %s %s", prefix, message, 0 );
-}
-
-
-/*  startup/shutdown per backend type  */
-
-static int
-bdb2i_back_startup_internal(
-    BackendInfo        *bi
-)
-{
-       struct ldbtype  *lty = (struct ldbtype *) bi->bi_private;
-       u_int32_t               envFlags;
-       int             err      = 0;
-       char            *home;
-
-       /*  set the flags for a full-feldged transaction schema  */
-       envFlags = ( DB_CREATE | DB_THREAD | DB_INIT_TXN | DB_INIT_LOG |
-                                       DB_INIT_LOCK | DB_INIT_MPOOL );
-
-       /*  make sure, dbhome is an absolute path  */
-       if ( *lty->lty_dbhome != *LDAP_DIRSEP ) {
-               char   cwd[MAXPATHLEN];
-
-               (void) getcwd( cwd, MAXPATHLEN );
-               sprintf( cwd, "%s" LDAP_DIRSEP "%s",
-                       cwd, lty->lty_dbhome );
-               free( lty->lty_dbhome );
-               lty->lty_dbhome = ch_strdup( cwd );
-
-       }
-       home = lty->lty_dbhome;
-
-       /*  general initialization of the environment  */
-       memset( &bdb2i_dbEnv, 0, sizeof( DB_ENV ));
-       bdb2i_dbEnv.db_errcall = bdb2i_db_errcall;
-       bdb2i_dbEnv.db_errpfx  = "==>";
-
-       /*  initialize the lock subsystem  */
-       bdb2i_dbEnv.lk_max     = 0;
-
-       /*  remove old locking tables  */
-       remove_old_locks( home );
-
-       /*  initialize the mpool subsystem  */
-       bdb2i_dbEnv.mp_size   = lty->lty_mpsize;
-
-       /*  now do the db_appinit  */
-       if ( ( err = db_appinit( home, NULL, &bdb2i_dbEnv, envFlags )) ) {
-               char  error[BUFSIZ];
-
-               if ( err < 0 ) sprintf( error, "%ld\n", (long) err );
-               else           sprintf( error, "%s\n", strerror( err ));
-
-               Debug( LDAP_DEBUG_ANY,
-                               "bdb2i_back_startup(): FATAL error in db_appinit() : %s\n",
-                               error, 0, 0 );
-               return( 1 );
-
-       }
-
-       return 0;
-}
-
-
-static int
-bdb2i_back_shutdown_internal(
-    BackendInfo        *bi
-)
-{
-       struct ldbtype  *lty = (struct ldbtype *) bi->bi_private;
-       int              err;
-
-       /*  remove old locking tables  */
-       bdb2i_dbEnv.db_errpfx  = "bdb2i_back_shutdown(): lock_unlink:";
-       if ( ( err = lock_unlink( NULL, 1, &bdb2i_dbEnv )) != 0 )
-               Debug( LDAP_DEBUG_ANY, "bdb2i_back_shutdown(): lock_unlink: %s\n",
-                                       strerror( err ), 0, 0);
-
-       /*  remove old memory pool  */
-       bdb2i_dbEnv.db_errpfx  = "bdb2i_back_shutdown(): memp_unlink:";
-       if ( ( err = memp_unlink( NULL, 1, &bdb2i_dbEnv )) != 0 )
-               Debug( LDAP_DEBUG_ANY, "bdb2i_back_shutdown(): memp_unlink: %s\n",
-                                       strerror( err ), 0, 0);
-
-       (void) db_appexit( &bdb2i_dbEnv );
-
-       return( 0 );
-}
-
-
-int
-bdb2i_back_startup(
-    BackendInfo        *bi
-)
-{
-       struct timeval  time1;
-       int             ret;
-
-       bdb2i_start_timing( bi, &time1 );
-
-       ret = bdb2i_back_startup_internal( bi );
-       bdb2i_stop_timing( bi, time1, "BE-START", NULL, NULL );
-
-       return( ret );
-}
-
-
-int
-bdb2i_back_shutdown(
-    BackendInfo        *bi
-)
-{
-       struct timeval  time1;
-       int             ret;
-
-       bdb2i_start_timing( bi, &time1 );
-
-       ret = bdb2i_back_shutdown_internal( bi );
-       bdb2i_stop_timing( bi, time1, "BE-SHUTDOWN", NULL, NULL );
-
-       return( ret );
-}
-
-
-/*  startup/shutdown per backend database  */
-
-static int
-bdb2i_back_db_startup_internal(
-    BackendDB  *be
-)
-{
-       struct ldbminfo  *li = (struct ldbminfo *) be->be_private;
-
-       /*  if the data directory is not an absolute path, have it relative
-        to the current working directory (which should not be configured !)  */
-       if ( *li->li_directory != *LDAP_DIRSEP ) {
-               char   cwd[MAXPATHLEN];
-
-               (void) getcwd( cwd, MAXPATHLEN );
-               sprintf( cwd, "%s" LDAP_DIRSEP "%s",
-                       cwd, li->li_directory );
-
-               free( li->li_directory );
-               li->li_directory = ch_strdup( cwd );
-
-       }
-
-       /*  if there are more index files, add them to the DB file list  */
-       if ( bdb2i_check_additional_attr_index( li ) != 0 )
-               return 1;
-
-       /*  now open all DB files  */
-       if ( bdb2i_txn_open_files( be ) != 0 )
-               return 1;
-
-       return 0;
-}
-
-
-static int
-bdb2i_back_db_shutdown_internal(
-    BackendDB  *be
-)
-{
-       return 0;
-}
-
-
-int
-bdb2_back_db_startup(
-    BackendDB  *be
-)
-{
-       struct timeval  time1;
-       int             ret;
-
-       bdb2i_start_timing( be->bd_info, &time1 );
-
-       ret = bdb2i_back_db_startup_internal( be );
-       bdb2i_stop_timing( be->bd_info, time1, "DB-START", NULL, NULL );
-
-       return( ret );
-}
-
-
-int
-bdb2_back_db_shutdown(
-    BackendDB  *be
-)
-{
-       struct timeval  time1;
-       int             ret;
-
-       bdb2i_start_timing( be->bd_info, &time1 );
-
-       ret = bdb2i_back_db_shutdown_internal( be );
-       bdb2i_stop_timing( be->bd_info, time1, "DB-SHUTDOWN", NULL, NULL );
-
-       return( ret );
-}
-
-
-static void
-remove_old_locks( char *home )
-{
-       DB_ENV  dbEnv;
-       int     err;
-
-       memset( &dbEnv, 0, sizeof( DB_ENV ));
-       dbEnv.db_errcall = bdb2i_db_errcall;
-       dbEnv.db_errpfx  = "remove_old_locks(): db_appinit:";
-       dbEnv.lk_max     = 0;
-
-       if ( ( err = db_appinit( home, NULL, &dbEnv, 0 )) != 0 )
-               Debug( LDAP_DEBUG_ANY, "remove_old_locks(): db_appinit: %s\n",
-                                       strerror( err ), 0, 0);
-
-       dbEnv.db_errpfx  = "remove_old_locks(): lock_unlink:";
-       if ( ( err = lock_unlink( NULL, 1, &dbEnv )) != 0 )
-               Debug( LDAP_DEBUG_ANY, "remove_old_locks(): lock_unlink: %s\n",
-                                       strerror( err ), 0, 0);
-
-       dbEnv.db_errpfx  = "remove_old_locks(): db_appexit:";
-       if ( ( err = db_appexit( &dbEnv )) != 0 )
-               Debug( LDAP_DEBUG_ANY, "remove_old_locks(): db_appexit: %s\n",
-                                       strerror( err ), 0, 0);
-
-}
-
-
diff --git a/servers/slapd/back-bdb2/timing.c b/servers/slapd/back-bdb2/timing.c
deleted file mode 100644 (file)
index c1d6605..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/* timing.c - timing bdb2 backend */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/time.h>
-#include <ac/unistd.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-
-
-static char *
-bdb2i_elapsed( struct timeval firsttime,  struct timeval secondtime )
-{
-    long int elapsedmicrosec, elapsedsec;
-    char elapsed_string[BUFSIZ];
-    
-    elapsedsec = secondtime.tv_sec - firsttime.tv_sec;
-    elapsedmicrosec = secondtime.tv_usec - firsttime.tv_usec;
-    if(elapsedmicrosec < 0) {
-        elapsedmicrosec += 1000000;
-        elapsedsec -= 1;
-    }
-
-    sprintf( elapsed_string, "%ld.%.6ld", elapsedsec, elapsedmicrosec );
-    return( ch_strdup( elapsed_string ));
-}
-
-
-void
-bdb2i_uncond_start_timing(
-       struct timeval  *time1
-)
-{
-       gettimeofday( time1, NULL );
-}
-
-
-void
-bdb2i_uncond_stop_timing(
-       struct timeval  time1,
-       char            *func,
-       Connection      *conn,
-       Operation       *op,
-       int             level
-)
-{
-       struct timeval  time2;
-       char            *elapsed_time;
-       char            buf[BUFSIZ];
-
-       *buf = '\0';
-
-       gettimeofday( &time2, NULL);
-       elapsed_time = bdb2i_elapsed( time1, time2 );
-
-       if ( conn != NULL ) sprintf( buf, "conn=%d ", conn->c_connid );
-       if ( op != NULL )   sprintf( buf, "%sop=%d ", buf, op->o_opid );
-
-       Debug( level, "%s%s elapsed=%s\n", buf, func, elapsed_time );
-
-       free( elapsed_time );
-
-}
-
-
diff --git a/servers/slapd/back-bdb2/tools.c b/servers/slapd/back-bdb2/tools.c
deleted file mode 100644 (file)
index 662381d..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-/* tools.c - tools for slap tools */
-/* $OpenLDAP$ */
-/*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-
-static LDBMCursor *cursorp = NULL;
-static DBCache *id2entry = NULL;
-
-int bdb2_tool_entry_open(
-       BackendDB *be, int mode )
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       int flags;
-
-       assert( slapMode & SLAP_TOOL_MODE );
-       assert( id2entry == NULL );
-
-       switch( mode ) {
-       case 1:
-               flags = LDBM_WRCREAT;
-               break;
-       case 2:
-#ifdef TRUNCATE_MODE
-               flags = LDBM_NEWDB;
-#else
-               flags = LDBM_WRCREAT;
-#endif
-               break;
-       default:
-               flags = LDBM_READER;
-       }
-
-       li->li_dbcachewsync = 0;
-
-       if ( (id2entry = bdb2i_cache_open( be, "id2entry", BDB2_SUFFIX, flags ))
-           == NULL ) {
-               Debug( LDAP_DEBUG_ANY, "Could not open/create id2entry" BDB2_SUFFIX "\n",
-                   0, 0, 0 );
-               return( -1 );
-       }
-
-       return 0;
-}
-
-int bdb2_tool_entry_close(
-       BackendDB *be )
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-
-       assert( slapMode & SLAP_TOOL_MODE );
-       assert( id2entry != NULL );
-
-       bdb2i_cache_close( be, id2entry );
-       li->li_dbcachewsync = 1;
-       id2entry = NULL;
-
-       return 0;
-}
-
-ID bdb2_tool_entry_first(
-       BackendDB *be )
-{
-       Datum key;
-       ID id;
-
-       assert( slapMode & SLAP_TOOL_MODE );
-       assert( id2entry != NULL );
-
-       key = ldbm_firstkey( id2entry->dbc_db, &cursorp );
-
-       if( key.dptr == NULL ) {
-               return NOID;
-       }
-
-       memcpy( &id, key.dptr, key.dsize );
-
-       ldbm_datum_free( id2entry->dbc_db, key );
-
-       return id;
-}
-
-ID bdb2_tool_entry_next(
-       BackendDB *be )
-{
-       Datum key;
-       ID id;
-
-       assert( slapMode & SLAP_TOOL_MODE );
-       assert( id2entry != NULL );
-
-       /* allow for NEXTID */
-       ldbm_datum_init( key );
-
-       key = ldbm_nextkey( id2entry->dbc_db, key, cursorp );
-
-       if( key.dptr == NULL ) {
-               return NOID;
-       }
-
-       memcpy( &id, key.dptr, key.dsize );
-
-       ldbm_datum_free( id2entry->dbc_db, key );
-
-       return id;
-}
-
-Entry* bdb2_tool_entry_get( BackendDB *be, ID id )
-{
-       Entry *e;
-       Datum key, data;
-       assert( slapMode & SLAP_TOOL_MODE );
-       assert( id2entry != NULL );
-
-       ldbm_datum_init( key );
-
-       key.dptr = (char *) &id;
-       key.dsize = sizeof(ID);
-
-       data = bdb2i_cache_fetch( id2entry, key );
-
-       if ( data.dptr == NULL ) {
-               return NULL;
-       }
-
-       e = str2entry( data.dptr );
-       ldbm_datum_free( id2entry->dbc_db, data );
-
-       return e;
-}
-
-ID bdb2_tool_entry_put(
-       BackendDB *be,
-       Entry *e )
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       Datum key, data;
-       int rc, len;
-
-       assert( slapMode & SLAP_TOOL_MODE );
-       assert( id2entry != NULL );
-
-       if( bdb2i_next_id_get( be ) == NOID ) {
-               return NOID;
-       }
-
-       e->e_id = li->li_nextid++;
-
-       Debug( LDAP_DEBUG_TRACE, "=> bdb2_tool_entry_put( %ld, \"%s\" )\n",
-               e->e_id, e->e_dn, 0 );
-
-       rc = bdb2i_index_add_entry( be, e );
-
-       if( rc != 0 ) {
-               return NOID;
-       }
-
-       rc = bdb2i_dn2id_add( be, e->e_ndn, e->e_id );
-
-       if( rc != 0 ) {
-               return NOID;
-       }
-
-       ldbm_datum_init( key );
-       ldbm_datum_init( data );
-
-       key.dptr = (char *) &e->e_id;
-       key.dsize = sizeof(ID);
-
-       data.dptr = entry2str( e, &len );
-       data.dsize = len + 1;
-
-       /* store it */
-       rc = bdb2i_cache_store( id2entry, key, data, LDBM_REPLACE );
-
-       if( rc != 0 ) {
-               (void) bdb2i_dn2id_delete( be, e->e_ndn, e->e_id );
-               return NOID;
-       }
-
-       return e->e_id;
-}
-
-int bdb2_tool_index_attr(
-       BackendDB *be,
-       char* type )
-{
-       static DBCache *db = NULL;
-       int indexmask, syntaxmask;
-       char * at_cn;
-
-       assert( slapMode & SLAP_TOOL_MODE );
-
-       bdb2i_attr_masks( be->be_private, type, &indexmask, &syntaxmask );
-
-       attr_normalize( type );
-       at_cn = at_canonical_name( type );
-
-       if ( (db = bdb2i_cache_open( be, at_cn, LDBM_SUFFIX, LDBM_NEWDB ))
-           == NULL ) {
-               Debug( LDAP_DEBUG_ANY,
-                   "<= index_read NULL (could not open %s%s)\n", at_cn,
-                   BDB2_SUFFIX, 0 );
-               return 0;
-       }
-
-       bdb2i_cache_close( be, db );
-
-       return indexmask != 0;
-}
-
-int bdb2_tool_index_change(
-       BackendDB *be,
-       char* type,
-       struct berval **bv,
-       ID id,
-       int op )
-{
-       assert( slapMode & SLAP_TOOL_MODE );
-
-       bdb2i_index_add_values( be,
-               type, bv, id );
-
-       return 0;
-}
-
-int bdb2_tool_sync( BackendDB *be )
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-
-       assert( slapMode & SLAP_TOOL_MODE );
-
-       if ( li->li_nextid != NOID ) {
-               bdb2i_next_id_save( be );
-       }
-
-       return 0;
-}
diff --git a/servers/slapd/back-bdb2/txn.c b/servers/slapd/back-bdb2/txn.c
deleted file mode 100644 (file)
index 2a71138..0000000
+++ /dev/null
@@ -1,825 +0,0 @@
-/* txn.c - TP support functions of the bdb2 backend */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#include "txn.h"
-
-/*  default DB files  */
-char  *bdb2i_fixed_filenames[] = {
-       "id2entry",
-       "dn2id",
-       "objectclass",
-       NULL
-};
-
-
-int
-bdb2i_txn_head_init( BDB2_TXN_HEAD *head )
-{
-       int             dbFile;
-       BDB2_TXN_FILES  **fileNodeH;
-
-       /*  for each fixed DB file allocate a file descriptor node and
-        initialize the file's name  */
-       fileNodeH = &head->dbFiles;
-
-       for ( dbFile = 0; bdb2i_fixed_filenames[dbFile] != NULL; dbFile++ ) {
-               char fileName[MAXPATHLEN];
-
-               *fileNodeH = (BDB2_TXN_FILES *) ch_calloc( 1, sizeof( BDB2_TXN_FILES ));
-
-               if ( *fileNodeH == NULL ) {
-                       Debug( LDAP_DEBUG_ANY, "bdb2i_txn_head_init(): out of memory!\n",
-                                       0, 0, 0 );
-                       return( 1 );
-               }
-
-               sprintf( fileName, "%s" BDB2_SUFFIX, bdb2i_fixed_filenames[dbFile] );
-               (*fileNodeH)->dbc_name = ch_strdup( fileName );
-
-               fileNodeH = &(*fileNodeH)->next;
-
-       }
-
-       /*  set defaults for checkpointing  */
-       head->txn_log  = BDB2_TXN_CHKP_MAX_LOG;
-       head->txn_time = BDB2_TXN_CHKP_MAX_TIME;
-
-       /*  initialize the txn_dirty_mutex  */
-       ldap_pvt_thread_mutex_init( &txn_dirty_mutex );
-
-       return 0;
-}
-
-
-static void
-bdb2i_init_db_file_cache( struct ldbminfo *li, BDB2_TXN_FILES *fileinfo )
-{
-       struct stat st;
-       char        buf[MAXPATHLEN];
-
-       fileinfo->dbc_refcnt = 1;
-
-       sprintf( buf, "%s" LDAP_DIRSEP "%s",
-               li->li_directory, fileinfo->dbc_name );
-
-       if ( stat( buf, &st ) == 0 ) {
-               fileinfo->dbc_blksize = st.st_blksize;
-       } else {
-               fileinfo->dbc_blksize = DEFAULT_BLOCKSIZE;
-       }
-
-       fileinfo->dbc_maxids = ( fileinfo->dbc_blksize / sizeof( ID )) -
-                       ID_BLOCK_IDS_OFFSET;
-       fileinfo->dbc_maxindirect = ( SLAPD_LDBM_MIN_MAXIDS /
-               fileinfo->dbc_maxids ) + 1;
-
-}
-
-
-/*  create a DB file cache entry for a specified index attribute
-       (if not already done); the function is called during config
-       file read for all index'ed attributes; if "default" index with
-       a non-none selection is given, this is remembered for run-time
-       extension of the list of index files; the function is also
-       called before add or modify operations to check for putative
-       new "default" index files; at that time, files are also opened
-*/
-void
-bdb2i_txn_attr_config(
-       struct ldbminfo  *li,
-       char             *attr,
-       int              open )
-{
-       BDB2_TXN_HEAD  *head = &li->li_txn_head;
-
-       /*  the "attribute" 'default' is special  */
-       if ( strcasecmp( attr, "default" )) {
-
-               /*  create a new index file node, if the index is not known  already  */
-               BDB2_TXN_FILES  **fileNodeH;
-               char            fileName[MAXPATHLEN];
-
-               sprintf( fileName, "%s%s", attr,  BDB2_SUFFIX );
-
-               /*  search for the end of the list or a node describing
-                       the current attribute  */
-               for ( fileNodeH = &head->dbFiles;
-                               ( *fileNodeH && strcasecmp( (*fileNodeH)->dbc_name, fileName ));
-                               fileNodeH = &(*fileNodeH)->next ) {
-
-               }
-
-               /*  unless we have that attribute already...  */
-               if ( *fileNodeH == NULL ) {
-                       BDB2_TXN_FILES *p;
-
-                       Debug( LDAP_DEBUG_TRACE,
-                                       "bdb2i_txn_attr_config(): adding node for \"%s\"\n",
-                                       fileName, 0, 0 );
-
-                       /*  if we're out of memory, we have to see, how to exit...  */
-                       if ( ( *fileNodeH = p = (BDB2_TXN_FILES *)
-                                       ch_calloc( 1, sizeof( BDB2_TXN_FILES )) ) == NULL ) {
-
-                               Debug( LDAP_DEBUG_ANY,
-                                               "bdb2i_txn_attr_config(): out of memory -- FATAL.\n",
-                                               0, 0, 0 );
-
-                               /*  during configuration (no files are opened)
-                                       we can just exit, otherwise we kill ourself and
-                                       hope to shutdown cleanly...  */
-                               if ( open ) {
-                                       pthread_kill( pthread_self(), LDAP_SIGUSR1 );
-                               } else {
-                                       exit( EXIT_FAILURE );
-                               }
-                       }
-
-                       p->dbc_name = ch_strdup( fileName );
-
-                       /*  if requested for, we have to open the DB file  */
-                       /*  BUT NOT "objectclass", 'cause that's a default index !  */
-                       if ( open && strcasecmp( fileName, "objectclass" )) {
-
-                               /*  re-use filename to get the complete path  */
-                               sprintf( fileName, "%s" LDAP_DIRSEP "%s",
-                                                       li->li_directory, p->dbc_name );
-
-                               /*  since we have an mpool, we should not define a cache size */
-                               p->dbc_db = bdb2i_db_open( fileName, DB_TYPE,
-                                                                       LDBM_WRCREAT, li->li_mode, 0 );
-
-                               /*  if the files could not be opened, something is wrong;
-                                       complain  */
-                               if ( p->dbc_db == NULL ) {
-
-                                       Debug( LDAP_DEBUG_ANY,
-                               "bdb2i_txn_open_files(): couldn't open file \"%s\" -- FATAL.\n",
-                                               p->dbc_name, 0, 0 );
-                                       pthread_kill( pthread_self(), LDAP_SIGUSR1 );
-
-                               }
-
-                               bdb2i_init_db_file_cache( li, p );
-
-                               Debug( LDAP_DEBUG_TRACE,
-                                       "bdb2i_txn_attr_config(): NEW INDEX FILE \"%s\"\n",
-                                       p->dbc_name, 0, 0 );
-
-                       }
-               }
-
-       } else {  /*  it is "attribute" 'default'  */
-
-               head->withDefIDX = BDB2_WITH_DEF_IDX;
-
-       }
-}
-
-
-/*  open the NEXTID file for read/write; if it does not exist,
-       create it (access to the file must be preceeded by a rewind)
-*/
-static int
-bdb2i_open_nextid( BackendDB *be )
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       BDB2_TXN_HEAD   *head = &li->li_txn_head;
-       LDBM            db = NULL;
-       DB_INFO                 dbinfo;
-       char            fileName[MAXPATHLEN];
-
-       sprintf( fileName, "%s" LDAP_DIRSEP "%s",
-                               li->li_directory, NEXTID_NAME );
-
-       /*  try to open the file for read and write  */
-       memset( &dbinfo, 0, sizeof( dbinfo ));
-       dbinfo.db_pagesize  = DEFAULT_DB_PAGE_SIZE;
-       dbinfo.db_malloc    = ldbm_malloc;
-
-       (void) db_open( fileName, DB_RECNO, DB_CREATE | DB_THREAD,
-                                       li->li_mode, &bdb2i_dbEnv, &dbinfo, &db );
-
-       if ( db == NULL ) {
-
-                       Debug( LDAP_DEBUG_ANY,
-                               "bdb2i_open_nextid: could not open \"%s\"\n",
-                               NEXTID_NAME, 0, 0 );
-                       return( -1 );
-
-       }
-
-       /*  the file is open for read/write  */
-       head->nextidFile = db;
-
-       return( 0 );
-}
-
-
-/*  open all DB during startup of the backend (necessary due to TP)
-       additional files may be opened during slapd life-time due to
-       default indexes (must be configured in slapd.conf;
-       see bdb2i_txn_attr_config)
-       also, set the counter and timer for TP checkpointing
-*/
-int
-bdb2i_txn_open_files( BackendDB *be )
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       BDB2_TXN_HEAD   *head = &li->li_txn_head;
-       BDB2_TXN_FILES  *dbFile;
-       int             rc;
-
-       for ( dbFile = head->dbFiles; dbFile; dbFile = dbFile->next ) {
-               char   fileName[MAXPATHLEN];
-
-               sprintf( fileName, "%s" LDAP_DIRSEP "%s",
-                                       li->li_directory, dbFile->dbc_name );
-
-               /*  since we have an mpool, we should not define a cache size */
-               dbFile->dbc_db = bdb2i_db_open( fileName, DB_TYPE,
-                                                       LDBM_WRCREAT, li->li_mode, 0 );
-
-               /*  if the files could not be opened, something is wrong; complain  */
-               if ( dbFile->dbc_db == NULL ) {
-
-                       Debug( LDAP_DEBUG_ANY,
-                               "bdb2i_txn_open_files(): couldn't open file \"%s\" -- FATAL.\n",
-                               dbFile->dbc_name, 0, 0 );
-                       return( -1 );
-
-               }
-
-               /*  initialize the file info  */
-               bdb2i_init_db_file_cache( li, dbFile );
-
-               Debug( LDAP_DEBUG_TRACE, "bdb2i_txn_open_files(): OPEN INDEX \"%s\"\n",
-                               dbFile->dbc_name, 0, 0 );
-
-       }
-
-       rc = bdb2i_open_nextid( be );
-
-       txn_max_pending_log  = head->txn_log;
-       txn_max_pending_time = head->txn_time;
-
-       return rc;
-}
-
-
-/*  close all DB files during shutdown of the backend  */
-void
-bdb2i_txn_close_files( BackendDB *be )
-{
-       struct ldbminfo  *li = (struct ldbminfo *) be->be_private;
-       BDB2_TXN_HEAD    *head = &li->li_txn_head;
-       BDB2_TXN_FILES   *dbFile;
-
-       for ( dbFile = head->dbFiles; dbFile; dbFile = dbFile->next ) {
-
-               ldbm_close( dbFile->dbc_db );
-
-       }
-
-       if ( head->nextidFile )
-               ldbm_close( head->nextidFile );
-
-}
-
-
-/*  get the db_cache structure associated with a specified
-       DB file (replaces the on-the-fly opening of files in cache_open()
-*/
-BDB2_TXN_FILES *
-bdb2i_get_db_file_cache( struct ldbminfo *li, char *name )
-{
-       BDB2_TXN_HEAD  *head = &li->li_txn_head;
-       BDB2_TXN_FILES *dbFile;
-       int            dbFileNum;
-
-       Debug( LDAP_DEBUG_TRACE, "bdb2i_get_db_file_cache(): looking for file %s\n",
-                       name, 0, 0 );
-
-       for ( dbFile = head->dbFiles; dbFile; dbFile = dbFile->next ) {
-
-               /*  we've got it  */
-               if ( !strcasecmp( dbFile->dbc_name, name )) return( dbFile );
-
-       }
-
-       Debug( LDAP_DEBUG_ANY,
-               "bdb2i_get_db_file_cache(): UPS, could't find \"%s\" \n", name, 0, 0 );
-
-       /*  ups, we couldn't find the file  */
-       return( NULL );
-
-}
-
-
-/*  check for new attribute indexes, that might have been created
-    during former runs of slapd  */
-/*  this is called during startup of the slapd server  */
-int
-bdb2i_check_additional_attr_index( struct ldbminfo *li )
-{
-       DIR            *datadir;
-       struct dirent  *file;
-
-       if ( ( datadir = opendir( li->li_directory ) ) == NULL ) {
-               int err = errno;
-
-               Debug( LDAP_DEBUG_ANY,
-       "bdb2i_check_additional_attr_index(): ERROR while opening datadir: %s\n",
-                               strerror( err ), 0, 0 );
-               return( 1 );
-
-       }
-
-       for ( file = readdir( datadir ); file; file = readdir( datadir )) {
-               char  filename[MAXPATHLEN];
-               int   namelen;
-
-               strcpy( filename, file->d_name );
-               namelen = strlen( filename );
-
-               if ( namelen > strlen( BDB2_SUFFIX )) {
-
-                       if ( !strcasecmp( filename + namelen - strlen( BDB2_SUFFIX ),
-                                                       BDB2_SUFFIX )) {
-
-                               *(filename + namelen - strlen( BDB2_SUFFIX )) = '\0';
-                               bdb2i_txn_attr_config( li, filename, 0 );
-
-                               Debug( LDAP_DEBUG_TRACE, "INDEX FILE: %s\n", filename, 0, 0 );
-
-                       }
-
-               }
-
-       }
-
-       closedir( datadir );
-
-       return 0;
-}
-
-
-/*  check for the addition of new attribute indexes during add  */
-/*  this is called after startup of the slapd server  */
-/*  DON'T WORRY ABOUT ACCESS RIGHTS, THAT MIGHT PREVENT US
-       FROM ADDING ATTRIBUTES LATER ON  */
-void
-bdb2i_check_default_attr_index_add( struct ldbminfo *li, Entry *e )
-{
-       BDB2_TXN_HEAD  *head = &li->li_txn_head;
-
-       if ( head->withDefIDX == BDB2_WITH_DEF_IDX ) {
-               Attribute   *ap;
-
-               for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) {
-                       if ( strcasecmp( ap->a_type, "objectclass" ))
-                               bdb2i_txn_attr_config( li, ap->a_type, 1 );
-               }
-       }
-}
-
-
-/*  check for the addition of new attribute indexes during modify  */
-/*  this is called after startup of the slapd server  */
-/*  DON'T WORRY ABOUT ACCESS RIGHTS, THAT MIGHT PREVENT US
-       FROM ADDING ATTRIBUTES LATER ON  */
-void
-bdb2i_check_default_attr_index_mod( struct ldbminfo *li, LDAPModList *modlist )
-{
-       BDB2_TXN_HEAD  *head = &li->li_txn_head;
-
-       if ( head->withDefIDX == BDB2_WITH_DEF_IDX ) {
-               LDAPModList *ml;
-               char  *default_attrs[] = { "modifytimestamp", "modifiersname", NULL };
-               int   attr;
-
-               for ( ml = modlist; ml != NULL; ml = ml->ml_next ) {
-                       LDAPMod *mod = &ml->ml_mod;
-
-                       if (( mod->mod_op & ~LDAP_MOD_BVALUES ) == LDAP_MOD_ADD )
-                               if ( strcasecmp( mod->mod_type, "objectclass" ))
-                                       bdb2i_txn_attr_config( li, mod->mod_type, 1 );
-               }
-
-               /*  these attributes are default when modifying  */
-               for ( attr = 0; default_attrs[attr]; attr++ ) {
-                       bdb2i_txn_attr_config( li, default_attrs[attr], 1 );
-               }
-       }
-}
-
-
-/*  get the next ID from the NEXTID file  */
-ID
-bdb2i_get_nextid( BackendDB *be )
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       BDB2_TXN_HEAD   *head = &li->li_txn_head;
-       ID                              id;
-       Datum                   key;
-       Datum                   data;
-       db_recno_t              rec = NEXTID_RECNO;
-
-       ldbm_datum_init( key );
-       ldbm_datum_init( data );
-
-       key.data = &rec;
-       key.size = sizeof( rec );
-
-       data = bdb2i_db_fetch( head->nextidFile, key );
-       if ( data.data == NULL ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "next_id_read: could not get nextid from \"%s\"\n",
-                       NEXTID_NAME, 0, 0 );
-               return NOID;
-       }
-
-       id = atol( data.data );
-       ldbm_datum_free( head->nextidFile, data );
-
-       if ( id < 1 ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "next_id_read %ld: return non-positive integer\n",
-                       id, 0, 0 );
-               return NOID;
-       }
-
-       return( id );
-}
-
-
-int
-bdb2i_put_nextid( BackendDB *be, ID id )
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       BDB2_TXN_HEAD   *head = &li->li_txn_head;
-       int                             rc, flags;
-       Datum                   key;
-       Datum                   data;
-       db_recno_t              rec = NEXTID_RECNO;
-       char                    buf[20];
-
-       sprintf( buf, "%ld\n", id );
-
-       ldbm_datum_init( key );
-       ldbm_datum_init( data );
-
-       key.data = &rec;
-       key.size = sizeof( rec );
-
-       data.data = &buf;
-       data.size = sizeof( buf );
-
-       flags = LDBM_REPLACE;
-       if ( li->li_dbcachewsync ) flags |= LDBM_SYNC;
-
-       if (( rc = bdb2i_db_store( head->nextidFile, key, data, flags )) != 0 ) {
-               Debug( LDAP_DEBUG_ANY, "next_id_write(%ld): store failed (%d)\n",
-                       id, rc, 0 );
-               return( -1 );
-       }
-
-       return( rc );
-}
-
-
-/*  BDB2 backend-private functions of libldbm  */
-LDBM
-bdb2i_db_open(
-       char *name,
-       int type,
-       int rw,
-       int mode,
-       int dbcachesize )
-{
-       LDBM            ret = NULL;
-       DB_INFO         dbinfo;
-
-       memset( &dbinfo, 0, sizeof( dbinfo ));
-       if ( bdb2i_dbEnv.mp_info == NULL )
-               dbinfo.db_cachesize = dbcachesize;
-       dbinfo.db_pagesize  = DEFAULT_DB_PAGE_SIZE;
-       dbinfo.db_malloc    = ldbm_malloc;
-
-       (void) db_open( name, type, rw, mode, &bdb2i_dbEnv, &dbinfo, &ret );
-
-       return( ret );
-}
-
-
-int
-bdb2i_db_store( LDBM ldbm, Datum key, Datum data, int flags )
-{
-       int     rc;
-
-       rc = (*ldbm->put)( ldbm, txnid, &key, &data, flags & ~LDBM_SYNC );
-       rc = (-1 ) * rc;
-
-       if ( txnid != NULL ) {
-
-               /*  if the store was OK, set the dirty flag,
-                       otherwise set the abort flag  */
-               if ( rc == 0 ) {
-
-                       txn_dirty = 1;
-
-               } else {
-
-                       Debug( LDAP_DEBUG_ANY,
-                               "bdb2i_db_store: transaction failed: aborted.\n",
-                               0, 0, 0 );
-                       txn_do_abort = 1;
-
-               }
-       }
-
-       return( rc );
-}
-
-
-int
-bdb2i_db_delete( LDBM ldbm, Datum key )
-{
-       int     rc;
-
-       rc = (*ldbm->del)( ldbm, txnid, &key, 0 );
-       rc = (-1 ) * rc;
-
-       if ( txnid != NULL ) {
-
-               /*  if the delete was OK, set the dirty flag,
-                       otherwise set the abort flag  */
-               if ( rc == 0 ) {
-
-                       txn_dirty = 1;
-
-               } else {
-
-                       Debug( LDAP_DEBUG_ANY,
-                               "bdb2i_db_delete: transaction failed: aborted.\n",
-                               0, 0, 0 );
-                       txn_do_abort = 1;
-
-               }
-       }
-
-       return( rc );
-}
-
-
-Datum
-bdb2i_db_fetch( LDBM ldbm, Datum key )
-{
-       Datum   data;
-       int     rc;
-
-       ldbm_datum_init( data );
-       data.flags = DB_DBT_MALLOC;
-
-       if ( (rc = (*ldbm->get)( ldbm, txnid, &key, &data, 0 )) != 0 ) {
-               if (( txnid != NULL ) && ( rc != DB_NOTFOUND )) {
-
-                       Debug( LDAP_DEBUG_ANY,
-                               "bdb2i_db_fetch: transaction failed: aborted.\n",
-                               0, 0, 0 );
-                       txn_do_abort = 1;
-
-               }
-               if ( data.dptr ) free( data.dptr );
-               data.dptr = NULL;
-               data.dsize = 0;
-       }
-
-       return( data );
-}
-
-
-Datum
-bdb2i_db_firstkey( LDBM ldbm, DBC **dbch )
-{
-       Datum   key, data;
-       int             rc;
-       DBC             *dbci;
-
-       ldbm_datum_init( key );
-       ldbm_datum_init( data );
-
-       key.flags = data.flags = DB_DBT_MALLOC;
-
-#if defined( DB_VERSION_MAJOR ) && defined( DB_VERSION_MINOR ) && \
-   DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6
-
-       if ( (*ldbm->cursor)( ldbm, txnid, &dbci ))
-
-#else
-
-       if ( (*ldbm->cursor)( ldbm, txnid, &dbci, 0 ))
-
-#endif
-       {
-               if ( txnid != NULL ) {
-
-                       Debug( LDAP_DEBUG_ANY,
-                               "bdb2i_db_firstkey: transaction failed: aborted.\n",
-                               0, 0, 0 );
-                       txn_do_abort = 1;
-
-               }
-               key.flags = 0;
-               return( key );
-       } else {
-               *dbch = dbci;
-               if ( (*dbci->c_get)( dbci, &key, &data, DB_NEXT ) == 0 ) {
-                       ldbm_datum_free( ldbm, data );
-               } else {
-                       if ( txnid != NULL ) {
-
-                               Debug( LDAP_DEBUG_ANY,
-                                       "bdb2i_db_firstkey: transaction failed: aborted.\n",
-                                       0, 0, 0 );
-                               txn_do_abort = 1;
-
-                       }
-                       ldbm_datum_free( ldbm, key );
-                       key.flags = 0;
-                       key.dptr = NULL;
-                       key.dsize = 0;
-               }
-       }
-
-       return( key );
-}
-
-
-Datum
-bdb2i_db_nextkey( LDBM ldbm, Datum key, DBC *dbcp )
-{
-       Datum   data;
-       int             rc;
-
-       ldbm_datum_init( data );
-       ldbm_datum_free( ldbm, key );
-       key.flags = data.flags = DB_DBT_MALLOC;
-
-       if ( (*dbcp->c_get)( dbcp, &key, &data, DB_NEXT ) == 0 ) {
-               ldbm_datum_free( ldbm, data );
-       } else {
-               if ( txnid != NULL ) {
-
-                       Debug( LDAP_DEBUG_ANY,
-                               "bdb2i_db_nextkey: transaction failed: aborted.\n",
-                               0, 0, 0 );
-                       txn_do_abort = 1;
-
-               }
-               key.flags = 0;
-               key.dptr = NULL;
-               key.dsize = 0;
-       }
-
-       return( key );
-}
-
-
-/*  Transaction control of write access  */
-/*  Since these functions are only used by one writer at a time,
-       we do not have any concurrency (locking) problem  */
-
-/*  initialize a new transaction  */
-int
-bdb2i_start_transction( DB_TXNMGR *txmgr )
-{
-       int             rc;
-
-       txnid        = NULL;
-       txn_do_abort = 0;
-
-       if (( rc = txn_begin( txmgr, NULL, &txnid )) != 0 ) {
-               int err = errno;
-               Debug( LDAP_DEBUG_ANY, "bdb2i_start_transction failed: %d: errno=%s\n",
-                                       rc, strerror( err ), 0 );
-
-               if ( txnid != NULL )
-                       (void) txn_abort( txnid );
-               return( -1 );
-       }
-
-       Debug( LDAP_DEBUG_TRACE,
-                       "bdb2i_start_transaction: transaction started.\n",
-                       0, 0, 0 );
-
-       return( 0 );
-}
-
-
-/*  finish the transaction  */
-int
-bdb2i_finish_transaction()
-{
-       int             rc = 0;
-
-       /*  if transaction was NOT selected, just return  */
-       if ( txnid == NULL ) return( 0 );
-
-       /*  if nothing was wrong so far, we can try to commit the transaction  */
-       /*  complain, if the commit fails  */
-       if (( txn_do_abort == 0 ) && ( txn_commit( txnid )) != 0 ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "bdb2i_finish_transaction: transaction commit failed: aborted.\n",
-                       0, 0, 0 );
-               txn_do_abort = 1;
-       }
-
-       /*  if anything went wrong, we have to abort the transaction  */
-       if ( txn_do_abort ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "bdb2i_finish_transaction: transaction aborted.\n",
-                       0, 0, 0 );
-               (void) txn_abort( txnid );
-               rc = -1;
-       } else {
-               Debug( LDAP_DEBUG_TRACE,
-                       "bdb2i_finish_transaction: transaction commited.\n",
-                       0, 0, 0 );
-       }
-
-       /*  XXX do NOT free the txnid memory !!!  */
-       txnid        = NULL;
-       txn_do_abort = 0;
-
-       return( rc );
-}
-
-
-/*  set a checkpoint
-       either forced (during shutdown) or when logsize or time are exceeded
-       (is called by reader and writer, so protect txn_dirty)
-*/
-int
-bdb2i_set_txn_checkpoint( DB_TXNMGR *txmgr, int forced )
-{
-       int   rc = 0;
-
-       /*  set dirty mutex  */
-       ldap_pvt_thread_mutex_lock( &txn_dirty_mutex );
-
-       if ( txn_dirty ) {
-               int  rc;
-               u_int32_t   logsize;
-               u_int32_t   mins;
-               time_t      now;
-
-               logsize = forced ? (u_int32_t) 0 : txn_max_pending_log;
-               mins    = forced ? (u_int32_t) 0 : txn_max_pending_time;
-
-               now = slap_get_time();
-
-               rc = txn_checkpoint( txmgr, logsize, mins );
-
-               /*  if checkpointing was successful, reset txn_dirty  */
-               if ( rc == 0 ) {
-                       DB_TXN_STAT  *statp = NULL;
-
-                       /*  check whether the checkpoint was actually written;
-                               if so, unset the txn_dirty flag  */
-                       if (( rc = txn_stat( txmgr, &statp, ldbm_malloc )) == 0 ) {
-
-                               if ( statp && ( statp->st_time_ckp >= now )) {
-
-                                       Debug( LDAP_DEBUG_TRACE,
-                                               "bdb2i_set_txn_checkpoint succeded.\n",
-                                               0, 0, 0 );
-                                       txn_dirty = 0;
-
-                               }
-
-                               if ( statp ) free( statp );
-
-                       } else {
-                               Debug( LDAP_DEBUG_ANY,
-                                               "bdb2i_set_txn_checkpoint: txn_stat failed: %d\n",
-                                               rc, 0, 0 );
-                       }
-               } else {
-                       Debug( LDAP_DEBUG_ANY, "bdb2i_set_txn_checkpoint failed: %d\n",
-                                       rc, 0, 0 );
-               }
-       }
-
-       /*  release dirty mutex  */
-       ldap_pvt_thread_mutex_unlock( &txn_dirty_mutex );
-
-       return( rc );
-}
-
-
diff --git a/servers/slapd/back-bdb2/txn.h b/servers/slapd/back-bdb2/txn.h
deleted file mode 100644 (file)
index 9093127..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* txn.h - Header for TP support functions of the bdb2 backend */
-/* $OpenLDAP$ */
-
-#ifndef _BDB2_TXN_H_
-#define _BDB2_TXN_H_
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <sys/stat.h>
-
-#include <ac/dirent.h>
-#include <ac/errno.h>
-#include <ac/signal.h>
-#include <ac/socket.h>
-#include <ac/string.h>
-#include <ac/time.h>
-#include <ac/unistd.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-
-
-
-/*  the DB environment for the backend  */
-DB_ENV                    bdb2i_dbEnv;
-
-
-/*  variables for transaction support  */
-DB_TXN                    *txnid       = NULL;
-int                       txn_do_abort = 0;
-
-u_int32_t                 txn_max_pending_log;
-u_int32_t                 txn_max_pending_time;
-int                       txn_dirty = 0;
-ldap_pvt_thread_mutex_t   txn_dirty_mutex;
-
-/*  defaults for checkpointing  */
-#define  BDB2_TXN_CHKP_MAX_LOG     2000    /*  checkpoint every 2MB lock file
-                                               (approx. 20 ADD TXNs)  */
-#define  BDB2_TXN_CHKP_MAX_TIME       5    /*  checkpoint after 5 minutes */
-
-
-/*  the name of the file and the record number of the NEXTID datum  */
-#define NEXTID_NAME    "NEXTID"
-#define NEXTID_RECNO   (db_recno_t) 1
-
-
-
-#endif  /*  _BDB2_TXN_H_  */
-
diff --git a/servers/slapd/back-bdb2/unbind.c b/servers/slapd/back-bdb2/unbind.c
deleted file mode 100644 (file)
index b2c179d..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* unbind.c - handle an ldap unbind operation */
-/* $OpenLDAP$ */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-bdb2.h"
-
-static int
-bdb2i_back_unbind_internal(
-       BackendDB     *be,
-       Connection  *conn,
-       Operation   *op
-)
-{
-       return( 0 );
-}
-
-
-int
-bdb2_back_unbind(
-       BackendDB     *be,
-       Connection  *conn,
-       Operation   *op
-)
-{
-       struct timeval  time1;
-       int             ret;
-
-       bdb2i_start_timing( be->bd_info, &time1 );
-
-       ret = bdb2i_back_unbind_internal( be, conn, op );
-       bdb2i_stop_timing( be->bd_info, time1, "UNBIND", conn, op );
-
-       return( ret );
-}
diff --git a/servers/slapd/back-dnssrv/Makefile.in b/servers/slapd/back-dnssrv/Makefile.in
new file mode 100644 (file)
index 0000000..8849ce3
--- /dev/null
@@ -0,0 +1,34 @@
+# $OpenLDAP$
+########################################################################### 
+#   Copyright 2000, OpenLDAP Foundation, All rights reserved.
+#
+#   Redistribution and use in source and binary forms are permitted only
+#   as authorized by the OpenLDAP Public License.  A copy of this
+#   license is available at http://www.OpenLDAP.org/license.html or
+#   in file LICENSE in the top-level directory of the distribution.
+########################################################################### 
+# DNSSRV backend written by Kurt Zeilenga
+##########################################################################
+
+SRCS   = init.c bind.c search.c config.c compare.c \
+               modify.c add.c modrdn.c delete.c request.c
+OBJS   = init.lo bind.lo search.lo config.lo compare.lo \
+               modify.lo add.lo modrdn.lo delete.lo request.lo
+
+LDAP_INCDIR= ../../../include       
+LDAP_LIBDIR= ../../../libraries
+
+BUILD_OPT = "--enable-dnssrv"
+BUILD_MOD = @BUILD_DNSSRV@
+LINKAGE = @BUILD_DNSSRV_DYNAMIC@
+
+LIBBASE = back_dnssrv
+
+XINCPATH = -I.. -I$(srcdir)/..
+XDEFS = $(MODULES_CPPFLAGS)
+
+all-local-lib: ../.backend
+
+../.backend: lib$(LIBBASE).a
+       @touch $@
+
diff --git a/servers/slapd/back-dnssrv/add.c b/servers/slapd/back-dnssrv/add.c
new file mode 100644 (file)
index 0000000..67292e7
--- /dev/null
@@ -0,0 +1,28 @@
+/* add.c - DNS SRV backend add function */
+/* $OpenLDAP$ */
+/*
+ * Copyright 2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "back-dnssrv.h"
+
+int
+dnssrv_back_add(
+    Backend    *be,
+    Connection *conn,
+    Operation  *op,
+    Entry      *e
+)
+{
+       return dnssrv_back_request( be, conn, op, e->e_dn, e->e_ndn,
+               0, NULL, NULL, 0 );
+}
diff --git a/servers/slapd/back-dnssrv/back-dnssrv.h b/servers/slapd/back-dnssrv/back-dnssrv.h
new file mode 100644 (file)
index 0000000..e4a401d
--- /dev/null
@@ -0,0 +1,29 @@
+/* $OpenLDAP$ */
+/*
+ *   Copyright 2000, OpenLDAP Foundation, All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms are permitted only
+ *   as authorized by the OpenLDAP Public License.  A copy of this
+ *   license is available at http://www.OpenLDAP.org/license.html or
+ *   in file LICENSE in the top-level directory of the distribution.
+ */
+
+#ifndef DNSSRV_BACK_H
+#define DNSSRV_BACK_H 1
+
+#include "external.h"
+
+LDAP_BEGIN_DECL
+
+int dnssrv_result();
+       
+extern int dnssrv_back_request LDAP_P((
+       BackendDB *bd,
+       Connection *conn, Operation *op,
+       const char *dn, const char *ndn,
+       int scope, Filter *filter,
+       char **attrs, int attrsonly ));
+
+LDAP_END_DECL
+
+#endif /* DNSSRV_BACK_H */
diff --git a/servers/slapd/back-dnssrv/bind.c b/servers/slapd/back-dnssrv/bind.c
new file mode 100644 (file)
index 0000000..4739746
--- /dev/null
@@ -0,0 +1,59 @@
+/* bind.c - DNS SRV backend bind function */
+/* $OpenLDAP$ */
+/*
+ * Copyright 2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/socket.h>
+#include <ac/string.h>
+
+#include "slap.h"
+#include "back-dnssrv.h"
+
+int
+dnssrv_back_bind(
+    Backend            *be,
+    Connection         *conn,
+    Operation          *op,
+    const char         *dn,
+    const char         *ndn,
+    int                        method,
+    struct berval      *cred,
+       char            **edn
+)
+{
+       Debug( LDAP_DEBUG_TRACE, "DNSSRV: bind %s (%d)\n",
+               dn == NULL ? "" : dn, 
+               method, NULL );
+               
+       if( method == LDAP_AUTH_SIMPLE && cred != NULL && cred->bv_len ) {
+               Statslog( LDAP_DEBUG_STATS,
+                       "conn=%ld op=%d DNSSRV BIND dn=\"%s\" provided passwd\n",
+                        op->o_connid, op->o_opid,
+                       dn == NULL ? "" : dn , 0, 0 );
+
+               Debug( LDAP_DEBUG_TRACE,
+                       "DNSSRV: BIND dn=\"%s\" provided cleartext password\n",
+                       dn == NULL ? "" : dn, 0, 0 );
+
+               send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
+                       NULL, "you shouldn\'t send strangers your password",
+                       NULL, NULL );
+
+       } else {
+               Debug( LDAP_DEBUG_TRACE, "DNSSRV: BIND dn=\"%s\"\n",
+                       dn == NULL ? "" : dn, 0, 0 );
+
+               send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
+                       NULL, "anonymous bind expected",
+                       NULL, NULL );
+       }
+
+       return 1;
+}
diff --git a/servers/slapd/back-dnssrv/compare.c b/servers/slapd/back-dnssrv/compare.c
new file mode 100644 (file)
index 0000000..0d1beaa
--- /dev/null
@@ -0,0 +1,30 @@
+/* compare.c - DNS SRV backend compare function */
+/* $OpenLDAP$ */
+/*
+ * Copyright 2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "back-dnssrv.h"
+
+int
+dnssrv_back_compare(
+    Backend    *be,
+    Connection *conn,
+    Operation  *op,
+    const char *dn,
+    const char *ndn,
+       AttributeAssertion *ava
+)
+{
+       return dnssrv_back_request( be, conn, op, dn, ndn,
+               0, NULL, NULL, 0 );
+}
diff --git a/servers/slapd/back-dnssrv/config.c b/servers/slapd/back-dnssrv/config.c
new file mode 100644 (file)
index 0000000..5aaa66f
--- /dev/null
@@ -0,0 +1,43 @@
+/* config.c - DNS SRV backend configuration file routine */
+/* $OpenLDAP$ */
+/*
+ * Copyright 2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "back-dnssrv.h"
+
+int
+dnssrv_back_db_config(
+    BackendDB  *be,
+    const char *fname,
+    int                lineno,
+    int                argc,
+    char       **argv
+)
+{
+       struct ldapinfo *li = (struct ldapinfo *) be->be_private;
+       char *port;
+
+       if ( li == NULL ) {
+               fprintf( stderr, "%s: line %d: DNSSRV backend info is null!\n",
+                   fname, lineno );
+               return( 1 );
+       }
+
+       /* no configuration options (yet) */
+       {
+               fprintf( stderr,
+"%s: line %d: unknown directive \"%s\" in DNSSRV database definition (ignored)\n",
+                   fname, lineno, argv[0] );
+       }
+       return 0;
+}
diff --git a/servers/slapd/back-dnssrv/delete.c b/servers/slapd/back-dnssrv/delete.c
new file mode 100644 (file)
index 0000000..abcbf3f
--- /dev/null
@@ -0,0 +1,30 @@
+/* delete.c - DNS SRV backend delete function */
+/* $OpenLDAP$ */
+/*
+ * Copyright 2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "back-dnssrv.h"
+
+int
+dnssrv_back_delete(
+    Backend    *be,
+    Connection *conn,
+    Operation  *op,
+    const char *dn,
+    const char *ndn
+)
+{
+       return dnssrv_back_request( be, conn, op, dn, ndn,
+               0, NULL, NULL, 0 );
+}
diff --git a/servers/slapd/back-dnssrv/external.h b/servers/slapd/back-dnssrv/external.h
new file mode 100644 (file)
index 0000000..3358a30
--- /dev/null
@@ -0,0 +1,63 @@
+/* $OpenLDAP$ */
+/*
+ *      Copyright 2000, OpenLDAP Foundation, All rights reserved.
+ *
+ *      Redistribution and use in source and binary forms are permitted only
+ *      as authorized by the OpenLDAP Public License.  A copy of this
+ *      license is available at http://www.OpenLDAP.org/license.html or
+ *      in file LICENSE in the top-level directory of the distribution.
+ */
+#ifndef _DNSSRV_EXTERNAL_H
+#define _DNSSRV_EXTERNAL_H
+
+LDAP_BEGIN_DECL
+
+extern int     dnssrv_back_initialize LDAP_P(( BackendInfo *bi ));
+extern int     dnssrv_back_open LDAP_P(( BackendInfo *bi ));
+extern int     dnssrv_back_close LDAP_P(( BackendInfo *bi ));
+extern int     dnssrv_back_destroy LDAP_P(( BackendInfo *bi ));
+
+extern int     dnssrv_back_db_init LDAP_P(( BackendDB *bd ));
+extern int     dnssrv_back_db_destroy LDAP_P(( BackendDB *bd ));
+
+extern int     dnssrv_back_db_config LDAP_P(( BackendDB *bd,
+       const char *fname, int lineno, int argc, char **argv ));
+
+extern int dnssrv_back_bind LDAP_P(( BackendDB *bd,
+       Connection *conn, Operation *op,
+       const char *dn, const char *ndn, int method,
+       struct berval *cred, char** edn ));
+
+extern int     dnssrv_back_search LDAP_P(( BackendDB *bd,
+       Connection *conn, Operation *op,
+       const char *base, const char *nbase,
+       int scope, int deref, int sizelimit, int timelimit,
+       Filter *filter, const char *filterstr,
+       char **attrs, int attrsonly ));
+
+extern int     dnssrv_back_compare LDAP_P((BackendDB *bd,
+       Connection *conn, Operation *op,
+       const char *dn, const char *ndn, AttributeAssertion *ava ));
+
+extern int     dnssrv_back_modify LDAP_P(( BackendDB *bd,
+       Connection *conn, Operation *op,
+       const char *dn, const char *ndn,
+       Modifications *ml ));
+
+extern int     dnssrv_back_modrdn LDAP_P(( BackendDB *bd,
+       Connection *conn, Operation *op,
+       const char *dn, const char *ndn,
+       const char *newrdn, int deleteoldrdn,
+       const char *newSuperior ));
+
+extern int     dnssrv_back_add LDAP_P(( BackendDB *bd,
+       Connection *conn, Operation *op, Entry *e ));
+
+extern int     dnssrv_back_delete LDAP_P(( BackendDB *bd,
+       Connection *conn, Operation *op,
+       const char *dn, const char *ndn ));
+
+LDAP_END_DECL
+
+#endif /* _DNSSRV_EXTERNAL_H */
+
diff --git a/servers/slapd/back-dnssrv/init.c b/servers/slapd/back-dnssrv/init.c
new file mode 100644 (file)
index 0000000..9a77eff
--- /dev/null
@@ -0,0 +1,122 @@
+/* init.c - initialize ldap backend */
+/* $OpenLDAP$ */
+/*
+ * Copyright 2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "back-dnssrv.h"
+
+#ifdef SLAPD_DNSSRV_DYNAMIC
+
+int back_dnssrv_LTX_init_module(int argc, char *argv[]) {
+    BackendInfo bi;
+
+    memset( &bi, '\0', sizeof(bi) );
+    bi.bi_type = "dnssrv";
+    bi.bi_init = dnssrv_back_initialize;
+
+    backend_add(&bi);
+    return 0;
+}
+
+#endif /* SLAPD_DNSSRV_DYNAMIC */
+
+int
+dnssrv_back_initialize(
+    BackendInfo        *bi
+)
+{
+       static char *controls[] = {
+               LDAP_CONTROL_MANAGEDSAIT,
+               NULL
+       };
+
+       bi->bi_controls = controls;
+
+       bi->bi_open = 0;
+       bi->bi_config = 0;
+       bi->bi_close = 0;
+       bi->bi_destroy = 0;
+
+       bi->bi_db_init = dnssrv_back_db_init;
+       bi->bi_db_config = dnssrv_back_db_config;
+       bi->bi_db_open = 0;
+       bi->bi_db_close = 0;
+       bi->bi_db_destroy = dnssrv_back_db_destroy;
+
+       bi->bi_op_bind = dnssrv_back_bind;
+       bi->bi_op_unbind = 0;
+       bi->bi_op_search = dnssrv_back_search;
+       bi->bi_op_compare = dnssrv_back_compare;
+       bi->bi_op_modify = dnssrv_back_modify;
+       bi->bi_op_modrdn = dnssrv_back_modrdn;
+       bi->bi_op_add = dnssrv_back_add;
+       bi->bi_op_delete = dnssrv_back_delete;
+       bi->bi_op_abandon = 0;
+
+       bi->bi_extended = 0;
+
+       bi->bi_acl_group = 0;
+
+#ifdef HAVE_CYRUS_SASL
+       bi->bi_sasl_authorize = 0;
+       bi->bi_sasl_getsecret = 0;
+       bi->bi_sasl_putsecret = 0;
+#endif /* HAVE_CYRUS_SASL */
+
+       bi->bi_connection_init = 0;
+       bi->bi_connection_destroy = 0;
+
+       return 0;
+}
+
+int
+dnssrv_back_db_init(
+    Backend    *be
+)
+{
+#if 0
+       struct ldapinfo *li;
+
+       li = (struct ldapinfo *) ch_calloc( 1, sizeof(struct ldapinfo) );
+       ldap_pvt_thread_mutex_init( &li->conn_mutex );
+
+       be->be_private = li;
+
+       return li == NULL;
+#else
+       return 0;
+#endif
+}
+
+int
+dnssrv_back_db_destroy(
+    Backend    *be
+)
+{
+#if 0
+       struct ldapinfo *li;
+
+       if (be->be_private) {
+               li = (struct ldapinfo *)be->be_private;
+               if (li->host) {
+                       free(li->host);
+                       li->host = NULL;
+               }
+               ldap_pvt_thread_mutex_destroy( &li->conn_mutex );
+       }
+
+       free( be->be_private );
+       return 0;
+#else
+       return 0;
+#endif
+}
diff --git a/servers/slapd/back-dnssrv/modify.c b/servers/slapd/back-dnssrv/modify.c
new file mode 100644 (file)
index 0000000..53d7c23
--- /dev/null
@@ -0,0 +1,31 @@
+/* modify.c - DNS SRV backend modify function */
+/* $OpenLDAP$ */
+/*
+ * Copyright 2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "back-dnssrv.h"
+
+int
+dnssrv_back_modify(
+    Backend    *be,
+    Connection *conn,
+    Operation  *op,
+    const char *dn,
+    const char *ndn,
+    Modifications      *ml
+)
+{
+       return dnssrv_back_request( be, conn, op, dn, ndn,
+               0, NULL, NULL, 0 );
+}
diff --git a/servers/slapd/back-dnssrv/modrdn.c b/servers/slapd/back-dnssrv/modrdn.c
new file mode 100644 (file)
index 0000000..c595dcb
--- /dev/null
@@ -0,0 +1,32 @@
+/* modrdn.c - DNS SRV backend modrdn function */
+/* $OpenLDAP$ */
+/*
+ * Copyright 2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/socket.h>
+#include <ac/string.h>
+
+#include "slap.h"
+#include "back-dnssrv.h"
+
+int
+dnssrv_back_modrdn(
+    Backend    *be,
+    Connection *conn,
+    Operation  *op,
+    const char *dn,
+    const char *ndn,
+    const char *newrdn,
+    int                deleteoldrdn,
+    const char *newSuperior
+)
+{
+       return dnssrv_back_request( be, conn, op, dn, ndn,
+               0, NULL, NULL, 0 );
+}
diff --git a/servers/slapd/back-dnssrv/request.c b/servers/slapd/back-dnssrv/request.c
new file mode 100644 (file)
index 0000000..a79f632
--- /dev/null
@@ -0,0 +1,231 @@
+/* add.c - DNS SRV backend request handler */
+/* $OpenLDAP$ */
+/*
+ * Copyright 2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "back-dnssrv.h"
+
+int
+dnssrv_back_request(
+    Backend    *be,
+    Connection *conn,
+    Operation  *op,
+    const char *dn,
+    const char *ndn,
+       int scope, Filter *filter,
+       char **attrs, int attrsonly )
+{
+       int i;
+       int rc;
+       char *domain = NULL;
+       char *hostlist = NULL;
+       char **hosts = NULL;
+       struct berval **urls = NULL;
+       int             manageDSAit = get_manageDSAit( op );
+
+       if( ndn == NULL || *ndn == '\0' ) {
+               send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
+                       NULL, "operation upon null (empty) DN disallowed",
+                       NULL, NULL );
+               goto done;
+       }
+
+       if( ldap_dn2domain( dn, &domain ) ) {
+               send_ldap_result( conn, op, LDAP_REFERRAL,
+                       NULL, NULL, default_referral, NULL );
+               goto done;
+       }
+
+       Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" -> domain=\"%s\"\n",
+               dn == NULL ? "" : dn,
+               domain == NULL ? "" : domain,
+               0 );
+
+       if( rc = ldap_domain2hostlist( domain, &hostlist ) ) {
+               Debug( LDAP_DEBUG_TRACE, "DNSSRV: domain2hostlist returned %d\n",
+                       rc, 0, 0 );
+               send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
+                       NULL, "no DNS SRV RR available for DN", NULL, NULL );
+               goto done;
+       }
+
+       hosts = str2charray( hostlist, " " );
+
+       if( hosts == NULL ) {
+               Debug( LDAP_DEBUG_TRACE, "DNSSRV: str2charrary error\n", 0, 0, 0 );
+               send_ldap_result( conn, op, LDAP_OTHER,
+                       NULL, "problem processing DNS SRV records for DN", NULL, NULL );
+               goto done;
+       }
+
+       for( i=0; hosts[i] != NULL; i++) {
+               struct berval *url = ch_malloc( sizeof( struct berval ) ); 
+
+               url->bv_len = sizeof("ldap://")-1 + strlen(hosts[i]);
+               url->bv_val = ch_malloc( url->bv_len + 1 );
+
+               strcpy( url->bv_val, "ldap://" );
+               strcpy( &url->bv_val[sizeof("ldap://")-1], hosts[i] );
+
+               if( ber_bvecadd( &urls, url ) < 0 ) {
+                       ber_bvfree( url );
+                       send_ldap_result( conn, op, LDAP_OTHER,
+                               NULL, "problem processing DNS SRV records for DN",
+                               NULL, NULL );
+                       goto done;
+               }
+       }
+
+       Statslog( LDAP_DEBUG_STATS,
+           "conn=%ld op=%d DNSSRV p=%d dn=\"%s\" url=\"%s\"\n",
+           op->o_connid, op->o_opid, op->o_protocol, dn, urls[0]->bv_val );
+
+       Debug( LDAP_DEBUG_TRACE, "DNSSRV: %sdn=\"%s\" -> url=\"%s\"\n",
+               manageDSAit ? "ManageDSAit " : "",
+               dn == NULL ? "" : dn,
+               urls[0]->bv_val );
+
+       if( manageDSAit ) {
+               char *refdn, *nrefdn;
+               rc = ldap_domain2dn(domain, &refdn);
+
+               if( rc != LDAP_SUCCESS ) {
+                       send_ldap_result( conn, op, LDAP_OTHER,
+                               NULL, "DNS SRV problem processing manageDSAit control",
+                               NULL, NULL );
+                       goto done;
+               }
+
+               nrefdn = ch_strdup( refdn );
+               dn_normalize(nrefdn);
+
+               if( strcmp( nrefdn, ndn ) != 0 ) {
+                       /* requested dn is subordinate */
+
+                       Debug( LDAP_DEBUG_TRACE,
+                                       "DNSSRV: dn=\"%s\" subordindate to refdn=\"%s\"\n",
+                                       dn == NULL ? "" : dn,
+                                       refdn == NULL ? "" : refdn,
+                                       NULL );
+
+                       send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
+                               refdn, NULL,
+                               NULL, NULL );
+
+               } else if( op->o_tag != LDAP_REQ_SEARCH ) {
+                       send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
+                               dn, "DNS SRV ManageDSAIT control disallowed",
+                               NULL, NULL );
+
+               } else if ( scope != LDAP_SCOPE_ONELEVEL ) {
+                       struct berval   val;
+                       struct berval   *vals[2];
+                       Entry *e = ch_calloc( 1, sizeof(Entry) );
+                       AttributeDescription *ad_objectClass
+                               = slap_schema.si_ad_objectClass;
+                       AttributeDescription *ad_ref = slap_schema.si_ad_ref;
+                       e->e_dn = strdup( dn );
+                       e->e_ndn = strdup( ndn );
+
+                       e->e_attrs = NULL;
+                       e->e_private = NULL;
+
+                       vals[0] = &val;
+                       vals[1] = NULL;
+
+                       val.bv_val = "top";
+                       val.bv_len = sizeof("top")-1;
+                       attr_merge( e, ad_objectClass, vals );
+
+                       val.bv_val = "referral";
+                       val.bv_len = sizeof("referral")-1;
+                       attr_merge( e, ad_objectClass, vals );
+
+                       val.bv_val = "extensibleObject";
+                       val.bv_len = sizeof("extensibleObject")-1;
+                       attr_merge( e, ad_objectClass, vals );
+
+                       {
+                               AttributeDescription *ad = NULL;
+                               const char *text;
+
+                               rc = slap_str2ad( "dc", &ad, &text );
+
+                               if( rc == LDAP_SUCCESS ) {
+                                       char *p;
+                                       val.bv_val = ch_strdup( domain );
+
+                                       p = strchr( val.bv_val, '.' );
+                                       
+                                       if( p == val.bv_val ) {
+                                               val.bv_val[1] = '\0';
+                                       } else if ( p != NULL ) {
+                                               *p = '\0';
+                                       }
+
+                                       val.bv_len = strlen(val.bv_val);
+                                       attr_merge( e, ad, vals );
+
+                                       ad_free( ad, 1 );
+                               }
+                       }
+
+                       {
+                               AttributeDescription *ad = NULL;
+                               const char *text;
+
+                               rc = slap_str2ad( "associatedDomain", &ad, &text );
+
+                               if( rc == LDAP_SUCCESS ) {
+                                       val.bv_val = domain;
+                                       val.bv_len = strlen(domain);
+                                       attr_merge( e, ad, vals );
+
+                                       ad_free( ad, 1 );
+                               }
+                       }
+
+                       attr_merge( e, ad_ref, urls );
+
+                       rc = test_filter( be, conn, op, e, filter ); 
+
+                       if( rc == LDAP_COMPARE_TRUE ) {
+                               send_search_entry( be, conn, op,
+                                       e, attrs, attrsonly, NULL );
+                       }
+
+                       entry_free( e );
+                       
+                       send_ldap_result( conn, op, LDAP_SUCCESS,
+                               NULL, NULL, NULL, NULL );
+
+               } else {
+                       send_ldap_result( conn, op, LDAP_SUCCESS,
+                               NULL, NULL, NULL, NULL );
+               }
+
+               free( refdn );
+               free( nrefdn );
+
+       } else {
+               send_ldap_result( conn, op, LDAP_REFERRAL,
+                       NULL, "DNS SRV generated referrals", urls, NULL );
+       }
+
+done:
+       if( domain != NULL ) ch_free( domain );
+       if( hostlist != NULL ) ch_free( hostlist );
+       if( hosts != NULL ) charray_free( hosts );
+       if( urls != NULL ) ber_bvecfree( urls );
+       return 0;
+}
diff --git a/servers/slapd/back-dnssrv/search.c b/servers/slapd/back-dnssrv/search.c
new file mode 100644 (file)
index 0000000..d9dea2e
--- /dev/null
@@ -0,0 +1,39 @@
+/* search.c - DNS SRV backend search function */
+/* $OpenLDAP$ */
+/*
+ * Copyright 2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/time.h>
+
+#include "slap.h"
+#include "back-dnssrv.h"
+
+int
+dnssrv_back_search(
+    Backend    *be,
+    Connection *conn,
+    Operation  *op,
+    const char *dn,
+    const char *ndn,
+    int                scope,
+    int                deref,
+    int                size,
+    int                time,
+    Filter     *filter,
+    const char *filterstr,
+    char       **attrs,
+    int                attrsonly
+)
+{
+       return dnssrv_back_request( be, conn, op, dn, ndn,
+               scope, filter, attrs, attrsonly );
+}
index fe015081fca66f321aa684010a1ac0b4c4443cc8..99808c446e0d1057abc3e655f58d69e001f072ce 100644 (file)
@@ -1,9 +1,9 @@
 # $OpenLDAP$
 
 SRCS   = init.c config.c search.c bind.c unbind.c add.c compare.c \
-               delete.c modify.c modrdn.c
+               delete.c modify.c modrdn.c group.c
 OBJS   = init.lo config.lo search.lo bind.lo unbind.lo add.lo compare.lo \
-               delete.lo modify.lo modrdn.lo
+               delete.lo modify.lo modrdn.lo group.lo
 
 LDAP_INCDIR= ../../../include       
 LDAP_LIBDIR= ../../../libraries
@@ -16,7 +16,6 @@ LIBBASE = back_ldap
 
 XINCPATH = -I.. -I$(srcdir)/..
 XDEFS = $(MODULES_CPPFLAGS)
-XLDFLAGS = $(MODULES_LDFLAGS)
 
 all-local-lib: ../.backend
 
index 2ff2b7568cd5e16b010625db3a5cb2c085d887cd..13064fd27ff95f31a6743131a7ffe341eae106e2 100644 (file)
@@ -67,7 +67,7 @@ ldap_back_add(
        for (i=0, a=e->e_attrs; a; i++, a=a->a_next) {
                attrs[i] = (LDAPMod *)ch_malloc(sizeof(LDAPMod));
                attrs[i]->mod_op = LDAP_MOD_BVALUES;
-               attrs[i]->mod_type = a->a_type;
+               attrs[i]->mod_type = a->a_desc->ad_cname->bv_val;
                attrs[i]->mod_vals.modv_bvals = a->a_vals;
        }
 
index f3063a8c0c93f94afef81d07c1b782156b1e5897..1906933ab7d186c5a395fde2e7918c3f807b79df 100644 (file)
@@ -40,9 +40,10 @@ struct ldapconn {
 };
 
 struct ldapinfo {
-       char *host;
-       int port;
+       char *url;
        char *suffix;
+       char *binddn;
+       char *bindpw;
        ldap_pvt_thread_mutex_t         conn_mutex;
        struct ldapconn *lcs;
 };
index 45f9df5c1e30d31c5b3ff78a590174fe9bc368e5..705203d2759270ca9bc933560100a5294b476241 100644 (file)
@@ -37,9 +37,9 @@ ldap_back_bind(
     Backend            *be,
     Connection         *conn,
     Operation          *op,
-    char               *dn,
+    const char         *dn,
+    const char         *ndn,
     int                        method,
-       char            *mech,
     struct berval      *cred,
        char            **edn
 )
@@ -74,9 +74,8 @@ ldap_back_getconn(struct ldapinfo *li, Connection *conn, Operation *op)
 
        /* Looks like we didn't get a bind. Open a new session... */
        if (!lc) {
-               ld = ldap_init(li->host, li->port);
-               if (!ld) {
-                       send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
+               if (ldap_initialize(&ld, li->url) != LDAP_SUCCESS) {
+                       send_ldap_result( conn, op, LDAP_OTHER,
                                NULL, "ldap_init failed", NULL, NULL );
                        return( NULL );
                }
index 206437d4324496a53b58f9c0237cd4cc6789aedb..3cade31ce96a17eb9350a6e08f4f02f188c23150 100644 (file)
@@ -37,8 +37,9 @@ ldap_back_compare(
     Backend    *be,
     Connection *conn,
     Operation  *op,
-    char       *dn,
-    Ava                *ava
+    const char *dn,
+    const char *ndn,
+       AttributeAssertion *ava
 )
 {
        struct ldapinfo *li = (struct ldapinfo *) be->be_private;
@@ -54,6 +55,6 @@ ldap_back_compare(
                        return( -1 );
        }
 
-       ldap_compare_s( lc->ld, dn, ava->ava_type, ava->ava_value.bv_val );
+       ldap_compare_s( lc->ld, dn, ava->aa_desc->ad_cname->bv_val, ava->aa_value->bv_val );
        return( ldap_back_op_result( lc, op ) );
 }
index 6326116f73a7e06e26268757f6da3da65b4ad356..8321980c58b7280305b87cf9b4b4b087911279dd 100644 (file)
@@ -42,7 +42,6 @@ ldap_back_db_config(
 )
 {
        struct ldapinfo *li = (struct ldapinfo *) be->be_private;
-       char *port;
 
        if ( li == NULL ) {
                fprintf( stderr, "%s: line %d: ldap backend info is null!\n",
@@ -50,7 +49,7 @@ ldap_back_db_config(
                return( 1 );
        }
 
-       /* server address to query */
+       /* server address to query (depricated, use "uri" directive) */
        if ( strcasecmp( argv[0], "server" ) == 0 ) {
                if (argc != 2) {
                        fprintf( stderr,
@@ -58,12 +57,47 @@ ldap_back_db_config(
                            fname, lineno );
                        return( 1 );
                }
-               port=strchr(argv[1],':');
-               if (port) {
-                       *port++ = '\0';
-                       li->port = atoi(port);
+               if (li->url != NULL)
+                       ch_free(li->url);
+               li->url = ch_calloc(strlen(argv[1]) + 9, sizeof(char));
+               if (li->url != NULL) {
+                       strcpy(li->url, "ldap://");
+                       strcat(li->url, argv[1]);
+                       strcat(li->url, "/");
                }
-               li->host = ch_strdup(argv[1]);
+
+       /* URI of server to query (preferred over "server" directive) */
+       } else if ( strcasecmp( argv[0], "uri" ) == 0 ) {
+               if (argc != 2) {
+                       fprintf( stderr,
+       "%s: line %d: missing address in \"uri <address>\" line\n",
+                           fname, lineno );
+                       return( 1 );
+               }
+               if (li->url != NULL)
+                       ch_free(li->url);
+               li->url = ch_strdup(argv[1]);
+
+       /* name to use for ldap_back_group */
+       } else if ( strcasecmp( argv[0], "binddn" ) == 0 ) {
+               if (argc != 2) {
+                       fprintf( stderr,
+       "%s: line %d: missing name in \"binddn <name>\" line\n",
+                           fname, lineno );
+                       return( 1 );
+               }
+               li->binddn = ch_strdup(argv[1]);
+
+       /* password to use for ldap_back_group */
+       } else if ( strcasecmp( argv[0], "bindpw" ) == 0 ) {
+               if (argc != 2) {
+                       fprintf( stderr,
+       "%s: line %d: missing password in \"bindpw <password>\" line\n",
+                           fname, lineno );
+                       return( 1 );
+               }
+               li->bindpw = ch_strdup(argv[1]);
+
        /* anything else */
        } else {
                fprintf( stderr,
index b5e00cc2bbb8fb31fa75d5cc62edcc0113850f82..f2554ba30e2c6d70a7c2878bbf5dfd0e8699866e 100644 (file)
@@ -37,7 +37,8 @@ ldap_back_delete(
     Backend    *be,
     Connection *conn,
     Operation  *op,
-    char       *dn
+    const char *dn,
+    const char *ndn
 )
 {
        struct ldapinfo *li = (struct ldapinfo *) be->be_private;
index 58b5e77a07112347d195e75369585cf7525eb7d8..46c39edcac82a61e500d42158da45dc303b899a1 100644 (file)
@@ -17,7 +17,7 @@ extern int    ldap_back_db_config LDAP_P(( BackendDB *bd,
 
 extern int ldap_back_bind LDAP_P(( BackendDB *bd,
        Connection *conn, Operation *op,
-       char *dn, int method, char* mech,
+       const char *dn, const char *ndn, int method,
        struct berval *cred, char** edn ));
 
 extern int     ldap_back_conn_destroy LDAP_P(( BackendDB *bd,
@@ -25,31 +25,43 @@ extern int  ldap_back_conn_destroy LDAP_P(( BackendDB *bd,
 
 extern int     ldap_back_search LDAP_P(( BackendDB *bd,
        Connection *conn, Operation *op,
-       char *base, int scope, int deref, int sizelimit, int timelimit,
-       Filter *filter, char *filterstr, char **attrs, int attrsonly ));
+       const char *base, const char *nbase,
+       int scope, int deref, int sizelimit, int timelimit,
+       Filter *filter, const char *filterstr,
+       char **attrs, int attrsonly ));
 
-extern int     ldap_back_compare LDAP_P((BackendDB *bd,
+extern int     ldap_back_compare LDAP_P(( BackendDB *bd,
        Connection *conn, Operation *op,
-       char *dn, Ava   *ava ));
+       const char *dn, const char *ndn,
+       AttributeAssertion *ava ));
 
 extern int     ldap_back_modify LDAP_P(( BackendDB *bd,
        Connection *conn, Operation *op,
-       char *dn, LDAPModList *ml ));
+       const char *dn, const char *ndn, Modifications *ml ));
 
 extern int     ldap_back_modrdn LDAP_P(( BackendDB *bd,
        Connection *conn, Operation *op,
-       char *dn, char*newrdn, int deleteoldrdn,
-        char *newSuperior ));
+       const char *dn, const char *ndn,
+       const char *newrdn, int deleteoldrdn,
+       const char *newSuperior ));
 
 extern int     ldap_back_add LDAP_P(( BackendDB *bd,
        Connection *conn, Operation *op, Entry *e ));
 
 extern int     ldap_back_delete LDAP_P(( BackendDB *bd,
-       Connection *conn, Operation *op, char *dn ));
+       Connection *conn, Operation *op,
+       const char *dn, const char *ndn ));
 
 extern int     ldap_back_abandon LDAP_P(( BackendDB *bd,
        Connection *conn, Operation *op, int msgid ));
 
+extern int     ldap_back_group LDAP_P(( BackendDB *bd,
+       Entry *target,
+       const char* gr_ndn,
+       const char* op_ndn,
+       ObjectClass* group_oc,
+       AttributeDescription* group_at));
+
 LDAP_END_DECL
 
 #endif /* _LDAP_EXTERNAL_H */
diff --git a/servers/slapd/back-ldap/group.c b/servers/slapd/back-ldap/group.c
new file mode 100644 (file)
index 0000000..0864ad4
--- /dev/null
@@ -0,0 +1,109 @@
+/* group.c - ldap backend acl group routine */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/socket.h>
+#include <ac/string.h>
+
+#include "slap.h"
+#include "back-ldap.h"
+
+
+/* return 0 IFF op_dn is a value in member attribute
+ * of entry with gr_dn AND that entry has an objectClass
+ * value of groupOfNames
+ */
+int
+ldap_back_group(
+       Backend *be,
+       Entry   *target,
+       const char      *gr_ndn,
+       const char      *op_ndn,
+       ObjectClass* group_oc,
+       AttributeDescription* group_at
+)
+{
+       struct ldapinfo *li = (struct ldapinfo *) be->be_private;    
+       int rc = 1;
+       Attribute   *attr;
+       Entry *e;
+       struct berval bv;
+       LDAPMessage     *result;
+       char *gattr[2];
+       char *filter;
+       LDAP *ld;
+
+       AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass;
+       const char *group_oc_name = NULL;
+       const char *group_at_name = group_at->ad_cname->bv_val;
+
+       if( group_oc->soc_names && group_oc->soc_names[0] ) {
+               group_oc_name = group_oc->soc_names[0];
+       } else {
+               group_oc_name = group_oc->soc_oid;
+       }
+
+       if (target != NULL && strcmp(target->e_ndn, gr_ndn) == 0) {
+               /* we already have a copy of the entry */
+               e = target;
+
+               if( is_entry_objectclass( e, group_oc ) ) {
+                       return(1);
+               }
+
+               if ((attr = attr_find(e->e_attrs, group_at)) == NULL)
+                       return(1);
+
+               bv.bv_val = (char *) op_ndn;
+               bv.bv_len = strlen( op_ndn );         
+               if( value_find( group_at, attr->a_vals, &bv ) == 0  )
+                       return(1);
+
+       } else {
+               filter = ch_malloc(sizeof("(&(objectclass=)(=))")
+                                                       + strlen(group_oc_name)
+                                                       + strlen(group_at_name)
+                                                       + strlen(op_ndn) + 1);
+               if (filter == NULL)
+                       return(1);
+
+               if (ldap_initialize(&ld, li->url) != LDAP_SUCCESS) {
+                       ch_free(filter);
+                       return(1);
+               }
+
+               if (ldap_bind_s(ld, li->binddn, li->bindpw, LDAP_AUTH_SIMPLE) == LDAP_SUCCESS) {
+                       strcpy(filter, "(&(objectclass=");
+                       strcat(filter, group_oc_name);
+                       strcat(filter, ")(");
+                       strcat(filter, group_at_name);
+                       strcat(filter, "=");
+                       strcat(filter, op_ndn);
+                       strcat(filter, "))");
+
+                       gattr[0] = "objectclass";
+                       gattr[1] = NULL;
+                       if (ldap_search_ext_s(ld, gr_ndn, LDAP_SCOPE_BASE, filter,
+                                                                       gattr, 0, NULL, NULL, LDAP_NO_LIMIT,
+                                                                       LDAP_NO_LIMIT, &result) == LDAP_SUCCESS)
+                       {
+                               if (ldap_first_entry(ld, result) != NULL)
+                                       rc = 0;
+                               ldap_msgfree(result);
+                       }
+               }
+               ldap_unbind(ld);
+               ch_free(filter);
+               return(rc);
+    }
+
+       return(0);
+}
+
index e1d80f76e68bd9277e8b13414705f9eb881ddca7..98d9191ec31b8ea740f50081d0f94a1cfd5e712b 100644 (file)
@@ -36,7 +36,7 @@
 int back_ldap_LTX_init_module(int argc, char *argv[]) {
     BackendInfo bi;
 
-    memset( &bi, 0, sizeof(bi) );
+    memset( &bi, '\0', sizeof(bi) );
     bi.bi_type = "ldap";
     bi.bi_init = ldap_back_initialize;
 
@@ -72,7 +72,15 @@ ldap_back_initialize(
        bi->bi_op_delete = ldap_back_delete;
        bi->bi_op_abandon = 0;
 
-       bi->bi_acl_group = 0;
+       bi->bi_extended = 0;
+
+       bi->bi_acl_group = ldap_back_group;
+
+#ifdef HAVE_CYRUS_SASL
+       bi->bi_sasl_authorize = 0;
+       bi->bi_sasl_getsecret = 0;
+       bi->bi_sasl_putsecret = 0;
+#endif /* HAVE_CYRUS_SASL */
 
        bi->bi_connection_init = 0;
        bi->bi_connection_destroy = ldap_back_conn_destroy;
@@ -104,9 +112,17 @@ ldap_back_db_destroy(
 
        if (be->be_private) {
                li = (struct ldapinfo *)be->be_private;
-               if (li->host) {
-                       free(li->host);
-                       li->host = NULL;
+               if (li->url) {
+                       free(li->url);
+                       li->url = NULL;
+               }
+               if (li->binddn) {
+                       free(li->binddn);
+                       li->binddn = NULL;
+               }
+               if (li->bindpw) {
+                       free(li->bindpw);
+                       li->bindpw = NULL;
                }
                ldap_pvt_thread_mutex_destroy( &li->conn_mutex );
        }
index c1b7df03376e710b1ba2b7e00cb0c03c8664742d..f76e75f7a6f5d1fa7a1be0180ac231166fc9b92e 100644 (file)
@@ -37,14 +37,16 @@ ldap_back_modify(
     Backend    *be,
     Connection *conn,
     Operation  *op,
-    char       *dn,
-    LDAPModList        *ml
+    const char *dn,
+    const char *ndn,
+    Modifications      *modlist
 )
 {
        struct ldapinfo *li = (struct ldapinfo *) be->be_private;
        struct ldapconn *lc;
-       LDAPMod **mods;
-       LDAPModList *m;
+       LDAPMod **modv;
+       LDAPMod *mods;
+       Modifications *ml;
        int i;
 
        lc = ldap_back_getconn(li, conn, op);
@@ -57,15 +59,29 @@ ldap_back_modify(
                        return( -1 );
        }
 
-       for (i=1, m=ml->ml_next; m; i++,m=m->ml_next)
+       for (i=0, ml=modlist; ml; i++,ml=ml->sml_next)
                ;
-       mods = (LDAPMod **)ch_malloc((i+1)*sizeof(LDAPMod *));
-       mods[i] = 0;
 
-       for (i=0, m=ml; m; i++, m=m->ml_next)
-               mods[i] = &m->ml_mod;
+       mods = (LDAPMod *)ch_malloc(i*sizeof(LDAPMod));
+       if (mods == NULL)
+               return( -1 );
+       modv = (LDAPMod **)ch_malloc((i+1)*sizeof(LDAPMod *));
+       if (modv == NULL) {
+               free(mods);
+               return( -1 );
+       }
+
+       modv[i] = 0;
+
+       for (i=0, ml=modlist; ml; i++, ml=ml->sml_next) {
+               modv[i] = &mods[i];
+               mods[i].mod_op = ml->sml_op;
+               mods[i].mod_type = ml->sml_desc->ad_cname->bv_val;
+               mods[i].mod_bvalues = ml->sml_bvalues;
+       }
 
-       ldap_modify_s( lc->ld, dn, mods );
+       ldap_modify_s( lc->ld, dn, modv );
        free(mods);     
+       free(modv);     
        return( ldap_back_op_result( lc, op ));
 }
index b2c4cecd3b261fd977f29ceaff3e791dbcfb27db..167c22cb75754f354ca39f0f6c82f07760e015b0 100644 (file)
@@ -37,10 +37,11 @@ ldap_back_modrdn(
     Backend    *be,
     Connection *conn,
     Operation  *op,
-    char       *dn,
-    char       *newrdn,
+    const char *dn,
+    const char *ndn,
+    const char *newrdn,
     int                deleteoldrdn,
-    char       *newSuperior
+    const char *newSuperior
 )
 {
        struct ldapinfo *li = (struct ldapinfo *) be->be_private;
@@ -61,6 +62,6 @@ ldap_back_modrdn(
                        return( -1 );
        }
 
-       ldap_rename2_s( lc->ld, dn, newrdn, deleteoldrdn, newSuperior );
+       ldap_rename2_s( lc->ld, dn, newrdn, newSuperior, deleteoldrdn );
        return( ldap_back_op_result( lc, op ) );
 }
index 8eb4a31f0b3e9ee8a56203a0f8faeac4b2a9a043..5f0c5803f484ef2d6fccba24c23866a914474b1e 100644 (file)
@@ -41,13 +41,14 @@ ldap_back_search(
     Backend    *be,
     Connection *conn,
     Operation  *op,
-    char       *base,
+    const char *base,
+    const char *nbase,
     int                scope,
     int                deref,
     int                size,
     int                time,
     Filter     *filter,
-    char       *filterstr,
+    const char *filterstr,
     char       **attrs,
     int                attrsonly
 )
@@ -144,21 +145,25 @@ ldap_send_entry(
        BerElement *ber = NULL;
        Attribute *attr, **attrp;
        struct berval *dummy = NULL;
+       const char *text;
 
        ent.e_dn = ldap_get_dn(lc->ld, e);
        ent.e_ndn = ch_strdup( ent.e_dn);
-       (void) dn_normalize_case( ent.e_ndn );
+       (void) dn_normalize( ent.e_ndn );
        ent.e_id = 0;
        ent.e_attrs = 0;
        ent.e_private = 0;
        attrp = &ent.e_attrs;
 
-       for (a = ldap_first_attribute(lc->ld, e, &ber); a;
-               a = ldap_next_attribute(lc->ld, e, ber)) {
+       for (   a = ldap_first_attribute(lc->ld, e, &ber);
+                       a != NULL;
+                       a = ldap_next_attribute(lc->ld, e, ber))
+       {
                attr = (Attribute *)ch_malloc( sizeof(Attribute) );
+               if (attr == NULL)
+                       continue;
                attr->a_next = 0;
-               attr->a_type = ch_strdup(a);
-               attr->a_syntax = attr_syntax(a);
+               slap_str2ad(a, &attr->a_desc, &text);
                attr->a_vals = ldap_get_values_len(lc->ld, e, a);
                if (!attr->a_vals)
                        attr->a_vals = &dummy;
@@ -169,7 +174,7 @@ ldap_send_entry(
        for (;ent.e_attrs;) {
                attr=ent.e_attrs;
                ent.e_attrs = attr->a_next;
-               free(attr->a_type);
+               ad_free(attr->a_desc, 1);
                if (attr->a_vals != &dummy)
                        ber_bvecfree(attr->a_vals);
                free(attr);
index ac1adcb7405a9488861bc4d7665f2b810f999bba..63519bbc98a05b18bda2a4aed2f687517c676249 100644 (file)
@@ -51,8 +51,7 @@ ldap_back_conn_destroy(
        ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
 
        if (lc) {
-               if (lc->bound)
-                       ldap_unbind(lc->ld);
+               ldap_unbind(lc->ld);
                free(lc);
        }
 
index d6ce0169041cd47ed99f3501746fe63deac9793a..8acb89f9e77a805fa87cd8df301fbb6f102a3ab2 100644 (file)
@@ -3,11 +3,13 @@
 SRCS = idl.c add.c search.c cache.c dbcache.c dn2id.c entry.c id2entry.c \
                index.c id2children.c nextid.c abandon.c compare.c group.c \
                modify.c modrdn.c delete.c init.c config.c bind.c attr.c \
-               filterindex.c unbind.c kerberos.c close.c alias.c tools.c
+               filterindex.c unbind.c close.c alias.c tools.c key.c \
+               extended.c passwd.c sasl.c
 OBJS = idl.lo add.lo search.lo cache.lo dbcache.lo dn2id.lo entry.lo id2entry.lo \
                index.lo id2children.lo nextid.lo abandon.lo compare.lo group.lo \
                modify.lo modrdn.lo delete.lo init.lo config.lo bind.lo attr.lo \
-               filterindex.lo unbind.lo kerberos.lo close.lo alias.lo tools.lo
+               filterindex.lo unbind.lo close.lo alias.lo tools.lo key.lo \
+               extended.lo passwd.lo sasl.lo
 
 LDAP_INCDIR= ../../../include       
 LDAP_LIBDIR= ../../../libraries
@@ -16,11 +18,21 @@ BUILD_OPT = "--enable-ldbm"
 BUILD_MOD = @BUILD_LDBM@
 LINKAGE = @BUILD_LDBM_DYNAMIC@
 
+DYN_DEFS = -DLIBLBER_DECL=dllimport -DLIBLDAP_DECL=dllimport
+
+# TODO
+#NT_mod_DYN_MODDEFS    =
+#NT_mod_STAT_MODDEFS   =
+
+NT_yes_DYN_MODDEFS     = $(DYN_DEFS)
+NT_yes_STAT_MODDEFS    =
+
+MODDEFS = $(@PLAT@_@BUILD_LDBM@_@LIB_LINKAGE@_MODDEFS)
+
 LIBBASE = back_ldbm
 
 XINCPATH = -I.. -I$(srcdir)/..
 XDEFS = $(MODULES_CPPFLAGS)
-XLDFLAGS = $(MODULES_LDFLAGS)
 
 all-local-lib: ../.backend
 
index 27ace1a927064fea6e62dc4c29a09bb6d31a1fd9..a89dea223a21b1d0d3941b4ef993d6bf17068657 100644 (file)
@@ -1,7 +1,7 @@
 /* abandon.c - ldbm backend abandon routine */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
index edeaf57a10062c0a28be9291182a0e6ef364075b..1577c74bede1d4e7a5e96d4b8c4c46f2fa1c3b18 100644 (file)
@@ -1,7 +1,7 @@
 /* add.c - ldap ldbm back-end add routine */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -29,6 +29,9 @@ ldbm_back_add(
        Entry           *p = NULL;
        int                     rootlock = 0;
        int                     rc; 
+       const char      *text = NULL;
+       AttributeDescription *children = slap_schema.si_ad_children;
+
 
        Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_add: %s\n", e->e_dn, 0, 0);
 
@@ -37,21 +40,21 @@ ldbm_back_add(
 
        if ( ( dn2id( be, e->e_ndn ) ) != NOID ) {
                ldap_pvt_thread_mutex_unlock(&li->li_add_mutex);
-               entry_free( e );
                send_ldap_result( conn, op, LDAP_ALREADY_EXISTS,
                        NULL, NULL, NULL, NULL );
                return( -1 );
        }
 
-       if ( global_schemacheck && oc_schema_check( e ) != 0 ) {
+       rc = entry_schema_check( e, NULL, &text );
+
+       if ( rc != LDAP_SUCCESS ) {
                ldap_pvt_thread_mutex_unlock(&li->li_add_mutex);
 
-               Debug( LDAP_DEBUG_TRACE, "entry failed schema check\n",
-                       0, 0, 0 );
+               Debug( LDAP_DEBUG_TRACE, "entry failed schema check: %s\n",
+                       text, 0, 0 );
 
-               entry_free( e );
-               send_ldap_result( conn, op, LDAP_OBJECT_CLASS_VIOLATION,
-                       NULL, NULL, NULL, NULL );
+               send_ldap_result( conn, op, rc,
+                       NULL, text, NULL, NULL );
                return( -1 );
        }
 
@@ -98,7 +101,6 @@ ldbm_back_add(
                                free( matched_dn );
                        }
 
-                       entry_free( e );
                        free( pdn );
                        return -1;
                }
@@ -109,18 +111,17 @@ ldbm_back_add(
                free(pdn);
 
                if ( ! access_allowed( be, conn, op, p,
-                       "children", NULL, ACL_WRITE ) )
+                       children, NULL, ACL_WRITE ) )
                {
                        /* free parent and writer lock */
                        cache_return_entry_w( &li->li_cache, p ); 
 
-                       Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
+                       Debug( LDAP_DEBUG_TRACE, "no write access to parent\n", 0,
                            0, 0 );
                        send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
-                           NULL, NULL, NULL, NULL );
+                           NULL, "no write access to parent", NULL, NULL );
 
 
-                       entry_free( e );
                        return -1;
                }
 
@@ -134,9 +135,8 @@ ldbm_back_add(
                            0, 0 );
 
                        send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM,
-                           NULL, NULL, NULL, NULL );
+                           NULL, "parent is an alias", NULL, NULL );
 
-                       entry_free( e );
                        return -1;
                }
 
@@ -157,7 +157,6 @@ ldbm_back_add(
 
                        ber_bvecfree( refs );
                        free( matched_dn );
-                       entry_free( e );
                        return -1;
                }
 
@@ -178,7 +177,6 @@ ldbm_back_add(
                        send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
                            NULL, NULL, NULL, NULL );
 
-                       entry_free( e );
                        return -1;
                }
 
@@ -212,29 +210,21 @@ ldbm_back_add(
                Debug( LDAP_DEBUG_ANY, "cache_add_entry_lock failed\n", 0, 0,
                    0 );
 
-               /* free the entry */
-               entry_free( e );
-
                send_ldap_result( conn, op,
-                       rc > 0 ? LDAP_ALREADY_EXISTS : LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
+                       rc > 0 ? LDAP_ALREADY_EXISTS : LDAP_OTHER,
+                       NULL, rc > 0 ? NULL : "cache add failed", NULL, NULL );
 
                return( -1 );
        }
 
        rc = -1;
 
-       /*
-        * Add the entry to the attribute indexes, then add it to
-        * the id2children index, dn2id index, and the id2entry index.
-        */
-
        /* attribute indexes */
-       if ( index_add_entry( be, e ) != 0 ) {
-               Debug( LDAP_DEBUG_TRACE, "index_add_entry failed\n", 0,
+       if ( index_entry_add( be, e, e->e_attrs ) != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "index_entry_add failed\n", 0,
                    0, 0 );
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
+               send_ldap_result( conn, op, LDAP_OTHER,
+                       NULL, "index generation failed", NULL, NULL );
 
                goto return_results;
        }
@@ -243,8 +233,8 @@ ldbm_back_add(
        if ( dn2id_add( be, e->e_ndn, e->e_id ) != 0 ) {
                Debug( LDAP_DEBUG_TRACE, "dn2id_add failed\n", 0,
                    0, 0 );
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
+               send_ldap_result( conn, op, LDAP_OTHER,
+                       NULL, "DN index generation failed", NULL, NULL );
 
                goto return_results;
        }
@@ -254,8 +244,8 @@ ldbm_back_add(
                Debug( LDAP_DEBUG_TRACE, "id2entry_add failed\n", 0,
                    0, 0 );
                (void) dn2id_delete( be, e->e_ndn, e->e_id );
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
+               send_ldap_result( conn, op, LDAP_OTHER,
+                       NULL, "entry store failed", NULL, NULL );
 
                goto return_results;
        }
index ccc68804e3c4ae894df99137ce7f24978ff7fe00..fb7256c5efde4ba2847b670f28122eeee9fa55fc 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 static char* get_alias_dn(
        Entry *e,
        int *err,
-       char **errmsg );
+       const char **errmsg );
 
 static char* new_superior(
-       char *dn,
-       char *oldSup,
-       char *newSup );
+       const char *dn,
+       const char *oldSup,
+       const char *newSup );
 
 static int dnlist_subordinate(
        char** dnlist,
-       char *dn );
+       const char *dn );
 
 Entry *deref_internal_r(
        Backend*        be,
        Entry*          alias,
-       char*           dn,
+       const char*             dn_in,
        int*            err,
        Entry**         matched,
-       char**          text )
+       const char**            text )
 {
+       char *dn;
        struct ldbminfo *li = (struct ldbminfo *) be->be_private;
        Entry *entry;
        Entry *sup;
@@ -49,7 +50,7 @@ Entry *deref_internal_r(
        *text = NULL;
 
        if( alias == NULL ) {
-               dn = ch_strdup( dn );
+               dn = ch_strdup( dn_in );
                entry = dn2entry_r( be, dn, &sup );
 
        } else {
@@ -205,6 +206,7 @@ Entry *deref_internal_r(
        }
 
        free( dn );
+       charray_free( dnlist );
        return entry;
 }
 
@@ -212,9 +214,12 @@ Entry *deref_internal_r(
 static char* get_alias_dn(
        Entry *e,
        int *err,
-       char **errmsg )
+       const char **errmsg )
 {      
-       Attribute *a = attr_find( e->e_attrs, "aliasedobjectname" );
+       Attribute *a;
+       AttributeDescription *aliasedObjectName = slap_schema.si_ad_aliasedObjectName;
+
+       a = attr_find( e->e_attrs, aliasedObjectName );
 
        if( a == NULL ) {
                /*
@@ -247,9 +252,9 @@ static char* get_alias_dn(
 }
 
 char* new_superior(
-       char *dn,
-       char *oldSup,
-       char *newSup )
+       const char *dn,
+       const char *oldSup,
+       const char *newSup )
 {
        char *newDN;
        size_t dnlen, olen, nlen;
@@ -270,7 +275,7 @@ char* new_superior(
 
 static int dnlist_subordinate(
        char** dnlist,
-       char *dn )
+       const char *dn )
 {
        int i;
        assert( dnlist );
index 37a5cf94b34b929be3ca297594108ad4982f2a21..9eb492000d57a3062c9292655740becd8ddc6111 100644 (file)
@@ -1,7 +1,7 @@
 /* attr.c - backend routines for dealing with attributes */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 #include "slap.h"
 #include "back-ldbm.h"
 
+
+/* for the cache of attribute information (which are indexed, etc.) */
+typedef struct ldbm_attrinfo {
+#ifdef SLAPD_USE_AD
+       AttributeDescription *ai_desc; /* attribute description cn;lang-en      */
+#else
+       char *ai_desc;
+#endif
+       slap_index ai_indexmask;        /* how the attr is indexed      */
+} AttrInfo;
+
 static int
 ainfo_type_cmp(
-    char               *type,
+#ifdef SLAPD_USE_AD
+       AttributeDescription *desc,
+#else
+    char               *desc,
+#endif
     AttrInfo   *a
 )
 {
-       return( strcasecmp( type, a->ai_type ) );
+#ifdef SLAPD_USE_AD
+       return ad_cmp( desc, a->ai_desc );
+#else
+       return( strcasecmp( desc, a->ai_desc ) );
+#endif
 }
 
 static int
@@ -30,146 +49,186 @@ ainfo_cmp(
     AttrInfo   *b
 )
 {
-       return( strcasecmp( a->ai_type, b->ai_type ) );
-}
-
-/*
- * Called when a duplicate "index" line is encountered.
- *
- * returns 1 => original from init code, indexmask updated
- *        2 => original not from init code, warn the user
- */
-
-static int
-ainfo_dup(
-    AttrInfo   *a,
-    AttrInfo   *b
-)
-{
-       /*
-        * if the duplicate definition is because we initialized the attr,
-        * just add what came from the config file. otherwise, complain.
-        */
-       if ( a->ai_indexmask & INDEX_FROMINIT ) {
-               a->ai_indexmask |= b->ai_indexmask;
-
-               return( 1 );
-       }
-
-       return( 2 );
+#ifdef SLAPD_USE_AD
+       return ad_cmp( a->ai_desc, b->ai_desc );
+#else
+       return( strcasecmp( a->ai_desc, b->ai_desc ) );
+#endif
 }
 
 void
-attr_masks(
+attr_mask(
     struct ldbminfo    *li,
-    char               *type,
-    int                        *indexmask,
-    int                        *syntaxmask
-)
+#ifdef SLAPD_USE_AD
+       AttributeDescription *desc,
+#else
+    const char *desc,
+#endif
+    slap_index *indexmask )
 {
        AttrInfo        *a;
 
-       *indexmask = 0;
-       *syntaxmask = 0;
-       if ( (a = (AttrInfo *) avl_find( li->li_attrs, type,
-           (AVL_CMP) ainfo_type_cmp )) == NULL ) {
-               if ( (a = (AttrInfo *) avl_find( li->li_attrs, "default",
-                   (AVL_CMP) ainfo_type_cmp )) == NULL ) {
-                       return;
-               }
-       }
-       *indexmask = a->ai_indexmask;
-       if ( strcasecmp( a->ai_type, "default" ) == 0 ) {
-               *syntaxmask = attr_syntax( type );
-       } else {
-               *syntaxmask = a->ai_syntaxmask;
-       }
+       a = (AttrInfo *) avl_find( li->li_attrs, desc,
+           (AVL_CMP) ainfo_type_cmp );
+       
+       *indexmask = a != NULL ? a->ai_indexmask : 0;
 }
 
-void
+int
 attr_index_config(
     struct ldbminfo    *li,
     const char         *fname,
     int                        lineno,
     int                        argc,
-    char               **argv,
-    int                        init
-)
+    char               **argv )
 {
-       int             i, j;
-       char            **attrs, **indexes;
-       AttrInfo        *a;
+       int rc;
+       int     i;
+       slap_index mask;
+       char **attrs;
+       char **indexes = NULL;
 
        attrs = str2charray( argv[0], "," );
+
+       if( attrs == NULL ) {
+               fprintf( stderr, "%s: line %d: "
+                       "no attributes specified: %s\n",
+                       fname, lineno, argv[0] );
+               return LDAP_PARAM_ERROR;
+       }
+
        if ( argc > 1 ) {
                indexes = str2charray( argv[1], "," );
+
+               if( indexes == NULL ) {
+                       fprintf( stderr, "%s: line %d: "
+                               "no indexes specified: %s\n",
+                               fname, lineno, argv[1] );
+                       return LDAP_PARAM_ERROR;
+               }
        }
+
+       if( indexes == NULL ) {
+               mask = li->li_defaultmask;
+
+       } else {
+               mask = 0;
+
+               for ( i = 0; indexes[i] != NULL; i++ ) {
+                       slap_index index;
+                       rc = slap_str2index( indexes[i], &index );
+
+                       if( rc != LDAP_SUCCESS ) {
+                               fprintf( stderr, "%s: line %d: "
+                                       "index type \"%s\" undefined\n",
+                                       fname, lineno, indexes[i] );
+                               return LDAP_PARAM_ERROR;
+                       }
+
+                       mask |= index;
+               }
+       }
+
+    if( !mask ) {
+               fprintf( stderr, "%s: line %d: "
+                       "no indexes selected\n",
+                       fname, lineno );
+               return LDAP_PARAM_ERROR;
+       }
+
        for ( i = 0; attrs[i] != NULL; i++ ) {
+               AttrInfo        *a;
+               AttributeDescription *ad;
+               const char *text;
+
+               if( strcasecmp( attrs[i], "default" ) == 0 ) {
+                       li->li_defaultmask = mask;
+                       continue;
+               }
+
                a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) );
-               a->ai_type = ch_strdup( attrs[i] );
-               a->ai_syntaxmask = attr_syntax( a->ai_type );
-               if ( argc == 1 ) {
-                       a->ai_indexmask = (INDEX_PRESENCE | INDEX_EQUALITY |
-                           INDEX_APPROX | INDEX_SUB);
-               } else {
-                       a->ai_indexmask = 0;
-                       for ( j = 0; indexes[j] != NULL; j++ ) {
-                               if ( strncasecmp( indexes[j], "pres", 4 )
-                                   == 0 ) {
-                                       a->ai_indexmask |= INDEX_PRESENCE;
-                               } else if ( strncasecmp( indexes[j], "eq", 2 )
-                                   == 0 ) {
-                                       a->ai_indexmask |= INDEX_EQUALITY;
-                               } else if ( strncasecmp( indexes[j], "approx",
-                                   6 ) == 0 ) {
-                                       a->ai_indexmask |= INDEX_APPROX;
-                               } else if ( strncasecmp( indexes[j], "sub", 3 )
-                                   == 0 ) {
-                                       a->ai_indexmask |= INDEX_SUB;
-                               } else if ( strncasecmp( indexes[j], "none", 4 )
-                                   == 0 ) {
-                                       if ( a->ai_indexmask != 0 ) {
-                                               fprintf( stderr,
-"%s: line %d: index type \"none\" cannot be combined with other types\n",
-                                                   fname, lineno );
-                                       }
-                                       a->ai_indexmask = 0;
-                               } else {
-                                       fprintf( stderr,
-                       "%s: line %d: unknown index type \"%s\" (ignored)\n",
-                                           fname, lineno, indexes[j] );
-                                       fprintf( stderr,
-       "valid index types are \"pres\", \"eq\", \"approx\", or \"sub\"\n" );
-                               }
-                       }
+
+               ad = NULL;
+               rc = slap_str2ad( attrs[i], &ad, &text );
+
+               if( rc != LDAP_SUCCESS ) {
+                       fprintf( stderr, "%s: line %d: "
+                               "index attribute \"%s\" undefined\n",
+                               fname, lineno, attrs[i] );
+                       return rc;
+               }
+
+               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;
+               }
+
+               if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) && !(
+                       ( ad->ad_type->sat_approx
+                               && ad->ad_type->sat_approx->smr_indexer
+                               && ad->ad_type->sat_approx->smr_filter )
+                       && ( ad->ad_type->sat_equality
+                               && ad->ad_type->sat_equality->smr_indexer
+                               && ad->ad_type->sat_equality->smr_filter ) ) )
+               {
+                       fprintf( stderr, "%s: line %d: "
+                               "approx index of attribute \"%s\" disallowed\n",
+                               fname, lineno, attrs[i] );
+                       return LDAP_INAPPROPRIATE_MATCHING;
                }
-               if ( init ) {
-                       a->ai_indexmask |= INDEX_FROMINIT;
+
+               if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) && !(
+                       ad->ad_type->sat_equality
+                               && ad->ad_type->sat_equality->smr_indexer
+                               && ad->ad_type->sat_equality->smr_filter ) )
+               {
+                       fprintf( stderr, "%s: line %d: "
+                               "equality index of attribute \"%s\" disallowed\n",
+                               fname, lineno, attrs[i] );
+                       return LDAP_INAPPROPRIATE_MATCHING;
                }
 
-               switch (avl_insert( &li->li_attrs, (caddr_t) a,
-                       (AVL_CMP) ainfo_cmp, (AVL_DUP) ainfo_dup ))
+               if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) && !(
+                       ad->ad_type->sat_substr
+                               && ad->ad_type->sat_substr->smr_indexer
+                               && ad->ad_type->sat_substr->smr_filter ) )
                {
-               case 1:         /* duplicate - updating init version */
-                       free( a->ai_type );
-                       free( (char *) a );
-                       break;
-
-               case 2:         /* user duplicate - ignore and warn */
-                       fprintf( stderr,
-    "%s: line %d: duplicate index definition for attr \"%s\" (ignored)\n",
-                           fname, lineno, a->ai_type );
-                       free( a->ai_type );
-                       free( (char *) a );
-                       break;
-
-               default:;       /* inserted ok */
-                       /* FALL */
+                       fprintf( stderr, "%s: line %d: "
+                               "substr index of attribute \"%s\" disallowed\n",
+                               fname, lineno, attrs[i] );
+                       return LDAP_INAPPROPRIATE_MATCHING;
+               }
+
+               Debug( LDAP_DEBUG_CONFIG, "index %s 0x%04x\n",
+                       ad->ad_cname->bv_val, mask, 0 ); 
+
+#ifdef SLAPD_USE_AD
+               a->ai_desc = ad;
+#else
+               a->ai_desc = ch_strdup( ad->ad_cname->bv_val );
+               ad_free( ad, 1 );
+#endif
+
+               a->ai_indexmask = mask;
+
+               rc = avl_insert( &li->li_attrs, (caddr_t) a,
+                       (AVL_CMP) ainfo_cmp, (AVL_DUP) avl_dup_error );
+
+               if( rc ) {
+                       fprintf( stderr, "%s: line %d: duplicate index definition "
+                               "for attr \"%s\" (ignored)\n",
+                           fname, lineno, attrs[i] );
+
+                       return LDAP_PARAM_ERROR;
                }
        }
+
        charray_free( attrs );
-       if ( argc > 1 )
-               charray_free( indexes );
+       if ( indexes != NULL ) charray_free( indexes );
+
+       return LDAP_SUCCESS;
 }
 
 
@@ -177,7 +236,11 @@ static void
 ainfo_free( void *attr )
 {
        AttrInfo *ai = attr;
-       free( ai->ai_type );
+#ifdef SLAPD_USE_AD
+       ad_free( ai->ai_desc, 1 );
+#else
+       free( ai->ai_desc );
+#endif
        free( ai );
 }
 
index cf381da96f4f0627df6e0cf0a347c32b568de4cc..6ea8e8c3a1ee1f73705870115e38b205adca4ed3 100644 (file)
@@ -1,7 +1,7 @@
 /* back-ldbm.h - ldap ldbm back-end header file */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -14,37 +14,26 @@ LDAP_BEGIN_DECL
 
 #define DEFAULT_CACHE_SIZE     1000
 
-#ifdef HAVE_BERKELEY_DB2
+#if defined(HAVE_BERKELEY_DB) && DB_VERSION_MAJOR >= 2
 #      define DEFAULT_DBCACHE_SIZE (100 * DEFAULT_DB_PAGE_SIZE)
 #else
 #      define DEFAULT_DBCACHE_SIZE 100000
 #endif
 
-#define DEFAULT_DB_DIRECTORY   "/usr/tmp"
+#define DEFAULT_DB_DIRECTORY   LDAP_RUNDIR LDAP_DIRSEP "openldap-ldbm"
 #define DEFAULT_MODE           0600
 
-#define SUBLEN                 3
-
-#define DN_BASE_PREFIX         '='
-#define DN_ONE_PREFIX          '@'
-#define DN_SUBTREE_PREFIX      '?'
-
-#define SLAPD_FILTER_DN_ONE            ((ber_tag_t) -2)
-#define SLAPD_FILTER_DN_SUBTREE        ((ber_tag_t) -3)
+#define DN_BASE_PREFIX         SLAP_INDEX_EQUALITY_PREFIX
+#define DN_ONE_PREFIX          '%'
+#define DN_SUBTREE_PREFIX      '@'
 
 /*
  * there is a single index for each attribute.  these prefixes ensure
  * that there is no collision among keys.
  */
-#define EQ_PREFIX      '='     /* prefix for equality keys     */
-#define APPROX_PREFIX  '~'     /* prefix for approx keys       */
-#define SUB_PREFIX     '*'     /* prefix for substring keys    */
-#define CONT_PREFIX    '\\'    /* prefix for continuation keys */
 
-/* allow 3 characters per byte + PREFIX + EOS */
-#define CONT_SIZE ( sizeof(long)*3 + 1 + 1 )
-
-#define UNKNOWN_PREFIX '?'     /* prefix for unknown keys    */
+/* allow PREFIX + byte for continuate number */
+#define SLAP_INDEX_CONT_SIZE ( sizeof(SLAP_INDEX_CONT_PREFIX) + sizeof(unsigned char) )
 
 #define DEFAULT_BLOCKSIZE      8192
 
@@ -102,32 +91,14 @@ typedef struct ldbm_dbcache {
        int             dbc_refcnt;
        int             dbc_maxids;
        int             dbc_maxindirect;
+       int             dbc_dirty;
        time_t  dbc_lastref;
        long    dbc_blksize;
        char    *dbc_name;
        LDBM    dbc_db;
 } DBCache;
 
-/* for the cache of attribute information (which are indexed, etc.) */
-typedef struct ldbm_attrinfo {
-       char    *ai_type;       /* type name (cn, sn, ...)      */
-       int     ai_indexmask;   /* how the attr is indexed      */
-#define INDEX_PRESENCE         0x0001
-#define INDEX_EQUALITY         0x0002
-#define INDEX_APPROX           0x0004
-#define INDEX_SUB                      0x0008
-#define INDEX_UNKNOWN          0x0010
-#define INDEX_FROMINIT         0x1000
-       int     ai_syntaxmask;  /* what kind of syntax          */
-/* ...from slap.h...
-#define SYNTAX_CIS      0x01
-#define SYNTAX_CES      0x02
-#define SYNTAX_BIN      0x04
-   ... etc. ...
-*/
-} AttrInfo;
-
-#define MAXDBCACHE     16
+#define MAXDBCACHE     128
 
 struct ldbminfo {
        ID                      li_nextid;
@@ -135,17 +106,16 @@ struct ldbminfo {
        ldap_pvt_thread_mutex_t         li_root_mutex;
        ldap_pvt_thread_mutex_t         li_add_mutex;
        int                     li_mode;
+       slap_index      li_defaultmask;
        char                    *li_directory;
        Cache           li_cache;
        Avlnode                 *li_attrs;
+       int                     li_dblocking;   /* lock databases */
+       int                     li_dbwritesync; /* write sync */
        int                     li_dbcachesize;
-       int                     li_dbcachewsync;
        DBCache         li_dbcache[MAXDBCACHE];
        ldap_pvt_thread_mutex_t         li_dbcache_mutex;
        ldap_pvt_thread_cond_t          li_dbcache_cv;
-#ifdef HAVE_BERKELEY_DB2
-       DB_ENV                      li_db_env;
-#endif
 };
 
 LDAP_END_DECL
index 377cc8ad3c9c3fda8921fb1f6e6d6fa7d099da19..5aeb74523d66720b772a8ed3505ed785897ccb20 100644 (file)
@@ -39,9 +39,10 @@ CPP=cl.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\Release"
-# PROP Intermediate_Dir "..\Release\backldbm"
+# PROP Output_Dir "..\..\..\Release"
+# PROP Intermediate_Dir "..\..\..\Release\backldbm"
 # PROP Target_Dir ""
+RSC=rc.exe
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
 # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\\" /I "..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
 BSC32=bscmake.exe
@@ -60,9 +61,10 @@ LIB32=link.exe -lib
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\Debug"
-# PROP Intermediate_Dir "..\Debug\backldbm"
+# PROP Output_Dir "..\..\..\Debug"
+# PROP Intermediate_Dir "..\..\..\Debug\backldbm"
 # PROP Target_Dir ""
+RSC=rc.exe
 # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
 # ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\\" /I "..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
 BSC32=bscmake.exe
@@ -81,9 +83,10 @@ LIB32=link.exe -lib
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\SDebug"
-# PROP Intermediate_Dir "..\SDebug\backldbm"
+# PROP Output_Dir "..\..\..\SDebug"
+# PROP Intermediate_Dir "..\..\..\SDebug\backldbm"
 # PROP Target_Dir ""
+RSC=rc.exe
 # ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\\" /I "..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
 # ADD CPP /nologo /W3 /GX /Z7 /Od /I "..\\" /I "..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
 BSC32=bscmake.exe
@@ -102,9 +105,10 @@ LIB32=link.exe -lib
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\SRelease"
-# PROP Intermediate_Dir "..\SRelease\backldbm"
+# PROP Output_Dir "..\..\..\SRelease"
+# PROP Intermediate_Dir "..\..\..\SRelease\backldbm"
 # PROP Target_Dir ""
+RSC=rc.exe
 # ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\\" /I "..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
 # ADD CPP /nologo /W3 /GX /O2 /I "..\\" /I "..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
 BSC32=bscmake.exe
@@ -180,6 +184,10 @@ SOURCE=.\entry.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\extended.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\external.h
 # End Source File
 # Begin Source File
@@ -212,7 +220,7 @@ SOURCE=.\init.c
 # End Source File
 # Begin Source File
 
-SOURCE=.\kerberos.c
+SOURCE=.\key.c
 # End Source File
 # Begin Source File
 
@@ -228,15 +236,15 @@ SOURCE=.\nextid.c
 # End Source File
 # Begin Source File
 
-SOURCE=".\proto-back-ldbm.h"
+SOURCE=.\passwd.c
 # End Source File
 # Begin Source File
 
-SOURCE=.\search.c
+SOURCE=".\proto-back-ldbm.h"
 # End Source File
 # Begin Source File
 
-SOURCE=.\startup.c
+SOURCE=.\search.c
 # End Source File
 # Begin Source File
 
index 1880a8a8ccb10f147dd00b96a0c13570917a42c5..1c72e0eda18c8208ff062db0e796d2ecc3ab3af5 100644 (file)
@@ -1,7 +1,7 @@
 /* bind.c - ldbm backend bind and unbind routines */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 #include "back-ldbm.h"
 #include "proto-back-ldbm.h"
 
-#include <lutil.h>
-
-#ifdef HAVE_KERBEROS
-extern int     krbv4_ldap_auth();
-#endif
-
-static int
-crypted_value_find(
-       struct berval       **vals,
-       struct berval       *v,
-       int                 syntax,
-       int                 normalize,
-       struct berval           *cred
-)
-{
-       int     i;
-       for ( i = 0; vals[i] != NULL; i++ ) {
-               if ( syntax != SYNTAX_BIN ) {
-                       int result;
-
-#ifdef SLAPD_CRYPT
-                       ldap_pvt_thread_mutex_lock( &crypt_mutex );
-#endif
-
-                       result = lutil_passwd(
-                               (char*) cred->bv_val,
-                               (char*) vals[i]->bv_val,
-                               NULL );
-
-#ifdef SLAPD_CRYPT
-                       ldap_pvt_thread_mutex_unlock( &crypt_mutex );
-#endif
-
-                       return result;
-
-               } else {
-                if ( value_cmp( vals[i], v, syntax, normalize ) == 0 ) {
-                        return( 0 );
-                }
-        }
-       }
-
-       return( 1 );
-}
-
 int
 ldbm_back_bind(
     Backend            *be,
     Connection         *conn,
     Operation          *op,
-    char               *dn,
+    const char         *dn,
+    const char         *ndn,
     int                        method,
-       char            *mech,
     struct berval      *cred,
        char**  edn
 )
@@ -80,14 +35,18 @@ ldbm_back_bind(
        Attribute       *a;
        int             rc;
        Entry           *matched;
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
        char            krbname[MAX_K_NAME_SZ + 1];
        AUTH_DAT        ad;
 #endif
 
+       AttributeDescription *password = slap_schema.si_ad_userPassword;
+       AttributeDescription *entry = slap_schema.si_ad_entry;
+
        Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_bind: dn: %s\n", dn, 0, 0);
 
        *edn = NULL;
+       dn = ndn;
 
        /* get entry with reader lock */
        if ( (e = dn2entry_r( be, dn, &matched )) == NULL ) {
@@ -109,34 +68,26 @@ ldbm_back_bind(
                /* allow noauth binds */
                rc = 1;
                if ( method == LDAP_AUTH_SIMPLE ) {
-                       if( cred->bv_len == 0 ) {
-                               /* SUCCESS */
-                               send_ldap_result( conn, op, LDAP_SUCCESS,
-                                       NULL, NULL, NULL, NULL );
-
-                       } else if ( be_isroot_pw( be, dn, cred ) ) {
+                       if ( be_isroot_pw( be, dn, cred ) ) {
                                *edn = ch_strdup( be_root_dn( be ) );
                                rc = 0; /* front end will send result */
 
-                       } else {
+                       } else if ( refs != NULL ) {
                                send_ldap_result( conn, op, LDAP_REFERRAL,
                                        matched_dn, NULL, refs, NULL );
-                       }
 
-               } else if ( method == LDAP_AUTH_SASL ) {
-                       if( mech != NULL && strcasecmp(mech,"DIGEST-MD5") == 0 ) {
-                               /* insert DIGEST calls here */
-                               send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED,
-                                       NULL, NULL, NULL, NULL );
-                               
                        } else {
-                               send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED,
+                               send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
                                        NULL, NULL, NULL, NULL );
                        }
 
-               } else {
+               } else if ( refs != NULL ) {
                        send_ldap_result( conn, op, LDAP_REFERRAL,
                                matched_dn, NULL, refs, NULL );
+
+               } else {
+                       send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
+                               NULL, NULL, NULL, NULL );
                }
 
                if ( matched != NULL ) {
@@ -151,7 +102,7 @@ ldbm_back_bind(
        /* check for deleted */
 
        if ( ! access_allowed( be, conn, op, e,
-               "entry", NULL, ACL_AUTH ) )
+               entry, NULL, ACL_AUTH ) )
        {
                send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
                        NULL, NULL, NULL, NULL );
@@ -165,7 +116,7 @@ ldbm_back_bind(
                    0, 0 );
 
                send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM,
-                   NULL, NULL, NULL, NULL );
+                   NULL, "entry is alias", NULL, NULL );
 
                rc = 1;
                goto return_results;
@@ -179,8 +130,14 @@ ldbm_back_bind(
                Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
                    0, 0 );
 
-               send_ldap_result( conn, op, LDAP_REFERRAL,
-                   e->e_dn, NULL, refs, NULL );
+               if( refs != NULL ) {
+                       send_ldap_result( conn, op, LDAP_REFERRAL,
+                               e->e_dn, NULL, refs, NULL );
+
+               } else {
+                       send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
+                               NULL, NULL, NULL, NULL );
+               }
 
                ber_bvecfree( refs );
 
@@ -190,15 +147,6 @@ ldbm_back_bind(
 
        switch ( method ) {
        case LDAP_AUTH_SIMPLE:
-               if ( cred->bv_len == 0 ) {
-                       send_ldap_result( conn, op, LDAP_SUCCESS,
-                               NULL, NULL, NULL, NULL );
-
-                       /* stop front end from sending result */
-                       rc = 1;
-                       goto return_results;
-               } 
-
                /* check for root dn/passwd */
                if ( be_isroot_pw( be, dn, cred ) ) {
                        /* front end will send result */
@@ -209,7 +157,7 @@ ldbm_back_bind(
                }
 
                if ( ! access_allowed( be, conn, op, e,
-                       "userpassword", NULL, ACL_AUTH ) )
+                       password, NULL, ACL_AUTH ) )
                {
                        send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
                                NULL, NULL, NULL, NULL );
@@ -217,7 +165,7 @@ ldbm_back_bind(
                        goto return_results;
                }
 
-               if ( (a = attr_find( e->e_attrs, "userpassword" )) == NULL ) {
+               if ( (a = attr_find( e->e_attrs, password )) == NULL ) {
                        send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
                            NULL, NULL, NULL, NULL );
 
@@ -226,8 +174,7 @@ ldbm_back_bind(
                        goto return_results;
                }
 
-               if ( crypted_value_find( a->a_vals, cred, a->a_syntax, 0, cred ) != 0 )
-               {
+               if ( slap_passwd_check( a, cred ) != 0 ) {
                        send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
                                NULL, NULL, NULL, NULL );
                        /* stop front end from sending result */
@@ -238,17 +185,8 @@ ldbm_back_bind(
                rc = 0;
                break;
 
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
        case LDAP_AUTH_KRBV41:
-               if ( ! access_allowed( be, conn, op, e,
-                       "krbname", NULL, ACL_AUTH ) )
-               {
-                       send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
-                               NULL, NULL, NULL, NULL );
-                       rc = 1;
-                       goto return_results;
-               }
-
                if ( krbv4_ldap_auth( be, cred, &ad ) != LDAP_SUCCESS ) {
                        send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
                            NULL, NULL, NULL, NULL );
@@ -268,10 +206,9 @@ ldbm_back_bind(
                sprintf( krbname, "%s%s%s@%s", ad.pname, *ad.pinst ? "."
                    : "", ad.pinst, ad.prealm );
 
-
                if ( (a = attr_find( e->e_attrs, "krbname" )) == NULL ) {
                        /*
-                        * no krbName values present:  check against DN
+                        * no krbname values present:  check against DN
                         */
                        if ( strcasecmp( dn, krbname ) == 0 ) {
                                rc = 0;
@@ -282,7 +219,7 @@ ldbm_back_bind(
                        rc = 1;
                        goto return_results;
 
-               } else {        /* look for krbName match */
+               } else {        /* look for krbname match */
                        struct berval   krbval;
 
                        krbval.bv_val = krbname;
@@ -307,12 +244,9 @@ ldbm_back_bind(
                goto return_results;
 #endif
 
-       case LDAP_AUTH_SASL:
-               /* insert SASL code here */
-
        default:
                send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
-                   NULL, "auth method not supported", NULL, NULL );
+                   NULL, "authentication method not supported", NULL, NULL );
                rc = 1;
                goto return_results;
        }
index 0ef36d7d349325b1b1fcc70a995c4651d6624c9a..c1ad17102017dafd92da45b292a15c5d6ec41020 100644 (file)
@@ -1,7 +1,7 @@
 /* cache.c - routines to maintain an in-core cache of entries */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -36,6 +36,7 @@ typedef struct ldbm_entry_info {
        Entry   *lei_lrunext;   /* for cache lru list */
        Entry   *lei_lruprev;
 } EntryInfo;
+#undef LEI
 #define LEI(e) ((EntryInfo *) ((e)->e_private))
 
 static int     cache_delete_entry_internal(Cache *cache, Entry *e);
@@ -445,7 +446,7 @@ cache_find_entry_dn2id(
 
        e.e_dn = (char *) dn;
        e.e_ndn = ch_strdup( dn );
-       (void) dn_normalize_case( e.e_ndn );
+       (void) dn_normalize( e.e_ndn );
 
 try_again:
        /* set cache mutex */
@@ -685,7 +686,9 @@ cache_release_all( Cache *cache )
        Debug( LDAP_DEBUG_TRACE, "====> cache_release_all\n", 0, 0, 0 );
 
        while ( (e = cache->c_lrutail) != NULL && LEI(e)->lei_refcnt == 0 ) {
+#ifdef LDAP_RDWR_DEBUG
                assert(!ldap_pvt_thread_rdwr_active(&LEI(e)->lei_rdwr));
+#endif
 
                /* delete from cache and lru q */
                /* XXX do we need rc ? */
index 9aa2ca4169d22438a172e4ac28f59e076581141b..5ba0c64503adfdad18dc4c98c95117c9edb39b4d 100644 (file)
@@ -1,7 +1,7 @@
 /* close.c - close ldbm backend */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
index 96932cecfc49e15e9276daee84c1f2cca3b6e164..d17c1f4cbbc9feb9e0a7273ad4afdc83b5bfbfd2 100644 (file)
@@ -1,7 +1,7 @@
 /* compare.c - ldbm backend compare routine */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -21,8 +21,9 @@ ldbm_back_compare(
     Backend    *be,
     Connection *conn,
     Operation  *op,
-    char       *dn,
-    Ava                *ava
+    const char *dn,
+    const char *ndn,
+       AttributeAssertion *ava
 )
 {
        struct ldbminfo *li = (struct ldbminfo *) be->be_private;
@@ -33,7 +34,7 @@ ldbm_back_compare(
        int             manageDSAit = get_manageDSAit( op );
 
        /* get entry with reader lock */
-       if ( (e = dn2entry_r( be, dn, &matched )) == NULL ) {
+       if ( (e = dn2entry_r( be, ndn, &matched )) == NULL ) {
                char *matched_dn = NULL;
                struct berval **refs = NULL;
 
@@ -76,7 +77,7 @@ ldbm_back_compare(
        }
 
        if ( ! access_allowed( be, conn, op, e,
-               ava->ava_type, &ava->ava_value, ACL_COMPARE ) )
+               ava->aa_desc, ava->aa_value, ACL_COMPARE ) )
        {
                send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
                        NULL, NULL, NULL, NULL );
@@ -84,21 +85,29 @@ ldbm_back_compare(
                goto return_results;
        }
 
-       if ( (a = attr_find( e->e_attrs, ava->ava_type )) == NULL ) {
-               send_ldap_result( conn, op, LDAP_NO_SUCH_ATTRIBUTE,
-                       NULL, NULL, NULL, NULL );
-               rc = 1;
-               goto return_results;
+       rc = LDAP_NO_SUCH_ATTRIBUTE;
+
+       for(a = attrs_find( e->e_attrs, ava->aa_desc );
+               a != NULL;
+               a = attrs_find( a->a_next, ava->aa_desc ))
+       {
+               rc = LDAP_COMPARE_FALSE;
+
+               if ( value_find( ava->aa_desc, a->a_vals, ava->aa_value ) == 0 )
+               {
+                       rc = LDAP_COMPARE_TRUE;
+                       break;
+               }
+
        }
 
-       if ( value_find( a->a_vals, &ava->ava_value, a->a_syntax, 1 ) == 0 ) 
-               send_ldap_result( conn, op, LDAP_COMPARE_TRUE,
-                       NULL, NULL, NULL, NULL );
-       else
-               send_ldap_result( conn, op, LDAP_COMPARE_FALSE,
-                       NULL, NULL, NULL, NULL );
+       send_ldap_result( conn, op, rc,
+               NULL, NULL, NULL, NULL );
+
+       if( rc != LDAP_NO_SUCH_ATTRIBUTE ) {
+               rc = 0;
+       }
 
-       rc = 0;
 
 return_results:;
        cache_return_entry_r( &li->li_cache, e );
index ef06a4fcc729e66300479246e1f5d41227fa3ed5..a6c3e15a5b189af9be5a66d597e9b57fc2d361d1 100644 (file)
@@ -1,7 +1,7 @@
 /* config.c - ldbm backend configuration file routine */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -25,6 +25,7 @@ ldbm_back_db_config(
     char       **argv
 )
 {
+       int rc;
        struct ldbminfo *li = (struct ldbminfo *) be->be_private;
 
        if ( li == NULL ) {
@@ -67,7 +68,9 @@ ldbm_back_db_config(
 "%s: line %d: extra junk after \"index <attr> [pres,eq,approx,sub]\" line (ignored)\n",
                            fname, lineno );
                }
-               attr_index_config( li, fname, lineno, argc - 1, &argv[1], 0 );
+               rc = attr_index_config( li, fname, lineno, argc - 1, &argv[1] );
+
+               if( rc != LDAP_SUCCESS ) return 1;
 
        /* size of the cache in entries */
        } else if ( strcasecmp( argv[0], "cachesize" ) == 0 ) {
@@ -89,9 +92,15 @@ ldbm_back_db_config(
                }
                li->li_dbcachesize = atoi( argv[1] );
 
-       /* no write sync */
-       } else if ( strcasecmp( argv[0], "dbcachenowsync" ) == 0 ) {
-               li->li_dbcachewsync = 0;
+       /* no locking (not safe) */
+       } else if ( strcasecmp( argv[0], "dbnolocking" ) == 0 ) {
+               li->li_dblocking = 0;
+
+       /* no write sync (not safe) */
+       } else if ( ( strcasecmp( argv[0], "dbnosync" ) == 0 )
+               || ( strcasecmp( argv[0], "dbcachenowsync" ) == 0 ) )
+       {
+               li->li_dbwritesync = 0;
 
        /* anything else */
        } else {
index eecf2c954b3f39690dd24b7bc4e2afc9e8f21186..ad65ddc73e2c945dcce3be9f623294a3ee48469b 100644 (file)
@@ -1,7 +1,7 @@
 /* ldbmcache.c - maintain a cache of open ldbm files */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 #include <ac/socket.h>
 #include <ac/string.h>
 #include <ac/time.h>
-
 #include <sys/stat.h>
 
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
 #include "slap.h"
 #include "back-ldbm.h"
 
 DBCache *
 ldbm_cache_open(
     Backend    *be,
-    char       *name,
-    char       *suffix,
+    const char *name,
+    const char *suffix,
     int                flags
 )
 {
@@ -42,6 +37,18 @@ ldbm_cache_open(
        sprintf( buf, "%s" LDAP_DIRSEP "%s%s",
                li->li_directory, name, suffix );
 
+       if( li->li_dblocking ) {
+               flags |= LDBM_LOCKING;
+       } else {
+               flags |= LDBM_NOLOCKING;
+       }
+       
+       if( li->li_dbwritesync ) {
+               flags |= LDBM_SYNC;
+       } else {
+               flags |= LDBM_NOSYNC;
+       }
+       
        Debug( LDAP_DEBUG_TRACE, "=> ldbm_cache_open( \"%s\", %d, %o )\n", buf,
            flags, li->li_mode );
 
@@ -108,6 +115,7 @@ ldbm_cache_open(
        li->li_dbcache[i].dbc_name = ch_strdup( buf );
        li->li_dbcache[i].dbc_refcnt = 1;
        li->li_dbcache[i].dbc_lastref = curtime;
+       li->li_dbcache[i].dbc_dirty = 0;
 #ifdef HAVE_ST_BLKSIZE
        if ( stat( buf, &st ) == 0 ) {
                li->li_dbcache[i].dbc_blksize = st.st_blksize;
@@ -118,8 +126,10 @@ ldbm_cache_open(
        }
        li->li_dbcache[i].dbc_maxids = (li->li_dbcache[i].dbc_blksize /
            sizeof(ID)) - ID_BLOCK_IDS_OFFSET;
-       li->li_dbcache[i].dbc_maxindirect = (SLAPD_LDBM_MIN_MAXIDS /
-           li->li_dbcache[i].dbc_maxids) + 1;
+       li->li_dbcache[i].dbc_maxindirect = ( SLAPD_LDBM_MIN_MAXIDS /
+           li->li_dbcache[i].dbc_maxids ) + 1;
+
+       assert( li->li_dbcache[i].dbc_maxindirect < 256 );
 
        Debug( LDAP_DEBUG_ARGS,
            "ldbm_cache_open (blksize %ld) (maxids %d) (maxindirect %d)\n",
@@ -135,6 +145,11 @@ ldbm_cache_close( Backend *be, DBCache *db )
 {
        struct ldbminfo *li = (struct ldbminfo *) be->be_private;
 
+       if( li->li_dbwritesync && db->dbc_dirty ) {
+               ldbm_sync( db->dbc_db );
+               db->dbc_dirty = 0;
+       }
+
        ldap_pvt_thread_mutex_lock( &li->li_dbcache_mutex );
        if ( --db->dbc_refcnt == 0 ) {
                ldap_pvt_thread_cond_signal( &li->li_dbcache_cv );
@@ -169,6 +184,7 @@ ldbm_cache_flush_all( Backend *be )
                        Debug( LDAP_DEBUG_TRACE, "ldbm flushing db (%s)\n",
                            li->li_dbcache[i].dbc_name, 0, 0 );
                        ldbm_sync( li->li_dbcache[i].dbc_db );
+                       li->li_dbcache[i].dbc_dirty = 0;
                        if ( li->li_dbcache[i].dbc_refcnt != 0 ) {
                                Debug( LDAP_DEBUG_TRACE,
                                       "refcnt = %d, couldn't close db (%s)\n",
@@ -229,6 +245,7 @@ ldbm_cache_store(
                flags, 0, 0, 0, 0 );
 #endif /* LDBM_DEBUG */
 
+       db->dbc_dirty = 1;
        rc = ldbm_store( db->dbc_db, key, data, flags );
 
        return( rc );
@@ -242,6 +259,7 @@ ldbm_cache_delete(
 {
        int     rc;
 
+       db->dbc_dirty = 1;
        rc = ldbm_delete( db->dbc_db, key );
 
        return( rc );
index eb3ed850e2006ca68242d68ec01117f87b3b1be6..c216f6b90136657ac87fbd3af4a2dfc43e2e83e8 100644 (file)
@@ -1,7 +1,7 @@
 /* delete.c - ldbm backend delete routine */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -21,7 +21,8 @@ ldbm_back_delete(
     Backend    *be,
     Connection *conn,
     Operation  *op,
-    char       *dn
+    const char *dn,
+    const char *ndn
 )
 {
        struct ldbminfo *li = (struct ldbminfo *) be->be_private;
@@ -31,11 +32,12 @@ ldbm_back_delete(
        int rootlock = 0;
        int     rc = -1;
        int             manageDSAit = get_manageDSAit( op );
+       AttributeDescription *children = slap_schema.si_ad_children;
 
        Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_delete: %s\n", dn, 0, 0);
 
        /* get entry with writer lock */
-       if ( (e = dn2entry_w( be, dn, &matched )) == NULL ) {
+       if ( (e = dn2entry_w( be, ndn, &matched )) == NULL ) {
                char *matched_dn = NULL;
                struct berval **refs = NULL;
 
@@ -99,7 +101,7 @@ ldbm_back_delete(
                Debug(LDAP_DEBUG_ARGS, "<=- ldbm_back_delete: non leaf %s\n",
                        dn, 0, 0);
                send_ldap_result( conn, op, LDAP_NOT_ALLOWED_ON_NONLEAF,
-                       NULL, NULL, NULL, NULL );
+                       NULL, "subtree delete not supported", NULL, NULL );
                goto return_results;
        }
 
@@ -109,14 +111,14 @@ ldbm_back_delete(
                        Debug( LDAP_DEBUG_TRACE,
                                "<=- ldbm_back_delete: parent does not exist\n",
                                0, 0, 0);
-                       send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                               NULL, NULL, NULL, NULL );
+                       send_ldap_result( conn, op, LDAP_OTHER,
+                               NULL, "could not locate parent of entry", NULL, NULL );
                        goto return_results;
                }
 
                /* check parent for "children" acl */
                if ( ! access_allowed( be, conn, op, p,
-                       "children", NULL, ACL_WRITE ) )
+                       children, NULL, ACL_WRITE ) )
                {
                        Debug( LDAP_DEBUG_TRACE,
                                "<=- ldbm_back_delete: no access to parent\n", 0,
@@ -146,8 +148,8 @@ ldbm_back_delete(
                Debug(LDAP_DEBUG_ARGS,
                        "<=- ldbm_back_delete: operations error %s\n",
                        dn, 0, 0);
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
+               send_ldap_result( conn, op, LDAP_OTHER,
+                       NULL, "DN index delete failed", NULL, NULL );
                goto return_results;
        }
 
@@ -156,8 +158,8 @@ ldbm_back_delete(
                Debug(LDAP_DEBUG_ARGS,
                        "<=- ldbm_back_delete: operations error %s\n",
                        dn, 0, 0);
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
+               send_ldap_result( conn, op, LDAP_OTHER,
+                       NULL, "entry delete failed", NULL, NULL );
                goto return_results;
        }
 
index afa1c27de6d4c9c18e8b8321af44bba3eaabb32f..ca614d978acdc0cbfab0aca68f2f992f5b7a8a55 100644 (file)
@@ -1,7 +1,7 @@
 /* dn2id.c - routines to deal with the dn2id index */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -48,8 +48,6 @@ dn2id_add(
        data.dsize = sizeof(ID);
 
        flags = LDBM_INSERT;
-       if ( li->li_dbcachewsync ) flags |= LDBM_SYNC;
-
        rc = ldbm_cache_store( db, key, data, flags );
 
        free( key.dptr );
index 7ff873b85550f101b873e1664fc8b3c106d3c533..9f644faeefb200c5d64e6ad64446338cfad0f93a 100644 (file)
@@ -1,7 +1,7 @@
 /* entry.c - ldbm backend entry_release routine */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
diff --git a/servers/slapd/back-ldbm/extended.c b/servers/slapd/back-ldbm/extended.c
new file mode 100644 (file)
index 0000000..5e4762e
--- /dev/null
@@ -0,0 +1,56 @@
+/* extended.c - ldbm backend extended routines */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/socket.h>
+#include <ac/string.h>
+
+#include "slap.h"
+#include "back-ldbm.h"
+#include "proto-back-ldbm.h"
+
+struct exop {
+       char *oid;
+       SLAP_EXTENDED_FN        extended;
+} exop_table[] = {
+       { LDAP_EXOP_X_MODIFY_PASSWD, ldbm_back_exop_passwd },
+       { NULL, NULL }
+};
+
+int
+ldbm_back_extended(
+    Backend            *be,
+    Connection         *conn,
+    Operation          *op,
+       const char              *reqoid,
+    struct berval      *reqdata,
+       char            **rspoid,
+    struct berval      **rspdata,
+       LDAPControl *** rspctrls,
+       const char**    text,
+    struct berval *** refs 
+)
+{
+       int i;
+
+       for( i=0; exop_table[i].oid != NULL; i++ ) {
+               if( strcmp( exop_table[i].oid, reqoid ) == 0 ) {
+                       return (exop_table[i].extended)(
+                               be, conn, op,
+                               reqoid, reqdata,
+                               rspoid, rspdata, rspctrls,
+                               text, refs );
+               }
+       }
+
+       *text = ch_strdup("not supported within naming context");
+       return LDAP_OPERATIONS_ERROR;
+}
+
index e1b8696db6dafa39ff88df9f90cf520e14bdfb7a..5ba17a182e1afb662b2ad10138c8a2f0d0423470 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -20,11 +20,22 @@ extern int  ldbm_back_db_close LDAP_P(( BackendDB *bd ));
 extern int     ldbm_back_db_destroy LDAP_P(( BackendDB *bd ));
 
 extern int     ldbm_back_db_config LDAP_P(( BackendDB *bd,
-       const char *fname, int lineno, int argc, char **argv ));
+       const char *fname, int lineno,
+       int argc, char **argv ));
+
+extern int ldbm_back_extended LDAP_P(( BackendDB *bd,
+       Connection *conn, Operation *op,
+       const char *reqoid,
+       struct berval *reqdata,
+       char **rspoid,
+       struct berval **rspdata,
+       LDAPControl *** rspctrls,
+       const char **text,
+       struct berval *** refs ));
 
 extern int ldbm_back_bind LDAP_P(( BackendDB *bd,
        Connection *conn, Operation *op,
-       char *dn, int method, char* mech,
+       const char *dn, const char *ndn, int method,
        struct berval *cred, char** edn ));
 
 extern int     ldbm_back_unbind LDAP_P(( BackendDB *bd,
@@ -32,34 +43,42 @@ extern int  ldbm_back_unbind LDAP_P(( BackendDB *bd,
 
 extern int     ldbm_back_search LDAP_P(( BackendDB *bd,
        Connection *conn, Operation *op,
-       char *base, int scope, int deref, int sizelimit, int timelimit,
-       Filter *filter, char *filterstr, char **attrs, int attrsonly ));
+       const char *base, const char *nbase,
+       int scope, int deref, int sizelimit, int timelimit,
+       Filter *filter, const char *filterstr,
+       char **attrs, int attrsonly ));
 
-extern int     ldbm_back_compare LDAP_P((BackendDB *bd,
+extern int     ldbm_back_compare LDAP_P(( BackendDB *bd,
        Connection *conn, Operation *op,
-       char *dn, Ava   *ava ));
+       const char *dn, const char *ndn,
+       AttributeAssertion *ava ));
 
 extern int     ldbm_back_modify LDAP_P(( BackendDB *bd,
        Connection *conn, Operation *op,
-       char *dn, LDAPModList *ml ));
+       const char *dn, const char *ndn, Modifications *ml ));
 
 extern int     ldbm_back_modrdn LDAP_P(( BackendDB *bd,
        Connection *conn, Operation *op,
-       char *dn, char* newrdn, int deleteoldrdn,
-       char *newSuperior ));
+       const char *dn, const char *ndn,
+       const char* newrdn, int deleteoldrdn,
+       const char *newSuperior ));
 
 extern int     ldbm_back_add LDAP_P(( BackendDB *bd,
        Connection *conn, Operation *op, Entry *e ));
 
 extern int     ldbm_back_delete LDAP_P(( BackendDB *bd,
-       Connection *conn, Operation *op, char *dn ));
+       Connection *conn, Operation *op,
+       const char *dn, const char *ndn ));
 
 extern int     ldbm_back_abandon LDAP_P(( BackendDB *bd,
        Connection *conn, Operation *op, ber_int_t msgid ));
 
 extern int     ldbm_back_group LDAP_P(( BackendDB *bd,
-       Entry *target, const char* gr_ndn, const char* op_ndn,
-       const char* objectclassValue, const char* groupattrName));
+       Entry *target,
+       const char* gr_ndn,
+       const char* op_ndn,
+       ObjectClass* group_oc,
+       AttributeDescription* group_at));
 
 
 /* hooks for slap tools */
@@ -69,8 +88,11 @@ extern ID ldbm_tool_entry_first LDAP_P(( BackendDB *be ));
 extern ID ldbm_tool_entry_next LDAP_P(( BackendDB *be ));
 extern Entry* ldbm_tool_entry_get LDAP_P(( BackendDB *be, ID id ));
 extern ID ldbm_tool_entry_put LDAP_P(( BackendDB *be, Entry *e ));
-extern int ldbm_tool_index_attr LDAP_P(( BackendDB *be, char* type ));
-extern int ldbm_tool_index_change LDAP_P(( BackendDB *be, char* type,
+
+extern int ldbm_tool_index_attr LDAP_P(( BackendDB *be,
+       AttributeDescription* desc ));
+extern int ldbm_tool_index_change LDAP_P(( BackendDB *be,
+       AttributeDescription* desc,
        struct berval **bv, ID id, int op ));
 extern int ldbm_tool_sync LDAP_P(( BackendDB *be ));
 
index 81deb55a608c602e271bed5abdc77ba2f132f703..59acdb94a1394762d89ed429c11e0a7b422d8498 100644 (file)
@@ -1,7 +1,7 @@
 /* filterindex.c - generate the list of candidate entries from a filter */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 #include "slap.h"
 #include "back-ldbm.h"
 
-static ID_BLOCK        *ava_candidates( Backend *be, Ava *ava, int type );
-static ID_BLOCK        *presence_candidates( Backend *be, char *type );
-static ID_BLOCK        *approx_candidates( Backend *be, Ava *ava );
-static ID_BLOCK        *list_candidates( Backend *be, Filter *flist, int ftype );
-static ID_BLOCK        *substring_candidates( Backend *be, Filter *f );
-static ID_BLOCK        *substring_comp_candidates( Backend *be, char *type, char *val, int prepost );
-
-/*
- * test_filter - test a filter against a single entry.
- * returns     0       filter matched
- *             -1      filter did not match
- *             >0      an ldap error code
- */
+static ID_BLOCK        *presence_candidates(
+       Backend *be,
+       AttributeDescription *desc );
+static ID_BLOCK        *equality_candidates(
+       Backend *be, AttributeAssertion *ava );
+static ID_BLOCK        *approx_candidates(
+       Backend *be, AttributeAssertion *ava );
+static ID_BLOCK        *substring_candidates(
+       Backend *be,
+       Filter *f );
+static ID_BLOCK        *list_candidates(
+       Backend *be,
+       Filter *flist,
+       int ftype );
 
 ID_BLOCK *
 filter_candidates(
@@ -51,9 +52,19 @@ filter_candidates(
                result = dn2idl( be, f->f_dn, DN_SUBTREE_PREFIX );
                break;
 
+       case LDAP_FILTER_PRESENT:
+               Debug( LDAP_DEBUG_FILTER, "\tPRESENT\n", 0, 0, 0 );
+               result = presence_candidates( be, f->f_desc );
+               break;
+
        case LDAP_FILTER_EQUALITY:
                Debug( LDAP_DEBUG_FILTER, "\tEQUALITY\n", 0, 0, 0 );
-               result = ava_candidates( be, &f->f_ava, LDAP_FILTER_EQUALITY );
+               result = equality_candidates( be, f->f_ava );
+               break;
+
+       case LDAP_FILTER_APPROX:
+               Debug( LDAP_DEBUG_FILTER, "\tAPPROX\n", 0, 0, 0 );
+               result = approx_candidates( be, f->f_ava );
                break;
 
        case LDAP_FILTER_SUBSTRINGS:
@@ -63,22 +74,12 @@ filter_candidates(
 
        case LDAP_FILTER_GE:
                Debug( LDAP_DEBUG_FILTER, "\tGE\n", 0, 0, 0 );
-               result = ava_candidates( be, &f->f_ava, LDAP_FILTER_GE );
+               result = idl_allids( be );
                break;
 
        case LDAP_FILTER_LE:
                Debug( LDAP_DEBUG_FILTER, "\tLE\n", 0, 0, 0 );
-               result = ava_candidates( be, &f->f_ava, LDAP_FILTER_LE );
-               break;
-
-       case LDAP_FILTER_PRESENT:
-               Debug( LDAP_DEBUG_FILTER, "\tPRESENT\n", 0, 0, 0 );
-               result = presence_candidates( be, f->f_type );
-               break;
-
-       case LDAP_FILTER_APPROX:
-               Debug( LDAP_DEBUG_FILTER, "\tAPPROX\n", 0, 0, 0 );
-               result = approx_candidates( be, &f->f_ava );
+               result = idl_allids( be );
                break;
 
        case LDAP_FILTER_AND:
@@ -107,49 +108,165 @@ filter_candidates(
 }
 
 static ID_BLOCK *
-ava_candidates(
+presence_candidates(
     Backend    *be,
-    Ava                *ava,
-    int                type
+       AttributeDescription *desc
 )
 {
        ID_BLOCK        *idl;
+       DBCache *db;
+       int rc;
+       char *dbname;
+       slap_index mask;
+       struct berval *prefix;
 
-       Debug( LDAP_DEBUG_TRACE, "=> ava_candidates 0x%x\n", type, 0, 0 );
+       Debug( LDAP_DEBUG_TRACE, "=> presence_candidates\n", 0, 0, 0 );
 
-       switch ( type ) {
-       case LDAP_FILTER_EQUALITY:
-               idl = index_read( be, ava->ava_type, INDEX_EQUALITY,
-                   ava->ava_value.bv_val );
-               break;
+       idl = idl_allids( be );
 
-       case LDAP_FILTER_GE:
-               idl = idl_allids( be );
-               break;
+       rc = index_param( be, desc, LDAP_FILTER_PRESENT,
+               &dbname, &mask, &prefix );
 
-       case LDAP_FILTER_LE:
-               idl = idl_allids( be );
-               break;
+       if( rc != LDAP_SUCCESS ) {
+               return idl;
+       }
+
+       if( dbname == NULL ) {
+               /* not indexed */
+               return idl;
+       }
+
+       db = ldbm_cache_open( be, dbname, LDBM_SUFFIX, LDBM_READER );
+       
+       if ( db == NULL ) {
+               Debug( LDAP_DEBUG_ANY,
+                   "<= presense_candidates db open failed (%s%s)\n",
+                       dbname, LDBM_SUFFIX, 0 );
+               return idl;
+       }
+
+       if( prefix != NULL ) {
+               idl_free( idl );
+               idl = NULL;
+
+               rc = key_read( be, db, prefix, &idl );
+
+               if( rc != LDAP_SUCCESS ) {
+                       Debug( LDAP_DEBUG_TRACE, "<= presense_candidates key read failed (%d)\n",
+                           rc, 0, 0 );
+
+               } else if( idl == NULL ) {
+                       Debug( LDAP_DEBUG_TRACE, "<= presense_candidates NULL\n",
+                           0, 0, 0 );
+               }
        }
 
-       Debug( LDAP_DEBUG_TRACE, "<= ava_candidates %ld\n",
+       ldbm_cache_close( be, db );
+
+
+       Debug( LDAP_DEBUG_TRACE, "<= presence_candidates %ld\n",
            idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
        return( idl );
 }
 
 static ID_BLOCK *
-presence_candidates(
+equality_candidates(
     Backend    *be,
-    char       *type
+       AttributeAssertion *ava
 )
 {
        ID_BLOCK        *idl;
+       DBCache *db;
+       int i;
+       int rc;
+       char *dbname;
+       slap_index mask;
+       struct berval *prefix;
+       struct berval **keys = NULL;
+       MatchingRule *mr;
 
-       Debug( LDAP_DEBUG_TRACE, "=> presence_candidates\n", 0, 0, 0 );
+       Debug( LDAP_DEBUG_TRACE, "=> equality_candidates\n", 0, 0, 0 );
 
-       idl = index_read( be, type, 0, "*" );
+       idl = idl_allids( be );
 
-       Debug( LDAP_DEBUG_TRACE, "<= presence_candidates %ld\n",
+       rc = index_param( be, ava->aa_desc, LDAP_FILTER_EQUALITY,
+               &dbname, &mask, &prefix );
+
+       if( rc != LDAP_SUCCESS ) {
+               return idl;
+       }
+
+       if( dbname == NULL ) {
+               /* not indexed */
+               return idl;
+       }
+
+       mr = ava->aa_desc->ad_type->sat_equality;
+       if( !mr ) {
+               /* return LDAP_INAPPROPRIATE_MATCHING; */
+               return idl;
+       }
+
+       if( !mr->smr_filter ) {
+               return idl;
+       }
+
+       rc = (mr->smr_filter)(
+               LDAP_FILTER_EQUALITY,
+               ava->aa_desc->ad_type->sat_syntax,
+               mr,
+               prefix,
+               ava->aa_value,
+               &keys );
+
+       if( rc != LDAP_SUCCESS ) {
+               return idl;
+       }
+
+       db = ldbm_cache_open( be, dbname, LDBM_SUFFIX, LDBM_READER );
+       
+       if ( db == NULL ) {
+               Debug( LDAP_DEBUG_ANY,
+                   "<= equality_candidates db open failed (%s%s)\n",
+                       dbname, LDBM_SUFFIX, 0 );
+               return idl;
+       }
+
+       for ( i= 0; keys[i] != NULL; i++ ) {
+               ID_BLOCK *save;
+               ID_BLOCK *tmp;
+
+               rc = key_read( be, db, keys[i], &tmp );
+
+               if( rc != LDAP_SUCCESS ) {
+                       idl_free( idl );
+                       idl = NULL;
+                       Debug( LDAP_DEBUG_TRACE, "<= equality_candidates key read failed (%d)\n",
+                           rc, 0, 0 );
+                       break;
+               }
+
+               if( tmp == NULL ) {
+                       idl_free( idl );
+                       idl = NULL;
+                       Debug( LDAP_DEBUG_TRACE, "<= equality_candidates NULL\n",
+                           0, 0, 0 );
+                       break;
+               }
+
+               save = idl;
+               idl = idl_intersection( be, idl, tmp );
+               idl_free( save );
+
+               if( idl == NULL ) break;
+       }
+
+       ber_bvecfree( keys );
+
+       ldbm_cache_close( be, db );
+
+
+       Debug( LDAP_DEBUG_TRACE, "<= equality_candidates %ld\n",
            idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
        return( idl );
 }
@@ -157,35 +274,104 @@ presence_candidates(
 static ID_BLOCK *
 approx_candidates(
     Backend    *be,
-    Ava                *ava
+       AttributeAssertion *ava
 )
 {
-       char    *w, *c;
-       ID_BLOCK        *idl, *tmp;
+       ID_BLOCK *idl;
+       DBCache *db;
+       int i;
+       int rc;
+       char *dbname;
+       slap_index mask;
+       struct berval *prefix;
+       struct berval **keys = NULL;
+       MatchingRule *mr;
 
        Debug( LDAP_DEBUG_TRACE, "=> approx_candidates\n", 0, 0, 0 );
 
-       idl = NULL;
-       for ( w = first_word( ava->ava_value.bv_val ); w != NULL;
-           w = next_word( w ) ) {
-               c = phonetic( w );
-               if ( (tmp = index_read( be, ava->ava_type, INDEX_APPROX, c ))
-                   == NULL ) {
-                       free( c );
+       idl = idl_allids( be );
+
+       rc = index_param( be, ava->aa_desc, LDAP_FILTER_EQUALITY,
+               &dbname, &mask, &prefix );
+
+       if( rc != LDAP_SUCCESS ) {
+               return idl;
+       }
+
+       if( dbname == NULL ) {
+               /* not indexed */
+               return idl;
+       }
+
+       mr = ava->aa_desc->ad_type->sat_approx;
+       if( mr == NULL ) {
+               /* no approx matching rule, try equality matching rule */
+               mr = ava->aa_desc->ad_type->sat_equality;
+       }
+
+       if( !mr ) {
+               /* return LDAP_INAPPROPRIATE_MATCHING; */
+               return idl;
+       }
+
+       if( !mr->smr_filter ) {
+               return idl;
+       }
+
+       rc = (mr->smr_filter)(
+               LDAP_FILTER_EQUALITY,
+               ava->aa_desc->ad_type->sat_syntax,
+               mr,
+               prefix,
+               ava->aa_value,
+               &keys );
+
+       if( rc != LDAP_SUCCESS ) {
+               return idl;
+       }
+
+       db = ldbm_cache_open( be, dbname, LDBM_SUFFIX, LDBM_READER );
+       
+       if ( db == NULL ) {
+               Debug( LDAP_DEBUG_ANY,
+                   "<= approx_candidates db open failed (%s%s)\n",
+                       dbname, LDBM_SUFFIX, 0 );
+               return idl;
+       }
+
+       for ( i= 0; keys[i] != NULL; i++ ) {
+               ID_BLOCK *save;
+               ID_BLOCK *tmp;
+
+               rc = key_read( be, db, keys[i], &tmp );
+
+               if( rc != LDAP_SUCCESS ) {
+                       idl_free( idl );
+                       idl = NULL;
+                       Debug( LDAP_DEBUG_TRACE, "<= approx_candidates key read failed (%d)\n",
+                           rc, 0, 0 );
+                       break;
+               }
+
+               if( tmp == NULL ) {
                        idl_free( idl );
+                       idl = NULL;
                        Debug( LDAP_DEBUG_TRACE, "<= approx_candidates NULL\n",
                            0, 0, 0 );
-                       return( NULL );
+                       break;
                }
-               free( c );
 
-               if ( idl == NULL ) {
-                       idl = tmp;
-               } else {
-                       idl = idl_intersection( be, idl, tmp );
-               }
+               save = idl;
+               idl = idl_intersection( be, idl, tmp );
+               idl_free( save );
+
+               if( idl == NULL ) break;
        }
 
+       ber_bvecfree( keys );
+
+       ldbm_cache_close( be, db );
+
        Debug( LDAP_DEBUG_TRACE, "<= approx_candidates %ld\n",
            idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
        return( idl );
@@ -238,136 +424,13 @@ substring_candidates(
     Filter     *f
 )
 {
-       int     i;
-       ID_BLOCK        *idl, *tmp, *tmp2;
+       ID_BLOCK *idl;
 
        Debug( LDAP_DEBUG_TRACE, "=> substring_candidates\n", 0, 0, 0 );
 
-       idl = NULL;
-
-       /* initial */
-       if ( f->f_sub_initial != NULL ) {
-               if ( (int) strlen( f->f_sub_initial ) < SUBLEN - 1 ) {
-                       idl = idl_allids( be );
-               } else if ( (idl = substring_comp_candidates( be, f->f_sub_type,
-                   f->f_sub_initial, '^' )) == NULL ) {
-                       return( NULL );
-               }
-       }
-
-       /* final */
-       if ( f->f_sub_final != NULL ) {
-               if ( (int) strlen( f->f_sub_final ) < SUBLEN - 1 ) {
-                       tmp = idl_allids( be );
-               } else if ( (tmp = substring_comp_candidates( be, f->f_sub_type,
-                   f->f_sub_final, '$' )) == NULL ) {
-                       idl_free( idl );
-                       return( NULL );
-               }
-
-               if ( idl == NULL ) {
-                       idl = tmp;
-               } else {
-                       tmp2 = idl;
-                       idl = idl_intersection( be, idl, tmp );
-                       idl_free( tmp );
-                       idl_free( tmp2 );
-               }
-       }
-
-       for ( i = 0; f->f_sub_any != NULL && f->f_sub_any[i] != NULL; i++ ) {
-               if ( (int) strlen( f->f_sub_any[i] ) < SUBLEN ) {
-                       tmp = idl_allids( be );
-               } else if ( (tmp = substring_comp_candidates( be, f->f_sub_type,
-                   f->f_sub_any[i], 0 )) == NULL ) {
-                       idl_free( idl );
-                       return( NULL );
-               }
-
-               if ( idl == NULL ) {
-                       idl = tmp;
-               } else {
-                       tmp2 = idl;
-                       idl = idl_intersection( be, idl, tmp );
-                       idl_free( tmp );
-                       idl_free( tmp2 );
-               }
-       }
-
+       idl = idl_allids( be );
        Debug( LDAP_DEBUG_TRACE, "<= substring_candidates %ld\n",
            idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
        return( idl );
 }
 
-static ID_BLOCK *
-substring_comp_candidates(
-    Backend    *be,
-    char       *type,
-    char       *val,
-    int                prepost
-)
-{
-       int     i, len;
-       ID_BLOCK        *idl, *tmp, *tmp2;
-       char    *p;
-       char    buf[SUBLEN + 1];
-
-       Debug( LDAP_DEBUG_TRACE, "=> substring_comp_candidates\n", 0, 0, 0 );
-
-       len = strlen( val );
-       idl = NULL;
-
-       /* prepend ^ for initial substring */
-       if ( prepost == '^' ) {
-               buf[0] = '^';
-               for ( i = 0; i < SUBLEN - 1; i++ ) {
-                       buf[i + 1] = val[i];
-               }
-               buf[SUBLEN] = '\0';
-
-               if ( (idl = index_read( be, type, INDEX_SUB, buf )) == NULL ) {
-                       return( NULL );
-               }
-       } else if ( prepost == '$' ) {
-               p = val + len - SUBLEN + 1;
-               for ( i = 0; i < SUBLEN - 1; i++ ) {
-                       buf[i] = p[i];
-               }
-               buf[SUBLEN - 1] = '$';
-               buf[SUBLEN] = '\0';
-
-               if ( (idl = index_read( be, type, INDEX_SUB, buf )) == NULL ) {
-                       return( NULL );
-               }
-       }
-
-       for ( p = val; p < (val + len - SUBLEN + 1); p++ ) {
-               for ( i = 0; i < SUBLEN; i++ ) {
-                       buf[i] = p[i];
-               }
-               buf[SUBLEN] = '\0';
-
-               if ( (tmp = index_read( be, type, INDEX_SUB, buf )) == NULL ) {
-                       idl_free( idl );
-                       return( NULL );
-               }
-
-               if ( idl == NULL ) {
-                       idl = tmp;
-               } else {
-                       tmp2 = idl;
-                       idl = idl_intersection( be, idl, tmp );
-                       idl_free( tmp );
-                       idl_free( tmp2 );
-               }
-
-               /* break if no candidates */
-               if( idl == NULL ) {
-                       break;
-               }
-       }
-
-       Debug( LDAP_DEBUG_TRACE, "<= substring_comp_candidates %ld\n",
-           idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
-       return( idl );
-}
index 8dbe75922a4ad251cc7c1cb04dec006a6c5ef916..d5b8aad4397db60140d1b8c9af01d835054eced1 100644 (file)
@@ -1,7 +1,7 @@
 /* group.c - ldbm backend acl group routine */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -27,17 +27,26 @@ ldbm_back_group(
        Entry   *target,
        const char      *gr_ndn,
        const char      *op_ndn,
-       const char      *objectclassValue,
-       const char      *groupattrName
+       ObjectClass *group_oc,
+       AttributeDescription *group_at
 )
 {
        struct ldbminfo *li = (struct ldbminfo *) be->be_private;    
        Entry        *e;
        int          rc = 1;
-
        Attribute   *attr;
        struct berval bv;
 
+       AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass;
+       const char *group_oc_name = NULL;
+       const char *group_at_name = group_at->ad_cname->bv_val;
+
+       if( group_oc->soc_names && group_oc->soc_names[0] ) {
+               group_oc_name = group_oc->soc_names[0];
+       } else {
+               group_oc_name = group_oc->soc_oid;
+       }
+
        Debug( LDAP_DEBUG_ARGS,
                "=> ldbm_back_group: gr dn: \"%s\"\n",
                gr_ndn, 0, 0 ); 
@@ -45,8 +54,8 @@ ldbm_back_group(
                "=> ldbm_back_group: op dn: \"%s\"\n",
                op_ndn, 0, 0 ); 
        Debug( LDAP_DEBUG_ARGS,
-               "=> ldbm_back_group: objectClass: \"%s\" attrName: \"%s\"\n", 
-               objectclassValue, groupattrName, 0 ); 
+               "=> ldbm_back_group: oc: \"%s\" at: \"%s\"\n", 
+               group_oc_name, group_at_name, 0 ); 
 
        Debug( LDAP_DEBUG_ARGS,
                "=> ldbm_back_group: tr dn: \"%s\"\n",
@@ -80,66 +89,52 @@ ldbm_back_group(
         
        rc = 1;
         
-       if ((attr = attr_find(e->e_attrs, "objectclass")) == NULL)  {
-               Debug( LDAP_DEBUG_ACL,
-                       "<= ldbm_back_group: failed to find objectClass\n", 0, 0, 0 );
-               goto return_results;
-       }
        
-       bv.bv_val = "ALIAS";
-       bv.bv_len = sizeof("ALIAS")-1;
-
-       if ( value_find(attr->a_vals, &bv, attr->a_syntax, 1) == 0) {
+       if( is_entry_alias( e ) ) {
                Debug( LDAP_DEBUG_ACL,
                        "<= ldbm_back_group: group is an alias\n", 0, 0, 0 );
                goto return_results;
        }
 
-       bv.bv_val = "REFERRAL";
-       bv.bv_len = sizeof("REFERRAL")-1;
-
-       if ( value_find(attr->a_vals, &bv, attr->a_syntax, 1) == 0) {
+       if( is_entry_referral( e ) ) {
                Debug( LDAP_DEBUG_ACL,
-                       "<= ldbm_back_group: group is a referral\n",
-                       0, 0, 0 );
+                       "<= ldbm_back_group: group is an referral\n", 0, 0, 0 );
                goto return_results;
        }
 
-       bv.bv_val = (char *) objectclassValue;
-       bv.bv_len = strlen( bv.bv_val );         
-
-       if (value_find(attr->a_vals, &bv, attr->a_syntax, 1) != 0) {
+       if( is_entry_objectclass( e, group_oc ) ) {
                Debug( LDAP_DEBUG_ACL,
                        "<= ldbm_back_group: failed to find %s in objectClass\n", 
-                               objectclassValue, 0, 0 ); 
+                               group_oc_name, 0, 0 ); 
                goto return_results;
        }
 
-       if ((attr = attr_find(e->e_attrs, groupattrName)) == NULL) {
+       if ((attr = attr_find(e->e_attrs, group_at)) == NULL) {
                Debug( LDAP_DEBUG_ACL,
                        "<= ldbm_back_group: failed to find %s\n",
-                       groupattrName, 0, 0 ); 
+                       group_at_name, 0, 0 ); 
                goto return_results;
        }
 
        Debug( LDAP_DEBUG_ACL,
                "<= ldbm_back_group: found objectClass %s and %s\n",
-               objectclassValue, groupattrName, 0 ); 
+               group_oc_name, group_at_name, 0 ); 
 
        bv.bv_val = (char *) op_ndn;
        bv.bv_len = strlen( op_ndn );         
 
-       if( value_find( attr->a_vals, &bv, attr->a_syntax, 1) != 0 )
-       {
+       if( value_find( group_at, attr->a_vals, &bv ) == 0 ) {
                Debug( LDAP_DEBUG_ACL,
                        "<= ldbm_back_group: \"%s\" not in \"%s\": %s\n", 
-                       op_ndn, gr_ndn, groupattrName ); 
+                       op_ndn, gr_ndn, group_at_name ); 
                goto return_results;
        }
 
+
+
        Debug( LDAP_DEBUG_ACL,
                "<= ldbm_back_group: \"%s\" is in \"%s\": %s\n", 
-               op_ndn, gr_ndn, groupattrName ); 
+               op_ndn, gr_ndn, group_at_name ); 
 
        rc = 0;
 
index acbab8fd77a88bf6b5b0b69bff8caf9fccc7ba74..983f4e05cbcb2ed5f6ec92678697c2c80ca7c2fa 100644 (file)
@@ -1,7 +1,7 @@
 /* id2children.c - routines to deal with the id2children index */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
index 53f52d85a52e6a1263627375869f1daac6078f33..f38802126deecc62dc63e000b8e4529a1d81c2d0 100644 (file)
@@ -1,7 +1,7 @@
 /* id2entry.c - routines to deal with the id2entry index */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -49,7 +49,6 @@ id2entry_add( Backend *be, Entry *e )
 
        /* store it */
        flags = LDBM_REPLACE;
-       if ( li->li_dbcachewsync ) flags |= LDBM_SYNC;
        rc = ldbm_cache_store( db, key, data, flags );
 
        ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
@@ -73,7 +72,7 @@ id2entry_delete( Backend *be, Entry *e )
            e->e_dn, 0 );
 
 #ifdef notdef
-#ifdef LDAP_DEBUG
+#ifdef LDAP_RDWR_DEBUG
        /* check for writer lock */
        assert(ldap_pvt_thread_rdwr_writers(&e->e_rdwr) == 1);
 #endif
index f528fa8665f044e43e00fdfc1dd16d81058f25c7..7d18956361435b776a8467c62ff17ab0284e9684 100644 (file)
@@ -1,7 +1,7 @@
 /* idl.c - ldap id list handling routines */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 
 static ID_BLOCK* idl_dup( ID_BLOCK *idl );
 
+static void cont_alloc( Datum cont, Datum key )
+{
+       ldbm_datum_init( cont );
+       cont.dsize = 1 + sizeof(ID) + key.dsize;
+       cont.dptr = ch_malloc( cont.dsize );
+
+       memcpy( &((unsigned char *)cont.dptr)[1 + sizeof(ID)],
+               key.dptr, key.dsize );
+}
+
+static void cont_id( Datum cont, ID id )
+{
+       int i;
+
+       for( i=1; i <= sizeof(id); i++) {
+               ((unsigned char *)cont.dptr)[i] = (unsigned char)(id & 0xFF);
+               id >>= 8;
+       }
+
+}
+
+static void cont_free( Datum cont )
+{
+       ch_free( cont.dptr );
+}
+
 /* Allocate an ID_BLOCK with room for nids ids */
 ID_BLOCK *
 idl_alloc( unsigned int nids )
@@ -106,7 +132,6 @@ idl_fetch(
        Datum   data;
        ID_BLOCK        *idl;
        ID_BLOCK        **tmp;
-       char    *kstr;
        int     i, nids;
 
        idl = idl_fetch_one( be, db, key );
@@ -141,27 +166,21 @@ idl_fetch(
        tmp = (ID_BLOCK **) ch_malloc( (i + 1) * sizeof(ID_BLOCK *) );
 
        /* read in all the blocks */
-       kstr = (char *) ch_malloc( key.dsize + CONT_SIZE );
+       cont_alloc( data, key );
        nids = 0;
        for ( i = 0; !ID_BLOCK_NOID(idl, i); i++ ) {
-               ldbm_datum_init( data );
-
-               sprintf( kstr, "%c%ld%s", CONT_PREFIX,
-                       ID_BLOCK_ID(idl, i), key.dptr );
-
-               data.dptr = kstr;
-               data.dsize = strlen( kstr ) + 1;
+               cont_id( data, ID_BLOCK_ID(idl, i) );
 
                if ( (tmp[i] = idl_fetch_one( be, db, data )) == NULL ) {
                        Debug( LDAP_DEBUG_ANY,
-                           "idl_fetch of (%s) returns NULL\n", data.dptr, 0, 0 );
+                           "idl_fetch: one returned NULL\n", 0, 0, 0 );
                        continue;
                }
 
                nids += ID_BLOCK_NIDS(tmp[i]);
        }
        tmp[i] = NULL;
-       free( kstr );
+       cont_free( data );
        idl_free( idl );
 
        /* allocate space for the big block */
@@ -217,7 +236,6 @@ idl_store(
 #endif
 
        flags = LDBM_REPLACE;
-       if( li->li_dbcachewsync ) flags |= LDBM_SYNC;
        rc = ldbm_cache_store( db, key, data, flags );
 
        /* Debug( LDAP_DEBUG_TRACE, "<= idl_store %d\n", rc, 0, 0 ); */
@@ -295,19 +313,17 @@ idl_change_first(
        /* delete old key block */
        if ( (rc = ldbm_cache_delete( db, bkey )) != 0 ) {
                Debug( LDAP_DEBUG_ANY,
-                   "ldbm_delete of (%s) returns %d\n", bkey.dptr, rc,
-                   0 );
+                   "idl_change_first: ldbm_cache_delete returned %d\n",
+                       rc, 0, 0 );
                return( rc );
        }
 
        /* write block with new key */
-       sprintf( bkey.dptr, "%c%ld%s", CONT_PREFIX,
-               ID_BLOCK_ID(b, 0), hkey.dptr );
+       cont_id( bkey, ID_BLOCK_ID(b, 0) );
 
-       bkey.dsize = strlen( bkey.dptr ) + 1;
        if ( (rc = idl_store( be, db, bkey, b )) != 0 ) {
                Debug( LDAP_DEBUG_ANY,
-                   "idl_store of (%s) returns %d\n", bkey.dptr, rc, 0 );
+                   "idl_change_first: idl_store returned %d\n", rc, 0, 0 );
                return( rc );
        }
 
@@ -315,7 +331,7 @@ idl_change_first(
        ID_BLOCK_ID(h, pos) = ID_BLOCK_ID(b, 0);
        if ( (rc = idl_store( be, db, hkey, h )) != 0 ) {
                Debug( LDAP_DEBUG_ANY,
-                   "idl_store of (%s) returns %d\n", hkey.dptr, rc, 0 );
+                   "idl_change_first: idl_store returned %d\n", rc, 0, 0 );
                return( rc );
        }
 
@@ -333,17 +349,9 @@ idl_insert_key(
 {
        int     i, j, first, rc;
        ID_BLOCK        *idl, *tmp, *tmp2, *tmp3;
-       char    *kstr;
        Datum   k2;
 
-       ldbm_datum_init( k2 );
-
        if ( (idl = idl_fetch_one( be, db, key )) == NULL ) {
-#ifdef LDBM_DEBUG
-               Statslog( LDAP_DEBUG_STATS, "=> idl_insert_key(): no key yet\n",
-                       0, 0, 0, 0, 0 );
-#endif
-
                idl = idl_alloc( 1 );
                ID_BLOCK_ID(idl, ID_BLOCK_NIDS(idl)++) = id;
                rc = idl_store( be, db, key, idl );
@@ -393,23 +401,16 @@ idl_insert_key(
                        /* store it */
                        rc = idl_store( be, db, key, idl );
 
-                       /* store the first id block */
-                       kstr = (char *) ch_malloc( key.dsize + CONT_SIZE );
-                       sprintf( kstr, "%c%ld%s", CONT_PREFIX,
-                               ID_BLOCK_ID(tmp, 0), key.dptr );
+                       cont_alloc( k2, key );
+                       cont_id( k2, ID_BLOCK_ID(tmp, 0) );
 
-                       k2.dptr = kstr;
-                       k2.dsize = strlen( kstr ) + 1;
                        rc = idl_store( be, db, k2, tmp );
 
-                       /* store the second id block */
-                       sprintf( kstr, "%c%ld%s", CONT_PREFIX,
-                               ID_BLOCK_ID(tmp2, 0), key.dptr );
-                       k2.dptr = kstr;
-                       k2.dsize = strlen( kstr ) + 1;
+                       cont_id( k2, ID_BLOCK_ID(tmp2, 0) );
                        rc = idl_store( be, db, k2, tmp2 );
 
-                       free( kstr );
+                       cont_free( k2 );
+
                        idl_free( tmp );
                        idl_free( tmp2 );
                        break;
@@ -430,6 +431,7 @@ idl_insert_key(
        /* select the block to try inserting into *//* XXX linear search XXX */
        for ( i = 0; !ID_BLOCK_NOID(idl, i) && id > ID_BLOCK_ID(idl, i); i++ )
                ;       /* NULL */
+
        if ( i != 0 ) {
                i--;
                first = 0;
@@ -438,15 +440,13 @@ idl_insert_key(
        }
 
        /* get the block */
-       kstr = (char *) ch_malloc( key.dsize + CONT_SIZE );
-       sprintf( kstr, "%c%ld%s", CONT_PREFIX,
-               ID_BLOCK_ID(idl, i), key.dptr );
-       k2.dptr = kstr;
-       k2.dsize = strlen( kstr ) + 1;
+       cont_alloc( k2, key );
+       cont_id( k2, ID_BLOCK_ID(idl, i) );
+
        if ( (tmp = idl_fetch_one( be, db, k2 )) == NULL ) {
-               Debug( LDAP_DEBUG_ANY, "nonexistent continuation block (%s)\n",
-                   k2.dptr, 0, 0 );
-               free( kstr );
+               Debug( LDAP_DEBUG_ANY, "idl_insert_key: nonexistent continuation block\n",
+                   0, 0, 0 );
+               cont_free( k2 );
                idl_free( idl );
                return( -1 );
        }
@@ -456,7 +456,7 @@ idl_insert_key(
        case 0:         /* id inserted ok */
                if ( (rc = idl_store( be, db, k2, tmp )) != 0 ) {
                        Debug( LDAP_DEBUG_ANY,
-                           "idl_store of (%s) returns %d\n", k2.dptr, rc, 0 );
+                           "idl_insert_key: idl_store returned %d\n", rc, 0, 0 );
                }
                break;
 
@@ -485,18 +485,51 @@ idl_insert_key(
                /* is there a next block? */
                if ( !first && !ID_BLOCK_NOID(idl, i + 1) ) {
                        /* read it in */
-                       sprintf( kstr, "%c%ld%s", CONT_PREFIX,
-                               ID_BLOCK_ID(idl, i + 1), key.dptr );
-                       k2.dptr = kstr;
-                       k2.dsize = strlen( kstr ) + 1;
+                       cont_alloc( k2, key );
+                       cont_id( k2, ID_BLOCK_ID(idl, i) );
                        if ( (tmp2 = idl_fetch_one( be, db, k2 )) == NULL ) {
                                Debug( LDAP_DEBUG_ANY,
-                                   "idl_fetch_one (%s) returns NULL\n",
-                                   k2.dptr, 0, 0 );
+                                   "idl_insert_key: idl_fetch_one returned NULL\n",
+                                   0, 0, 0 );
                                /* split the original block */
+                               cont_free( k2 );
                                goto split;
                        }
 
+                       /* If the new id is less than the last id in the
+                        * current block, it must not be put into the next
+                        * block. Push the last id of the current block
+                        * into the next block instead.
+                        */
+                       if (id < ID_BLOCK_ID(tmp, ID_BLOCK_NIDS(tmp) - 1)) {
+                           ID id2 = ID_BLOCK_ID(tmp, ID_BLOCK_NIDS(tmp) - 1);
+                           Datum k3;
+
+                           ldbm_datum_init( k3 );
+
+                           --ID_BLOCK_NIDS(tmp);
+                           /* This must succeed since we just popped one
+                            * ID off the end of it.
+                            */
+                           rc = idl_insert( &tmp, id, db->dbc_maxids );
+
+                               k3.dptr = ch_malloc(k2.dsize);
+                               k3.dsize = k2.dsize;
+                               memcpy(k3.dptr, k2.dptr, k3.dsize);
+                           if ( (rc = idl_store( be, db, k3, tmp )) != 0 ) {
+                               Debug( LDAP_DEBUG_ANY,
+                           "idl_insert_key: idl_store returned %d\n", rc, 0, 0 );
+                           }
+
+                               free( k3.dptr );
+
+                           id = id2;
+                           /* This new id will necessarily be inserted
+                            * as the first id of the next block by the
+                            * following switch() statement.
+                            */
+                       }
+
                        switch ( (rc = idl_insert( &tmp2, id,
                            db->dbc_maxids )) ) {
                        case 1:         /* id inserted first in block */
@@ -505,13 +538,18 @@ idl_insert_key(
                                /* FALL */
 
                        case 2:         /* id already there - how? */
-                       case 0:         /* id inserted */
+                       case 0:         /* id inserted: this can never be
+                                        * the result of idl_insert, because
+                                        * we guaranteed that idl_change_first
+                                        * will always be called.
+                                        */
                                if ( rc == 2 ) {
                                        Debug( LDAP_DEBUG_ANY,
-                                           "id %ld already in next block\n",
+                                           "idl_insert_key: id %ld already in next block\n",
                                            id, 0, 0 );
                                }
-                               free( kstr );
+
+                               assert( 0 ); /* not yet implemented */
                                idl_free( tmp );
                                idl_free( tmp2 );
                                idl_free( idl );
@@ -549,10 +587,7 @@ split:
 
                        /* delete all indirect blocks */
                        for ( j = 0; !ID_BLOCK_NOID(idl, j); j++ ) {
-                               sprintf( kstr, "%c%ld%s", CONT_PREFIX,
-                                       ID_BLOCK_ID(idl, j), key.dptr );
-                               k2.dptr = kstr;
-                               k2.dsize = strlen( kstr ) + 1;
+                               cont_id( k2, ID_BLOCK_ID(idl, j) );
 
                                rc = ldbm_cache_delete( db, k2 );
                        }
@@ -562,7 +597,7 @@ split:
                        idl = idl_allids( be );
                        rc = idl_store( be, db, key, idl );
 
-                       free( kstr );
+                       cont_free( k2 );
                        idl_free( idl );
                        idl_free( tmp );
                        return( rc );
@@ -592,17 +627,11 @@ split:
                rc = idl_store( be, db, key, tmp );
 
                /* store the first id block */
-               sprintf( kstr, "%c%ld%s", CONT_PREFIX,
-                       ID_BLOCK_ID(tmp2, 0), key.dptr );
-               k2.dptr = kstr;
-               k2.dsize = strlen( kstr ) + 1;
+               cont_id( k2, ID_BLOCK_ID(tmp2, 0) );
                rc = idl_store( be, db, k2, tmp2 );
 
                /* store the second id block */
-               sprintf( kstr, "%c%ld%s", CONT_PREFIX,
-                       ID_BLOCK_ID(tmp3, 0), key.dptr );
-               k2.dptr = kstr;
-               k2.dsize = strlen( kstr ) + 1;
+               cont_id( k2, ID_BLOCK_ID(tmp3, 0) );
                rc = idl_store( be, db, k2, tmp3 );
 
                idl_free( tmp2 );
@@ -610,7 +639,7 @@ split:
                break;
        }
 
-       free( kstr );
+       cont_free( k2 );
        idl_free( tmp );
        idl_free( idl );
        return( rc );
@@ -685,7 +714,6 @@ idl_delete_key (
        ID_BLOCK *idl;
        unsigned i;
        int j, nids;
-       char    *kstr;
 
        if ( (idl = idl_fetch_one( be, db, key ) ) == NULL )
        {
@@ -729,20 +757,17 @@ idl_delete_key (
           */
        for ( nids = 0; !ID_BLOCK_NOID(idl, nids); nids++ )
                ;       /* NULL */
-       kstr = (char *) ch_malloc( key.dsize + CONT_SIZE );
+
+       cont_alloc( data, key );
 
        for ( j = 0; !ID_BLOCK_NOID(idl, j); j++ ) 
        {
                ID_BLOCK *tmp;
-               ldbm_datum_init( data );
-               sprintf( kstr, "%c%ld%s", CONT_PREFIX,
-                       ID_BLOCK_ID(idl, j), key.dptr );
-               data.dptr = kstr;
-               data.dsize = strlen( kstr ) + 1;
+               cont_id( data, ID_BLOCK_ID(idl, j) );
 
                if ( (tmp = idl_fetch_one( be, db, data )) == NULL ) {
                        Debug( LDAP_DEBUG_ANY,
-                           "idl_fetch of (%s) returns NULL\n", data.dptr, 0, 0 );
+                           "idl_delete_key: idl_fetch of returned NULL\n", 0, 0, 0 );
                        continue;
                }
                /*
@@ -776,14 +801,15 @@ idl_delete_key (
                                                idl_store( be, db, key, idl );
                                }
                                idl_free( tmp );
-                               free( kstr );
+                               cont_free( data );
                                idl_free( idl );
                                return 0;
                        }
                }
                idl_free( tmp );
        }
-       free( kstr );
+
+       cont_free( data );
        idl_free( idl );
        return -1;
 }
index 12db542582c9d05017050f3ff771b1f21de44a80..0d93e525ea58314e09bd1f8d9865d2f47df6f38d 100644 (file)
@@ -1,7 +1,7 @@
 /* index.c - routines for dealing with attribute indexes */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 #include "slap.h"
 #include "back-ldbm.h"
 
-static int     change_value(Backend *be,
-                         DBCache *db,
-                         char *type,
-                         int indextype,
-                         char *val,
-                         ID id,
-                         int
-                         (*idl_func)(Backend *, DBCache *, Datum, ID));
-static int     index2prefix(int indextype);
-
-int
-index_add_entry(
-    Backend    *be,
-    Entry      *e
-)
+static index_mask(
+       Backend *be,
+       AttributeDescription *desc,
+       char **dbname,
+       char **atname )
 {
-       Attribute       *ap;
-       struct berval   bv;
-       struct berval   *bvals[2];
-
-       Debug( LDAP_DEBUG_TRACE, "=> index_add( %ld, \"%s\" )\n", e->e_id,
-           e->e_dn, 0 );
-
-       /*
-        * dn index entry - make it look like an attribute so it works
-        * with index_change_values() call
-        */
-
-       bv.bv_val = ch_strdup( e->e_ndn );
-       bv.bv_len = strlen( bv.bv_val );
-       bvals[0] = &bv;
-       bvals[1] = NULL;
-
-       /* add the dn to the indexes */
-       {
-               char *dn = ch_strdup("dn");
-               index_change_values( be, dn, bvals, e->e_id, SLAP_INDEX_ADD_OP );
-               free( dn );
-       }
+       AttributeType *at;
+       slap_index mask = 0;
 
-       free( bv.bv_val );
+       /* we do support indexing of binary attributes */
+       if( slap_ad_is_binary( desc ) ) return 0;
 
-       /* add each attribute to the indexes */
-       for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) {
-               index_change_values( be, ap->a_type, ap->a_vals, e->e_id,
-                                    SLAP_INDEX_ADD_OP );
+       attr_mask( be->be_private, desc->ad_cname->bv_val, &mask );
+
+       if( mask ) {
+               *atname = desc->ad_cname->bv_val;
+               *dbname = desc->ad_cname->bv_val;
+               return mask;
        }
 
-       Debug( LDAP_DEBUG_TRACE, "<= index_add( %ld, \"%s\" ) 0\n", e->e_id,
-           e->e_ndn, 0 );
-       return( 0 );
-}
+       if( slap_ad_is_lang( desc ) ) {
+               /* has language tag */
+               attr_mask( be->be_private, desc->ad_type->sat_cname, &mask );
 
-int
-index_add_mods(
-    Backend    *be,
-    LDAPModList        *ml,
-    ID         id
-)
-{
-       int     rc;
-
-       for ( ; ml != NULL; ml = ml->ml_next ) {
-               LDAPMod *mod = &ml->ml_mod;
-
-               switch ( mod->mod_op & ~LDAP_MOD_BVALUES ) {
-               case LDAP_MOD_REPLACE:
-                       /* XXX: Delete old index data==>problem when this 
-                        * gets called we lost values already!
-                        */
-               case LDAP_MOD_ADD:
-                       rc = index_change_values( be,
-                                              mod->mod_type,
-                                              mod->mod_bvalues,
-                                              id,
-                                              SLAP_INDEX_ADD_OP );
-                       break;
-               case LDAP_MOD_DELETE:
-                       rc =  index_change_values( be,
-                                                  mod->mod_type,
-                                                  mod->mod_bvalues,
-                                                  id,
-                                                  SLAP_INDEX_DELETE_OP );
-                       break;
-               case LDAP_MOD_SOFTADD:  /* SOFTADD means index was there */
-                       rc = 0;
-                       break;
+               if( mask & SLAP_INDEX_AUTO_LANG ) {
+                       *atname = desc->ad_cname->bv_val;
+                       *dbname = desc->ad_type->sat_cname;
+                       return mask;
+               }
+               if( mask & SLAP_INDEX_LANG ) {
+                       *atname = desc->ad_type->sat_cname;
+                       *dbname = desc->ad_type->sat_cname;
+                       return mask;
                }
+       }
 
-               if ( rc != 0 ) {
-                       return( rc );
+       /* see if supertype defined mask for its subtypes */
+       for( at = desc->ad_type; at != NULL ; at = at->sat_sup ) {
+               attr_mask( be->be_private, at->sat_cname, &mask );
+
+               if( mask & SLAP_INDEX_AUTO_SUBTYPES ) {
+                       *atname = desc->ad_type->sat_cname;
+                       *dbname = at->sat_cname;
+                       return mask;
+               }
+               if( mask & SLAP_INDEX_SUBTYPES ) {
+                       *atname = at->sat_cname;
+                       *dbname = at->sat_cname;
+                       return mask;
                }
+
+               if( mask ) break;
        }
 
-       return( 0 );
+       return 0;
 }
 
-ID_BLOCK *
-index_read(
-    Backend    *be,
-    char       *type,
-    int                indextype,
-    char       *val
-)
+int index_param(
+       Backend *be,
+       AttributeDescription *desc,
+       int ftype,
+       char **dbnamep,
+       slap_index *maskp,
+       struct berval **prefixp )
 {
-       DBCache *db;
-       Datum           key;
-       ID_BLOCK                *idl;
-       int             indexmask, syntax;
-       char            prefix;
-       char            *realval, *tmpval;
-       char            buf[BUFSIZ];
-
-       char            *at_cn;
-
-       ldbm_datum_init( key );
-
-       prefix = index2prefix( indextype );
-       Debug( LDAP_DEBUG_TRACE, "=> index_read(\"%c%s\"->\"%s\")\n",
-           prefix, type, val );
-
-       attr_masks( be->be_private, type, &indexmask, &syntax );
-       if ( ! (indextype & indexmask) ) {
-               idl =  idl_allids( be );
-               Debug( LDAP_DEBUG_TRACE,
-                   "<= index_read %ld candidates (allids - not indexed)\n",
-                   idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
-               return( idl );
-       }
+       slap_index mask;
+       char *dbname;
+       char *atname;
 
-       attr_normalize( type );
-       at_cn = at_canonical_name( type );
+       mask = index_mask( be, desc, &dbname, &atname );
 
-       if ( (db = ldbm_cache_open( be, at_cn, LDBM_SUFFIX, LDBM_WRCREAT ))
-           == NULL ) {
-               Debug( LDAP_DEBUG_ANY,
-                   "<= index_read NULL (could not open %s%s)\n", at_cn,
-                   LDBM_SUFFIX, 0 );
-               return( NULL );
+       if( mask == 0 ) {
+               return LDAP_INAPPROPRIATE_MATCHING;
        }
 
-       realval = val;
-       tmpval = NULL;
-       if ( prefix != UNKNOWN_PREFIX ) {
-               unsigned int    len = strlen( val );
-
-               if ( (len + 2) < sizeof(buf) ) {
-                       realval = buf;
-               } else {
-                       /* value + prefix + null */
-                       tmpval = (char *) ch_malloc( len + 2 );
-                       realval = tmpval;
+       switch(ftype) {
+       case LDAP_FILTER_PRESENT:
+               if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) {
+                       goto done;
+               }
+               break;
+
+       case LDAP_FILTER_APPROX:
+               if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) {
+                       goto done;
                }
+               /* fall thru */
 
-               realval[0] = prefix;
-               strcpy( &realval[1], val );
-       }
+       case LDAP_FILTER_EQUALITY:
+               if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) {
+                       goto done;
+               }
+               break;
 
-       key.dptr = realval;
-       key.dsize = strlen( realval ) + 1;
+       case LDAP_FILTER_SUBSTRINGS:
+               if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) {
+                       goto done;
+               }
+               break;
 
-       idl = idl_fetch( be, db, key );
-       if ( tmpval != NULL ) {
-              free( tmpval );
+       default:
+               return LDAP_OTHER;
        }
 
-       ldbm_cache_close( be, db );
+       return LDAP_INAPPROPRIATE_MATCHING;
 
-       Debug( LDAP_DEBUG_TRACE, "<= index_read %ld candidates\n",
-              idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
-       return( idl );
+done:
+       *dbnamep = dbname;
+       *prefixp = ber_bvstrdup( atname );
+       *maskp = mask;
+       return LDAP_SUCCESS;
 }
 
-/* Add or remove stuff from index files */
-
-static int
-change_value(
-    Backend            *be,
-    DBCache    *db,
-    char               *type,
-    int                        indextype,
-    char               *val,
-    ID                 id,
-    int                        (*idl_func)(Backend *, DBCache *, Datum, ID)
-)
+static int indexer(
+       Backend *be,
+       char *dbname,
+       char *atname,
+       struct berval **vals,
+       ID id,
+       int op,
+       slap_index mask )
 {
-       int     rc;
-       Datum   key;
-       char    *tmpval = NULL;
-       char    *realval = val;
-       char    buf[BUFSIZ];
-
-       char    prefix = index2prefix( indextype );
-
-       ldbm_datum_init( key );
-
-       Debug( LDAP_DEBUG_TRACE,
-              "=> change_value( \"%c%s\", op=%s )\n",
-              prefix, val, (idl_func == idl_insert_key ? "ADD":"DELETE") );
-
-       if ( prefix != UNKNOWN_PREFIX ) {
-              unsigned int     len = strlen( val );
-
-              if ( (len + 2) < sizeof(buf) ) {
-                       realval = buf;
-             } else {
-                       /* value + prefix + null */
-                       tmpval = (char *) ch_malloc( len + 2 );
-                       realval = tmpval;
-             }
-              realval[0] = prefix;
-              strcpy( &realval[1], val );
-       }
+       int rc, i;
+       const char *text;
+    DBCache    *db;
+       AttributeDescription *ad = NULL;
+       struct berval **keys;
+       struct berval prefix;
 
-       key.dptr = realval;
-       key.dsize = strlen( realval ) + 1;
+       assert( mask );
 
-       rc = idl_func( be, db, key, id );
+       rc = slap_str2ad( atname, &ad, &text );
 
-       if ( tmpval != NULL ) {
-               free( tmpval );
-       }
-
-       ldap_pvt_thread_yield();
-
-       Debug( LDAP_DEBUG_TRACE, "<= change_value %d\n", rc, 0, 0 );
-
-       return( rc );
-
-}/* static int change_value() */
-
-
-int
-index_change_values(
-    Backend            *be,
-    char               *type,
-    struct berval      **vals,
-    ID                 id,
-    unsigned int       op
-)
-{
-       char            *val, *p, *code, *w;
-       unsigned        i, j, len;
-       int             indexmask, syntax;
-       char            buf[SUBLEN + 1];
-       char            vbuf[BUFSIZ];
-       char            *bigbuf;
-       DBCache *db;
-
-       int             (*idl_funct)(Backend *,
-                                   DBCache *,
-                                   Datum, ID);
-       char            *at_cn; /* Attribute canonical name */
-       int             mode;
-
-       if( vals == NULL ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "=> index_change_values( %s, NULL, %ld, op=%s )\n", 
-                       type, id, ((op == SLAP_INDEX_ADD_OP) ? "ADD" : "DELETE" ) );
-               return 0;
-       }
+       if( rc != LDAP_SUCCESS ) return rc;
 
-       Debug( LDAP_DEBUG_TRACE,
-              "=> index_change_values( \"%s\", %ld, op=%s )\n", 
-              type, id, ((op == SLAP_INDEX_ADD_OP) ? "ADD" : "DELETE" ) );
+       prefix.bv_val = atname;
+       prefix.bv_len = strlen( atname );
 
+       db = ldbm_cache_open( be, dbname, LDBM_SUFFIX, LDBM_WRCREAT );
        
-       if (op == SLAP_INDEX_ADD_OP) {
+       if ( db == NULL ) {
+               Debug( LDAP_DEBUG_ANY,
+                   "<= index_read NULL (could not open %s%s)\n",
+                       dbname, LDBM_SUFFIX, 0 );
+               ad_free( ad, 1 );
+               return LDAP_OTHER;
+       }
 
-           /* Add values */
+       if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) {
+               key_change( be, db, &prefix, id, op );
+       }
 
-           idl_funct =  idl_insert_key;
-           mode = LDBM_WRCREAT;
+       if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) {
+               rc = ad->ad_type->sat_equality->smr_indexer(
+                       mask,
+                       ad->ad_type->sat_syntax,
+                       ad->ad_type->sat_equality,
+                       &prefix, vals, &keys );
+
+               if( rc == LDAP_SUCCESS ) {
+                       for( i= 0; keys[i] != NULL; i++ ) {
+                               key_change( be, db, keys[i], id, op );
+                       }
+               }
+       }
 
-       } else {
+       if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) {
+               rc = ad->ad_type->sat_approx->smr_indexer(
+                       mask,
+                       ad->ad_type->sat_syntax,
+                       ad->ad_type->sat_approx,
+                       &prefix, vals, &keys );
+
+               if( rc == LDAP_SUCCESS ) {
+                       for( i= 0; keys[i] != NULL; i++ ) {
+                               key_change( be, db, keys[i], id, op );
+                       }
+               }
+       }
 
-           /* Delete values */
+       if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) {
+               rc = ad->ad_type->sat_substr->smr_indexer(
+                       mask,
+                       ad->ad_type->sat_syntax,
+                       ad->ad_type->sat_substr,
+                       &prefix, vals, &keys );
+
+               if( rc == LDAP_SUCCESS ) {
+                       for( i= 0; keys[i] != NULL; i++ ) {
+                               key_change( be, db, keys[i], id, op );
+                       }
+               }
+       }
 
-           idl_funct = idl_delete_key;
-           mode = LDBM_WRITER;
+       ldbm_cache_close( be, db );
+       ad_free( ad, 1 );
+       return LDAP_SUCCESS;
+}
 
+static int index_at_values(
+       Backend *be,
+       AttributeType *type,
+       const char *lang,
+       struct berval **vals,
+       ID id,
+       int op,
+       char ** dbnamep,
+       slap_index *maskp )
+{
+       slap_index mask;
+       slap_index tmpmask = 0;
+       int lindex = 0;
+
+       if( type->sat_sup ) {
+               /* recurse */
+               (void) index_at_values( be,
+                       type->sat_sup, lang,
+                       vals, id, op,
+                       dbnamep, &tmpmask );
        }
 
-       attr_normalize(type);
-       attr_masks( be->be_private, type, &indexmask, &syntax );
+       attr_mask( be->be_private, type->sat_cname, &mask );
 
-       if ( indexmask == 0 ) {
-               return( 0 );
+       if( mask ) {
+               *dbnamep = type->sat_cname;
+       } else if ( tmpmask & SLAP_INDEX_AUTO_SUBTYPES ) {
+               mask = tmpmask;
        }
 
-       at_cn = at_canonical_name( type );
-
-       if ( (db = ldbm_cache_open( be, at_cn, LDBM_SUFFIX, mode ))
-            == NULL ) {
-               Debug( LDAP_DEBUG_ANY,
-                      "<= index_change_values (couldn't open(%s%s),md=%s)\n",
-                      at_cn,
-                      LDBM_SUFFIX,
-                      ((mode==LDBM_WRCREAT)?"LDBM_WRCREAT":"LDBM_WRITER") );
-               return( -1 );
+       if( mask ) {
+               indexer( be, *dbnamep,
+                       type->sat_cname,
+                       vals, id, op,
+                       mask );
        }
 
+       if( lang ) {
+               char *dbname = NULL;
+               size_t tlen = strlen( type->sat_cname );
+               size_t llen = strlen( lang );
+               char *lname = ch_malloc( tlen + llen + sizeof(";") );
 
-       for ( i = 0; vals[i] != NULL; i++ ) {
-               /*
-                * presence index entry
-                */
-               if ( indexmask & INDEX_PRESENCE ) {
+               sprintf( lname, "%s;%s", type->sat_cname, lang );
 
-                       change_value( be, db, at_cn, INDEX_PRESENCE,
-                                     "*", id, idl_funct );
+               attr_mask( be->be_private, lname, &tmpmask );
 
+               if( tmpmask ) {
+                       dbname = lname;
+               } else if ( mask & SLAP_INDEX_AUTO_LANG ) {
+                       dbname = *dbnamep;
+                       tmpmask = mask;
                }
 
-               Debug( LDAP_DEBUG_TRACE,
-                      "index_change_values syntax 0x%x syntax bin 0x%x\n",
-                      syntax, SYNTAX_BIN, 0 );
-
-               if ( syntax & SYNTAX_BIN ) {
+               if( dbname != NULL ) {
+                       indexer( be, dbname, lname,
+                               vals, id, op,
+                               tmpmask );
+               }
 
-                       ldbm_cache_close( be, db );
-                       return( 0 );
+               ch_free( lname );
+       }
 
-               }
+       return LDAP_SUCCESS;
+}
 
-               bigbuf = NULL;
-               len = vals[i]->bv_len;
+int index_values(
+       Backend *be,
+       AttributeDescription *desc,
+       struct berval **vals,
+       ID id,
+       int op )
+{
+       char *dbname = NULL;
+       slap_index mask;
 
-               /* value + null */
-               if ( len + 2 > sizeof(vbuf) ) {
-                       bigbuf = (char *) ch_malloc( len + 1 );
-                       val = bigbuf;
-               } else {
-                       val = vbuf;
-               }
-               (void) memcpy( val, vals[i]->bv_val, len );
-               val[len] = '\0';
+       if( slap_ad_is_binary( desc ) ) {
+               /* binary attributes have no index capabilities */
+               return LDAP_SUCCESS;
+       }
 
-               value_normalize( val, syntax );
+       (void) index_at_values( be,
+               desc->ad_type, desc->ad_lang,
+               vals, id, op,
+               &dbname, &mask );
 
-               /* value_normalize could change the length of val */
-               len = strlen( val );
+       return LDAP_SUCCESS;
+}
 
-               /*
-                * equality index entry
-                */
-               if ( indexmask & INDEX_EQUALITY ) {
-                   
-                       change_value( be, db, at_cn, INDEX_EQUALITY,
-                                     val, id, idl_funct);
 
-               }
+int
+index_entry(
+    Backend    *be,
+       int op,
+    Entry      *e,
+       Attribute *ap
+)
+{
 
-               /*
-                * approximate index entry
-                */
-               if ( indexmask & INDEX_APPROX ) {
-                       for ( w = first_word( val ); w != NULL;
-                           w = next_word( w ) ) {
-                               if ( (code = phonetic( w )) != NULL ) {
-                                       change_value( be,
-                                                     db,
-                                                     at_cn,
-                                                     INDEX_APPROX,
-                                                     code,
-                                                     id,
-                                                     idl_funct );
-                                       free( code );
-                               }
-                       }
-               }
+       Debug( LDAP_DEBUG_TRACE, "=> index_entry_%s( %ld, \"%s\" )\n",
+               op == SLAP_INDEX_ADD_OP ? "add" : "del",
+               e->e_id, e->e_dn );
 
-               /*
-                * substrings index entry
-                */
-               if ( indexmask & INDEX_SUB ) {
-                       /* leading and trailing */
-                       if ( len > SUBLEN - 2 ) {
-                               buf[0] = '^';
-                               for ( j = 0; j < SUBLEN - 1; j++ ) {
-                                       buf[j + 1] = val[j];
-                               }
-                               buf[SUBLEN] = '\0';
-
-                               change_value( be, db, at_cn, INDEX_SUB,
-                                             buf, id, idl_funct );
-
-                               p = val + len - SUBLEN + 1;
-                               for ( j = 0; j < SUBLEN - 1; j++ ) {
-                                       buf[j] = p[j];
-                               }
-                               buf[SUBLEN - 1] = '$';
-                               buf[SUBLEN] = '\0';
-
-                               change_value( be, db, at_cn, INDEX_SUB,
-                                             buf, id, idl_funct );
-                       }
-
-                       /* any */
-                       for ( p = val; p < (val + len - SUBLEN + 1); p++ ) {
-                               for ( j = 0; j < SUBLEN; j++ ) {
-                                       buf[j] = p[j];
-                               }
-                               buf[SUBLEN] = '\0';
-
-                               change_value( be, db, at_cn, INDEX_SUB,
-                                             buf, id, idl_funct );
-                       }
-               }
 
-               if ( bigbuf != NULL ) {
-                       free( bigbuf );
-               }
+       /* add each attribute to the indexes */
+       for ( ap; ap != NULL; ap = ap->a_next ) {
+               index_values( be, ap->a_desc, ap->a_vals, e->e_id, op );
        }
 
-       ldbm_cache_close( be, db );
-
-       return( 0 );
+       Debug( LDAP_DEBUG_TRACE, "<= index_entry_%s( %ld, \"%s\" ) success\n",
+           op == SLAP_INDEX_ADD_OP ? "add" : "del",
+               e->e_id, e->e_dn );
 
+       return LDAP_SUCCESS;
 }
 
-static int
-index2prefix( int indextype )
-{
-       int     prefix;
-
-       switch ( indextype ) {
-       case INDEX_EQUALITY:
-               prefix = EQ_PREFIX;
-               break;
-       case INDEX_APPROX:
-               prefix = APPROX_PREFIX;
-               break;
-       case INDEX_SUB:
-               prefix = SUB_PREFIX;
-               break;
-       default:
-               prefix = UNKNOWN_PREFIX;
-               break;
-       }
-
-       return( prefix );
-}
index d7b6345e9fe2da2ac4b06367850756c975980629..5dcd6507b9c9f1bc2af34447d6fc65f67f9ffa86 100644 (file)
@@ -1,7 +1,7 @@
 /* init.c - initialize ldbm backend */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -20,7 +20,7 @@
 int back_ldbm_LTX_init_module(int argc, char *argv[]) {
     BackendInfo bi;
 
-    memset( &bi, 0, sizeof(bi) );
+    memset( &bi, '\0', sizeof(bi) );
     bi.bi_type = "ldbm";
     bi.bi_init = ldbm_back_initialize;
 
@@ -35,6 +35,13 @@ ldbm_back_initialize(
     BackendInfo        *bi
 )
 {
+       static char *controls[] = {
+               LDAP_CONTROL_MANAGEDSAIT,
+               NULL
+       };
+
+       bi->bi_controls = controls;
+
        bi->bi_open = ldbm_back_open;
        bi->bi_config = 0;
        bi->bi_close = ldbm_back_close;
@@ -56,6 +63,8 @@ ldbm_back_initialize(
        bi->bi_op_delete = ldbm_back_delete;
        bi->bi_op_abandon = ldbm_back_abandon;
 
+       bi->bi_extended = ldbm_back_extended;
+
        bi->bi_entry_release_rw = ldbm_back_entry_release_rw;
        bi->bi_acl_group = ldbm_back_group;
 
@@ -69,9 +78,14 @@ ldbm_back_initialize(
        bi->bi_tool_entry_get = ldbm_tool_entry_get;
        bi->bi_tool_entry_put = ldbm_tool_entry_put;
        bi->bi_tool_index_attr = ldbm_tool_index_attr;
-       bi->bi_tool_index_change = ldbm_tool_index_change;
        bi->bi_tool_sync = ldbm_tool_sync;
 
+#ifdef HAVE_CYRUS_SASL
+       bi->bi_sasl_authorize = 0;
+       bi->bi_sasl_getsecret = 0;
+       bi->bi_sasl_putsecret = 0;
+#endif /* HAVE_CYRUS_SASL */
+
        bi->bi_connection_init = 0;
        bi->bi_connection_destroy = 0;
 
@@ -116,7 +130,6 @@ ldbm_back_db_init(
 )
 {
        struct ldbminfo *li;
-       char            *argv[ 4 ];
 
        /* allocate backend-database-specific stuff */
        li = (struct ldbminfo *) ch_calloc( 1, sizeof(struct ldbminfo) );
@@ -130,8 +143,11 @@ ldbm_back_db_init(
        /* default database cache size */
        li->li_dbcachesize = DEFAULT_DBCACHE_SIZE;
 
-       /* default cache mode is sync on write */
-       li->li_dbcachewsync = 1;
+       /* default db mode is with locking */ 
+       li->li_dblocking = 1;
+
+       /* default db mode is with write synchronization */ 
+       li->li_dbwritesync = 1;
 
        /* default file creation mode */
        li->li_mode = DEFAULT_MODE;
@@ -139,12 +155,6 @@ ldbm_back_db_init(
        /* default database directory */
        li->li_directory = ch_strdup( DEFAULT_DB_DIRECTORY );
 
-       argv[ 0 ] = "objectclass";
-       argv[ 1 ] = "pres,eq";
-       argv[ 2 ] = NULL;
-       attr_index_config( li, "ldbm objectclass initialization",
-               0, 2, argv, 1 );
-
        /* initialize various mutex locks & condition variables */
        ldap_pvt_thread_mutex_init( &li->li_root_mutex );
        ldap_pvt_thread_mutex_init( &li->li_add_mutex );
diff --git a/servers/slapd/back-ldbm/kerberos.c b/servers/slapd/back-ldbm/kerberos.c
deleted file mode 100644 (file)
index 7a80877..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* kerberos.c - ldbm backend kerberos bind routines */
-/* $OpenLDAP$ */
-/*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
- */
-
-#include "portable.h"
-
-#ifdef HAVE_KERBEROS
-
-#include <stdio.h>
-
-#include <ac/krb.h>
-#include <ac/socket.h>
-#include <ac/string.h>
-
-#include "slap.h"
-#include "back-ldbm.h"
-
-#define LDAP_KRB_PRINCIPAL     "ldapserver"
-
-extern char            *ldap_srvtab;
-extern Attribute       *attr_find();
-
-krbv4_ldap_auth(
-    Backend            *be,
-    struct berval      *cred,
-    AUTH_DAT           *ad
-)
-{
-       KTEXT_ST        k;
-       KTEXT           ktxt = &k;
-       char            instance[INST_SZ];
-       int             err;
-
-       Debug( LDAP_DEBUG_TRACE, "=> kerberosv4_ldap_auth\n", 0, 0, 0 );
-
-       SAFEMEMCPY( ktxt->dat, cred->bv_val, cred->bv_len );
-       ktxt->length = cred->bv_len;
-
-       strcpy( instance, "*" );
-       if ( (err = krb_rd_req( ktxt, LDAP_KRB_PRINCIPAL, instance, 0L, ad,
-           ldap_srvtab )) != KSUCCESS ) {
-               Debug( LDAP_DEBUG_ANY, "krb_rd_req failed (%s)\n",
-                   krb_err_txt[err], 0, 0 );
-               return( LDAP_INVALID_CREDENTIALS );
-       }
-
-       return( LDAP_SUCCESS );
-}
-
-#endif /* kerberos */
diff --git a/servers/slapd/back-ldbm/key.c b/servers/slapd/back-ldbm/key.c
new file mode 100644 (file)
index 0000000..c8dc26e
--- /dev/null
@@ -0,0 +1,80 @@
+/* index.c - routines for dealing with attribute indexes */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "back-ldbm.h"
+
+/* read a key */
+int
+key_read(
+    Backend    *be,
+       DBCache *db,
+    struct berval *k,
+       ID_BLOCK **idout
+)
+{
+       Datum           key;
+       ID_BLOCK                *idl;
+
+       Debug( LDAP_DEBUG_TRACE, "=> key_read\n", 0, 0, 0 );
+
+       ldbm_datum_init( key );
+       key.dptr = k->bv_val;
+       key.dsize = k->bv_len;
+
+       idl = idl_fetch( be, db, key );
+
+       Debug( LDAP_DEBUG_TRACE, "<= index_read %ld candidates\n",
+              idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
+
+       *idout = idl;
+       return LDAP_SUCCESS;
+}
+
+/* Add or remove stuff from index files */
+int
+key_change(
+    Backend            *be,
+    DBCache    *db,
+    struct berval *k,
+    ID                 id,
+    int                        op
+)
+{
+       int     rc;
+       Datum   key;
+
+       Debug( LDAP_DEBUG_TRACE, "=> key_change(%s,%lx)\n",
+               op == SLAP_INDEX_ADD_OP ? "ADD":"DELETE", (long) id, 0 );
+
+       ldbm_datum_init( key );
+       key.dptr = k->bv_val;
+       key.dsize = k->bv_len;
+
+       if (op == SLAP_INDEX_ADD_OP) {
+           /* Add values */
+           rc = idl_insert_key( be, db, key, id );
+
+       } else {
+           /* Delete values */
+           rc = idl_delete_key( be, db, key, id );
+       }
+
+
+       Debug( LDAP_DEBUG_TRACE, "<= key_change %d\n", rc, 0, 0 );
+
+       ldap_pvt_thread_yield();
+
+       return rc;
+}
index 770be8dbc2632057140251b1fa6691b8b19a116b..7791816a6daa5a4a2bb797e50605c30511327325 100644 (file)
@@ -1,7 +1,7 @@
 /* modify.c - ldbm backend modify routine */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 #include "back-ldbm.h"
 #include "proto-back-ldbm.h"
 
+static int add_values LDAP_P(( Entry *e, Modification *mod, char *dn ));
+static int delete_values LDAP_P(( Entry *e, Modification *mod, char *dn ));
+static int replace_values LDAP_P(( Entry *e, Modification *mod, char *dn ));
+
 /* We need this function because of LDAP modrdn. If we do not 
  * add this there would be a bunch of code replication here 
  * and there and of course the likelihood of bugs increases.
@@ -27,66 +31,96 @@ int ldbm_modify_internal(
     Backend    *be,
     Connection *conn,
     Operation  *op,
-    char       *dn,
-    LDAPModList        *modlist,
-    Entry      *e 
+    const char *dn,
+    Modifications      *modlist,
+    Entry      *e,
+       const char **text 
 )
 {
-       int err;
-       LDAPMod         *mod;
-       LDAPModList     *ml;
-       Attribute       *a;
+       int rc, err;
+       Modification    *mod;
+       Modifications   *ml;
        Attribute       *save_attrs;
 
-       if ( (err = acl_check_modlist( be, conn, op, e, modlist ))
-            != LDAP_SUCCESS )
-       {
-               send_ldap_result( conn, op, err,
-                       NULL, NULL, NULL, NULL );
-               return -1;
+       Debug(LDAP_DEBUG_TRACE, "ldbm_modify_internal:\n", 0, 0, 0);
+
+       if ( !acl_check_modlist( be, conn, op, e, modlist )) {
+               return LDAP_INSUFFICIENT_ACCESS;
        }
 
        save_attrs = e->e_attrs;
        e->e_attrs = attrs_dup( e->e_attrs );
 
-       for ( ml = modlist; ml != NULL; ml = ml->ml_next ) {
-               mod = &ml->ml_mod;
+       for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
+               mod = &ml->sml_mod;
 
-               switch ( mod->mod_op & ~LDAP_MOD_BVALUES ) {
+               switch ( mod->sm_op ) {
                case LDAP_MOD_ADD:
+                       Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: add\n", 0, 0, 0);
                        err = add_values( e, mod, op->o_ndn );
+
+                       if( err != LDAP_SUCCESS ) {
+                               Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: %d %s\n",
+                                       err, text, 0);
+                               *text = "modify: add values failed";
+                       }
                        break;
 
                case LDAP_MOD_DELETE:
+                       Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: delete\n", 0, 0, 0);
                        err = delete_values( e, mod, op->o_ndn );
+                       assert( err != LDAP_TYPE_OR_VALUE_EXISTS );
+                       if( err != LDAP_SUCCESS ) {
+                               Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: %d %s\n",
+                                       err, text, 0);
+                               *text = "modify: delete values failed";
+                       }
                        break;
 
                case LDAP_MOD_REPLACE:
+                       Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: replace\n", 0, 0, 0);
                        err = replace_values( e, mod, op->o_ndn );
+                       assert( err != LDAP_TYPE_OR_VALUE_EXISTS );
+                       if( err != LDAP_SUCCESS ) {
+                               Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: %d %s\n",
+                                       err, text, 0);
+                               *text = "modify: replace values failed";
+                       }
                        break;
 
-               case LDAP_MOD_SOFTADD:
+               case SLAP_MOD_SOFTADD:
+                       Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: softadd\n", 0, 0, 0);
                        /* Avoid problems in index_add_mods()
                         * We need to add index if necessary.
                         */
-                       mod->mod_op = LDAP_MOD_ADD;
-                       if ( (err = add_values( e, mod, op->o_ndn ))
-                               ==  LDAP_TYPE_OR_VALUE_EXISTS ) {
+                       mod->sm_op = LDAP_MOD_ADD;
+                       err = add_values( e, mod, op->o_ndn );
+
+                       if ( err == LDAP_TYPE_OR_VALUE_EXISTS ) {
                                err = LDAP_SUCCESS;
-                               mod->mod_op = LDAP_MOD_SOFTADD;
                        }
+
+                       if( err != LDAP_SUCCESS ) {
+                               Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: %d %s\n",
+                                       err, text, 0);
+                               *text = "modify: (soft)add values failed";
+                       }
                        break;
+
+               default:
+                       Debug(LDAP_DEBUG_ANY, "ldbm_modify_internal: invalid op %d\n",
+                               mod->sm_op, 0, 0);
+                       *text = "Invalid modify operation";
+                       err = LDAP_OTHER;
+                       Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: %d %s\n",
+                               err, text, 0);
                }
 
                if ( err != LDAP_SUCCESS ) {
                        attrs_free( e->e_attrs );
                        e->e_attrs = save_attrs;
                        /* unlock entry, delete from cache */
-                       send_ldap_result( conn, op, err,
-                               NULL, NULL, NULL, NULL );
-                       return -1;
+                       return err; 
                }
        }
 
@@ -96,18 +130,18 @@ int ldbm_modify_internal(
                attrs_free( e->e_attrs );
                e->e_attrs = save_attrs;
                ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
-               return -1;
+               return SLAPD_ABANDON;
        }
        ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
 
        /* check that the entry still obeys the schema */
-       if ( global_schemacheck && oc_schema_check( e ) != 0 ) {
+       rc = entry_schema_check( e, save_attrs, text );
+       if ( rc != LDAP_SUCCESS ) {
                attrs_free( e->e_attrs );
                e->e_attrs = save_attrs;
-               Debug( LDAP_DEBUG_ANY, "entry failed schema check\n", 0, 0, 0 );
-               send_ldap_result( conn, op, LDAP_OBJECT_CLASS_VIOLATION,
-                       NULL, NULL, NULL, NULL );
-               return -1;
+               Debug( LDAP_DEBUG_ANY, "entry failed schema check: %s\n",
+                       *text, 0, 0 );
+               return rc;
        }
 
        /* check for abandon */
@@ -116,49 +150,19 @@ int ldbm_modify_internal(
                attrs_free( e->e_attrs );
                e->e_attrs = save_attrs;
                ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
-               return -1;
+               return SLAPD_ABANDON;
        }
        ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
 
-       /* remove old indices */
-       if( save_attrs != NULL ) {
-               for ( ml = modlist; ml != NULL; ml = ml->ml_next ) {
-                       mod = &ml->ml_mod;
-                       if( ( mod->mod_op & ~LDAP_MOD_BVALUES )
-                               == LDAP_MOD_REPLACE )
-                       {
-                               /* Need to remove all values from indexes */
-                               a = attr_find( save_attrs, mod->mod_type );
-
-                               if( a != NULL ) {
-                                       (void) index_change_values( be,
-                                               mod->mod_type,
-                                               a->a_vals,
-                                               e->e_id,
-                                               SLAP_INDEX_DELETE_OP);
-                               }
-                       }
-               }
-               attrs_free( save_attrs );
-       }
+       /* delete indices for old attributes */
+       index_entry_del( be, e, save_attrs);
 
-       /* modify indexes */
-       if ( index_add_mods( be, modlist, e->e_id ) != 0 ) {
-               /* our indices are likely hosed */
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-               return -1;
-       }
+       /* add indices for new attributes */
+       index_entry_add( be, e, e->e_attrs);
 
-       /* check for abandon */
-       ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
-       if ( op->o_abandon ) {
-               ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
-               return -1;
-       }
-       ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
+       attrs_free( save_attrs );
 
-       return 0;
+       return LDAP_SUCCESS;
 }
 
 
@@ -167,19 +171,22 @@ ldbm_back_modify(
     Backend    *be,
     Connection *conn,
     Operation  *op,
-    char       *dn,
-    LDAPModList        *modlist
+    const char *dn,
+    const char *ndn,
+    Modifications      *modlist
 )
 {
+       int rc;
        struct ldbminfo *li = (struct ldbminfo *) be->be_private;
        Entry           *matched;
        Entry           *e;
        int             manageDSAit = get_manageDSAit( op );
+       const char *text = NULL;
 
        Debug(LDAP_DEBUG_ARGS, "ldbm_back_modify:\n", 0, 0, 0);
 
        /* acquire and lock entry */
-       if ( (e = dn2entry_w( be, dn, &matched )) == NULL ) {
+       if ( (e = dn2entry_w( be, ndn, &matched )) == NULL ) {
                char* matched_dn = NULL;
                struct berval **refs = NULL;
 
@@ -222,19 +229,27 @@ ldbm_back_modify(
        }
        
        /* Modify the entry */
-       if ( ldbm_modify_internal( be, conn, op, dn, modlist, e ) != 0 ) {
+       rc = ldbm_modify_internal( be, conn, op, ndn, modlist, e, &text );
+
+       if( rc != LDAP_SUCCESS ) {
+               if( rc != SLAPD_ABANDON ) {
+                       send_ldap_result( conn, op, rc,
+                               NULL, text, NULL, NULL );
+               }
+
                goto error_return;
        }
 
        /* change the entry itself */
        if ( id2entry_add( be, e ) != 0 ) {
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
+               send_ldap_result( conn, op, LDAP_OTHER,
+                       NULL, "id2entry failure", NULL, NULL );
                goto error_return;
        }
 
        send_ldap_result( conn, op, LDAP_SUCCESS,
                NULL, NULL, NULL, NULL );
+
        cache_return_entry_w( &li->li_cache, e );
        return( 0 );
 
@@ -243,65 +258,121 @@ error_return:;
        return( -1 );
 }
 
-int
+static int
 add_values(
     Entry      *e,
-    LDAPMod    *mod,
+    Modification       *mod,
     char       *dn
 )
 {
        int             i;
        Attribute       *a;
 
+       /* char *desc = mod->sm_desc->ad_cname->bv_val; */
+       MatchingRule *mr = mod->sm_desc->ad_type->sat_equality;
+
+       if( mr == NULL ) {
+               return LDAP_INAPPROPRIATE_MATCHING;
+       }
+
+
+       a = attr_find( e->e_attrs, mod->sm_desc );
+
        /* check if the values we're adding already exist */
-       if ( (a = attr_find( e->e_attrs, mod->mod_type )) != NULL ) {
-               for ( i = 0; mod->mod_bvalues[i] != NULL; i++ ) {
-                       if ( value_find( a->a_vals, mod->mod_bvalues[i],
-                           a->a_syntax, 3 ) == 0 ) {
-                               return( LDAP_TYPE_OR_VALUE_EXISTS );
+       if ( a != NULL ) {
+               for ( i = 0; mod->sm_bvalues[i] != NULL; i++ ) {
+                       int rc;
+                       int j;
+                       const char *text = NULL;
+                       struct berval *asserted;
+
+                       rc = value_normalize( mod->sm_desc,
+                               SLAP_MR_EQUALITY,
+                               mod->sm_bvalues[i],
+                               &asserted,
+                               &text );
+
+                       if( rc != LDAP_SUCCESS ) return rc;
+
+                       for ( j = 0; a->a_vals[j] != NULL; j++ ) {
+                               int match;
+                               int rc = value_match( &match, mod->sm_desc, mr,
+                                       a->a_vals[j], asserted, &text );
+
+                               if( rc == LDAP_SUCCESS && match == 0 ) {
+                                       ber_bvfree( asserted );
+                                       return LDAP_TYPE_OR_VALUE_EXISTS;
+                               }
                        }
+
+                       ber_bvfree( asserted );
                }
        }
 
        /* no - add them */
-       if( attr_merge( e, mod->mod_type, mod->mod_bvalues ) != 0 ) {
-               return( LDAP_CONSTRAINT_VIOLATION );
+       if( attr_merge( e, mod->sm_desc, mod->sm_bvalues ) != 0 ) {
+               /* this should return result return of attr_merge */
+               return LDAP_OTHER;
        }
 
-       return( LDAP_SUCCESS );
+       return LDAP_SUCCESS;
 }
 
-int
+static int
 delete_values(
     Entry      *e,
-    LDAPMod    *mod,
+    Modification       *mod,
     char       *dn
 )
 {
        int             i, j, k, found;
        Attribute       *a;
+       char *desc = mod->sm_desc->ad_cname->bv_val;
+       MatchingRule *mr = mod->sm_desc->ad_type->sat_equality;
+
+       if( mr == NULL || !mr->smr_match ) {
+               return LDAP_INAPPROPRIATE_MATCHING;
+       }
 
        /* delete the entire attribute */
-       if ( mod->mod_bvalues == NULL ) {
+       if ( mod->sm_bvalues == NULL ) {
                Debug( LDAP_DEBUG_ARGS, "removing entire attribute %s\n",
-                   mod->mod_type, 0, 0 );
-               return( attr_delete( &e->e_attrs, mod->mod_type ) ?
+                   desc, 0, 0 );
+               return( attr_delete( &e->e_attrs, mod->sm_desc ) ?
                    LDAP_NO_SUCH_ATTRIBUTE : LDAP_SUCCESS );
        }
 
        /* delete specific values - find the attribute first */
-       if ( (a = attr_find( e->e_attrs, mod->mod_type )) == NULL ) {
-               Debug( LDAP_DEBUG_ARGS, "could not find attribute %s\n",
-                   mod->mod_type, 0, 0 );
+       if ( (a = attr_find( e->e_attrs, mod->sm_desc )) == NULL ) {
+               Debug( LDAP_DEBUG_ARGS, "ldap_modify_delete: "
+                       "could not find attribute %s\n",
+                   desc, 0, 0 );
                return( LDAP_NO_SUCH_ATTRIBUTE );
        }
 
        /* find each value to delete */
-       for ( i = 0; mod->mod_bvalues[i] != NULL; i++ ) {
+       for ( i = 0; mod->sm_bvalues[i] != NULL; i++ ) {
+               int rc;
+               const char *text = NULL;
+
+               struct berval *asserted;
+
+               rc = value_normalize( mod->sm_desc,
+                       SLAP_MR_EQUALITY,
+                       mod->sm_bvalues[i],
+                       &asserted,
+                       &text );
+
+               if( rc != LDAP_SUCCESS ) return rc;
+
                found = 0;
                for ( j = 0; a->a_vals[j] != NULL; j++ ) {
-                       if ( value_cmp( mod->mod_bvalues[i], a->a_vals[j],
-                           a->a_syntax, 3 ) != 0 ) {
+                       int match;
+                       int rc = value_match( &match, mod->sm_desc, mr,
+                               a->a_vals[j], asserted, &text );
+
+                       if( rc == LDAP_SUCCESS && match != 0 )
+                       {
                                continue;
                        }
                        found = 1;
@@ -317,8 +388,9 @@ delete_values(
                        if ( a->a_vals[0] == NULL) {
                                Debug( LDAP_DEBUG_ARGS,
                                        "removing entire attribute %s\n",
-                                       mod->mod_type, 0, 0 );
-                               if ( attr_delete( &e->e_attrs, mod->mod_type ) ) {
+                                       desc, 0, 0 );
+                               if ( attr_delete( &e->e_attrs, mod->sm_desc ) ) {
+                                       ber_bvfree( asserted );
                                        return LDAP_NO_SUCH_ATTRIBUTE;
                                }
                        }
@@ -326,32 +398,38 @@ delete_values(
                        break;
                }
 
+               ber_bvfree( asserted );
+
                /* looked through them all w/o finding it */
                if ( ! found ) {
                        Debug( LDAP_DEBUG_ARGS,
-                           "could not find value for attr %s\n",
-                           mod->mod_type, 0, 0 );
-                       return( LDAP_NO_SUCH_ATTRIBUTE );
+                           "ldbm_modify_delete: could not find value for attr %s\n",
+                           desc, 0, 0 );
+                       return LDAP_NO_SUCH_ATTRIBUTE;
                }
        }
 
-       return( LDAP_SUCCESS );
+       return LDAP_SUCCESS;
 }
 
-int
+static int
 replace_values(
     Entry      *e,
-    LDAPMod    *mod,
+    Modification       *mod,
     char       *dn
 )
 {
-       (void) attr_delete( &e->e_attrs, mod->mod_type );
+       int rc = attr_delete( &e->e_attrs, mod->sm_desc );
+
+       if( rc != LDAP_SUCCESS && rc != LDAP_NO_SUCH_ATTRIBUTE ) {
+               return rc;
+       }
 
-       if ( mod->mod_bvalues != NULL &&
-               attr_merge( e, mod->mod_type, mod->mod_bvalues ) != 0 )
+       if ( mod->sm_bvalues != NULL &&
+               attr_merge( e, mod->sm_desc, mod->sm_bvalues ) != 0 )
        {
-               return( LDAP_CONSTRAINT_VIOLATION );
+               return LDAP_OTHER;
        }
 
-       return( LDAP_SUCCESS );
+       return LDAP_SUCCESS;
 }
index 08300fbf6834af17cb59a6e134f4b03aa7968352..3f1438fbf97df3bfd7040a15263258f3bfe6d95f 100644 (file)
@@ -1,7 +1,7 @@
 /* modrdn.c - ldbm backend modrdn routine */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -37,12 +37,14 @@ ldbm_back_modrdn(
     Backend    *be,
     Connection *conn,
     Operation  *op,
-    char       *dn,
-    char       *newrdn,
+    const char *dn,
+    const char *ndn,
+    const char *newrdn,
     int                deleteoldrdn,
-    char       *newSuperior
+    const char *newSuperior
 )
 {
+       AttributeDescription *children = slap_schema.si_ad_children;
        struct ldbminfo *li = (struct ldbminfo *) be->be_private;
        char            *p_dn = NULL, *p_ndn = NULL;
        char            *new_dn = NULL, *new_ndn = NULL;
@@ -50,6 +52,7 @@ ldbm_back_modrdn(
        Entry           *matched;
        int                     rootlock = 0;
        int                     rc = -1;
+       const char *text = NULL;
        /* Added to support LDAP v2 correctly (deleteoldrdn thing) */
        char            *new_rdn_val = NULL;    /* Val of new rdn */
        char            *new_rdn_type = NULL;   /* Type of new rdn */
@@ -66,7 +69,7 @@ ldbm_back_modrdn(
        struct berval   *add_bvals[2];          /* Stores new rdn att */
        struct berval   del_bv;                 /* Stores old rdn att */
        struct berval   *del_bvals[2];          /* Stores old rdn att */
-       LDAPModList     mod[2];                 /* Used to delete old rdn */
+       Modifications   mod[2];                 /* Used to delete old rdn */
        int             manageDSAit = get_manageDSAit( op );
 
        Debug( LDAP_DEBUG_TRACE, "==>ldbm_back_modrdn(newSuperior=%s)\n",
@@ -74,7 +77,7 @@ ldbm_back_modrdn(
               0, 0 );
 
        /* get entry with writer lock */
-       if ( (e = dn2entry_w( be, dn, &matched )) == NULL ) {
+       if ( (e = dn2entry_w( be, ndn, &matched )) == NULL ) {
                char* matched_dn = NULL;
                struct berval** refs = NULL;
 
@@ -137,14 +140,14 @@ ldbm_back_modrdn(
                if( (p = dn2entry_w( be, p_ndn, NULL )) == NULL) {
                        Debug( LDAP_DEBUG_TRACE, "parent does not exist\n",
                                0, 0, 0);
-                       send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
+                       send_ldap_result( conn, op, LDAP_OTHER,
                                NULL, NULL, NULL, NULL );
                        goto return_results;
                }
 
                /* check parent for "children" acl */
                if ( ! access_allowed( be, conn, op, p,
-                       "children", NULL, ACL_WRITE ) )
+                       children, NULL, ACL_WRITE ) )
                {
                        Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
                                0, 0 );
@@ -184,13 +187,14 @@ ldbm_back_modrdn(
 
        new_parent_dn = p_dn;   /* New Parent unless newSuperior given */
 
-       if ( (np_dn = newSuperior) != NULL) {
+       if ( newSuperior != NULL ) {
                Debug( LDAP_DEBUG_TRACE, 
-                      "ldbm_back_modrdn: new parent requested...\n",
-                      0, 0, 0 );
+                       "ldbm_back_modrdn: new parent \"%s\" requested...\n",
+                       newSuperior, 0, 0 );
 
+               np_dn = ch_strdup( newSuperior );
                np_ndn = ch_strdup( np_dn );
-               (void) dn_normalize_case( np_ndn );
+               (void) dn_normalize( np_ndn );
 
                /* newSuperior == oldParent?, if so ==> ERROR */
                /* newSuperior == entry being moved?, if so ==> ERROR */
@@ -200,7 +204,7 @@ ldbm_back_modrdn(
                        Debug( LDAP_DEBUG_TRACE,
                               "ldbm_back_modrdn: newSup(ndn=%s) not here!\n",
                               np_ndn, 0, 0);
-                       send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
+                       send_ldap_result( conn, op, LDAP_OTHER,
                                NULL, NULL, NULL, NULL );
                        goto return_results;
                }
@@ -210,7 +214,7 @@ ldbm_back_modrdn(
                       np, np->e_id, 0 );
            
                /* check newSuperior for "children" acl */
-               if ( !access_allowed( be, conn, op, np, "children", NULL,
+               if ( !access_allowed( be, conn, op, np, children, NULL,
                                      ACL_WRITE ) )
                {
                        Debug( LDAP_DEBUG_TRACE,
@@ -257,7 +261,7 @@ ldbm_back_modrdn(
 
 
        new_ndn = ch_strdup(new_dn);
-       (void) dn_normalize_case( new_ndn );
+       (void) dn_normalize( new_ndn );
 
        Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: new ndn=%s\n",
               new_ndn, 0, 0 );
@@ -290,7 +294,7 @@ ldbm_back_modrdn(
                       "ldbm_back_modrdn: can't figure out type of newrdn\n",
                       0, 0, 0 );
                send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
+                       NULL, "unknown type used in RDN", NULL, NULL );
                goto return_results;            
 
        }
@@ -301,7 +305,7 @@ ldbm_back_modrdn(
                       "ldbm_back_modrdn: can't figure out val of newrdn\n",
                       0, 0, 0 );
                send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
+                       NULL, "could not parse RDN value", NULL, NULL );
                goto return_results;            
 
        }
@@ -313,40 +317,30 @@ ldbm_back_modrdn(
        /* Retrieve the old rdn from the entry's dn */
 
        if ( (old_rdn = dn_rdn( be, dn )) == NULL ) {
-
                Debug( LDAP_DEBUG_TRACE,
                       "ldbm_back_modrdn: can't figure out old_rdn from dn\n",
                       0, 0, 0 );
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
+               send_ldap_result( conn, op, LDAP_OTHER,
+                       NULL, "could not parse old DN", NULL, NULL );
                goto return_results;            
-
        }
 
        if ( (old_rdn_type = rdn_attr_type( old_rdn )) == NULL ) {
-           
                Debug( LDAP_DEBUG_TRACE,
                       "ldbm_back_modrdn: can't figure out the old_rdn type\n",
                       0, 0, 0 );
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
+               send_ldap_result( conn, op, LDAP_OTHER,
+                       NULL, "count parse RDN from old DN", NULL, NULL );
                goto return_results;            
-               
        }
        
        if ( strcasecmp( old_rdn_type, new_rdn_type ) != 0 ) {
-
            /* Not a big deal but we may say something */
            Debug( LDAP_DEBUG_TRACE,
                   "ldbm_back_modrdn: old_rdn_type=%s, new_rdn_type=%s!\n",
                   old_rdn_type, new_rdn_type, 0 );
-           
        }               
 
-#ifdef DNS_DN
-       if ( dn_type( old_rdn ) == DN_X500 ) {
-#endif
-
                Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: DN_X500\n",
                       0, 0, 0 );
                
@@ -359,10 +353,24 @@ ldbm_back_modrdn(
                add_bv.bv_val = new_rdn_val;
                add_bv.bv_len = strlen(new_rdn_val);
                
-               mod[0].ml_type = new_rdn_type;  
-               mod[0].ml_bvalues = add_bvals;
-               mod[0].ml_op = LDAP_MOD_SOFTADD;
-               mod[0].ml_next = NULL;
+               {
+                       int rc;
+
+                       mod[0].sml_desc = NULL;
+                       rc = slap_str2ad( new_rdn_type, &mod[0].sml_desc, &text );
+
+                       if( rc != LDAP_SUCCESS ) {
+                               Debug( LDAP_DEBUG_TRACE,
+                                       "ldbm_back_modrdn: %s: %s (new)\n",
+                                       text, new_rdn_type, 0 );
+                               send_ldap_result( conn, op, rc,
+                                       NULL, text, NULL, NULL );
+                               goto return_results;            
+                       }
+               }
+               mod[0].sml_bvalues = add_bvals;
+               mod[0].sml_op = SLAP_MOD_SOFTADD;
+               mod[0].sml_next = NULL;
 
                /* Remove old rdn value if required */
 
@@ -375,8 +383,8 @@ ldbm_back_modrdn(
                                Debug( LDAP_DEBUG_TRACE,
                                       "ldbm_back_modrdn: can't figure out old_rdn_val from old_rdn\n",
                                       0, 0, 0 );
-                               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                                       NULL, NULL, NULL, NULL );
+                               send_ldap_result( conn, op, LDAP_OTHER,
+                                       NULL, "could not parse value from old RDN", NULL, NULL );
                                goto return_results;            
                        }
 
@@ -388,36 +396,31 @@ ldbm_back_modrdn(
                        del_bv.bv_val = old_rdn_val;
                        del_bv.bv_len = strlen(old_rdn_val);
 
-                       /* No need to normalize old_rdn_type, delete_values()
-                        * does that for us
-                        */
-                       mod[0].ml_next = &mod[1];
-                       mod[1].ml_type = old_rdn_type;  
-                       mod[1].ml_bvalues = del_bvals;
-                       mod[1].ml_op = LDAP_MOD_DELETE;
-                       mod[1].ml_next = NULL;
+                       {
+                               int rc;
+
+                               mod[1].sml_desc = NULL;
+                               rc = slap_str2ad( old_rdn_type, &mod[1].sml_desc, &text );
+
+                               if( rc != LDAP_SUCCESS ) {
+                                       Debug( LDAP_DEBUG_TRACE,
+                                               "ldbm_back_modrdn: %s: %s (old)\n",
+                                               text, old_rdn_type, 0 );
+                                       send_ldap_result( conn, op, rc,
+                                               NULL, text, NULL, NULL );
+                                       goto return_results;            
+                               }
+                       }
+                       mod[0].sml_next = &mod[1];
+                       mod[1].sml_bvalues = del_bvals;
+                       mod[1].sml_op = LDAP_MOD_DELETE;
+                       mod[1].sml_next = NULL;
 
                        Debug( LDAP_DEBUG_TRACE,
                               "ldbm_back_modrdn: removing old_rdn_val=%s\n",
                               old_rdn_val, 0, 0 );
                }
        
-#ifdef DNS_DN
-       } else {
-               Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: DNS DN\n",
-                      0, 0, 0 );
-               /* XXXV3: not sure of what to do here */
-               Debug( LDAP_DEBUG_TRACE,
-                      "ldbm_back_modrdn: not fully implemented...\n",
-                      0, 0, 0 );
-  
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-               goto return_results;
-
-       }
-#endif
-
        /* check for abandon */
        ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
        if ( op->o_abandon ) {
@@ -428,8 +431,8 @@ ldbm_back_modrdn(
 
        /* delete old one */
        if ( dn2id_delete( be, e->e_ndn, e->e_id ) != 0 ) {
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
+               send_ldap_result( conn, op, LDAP_OTHER,
+                       NULL, "DN index delete fail", NULL, NULL );
                goto return_results;
        }
 
@@ -446,14 +449,19 @@ ldbm_back_modrdn(
 
        /* add new one */
        if ( dn2id_add( be, e->e_ndn, e->e_id ) != 0 ) {
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
+               send_ldap_result( conn, op, LDAP_OTHER,
+                       NULL, "DN index add failed", NULL, NULL );
                goto return_results;
        }
 
        /* modify memory copy of entry */
-       if ( ldbm_modify_internal( be, conn, op, dn, &mod[0], e )
-            != 0 ) {
+       rc = ldbm_modify_internal( be, conn, op, dn, &mod[0], e, &text );
+
+       if( rc != LDAP_SUCCESS ) {
+               if( rc != SLAPD_ABANDON ) {
+                       send_ldap_result( conn, op, rc,
+                               NULL, text, NULL, NULL );
+               }
            
            goto return_results;
        }
@@ -467,8 +475,8 @@ ldbm_back_modrdn(
        /* id2entry index */
        if ( id2entry_add( be, e ) != 0 ) {
                entry_free( e );
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
+               send_ldap_result( conn, op, LDAP_OTHER,
+                       NULL, "entry update failed", NULL, NULL );
                goto return_results;
        }
 
index ebe6f3897119b5cbab989be08a2c4f497ee0850c..37cbfc5f05f074324f039ed6e7a56dfae94e6b2f 100644 (file)
@@ -1,7 +1,7 @@
 /* nextid.c - keep track of the next id to be given out */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -77,8 +77,6 @@ next_id_write( Backend *be, ID id )
        data.dsize = sizeof(ID);
 
        flags = LDBM_REPLACE;
-       if( li->li_dbcachewsync ) flags |= LDBM_SYNC;
-
        if ( ldbm_cache_store( db, key, data, flags ) != 0 ) {
                id = NOID;
        }
diff --git a/servers/slapd/back-ldbm/passwd.c b/servers/slapd/back-ldbm/passwd.c
new file mode 100644 (file)
index 0000000..8f2c968
--- /dev/null
@@ -0,0 +1,161 @@
+/* extended.c - ldbm backend extended routines */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/socket.h>
+#include <ac/string.h>
+
+#include "slap.h"
+#include "back-ldbm.h"
+#include "proto-back-ldbm.h"
+
+int
+ldbm_back_exop_passwd(
+    Backend            *be,
+    Connection         *conn,
+    Operation          *op,
+       const char              *reqoid,
+    struct berval      *reqdata,
+       char                    **rspoid,
+    struct berval      **rspdata,
+       LDAPControl             *** rspctrls,
+       const char              **text,
+    struct berval      *** refs
+)
+{
+       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
+       int rc;
+       Entry *e = NULL;
+       struct berval *hash = NULL;
+
+       struct berval *id = NULL;
+       struct berval *new = NULL;
+
+       char *dn;
+
+       AttributeDescription *entry = slap_schema.si_ad_entry;
+
+       assert( reqoid != NULL );
+       assert( strcmp( LDAP_EXOP_X_MODIFY_PASSWD, reqoid ) == 0 );
+
+       rc = slap_passwd_parse( reqdata,
+               &id, NULL, &new, text );
+
+       Debug( LDAP_DEBUG_ARGS, "==> ldbm_back_exop_passwd: \"%s\"\n",
+               id ? id->bv_val : "", 0, 0 );
+
+       if( rc != LDAP_SUCCESS ) {
+               goto done;
+       }
+
+       if( new == NULL || new->bv_len == 0 ) {
+               new = slap_passwd_generate();
+
+               if( new == NULL || new->bv_len == 0 ) {
+                       *text = "password generation failed.";
+                       rc = LDAP_OTHER;
+                       goto done;
+               }
+               
+               *rspdata = slap_passwd_return( new );
+       }
+
+       hash = slap_passwd_hash( new );
+
+       if( hash == NULL || hash->bv_len == 0 ) {
+               *text = "password hash failed";
+               rc = LDAP_OTHER;
+               goto done;
+       }
+
+       dn = id ? id->bv_val : op->o_dn;
+
+       Debug( LDAP_DEBUG_TRACE, "passwd: \"%s\"%s\n",
+               dn, id ? " (proxy)" : "", 0 );
+
+       if( dn == NULL || dn[0] == '\0' ) {
+               *text = "No password is associated with the Root DSE";
+               rc = LDAP_OPERATIONS_ERROR;
+               goto done;
+       }
+
+       e = dn2entry_w( be, dn, NULL );
+
+       if( e == NULL ) {
+               *text = "could not locate authorization entry";
+               rc = LDAP_OPERATIONS_ERROR;
+               goto done;
+       }
+
+       if( ! access_allowed( be, conn, op, e, entry, NULL, ACL_WRITE ) ) {
+               *text = "access to authorization entry denied";
+               rc = LDAP_INSUFFICIENT_ACCESS;
+               goto done;
+       }
+
+       if( is_entry_alias( e ) ) {
+               /* entry is an alias, don't allow operation */
+               *text = "authorization entry is alias";
+               rc = LDAP_ALIAS_PROBLEM;
+               goto done;
+       }
+
+       rc = LDAP_OPERATIONS_ERROR;
+
+       if( is_entry_referral( e ) ) {
+               /* entry is an referral, don't allow operation */
+               *text = "authorization entry is referral";
+               goto done;
+       }
+
+       {
+               Modifications ml;
+               struct berval *vals[2];
+
+               vals[0] = hash;
+               vals[1] = NULL;
+
+               ml.sml_desc = slap_schema.si_ad_userPassword;
+               ml.sml_bvalues = vals;
+               ml.sml_op = LDAP_MOD_REPLACE;
+               ml.sml_next = NULL;
+
+               rc = ldbm_modify_internal( be,
+                       conn, op, op->o_ndn, &ml, e, text );
+
+       }
+
+       if( rc == LDAP_SUCCESS ) {
+               /* change the entry itself */
+               if( id2entry_add( be, e ) != 0 ) {
+                       *text = "entry update failed";
+                       rc = LDAP_OTHER;
+               }
+       }
+       
+done:
+       if( e != NULL ) {
+               cache_return_entry_w( &li->li_cache, e );
+       }
+
+       if( id != NULL ) {
+               ber_bvfree( id );
+       }
+
+       if( new != NULL ) {
+               ber_bvfree( new );
+       }
+
+       if( hash != NULL ) {
+               ber_bvfree( hash );
+       }
+
+       return rc;
+}
index 1b466f4eb69f87bbe73ed403a0030c23a61747ea..a50cc731964889c38e0d275a335af857a7073fdb 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -19,10 +19,10 @@ LDAP_BEGIN_DECL
 Entry *deref_internal_r LDAP_P((
        Backend *be,
        Entry *e,
-       char *dn,
+       const char *dn,
        int *err,
        Entry **matched,
-       char **text ));
+       const char **text ));
 
 #define deref_entry_r( be, e, err, matched, text ) \
        deref_internal_r( be, e, NULL, err, matched, text )
@@ -33,11 +33,13 @@ Entry *deref_internal_r LDAP_P((
  * attr.c
  */
 
-void attr_masks LDAP_P(( struct ldbminfo *li, char *type, int *indexmask,
- int *syntaxmask ));
-void attr_index_config LDAP_P(( struct ldbminfo *li,
+void attr_mask LDAP_P(( struct ldbminfo *li,
+       const char *desc,
+       slap_index *indexmask ));
+
+int attr_index_config LDAP_P(( struct ldbminfo *li,
        const char *fname, int lineno,
-       int argc, char **argv, int init ));
+       int argc, char **argv ));
 void attr_index_destroy LDAP_P(( Avlnode *tree ));
 
 /*
@@ -60,7 +62,7 @@ void cache_release_all LDAP_P(( Cache *cache ));
  */
 
 DBCache * ldbm_cache_open LDAP_P(( Backend *be,
-       char *name, char *suffix, int flags ));
+       const char *name, const char *suffix, int flags ));
 void ldbm_cache_close LDAP_P(( Backend *be, DBCache *db ));
 void ldbm_cache_really_close LDAP_P(( Backend *be, DBCache *db ));
 void ldbm_cache_flush_all LDAP_P(( Backend *be ));
@@ -131,26 +133,59 @@ ID idl_nextid LDAP_P(( ID_BLOCK *idl, ID *cursor ));
 /*
  * index.c
  */
+extern int
+index_param LDAP_P((
+       Backend *be,
+       AttributeDescription *desc,
+       int ftype,
+       char **dbname,
+       slap_index *mask,
+       struct berval **prefix ));
+
+extern int
+index_values LDAP_P((
+       Backend *be,
+       AttributeDescription *desc,
+       struct berval **vals,
+       ID id,
+       int op ));
+
+int index_entry LDAP_P(( Backend *be, int r, Entry *e, Attribute *ap ));
+#define index_entry_add(be,e,ap) index_entry((be),SLAP_INDEX_ADD_OP,(e),(ap))
+#define index_entry_del(be,e,ap) index_entry((be),SLAP_INDEX_DELETE_OP,(e),(ap))
 
-int index_add_entry LDAP_P(( Backend *be, Entry *e ));
-int index_add_mods LDAP_P(( Backend *be, LDAPModList *ml, ID id ));
-ID_BLOCK * index_read LDAP_P(( Backend *be,
-       char *type, int indextype, char *val ));
-/* Possible operations supported (op) by index_change_values() */
-int index_change_values LDAP_P(( Backend *be,
-                                char *type,
-                                struct berval **vals,
-                                ID  id,
-                                unsigned int op ));
 
 /*
- * kerberos.c
+ * key.c
  */
+extern int
+key_change LDAP_P((
+    Backend            *be,
+    DBCache    *db,
+    struct berval *k,
+    ID                 id,
+    int                        op ));
+extern int
+key_read LDAP_P((
+    Backend    *be,
+       DBCache *db,
+    struct berval *k,
+       ID_BLOCK **idout ));
 
-#ifdef HAVE_KERBEROS
-/* krbv4_ldap_auth LDAP_P(( Backend *be, struct berval *cred, AUTH_DAT *ad )); */
-#endif
+/*
+ * passwd.c
+ */
+extern int ldbm_back_exop_passwd LDAP_P(( BackendDB *bd,
+       Connection *conn, Operation *op,
+       const char *reqoid,
+       struct berval *reqdata,
+       char **rspoid,
+       struct berval **rspdata,
+       LDAPControl ***rspctrls,
+       const char **text,
+       struct berval *** refs ));
  
+
 /*
  * modify.c
  * These prototypes are placed here because they are used by modify and
@@ -163,12 +198,35 @@ int index_change_values LDAP_P(( Backend *be,
  * 
  */
 
-int add_values LDAP_P(( Entry *e, LDAPMod *mod, char *dn ));
-int delete_values LDAP_P(( Entry *e, LDAPMod *mod, char *dn ));
-int replace_values LDAP_P(( Entry *e, LDAPMod *mod, char *dn ));
+/* returns LDAP error code indicating error OR SLAPD_ABANDON */
 int ldbm_modify_internal LDAP_P((Backend *be,
        Connection *conn, Operation *op,
-       char *dn, LDAPModList *mods, Entry *e));
+       const char *dn, Modifications *mods, Entry *e,
+       const char ** ));
+
+#ifdef HAVE_CYRUS_SASL
+/*
+ * sasl.c
+ */
+int ldbm_sasl_authorize LDAP_P((
+        BackendDB *be,
+        const char *auth_identity,
+        const char *requested_user,
+        const char **user,
+        const char **errstring ));
+int ldbm_sasl_getsecret LDAP_P((
+        Backend *be,
+        const char *mechanism,
+        const char *auth_identity,
+        const char *realm,
+        sasl_secret_t **secret ));
+int ldbm_sasl_putsecret LDAP_P((
+        Backend *be,
+        const char *mechanism,
+        const char *auth_identity,
+        const char *realm,
+        const sasl_secret_t *secret ));
+#endif /* HAVE_CYRUS_SASL */
 
 /*
  * nextid.c
diff --git a/servers/slapd/back-ldbm/sasl.c b/servers/slapd/back-ldbm/sasl.c
new file mode 100644 (file)
index 0000000..37e6c7a
--- /dev/null
@@ -0,0 +1,59 @@
+/* bind.c - ldbm backend bind and unbind routines */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#ifdef HAVE_CYRUS_SASL
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/krb.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/unistd.h>
+
+#include "slap.h"
+#include "back-ldbm.h"
+#include "proto-back-ldbm.h"
+
+int
+back_ldbm_sasl_authorize(
+       BackendDB *be,
+       const char *auth_identity,
+       const char *requested_user,
+       const char **user,
+       const char **errstring)
+{
+       return SASL_FAIL;
+}
+
+int
+back_ldbm_sasl_getsecret(
+       Backend *be,
+       const char *mechanism,
+       const char *auth_identity,
+       const char *realm,
+       sasl_secret_t **secret)
+{
+       return SASL_FAIL;
+}
+
+int
+back_ldbm_sasl_putsecret(
+       Backend *be,
+       const char *mechanism,
+       const char *auth_identity,
+       const char *realm,
+       const sasl_secret_t *secret)
+{
+       return SASL_FAIL;
+}
+
+#else
+static int dummy = 1;
+#endif
+
index 2858e249610486af8ab6af19568ee75175f87bd5..36bbc008faaa296faba5a8739d8a582410140cb5 100644 (file)
@@ -1,7 +1,7 @@
 /* search.c - ldbm backend search function */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -29,20 +29,21 @@ ldbm_back_search(
     Backend    *be,
     Connection *conn,
     Operation  *op,
-    char       *base,
+    const char *base,
+    const char *nbase,
     int                scope,
     int                deref,
     int                slimit,
     int                tlimit,
     Filter     *filter,
-    char       *filterstr,
+    const char *filterstr,
     char       **attrs,
     int                attrsonly
 )
 {
        struct ldbminfo *li = (struct ldbminfo *) be->be_private;
        int             rc, err;
-       char *text;
+       const char *text = NULL;
        time_t          stoptime;
        ID_BLOCK                *candidates;
        ID              id, cursor;
@@ -57,10 +58,10 @@ ldbm_back_search(
 
        /* get entry with reader lock */
        if ( deref & LDAP_DEREF_FINDING ) {
-               e = deref_dn_r( be, base, &err, &matched, &text );
+               e = deref_dn_r( be, nbase, &err, &matched, &text );
 
        } else {
-               e = dn2entry_r( be, base, &matched );
+               e = dn2entry_r( be, nbase, &matched );
                err = e != NULL ? LDAP_SUCCESS : LDAP_REFERRAL;
                text = NULL;
        }
@@ -127,7 +128,7 @@ ldbm_back_search(
                    be->be_sizelimit : slimit;
        }
 
-       if ( scope == LDAP_SCOPE_BASE) {
+       if ( scope == LDAP_SCOPE_BASE ) {
                candidates = base_candidate( be, e );
 
        } else {
@@ -137,6 +138,7 @@ ldbm_back_search(
 
        /* need normalized dn below */
        realbase = ch_strdup( e->e_ndn );
+
        cache_return_entry_r( &li->li_cache, e );
 
        if ( candidates == NULL ) {
@@ -189,7 +191,7 @@ ldbm_back_search(
                if ( deref & LDAP_DEREF_SEARCHING && is_entry_alias( e ) ) {
                        Entry *matched;
                        int err;
-                       char *text;
+                       const char *text;
                        
                        e = deref_entry_r( be, e, &err, &matched, &text );
 
@@ -244,13 +246,13 @@ ldbm_back_search(
                }
 
                /* if it matches the filter and scope, send it */
-               if ( test_filter( be, conn, op, e, filter ) == 0 ) {
+               if ( test_filter( be, conn, op, e, filter ) == LDAP_COMPARE_TRUE ) {
                        char    *dn;
 
                        /* check scope */
                        if ( !scopeok && scope == LDAP_SCOPE_ONELEVEL ) {
                                if ( (dn = dn_parent( be, e->e_ndn )) != NULL ) {
-                                       (void) dn_normalize_case( dn );
+                                       (void) dn_normalize( dn );
                                        scopeok = (dn == realbase)
                                                ? 1
                                                : (strcmp( dn, realbase ) ? 0 : 1 );
@@ -281,8 +283,52 @@ ldbm_back_search(
                                }
 
                                if (e) {
-                                       switch ( send_search_entry( be, conn, op, e,
-                                               attrs, attrsonly, NULL ) ) {
+                                       int result;
+#ifdef BROKEN_NUM_SUBORDINATES
+                                       /* Tack on subordinates attr */
+                                       ID_BLOCK *idl = NULL;
+                                       char CATTR_SUBS[] = "numsubordinates";
+
+                                       if (attrs &&
+                                           charray_inlist(attrs,
+                                                          CATTR_SUBS))
+                                       {
+                                           idl = dn2idl(be, e->e_ndn,
+                                                        DN_ONE_PREFIX);
+                                           if (idl)
+                                           {
+                                               char buf[30];
+                                               struct berval val, *vals[2];
+
+                                               vals[0] = &val;
+                                               vals[1] = NULL;
+
+                                               sprintf(buf, "%lu",
+                                                       ID_BLOCK_NIDS(idl));
+
+                                               val.bv_val = buf;
+                                               val.bv_len = strlen(buf);
+
+                                               attr_merge(e, CATTR_SUBS,
+                                                          vals);
+                                           }
+                                       }
+#endif
+
+                                       result = send_search_entry(be, conn, op,
+                                               e, attrs, attrsonly, NULL);
+
+#ifdef BROKEN_NUM_SUBORDINATES
+                                       if (idl)
+                                       {
+                                           idl_free(idl);
+                                           attr_delete(&e->e_attrs,
+                                                       CATTR_SUBS);
+                                       }
+#endif
+
+                                       switch (result)
+                                       {
                                        case 0:         /* entry sent ok */
                                                nentries++;
                                                break;
@@ -355,91 +401,7 @@ search_candidates(
 )
 {
        ID_BLOCK                *candidates;
-       Filter          *f, *rf, *af, *lf;
-
-       Debug(LDAP_DEBUG_TRACE, "search_candidates: base=\"%s\" s=%d d=%d\n",
-               e->e_ndn, scope, deref );
-
-       f = NULL;
-
-       if( !manageDSAit ) {
-               /* match referrals */
-               rf = (Filter *) ch_malloc( sizeof(Filter) );
-               rf->f_next = NULL;
-               rf->f_choice = LDAP_FILTER_OR;
-               rf->f_or = (Filter *) ch_malloc( sizeof(Filter) );
-               rf->f_or->f_choice = LDAP_FILTER_EQUALITY;
-               rf->f_or->f_avtype = ch_strdup( "objectclass" );
-               rf->f_or->f_avvalue.bv_val = ch_strdup( "REFERRAL" );
-               rf->f_or->f_avvalue.bv_len = sizeof("REFERRAL")-1;
-               rf->f_or->f_next = filter;
-               f = rf;
-       } else {
-               rf = NULL;
-               f = filter;
-       }
-
-       if( deref & LDAP_DEREF_SEARCHING ) {
-               /* match aliases */
-               af = (Filter *) ch_malloc( sizeof(Filter) );
-               af->f_next = NULL;
-               af->f_choice = LDAP_FILTER_OR;
-               af->f_or = (Filter *) ch_malloc( sizeof(Filter) );
-               af->f_or->f_choice = LDAP_FILTER_EQUALITY;
-               af->f_or->f_avtype = ch_strdup( "objectclass" );
-               af->f_or->f_avvalue.bv_val = ch_strdup( "ALIAS" );
-               af->f_or->f_avvalue.bv_len = sizeof("ALIAS")-1;
-               af->f_or->f_next = f;
-               f = af;
-       } else {
-               af = NULL;
-       }
-
-       if ( scope == LDAP_SCOPE_SUBTREE ) {
-               lf = (Filter *) ch_malloc( sizeof(Filter) );
-               lf->f_next = NULL;
-               lf->f_choice = LDAP_FILTER_AND;
-               lf->f_and = (Filter *) ch_malloc( sizeof(Filter) );
-
-               lf->f_and->f_choice = SLAPD_FILTER_DN_SUBTREE;
-               lf->f_and->f_dn = e->e_ndn;
-
-               lf->f_and->f_next = f;
-               f = lf;
-
-       } else if ( scope == LDAP_SCOPE_ONELEVEL ) {
-               lf = (Filter *) ch_malloc( sizeof(Filter) );
-               lf->f_next = NULL;
-               lf->f_choice = LDAP_FILTER_AND;
-               lf->f_and = (Filter *) ch_malloc( sizeof(Filter) );
-
-               lf->f_and->f_choice = SLAPD_FILTER_DN_ONE;
-               lf->f_and->f_dn = e->e_ndn;
-
-               lf->f_and->f_next = f;
-               f = lf;
-
-       } else {
-               lf = NULL;
-       }
-
-       candidates = filter_candidates( be, f );
-
-       /* free up filter additions we allocated above */
-       if( lf != NULL ) {
-               free( lf->f_and );
-               free( lf );
-       }
-
-       if( af != NULL ) {
-               af->f_or->f_next = NULL;
-               filter_free( af );
-       }
-
-       if( rf != NULL ) {
-               rf->f_or->f_next = NULL;
-               filter_free( rf );
-       }
+       candidates = filter_candidates( be, filter );
 
        return( candidates );
 }
diff --git a/servers/slapd/back-ldbm/startup.c b/servers/slapd/back-ldbm/startup.c
deleted file mode 100644 (file)
index 8137e0b..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/* startup.c - startup ldbm backend */
-/* $OpenLDAP$ */
-/*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <direct.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-ldbm.h"
-
-#ifdef HAVE_DB1_DB_H
-#      include <db1/db.h>
-#else
-#      include <db.h>
-#endif
-
-#ifdef HAVE_BERKELEY_DB2
-
-void
-ldbm_db_errcall( const char *prefix, const char *message )
-{
-       Debug( LDAP_DEBUG_ANY, "ldbm_db_errcall(): %s %s", prefix, message, 0 );
-}
-
-#endif  /*  HAVE_BERKELEY_DB2  */
-
-
-void
-ldbm_back_startup(
-    Backend    *be
-)
-{
-#ifndef HAVE_BERKELEY_DB2
-       /* make sure we have one and only one big mutex */
-       static int protect = 0;
-
-       if(!protect++) {
-               ldap_pvt_thread_mutex_init( &ldbm_big_mutex );
-       }
-
-#else
-       struct ldbminfo  *li = (struct ldbminfo *) be->be_private;
-       DB_ENV           *dbEnv = &li->li_db_env;
-       u_int32_t    envFlags = DB_CREATE | DB_THREAD;
-       int    err      = 0;
-       char   *home;
-
-       /*  if the data directory is not an absolute path, have it relative
-        to the current working directory (which should not be configured !)  */
-       if ( *li->li_directory != *LDAP_DIRSEP ) {
-               char   cwd[MAXPATHLEN];
-
-               (void) getcwd( cwd, MAXPATHLEN );
-               sprintf( cwd, "%s" LDAP_DIRSEP "%s", cwd, li->li_directory );
-               free( li->li_directory );
-               li->li_directory = strdup( cwd );
-
-       }
-
-       /*  set the DB home directory to the data dir  */
-       home = li->li_directory;
-
-       /*  general initialization of the environment  */
-       memset( dbEnv, 0, sizeof( DB_ENV ));
-       dbEnv->db_errcall = ldbm_db_errcall;
-       dbEnv->db_errpfx  = "==>";
-
-       /*  now do the db_appinit  */
-       if ( ( err = db_appinit( home, NULL, dbEnv, envFlags )) ) {
-               char  error[BUFSIZ];
-
-               if ( err < 0 ) sprintf( error, "%ld\n", (long) err );
-               else           sprintf( error, "%s\n", strerror( err ));
-
-               fprintf( stderr,
-                               "ldbm_back_startup(): FATAL error in db_appinit() : %s\n",
-                               error );
-               exit( EXIT_FAILURE );
-
-       }
-#endif
-}
-
-
-void
-ldbm_back_shutdown(
-    Backend    *be
-)
-{
-#ifdef HAVE_BERKELEY_DB2
-       struct ldbminfo  *li = (struct ldbminfo *) be->be_private;
-
-       (void) db_appexit( &li->li_db_env );
-#endif
-}
index 840449e473d87fa702cb6a9ea688fe55d6cd959c..1715465e69b4bbb1c3e77c942259c0ee68f2e50b 100644 (file)
@@ -1,7 +1,7 @@
 /* tools.c - tools for slap tools */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -42,7 +42,7 @@ int ldbm_tool_entry_open(
                flags = LDBM_READER;
        }
 
-       li->li_dbcachewsync = 0;
+       li->li_dbwritesync = 0;
 
        if ( (id2entry = ldbm_cache_open( be, "id2entry", LDBM_SUFFIX, flags ))
            == NULL ) {
@@ -63,7 +63,7 @@ int ldbm_tool_entry_close(
        assert( id2entry != NULL );
 
        ldbm_cache_close( be, id2entry );
-       li->li_dbcachewsync = 1;
+       li->li_dbwritesync = 1;
        id2entry = NULL;
 
        return 0;
@@ -160,7 +160,7 @@ ID ldbm_tool_entry_put(
        Debug( LDAP_DEBUG_TRACE, "=> ldbm_tool_entry_put( %ld, \"%s\" )\n",
                e->e_id, e->e_dn, 0 );
 
-       rc = index_add_entry( be, e );
+       rc = index_entry_add( be, e, e->e_attrs );
 
        if( rc != 0 ) {
                return NOID;
@@ -194,23 +194,25 @@ ID ldbm_tool_entry_put(
 
 int ldbm_tool_index_attr(
        BackendDB *be,
-       char* type )
+       AttributeDescription *desc
+)
 {
        static DBCache *db = NULL;
-       int indexmask, syntaxmask;
-       char * at_cn;
+       slap_index indexmask;
+       char *at_cname;
 
        assert( slapMode & SLAP_TOOL_MODE );
 
-       attr_masks( be->be_private, type, &indexmask, &syntaxmask );
+       at_cname = desc->ad_cname->bv_val;
 
-       attr_normalize( type );
-       at_cn = at_canonical_name( type );
+       assert( desc != NULL );
+       attr_mask( be->be_private, at_cname, &indexmask );
 
-       if ( (db = ldbm_cache_open( be, at_cn, LDBM_SUFFIX, LDBM_NEWDB ))
-           == NULL ) {
+       if ( (db = ldbm_cache_open( be, at_cname, LDBM_SUFFIX, LDBM_NEWDB ))
+           == NULL )
+       {
                Debug( LDAP_DEBUG_ANY,
-                   "<= index_read NULL (could not open %s%s)\n", at_cn,
+                   "<= index_attr NULL (could not open %s%s)\n", at_cname,
                    LDBM_SUFFIX, 0 );
                return 0;
        }
@@ -222,15 +224,14 @@ int ldbm_tool_index_attr(
 
 int ldbm_tool_index_change(
        BackendDB *be,
-       char* type,
+       AttributeDescription *desc,
        struct berval **bv,
        ID id,
        int op )
 {
        assert( slapMode & SLAP_TOOL_MODE );
 
-       index_change_values( be,
-               type, bv, id, op );
+       index_values( be, desc, bv, id, op );
 
        return 0;
 }
index 69538da67bb7c198b4f3a166a79225d6d52e04b8..d859d7a8849b53a31b89e4cc1c1d53fb67233097 100644 (file)
@@ -1,7 +1,7 @@
 /* unbind.c - handle an ldap unbind operation */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
index 090ff008a0ba322ce5507d936e8f5cc9e9fb1d37..a3a7aa5d059da0bccc9799f4475d390dc352bbd1 100644 (file)
@@ -14,7 +14,6 @@ LIBBASE = back_passwd
 
 XINCPATH = -I.. -I$(srcdir)/..
 XDEFS = $(MODULES_CPPFLAGS)
-XLDFLAGS = $(MODULES_LDFLAGS)
 
 all-local-lib: ../.backend
 
index 92dd26e95d47fc02292764ee656ed7e8bdf0495b..1561c8d4a6930462243d8766241414622b809110 100644 (file)
@@ -8,8 +8,10 @@ extern int     passwd_back_initialize LDAP_P(( BackendInfo *bi ));
 
 extern int  passwd_back_search LDAP_P(( BackendDB *be,
        Connection *c, Operation *o,
-       char *base, int scope, int deref, int slimit, int tlimit,
-       Filter *f, char *filterstr, char **attrs, int attrsonly));
+       const char *base, const char *nbase,
+       int scope, int deref, int slimit, int tlimit,
+       Filter *f, const char *filterstr,
+       char **attrs, int attrsonly));
 
 extern int passwd_back_db_config LDAP_P((BackendDB *bd,
        const char *fname, int lineno, int argc, char **argv ));
index 609231dba429661ea69646c9ea0d694108c0bb54..3e310d49e49849cdcca4440f926b2a1445f74a0f 100644 (file)
@@ -15,7 +15,7 @@
 int back_passwd_LTX_init_module(int argc, char *argv[]) {
     BackendInfo bi;
 
-    memset( &bi, 0, sizeof(bi) );
+    memset( &bi, '\0', sizeof(bi) );
     bi.bi_type = "passwd";
     bi.bi_init = passwd_back_initialize;
 
@@ -51,8 +51,16 @@ passwd_back_initialize(
        bi->bi_op_delete = 0;
        bi->bi_op_abandon = 0;
 
+       bi->bi_extended = 0;
+
        bi->bi_acl_group = 0;
 
+#ifdef HAVE_CYRUS_SASL
+       bi->bi_sasl_authorize = 0;
+       bi->bi_sasl_getsecret = 0;
+       bi->bi_sasl_putsecret = 0;
+#endif /* HAVE_CYRUS_SASL */
+
        bi->bi_connection_init = 0;
        bi->bi_connection_destroy = 0;
 
index 68af4b3fa44ed6f670cc83a7c51cbd58e3cb0581..fbd84fd209a706adf7965574e9d124a7a32f59b6 100644 (file)
@@ -26,13 +26,14 @@ passwd_back_search(
     Backend    *be,
     Connection *conn,
     Operation  *op,
-    char       *base,
+    const char *base,
+    const char *nbase,
     int                scope,
     int                deref,
     int                slimit,
     int                tlimit,
     Filter     *filter,
-    char       *filterstr,
+    const char *filterstr,
     char       **attrs,
     int                attrsonly
 )
@@ -50,6 +51,8 @@ passwd_back_search(
        char *matched = NULL;
        char *user = NULL;
 
+       AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass;
+
        tlimit = (tlimit > be->be_timelimit || tlimit < 1) ? be->be_timelimit
            : tlimit;
        stoptime = op->o_time + tlimit;
@@ -65,7 +68,7 @@ passwd_back_search(
 #endif /* HAVE_SETPWFILE */
 
        /* Handle a query for the base of this backend */
-       if ( be_issuffix( be,  base ) ) {
+       if ( be_issuffix( be,  nbase ) ) {
                struct berval   val, *vals[2];
 
                vals[0] = &val;
@@ -74,6 +77,9 @@ passwd_back_search(
                matched = ch_strdup( base );
 
                if( scope != LDAP_SCOPE_ONELEVEL ) {
+                       char *type;
+                       AttributeDescription *desc = NULL;
+
                        /* Create an entry corresponding to the base DN */
                        e = (Entry *) ch_calloc(1, sizeof(Entry));
                        e->e_attrs = NULL;
@@ -86,12 +92,30 @@ passwd_back_search(
 
                        if( rdn == NULL || (s = strchr(rdn, '=')) == NULL ) {
                                err = LDAP_INVALID_DN_SYNTAX;
+                               free(rdn);
                                goto done;
                        }
 
                        val.bv_val = rdn_attr_value(rdn);
                        val.bv_len = strlen( val.bv_val );
-                       attr_merge( e, rdn_attr_type(rdn), vals );
+
+                       type = rdn_attr_type(rdn);
+
+                       {
+                               int rc;
+                               const char *text;
+                               rc = slap_str2ad( type, &desc, &text );
+
+                               if( rc != LDAP_SUCCESS ) {
+                                       err = LDAP_NO_SUCH_OBJECT;
+                                       free(rdn);
+                                       goto done;
+                               }
+                       }
+
+                       attr_merge( e, desc, vals );
+
+                       ad_free( desc, 1 );
 
                        free(rdn);
                        rdn = NULL;
@@ -104,10 +128,10 @@ passwd_back_search(
                         * should be a configuratable item
                         */
                        val.bv_val = "organizationalUnit";
-                       val.bv_len = strlen( val.bv_val );
-                       attr_merge( e, "objectClass", vals );
+                       val.bv_len = sizeof("organizationalUnit")-1;
+                       attr_merge( e, ad_objectClass, vals );
        
-                       if ( test_filter( be, conn, op, e, filter ) == 0 ) {
+                       if ( test_filter( be, conn, op, e, filter ) == LDAP_COMPARE_TRUE ) {
                                send_search_entry( be, conn, op,
                                        e, attrs, attrsonly, NULL );
                                sent++;
@@ -137,7 +161,7 @@ passwd_back_search(
 
                                e = pw2entry( be, pw, NULL );
 
-                               if ( test_filter( be, conn, op, e, filter ) == 0 ) {
+                               if ( test_filter( be, conn, op, e, filter ) == LDAP_COMPARE_TRUE ) {
                                        /* check size limit */
                                        if ( --slimit == -1 ) {
                                                send_ldap_result( conn, op, LDAP_SIZELIMIT_EXCEEDED,
@@ -164,8 +188,8 @@ passwd_back_search(
                 */
                if( !be_issuffix( be, parent ) ) {
                        int i;
-                       for( i=0; be->be_suffix[i] != NULL; i++ ) {
-                               if( dn_issuffix( base, be->be_suffix[i] ) ) {
+                       for( i=0; be->be_nsuffix[i] != NULL; i++ ) {
+                               if( dn_issuffix( nbase, be->be_nsuffix[i] ) ) {
                                        matched = ch_strdup( be->be_suffix[i] );
                                        break;
                                }
@@ -185,8 +209,6 @@ passwd_back_search(
                        goto done;
                }
 
-               user = ldap_pvt_str2lower( user );
-
                if ( (pw = getpwnam( user )) == NULL ) {
                        matched = parent;
                        parent = NULL;
@@ -196,7 +218,7 @@ passwd_back_search(
 
                e = pw2entry( be, pw, rdn );
 
-               if ( test_filter( be, conn, op, e, filter ) == 0 ) {
+               if ( test_filter( be, conn, op, e, filter ) == LDAP_COMPARE_TRUE ) {
                        send_search_entry( be, conn, op,
                                e, attrs, attrsonly, NULL );
                        sent++;
@@ -226,6 +248,28 @@ pw2entry( Backend *be, struct passwd *pw, char *rdn )
        struct berval   val;
        struct berval   *vals[2];
 
+       int rc;
+       const char *text;
+
+       AttributeDescription *ad_objectClass = NULL;
+       AttributeDescription *ad_cn = NULL;
+       AttributeDescription *ad_sn = NULL;
+       AttributeDescription *ad_uid = NULL;
+       AttributeDescription *ad_description = NULL;
+
+       rc = slap_str2ad( "objectClass", &ad_objectClass, &text );
+
+       if(rc != LDAP_SUCCESS) return NULL;
+       rc = slap_str2ad( "cn", &ad_cn, &text );
+       if(rc != LDAP_SUCCESS) return NULL;
+       rc = slap_str2ad( "sn", &ad_sn, &text );
+       if(rc != LDAP_SUCCESS) return NULL;
+       rc = slap_str2ad( "uid", &ad_uid, &text );
+       if(rc != LDAP_SUCCESS) return NULL;
+       rc = slap_str2ad( "description", &ad_description, &text );
+       if(rc != LDAP_SUCCESS) return NULL;
+
+
        vals[0] = &val;
        vals[1] = NULL;
 
@@ -237,17 +281,30 @@ pw2entry( Backend *be, struct passwd *pw, char *rdn )
        e = (Entry *) ch_calloc( 1, sizeof(Entry) );
        e->e_attrs = NULL;
 
+       /* objectclasses should be configuratable items */
+       val.bv_val = "top";
+       val.bv_len = sizeof("top")-1;
+       attr_merge( e, ad_objectClass, vals );
+
+       val.bv_val = "person";
+       val.bv_len = sizeof("person")-1;
+       attr_merge( e, ad_objectClass, vals );
+
+       val.bv_val = "uidObject";
+       val.bv_len = sizeof("uidObject")-1;
+       attr_merge( e, ad_objectClass, vals );
+
        /* rdn attribute type should be a configuratable item */
        sprintf( buf, "uid=%s,%s", pw->pw_name, be->be_suffix[0] );
        e->e_dn = ch_strdup( buf );
        e->e_ndn = ch_strdup( buf );
-       (void) dn_normalize_case( e->e_ndn );
+       (void) dn_normalize( e->e_ndn );
 
        val.bv_val = pw->pw_name;
        val.bv_len = strlen( pw->pw_name );
-       attr_merge( e, "uid", vals );   /* required by uidObject */
-       attr_merge( e, "cn", vals );    /* required by person */
-       attr_merge( e, "sn", vals );    /* required by person */
+       attr_merge( e, ad_uid, vals );  /* required by uidObject */
+       attr_merge( e, ad_cn, vals );   /* required by person */
+       attr_merge( e, ad_sn, vals );   /* required by person */
 
 #ifdef HAVE_PW_GECOS
        /*
@@ -260,7 +317,7 @@ pw2entry( Backend *be, struct passwd *pw, char *rdn )
 
                val.bv_val = pw->pw_gecos;
                val.bv_len = strlen(val.bv_val);
-               attr_merge(e, "description", vals);
+               attr_merge(e, ad_description, vals);
 
                s = strchr(val.bv_val, ',');
                if (s)
@@ -277,22 +334,14 @@ pw2entry( Backend *be, struct passwd *pw, char *rdn )
                }
                val.bv_len = strlen(val.bv_val);
                if ( strcmp( val.bv_val, pw->pw_name ))
-                       attr_merge( e, "cn", vals );
+                       attr_merge( e, ad_cn, vals );
                if ( (s=strrchr(val.bv_val, ' '))) {
                        val.bv_val = s + 1;
                        val.bv_len = strlen(val.bv_val);
-                       attr_merge(e, "sn", vals);
+                       attr_merge(e, ad_sn, vals);
                }
        }
 #endif
 
-       /* objectclasses should be configuratable items */
-       val.bv_val = "person";
-       val.bv_len = strlen( val.bv_val );
-       attr_merge( e, "objectclass", vals );
-
-       val.bv_val = "uidObject";
-       val.bv_len = strlen( val.bv_val );
-       attr_merge( e, "objectclass", vals );
        return( e );
 }
diff --git a/servers/slapd/back-perl/Makefile.in b/servers/slapd/back-perl/Makefile.in
deleted file mode 100644 (file)
index aaaf32d..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-# $OpenLDAP$
-########################################################################### 
-# 
-#    Copyright 1999, John C. Quillan, All rights reserved.
-# 
-#    Redistribution and use in source and binary forms are permitted only
-#    as authorized by the OpenLDAP Public License.  A copy of this
-#    license is available at http://www.OpenLDAP.org/license.html or
-#    in file LICENSE in the top-level directory of the distribution.
-# 
-##########################################################################
-
-SRCS   = init.c search.c close.c config.c bind.c unbind.c compare.c \
-               modify.c add.c modrdn.c delete.c
-OBJS   = init.lo search.lo close.lo config.lo bind.lo unbind.lo compare.lo \
-               modify.lo add.lo modrdn.lo delete.lo
-
-LDAP_INCDIR= ../../../include       
-LDAP_LIBDIR= ../../../libraries
-
-BUILD_OPT = "--enable-perl"
-BUILD_MOD = @BUILD_PERL@
-LINKAGE = @BUILD_PERL_DYNAMIC@
-
-LIBBASE = back_perl
-
-XINCPATH = -I.. -I$(srcdir)/..
-XDEFS = $(PERL_CPPFLAGS) $(MODULES_CPPFLAGS)
-XLDFLAGS = $(MODULES_LDFLAGS)
-
-all-local-lib: ../.backend
-
-../.backend: lib$(LIBBASE).a
-       @touch $@
-
diff --git a/servers/slapd/back-perl/add.c b/servers/slapd/back-perl/add.c
deleted file mode 100644 (file)
index 707b140..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/* $OpenLDAP$ */
-/*
- *      Copyright 1999, John C. Quillan, All rights reserved.
- *
- *      Redistribution and use in source and binary forms are permitted only
- *      as authorized by the OpenLDAP Public License.  A copy of this
- *      license is available at http://www.OpenLDAP.org/license.html or
- *      in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-/*     #include <ac/types.h>
-       #include <ac/socket.h>
-*/
-
-#include <EXTERN.h>
-#include <perl.h>
-
-#include "slap.h"
-#include "perl_back.h"
-
-int
-perl_back_add(
-       Backend *be,
-       Connection      *conn,
-       Operation       *op,
-       Entry   *e
-)
-{
-       int len;
-       int count;
-       int return_code;
-
-       PerlBackend *perl_back = (PerlBackend *) be->be_private;
-
-       ldap_pvt_thread_mutex_lock( &perl_interpreter_mutex );
-       ldap_pvt_thread_mutex_lock( &entry2str_mutex );
-
-       {
-               dSP; ENTER; SAVETMPS;
-
-               PUSHMARK(sp);
-               XPUSHs( perl_back->pb_obj_ref );
-               XPUSHs(sv_2mortal(newSVpv( entry2str( e, &len ), 0 )));
-
-               PUTBACK;
-
-               count = perl_call_method("add", G_SCALAR);
-
-               SPAGAIN;
-
-               if (count != 1) {
-                       croak("Big trouble in back_search\n");
-               }
-                                                        
-               return_code = POPi;
-
-               PUTBACK; FREETMPS; LEAVE;
-       }
-
-       ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
-       ldap_pvt_thread_mutex_unlock( &perl_interpreter_mutex );        
-
-       if( return_code != 0 ) {
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-
-       } else {
-               send_ldap_result( conn, op, LDAP_SUCCESS,
-                       NULL, NULL, NULL, NULL );
-       }
-
-       Debug( LDAP_DEBUG_ANY, "Here ADD\n", 0, 0, 0 );
-       return( 0 );
-}
diff --git a/servers/slapd/back-perl/bind.c b/servers/slapd/back-perl/bind.c
deleted file mode 100644 (file)
index 9d20afd..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/* $OpenLDAP$ */
-/*
- *      Copyright 1999, John C. Quillan, All rights reserved.
- *
- *      Redistribution and use in source and binary forms are permitted only
- *      as authorized by the OpenLDAP Public License.  A copy of this
- *      license is available at http://www.OpenLDAP.org/license.html or
- *      in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
-/* init.c - initialize shell backend */
-       
-#include <stdio.h>
-/*     #include <ac/types.h>
-       #include <ac/socket.h>
-*/
-
-#include <EXTERN.h>
-#include <perl.h>
-
-#include "slap.h"
-#include "perl_back.h"
-
-
-/**********************************************************
- *
- * Bind
- *
- **********************************************************/
-int
-perl_back_bind(
-       Backend *be,
-       Connection *conn,
-       Operation *op,
-       char *dn,
-       int method,
-       char            *mech,
-       struct berval *cred,
-       char** edn
-)
-{
-       int return_code;
-       int count;
-
-       PerlBackend *perl_back = (PerlBackend *) be->be_private;
-
-       *edn = NULL;
-
-       ldap_pvt_thread_mutex_lock( &perl_interpreter_mutex );  
-
-       {
-               dSP; ENTER; SAVETMPS;
-
-               PUSHMARK(sp);
-               XPUSHs( perl_back->pb_obj_ref );
-               XPUSHs(sv_2mortal(newSVpv( dn , 0)));
-               XPUSHs(sv_2mortal(newSVpv( cred->bv_val , cred->bv_len)));
-               PUTBACK;
-
-               count = perl_call_method("bind", G_SCALAR);
-
-               SPAGAIN;
-
-               if (count != 1) {
-                       croak("Big trouble in back_search\n");
-               }
-
-               return_code = POPi;
-                                                        
-
-               PUTBACK; FREETMPS; LEAVE;
-       }
-
-       ldap_pvt_thread_mutex_unlock( &perl_interpreter_mutex );        
-
-       Debug( LDAP_DEBUG_ANY, "Perl BIND\n", 0, 0, 0 );
-
-       return ( return_code );
-}
-
-
diff --git a/servers/slapd/back-perl/close.c b/servers/slapd/back-perl/close.c
deleted file mode 100644 (file)
index 79b62af..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/* $OpenLDAP$ */
-/*
- *      Copyright 1999, John C. Quillan, All rights reserved.
- *
- *      Redistribution and use in source and binary forms are permitted only
- *      as authorized by the OpenLDAP Public License.  A copy of this
- *      license is available at http://www.OpenLDAP.org/license.html or
- *      in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
-/* init.c - initialize shell backend */
-       
-#include <stdio.h>
-/*     #include <ac/types.h>
-       #include <ac/socket.h>
-*/
-
-#include <EXTERN.h>
-#include <perl.h>
-
-#include "slap.h"
-#include "perl_back.h"
-
-/**********************************************************
- *
- * Close
- *
- **********************************************************/
-
-int
-perl_back_close(
-       BackendInfo *bd
-)
-{
-       ldap_pvt_thread_mutex_lock( &perl_interpreter_mutex );  
-
-       perl_destruct(perl_interpreter);
-
-       ldap_pvt_thread_mutex_unlock( &perl_interpreter_mutex );        
-
-       return 0;
-}
-
-int
-perl_back_destroy(
-       BackendInfo *bd
-)
-{
-       perl_free(perl_interpreter);
-       perl_interpreter = NULL;
-
-       ldap_pvt_thread_mutex_destroy( &perl_interpreter_mutex );       
-
-       return 0;
-}
-
-int
-perl_back_db_destroy(
-       BackendDB *be
-)
-{
-       free( be->be_private );
-       be->be_private = NULL;
-}
diff --git a/servers/slapd/back-perl/compare.c b/servers/slapd/back-perl/compare.c
deleted file mode 100644 (file)
index 4c9f390..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/* $OpenLDAP$ */
-/*
- *      Copyright 1999, John C. Quillan, All rights reserved.
- *
- *      Redistribution and use in source and binary forms are permitted only
- *      as authorized by the OpenLDAP Public License.  A copy of this
- *      license is available at http://www.OpenLDAP.org/license.html or
- *      in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-/*     #include <ac/types.h>
-       #include <ac/socket.h>
-*/
-
-#include <EXTERN.h>
-#include <perl.h>
-
-#include "slap.h"
-#include "perl_back.h"
-
-/**********************************************************
- *
- * Compare
- *
- **********************************************************/
-
-perl_back_compare(
-       Backend *be,
-       Connection      *conn,
-       Operation       *op,
-       char    *dn,
-       Ava             *ava
-)
-{
-       int return_code;
-       int count;
-
-       PerlBackend *perl_back = (PerlBackend *)be->be_private;
-
-       send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
-               NULL, "not yet implemented", NULL, NULL );
-
-#ifdef notdef
-       ldap_pvt_thread_mutex_lock( &perl_interpreter_mutex );  
-
-       {
-               dSP; ENTER; SAVETMPS;
-
-               PUSHMARK(sp);
-               XPUSHs( perl_back->pb_obj_ref );
-               XPUSHs(sv_2mortal(newSVpv( dn , 0)));
-               /* XPUSHs(sv_2mortal(newSVpv( cred->bv_val , cred->bv_len))); */
-               PUTBACK;
-
-               count = perl_call_method("bind", G_SCALAR);
-
-               SPAGAIN;
-
-               if (count != 1) {
-                       croak("Big trouble in back_search\n");
-               }
-
-               return_code = POPi;
-                                                        
-               PUTBACK; FREETMPS; LEAVE;
-       }
-
-       ldap_pvt_thread_mutex_unlock( &perl_interpreter_mutex );        
-
-       if( return_code != 0 ) {
-               send_ldap_result( conn, op, LDAP_COMPARE_TRUE, NULL, NULL );
-
-       } else {
-               send_ldap_result( conn, op, LDAP_COMPARE_FALSE, NULL, NULL );
-       }
-#endif
-
-       Debug( LDAP_DEBUG_ANY, "Here BIND\n", 0, 0, 0 );
-
-       return (0);
-}
-
diff --git a/servers/slapd/back-perl/config.c b/servers/slapd/back-perl/config.c
deleted file mode 100644 (file)
index f68a0a1..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/* $OpenLDAP$ */
-/*
- *      Copyright 1999, John C. Quillan, All rights reserved.
- *
- *      Redistribution and use in source and binary forms are permitted only
- *      as authorized by the OpenLDAP Public License.  A copy of this
- *      license is available at http://www.OpenLDAP.org/license.html or
- *      in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
-/* init.c - initialize shell backend */
-       
-#include <stdio.h>
-/*     #include <ac/types.h>
-       #include <ac/socket.h>
-*/
-
-#include <EXTERN.h>
-#include <perl.h>
-
-#include "slap.h"
-#include "perl_back.h"
-
-
-/**********************************************************
- *
- * Config
- *
- **********************************************************/
-int
-perl_back_db_config(
-        BackendDB *be,
-        const char *fname,
-        int lineno,
-        int argc,
-        char **argv
-)
-{
-       SV* loc_sv;
-       PerlBackend *perl_back = (PerlBackend *) be->be_private;
-       char eval_str[EVAL_BUF_SIZE];
-       int count ;
-       int args;
-       int return_code;
-       
-
-       if ( strcasecmp( argv[0], "perlModule" ) == 0 ) {
-               if ( argc < 2 ) {
-                       Debug( LDAP_DEBUG_ANY,
-                                "%s.pm: line %d: missing module in \"perlModule <module>\" line\n",
-                               fname, lineno, 0 );
-                       return( 1 );
-               }
-
-               strncpy(eval_str, argv[1], EVAL_BUF_SIZE );
-
-               perl_require_pv( strcat( eval_str, ".pm" ));
-
-               if (SvTRUE(GvSV(errgv))) {
-                       fprintf(stderr , "Error %s\n", SvPV(GvSV(errgv), na)) ;
-
-               } else {
-                       dSP; ENTER; SAVETMPS;
-                       PUSHMARK(sp);
-                       XPUSHs(sv_2mortal(newSVpv(argv[1], 0)));
-                       PUTBACK;
-
-                       count = perl_call_method("new", G_SCALAR);
-                       
-                       SPAGAIN;
-
-                       if (count != 1) {
-                               croak("Big trouble in config\n") ;
-                       }
-
-                       perl_back->pb_obj_ref = newSVsv(POPs);
-
-                       PUTBACK; FREETMPS; LEAVE ;
-               }
-
-       } else if ( strcasecmp( argv[0], "perlModulePath" ) == 0 ) {
-               if ( argc < 2 ) {
-                       fprintf( stderr,
-                               "%s: line %d: missing module in \"PerlModulePath <module>\" line\n",
-                               fname, lineno );
-                       return( 1 );
-               }
-
-               sprintf( eval_str, "push @INC, '%s';", argv[1] );
-               loc_sv = perl_eval_pv( eval_str, 0 );
-
-       } else {
-               /*
-                * Pass it to Perl module if defined
-                */
-
-               {
-                       dSP ;  ENTER ; SAVETMPS;
-
-                       PUSHMARK(sp) ;
-                       XPUSHs( perl_back->pb_obj_ref );
-
-                       /* Put all arguments on the perl stack */
-                       for( args = 0; args < argc; args++ ) {
-                               XPUSHs(sv_2mortal(newSVpv(argv[args], 0)));
-                       }
-
-                       PUTBACK ;
-
-                       count = perl_call_method("config", G_SCALAR);
-
-                       SPAGAIN ;
-
-                       if (count != 1) {
-                               croak("Big trouble in config\n") ;
-                       }
-
-                       return_code = POPi;
-
-                       PUTBACK ; FREETMPS ;  LEAVE ;
-
-               }
-
-               /* if the module rejected it then we should reject it */
-               if ( return_code != 0 ) {
-                       fprintf( stderr,
-                                "Unknown perl backeng config: %s\n", argv[0]);
-                       exit( EXIT_FAILURE );
-               }
-       }
-
-       return 0;
-}
diff --git a/servers/slapd/back-perl/delete.c b/servers/slapd/back-perl/delete.c
deleted file mode 100644 (file)
index 19d2346..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/* $OpenLDAP$ */
-/*
- *      Copyright 1999, John C. Quillan, All rights reserved.
- *
- *      Redistribution and use in source and binary forms are permitted only
- *      as authorized by the OpenLDAP Public License.  A copy of this
- *      license is available at http://www.OpenLDAP.org/license.html or
- *      in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-/* #include <ac/types.h>
-#include <ac/socket.h>
-*/
-
-#include <EXTERN.h>
-#include <perl.h>
-
-#include "slap.h"
-#include "perl_back.h"
-
-perl_back_delete(
-       Backend *be,
-       Connection      *conn,
-       Operation       *op,
-       char    *dn
-)
-{
-       int len;
-       int count;
-       int return_code;
-
-       PerlBackend *perl_back = (PerlBackend *) be->be_private;
-
-       ldap_pvt_thread_mutex_lock( &perl_interpreter_mutex );  
-
-       {
-               dSP; ENTER; SAVETMPS;
-
-               PUSHMARK(sp);
-               XPUSHs( perl_back->pb_obj_ref );
-               XPUSHs(sv_2mortal(newSVpv( dn , 0 )));
-
-               PUTBACK;
-
-               count = perl_call_method("delete", G_SCALAR);
-
-               SPAGAIN;
-
-               if (count != 1) {
-                       croak("Big trouble in perl-back_delete\n");
-               }
-                                                        
-               return_code = POPi;
-
-               PUTBACK; FREETMPS; LEAVE;
-       }
-
-       ldap_pvt_thread_mutex_unlock( &perl_interpreter_mutex );        
-
-       if( return_code != 0 ) {
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-
-       } else {
-               send_ldap_result( conn, op, LDAP_SUCCESS,
-                       NULL, NULL, NULL, NULL );
-       }
-
-       Debug( LDAP_DEBUG_ANY, "Here DELETE\n", 0, 0, 0 );
-       return( 0 );
-}
diff --git a/servers/slapd/back-perl/external.h b/servers/slapd/back-perl/external.h
deleted file mode 100644 (file)
index d41fb13..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* $OpenLDAP$ */
-#ifndef _PERL_EXTERNAL_H
-#define _PERL_EXTERNAL_H
-
-LDAP_BEGIN_DECL
-
-extern int     perl_back_initialize LDAP_P(( BackendInfo *bi ));
-extern int     perl_back_open LDAP_P(( BackendInfo *bi ));
-extern int     perl_back_close LDAP_P(( BackendInfo *bi ));
-extern int     perl_back_destroy LDAP_P(( BackendInfo *bi ));
-
-extern int     perl_back_db_init LDAP_P(( BackendDB *bd ));
-extern int     perl_back_db_destroy LDAP_P(( BackendDB *bd ));
-
-extern int     perl_back_db_config LDAP_P(( BackendDB *bd,
-       const char *fname, int lineno, int argc, char **argv ));
-
-extern int perl_back_bind LDAP_P(( BackendDB *bd,
-       Connection *conn, Operation *op,
-       char *dn, int method, char* mech,
-       struct berval *cred, char** edn ));
-
-extern int     perl_back_unbind LDAP_P(( BackendDB *bd,
-       Connection *conn, Operation *op ));
-
-extern int     perl_back_search LDAP_P(( BackendDB *bd,
-       Connection *conn, Operation *op,
-       char *base, int scope, int deref, int sizelimit, int timelimit,
-       Filter *filter, char *filterstr, char **attrs, int attrsonly ));
-
-extern int     perl_back_compare LDAP_P((BackendDB *bd,
-       Connection *conn, Operation *op,
-       char *dn, Ava   *ava ));
-
-extern int     perl_back_modify LDAP_P(( BackendDB *bd,
-       Connection *conn, Operation *op,
-       char *dn, LDAPModList *ml ));
-
-extern int     perl_back_modrdn LDAP_P(( BackendDB *bd,
-       Connection *conn, Operation *op,
-       char *dn, char*newrdn, int deleteoldrdn,
-       char *newSuperior ));
-
-extern int     perl_back_add LDAP_P(( BackendDB *bd,
-       Connection *conn, Operation *op, Entry *e ));
-
-extern int     perl_back_delete LDAP_P(( BackendDB *bd,
-       Connection *conn, Operation *op, char *dn ));
-
-LDAP_END_DECL
-
-#endif /* _PERL_EXTERNAL_H */
-
diff --git a/servers/slapd/back-perl/init.c b/servers/slapd/back-perl/init.c
deleted file mode 100644 (file)
index e215acd..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/* $OpenLDAP$ */
-/*
- *      Copyright 1999, John C. Quillan, All rights reserved.
- *
- *      Redistribution and use in source and binary forms are permitted only
- *      as authorized by the OpenLDAP Public License.  A copy of this
- *      license is available at http://www.OpenLDAP.org/license.html or
- *      in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
- /* init.c - initialize shell backend */
-       
-#include <stdio.h>
-/* #include <ac/types.h>
-       #include <ac/socket.h>
-*/
-
-
-
-#include <EXTERN.h>
-#include <perl.h>
-
-#include "slap.h"
-#include "perl_back.h"
-
-
-
-PerlInterpreter *perl_interpreter = NULL;
-ldap_pvt_thread_mutex_t        perl_interpreter_mutex;
-
-#ifdef SLAPD_PERL_DYNAMIC
-
-int back_perl_LTX_init_module(int argc, char *argv[]) {
-    BackendInfo bi;
-
-    memset( &bi, 0, sizeof(bi) );
-    bi.bi_type = "perl";
-    bi.bi_init = perl_back_initialize;
-
-    backend_add(&bi);
-    return 0;
-}
-
-#endif /* SLAPD_PERL_DYNAMIC */
-
-
-/**********************************************************
- *
- * Init
- *
- **********************************************************/
-
-int
-perl_back_initialize(
-       BackendInfo     *bi
-)
-{
-       char *embedding[] = { "", "-e", "0" };
-
-       Debug( LDAP_DEBUG_TRACE, "perl backend open\n", 0, 0, 0 );
-
-       if( perl_interpreter != NULL ) {
-               Debug( LDAP_DEBUG_ANY, "perl backend open: already opened\n",
-                       0, 0, 0 );
-               return 1;
-       }
-       
-       perl_interpreter = perl_alloc();
-       perl_construct(perl_interpreter);
-       perl_parse(perl_interpreter, NULL, 3, embedding, (char **)NULL);
-       perl_run(perl_interpreter);
-
-       bi->bi_open = perl_back_open;
-       bi->bi_config = 0;
-       bi->bi_close = perl_back_close;
-       bi->bi_destroy = perl_back_destroy;
-
-       bi->bi_db_init = perl_back_db_init;
-       bi->bi_db_config = perl_back_db_config;
-       bi->bi_db_open = 0;
-       bi->bi_db_close = 0;
-       bi->bi_db_destroy = perl_back_db_destroy;
-
-       bi->bi_op_bind = perl_back_bind;
-       bi->bi_op_unbind = perl_back_unbind;
-       bi->bi_op_search = perl_back_search;
-       bi->bi_op_compare = perl_back_compare;
-       bi->bi_op_modify = perl_back_modify;
-       bi->bi_op_modrdn = perl_back_modrdn;
-       bi->bi_op_add = perl_back_add;
-       bi->bi_op_delete = perl_back_delete;
-       bi->bi_op_abandon = 0;
-
-       bi->bi_acl_group = 0;
-
-       bi->bi_connection_init = 0;
-       bi->bi_connection_destroy = 0;
-
-       return 0;
-}
-               
-int
-perl_back_open(
-       BackendInfo     *bi
-)
-{
-       ldap_pvt_thread_mutex_init( &perl_interpreter_mutex );
-       return 0;
-}
-
-int
-perl_back_db_init(
-       Backend *be
-)
-{
-       be->be_private = (PerlBackend *) ch_malloc( sizeof(PerlBackend) );
-       memset( be->be_private, 0, sizeof(PerlBackend));
-
-       Debug( LDAP_DEBUG_TRACE, "perl backend db init\n", 0, 0, 0 );
-
-       return 0;
-}
-
diff --git a/servers/slapd/back-perl/modify.c b/servers/slapd/back-perl/modify.c
deleted file mode 100644 (file)
index 028b42e..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/* $OpenLDAP$ */
-/*
- *      Copyright 1999, John C. Quillan, All rights reserved.
- *
- *      Redistribution and use in source and binary forms are permitted only
- *      as authorized by the OpenLDAP Public License.  A copy of this
- *      license is available at http://www.OpenLDAP.org/license.html or
- *      in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-/* #include <ac/types.h>
-       #include <ac/socket.h>
-*/
-
-#include <EXTERN.h>
-#include <perl.h>
-
-#include "slap.h"
-#include "perl_back.h"
-
-int
-perl_back_modify(
-       Backend *be,
-       Connection      *conn,
-       Operation       *op,
-       char    *dn,
-       LDAPModList     *modlist
-)
-{
-       char test[500];
-       int return_code;
-       int count;
-       int i;
-       int err = 0;
-       char *matched = NULL, *info = NULL;
-
-       PerlBackend *perl_back = (PerlBackend *)be->be_private;
-
-       ldap_pvt_thread_mutex_lock( &perl_interpreter_mutex );  
-
-       {
-               dSP; ENTER; SAVETMPS;
-               
-               PUSHMARK(sp);
-               XPUSHs( perl_back->pb_obj_ref );
-               XPUSHs(sv_2mortal(newSVpv( dn , 0)));
-
-               for (; modlist != NULL; modlist = modlist->ml_next ) {
-                       LDAPMod *mods = &modlist->ml_mod;
-
-                       switch ( mods->mod_op & ~LDAP_MOD_BVALUES ) {
-                       case LDAP_MOD_ADD:
-                               XPUSHs(sv_2mortal(newSVpv("ADD", 0 )));
-                               break;
-                               
-                       case LDAP_MOD_DELETE:
-                               XPUSHs(sv_2mortal(newSVpv("DELETE", 0 )));
-                               break;
-                               
-                       case LDAP_MOD_REPLACE:
-                               XPUSHs(sv_2mortal(newSVpv("REPLACE", 0 )));
-                               break;
-                       }
-
-                       
-                       XPUSHs(sv_2mortal(newSVpv( mods->mod_type, 0 )));
-
-                       for ( i = 0;
-                               mods->mod_bvalues != NULL && mods->mod_bvalues[i] != NULL;
-                               i++ )
-                       {
-                               XPUSHs(sv_2mortal(newSVpv( mods->mod_bvalues[i]->bv_val, 0 )));
-                       }
-               }
-
-               PUTBACK;
-
-               count = perl_call_method("modify", G_SCALAR);
-
-               SPAGAIN;
-
-               if (count != 1) {
-                       croak("Big trouble in back_search\n");
-               }
-                                                        
-               return_code = POPi;
-
-               PUTBACK; FREETMPS; LEAVE;
-       }
-
-       ldap_pvt_thread_mutex_unlock( &perl_interpreter_mutex );
-
-       if( return_code != 0 ) {
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-
-       } else {
-               send_ldap_result( conn, op, LDAP_SUCCESS,
-                       NULL, NULL, NULL, NULL );
-       }
-
-       Debug( LDAP_DEBUG_ANY, "Perl MODIFY\n", 0, 0, 0 );
-       return( 0 );
-}
-
diff --git a/servers/slapd/back-perl/modrdn.c b/servers/slapd/back-perl/modrdn.c
deleted file mode 100644 (file)
index d747014..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/* $OpenLDAP$ */
-/*
- *      Copyright 1999, John C. Quillan, All rights reserved.
- *
- *      Redistribution and use in source and binary forms are permitted only
- *      as authorized by the OpenLDAP Public License.  A copy of this
- *      license is available at http://www.OpenLDAP.org/license.html or
- *      in file LICENSE in the top-level directory of the distribution.
- */
-
-/*
- * LDAP v3 newSuperior support.
- *
- * Copyright 1999, Juan C. Gomez, All rights reserved.
- * This software is not subject to any license of Silicon Graphics 
- * Inc. or Purdue University.
- *
- * Redistribution and use in source and binary forms are permitted
- * without restriction or fee of any kind as long as this notice
- * is preserved.
- *
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-/*     #include <ac/types.h>
-       #include <ac/socket.h>
-*/
-
-#include <EXTERN.h>
-#include <perl.h>
-
-#include "slap.h"
-#include "perl_back.h"
-
-int
-perl_back_modrdn(
-       Backend *be,
-       Connection      *conn,
-       Operation       *op,
-       char    *dn,
-       char    *newrdn,
-       int             deleteoldrdn,
-       char    *newSuperior
-)
-{
-       int len;
-       int count;
-       int return_code;
-
-       PerlBackend *perl_back = (PerlBackend *) be->be_private;
-
-       ldap_pvt_thread_mutex_lock( &perl_interpreter_mutex );  
-
-       {
-               dSP; ENTER; SAVETMPS;
-               
-               PUSHMARK(sp) ;
-               XPUSHs( perl_back->pb_obj_ref );
-               XPUSHs(sv_2mortal(newSVpv( dn , 0 )));
-               XPUSHs(sv_2mortal(newSVpv( newrdn , 0 )));
-               XPUSHs(sv_2mortal(newSViv( deleteoldrdn )));
-               if ( newSuperior != NULL ) {
-                       XPUSHs(sv_2mortal(newSVpv( newSuperior , 0 )));
-               }
-               PUTBACK ;
-
-               count = perl_call_method("modrdn", G_SCALAR);
-
-               SPAGAIN ;
-
-               if (count != 1) {
-                       croak("Big trouble in back_search\n") ;
-               }
-                                                        
-               return_code = POPi;
-
-               PUTBACK; FREETMPS; LEAVE ;
-       }
-
-       ldap_pvt_thread_mutex_unlock( &perl_interpreter_mutex );
-       
-       if( return_code != 0 ) {
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-
-       } else {
-               send_ldap_result( conn, op, LDAP_SUCCESS,
-                       NULL, NULL, NULL, NULL );
-       }
-
-       Debug( LDAP_DEBUG_ANY, "Perl MODRDN\n", 0, 0, 0 );
-       return( 0 );
-}
-
-
diff --git a/servers/slapd/back-perl/perl_back.h b/servers/slapd/back-perl/perl_back.h
deleted file mode 100644 (file)
index 6e53a7f..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* $OpenLDAP$ */
-#ifndef PERL_BACK_H
-#define PERL_BACK_H 1
-
-LDAP_BEGIN_DECL
-
-/*
- */
-#define EVAL_BUF_SIZE 500
-
-extern PerlInterpreter *perl_interpreter;
-extern ldap_pvt_thread_mutex_t  perl_interpreter_mutex;
-
-typedef struct perl_backend_instance {
-  char *pb_module_name;
-  SV   *pb_obj_ref;
-} PerlBackend;
-
-LDAP_END_DECL
-
-#include "external.h"
-
-#endif
diff --git a/servers/slapd/back-perl/search.c b/servers/slapd/back-perl/search.c
deleted file mode 100644 (file)
index 0feb288..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/* $OpenLDAP$ */
-/*
- *      Copyright 1999, John C. Quillan, All rights reserved.
- *
- *      Redistribution and use in source and binary forms are permitted only
- *      as authorized by the OpenLDAP Public License.  A copy of this
- *      license is available at http://www.OpenLDAP.org/license.html or
- *      in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-/*     #include <ac/types.h>
-       #include <ac/socket.h>
-*/
-
-#include <EXTERN.h>
-#include <perl.h>
-
-#include "slap.h"
-#include "perl_back.h"
-
-/**********************************************************
- *
- * Search
- *
- **********************************************************/
-int
-perl_back_search(
-       Backend *be,
-       Connection *conn,
-       Operation *op,
-       char *base,
-       int scope,
-       int deref,
-       int sizelimit,
-       int timelimit,
-       Filter *filter,
-       char *filterstr,
-       char **attrs,
-       int attrsonly
-       )
-{
-       char test[500];
-       int count ;
-       int err = 0;
-       char *matched = NULL, *info = NULL;
-       PerlBackend *perl_back = (PerlBackend *)be->be_private;
-       Entry   *e;
-       char *buf;
-       int i;
-       int return_code;
-
-       ldap_pvt_thread_mutex_lock( &perl_interpreter_mutex );  
-
-       {
-               dSP; ENTER; SAVETMPS;
-
-               PUSHMARK(sp) ;
-               XPUSHs( perl_back->pb_obj_ref );
-               XPUSHs(sv_2mortal(newSVpv( filterstr , 0)));
-               XPUSHs(sv_2mortal(newSViv( sizelimit )));
-               XPUSHs(sv_2mortal(newSViv( timelimit )));
-               XPUSHs(sv_2mortal(newSViv( attrsonly )));
-
-               for ( i = 0; attrs != NULL && attrs[i] != NULL; i++ ) {
-                       XPUSHs(sv_2mortal(newSVpv( attrs[i] , 0)));
-               }
-               PUTBACK;
-
-               count = perl_call_method("search", G_ARRAY );
-
-               SPAGAIN;
-
-               if (count < 1) {
-                       croak("Big trouble in back_search\n") ;
-               }
-
-               if ( count > 1 ) {
-                                                        
-                       for ( i = 1; i < count; i++ ) {
-
-                               buf = POPp;
-
-                               if ( (e = str2entry( buf )) == NULL ) {
-                                       Debug( LDAP_DEBUG_ANY, "str2entry(%s) failed\n", buf, 0, 0 );
-
-                               } else {
-                                       send_search_entry( be, conn, op,
-                                               e, attrs, attrsonly, NULL );
-                                                        
-                                       entry_free( e );
-                               }
-                       }
-               }
-
-               /*
-                * We grab the return code last because the stack comes
-                * from perl in reverse order. 
-                *
-                * ex perl: return ( 0, $res_1, $res_2 );
-                *
-                * ex stack: <$res_2> <$res_1> <0>
-                */
-
-               return_code = POPi;
-
-
-
-               PUTBACK; FREETMPS; LEAVE;
-       }
-
-       ldap_pvt_thread_mutex_unlock( &perl_interpreter_mutex );        
-
-       if( return_code != 0 ) {
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, NULL, NULL, NULL );
-
-       } else {
-               send_ldap_result( conn, op, LDAP_SUCCESS,
-                       NULL, NULL, NULL, NULL );
-       }
-}
-
diff --git a/servers/slapd/back-perl/unbind.c b/servers/slapd/back-perl/unbind.c
deleted file mode 100644 (file)
index a79f906..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* $OpenLDAP$ */
-/*
- *   Copyright 1999, John C. Quillan, All rights reserved.
- *
- *   Redistribution and use in source and binary forms are permitted only
- *   as authorized by the OpenLDAP Public License.  A copy of this
- *   license is available at http://www.OpenLDAP.org/license.html or
- *   in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
- /* init.c - initialize shell backend */
-  
-#include <stdio.h>
-/*     #include <ac/types.h>
-       #include <ac/socket.h>
-*/
-
-#include <EXTERN.h>
-#include <perl.h>
-
-#include "slap.h"
-#include "perl_back.h"
-
-
-/**********************************************************
- *
- * UnBind
- *
- **********************************************************/
-int
-perl_back_unbind(
-       Backend *be,
-       Connection *conn,
-       Operation *op
-)
-{
-       Debug( LDAP_DEBUG_TRACE, "Perl UNBIND\n", 0, 0, 0 );
-       return 0;
-}
-
index e0c052cc3d26059373147da9a6be550df899d4e0..d7f85df220a0d22e80ff0bcf85cdbd041e849901 100644 (file)
@@ -1,4 +1,6 @@
 # $OpenLDAP$
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 
 SRCS   = init.c config.c fork.c search.c bind.c unbind.c add.c delete.c \
                modify.c modrdn.c compare.c abandon.c result.c
@@ -16,7 +18,6 @@ LIBBASE = back_shell
 
 XINCPATH = -I.. -I$(srcdir)/..
 XDEFS = $(MODULES_CPPFLAGS)
-XLDFLAGS = $(MODULES_LDFLAGS)
 
 all-local-lib: ../.backend
 
index 4f2932793ecdfa2b16a027de2ed14d760e179a4c..620b2939d4fce40d0114111fcf0dbd1c2e062f44 100644 (file)
@@ -1,5 +1,9 @@
 /* abandon.c - shell backend abandon function */
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 
 #include "portable.h"
 
index 293f3a8709a3f326010a0471ffef3ed6a630833e..b2c7b80b950775710b98cf40b28310461e24f70c 100644 (file)
@@ -1,5 +1,9 @@
 /* add.c - shell backend add function */
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 
 #include "portable.h"
 
index 44bd6cd5e2ca9ea06f9feb7663deceebd9cd3b49..aa5ef04ef9e81099ceb8662a2ab3285f5417d50a 100644 (file)
@@ -1,5 +1,9 @@
 /* bind.c - shell backend bind function */
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 
 #include "portable.h"
 
@@ -16,9 +20,9 @@ shell_back_bind(
     Backend            *be,
     Connection         *conn,
     Operation          *op,
-    char               *dn,
+    const char         *dn,
+    const char         *ndn,
     int                        method,
-       char            *mech,
     struct berval      *cred,
        char            **edn
 )
index 940f213fc5a927a8ff8681a3922344a06753f256..c7c85f8d68b16df19bcff462cbb5f9fa147ea7c8 100644 (file)
@@ -1,5 +1,9 @@
 /* compare.c - shell backend compare function */
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 
 #include "portable.h"
 
@@ -16,8 +20,9 @@ shell_back_compare(
     Backend    *be,
     Connection *conn,
     Operation  *op,
-    char       *dn,
-    Ava                *ava
+    const char *dn,
+    const char *ndn,
+    AttributeAssertion *ava
 )
 {
        struct shellinfo        *si = (struct shellinfo *) be->be_private;
@@ -36,12 +41,19 @@ shell_back_compare(
                return( -1 );
        }
 
+       /*
+        * FIX ME:  This should use LDIF routines so that binary
+        *      values are properly dealt with
+        */
+
        /* write out the request to the compare process */
        fprintf( wfp, "COMPARE\n" );
        fprintf( wfp, "msgid: %ld\n", (long) op->o_msgid );
        print_suffixes( wfp, be );
        fprintf( wfp, "dn: %s\n", dn );
-       fprintf( wfp, "%s: %s\n", ava->ava_type, ava->ava_value.bv_val );
+       fprintf( wfp, "%s: %s\n",
+               ava->aa_desc->ad_cname->bv_val,
+               ava->aa_value->bv_val /* could be binary! */ );
        fclose( wfp );
 
        /* read in the result and send it along */
index 03c7b7da76516ccd5251ab94a0ba29746eb05c73..5fa4876a357a57f7ade3a09fa24d64cd46b287c0 100644 (file)
@@ -1,5 +1,9 @@
 /* config.c - shell backend configuration file routine */
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 
 #include "portable.h"
 
index 27f67a2c6375de5516df322355675da3c396bcfb..feb737fe35314eb37b93384eb8b93871fb057f48 100644 (file)
@@ -1,5 +1,9 @@
 /* delete.c - shell backend delete function */
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 
 #include "portable.h"
 
@@ -16,7 +20,8 @@ shell_back_delete(
     Backend    *be,
     Connection *conn,
     Operation  *op,
-    char       *dn
+    const char *dn,
+    const char *ndn
 )
 {
        struct shellinfo        *si = (struct shellinfo *) be->be_private;
index 64c2dce5bcc5436c7e5ccabe190e4576b49eada1..0ace4657f7db1b4c32ded64e9249432c08ed5cd7 100644 (file)
@@ -1,4 +1,8 @@
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 #ifndef _SHELL_EXTERNAL_H
 #define _SHELL_EXTERNAL_H
 
@@ -17,7 +21,7 @@ extern int    shell_back_db_config LDAP_P(( BackendDB *bd,
 
 extern int shell_back_bind LDAP_P(( BackendDB *bd,
        Connection *conn, Operation *op,
-       char *dn, int method, char* mech,
+       const char *dn, const char *ndn, int method,
        struct berval *cred, char** edn ));
 
 extern int     shell_back_unbind LDAP_P(( BackendDB *bd,
@@ -25,27 +29,33 @@ extern int  shell_back_unbind LDAP_P(( BackendDB *bd,
 
 extern int     shell_back_search LDAP_P(( BackendDB *bd,
        Connection *conn, Operation *op,
-       char *base, int scope, int deref, int sizelimit, int timelimit,
-       Filter *filter, char *filterstr, char **attrs, int attrsonly ));
+       const char *base, const char *nbase,
+       int scope, int deref, int sizelimit, int timelimit,
+       Filter *filter, const char *filterstr,
+       char **attrs, int attrsonly ));
 
 extern int     shell_back_compare LDAP_P((BackendDB *bd,
        Connection *conn, Operation *op,
-       char *dn, Ava   *ava ));
+       const char *dn, const char *ndn,
+       AttributeAssertion *ava ));
 
 extern int     shell_back_modify LDAP_P(( BackendDB *bd,
        Connection *conn, Operation *op,
-       char *dn, LDAPModList *ml ));
+       const char *dn, const char *ndn,
+       Modifications *ml ));
 
 extern int     shell_back_modrdn LDAP_P(( BackendDB *bd,
        Connection *conn, Operation *op,
-       char *dn, char*newrdn, int deleteoldrdn,
-        char *newSuperior ));
+       const char *dn, const char *ndn,
+       const char *newrdn, int deleteoldrdn,
+       const char *newSuperior ));
 
 extern int     shell_back_add LDAP_P(( BackendDB *bd,
        Connection *conn, Operation *op, Entry *e ));
 
 extern int     shell_back_delete LDAP_P(( BackendDB *bd,
-       Connection *conn, Operation *op, char *dn ));
+       Connection *conn, Operation *op,
+       const char *dn, const char *ndn ));
 
 extern int     shell_back_abandon LDAP_P(( BackendDB *bd,
        Connection *conn, Operation *op, int msgid ));
index 34adf8b5a33e4cdd693b1b08a9a65c4100af65a7..ebe44be45c57844a3d387eb45d21f928ef5280a6 100644 (file)
@@ -1,5 +1,9 @@
 /* fork.c - fork and exec a process, connecting stdin/out w/pipes */
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 
 #include "portable.h"
 
index 57c3742c4eae7c6c635b6272f88f7ac8074ca363..cb88e851f00b1e18af73d11478cad37ddf8810fe 100644 (file)
@@ -1,5 +1,9 @@
 /* init.c - initialize shell backend */
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 
 #include "portable.h"
 
@@ -15,7 +19,7 @@
 int back_shell_LTX_init_module(int argc, char *argv[]) {
     BackendInfo bi;
 
-    memset( &bi, 0, sizeof(bi) );
+    memset( &bi, '\0', sizeof(bi) );
     bi.bi_type = "shell";
     bi.bi_init = shell_back_initialize;
 
@@ -51,8 +55,16 @@ shell_back_initialize(
        bi->bi_op_delete = shell_back_delete;
        bi->bi_op_abandon = shell_back_abandon;
 
+       bi->bi_extended = 0;
+
        bi->bi_acl_group = 0;
 
+#ifdef HAVE_CYRUS_SASL
+       bi->bi_sasl_authorize = 0;
+       bi->bi_sasl_getsecret = 0;
+       bi->bi_sasl_putsecret = 0;
+#endif /* HAVE_CYRUS_SASL */
+
        bi->bi_connection_init = 0;
        bi->bi_connection_destroy = 0;
 
index 154bd2a6eb5c15cfbcae6d9e26949f6b5030f9a0..4d97851eaba2b0d9c273418a6721056201188e70 100644 (file)
@@ -1,5 +1,9 @@
 /* modify.c - shell backend modify function */
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 
 #include "portable.h"
 
@@ -16,10 +20,12 @@ shell_back_modify(
     Backend    *be,
     Connection *conn,
     Operation  *op,
-    char       *dn,
-    LDAPModList        *ml
+    const char *dn,
+    const char *ndn,
+    Modifications      *ml
 )
 {
+       Modification *mod;
        struct shellinfo        *si = (struct shellinfo *) be->be_private;
        FILE                    *rfp, *wfp;
        int                     i;
@@ -42,25 +48,30 @@ shell_back_modify(
        fprintf( wfp, "msgid: %ld\n", (long) op->o_msgid );
        print_suffixes( wfp, be );
        fprintf( wfp, "dn: %s\n", dn );
-       for ( ; ml != NULL; ml = ml->ml_next ) {
-               switch ( ml->ml_op & ~LDAP_MOD_BVALUES ) {
+       for ( ; ml != NULL; ml = ml->sml_next ) {
+               mod = &ml->sml_mod;
+
+               /* FIXME: should use LDIF routines to deal with binary data */
+
+               switch ( mod->sm_op ) {
                case LDAP_MOD_ADD:
-                       fprintf( wfp, "add: %s\n", ml->ml_type );
+                       fprintf( wfp, "add: %s\n", mod->sm_desc->ad_cname->bv_val );
                        break;
 
                case LDAP_MOD_DELETE:
-                       fprintf( wfp, "delete: %s\n", ml->ml_type );
+                       fprintf( wfp, "delete: %s\n", mod->sm_desc->ad_cname->bv_val );
                        break;
 
                case LDAP_MOD_REPLACE:
-                       fprintf( wfp, "replace: %s\n", ml->ml_type );
+                       fprintf( wfp, "replace: %s\n", mod->sm_desc->ad_cname->bv_val );
                        break;
                }
 
-               for ( i = 0; ml->ml_bvalues != NULL && ml->ml_bvalues[i]
-                   != NULL; i++ ) {
-                       fprintf( wfp, "%s: %s\n", ml->ml_type,
-                           ml->ml_bvalues[i]->bv_val );
+               if( mod->sm_bvalues != NULL ) {
+                       for ( i = 0; mod->sm_bvalues[i] != NULL; i++ ) {
+                               fprintf( wfp, "%s: %s\n", mod->sm_desc->ad_cname->bv_val,
+                                       mod->sm_bvalues[i]->bv_val /* binary! */ );
+                       }
                }
        }
        fclose( wfp );
@@ -69,5 +80,4 @@ shell_back_modify(
        read_and_send_results( be, conn, op, rfp, NULL, 0 );
        fclose( rfp );
        return( 0 );
-
 }
index 1df37d579c90b5609a418d3b3b513278eda0fc2a..ec831f1ce0fa386a119a4b4321c10fc378e0dc7e 100644 (file)
@@ -1,5 +1,9 @@
 /* modrdn.c - shell backend modrdn function */
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 
 /*
  * LDAP v3 newSuperior support.
@@ -29,10 +33,11 @@ shell_back_modrdn(
     Backend    *be,
     Connection *conn,
     Operation  *op,
-    char       *dn,
-    char       *newrdn,
+    const char *dn,
+    const char *ndn,
+    const char *newrdn,
     int                deleteoldrdn,
-    char       *newSuperior
+    const char *newSuperior
 )
 {
        struct shellinfo        *si = (struct shellinfo *) be->be_private;
index 4d9f39c2f557b093fe63952e874ee4790c680604..113439b62a8eee28d18f73c2451164bed821a324 100644 (file)
@@ -1,5 +1,9 @@
 /* result.c - shell backend result reading function */
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 
 #include "portable.h"
 
@@ -43,8 +47,10 @@ read_and_send_results(
                }
                len = strlen( line );
                while ( bp + len - buf > bsize ) {
+                       size_t offset = bp - buf;
                        bsize += BUFSIZ;
                        buf = (char *) ch_realloc( buf, bsize );
+                       bp = &buf[offset];
                }
                strcpy( bp, line );
                bp += len;
index b2b6587719ba9fd30fa4fcebb6d4190d7a6da487..15560870c8783e0ddec7e5be1fb84af8badd6b91 100644 (file)
@@ -1,5 +1,9 @@
 /* search.c - shell backend search function */
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 
 #include "portable.h"
 
@@ -16,13 +20,14 @@ shell_back_search(
     Backend    *be,
     Connection *conn,
     Operation  *op,
-    char       *base,
+    const char *base,
+    const char *nbase,
     int                scope,
     int                deref,
     int                size,
     int                time,
     Filter     *filter,
-    char       *filterstr,
+    const char *filterstr,
     char       **attrs,
     int                attrsonly
 )
index 4defa4ba6531f4878d2ba8193f24b268974030bc..864ab22a3aa8084f5ca416c476ecd62fe0657e6c 100644 (file)
@@ -1,4 +1,7 @@
-referral       ldap://ldap.itd.umich.edu
+# $OpenLDAP$
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+
 database       shell
-suffix         "o=university of michigan, c=us"
+suffix         "dc=openldap,dc=org"
 search         /usr/local/etc/searchexample.sh
index 26b70fefbd39ebf75758749cabe635098f495fa4..c0489d67d6f722583f58c8100bef6d8c6c307a02 100644 (file)
@@ -1,4 +1,7 @@
-#!/bin/sh
+#! /bin/sh
+# $OpenLDAP$
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 
 while [ 1 ]; do
        read TAG VALUE
@@ -25,6 +28,8 @@ sleep 60
 if [ $? = 0 ]; then
        echo $PWLINE | awk -F: '{
                printf("dn: cn=%s,%s\n", $1, base);
+               printf("objectclass: top\n");
+               printf("objectclass: person\n");
                printf("cn: %s\n", $1);
                printf("cn: %s\n", $5);
                printf("sn: %s\n", $1);
index 573f485e8d2b4cf79049cec3c6f0ff9c115170b5..bb72f0587fb88964ebc2378e50e77bad28c7f09d 100644 (file)
@@ -1,5 +1,9 @@
 /* shell.h - shell backend header file */
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 
 #ifndef SLAPD_SHELL_H
 #define SLAPD_SHELL_H
index ca091da4361990c75f316340cf8d4efddb15f420..8cbd1116b988d21785f45ee85efda9435aa92aca 100644 (file)
@@ -1,5 +1,9 @@
 /* unbind.c - shell backend unbind function */
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 
 #include "portable.h"
 
diff --git a/servers/slapd/back-tcl/Makefile.in b/servers/slapd/back-tcl/Makefile.in
deleted file mode 100644 (file)
index 6a56540..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-# $OpenLDAP$
-########################################################################### 
-# 
-# Copyright 1999, Ben Collins <bcollins@debian.org>, All rights reserved.
-# 
-# Redistribution and use in source and binary forms are permitted only
-# as authorized by the OpenLDAP Public License.  A copy of this
-# license is available at http://www.OpenLDAP.org/license.html or
-# in file LICENSE in the top-level directory of the distribution.
-# 
-##########################################################################
-
-SRCS   = tcl_init.c tcl_search.c tcl_close.c tcl_config.c tcl_bind.c \
-       tcl_unbind.c tcl_compare.c tcl_modify.c tcl_add.c tcl_modrdn.c \
-       tcl_delete.c tcl_abandon.c tcl_util.c
-OBJS   = tcl_init.lo tcl_search.lo tcl_close.lo tcl_config.lo tcl_bind.lo \
-       tcl_unbind.lo tcl_compare.lo tcl_modify.lo tcl_add.lo tcl_modrdn.lo \
-       tcl_delete.lo tcl_abandon.lo tcl_util.lo
-
-LDAP_INCDIR= ../../../include       
-LDAP_LIBDIR= ../../../libraries
-
-BUILD_OPT = "--enable-tcl"
-BUILD_MOD = @BUILD_TCL@
-LINKAGE = @BUILD_TCL_DYNAMIC@
-
-LIBBASE = back_tcl
-
-XDEFS = $(MODULES_CPPFLAGS)
-XLDFLAGS = $(MODULES_LDFLAGS)
-XINCPATH = -I.. -I$(srcdir)/..
-
-all-local-lib: ../.backend
-
-../.backend: lib$(LIBBASE).a
-       @touch $@
-
diff --git a/servers/slapd/back-tcl/external.h b/servers/slapd/back-tcl/external.h
deleted file mode 100644 (file)
index ece4c51..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/* $OpenLDAP$ */
-
-#ifndef _TCL_EXTERNAL_H
-#define _TCL_EXTERNAL_H
-
-LDAP_BEGIN_DECL
-
-extern int tcl_back_initialize LDAP_P ((BackendInfo * bi));
-extern int tcl_back_open LDAP_P ((BackendInfo * bi));
-extern int tcl_back_close LDAP_P ((BackendInfo * bi));
-extern int tcl_back_destroy LDAP_P ((BackendInfo * bi));
-
-extern int tcl_back_db_init LDAP_P ((BackendDB * bd));
-extern int tcl_back_db_open LDAP_P ((BackendDB * bd));
-extern int tcl_back_db_close LDAP_P ((BackendDB * bd));
-extern int tcl_back_db_destroy LDAP_P ((BackendDB * bd));
-
-extern int tcl_back_db_config LDAP_P ((BackendDB * bd,
-               const char *fname, int lineno, int argc, char **argv));
-
-extern int tcl_back_bind LDAP_P ((BackendDB * bd,
-               Connection * conn, Operation * op,
-               char *dn, int method, char *mech,
-               struct berval * cred, char **edn));
-
-extern int tcl_back_unbind LDAP_P ((BackendDB * bd,
-               Connection * conn, Operation * op));
-
-extern int tcl_back_search LDAP_P ((BackendDB * bd,
-               Connection * conn, Operation * op,
-               char *base, int scope, int deref, int sizelimit, int timelimit,
-               Filter * filter, char *filterstr, char **attrs, int attrsonly));
-
-extern int tcl_back_compare LDAP_P ((BackendDB * bd,
-               Connection * conn, Operation * op,
-               char *dn, Ava * ava));
-
-extern int tcl_back_modify LDAP_P ((BackendDB * bd,
-               Connection * conn, Operation * op,
-               char *dn, LDAPModList * ml));
-
-extern int tcl_back_modrdn LDAP_P ((BackendDB * bd,
-               Connection * conn, Operation * op,
-               char *dn, char *newrdn, int deleteoldrdn,
-               char *newSuperior));
-
-extern int tcl_back_add LDAP_P ((BackendDB * bd,
-               Connection * conn, Operation * op, Entry * e));
-
-extern int tcl_back_delete LDAP_P ((BackendDB * bd,
-               Connection * conn, Operation * op, char *dn));
-
-extern int tcl_back_abandon LDAP_P ((BackendDB * bd,
-               Connection * conn, Operation * op, int msgid));
-
-LDAP_END_DECL
-
-#endif /* _TCL_EXTERNAL_H */
diff --git a/servers/slapd/back-tcl/tcl_abandon.c b/servers/slapd/back-tcl/tcl_abandon.c
deleted file mode 100644 (file)
index 5fcf8c5..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/* $OpenLDAP$ */
-/* abandon.c - tcl abandon routine
- *
- * Copyright 1999, Ben Collins <bcollins@debian.org>, All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted only
- * as authorized by the OpenLDAP Public License.  A copy of this
- * license is available at http://www.OpenLDAP.org/license.html or
- * in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include "slap.h"
-#include "tcl_back.h"
-
-int
-tcl_back_abandon (
-       Backend * be,
-       Connection * conn,
-       Operation * op,
-       int msgid
-)
-{
-       char *suf_tcl, *results, *command;
-       int i, code, err = 0;
-       struct tclinfo *ti = (struct tclinfo *) be->be_private;
-
-       if (ti->ti_abandon == NULL) {
-               return (-1);
-       }
-
-       for (i = 0; be->be_suffix[i] != NULL; i++);
-       suf_tcl = Tcl_Merge (i, be->be_suffix);
-
-       command = (char *) ch_malloc (strlen (ti->ti_abandon) + strlen (suf_tcl)
-               + 20);
-       sprintf (command, "%s ABANDON {%ld} {%s}",
-               ti->ti_abandon, op->o_msgid, suf_tcl);
-       Tcl_Free (suf_tcl);
-
-       ldap_pvt_thread_mutex_lock (&tcl_interpreter_mutex);
-       code = Tcl_GlobalEval (ti->ti_ii->interp, command);
-       results = (char *) ch_strdup (ti->ti_ii->interp->result);
-       ldap_pvt_thread_mutex_unlock (&tcl_interpreter_mutex);
-       free (command);
-
-       if (code != TCL_OK) {
-               err = LDAP_OPERATIONS_ERROR;
-               Debug (LDAP_DEBUG_SHELL, "tcl_abandon_error: %s\n", results,
-                       0, 0);
-       }
-
-       free (results);
-       return (err);
-}
diff --git a/servers/slapd/back-tcl/tcl_add.c b/servers/slapd/back-tcl/tcl_add.c
deleted file mode 100644 (file)
index e2d324b..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/* $OpenLDAP$ */
-/* add.c - tcl add routine
- *
- * Copyright 1999, Ben Collins <bcollins@debian.org>, All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted only
- * as authorized by the OpenLDAP Public License.  A copy of this
- * license is available at http://www.OpenLDAP.org/license.html or
- * in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include "slap.h"
-#include "tcl_back.h"
-
-int
-tcl_back_add (
-       Backend * be,
-       Connection * conn,
-       Operation * op,
-       Entry * e
-)
-{
-       char *command, *suf_tcl, *entrystr, *results;
-       int i, code, err = 0;
-       struct tclinfo *ti = (struct tclinfo *) be->be_private;
-
-       if (ti->ti_add == NULL) {
-               send_ldap_result (conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
-                       "add not implemented", NULL, NULL );
-               return (-1);
-       }
-
-       for (i = 0; be->be_suffix[i] != NULL; i++);
-       suf_tcl = Tcl_Merge (i, be->be_suffix);
-
-       entrystr = tcl_clean_entry (e);
-
-       command = (char *) ch_malloc (strlen (ti->ti_add) + strlen
-               (suf_tcl) +
-               strlen (entrystr) + 32);
-       sprintf (command, "%s ADD {%ld} {%s} {%s}",
-               ti->ti_add, op->o_msgid, suf_tcl, entrystr);
-       Tcl_Free (suf_tcl);
-       free (entrystr);
-
-       ldap_pvt_thread_mutex_lock (&tcl_interpreter_mutex);
-       code = Tcl_GlobalEval (ti->ti_ii->interp, command);
-       results = (char *) ch_strdup (ti->ti_ii->interp->result);
-       ldap_pvt_thread_mutex_unlock (&tcl_interpreter_mutex);
-       free (command);
-
-       if (code != TCL_OK) {
-               err = LDAP_OPERATIONS_ERROR;
-               Debug (LDAP_DEBUG_SHELL, "tcl_add_error: %s\n", results, 0, 0);
-       } else {
-               interp_send_results (be, conn, op, results, NULL, 0);
-       }
-
-       if (err != LDAP_SUCCESS)
-               send_ldap_result (conn, op, err, NULL,
-                       "internal backend error", NULL, NULL );
-
-       free (results);
-       return (err);
-}
diff --git a/servers/slapd/back-tcl/tcl_back.h b/servers/slapd/back-tcl/tcl_back.h
deleted file mode 100644 (file)
index cba34eb..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/* $OpenLDAP$ */
-/* tcl_back.h - tcl backend header (structs, functions)
- *
- * Copyright 1999, Ben Collins <bcollins@debian.org>, All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted only
- * as authorized by the OpenLDAP Public License.  A copy of this
- * license is available at http://www.OpenLDAP.org/license.html or
- * in file LICENSE in the top-level directory of the distribution.
- */
-
-#include <tcl.h>
-
-#ifndef SLAPD_TCL_H
-#define SLAPD_TCL_H
-
-#include <ldap_cdefs.h>
-#include "external.h"
-
-extern ldap_pvt_thread_mutex_t tcl_interpreter_mutex;
-
-struct i_info {
-       Tcl_Interp *interp;
-       char *name;
-       struct i_info *next;
-       int count;
-};
-
-extern struct i_info *global_i;
-
-struct tclinfo {
-       char *script_path;
-       struct i_info *ti_ii;
-       char *ti_bind;
-       char *ti_unbind;
-       char *ti_search;
-       char *ti_compare;
-       char *ti_modify;
-       char *ti_modrdn;
-       char *ti_add;
-       char *ti_delete;
-       char *ti_abandon;
-};
-
-void readtclscript (char *script, Tcl_Interp * my_tcl);
-char *tcl_clean_entry (Entry * e);
-
-int tcl_ldap_debug (
-       ClientData clientData,
-       Tcl_Interp * interp,
-       int argc,
-       char *argv[]
-);
-
-int interp_send_results (
-       Backend * be,
-       Connection * conn,
-       Operation * op,
-       char *result,
-       char **attrs,
-       int attrsonly
-);
-
-#endif
diff --git a/servers/slapd/back-tcl/tcl_bind.c b/servers/slapd/back-tcl/tcl_bind.c
deleted file mode 100644 (file)
index a26da55..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/* $OpenLDAP$ */
-/* bind.c - tcl bind routines
- *
- * Copyright 1999, Ben Collins <bcollins@debian.org>, All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted only
- * as authorized by the OpenLDAP Public License.  A copy of this
- * license is available at http://www.OpenLDAP.org/license.html or
- * in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include "slap.h"
-#include "tcl_back.h"
-
-int
-tcl_back_bind (
-       Backend * be,
-       Connection * conn,
-       Operation * op,
-       char *dn,
-       int method,
-       char            *mech,
-       struct berval *cred,
-       char **edn
-)
-{
-       char *command, *suf_tcl, *results;
-       int i, code, err = 0;
-       struct tclinfo *ti = (struct tclinfo *) be->be_private;
-
-       *edn = NULL;
-
-       if (ti->ti_bind == NULL) {
-               send_ldap_result (conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
-                       "bind not implemented", NULL, NULL );
-               return (-1);
-       }
-
-       for (i = 0; be->be_suffix[i] != NULL; i++);
-       suf_tcl = Tcl_Merge (i, be->be_suffix);
-
-       command = (char *) ch_malloc (strlen (ti->ti_bind) + strlen
-               (suf_tcl) +
-               strlen (dn) + strlen (cred->bv_val) + 64);
-       sprintf (command, "%s BIND {%ld} {%s} {%s} {%d} {%lu} {%s}",
-               ti->ti_bind, op->o_msgid, suf_tcl, dn, method, cred->bv_len,
-               cred->bv_val);
-       Tcl_Free (suf_tcl);
-
-       ldap_pvt_thread_mutex_lock (&tcl_interpreter_mutex);
-       code = Tcl_GlobalEval (ti->ti_ii->interp, command);
-       results = (char *) ch_strdup (ti->ti_ii->interp->result);
-       ldap_pvt_thread_mutex_unlock (&tcl_interpreter_mutex);
-       free (command);
-
-       if (code != TCL_OK) {
-               err = LDAP_OPERATIONS_ERROR;
-               Debug (LDAP_DEBUG_SHELL, "tcl_bind_error: %s\n", results, 0, 0);
-       } else {
-               err = interp_send_results (be, conn, op, results, NULL, 0);
-       }
-
-       if (err != LDAP_SUCCESS)
-               send_ldap_result (conn, op, err, NULL,
-                       "internal backend error", NULL, NULL );
-
-       free (results);
-       return (err);
-}
diff --git a/servers/slapd/back-tcl/tcl_close.c b/servers/slapd/back-tcl/tcl_close.c
deleted file mode 100644 (file)
index 4fb893a..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/* $OpenLDAP$ */
-/* close.c - tcl close routines
- *
- * Copyright 1999, Ben Collins <bcollins@debian.org>, All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted only
- * as authorized by the OpenLDAP Public License.  A copy of this
- * license is available at http://www.OpenLDAP.org/license.html or
- * in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include "slap.h"
-#include "tcl_back.h"
-
-int
-tcl_back_close (
-       BackendInfo * bi
-)
-{
-       Tcl_DeleteInterp (global_i->interp);
-
-       return (0);
-}
-
-int
-tcl_back_destroy (
-       BackendInfo * bi
-)
-{
-       free (global_i->interp);
-       free (global_i);
-       ldap_pvt_thread_mutex_destroy (&tcl_interpreter_mutex);
-
-       return (0);
-}
-
-int
-tcl_back_db_close (
-       BackendDB * bd
-)
-{
-       struct tclinfo *ti = (struct tclinfo *) bd->be_private;
-       struct i_info *ti_tmp;
-
-       /* Disable the interp and associated struct */
-       ti->ti_ii->count--;
-       if (!ti->ti_ii->count && strcasecmp ("default", ti->ti_ii->name)) {
-               /* no more db's using this and it's not the default */
-               for (ti_tmp = global_i; ti_tmp->next != ti->ti_ii; ti_tmp
-                       = ti_tmp->next);
-               /* This bypasses this interp struct in the global hash */
-               ti_tmp->next = ti->ti_ii->next;
-               Tcl_DeleteInterp (ti->ti_ii->interp);
-       }
-       return (0);
-}
-
-int
-tcl_back_db_destroy (
-       BackendDB * bd
-)
-{
-       struct tclinfo *ti = (struct tclinfo *) bd->be_private;
-
-       /*
-        * Now free up the allocated memory used
-        */
-       ti->ti_ii->count--;
-       if (!ti->ti_ii->count && strcasecmp ("default", ti->ti_ii->name)) {
-               free (ti->ti_ii->interp);
-               free (ti->ti_ii);
-               free (ti);
-       }
-       free (bd->be_private);
-       bd->be_private = NULL;
-
-       return (0);
-}
diff --git a/servers/slapd/back-tcl/tcl_compare.c b/servers/slapd/back-tcl/tcl_compare.c
deleted file mode 100644 (file)
index 06d23f5..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/* $OpenLDAP$ */
-/* compare.c - tcl compare routines
- *
- * Copyright 1999, Ben Collins <bcollins@debian.org>, All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted only
- * as authorized by the OpenLDAP Public License.  A copy of this
- * license is available at http://www.OpenLDAP.org/license.html or
- * in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include "slap.h"
-#include "tcl_back.h"
-
-int
-tcl_back_compare (
-       Backend * be,
-       Connection * conn,
-       Operation * op,
-       char *dn,
-       Ava * ava
-)
-{
-       char *command, *suf_tcl, *results;
-       int i, code, err = 0;
-       struct tclinfo *ti = (struct tclinfo *) be->be_private;
-
-       if (ti->ti_compare == NULL) {
-               send_ldap_result (conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
-                       "compare not implemented", NULL, NULL );
-               return (-1);
-       }
-
-       for (i = 0; be->be_suffix[i] != NULL; i++);
-       suf_tcl = Tcl_Merge (i, be->be_suffix);
-
-       command = (char *) ch_malloc (strlen (ti->ti_compare) +
-               strlen (suf_tcl) + strlen (dn) + strlen (ava->ava_type) +
-               strlen (ava->ava_value.bv_val) + 64);
-       sprintf (command, "%s COMPARE {%ld} {%s} {%s} {%s: %s}",
-               ti->ti_compare, op->o_msgid, suf_tcl, dn, ava->ava_type,
-               ava->ava_value.bv_val);
-       Tcl_Free (suf_tcl);
-
-       ldap_pvt_thread_mutex_lock (&tcl_interpreter_mutex);
-       code = Tcl_GlobalEval (ti->ti_ii->interp, command);
-       results = (char *) ch_strdup (ti->ti_ii->interp->result);
-       ldap_pvt_thread_mutex_unlock (&tcl_interpreter_mutex);
-       free (command);
-
-       if (code != TCL_OK) {
-               err = LDAP_OPERATIONS_ERROR;
-               Debug (LDAP_DEBUG_SHELL, "tcl_compare_error: %s\n", results,
-                       0, 0);
-       } else {
-               interp_send_results (be, conn, op, results, NULL, 0);
-       }
-
-       if (err != LDAP_SUCCESS)
-               send_ldap_result (conn, op, err, NULL,
-                       "internal backend error", NULL, NULL );
-
-       free (results);
-       return (err);
-}
diff --git a/servers/slapd/back-tcl/tcl_config.c b/servers/slapd/back-tcl/tcl_config.c
deleted file mode 100644 (file)
index 64174bc..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/* $OpenLDAP$ */
-/* config.c - tcl backend configuration file routine
- *
- * Copyright 1999, Ben Collins <bcollins@debian.org>, All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted only
- * as authorized by the OpenLDAP Public License.  A copy of this
- * license is available at http://www.OpenLDAP.org/license.html or
- * in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include "slap.h"
-#include "tcl_back.h"
-
-struct i_info *global_i;
-
-int
-tcl_back_db_config (
-       BackendDB * bd,
-       const char *fname,
-       int lineno,
-       int argc,
-       char **argv
-)
-{
-       struct tclinfo *ti = (struct tclinfo *) bd->be_private;
-       int script_loaded = 0;
-
-       if (ti == NULL) {
-               fprintf (stderr,
-                       "%s: line %d: tcl backend info is null!\n", fname,
-                       lineno);
-               return (1);
-       }
-       if (ti->ti_ii == NULL) {
-               ti->ti_ii = global_i;
-       }
-
-       /* Script to load */
-       if (strcasecmp (argv[0], "scriptpath") == 0) {
-               if (argc < 2) {
-                       Debug (LDAP_DEBUG_CONFIG,
-                               "%s: line %d: missing script in \"scriptpath <script>\" line\n",
-                               fname, lineno, 0);
-                       return (1);
-               }
-               ti->script_path = (char *) ch_strdup (argv[1]);
-
-               /* use local interpreter */
-       } else if (strcasecmp (argv[0], "tclrealm") == 0) {
-               struct i_info *ii;
-
-               if (argc < 2) {
-                       Debug (LDAP_DEBUG_CONFIG,
-                               "%s: line %d: missing script in \"tclrealm <name>\" line\n",
-                               fname, lineno, 0);
-                       return (1);
-               }
-               ti->ti_ii = NULL;
-
-               ii = global_i;
-               /* Try to see if it already exists */
-               do {
-                       if (ii != NULL && !strcasecmp (ii->name, argv[1]))
-                               ti->ti_ii = ii;
-                       if (ii->next != NULL)
-                               ii = ii->next;
-               } while (ii->next != NULL);
-
-               if (ti->ti_ii == NULL) {        /* we need to make a new one */
-                       ii->next = (struct i_info *) ch_malloc
-                               (sizeof (struct i_info));
-
-                       ii->next->count = 0;
-                       ii->next->name = (char *) ch_strdup (argv[1]);
-                       ii->next->interp = NULL;
-                       ii->next->next = NULL;
-                       ti->ti_ii = ii->next;
-               }
-
-               /* proc for binds */
-       } else if (strcasecmp (argv[0], "bind") == 0) {
-               if (argc < 2) {
-                       Debug (LDAP_DEBUG_CONFIG,
-                               "%s: line %d: missing proc in \"bind <proc>\" line\n",
-                               fname, lineno, 0);
-                       return (1);
-               }
-               ti->ti_bind = (char *) ch_strdup (argv[1]);
-
-               /* proc for unbinds */
-       } else if (strcasecmp (argv[0], "unbind") == 0) {
-               if (argc < 2) {
-                       Debug (LDAP_DEBUG_CONFIG,
-                               "%s: line %d: missing proc in \"unbind <proc>\" line\n",
-                               fname, lineno, 0);
-                       return (1);
-               }
-               ti->ti_unbind = (char *) ch_strdup (argv[1]);
-
-               /* proc for search */
-       } else if (strcasecmp (argv[0], "search") == 0) {
-               if (argc < 2) {
-                       Debug (LDAP_DEBUG_CONFIG,
-                               "%s: line %d: missing proc in \"search <proc>\" line\n",
-                               fname, lineno, 0);
-                       return (1);
-               }
-               ti->ti_search = (char *) ch_strdup (argv[1]);
-
-               /* proc for compares */
-       } else if (strcasecmp (argv[0], "compare") == 0) {
-               if (argc < 2) {
-                       Debug (LDAP_DEBUG_CONFIG,
-                               "%s: line %d: missing proc in \"compare <proc>\" line\n",
-                               fname, lineno, 0);
-                       return (1);
-               }
-               ti->ti_compare = (char *) ch_strdup (argv[1]);
-
-               /* proc for modify */
-       } else if (strcasecmp (argv[0], "modify") == 0) {
-               if (argc < 2) {
-                       Debug (LDAP_DEBUG_CONFIG,
-                               "%s: line %d: missing proc in \"modify <proc>\" line\n",
-                               fname, lineno, 0);
-                       return (1);
-               }
-               ti->ti_modify = (char *) ch_strdup (argv[1]);
-
-               /* proc for modrdn */
-       } else if (strcasecmp (argv[0], "modrdn") == 0) {
-               if (argc < 2) {
-                       Debug (LDAP_DEBUG_CONFIG,
-                               "%s: line %d: missing proc in \"modrdn <proc>\" line\n",
-                               fname, lineno, 0);
-                       return (1);
-               }
-               ti->ti_modrdn = (char *) ch_strdup (argv[1]);
-
-               /* proc for add */
-       } else if (strcasecmp (argv[0], "add") == 0) {
-               if (argc < 2) {
-                       Debug (LDAP_DEBUG_CONFIG,
-                               "%s: line %d: missing proc in \"add <proc>\" line\n",
-                               fname, lineno, 0);
-                       return (1);
-               }
-               ti->ti_add = (char *) ch_strdup (argv[1]);
-
-               /* proc for delete */
-       } else if (strcasecmp (argv[0], "delete") == 0) {
-               if (argc < 2) {
-                       Debug (LDAP_DEBUG_CONFIG,
-                               "%s: line %d: missing proc in \"delete <proc>\" line\n",
-                               fname, lineno, 0);
-                       return (1);
-               }
-               ti->ti_delete = (char *) ch_strdup (argv[1]);
-
-               /* proc for abandon */
-       } else if (strcasecmp (argv[0], "abandon") == 0) {
-               if (argc < 2) {
-                       Debug (LDAP_DEBUG_CONFIG,
-                               "%s: line %d: missing proc in \"abandon <proc>\" line\n",
-                               fname, lineno, 0);
-                       return (1);
-               }
-               ti->ti_search = (char *) ch_strdup (argv[1]);
-
-       } else {
-               Debug (LDAP_DEBUG_CONFIG,
-                       "Unknown tcl backend config: %s\n", argv[0], 0, 0);
-               return (1);
-       }
-
-       return 0;
-}
diff --git a/servers/slapd/back-tcl/tcl_delete.c b/servers/slapd/back-tcl/tcl_delete.c
deleted file mode 100644 (file)
index 53946ec..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/* $OpenLDAP$ */
-/* delete.c - tcl delete routines
- *
- * Copyright 1999, Ben Collins <bcollins@debian.org>, All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted only
- * as authorized by the OpenLDAP Public License.  A copy of this
- * license is available at http://www.OpenLDAP.org/license.html or
- * in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include "slap.h"
-#include "tcl_back.h"
-
-tcl_back_delete (
-       Backend * be,
-       Connection * conn,
-       Operation * op,
-       char *dn
-)
-{
-       char *command, *suf_tcl, *results;
-       int i, code, err = 0;
-       struct tclinfo *ti = (struct tclinfo *) be->be_private;
-
-       if (ti->ti_delete == NULL) {
-               send_ldap_result (conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
-                       "delete not implemented", NULL, NULL );
-               return (-1);
-       }
-
-       for (i = 0; be->be_suffix[i] != NULL; i++);
-       suf_tcl = Tcl_Merge (i, be->be_suffix);
-
-       command = (char *) ch_malloc (strlen (ti->ti_delete) + strlen (suf_tcl)
-               + strlen (dn) + 64);
-       sprintf (command, "%s DELETE {%ld} {%s} {%s}",
-               ti->ti_delete, op->o_msgid, suf_tcl, dn);
-       Tcl_Free (suf_tcl);
-
-       ldap_pvt_thread_mutex_lock (&tcl_interpreter_mutex);
-       code = Tcl_GlobalEval (ti->ti_ii->interp, command);
-       results = (char *) ch_strdup (ti->ti_ii->interp->result);
-       ldap_pvt_thread_mutex_unlock (&tcl_interpreter_mutex);
-       free (command);
-
-       if (code != TCL_OK) {
-               err = LDAP_OPERATIONS_ERROR;
-               Debug (LDAP_DEBUG_SHELL, "tcl_delete_error: %s\n", results,
-                       0, 0);
-       } else {
-               interp_send_results (be, conn, op, results, NULL, 0);
-       }
-
-       if (err != LDAP_SUCCESS)
-               send_ldap_result (conn, op, err, NULL,
-                       "internal backend error", NULL, NULL );
-
-       free (results);
-       return (err);
-}
diff --git a/servers/slapd/back-tcl/tcl_init.c b/servers/slapd/back-tcl/tcl_init.c
deleted file mode 100644 (file)
index 8acaa3c..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/* $OpenLDAP$ */
-/* tcl_init.c - tcl backend initialization
- *
- * Copyright 1999, Ben Collins <bcollins@debian.org>, All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted only
- * as authorized by the OpenLDAP Public License.  A copy of this
- * license is available at http://www.OpenLDAP.org/license.html or
- * in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "tcl_back.h"
-
-ldap_pvt_thread_mutex_t tcl_interpreter_mutex;
-
-#ifdef SLAPD_TCL_DYNAMIC
-
-void back_tcl_LTX_init_module(int argc, char *argv[]) {
-   BackendInfo bi;
-
-   memset( &bi, 0, sizeof(bi) );
-   bi.bi_type = "tcl";
-   bi.bi_init = tcl_back_initialize;
-
-   backend_add(&bi);
-}
-
-#endif /* SLAPD_TCL_DYNAMIC */
-
-int
-tcl_back_initialize (
-       BackendInfo * bi
-)
-{
-       /* Initialize the global interpreter array */
-       global_i = (struct i_info *) ch_malloc (sizeof (struct i_info));
-
-       global_i->count = 0;
-       global_i->name = "default";
-       global_i->next = NULL;
-       global_i->interp = Tcl_CreateInterp ();
-       Tcl_Init (global_i->interp);
-
-       /* Initialize the global interpreter lock */
-       ldap_pvt_thread_mutex_init (&tcl_interpreter_mutex);
-
-       bi->bi_open = tcl_back_open;
-       bi->bi_config = 0;
-       bi->bi_close = tcl_back_close;
-       bi->bi_destroy = tcl_back_destroy;
-
-       bi->bi_db_init = tcl_back_db_init;
-       bi->bi_db_config = tcl_back_db_config;
-       bi->bi_db_open = tcl_back_db_open;
-       bi->bi_db_close = tcl_back_db_close;
-       bi->bi_db_destroy = tcl_back_db_destroy;
-
-       bi->bi_op_bind = tcl_back_bind;
-       bi->bi_op_unbind = tcl_back_unbind;
-       bi->bi_op_search = tcl_back_search;
-       bi->bi_op_compare = tcl_back_compare;
-       bi->bi_op_modify = tcl_back_modify;
-       bi->bi_op_modrdn = tcl_back_modrdn;
-       bi->bi_op_add = tcl_back_add;
-       bi->bi_op_delete = tcl_back_delete;
-       bi->bi_op_abandon = tcl_back_abandon;
-
-       bi->bi_acl_group = 0;
-
-       bi->bi_connection_init = 0;
-       bi->bi_connection_destroy = 0;
-
-       return 0;
-}
-
-int
-tcl_back_open (
-       BackendInfo * bi
-)
-{
-       /* Initialize the global interpreter array */
-       global_i = (struct i_info *) ch_malloc (sizeof (struct i_info));
-
-       global_i->count = 0;
-       global_i->name = "default";
-       global_i->next = NULL;
-       global_i->interp = Tcl_CreateInterp ();
-       Tcl_Init (global_i->interp);
-
-       /* Initialize the global interpreter lock */
-       ldap_pvt_thread_mutex_init (&tcl_interpreter_mutex);
-
-       return (0);
-}
-
-int
-tcl_back_db_init (
-       Backend * be
-)
-{
-       struct tclinfo *ti;
-
-       ti = (struct tclinfo *) ch_calloc (1, sizeof (struct tclinfo));
-
-       /*
-        * For some reason this causes problems
-        * specifically set to NULL
-        */
-       ti->ti_bind = NULL;
-       ti->ti_unbind = NULL;
-       ti->ti_search = NULL;
-       ti->ti_compare = NULL;
-       ti->ti_modify = NULL;
-       ti->ti_modrdn = NULL;
-       ti->ti_add = NULL;
-       ti->ti_delete = NULL;
-       ti->ti_abandon = NULL;
-
-       be->be_private = ti;
-
-       return ti == NULL;
-}
-
-int
-tcl_back_db_open (
-       BackendDB * bd
-)
-{
-       struct tclinfo *ti = (struct tclinfo *) bd->be_private;
-
-       if (ti->ti_ii->interp == NULL) {        /* we need to make a new one */
-               ti->ti_ii->interp = Tcl_CreateInterp ();
-               Tcl_Init (ti->ti_ii->interp);
-       }
-
-       /* raise that count for the interpreter */
-       ti->ti_ii->count++;
-
-       /* now let's (try to) load the script */
-       readtclscript (ti->script_path, ti->ti_ii->interp);
-
-       /* Intall the debug command */
-       Tcl_CreateCommand (ti->ti_ii->interp, "ldap:debug", &tcl_ldap_debug,
-               NULL, NULL);
-
-       return 0;
-}
diff --git a/servers/slapd/back-tcl/tcl_modify.c b/servers/slapd/back-tcl/tcl_modify.c
deleted file mode 100644 (file)
index e79bc94..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/* $OpenLDAP$ */
-/* modify.c - tcl modify routines
- *
- * Copyright 1999, Ben Collins <bcollins@debian.org>, All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted only
- * as authorized by the OpenLDAP Public License.  A copy of this
- * license is available at http://www.OpenLDAP.org/license.html or
- * in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include "slap.h"
-#include "tcl_back.h"
-
-int
-tcl_back_modify (
-       Backend * be,
-       Connection * conn,
-       Operation * op,
-       char *dn,
-       LDAPModList * modlist
-)
-{
-       char *command, *suf_tcl, *bp, *tcl_mods, *results;
-       int i, code, err = 0, len, bsize;
-       struct tclinfo *ti = (struct tclinfo *) be->be_private;
-
-       if (ti->ti_modify == NULL) {
-               send_ldap_result (conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
-                       "modify not implemented", NULL, NULL );
-               return (-1);
-       }
-
-       for (i = 0; be->be_suffix[i] != NULL; i++);
-       suf_tcl = Tcl_Merge (i, be->be_suffix);
-
-       tcl_mods = (char *) ch_malloc (BUFSIZ);
-       tcl_mods[0] = '\0';
-       bsize = BUFSIZ;
-       bp = tcl_mods;
-
-       for (; modlist != NULL; modlist = modlist->ml_next) {
-               LDAPMod *mods = &modlist->ml_mod;
-               char *op = NULL;
-
-               switch (mods->mod_op & ~LDAP_MOD_BVALUES) {
-               case LDAP_MOD_ADD:
-                       op = "add";
-                       break;
-               case LDAP_MOD_DELETE:
-                       op = "delete";
-                       break;
-               case LDAP_MOD_REPLACE:
-                       op = "replace";
-                       break;
-               }
-
-               len = strlen (mods->mod_type) + strlen (op) + 7;
-               while (bp + len - tcl_mods > bsize) {
-                       bsize += BUFSIZ;
-                       tcl_mods = (char *) ch_realloc (tcl_mods, bsize);
-               }
-               sprintf (bp, "{ {%s: %s} ", op, mods->mod_type);
-               bp += len;
-               for (i = 0;
-                       mods->mod_bvalues != NULL && mods->mod_bvalues[i]
-                       != NULL;
-                       i++) {
-                       len = strlen (mods->mod_type) + strlen (
-                               mods->mod_bvalues[i]->bv_val) + 5 +
-                               (mods->mod_bvalues[i + 1] == NULL ? 2 : 0);
-                       while (bp + len - tcl_mods > bsize) {
-                               bsize += BUFSIZ;
-                               tcl_mods = (char *) ch_realloc (tcl_mods, bsize);
-                       }
-                       sprintf (bp, "{%s: %s} %s", mods->mod_type,
-                               mods->mod_bvalues[i]->bv_val,
-                               mods->mod_bvalues[i + 1] ==
-                               NULL ? "} " : "");
-                       bp += len;
-               }
-       }
-
-       command = (char *) ch_malloc (strlen (ti->ti_modify) + strlen (suf_tcl)
-               + strlen (dn) + strlen (tcl_mods) + 64);
-       /* This space is simply for aesthetics--\  */
-       sprintf (command, "%s MODIFY {%ld} {%s} {%s} { %s}",
-               ti->ti_modify, op->o_msgid, suf_tcl, dn, tcl_mods);
-       Tcl_Free (suf_tcl);
-       free (tcl_mods);
-
-       ldap_pvt_thread_mutex_lock (&tcl_interpreter_mutex);
-       code = Tcl_GlobalEval (ti->ti_ii->interp, command);
-       results = (char *) ch_strdup (ti->ti_ii->interp->result);
-       ldap_pvt_thread_mutex_unlock (&tcl_interpreter_mutex);
-       free (command);
-
-       if (code != TCL_OK) {
-               err = LDAP_OPERATIONS_ERROR;
-               Debug (LDAP_DEBUG_SHELL, "tcl_modify_error: %s\n", results,
-                       0, 0);
-       } else {
-               interp_send_results (be, conn, op, results, NULL, 0);
-       }
-
-       if (err != LDAP_SUCCESS)
-               send_ldap_result (conn, op, err, NULL,
-                       "internal backend error", NULL, NULL );
-
-       free (results);
-       return (err);
-}
diff --git a/servers/slapd/back-tcl/tcl_modrdn.c b/servers/slapd/back-tcl/tcl_modrdn.c
deleted file mode 100644 (file)
index d6aa9fb..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/* $OpenLDAP$ */
-/* modrdn.c - tcl modify rdn routines
- *
- * Copyright 1999, Ben Collins <bcollins@debian.org>, All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted only
- * as authorized by the OpenLDAP Public License.  A copy of this
- * license is available at http://www.OpenLDAP.org/license.html or
- * in file LICENSE in the top-level directory of the distribution.
- */
-
-/*
- * LDAP v3 newSuperior support.
- *
- * Copyright 1999, Juan C. Gomez, All rights reserved.
- * This software is not subject to any license of Silicon Graphics 
- * Inc. or Purdue University.
- *
- * Redistribution and use in source and binary forms are permitted
- * without restriction or fee of any kind as long as this notice
- * is preserved.
- *
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include "slap.h"
-#include "tcl_back.h"
-
-int
-tcl_back_modrdn (
-       Backend * be,
-       Connection * conn,
-       Operation * op,
-       char *dn,
-       char *newrdn,
-       int deleteoldrdn,
-       char *newSuperior
-)
-{
-       char *command, *suf_tcl, *results;
-       int i, code, err = 0;
-       struct tclinfo *ti = (struct tclinfo *) be->be_private;
-
-       if (ti->ti_modrdn == NULL) {
-               send_ldap_result (conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
-                       "modrdn not implemented", NULL, NULL );
-               return (-1);
-       }
-
-       for (i = 0; be->be_suffix[i] != NULL; i++);
-       suf_tcl = Tcl_Merge (i, be->be_suffix);
-
-       command = (char *) ch_malloc (strlen (ti->ti_modrdn) + strlen (suf_tcl)
-               + strlen (dn) + strlen (newrdn)
-               + (newSuperior ? strlen(newSuperior) : 0) + 64);
-       if ( newSuperior ) {
-               sprintf (command, "%s MODRDN {%ld} {%s} {%s} {%s} %d {%s}",
-                        ti->ti_add, op->o_msgid, suf_tcl, dn, newrdn,
-                        deleteoldrdn ? 1 : 0, newSuperior );
-       } else {
-               sprintf (command, "%s MODRDN {%ld} {%s} {%s} {%s} %d",
-                        ti->ti_add, op->o_msgid, suf_tcl, dn, newrdn,
-                        deleteoldrdn ? 1 : 0 );
-       }       
-       Tcl_Free (suf_tcl);
-
-       ldap_pvt_thread_mutex_lock (&tcl_interpreter_mutex);
-       code = Tcl_GlobalEval (ti->ti_ii->interp, command);
-       results = (char *) ch_strdup (ti->ti_ii->interp->result);
-       ldap_pvt_thread_mutex_unlock (&tcl_interpreter_mutex);
-       free (command);
-
-       if (code != TCL_OK) {
-               err = LDAP_OPERATIONS_ERROR;
-               Debug (LDAP_DEBUG_SHELL, "tcl_modrdn_error: %s\n", results,
-                       0, 0);
-       } else {
-               interp_send_results (be, conn, op, results, NULL, 0);
-       }
-
-       if (err != LDAP_SUCCESS)
-               send_ldap_result (conn, op, err, NULL,
-                       "internal backend error", NULL, NULL );
-
-       free (results);
-       return (err);
-}
diff --git a/servers/slapd/back-tcl/tcl_search.c b/servers/slapd/back-tcl/tcl_search.c
deleted file mode 100644 (file)
index a26c482..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/* $OpenLDAP$ */
-/* search.c - tcl search routines
- *
- * Copyright 1999, Ben Collins <bcollins@debian.org>, All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted only
- * as authorized by the OpenLDAP Public License.  A copy of this
- * license is available at http://www.OpenLDAP.org/license.html or
- * in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include "slap.h"
-#include "tcl_back.h"
-
-int
-tcl_back_search (
-       Backend * be,
-       Connection * conn,
-       Operation * op,
-       char *base,
-       int scope,
-       int deref,
-       int sizelimit,
-       int timelimit,
-       Filter * filter,
-       char *filterstr,
-       char **attrs,
-       int attrsonly
-)
-{
-       char *attrs_tcl = NULL, *suf_tcl, *results, *command;
-       int i, err = 0, code;
-       struct tclinfo *ti = (struct tclinfo *) be->be_private;
-       Entry *e;
-
-       if (ti->ti_search == NULL) {
-               send_ldap_result (conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
-                       "search not implemented", NULL, NULL );
-               return (-1);
-       }
-
-       for (i = 0; attrs != NULL && attrs[i] != NULL; i++);
-       if (i > 0)
-               attrs_tcl = Tcl_Merge (i, attrs);
-
-       for (i = 0; be->be_suffix[i] != NULL; i++);
-       suf_tcl = Tcl_Merge (i, be->be_suffix);
-
-       command = (char *) ch_malloc (strlen (ti->ti_search) + strlen (suf_tcl)
-               + strlen (base) + 40 + strlen (filterstr) + (attrs_tcl ==
-                       NULL ? 5
-                       : strlen (attrs_tcl)) + 72);
-       sprintf (command,
-               "%s SEARCH {%ld} {%s} {%s} {%d} {%d} {%d} {%d} {%s} {%d} {%s}",
-               ti->ti_search, op->o_msgid, suf_tcl, base, scope, deref,
-               sizelimit, timelimit, filterstr, attrsonly ? 1 : 0,
-               attrs_tcl ==
-               NULL ? "{all}" : attrs_tcl);
-       Tcl_Free (attrs_tcl);
-       Tcl_Free (suf_tcl);
-
-       ldap_pvt_thread_mutex_lock (&tcl_interpreter_mutex);
-       code = Tcl_GlobalEval (ti->ti_ii->interp, command);
-       results = (char *) ch_strdup (ti->ti_ii->interp->result);
-       ldap_pvt_thread_mutex_unlock (&tcl_interpreter_mutex);
-       free (command);
-
-       if (code != TCL_OK) {
-               err = LDAP_OPERATIONS_ERROR;
-               Debug (LDAP_DEBUG_SHELL, "tcl_search_error: %s\n", results,
-                       0, 0);
-       } else {
-               interp_send_results (be, conn, op, results, NULL, 0);
-       }
-
-       if (err != LDAP_SUCCESS)
-               send_ldap_result (conn, op, err, NULL,
-                       "internal backend error", NULL, NULL );
-
-       free (results);
-       return (err);
-}
diff --git a/servers/slapd/back-tcl/tcl_unbind.c b/servers/slapd/back-tcl/tcl_unbind.c
deleted file mode 100644 (file)
index a4f5477..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* $OpenLDAP$ */
-/* unbind.c - tcl unbind routines
- *
- * Copyright 1999, Ben Collins <bcollins@debian.org>, All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted only
- * as authorized by the OpenLDAP Public License.  A copy of this
- * license is available at http://www.OpenLDAP.org/license.html or
- * in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include "slap.h"
-#include "tcl_back.h"
-
-int
-tcl_back_unbind (
-       Backend * be,
-       Connection * conn,
-       Operation * op
-)
-{
-       char *command, *suf_tcl, *results;
-       int i, code, err = 0;
-       struct tclinfo *ti = (struct tclinfo *) be->be_private;
-
-       if (ti->ti_unbind == NULL) {
-               return (-1);
-       }
-
-       for (i = 0; be->be_suffix[i] != NULL; i++);
-       suf_tcl = Tcl_Merge (i, be->be_suffix);
-
-       command = (char *) ch_malloc (strlen (ti->ti_unbind) + strlen (suf_tcl)
-               + strlen (conn->c_dn ? conn->c_dn : "") + 64);
-       sprintf (command, "%s UNBIND {%ld} {%s} {%s}",
-               ti->ti_unbind, op->o_msgid, suf_tcl, conn->c_dn ?
-               conn->c_dn : "");
-       Tcl_Free (suf_tcl);
-
-       ldap_pvt_thread_mutex_lock (&tcl_interpreter_mutex);
-       code = Tcl_GlobalEval (ti->ti_ii->interp, command);
-       results = (char *) ch_strdup (ti->ti_ii->interp->result);
-       ldap_pvt_thread_mutex_unlock (&tcl_interpreter_mutex);
-       free (command);
-
-       if (code != TCL_OK) {
-               Debug (LDAP_DEBUG_SHELL, "tcl_unbind_error: %s\n", results,
-                       0, 0);
-       }
-
-       free (results);
-       return (err);
-}
diff --git a/servers/slapd/back-tcl/tcl_util.c b/servers/slapd/back-tcl/tcl_util.c
deleted file mode 100644 (file)
index 4e57669..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/* $OpenLDAP$ */
-/* result.c - tcl backend utility functions
- *
- * Copyright 1999, Ben Collins <bcollins@debian.org>, All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted only
- * as authorized by the OpenLDAP Public License.  A copy of this
- * license is available at http://www.OpenLDAP.org/license.html or
- * in file LICENSE in the top-level directory of the distribution.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-#include <ac/unistd.h>
-
-#include "slap.h"
-#include "tcl_back.h"
-
-int
-interp_send_results (
-       Backend * be,
-       Connection * conn,
-       Operation * op,
-       char *result,
-       char **attrs,
-       int attrsonly
-)
-{
-       int bsize, len, argcPtr, i, err, code;
-       char *buf, *bp, **argvPtr, *line, *matched, *info;
-       Entry *e;
-       struct tclinfo *ti = (struct tclinfo *) be->be_private;
-
-       /*
-        * read in the result and send it along 
-        */
-       buf = (char *) ch_malloc (BUFSIZ);
-       buf[0] = '\0';
-       bsize = BUFSIZ;
-       bp = buf;
-       code = Tcl_SplitList (ti->ti_ii->interp, result, &argcPtr, &argvPtr);
-       if (code != TCL_OK) {
-               argcPtr = 0;
-               send_ldap_result (conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
-                       "internal backend error", NULL, NULL );
-               return -1;
-       }
-       for (i = 0; i < argcPtr; i++) {
-               line = argvPtr[i];
-
-               /*
-                * ignore lines beginning with DEBUG: 
-                */
-               if (strncasecmp (line, "DEBUG:", 6) == 0) {
-                       continue;
-               }
-               len = strlen (line) + 1;
-               while (bp + len - buf > bsize) {
-                       bsize += BUFSIZ;
-                       buf = (char *) ch_realloc (buf, bsize);
-               }
-               sprintf (bp, "%s\n", line);
-               bp += len;
-
-               /*
-                * line marked the end of an entry or result 
-                */
-               if (line[0] == '\0') {
-                       if (strncasecmp (buf, "RESULT", 6) == 0) {
-                               break;
-                       }
-                       if ((e = str2entry (buf)) == NULL) {
-                               Debug (LDAP_DEBUG_SHELL,
-                                       "str2entry(%s) failed\n",
-                                       buf, 0, 0);
-                       } else {
-                               send_search_entry (be, conn, op, e, attrs,
-                                       attrsonly, NULL );
-                               entry_free (e);
-                       }
-
-                       bp = buf;
-               }
-       }
-
-       (void) str2result (buf, &err, &matched, &info);
-
-       /*
-        * otherwise, front end will send this result 
-        */
-       if (err != 0 || op->o_tag != LDAP_REQ_BIND) {
-               send_ldap_result (conn, op, err, matched, info, NULL, NULL );
-       }
-
-       free (buf);
-       Tcl_Free ((char *) argvPtr);
-       return (err);
-}
-
-char *
-tcl_clean_entry (
-       Entry * e
-)
-{
-       char *entrystr, *mark1, *mark2, *buf, *bp, *dup;
-       int len, bsize;
-
-       ldap_pvt_thread_mutex_lock(&entry2str_mutex);
-       entrystr = entry2str (e, &len);
-
-       buf = (char *) ch_malloc (BUFSIZ);
-       buf[0] = '\0';
-       bsize = BUFSIZ;
-       bp = buf;
-       bp++[0] = ' ';
-
-       mark1 = entrystr;
-       do {
-               if (mark1[0] == '\n') {
-                       mark1++;
-               }
-               dup = (char *) ch_strdup (mark1);
-               if (dup[0] != '\0') {
-                       if ((mark2 = (char *) strchr (dup, '\n')) != NULL) {
-                               mark2[0] = '\0';
-                       }
-                       len = strlen (dup) + 3;
-                       while (bp + len - buf > bsize) {
-                               bsize += BUFSIZ;
-                               buf = (char *) ch_realloc (buf, bsize);
-                       }
-                       if (mark1[0] == '\0') {
-                               sprintf (bp, "{} ");
-                       } else {
-                               sprintf (bp, "{%s} ", dup);
-                       }
-                       bp += len;
-                       if (mark2 != NULL) {
-                               mark2[0] = '\n';
-                       }
-               }
-               free (dup);
-       } while ((mark1 = (char *) strchr (mark1, '\n')) != NULL);
-
-       ldap_pvt_thread_mutex_unlock (&entry2str_mutex);
-       return buf;
-}
-
-int
-tcl_ldap_debug (
-       ClientData clientData,
-       Tcl_Interp * interp,
-       int argc,
-       char *argv[]
-)
-{
-       if (argv[1] != NULL) {
-               Debug (LDAP_DEBUG_SHELL, "tcl_debug: %s\n", argv[1], 0, 0);
-       }
-       return TCL_OK;
-}
-
-void
-readtclscript (
-       char *script,
-       Tcl_Interp * my_tcl)
-{
-       int code;
-       FILE *f;
-
-       f = fopen (script, "r");
-       if (f == NULL) {
-               Debug (LDAP_DEBUG_SHELL, "Could not open scriptpath %s\n", script,
-                       0, 0);
-               return;
-       }
-       fclose (f);
-       code = Tcl_EvalFile (my_tcl, script);
-       if (code != TCL_OK) {
-               Debug (LDAP_DEBUG_SHELL, "%s: %s\n", script,
-                       Tcl_GetVar (my_tcl, "errorInfo", TCL_GLOBAL_ONLY), 0);
-               Debug (LDAP_DEBUG_SHELL, "%s: error at line\n", script,
-                       my_tcl->errorLine, 0);
-               return;
-       }
-}
index 39c3fdb8a99a097113073b70976597a14960e629..bcb3e0424fbce5895f88c6c4142ca42e78b9793b 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* backend.c - routines for dealing with back-end databases */
@@ -18,6 +18,9 @@
 #include "slap.h"
 #include "lutil.h"
 
+#ifdef SLAPD_DNSSRV
+#include "back-dnssrv/external.h"
+#endif
 #ifdef SLAPD_LDAP
 #include "back-ldap/external.h"
 #endif
 #ifdef SLAPD_TCL
 #include "back-tcl/external.h"
 #endif
+#ifdef SLAPD_NTDOMAIN
+#include "back-domain/external.h"
+#endif
+#ifdef SLAPD_SQL
+#include "back-sql/external.h"
+#endif
 
 static BackendInfo binfo[] = {
+#if defined(SLAPD_DNSSRV) && !defined(SLAPD_DNSSRV_DYNAMIC)
+       {"dnssrv",      dnssrv_back_initialize},
+#endif
 #if defined(SLAPD_LDAP) && !defined(SLAPD_LDAP_DYNAMIC)
        {"ldap",        ldap_back_initialize},
 #endif
@@ -59,8 +71,14 @@ static BackendInfo binfo[] = {
 #if defined(SLAPD_SHELL) && !defined(SLAPD_SHELL_DYNAMIC)
        {"shell",       shell_back_initialize},
 #endif
-#if defined(SLAPD_TCL) && !defined(SLAPD_LDAP_TCL)
+#if defined(SLAPD_TCL) && !defined(SLAPD_TCL_DYNAMIC)
        {"tcl",         tcl_back_initialize},
+#endif
+#if defined(SLAPD_NTDOMAIN) && !defined(SLAPD_NTDOMAIN_DYNAMIC)
+       {"ntdom",       domain_back_initialize},
+#endif
+#if defined(SLAPD_SQL) && !defined(SLAPD_SQL_DYNAMIC)
+       {"sql",         sql_back_initialize},
 #endif
        {NULL}
 };
@@ -222,6 +240,9 @@ int backend_startup(Backend *be)
 
        /* open each backend database */
        for( i = 0; i < nBackendDB; i++ ) {
+               /* append global access controls */
+               acl_append( &backendDB[i].be_acl, global_acl );
+
                if ( backendDB[i].bd_info->bi_db_open ) {
                        rc = backendDB[i].bd_info->bi_db_open(
                                &backendDB[i] );
@@ -376,6 +397,7 @@ backend_db_init(
        be->bd_info = bi;
        be->be_sizelimit = defsize;
        be->be_timelimit = deftime;
+       be->be_dfltaccess = global_default_access;
 
        /* assign a default depth limit for alias deref */
        be->be_max_deref_depth = SLAPD_DEFAULT_MAXDEREFDEPTH; 
@@ -432,20 +454,6 @@ select_backend( const char * dn )
                }
        }
 
-#ifdef LDAP_ALLOW_NULL_SEARCH_BASE
-       /* Add greg@greg.rim.or.jp
-        * It's quick hack for cheap client
-        * Some browser offer a NULL base at ldap_search
-        *
-        * Should only be used as a last resort. -Kdz
-        */
-       if(dnlen == 0) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "select_backend: use default backend\n", 0, 0, 0 );
-               return( &backends[0] );
-       }
-#endif /* LDAP_ALLOW_NULL_SEARCH_BASE */
-
        return( NULL );
 }
 
@@ -471,7 +479,11 @@ be_isroot( Backend *be, const char *ndn )
 {
        int rc;
 
-       if ( ndn == NULL || be->be_root_ndn == NULL ) {
+       if ( ndn == NULL || *ndn == '\0' ) {
+               return( 0 );
+       }
+
+       if ( be->be_root_ndn == NULL || *be->be_root_ndn == '\0' ) {
                return( 0 );
        }
 
@@ -496,14 +508,18 @@ be_isroot_pw( Backend *be, const char *ndn, struct berval *cred )
        int result;
 
        if ( ! be_isroot( be, ndn ) ) {
-               return( 0 );
+               return 0;
+       }
+
+       if( be->be_root_pw.bv_len == 0 ) {
+               return 0;
        }
 
 #ifdef SLAPD_CRYPT
        ldap_pvt_thread_mutex_lock( &crypt_mutex );
 #endif
 
-       result = lutil_passwd( cred->bv_val, be->be_root_pw, NULL );
+       result = lutil_passwd( &be->be_root_pw, cred, NULL );
 
 #ifdef SLAPD_CRYPT
        ldap_pvt_thread_mutex_unlock( &crypt_mutex );
@@ -574,38 +590,76 @@ backend_connection_destroy(
        return 0;
 }
 
+int
+backend_check_controls(
+       Backend *be,
+       Connection *conn,
+       Operation *op,
+       const char **text )
+{
+       LDAPControl **ctrls;
+       ctrls = op->o_ctrls;
+       if( ctrls == NULL ) {
+               return LDAP_SUCCESS;
+       }
+
+       for( ; *ctrls != NULL ; ctrls++ ) {
+               if( (*ctrls)->ldctl_iscritical &&
+                       !charray_inlist( be->be_controls, (*ctrls)->ldctl_oid ) )
+               {
+                       *text = "control unavailable in NamingContext";
+                       return LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
+               }
+       }
+
+       return LDAP_SUCCESS;
+}
+
 int 
 backend_group(
        Backend *be,
        Entry   *target,
        const char      *gr_ndn,
        const char      *op_ndn,
-       const char      *objectclassValue,
-       const char      *groupattrName
+       ObjectClass *group_oc,
+       AttributeDescription *group_at
 )
 {
-       if (be->be_group)
-               return( be->be_group(be, target, gr_ndn, op_ndn,
-                       objectclassValue, groupattrName) );
-       else
-               return(1);
+       if( strcmp( target->e_ndn, gr_ndn ) != 0 ) {
+               /* we won't attempt to send it to a different backend */
+               
+               be = select_backend(gr_ndn);
+
+               if (be == NULL) {
+                       return LDAP_NO_SUCH_OBJECT;
+               }
+       } 
+
+       if( be->be_group ) {
+               return be->be_group( be, target, gr_ndn, op_ndn,
+                       group_oc, group_at );
+       }
+
+       return LDAP_UNWILLING_TO_PERFORM;
 }
 
-#ifdef SLAPD_SCHEMA_DN
-Attribute *backend_subschemasubentry( Backend *be )
+Attribute *backend_operational(
+       Backend *be,
+       Entry *e )
 {
-       /* should be backend specific */
-       static struct berval ss_val = {
-               sizeof(SLAPD_SCHEMA_DN)-1,
-               SLAPD_SCHEMA_DN };
-       static struct berval *ss_vals[2] = { &ss_val, NULL };
-       static Attribute ss_attr = {
-               "subschemasubentry",
-               ss_vals,
-               SYNTAX_DN | SYNTAX_CIS,
-               NULL
-       };
-
-       return &ss_attr;
-}
+       Attribute *a = NULL;
+
+#ifdef SLAPD_SCHEMA_DN
+       a = ch_malloc( sizeof( Attribute ) );
+       a->a_desc = ad_dup( slap_schema.si_ad_subschemaSubentry );
+
+       /* Should be backend specific */
+       a->a_vals = ch_malloc( 2 * sizeof( struct berval * ) );
+       a->a_vals[0] = ber_bvstrdup( SLAPD_SCHEMA_DN );
+       a->a_vals[1] = NULL;
+
+       a->a_next = NULL;
 #endif
+
+       return a;
+}
index d42080d70f6954ff0439cfe66af722ece03e648c..91fe75896155b8bc55f4ab4cd8a32395d5bcebc7 100644 (file)
@@ -1,7 +1,7 @@
 /* bind.c - decode an ldap bind operation and pass it to a backend db */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -24,6 +24,7 @@
 #include <ac/string.h>
 #include <ac/socket.h>
 
+#include "ldap_pvt.h"
 #include "slap.h"
 
 int
@@ -40,6 +41,7 @@ do_bind(
        char *ndn;
        ber_tag_t       tag;
        int                     rc = LDAP_SUCCESS;
+       const char      *text;
        struct berval   cred;
        Backend         *be;
 
@@ -52,9 +54,8 @@ do_bind(
 
        ldap_pvt_thread_mutex_lock( &conn->c_mutex );
 
-       /* Force to connection to "anonymous" until bind succeeds.
-        * This may need to be relocated or done on a case by case basis
-        * to handle certain SASL mechanisms.
+       /*
+        * Force to connection to "anonymous" until bind succeeds.
         */
 
        if ( conn->c_cdn != NULL ) {
@@ -67,6 +68,9 @@ do_bind(
                conn->c_dn = NULL;
        }
 
+       conn->c_authc_backend = NULL;
+       conn->c_authz_backend = NULL;
+
        ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
 
        if ( op->o_dn != NULL ) {
@@ -109,15 +113,6 @@ do_bind(
                goto cleanup;
        }
 
-       ndn = ch_strdup( dn );
-
-       if ( dn_normalize_case( ndn ) == NULL ) {
-               Debug( LDAP_DEBUG_ANY, "bind: invalid dn (%s)\n", dn, 0, 0 );
-               send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
-                   "invalid DN", NULL, NULL );
-               goto cleanup;
-       }
-
        op->o_protocol = version;
 
        if( method != LDAP_AUTH_SASL ) {
@@ -144,7 +139,7 @@ do_bind(
                send_ldap_disconnect( conn, op,
                        LDAP_PROTOCOL_ERROR,
                "decoding error" );
-               rc = -1;
+               rc = SLAPD_DISCONNECT;
                goto cleanup;
        }
 
@@ -153,6 +148,15 @@ do_bind(
                goto cleanup;
        } 
 
+       ndn = ch_strdup( dn );
+
+       if ( dn_normalize( ndn ) == NULL ) {
+               Debug( LDAP_DEBUG_ANY, "bind: invalid dn (%s)\n", dn, 0, 0 );
+               send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
+                   "invalid DN", NULL, NULL );
+               goto cleanup;
+       }
+
        if( method == LDAP_AUTH_SASL ) {
                Debug( LDAP_DEBUG_TRACE, "do_sasl_bind: dn (%s) mech %s\n",
                        dn, mech, NULL );
@@ -168,17 +172,26 @@ do_bind(
                Debug( LDAP_DEBUG_ANY, "do_bind: unknown version=%ld\n",
                        (unsigned long) version, 0, 0 );
                send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
-                       NULL, "version not supported", NULL, NULL );
+                       NULL, "requested protocol version not supported", NULL, NULL );
                goto cleanup;
        }
 
+       /* we set connection version regardless of whether bind succeeds
+        * or not.
+        */
+       ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+       conn->c_protocol = version;
+       ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+
        if ( method == LDAP_AUTH_SASL ) {
+               char *edn;
+
                if ( version < LDAP_VERSION3 ) {
                        Debug( LDAP_DEBUG_ANY, "do_bind: sasl with LDAPv%ld\n",
                                (unsigned long) version, 0, 0 );
                        send_ldap_disconnect( conn, op,
-                               LDAP_PROTOCOL_ERROR, "sasl bind requires LDAPv3" );
-                       rc = -1;
+                               LDAP_PROTOCOL_ERROR, "SASL bind requires LDAPv3" );
+                       rc = SLAPD_DISCONNECT;
                        goto cleanup;
                }
 
@@ -187,7 +200,7 @@ do_bind(
                                "do_bind: no sasl mechanism provided\n",
                                0, 0, 0 );
                        send_ldap_result( conn, op, rc = LDAP_AUTH_METHOD_NOT_SUPPORTED,
-                               NULL, "no sasl mechanism provided", NULL, NULL );
+                               NULL, "no SASL mechanism provided", NULL, NULL );
                        goto cleanup;
                }
 
@@ -196,63 +209,94 @@ do_bind(
                                "do_bind: sasl mechanism=\"%s\" not supported.\n",
                                mech, 0, 0 );
                        send_ldap_result( conn, op, rc = LDAP_AUTH_METHOD_NOT_SUPPORTED,
-                               NULL, "sasl mechanism not supported", NULL, NULL );
+                               NULL, "SASL mechanism not supported", NULL, NULL );
                        goto cleanup;
                }
 
                ldap_pvt_thread_mutex_lock( &conn->c_mutex );
 
-               if ( conn->c_authmech != NULL ) {
-                       assert( conn->c_bind_in_progress );
-
-                       if((strcmp(conn->c_authmech, mech) != 0)) {
+               if ( conn->c_sasl_bind_mech != NULL ) {
+                       if((strcmp(conn->c_sasl_bind_mech, mech) != 0)) {
                                /* mechanism changed, cancel in progress bind */
-                               conn->c_bind_in_progress = 0;
-                               if( conn->c_authstate != NULL ) {
-                                       free(conn->c_authstate);
-                                       conn->c_authstate = NULL;
-                               }
-                               free(conn->c_authmech);
-                               conn->c_authmech = NULL;
+#ifdef HAVE_CYRUS_SASL
+                               sasl_dispose(&conn->c_sasl_bind_context);
+                               conn->c_sasl_bind_context = NULL;
+#endif
                        }
+                       free( conn->c_sasl_bind_mech );
+                       conn->c_sasl_bind_mech = NULL;
 
 #ifdef LDAP_DEBUG
+#ifdef HAVE_CYRUS_SASL
                } else {
-                       assert( !conn->c_bind_in_progress );
-                       assert( conn->c_authmech == NULL );
-                       assert( conn->c_authstate == NULL );
+                       assert( conn->c_sasl_bind_context == NULL );
+#endif
 #endif
                }
 
+               ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+
+               edn = NULL;
+               rc = sasl_bind( conn, op, dn, ndn, mech, &cred, &edn );
+
+               if( rc == LDAP_SUCCESS ) {
+                       ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+#ifdef HAVE_CYRUS_SASL
+                       assert( conn->c_sasl_bind_context == NULL );
+#endif
+                       conn->c_dn = edn;
+                       ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+
+               } else if ( rc == LDAP_SASL_BIND_IN_PROGRESS ) {
+#ifdef HAVE_CYRUS_SASL
+                       assert( conn->c_sasl_bind_context != NULL );
+#endif
+                       conn->c_sasl_bind_mech = mech;
+                       mech = NULL;
+
+#ifdef HAVE_CYRUS_SASL
+               } else {
+                       assert( conn->c_sasl_bind_context != NULL );
+#endif
+               }
+
+               goto cleanup;
+
        } else {
+               /* Not SASL, cancel any in-progress bind */
                ldap_pvt_thread_mutex_lock( &conn->c_mutex );
 
-               if ( conn->c_authmech != NULL ) {
-                       assert( conn->c_bind_in_progress );
+               if ( conn->c_sasl_bind_mech != NULL ) {
+                       assert( conn->c_sasl_bind_in_progress );
 
-                       /* cancel in progress bind */
-                       conn->c_bind_in_progress = 0;
+                       free(conn->c_sasl_bind_mech);
+                       conn->c_sasl_bind_mech = NULL;
 
-                       if( conn->c_authstate != NULL ) {
-                               free(conn->c_authstate);
-                               conn->c_authstate = NULL;
-                       }
-                       free(conn->c_authmech);
-                       conn->c_authmech = NULL;
+#ifdef HAVE_CYRUS_SASL
+                       assert( conn->c_sasl_bind_context != NULL );
+                       sasl_dispose(&conn->c_sasl_bind_context);
+                       conn->c_sasl_bind_context = NULL;
+#endif
+               } else {
+                       assert( !conn->c_sasl_bind_in_progress );
+#ifdef HAVE_CYRUS_SASL
+                       assert( conn->c_sasl_bind_context == NULL );
+#endif
                }
-       }
 
-       conn->c_protocol = version;
-       ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+               ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+       }
 
-       /* accept null binds */
-       if ( ndn == NULL || *ndn == '\0' ) {
+       /* accept "anonymous" binds */
+       if ( cred.bv_len == 0 || ndn == NULL || *ndn == '\0' ) {
                /*
-                * we already forced connection to "anonymous", we just
-                * need to send success
+                * we already forced connection to "anonymous",
+                * just need to send success
                 */
                send_ldap_result( conn, op, LDAP_SUCCESS,
                        NULL, NULL, NULL, NULL );
+               Debug( LDAP_DEBUG_TRACE, "do_bind: v%d anonymous bind\n",
+                       version, 0, 0 );
                goto cleanup;
        }
 
@@ -263,15 +307,12 @@ do_bind(
         */
 
        if ( (be = select_backend( ndn )) == NULL ) {
-               if ( cred.bv_len == 0 ) {
-                       send_ldap_result( conn, op, LDAP_SUCCESS,
-                               NULL, NULL, NULL, NULL );
-
-               } else if ( default_referral ) {
+               if ( default_referral ) {
                        send_ldap_result( conn, op, rc = LDAP_REFERRAL,
                                NULL, NULL, default_referral, NULL );
 
                } else {
+                       /* noSuchObject is not allowed to be returned by bind */
                        send_ldap_result( conn, op, rc = LDAP_INVALID_CREDENTIALS,
                                NULL, NULL, NULL, NULL );
                }
@@ -279,14 +320,29 @@ do_bind(
                goto cleanup;
        }
 
+       conn->c_authz_backend = be;
+
+       /* make sure this backend recongizes critical controls */
+       rc = backend_check_controls( be, conn, op, &text ) ;
+
+       if( rc != LDAP_SUCCESS ) {
+               send_ldap_result( conn, op, rc,
+                       NULL, text, NULL, NULL );
+               goto cleanup;
+       }
+
        if ( be->be_bind ) {
+               int ret;
                /* alias suffix */
-               char *edn;
+               char *edn = NULL;
 
                /* deref suffix alias if appropriate */
                ndn = suffix_alias( be, ndn );
 
-               if ( (*be->be_bind)( be, conn, op, ndn, method, mech, &cred, &edn ) == 0 ) {
+               ret = (*be->be_bind)( be, conn, op, dn, ndn,
+                       method, &cred, &edn );
+
+               if ( ret == 0 ) {
                        ldap_pvt_thread_mutex_lock( &conn->c_mutex );
 
                        conn->c_cdn = dn;
@@ -299,8 +355,8 @@ do_bind(
                                ndn = NULL;
                        }
 
-                       Debug( LDAP_DEBUG_TRACE, "do_bind: bound \"%s\" to \"%s\"\n",
-                       conn->c_cdn, conn->c_dn, method );
+                       Debug( LDAP_DEBUG_TRACE, "do_bind: v%d bind: \"%s\" to \"%s\"\n",
+                       version, conn->c_cdn, conn->c_dn );
 
                        ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
 
@@ -314,7 +370,7 @@ do_bind(
 
        } else {
                send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
-                       NULL, "Function not implemented", NULL, NULL );
+                       NULL, "operation not supported within namingContext", NULL, NULL );
        }
 
 cleanup:
index 72d63b69e23a839cb10426715b7d73bda4e7610d..9eb248e6ffea4dab75e8c583d6e4433925768d30 100644 (file)
@@ -1,7 +1,7 @@
 /* ch_malloc.c - malloc routines that test returns from malloc and friends */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
index 60c212e509042940ba3cf8d3539516f9f5838ef0..b51659141a24ccfe13a5fb12d7a16c9d12ec0da5 100644 (file)
@@ -1,7 +1,7 @@
 /* charray.c - routines for dealing with char * arrays */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -86,6 +86,8 @@ charray_inlist(
 {
        int     i;
 
+       if( a == NULL ) return 0;
+
        for ( i = 0; a[i] != NULL; i++ ) {
                if ( strcasecmp( s, a[i] ) == 0 ) {
                        return( 1 );
@@ -115,34 +117,6 @@ charray_dup( char **a )
 }
 
 
-char *
-charray2str( char **a )
-{
-       char *s;
-       int i;
-       size_t cur, len = 0;
-
-       if( a == NULL ) return NULL;
-
-       for( i=0 ; a[i] != NULL ; i++ ) {
-               len += strlen( a[i] );
-       }
-
-       if( len == 0 ) return NULL;
-
-       s = ch_malloc( len + 1 );
-
-       cur = 0;
-       for( i=0 ; a[i] != NULL ; i++ ) {
-               len = strlen( a[i] );
-               strncpy( &s[cur], a[i], len );
-               cur += len;
-       }
-       s[len] = '\0';
-       return s;
-}
-
-
 char **
 str2charray( const char *str_in, const char *brkstr )
 {
index 1176265b413fbca6012f07699e2f82c3d826eab1..a26c49741cf65ba11394ce0e4db25958f6aa86d4 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
@@ -21,6 +21,7 @@
 
 #include <ac/socket.h>
 
+#include "ldap_pvt.h"
 #include "slap.h"
 
 int
@@ -29,20 +30,19 @@ do_compare(
     Operation  *op
 )
 {
-       char    *ndn;
-       Ava     ava;
+       char    *dn = NULL, *ndn=NULL;
+       struct berval desc;
+       struct berval value;
+       struct berval *nvalue;
+       AttributeAssertion ava;
        Backend *be;
        int rc = LDAP_SUCCESS;
+       const char *text = NULL;
 
-       Debug( LDAP_DEBUG_TRACE, "do_compare\n", 0, 0, 0 );
+       desc.bv_val = NULL;
+       value.bv_val = NULL;
 
-       if( op->o_bind_in_progress ) {
-               Debug( LDAP_DEBUG_ANY, "do_compare: SASL bind in progress.\n",
-                       0, 0, 0 );
-               send_ldap_result( conn, op, LDAP_SASL_BIND_IN_PROGRESS,
-                       NULL, "SASL bind in progress", NULL, NULL );
-               return LDAP_SASL_BIND_IN_PROGRESS;
-       }
+       Debug( LDAP_DEBUG_TRACE, "do_compare\n", 0, 0, 0 );
 
        /*
         * Parse the compare request.  It looks like this:
@@ -56,37 +56,75 @@ do_compare(
         *      }
         */
 
-       if ( ber_scanf( op->o_ber, "{a{ao}}", &ndn, &ava.ava_type,
-           &ava.ava_value ) == LBER_ERROR ) {
+       if ( ber_scanf( op->o_ber, "{a" /*}*/, &dn ) == LBER_ERROR ) {
                Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
                send_ldap_disconnect( conn, op,
                        LDAP_PROTOCOL_ERROR, "decoding error" );
-               return -1;
+               return SLAPD_DISCONNECT;
        }
 
-       if( dn_normalize_case( ndn ) == NULL ) {
-               Debug( LDAP_DEBUG_ANY, "do_compare: invalid dn (%s)\n", ndn, 0, 0 );
-               send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
-                   "invalid DN", NULL, NULL );
-               free( ndn );
-               ava_free( &ava, 0 );
-               return rc;
+       if ( ber_scanf( op->o_ber, "{oo}", &desc, &value ) == LBER_ERROR ) {
+               Debug( LDAP_DEBUG_ANY, "do_compare: get ava failed\n", 0, 0, 0 );
+               send_ldap_disconnect( conn, op,
+                       LDAP_PROTOCOL_ERROR, "decoding error" );
+               rc = SLAPD_DISCONNECT;
+               goto cleanup;
+       }
+
+       if ( ber_scanf( op->o_ber, /*{*/ "}" ) == LBER_ERROR ) {
+               Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
+               send_ldap_disconnect( conn, op,
+                       LDAP_PROTOCOL_ERROR, "decoding error" );
+               rc = SLAPD_DISCONNECT;
+               goto cleanup;
        }
 
        if( ( rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) {
-               free( ndn );
-               ava_free( &ava, 0 );
                Debug( LDAP_DEBUG_ANY, "do_compare: get_ctrls failed\n", 0, 0, 0 );
-               return rc;
+               goto cleanup;
        } 
 
-       value_normalize( ava.ava_value.bv_val, attr_syntax( ava.ava_type ) );
+       ndn = ch_strdup( dn );
+
+       if( dn_normalize( ndn ) == NULL ) {
+               Debug( LDAP_DEBUG_ANY, "do_compare: invalid dn (%s)\n", dn, 0, 0 );
+               send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
+                   "invalid DN", NULL, NULL );
+               goto cleanup;
+       }
+
+       ava.aa_desc = NULL;
+       rc = slap_bv2ad( &desc, &ava.aa_desc, &text );
+       if( rc != LDAP_SUCCESS ) {
+               send_ldap_result( conn, op, rc, NULL,
+                   text, NULL, NULL );
+               goto cleanup;
+       }
+
+       if( !ava.aa_desc->ad_type->sat_equality ) {
+               /* no equality matching rule */
+               send_ldap_result( conn, op, rc = LDAP_INAPPROPRIATE_MATCHING, NULL,
+                   "no equality matching rule defined", NULL, NULL );
+               goto cleanup;
+       }
+
+       rc = value_normalize( ava.aa_desc, SLAP_MR_EQUALITY, &value, &nvalue, &text );
+
+       if( rc != LDAP_SUCCESS ) {
+               send_ldap_result( conn, op, rc, NULL,
+                   text, NULL, NULL );
+               goto cleanup;
+       }
+
+       ava.aa_value = nvalue;
 
        Debug( LDAP_DEBUG_ARGS, "do_compare: dn (%s) attr (%s) value (%s)\n",
-           ndn, ava.ava_type, ava.ava_value.bv_val );
+           dn, ava.aa_desc->ad_cname->bv_val, ava.aa_value->bv_val );
 
        Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d CMP dn=\"%s\" attr=\"%s\"\n",
-           op->o_connid, op->o_opid, ndn, ava.ava_type, 0 );
+           op->o_connid, op->o_opid, dn, ava.aa_desc->ad_cname->bv_val, 0 );
+
+
 
        /*
         * We could be serving multiple database backends.  Select the
@@ -94,26 +132,39 @@ do_compare(
         * if we don't hold it.
         */
        if ( (be = select_backend( ndn )) == NULL ) {
-               free( ndn );
-               ava_free( &ava, 0 );
-
                send_ldap_result( conn, op, rc = LDAP_REFERRAL,
                        NULL, NULL, default_referral, NULL );
-               return 1;
+               rc = 1;
+               goto cleanup;
+       }
+
+       /* make sure this backend recongizes critical controls */
+       rc = backend_check_controls( be, conn, op, &text ) ;
+
+       if( rc != LDAP_SUCCESS ) {
+               send_ldap_result( conn, op, rc,
+                       NULL, text, NULL, NULL );
+               goto cleanup;
        }
 
        /* deref suffix alias if appropriate */
        ndn = suffix_alias( be, ndn );
 
        if ( be->be_compare ) {
-               (*be->be_compare)( be, conn, op, ndn, &ava );
+               (*be->be_compare)( be, conn, op, dn, ndn, &ava );
        } else {
                send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
-                       NULL, "Function not implemented", NULL, NULL );
+                       NULL, "operation not supported within namingContext", NULL, NULL );
        }
 
+cleanup:
+       free( dn );
        free( ndn );
-       ava_free( &ava, 0 );
+       free( desc.bv_val );
+       free( value.bv_val );
+       if( ava.aa_desc != NULL ) {
+               ad_free( ava.aa_desc, 1 );
+       }
 
        return rc;
 }
index 493045cdf2dfe24ad6494fe0a107b042170c8613..9f78b99911eef351d616512057ce98073c134065 100644 (file)
@@ -1,7 +1,7 @@
 /* config.c - configuration file handling routines */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 int            defsize = SLAPD_DEFAULT_SIZELIMIT;
 int            deftime = SLAPD_DEFAULT_TIMELIMIT;
 AccessControl  *global_acl = NULL;
-int            global_default_access = ACL_READ;
+slap_access_t          global_default_access = ACL_READ;
 int            global_readonly = 0;
 char           *replogfile;
 int            global_lastmod = ON;
 int            global_idletimeout = 0;
 char   *global_realm = NULL;
 char           *ldap_srvtab = "";
+char           *default_passwd_hash;
 
 char   *slapd_pid_file  = NULL;
 char   *slapd_args_file = NULL;
@@ -75,13 +76,6 @@ read_config( const char *fname )
 
        Debug( LDAP_DEBUG_CONFIG, "reading config file %s\n", fname, 0, 0 );
 
-       if ( schema_init( ) != 0 ) {
-               Debug( LDAP_DEBUG_ANY,
-                   "error initializing the schema\n",
-                   0, 0, 0 );
-               return( 1 );
-       }
-
        fp_getline_init( &lineno );
 
        while ( (line = fp_getline( fp, &lineno )) != NULL ) {
@@ -123,6 +117,13 @@ read_config( const char *fname )
 
                        bi = backend_info( cargv[1] );
 
+                       if( bi == NULL ) {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "backend %s initialization failed.n",
+                                   cargv[1], 0, 0 );
+                               return( 1 );
+                       }
+
                /* start of a new database definition */
                } else if ( strcasecmp( cargv[0], "database" ) == 0 ) {
                        if ( cargc < 2 ) {
@@ -131,9 +132,38 @@ read_config( const char *fname )
                                    fname, lineno, 0 );
                                return( 1 );
                        }
+
                        bi = NULL;
                        be = backend_db_init( cargv[1] );
 
+                       if( be == NULL ) {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "database %s initialization failed.n",
+                                   cargv[1], 0, 0 );
+                               return( 1 );
+                       }
+
+               /* set thread concurrency */
+               } else if ( strcasecmp( cargv[0], "concurrency" ) == 0 ) {
+                       int c;
+                       if ( cargc < 2 ) {
+                               Debug( LDAP_DEBUG_ANY,
+           "%s: line %d: missing level in \"concurrency <level>\" line\n",
+                                   fname, lineno, 0 );
+                               return( 1 );
+                       }
+
+                       c = atoi( cargv[1] );
+
+                       if( c < 1 ) {
+                               Debug( LDAP_DEBUG_ANY,
+           "%s: line %d: invalid level (%d) in \"concurrency <level>\" line\n",
+                                   fname, lineno, c );
+                               return( 1 );
+                       }
+
+                       ldap_pvt_thread_set_concurrency( c );
+
                /* get pid file name */
                } else if ( strcasecmp( cargv[0], "pidfile" ) == 0 ) {
                        if ( cargc < 2 ) {
@@ -156,6 +186,24 @@ read_config( const char *fname )
 
                        slapd_args_file = ch_strdup( cargv[1] );
 
+               /* default password hash */
+               } else if ( strcasecmp( cargv[0], "password-hash" ) == 0 ) {
+                       if ( cargc < 2 ) {
+                               Debug( LDAP_DEBUG_ANY,
+           "%s: line %d: missing realm in \"password-hash <hash>\" line\n",
+                                   fname, lineno, 0 );
+                               return( 1 );
+                       }
+                       if ( default_passwd_hash != NULL ) {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "%s: line %d: already set default password_hash!\n",
+                                       fname, lineno, 0 );
+                               return 1;
+
+                       } else {
+                               default_passwd_hash = ch_strdup( cargv[1] );
+                       }
+
                /* set DIGEST realm */
                } else if ( strcasecmp( cargv[0], "digest-realm" ) == 0 ) {
                        if ( cargc < 2 ) {
@@ -232,7 +280,7 @@ read_config( const char *fname )
                                    fname, lineno, tmp_be->be_suffix[0] );
                        } else {
                                char *dn = ch_strdup( cargv[1] );
-                               (void) dn_normalize( dn );
+                               (void) dn_validate( dn );
                                charray_add( &be->be_suffix, dn );
                                (void) ldap_pvt_str2upper( dn );
                                charray_add( &be->be_nsuffix, dn );
@@ -284,8 +332,6 @@ read_config( const char *fname )
                                aliased_dn = ch_strdup( cargv[2] );
                                (void) dn_normalize( aliased_dn );
 
-                               (void) dn_normalize_case( alias );
-                               (void) dn_normalize_case( aliased_dn );
                                charray_add( &be->be_suffixAlias, alias );
                                charray_add( &be->be_suffixAlias, aliased_dn );
 
@@ -332,7 +378,7 @@ read_config( const char *fname )
                                be->be_root_dn = ch_strdup( cargv[1] );
                                be->be_root_ndn = ch_strdup( cargv[1] );
 
-                               if( dn_normalize_case( be->be_root_ndn ) == NULL ) {
+                               if( dn_normalize( be->be_root_ndn ) == NULL ) {
                                        free( be->be_root_dn );
                                        free( be->be_root_ndn );
                                        Debug( LDAP_DEBUG_ANY,
@@ -355,7 +401,8 @@ read_config( const char *fname )
 "%s: line %d: rootpw line must appear inside a database definition (ignored)\n",
                                    fname, lineno, 0 );
                        } else {
-                               be->be_root_pw = ch_strdup( cargv[1] );
+                               be->be_root_pw.bv_val = ch_strdup( cargv[1] );
+                               be->be_root_pw.bv_len = strlen( be->be_root_pw.bv_val );
                        }
 
                /* make this database read-only */
@@ -421,6 +468,7 @@ read_config( const char *fname )
                /* specify an Object Identifier macro */
                } else if ( strcasecmp( cargv[0], "objectidentifier" ) == 0 ) {
                        parse_oidm( fname, lineno, cargc, cargv );
+
                /* specify an objectclass */
                } else if ( strcasecmp( cargv[0], "objectclass" ) == 0 ) {
                        if ( *cargv[1] == '(' ) {
@@ -428,18 +476,23 @@ read_config( const char *fname )
                                p = strchr(saveline,'(');
                                parse_oc( fname, lineno, p, cargv );
                        } else {
-                               parse_oc_old( be, fname, lineno, cargc, cargv );
+                               Debug( LDAP_DEBUG_ANY,
+    "%s: line %d: old objectclass format not supported.\n",
+                                   fname, lineno, 0 );
                        }
 
-               /* specify an attribute */
-               } else if ( strcasecmp( cargv[0], "attribute" ) == 0 ) {
+               /* specify an attribute type */
+               } else if (( strcasecmp( cargv[0], "attributetype" ) == 0 )
+                       || ( strcasecmp( cargv[0], "attribute" ) == 0 ))
+               {
                        if ( *cargv[1] == '(' ) {
                                char * p;
                                p = strchr(saveline,'(');
                                parse_at( fname, lineno, p, cargv );
                        } else {
-                               attr_syntax_config( fname, lineno, cargc - 1,
-                                   &cargv[1] );
+                               Debug( LDAP_DEBUG_ANY,
+    "%s: line %d: old attribute type format not supported.\n",
+                                   fname, lineno, 0 );
                        }
 
                /* turn on/off schema checking */
@@ -462,31 +515,29 @@ read_config( const char *fname )
 
                /* specify default access control info */
                } else if ( strcasecmp( cargv[0], "defaultaccess" ) == 0 ) {
+                       slap_access_t access;
+
                        if ( cargc < 2 ) {
                                Debug( LDAP_DEBUG_ANY,
            "%s: line %d: missing limit in \"defaultaccess <access>\" line\n",
                                    fname, lineno, 0 );
                                return( 1 );
                        }
+
+                       access = str2access( cargv[1] );
+
+                       if ( access == ACL_INVALID_ACCESS ) {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "%s: line %d: bad access level \"%s\", "
+                                       "expecting none|auth|compare|search|read|write\n",
+                                   fname, lineno, cargv[1] );
+                               return( 1 );
+                       }
+
                        if ( be == NULL ) {
-                               if ( ACL_IS_INVALID(ACL_SET(global_default_access,
-                                               str2access(cargv[1]))) )
-                               {
-                                       Debug( LDAP_DEBUG_ANY,
-"%s: line %d: bad access \"%s\" expecting [self]{none|auth|compare|search|read|write}\n",
-                                           fname, lineno, cargv[1] );
-                                       return( 1 );
-                               }
+                               global_default_access = access;
                        } else {
-                               if ( ACL_IS_INVALID(ACL_SET(be->be_dfltaccess,
-                                               str2access(cargv[1]))) )
-                               {
-                                       Debug( LDAP_DEBUG_ANY,
-                                               "%s: line %d: bad access \"%s\", "
-                                               "expecting [self]{none|auth|compare|search|read|write}\n",
-                                           fname, lineno, cargv[1] );
-                                       return( 1 );
-                               }
+                               be->be_dfltaccess = access;
                        }
 
                /* debug level to log things to syslog */
@@ -541,7 +592,7 @@ read_config( const char *fname )
                                    fname, lineno, 0 );
                        } else {
                                be->be_update_ndn = ch_strdup( cargv[1] );
-                               if( dn_normalize_case( be->be_update_ndn ) == NULL ) {
+                               if( dn_normalize( be->be_update_ndn ) == NULL ) {
                                        Debug( LDAP_DEBUG_ANY,
 "%s: line %d: updatedn DN is invalid\n",
                                            fname, lineno, 0 );
index 692b8575f203f33b8375fd88017fd2faa3372772..51874a539f4ce5d3b28a3c33d0828cfec43b36c7 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
  * no mutex protection in here - take our chances!
  */
 
-void
+int
 config_info(
-       Connection *conn,
-       Operation *op,
-       char **attrs,
-       int attrsonly )
+       Entry **entry, const char **text )
 {
        Entry           *e;
        char            buf[BUFSIZ];
@@ -51,9 +48,21 @@ config_info(
        e->e_attrs = NULL;
        e->e_dn = ch_strdup( SLAPD_CONFIG_DN );
        e->e_ndn = ch_strdup( SLAPD_CONFIG_DN );
-       (void) dn_normalize_case( e->e_ndn );
+       (void) dn_normalize( e->e_ndn );
        e->e_private = NULL;
 
+       val.bv_val = "top";
+       val.bv_len = sizeof("top")-1;
+       attr_merge( e, "objectClass", vals );
+
+       val.bv_val = "LDAPsubentry";
+       val.bv_len = sizeof("LDAPsubentry")-1;
+       attr_merge( e, "objectClass", vals );
+
+       val.bv_val = "extensibleObject";
+       val.bv_len = sizeof("extensibleObject")-1;
+       attr_merge( e, "objectClass", vals );
+
        {
                char *rdn = ch_strdup( SLAPD_CONFIG_DN );
                val.bv_val = strchr( rdn, '=' );
@@ -79,24 +88,8 @@ config_info(
                attr_merge( e, "database", vals );
        }
 
-       val.bv_val = "top";
-       val.bv_len = sizeof("top")-1;
-       attr_merge( e, "objectClass", vals );
-
-       val.bv_val = "LDAPsubentry";
-       val.bv_len = sizeof("LDAPsubentry")-1;
-       attr_merge( e, "objectClass", vals );
-
-       val.bv_val = "extensibleObject";
-       val.bv_len = sizeof("extensibleObject")-1;
-       attr_merge( e, "objectClass", vals );
-
-       send_search_entry( &backends[0], conn, op, e,
-               attrs, attrsonly, NULL );
-       send_search_result( conn, op, LDAP_SUCCESS,
-               NULL, NULL, NULL, NULL, 1 );
-
-       entry_free( e );
+       *entry = e;
+       return LDAP_SUCCESS;
 }
 
 #endif /* slapd_config_dn */
index 9c6e61d593bf335b4d0674d67ce3e9a6adefd1d8..f1e075eb4582be5f363c928a5f4d14cd4878853c 100644 (file)
@@ -1,12 +1,13 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 #include "portable.h"
 
 #include <stdio.h>
+#include <limits.h>
 
 #include <ac/socket.h>
 #include <ac/errno.h>
@@ -16,9 +17,6 @@
 
 #include "slap.h"
 
-/* we need LBER internals */
-#include "../../libraries/liblber/lber-int.h"
-
 /* protected by connections_mutex */
 static ldap_pvt_thread_mutex_t connections_mutex;
 static Connection *connections = NULL;
@@ -213,9 +211,12 @@ static Connection* connection_get( ber_socket_t s )
 #else
        c = NULL;
        {
-               ber_socket_t i;
+               ber_socket_t i, sd;
 
                for(i=0; i<dtblsize; i++) {
+                       ber_sockbuf_ctrl( connections[i].c_sb,
+                               LBER_SB_OPT_GET_FD, &sd );
+
                        if( connections[i].c_struct_state == SLAP_C_UNINITIALIZED ) {
                                assert( connections[i].c_conn_state == SLAP_C_INVALID );
                                assert( connections[i].c_sb == 0 );
@@ -224,7 +225,7 @@ static Connection* connection_get( ber_socket_t s )
 
                        if( connections[i].c_struct_state == SLAP_C_UNUSED ) {
                                assert( connections[i].c_conn_state == SLAP_C_INVALID );
-                               assert( !ber_pvt_sb_in_use( connections[i].c_sb ) );
+                               assert( sd == AC_SOCKET_INVALID );
                                continue;
                        }
 
@@ -232,7 +233,7 @@ static Connection* connection_get( ber_socket_t s )
                         * so don't assert details here.
                         */
 
-                       if( ber_pvt_sb_get_desc( connections[i].c_sb ) == s ) {
+                       if( sd == s ) {
                                c = &connections[i];
                                break;
                        }
@@ -241,13 +242,16 @@ static Connection* connection_get( ber_socket_t s )
 #endif
 
        if( c != NULL ) {
+               ber_socket_t    sd;
+
                ldap_pvt_thread_mutex_lock( &c->c_mutex );
 
+               ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_GET_FD, &sd );
                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( !ber_pvt_sb_in_use( c->c_sb ) );
+                       assert( sd == AC_SOCKET_INVALID );
 
                        Debug( LDAP_DEBUG_TRACE,
                                "connection_get(%d): connection not used\n",
@@ -265,7 +269,7 @@ static Connection* connection_get( ber_socket_t s )
 
                assert( c->c_struct_state == SLAP_C_USED );
                assert( c->c_conn_state != SLAP_C_INVALID );
-               assert( ber_pvt_sb_in_use( c->c_sb ) );
+               assert( sd != AC_SOCKET_INVALID );
 
        c->c_activitytime = slap_get_time();
        }
@@ -323,21 +327,27 @@ long connection_init(
                c = NULL;
 
         for( i=0; i < dtblsize; i++) {
+               ber_socket_t    sd;
+
             if( connections[i].c_struct_state == SLAP_C_UNINITIALIZED ) {
                 assert( connections[i].c_sb == 0 );
                 c = &connections[i];
                 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( !ber_pvt_sb_in_use( connections[i].c_sb ));
+                assert( sd == AC_SOCKET_INVALID );
                 c = &connections[i];
                 break;
             }
 
             assert( connections[i].c_struct_state == SLAP_C_USED );
             assert( connections[i].c_conn_state != SLAP_C_INVALID );
-            assert( ber_pvt_sb_in_use( connections[i].c_sb ));
+            assert( sd != AC_SOCKET_INVALID );
         }
 
         if( c == NULL ) {
@@ -353,6 +363,7 @@ long connection_init(
     assert( c != NULL );
 
     if( c->c_struct_state == SLAP_C_UNINITIALIZED ) {
+               c->c_authmech = NULL;
         c->c_dn = NULL;
         c->c_cdn = NULL;
 
@@ -363,11 +374,10 @@ long connection_init(
 
         c->c_ops = NULL;
         c->c_pending_ops = NULL;
-               c->c_authmech = NULL;
-               c->c_authstate = NULL;
 
+               c->c_sasl_bind_mech = NULL;
 #ifdef HAVE_CYRUS_SASL
-               c->c_sasl_context = NULL;
+               c->c_sasl_bind_context = NULL;
 #endif
 
         c->c_sb = ber_sockbuf_alloc( );
@@ -384,6 +394,7 @@ long connection_init(
     ldap_pvt_thread_mutex_lock( &c->c_mutex );
 
     assert( c->c_struct_state == SLAP_C_UNUSED );
+       assert( c->c_authmech == NULL );
     assert(    c->c_dn == NULL );
     assert(    c->c_cdn == NULL );
     assert( c->c_listener_url == NULL );
@@ -392,10 +403,9 @@ long connection_init(
     assert( c->c_sock_name == NULL );
     assert( c->c_ops == NULL );
     assert( c->c_pending_ops == NULL );
-       assert( c->c_authmech == NULL );
-       assert( c->c_authstate == NULL );
+       assert( c->c_sasl_bind_mech == NULL );
 #ifdef HAVE_CYRUS_SASL
-       assert( c->c_sasl_context == NULL );
+       assert( c->c_sasl_bind_context == NULL );
 #endif
        assert( c->c_currentber == NULL );
 
@@ -418,13 +428,17 @@ long connection_init(
 
     c->c_activitytime = c->c_starttime = slap_get_time();
 
-    ber_pvt_sb_set_desc( c->c_sb, s );
-    ber_pvt_sb_set_io( c->c_sb, &ber_pvt_sb_io_tcp, NULL );
-
-    if( ber_pvt_sb_set_nonblock( c->c_sb, 1 ) < 0 ) {
+    ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_tcp, LBER_SBIOD_LEVEL_PROVIDER,
+       (void *)&s );
+    ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_readahead,
+       LBER_SBIOD_LEVEL_PROVIDER, NULL );
+#ifdef LDAP_DEBUG
+    ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_debug, INT_MAX, NULL );
+#endif
+    if( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_NONBLOCK, c /* non-NULL */ ) < 0 ) {
         Debug( LDAP_DEBUG_ANY,
             "connection_init(%d, %s): set nonblocking failed\n",
-            s, c->c_peer_name,0 );
+            s, c->c_peer_name, 0 );
     }
 
     id = c->c_connid = conn_nextid++;
@@ -436,6 +450,9 @@ long connection_init(
     if ( use_tls ) {
            c->c_is_tls = 1;
            c->c_needs_tls_accept = 1;
+    } else {
+           c->c_is_tls = 0;
+           c->c_needs_tls_accept = 0;
     }
 #endif
 
@@ -451,6 +468,7 @@ static void
 connection_destroy( Connection *c )
 {
        /* note: connections_mutex should be locked by caller */
+    ber_socket_t       sd;
 
     assert( connections != NULL );
     assert( c != NULL );
@@ -465,6 +483,10 @@ connection_destroy( Connection *c )
 
     c->c_activitytime = c->c_starttime = 0;
 
+       if(c->c_authmech != NULL ) {
+               free(c->c_authmech);
+               c->c_authmech = NULL;
+       }
     if(c->c_dn != NULL) {
         free(c->c_dn);
         c->c_dn = NULL;
@@ -482,6 +504,20 @@ connection_destroy( Connection *c )
                c->c_peer_domain = NULL;
        }
        if(c->c_peer_name != NULL) {
+#ifdef LDAP_PF_UNIX
+               /*
+                * If peer was a domain socket, unlink. Mind you,
+                * they may be un-named. Should we leave this to
+                * the client?
+                */
+               if (strncmp(c->c_peer_name, "PATH=", 5) == 0) {
+                       char *path = c->c_peer_name + 5;
+                       if (path != '\0') {
+                               (void)unlink(path);
+                       }
+               }
+#endif /* LDAP_PF_UNIX */
+
                free(c->c_peer_name);
                c->c_peer_name = NULL;
        }
@@ -489,19 +525,16 @@ connection_destroy( Connection *c )
                free(c->c_sock_name);
                c->c_sock_name = NULL;
        }
-       if(c->c_authmech != NULL ) {
-               free(c->c_authmech);
-               c->c_authmech = NULL;
-       }
-       if(c->c_authstate != NULL ) {
-               free(c->c_authstate);
-               c->c_authstate = NULL;
-       }
 
+       c->c_sasl_bind_in_progress = 0;
+       if(c->c_sasl_bind_mech != NULL) {
+               free(c->c_sasl_bind_mech);
+               c->c_sasl_bind_mech = NULL;
+       }
 #ifdef HAVE_CYRUS_SASL
-       if(c->c_sasl_context != NULL ) {
-               sasl_dispose( &c->c_sasl_context );
-               c->c_sasl_context = NULL;
+       if(c->c_sasl_bind_context != NULL ) {
+               sasl_dispose( &c->c_sasl_bind_context );
+               c->c_sasl_bind_context = NULL;
        }
 #endif
 
@@ -510,18 +543,17 @@ connection_destroy( Connection *c )
                c->c_currentber = NULL;
        }
 
-       if ( ber_pvt_sb_in_use(c->c_sb) ) {
-               int sd = ber_pvt_sb_get_desc(c->c_sb);
-
+       ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_GET_FD, &sd );
+       if ( sd != AC_SOCKET_INVALID ) {
                slapd_remove( sd, 0 );
-               ber_pvt_sb_close( c->c_sb );
 
                Statslog( LDAP_DEBUG_STATS,
                    "conn=%ld fd=%d closed\n",
                        c->c_connid, sd, 0, 0, 0 );
        }
 
-       ber_pvt_sb_destroy( c->c_sb );
+       ber_sockbuf_free( c->c_sb );
+       c->c_sb = ber_sockbuf_alloc( );
 
     c->c_conn_state = SLAP_C_INVALID;
     c->c_struct_state = SLAP_C_UNUSED;
@@ -573,30 +605,32 @@ void connection_closing( Connection *c )
        /* 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=%ld sd=%d for close\n",
-                       c->c_connid, ber_pvt_sb_get_desc( c->c_sb ), 0 );
+                       c->c_connid, sd, 0 );
 
                /* update state to closing */
                c->c_conn_state = SLAP_C_CLOSING;
 
                /* don't listen on this port anymore */
-               slapd_clr_read( ber_pvt_sb_get_desc( c->c_sb ), 1 );
-
-               /* shutdown I/O -- not yet implemented */
+               slapd_clr_read( sd, 1 );
 
                /* abandon active operations */
                connection_abandon( c );
 
                /* wake write blocked operations */
-               slapd_clr_write( ber_pvt_sb_get_desc(c->c_sb), 1 );
+               slapd_clr_write( sd, 1 );
                ldap_pvt_thread_cond_signal( &c->c_write_cv );
        }
 }
 
 static void connection_close( Connection *c )
 {
+       ber_socket_t    sd;
+
        assert( connections != NULL );
        assert( c != NULL );
        assert( c->c_struct_state == SLAP_C_USED );
@@ -604,16 +638,17 @@ static void connection_close( Connection *c )
 
        /* note: connections_mutex and c_mutex should be locked by caller */
 
+       ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_GET_FD, &sd );
        if( c->c_ops != NULL ) {
                Debug( LDAP_DEBUG_TRACE,
                        "connection_close: deferring conn=%ld sd=%d\n",
-                       c->c_connid, ber_pvt_sb_get_desc( c->c_sb ), 0 );
+                       c->c_connid, sd, 0 );
 
                return;
        }
 
        Debug( LDAP_DEBUG_TRACE, "connection_close: conn=%ld sd=%d\n",
-               c->c_connid, ber_pvt_sb_get_desc( c->c_sb ), 0 );
+               c->c_connid, sd, 0 );
 
        connection_destroy( c );
 }
@@ -712,6 +747,16 @@ connection_operation( void *arg_v )
        num_ops_initiated++;
        ldap_pvt_thread_mutex_unlock( &num_ops_mutex );
 
+       if( conn->c_sasl_bind_in_progress && tag != LDAP_REQ_BIND ) {
+               Debug( LDAP_DEBUG_ANY, "connection_operation: "
+                       "error: SASL bind in progress (tag=%ld).\n",
+                       (long) tag, 0, 0 );
+               send_ldap_result( conn, arg->co_op,
+                       rc = LDAP_OPERATIONS_ERROR,
+                       NULL, "SASL bind in progress", NULL, NULL );
+               goto operations_error;
+       }
+
        switch ( tag ) {
        case LDAP_REQ_BIND:
                rc = do_bind( conn, arg->co_op );
@@ -763,8 +808,9 @@ connection_operation( void *arg_v )
                break;
        }
 
-       if( rc == -1 ) tag = LBER_ERROR;
+       if( rc == SLAPD_DISCONNECT ) tag = LBER_ERROR;
 
+operations_error:
        ldap_pvt_thread_mutex_lock( &num_ops_mutex );
        num_ops_completed++;
        ldap_pvt_thread_mutex_unlock( &num_ops_mutex );
@@ -789,18 +835,13 @@ connection_operation( void *arg_v )
                break;
 
        case LDAP_REQ_BIND:
+               conn->c_sasl_bind_in_progress =
+                       rc == LDAP_SASL_BIND_IN_PROGRESS ? 1 : 0;
+
                if( conn->c_conn_state == SLAP_C_BINDING) {
                        conn->c_conn_state = SLAP_C_ACTIVE;
                }
-               conn->c_bind_in_progress = ( rc == LDAP_SASL_BIND_IN_PROGRESS );
-       }
-
-       ldap_pvt_thread_mutex_lock( &active_threads_mutex );
-       active_threads--;
-       if( active_threads < 1 ) {
-               ldap_pvt_thread_cond_signal(&active_threads_cond);
        }
-       ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
 
        connection_resched( conn );
 
@@ -851,6 +892,9 @@ int connection_read(ber_socket_t s)
        if ( c->c_is_tls && c->c_needs_tls_accept ) {
                rc = ldap_pvt_tls_accept( c->c_sb, NULL );
                if ( rc < 0 ) {
+                       struct timeval tv;
+                       fd_set rfd;
+
                        Debug( LDAP_DEBUG_TRACE,
                               "connection_read(%d): TLS accept error error=%d id=%ld, closing\n",
                               s, rc, c->c_connid );
@@ -858,6 +902,20 @@ int connection_read(ber_socket_t s)
                        c->c_needs_tls_accept = 0;
                        /* connections_mutex and c_mutex are locked */
                        connection_closing( c );
+
+                       /* Drain input before close, to allow SSL error codes
+                        * to propagate to client. */
+                       FD_ZERO(&rfd);
+                       FD_SET(s, &rfd);
+                       for (rc=1; rc>0;)
+                       {
+                           tv.tv_sec = 1;
+                           tv.tv_usec = 0;
+                           rc = select(s+1, &rfd, NULL, NULL, &tv);
+                           if (rc == 1)
+                               ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_DRAIN,
+                                   NULL);
+                       }
                        connection_close( c );
                } else if ( rc == 0 ) {
                        c->c_needs_tls_accept = 0;
@@ -871,7 +929,7 @@ int connection_read(ber_socket_t s)
 #define CONNECTION_INPUT_LOOP 1
 
 #ifdef DATA_READY_LOOP
-       while(!rc && ber_pvt_sb_data_ready(&c->c_sb))
+       while( !rc && ber_sockbuf_ctrl( c->c_sb, LBER_SB_DATA_READY, NULL ) )
 #elif CONNECTION_INPUT_LOOP
        while(!rc)
 #endif
@@ -890,9 +948,9 @@ int connection_read(ber_socket_t s)
                connection_close( c );
        }
 
-       if ( ber_pvt_sb_needs_read( c->c_sb ) )
+       if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_READ, NULL ) )
                slapd_set_read( s, 1 );
-       if ( ber_pvt_sb_needs_write( c->c_sb ) )
+       if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_WRITE, NULL ) )
                slapd_set_write( s, 1 );
        connection_return( c );
        ldap_pvt_thread_mutex_unlock( &connections_mutex );
@@ -921,14 +979,13 @@ connection_input(
            != LDAP_TAG_MESSAGE )
        {
                int err = errno;
+               ber_socket_t    sd;
+
+               ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_GET_FD, &sd );
 
                Debug( LDAP_DEBUG_TRACE,
                        "ber_get_next on fd %d failed errno=%d (%s)\n",
-                       ber_pvt_sb_get_desc( conn->c_sb ), err, STRERROR(err) );
-               Debug( LDAP_DEBUG_TRACE,
-                       "\t*** got %ld of %lu so far\n",
-                       (long)(conn->c_currentber->ber_rwptr - conn->c_currentber->ber_buf),
-                       conn->c_currentber->ber_len, 0 );
+                       sd, err, sock_errstr(err) );
 
                if ( err != EWOULDBLOCK && err != EAGAIN ) {
                        /* log, close and send error */
@@ -996,11 +1053,16 @@ connection_resched( Connection *conn )
        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=%ld sd=%d\n",
-                       conn->c_connid, ber_pvt_sb_get_desc( conn->c_sb ), 0 );
+                       conn->c_connid, sd, 0 );
 
+               ldap_pvt_thread_mutex_lock( &connections_mutex );
                connection_close( conn );
+               ldap_pvt_thread_mutex_unlock( &connections_mutex );
                return 0;
        }
 
@@ -1049,11 +1111,9 @@ static int connection_op_activate( Connection *conn, Operation *op )
        arg->co_conn = conn;
        arg->co_op = op;
 
-       arg->co_op->o_bind_in_progress = conn->c_bind_in_progress;
-
        arg->co_op->o_dn = ch_strdup( tmpdn != NULL ? tmpdn : "" );
        arg->co_op->o_ndn = ch_strdup( arg->co_op->o_dn );
-       (void) dn_normalize_case( arg->co_op->o_ndn );
+       (void) dn_normalize( arg->co_op->o_ndn );
 
        arg->co_op->o_protocol = conn->c_protocol;
        arg->co_op->o_connid = conn->c_connid;
@@ -1068,12 +1128,8 @@ static int connection_op_activate( Connection *conn, Operation *op )
                free( tmpdn );
        }
 
-       ldap_pvt_thread_mutex_lock( &active_threads_mutex );
-       active_threads++;
-       ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
-
-       status = ldap_pvt_thread_create( &arg->co_op->o_tid, 1,
-                                        connection_operation, (void *) arg );
+       status = ldap_pvt_thread_pool_submit( &connection_pool,
+               connection_operation, (void *) arg );
 
        if ( status != 0 ) {
                Debug( LDAP_DEBUG_ANY,
@@ -1113,9 +1169,9 @@ int connection_write(ber_socket_t s)
 
        ldap_pvt_thread_cond_signal( &c->c_write_cv );
 
-       if ( ber_pvt_sb_needs_read( c->c_sb ) )
+       if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_READ, NULL ) )
                slapd_set_read( s, 1 );
-       if ( ber_pvt_sb_needs_write( c->c_sb ) )
+       if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_WRITE, NULL ) )
                slapd_set_write( s, 1 );
        connection_return( c );
        ldap_pvt_thread_mutex_unlock( &connections_mutex );
index 03100eb05bedd4ffc5bcbb80c774be1ad534a3a8..e99eeed1e5909301c8c437bcf9ceadcc7be78ef2 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /* 
- * Copyright 1999 The OpenLDAP Foundation.
+ * Copyright 1999-2000 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
@@ -48,7 +48,7 @@ int get_ctrls(
 
        if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
                if( tag == LBER_ERROR ) {
-                       rc = -1;
+                       rc = SLAPD_DISCONNECT;
                        errmsg = "unexpected data in PDU";
                }
 
@@ -58,7 +58,7 @@ int get_ctrls(
        Debug( LDAP_DEBUG_TRACE, "=> get_ctrls\n", 0, 0, 0 );
 
        if( op->o_protocol < LDAP_VERSION3 ) {
-               rc = -1;
+               rc = SLAPD_DISCONNECT;
                errmsg = "controls require LDAPv3";
                goto return_results;
        }
@@ -74,7 +74,7 @@ int get_ctrls(
        }
 #endif
 
-       ctrls[nctrls] = NULL;
+       *ctrls[nctrls] = NULL;
 
        for( tag = ber_first_element( ber, &len, &opaque );
                tag != LBER_ERROR;
@@ -120,7 +120,7 @@ int get_ctrls(
                                0, 0, 0 );
                        *ctrls = NULL;
                        ldap_controls_free( tctrls );
-                       rc = -1;
+                       rc = SLAPD_DISCONNECT;
                        errmsg = "decoding controls error";
                        goto return_results;
                }
@@ -136,7 +136,7 @@ int get_ctrls(
                                        0, 0, 0 );
                                *ctrls = NULL;
                                ldap_controls_free( tctrls );
-                               rc = -1;
+                               rc = SLAPD_DISCONNECT;
                                errmsg = "decoding controls error";
                                goto return_results;
                        }
@@ -158,7 +158,7 @@ int get_ctrls(
                                        0, 0, 0 );
                                *ctrls = NULL;
                                ldap_controls_free( tctrls );
-                               rc = -1;
+                               rc = SLAPD_DISCONNECT;
                                errmsg = "decoding controls error";
                                goto return_results;
                        }
@@ -180,7 +180,7 @@ return_results:
                nctrls, rc, errmsg ? errmsg : "");
 
        if( sendres && rc != LDAP_SUCCESS ) {
-               if( rc == -1 ) {
+               if( rc == SLAPD_DISCONNECT ) {
                        send_ldap_disconnect( conn, op, rc, errmsg );
                } else {
                        send_ldap_result( conn, op, rc,
index b5e55316907db793a7cfa7f98f5ae28a3a5db47c..61a7989be51509ac6cc3b1bc82e5d95a21ec03a5 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -27,10 +27,25 @@ int allow_severity = LOG_INFO;
 int deny_severity = LOG_NOTICE;
 #endif /* TCP Wrappers */
 
+#ifdef LDAP_PF_UNIX
+#include <sys/stat.h>
+#endif /* LDAP_PF_UNIX */
+
 /* globals */
 time_t starttime;
 ber_socket_t dtblsize;
 
+typedef union slap_sockaddr {
+       struct sockaddr sa_addr;
+       struct sockaddr_in sa_in_addr;
+#ifdef LDAP_PF_INET6
+       struct sockaddr_in6 sa_in6_addr;
+#endif
+#ifdef LDAP_PF_UNIX
+       struct sockaddr_un sa_un_addr;
+#endif
+} Sockaddr;
+
 typedef struct slap_listener {
        char* sl_url;
        char* sl_name;
@@ -38,19 +53,27 @@ typedef struct slap_listener {
        int             sl_is_tls;
 #endif
        ber_socket_t            sl_sd;
-       struct sockaddr_in      sl_addr;
+       Sockaddr sl_sa;
+#define sl_addr        sl_sa.sa_in_addr
 } Listener;
 
 Listener **slap_listeners = NULL;
 
 static ber_socket_t wake_sds[2];
 
+#ifdef NO_THREADS
+static int waking;
+#define WAKE_LISTENER(w) \
+((w && !waking) ? tcp_write( wake_sds[1], "0", 1 ), waking=1 : 0)
+#else
 #define WAKE_LISTENER(w) \
 do { if (w) tcp_write( wake_sds[1], "0", 1 ); } while(0)
+#endif
 
-#ifdef HAVE_WINSOCK2
+#ifdef HAVE_NT_SERVICE_MANAGER
 /* in nt_main.c */
 extern ldap_pvt_thread_cond_t                  started_event;
+extern int       is_NT_Service;
 #endif
 
 #ifndef HAVE_WINSOCK
@@ -136,7 +159,8 @@ void slapd_set_write(ber_socket_t s, int wake) {
        ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
 
        assert( FD_ISSET( s, &slap_daemon.sd_actives) );
-       FD_SET( (unsigned) s, &slap_daemon.sd_writers );
+       if (!FD_ISSET(s, &slap_daemon.sd_writers))
+           FD_SET( (unsigned) s, &slap_daemon.sd_writers );
 
        ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
        WAKE_LISTENER(wake);
@@ -156,7 +180,8 @@ void slapd_set_read(ber_socket_t s, int wake) {
        ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
 
        assert( FD_ISSET( s, &slap_daemon.sd_actives) );
-       FD_SET( s, &slap_daemon.sd_readers );
+       if (!FD_ISSET(s, &slap_daemon.sd_readers))
+           FD_SET( s, &slap_daemon.sd_readers );
 
        ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
        WAKE_LISTENER(wake);
@@ -169,17 +194,19 @@ static void slapd_close(ber_socket_t s) {
 }
 
 
-static Listener *
-open_listener(
-       const char* url,
-       int port,
-       int tls_port )
+static Listener * open_listener( const char* url )
 {
        int     tmp, rc;
        Listener l;
        Listener *li;
        LDAPURLDesc *lud;
        char *s;
+       int port;
+#ifdef HAVE_GETADDRINFO
+       char serv[7];
+       struct addrinfo hints, *res, *sai;
+       int err;
+#endif
 
        rc = ldap_url_parse( url, &lud );
 
@@ -191,7 +218,7 @@ open_listener(
        }
 
 #ifndef HAVE_TLS
-       if( lud->lud_ldaps ) {
+       if( ldap_pvt_url_scheme2tls( lud->lud_scheme ) ) {
                Debug( LDAP_DEBUG_ANY,
                        "daemon: TLS not supported (%s)\n",
                        url, 0, 0 );
@@ -200,17 +227,102 @@ open_listener(
        }
 
        if(! lud->lud_port ) {
-               lud->lud_port = port;
+               lud->lud_port = LDAP_PORT;
        }
 
 #else
-       l.sl_is_tls = lud->lud_ldaps;
+       l.sl_is_tls = ldap_pvt_url_scheme2tls( lud->lud_scheme );
 
        if(! lud->lud_port ) {
-               lud->lud_port = lud->lud_ldaps ? tls_port : port;
+               lud->lud_port = l.sl_is_tls ? LDAPS_PORT : LDAP_PORT;
        }
 #endif
 
+#ifdef HAVE_GETADDRINFO
+       memset( &hints, '\0', sizeof(hints) );
+       hints.ai_flags = AI_PASSIVE;
+       hints.ai_family = AF_UNSPEC;
+       hints.ai_socktype = SOCK_STREAM;
+
+#  ifdef LDAP_PF_UNIX
+       if ( ldap_pvt_url_scheme2proto(lud->lud_scheme) == LDAP_PROTO_IPC ) {
+               if ( lud->lud_host == NULL || lud->lud_host[0] == '\0' ) {
+                       err = getaddrinfo(NULL, "/tmp/.ldap-sock", &hints, &res);
+                       if (!err)
+                               unlink( "/tmp/.ldap-sock" );
+               } else {
+                       err = getaddrinfo(NULL, lud->lud_host, &hints, &res);
+                       if (!err)
+                               unlink( lud->lud_host );
+               }
+       } else
+#  endif /* LDAP_PF_UNIX */
+       {
+               snprintf(serv, sizeof serv, "%d", lud->lud_port);
+               if( lud->lud_host == NULL || lud->lud_host[0] == '\0'
+                       || strcmp(lud->lud_host, "*") == 0 )
+               {
+                       err = getaddrinfo(NULL, serv, &hints, &res);
+               } else {
+                       err = getaddrinfo(lud->lud_host, serv, &hints, &res);
+               }
+       }
+
+       if ( err ) {
+               Debug( LDAP_DEBUG_ANY, "daemon: getaddrinfo failed\n", 0, 0, 0);
+               ldap_free_urldesc( lud );
+               return NULL;
+       }
+
+       ldap_free_urldesc( lud );
+       sai = res;
+       do {
+               l.sl_sd = socket( sai->ai_family, sai->ai_socktype, sai->ai_protocol);
+               if ( l.sl_sd == AC_SOCKET_INVALID ) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "daemon: socket() failed errno=%d (%s)\n", err,
+                               sock_errstr(err), 0 );
+                       continue;
+               }
+
+               if ( sai->ai_family != AF_UNIX ) {
+#else
+
+       if ( ldap_pvt_url_scheme2proto(lud->lud_scheme) == LDAP_PROTO_IPC ) {
+#ifdef LDAP_PF_UNIX
+               port = 0;
+               (void) memset( (void *)&l.sl_sa.sa_un_addr, '\0', sizeof(l.sl_sa.sa_un_addr) );
+
+               l.sl_sa.sa_un_addr.sun_family = AF_UNIX;
+
+               /* hack: overload the host to be the path */
+               if ( lud->lud_host == NULL || lud->lud_host[0] == '\0' ) {
+                       strcpy( l.sl_sa.sa_un_addr.sun_path, "/tmp/.ldap-sock" );
+               } else {
+                       if ( strlen(lud->lud_host) > (sizeof(l.sl_sa.sa_un_addr.sun_path) - 1) ) {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "daemon: domain socket path (%s) too long in URL: %s",
+                                       lud->lud_host, url, 0);
+                               ldap_free_urldesc( lud );
+                               return NULL;
+                       }
+                       strcpy( l.sl_sa.sa_un_addr.sun_path, lud->lud_host );
+               }
+               unlink( l.sl_sa.sa_un_addr.sun_path ); 
+#if 0
+               /* I don't think we need to set this. */
+               l.sl_sa.sa_un_addr.sun_len = sizeof( l.sl_sa.sa_un_addr.sun_len ) +
+                       sizeof( l.sl_sa.sa_un_addr.sun_family ) +
+                       strlen( l.sl_sa.sa_un_addr.sun_path ) + 1;
+#endif
+#else
+               Debug( LDAP_DEBUG_ANY, "daemon: URL scheme not supported: %s",
+                       url, 0, 0);
+               ldap_free_urldesc( lud );
+               return NULL;
+#endif /* LDAP_PF_UNIX */
+       } else {
+
        port = lud->lud_port;
 
        (void) memset( (void*) &l.sl_addr, '\0', sizeof(l.sl_addr) );
@@ -228,7 +340,8 @@ open_listener(
                if( !inet_aton( lud->lud_host, &l.sl_addr.sin_addr ) ) {
                        struct hostent *he = gethostbyname( lud->lud_host );
                        if( he == NULL ) {
-                               Debug( LDAP_DEBUG_ANY, "invalid host (%s) in URL: %s",
+                               Debug( LDAP_DEBUG_ANY,
+                                       "daemon: invalid host (%s) in URL: %s",
                                        lud->lud_host, url, 0);
                                ldap_free_urldesc( lud );
                                return NULL;
@@ -238,11 +351,12 @@ open_listener(
                               sizeof( l.sl_addr.sin_addr ) );
                }
        }
+       }
 
        ldap_free_urldesc( lud );
 
-
-       if ( (l.sl_sd = socket( AF_INET, SOCK_STREAM, 0 )) == AC_SOCKET_INVALID ) {
+       l.sl_sd = socket( l.sl_sa.sa_addr.sa_family, SOCK_STREAM, 0 );
+       if ( l.sl_sd == AC_SOCKET_INVALID ) {
                int err = sock_errno();
                Debug( LDAP_DEBUG_ANY,
                        "daemon: socket() failed errno=%d (%s)\n", err,
@@ -260,6 +374,12 @@ open_listener(
        }
 #endif
 
+#ifdef LDAP_PF_UNIX
+       /* for IP sockets only */
+       if ( l.sl_sa.sa_addr.sa_family == AF_INET ) {
+#endif /* LDAP_PF_UNIX */
+#endif /* HAVE_GETADDRINFO */
+
 #ifdef SO_REUSEADDR
        /* enable address reuse */
        tmp = 1;
@@ -297,7 +417,87 @@ open_listener(
        }
 #endif
 
-       rc = bind( l.sl_sd, (struct sockaddr *) &l.sl_addr, sizeof(l.sl_addr) );
+#ifdef HAVE_GETADDRINFO
+               } /* sai->ai_family != AF_UNIX */
+               if (!bind(l.sl_sd, sai->ai_addr, sai->ai_addrlen))
+                       break;
+               err = sock_errno();
+               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 );
+       } while ((sai = sai->ai_next) != NULL);
+
+       if (!sai) {
+               Debug( LDAP_DEBUG_ANY, "daemon: bind(%ld) failed\n",
+                       (long) l.sl_sd, 0, 0 );
+               return NULL;
+       }
+
+       switch ( sai->ai_family ) {
+#  ifdef LDAP_PF_UNIX
+       case AF_UNIX:
+               if ( chmod( (char *)sai->ai_addr, S_IRWXU ) < 0 ) {
+                       err = sock_errno();
+                       Debug( LDAP_DEBUG_ANY, "daemon: fchmod(%ld) failed errno=%d (%s)",
+                               (long) l.sl_sd, err, sock_errstr(err) );
+                       tcp_close( l.sl_sd );
+                       return NULL;
+               }
+               l.sl_name = ch_malloc( strlen((char *)sai->ai_addr) + sizeof("PATH=") );
+               sprintf( l.sl_name, "PATH=%s", sai->ai_addr );
+               break;
+#  endif /* LDAP_PF_UNIX */
+
+       case AF_INET: {
+               char addr[INET_ADDRSTRLEN];
+               inet_ntop( AF_INET,
+                       &((struct sockaddr_in *)sai->ai_addr)->sin_addr,
+                       addr, sizeof(addr) );
+               l.sl_name = ch_malloc( strlen(addr) + strlen(serv) + sizeof("IP=:") );
+               sprintf( l.sl_name, "IP=%s:%s", addr, serv );
+       } break;
+
+#  ifdef LDAP_PF_INET6
+       case AF_INET6: {
+               char addr[INET6_ADDRSTRLEN];
+               inet_ntop( AF_INET6,
+                       &((struct sockaddr_in6 *)sai->ai_addr)->sin6_addr,
+                       addr, sizeof addr);
+               l.sl_name = ch_malloc( strlen(addr) + strlen(serv) + sizeof("IP= ") );
+               sprintf( l.sl_name, "IP=%s %s", addr, serv );
+       } break;
+#  endif /* LDAP_PF_INET6 */
+
+       default:
+               Debug( LDAP_DEBUG_ANY, "daemon: unsupported address family (%d)\n",
+                       (int) sai->ai_family, 0, 0 );
+               break;
+       }
+#else
+#ifdef LDAP_PF_UNIX
+       /* close conditional */
+       }
+#endif /* LDAP_PF_UNIX */
+
+       switch ( l.sl_sa.sa_addr.sa_family ) {
+#ifdef LDAP_PF_UNIX
+               case AF_UNIX:
+                       rc = bind( l.sl_sd, (struct sockaddr *)&l.sl_sa,
+                               sizeof(l.sl_sa.sa_un_addr) );
+                       break;
+#endif
+
+               case AF_INET:
+                       rc = bind( l.sl_sd, (struct sockaddr *)&l.sl_sa,
+                               sizeof(l.sl_sa.sa_in_addr) );
+                       break;
+
+               default:
+                       rc = AC_SOCKET_ERROR;
+                       errno = EINVAL;
+                       break;
+       }
+
        if ( rc == AC_SOCKET_ERROR ) {
                int err = sock_errno();
                Debug( LDAP_DEBUG_ANY, "daemon: bind(%ld) failed errno=%d (%s)\n",
@@ -306,13 +506,39 @@ open_listener(
                return NULL;
        }
 
-       l.sl_url = ch_strdup( url );
+       switch ( l.sl_sa.sa_addr.sa_family ) {
+#ifdef LDAP_PF_UNIX
+               case AF_UNIX:
+                       if ( chmod( l.sl_sa.sa_un_addr.sun_path, S_IRWXU ) < 0 ) {
+                               int err = sock_errno();
+                               Debug( LDAP_DEBUG_ANY,
+                                       "daemon: chmod(%ld) failed errno=%d (%s)",
+                                       (long) l.sl_sd, err, sock_errstr(err) );
+                               tcp_close( l.sl_sd );
+                               return NULL;
+                       }
 
-       l.sl_name = ch_malloc( sizeof("IP=255.255.255.255:65336") );
-       s = inet_ntoa( l.sl_addr.sin_addr );
-       sprintf( l.sl_name, "IP=%s:%d",
-               s != NULL ? s : "unknown" , port );
+                       l.sl_name = ch_malloc( strlen(l.sl_sa.sa_un_addr.sun_path)
+                               + sizeof("PATH=") );
+                       sprintf( l.sl_name, "PATH=%s", l.sl_sa.sa_un_addr.sun_path );
+                       break;
+#endif /* LDAP_PF_UNIX */
 
+               case AF_INET:
+                       l.sl_name = ch_malloc( sizeof("IP=255.255.255.255:65336") );
+                       s = inet_ntoa( l.sl_addr.sin_addr );
+                       sprintf( l.sl_name, "IP=%s:%d",
+                               s != NULL ? s : "unknown" , port );
+                       break;
+
+               default:
+                       l.sl_name = ch_strdup( "UNKNOWN" );
+                       break;
+       }
+
+#endif /* HAVE_GETADDRINFO */
+
+       l.sl_url = ch_strdup( url );
        li = ch_malloc( sizeof( Listener ) );
        *li = l;
 
@@ -325,17 +551,13 @@ open_listener(
 static int sockinit(void);
 static int sockdestroy(void);
 
-int slapd_daemon_init(char *urls, int port, int tls_port )
+int slapd_daemon_init( const char *urls )
 {
        int i, rc;
        char **u;
 
-#ifndef HAVE_TLS
-       assert( tls_port == 0 );
-#endif
-
-       Debug( LDAP_DEBUG_ARGS, "daemon_init: %s (%d/%d)\n",
-               urls ? urls : "<null>", port, tls_port );
+       Debug( LDAP_DEBUG_ARGS, "daemon_init: %s\n",
+               urls ? urls : "<null>", 0, 0 );
 
        if( (rc = sockinit()) != 0 ) {
                return rc;
@@ -400,7 +622,7 @@ int slapd_daemon_init(char *urls, int port, int tls_port )
        slap_listeners = ch_malloc( (i+1)*sizeof(Listener *) );
 
        for(i = 0; u[i] != NULL; i++ ) {
-               slap_listeners[i] = open_listener( u[i], port, tls_port );
+               slap_listeners[i] = open_listener( u[i] );
 
                if( slap_listeners[i] == NULL ) {
                        charray_free( u );
@@ -454,7 +676,7 @@ slapd_daemon_task(
                slapd_add( slap_listeners[l]->sl_sd );
        }
 
-#ifdef HAVE_WINSOCK
+#ifdef HAVE_NT_SERVICE_MANAGER
        if ( started_event != NULL ) {
                ldap_pvt_thread_cond_signal( &started_event );
        }
@@ -475,9 +697,9 @@ slapd_daemon_task(
 
                fd_set                  readfds;
                fd_set                  writefds;
+               Sockaddr                from;
 
-               struct sockaddr_in      from;
-#if defined(SLAPD_RLOOKUPS) || defined(HAVE_TCPD)
+#if defined(SLAPD_RLOOKUPS)
         struct hostent         *hp;
 #endif
                struct timeval          zero;
@@ -511,12 +733,14 @@ slapd_daemon_task(
                memcpy( &readfds, &slap_daemon.sd_readers, sizeof(fd_set) );
                memcpy( &writefds, &slap_daemon.sd_writers, sizeof(fd_set) );
 #endif
+               assert(!FD_ISSET(wake_sds[0], &readfds));
                FD_SET( wake_sds[0], &readfds );
 
                for ( l = 0; slap_listeners[l] != NULL; l++ ) {
                        if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
                                continue;
-                       FD_SET( slap_listeners[l]->sl_sd, &readfds );
+                       if (!FD_ISSET(slap_listeners[l]->sl_sd, &readfds))
+                           FD_SET( slap_listeners[l]->sl_sd, &readfds );
                }
 
 #ifndef HAVE_WINSOCK
@@ -527,9 +751,7 @@ slapd_daemon_task(
 
                ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
 
-               ldap_pvt_thread_mutex_lock( &active_threads_mutex );
-               at = active_threads;
-               ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
+               at = ldap_pvt_thread_pool_backload(&connection_pool);
 
 #if defined( HAVE_YIELDING_SELECT ) || defined( NO_THREADS )
                tvp = NULL;
@@ -559,8 +781,13 @@ slapd_daemon_task(
                case -1: {      /* failure - try again */
                                int err = sock_errno();
 
-                               if( err == EBADF && ++ebadf < SLAPD_EBADF_LIMIT) {
-                                       continue;
+                               if( err == EBADF 
+#ifdef HAVE_WINSOCK
+                                       || err == WSAENOTSOCK   /* you'd think this would be EBADF */
+#endif
+                               ) {
+                                       if (++ebadf < SLAPD_EBADF_LIMIT)
+                                               continue;
                                }
 
                                if( err != EINTR ) {
@@ -588,8 +815,11 @@ slapd_daemon_task(
                }
 
                if( FD_ISSET( wake_sds[0], &readfds ) ) {
-                       char c;
-                       tcp_read( wake_sds[0], &c, 1 );
+                       char c[BUFSIZ];
+                       tcp_read( wake_sds[0], c, sizeof(c) );
+#ifdef NO_THREADS
+                       waking = 0;
+#endif
                        continue;
                }
 
@@ -600,8 +830,15 @@ slapd_daemon_task(
 
                        char    *dnsname;
                        char    *peeraddr;
-
+#ifdef LDAP_PF_UNIX
+                       char    peername[MAXPATHLEN + sizeof("PATH=")];
+#elif defined(LDAP_PF_INET6)
+                       char    peername[sizeof("IP=ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 65535")];
+#else
                        char    peername[sizeof("IP=255.255.255.255:65336")];
+#endif /* LDAP_PF_UNIX */
+
+                       peername[0] = '\0';
 
                        if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
                                continue;
@@ -657,44 +894,76 @@ slapd_daemon_task(
                                continue;
                        }
 
-                       peeraddr = inet_ntoa( from.sin_addr );
+                       switch ( from.sa_addr.sa_family ) {
+#  ifdef LDAP_PF_UNIX
+                       case AF_UNIX:
+                               sprintf( peername, "PATH=%s", from.sa_un_addr.sun_path );
+                               break;
+#endif /* LDAP_PF_UNIX */
+
+#  ifdef LDAP_PF_INET6
+                       case AF_INET6: {
+                               char addr[INET6_ADDRSTRLEN];
+                               sprintf( peername, "IP=%s %d",
+                                       inet_ntop( AF_INET6,
+                                               &from.sa_in6_addr.sin6_addr,
+                                           addr, sizeof addr) ? addr : "unknown",
+                                       (unsigned) ntohs( from.sa_in6_addr.sin6_port ) );
+                       } break;
+#  endif /* LDAP_PF_INET6 */
+
+                       case AF_INET:
+                       peeraddr = inet_ntoa( from.sa_in_addr.sin_addr );
                        sprintf( peername, "IP=%s:%d",
                                peeraddr != NULL ? peeraddr : "unknown",
-                               (unsigned) ntohs( from.sin_port ) );
-
-#if defined(SLAPD_RLOOKUPS) || defined(HAVE_TCPD)
-                       hp = gethostbyaddr( (char *)
-                           &(from.sin_addr.s_addr),
-                           sizeof(from.sin_addr.s_addr), AF_INET );
+                               (unsigned) ntohs( from.sa_in_addr.sin_port ) );
+                               break;
 
-                       if(hp) {
-                               dnsname = ldap_pvt_str2lower( hp->h_name );
-
-                       } else {
-                               dnsname = NULL;
+                       default:
+                               slapd_close(s);
+                               continue;
                        }
-#else
-                       dnsname = NULL;
+                       if ( ( from.sa_addr.sa_family == AF_INET ) 
+#ifdef LDAP_PF_INET6
+                               || ( from.sa_addr.sa_family == AF_INET6 )
 #endif
+                       ) {
+#ifdef SLAPD_RLOOKUPS
+#  ifdef LDAP_PF_INET6
+                               if ( from.sa_addr.sa_family == AF_INET6 )
+                                       hp = gethostbyaddr(
+                                               (char *)&(from.sa_in6_addr.sin6_addr),
+                                               sizeof(from.sa_in6_addr.sin6_addr),
+                                               AF_INET6 );
+                               else
+#  endif LDAP_PF_INET6
+                               hp = gethostbyaddr(
+                                       (char *) &(from.sa_in_addr.sin_addr),
+                                       sizeof(from.sa_in_addr.sin_addr),
+                                       AF_INET );
+                               dnsname = hp ? ldap_pvt_str2lower( hp->h_name ) : NULL;
+#else
+                               dnsname = NULL;
+#endif /* SLAPD_RLOOKUPS */
 
 #ifdef HAVE_TCPD
-                       if( !hosts_ctl("slapd",
-                               dnsname != NULL ? dnsname : STRING_UNKNOWN,
-                               peeraddr != NULL ? peeraddr : STRING_UNKNOWN,
-                               STRING_UNKNOWN ))
-                       {
-                               /* DENY ACCESS */
-                               Statslog( LDAP_DEBUG_ANY,
-                                "fd=%ld connection from %s (%s) denied.\n",
-                                       (long) s,
-                                       dnsname != NULL ? dnsname : "unknown",
-                                       peeraddr != NULL ? peeraddr : "unknown",
-                                 0, 0 );
-
-                               slapd_close(s);
-                               continue;
-                       }
+                               if ( !hosts_ctl("slapd",
+                                               dnsname != NULL ? dnsname : STRING_UNKNOWN,
+                                               peeraddr != NULL ? peeraddr : STRING_UNKNOWN,
+                                               STRING_UNKNOWN ))
+                               {
+                                       /* DENY ACCESS */
+                                       Statslog( LDAP_DEBUG_ANY,
+                                               "fd=%ld connection from %s (%s) denied.\n",
+                                               (long) s,
+                                               dnsname != NULL ? dnsname : "unknown",
+                                               peeraddr != NULL ? peeraddr : "unknown",
+                                               0, 0 );
+                                       slapd_close(s);
+                                       continue;
+                               }
 #endif /* HAVE_TCPD */
+                       }
 
                        if( (id = connection_init(s,
                                slap_listeners[l]->sl_url,
@@ -859,6 +1128,13 @@ slapd_daemon_task(
                        0, 0, 0 );
 
        } else if ( slapd_shutdown < 0 ) {
+#ifdef HAVE_NT_SERVICE_MANAGER
+               if (slapd_shutdown == -1)
+                   Debug( LDAP_DEBUG_TRACE,
+                         "daemon: shutdown initiated by Service Manager.\n",
+                         0, 0, 0);
+               else
+#endif
                Debug( LDAP_DEBUG_TRACE,
                        "daemon: abnormal condition, shutdown initiated.\n",
                        0, 0, 0 );
@@ -870,19 +1146,21 @@ slapd_daemon_task(
 
        for ( l = 0; slap_listeners[l] != NULL; l++ ) {
                if ( slap_listeners[l]->sl_sd != AC_SOCKET_INVALID ) {
+#ifdef LDAP_PF_UNIX
+                       if ( slap_listeners[l]->sl_sa.sa_addr.sa_family == AF_UNIX ) {
+                               unlink( slap_listeners[l]->sl_sa.sa_un_addr.sun_path );
+                       }
+#endif /* LDAP_PF_UNIX */
                        slapd_close( slap_listeners[l]->sl_sd );
                        break;
                }
        }
 
-       ldap_pvt_thread_mutex_lock( &active_threads_mutex );
        Debug( LDAP_DEBUG_ANY,
            "slapd shutdown: waiting for %d threads to terminate\n",
-           active_threads, 0, 0 );
-       while ( active_threads > 0 ) {
-               ldap_pvt_thread_cond_wait(&active_threads_cond, &active_threads_mutex);
-       }
-       ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
+           ldap_pvt_thread_pool_backload(&connection_pool), 0, 0 );
+
+       ldap_pvt_thread_pool_destroy(&connection_pool, 1);
 
        return NULL;
 }
@@ -989,7 +1267,22 @@ static int sockdestroy(void)
 RETSIGTYPE
 slap_sig_shutdown( int sig )
 {
+       Debug(LDAP_DEBUG_TRACE, "slap_sig_shutdown: signal %d\n", sig, 0, 0);
+
+       /*
+        * If the NT Service Manager is controlling the server, we don't
+        * want SIGBREAK to kill the server. For some strange reason,
+        * SIGBREAK is generated when a user logs out.
+        */
+
+#if HAVE_NT_SERVICE_MANAGER && SIGBREAK
+       if (is_NT_Service && sig == SIGBREAK)
+           Debug(LDAP_DEBUG_TRACE, "slap_sig_shutdown: SIGBREAK ignored.\n",
+                 0, 0, 0);
+       else
+#endif
        slapd_shutdown = sig;
+
        WAKE_LISTENER(1);
 
        /* reinstall self */
index 292e1019e4c23b6e5255f156347aaba1411ac620..ad6988ef9ead5ddc4cc4b4f4c8fb6b8e232a4026 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
@@ -22,6 +22,7 @@
 #include <ac/string.h>
 #include <ac/socket.h>
 
+#include "ldap_pvt.h"
 #include "slap.h"
 
 int
@@ -30,49 +31,42 @@ do_delete(
     Operation  *op
 )
 {
-       char    *ndn;
+       char *dn, *ndn = NULL;
+       const char *text;
        Backend *be;
        int rc;
 
        Debug( LDAP_DEBUG_TRACE, "do_delete\n", 0, 0, 0 );
 
-       if( op->o_bind_in_progress ) {
-               Debug( LDAP_DEBUG_ANY, "do_delete: SASL bind in progress.\n",
-                       0, 0, 0 );
-               send_ldap_result( conn, op, LDAP_SASL_BIND_IN_PROGRESS,
-                       NULL, "SASL bind in progress", NULL, NULL );
-               return LDAP_SASL_BIND_IN_PROGRESS;
-       }
-
        /*
         * Parse the delete request.  It looks like this:
         *
         *      DelRequest := DistinguishedName
         */
 
-       if ( ber_scanf( op->o_ber, "a", &ndn ) == LBER_ERROR ) {
+       if ( ber_scanf( op->o_ber, "a", &dn ) == LBER_ERROR ) {
                Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
                send_ldap_disconnect( conn, op,
                        LDAP_PROTOCOL_ERROR, "decoding error" );
-               return -1;
+               return SLAPD_DISCONNECT;
        }
 
-       if(     dn_normalize_case( ndn ) == NULL ) {
-               Debug( LDAP_DEBUG_ANY, "do_delete: invalid dn (%s)\n", ndn, 0, 0 );
+       if( ( rc = get_ctrls( conn, op, 1 ) ) != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_ANY, "do_delete: get_ctrls failed\n", 0, 0, 0 );
+               goto cleanup;
+       } 
+
+       ndn = ch_strdup( dn );
+
+       if(     dn_normalize( ndn ) == NULL ) {
+               Debug( LDAP_DEBUG_ANY, "do_delete: invalid dn (%s)\n", dn, 0, 0 );
                send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
                    "invalid DN", NULL, NULL );
-               free( ndn );
-               return rc;
+               goto cleanup;
        }
 
-       if( ( rc = get_ctrls( conn, op, 1 ) ) != LDAP_SUCCESS ) {
-               free( ndn );
-               Debug( LDAP_DEBUG_ANY, "do_add: get_ctrls failed\n", 0, 0, 0 );
-               return rc;
-       } 
-
-       Debug( LDAP_DEBUG_ARGS, "do_delete: dn (%s)\n", ndn, 0, 0 );
-       Debug( LDAP_DEBUG_STATS, "DEL dn=\"%s\"\n", ndn, 0, 0 );
+       Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d DEL dn=\"%s\"\n",
+               op->o_connid, op->o_opid, dn, 0, 0 );
 
        /*
         * We could be serving multiple database backends.  Select the
@@ -82,17 +76,24 @@ do_delete(
        if ( (be = select_backend( ndn )) == NULL ) {
                send_ldap_result( conn, op, rc = LDAP_REFERRAL,
                        NULL, NULL, default_referral, NULL );
-               free( ndn );
-               return rc;
+               goto cleanup;
+       }
+
+       /* make sure this backend recongizes critical controls */
+       rc = backend_check_controls( be, conn, op, &text ) ;
+
+       if( rc != LDAP_SUCCESS ) {
+               send_ldap_result( conn, op, rc,
+                       NULL, text, NULL, NULL );
+               goto cleanup;
        }
 
        if ( global_readonly || be->be_readonly ) {
                Debug( LDAP_DEBUG_ANY, "do_delete: database is read-only\n",
                       0, 0, 0 );
-               free( ndn );
-               send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
-                                 NULL, "database is read-only", NULL, NULL );
-               return LDAP_UNWILLING_TO_PERFORM;
+               send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
+                                 NULL, "directory is read-only", NULL, NULL );
+               goto cleanup;
        }
 
        /* deref suffix alias if appropriate */
@@ -111,13 +112,13 @@ do_delete(
                        strcmp( be->be_update_ndn, op->o_ndn ) == 0 )
 #endif
                {
-                       if ( (*be->be_delete)( be, conn, op, ndn ) == 0 ) {
+                       if ( (*be->be_delete)( be, conn, op, dn, ndn ) == 0 ) {
 #ifdef SLAPD_MULTIMASTER
                                if (be->be_update_ndn == NULL ||
                                        strcmp( be->be_update_ndn, op->o_ndn ))
 #endif
                                {
-                                       replog( be, op, ndn, NULL );
+                                       replog( be, op, dn, NULL );
                                }
                        }
 #ifndef SLAPD_MULTIMASTER
@@ -129,9 +130,10 @@ do_delete(
 
        } else {
                send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
-                       NULL, "Function not implemented", NULL, NULL );
+                       NULL, "operation not supported within namingContext", NULL, NULL );
        }
-
-       free( ndn );
+cleanup:
+       if( ndn != NULL ) free( ndn );
+       free( dn );
        return rc;
 }
index d2a7daa8e8d57f5a7792d1aba330c526ba0114b6..dd3a8ef76dfaadd371f19cfb204c9c041132c52f 100644 (file)
@@ -1,7 +1,7 @@
 /* dn.c - routines for dealing with distinguished names */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 #define B4SEPARATOR            8
 
 /*
- * dn_normalize - put dn into a canonical format.  the dn is
- * normalized in place, as well as returned if valid.
+ * dn_validate - validate and compress dn.  the dn is
+ * compressed in place are returned if valid.
  */
 
 char *
-dn_normalize( char *dn )
+dn_validate( char *dn )
 {
        char    *d, *s;
        int     state, gotesc;
@@ -45,13 +45,13 @@ dn_normalize( char *dn )
                switch ( state ) {
                case B4LEADTYPE:
                case B4TYPE:
-                       if ( LEADOIDCHAR(*s) ) {
+                       if ( OID_LEADCHAR(*s) ) {
                                state = INOIDTYPE;
                                *d++ = *s;
-                       } else if ( LEADKEYCHAR(*s) ) {
+                       } else if ( ATTR_LEADCHAR(*s) ) {
                                state = INKEYTYPE;
                                *d++ = *s;
-                       } else if ( ! SPACE( *s ) ) {
+                       } else if ( ! ASCII_SPACE( *s ) ) {
                                dn = NULL;
                                state = INKEYTYPE;
                                *d++ = *s;
@@ -59,12 +59,12 @@ dn_normalize( char *dn )
                        break;
 
                case INOIDTYPE:
-                       if ( OIDCHAR(*s) ) {
+                       if ( OID_CHAR(*s) ) {
                                *d++ = *s;
                        } else if ( *s == '=' ) {
                                state = B4VALUE;
                                *d++ = *s;
-                       } else if ( SPACE( *s ) ) {
+                       } else if ( ASCII_SPACE( *s ) ) {
                                state = B4EQUAL;
                        } else {
                                dn = NULL;
@@ -73,12 +73,12 @@ dn_normalize( char *dn )
                        break;
 
                case INKEYTYPE:
-                       if ( KEYCHAR(*s) ) {
+                       if ( ATTR_CHAR(*s) ) {
                                *d++ = *s;
                        } else if ( *s == '=' ) {
                                state = B4VALUE;
                                *d++ = *s;
-                       } else if ( SPACE( *s ) ) {
+                       } else if ( ASCII_SPACE( *s ) ) {
                                state = B4EQUAL;
                        } else {
                                dn = NULL;
@@ -90,7 +90,7 @@ dn_normalize( char *dn )
                        if ( *s == '=' ) {
                                state = B4VALUE;
                                *d++ = *s;
-                       } else if ( ! SPACE( *s ) ) {
+                       } else if ( ! ASCII_SPACE( *s ) ) {
                                /* not a valid dn - but what can we do here? */
                                *d++ = *s;
                                dn = NULL;
@@ -101,15 +101,15 @@ dn_normalize( char *dn )
                        if ( *s == '"' ) {
                                state = INQUOTEDVALUE;
                                *d++ = *s;
-                       } else if ( ! SPACE( *s ) ) { 
+                       } else if ( ! ASCII_SPACE( *s ) ) { 
                                state = INVALUE;
                                *d++ = *s;
                        }
                        break;
 
                case INVALUE:
-                       if ( !gotesc && SEPARATOR( *s ) ) {
-                               while ( SPACE( *(d - 1) ) )
+                       if ( !gotesc && RDN_SEPARATOR( *s ) ) {
+                               while ( ASCII_SPACE( *(d - 1) ) )
                                        d--;
                                state = B4TYPE;
                                if ( *s == '+' ) {
@@ -117,8 +117,8 @@ dn_normalize( char *dn )
                                } else {
                                        *d++ = ',';
                                }
-                       } else if ( gotesc && !NEEDSESCAPE( *s ) &&
-                           !SEPARATOR( *s ) ) {
+                       } else if ( gotesc && !RDN_NEEDSESCAPE( *s ) &&
+                           !RDN_SEPARATOR( *s ) ) {
                                *--d = *s;
                                d++;
                        } else {
@@ -130,7 +130,7 @@ dn_normalize( char *dn )
                        if ( !gotesc && *s == '"' ) {
                                state = B4SEPARATOR;
                                *d++ = *s;
-                       } else if ( gotesc && !NEEDSESCAPE( *s ) ) {
+                       } else if ( gotesc && !RDN_NEEDSESCAPE( *s ) ) {
                                *--d = *s;
                                d++;
                        } else {
@@ -138,7 +138,7 @@ dn_normalize( char *dn )
                        }
                        break;
                case B4SEPARATOR:
-                       if ( SEPARATOR( *s ) ) {
+                       if ( RDN_SEPARATOR( *s ) ) {
                                state = B4TYPE;
                                *d++ = *s;
                        }
@@ -146,7 +146,7 @@ dn_normalize( char *dn )
                default:
                        dn = NULL;
                        Debug( LDAP_DEBUG_ANY,
-                           "dn_normalize - unknown state %d\n", state, 0, 0 );
+                           "dn_validate - unknown state %d\n", state, 0, 0 );
                        break;
                }
                if ( *s == '\\' ) {
@@ -176,20 +176,20 @@ dn_normalize( char *dn )
 }
 
 /*
- * dn_normalize_case - put dn into a canonical form suitable for storing
+ * dn_normalize - put dn into a canonical form suitable for storing
  * in a hash database.  this involves normalizing the case as well as
  * the format.  the dn is normalized in place as well as returned if valid.
  */
 
 char *
-dn_normalize_case( char *dn )
+dn_normalize( char *dn )
 {
+       /* upper case it */
        ldap_pvt_str2upper( dn );
 
-       /* normalize format */
-       dn = dn_normalize( dn );
+       /* validate and compress dn */
+       dn = dn_validate( dn );
 
-       /* and upper case it */
        return( dn );
 }
 
@@ -210,7 +210,7 @@ dn_parent(
                return NULL;
        }
 
-       while(*dn && SPACE(*dn)) {
+       while(*dn != '\0' && ASCII_SPACE(*dn)) {
                dn++;
        }
 
@@ -222,28 +222,8 @@ dn_parent(
                return( NULL );
        }
 
-#ifdef DNS_DN
-       /*
-        * no =, assume it is a dns name, like blah@some.domain.name
-        * if the blah@ part is there, return some.domain.name.  if
-        * it's just some.domain.name, return domain.name.
-        */
-       if ( strchr( dn, '=' ) == NULL ) {
-               if ( (s = strchr( dn, '@' )) == NULL ) {
-                       if ( (s = strchr( dn, '.' )) == NULL ) {
-                               return( NULL );
-                       }
-               }
-               if ( *(s + 1) == '\0' ) {
-                       return( NULL );
-               } else {
-                       return( ch_strdup( &s[1] ) );
-               }
-       }
-#endif
-
        /*
-        * else assume it is an X.500-style name, which looks like
+        * assume it is an X.500-style name, which looks like
         * foo=bar,sha=baz,...
         */
 
@@ -262,7 +242,7 @@ dn_parent(
                } else {
                        if ( *s == '"' ) {
                                inquote = 1;
-                       } else if ( DNSEPARATOR( *s ) ) {
+                       } else if ( DN_SEPARATOR( *s ) ) {
                                return( ch_strdup( &s[1] ) );
                        }
                }
@@ -273,50 +253,28 @@ dn_parent(
 
 char * dn_rdn( 
     Backend    *be,
-    char       *dn )
+    const char *dn_in )
 {
-       char    *s;
+       char    *dn, *s;
        int     inquote;
 
-       if( dn == NULL ) {
+       if( dn_in == NULL ) {
                return NULL;
        }
 
-       while(*dn && SPACE(*dn)) {
+       while(*dn_in && ASCII_SPACE(*dn_in)) {
                dn++;
        }
 
-       if( *dn == '\0' ) {
+       if( *dn_in == '\0' ) {
                return( NULL );
        }
 
-       if ( be != NULL && be_issuffix( be, dn ) ) {
+       if ( be != NULL && be_issuffix( be, dn_in ) ) {
                return( NULL );
        }
 
-       dn = ch_strdup( dn );
-
-#ifdef DNS_DN
-       /*
-        * no =, assume it is a dns name, like blah@some.domain.name
-        * if the blah@ part is there, return some.domain.name.  if
-        * it's just some.domain.name, return domain.name.
-        */
-       if ( strchr( dn, '=' ) == NULL ) {
-               if ( (s = strchr( dn, '@' )) == NULL ) {
-                       if ( (s = strchr( dn, '.' )) == NULL ) {
-                               return( dn );
-                       }
-               }
-               *s = '\0';
-               return( dn );
-       }
-#endif
-
-       /*
-        * else assume it is an X.500-style name, which looks like
-        * foo=bar,sha=baz,...
-        */
+       dn = ch_strdup( dn_in );
 
        inquote = 0;
 
@@ -334,7 +292,7 @@ char * dn_rdn(
                } else {
                        if ( *s == '"' ) {
                                inquote = 1;
-                       } else if ( DNSEPARATOR( *s ) ) {
+                       } else if ( DN_SEPARATOR( *s ) ) {
                                *s = '\0';
                                return( dn );
                        }
@@ -378,8 +336,8 @@ char **dn_subtree(
 
 int
 dn_issuffix(
-    char       *dn,
-    char       *suffix
+    const char *dn,
+    const char *suffix
 )
 {
        int     dnlen, suffixlen;
@@ -398,20 +356,6 @@ dn_issuffix(
        return( strcmp( dn + dnlen - suffixlen, suffix ) == 0 );
 }
 
-#ifdef DNS_DN
-/*
- * dn_type - tells whether the given dn is an X.500 thing or DNS thing
- * returns (defined in slap.h):        DN_DNS          dns-style thing
- *                             DN_X500         x500-style thing
- */
-
-int
-dn_type( char *dn )
-{
-       return( strchr( dn, '=' ) == NULL ? DN_DNS : DN_X500 );
-}
-#endif
-
 /*
  * get_next_substring(), rdn_attr_type(), rdn_attr_value(), and
  * build_new_dn().
@@ -434,7 +378,7 @@ dn_type( char *dn )
  */ 
 
 static char * 
-get_next_substring( char * s, char d )
+get_next_substring( const char * s, char d )
 {
 
        char    *str, *r;
@@ -443,10 +387,8 @@ get_next_substring( char * s, char d )
 
        /* Skip leading spaces */
        
-       while ( *s && SPACE(*s) ) {
-           
+       while ( *s && ASCII_SPACE(*s) ) {
                s++;
-           
        }
        
        /* Copy word */
@@ -477,11 +419,9 @@ get_next_substring( char * s, char d )
  * memory. The returned string will be null-terminated.
  */
 
-char * rdn_attr_type( char * s )
+char * rdn_attr_type( const char * s )
 {
-
        return get_next_substring( s, '=' );
-
 }
 
 
@@ -495,15 +435,13 @@ char * rdn_attr_type( char * s )
  */
 
 char * 
-rdn_attr_value( char * rdn )
+rdn_attr_value( const char * rdn )
 {
 
-       char    *str;
+       const char      *str;
 
        if ( (str = strchr( rdn, '=' )) != NULL ) {
-
                return get_next_substring(++str, '\0');
-
        }
 
        return NULL;
@@ -534,47 +472,13 @@ build_new_dn( char ** new_dn,
 {
 
     if ( p_dn == NULL ) {
-
        *new_dn = ch_strdup( newrdn );
        return;
-
     }
     
     *new_dn = (char *) ch_malloc( strlen( p_dn ) + strlen( newrdn ) + 3 );
 
-#ifdef DNS_DN
-    if ( dn_type( e_dn ) == DN_X500 ) {
-#endif
-
        strcpy( *new_dn, newrdn );
        strcat( *new_dn, "," );
        strcat( *new_dn, p_dn );
-
-#ifdef DNS_DN
-    } else {
-
-       char    *s;
-       char    sep[2];
-
-       strcpy( *new_dn, newrdn );
-       s = strchr( newrdn, '\0' );
-       s--;
-
-       if ( (*s != '.') && (*s != '@') ) {
-
-           if ( (s = strpbrk( e_dn, ".@" )) != NULL ) {
-
-               sep[0] = *s;
-               sep[1] = '\0';
-               strcat( *new_dn, sep );
-
-           }
-
-       }
-
-       strcat( *new_dn, p_dn );
-
-    }
-#endif
-    
 }
index d530e5200228849182b00b1d9b62a517cffde814..115daa3eea959587b2609f511c39931cfb8814b8 100644 (file)
@@ -1,7 +1,7 @@
 /* entry.c - routines for dealing with entries */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -29,19 +29,19 @@ int entry_destroy(void)
        return 0;
 }
 
+
 Entry *
 str2entry( char *s )
 {
+       int rc;
        Entry           *e;
-       Attribute       **a;
+       Attribute       **a = NULL;
        char            *type;
-       char            *value;
-       char            *next;
-       ber_len_t       vlen;
-       int             nvals, maxvals;
-       struct berval   bval;
+       struct berval value;
        struct berval   *vals[2];
-       char            ptype[64];
+       AttributeDescription *ad;
+       const char *text;
+       char    *next;
 
        /*
         * LDIF is used as the string format.
@@ -61,10 +61,8 @@ str2entry( char *s )
        Debug( LDAP_DEBUG_TRACE, "=> str2entry\n",
                s ? s : "NULL", 0, 0 );
 
-       next = s;
-
        /* initialize reader/writer lock */
-       e = (Entry *) ch_calloc( 1, sizeof(Entry) );
+       e = (Entry *) ch_malloc( sizeof(Entry) );
 
        if( e == NULL ) {
                Debug( LDAP_DEBUG_TRACE,
@@ -73,32 +71,29 @@ str2entry( char *s )
                return( NULL );
        }
 
+       /* initialize entry */
        e->e_id = NOID;
+       e->e_dn = NULL;
+       e->e_ndn = NULL;
+       e->e_attrs = NULL;
        e->e_private = NULL;
 
        /* dn + attributes */
-       e->e_attrs = NULL;
-       vals[0] = &bval;
+       vals[0] = &value;
        vals[1] = NULL;
-       ptype[0] = '\0';
+
+       next = s;
        while ( (s = ldif_getline( &next )) != NULL ) {
                if ( *s == '\n' || *s == '\0' ) {
                        break;
                }
 
-               if ( ldif_parse_line( s, &type, &value, &vlen ) != 0 ) {
+               if ( ldif_parse_line( s, &type, &value.bv_val, &value.bv_len ) != 0 ) {
                        Debug( LDAP_DEBUG_TRACE,
                            "<= str2entry NULL (parse_line)\n", 0, 0, 0 );
                        continue;
                }
 
-               if ( strcasecmp( type, ptype ) != 0 ) {
-                       strncpy( ptype, type, sizeof(ptype) - 1 );
-                       nvals = 0;
-                       maxvals = 0;
-                       a = NULL;
-               }
-
                if ( strcasecmp( type, "dn" ) == 0 ) {
                        free( type );
 
@@ -106,39 +101,42 @@ str2entry( char *s )
                                Debug( LDAP_DEBUG_ANY,
  "str2entry: entry %ld has multiple dns \"%s\" and \"%s\" (second ignored)\n",
                                    e->e_id, e->e_dn,
-                                       value != NULL ? value : NULL );
-                               if( value != NULL ) free( value );
+                                       value.bv_val != NULL ? value.bv_val : "" );
+                               if( value.bv_val != NULL ) free( value.bv_val );
                                continue;
                        }
-                       e->e_dn = value != NULL ? value : ch_strdup( "" );
 
-                       if ( e->e_ndn != NULL ) {
-                               Debug( LDAP_DEBUG_ANY,
- "str2entry: entry %ld already has a normalized dn \"%s\" for \"%s\" (first ignored)\n",
-                                   e->e_id, e->e_ndn,
-                                       value != NULL ? value : NULL );
-                               free( e->e_ndn );
-                       }
-                       e->e_ndn = ch_strdup( e->e_dn );
-                       (void) dn_normalize_case( e->e_ndn );
+                       e->e_dn = value.bv_val != NULL ? value.bv_val : ch_strdup( "" );
                        continue;
                }
 
-               bval.bv_val = value;
-               bval.bv_len = vlen;
-               if ( attr_merge_fast( e, type, vals, nvals, 1, &maxvals, &a )
-                   != 0 ) {
+               ad = NULL;
+               rc = slap_str2ad( type, &ad, &text );
+
+               if( rc != LDAP_SUCCESS ) {
+                       Debug( LDAP_DEBUG_TRACE,
+                               "<= str2entry NULL (str2ad=%s)\n", text, 0, 0 );
+                       entry_free( e );
+                       free( value.bv_val );
+                       free( type );
+                       return( NULL );
+               }
+
+               rc = attr_merge( e, ad, vals );
+
+               ad_free( ad, 1 );
+
+               if( rc != 0 ) {
                        Debug( LDAP_DEBUG_TRACE,
                            "<= str2entry NULL (attr_merge)\n", 0, 0, 0 );
                        entry_free( e );
-                       free( value );
+                       free( value.bv_val );
                        free( type );
                        return( NULL );
                }
 
-               free( value );
                free( type );
-               nvals++;
+               free( value.bv_val );
        }
 
        /* check to make sure there was a dn: line */
@@ -149,13 +147,9 @@ str2entry( char *s )
                return( NULL );
        }
 
-       if ( e->e_ndn == NULL ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "str2entry: entry %ld (\"%s\") has no normalized dn\n",
-                   e->e_id, e->e_dn, 0 );
-               entry_free( e );
-               return( NULL );
-       }
+       /* generate normalized dn */
+       e->e_ndn = ch_strdup( e->e_dn );
+       (void) dn_normalize( e->e_ndn );
 
        Debug(LDAP_DEBUG_TRACE, "<= str2entry(%s) -> %ld (0x%lx)\n",
                e->e_dn, e->e_id, (unsigned long)e );
@@ -163,18 +157,19 @@ str2entry( char *s )
        return( e );
 }
 
+
 #define GRABSIZE       BUFSIZ
 
 #define MAKE_SPACE( n )        { \
                while ( ecur + (n) > ebuf + emaxsize ) { \
-                       int     offset; \
+                       ptrdiff_t       offset; \
                        offset = (int) (ecur - ebuf); \
                        ebuf = (unsigned char *) ch_realloc( (char *) ebuf, \
                            emaxsize + GRABSIZE ); \
                        emaxsize += GRABSIZE; \
                        ecur = ebuf + offset; \
                } \
-}
+       }
 
 char *
 entry2str(
@@ -187,7 +182,6 @@ entry2str(
 
        /*
         * In string format, an entry looks like this:
-        *      <id>\n
         *      dn: <dn>\n
         *      [<attr>: <value>\n]*
         */
@@ -207,9 +201,10 @@ entry2str(
                /* put "<type>:[:] <value>" line for each value */
                for ( i = 0; a->a_vals[i] != NULL; i++ ) {
                        bv = a->a_vals[i];
-                       tmplen = strlen( a->a_type );
+                       tmplen = a->a_desc->ad_cname->bv_len;
                        MAKE_SPACE( LDIF_SIZE_NEEDED( tmplen, bv->bv_len ));
-                       ldif_sput( (char **) &ecur, LDIF_PUT_VALUE, a->a_type,
+                       ldif_sput( (char **) &ecur, LDIF_PUT_VALUE,
+                               a->a_desc->ad_cname->bv_val,
                            bv->bv_val, bv->bv_len );
                }
        }
index fd9573cebd82602481fda2c62585e6b3bf276ba1..23923fc82686eae077bb650af27b04be13c5855d 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /* 
- * Copyright 1999 The OpenLDAP Foundation.
+ * Copyright 1999-2000 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 
 #include "slap.h"
 
-char *supportedExtensions[] = {
-       NULL
-};
+#define MAX_OID_LENGTH 128
 
+typedef struct extop_list_t {
+       struct extop_list_t *next;
+       char *oid;
+       SLAP_EXTOP_MAIN_FN ext_main;
+} extop_list_t;
+
+extop_list_t *supp_ext_list = NULL;
+
+/* this list of built-in extops is for extops that are not part
+ * of backends or in external modules.  essentially, this is
+ * just a way to get built-in extops onto the extop list without
+ * having a separate init routine for each built-in extop.
+ */
+struct {
+       char *oid;
+       SLAP_EXTOP_MAIN_FN ext_main;
+} builtin_extops[] = {
+#ifdef HAVE_TLS
+               { LDAP_EXOP_START_TLS, starttls_extop },
+#endif
+               { LDAP_EXOP_X_MODIFY_PASSWD, passwd_extop },
+               { NULL, NULL }
+       };
+
+
+static extop_list_t *find_extop( extop_list_t *list, char *oid );
+
+static int extop_callback(
+       Connection *conn, Operation *op,
+       int msg, int arg, void *argp);
+
+char *
+get_supported_extop (int index)
+{
+       extop_list_t *ext;
+
+       /* linear scan is slow, but this way doesn't force a
+        * big change on root_dse.c, where this routine is used.
+        */
+       for (ext = supp_ext_list; ext != NULL && --index >= 0; ext = ext->next) ;
+       if (ext == NULL)
+               return(NULL);
+       return(ext->oid);
+}
 
 int
 do_extended(
@@ -44,15 +86,21 @@ do_extended(
 )
 {
        int rc = LDAP_SUCCESS;
-       char* reqoid ;
-       struct berval reqdata;
+       char* reqoid;
+       struct berval *reqdata;
        ber_tag_t tag;
        ber_len_t len;
+       extop_list_t *ext;
+       const char *text;
+       struct berval **refs;
+       char *rspoid;
+       struct berval *rspdata;
+       LDAPControl **rspctrls;
 
        Debug( LDAP_DEBUG_TRACE, "do_extended\n", 0, 0, 0 );
 
        reqoid = NULL;
-       reqdata.bv_val = NULL;
+       reqdata = NULL;
 
        if( op->o_protocol < LDAP_VERSION3 ) {
                Debug( LDAP_DEBUG_ANY, "do_extended: protocol version (%d) too low\n",
@@ -63,7 +111,7 @@ do_extended(
                goto done;
        }
 
-       if ( ber_scanf( op->o_ber, "a", &reqoid ) == LBER_ERROR ) {
+       if ( ber_scanf( op->o_ber, "{a" /*}*/, &reqoid ) == LBER_ERROR ) {
                Debug( LDAP_DEBUG_ANY, "do_extended: ber_scanf failed\n", 0, 0 ,0 );
                send_ldap_disconnect( conn, op,
                        LDAP_PROTOCOL_ERROR, "decoding error" );
@@ -71,18 +119,18 @@ do_extended(
                goto done;
        }
 
-       if( !charray_inlist( supportedExtensions, reqoid ) ) {
+       if( !(ext = find_extop(supp_ext_list, reqoid)) ) {
                Debug( LDAP_DEBUG_ANY, "do_extended: unsupported operation \"%s\"\n",
                        reqoid, 0 ,0 );
                send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
-                       NULL, "unsuppored extended operation", NULL, NULL );
+                       NULL, "unsupported extended operation", NULL, NULL );
                goto done;
        }
 
        tag = ber_peek_tag( op->o_ber, &len );
        
        if( ber_peek_tag( op->o_ber, &len ) == LDAP_TAG_EXOP_REQ_VALUE ) {
-               if( ber_scanf( op->o_ber, "o", &reqdata ) != LBER_ERROR ) {
+               if( ber_scanf( op->o_ber, "O", &reqdata ) == LBER_ERROR ) {
                        Debug( LDAP_DEBUG_ANY, "do_extended: ber_scanf failed\n", 0, 0 ,0 );
                        send_ldap_disconnect( conn, op,
                                LDAP_PROTOCOL_ERROR, "decoding error" );
@@ -96,18 +144,149 @@ do_extended(
                return rc;
        } 
 
-       Debug( LDAP_DEBUG_ARGS, "do_extended: oid \"%s\"\n", reqoid, 0 ,0 );
+       Debug( LDAP_DEBUG_ARGS, "do_extended: oid=%s\n", reqoid, 0 ,0 );
+
+       rspoid = NULL;
+       rspdata = NULL;
+       rspctrls = NULL;
+       text = NULL;
+       refs = NULL;
+
+       rc = (ext->ext_main)( extop_callback, conn, op,
+               reqoid, reqdata,
+               &rspoid, &rspdata, &rspctrls, &text, &refs );
 
-       send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
-               NULL, "unsupported extended operation", NULL, NULL );
+       if( rc != SLAPD_ABANDON ) {
+               if (rc == LDAP_REFERRAL) {
+                       refs = default_referral;
+               }
+
+               send_ldap_extended( conn, op, rc, NULL, text, refs,
+                       rspoid, rspdata, rspctrls );
+       }
+
+       if ( rspoid != NULL ) {
+               free( rspoid );
+       }
+
+       if ( rspdata != NULL )
+               ber_bvfree( rspdata );
 
 done:
+       if ( reqdata != NULL ) {
+               ber_bvfree( reqdata );
+       }
        if ( reqoid != NULL ) {
                free( reqoid );
        }
-       if ( reqdata.bv_val != NULL ) {
-               free( reqdata.bv_val );
-       }
 
        return rc;
 }
+
+int
+load_extop(
+       const char *ext_oid,
+       SLAP_EXTOP_MAIN_FN ext_main )
+{
+       extop_list_t *ext;
+
+       if( ext_oid == NULL || *ext_oid == '\0' ) return -1; 
+       if(!ext_main) return -1; 
+
+       ext = ch_calloc(1, sizeof(extop_list_t));
+       if (ext == NULL)
+               return(-1);
+
+       ext->oid = ch_strdup( ext_oid );
+       if (ext->oid == NULL) {
+               free(ext);
+               return(-1);
+       }
+
+       ext->ext_main = ext_main;
+       ext->next = supp_ext_list;
+
+       supp_ext_list = ext;
+
+       return(0);
+}
+
+int
+extops_init (void)
+{
+       int i;
+
+       for (i = 0; builtin_extops[i].oid != NULL; i++) {
+               load_extop(builtin_extops[i].oid, builtin_extops[i].ext_main);
+       }
+       return(0);
+}
+
+int
+extops_kill (void)
+{
+       extop_list_t *ext;
+
+       /* we allocated the memory, so we have to free it, too. */
+       while ((ext = supp_ext_list) != NULL) {
+               supp_ext_list = ext->next;
+               if (ext->oid != NULL)
+                       ch_free(ext->oid);
+               ch_free(ext);
+       }
+       return(0);
+}
+
+static extop_list_t *
+find_extop( extop_list_t *list, char *oid )
+{
+       extop_list_t *ext;
+
+       for (ext = list; ext; ext = ext->next) {
+               if (strcmp(ext->oid, oid) == 0)
+                       return(ext);
+       }
+       return(NULL);
+}
+
+int
+extop_callback(
+       Connection *conn, Operation *op,
+       int msg, int arg, void *argp)
+{
+       if (argp == NULL)
+               return(-1);
+
+       switch (msg) {
+       case SLAPD_EXTOP_GETVERSION:
+               *(int *)argp = 1;
+               return(0);
+
+       case SLAPD_EXTOP_GETPROTO:
+               *(int *)argp = op->o_protocol;
+               return(0);
+       
+       case SLAPD_EXTOP_GETAUTH:
+               *(int *)argp = op->o_authtype;
+               return(0);
+       
+       case SLAPD_EXTOP_GETDN:
+               *(char **)argp = op->o_dn;
+               return(0);
+       
+       case SLAPD_EXTOP_GETCLIENT:
+               if (conn->c_peer_domain != NULL && *conn->c_peer_domain != 0) {
+                       *(char **)argp = conn->c_peer_domain;
+                       return(0);
+               }
+               if (conn->c_peer_name != NULL && *conn->c_peer_name != 0) {
+                       *(char **)argp = conn->c_peer_name;
+                       return(0);
+               }
+               break;
+       
+       default:
+               break;
+       }
+       return(-1);
+}
index 35604cf6b9bc1b371e23e0db18f536a7f8bbe082..6c44ca305a74306d60f5af6fb09226f6f315f22f 100644 (file)
@@ -1,7 +1,7 @@
 /* filter.c - routines for parsing and dealing with filters */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 
 #include "slap.h"
 
-static int     get_filter_list(Connection *conn, BerElement *ber, Filter **f, char **fstr);
-static int     get_substring_filter(Connection *conn, BerElement *ber, Filter *f, char **fstr);
+static int     get_filter_list(
+       Connection *conn,
+       BerElement *ber,
+       Filter **f,
+       char **fstr,
+       const char **text );
+
+static int     get_substring_filter(
+       Connection *conn,
+       BerElement *ber,
+       Filter *f,
+       char **fstr,
+       const char **text );
 
 int
-get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
+get_filter(
+       Connection *conn,
+       BerElement *ber,
+       Filter **filt,
+       char **fstr,
+       const char **text )
 {
+       ber_tag_t       tag;
        ber_len_t       len;
        int             err;
        Filter          *f;
-       char            *ftmp;
+       char            *ftmp = NULL;
 
        Debug( LDAP_DEBUG_FILTER, "begin get_filter\n", 0, 0, 0 );
 
@@ -60,122 +77,202 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
         *
         */
 
+       tag = ber_peek_tag( ber, &len );
+
+       if( tag == LBER_ERROR ) {
+               *text = "error decoding filter";
+               return SLAPD_DISCONNECT;
+       }
+
        f = (Filter *) ch_malloc( sizeof(Filter) );
        f->f_next = NULL;
 
        err = LDAP_SUCCESS;
        *fstr = NULL;
-       f->f_choice = ber_peek_tag( ber, &len );
+       f->f_choice = tag; 
 
        switch ( f->f_choice ) {
        case LDAP_FILTER_EQUALITY:
                Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
-               if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) {
-                       *fstr = ch_malloc(4 + strlen( f->f_avtype ) +
-                           f->f_avvalue.bv_len);
-                       sprintf( *fstr, "(%s=%s)", f->f_avtype,
-                           f->f_avvalue.bv_val );
+
+               err = get_ava( ber, &f->f_ava, SLAP_MR_EQUALITY, text );
+               if ( err != LDAP_SUCCESS ) {
+                       break;
                }
+
+               assert( f->f_ava != NULL );
+
+               *fstr = ch_malloc( sizeof("(=)")
+                       + f->f_av_desc->ad_cname->bv_len
+                       + f->f_av_value->bv_len );
+
+               sprintf( *fstr, "(%s=%s)",
+                       f->f_av_desc->ad_cname->bv_val,
+                   f->f_av_value->bv_val );
+
                break;
 
        case LDAP_FILTER_SUBSTRINGS:
                Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 );
-               err = get_substring_filter( conn, ber, f, fstr );
+               err = get_substring_filter( conn, ber, f, fstr, text );
                break;
 
        case LDAP_FILTER_GE:
                Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
-               if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) {
-                       *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
-                           f->f_avvalue.bv_len);
-                       sprintf( *fstr, "(%s>=%s)", f->f_avtype,
-                           f->f_avvalue.bv_val );
+
+               err = get_ava( ber, &f->f_ava, SLAP_MR_ORDERING, text );
+               if ( err != LDAP_SUCCESS ) {
+                       break;
                }
+
+               *fstr = ch_malloc( sizeof("(>=)")
+                       + f->f_av_desc->ad_cname->bv_len
+                       + f->f_av_value->bv_len );
+
+               sprintf( *fstr, "(%s>=%s)",
+                       f->f_av_desc->ad_cname->bv_val,
+                   f->f_av_value->bv_val );
+
                break;
 
        case LDAP_FILTER_LE:
                Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
-               if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) {
-                       *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
-                           f->f_avvalue.bv_len);
-                       sprintf( *fstr, "(%s<=%s)", f->f_avtype,
-                           f->f_avvalue.bv_val );
+
+               err = get_ava( ber, &f->f_ava, SLAP_MR_ORDERING, text );
+               if ( err != LDAP_SUCCESS ) {
+                       break;
                }
+
+
+               *fstr = ch_malloc( sizeof("(<=)")
+                       + f->f_av_desc->ad_cname->bv_len
+                       + f->f_av_value->bv_len );
+
+               sprintf( *fstr, "(%s<=%s)",
+                       f->f_av_desc->ad_cname->bv_val,
+                   f->f_av_value->bv_val );
+
                break;
 
-       case LDAP_FILTER_PRESENT:
+       case LDAP_FILTER_PRESENT: {
+               struct berval type;
+
                Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 );
-               if ( ber_scanf( ber, "a", &f->f_type ) == LBER_ERROR ) {
-                       err = -1;
-               } else {
-                       err = LDAP_SUCCESS;
-                       attr_normalize( f->f_type );
-                       *fstr = ch_malloc( 5 + strlen( f->f_type ) );
-                       sprintf( *fstr, "(%s=*)", f->f_type );
+
+               if ( ber_scanf( ber, "o", &type ) == LBER_ERROR ) {
+                       err = SLAPD_DISCONNECT;
+                       *text = "error decoding filter";
+                       break;
                }
-               break;
+
+               f->f_desc = NULL;
+               err = slap_bv2ad( &type, &f->f_desc, text );
+
+               if( err != LDAP_SUCCESS ) {
+                       ch_free( type.bv_val );
+                       break;
+               }
+
+               ch_free( type.bv_val );
+
+               *fstr = ch_malloc( sizeof("(=*)")
+                       + f->f_desc->ad_cname->bv_len );
+               sprintf( *fstr, "(%s=*)",
+                       f->f_desc->ad_cname->bv_val );
+
+               } break;
 
        case LDAP_FILTER_APPROX:
                Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
-               if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) {
-                       *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
-                           f->f_avvalue.bv_len);
-                       sprintf( *fstr, "(%s~=%s)", f->f_avtype,
-                           f->f_avvalue.bv_val );
+
+               err = get_ava( ber, &f->f_ava, SLAP_MR_EQUALITY_APPROX, text );
+               if ( err != LDAP_SUCCESS ) {
+                       break;
                }
+
+               *fstr = ch_malloc( sizeof("(~=)")
+                       + f->f_av_desc->ad_cname->bv_len
+                       + f->f_av_value->bv_len );
+
+               sprintf( *fstr, "(%s~=%s)",
+                       f->f_av_desc->ad_cname->bv_val,
+                   f->f_av_value->bv_val );
+
                break;
 
        case LDAP_FILTER_AND:
                Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 );
-               if ( (err = get_filter_list( conn, ber, &f->f_and, &ftmp ))
-                   == LDAP_SUCCESS ) {
-                       if (ftmp == NULL) ftmp = ch_strdup("");
-                       *fstr = ch_malloc( 4 + strlen( ftmp ) );
-                       sprintf( *fstr, "(&%s)", ftmp );
-                       free( ftmp );
+               err = get_filter_list( conn, ber, &f->f_and, &ftmp, text );
+               if ( err != LDAP_SUCCESS ) {
+                       break;
                }
+               *fstr = ch_malloc( sizeof("(&)")
+                       + ( ftmp == NULL ? 0 : strlen( ftmp ) ) );
+               sprintf( *fstr, "(&%s)",
+                       ftmp == NULL ? "" : ftmp );
                break;
 
        case LDAP_FILTER_OR:
                Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 );
-               if ( (err = get_filter_list( conn, ber, &f->f_or, &ftmp ))
-                   == LDAP_SUCCESS ) {
-                       if (ftmp == NULL) ftmp = ch_strdup("");
-                       *fstr = ch_malloc( 4 + strlen( ftmp ) );
-                       sprintf( *fstr, "(|%s)", ftmp );
-                       free( ftmp );
+               err = get_filter_list( conn, ber, &f->f_and, &ftmp, text );
+               if ( err != LDAP_SUCCESS ) {
+                       break;
                }
+               *fstr = ch_malloc( sizeof("(!)")
+                       + ( ftmp == NULL ? 0 : strlen( ftmp ) ) );
+               sprintf( *fstr, "(|%s)",
+                       ftmp == NULL ? "" : ftmp );
                break;
 
        case LDAP_FILTER_NOT:
                Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 );
                (void) ber_skip_tag( ber, &len );
-               if ( (err = get_filter( conn, ber, &f->f_not, &ftmp )) == LDAP_SUCCESS ) {
-                       if (ftmp == NULL) ftmp = ch_strdup("");
-                       *fstr = ch_malloc( 4 + strlen( ftmp ) );
-                       sprintf( *fstr, "(!%s)", ftmp );
-                       free( ftmp );
+               err = get_filter( conn, ber, &f->f_not, &ftmp, text );
+               if ( err != LDAP_SUCCESS ) {
+                       break;
                }
+               *fstr = ch_malloc( sizeof("(!)")
+                       + ( ftmp == NULL ? 0 : strlen( ftmp ) ) );
+               sprintf( *fstr, "(!%s)",
+                       ftmp == NULL ? "" : ftmp );
                break;
 
-       case LBER_DEFAULT:
-               Debug( LDAP_DEBUG_ANY, "decoding filter error\n",
-                      0, 0, 0 );
-               err = -1;
+       case LDAP_FILTER_EXT:
+               /* not yet implemented */
+               Debug( LDAP_DEBUG_ANY, "extensible match not yet implemented.\n",
+                      f->f_choice, 0, 0 );
+               f->f_choice = SLAPD_FILTER_COMPUTED;
+               f->f_result = SLAPD_COMPARE_UNDEFINED;
+               *fstr = ch_strdup( "(extended)" );
                break;
 
        default:
-               Debug( LDAP_DEBUG_ANY, "unknown filter type %lu\n",
+               Debug( LDAP_DEBUG_ANY, "get_filter: unknown filter type=%lu\n",
                       f->f_choice, 0, 0 );
-               err = LDAP_PROTOCOL_ERROR;
+               f->f_choice = SLAPD_FILTER_COMPUTED;
+               f->f_result = SLAPD_COMPARE_UNDEFINED;
+               *fstr = ch_strdup( "(undefined)" );
                break;
        }
 
+       free( ftmp );
+
        if ( err != LDAP_SUCCESS ) {
-               free( (char *) f );
                if ( *fstr != NULL ) {
                        free( *fstr );
                }
+
+               if( err != SLAPD_DISCONNECT ) {
+                       /* ignore error */
+                       f->f_choice = SLAPD_FILTER_COMPUTED;
+                       f->f_result = SLAPD_COMPARE_UNDEFINED;
+                       *fstr = ch_strdup( "(badfilter)" );
+                       err = LDAP_SUCCESS;
+                       *filt = f;
+
+               } else {
+                       free(f);
+               }
        } else {
                *filt = f;
        }
@@ -185,7 +282,9 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
 }
 
 static int
-get_filter_list( Connection *conn, BerElement *ber, Filter **f, char **fstr )
+get_filter_list( Connection *conn, BerElement *ber,
+       Filter **f, char **fstr,
+       const char **text )
 {
        Filter          **new;
        int             err;
@@ -200,8 +299,10 @@ get_filter_list( Connection *conn, BerElement *ber, Filter **f, char **fstr )
        for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
            tag = ber_next_element( ber, &len, last ) )
        {
-               if ( (err = get_filter( conn, ber, new, &ftmp )) != LDAP_SUCCESS )
+               err = get_filter( conn, ber, new, &ftmp, text );
+               if ( err != LDAP_SUCCESS )
                        return( err );
+
                if ( *fstr == NULL ) {
                        *fstr = ftmp;
                } else {
@@ -223,87 +324,182 @@ get_substring_filter(
     Connection *conn,
     BerElement *ber,
     Filter     *f,
-    char       **fstr
+    char       **fstr,
+       const char      **text
 )
 {
        ber_tag_t       tag;
        ber_len_t       len;
        ber_tag_t       rc;
-       char            *val, *last;
-       int             syntax;
+       struct berval *value;
+       char            *last;
+       struct berval type;
+       struct berval *nvalue;
+       *text = "error decoding filter";
 
        Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 );
 
-       if ( ber_scanf( ber, "{a" /*}*/, &f->f_sub_type ) == LBER_ERROR ) {
-               return( -1 );
+       if ( ber_scanf( ber, "{o" /*}*/, &type ) == LBER_ERROR ) {
+               return SLAPD_DISCONNECT;
+       }
+
+       f->f_sub = ch_calloc( 1, sizeof(SubstringsAssertion) );
+       f->f_sub_desc = NULL;
+       rc = slap_bv2ad( &type, &f->f_sub_desc, text );
+
+       ch_free( type.bv_val );
+
+       if( rc != LDAP_SUCCESS ) {
+               text = NULL;
+               ch_free( f->f_sub );
+               f->f_choice = SLAPD_FILTER_COMPUTED;
+               f->f_result = SLAPD_COMPARE_UNDEFINED;
+               *fstr = ch_strdup( "(undefined)" );
+               return LDAP_SUCCESS;
        }
-       attr_normalize( f->f_sub_type );
-       syntax = attr_syntax( f->f_sub_type );
+
        f->f_sub_initial = NULL;
        f->f_sub_any = NULL;
        f->f_sub_final = NULL;
 
-       *fstr = ch_malloc( strlen( f->f_sub_type ) + 3 );
-       sprintf( *fstr, "(%s=", f->f_sub_type );
+       if( fstr ) {
+               *fstr = ch_malloc( sizeof("(=" /*)*/) +
+                       f->f_sub_desc->ad_cname->bv_len );
+               sprintf( *fstr, "(%s=" /*)*/, f->f_sub_desc->ad_cname->bv_val );
+       }
+
        for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
            tag = ber_next_element( ber, &len, last ) )
        {
-               rc = ber_scanf( ber, "a", &val );
+               unsigned usage;
+
+               rc = ber_scanf( ber, "O", &value );
                if ( rc == LBER_ERROR ) {
-                       return( -1 );
+                       rc = SLAPD_DISCONNECT;
+                       goto return_error;
                }
-               if ( val == NULL || *val == '\0' ) {
-                       if ( val != NULL ) {
-                               free( val );
-                       }
-                       return( LDAP_INVALID_SYNTAX );
+
+               if ( value == NULL || value->bv_len == 0 ) {
+                       ber_bvfree( value );
+                       rc = LDAP_INVALID_SYNTAX;
+                       goto return_error;
+               } 
+
+               switch ( tag ) {
+               case LDAP_SUBSTRING_INITIAL:
+                       usage = SLAP_MR_SUBSTR_INITIAL;
+                       break;
+
+               case LDAP_SUBSTRING_ANY:
+                       usage = SLAP_MR_SUBSTR_ANY;
+                       break;
+
+               case LDAP_SUBSTRING_FINAL:
+                       usage = SLAP_MR_SUBSTR_FINAL;
+                       break;
+
+               default:
+                       rc = LDAP_PROTOCOL_ERROR;
+
+                       Debug( LDAP_DEBUG_FILTER,
+                               "  unknown substring choice=%ld\n",
+                               (long) tag, 0, 0 );
+
+                       ber_bvfree( value );
+                       goto return_error;
+               }
+
+               rc = value_normalize( f->f_sub_desc, usage, value, &nvalue, text );
+               ber_bvfree( value );
+
+               if( rc != LDAP_SUCCESS ) {
+                       goto return_error;
                }
-               value_normalize( val, syntax );
+
+               value = nvalue;
+
+               rc = LDAP_PROTOCOL_ERROR;
 
                switch ( tag ) {
                case LDAP_SUBSTRING_INITIAL:
                        Debug( LDAP_DEBUG_FILTER, "  INITIAL\n", 0, 0, 0 );
                        if ( f->f_sub_initial != NULL ) {
-                               return( LDAP_PROTOCOL_ERROR );
+                               ber_bvfree( value );
+                               goto return_error;
+                       }
+
+                       f->f_sub_initial = value;
+
+                       if( fstr ) {
+                               *fstr = ch_realloc( *fstr,
+                                       strlen( *fstr ) + value->bv_len + 1 );
+                               strcat( *fstr, value->bv_val );
                        }
-                       f->f_sub_initial = val;
-                       *fstr = ch_realloc( *fstr, strlen( *fstr ) +
-                           strlen( val ) + 1 );
-                       strcat( *fstr, val );
                        break;
 
                case LDAP_SUBSTRING_ANY:
                        Debug( LDAP_DEBUG_FILTER, "  ANY\n", 0, 0, 0 );
-                       charray_add( &f->f_sub_any, val );
-                       *fstr = ch_realloc( *fstr, strlen( *fstr ) +
-                           strlen( val ) + 2 );
-                       strcat( *fstr, "*" );
-                       strcat( *fstr, val );
+                       if( ber_bvecadd( &f->f_sub_any, value ) < 0 ) {
+                               ber_bvfree( value );
+                               goto return_error;
+                       }
+
+                       if( fstr ) {
+                               *fstr = ch_realloc( *fstr,
+                                       strlen( *fstr ) + value->bv_len + 2 );
+                               strcat( *fstr, "*" );
+                               strcat( *fstr, value->bv_val );
+                       }
                        break;
 
                case LDAP_SUBSTRING_FINAL:
                        Debug( LDAP_DEBUG_FILTER, "  FINAL\n", 0, 0, 0 );
                        if ( f->f_sub_final != NULL ) {
-                               return( LDAP_PROTOCOL_ERROR );
+                               ber_bvfree( value );
+                               goto return_error;
+                       }
+                       f->f_sub_final = value;
+
+                       if( fstr ) {
+                               *fstr = ch_realloc( *fstr,
+                                       strlen( *fstr ) + value->bv_len + 2 );
+                               strcat( *fstr, "*" );
+                               strcat( *fstr, value->bv_val );
                        }
-                       f->f_sub_final = val;
-                       *fstr = ch_realloc( *fstr, strlen( *fstr ) +
-                           strlen( val ) + 2 );
-                       strcat( *fstr, "*" );
-                       strcat( *fstr, val );
                        break;
 
                default:
-                       Debug( LDAP_DEBUG_FILTER, "  unknown type\n", tag, 0,
-                           0 );
-                       return( LDAP_PROTOCOL_ERROR );
+                       Debug( LDAP_DEBUG_FILTER,
+                               "  unknown substring type=%ld\n",
+                               (long) tag, 0, 0 );
+
+                       ber_bvfree( value );
+
+return_error:
+                       Debug( LDAP_DEBUG_FILTER, "  error=%ld\n",
+                               (long) rc, 0, 0 );
+
+                       if( fstr ) {
+                               free( *fstr );
+                               *fstr = NULL;
+                       }
+
+                       ad_free( f->f_sub_desc, 1 );
+                       ber_bvfree( f->f_sub_initial );
+                       ber_bvecfree( f->f_sub_any );
+                       ber_bvfree( f->f_sub_final );
+                       ch_free( f->f_sub );
+                       return rc;
                }
        }
-       *fstr = ch_realloc( *fstr, strlen( *fstr ) + 3 );
-       if ( f->f_sub_final == NULL ) {
-               strcat( *fstr, "*" );
+
+       if( fstr ) {
+               *fstr = ch_realloc( *fstr, strlen( *fstr ) + 3 );
+               if ( f->f_sub_final == NULL ) {
+                       strcat( *fstr, "*" );
+               }
+               strcat( *fstr, /*(*/ ")" );
        }
-       strcat( *fstr, ")" );
 
        Debug( LDAP_DEBUG_FILTER, "end get_substring_filter\n", 0, 0, 0 );
        return( LDAP_SUCCESS );
@@ -319,29 +515,25 @@ filter_free( Filter *f )
        }
 
        switch ( f->f_choice ) {
+       case LDAP_FILTER_PRESENT:
+               ad_free( f->f_desc, 1 );
+               break;
+
        case LDAP_FILTER_EQUALITY:
        case LDAP_FILTER_GE:
        case LDAP_FILTER_LE:
        case LDAP_FILTER_APPROX:
-               ava_free( &f->f_ava, 0 );
+               ava_free( f->f_ava, 1 );
                break;
 
        case LDAP_FILTER_SUBSTRINGS:
-               if ( f->f_sub_type != NULL ) {
-                       free( f->f_sub_type );
-               }
+               ad_free( f->f_sub_desc, 1 );
                if ( f->f_sub_initial != NULL ) {
-                       free( f->f_sub_initial );
+                       ber_bvfree( f->f_sub_initial );
                }
-               charray_free( f->f_sub_any );
+               ber_bvecfree( f->f_sub_any );
                if ( f->f_sub_final != NULL ) {
-                       free( f->f_sub_final );
-               }
-               break;
-
-       case LDAP_FILTER_PRESENT:
-               if ( f->f_type != NULL ) {
-                       free( f->f_type );
+                       ber_bvfree( f->f_sub_final );
                }
                break;
 
@@ -354,11 +546,15 @@ filter_free( Filter *f )
                }
                break;
 
+       case SLAPD_FILTER_COMPUTED:
+               break;
+
        default:
-               Debug( LDAP_DEBUG_ANY, "unknown filter type %lu\n",
+               Debug( LDAP_DEBUG_ANY, "filter_free: unknown filter type=%lu\n",
                       f->f_choice, 0, 0 );
                break;
        }
+
        free( f );
 }
 
@@ -371,63 +567,81 @@ filter_print( Filter *f )
        Filter  *p;
 
        if ( f == NULL ) {
-               fprintf( stderr, "NULL" );
+               fprintf( stderr, "No filter!" );
        }
 
        switch ( f->f_choice ) {
        case LDAP_FILTER_EQUALITY:
-               fprintf( stderr, "(%s=%s)", f->f_ava.ava_type,
-                   f->f_ava.ava_value.bv_val );
+               fprintf( stderr, "(%s=%s)",
+                       f->f_av_desc->ad_cname->bv_val,
+                   f->f_av_value->bv_val );
                break;
 
        case LDAP_FILTER_GE:
-               fprintf( stderr, "(%s>=%s)", f->f_ava.ava_type,
-                   f->f_ava.ava_value.bv_val );
+               fprintf( stderr, "(%s>=%s)",
+                       f->f_av_desc->ad_cname->bv_val,
+                   f->f_av_value->bv_val );
                break;
 
        case LDAP_FILTER_LE:
-               fprintf( stderr, "(%s<=%s)", f->f_ava.ava_type,
-                   f->f_ava.ava_value.bv_val );
+               fprintf( stderr, "(%s<=%s)",
+                       f->f_ava->aa_desc->ad_cname->bv_val,
+                   f->f_ava->aa_value->bv_val );
                break;
 
        case LDAP_FILTER_APPROX:
-               fprintf( stderr, "(%s~=%s)", f->f_ava.ava_type,
-                   f->f_ava.ava_value.bv_val );
+               fprintf( stderr, "(%s~=%s)",
+                       f->f_ava->aa_desc->ad_cname->bv_val,
+                   f->f_ava->aa_value->bv_val );
                break;
 
        case LDAP_FILTER_SUBSTRINGS:
-               fprintf( stderr, "(%s=", f->f_sub_type );
+               fprintf( stderr, "(%s=" /*)*/,
+                       f->f_sub_desc->ad_cname->bv_val );
                if ( f->f_sub_initial != NULL ) {
-                       fprintf( stderr, "%s", f->f_sub_initial );
+                       fprintf( stderr, "%s",
+                               f->f_sub_initial->bv_val );
                }
                if ( f->f_sub_any != NULL ) {
                        for ( i = 0; f->f_sub_any[i] != NULL; i++ ) {
-                               fprintf( stderr, "*%s", f->f_sub_any[i] );
+                               fprintf( stderr, "*%s",
+                                       f->f_sub_any[i]->bv_val );
                        }
                }
-               charray_free( f->f_sub_any );
                if ( f->f_sub_final != NULL ) {
-                       fprintf( stderr, "*%s", f->f_sub_final );
+                       fprintf( stderr,
+                               "*%s", f->f_sub_final->bv_val );
                }
+               fprintf( stderr, /*(*/ ")" );
                break;
 
        case LDAP_FILTER_PRESENT:
-               fprintf( stderr, "%s=*", f->f_type );
+               fprintf( stderr, "(%s=*)",
+                       f->f_desc->ad_cname->bv_val );
                break;
 
        case LDAP_FILTER_AND:
        case LDAP_FILTER_OR:
        case LDAP_FILTER_NOT:
-               fprintf( stderr, "(%c", f->f_choice == LDAP_FILTER_AND ? '&' :
+               fprintf( stderr, "(%c" /*)*/,
+                       f->f_choice == LDAP_FILTER_AND ? '&' :
                    f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
                for ( p = f->f_list; p != NULL; p = p->f_next ) {
                        filter_print( p );
                }
-               fprintf( stderr, ")" );
+               fprintf( stderr, /*(*/ ")" );
+               break;
+
+       case SLAPD_FILTER_COMPUTED:
+               fprintf( stderr, "(?=%s)",
+                       f->f_result == LDAP_COMPARE_FALSE ? "false" :
+                       f->f_result == LDAP_COMPARE_TRUE ? "true" :
+                       f->f_result == SLAPD_COMPARE_UNDEFINED ? "undefined" :
+                       "error" );
                break;
 
        default:
-               fprintf( stderr, "unknown type %lu", f->f_choice );
+               fprintf( stderr, "(unknown-filter=%lu)", f->f_choice );
                break;
        }
 }
index c1abb4555d4b7a2b5d9be305671e0828fd9e664b..bd3e62eaed3b187d0c59f20822e00718b06d9996 100644 (file)
@@ -1,7 +1,7 @@
 /* filterentry.c - apply a filter to an entry */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 
 #include <ac/socket.h>
 #include <ac/string.h>
-#include <ac/regex.h>
+
 
 #include "slap.h"
 
-static int     test_filter_list(Backend *be, Connection *conn, Operation *op, Entry *e, Filter *flist, int ftype);
-static int     test_substring_filter(Backend *be, Connection *conn, Operation *op, Entry *e, Filter *f);
-static int     test_ava_filter(Backend *be, Connection *conn, Operation *op, Entry *e, Ava *ava, int type);
-static int     test_approx_filter(Backend *be, Connection *conn, Operation *op, Entry *e, Ava *ava);
-static int     test_presence_filter(Backend *be, Connection *conn, Operation *op, Entry *e, char *type);
+static int     test_filter_and( Backend *be,
+       Connection *conn, Operation *op,
+       Entry *e, Filter *flist );
+static int     test_filter_or( Backend *be,
+       Connection *conn, Operation *op,
+       Entry *e, Filter *flist );
+static int     test_substring_filter( Backend *be,
+       Connection *conn, Operation *op,
+       Entry *e, Filter *f);
+static int     test_ava_filter( Backend *be,
+       Connection *conn, Operation *op,
+       Entry *e, AttributeAssertion *ava, int type );
+static int     test_mra_filter( Backend *be,
+       Connection *conn, Operation *op,
+       Entry *e, MatchingRuleAssertion *mra );
+static int     test_presence_filter( Backend *be,
+       Connection *conn, Operation *op,
+       Entry *e, AttributeDescription *desc );
+
 
 /*
  * test_filter - test a filter against a single entry.
- * returns     0       filter matched
- *             -1      filter did not match
- *             >0      an ldap error code
+ * returns:
+ *             LDAP_COMPARE_TRUE               filter matched
+ *             LDAP_COMPARE_FALSE              filter did not match
+ *             SLAPD_COMPARE_UNDEFINED filter is undefined
+ *     or an ldap result code indicating error
  */
 
 int
@@ -42,9 +58,18 @@ test_filter(
        Debug( LDAP_DEBUG_FILTER, "=> test_filter\n", 0, 0, 0 );
 
        switch ( f->f_choice ) {
+       case SLAPD_FILTER_COMPUTED:
+               Debug( LDAP_DEBUG_FILTER, "    COMPUTED %s (%d)\n",
+                       f->f_result == LDAP_COMPARE_FALSE ? "false" :
+                       f->f_result == LDAP_COMPARE_TRUE ? "true" :
+                       f->f_result == SLAPD_COMPARE_UNDEFINED ? "undefined" : "error",
+                       f->f_result, 0 );
+               rc = f->f_result;
+               break;
+
        case LDAP_FILTER_EQUALITY:
                Debug( LDAP_DEBUG_FILTER, "    EQUALITY\n", 0, 0, 0 );
-               rc = test_ava_filter( be, conn, op, e, &f->f_ava,
+               rc = test_ava_filter( be, conn, op, e, f->f_ava,
                    LDAP_FILTER_EQUALITY );
                break;
 
@@ -54,262 +79,235 @@ test_filter(
                break;
 
        case LDAP_FILTER_GE:
-               Debug( LDAP_DEBUG_FILTER, "    GE\n", 0, 0, 0 );
-               rc = test_ava_filter( be, conn, op, e, &f->f_ava,
+               rc = test_ava_filter( be, conn, op, e, f->f_ava,
                    LDAP_FILTER_GE );
                break;
 
        case LDAP_FILTER_LE:
-               Debug( LDAP_DEBUG_FILTER, "    LE\n", 0, 0, 0 );
-               rc = test_ava_filter( be, conn, op, e, &f->f_ava,
+               rc = test_ava_filter( be, conn, op, e, f->f_ava,
                    LDAP_FILTER_LE );
                break;
 
        case LDAP_FILTER_PRESENT:
                Debug( LDAP_DEBUG_FILTER, "    PRESENT\n", 0, 0, 0 );
-               rc = test_presence_filter( be, conn, op, e, f->f_type );
+               rc = test_presence_filter( be, conn, op, e, f->f_desc );
                break;
 
        case LDAP_FILTER_APPROX:
                Debug( LDAP_DEBUG_FILTER, "    APPROX\n", 0, 0, 0 );
-               rc = test_approx_filter( be, conn, op, e, &f->f_ava );
+               rc = test_ava_filter( be, conn, op, e, f->f_ava,
+                   LDAP_FILTER_APPROX );
                break;
 
        case LDAP_FILTER_AND:
                Debug( LDAP_DEBUG_FILTER, "    AND\n", 0, 0, 0 );
-               rc = test_filter_list( be, conn, op, e, f->f_and,
-                   LDAP_FILTER_AND );
+               rc = test_filter_and( be, conn, op, e, f->f_and );
                break;
 
        case LDAP_FILTER_OR:
                Debug( LDAP_DEBUG_FILTER, "    OR\n", 0, 0, 0 );
-               rc = test_filter_list( be, conn, op, e, f->f_or,
-                   LDAP_FILTER_OR );
+               rc = test_filter_or( be, conn, op, e, f->f_or );
                break;
 
        case LDAP_FILTER_NOT:
                Debug( LDAP_DEBUG_FILTER, "    NOT\n", 0, 0, 0 );
-               rc = (! test_filter( be, conn, op, e, f->f_not ) );
+               rc = test_filter( be, conn, op, e, f->f_not );
+
+               switch( rc ) {
+               case LDAP_COMPARE_TRUE:
+                       rc = LDAP_COMPARE_FALSE;
+                       break;
+               case LDAP_COMPARE_FALSE:
+                       rc = LDAP_COMPARE_TRUE;
+                       break;
+               }
                break;
 
+#ifdef SLAPD_EXT_FILTERS
+       case LDAP_FILTER_EXT:
+               Debug( LDAP_DEBUG_FILTER, "    EXT\n", 0, 0, 0 );
+               rc = test_mra_filter( be, conn, op, e, f->f_mra );
+               break;
+#endif
+
        default:
                Debug( LDAP_DEBUG_ANY, "    unknown filter type %lu\n",
                    f->f_choice, 0, 0 );
-               rc = -1;
+               rc = LDAP_PROTOCOL_ERROR;
        }
 
        Debug( LDAP_DEBUG_FILTER, "<= test_filter %d\n", rc, 0, 0 );
        return( rc );
 }
 
+
 static int
 test_ava_filter(
     Backend    *be,
     Connection *conn,
     Operation  *op,
     Entry      *e,
-    Ava                *ava,
+       AttributeAssertion *ava,
     int                type
 )
 {
-       int             i, rc;
+       int             i;
        Attribute       *a;
 
        if ( be != NULL && ! access_allowed( be, conn, op, e,
-               ava->ava_type, &ava->ava_value, ACL_SEARCH ) )
+               ava->aa_desc, ava->aa_value, ACL_SEARCH ) )
        {
-               return( -2 );
-       }
-
-       if ( (a = attr_find( e->e_attrs, ava->ava_type )) == NULL ) {
-               return( -1 );
+               return LDAP_INSUFFICIENT_ACCESS;
        }
 
-       if ( a->a_syntax == 0 ) {
-               a->a_syntax = attr_syntax( ava->ava_type );
-       }
-       for ( i = 0; a->a_vals[i] != NULL; i++ ) {
-               rc = value_cmp( a->a_vals[i], &ava->ava_value, a->a_syntax,
-                   3 );
+       for(a = attrs_find( e->e_attrs, ava->aa_desc );
+               a != NULL;
+               a = attrs_find( a->a_next, ava->aa_desc ) )
+       {
+               MatchingRule *mr;
 
                switch ( type ) {
+               case LDAP_FILTER_APPROX:
+                       mr = a->a_desc->ad_type->sat_approx;
+                       if( mr != NULL ) break;
+
                case LDAP_FILTER_EQUALITY:
-                       if ( rc == 0 ) {
-                               return( 0 );
-                       }
+                       mr = a->a_desc->ad_type->sat_equality;
                        break;
 
                case LDAP_FILTER_GE:
-                       if ( rc >= 0 ) {
-                               return( 0 );
-                       }
+               case LDAP_FILTER_LE:
+                       mr = a->a_desc->ad_type->sat_ordering;
                        break;
 
-               case LDAP_FILTER_LE:
-                       if ( rc <= 0 ) {
-                               return( 0 );
+               default:
+                       mr = NULL;
+               }
+
+               if( mr == NULL ) {
+                       continue;
+               }
+
+               for ( i = 0; a->a_vals[i] != NULL; i++ ) {
+                       int ret;
+                       int rc;
+                       const char *text;
+
+                       rc = value_match( &ret, a->a_desc, mr,
+                               a->a_vals[i], ava->aa_value,
+                               &text );
+
+                       if( rc != LDAP_SUCCESS ) {
+                               return rc;
+                       }
+
+                       switch ( type ) {
+                       case LDAP_FILTER_EQUALITY:
+                       case LDAP_FILTER_APPROX:
+                               if ( ret == 0 ) {
+                                       return LDAP_COMPARE_TRUE;
+                               }
+                               break;
+
+                       case LDAP_FILTER_GE:
+                               if ( ret >= 0 ) {
+                                       return LDAP_COMPARE_TRUE;
+                               }
+                               break;
+
+                       case LDAP_FILTER_LE:
+                               if ( ret <= 0 ) {
+                                       return LDAP_COMPARE_TRUE;
+                               }
+                               break;
                        }
-                       break;
                }
        }
 
-       return( 1 );
+       return( LDAP_COMPARE_FALSE );
 }
 
+
 static int
 test_presence_filter(
     Backend    *be,
     Connection *conn,
     Operation  *op,
     Entry      *e,
-    char       *type
+       AttributeDescription *desc
 )
 {
        if ( be != NULL && ! access_allowed( be, conn, op, e,
-               type, NULL, ACL_SEARCH ) )
+               desc, NULL, ACL_SEARCH ) )
        {
-               return( -2 );
+               return LDAP_INSUFFICIENT_ACCESS;
        }
 
-       return( attr_find( e->e_attrs, type ) != NULL ? 0 : -1 );
+       return attrs_find( e->e_attrs, desc ) != NULL
+               ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE;
 }
 
+
 static int
-test_approx_filter(
+test_filter_and(
     Backend    *be,
     Connection *conn,
     Operation  *op,
     Entry      *e,
-    Ava                *ava
+    Filter     *flist
 )
 {
-       char            *w1, *w2, *c1, *c2;
-       int             i;
-       Attribute       *a;
+       Filter  *f;
+       int rtn = LDAP_COMPARE_TRUE;
 
-       if ( be != NULL && ! access_allowed( be, conn, op, e,
-               ava->ava_type, NULL, ACL_SEARCH ) )
-       {
-               return( -2 );
-       }
+       Debug( LDAP_DEBUG_FILTER, "=> test_filter_and\n", 0, 0, 0 );
 
-       if ( (a = attr_find( e->e_attrs, ava->ava_type )) == NULL ) {
-               return( -1 );
-       }
-
-       /* for each value in the attribute */
-       for ( i = 0; a->a_vals[i] != NULL; i++ ) {
-               /*
-                * try to match words in the filter value in order
-                * in the attribute value.
-                */
-
-               w2 = a->a_vals[i]->bv_val;
-               /* for each word in the filter value */
-               for ( w1 = first_word( ava->ava_value.bv_val ); w1 != NULL;
-                   w1 = next_word( w1 ) ) {
-                       if ( (c1 = phonetic( w1 )) == NULL ) {
-                               break;
-                       }
+       for ( f = flist; f != NULL; f = f->f_next ) {
+               int rc = test_filter( be, conn, op, e, f );
 
-                       /*
-                        * for each word in the attribute value from
-                        * where we left off...
-                        */
-                       for ( w2 = first_word( w2 ); w2 != NULL;
-                           w2 = next_word( w2 ) ) {
-                               c2 = phonetic( w2 );
-                               if ( strcmp( c1, c2 ) == 0 ) {
-                                       free( c2 );
-                                       break;
-                               }
-                               free( c2 );
-                       }
-                       free( c1 );
-
-                       /*
-                        * if we stopped because we ran out of words
-                        * before making a match, go on to the next
-                        * value.  otherwise try to keep matching
-                        * words in this value from where we left off.
-                        */
-                       if ( w2 == NULL ) {
-                               break;
-                       } else {
-                               w2 = next_word( w2 );
-                       }
+               if ( rc == LDAP_COMPARE_FALSE ) {
+                       rtn = LDAP_COMPARE_FALSE;
+                       break;
                }
-               /*
-                * if we stopped because we ran out of words we
-                * have a match.
-                */
-               if ( w1 == NULL ) {
-                       return( 0 );
+               if ( rc != LDAP_COMPARE_TRUE ) {
+                       rtn = rc;
                }
        }
 
-       return( 1 );
+       Debug( LDAP_DEBUG_FILTER, "<= test_filter_and %d\n", rtn, 0, 0 );
+       return rtn;
 }
 
 static int
-test_filter_list(
+test_filter_or(
     Backend    *be,
     Connection *conn,
     Operation  *op,
     Entry      *e,
-    Filter     *flist,
-    int                ftype
+    Filter     *flist
 )
 {
-       int     nomatch;
        Filter  *f;
+       int rtn = LDAP_COMPARE_FALSE;
 
-       Debug( LDAP_DEBUG_FILTER, "=> test_filter_list\n", 0, 0, 0 );
+       Debug( LDAP_DEBUG_FILTER, "=> test_filter_or\n", 0, 0, 0 );
 
-       nomatch = 1;
        for ( f = flist; f != NULL; f = f->f_next ) {
-               if ( test_filter( be, conn, op, e, f ) != 0 ) {
-                       if ( ftype == LDAP_FILTER_AND ) {
-                               Debug( LDAP_DEBUG_FILTER,
-                                   "<= test_filter_list 1\n", 0, 0, 0 );
-                               return( 1 );
-                       }
-               } else {
-                       nomatch = 0;
+               int rc = test_filter( be, conn, op, e, f );
+
+               if ( rc == LDAP_COMPARE_TRUE ) {
+                       rtn = LDAP_COMPARE_TRUE;
+                       break;
+               }
+               if ( rc != LDAP_COMPARE_TRUE ) {
+                       rtn = rc;
                }
        }
 
-       Debug( LDAP_DEBUG_FILTER, "<= test_filter_list %d\n", nomatch, 0, 0 );
-       return( nomatch );
+       Debug( LDAP_DEBUG_FILTER, "<= test_filter_or %d\n", rtn, 0, 0 );
+       return rtn;
 }
 
-static void
-strcpy_regex( char *d, char *s )
-{
-       for ( ; *s; s++ ) {
-               switch ( *s ) {
-               case '^':
-               case '.':
-               case '[':
-               case ']': /* ? */
-               case '$':
-               case '(':
-               case ')': /* ? */
-               case '|':
-               case '*':
-               case '+':
-               case '?':
-               case '{':
-               case '}': /* ? */
-               case '\\':
-                       *d++ = '\\';
-                       /* FALL */
-               default:
-                       *d++ = *s;
-               }
-       }
-       *d = '\0';
-}
 
 static int
 test_substring_filter(
@@ -321,118 +319,45 @@ test_substring_filter(
 )
 {
        Attribute       *a;
-       int             i, rc;
-       char            *p, *end, *realval, *tmp;
-       char            pat[BUFSIZ];
-       char            buf[BUFSIZ];
-       struct berval   *val;
-       regex_t         re;
 
        Debug( LDAP_DEBUG_FILTER, "begin test_substring_filter\n", 0, 0, 0 );
 
        if ( be != NULL && ! access_allowed( be, conn, op, e,
-               f->f_sub_type, NULL, ACL_SEARCH ) )
+               f->f_sub_desc, NULL, ACL_SEARCH ) )
        {
-               return( -2 );
-       }
-
-       if ( (a = attr_find( e->e_attrs, f->f_sub_type )) == NULL ) {
-               return( -1 );
+               return LDAP_INSUFFICIENT_ACCESS;
        }
 
-       if ( a->a_syntax & SYNTAX_BIN ) {
-               Debug( LDAP_DEBUG_FILTER, "test_substring_filter bin attr\n",
-                   0, 0, 0 );
-               return( -1 );
-       }
+       for(a = attrs_find( e->e_attrs, f->f_sub_desc );
+               a != NULL;
+               a = attrs_find( a->a_next, f->f_sub_desc ) )
+       {
+               int i;
+               MatchingRule *mr = a->a_desc->ad_type->sat_substr;
 
-       /*
-        * construct a regular expression corresponding to the
-        * filter and let regex do the work
-        */
-
-       pat[0] = '\0';
-       p = pat;
-       end = pat + sizeof(pat) - 2;    /* leave room for null */
-       if ( f->f_sub_initial != NULL ) {
-               strcpy( p, "^" );
-               p = strchr( p, '\0' );
-               /* 2 * in case every char is special */
-               if ( p + 2 * strlen( f->f_sub_initial ) > end ) {
-                       Debug( LDAP_DEBUG_ANY, "not enough pattern space\n",
-                           0, 0, 0 );
-                       return( -1 );
-               }
-               strcpy_regex( p, f->f_sub_initial );
-               p = strchr( p, '\0' );
-       }
-       if ( f->f_sub_any != NULL ) {
-               for ( i = 0; f->f_sub_any[i] != NULL; i++ ) {
-                       /* ".*" + value */
-                       if ( p + 2 * strlen( f->f_sub_any[i] ) + 2 > end ) {
-                               Debug( LDAP_DEBUG_ANY,
-                                   "not enough pattern space\n", 0, 0, 0 );
-                               return( -1 );
-                       }
-                       strcpy( p, ".*" );
-                       p = strchr( p, '\0' );
-                       strcpy_regex( p, f->f_sub_any[i] );
-                       p = strchr( p, '\0' );
+               if( mr == NULL ) {
+                       continue;
                }
-       }
-       if ( f->f_sub_final != NULL ) {
-               /* ".*" + value */
-               if ( p + 2 * strlen( f->f_sub_final ) + 2 > end ) {
-                       Debug( LDAP_DEBUG_ANY, "not enough pattern space\n",
-                           0, 0, 0 );
-                       return( -1 );
-               }
-               strcpy( p, ".*" );
-               p = strchr( p, '\0' );
-               strcpy_regex( p, f->f_sub_final );
-               p = strchr( p, '\0' );
-               strcpy( p, "$" );
-       }
 
-       /* compile the regex */
-       Debug( LDAP_DEBUG_FILTER, "test_substring_filter: regcomp pat: %s\n",
-               pat, 0, 0 );
-       if ((rc = regcomp(&re, pat, REG_EXTENDED|REG_NOSUB))) {
-               char error[512];
-
-               regerror(rc, &re, error, sizeof(error));
-               Debug( LDAP_DEBUG_ANY, "regcomp failed (%s) %s\n",
-                       p, error, 0 );
-               return( -1 );
-       }
+               for ( i = 0; a->a_vals[i] != NULL; i++ ) {
+                       int ret;
+                       int rc;
+                       const char *text;
 
-       /* for each value in the attribute see if regex matches */
-       for ( i = 0; a->a_vals[i] != NULL; i++ ) {
-               val = a->a_vals[i];
-               tmp = NULL;
-               if ( val->bv_len < sizeof(buf) ) {
-                       strcpy( buf, val->bv_val );
-                       realval = buf;
-               } else {
-                       tmp = (char *) ch_malloc( val->bv_len + 1 );
-                       strcpy( tmp, val->bv_val );
-                       realval = tmp;
-               }
-               value_normalize( realval, a->a_syntax );
+                       rc = value_match( &ret, a->a_desc, mr,
+                               a->a_vals[i], f->f_sub,
+                               &text );
 
-               rc = !regexec(&re, realval, 0, NULL, 0);
+                       if( rc != LDAP_SUCCESS ) {
+                               return rc;
+                       }
 
-               if ( tmp != NULL ) {
-                       free( tmp );
-               }
-               if ( rc == 1 ) {
-                       regfree(&re);
-                       return( 0 );
+                       if ( ret == 0 ) {
+                               return LDAP_COMPARE_TRUE;
+                       }
                }
        }
 
-       regfree(&re);
-
        Debug( LDAP_DEBUG_FILTER, "end test_substring_filter 1\n", 0, 0, 0 );
-       return( 1 );
+       return LDAP_COMPARE_FALSE;
 }
diff --git a/servers/slapd/index.c b/servers/slapd/index.c
new file mode 100644 (file)
index 0000000..153cff7
--- /dev/null
@@ -0,0 +1,68 @@
+/* index.c - index utilities */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include "slap.h"
+
+int
+slap_index2prefix( int indextype )
+{
+       int     prefix;
+
+       switch ( indextype ) {
+       case SLAP_INDEX_EQUALITY:
+               prefix = SLAP_INDEX_EQUALITY_PREFIX;
+               break;
+       case SLAP_INDEX_APPROX:
+               prefix = SLAP_INDEX_APPROX_PREFIX;
+               break;
+       case SLAP_INDEX_SUBSTR:
+               prefix = SLAP_INDEX_SUBSTR_PREFIX;
+               break;
+       default:
+               prefix = SLAP_INDEX_UNKNOWN_PREFIX;
+               break;
+       }
+
+       return( prefix );
+}
+
+int slap_str2index( const char *str, slap_index *idx )
+{
+       if ( strcasecmp( str, "pres" ) == 0 ) {
+               *idx = SLAP_INDEX_PRESENT;
+       } else if ( strcasecmp( str, "eq" ) == 0 ) {
+               *idx = SLAP_INDEX_EQUALITY;
+       } else if ( strcasecmp( str, "approx" ) == 0 ) {
+               *idx = SLAP_INDEX_APPROX;
+       } else if ( strcasecmp( str, "subinitial" ) == 0 ) {
+               *idx = SLAP_INDEX_SUBSTR_INITIAL;
+       } else if ( strcasecmp( str, "subany" ) == 0 ) {
+               *idx = SLAP_INDEX_SUBSTR_ANY;
+       } else if ( strcasecmp( str, "subfinal" ) == 0 ) {
+               *idx = SLAP_INDEX_SUBSTR_FINAL;
+       } else if ( strcasecmp( str, "substr" ) == 0 ||
+               strcasecmp( str, "sub" ) == 0 )
+       {
+               *idx = SLAP_INDEX_SUBSTR_DEFAULT;
+       } else if ( strcasecmp( str, "lang" ) == 0 ) {
+               *idx = SLAP_INDEX_LANG;
+       } else if ( strcasecmp( str, "autolang" ) == 0 ) {
+               *idx = SLAP_INDEX_AUTO_LANG;
+       } else if ( strcasecmp( str, "subtypes" ) == 0 ) {
+               *idx = SLAP_INDEX_SUBTYPES;
+       } else if ( strcasecmp( str, "autosubtypes" ) == 0 ) {
+               *idx = SLAP_INDEX_AUTO_SUBTYPES;
+       } else {
+               return LDAP_OTHER;
+       }
+
+       return LDAP_SUCCESS;
+}
index f6e2cf9fc7bf40711b9b8b266999415e889dbb21..cda4397d1aab8ed5fa7df822b73c0d5e2d41e8d0 100644 (file)
@@ -1,7 +1,7 @@
 /* init.c - initialize various things */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -27,7 +27,10 @@ int          ldap_syslog = LDAP_DEBUG_STATS;
 int            ldap_syslog;
 #endif
 
+#ifdef LOG_DEBUG
 int            ldap_syslog_level = LOG_DEBUG;
+#endif
+
 struct berval **default_referral = NULL;
 int            g_argc;
 char           **g_argv;
@@ -35,10 +38,7 @@ char         **g_argv;
 /*
  * global variables that need mutex protection
  */
-int                            active_threads;
-ldap_pvt_thread_mutex_t        active_threads_mutex;
-ldap_pvt_thread_cond_t active_threads_cond;
-
+ldap_pvt_thread_pool_t connection_pool;
 ldap_pvt_thread_mutex_t        gmtime_mutex;
 #ifdef SLAPD_CRYPT
 ldap_pvt_thread_mutex_t        crypt_mutex;
@@ -61,13 +61,13 @@ ldap_pvt_thread_mutex_t     num_sent_mutex;
 ldap_pvt_thread_mutex_t        entry2str_mutex;
 ldap_pvt_thread_mutex_t        replog_mutex;
 
-static char* slap_name;
+static const char* slap_name = NULL;
 int slapMode = SLAP_UNDEFINED_MODE;
 
 static ldap_pvt_thread_mutex_t currenttime_mutex;
 
 int
-slap_init( int mode, char *name )
+slap_init( int mode, const char *name )
 {
        int rc;
 
@@ -86,15 +86,15 @@ slap_init( int mode, char *name )
                case SLAP_SERVER_MODE:
                case SLAP_TOOL_MODE:
                        Debug( LDAP_DEBUG_TRACE,
-                               "%s init: initiated %s.\n",
-                               name, ( mode & SLAP_TOOL_MODE ) ? "tool" : "server", 0 );
+                               "%s init: initiated %s.\n",     name,
+                               (mode & SLAP_MODE) == SLAP_TOOL_MODE ? "tool" : "server",
+                               0 );
 
                        slap_name = name;
        
                        (void) ldap_pvt_thread_initialize();
 
-                       ldap_pvt_thread_mutex_init( &active_threads_mutex );
-                       ldap_pvt_thread_cond_init( &active_threads_cond );
+                       ldap_pvt_thread_pool_init(&connection_pool, 0, 0);
 
                        ldap_pvt_thread_mutex_init( &currenttime_mutex );
                        ldap_pvt_thread_mutex_init( &entry2str_mutex );
diff --git a/servers/slapd/kerberos.c b/servers/slapd/kerberos.c
new file mode 100644 (file)
index 0000000..66825e5
--- /dev/null
@@ -0,0 +1,49 @@
+/* kerberos.c - ldbm backend kerberos bind routines */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
+
+#include <stdio.h>
+
+#include <ac/krb.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+
+#include "slap.h"
+
+#define LDAP_KRB_PRINCIPAL     "ldapserver"
+
+krbv4_ldap_auth(
+    Backend            *be,
+    struct berval      *cred,
+    AUTH_DAT           *ad
+)
+{
+       KTEXT_ST        k;
+       KTEXT           ktxt = &k;
+       char            instance[INST_SZ];
+       int             err;
+
+       Debug( LDAP_DEBUG_TRACE, "=> kerberosv4_ldap_auth\n", 0, 0, 0 );
+
+       SAFEMEMCPY( ktxt->dat, cred->bv_val, cred->bv_len );
+       ktxt->length = cred->bv_len;
+
+       strcpy( instance, "*" );
+       if ( (err = krb_rd_req( ktxt, LDAP_KRB_PRINCIPAL, instance, 0L, ad,
+           ldap_srvtab )) != KSUCCESS ) {
+               Debug( LDAP_DEBUG_ANY, "krb_rd_req failed (%s)\n",
+                   krb_err_txt[err], 0, 0 );
+               return( LDAP_INVALID_CREDENTIALS );
+       }
+
+       return( LDAP_SUCCESS );
+}
+
+#endif /* kerberos */
index b18f03e2f01019249d45c3d99ab0b96d5c3638b3..da4167d05a4584d1189ab4226d6468b96d1c31fa 100644 (file)
@@ -39,9 +39,10 @@ CPP=cl.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release\libslapd"
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\libslapd"
 # PROP Target_Dir ""
+RSC=rc.exe
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
 # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
 BSC32=bscmake.exe
@@ -60,9 +61,10 @@ LIB32=link.exe -lib
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug\libslapd"
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\libslapd"
 # PROP Target_Dir ""
+RSC=rc.exe
 # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
 # ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
 BSC32=bscmake.exe
@@ -81,9 +83,10 @@ LIB32=link.exe -lib
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir "SDebug"
-# PROP Intermediate_Dir "SDebug\libslapd"
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\libslapd"
 # PROP Target_Dir ""
+RSC=rc.exe
 # ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
 # ADD CPP /nologo /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
 BSC32=bscmake.exe
@@ -102,9 +105,10 @@ LIB32=link.exe -lib
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir "SRelease"
-# PROP Intermediate_Dir "SRelease\libslapd"
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\libslapd"
 # PROP Target_Dir ""
+RSC=rc.exe
 # ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
 # ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
 BSC32=bscmake.exe
@@ -136,10 +140,18 @@ SOURCE=.\aclparse.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\ad.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\add.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\at.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\attr.c
 # End Source File
 # Begin Source File
@@ -212,10 +224,18 @@ SOURCE=.\filterentry.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\index.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\init.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\kerberos.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\lock.c
 # End Source File
 # Begin Source File
@@ -232,10 +252,22 @@ SOURCE=.\monitor.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\mr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\oc.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\operation.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\passwd.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\phonetic.c
 # End Source File
 # Begin Source File
@@ -260,6 +292,18 @@ SOURCE=.\schema.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\schema_check.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\schema_init.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\schema_prep.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\schemaparse.c
 # End Source File
 # Begin Source File
@@ -272,6 +316,10 @@ SOURCE=.\slap.h
 # End Source File
 # Begin Source File
 
+SOURCE=.\starttls.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\str2filter.c
 # End Source File
 # Begin Source File
@@ -280,6 +328,10 @@ SOURCE=.\suffixalias.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\syntax.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\unbind.c
 # End Source File
 # Begin Source File
index e9f5fda164383f1948fd6279e831ea324d2b8c59..14f0315dca502d154b936c5d97bd88e75f5c4f60 100644 (file)
@@ -1,7 +1,7 @@
 /* lock.c - routines to open and apply an advisory lock to a file */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -17,9 +17,7 @@
 #ifdef HAVE_SYS_FILE_H
 #include <sys/file.h>
 #endif
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
+
 #include "slap.h"
 
 FILE *
index a797cf621d126a3d9426196dad677f81b91a54f3..b065a21db026523046f21d4fb3616cf67ffadeb6 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 #include "portable.h"
 static RETSIGTYPE wait4child( int sig );
 #endif
 
-#ifdef HAVE_WINSOCK
+#ifdef HAVE_NT_SERVICE_MANAGER
 #define MAIN_RETURN(x) return
 struct sockaddr_in     bind_addr;
 
 /* in nt_main.c */
-extern SERVICE_STATUS                  SLAPDServiceStatus;
-extern SERVICE_STATUS_HANDLE   hSLAPDServiceStatus;
+LIBLUTIL_F (SERVICE_STATUS)            SLAPDServiceStatus;
+LIBLUTIL_F (SERVICE_STATUS_HANDLE)     hSLAPDServiceStatus;
 extern ldap_pvt_thread_cond_t  started_event,          stopped_event;
 extern int       is_NT_Service;
 
-void LogSlapdStartedEvent( char *svc, int slap_debug, char *configfile, char *urls );
-void LogSlapdStoppedEvent( char *svc );
-
-void CommenceStartupProcessing( LPCTSTR serviceName,
+void CommenceStartupProcessing( LPCTSTR serverName,
                                                           void(*stopper)(int));
 void ReportSlapdShutdownComplete( void );
 void *getRegParam( char *svc, char *value );
 
-#define SERVICE_EXIT( e, n ) \
-               if ( is_NT_Service ) \
-{ \
-                       SLAPDServiceStatus.dwWin32ExitCode                              = e; \
-                       SLAPDServiceStatus.dwServiceSpecificExitCode    = n; \
-} 
+#define SERVICE_EXIT( e, n )   do { \
+       if ( is_NT_Service ) { \
+               SLAPDServiceStatus.dwWin32ExitCode                              = (e); \
+               SLAPDServiceStatus.dwServiceSpecificExitCode    = (n); \
+       } \
+} while ( 0 )
+
 #else
 #define SERVICE_EXIT( e, n )
 #define MAIN_RETURN(x) return(x)
 #endif
 
+#ifdef HAVE_NT_EVENT_LOG
+void LogSlapdStartedEvent( char *svc, int slap_debug, char *configfile, char *urls );
+void LogSlapdStoppedEvent( char *svc );
+#endif
+
 /*
  * when more than one slapd is running on one machine, each one might have
  * it's own LOCAL for syslogging and must have its own pid/args files
@@ -109,14 +112,7 @@ usage( char *name )
 #ifdef LOG_LOCAL4
                "\t-l sysloguser\tSyslog User (default: LOCAL4)\n"
 #endif
-#ifdef HAVE_WINSOCK
-               "\t-n NTserviceName\tNT service name\n"
-#endif
-
-               "\t-p port\tLDAP Port\n"
-#ifdef HAVE_TLS
-               "\t-P port\tLDAP over TLS Port\n"
-#endif
+               "\t-n serverName\tservice name\n"
                "\t-s level\tSyslog Level\n"
 #ifdef SLAPD_BDB2
                "\t-t\t\tEnable BDB2 timing\n"
@@ -127,7 +123,7 @@ usage( char *name )
     );
 }
 
-#ifdef HAVE_WINSOCK
+#ifdef HAVE_NT_SERVICE_MANAGER
 void WINAPI ServiceMain( DWORD argc, LPTSTR *argv )
 #else
 int main( int argc, char **argv )
@@ -140,25 +136,21 @@ int main( int argc, char **argv )
        char *username = NULL;
        char *groupname = NULL;
 #endif
+#if defined(HAVE_CHROOT)
+       char *sandbox = NULL;
+#endif
 #ifdef LOG_LOCAL4
     int     syslogUser = DEFAULT_SYSLOG_USER;
 #endif
-#ifdef HAVE_WINSOCK
-       char        *NTservice  = SERVICE_NAME;
+
+#ifdef HAVE_NT_SERVICE_MANAGER
        char            *configfile = ".\\slapd.conf";
 #else
        char            *configfile = SLAPD_DEFAULT_CONFIGFILE;
 #endif
-       char        *serverName;
+       char        *serverName = NULL;
        int         serverMode = SLAP_SERVER_MODE;
 
-       int port = LDAP_PORT;
-#ifdef HAVE_TLS
-       int tls_port = LDAPS_PORT;
-#else
-       int tls_port = 0;
-#endif
-
 #ifdef CSRIMALLOC
        FILE *leakfile;
        if( ( leakfile = fopen( "slapd.leak", "w" )) == NULL ) {
@@ -169,36 +161,39 @@ int main( int argc, char **argv )
        g_argc = argc;
        g_argv = argv;
 
-#ifdef HAVE_WINSOCK
+#ifdef HAVE_NT_SERVICE_MANAGER
        {
                int *i;
                char *newConfigFile;
+               char *newUrls;
+               char *regService = NULL;
 
                if ( is_NT_Service ) {
-                       CommenceStartupProcessing( NTservice, slap_sig_shutdown );
+                       serverName = argv[0];
+                       CommenceStartupProcessing( serverName, slap_sig_shutdown );
+                       if ( strcmp(serverName, SERVICE_NAME) )
+                           regService = serverName;
                }
 
-               i = (int*)getRegParam( NULL, "Port" );
-               if ( i != NULL )
-               {
-                       port = *i;
-                       Debug ( LDAP_DEBUG_ANY, "new port from registry is: %d\n", port, 0, 0 );
-               }
-#ifdef HAVE_TLS
-               i = (int*)getRegParam( NULL, "TLSPort" );
-               if ( i != NULL )
-               {
-                       tls_port = *i;
-                       Debug ( LDAP_DEBUG_ANY, "new TLS port from registry is: %d\n", tls_port, 0, 0 );
-               }
-#endif
-               i = (int*)getRegParam( NULL, "DebugLevel" );
+               i = (int*)getRegParam( regService, "DebugLevel" );
                if ( i != NULL ) 
                {
                        slap_debug = *i;
                        Debug( LDAP_DEBUG_ANY, "new debug level from registry is: %d\n", slap_debug, 0, 0 );
                }
-               newConfigFile = (char*)getRegParam( NULL, "ConfigFile" );
+
+               newUrls = (char *) getRegParam(regService, "Urls");
+               if (newUrls)
+               {
+                   if (urls)
+                       ch_free(urls);
+
+                   urls = ch_strdup(newUrls);
+                   Debug(LDAP_DEBUG_ANY, "new urls from registry: %s\n",
+                         urls, 0, 0);
+               }
+
+               newConfigFile = (char*)getRegParam( regService, "ConfigFile" );
                if ( newConfigFile != NULL ) 
                {
                        configfile = newConfigFile;
@@ -208,7 +203,10 @@ int main( int argc, char **argv )
 #endif
 
        while ( (i = getopt( argc, argv,
-                            "d:f:h:p:s:"
+                            "d:f:h:s:n:"
+#ifdef HAVE_CHROOT
+                               "r:"
+#endif
 #ifdef LOG_LOCAL4
                             "l:"
 #endif
@@ -220,12 +218,6 @@ int main( int argc, char **argv )
 #endif
 #ifdef LDAP_CONNECTIONLESS
                                 "c"
-#endif
-#ifdef HAVE_WINSOCK
-                                "n:"
-#endif
-#ifdef HAVE_TLS
-                            "P:"
 #endif
                             )) != EOF ) {
                switch ( i ) {
@@ -249,30 +241,6 @@ int main( int argc, char **argv )
                        configfile = ch_strdup( optarg );
                        break;
 
-               case 'p': {     /* port on which to listen */
-                               int p = atoi( optarg );
-                               if(! p ) {
-                                       fprintf(stderr, "-p %s must be numeric\n", optarg);
-                               } else if( p < 0 || p >= 1<<16) {
-                                       fprintf(stderr, "-p %s invalid\n", optarg);
-                               } else {
-                                       port = p;
-                               }
-                       } break;
-
-#ifdef HAVE_TLS
-               case 'P': {     /* port on which to listen for TLS */
-                               int p = atoi( optarg );
-                               if(! p ) {
-                                       fprintf(stderr, "-P %s must be numeric\n", optarg);
-                               } else if( p < 0 || p >= 1<<16) {
-                                       fprintf(stderr, "-P %s invalid\n", optarg);
-                               } else {
-                                       tls_port = p;
-                               }
-                       } break;
-#endif
-
                case 's':       /* set syslog level */
                        ldap_syslog = atoi( optarg );
                        break;
@@ -298,6 +266,13 @@ int main( int argc, char **argv )
                        break;
 #endif
 
+#ifdef HAVE_CHROOT
+               case 'r':
+                       if( sandbox ) free(sandbox);
+                       sandbox = ch_strdup( optarg );
+                       break;
+#endif
+
 #if defined(HAVE_SETUID) && defined(HAVE_SETGID)
                case 'u':       /* user name */
                        if( username ) free(username);
@@ -310,11 +285,11 @@ int main( int argc, char **argv )
                        break;
 #endif /* SETUID && GETUID */
 
-#ifdef HAVE_WINSOCK
                case 'n':  /* NT service name */
-                       NTservice = ch_strdup( optarg );
+                       if( serverName != NULL ) free( serverName );
+                       serverName = ch_strdup( optarg );
                        break;
-#endif
+
                default:
                        usage( argv[0] );
                        rc = 1;
@@ -329,45 +304,85 @@ int main( int argc, char **argv )
 
        Debug( LDAP_DEBUG_TRACE, "%s", Versionstr, 0, 0 );
 
-       if ( (serverName = strrchr( argv[0], *LDAP_DIRSEP )) == NULL ) {
-               serverName = ch_strdup( argv[0] );
-       } else {
-               serverName = ch_strdup( serverName + 1 );
+       if( serverName == NULL ) {
+               if ( (serverName = strrchr( argv[0], *LDAP_DIRSEP )) == NULL ) {
+                       serverName = ch_strdup( argv[0] );
+               } else {
+                       serverName = ch_strdup( serverName + 1 );
+               }
        }
 
 #ifdef LOG_LOCAL4
        openlog( serverName, OPENLOG_OPTIONS, syslogUser );
-#else
+#elif LOG_DEBUG
        openlog( serverName, OPENLOG_OPTIONS );
 #endif
 
-       if( slapd_daemon_init( urls, port, tls_port ) != 0 ) {
+       if( slapd_daemon_init( urls ) != 0 ) {
                rc = 1;
                SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 16 );
                goto stop;
        }
 
+#if defined(HAVE_CHROOT)
+       if ( sandbox && chroot( sandbox ) ) {
+               perror("chroot");
+               rc = 1;
+               goto stop;
+       }
+#endif
+
 #if defined(HAVE_SETUID) && defined(HAVE_SETGID)
        if ( username != NULL || groupname != NULL ) {
                slap_init_user( username, groupname );
        }
 #endif
 
+       extops_init();
+
+#ifdef SLAPD_MODULES
+       if ( module_init() != 0 ) {
+               rc = 1;
+               SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 17 );
+               goto destroy;
+       }
+#endif
+
        if ( slap_init( serverMode, serverName ) != 0 ) {
                rc = 1;
                SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 18 );
                goto destroy;
        }
 
+       if ( schema_init( ) != 0 ) {
+               Debug( LDAP_DEBUG_ANY,
+                   "schema initialization error\n",
+                   0, 0, 0 );
+               goto destroy;
+       }
+
        if ( read_config( configfile ) != 0 ) {
                rc = 1;
                SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 19 );
                goto destroy;
        }
 
+       if ( schema_prep( ) != 0 ) {
+               Debug( LDAP_DEBUG_ANY,
+                   "schema prep error\n",
+                   0, 0, 0 );
+               goto destroy;
+       }
+
 #ifdef HAVE_TLS
        ldap_pvt_tls_init();
-       ldap_pvt_tls_init_def_ctx();
+
+       if (ldap_pvt_tls_init_def_ctx() != 0)
+       {
+               rc = 1;
+               SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 20 );
+               goto destroy;
+       }
 #endif
 
        (void) SIGNAL( LDAP_SIGUSR1, slap_sig_wake );
@@ -390,7 +405,7 @@ int main( int argc, char **argv )
 #endif
 
 #ifndef HAVE_WINSOCK
-               lutil_detach( no_detach, 0 );
+       lutil_detach( no_detach, 0 );
 #endif /* HAVE_WINSOCK */
 
 #ifdef CSRIMALLOC
@@ -399,7 +414,7 @@ int main( int argc, char **argv )
 
        if ( slap_startup( NULL )  != 0 ) {
                rc = 1;
-               SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 20 );
+               SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 21 );
                goto shutdown;
        }
 
@@ -426,13 +441,14 @@ int main( int argc, char **argv )
                }
        }
 
-#ifdef HAVE_WINSOCK
-       LogSlapdStartedEvent( NTservice, slap_debug, configfile, urls );
+#ifdef HAVE_NT_EVENT_LOG
+       if (is_NT_Service)
+       LogSlapdStartedEvent( serverName, slap_debug, configfile, urls );
 #endif
 
        rc = slapd_daemon();
 
-#ifdef HAVE_WINSOCK
+#ifdef HAVE_NT_SERVICE_MANAGER
        /* Throw away the event that we used during the startup process. */
        if ( is_NT_Service )
                ldap_pvt_thread_cond_destroy( &started_event );
@@ -446,18 +462,27 @@ destroy:
        /* remember an error during destroy */
        rc |= slap_destroy();
 
+#ifdef SLAPD_MODULES
+       module_kill();
+#endif
+
+       extops_kill();
+
 stop:
-#ifdef HAVE_WINSOCK
-       LogSlapdStoppedEvent( NTservice );
+#ifdef HAVE_NT_EVENT_LOG
+       if (is_NT_Service)
+       LogSlapdStoppedEvent( serverName );
 #endif
 
        Debug( LDAP_DEBUG_ANY, "slapd stopped.\n", 0, 0, 0 );
 
-#ifdef HAVE_WINSOCK
+#ifdef HAVE_NT_SERVICE_MANAGER
        ReportSlapdShutdownComplete();
 #endif
 
+#ifdef LOG_DEBUG
     closelog();
+#endif
        slapd_daemon_destroy();
 
 #ifdef CSRIMALLOC
index 8e3521bfac690c7c0d7dcce6f9ee5393085af629..b39e4fa363c6daa9b3744c2a8b1ff438b0773dab 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
 #include <ac/string.h>
 #include <ac/time.h>
 
+#include "ldap_pvt.h"
 #include "slap.h"
 
-static void    modlist_free(LDAPModList *ml);
 
-static int add_modified_attrs( Operation *op, LDAPModList **modlist );
 
 int
 do_modify(
@@ -35,28 +34,22 @@ do_modify(
     Operation  *op
 )
 {
-       char            *ndn;
+       char            *dn, *ndn = NULL;
        char            *last;
        ber_tag_t       tag;
        ber_len_t       len;
-       LDAPModList     *modlist;
-       LDAPModList     **modtail;
+       LDAPModList     *modlist = NULL;
+       LDAPModList     **modtail = &modlist;
 #ifdef LDAP_DEBUG
        LDAPModList *tmp;
 #endif
+       Modifications *mods = NULL;
        Backend         *be;
        int rc;
+       const char      *text;
 
        Debug( LDAP_DEBUG_TRACE, "do_modify\n", 0, 0, 0 );
 
-       if( op->o_bind_in_progress ) {
-               Debug( LDAP_DEBUG_ANY, "do_modify: SASL bind in progress.\n",
-                       0, 0, 0 );
-               send_ldap_result( conn, op, LDAP_SASL_BIND_IN_PROGRESS,
-                       NULL, "SASL bind in progress", NULL, NULL );
-               return LDAP_SASL_BIND_IN_PROGRESS;
-       }
-
        /*
         * Parse the modify request.  It looks like this:
         *
@@ -76,26 +69,16 @@ do_modify(
         *      }
         */
 
-       if ( ber_scanf( op->o_ber, "{a" /*}*/, &ndn ) == LBER_ERROR ) {
+       if ( ber_scanf( op->o_ber, "{a" /*}*/, &dn ) == LBER_ERROR ) {
                Debug( LDAP_DEBUG_ANY, "do_modify: ber_scanf failed\n", 0, 0, 0 );
                send_ldap_disconnect( conn, op,
                        LDAP_PROTOCOL_ERROR, "decoding error" );
-               return -1;
+               return SLAPD_DISCONNECT;
        }
 
-       Debug( LDAP_DEBUG_ARGS, "do_modify: dn (%s)\n", ndn, 0, 0 );
-
-       if(     dn_normalize_case( ndn ) == NULL ) {
-               Debug( LDAP_DEBUG_ANY, "do_modify: invalid dn (%s)\n", ndn, 0, 0 );
-               send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
-                   "invalid DN", NULL, NULL );
-               free( ndn );
-               return rc;
-       }
+       Debug( LDAP_DEBUG_ARGS, "do_modify: dn (%s)\n", dn, 0, 0 );
 
        /* collect modifications & save for later */
-       modlist = NULL;
-       modtail = &modlist;
 
        for ( tag = ber_first_element( op->o_ber, &len, &last );
            tag != LBER_DEFAULT;
@@ -111,49 +94,61 @@ do_modify(
                {
                        send_ldap_disconnect( conn, op,
                                LDAP_PROTOCOL_ERROR, "decoding modlist error" );
-                       free( ndn );
-                       free( *modtail );
-                       *modtail = NULL;
-                       modlist_free( modlist );
-                       return -1;
+                       rc = SLAPD_DISCONNECT;
+                       goto cleanup;
                }
 
-               (*modtail)->ml_op = mop;
-               
-               if ( (*modtail)->ml_op != LDAP_MOD_ADD &&
-                   (*modtail)->ml_op != LDAP_MOD_DELETE &&
-                   (*modtail)->ml_op != LDAP_MOD_REPLACE )
-               {
-                       Debug( LDAP_DEBUG_ANY,
-                               "do_modify: invalid modify operation (%ld)\n",
-                               (long) (*modtail)->ml_op, 0, 0 );
-                       send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR,
-                           NULL, "unrecognized modify operation", NULL, NULL );
-                       free( ndn );
-                       modlist_free( modlist );
-                       return LDAP_PROTOCOL_ERROR;
-               }
+               switch( mop ) {
+               case LDAP_MOD_ADD:
+                       if ( (*modtail)->ml_bvalues == NULL ) {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "do_modify: modify/add operation (%ld) requires values\n",
+                                       (long) mop, 0, 0 );
+                               send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR,
+                                       NULL, "modify/add operation requires values",
+                                       NULL, NULL );
+                               rc = LDAP_PROTOCOL_ERROR;
+                               goto cleanup;
+                       }
 
-               if ( (*modtail)->ml_bvalues == NULL && (
-                       (*modtail)->ml_op != LDAP_MOD_REPLACE &&
-                       (*modtail)->ml_op != LDAP_MOD_DELETE ) )
-               {
-                       Debug( LDAP_DEBUG_ANY,
-                               "do_modify: invalid modify operation (%ld) without values\n",
-                               (long) (*modtail)->ml_op, 0, 0 );
-                       send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR,
-                           NULL, "unrecognized modify operation without values",
-                               NULL, NULL );
-                       free( ndn );
-                       modlist_free( modlist );
-                       return LDAP_PROTOCOL_ERROR;
+                       /* fall through */
+
+               case LDAP_MOD_DELETE:
+               case LDAP_MOD_REPLACE:
+                       break;
+
+               default: {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "do_modify: invalid modify operation (%ld)\n",
+                                       (long) mop, 0, 0 );
+                               send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR,
+                                       NULL, "unrecognized modify operation", NULL, NULL );
+                               rc = LDAP_PROTOCOL_ERROR;
+                               goto cleanup;
+                       }
                }
-               attr_normalize( (*modtail)->ml_type );
+
+               (*modtail)->ml_op = mop;
+               
 
                modtail = &(*modtail)->ml_next;
        }
        *modtail = NULL;
 
+       if( (rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_ANY, "do_modify: get_ctrls failed\n", 0, 0, 0 );
+               goto cleanup;
+       }
+
+       ndn = ch_strdup( dn );
+
+       if(     dn_normalize( ndn ) == NULL ) {
+               Debug( LDAP_DEBUG_ANY, "do_modify: invalid dn (%s)\n", dn, 0, 0 );
+               send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
+                   "invalid DN", NULL, NULL );
+               goto cleanup;
+       }
+
 #ifdef LDAP_DEBUG
        Debug( LDAP_DEBUG_ARGS, "modifications:\n", 0, 0, 0 );
        for ( tmp = modlist; tmp != NULL; tmp = tmp->ml_next ) {
@@ -164,15 +159,9 @@ do_modify(
        }
 #endif
 
-       if( (rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) {
-               free( ndn );
-               modlist_free( modlist );
-               Debug( LDAP_DEBUG_ANY, "do_modify: get_ctrls failed\n", 0, 0, 0 );
-               return rc;
-       } 
 
        Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d MOD dn=\"%s\"\n",
-           op->o_connid, op->o_opid, ndn, 0, 0 );
+           op->o_connid, op->o_opid, dn, 0, 0 );
 
        /*
         * We could be serving multiple database backends.  Select the
@@ -180,19 +169,26 @@ do_modify(
         * if we don't hold it.
         */
        if ( (be = select_backend( ndn )) == NULL ) {
-               free( ndn );
-               modlist_free( modlist );
                send_ldap_result( conn, op, rc = LDAP_REFERRAL,
                        NULL, NULL, default_referral, NULL );
-               return rc;
+               goto cleanup;
+       }
+
+       /* make sure this backend recongizes critical controls */
+       rc = backend_check_controls( be, conn, op, &text ) ;
+
+       if( rc != LDAP_SUCCESS ) {
+               send_ldap_result( conn, op, rc,
+                       NULL, text, NULL, NULL );
+               goto cleanup;
        }
 
        if ( global_readonly || be->be_readonly ) {
                Debug( LDAP_DEBUG_ANY, "do_modify: database is read-only\n",
                       0, 0, 0 );
                send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
-                                 NULL, "database is read-only", NULL, NULL );
-               goto done;
+                                 NULL, "directory is read-only", NULL, NULL );
+               goto cleanup;
        }
 
        /* deref suffix alias if appropriate */
@@ -214,29 +210,44 @@ do_modify(
                        strcmp( be->be_update_ndn, op->o_ndn ) == 0 )
 #endif
                {
+                       int update = be->be_update_ndn != NULL;
+                       const char *text;
+                       rc = slap_modlist2mods( modlist, update, &mods, &text );
+
+                       if( rc != LDAP_SUCCESS ) {
+                               send_ldap_result( conn, op, rc,
+                                       NULL, text, NULL, NULL );
+                               goto cleanup;
+                       }
+
                        if ( (be->be_lastmod == ON || (be->be_lastmod == UNDEFINED &&
-                               global_lastmod == ON)) && be->be_update_ndn == NULL )
+                               global_lastmod == ON)) && !update )
                        {
-                               rc = add_modified_attrs( op, &modlist );
+                               Modifications **modstail;
+                               for( modstail = &mods;
+                                       *modstail != NULL;
+                                       modstail = &(*modstail)->sml_next )
+                               {
+                                       /* empty */
+                               }
+                               rc = slap_mods_opattrs( op, modstail, &text );
 
                                if( rc != LDAP_SUCCESS ) {
-                                       free( ndn );
-                                       modlist_free( modlist );
                                        send_ldap_result( conn, op, rc,
-                                               NULL, "no-user-modification attribute type",
+                                               NULL, text,
                                                NULL, NULL );
-                                       return rc;
+                                       goto cleanup;
                                }
                        }
 
-                       if ( (*be->be_modify)( be, conn, op, ndn, modlist ) == 0 
+                       if ( (*be->be_modify)( be, conn, op, dn, ndn, mods ) == 0 
 #ifdef SLAPD_MULTIMASTER
                                && ( be->be_update_ndn == NULL ||
                                        strcmp( be->be_update_ndn, op->o_ndn ) != 0 )
 #endif
                        ) {
                                /* but we log only the ones not from a replicator user */
-                               replog( be, op, ndn, modlist );
+                               replog( be, op, dn, mods );
                        }
 
 #ifndef SLAPD_MULTIMASTER
@@ -249,76 +260,237 @@ do_modify(
                }
        } else {
                send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
-                   NULL, "Function not implemented", NULL, NULL );
+                   NULL, "operation not supported within namingContext", NULL, NULL );
        }
 
-done:
-       free( ndn );
-       modlist_free( modlist );
+cleanup:
+       free( dn );
+       if( ndn != NULL ) free( ndn );
+       if ( modlist != NULL )
+               slap_modlist_free( modlist );
+       if ( mods != NULL )
+               slap_mods_free( mods );
        return rc;
 }
 
-static int
-add_modified_attrs( Operation *op, LDAPModList **modlist )
+/*
+ * convert a raw list of modifications to internal format
+ * Do basic attribute type checking and syntax validation.
+ */
+int slap_modlist2mods(
+       LDAPModList *ml,
+       int update,
+       Modifications **mods,
+       const char **text )
 {
-       char            buf[22];
-       struct berval   bv;
-       struct berval   *bvals[2];
-       LDAPModList             *m;
-       struct tm       *ltm;
-       time_t          currenttime;
-
-       bvals[0] = &bv;
-       bvals[1] = NULL;
-
-       /* remove any attempts by the user to modify these attrs */
-       for ( m = *modlist; m != NULL; m = m->ml_next ) {
-               if ( oc_check_no_usermod_attr( m->ml_type ) ) {
+       int rc;
+       Modifications **modtail = mods;
+
+       for( ; ml != NULL; ml = ml->ml_next ) {
+               Modifications *mod;
+               AttributeDescription *ad = NULL;
+
+               mod = (Modifications *)
+                       ch_calloc( 1, sizeof(Modifications) );
+
+               /* copy the op */
+               mod->sml_op = ml->ml_op;
+
+               /* convert to attribute description */
+               rc = slap_str2ad( ml->ml_type, &mod->sml_desc, text );
+
+               if( rc != LDAP_SUCCESS ) {
+                       slap_mods_free( mod );
+                       return rc;
+               }
+
+               ad = mod->sml_desc;
+
+               if( slap_syntax_is_binary( ad->ad_type->sat_syntax )
+                       && !slap_ad_is_binary( ad ))
+               {
+                       /* attribute requires binary transfer */
+                       slap_mods_free( mod );
+                       *text = "attribute requires ;binary transfer";
+                       return LDAP_UNDEFINED_TYPE;
+               }
+
+               if( !slap_syntax_is_binary( ad->ad_type->sat_syntax )
+                       && slap_ad_is_binary( ad ))
+               {
+                       /* attribute requires binary transfer */
+                       slap_mods_free( mod );
+                       *text = "attribute disallows ;binary transfer";
+                       return LDAP_UNDEFINED_TYPE;
+               }
+
+               if (!update && is_at_no_user_mod( ad->ad_type )) {
+                       /* user modification disallowed */
+                       slap_mods_free( mod );
+                       *text = "no user modification allowed";
                        return LDAP_CONSTRAINT_VIOLATION;
                }
-       }
 
-       if ( op->o_dn == NULL || op->o_dn[0] == '\0' ) {
-               bv.bv_val = "NULLDN";
-               bv.bv_len = strlen( bv.bv_val );
-       } else {
-               bv.bv_val = op->o_dn;
-               bv.bv_len = strlen( bv.bv_val );
+               /*
+                * check values
+                */
+               if( ml->ml_bvalues != NULL ) {
+                       ber_len_t nvals;
+                       slap_syntax_validate_func *validate =
+                               ad->ad_type->sat_syntax->ssyn_validate;
+
+                       if( !validate ) {
+                               Debug( LDAP_DEBUG_TRACE,
+                                       "modlist2mods: no validator for syntax %s\n",
+                                       ad->ad_type->sat_syntax->ssyn_oid, 0, 0 );
+                               slap_mods_free( mod );
+                               *text = "no validator for syntax";
+                               return LDAP_INVALID_SYNTAX;
+                       }
+
+                       /*
+                        * check that each value is valid per syntax
+                        */
+                       for( nvals = 0; ml->ml_bvalues[nvals]; nvals++ ) {
+                               rc = validate( ad->ad_type->sat_syntax, ml->ml_bvalues[nvals] );
+
+                               if( rc != 0 ) {
+                                       slap_mods_free( mod );
+                                       *text = "value contains invalid data";
+                                       return LDAP_INVALID_SYNTAX;
+                               }
+                       }
+
+                       /*
+                        * a rough single value check... an additional check is needed
+                        * to catch add of single value to existing single valued attribute
+                        */
+                       if( ( mod->sml_op == LDAP_MOD_ADD || mod->sml_op == LDAP_MOD_REPLACE )
+                               && nvals > 1 && is_at_single_value( ad->ad_type ))
+                       {
+                               slap_mods_free( mod );
+                               *text = "multiple values provided";
+                               return LDAP_INVALID_SYNTAX;
+                       }
+               }
+
+               mod->sml_bvalues = ml->ml_bvalues;
+               ml->ml_values = NULL;
+
+               *modtail = mod;
+               modtail = &mod->sml_next;
        }
-       m = (LDAPModList *) ch_calloc( 1, sizeof(LDAPModList) );
-       m->ml_type = ch_strdup( "modifiersname" );
-       m->ml_op = LDAP_MOD_REPLACE;
-       m->ml_bvalues = (struct berval **) ch_calloc(2, sizeof(struct berval *));
-       m->ml_bvalues[0] = ber_bvdup( &bv );
-       m->ml_next = *modlist;
-       *modlist = m;
-
-       currenttime = slap_get_time();
+
+       return LDAP_SUCCESS;
+}
+
+int slap_mods_opattrs(
+       Operation *op,
+       Modifications **modtail,
+       const char **text )
+{
+       struct berval name, timestamp;
+       time_t now = slap_get_time();
+       char timebuf[22];
+       struct tm *ltm;
+       Modifications *mod;
+
+       int mop = op->o_tag == LDAP_REQ_ADD
+               ? LDAP_MOD_ADD : LDAP_MOD_REPLACE;
+
+       assert( modtail != NULL );
+       assert( *modtail == NULL );
+
        ldap_pvt_thread_mutex_lock( &gmtime_mutex );
-#ifndef LDAP_LOCALTIME
-       ltm = gmtime( &currenttime );
-       strftime( buf, sizeof(buf), "%Y%m%d%H%M%SZ", ltm );
-#else
-       ltm = localtime( &currenttime );
-       strftime( buf, sizeof(buf), "%y%m%d%H%M%SZ", ltm );
-#endif
+       ltm = gmtime( &now );
+       strftime( timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", ltm );
        ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
+       timestamp.bv_val = timebuf;
+       timestamp.bv_len = strlen(timebuf);
+
+       if( op->o_dn == NULL || op->o_dn[0] == '\0' ) {
+               name.bv_val = SLAPD_ANONYMOUS;
+               name.bv_len = sizeof(SLAPD_ANONYMOUS)-1;
+       } else {
+               name.bv_val = op->o_dn;
+               name.bv_len = strlen( op->o_dn );
+       }
+
+       if( op->o_tag == LDAP_REQ_ADD ) {
+               mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) );
+               mod->sml_op = mop;
+               mod->sml_desc = ad_dup( slap_schema.si_ad_creatorsName );
+               mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) );
+               mod->sml_bvalues[0] = ber_bvdup( &name );
+               mod->sml_bvalues[1] = NULL;
+
+               *modtail = mod;
+               modtail = &mod->sml_next;
+
+               mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) );
+               mod->sml_op = mop;
+               mod->sml_desc = ad_dup( slap_schema.si_ad_createTimestamp );
+               mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) );
+               mod->sml_bvalues[0] = ber_bvdup( &timestamp );
+               mod->sml_bvalues[1] = NULL;
+               *modtail = mod;
+               modtail = &mod->sml_next;
+       }
 
-       bv.bv_val = buf;
-       bv.bv_len = strlen( bv.bv_val );
-       m = (LDAPModList *) ch_calloc( 1, sizeof(LDAPModList) );
-       m->ml_type = ch_strdup( "modifytimestamp" );
-       m->ml_op = LDAP_MOD_REPLACE;
-       m->ml_bvalues = (struct berval **) ch_calloc(2, sizeof(struct berval *));
-       m->ml_bvalues[0] = ber_bvdup( &bv );
-       m->ml_next = *modlist;
-       *modlist = m;
+       mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) );
+       mod->sml_op = mop;
+       mod->sml_desc = ad_dup( slap_schema.si_ad_modifiersName );
+       mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) );
+       mod->sml_bvalues[0] = ber_bvdup( &name );
+       mod->sml_bvalues[1] = NULL;
+       *modtail = mod;
+       modtail = &mod->sml_next;
+
+       mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) );
+       mod->sml_op = mop;
+       mod->sml_desc = ad_dup( slap_schema.si_ad_modifyTimestamp );
+       mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) );
+       mod->sml_bvalues[0] = ber_bvdup( &timestamp );
+       mod->sml_bvalues[1] = NULL;
+       *modtail = mod;
+       modtail = &mod->sml_next;
 
        return LDAP_SUCCESS;
 }
 
-static void
-modlist_free(
+
+void
+slap_mod_free(
+       Modification    *mod,
+       int                             freeit
+)
+{
+       ad_free( mod->sm_desc, 1 );
+
+       if ( mod->sm_bvalues != NULL )
+               ber_bvecfree( mod->sm_bvalues );
+
+       if( freeit )
+               free( mod );
+}
+
+void
+slap_mods_free(
+    Modifications      *ml
+)
+{
+       Modifications *next;
+
+       for ( ; ml != NULL; ml = next ) {
+               next = ml->sml_next;
+
+               slap_mod_free( &ml->sml_mod, 0 );
+               free( ml );
+       }
+}
+
+void
+slap_modlist_free(
     LDAPModList        *ml
 )
 {
@@ -327,7 +499,9 @@ modlist_free(
        for ( ; ml != NULL; ml = next ) {
                next = ml->ml_next;
 
-               free( ml->ml_type );
+               if (ml->ml_type)
+                       free( ml->ml_type );
+
                if ( ml->ml_bvalues != NULL )
                        ber_bvecfree( ml->ml_bvalues );
 
index 14d643545b85dc16f4410783698323ed355f7c83..11434c9635ed02ea5559a4dde181e7e981c1ca0b 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
@@ -35,6 +35,7 @@
 #include <ac/socket.h>
 #include <ac/string.h>
 
+#include "ldap_pvt.h"
 #include "slap.h"
 
 int
@@ -43,7 +44,7 @@ do_modrdn(
     Operation  *op
 )
 {
-       char    *ndn, *newrdn;
+       char    *dn, *ndn = NULL, *newrdn;
        ber_int_t       deloldrdn;
        Backend *be;
        /* Vars for LDAP v3 newSuperior support */
@@ -52,17 +53,10 @@ do_modrdn(
        Backend *newSuperior_be = NULL;
        ber_len_t       length;
        int rc;
+       const char *text;
 
        Debug( LDAP_DEBUG_TRACE, "do_modrdn\n", 0, 0, 0 );
 
-       if( op->o_bind_in_progress ) {
-               Debug( LDAP_DEBUG_ANY, "do_modrdn: SASL bind in progress.\n",
-                       0, 0, 0 );
-               send_ldap_result( conn, op, LDAP_SASL_BIND_IN_PROGRESS,
-                       NULL, "SASL bind in progress", NULL, NULL );
-               return LDAP_SASL_BIND_IN_PROGRESS;
-       }
-
        /*
         * Parse the modrdn request.  It looks like this:
         *
@@ -74,30 +68,12 @@ do_modrdn(
         *      }
         */
 
-       if ( ber_scanf( op->o_ber, "{aab", &ndn, &newrdn, &deloldrdn )
+       if ( ber_scanf( op->o_ber, "{aab", &dn, &newrdn, &deloldrdn )
            == LBER_ERROR ) {
                Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
                send_ldap_disconnect( conn, op,
                        LDAP_PROTOCOL_ERROR, "decoding error" );
-               return -1;
-       }
-
-       if( dn_normalize_case( ndn ) == NULL ) {
-               Debug( LDAP_DEBUG_ANY, "do_modrdn: invalid dn (%s)\n", ndn, 0, 0 );
-               send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
-                   "invalid DN", NULL, NULL );
-               free( ndn );
-               free( newrdn );
-               return rc;
-       }
-
-       if( !rdn_validate( newrdn ) ) {
-               Debug( LDAP_DEBUG_ANY, "do_modrdn: invalid rdn (%s)\n", newrdn, 0, 0 );
-               send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
-                   "invalid RDN", NULL, NULL );
-               free( ndn );
-               free( newrdn );
-               return rc;
+               return SLAPD_DISCONNECT;
        }
 
        /* Check for newSuperior parameter, if present scan it */
@@ -112,59 +88,70 @@ do_modrdn(
                               0, 0, 0 );
                        send_ldap_disconnect( conn, op,
                                LDAP_PROTOCOL_ERROR, "newSuperior requires LDAPv3" );
-                       free( ndn );
-                       free( newrdn );
-                       return -1;
+                       rc = SLAPD_DISCONNECT;
+                       goto cleanup;
                }
 
                if ( ber_scanf( op->o_ber, "a", &newSuperior ) 
                     == LBER_ERROR ) {
 
-                   Debug( LDAP_DEBUG_ANY, "ber_scanf(\"a\") failed\n",
+                       Debug( LDAP_DEBUG_ANY, "ber_scanf(\"a\") failed\n",
                           0, 0, 0 );
                        send_ldap_disconnect( conn, op,
                                LDAP_PROTOCOL_ERROR, "decoding error" );
-                       free( ndn );
-                       free( newrdn );
-                   return -1;
+                       rc = SLAPD_DISCONNECT;
+                       goto cleanup;
                }
 
                nnewSuperior = ch_strdup( newSuperior );
 
-               if( dn_normalize_case( nnewSuperior ) == NULL ) {
+               if( dn_normalize( nnewSuperior ) == NULL ) {
                        Debug( LDAP_DEBUG_ANY, "do_modrdn: invalid new superior (%s)\n",
                                newSuperior, 0, 0 );
                        send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
-                               "invalid (new superior) DN", NULL, NULL );
-                       goto done;
+                               "invalid new superior DN", NULL, NULL );
+                       goto cleanup;
                }
 
        }
 
        Debug( LDAP_DEBUG_ARGS,
            "do_modrdn: dn (%s) newrdn (%s) newsuperior (%s)\n",
-               ndn, newrdn,
+               dn, newrdn,
                newSuperior != NULL ? newSuperior : "" );
 
        if ( ber_scanf( op->o_ber, /*{*/ "}") == LBER_ERROR ) {
-               free( ndn );
-               free( newrdn ); 
-               free( newSuperior );
-               free( nnewSuperior );
                Debug( LDAP_DEBUG_ANY, "do_modrdn: ber_scanf failed\n", 0, 0, 0 );
                send_ldap_disconnect( conn, op,
                                LDAP_PROTOCOL_ERROR, "decoding error" );
-               return -1;
+               rc = SLAPD_DISCONNECT;
+               goto cleanup;
        }
 
        if( (rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_ANY, "do_modrdn: get_ctrls failed\n", 0, 0, 0 );
                /* get_ctrls has sent results.  Now clean up. */
-               goto done;
+               goto cleanup;
        } 
 
+       ndn = ch_strdup( dn );
+
+       if( dn_normalize( ndn ) == NULL ) {
+               Debug( LDAP_DEBUG_ANY, "do_modrdn: invalid dn (%s)\n", dn, 0, 0 );
+               send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
+                   "invalid DN", NULL, NULL );
+               goto cleanup;
+       }
+
+       if( !rdn_validate( newrdn ) ) {
+               Debug( LDAP_DEBUG_ANY, "do_modrdn: invalid rdn (%s)\n", newrdn, 0, 0 );
+               send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
+                   "invalid RDN", NULL, NULL );
+               goto cleanup;
+       }
+
        Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d MODRDN dn=\"%s\"\n",
-           op->o_connid, op->o_opid, ndn, 0, 0 );
+           op->o_connid, op->o_opid, dn, 0, 0 );
 
        /*
         * We could be serving multiple database backends.  Select the
@@ -173,13 +160,18 @@ do_modrdn(
         */
 
        if ( (be = select_backend( ndn )) == NULL ) {
-               free( ndn );
-               free( newrdn ); 
-               free( newSuperior );
-               free( nnewSuperior );
                send_ldap_result( conn, op, rc = LDAP_REFERRAL,
                        NULL, NULL, default_referral, NULL );
-               return rc;
+               goto cleanup;
+       }
+
+       /* make sure this backend recongizes critical controls */
+       rc = backend_check_controls( be, conn, op, &text ) ;
+
+       if( rc != LDAP_SUCCESS ) {
+               send_ldap_result( conn, op, rc,
+                       NULL, text, NULL, NULL );
+               goto cleanup;
        }
 
        if ( global_readonly || be->be_readonly ) {
@@ -187,7 +179,7 @@ do_modrdn(
                       0, 0, 0 );
                send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
                                  NULL, "database is read-only", NULL, NULL );
-               goto done;
+               goto cleanup;
        }
 
        /* Make sure that the entry being changed and the newSuperior are in 
@@ -201,14 +193,9 @@ do_modrdn(
                        rc = LDAP_AFFECTS_MULTIPLE_DSAS;
 
                        send_ldap_result( conn, op, rc,
-                               NULL, NULL, NULL, NULL );
-
-                       free( ndn );
-                       free( newrdn );
-                       free( newSuperior );
-                       free( nnewSuperior );
+                               NULL, "cannot rename between DSAa", NULL, NULL );
 
-                       return rc;
+                       goto cleanup;
                }
 
                /* deref suffix alias if appropriate */
@@ -231,7 +218,7 @@ do_modrdn(
                        strcmp( be->be_update_ndn, op->o_ndn ) == 0 )
 #endif
                {
-                       if ( (*be->be_modrdn)( be, conn, op, ndn, newrdn,
+                       if ( (*be->be_modrdn)( be, conn, op, dn, ndn, newrdn,
                            deloldrdn, newSuperior ) == 0
 #ifdef SLAPD_MULTIMASTER
                                && ( be->be_update_ndn == NULL ||
@@ -243,7 +230,7 @@ do_modrdn(
                                moddn.deloldrdn = deloldrdn;
                                moddn.newsup = newSuperior;
 
-                               replog( be, op, ndn, &moddn );
+                               replog( be, op, dn, &moddn );
                        }
 #ifndef SLAPD_MULTIMASTER
                } else {
@@ -253,13 +240,16 @@ do_modrdn(
                }
        } else {
                send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
-                       NULL, "Function not implemented", NULL, NULL );
+                       NULL, "operation not supported within namingContext", NULL, NULL );
        }
 
-done:
-       free( ndn );
+cleanup:
+       free( dn );
+       if( ndn != NULL ) free( ndn );
        free( newrdn ); 
-       free( newSuperior );
-       free( nnewSuperior );
+       if ( newSuperior != NULL )
+               free( newSuperior );
+       if ( nnewSuperior != NULL )
+               free( nnewSuperior );
        return rc;
 }
index 7dd253a8063d1d33c50a6ac2d5cde7895a561484..4559be0e0cf556c6b4b240de504e9a2a75544fbd 100644 (file)
 
 #include <ltdl.h>
 
-int module_load(const char* file_name, int argc, char *argv[]) {
-    lt_dlhandle* module = NULL;
-    int (*initialize) LDAP_P((int argc, char *argv[]));
-
-    if (lt_dlinit()) {
-       Debug(LDAP_DEBUG_ANY, "lt_dlinit failed: %s\n", lt_dlerror(), 0, 0);
-       return -1;
-    }
-
-    if ((module = lt_dlopen(file_name)) == NULL) {
-       Debug(LDAP_DEBUG_ANY, "lt_dlopen failed: (%s) %s\n", file_name,
-           lt_dlerror(), 0);
-       return -1;
-    }
-
-    Debug(LDAP_DEBUG_CONFIG, "loaded module %s\n", file_name, 0, 0);
+typedef int (*MODULE_INIT_FN)(
+       int argc,
+       char *argv[]);
+typedef int (*MODULE_LOAD_FN)(
+       const void *module,
+       const char *filename);
+typedef int (*MODULE_TERM_FN)(void);
+
+
+struct module_regtable_t {
+       char *type;
+       MODULE_LOAD_FN proc;
+} module_regtable[] = {
+               { "null", load_null_module },
+#ifdef SLAPD_EXTERNAL_EXTENSIONS
+               { "extension", load_extop_module },
+#endif
+               { NULL, NULL }
+};
+
+typedef struct module_loaded_t {
+       struct module_loaded_t *next;
+       lt_dlhandle *lib;
+} module_loaded_t;
+
+module_loaded_t *module_list = NULL;
+
+static int module_unload (module_loaded_t *module);
+
+int module_init (void)
+{
+       if (lt_dlinit()) {
+               const char *error = lt_dlerror();
+               Debug(LDAP_DEBUG_ANY, "lt_dlinit failed: %s\n", error, 0, 0);
+               return -1;
+       }
+       return 0;
+}
+
+int module_kill (void)
+{
+       /* unload all modules before shutdown */
+       while (module_list != NULL) {
+               module_unload(module_list);
+       }
+
+       if (lt_dlexit()) {
+               const char *error = lt_dlerror();
+               Debug(LDAP_DEBUG_ANY, "lt_dlexit failed: %s\n", error, 0, 0);
+               return -1;
+       }
+       return 0;
+}
+
+int module_load(const char* file_name, int argc, char *argv[])
+{
+       module_loaded_t *module = NULL;
+       const char *error;
+       int rc;
+       MODULE_INIT_FN initialize;
+
+       module = (module_loaded_t *)ch_calloc(1, sizeof(module_loaded_t));
+       if (module == NULL) {
+               Debug(LDAP_DEBUG_ANY, "module_load failed: (%s) out of memory\n", file_name,
+                       0, 0);
+               return -1;
+       }
+
+       /*
+        * The result of lt_dlerror(), when called, must be cached prior
+        * to calling Debug. This is because Debug is a macro that expands
+        * into multiple function calls.
+        */
+       if ((module->lib = lt_dlopen(file_name)) == NULL) {
+               error = lt_dlerror();
+               Debug(LDAP_DEBUG_ANY, "lt_dlopen failed: (%s) %s\n", file_name,
+                       error, 0);
+               ch_free(module);
+               return -1;
+       }
+
+       Debug(LDAP_DEBUG_CONFIG, "loaded module %s\n", file_name, 0, 0);
    
-    if ((initialize = lt_dlsym(module, "init_module")))
-       return initialize(argc, argv);
+       if ((initialize = lt_dlsym(module->lib, "init_module")) == NULL) {
+               Debug(LDAP_DEBUG_CONFIG, "module %s: no init_module() function found\n",
+                       file_name, 0, 0);
+               lt_dlclose(module->lib);
+               ch_free(module);
+               return -1;
+       }
+
+       /* The imported init_module() routine passes back the type of
+        * module (i.e., which part of slapd it should be hooked into)
+        * or -1 for error.  If it passes back 0, then you get the 
+        * old behavior (i.e., the library is loaded and not hooked
+        * into anything).
+        *
+        * It might be better if the conf file could specify the type
+        * of module.  That way, a single module could support multiple
+        * type of hooks. This could be done by using something like:
+        *
+        *    moduleload extension /usr/local/openldap/whatever.so
+        *
+        * then we'd search through module_regtable for a matching
+        * module type, and hook in there.
+        */
+       rc = initialize(argc, argv);
+       if (rc == -1) {
+               Debug(LDAP_DEBUG_CONFIG, "module %s: init_module() failed\n",
+                       file_name, 0, 0);
+               lt_dlclose(module->lib);
+               ch_free(module);
+               return rc;
+       }
+
+       if (rc >= (sizeof(module_regtable) / sizeof(struct module_regtable_t))
+               || module_regtable[rc].proc == NULL)
+       {
+               Debug(LDAP_DEBUG_CONFIG, "module %s: unknown registration type (%d)\n",
+                       file_name, rc, 0);
+               module_unload(module);
+               return -1;
+       }
 
-    Debug(LDAP_DEBUG_CONFIG, "module %s: no init_module() function found\n",
-       file_name, 0, 0);
-    return -1;
+       rc = (module_regtable[rc].proc)(module, file_name);
+       if (rc != 0) {
+               Debug(LDAP_DEBUG_CONFIG, "module %s: %s module could not be registered\n",
+                       file_name, module_regtable[rc].type, 0);
+               module_unload(module);
+               return rc;
+       }
+
+       module->next = module_list;
+       module_list = module;
+
+       Debug(LDAP_DEBUG_CONFIG, "module %s: %s module registered\n",
+               file_name, module_regtable[rc].type, 0);
+       return 0;
+}
+
+int module_path(const char *path)
+{
+       return lt_dlsetsearchpath( path );
 }
 
-int module_path(const char *path) {
+void *module_resolve (const void *module, const char *name)
+{
+       if (module == NULL || name == NULL)
+               return(NULL);
+       return(lt_dlsym(((module_loaded_t *)module)->lib, name));
+}
+
+static int module_unload (module_loaded_t *module)
+{
+       module_loaded_t *mod;
+       MODULE_TERM_FN terminate;
+
+       if (module != NULL) {
+               /* remove module from tracking list */
+               if (module_list == module) {
+                       module_list = module->next;
+               } else {
+                       for (mod = module_list; mod; mod = mod->next) {
+                               if (mod->next == module) {
+                                       mod->next = module->next;
+                                       break;
+                               }
+                       }
+               }
+
+               /* call module's terminate routine, if present */
+               if (terminate = lt_dlsym(module->lib, "term_module")) {
+                       terminate();
+               }
+
+               /* close the library and free the memory */
+               lt_dlclose(module->lib);
+               ch_free(module);
+       }
+       return 0;
+}
+
+int load_null_module (const void *module, const char *file_name)
+{
+       return 0;
+}
+
+#ifdef SLAPD_EXTERNAL_EXTENSIONS
+int
+load_extop_module (
+       const void *module,
+       const char *file_name
+)
+{
+       SLAP_EXTOP_MAIN_FN ext_main;
+       int (*ext_getoid)(int index, char *oid, int blen);
+       char *oid;
+       int rc;
+
+       ext_main = (SLAP_EXTOP_MAIN_FN)module_resolve(module, "ext_main");
+       if (ext_main == NULL) {
+               return(-1);
+       }
+
+       ext_getoid = module_resolve(module, "ext_getoid");
+       if (ext_getoid == NULL) {
+               return(-1);
+       }
 
-    if (lt_dlinit()) {
-       Debug(LDAP_DEBUG_ANY, "lt_dlinit failed: %s\n", lt_dlerror(), 0, 0);
-       return -1;
-    }
+       oid = ch_malloc(256);
+       rc = (ext_getoid)(0, oid, 256);
+       if (rc != 0) {
+               ch_free(oid);
+               return(rc);
+       }
+       if (*oid == 0) {
+               free(oid);
+               return(-1);
+       }
 
-    return lt_dlsetsearchpath( path );
+       rc = load_extop( oid, ext_main );
+       free(oid);
+       return rc;
 }
+#endif /* SLAPD_EXTERNAL_EXTENSIONS */
 #endif /* SLAPD_MODULES */
 
index 9ad7fbc0806d78b7ad3c5427a3a281427181e7a3..ce1cd803da0c06ccfff5b6f528757009d6022f9c 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
 
 #if defined( SLAPD_MONITOR_DN )
 
-void
+int
 monitor_info(
-       Connection *conn,
-       Operation *op,
-       char ** attrs,
-       int attrsonly )
+       Entry **entry,
+       const char **text )
 {
        Entry           *e;
        char            buf[BUFSIZ];
@@ -55,9 +53,21 @@ monitor_info(
        e->e_attrs = NULL;
        e->e_dn = ch_strdup( SLAPD_MONITOR_DN );
        e->e_ndn = ch_strdup(SLAPD_MONITOR_DN);
-       (void) dn_normalize_case( e->e_ndn );
+       (void) dn_normalize( e->e_ndn );
        e->e_private = NULL;
 
+       val.bv_val = "top";
+       val.bv_len = sizeof("top")-1;
+       attr_merge( e, "objectClass", vals );
+
+       val.bv_val = "LDAPsubentry";
+       val.bv_len = sizeof("LDAPsubentry")-1;
+       attr_merge( e, "objectClass", vals );
+
+       val.bv_val = "extensibleObject";
+       val.bv_len = sizeof("extensibleObject")-1;
+       attr_merge( e, "objectClass", vals );
+
        {
                char *rdn = ch_strdup( SLAPD_MONITOR_DN );
                val.bv_val = strchr( rdn, '=' );
@@ -80,9 +90,8 @@ monitor_info(
        }
        attr_merge( e, "version", vals );
 
-       ldap_pvt_thread_mutex_lock( &active_threads_mutex );
-       sprintf( buf, "%d", active_threads );
-       ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
+       sprintf( buf, "%d",
+               ldap_pvt_thread_pool_backload( &connection_pool) );
        val.bv_val = buf;
        val.bv_len = strlen( buf );
        attr_merge( e, "threads", vals );
@@ -105,19 +114,12 @@ monitor_info(
                }
 
                ldap_pvt_thread_mutex_lock( &gmtime_mutex );
-#ifndef LDAP_LOCALTIME
+
                ltm = gmtime( &c->c_starttime );
                strftime( buf2, sizeof(buf2), "%Y%m%d%H%M%SZ", ltm );
 
                ltm = gmtime( &c->c_activitytime );
                strftime( buf3, sizeof(buf2), "%Y%m%d%H%M%SZ", ltm );
-#else
-               ltm = localtime( &c->.c_starttime );
-               strftime( buf2, sizeof(buf2), "%y%m%d%H%M%SZ", ltm );
-
-               ltm = localtime( &c->c_activitytime );
-               strftime( buf3, sizeof(buf2), "%y%m%d%H%M%SZ", ltm );
-#endif
 
                ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
 
@@ -143,9 +145,9 @@ monitor_info(
                    c->c_ops != NULL ? "x" : "",
                    c->c_pending_ops != NULL ? "p" : "",
                        connection_state2str( c->c_conn_state ),
-                       c->c_bind_in_progress ? "S" : "",
+                       c->c_sasl_bind_in_progress ? "S" : "",
 
-                   c->c_cdn ? c->c_cdn : "<anonymous>",
+                   c->c_cdn ? c->c_cdn : SLAPD_ANONYMOUS,
 
                        c->c_listener_url,
                    c->c_peer_domain,
@@ -232,24 +234,14 @@ monitor_info(
        currenttime = slap_get_time();
 
        ldap_pvt_thread_mutex_lock( &gmtime_mutex );
-#ifndef LDAP_LOCALTIME
        ltm = gmtime( &currenttime );
        strftime( buf, sizeof(buf), "%Y%m%d%H%M%SZ", ltm );
-#else
-       ltm = localtime( &currenttime );
-       strftime( buf, sizeof(buf), "%y%m%d%H%M%SZ", ltm );
-#endif
        val.bv_val = buf;
        val.bv_len = strlen( buf );
        attr_merge( e, "currenttime", vals );
 
-#ifndef LDAP_LOCALTIME
        ltm = gmtime( &starttime );
        strftime( buf, sizeof(buf), "%Y%m%d%H%M%SZ", ltm );
-#else
-       ltm = localtime( &starttime );
-       strftime( buf, sizeof(buf), "%y%m%d%H%M%SZ", ltm );
-#endif
        ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
 
        val.bv_val = buf;
@@ -268,24 +260,8 @@ monitor_info(
        attr_merge( e, "concurrency", vals );
 #endif
 
-       val.bv_val = "top";
-       val.bv_len = sizeof("top")-1;
-       attr_merge( e, "objectClass", vals );
-
-       val.bv_val = "LDAPsubentry";
-       val.bv_len = sizeof("LDAPsubentry")-1;
-       attr_merge( e, "objectClass", vals );
-
-       val.bv_val = "extensibleObject";
-       val.bv_len = sizeof("extensibleObject")-1;
-       attr_merge( e, "objectClass", vals );
-
-       send_search_entry( &backends[0], conn, op, e,
-               attrs, attrsonly, NULL );
-       send_search_result( conn, op, LDAP_SUCCESS,
-               NULL, NULL, NULL, NULL, 1 );
-
-       entry_free( e );
+       *entry = e;
+       return LDAP_SUCCESS;
 }
 
 #endif /* slapd_monitor_dn */
diff --git a/servers/slapd/mr.c b/servers/slapd/mr.c
new file mode 100644 (file)
index 0000000..d846944
--- /dev/null
@@ -0,0 +1,224 @@
+/* mr.c - routines to manage matching rule definitions */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/ctype.h>
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "ldap_pvt.h"
+
+
+struct mindexrec {
+       char            *mir_name;
+       MatchingRule    *mir_mr;
+};
+
+static Avlnode *mr_index = NULL;
+static MatchingRule *mr_list = NULL;
+
+static int
+mr_index_cmp(
+    struct mindexrec   *mir1,
+    struct mindexrec   *mir2
+)
+{
+       return (strcmp( mir1->mir_name, mir2->mir_name ));
+}
+
+static int
+mr_index_name_cmp(
+    char               *name,
+    struct mindexrec   *mir
+)
+{
+       return (strcmp( name, mir->mir_name ));
+}
+
+MatchingRule *
+mr_find( const char *mrname )
+{
+       struct mindexrec        *mir = NULL;
+
+       if ( (mir = (struct mindexrec *) avl_find( mr_index, mrname,
+            (AVL_CMP) mr_index_name_cmp )) != NULL ) {
+               return( mir->mir_mr );
+       }
+       return( NULL );
+}
+
+static int
+mr_insert(
+    MatchingRule       *smr,
+    const char         **err
+)
+{
+       MatchingRule            **mrp;
+       struct mindexrec        *mir;
+       char                    **names;
+
+       mrp = &mr_list;
+       while ( *mrp != NULL ) {
+               mrp = &(*mrp)->smr_next;
+       }
+       *mrp = smr;
+
+       if ( smr->smr_oid ) {
+               mir = (struct mindexrec *)
+                       ch_calloc( 1, sizeof(struct mindexrec) );
+               mir->mir_name = smr->smr_oid;
+               mir->mir_mr = smr;
+               if ( avl_insert( &mr_index, (caddr_t) mir,
+                                (AVL_CMP) mr_index_cmp,
+                                (AVL_DUP) avl_dup_error ) ) {
+                       *err = smr->smr_oid;
+                       ldap_memfree(mir);
+                       return SLAP_SCHERR_DUP_RULE;
+               }
+               /* FIX: temporal consistency check */
+               mr_find(mir->mir_name);
+       }
+       if ( (names = smr->smr_names) ) {
+               while ( *names ) {
+                       mir = (struct mindexrec *)
+                               ch_calloc( 1, sizeof(struct mindexrec) );
+                       mir->mir_name = ch_strdup(*names);
+                       mir->mir_mr = smr;
+                       if ( avl_insert( &mr_index, (caddr_t) mir,
+                                        (AVL_CMP) mr_index_cmp,
+                                        (AVL_DUP) avl_dup_error ) ) {
+                               *err = *names;
+                               ldap_memfree(mir);
+                               return SLAP_SCHERR_DUP_RULE;
+                       }
+                       /* FIX: temporal consistency check */
+                       mr_find(mir->mir_name);
+                       names++;
+               }
+       }
+       return 0;
+}
+
+int
+mr_add(
+    LDAP_MATCHING_RULE         *mr,
+       unsigned usage,
+       slap_mr_convert_func *convert,
+       slap_mr_normalize_func *normalize,
+    slap_mr_match_func *match,
+       slap_mr_indexer_func *indexer,
+    slap_mr_filter_func        *filter,
+    const char         **err
+)
+{
+       MatchingRule    *smr;
+       Syntax          *syn;
+       int             code;
+
+       smr = (MatchingRule *) ch_calloc( 1, sizeof(MatchingRule) );
+       memcpy( &smr->smr_mrule, mr, sizeof(LDAP_MATCHING_RULE));
+
+       smr->smr_usage = usage;
+       smr->smr_convert = convert;
+       smr->smr_normalize = normalize;
+       smr->smr_match = match;
+       smr->smr_indexer = indexer;
+       smr->smr_filter = filter;
+
+       if ( smr->smr_syntax_oid ) {
+               if ( (syn = syn_find(smr->smr_syntax_oid)) ) {
+                       smr->smr_syntax = syn;
+               } else {
+                       *err = smr->smr_syntax_oid;
+                       return SLAP_SCHERR_SYN_NOT_FOUND;
+               }
+       } else {
+               *err = "";
+               return SLAP_SCHERR_MR_INCOMPLETE;
+       }
+       code = mr_insert(smr,err);
+       return code;
+}
+
+
+int
+register_matching_rule(
+       char * desc,
+       unsigned usage,
+       slap_mr_convert_func *convert,
+       slap_mr_normalize_func *normalize,
+       slap_mr_match_func *match,
+       slap_mr_indexer_func *indexer,
+       slap_mr_filter_func *filter )
+{
+       LDAP_MATCHING_RULE *mr;
+       int             code;
+       const char      *err;
+
+       if( usage == SLAP_MR_NONE ) {
+               Debug( LDAP_DEBUG_ANY, "register_matching_rule: not usable %s\n",
+                   desc, 0, 0 );
+               return -1;
+       }
+
+       mr = ldap_str2matchingrule( desc, &code, &err, LDAP_SCHEMA_ALLOW_ALL);
+       if ( !mr ) {
+               Debug( LDAP_DEBUG_ANY, "Error in register_matching_rule: %s before %s in %s\n",
+                   ldap_scherr2str(code), err, desc );
+               return( -1 );
+       }
+
+       code = mr_add( mr, usage,
+               convert, normalize, match, indexer, filter,
+               &err );
+
+       if ( code ) {
+               Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s for %s in %s\n",
+                   scherr2str(code), err, desc );
+               return( -1 );
+       }
+
+       return( 0 );
+}
+
+
+#if defined( SLAPD_SCHEMA_DN )
+
+int mr_schema_info( Entry *e )
+{
+       struct berval   val;
+       struct berval   *vals[2];
+       MatchingRule    *mr;
+
+       AttributeDescription *ad_matchingRules = slap_schema.si_ad_matchingRules;
+
+       vals[0] = &val;
+       vals[1] = NULL;
+
+       for ( mr = mr_list; mr; mr = mr->smr_next ) {
+               val.bv_val = ldap_matchingrule2str( &mr->smr_mrule );
+
+               if ( val.bv_val == NULL ) {
+                       return -1;
+               }
+
+               val.bv_len = strlen( val.bv_val );
+#if 0
+               Debug( LDAP_DEBUG_TRACE, "Merging mr [%ld] %s\n",
+              (long) val.bv_len, val.bv_val, 0 );
+#endif
+               attr_merge( e, ad_matchingRules, vals );
+               ldap_memfree( val.bv_val );
+       }
+       return 0;
+}
+
+#endif
index 30562627954da31a37ddb03a1bba36c7a34ab441..5bd46f9636430d6679947360b556faa312c8b417 100644 (file)
@@ -1,31 +1,41 @@
 /* $OpenLDAP$ */
-// nt_main.c
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
 #include "portable.h"
 #include <stdio.h>
-
 #include <ac/string.h>
-
 #include "slap.h"
 
-ldap_pvt_thread_cond_t started_event,          stopped_event;
-ldap_pvt_thread_t              start_status_tid,       stop_status_tid;
-
+#ifdef HAVE_NT_SERVICE_MANAGER
 
 /* in main.c */
 void WINAPI ServiceMain( DWORD argc, LPTSTR *argv );
 
 /* in ntservice.c */
-int srv_install( char* service, char* filename );
+int srv_install( char* service, char * displayName, char* filename,
+                BOOL auto_start );
 int srv_remove ( char* service, char* filename );
 
-int main( DWORD argc, LPTSTR *argv )
+int main( int argc, LPTSTR *argv )
 {
        int             length;
        char    filename[MAX_PATH], *fname_start;
        extern int is_NT_Service;
 
+       /*
+        * Because the service was registered as SERVICE_WIN32_OWN_PROCESS,
+        * the lpServiceName element of the SERVICE_TABLE_ENTRY will be
+        * ignored. Since we don't even know the name of the service at
+        * this point (since it could have been installed under a name
+        * different than SERVICE_NAME), we might as well just provide
+        * the parameter as "".
+        */
+
        SERVICE_TABLE_ENTRY             DispatchTable[] = {
-               {       SERVICE_NAME,   (LPSERVICE_MAIN_FUNCTION) ServiceMain   },
+               {       "",     (LPSERVICE_MAIN_FUNCTION) ServiceMain   },
                {       NULL,                   NULL    }
        };
 
@@ -42,14 +52,24 @@ int main( DWORD argc, LPTSTR *argv )
                if ( _stricmp( "install", argv[1] ) == 0 ) 
                {
                        char *svcName = SERVICE_NAME;
+                       char *displayName = "OpenLDAP Directory Service";
+                       BOOL auto_start = FALSE;
+
                        if ( (argc > 2) && (argv[2] != NULL) )
                                svcName = argv[2];
+
+                       if ( argc > 3 && argv[3])
+                               displayName = argv[3];
+
+                       if ( argc > 4 && stricmp(argv[4], "auto") == 0)
+                               auto_start = TRUE;
+
                        if ( (length = GetModuleFileName(NULL, filename, sizeof( filename ))) == 0 ) 
                        {
                                fputs( "unable to retrieve file name for the service.\n", stderr  );
                                return EXIT_FAILURE;
                        }
-                       if ( !srv_install(svcName, filename) ) 
+                       if ( !srv_install(svcName, displayName, filename, auto_start) ) 
                        {
                                fputs( "service failed installation ...\n", stderr  );
                                return EXIT_FAILURE;
@@ -87,3 +107,5 @@ int main( DWORD argc, LPTSTR *argv )
 
        return EXIT_SUCCESS;
 }
+
+#endif
diff --git a/servers/slapd/oc.c b/servers/slapd/oc.c
new file mode 100644 (file)
index 0000000..8c185e0
--- /dev/null
@@ -0,0 +1,413 @@
+/* oc.c - object class routines */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/ctype.h>
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "ldap_pvt.h"
+
+int is_object_subclass(
+       ObjectClass *sub,
+       ObjectClass *sup )
+{
+       int i;
+
+       if( sup == sub ) {
+               return 1;
+       }
+
+       if( sup->soc_sups == NULL ) {
+               return 0;
+       }
+
+       for( i=0; sup->soc_sups[i] != NULL; i++ ) {
+               if( is_object_subclass( sup->soc_sups[i], sup ) ) {
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+int is_entry_objectclass(
+       Entry*  e,
+       ObjectClass *oc
+)
+{
+       Attribute *attr;
+       int i;
+       AttributeDescription *objectClass = slap_schema.si_ad_objectClass;
+       assert(!( e == NULL || oc == NULL ));
+
+       if( e == NULL || oc == NULL ) {
+               return 0;
+       }
+
+       /*
+        * find objectClass attribute
+        */
+       attr = attr_find(e->e_attrs, objectClass);
+
+       if( attr == NULL ) {
+               /* no objectClass attribute */
+               Debug( LDAP_DEBUG_ANY, "is_entry_objectclass(\"%s\", \"%s\") "
+                       "no objectClass attribute\n",
+                       e->e_dn == NULL ? "" : e->e_dn,
+                       oc->soc_oclass.oc_oid, 0 );
+
+               return 0;
+       }
+
+       for( i=0; attr->a_vals[i]; i++ ) {
+               ObjectClass *objectClass = oc_find( attr->a_vals[i]->bv_val );
+
+               if( objectClass == oc ) {
+                       return 1;
+               }
+       }
+
+       return 0;
+
+}
+
+
+
+
+struct oindexrec {
+       char            *oir_name;
+       ObjectClass     *oir_oc;
+};
+
+static Avlnode *oc_index = NULL;
+static ObjectClass *oc_list = NULL;
+
+static int
+oc_index_cmp(
+    struct oindexrec   *oir1,
+    struct oindexrec   *oir2
+)
+{
+       assert( oir1->oir_name );
+       assert( oir1->oir_oc );
+       assert( oir2->oir_name );
+       assert( oir2->oir_oc );
+
+       return (strcasecmp( oir1->oir_name, oir2->oir_name ));
+}
+
+static int
+oc_index_name_cmp(
+    char               *name,
+    struct oindexrec   *oir
+)
+{
+       assert( oir->oir_name );
+       assert( oir->oir_oc );
+
+       return (strcasecmp( name, oir->oir_name ));
+}
+
+ObjectClass *
+oc_find( const char *ocname )
+{
+       struct oindexrec        *oir;
+
+       oir = (struct oindexrec *) avl_find( oc_index, ocname,
+            (AVL_CMP) oc_index_name_cmp );
+
+       if ( oir != NULL ) {
+               assert( oir->oir_name );
+               assert( oir->oir_oc );
+
+               return( oir->oir_oc );
+       }
+
+       return( NULL );
+}
+
+static int
+oc_create_required(
+    ObjectClass                *soc,
+    char               **attrs,
+    const char         **err
+)
+{
+       char            **attrs1;
+       AttributeType   *sat;
+       AttributeType   **satp;
+       int             i;
+
+       if ( attrs ) {
+               attrs1 = attrs;
+               while ( *attrs1 ) {
+                       sat = at_find(*attrs1);
+                       if ( !sat ) {
+                               *err = *attrs1;
+                               return SLAP_SCHERR_ATTR_NOT_FOUND;
+                       }
+                       if ( at_find_in_list(sat, soc->soc_required) < 0) {
+                               if ( at_append_to_list(sat, &soc->soc_required) ) {
+                                       *err = *attrs1;
+                                       return SLAP_SCHERR_OUTOFMEM;
+                               }
+                       }
+                       attrs1++;
+               }
+               /* Now delete duplicates from the allowed list */
+               for ( satp = soc->soc_required; *satp; satp++ ) {
+                       i = at_find_in_list(*satp,soc->soc_allowed);
+                       if ( i >= 0 ) {
+                               at_delete_from_list(i, &soc->soc_allowed);
+                       }
+               }
+       }
+       return 0;
+}
+
+static int
+oc_create_allowed(
+    ObjectClass                *soc,
+    char               **attrs,
+    const char         **err
+)
+{
+       char            **attrs1;
+       AttributeType   *sat;
+
+       if ( attrs ) {
+               attrs1 = attrs;
+               while ( *attrs1 ) {
+                       sat = at_find(*attrs1);
+                       if ( !sat ) {
+                               *err = *attrs1;
+                               return SLAP_SCHERR_ATTR_NOT_FOUND;
+                       }
+                       if ( at_find_in_list(sat, soc->soc_required) < 0 &&
+                            at_find_in_list(sat, soc->soc_allowed) < 0 ) {
+                               if ( at_append_to_list(sat, &soc->soc_allowed) ) {
+                                       *err = *attrs1;
+                                       return SLAP_SCHERR_OUTOFMEM;
+                               }
+                       }
+                       attrs1++;
+               }
+       }
+       return 0;
+}
+
+static int
+oc_add_sups(
+    ObjectClass                *soc,
+    char               **sups,
+    const char         **err
+)
+{
+       int             code;
+       ObjectClass     *soc1;
+       int             nsups;
+       char            **sups1;
+       int             add_sups = 0;
+
+       if ( sups ) {
+               if ( !soc->soc_sups ) {
+                       /* We are at the first recursive level */
+                       add_sups = 1;
+                       nsups = 0;
+                       sups1 = sups;
+                       while ( *sups1 ) {
+                               nsups++;
+                               sups1++;
+                       }
+                       nsups++;
+                       soc->soc_sups = (ObjectClass **)ch_calloc(nsups,
+                                         sizeof(ObjectClass *));
+               }
+               nsups = 0;
+               sups1 = sups;
+               while ( *sups1 ) {
+                       soc1 = oc_find(*sups1);
+                       if ( !soc1 ) {
+                               *err = *sups1;
+                               return SLAP_SCHERR_CLASS_NOT_FOUND;
+                       }
+
+                       if ( add_sups )
+                               soc->soc_sups[nsups] = soc1;
+
+                       code = oc_add_sups(soc,soc1->soc_sup_oids, err);
+                       if ( code )
+                               return code;
+
+                       code = oc_create_required(soc,soc1->soc_at_oids_must,err);
+                       if ( code )
+                               return code;
+                       code = oc_create_allowed(soc,soc1->soc_at_oids_may,err);
+                       if ( code )
+                               return code;
+
+                       nsups++;
+                       sups1++;
+               }
+       }
+       return 0;
+}
+
+static int
+oc_insert(
+    ObjectClass                *soc,
+    const char         **err
+)
+{
+       ObjectClass     **ocp;
+       struct oindexrec        *oir;
+       char                    **names;
+
+       ocp = &oc_list;
+       while ( *ocp != NULL ) {
+               ocp = &(*ocp)->soc_next;
+       }
+       *ocp = soc;
+
+       if ( soc->soc_oid ) {
+               oir = (struct oindexrec *)
+                       ch_calloc( 1, sizeof(struct oindexrec) );
+               oir->oir_name = soc->soc_oid;
+               oir->oir_oc = soc;
+
+               assert( oir->oir_name );
+               assert( oir->oir_oc );
+
+               if ( avl_insert( &oc_index, (caddr_t) oir,
+                                (AVL_CMP) oc_index_cmp,
+                                (AVL_DUP) avl_dup_error ) )
+               {
+                       *err = soc->soc_oid;
+                       ldap_memfree(oir->oir_name);
+                       ldap_memfree(oir);
+                       return SLAP_SCHERR_DUP_CLASS;
+               }
+
+               /* FIX: temporal consistency check */
+               assert( oc_find(oir->oir_name) != NULL );
+       }
+
+       if ( (names = soc->soc_names) ) {
+               while ( *names ) {
+                       oir = (struct oindexrec *)
+                               ch_calloc( 1, sizeof(struct oindexrec) );
+                       oir->oir_name = ch_strdup(*names);
+                       oir->oir_oc = soc;
+
+                       assert( oir->oir_name );
+                       assert( oir->oir_oc );
+
+                       if ( avl_insert( &oc_index, (caddr_t) oir,
+                                        (AVL_CMP) oc_index_cmp,
+                                        (AVL_DUP) avl_dup_error ) )
+                       {
+                               *err = *names;
+                               ldap_memfree(oir->oir_name);
+                               ldap_memfree(oir);
+                               return SLAP_SCHERR_DUP_CLASS;
+                       }
+
+                       /* FIX: temporal consistency check */
+                       assert( oc_find(oir->oir_name) != NULL );
+
+                       names++;
+               }
+       }
+
+       return 0;
+}
+
+int
+oc_add(
+    LDAP_OBJECT_CLASS  *oc,
+    const char         **err
+)
+{
+       ObjectClass     *soc;
+       int             code;
+
+       soc = (ObjectClass *) ch_calloc( 1, sizeof(ObjectClass) );
+       memcpy( &soc->soc_oclass, oc, sizeof(LDAP_OBJECT_CLASS));
+       if ( (code = oc_add_sups(soc,soc->soc_sup_oids,err)) != 0 )
+               return code;
+       if ( (code = oc_create_required(soc,soc->soc_at_oids_must,err)) != 0 )
+               return code;
+       if ( (code = oc_create_allowed(soc,soc->soc_at_oids_may,err)) != 0 )
+               return code;
+       code = oc_insert(soc,err);
+       return code;
+}
+
+#ifdef LDAP_DEBUG
+
+static void
+oc_print( ObjectClass *oc )
+{
+       int     i;
+       const char *mid;
+
+       printf( "objectclass %s\n", ldap_objectclass2name( &oc->soc_oclass ) );
+       if ( oc->soc_required != NULL ) {
+               mid = "\trequires ";
+               for ( i = 0; oc->soc_required[i] != NULL; i++, mid = "," )
+                       printf( "%s%s", mid,
+                               ldap_attributetype2name( &oc->soc_required[i]->sat_atype ) );
+               printf( "\n" );
+       }
+       if ( oc->soc_allowed != NULL ) {
+               mid = "\tallows ";
+               for ( i = 0; oc->soc_allowed[i] != NULL; i++, mid = "," )
+                       printf( "%s%s", mid,
+                               ldap_attributetype2name( &oc->soc_allowed[i]->sat_atype ) );
+               printf( "\n" );
+       }
+}
+
+#endif
+
+
+#if defined( SLAPD_SCHEMA_DN )
+
+int
+oc_schema_info( Entry *e )
+{
+       struct berval   val;
+       struct berval   *vals[2];
+       ObjectClass     *oc;
+
+       AttributeDescription *ad_objectClasses = slap_schema.si_ad_objectClasses;
+
+       vals[0] = &val;
+       vals[1] = NULL;
+
+       for ( oc = oc_list; oc; oc = oc->soc_next ) {
+               val.bv_val = ldap_objectclass2str( &oc->soc_oclass );
+               if ( val.bv_val == NULL ) {
+                       return -1;
+               }
+               val.bv_len = strlen( val.bv_val );
+#if 0
+               Debug( LDAP_DEBUG_TRACE, "Merging oc [%ld] %s\n",
+              (long) val.bv_len, val.bv_val, 0 );
+#endif
+               attr_merge( e, ad_objectClasses, vals );
+               ldap_memfree( val.bv_val );
+       }
+       return 0;
+}
+
+#endif
index dff00fcf7791a5840d7faf565b826dfa116e2b4d..ce2eef1179136540939be0160f770e8fc3c27a34 100644 (file)
@@ -1,7 +1,7 @@
 /* operation.c - routines to deal with pending ldap operations */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
diff --git a/servers/slapd/passwd.c b/servers/slapd/passwd.c
new file mode 100644 (file)
index 0000000..8246f55
--- /dev/null
@@ -0,0 +1,275 @@
+/* bind.c - ldbm backend bind and unbind routines */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/krb.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/unistd.h>
+
+#include "slap.h"
+
+#include <lutil.h>
+
+int passwd_extop(
+       SLAP_EXTOP_CALLBACK_FN ext_callback,
+       Connection *conn, Operation *op,
+       const char *reqoid,
+       struct berval *reqdata,
+       char **rspoid,
+       struct berval **rspdata,
+       LDAPControl ***rspctrls,
+       const char **text,
+       struct berval ***refs )
+{
+       int rc;
+
+       assert( reqoid != NULL );
+       assert( strcmp( LDAP_EXOP_X_MODIFY_PASSWD, reqoid ) == 0 );
+
+       if( op->o_dn == NULL || op->o_dn[0] == '\0' ) {
+               *text = "only authenicated users may change passwords";
+               return LDAP_STRONG_AUTH_REQUIRED;
+       }
+
+       if( conn->c_authz_backend != NULL && conn->c_authz_backend->be_extended )
+       {
+               if( global_readonly || conn->c_authz_backend->be_readonly ) {
+                       *text = "authorization database is read only";
+                       rc = LDAP_UNWILLING_TO_PERFORM;
+
+               } else if( conn->c_authz_backend->be_update_ndn != NULL ) {
+                       /* we SHOULD return a referral in this case */
+                       *refs = conn->c_authz_backend->be_update_refs;
+                       rc = LDAP_REFERRAL;
+
+               } else {
+                       rc = conn->c_authz_backend->be_extended(
+                               conn->c_authz_backend, conn, op,
+                               reqoid, reqdata,
+                               rspoid, rspdata, rspctrls,
+                               text, refs );
+               }
+
+       } else {
+               *text = "operation not supported for current user";
+               rc = LDAP_UNWILLING_TO_PERFORM;
+       }
+
+       return rc;
+}
+
+int slap_passwd_parse( struct berval *reqdata,
+       struct berval **id,
+       struct berval **oldpass,
+       struct berval **newpass,
+       const char **text )
+{
+       int rc = LDAP_SUCCESS;
+       ber_tag_t tag;
+       ber_len_t len;
+       BerElement *ber;
+
+       if( reqdata == NULL ) {
+               return LDAP_SUCCESS;
+       }
+
+       ber = ber_init( reqdata );
+
+       if( ber == NULL ) {
+               Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: ber_init failed\n",
+                       0, 0, 0 );
+               *text = "password decoding error";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       tag = ber_scanf( ber, "{" /*}*/ );
+
+       if( tag != LBER_ERROR ) {
+               tag = ber_peek_tag( ber, &len );
+       }
+
+       if( tag == LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID ) {
+               if( id == NULL ) {
+                       Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: ID not allowed.\n",
+                               0, 0, 0 );
+                       *text = "user must change own password";
+                       rc = LDAP_UNWILLING_TO_PERFORM;
+                       goto done;
+               }
+
+               tag = ber_scanf( ber, "O", id );
+
+               if( tag == LBER_ERROR ) {
+                       Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: ID parse failed.\n",
+                               0, 0, 0 );
+                       goto decoding_error;
+               }
+
+               tag = ber_peek_tag( ber, &len);
+       }
+
+       if( tag == LDAP_TAG_EXOP_X_MODIFY_PASSWD_OLD ) {
+               if( oldpass == NULL ) {
+                       Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: OLD not allowed.\n",
+                               0, 0, 0 );
+                       *text = "use bind to verify old password";
+                       rc = LDAP_UNWILLING_TO_PERFORM;
+                       goto done;
+               }
+
+               tag = ber_scanf( ber, "O", oldpass );
+
+               if( tag == LBER_ERROR ) {
+                       Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: ID parse failed.\n",
+                               0, 0, 0 );
+                       goto decoding_error;
+               }
+
+               tag = ber_peek_tag( ber, &len);
+       }
+
+       if( tag == LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW ) {
+               if( newpass == NULL ) {
+                       Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: NEW not allowed.\n",
+                               0, 0, 0 );
+                       *text = "user specified passwords disallowed";
+                       rc = LDAP_UNWILLING_TO_PERFORM;
+                       goto done;
+               }
+
+               tag = ber_scanf( ber, "O", newpass );
+
+               if( tag == LBER_ERROR ) {
+                       Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: OLD parse failed.\n",
+                               0, 0, 0 );
+                       goto decoding_error;
+               }
+
+               tag = ber_peek_tag( ber, &len );
+       }
+
+       if( len != 0 ) {
+decoding_error:
+               Debug( LDAP_DEBUG_TRACE,
+                       "slap_passwd_parse: decoding error, len=%ld\n",
+                       (long) len, 0, 0 );
+
+               *text = "data decoding error";
+               rc = LDAP_PROTOCOL_ERROR;
+       }
+
+done:
+       if( rc != LDAP_SUCCESS ) {
+               if( id != NULL ) {
+                       ber_bvfree( *id );
+                       *id = NULL;
+               }
+
+               if( oldpass != NULL ) {
+                       ber_bvfree( *oldpass );
+                       *oldpass = NULL;
+               }
+
+               if( newpass != NULL ) {
+                       ber_bvfree( *newpass );
+                       *newpass = NULL;
+               }
+       }
+
+       ber_free( ber, 1 );
+       return rc;
+}
+
+struct berval * slap_passwd_return(
+       struct berval           *cred )
+{
+       int rc;
+       struct berval *bv;
+       BerElement *ber = ber_alloc_t(LBER_USE_DER);
+
+       assert( cred != NULL );
+
+       Debug( LDAP_DEBUG_TRACE, "slap_passwd_return: %ld\n",
+               (long) cred->bv_len, 0, 0 );
+
+       if( ber == NULL ) return NULL;
+       
+       rc = ber_printf( ber, "{tO}",
+               LDAP_TAG_EXOP_X_MODIFY_PASSWD_GEN, cred );
+
+       if( rc == -1 ) {
+               ber_free( ber, 1 );
+               return NULL;
+       }
+
+       (void) ber_flatten( ber, &bv );
+
+       ber_free( ber, 1 );
+
+       return bv;
+}
+
+int
+slap_passwd_check(
+       Attribute *a,
+       struct berval *cred )
+{
+       int     i;
+       for ( i = 0; a->a_vals[i] != NULL; i++ ) {
+               int result;
+
+#ifdef SLAPD_CRYPT
+               ldap_pvt_thread_mutex_lock( &crypt_mutex );
+#endif
+
+               result = lutil_passwd( a->a_vals[i], cred, NULL );
+
+#ifdef SLAPD_CRYPT
+               ldap_pvt_thread_mutex_unlock( &crypt_mutex );
+#endif
+
+               if( !result )
+                       return result;
+       }
+
+       return( 1 );
+}
+
+struct berval * slap_passwd_generate( void )
+{
+       Debug( LDAP_DEBUG_TRACE, "slap_passwd_generate\n", 0, 0, 0 );
+
+       /*
+        * generate passwords of only 8 characters as some getpass(3)
+        * implementations truncate at 8 characters.
+        */
+       return lutil_passwd_generate( 8 );
+}
+
+struct berval * slap_passwd_hash(
+       struct berval * cred )
+{
+       char* hash = default_passwd_hash ? default_passwd_hash : "{SSHA}";
+
+       struct berval *new;
+
+#ifdef SLAPD_CRYPT
+       ldap_pvt_thread_mutex_lock( &crypt_mutex );
+#endif
+
+       new = lutil_passwd_hash( cred , hash );
+       
+#ifdef SLAPD_CRYPT
+       ldap_pvt_thread_mutex_unlock( &crypt_mutex );
+#endif
+
+       return new;
+}
index 5d58ca0a35732eb7aa9841420c40c79d635d1136..80adc78a34772deee634a80341bca2a44f9d5a0a 100644 (file)
@@ -1,7 +1,7 @@
 /* phonetic.c - routines to do phonetic matching */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
index 1e95a2805217b949b945cf815faed4deaaada5af..1f4e35217139b9997c8eca88040eda12b8f65a5b 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 #ifndef _PROTO_SLAP
 
 LDAP_BEGIN_DECL
 
+LIBSLAPD_F( int ) schema_init_done;
+LIBSLAPD_F( struct slap_internal_schema ) slap_schema;
+
+LIBSLAPD_F (int) slap_str2ad LDAP_P((
+       const char *,
+       AttributeDescription **ad,
+       const char **text ));
+
+LIBSLAPD_F (int) slap_bv2ad LDAP_P((
+       struct berval *bv,
+       AttributeDescription **ad,
+       const char **text ));
+
+LIBSLAPD_F (AttributeDescription *) ad_dup LDAP_P((
+       AttributeDescription *desc ));
+
+LIBSLAPD_F (void) ad_free LDAP_P((
+       AttributeDescription *desc,
+       int freeit ));
+
+#define ad_cmp(l,r)    ( strcasecmp( \
+       (l)->ad_cname->bv_val, (r)->ad_cname->bv_val ))
+
+LIBSLAPD_F (int) is_ad_subtype LDAP_P((
+       AttributeDescription *sub,
+       AttributeDescription *super ));
+
+LIBSLAPD_F (int) ad_inlist LDAP_P((
+       AttributeDescription *desc,
+       char **attrs ));
+
 /*
  * acl.c
  */
 
-int access_allowed LDAP_P(( Backend *be, Connection *conn,
-       Operation *op, Entry *e,
-       char *attr, struct berval *val, int access ));
-
-AccessControl * acl_get_applicable LDAP_P(( Backend *be,
-       Operation *op, Entry *e,
-       char *attr, int nmatches, regmatch_t *matches ));
+LIBSLAPD_F (int) access_allowed LDAP_P((
+       Backend *be, Connection *conn, Operation *op,
+       Entry *e, AttributeDescription *desc, struct berval *val,
+       slap_access_t access ));
+LIBSLAPD_F (int) acl_check_modlist LDAP_P((
+       Backend *be, Connection *conn, Operation *op,
+       Entry *e, Modifications *ml ));
 
-int acl_access_allowed LDAP_P((
-       AccessControl *a, char *attr, Backend *be, Connection *conn, Entry *e,
-       struct berval *val, Operation *op, int  access, char *edn,
-       regmatch_t *matches ));
-
-int acl_check_modlist LDAP_P(( Backend *be,
-       Connection *conn,
-       Operation *op,
-       Entry *e,
-       LDAPModList *ml ));
+LIBSLAPD_F (void) acl_append( AccessControl **l, AccessControl *a );
 
 /*
  * aclparse.c
  */
 
-void parse_acl LDAP_P(( Backend *be,
-       const char *fname,
-       int lineno,
+LIBSLAPD_F (void) parse_acl LDAP_P(( Backend *be,
+       const char *fname, int lineno,
        int argc, char **argv ));
-char * access2str LDAP_P(( int access ));
-int str2access LDAP_P(( char *str ));
+
+LIBSLAPD_F (char *) access2str LDAP_P(( slap_access_t access ));
+LIBSLAPD_F (slap_access_t) str2access LDAP_P(( const char *str ));
+
+#define ACCESSMASK_MAXLEN      sizeof("unknown (+wrscan)")
+LIBSLAPD_F (char *) accessmask2str LDAP_P(( slap_access_mask_t mask, char* ));
+LIBSLAPD_F (slap_access_mask_t) str2accessmask LDAP_P(( const char *str ));
+
+/*
+ * at.c
+ */
+
+LIBSLAPD_F (void) at_config LDAP_P(( const char *fname, int lineno, int argc, char **argv ));
+LIBSLAPD_F (AttributeType *) at_find LDAP_P(( const char *name ));
+LIBSLAPD_F (int) at_find_in_list LDAP_P(( AttributeType *sat, AttributeType **list ));
+LIBSLAPD_F (int) at_append_to_list LDAP_P(( AttributeType *sat, AttributeType ***listp ));
+LIBSLAPD_F (int) at_delete_from_list LDAP_P(( int pos, AttributeType ***listp ));
+LIBSLAPD_F (int) at_schema_info LDAP_P(( Entry *e ));
+LIBSLAPD_F (int) at_add LDAP_P(( LDAP_ATTRIBUTE_TYPE *at, const char **err ));
+
+LIBSLAPD_F (int) is_at_subtype LDAP_P((
+       AttributeType *sub,
+       AttributeType *super ));
+
+LIBSLAPD_F (int) is_at_syntax LDAP_P((
+       AttributeType *at,
+       const char *oid ));
+
+#      define at_canonical_name(at) ((at)->sat_cname)  
+
 
 /*
  * attr.c
  */
 
-void attr_free LDAP_P(( Attribute *a ));
-Attribute *attr_dup LDAP_P(( Attribute *a ));
-char * attr_normalize LDAP_P(( char *s ));
-int attr_merge_fast LDAP_P(( Entry *e, char *type, struct berval **vals, int  nvals,
-       int  naddvals, int  *maxvals, Attribute ***a ));
-int attr_merge LDAP_P(( Entry *e, char *type, struct berval **vals ));
-Attribute * attr_find LDAP_P(( Attribute *a, const char *type ));
-int attr_delete LDAP_P(( Attribute **attrs, const char *type ));
-int attr_syntax LDAP_P(( char *type ));
-void attr_syntax_config LDAP_P(( const char *fname, int lineno, int argc, char **argv ));
-AttributeType * at_find LDAP_P(( const char *name ));
-int at_find_in_list LDAP_P(( AttributeType *sat, AttributeType **list ));
-int at_append_to_list LDAP_P(( AttributeType *sat, AttributeType ***listp ));
-int at_delete_from_list LDAP_P(( int pos, AttributeType ***listp ));
-int at_fake_if_needed LDAP_P(( char *name ));
-int at_schema_info LDAP_P(( Entry *e ));
-int at_add LDAP_P(( LDAP_ATTRIBUTE_TYPE *at, const char **err ));
-char * at_canonical_name LDAP_P(( char * a_type ));
-
-void attrs_free LDAP_P(( Attribute *a ));
-Attribute *attrs_dup LDAP_P(( Attribute *a ));
+LIBSLAPD_F (void) attr_free LDAP_P(( Attribute *a ));
+LIBSLAPD_F (Attribute *) attr_dup LDAP_P(( Attribute *a ));
+
+LIBSLAPD_F (int) attr_merge LDAP_P(( Entry *e,
+       AttributeDescription *desc,
+       struct berval **vals ));
+LIBSLAPD_F (Attribute *) attrs_find LDAP_P(( Attribute *a, AttributeDescription *desc ));
+LIBSLAPD_F (Attribute *) attr_find LDAP_P(( Attribute *a, AttributeDescription *desc ));
+LIBSLAPD_F (int) attr_delete LDAP_P(( Attribute **attrs, AttributeDescription *desc ));
+
+LIBSLAPD_F (void) attrs_free LDAP_P(( Attribute *a ));
+LIBSLAPD_F (Attribute *) attrs_dup LDAP_P(( Attribute *a ));
+
 
 /*
  * ava.c
  */
-
-int get_ava LDAP_P(( BerElement *ber, Ava *ava ));
-void ava_free LDAP_P(( Ava *ava, int freeit ));
+LIBSLAPD_F (int) get_ava LDAP_P((
+       BerElement *ber,
+       AttributeAssertion **ava,
+       unsigned usage,
+       const char **text ));
+LIBSLAPD_F (void) ava_free LDAP_P((
+       AttributeAssertion *ava,
+       int freeit ));
 
 /*
  * backend.c
  */
 
-int backend_init LDAP_P((void));
-int backend_add LDAP_P((BackendInfo *aBackendInfo));
-int backend_num LDAP_P((Backend *be));
-int backend_startup LDAP_P((Backend *be));
-int backend_shutdown LDAP_P((Backend *be));
-int backend_destroy LDAP_P((void));
+LIBSLAPD_F (int) backend_init LDAP_P((void));
+LIBSLAPD_F (int) backend_add LDAP_P((BackendInfo *aBackendInfo));
+LIBSLAPD_F (int) backend_num LDAP_P((Backend *be));
+LIBSLAPD_F (int) backend_startup LDAP_P((Backend *be));
+LIBSLAPD_F (int) backend_shutdown LDAP_P((Backend *be));
+LIBSLAPD_F (int) backend_destroy LDAP_P((void));
 
-BackendInfo * backend_info LDAP_P(( const char *type ));
-BackendDB * backend_db_init LDAP_P(( const char *type ));
+LIBSLAPD_F (BackendInfo *) backend_info LDAP_P(( const char *type ));
+LIBSLAPD_F (BackendDB *) backend_db_init LDAP_P(( const char *type ));
 
-BackendDB * select_backend LDAP_P(( const char * dn ));
+LIBSLAPD_F (BackendDB *) select_backend LDAP_P(( const char * dn ));
 
-int be_issuffix LDAP_P(( Backend *be, const char *suffix ));
-int be_isroot LDAP_P(( Backend *be, const char *ndn ));
-int be_isroot_pw LDAP_P(( Backend *be, const char *ndn, struct berval *cred ));
-char* be_root_dn LDAP_P(( Backend *be ));
-int be_entry_release_rw LDAP_P(( Backend *be, Entry *e, int rw ));
+LIBSLAPD_F (int) be_issuffix LDAP_P(( Backend *be, const char *suffix ));
+LIBSLAPD_F (int) be_isroot LDAP_P(( Backend *be, const char *ndn ));
+LIBSLAPD_F (int) be_isroot_pw LDAP_P(( Backend *be, const char *ndn, struct berval *cred ));
+LIBSLAPD_F (char *) be_root_dn LDAP_P(( Backend *be ));
+LIBSLAPD_F (int) be_entry_release_rw LDAP_P(( Backend *be, Entry *e, int rw ));
 #define be_entry_release_r( be, e ) be_entry_release_rw( be, e, 0 )
 #define be_entry_release_w( be, e ) be_entry_release_rw( be, e, 1 )
 
+LIBSLAPD_F (int) backend_unbind LDAP_P((Connection *conn, Operation *op));
 
-extern int     backend_unbind LDAP_P((Connection *conn, Operation *op));
+LIBSLAPD_F( int )      backend_check_controls LDAP_P((
+       Backend *be,
+       Connection *conn,
+       Operation *op,
+       const char **text ));
 
-extern int     backend_connection_init LDAP_P((Connection *conn));
-extern int     backend_connection_destroy LDAP_P((Connection *conn));
+LIBSLAPD_F (int) backend_connection_init LDAP_P((Connection *conn));
+LIBSLAPD_F (int) backend_connection_destroy LDAP_P((Connection *conn));
 
-extern int     backend_group LDAP_P((Backend *be,
+LIBSLAPD_F (int) backend_group LDAP_P((Backend *be,
        Entry *target,
        const char *gr_ndn,
        const char *op_ndn,
-       const char *objectclassValue,
-       const char *groupattrName));
+       ObjectClass *group_oc,
+       AttributeDescription *group_at
+));
+
+LIBSLAPD_F (Attribute *) backend_operational( Backend *, Entry * );
 
-#ifdef SLAPD_SCHEMA_DN
-/* temporary extern for temporary routine*/
-extern Attribute *backend_subschemasubentry( Backend * );
-#endif
 
 
 /*
@@ -132,11 +182,11 @@ extern Attribute *backend_subschemasubentry( Backend * );
 #define ch_free free
 
 #else
-void * ch_malloc LDAP_P(( ber_len_t size ));
-void * ch_realloc LDAP_P(( void *block, ber_len_t size ));
-void * ch_calloc LDAP_P(( ber_len_t nelem, ber_len_t size ));
-char * ch_strdup LDAP_P(( const char *string ));
-void   ch_free LDAP_P(( void * ));
+LIBSLAPD_F (void *) ch_malloc LDAP_P(( ber_len_t size ));
+LIBSLAPD_F (void *) ch_realloc LDAP_P(( void *block, ber_len_t size ));
+LIBSLAPD_F (void *) ch_calloc LDAP_P(( ber_len_t nelem, ber_len_t size ));
+LIBSLAPD_F (char *) ch_strdup LDAP_P(( const char *string ));
+LIBSLAPD_F (void) ch_free LDAP_P(( void * ));
 
 #ifndef CH_FREE
 #undef free
@@ -148,39 +198,45 @@ void   ch_free LDAP_P(( void * ));
  * charray.c
  */
 
-void charray_add LDAP_P(( char ***a, const char *s ));
-void charray_merge LDAP_P(( char ***a, char **s ));
-void charray_free LDAP_P(( char **array ));
-int charray_inlist LDAP_P(( char **a, const char *s ));
-char ** charray_dup LDAP_P(( char **a ));
-char ** str2charray LDAP_P(( const char *str, const char *brkstr ));
-char * charray2str LDAP_P(( char **a ));
+LIBSLAPD_F (void) charray_add LDAP_P(( char ***a, const char *s ));
+LIBSLAPD_F (void) charray_merge LDAP_P(( char ***a, char **s ));
+LIBSLAPD_F (void) charray_free LDAP_P(( char **array ));
+LIBSLAPD_F (int) charray_inlist LDAP_P(( char **a, const char *s ));
+LIBSLAPD_F (char **) charray_dup LDAP_P(( char **a ));
+LIBSLAPD_F (char **) str2charray LDAP_P(( const char *str, const char *brkstr ));
 
 /*
  * controls.c
  */
-int get_ctrls LDAP_P((
+LIBSLAPD_F (int) get_ctrls LDAP_P((
        Connection *co,
        Operation *op,
        int senderrors ));
 
-int get_manageDSAit LDAP_P(( Operation *op ));
+LIBSLAPD_F (int) get_manageDSAit LDAP_P(( Operation *op ));
 
 /*
  * config.c
  */
 
-int read_config LDAP_P(( const char *fname ));
+LIBSLAPD_F (int) read_config LDAP_P(( const char *fname ));
+
+
+/*
+ * index.c
+ */
+LIBSLAPD_F (int) slap_index2prefix LDAP_P(( int indextype ));
+LIBSLAPD_F (int) slap_str2index LDAP_P(( const char *str, slap_index *idx ));
 
 /*
  * connection.c
  */
-int connections_init LDAP_P((void));
-int connections_shutdown LDAP_P((void));
-int connections_destroy LDAP_P((void));
-int connections_timeout_idle LDAP_P((time_t));
+LIBSLAPD_F (int) connections_init LDAP_P((void));
+LIBSLAPD_F (int) connections_shutdown LDAP_P((void));
+LIBSLAPD_F (int) connections_destroy LDAP_P((void));
+LIBSLAPD_F (int) connections_timeout_idle LDAP_P((time_t));
 
-long connection_init LDAP_P((
+LIBSLAPD_F (long) connection_init LDAP_P((
        ber_socket_t s,
        const char* url,
        const char* dnsname,
@@ -188,37 +244,34 @@ long connection_init LDAP_P((
        const char* sockname,
        int use_tls ));
 
-void connection_closing LDAP_P(( Connection *c ));
-int connection_state_closing LDAP_P(( Connection *c ));
-const char *connection_state2str LDAP_P(( int state )) LDAP_GCCATTR((const));
+LIBSLAPD_F (void) connection_closing LDAP_P(( Connection *c ));
+LIBSLAPD_F (int) connection_state_closing LDAP_P(( Connection *c ));
+LIBSLAPD_F (const char *) connection_state2str LDAP_P(( int state )) LDAP_GCCATTR((const));
 
-int connection_write LDAP_P((ber_socket_t s));
-int connection_read LDAP_P((ber_socket_t s));
+LIBSLAPD_F (int) connection_write LDAP_P((ber_socket_t s));
+LIBSLAPD_F (int) connection_read LDAP_P((ber_socket_t s));
 
-unsigned long connections_nextid(void);
+LIBSLAPD_F (unsigned long) connections_nextid(void);
 
-Connection* connection_first LDAP_P((ber_socket_t *));
-Connection* connection_next LDAP_P((Connection *, ber_socket_t *));
-void connection_done LDAP_P((Connection *));
+LIBSLAPD_F (Connection *) connection_first LDAP_P((ber_socket_t *));
+LIBSLAPD_F (Connection *) connection_next LDAP_P((Connection *, ber_socket_t *));
+LIBSLAPD_F (void) connection_done LDAP_P((Connection *));
 
 /*
  * dn.c
  */
 
-char * dn_normalize LDAP_P(( char *dn ));
-char * dn_normalize_case LDAP_P(( char *dn ));
-char * dn_parent LDAP_P(( Backend *be, const char *dn ));
-char ** dn_subtree LDAP_P(( Backend *be, const char *dn ));
-char * dn_rdn LDAP_P(( Backend *be, char *dn ));
-int dn_issuffix LDAP_P(( char *dn, char *suffix ));
-#ifdef DNS_DN
-int dn_type LDAP_P(( char *dn ));
-#endif
-int rdn_validate LDAP_P(( const char* str ));
-char * rdn_attr_value LDAP_P(( char * rdn ));
-char * rdn_attr_type LDAP_P(( char * rdn ));
-
-void build_new_dn LDAP_P(( char ** new_dn,
+LIBSLAPD_F (char *) dn_validate LDAP_P(( char *dn ));
+LIBSLAPD_F (char *) dn_normalize LDAP_P(( char *dn ));
+LIBSLAPD_F (char *) dn_parent LDAP_P(( Backend *be, const char *dn ));
+LIBSLAPD_F (char **) dn_subtree LDAP_P(( Backend *be, const char *dn ));
+LIBSLAPD_F (char *) dn_rdn LDAP_P(( Backend *be, const char *dn ));
+LIBSLAPD_F (int) dn_issuffix LDAP_P(( const char *dn, const char *suffix ));
+LIBSLAPD_F (int) rdn_validate LDAP_P(( const char* str ));
+LIBSLAPD_F (char *) rdn_attr_value LDAP_P(( const char * rdn ));
+LIBSLAPD_F (char *) rdn_attr_type LDAP_P(( const char * rdn ));
+
+LIBSLAPD_F (void) build_new_dn LDAP_P(( char ** new_dn,
        const char *e_dn,
        const char * p_dn,
        const char * newrdn ));
@@ -226,297 +279,535 @@ void build_new_dn LDAP_P(( char ** new_dn,
  * entry.c
  */
 
-int entry_destroy LDAP_P((void));
+LIBSLAPD_F (int) entry_destroy LDAP_P((void));
+
+LIBSLAPD_F (Entry *) str2entry LDAP_P(( char   *s ));
+LIBSLAPD_F (char *) entry2str LDAP_P(( Entry *e, int *len ));
+LIBSLAPD_F (void) entry_free LDAP_P(( Entry *e ));
+
+LIBSLAPD_F (int) entry_cmp LDAP_P(( Entry *a, Entry *b ));
+LIBSLAPD_F (int) entry_dn_cmp LDAP_P(( Entry *a, Entry *b ));
+LIBSLAPD_F (int) entry_id_cmp LDAP_P(( Entry *a, Entry *b ));
+
+/*
+ * extended.c
+ */
+
+#define SLAPD_EXTOP_GETVERSION 0
+#define SLAPD_EXTOP_GETPROTO 1
+#define SLAPD_EXTOP_GETAUTH 2
+#define SLAPD_EXTOP_GETDN 3
+#define SLAPD_EXTOP_GETCLIENT 4
+
+typedef int (*SLAP_EXTOP_CALLBACK_FN) LDAP_P((
+       Connection *conn, Operation *op,
+       int msg, int arg, void *argp ));
+
+typedef int (*SLAP_EXTOP_MAIN_FN) LDAP_P((
+       SLAP_EXTOP_CALLBACK_FN,
+       Connection *conn, Operation *op,
+       const char * reqoid,
+       struct berval * reqdata,
+       char ** rspoid,
+       struct berval ** rspdata,
+       LDAPControl *** rspctrls,
+       const char ** text,
+       struct berval *** refs ));
+
+typedef int (*SLAP_EXTOP_GETOID_FN) LDAP_P((
+       int index, char *oid, int blen ));
 
-Entry * str2entry LDAP_P(( char        *s ));
-char * entry2str LDAP_P(( Entry *e, int *len ));
-void entry_free LDAP_P(( Entry *e ));
+LIBSLAPD_F (int) load_extension LDAP_P((const void *module, const char *file_name));
+LIBSLAPD_F (char *) get_supported_extension LDAP_P((int index));
 
-int entry_cmp LDAP_P(( Entry *a, Entry *b ));
-int entry_dn_cmp LDAP_P(( Entry *a, Entry *b ));
-int entry_id_cmp LDAP_P(( Entry *a, Entry *b ));
+LIBSLAPD_F (int) load_extop LDAP_P((
+       const char *ext_oid,
+       SLAP_EXTOP_MAIN_FN ext_main ));
+
+LIBSLAPD_F (int) extops_init LDAP_P(( void ));
+
+LIBSLAPD_F (int) extops_kill LDAP_P(( void ));
+
+LIBSLAPD_F (char *) get_supported_extop LDAP_P((int index));
 
 /*
  * filter.c
  */
 
-int get_filter LDAP_P(( Connection *conn, BerElement *ber, Filter **filt, char **fstr ));
-void filter_free LDAP_P(( Filter *f ));
-void filter_print LDAP_P(( Filter *f ));
+LIBSLAPD_F (int) get_filter LDAP_P((
+       Connection *conn,
+       BerElement *ber,
+       Filter **filt,
+       char **fstr,
+       const char **text ));
+
+LIBSLAPD_F (void) filter_free LDAP_P(( Filter *f ));
+LIBSLAPD_F (void) filter_print LDAP_P(( Filter *f ));
 
 /*
  * filterentry.c
  */
 
-int test_filter LDAP_P(( Backend *be, Connection *conn, Operation *op, Entry *e,
-       Filter  *f ));
+LIBSLAPD_F (int) test_filter LDAP_P((
+       Backend *be, Connection *conn, Operation *op, Entry *e, Filter  *f ));
 
 /*
  * lock.c
  */
 
-FILE * lock_fopen LDAP_P(( const char *fname, const char *type, FILE **lfp ));
-int lock_fclose LDAP_P(( FILE *fp, FILE *lfp ));
+LIBSLAPD_F (FILE *) lock_fopen LDAP_P(( const char *fname, const char *type, FILE **lfp ));
+LIBSLAPD_F (int) lock_fclose LDAP_P(( FILE *fp, FILE *lfp ));
+
+
+/*
+ * modify.c
+ *     should be relocated to separate file
+ */
+LIBSLAPD_F( void ) slap_mod_free LDAP_P(( Modification *mod, int freeit ));
+LIBSLAPD_F( void ) slap_mods_free LDAP_P(( Modifications *mods ));
+LIBSLAPD_F( void ) slap_modlist_free LDAP_P(( LDAPModList *ml ));
+
+LIBSLAPD_F( int ) slap_modlist2mods(
+       LDAPModList *ml,
+       int update,
+       Modifications **mods,
+       const char **text );
+
+LIBSLAPD_F( int ) slap_mods_opattrs(
+       Operation *op,
+       Modifications **modlist,
+       const char **text );
 
 /*
  * module.c
  */
 
 #ifdef SLAPD_MODULES
-int module_load LDAP_P(( const char* file_name, int argc, char *argv[] ));
-int module_path LDAP_P(( const char* path ));
+
+LIBSLAPD_F (int) module_init LDAP_P(( void ));
+LIBSLAPD_F (int) module_kill LDAP_P(( void ));
+
+LIBSLAPD_F (int) load_null_module(
+       const void *module, const char *file_name);
+LIBSLAPD_F (int) load_extop_module(
+       const void *module, const char *file_name);
+
+LIBSLAPD_F (int) module_load LDAP_P((
+       const char* file_name,
+       int argc, char *argv[] ));
+LIBSLAPD_F (int) module_path LDAP_P(( const char* path ));
+
+LIBSLAPD_F (void) *module_resolve LDAP_P((
+       const void *module, const char *name));
+
 #endif /* SLAPD_MODULES */
 
 /*
  * monitor.c
  */
-extern char *supportedExtensions[];
-extern char *supportedControls[];
+LIBSLAPD_F (char *) supportedControls[];
 
-void monitor_info LDAP_P((
-       Connection *conn,
-       Operation *op,
-       char ** attrs,
-       int attrsonly ));
+LIBSLAPD_F (int) monitor_info LDAP_P((
+       Entry **entry, const char **text ));
 
 /*
  * operation.c
  */
 
-void slap_op_free LDAP_P(( Operation *op ));
-Operation * slap_op_alloc LDAP_P((
+LIBSLAPD_F (void) slap_op_free LDAP_P(( Operation *op ));
+LIBSLAPD_F (Operation *) slap_op_alloc LDAP_P((
        BerElement *ber, ber_int_t msgid,
        ber_tag_t tag, ber_int_t id ));
 
-int slap_op_add LDAP_P(( Operation **olist, Operation *op ));
-int slap_op_remove LDAP_P(( Operation **olist, Operation *op ));
-Operation * slap_op_pop LDAP_P(( Operation **olist ));
+LIBSLAPD_F (int) slap_op_add LDAP_P(( Operation **olist, Operation *op ));
+LIBSLAPD_F (int) slap_op_remove LDAP_P(( Operation **olist, Operation *op ));
+LIBSLAPD_F (Operation *) slap_op_pop LDAP_P(( Operation **olist ));
 
 /*
  * phonetic.c
  */
 
-char * first_word LDAP_P(( char *s ));
-char * next_word LDAP_P(( char *s ));
-char * word_dup LDAP_P(( char *w ));
-char * phonetic LDAP_P(( char *s ));
+LIBSLAPD_F (char *) first_word LDAP_P(( char *s ));
+LIBSLAPD_F (char *) next_word LDAP_P(( char *s ));
+LIBSLAPD_F (char *) word_dup LDAP_P(( char *w ));
+LIBSLAPD_F (char *) phonetic LDAP_P(( char *s ));
 
 /*
  * repl.c
  */
 
-void replog LDAP_P(( Backend *be, Operation *op, char *dn, void *change ));
+LIBSLAPD_F (void) replog LDAP_P(( Backend *be, Operation *op, char *dn, void *change ));
 
 /*
  * result.c
  */
 
-struct berval **get_entry_referrals LDAP_P((
+LIBSLAPD_F (struct berval **) get_entry_referrals LDAP_P((
        Backend *be, Connection *conn, Operation *op,
        Entry *e ));
 
-void send_ldap_result LDAP_P((
+LIBSLAPD_F (void) send_ldap_result LDAP_P((
        Connection *conn, Operation *op,
-       int err, const char *matched, const char *text,
+       ber_int_t err, const char *matched, const char *text,
        struct berval **refs,
        LDAPControl **ctrls ));
 
-void send_ldap_disconnect LDAP_P((
+LIBSLAPD_F (void) send_ldap_sasl LDAP_P((
+       Connection *conn, Operation *op,
+       ber_int_t err, const char *matched,
+       const char *text,
+       struct berval **refs,
+       LDAPControl **ctrls,
+       struct berval *cred ));
+
+LIBSLAPD_F (void) send_ldap_disconnect LDAP_P((
+       Connection *conn, Operation *op,
+       ber_int_t err, const char *text ));
+
+LIBSLAPD_F (void) send_ldap_extended LDAP_P((
+       Connection *conn, Operation *op,
+       ber_int_t err, const char *matched,
+       const char *text, struct berval **refs,
+       const char *rspoid, struct berval *rspdata,
+       LDAPControl **ctrls ));
+
+LIBSLAPD_F (void) send_ldap_partial LDAP_P((
        Connection *conn, Operation *op,
-       int err, const char *text ));
+       const char *rspoid, struct berval *rspdata,
+       LDAPControl **ctrls ));
 
-void send_search_result LDAP_P((
+LIBSLAPD_F (void) send_search_result LDAP_P((
        Connection *conn, Operation *op,
-       int err, const char *matched, const char *text,
+       ber_int_t err, const char *matched, const char *text,
        struct berval **refs,
        LDAPControl **ctrls,
        int nentries ));
 
-int send_search_reference LDAP_P((
+LIBSLAPD_F (int) send_search_reference LDAP_P((
        Backend *be, Connection *conn, Operation *op,
        Entry *e, struct berval **refs, int scope,
        LDAPControl **ctrls,
        struct berval ***v2refs ));
 
-int send_search_entry LDAP_P((
+LIBSLAPD_F (int) send_search_entry LDAP_P((
        Backend *be, Connection *conn, Operation *op,
        Entry *e, char **attrs, int attrsonly,
        LDAPControl **ctrls ));
 
-int str2result LDAP_P(( char *s,
+LIBSLAPD_F (int) str2result LDAP_P(( char *s,
        int *code, char **matched, char **info ));
 
 /*
  * sasl.c
  */
-extern char **supportedSASLMechanisms;
+LIBSLAPD_F (char **) supportedSASLMechanisms;
+
+LIBSLAPD_F (int) sasl_init(void);
+LIBSLAPD_F (int) sasl_destroy(void);
+LIBSLAPD_F (int) sasl_errldap LDAP_P(( int ));
+LIBSLAPD_F (int) sasl_bind LDAP_P((
+       Connection *conn, Operation *op, 
+       const char *dn, const char *ndn,
+       const char *mech, struct berval *cred,
+       char **edn ));
 
-int sasl_init(void);
-int sasl_destroy(void);
+/* oc.c */
+LIBSLAPD_F (int) oc_schema_info( Entry *e );
+
+/* mr.c */
+LIBSLAPD_F (int) mr_schema_info( Entry *e );
+
+/* syntax.c */
+LIBSLAPD_F (int) syn_schema_info( Entry *e );
 
 /*
  * schema.c
  */
 
-int oc_schema_check LDAP_P(( Entry *e ));
-int oc_check_operational_attr LDAP_P(( const char *type ));
-int oc_check_usermod_attr LDAP_P(( const char *type ));
-int oc_check_no_usermod_attr LDAP_P(( const char *type ));
-ObjectClass *oc_find LDAP_P((const char *ocname));
-int oc_add LDAP_P((LDAP_OBJECT_CLASS *oc, const char **err));
-Syntax *syn_find LDAP_P((const char *synname));
-Syntax *syn_find_desc LDAP_P((const char *syndesc, int *slen));
-int syn_add LDAP_P((LDAP_SYNTAX *syn, slap_syntax_check_func *check, const char **err));
-MatchingRule *mr_find LDAP_P((const char *mrname));
-int mr_add LDAP_P((LDAP_MATCHING_RULE *mr, slap_mr_normalize_func *normalize, slap_mr_compare_func *compare, const char **err));
-int case_ignore_normalize LDAP_P((struct berval *val, struct berval **normalized));
-int register_syntax LDAP_P((char *desc,        slap_syntax_check_func *check ));
-int register_matching_rule LDAP_P((char * desc,        slap_mr_normalize_func *normalize, slap_mr_compare_func *compare));
-void schema_info LDAP_P((Connection *conn, Operation *op, char **attrs, int attrsonly));
-int schema_init LDAP_P((void));
+LIBSLAPD_F (ObjectClass *) oc_find LDAP_P((
+       const char *ocname));
+
+LIBSLAPD_F (int) oc_add LDAP_P((
+       LDAP_OBJECT_CLASS *oc,
+       const char **err));
+
+LIBSLAPD_F (int) is_object_subclass LDAP_P((
+       ObjectClass *sub,
+       ObjectClass *sup ));
+
+
+LIBSLAPD_F (Syntax *) syn_find LDAP_P((const char *synname));
+LIBSLAPD_F (Syntax *) syn_find_desc LDAP_P((const char *syndesc, int *slen));
+#ifdef SLAPD_BINARY_CONVERSION
+LIBSLAPD_F (int) syn_add LDAP_P((
+       LDAP_SYNTAX *syn,
+       unsigned flags,
+       slap_syntax_validate_func *validate,
+       slap_syntax_transform_func *normalize,
+       slap_syntax_transform_func *pretty,
+       slap_syntax_transform_func *ber2str,
+       slap_syntax_transform_func *str2ber,
+       const char **err));
+#else
+LIBSLAPD_F (int) syn_add LDAP_P((
+       LDAP_SYNTAX *syn,
+       unsigned flags,
+       slap_syntax_validate_func *validate,
+       slap_syntax_transform_func *normalize,
+       slap_syntax_transform_func *pretty,
+       const char **err));
+#endif
 
-int is_entry_objectclass LDAP_P(( Entry *, const char* objectclass ));
-#define is_entry_alias(e)              is_entry_objectclass((e), "ALIAS")
-#define is_entry_referral(e)   is_entry_objectclass((e), "REFERRAL")
+LIBSLAPD_F (MatchingRule *) mr_find LDAP_P((const char *mrname));
+LIBSLAPD_F (int) mr_add LDAP_P((LDAP_MATCHING_RULE *mr,
+       unsigned usage,
+       slap_mr_convert_func *convert,
+       slap_mr_normalize_func *normalize,
+       slap_mr_match_func *match,
+       slap_mr_indexer_func *indexer,
+       slap_mr_filter_func *filter,
+       const char **err));
+
+LIBSLAPD_F (int) register_syntax LDAP_P((
+       char *desc,
+       unsigned flags,
+       slap_syntax_validate_func *validate,
+       slap_syntax_transform_func *ber2str,
+       slap_syntax_transform_func *str2ber ));
+
+LIBSLAPD_F (int) register_matching_rule LDAP_P((
+       char * desc,
+       unsigned usage,
+       slap_mr_convert_func *convert,
+       slap_mr_normalize_func *normalize,
+       slap_mr_match_func *match,
+       slap_mr_indexer_func *indexer,
+       slap_mr_filter_func *filter     ));
+
+LIBSLAPD_F (int) schema_info LDAP_P(( Entry **entry, const char **text ));
+
+LIBSLAPD_F (int) is_entry_objectclass LDAP_P((
+       Entry *, ObjectClass *oc ));
+#define is_entry_alias(e)              is_entry_objectclass((e), slap_schema.si_oc_alias)
+#define is_entry_referral(e)   is_entry_objectclass((e), slap_schema.si_oc_referral)
+
+
+/*
+ * schema_check.c
+ */
+int oc_check_allowed(
+       AttributeType *type,
+       struct berval **oclist );
+LIBSLAPD_F (int) entry_schema_check LDAP_P((
+       Entry *e, Attribute *attrs,
+       const char** text ));
+
+
+/*
+ * schema_init.c
+ */
+LIBSLAPD_F (int) schema_init LDAP_P((void));
+LIBSLAPD_F (int) schema_prep LDAP_P((void));
 
 
 /*
  * schemaparse.c
  */
 
-void parse_oc_old LDAP_P(( Backend *be, const char *fname, int lineno, int argc, char **argv ));
-void parse_oc LDAP_P(( const char *fname, int lineno, char *line, char **argv ));
-void parse_at LDAP_P(( const char *fname, int lineno, char *line, char **argv ));
-void parse_oidm LDAP_P(( const char *fname, int lineno, int argc, char **argv ));
-char *scherr2str LDAP_P((int code)) LDAP_GCCATTR((const));
-int dscompare LDAP_P(( const char *s1, const char *s2del, char delim ));
+LIBSLAPD_F (void) parse_oc_old LDAP_P(( Backend *be, const char *fname, int lineno, int argc, char **argv ));
+LIBSLAPD_F (void) parse_oc LDAP_P(( const char *fname, int lineno, char *line, char **argv ));
+LIBSLAPD_F (void) parse_at LDAP_P(( const char *fname, int lineno, char *line, char **argv ));
+LIBSLAPD_F (void) parse_oidm LDAP_P(( const char *fname, int lineno, int argc, char **argv ));
+LIBSLAPD_F (char *) scherr2str LDAP_P((int code)) LDAP_GCCATTR((const));
+LIBSLAPD_F (int) dscompare LDAP_P(( const char *s1, const char *s2del, char delim ));
+
+
+/*
+ * starttls.c
+ */
+
+LIBSLAPD_F (int) starttls_extop LDAP_P((
+       SLAP_EXTOP_CALLBACK_FN,
+       Connection *conn, Operation *op,
+       const char * reqoid,
+       struct berval * reqdata,
+       char ** rspoid,
+       struct berval ** rspdata,
+       LDAPControl ***rspctrls,
+       const char ** text,
+       struct berval *** refs ));
+
+
 /*
  * str2filter.c
  */
 
-Filter * str2filter LDAP_P(( char *str ));
+LIBSLAPD_F (Filter *) str2filter LDAP_P(( const char *str ));
 
 /*
  * suffixalias.c
  */
-char *suffix_alias LDAP_P(( Backend *be, char *ndn ));
+LIBSLAPD_F (char *) suffix_alias LDAP_P(( Backend *be, char *ndn ));
 
 /*
  * value.c
  */
-
-int value_add_fast LDAP_P(( struct berval ***vals, struct berval **addvals, int nvals,
-       int naddvals, int *maxvals ));
-int value_add LDAP_P(( struct berval ***vals, struct berval **addvals ));
-void value_normalize LDAP_P(( char *s, int syntax ));
-int value_cmp LDAP_P(( struct berval *v1, struct berval *v2, int syntax,
-       int normalize ));
-int value_find LDAP_P(( struct berval **vals, struct berval *v, int syntax,
-       int normalize ));
+LIBSLAPD_F (int) value_normalize LDAP_P((
+       AttributeDescription *ad,
+       unsigned usage,
+       struct berval *in,
+       struct berval **out,
+       const char ** text ));
+LIBSLAPD_F (int) value_match LDAP_P((
+       int *match,
+       AttributeDescription *ad,
+       MatchingRule *mr,
+       struct berval *v1,
+       void *v2,
+       const char ** text ));
+LIBSLAPD_F (int) value_find LDAP_P((
+       AttributeDescription *ad,
+       struct berval **values,
+       struct berval *value ));
+LIBSLAPD_F (int) value_add LDAP_P(( struct berval ***vals, struct berval **addvals ));
 
 /*
  * user.c
  */
 #if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
-void slap_init_user LDAP_P(( char *username, char *groupname ));
+LIBSLAPD_F (void) slap_init_user LDAP_P(( char *username, char *groupname ));
+#endif
+
+/*
+ * passwd.c
+ */
+LIBSLAPD_F (int) passwd_extop LDAP_P((
+       SLAP_EXTOP_CALLBACK_FN,
+       Connection *conn, Operation *op,
+       const char * reqoid,
+       struct berval * reqdata,
+       char ** rspoid,
+       struct berval ** rspdata,
+       LDAPControl *** rspctrls,
+       const char ** text,
+       struct berval *** refs ));
+
+LIBSLAPD_F (int) slap_passwd_check(
+       Attribute                       *attr,
+       struct berval           *cred );
+
+LIBSLAPD_F (struct berval *) slap_passwd_generate( void );
+
+LIBSLAPD_F (struct berval *) slap_passwd_hash(
+       struct berval           *cred );
+
+LIBSLAPD_F (struct berval *) slap_passwd_return(
+       struct berval           *cred );
+
+LIBSLAPD_F (int) slap_passwd_parse(
+       struct berval *reqdata,
+       struct berval **id,
+       struct berval **oldpass,
+       struct berval **newpass,
+       const char **text );
+
+/*
+ * kerberos.c
+ */
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
+extern char            *ldap_srvtab;
+LIBSLAPD_F (int)       krbv4_ldap_auth();
 #endif
 
 /*
  * Other...
  */
 
-extern struct berval **default_referral;
-extern char            *replogfile;
-extern const char Versionstr[];
-extern int             active_threads;
-extern int             defsize;
-extern int             deftime;
-extern int             g_argc;
-extern int             global_default_access;
-extern int             global_readonly;
-extern int             global_lastmod;
-extern int             global_idletimeout;
-extern int             global_schemacheck;
-extern char            *global_realm;
-extern int             lber_debug;
-extern int             ldap_syslog;
-
-extern ldap_pvt_thread_mutex_t num_sent_mutex;
-extern long            num_bytes_sent;
-extern long            num_pdu_sent;
-extern long            num_entries_sent;
-extern long            num_refs_sent;
-
-extern ldap_pvt_thread_mutex_t num_ops_mutex;
-extern long            num_ops_completed;
-extern long            num_ops_initiated;
-
-extern char   *slapd_pid_file;
-extern char   *slapd_args_file;
-extern char            **g_argv;
-extern time_t  starttime;
-
-time_t slap_get_time LDAP_P((void));
-
-extern ldap_pvt_thread_mutex_t active_threads_mutex;
-extern ldap_pvt_thread_cond_t  active_threads_cond;
-
-extern ldap_pvt_thread_mutex_t entry2str_mutex;
-extern ldap_pvt_thread_mutex_t replog_mutex;
+LIBSLAPD_F (struct berval **)  default_referral;
+LIBSLAPD_F (char *)            replogfile;
+LIBSLAPD_F (const char)        Versionstr[];
+LIBSLAPD_F (int)               defsize;
+LIBSLAPD_F (int)               deftime;
+LIBSLAPD_F (int)               g_argc;
+LIBSLAPD_F (slap_access_t)     global_default_access;
+LIBSLAPD_F (int)               global_readonly;
+LIBSLAPD_F (int)               global_lastmod;
+LIBSLAPD_F (int)               global_idletimeout;
+LIBSLAPD_F (int)               global_schemacheck;
+LIBSLAPD_F (char)              *global_realm;
+LIBSLAPD_F (char)              *default_passwd_hash;
+LIBSLAPD_F (int)               lber_debug;
+LIBSLAPD_F (int)               ldap_syslog;
+
+LIBSLAPD_F (ldap_pvt_thread_mutex_t)   num_sent_mutex;
+LIBSLAPD_F (long)              num_bytes_sent;
+LIBSLAPD_F (long)              num_pdu_sent;
+LIBSLAPD_F (long)              num_entries_sent;
+LIBSLAPD_F (long)              num_refs_sent;
+
+LIBSLAPD_F (ldap_pvt_thread_mutex_t)   num_ops_mutex;
+LIBSLAPD_F (long)              num_ops_completed;
+LIBSLAPD_F (long)              num_ops_initiated;
+
+LIBSLAPD_F (char *)            slapd_pid_file;
+LIBSLAPD_F (char *)            slapd_args_file;
+LIBSLAPD_F (char)              **g_argv;
+LIBSLAPD_F (time_t)            starttime;
+
+LIBSLAPD_F (time_t) slap_get_time LDAP_P((void));
+
+LIBSLAPD_F (ldap_pvt_thread_pool_t)    connection_pool;
+
+LIBSLAPD_F (ldap_pvt_thread_mutex_t)   entry2str_mutex;
+LIBSLAPD_F (ldap_pvt_thread_mutex_t)   replog_mutex;
 
 #ifdef SLAPD_CRYPT
-extern ldap_pvt_thread_mutex_t crypt_mutex;
+LIBSLAPD_F (ldap_pvt_thread_mutex_t)   crypt_mutex;
 #endif
-extern ldap_pvt_thread_mutex_t gmtime_mutex;
+LIBSLAPD_F (ldap_pvt_thread_mutex_t)   gmtime_mutex;
 
-extern AccessControl *global_acl;
+LIBSLAPD_F (AccessControl *) global_acl;
 
-int    slap_init LDAP_P((int mode, char* name));
-int    slap_startup LDAP_P(( Backend *be ));
-int    slap_shutdown LDAP_P(( Backend *be ));
-int    slap_destroy LDAP_P((void));
+LIBSLAPD_F (int)       slap_init LDAP_P((int mode, const char* name));
+LIBSLAPD_F (int)       slap_startup LDAP_P(( Backend *be ));
+LIBSLAPD_F (int)       slap_shutdown LDAP_P(( Backend *be ));
+LIBSLAPD_F (int)       slap_destroy LDAP_P((void));
 
 struct sockaddr_in;
 
-extern int     slapd_daemon_init( char *urls, int port, int tls_port );
-extern int     slapd_daemon_destroy(void);
-extern int     slapd_daemon(void);
+LIBSLAPD_F (int) slapd_daemon_init( const char *urls );
+LIBSLAPD_F (int) slapd_daemon_destroy(void);
+LIBSLAPD_F (int) slapd_daemon(void);
 
-extern void slapd_set_write LDAP_P((ber_socket_t s, int wake));
-extern void slapd_clr_write LDAP_P((ber_socket_t s, int wake));
-extern void slapd_set_read LDAP_P((ber_socket_t s, int wake));
-extern void slapd_clr_read LDAP_P((ber_socket_t s, int wake));
+LIBSLAPD_F (void) slapd_set_write LDAP_P((ber_socket_t s, int wake));
+LIBSLAPD_F (void) slapd_clr_write LDAP_P((ber_socket_t s, int wake));
+LIBSLAPD_F (void) slapd_set_read LDAP_P((ber_socket_t s, int wake));
+LIBSLAPD_F (void) slapd_clr_read LDAP_P((ber_socket_t s, int wake));
 
-extern void slapd_remove LDAP_P((ber_socket_t s, int wake));
+LIBSLAPD_F (void) slapd_remove LDAP_P((ber_socket_t s, int wake));
 
-extern RETSIGTYPE slap_sig_shutdown LDAP_P((int sig));
-extern RETSIGTYPE slap_sig_wake LDAP_P((int sig));
+LIBSLAPD_F (RETSIGTYPE) slap_sig_shutdown LDAP_P((int sig));
+LIBSLAPD_F (RETSIGTYPE) slap_sig_wake LDAP_P((int sig));
 
-extern void    config_info LDAP_P((
-       Connection *conn,
-       Operation *op,
-       char ** attrs,
-       int attrsonly ));
+LIBSLAPD_F (int) config_info LDAP_P((
+       Entry **e, const char **text ));
 
-extern void    root_dse_info LDAP_P((
-       Connection *conn,
-       Operation *op,
-       char ** attrs,
-       int attrsonly ));
-
-extern int     do_abandon LDAP_P((Connection *conn, Operation *op));
-extern int     do_add LDAP_P((Connection *conn, Operation *op));
-extern int     do_bind LDAP_P((Connection *conn, Operation *op));
-extern int     do_compare LDAP_P((Connection *conn, Operation *op));
-extern int     do_delete LDAP_P((Connection *conn, Operation *op));
-extern int     do_modify LDAP_P((Connection *conn, Operation *op));
-extern int     do_modrdn LDAP_P((Connection *conn, Operation *op));
-extern int     do_search LDAP_P((Connection *conn, Operation *op));
-extern int     do_unbind LDAP_P((Connection *conn, Operation *op));
-extern int     do_extended LDAP_P((Connection *conn, Operation *op));
-
-
-extern ber_socket_t dtblsize;
+LIBSLAPD_F (int) root_dse_info LDAP_P((
+       Entry **e, const char **text ));
+
+LIBSLAPD_F (int) do_abandon LDAP_P((Connection *conn, Operation *op));
+LIBSLAPD_F (int) do_add LDAP_P((Connection *conn, Operation *op));
+LIBSLAPD_F (int) do_bind LDAP_P((Connection *conn, Operation *op));
+LIBSLAPD_F (int) do_compare LDAP_P((Connection *conn, Operation *op));
+LIBSLAPD_F (int) do_delete LDAP_P((Connection *conn, Operation *op));
+LIBSLAPD_F (int) do_modify LDAP_P((Connection *conn, Operation *op));
+LIBSLAPD_F (int) do_modrdn LDAP_P((Connection *conn, Operation *op));
+LIBSLAPD_F (int) do_search LDAP_P((Connection *conn, Operation *op));
+LIBSLAPD_F (int) do_unbind LDAP_P((Connection *conn, Operation *op));
+LIBSLAPD_F (int) do_extended LDAP_P((Connection *conn, Operation *op));
+
+
+LIBSLAPD_F (ber_socket_t) dtblsize;
 
 LDAP_END_DECL
 
index 7477e8406e1f5c41ff555833ac9d704e72c958f7..443fe81d932f6565172d24fcdadc6970ff4cd245 100644 (file)
@@ -1,7 +1,7 @@
 /* repl.c - log modifications for replication purposes */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -28,7 +28,7 @@ replog(
     void       *change
 )
 {
-       LDAPModList     *ml;
+       Modifications   *ml;
        Entry   *e;
        struct replog_moddn *moddn;
        char *tmp;
@@ -57,35 +57,37 @@ replog(
        case LDAP_REQ_MODIFY:
                fprintf( fp, "changetype: modify\n" );
                ml = change;
-               for ( ; ml != NULL; ml = ml->ml_next ) {
-                       switch ( ml->ml_op & ~LDAP_MOD_BVALUES ) {
+               for ( ; ml != NULL; ml = ml->sml_next ) {
+                       char *type;
+                       type = ml->sml_desc->ad_cname->bv_val;
+                       switch ( ml->sml_op ) {
                        case LDAP_MOD_ADD:
-                               fprintf( fp, "add: %s\n", ml->ml_type );
+                               fprintf( fp, "add: %s\n", type );
                                break;
 
                        case LDAP_MOD_DELETE:
-                               fprintf( fp, "delete: %s\n", ml->ml_type );
+                               fprintf( fp, "delete: %s\n", type );
                                break;
 
                        case LDAP_MOD_REPLACE:
-                               fprintf( fp, "replace: %s\n", ml->ml_type );
+                               fprintf( fp, "replace: %s\n", type );
                                break;
                        }
 
-                       for ( i = 0; ml->ml_bvalues != NULL &&
-                           ml->ml_bvalues[i] != NULL; i++ ) {
+                       for ( i = 0; ml->sml_bvalues != NULL &&
+                           ml->sml_bvalues[i] != NULL; i++ ) {
                                char    *buf, *bufp;
 
-                               len = strlen( ml->ml_type );
+                               len = strlen( type );
                                len = LDIF_SIZE_NEEDED( len,
-                                   ml->ml_bvalues[i]->bv_len ) + 1;
+                                   ml->sml_bvalues[i]->bv_len ) + 1;
                                buf = (char *) ch_malloc( len );
 
                                bufp = buf;
                                ldif_sput( &bufp, LDIF_PUT_VALUE,
-                                       ml->ml_type,
-                                   ml->ml_bvalues[i]->bv_val,
-                                   ml->ml_bvalues[i]->bv_len );
+                                       type,
+                                   ml->sml_bvalues[i]->bv_val,
+                                   ml->sml_bvalues[i]->bv_len );
                                *bufp = '\0';
 
                                fputs( buf, fp );
index 9e316669bc0f565a13d59e2a9b9a38f30b3750af..70fabc0a9533f25e51afdd911f080d4d23a9773b 100644 (file)
@@ -1,5 +1,9 @@
 /* result.c - routines to send ldap results, errors, and referrals */
 /* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 
 #include "portable.h"
 
 
 #include "slap.h"
 
-/* we need LBER internals */
-#include "../../libraries/liblber/lber-int.h"
-
-static char *v2ref( struct berval **ref )
+static char *v2ref( struct berval **ref, const char *text )
 {
-       size_t len, i;
+       size_t len = 0, i = 0;
        char *v2;
 
-       if(ref == NULL) return NULL;
-
-       len = sizeof("Referral:");
-       v2 = ch_strdup("Referral:");
+       if(ref == NULL)
+       {
+           if (text)
+               return ch_strdup(text);
+           else
+               return NULL;
+       }
+       
+       if (text) {
+               len = strlen( text );
+               if (text[len-1] != '\n')
+                   i = 1;
+       }
+       v2 = ch_malloc( len+i+sizeof("Referral:") );
+       if (text) {
+               strcpy(v2, text);
+               if (i)
+                       v2[len++] = '\n';
+       }
+       strcpy( v2+len, "Referral:" );
+       len += sizeof("Referral:");
 
        for( i=0; ref[i] != NULL; i++ ) {
                v2 = ch_realloc( v2, len + ref[i]->bv_len + 1 );
                v2[len-1] = '\n';
                memcpy(&v2[len], ref[i]->bv_val, ref[i]->bv_len );
                len += ref[i]->bv_len;
+               if (ref[i]->bv_val[ref[i]->bv_len-1] != '/')
+                       ++len;
        }
 
        v2[len-1] = '\0';
@@ -105,7 +125,9 @@ struct berval **get_entry_referrals(
        struct berval **refs;
        unsigned i, j;
 
-       attr = attr_find( e->e_attrs, "ref" );
+       AttributeDescription *ad_ref = slap_schema.si_ad_ref;
+
+       attr = attr_find( e->e_attrs, ad_ref );
 
        if( attr == NULL ) return NULL;
 
@@ -115,7 +137,7 @@ struct berval **get_entry_referrals(
 
        if( i < 1 ) return NULL;
 
-       refs = ch_malloc( i + 1 );
+       refs = ch_malloc( (i + 1) * sizeof(struct berval *));
 
        for( i=0, j=0; attr->a_vals[i] != NULL; i++ ) {
                unsigned k;
@@ -154,7 +176,9 @@ static long send_ldap_ber(
        Connection *conn,
        BerElement *ber )
 {
-       ber_len_t bytes = ber_pvt_ber_bytes( ber );
+       ber_len_t bytes;
+
+       ber_get_option( ber, LBER_OPT_BER_BYTES_TO_WRITE, &bytes );
 
        /* write only one pdu at a time - wait til it's our turn */
        ldap_pvt_thread_mutex_lock( &conn->c_write_mutex );
@@ -165,6 +189,7 @@ static long send_ldap_ber(
        /* write the pdu */
        while( 1 ) {
                int err;
+               ber_socket_t    sd;
 
                if ( connection_state_closing( conn ) ) {
                        ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
@@ -186,7 +211,7 @@ static long send_ldap_ber(
                 */
 
                Debug( LDAP_DEBUG_CONNS, "ber_flush failed errno=%d reason=\"%s\"\n",
-                   err, STRERROR(err), 0 );
+                   err, sock_errstr(err), 0 );
 
                if ( err != EWOULDBLOCK && err != EAGAIN ) {
                        connection_closing( conn );
@@ -199,7 +224,8 @@ static long send_ldap_ber(
 
                /* wait for socket to be write-ready */
                conn->c_writewaiter = 1;
-               slapd_set_write( ber_pvt_sb_get_desc( conn->c_sb ), 1 );
+               ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_GET_FD, &sd );
+               slapd_set_write( sd, 1 );
 
                ldap_pvt_thread_cond_wait( &conn->c_write_cv, &conn->c_mutex );
                conn->c_writewaiter = 0;
@@ -223,6 +249,7 @@ send_ldap_response(
        struct berval   **ref,
        const char      *resoid,
        struct berval   *resdata,
+       struct berval   *sasldata,
        LDAPControl **ctrls
 )
 {
@@ -236,6 +263,11 @@ send_ldap_response(
 
        Debug( LDAP_DEBUG_TRACE, "send_ldap_response: msgid=%ld tag=%ld err=%ld\n",
                (long) msgid, (long) tag, (long) err );
+       if( ref ) {
+               Debug( LDAP_DEBUG_ARGS, "send_ldap_response: ref=%s\n",
+                       ref[0] && ref[0]->bv_val ? ref[0]->bv_val : "NULL",
+                       NULL, NULL );
+       }
 
        if ( ber == NULL ) {
                Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 );
@@ -254,17 +286,29 @@ send_ldap_response(
                        matched == NULL ? "" : matched,
                        text == NULL ? "" : text );
 
-               if( rc != -1 && ref != NULL ) {
-                       rc = ber_printf( ber, "{V}", ref );
+               if( rc != -1 ) {
+                       if ( ref != NULL ) {
+                               assert( err == LDAP_REFERRAL );
+                               rc = ber_printf( ber, "t{V}",
+                                       LDAP_TAG_REFERRAL, ref );
+                       } else {
+                               assert( err != LDAP_REFERRAL );
+                       }
+               }
+
+               if( rc != -1 && sasldata != NULL ) {
+                       rc = ber_printf( ber, "tO",
+                               LDAP_TAG_SASL_RES_CREDS, sasldata );
                }
 
                if( rc != -1 && resoid != NULL ) {
-                       rc = ber_printf( ber, "s", resoid );
+                       rc = ber_printf( ber, "ts",
+                               LDAP_TAG_EXOP_RES_OID, resoid );
                }
 
                if( rc != -1 && resdata != NULL ) {
-                       rc = ber_printf( ber, "O", resdata );
-
+                       rc = ber_printf( ber, "tO",
+                               LDAP_TAG_EXOP_RES_VALUE, resdata );
                }
 
                if( rc != -1 ) {
@@ -333,7 +377,8 @@ send_ldap_disconnect(
 
 #ifdef LDAP_CONNECTIONLESS
        if ( op->o_cldap ) {
-               ber_pvt_sb_udp_set_dst( conn->c_sb, &op->o_clientaddr );
+               ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_UDP_SET_DST,
+                   (void *)&op->o_clientaddr );
                Debug( LDAP_DEBUG_TRACE, "UDP response to %s port %d\n", 
                    inet_ntoa(((struct sockaddr_in *)
                    &op->o_clientaddr)->sin_addr ),
@@ -341,9 +386,10 @@ send_ldap_disconnect(
                    0 );
        }
 #endif
+
        send_ldap_response( conn, op, tag, msgid,
                err, NULL, text, NULL,
-               reqoid, NULL, NULL );
+               reqoid, NULL, NULL, NULL );
 
        Statslog( LDAP_DEBUG_STATS,
            "conn=%ld op=%ld DISCONNECT err=%ld tag=%lu text=%s\n",
@@ -372,6 +418,11 @@ send_ldap_result(
                (long) op->o_connid, (long) op->o_opid, op->o_protocol );
        Debug( LDAP_DEBUG_ARGS, "send_ldap_result: %d:%s:%s\n",
                err, matched ?  matched : "", text ? text : "" );
+       if( ref ) {
+       Debug( LDAP_DEBUG_ARGS, "send_ldap_result: referral: %s\n",
+               ref[0] && ref[0]->bv_val ? ref[0]->bv_val : "NULL",
+               NULL, NULL );
+       }
 
        assert( err != LDAP_PARTIAL_RESULTS );
 
@@ -384,18 +435,22 @@ send_ldap_result(
                        err = LDAP_NO_SUCH_OBJECT;
                } else if ( op->o_protocol < LDAP_VERSION3 ) {
                        err = LDAP_PARTIAL_RESULTS;
-                       tmp = v2ref( ref );
-                       text = tmp;
-                       ref = NULL;
                }
        }
 
+       if ( op->o_protocol < LDAP_VERSION3 ) {
+               tmp = v2ref( ref, text );
+               text = tmp;
+               ref = NULL;
+       }
+
        tag = req2res( op->o_tag );
        msgid = (tag != LBER_SEQUENCE) ? op->o_msgid : 0;
 
 #ifdef LDAP_CONNECTIONLESS
        if ( op->o_cldap ) {
-               ber_pvt_sb_udp_set_dst( conn->c_sb, &op->o_clientaddr );
+               ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_UDP_SET_DST,
+                   (void *)&op->o_clientaddr );
                Debug( LDAP_DEBUG_TRACE, "UDP response to %s port %d\n", 
                    inet_ntoa(((struct sockaddr_in *)
                    &op->o_clientaddr)->sin_addr ),
@@ -406,7 +461,7 @@ send_ldap_result(
 
        send_ldap_response( conn, op, tag, msgid,
                err, matched, text, ref,
-               NULL, NULL, ctrls );
+               NULL, NULL, NULL, ctrls );
 
        Statslog( LDAP_DEBUG_STATS,
            "conn=%ld op=%ld RESULT tag=%lu err=%ld text=%s\n",
@@ -414,8 +469,88 @@ send_ldap_result(
                (long) tag, (long) err, text ? text : "" );
 
        if( tmp != NULL ) {
-               free(tmp);
+               ch_free(tmp);
+       }
+}
+
+void
+send_ldap_sasl(
+    Connection *conn,
+    Operation  *op,
+    ber_int_t  err,
+    const char *matched,
+    const char *text,
+       struct berval **ref,
+       LDAPControl **ctrls,
+       struct berval *cred
+)
+{
+       ber_tag_t tag;
+       ber_int_t msgid;
+
+       Debug( LDAP_DEBUG_TRACE, "send_ldap_sasl %ld\n",
+               (long) err, NULL, NULL );
+
+       tag = req2res( op->o_tag );
+       msgid = (tag != LBER_SEQUENCE) ? op->o_msgid : 0;
+
+#ifdef LDAP_CONNECTIONLESS
+       if ( op->o_cldap ) {
+               ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_UDP_SET_DST,
+                   (void *)&op->o_clientaddr );
+               Debug( LDAP_DEBUG_TRACE, "UDP response to %s port %d\n", 
+                   inet_ntoa(((struct sockaddr_in *)
+                   &op->o_clientaddr)->sin_addr ),
+                   ((struct sockaddr_in *) &op->o_clientaddr)->sin_port,
+                   0 );
        }
+#endif
+
+       send_ldap_response( conn, op, tag, msgid,
+               err, matched, text, ref,
+               NULL, NULL, cred, ctrls  );
+}
+
+void
+send_ldap_extended(
+    Connection *conn,
+    Operation  *op,
+    ber_int_t  err,
+    const char *matched,
+    const char *text,
+    struct berval **refs,
+    const char         *rspoid,
+       struct berval *rspdata,
+       LDAPControl **ctrls
+)
+{
+       ber_tag_t tag;
+       ber_int_t msgid;
+
+       Debug( LDAP_DEBUG_TRACE,
+               "send_ldap_extended %ld:%s (%ld)\n",
+               (long) err,
+               rspoid ? rspoid : "",
+               rspdata != NULL ? (long) rspdata->bv_len : (long) 0 );
+
+       tag = req2res( op->o_tag );
+       msgid = (tag != LBER_SEQUENCE) ? op->o_msgid : 0;
+
+#ifdef LDAP_CONNECTIONLESS
+       if ( op->o_cldap ) {
+               ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_UDP_SET_DST,
+                   (void *)&op->o_clientaddr );
+               Debug( LDAP_DEBUG_TRACE, "UDP response to %s port %d\n", 
+                   inet_ntoa(((struct sockaddr_in *)
+                   &op->o_clientaddr)->sin_addr ),
+                   ((struct sockaddr_in *) &op->o_clientaddr)->sin_port,
+                   0 );
+       }
+#endif
+
+       send_ldap_response( conn, op, tag, msgid,
+               err, matched, text, refs,
+               rspoid, rspdata, NULL, ctrls );
 }
 
 
@@ -449,10 +584,9 @@ send_search_result(
                        err = LDAP_PARTIAL_RESULTS;
                }
 
-               tmp = v2ref( refs );
+               tmp = v2ref( refs, text );
                text = tmp;
                refs = NULL;
-
        } else {
                /* don't send references in search results */
                assert( refs == NULL );
@@ -468,7 +602,8 @@ send_search_result(
 
 #ifdef LDAP_CONNECTIONLESS
        if ( op->o_cldap ) {
-               ber_pvt_sb_udp_set_dst( conn->c_sb, &op->o_clientaddr );
+               ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_UDP_SET_DST,
+                   (void *)&op->o_clientaddr );
                Debug( LDAP_DEBUG_TRACE, "UDP response to %s port %d\n", 
                    inet_ntoa(((struct sockaddr_in *)
                    &op->o_clientaddr)->sin_addr ),
@@ -479,13 +614,15 @@ send_search_result(
 
        send_ldap_response( conn, op, tag, msgid,
                err, matched, text, refs,
-               NULL, NULL, ctrls );
+               NULL, NULL, NULL, ctrls );
 
        Statslog( LDAP_DEBUG_STATS,
            "conn=%ld op=%ld SEARCH RESULT tag=%lu err=%ld text=%s\n",
                (long) op->o_connid, (long) op->o_opid,
                (long) tag, (long) err, text ? text : "" );
 
+       if (tmp != NULL)
+           ch_free(tmp);
 }
 
 
@@ -501,17 +638,18 @@ send_search_entry(
 )
 {
        BerElement      *ber;
-       Attribute       *a;
+       Attribute       *a, *aa;
        int             i, rc=-1, bytes;
-       AccessControl   *acl;
        char            *edn;
        int             userattrs;
        int             opattrs;
 
+       AttributeDescription *ad_entry = slap_schema.si_ad_entry;
+
        Debug( LDAP_DEBUG_TRACE, "=> send_search_entry: \"%s\"\n", e->e_dn, 0, 0 );
 
        if ( ! access_allowed( be, conn, op, e,
-               "entry", NULL, ACL_READ ) )
+               ad_entry, NULL, ACL_READ ) )
        {
                Debug( LDAP_DEBUG_ACL, "acl: access to entry not allowed\n",
                    0, 0, 0 );
@@ -524,19 +662,19 @@ send_search_entry(
 
        if ( ber == NULL ) {
                Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 );
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, "allocating BER error", NULL, NULL );
+               send_ldap_result( conn, op, LDAP_OTHER,
+                       NULL, "BER allocation error", NULL, NULL );
                goto error_return;
        }
 
-       rc = ber_printf( ber, "{it{s{", op->o_msgid,
+       rc = ber_printf( ber, "{it{s{" /*}}}*/, op->o_msgid,
                LDAP_RES_SEARCH_ENTRY, e->e_dn );
 
        if ( rc == -1 ) {
                Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
                ber_free( ber, 1 );
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                   NULL, "encoding dn error", NULL, NULL );
+               send_ldap_result( conn, op, LDAP_OTHER,
+                   NULL, "encoding DN error", NULL, NULL );
                goto error_return;
        }
 
@@ -549,52 +687,52 @@ send_search_entry(
                : charray_inlist( attrs, LDAP_ALL_OPERATIONAL_ATTRIBUTES );
 
        for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
-               regmatch_t       matches[MAXREMATCHES];
+               AttributeDescription *desc = a->a_desc;
+               char *type = desc->ad_cname->bv_val;
 
                if ( attrs == NULL ) {
                        /* all addrs request, skip operational attributes */
-                       if( !opattrs && oc_check_operational_attr( a->a_type ) ) {
+                       if( is_at_operational( desc->ad_type ) )
+                       {
                                continue;
                        }
 
                } else {
                        /* specific addrs requested */
-                       if (  oc_check_operational_attr( a->a_type ) ) {
-                               if( !opattrs && !charray_inlist( attrs, a->a_type ) )
-                               {
+                       if ( is_at_operational( desc->ad_type ) )
+                       {
+                               if( !opattrs && !ad_inlist( desc, attrs ) ) {
                                        continue;
                                }
                        } else {
-                               if (!userattrs && !charray_inlist( attrs, a->a_type ) )
-                               {
+                               if (!userattrs && !ad_inlist( desc, attrs ) ) {
                                        continue;
                                }
                        }
                }
 
-               acl = acl_get_applicable( be, op, e, a->a_type,
-                       MAXREMATCHES, matches );
-
-               if ( ! acl_access_allowed( acl, a->a_type, be, conn, e,
-                       NULL, op, ACL_READ, edn, matches ) ) 
-               {
+               if ( ! access_allowed( be, conn, op, e, desc, NULL, ACL_READ ) ) {
+                       Debug( LDAP_DEBUG_ACL, "acl: access to attribute %s not allowed\n",
+                           desc->ad_cname->bv_val, 0, 0 );
                        continue;
                }
 
-               if (( rc = ber_printf( ber, "{s[" /*]}*/ , a->a_type )) == -1 ) {
+               if (( rc = ber_printf( ber, "{s[" /*]}*/ , type )) == -1 ) {
                        Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
                        ber_free( ber, 1 );
-                       send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                           NULL, "encoding type error", NULL, NULL );
+                       send_ldap_result( conn, op, LDAP_OTHER,
+                           NULL, "encoding description error", NULL, NULL );
                        goto error_return;
                }
 
                if ( ! attrsonly ) {
                        for ( i = 0; a->a_vals[i] != NULL; i++ ) {
-                               if ( a->a_syntax & SYNTAX_DN && 
-                                       ! acl_access_allowed( acl, a->a_type, be, conn, e, a->a_vals[i], op,
-                                               ACL_READ, edn, matches) )
+                               if ( ! access_allowed( be, conn, op, e,
+                                       desc, a->a_vals[i], ACL_READ ) )
                                {
+                                       Debug( LDAP_DEBUG_ACL,
+                                               "acl: access to attribute %s, value %d not allowed\n",
+                                       desc->ad_cname->bv_val, i, 0 );
                                        continue;
                                }
 
@@ -602,8 +740,8 @@ send_search_entry(
                                        Debug( LDAP_DEBUG_ANY,
                                            "ber_printf failed\n", 0, 0, 0 );
                                        ber_free( ber, 1 );
-                                       send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                                               NULL, "encoding value error", NULL, NULL );
+                                       send_ldap_result( conn, op, LDAP_OTHER,
+                                               NULL, "encoding values error", NULL, NULL );
                                        goto error_return;
                                }
                        }
@@ -612,73 +750,73 @@ send_search_entry(
                if (( rc = ber_printf( ber, /*{[*/ "]}" )) == -1 ) {
                        Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
                        ber_free( ber, 1 );
-                       send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
+                       send_ldap_result( conn, op, LDAP_OTHER,
                            NULL, "encode end error", NULL, NULL );
                        goto error_return;
                }
        }
 
-#ifdef SLAPD_SCHEMA_DN
        /* eventually will loop through generated operational attributes */
        /* only have subschemaSubentry implemented */
-       a = backend_subschemasubentry( be );
+       aa = backend_operational( be, e );
        
-       do {
-               regmatch_t       matches[MAXREMATCHES];
+       for (a = aa ; a != NULL; a = a->a_next ) {
+               AttributeDescription *desc = a->a_desc;
 
                if ( attrs == NULL ) {
                        /* all addrs request, skip operational attributes */
-                       if( !opattrs && oc_check_operational_attr( a->a_type ) ) {
+                       if( is_at_operational( desc->ad_type ) ) {
                                continue;
                        }
 
                } else {
                        /* specific addrs requested */
-                       if (  oc_check_operational_attr( a->a_type ) ) {
-                               if( !opattrs && !charray_inlist( attrs, a->a_type ) )
+                       if( is_at_operational( desc->ad_type ) ) {
+                               if( !opattrs && !ad_inlist( desc, attrs ) )
                                {
                                        continue;
                                }
                        } else {
-                               if (!userattrs && !charray_inlist( attrs, a->a_type ) )
+                               if (!userattrs && !ad_inlist( desc, attrs ) )
                                {
                                        continue;
                                }
                        }
                }
 
-               acl = acl_get_applicable( be, op, e, a->a_type,
-                       MAXREMATCHES, matches );
-
-               if ( ! acl_access_allowed( acl, a->a_type, be, conn, e,
-                       NULL, op, ACL_READ, edn, matches ) ) 
-               {
+               if ( ! access_allowed( be, conn, op, e, desc, NULL, ACL_READ ) ) {
+                       Debug( LDAP_DEBUG_ACL, "acl: access to attribute %s not allowed\n",
+                           desc->ad_cname->bv_val, 0, 0 );
                        continue;
                }
 
-               if (( rc = ber_printf( ber, "{s[" /*]}*/ , a->a_type )) == -1 ) {
+               rc = ber_printf( ber, "{s[" /*]}*/ , desc->ad_cname->bv_val );
+               if ( rc == -1 ) {
                        Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
                        ber_free( ber, 1 );
-                       send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                           NULL, "encoding type error", NULL, NULL );
+                       send_ldap_result( conn, op, LDAP_OTHER,
+                           NULL, "encoding description error", NULL, NULL );
                        goto error_return;
                }
 
                if ( ! attrsonly ) {
                        for ( i = 0; a->a_vals[i] != NULL; i++ ) {
-                               if ( a->a_syntax & SYNTAX_DN && 
-                                       ! acl_access_allowed( acl, a->a_type, be, conn, e, a->a_vals[i], op,
-                                               ACL_READ, edn, matches) )
+                               if ( ! access_allowed( be, conn, op, e,
+                                       desc, a->a_vals[i], ACL_READ ) )
                                {
+                                       Debug( LDAP_DEBUG_ACL,
+                                               "acl: access to attribute %s, value %d not allowed\n",
+                                       desc->ad_cname->bv_val, i, 0 );
                                        continue;
                                }
 
+
                                if (( rc = ber_printf( ber, "O", a->a_vals[i] )) == -1 ) {
                                        Debug( LDAP_DEBUG_ANY,
                                            "ber_printf failed\n", 0, 0, 0 );
                                        ber_free( ber, 1 );
-                                       send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                                               NULL, "encoding value error", NULL, NULL );
+                                       send_ldap_result( conn, op, LDAP_OTHER,
+                                               NULL, "encoding values error", NULL, NULL );
                                        goto error_return;
                                }
                        }
@@ -687,19 +825,20 @@ send_search_entry(
                if (( rc = ber_printf( ber, /*{[*/ "]}" )) == -1 ) {
                        Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
                        ber_free( ber, 1 );
-                       send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
+                       send_ldap_result( conn, op, LDAP_OTHER,
                            NULL, "encode end error", NULL, NULL );
                        goto error_return;
                }
-       } while (0);
-#endif
+       }
+
+       attrs_free( aa );
 
        rc = ber_printf( ber, /*{{{*/ "}}}" );
 
        if ( rc == -1 ) {
                Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
                ber_free( ber, 1 );
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
+               send_ldap_result( conn, op, LDAP_OTHER,
                        NULL, "encode entry end error", NULL, NULL );
                return( 1 );
        }
@@ -747,10 +886,13 @@ send_search_reference(
        int rc;
        int bytes;
 
+       AttributeDescription *ad_ref = slap_schema.si_ad_ref;
+       AttributeDescription *ad_entry = slap_schema.si_ad_entry;
+
        Debug( LDAP_DEBUG_TRACE, "=> send_search_reference (%s)\n", e->e_dn, 0, 0 );
 
        if ( ! access_allowed( be, conn, op, e,
-               "entry", NULL, ACL_READ ) )
+               ad_entry, NULL, ACL_READ ) )
        {
                Debug( LDAP_DEBUG_ACL,
                        "send_search_reference: access to entry not allowed\n",
@@ -759,7 +901,7 @@ send_search_reference(
        }
 
        if ( ! access_allowed( be, conn, op, e,
-               "ref", NULL, ACL_READ ) )
+               ad_ref, NULL, ACL_READ ) )
        {
                Debug( LDAP_DEBUG_ACL,
                        "send_search_reference: access to reference not allowed\n",
@@ -776,7 +918,7 @@ send_search_reference(
 
        if( op->o_protocol < LDAP_VERSION3 ) {
                /* save the references for the result */
-               if( *refs == NULL ) {
+               if( *refs != NULL ) {
                        value_add( v2refs, refs );
                }
                return 0;
@@ -787,7 +929,7 @@ send_search_reference(
        if ( ber == NULL ) {
                Debug( LDAP_DEBUG_ANY,
                        "send_search_reference: ber_alloc failed\n", 0, 0, 0 );
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
+               send_ldap_result( conn, op, LDAP_OTHER,
                        NULL, "alloc BER error", NULL, NULL );
                return -1;
        }
@@ -799,8 +941,8 @@ send_search_reference(
                Debug( LDAP_DEBUG_ANY,
                        "send_search_reference: ber_printf failed\n", 0, 0, 0 );
                ber_free( ber, 1 );
-               send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
-                       NULL, "encode dn error", NULL, NULL );
+               send_ldap_result( conn, op, LDAP_OTHER,
+                       NULL, "encode DN error", NULL, NULL );
                return -1;
        }
 
index 919830f6dee18fb7a3b2270d58adfd5254a068ee..f987948c1e5506a9b94c84dd43ec00ba9f7bd461 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* root_dse.c - Provides the ROOT DSA-Specific Entry
  *
- * Copyright 1999 The OpenLDAP Foundation.
+ * Copyright 1999-2000 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 #include "portable.h"
 
 #include <stdio.h>
-
 #include <ac/string.h>
 
 #include "slap.h"
 
-void
-root_dse_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
+int
+root_dse_info( Entry **entry, const char **text )
 {
        char buf[BUFSIZ];
        Entry           *e;
@@ -27,6 +26,14 @@ root_dse_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
        struct berval   *vals[2];
        int             i, j;
 
+       AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass;
+       AttributeDescription *ad_namingContexts = slap_schema.si_ad_namingContexts;
+       AttributeDescription *ad_supportedControl = slap_schema.si_ad_supportedControl;
+       AttributeDescription *ad_supportedExtension = slap_schema.si_ad_supportedExtension;
+       AttributeDescription *ad_supportedLDAPVersion = slap_schema.si_ad_supportedLDAPVersion;
+       AttributeDescription *ad_supportedSASLMechanisms = slap_schema.si_ad_supportedSASLMechanisms;
+       AttributeDescription *ad_ref = slap_schema.si_ad_ref;
+
        vals[0] = &val;
        vals[1] = NULL;
 
@@ -35,50 +42,38 @@ root_dse_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
        e->e_attrs = NULL;
        e->e_dn = ch_strdup( LDAP_ROOT_DSE );
        e->e_ndn = ch_strdup( LDAP_ROOT_DSE );
-       (void) dn_normalize_case( e->e_ndn );
+       (void) dn_normalize( e->e_ndn );
        e->e_private = NULL;
 
+       val.bv_val = "top";
+       val.bv_len = sizeof("top")-1;
+       attr_merge( e, ad_objectClass, vals );
+
+       val.bv_val = "OpenLDAProotDSE";
+       val.bv_len = sizeof("OpenLDAProotDSE")-1;
+       attr_merge( e, ad_objectClass, vals );
+
        for ( i = 0; i < nbackends; i++ ) {
                for ( j = 0; backends[i].be_suffix[j] != NULL; j++ ) {
                        val.bv_val = backends[i].be_suffix[j];
                        val.bv_len = strlen( val.bv_val );
-                       attr_merge( e, "namingContexts", vals );
+                       attr_merge( e, ad_namingContexts, vals );
                }
        }
 
-#if defined( SLAPD_MONITOR_DN )
-       val.bv_val = SLAPD_MONITOR_DN;
-       val.bv_len = strlen( val.bv_val );
-       attr_merge( e, "namingContexts", vals );
-       /* subschemasubentry is added by send_search_entry() */
-#endif
-
-#if defined( SLAPD_CONFIG_DN )
-       val.bv_val = SLAPD_CONFIG_DN;
-       val.bv_len = strlen( val.bv_val );
-       attr_merge( e, "namingContexts", vals );
-#endif
-
-#if defined( SLAPD_SCHEMA_DN )
-       val.bv_val = SLAPD_SCHEMA_DN;
-       val.bv_len = strlen( val.bv_val );
-       attr_merge( e, "namingContexts", vals );
-#endif
-
        /* altServer unsupported */
 
        /* supportedControl */
        for ( i=0; supportedControls[i] != NULL; i++ ) {
                val.bv_val = supportedControls[i];
                val.bv_len = strlen( val.bv_val );
-               attr_merge( e, "supportedControl", vals );
+               attr_merge( e, ad_supportedControl, vals );
        }
 
        /* supportedExtension */
-       for ( i=0; supportedExtensions[i] != NULL; i++ ) {
-               val.bv_val = supportedExtensions[i];
+       for ( i=0; (val.bv_val = get_supported_extop(i)) != NULL; i++ ) {
                val.bv_len = strlen( val.bv_val );
-               attr_merge( e, "supportedExtension", vals );
+               attr_merge( e, ad_supportedExtension, vals );
        }
 
        /* supportedLDAPVersion */
@@ -86,7 +81,7 @@ root_dse_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
                sprintf(buf,"%d",i);
                val.bv_val = buf;
                val.bv_len = strlen( val.bv_val );
-               attr_merge( e, "supportedLDAPVersion", vals );
+               attr_merge( e, ad_supportedLDAPVersion, vals );
        }
 
        /* supportedSASLMechanism */
@@ -94,31 +89,15 @@ root_dse_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
                for ( i=0; supportedSASLMechanisms[i] != NULL; i++ ) {
                        val.bv_val = supportedSASLMechanisms[i];
                        val.bv_len = strlen( val.bv_val );
-                       attr_merge( e, "supportedSASLMechanisms", vals );
+                       attr_merge( e, ad_supportedSASLMechanisms, vals );
                }
        }
 
        if ( default_referral != NULL ) {
-               attr_merge( e, "ref", default_referral );
+               attr_merge( e, ad_ref, default_referral );
        }
 
-       val.bv_val = "top";
-       val.bv_len = sizeof("top")-1;
-       attr_merge( e, "objectClass", vals );
-
-       val.bv_val = "LDAPsubentry";
-       val.bv_len = sizeof("LDAPsubentry")-1;
-       attr_merge( e, "objectClass", vals );
-
-       val.bv_val = "extensibleObject";
-       val.bv_len = sizeof("extensibleObject")-1;
-       attr_merge( e, "objectClass", vals );
-
-       send_search_entry( &backends[0], conn, op,
-               e, attrs, attrsonly, NULL );
-       send_search_result( conn, op, LDAP_SUCCESS,
-               NULL, NULL, NULL, NULL, 1 );
-
-       entry_free( e );
+       *entry = e;
+       return LDAP_SUCCESS;
 }
 
index 6eb8eea57034f81b0840df2585ae18c3fe5ee995..2fd29f5073609b9d6076dd78c84050470a6cf1bb 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 #include <ldap_log.h>
 
 char **supportedSASLMechanisms = NULL;
+char *sasl_host = NULL;
 
 #ifdef HAVE_CYRUS_SASL
-static sasl_callback_t callbacks[] = {
-       { SASL_CB_LIST_END, NULL, NULL }
-};
+
+#ifdef SLAPD_SPASSWD
+#include <lutil.h>
+#endif
+
+static void *slap_sasl_mutex_new(void)
+{
+       ldap_pvt_thread_mutex_t *mutex;
+
+       mutex = (ldap_pvt_thread_mutex_t *) ch_malloc( sizeof(ldap_pvt_thread_mutex_t) );
+       if ( ldap_pvt_thread_mutex_init( mutex ) == 0 ) {
+               return mutex;
+       }
+       return NULL;
+}
+
+static int slap_sasl_mutex_lock(void *mutex)
+{
+       return ldap_pvt_thread_mutex_lock( (ldap_pvt_thread_mutex_t *)mutex );
+}
+
+static int slap_sasl_mutex_unlock(void *mutex)
+{
+       return ldap_pvt_thread_mutex_unlock( (ldap_pvt_thread_mutex_t *)mutex );
+}
+
+static void slap_sasl_mutex_dispose(void *mutex)
+{
+       (void) ldap_pvt_thread_mutex_destroy( (ldap_pvt_thread_mutex_t *)mutex );
+       free( mutex );
+}
+
+static int
+slap_sasl_err2ldap( int saslerr )
+{
+       int rc;
+
+       switch (saslerr) {
+               case SASL_CONTINUE:
+                       rc = LDAP_SASL_BIND_IN_PROGRESS;
+                       break;
+               case SASL_OK:
+                       rc = LDAP_SUCCESS;
+                       break;
+               case SASL_FAIL:
+                       rc = LDAP_OTHER;
+                       break;
+               case SASL_NOMEM:
+                       rc = LDAP_OTHER;
+                       break;
+               case SASL_NOMECH:
+                       rc = LDAP_AUTH_METHOD_NOT_SUPPORTED;
+                       break;
+               case SASL_BADAUTH:
+                       rc = LDAP_INVALID_CREDENTIALS;
+                       break;
+               case SASL_NOAUTHZ:
+                       rc = LDAP_INSUFFICIENT_ACCESS;
+                       break;
+               case SASL_TOOWEAK:
+               case SASL_ENCRYPT:
+                       rc = LDAP_INAPPROPRIATE_AUTH;
+                       break;
+               default:
+                       rc = LDAP_OTHER;
+                       break;
+       }
+
+       return rc;
+}
+
 
 int sasl_init( void )
 {
@@ -28,7 +97,15 @@ int sasl_init( void )
        char *mechs;
        sasl_conn_t *server = NULL;
 
-       rc = sasl_server_init( callbacks, "slapd" );
+       sasl_set_alloc( ch_malloc, ch_calloc, ch_realloc, ch_free ); 
+
+       sasl_set_mutex(
+               slap_sasl_mutex_new,
+               slap_sasl_mutex_lock,
+               slap_sasl_mutex_unlock,
+               slap_sasl_mutex_dispose );
+
+       rc = sasl_server_init( NULL, "slapd" );
 
        if( rc != SASL_OK ) {
                Debug( LDAP_DEBUG_ANY, "sasl_server_init failed\n",
@@ -36,7 +113,16 @@ int sasl_init( void )
                return -1;
        }
 
-       rc = sasl_server_new( "ldap", NULL, NULL, NULL,
+       if( sasl_host == NULL ) {
+               static char hostname[MAXHOSTNAMELEN+1];
+
+               if( gethostname( hostname, MAXHOSTNAMELEN ) == 0 ) {
+                       hostname[MAXHOSTNAMELEN] = '\0';
+                       sasl_host = hostname;
+               }
+       }
+
+       rc = sasl_server_new( "ldap", sasl_host, NULL, NULL,
                SASL_SECURITY_LAYER, 
                &server );
 
@@ -49,7 +135,7 @@ int sasl_init( void )
 #ifdef RESTRICT_SASL
        {
                sasl_security_properties_t secprops;
-               memset(&secprops, 0, sizeof(secprops));
+               memset(&secprops, '\0', sizeof(secprops));
                secprops.security_flags = SASL_SEC_NOPLAINTEXT | SASL_SEC_NOANONYMOUS;
                secprops.property_names = NULL;
                secprops.property_values = NULL;
@@ -77,19 +163,170 @@ int sasl_init( void )
                mechs, 0, 0 );
 
        supportedSASLMechanisms = str2charray( mechs, "," );
+
+#ifdef SLAPD_SPASSWD
+       lutil_passwd_sasl_conn = server;
+#else
        sasl_dispose( &server );
+#endif
 
        return 0;
 }
 
 int sasl_destroy( void )
 {
+#ifdef SLAPD_SPASSWD
+       sasl_dispose( &lutil_passwd_sasl_conn );
+#endif
        charray_free( supportedSASLMechanisms );
        return 0;
 }
 
+#ifdef HAVE_CYRUS_SASL
+int sasl_bind(
+    Connection          *conn,
+    Operation           *op,  
+    const char          *dn,  
+    const char          *ndn,
+    const char          *mech,
+    struct berval       *cred,
+       char                            **edn )
+{
+       struct berval response;
+       const char *errstr;
+       int sc;
+       int rc = 1;
+
+       Debug(LDAP_DEBUG_ARGS,
+               "==> sasl_bind: dn=\"%s\" mech=%s cred->bv_len=%d\n",
+               dn, mech, cred ? cred->bv_len : 0 );
+
+       if ( conn->c_sasl_bind_context == NULL ) {
+               sasl_callback_t callbacks[4];
+               int cbnum = 0;
+
+#if 0
+               if (be->be_sasl_authorize) {
+                       callbacks[cbnum].id = SASL_CB_PROXY_POLICY;
+                       callbacks[cbnum].proc = be->be_sasl_authorize;
+                       callbacks[cbnum].context = be;
+                       ++cbnum;
+               }
+
+               if (be->be_sasl_getsecret) {
+                       callbacks[cbnum].id = SASL_CB_SERVER_GETSECRET;
+                       callbacks[cbnum].proc = be->be_sasl_getsecret;
+                       callbacks[cbnum].context = be;
+                       ++cbnum;
+               }
+
+               if (be->be_sasl_putsecret) {
+                       callbacks[cbnum].id = SASL_CB_SERVER_PUTSECRET;
+                       callbacks[cbnum].proc = be->be_sasl_putsecret;
+                       callbacks[cbnum].context = be;
+                       ++cbnum;
+               }
+#endif
+
+               callbacks[cbnum].id = SASL_CB_LIST_END;
+               callbacks[cbnum].proc = NULL;
+               callbacks[cbnum].context = NULL;
+
+               /* create new SASL context */
+               sc = sasl_server_new( "ldap", sasl_host, global_realm,
+                       callbacks, SASL_SECURITY_LAYER, &conn->c_sasl_bind_context );
+
+               if( sc != SASL_OK ) {
+                       send_ldap_result( conn, op, rc = LDAP_AUTH_METHOD_NOT_SUPPORTED,
+                               NULL, NULL, NULL, NULL );
+               } else {
+                       unsigned reslen;
+                       conn->c_authmech = ch_strdup( mech );
+
+                       sc = sasl_server_start( conn->c_sasl_bind_context, conn->c_authmech,
+                               cred->bv_val, cred->bv_len,
+                               (char **)&response.bv_val, &reslen, &errstr );
+
+                       response.bv_len = reslen;
+                       
+                       if ( (sc != SASL_OK) && (sc != SASL_CONTINUE) ) {
+                               send_ldap_result( conn, op, rc = slap_sasl_err2ldap( sc ),
+                                       NULL, errstr, NULL, NULL );
+                       }
+               }
+       } else {
+               unsigned reslen;
+               sc = sasl_server_step( conn->c_sasl_bind_context, cred->bv_val, cred->bv_len,
+                       (char **)&response.bv_val, &reslen, &errstr );
+
+               response.bv_len = reslen;
+       
+               if ( (sc != SASL_OK) && (sc != SASL_CONTINUE) ) {
+                       send_ldap_result( conn, op, rc = slap_sasl_err2ldap( sc ),
+                               NULL, errstr, NULL, NULL );
+               }
+       }
+
+       if ( sc == SASL_OK ) {
+               char *authzid;
+
+               if ( ( sc = sasl_getprop( conn->c_sasl_bind_context, SASL_USERNAME,
+                       (void **)&authzid ) ) != SASL_OK ) {
+                       send_ldap_result( conn, op, rc = slap_sasl_err2ldap( sc ),
+                               NULL, NULL, NULL, NULL );
+
+               } else {
+                       Debug(LDAP_DEBUG_TRACE, "<== sasl_bind: username=%s\n",
+                               authzid, 0, 0);
+
+                       if( strncasecmp( authzid, "anonymous", sizeof("anonyous")-1 ) &&
+                               ( ( authzid[sizeof("anonymous")] == '\0' ) ||
+                               ( authzid[sizeof("anonymous")] == '@' ) ) )
+                       {
+                               *edn = ch_malloc( sizeof( "authzid=" ) + strlen( authzid ) );
+                               strcpy( *edn, "authzid=" );
+                               strcat( *edn, authzid );
+                       }
+
+                       send_ldap_result( conn, op, rc = LDAP_SUCCESS,
+                               NULL, NULL, NULL, NULL );
+               }
+
+       } else if ( sc == SASL_CONTINUE ) {
+               send_ldap_sasl( conn, op, rc = LDAP_SASL_BIND_IN_PROGRESS,
+                       NULL, NULL, NULL, NULL,  &response );
+       } 
+
+       if ( sc != SASL_CONTINUE && conn->c_sasl_bind_context != NULL ) {
+               sasl_dispose( &conn->c_sasl_bind_context );
+               conn->c_sasl_bind_context = NULL;
+       }
+
+       Debug(LDAP_DEBUG_TRACE, "<== sasl_bind: rc=%d\n", rc, 0, 0);
+
+       return rc;
+}
+#endif /* HAVE_CYRUS_SASL */
+
 #else
 /* no SASL support */
+int sasl_bind(
+    Connection          *conn,
+    Operation           *op,  
+    const char          *dn,  
+    const char          *ndn,
+    const char          *mech,
+    struct berval       *cred,
+       char                            **edn )
+{
+       int rc;
+
+       send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
+               NULL, "SASL unavailable", NULL, NULL );
+
+       return rc;
+}
+
 int sasl_init( void ) { return 0; }
 int sasl_destroy( void ) { return 0; }
 #endif
index 0462243dabdd454b5c507dcbbdce25678d89cc7d..f56ca4deffbdc1fe0e6aa4924258810e20f3784f 100644 (file)
@@ -1,7 +1,7 @@
-/* schema.c - routines to enforce schema definitions */
+/* schema.c - routines to manage schema definitions */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 #include <ac/socket.h>
 
 #include "slap.h"
+#include "ldap_pvt.h"
 
-static char *  oc_check_required(Entry *e, char *ocname);
-static int             oc_check_allowed(char *type, struct berval **ocl);
-
-
-/*
- * oc_check - check that entry e conforms to the schema required by
- * its object class(es). returns 0 if so, non-zero otherwise.
- */
-
-int
-oc_schema_check( Entry *e )
-{
-       Attribute       *a, *aoc;
-       ObjectClass *oc;
-       int             i;
-       int             ret = 0;
-
-
-       /* find the object class attribute - could error out here */
-       if ( (aoc = attr_find( e->e_attrs, "objectclass" )) == NULL ) {
-               Debug( LDAP_DEBUG_ANY, "No object class for entry (%s)\n",
-                   e->e_dn, 0, 0 );
-               return( 1 );
-       }
-
-       /* check that the entry has required attrs for each oc */
-       for ( i = 0; aoc->a_vals[i] != NULL; i++ ) {
-               if ( (oc = oc_find( aoc->a_vals[i]->bv_val )) == NULL ) {
-                       Debug( LDAP_DEBUG_ANY,
-                               "Objectclass \"%s\" not defined",
-                               aoc->a_vals[i]->bv_val, 0, 0 );
-               }
-               else
-               {
-                       char *s = oc_check_required( e, aoc->a_vals[i]->bv_val );
-
-                       if (s != NULL) {
-                               Debug( LDAP_DEBUG_ANY,
-                                       "Entry (%s), oc \"%s\" requires attr \"%s\"\n",
-                                       e->e_dn, aoc->a_vals[i]->bv_val, s );
-                               ret = 1;
-                       }
-               }
-       }
-
-       if ( ret != 0 ) {
-           return( ret );
-       }
-
-       /* check that each attr in the entry is allowed by some oc */
-       for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
-               if ( oc_check_allowed( a->a_type, aoc->a_vals ) != 0 ) {
-                       Debug( LDAP_DEBUG_ANY,
-                           "Entry (%s), attr \"%s\" not allowed\n",
-                           e->e_dn, a->a_type, 0 );
-                       ret = 1;
-               }
-       }
-
-       return( ret );
-}
-
-static char *
-oc_check_required( Entry *e, char *ocname )
-{
-       ObjectClass     *oc;
-       AttributeType   *at;
-       int             i;
-       Attribute       *a;
-       char            **pp;
-
-       Debug( LDAP_DEBUG_TRACE,
-              "oc_check_required entry (%s), objectclass \"%s\"\n",
-              e->e_dn, ocname, 0 );
-
-       /* find global oc defn. it we don't know about it assume it's ok */
-       if ( (oc = oc_find( ocname )) == NULL ) {
-               return( 0 );
-       }
-
-       /* check for empty oc_required */
-       if(oc->soc_required == NULL) {
-               return( 0 );
-       }
-
-       /* for each required attribute */
-       for ( i = 0; oc->soc_required[i] != NULL; i++ ) {
-               at = oc->soc_required[i];
-               /* see if it's in the entry */
-               for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
-                       if ( at->sat_oid &&
-                            strcmp( a->a_type, at->sat_oid ) == 0 ) {
-                               break;
-                       }
-                       pp = at->sat_names;
-                       if ( pp  == NULL ) {
-                               /* Empty name list => not found */
-                               a = NULL;
-                               break;
-                       }
-                       while ( *pp ) {
-                               if ( strcasecmp( a->a_type, *pp ) == 0 ) {
-                                       break;
-                               }
-                               pp++;
-                       }
-                       if ( *pp ) {
-                               break;
-                       }
-               }
-               /* not there => schema violation */
-               if ( a == NULL ) {
-                       if ( at->sat_names && at->sat_names[0] ) {
-                               return at->sat_names[0];
-                       } else {
-                               return at->sat_oid;
-                       }
-               }
-       }
-
-       return( NULL );
-}
-
-static char *oc_usermod_attrs[] = {
-       /*
-        * OpenLDAP doesn't support any user modification of
-        * operational attributes.
-        */
-       NULL
-};
-
-static char *oc_operational_attrs[] = {
-       /*
-        * these are operational attributes 
-        * most could be user modifiable
-        */
-       "objectClasses",
-       "attributeTypes",
-       "matchingRules",
-       "matchingRuleUse",
-       "dITStructureRules",
-       "dITContentRules",
-       "nameForms",
-       "ldapSyntaxes",
-       "namingContexts",
-       "supportedExtension",
-       "supportedControl",
-       "supportedSASLMechanisms",
-       "supportedLDAPversion",
-       "subschemaSubentry",            /* NO USER MOD */
-       NULL
-
-};
-
-/* this list should be extensible  */
-static char *oc_no_usermod_attrs[] = {
-       /*
-        * Operational and 'no user modification' attributes
-        * which are STORED in the directory server.
-        */
-
-       /* RFC2252, 3.2.1 */
-       "creatorsName",
-       "createTimestamp",
-       "modifiersName",
-       "modifyTimestamp",
-
-       NULL
-};
-
-
-/*
- * check to see if attribute is 'operational' or not.
- */
-int
-oc_check_operational_attr( const char *type )
-{
-       return charray_inlist( oc_operational_attrs, type )
-               || charray_inlist( oc_usermod_attrs, type )
-               || charray_inlist( oc_no_usermod_attrs, type );
-}
-
-/*
- * check to see if attribute can be user modified or not.
- */
-int
-oc_check_usermod_attr( const char *type )
-{
-       return charray_inlist( oc_usermod_attrs, type );
-}
-
-/*
- * check to see if attribute is 'no user modification' or not.
- */
-int
-oc_check_no_usermod_attr( const char *type )
-{
-       return charray_inlist( oc_no_usermod_attrs, type );
-}
-
-
-static int
-oc_check_allowed( char *type, struct berval **ocl )
-{
-       ObjectClass     *oc;
-       AttributeType   *at;
-       int             i, j;
-       char            **pp;
-
-       Debug( LDAP_DEBUG_TRACE,
-              "oc_check_allowed type \"%s\"\n", type, 0, 0 );
-
-       /* always allow objectclass attribute */
-       if ( strcasecmp( type, "objectclass" ) == 0 ) {
-               return( 0 );
-       }
-
-       /*
-        * All operational attributions are allowed by schema rules.
-        * However, we only check attributions which are stored in the
-        * the directory regardless if they are user or non-user modified.
-        */
-       if ( oc_check_usermod_attr( type ) || oc_check_no_usermod_attr( type ) ) {
-               return( 0 );
-       }
-
-       /* check that the type appears as req or opt in at least one oc */
-       for ( i = 0; ocl[i] != NULL; i++ ) {
-               /* if we know about the oc */
-               if ( (oc = oc_find( ocl[i]->bv_val )) != NULL ) {
-                       /* does it require the type? */
-                       for ( j = 0; oc->soc_required != NULL && 
-                               oc->soc_required[j] != NULL; j++ ) {
-                               at = oc->soc_required[j];
-                               if ( at->sat_oid &&
-                                    strcmp(at->sat_oid, type ) == 0 ) {
-                                       return( 0 );
-                               }
-                               pp = at->sat_names;
-                               if ( pp == NULL )
-                                       continue;
-                               while ( *pp ) {
-                                       if ( strcasecmp( *pp, type ) == 0 ) {
-                                               return( 0 );
-                                       }
-                                       pp++;
-                               }
-                       }
-                       /* does it allow the type? */
-                       for ( j = 0; oc->soc_allowed != NULL && 
-                               oc->soc_allowed[j] != NULL; j++ ) {
-                               at = oc->soc_allowed[j];
-                               if ( at->sat_oid &&
-                                    strcmp(at->sat_oid, type ) == 0 ) {
-                                       return( 0 );
-                               }
-                               pp = at->sat_names;
-                               if ( pp == NULL )
-                                       continue;
-                               while ( *pp ) {
-                                       if ( strcasecmp( *pp, type ) == 0 ||
-                                            strcmp( *pp, "*" ) == 0 ) {
-                                               return( 0 );
-                                       }
-                                       pp++;
-                               }
-                       }
-                       /* maybe the next oc allows it */
-
-               /* we don't know about the oc. assume it allows it */
-               } else {
-                       return( 0 );
-               }
-       }
-
-       /* not allowed by any oc */
-       return( 1 );
-}
-
-struct oindexrec {
-       char            *oir_name;
-       ObjectClass     *oir_oc;
-};
-
-static Avlnode *oc_index = NULL;
-static ObjectClass *oc_list = NULL;
-
-static int
-oc_index_cmp(
-    struct oindexrec   *oir1,
-    struct oindexrec   *oir2
-)
-{
-       return (strcasecmp( oir1->oir_name, oir2->oir_name ));
-}
-
-static int
-oc_index_name_cmp(
-    char               *name,
-    struct oindexrec   *oir
-)
-{
-       return (strcasecmp( name, oir->oir_name ));
-}
-
-ObjectClass *
-oc_find( const char *ocname )
-{
-       struct oindexrec        *oir = NULL;
-
-       if ( (oir = (struct oindexrec *) avl_find( oc_index, ocname,
-            (AVL_CMP) oc_index_name_cmp )) != NULL ) {
-               return( oir->oir_oc );
-       }
-       return( NULL );
-}
-
-static int
-oc_create_required(
-    ObjectClass                *soc,
-    char               **attrs,
-    const char         **err
-)
-{
-       char            **attrs1;
-       AttributeType   *sat;
-       AttributeType   **satp;
-       int             i;
-
-       if ( attrs ) {
-               attrs1 = attrs;
-               while ( *attrs1 ) {
-                       sat = at_find(*attrs1);
-                       if ( !sat ) {
-                               *err = *attrs1;
-                               return SLAP_SCHERR_ATTR_NOT_FOUND;
-                       }
-                       if ( at_find_in_list(sat, soc->soc_required) < 0) {
-                               if ( at_append_to_list(sat, &soc->soc_required) ) {
-                                       *err = *attrs1;
-                                       return SLAP_SCHERR_OUTOFMEM;
-                               }
-                       }
-                       attrs1++;
-               }
-               /* Now delete duplicates from the allowed list */
-               for ( satp = soc->soc_required; *satp; satp++ ) {
-                       i = at_find_in_list(*satp,soc->soc_allowed);
-                       if ( i >= 0 ) {
-                               at_delete_from_list(i, &soc->soc_allowed);
-                       }
-               }
-       }
-       return 0;
-}
-
-static int
-oc_create_allowed(
-    ObjectClass                *soc,
-    char               **attrs,
-    const char         **err
-)
-{
-       char            **attrs1;
-       AttributeType   *sat;
-
-       if ( attrs ) {
-               attrs1 = attrs;
-               while ( *attrs1 ) {
-                       sat = at_find(*attrs1);
-                       if ( !sat ) {
-                               *err = *attrs1;
-                               return SLAP_SCHERR_ATTR_NOT_FOUND;
-                       }
-                       if ( at_find_in_list(sat, soc->soc_required) < 0 &&
-                            at_find_in_list(sat, soc->soc_allowed) < 0 ) {
-                               if ( at_append_to_list(sat, &soc->soc_allowed) ) {
-                                       *err = *attrs1;
-                                       return SLAP_SCHERR_OUTOFMEM;
-                               }
-                       }
-                       attrs1++;
-               }
-       }
-       return 0;
-}
-
-static int
-oc_add_sups(
-    ObjectClass                *soc,
-    char               **sups,
-    const char         **err
-)
-{
-       int             code;
-       ObjectClass     *soc1;
-       int             nsups;
-       char            **sups1;
-       int             add_sups = 0;
-
-       if ( sups ) {
-               if ( !soc->soc_sups ) {
-                       /* We are at the first recursive level */
-                       add_sups = 1;
-                       nsups = 0;
-                       sups1 = sups;
-                       while ( *sups1 ) {
-                               nsups++;
-                               sups1++;
-                       }
-                       nsups++;
-                       soc->soc_sups = (ObjectClass **)ch_calloc(1,
-                                         nsups*sizeof(ObjectClass *));
-               }
-               nsups = 0;
-               sups1 = sups;
-               while ( *sups1 ) {
-                       soc1 = oc_find(*sups1);
-                       if ( !soc1 ) {
-                               *err = *sups1;
-                               return SLAP_SCHERR_CLASS_NOT_FOUND;
-                       }
-
-                       if ( add_sups )
-                               soc->soc_sups[nsups] = soc1;
-
-                       code = oc_add_sups(soc,soc1->soc_sup_oids, err);
-                       if ( code )
-                               return code;
-
-                       code = oc_create_required(soc,soc1->soc_at_oids_must,err);
-                       if ( code )
-                               return code;
-                       code = oc_create_allowed(soc,soc1->soc_at_oids_may,err);
-                       if ( code )
-                               return code;
-
-                       nsups++;
-                       sups1++;
-               }
-       }
-       return 0;
-}
-
-static int
-oc_insert(
-    ObjectClass                *soc,
-    const char         **err
-)
-{
-       ObjectClass     **ocp;
-       struct oindexrec        *oir;
-       char                    **names;
-
-       ocp = &oc_list;
-       while ( *ocp != NULL ) {
-               ocp = &(*ocp)->soc_next;
-       }
-       *ocp = soc;
-
-       if ( soc->soc_oid ) {
-               oir = (struct oindexrec *)
-                       ch_calloc( 1, sizeof(struct oindexrec) );
-               oir->oir_name = soc->soc_oid;
-               oir->oir_oc = soc;
-               if ( avl_insert( &oc_index, (caddr_t) oir,
-                                (AVL_CMP) oc_index_cmp,
-                                (AVL_DUP) avl_dup_error ) ) {
-                       *err = soc->soc_oid;
-                       ldap_memfree(oir);
-                       return SLAP_SCHERR_DUP_CLASS;
-               }
-               /* FIX: temporal consistency check */
-               oc_find(oir->oir_name);
-       }
-       if ( (names = soc->soc_names) ) {
-               while ( *names ) {
-                       oir = (struct oindexrec *)
-                               ch_calloc( 1, sizeof(struct oindexrec) );
-                       oir->oir_name = ch_strdup(*names);
-                       oir->oir_oc = soc;
-                       if ( avl_insert( &oc_index, (caddr_t) oir,
-                                        (AVL_CMP) oc_index_cmp,
-                                        (AVL_DUP) avl_dup_error ) ) {
-                               *err = *names;
-                               ldap_memfree(oir);
-                               return SLAP_SCHERR_DUP_CLASS;
-                       }
-                       /* FIX: temporal consistency check */
-                       oc_find(oir->oir_name);
-                       names++;
-               }
-       }
-       return 0;
-}
-
-int
-oc_add(
-    LDAP_OBJECT_CLASS  *oc,
-    const char         **err
-)
-{
-       ObjectClass     *soc;
-       int             code;
-
-       soc = (ObjectClass *) ch_calloc( 1, sizeof(ObjectClass) );
-       memcpy( &soc->soc_oclass, oc, sizeof(LDAP_OBJECT_CLASS));
-       if ( (code = oc_add_sups(soc,soc->soc_sup_oids,err)) != 0 )
-               return code;
-       if ( (code = oc_create_required(soc,soc->soc_at_oids_must,err)) != 0 )
-               return code;
-       if ( (code = oc_create_allowed(soc,soc->soc_at_oids_may,err)) != 0 )
-               return code;
-       code = oc_insert(soc,err);
-       return code;
-}
-
-struct sindexrec {
-       char            *sir_name;
-       Syntax          *sir_syn;
-};
-
-static Avlnode *syn_index = NULL;
-static Syntax *syn_list = NULL;
-
-static int
-syn_index_cmp(
-    struct sindexrec   *sir1,
-    struct sindexrec   *sir2
-)
-{
-       return (strcmp( sir1->sir_name, sir2->sir_name ));
-}
-
-static int
-syn_index_name_cmp(
-    char               *name,
-    struct sindexrec   *sir
-)
-{
-       return (strcmp( name, sir->sir_name ));
-}
-
-Syntax *
-syn_find( const char *synname )
-{
-       struct sindexrec        *sir = NULL;
-
-       if ( (sir = (struct sindexrec *) avl_find( syn_index, synname,
-            (AVL_CMP) syn_index_name_cmp )) != NULL ) {
-               return( sir->sir_syn );
-       }
-       return( NULL );
-}
-
-Syntax *
-syn_find_desc( const char *syndesc, int *len )
-{
-       Syntax          *synp;
-
-       for (synp = syn_list; synp; synp = synp->ssyn_next)
-               if ((*len = dscompare( synp->ssyn_syn.syn_desc, syndesc, '{')))
-                       return synp;
-       return( NULL );
-}
-
-static int
-syn_insert(
-    Syntax             *ssyn,
-    const char         **err
-)
-{
-       Syntax          **synp;
-       struct sindexrec        *sir;
-
-       synp = &syn_list;
-       while ( *synp != NULL ) {
-               synp = &(*synp)->ssyn_next;
-       }
-       *synp = ssyn;
-
-       if ( ssyn->ssyn_oid ) {
-               sir = (struct sindexrec *)
-                       ch_calloc( 1, sizeof(struct sindexrec) );
-               sir->sir_name = ssyn->ssyn_oid;
-               sir->sir_syn = ssyn;
-               if ( avl_insert( &syn_index, (caddr_t) sir,
-                                (AVL_CMP) syn_index_cmp,
-                                (AVL_DUP) avl_dup_error ) ) {
-                       *err = ssyn->ssyn_oid;
-                       ldap_memfree(sir);
-                       return SLAP_SCHERR_DUP_SYNTAX;
-               }
-               /* FIX: temporal consistency check */
-               syn_find(sir->sir_name);
-       }
-       return 0;
-}
-
-int
-syn_add(
-    LDAP_SYNTAX                *syn,
-    slap_syntax_check_func     *check,
-    const char         **err
-)
-{
-       Syntax          *ssyn;
-       int             code;
-
-       ssyn = (Syntax *) ch_calloc( 1, sizeof(Syntax) );
-       memcpy( &ssyn->ssyn_syn, syn, sizeof(LDAP_SYNTAX));
-       ssyn->ssyn_check = check;
-       code = syn_insert(ssyn,err);
-       return code;
-}
-
-struct mindexrec {
-       char            *mir_name;
-       MatchingRule    *mir_mr;
-};
-
-static Avlnode *mr_index = NULL;
-static MatchingRule *mr_list = NULL;
-
-static int
-mr_index_cmp(
-    struct mindexrec   *mir1,
-    struct mindexrec   *mir2
-)
-{
-       return (strcmp( mir1->mir_name, mir2->mir_name ));
-}
-
-static int
-mr_index_name_cmp(
-    char               *name,
-    struct mindexrec   *mir
-)
-{
-       return (strcmp( name, mir->mir_name ));
-}
-
-MatchingRule *
-mr_find( const char *mrname )
-{
-       struct mindexrec        *mir = NULL;
-
-       if ( (mir = (struct mindexrec *) avl_find( mr_index, mrname,
-            (AVL_CMP) mr_index_name_cmp )) != NULL ) {
-               return( mir->mir_mr );
-       }
-       return( NULL );
-}
-
-static int
-mr_insert(
-    MatchingRule       *smr,
-    const char         **err
-)
-{
-       MatchingRule            **mrp;
-       struct mindexrec        *mir;
-       char                    **names;
-
-       mrp = &mr_list;
-       while ( *mrp != NULL ) {
-               mrp = &(*mrp)->smr_next;
-       }
-       *mrp = smr;
-
-       if ( smr->smr_oid ) {
-               mir = (struct mindexrec *)
-                       ch_calloc( 1, sizeof(struct mindexrec) );
-               mir->mir_name = smr->smr_oid;
-               mir->mir_mr = smr;
-               if ( avl_insert( &mr_index, (caddr_t) mir,
-                                (AVL_CMP) mr_index_cmp,
-                                (AVL_DUP) avl_dup_error ) ) {
-                       *err = smr->smr_oid;
-                       ldap_memfree(mir);
-                       return SLAP_SCHERR_DUP_RULE;
-               }
-               /* FIX: temporal consistency check */
-               mr_find(mir->mir_name);
-       }
-       if ( (names = smr->smr_names) ) {
-               while ( *names ) {
-                       mir = (struct mindexrec *)
-                               ch_calloc( 1, sizeof(struct mindexrec) );
-                       mir->mir_name = ch_strdup(*names);
-                       mir->mir_mr = smr;
-                       if ( avl_insert( &mr_index, (caddr_t) mir,
-                                        (AVL_CMP) mr_index_cmp,
-                                        (AVL_DUP) avl_dup_error ) ) {
-                               *err = *names;
-                               ldap_memfree(mir);
-                               return SLAP_SCHERR_DUP_RULE;
-                       }
-                       /* FIX: temporal consistency check */
-                       mr_find(mir->mir_name);
-                       names++;
-               }
-       }
-       return 0;
-}
-
-int
-mr_add(
-    LDAP_MATCHING_RULE         *mr,
-    slap_mr_normalize_func     *normalize,
-    slap_mr_compare_func       *compare,
-    const char         **err
-)
-{
-       MatchingRule    *smr;
-       Syntax          *syn;
-       int             code;
-
-       smr = (MatchingRule *) ch_calloc( 1, sizeof(MatchingRule) );
-       memcpy( &smr->smr_mrule, mr, sizeof(LDAP_MATCHING_RULE));
-       smr->smr_normalize = normalize;
-       smr->smr_compare = compare;
-       if ( smr->smr_syntax_oid ) {
-               if ( (syn = syn_find(smr->smr_syntax_oid)) ) {
-                       smr->smr_syntax = syn;
-               } else {
-                       *err = smr->smr_syntax_oid;
-                       return SLAP_SCHERR_SYN_NOT_FOUND;
-               }
-       } else {
-               *err = "";
-               return SLAP_SCHERR_MR_INCOMPLETE;
-       }
-       code = mr_insert(smr,err);
-       return code;
-}
-
-static int
-case_exact_normalize(
-       struct berval *val,
-       struct berval **normalized
-)
-{
-       struct berval *newval;
-       char *p, *q;
-
-       newval = ber_bvdup( val );
-       p = q = newval->bv_val;
-       /* Ignore initial whitespace */
-       while ( isspace( *p++ ) )
-               ;
-       while ( *p ) {
-               if ( isspace( *p ) ) {
-                       *q++ = *p++;
-                       /* Ignore the extra whitespace */
-                       while ( isspace(*p++) )
-                               ;
-               } else {
-                       *q++ = *p++;
-               }
-       }
-       /*
-        * If the string ended in space, backup the pointer one
-        * position.  One is enough because the above loop collapsed
-        * all whitespace to a single space.
-        */
-       if ( p != newval->bv_val && isspace( *(p-1) ) ) {
-               *(q-1) = '\0';
-       }
-       newval->bv_len = strlen( newval->bv_val );
-       normalized = &newval;
-
-       return 0;
-}
-
-static int
-case_exact_compare(
-       struct berval *val1,
-       struct berval *val2
-)
-{
-       return strcmp( val1->bv_val, val2->bv_val );
-}
-
-int
-case_ignore_normalize(
-       struct berval *val,
-       struct berval **normalized
-)
-{
-       struct berval *newval;
-       char *p, *q;
-
-       newval = ber_bvdup( val );
-       p = q = newval->bv_val;
-       /* Ignore initial whitespace */
-       while ( isspace( *p++ ) )
-               ;
-       while ( *p ) {
-               if ( isspace( *p ) ) {
-                       *q++ = *p++;
-                       /* Ignore the extra whitespace */
-                       while ( isspace(*p++) )
-                               ;
-               } else {
-                       *q++ = TOUPPER( *p++ );
-               }
-       }
-       /*
-        * If the string ended in space, backup the pointer one
-        * position.  One is enough because the above loop collapsed
-        * all whitespace to a single space.
-        */
-       if ( p != newval->bv_val && isspace( *(p-1) ) ) {
-               *(q-1) = '\0';
-       }
-       newval->bv_len = strlen( newval->bv_val );
-       normalized = &newval;
-
-       return 0;
-}
-
-static int
-case_ignore_compare(
-       struct berval *val1,
-       struct berval *val2
-)
-{
-       return strcasecmp( val1->bv_val, val2->bv_val );
-}
-
-int
-register_syntax(
-       char * desc,
-       slap_syntax_check_func *check )
-{
-       LDAP_SYNTAX     *syn;
-       int             code;
-       const char      *err;
-
-       syn = ldap_str2syntax( desc, &code, &err);
-       if ( !syn ) {
-               Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s before %s in %s\n",
-                   ldap_scherr2str(code), err, desc );
-               return( -1 );
-       }
-       code = syn_add( syn, check, &err );
-       if ( code ) {
-               Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s %s in %s\n",
-                   scherr2str(code), err, desc );
-               return( -1 );
-       }
-       return( 0 );
-}
-
-int
-register_matching_rule(
-       char * desc,
-       slap_mr_normalize_func *normalize,
-       slap_mr_compare_func *compare )
-{
-       LDAP_MATCHING_RULE *mr;
-       int             code;
-       const char      *err;
-
-       mr = ldap_str2matchingrule( desc, &code, &err);
-       if ( !mr ) {
-               Debug( LDAP_DEBUG_ANY, "Error in register_matching_rule: %s before %s in %s\n",
-                   ldap_scherr2str(code), err, desc );
-               return( -1 );
-       }
-       code = mr_add( mr, normalize, compare, &err );
-       if ( code ) {
-               Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s for %s in %s\n",
-                   scherr2str(code), err, desc );
-               return( -1 );
-       }
-       return( 0 );
-}
-
-struct syntax_defs_rec {
-       char *sd_desc;
-       slap_syntax_check_func *sd_check;
-};
-
-struct syntax_defs_rec syntax_defs[] = {
-       {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'AttributeTypeDescription' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'BitString' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'CertificateList' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'CertificatePair' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'DN' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'DeliveryMethod' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'DirectoryString' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DITContentRuleDescription' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DITStructureRuleDescription' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'EnhancedGuide' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'FacsimileTelephoneNumber' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'GeneralizedTime' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5String' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'MatchingRuleDescription' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'MatchingRuleUseDescription' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'MailPreference' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'NameAndOptionalUID' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'NameFormDescription' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'NumericString' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'ObjectClassDescription' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'OtherMailbox' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'OctetString' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'PostalAddress' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'ProtocolInformation' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'PresentationAddress' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'PrintableString' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'SupportedAlgorithm' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'TelephoneNumber' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'TeletexTerminalIdentifier' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'TelexNumber' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTCTime' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAPSyntaxDescription' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'SubstringAssertion' )", NULL},
-       {"( 1.3.6.1.1.1.0.0 DESC 'NISnetgrouptriple' )", NULL},
-       {"( 1.3.6.1.1.1.0.1 DESC 'Bootparameter' )", NULL},
-       {NULL, NULL}
-};
-
-struct mrule_defs_rec {
-       char *mrd_desc;
-       slap_mr_normalize_func *mrd_normalize;
-       slap_mr_compare_func *mrd_compare;
-};
-
-/*
- * Other matching rules in X.520 that we do not use:
- *
- * 2.5.13.9    numericStringOrderingMatch
- * 2.5.13.12   caseIgnoreListSubstringsMatch
- * 2.5.13.13   booleanMatch
- * 2.5.13.15   integerOrderingMatch
- * 2.5.13.18   octetStringOrderingMatch
- * 2.5.13.19   octetStringSubstringsMatch
- * 2.5.13.25   uTCTimeMatch
- * 2.5.13.26   uTCTimeOrderingMatch
- * 2.5.13.31   directoryStringFirstComponentMatch
- * 2.5.13.32   wordMatch
- * 2.5.13.33   keywordMatch
- * 2.5.13.34   certificateExactMatch
- * 2.5.13.35   certificateMatch
- * 2.5.13.36   certificatePairExactMatch
- * 2.5.13.37   certificatePairMatch
- * 2.5.13.38   certificateListExactMatch
- * 2.5.13.39   certificateListMatch
- * 2.5.13.40   algorithmIdentifierMatch
- * 2.5.13.41   storedPrefixMatch
- * 2.5.13.42   attributeCertificateMatch
- * 2.5.13.43   readerAndKeyIDMatch
- * 2.5.13.44   attributeIntegrityMatch
- */
-
-struct mrule_defs_rec mrule_defs[] = {
-       {"( 2.5.13.0 NAME 'objectIdentifierMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", NULL, NULL},
-       {"( 2.5.13.1 NAME 'distinguishedNameMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", NULL, NULL},
-       {"( 2.5.13.2 NAME 'caseIgnoreMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
-        case_ignore_normalize, case_ignore_compare},
-       {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
-        case_ignore_normalize, case_ignore_compare},
-       {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
-        case_ignore_normalize, case_ignore_compare},
-       /* Next three are not in the RFC's, but are needed for compatibility */
-       {"( 2.5.13.5 NAME 'caseExactMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
-        case_exact_normalize, case_exact_compare},
-       {"( 2.5.13.6 NAME 'caseExactOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
-        case_exact_normalize, case_exact_compare},
-       {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
-        case_exact_normalize, case_exact_compare},
-       {"( 2.5.13.8 NAME 'numericStringMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )", NULL, NULL},
-       {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", NULL, NULL},
-       {"( 2.5.13.11 NAME 'caseIgnoreListMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )", NULL, NULL},
-       {"( 2.5.13.14 NAME 'integerMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", NULL, NULL},
-       {"( 2.5.13.16 NAME 'bitStringMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )", NULL, NULL},
-       {"( 2.5.13.17 NAME 'octetStringMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", NULL, NULL},
-       {"( 2.5.13.20 NAME 'telephoneNumberMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )", NULL, NULL},
-       {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", NULL, NULL},
-       {"( 2.5.13.22 NAME 'presentationAddressMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )", NULL, NULL},
-       {"( 2.5.13.23 NAME 'uniqueMemberMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )", NULL, NULL},
-       {"( 2.5.13.24 NAME 'protocolInformationMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )", NULL, NULL},
-       {"( 2.5.13.27 NAME 'generalizedTimeMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )", NULL, NULL},
-       {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )", NULL, NULL},
-       {"( 2.5.13.29 NAME 'integerFirstComponentMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", NULL, NULL},
-       {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", NULL, NULL},
-       {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
-        case_exact_normalize, case_exact_compare},
-       {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
-        case_ignore_normalize, case_ignore_compare},
-       {NULL, NULL, NULL}
-};
-
-int
-schema_init( void )
-{
-       int             res;
-       int             i;
-       static int      schema_init_done = 0;
-
-       /* We are called from read_config that is recursive */
-       if ( schema_init_done )
-               return( 0 );
-       for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
-               res = register_syntax( syntax_defs[i].sd_desc,
-                   syntax_defs[i].sd_check );
-               if ( res ) {
-                       fprintf( stderr, "schema_init: Error registering syntax %s\n",
-                                syntax_defs[i].sd_desc );
-                       exit( EXIT_FAILURE );
-               }
-       }
-       for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
-               res = register_matching_rule( mrule_defs[i].mrd_desc,
-                   ( mrule_defs[i].mrd_normalize ?
-                     mrule_defs[i].mrd_normalize : case_ignore_normalize ),
-                   ( mrule_defs[i].mrd_compare ?
-                     mrule_defs[i].mrd_compare : case_ignore_compare ) );
-               if ( res ) {
-                       fprintf( stderr, "schema_init: Error registering matching rule %s\n",
-                                mrule_defs[i].mrd_desc );
-                       exit( EXIT_FAILURE );
-               }
-       }
-       schema_init_done = 1;
-       return( 0 );
-}
 
 #if defined( SLAPD_SCHEMA_DN )
 
-static int
-syn_schema_info( Entry *e )
-{
-       struct berval   val;
-       struct berval   *vals[2];
-       Syntax          *syn;
-
-       vals[0] = &val;
-       vals[1] = NULL;
-
-       for ( syn = syn_list; syn; syn = syn->ssyn_next ) {
-               val.bv_val = ldap_syntax2str( &syn->ssyn_syn );
-               if ( val.bv_val ) {
-                       val.bv_len = strlen( val.bv_val );
-                       Debug( LDAP_DEBUG_TRACE, "Merging syn [%ld] %s\n",
-                              (long) val.bv_len, val.bv_val, 0 );
-                       attr_merge( e, "ldapSyntaxes", vals );
-                       ldap_memfree( val.bv_val );
-               } else {
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-static int
-mr_schema_info( Entry *e )
-{
-       struct berval   val;
-       struct berval   *vals[2];
-       MatchingRule    *mr;
-
-       vals[0] = &val;
-       vals[1] = NULL;
-
-       for ( mr = mr_list; mr; mr = mr->smr_next ) {
-               val.bv_val = ldap_matchingrule2str( &mr->smr_mrule );
-               if ( val.bv_val ) {
-                       val.bv_len = strlen( val.bv_val );
-                       Debug( LDAP_DEBUG_TRACE, "Merging mr [%ld] %s\n",
-                              (long) val.bv_len, val.bv_val, 0 );
-                       attr_merge( e, "matchingRules", vals );
-                       ldap_memfree( val.bv_val );
-               } else {
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-static int
-oc_schema_info( Entry *e )
+int
+schema_info( Entry **entry, const char **text )
 {
-       struct berval   val;
-       struct berval   *vals[2];
-       ObjectClass     *oc;
-
-       vals[0] = &val;
-       vals[1] = NULL;
+       AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass;
 
-       for ( oc = oc_list; oc; oc = oc->soc_next ) {
-               val.bv_val = ldap_objectclass2str( &oc->soc_oclass );
-               if ( val.bv_val ) {
-                       val.bv_len = strlen( val.bv_val );
-                       Debug( LDAP_DEBUG_TRACE, "Merging oc [%ld] %s\n",
-                              (long) val.bv_len, val.bv_val, 0 );
-                       attr_merge( e, "objectClasses", vals );
-                       ldap_memfree( val.bv_val );
-               } else {
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-void
-schema_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
-{
        Entry           *e;
        struct berval   val;
        struct berval   *vals[2];
@@ -1143,124 +36,66 @@ schema_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
        e->e_attrs = NULL;
        e->e_dn = ch_strdup( SLAPD_SCHEMA_DN );
        e->e_ndn = ch_strdup( SLAPD_SCHEMA_DN );
-       (void) dn_normalize_case( e->e_ndn );
+       (void) dn_normalize( e->e_ndn );
        e->e_private = NULL;
 
-       {
-               char *rdn = ch_strdup( SLAPD_SCHEMA_DN );
-               val.bv_val = strchr( rdn, '=' );
-
-               if( val.bv_val != NULL ) {
-                       *val.bv_val = '\0';
-                       val.bv_len = strlen( ++val.bv_val );
-
-                       attr_merge( e, rdn, vals );
-               }
-
-               free( rdn );
-       }
-
-       if ( syn_schema_info( e ) ) {
-               /* Out of memory, do something about it */
-               entry_free( e );
-               return;
-       }
-       if ( mr_schema_info( e ) ) {
-               /* Out of memory, do something about it */
-               entry_free( e );
-               return;
-       }
-       if ( at_schema_info( e ) ) {
-               /* Out of memory, do something about it */
-               entry_free( e );
-               return;
-       }
-       if ( oc_schema_info( e ) ) {
-               /* Out of memory, do something about it */
-               entry_free( e );
-               return;
-       }
-       
        val.bv_val = "top";
        val.bv_len = sizeof("top")-1;
-       attr_merge( e, "objectClass", vals );
+       attr_merge( e, ad_objectClass, vals );
 
        val.bv_val = "LDAPsubentry";
        val.bv_len = sizeof("LDAPsubentry")-1;
-       attr_merge( e, "objectClass", vals );
+       attr_merge( e, ad_objectClass, vals );
 
        val.bv_val = "subschema";
        val.bv_len = sizeof("subschema")-1;
-       attr_merge( e, "objectClass", vals );
+       attr_merge( e, ad_objectClass, vals );
 
        val.bv_val = "extensibleObject";
        val.bv_len = sizeof("extensibleObject")-1;
-       attr_merge( e, "objectClass", vals );
-
-       send_search_entry( &backends[0], conn, op,
-               e, attrs, attrsonly, NULL );
-       send_search_result( conn, op, LDAP_SUCCESS,
-               NULL, NULL, NULL, NULL, 1 );
-
-       entry_free( e );
-}
-#endif
-
-#ifdef LDAP_DEBUG
-
-static void
-oc_print( ObjectClass *oc )
-{
-       int     i;
-       const char *mid;
+       attr_merge( e, ad_objectClass, vals );
 
-       printf( "objectclass %s\n", ldap_objectclass2name( &oc->soc_oclass ) );
-       if ( oc->soc_required != NULL ) {
-               mid = "\trequires ";
-               for ( i = 0; oc->soc_required[i] != NULL; i++, mid = "," )
-                       printf( "%s%s", mid,
-                               ldap_attributetype2name( &oc->soc_required[i]->sat_atype ) );
-               printf( "\n" );
-       }
-       if ( oc->soc_allowed != NULL ) {
-               mid = "\tallows ";
-               for ( i = 0; oc->soc_allowed[i] != NULL; i++, mid = "," )
-                       printf( "%s%s", mid,
-                               ldap_attributetype2name( &oc->soc_allowed[i]->sat_atype ) );
-               printf( "\n" );
-       }
-}
-
-#endif
+       {
+               int rc;
+               AttributeDescription *desc = NULL;
+               char *rdn = ch_strdup( SLAPD_SCHEMA_DN );
+               val.bv_val = strchr( rdn, '=' );
 
+               if( val.bv_val == NULL ) {
+                       free( rdn );
+                       *text = "improperly configured subschema subentry";
+                       return LDAP_OTHER;
+               }
 
-int is_entry_objectclass(
-       Entry*  e,
-       const char*     oc)
-{
-       Attribute *attr;
-       struct berval bv;
+               *val.bv_val = '\0';
+               val.bv_len = strlen( ++val.bv_val );
 
-       if( e == NULL || oc == NULL || *oc == '\0' )
-               return 0;
+               rc = slap_str2ad( rdn, &desc, text );
 
-       /*
-        * find objectClass attribute
-        */
-       attr = attr_find(e->e_attrs, "objectclass");
+               if( rc != LDAP_SUCCESS ) {
+                       free( rdn );
+                       entry_free( e );
+                       *text = "improperly configured subschema subentry";
+                       return LDAP_OTHER;
+               }
 
-       if( attr == NULL ) {
-               /* no objectClass attribute */
-               return 0;
+               attr_merge( e, desc, vals );
+               free( rdn );
        }
 
-       bv.bv_val = (char *) oc;
-       bv.bv_len = strlen( bv.bv_val );
-
-       if( value_find(attr->a_vals, &bv, attr->a_syntax, 1) != 0) {
-               /* entry is not of this objectclass */
-               return 0;
+       if ( syn_schema_info( e ) 
+               || mr_schema_info( e )
+               || at_schema_info( e )
+               || oc_schema_info( e ) )
+       {
+               /* Out of memory, do something about it */
+               entry_free( e );
+               *text = "out of memory";
+               return LDAP_OTHER;
        }
-
-       return 1;
+       
+       *entry = e;
+       return LDAP_SUCCESS;
 }
+#endif
+
index 37cccba5820683910a4ef62a09dc8ff4c0f6c673..bbf2dd593fa626e2fa69388112c5c9cc3153c8fa 100644 (file)
 #
 # OpenLDAP Core schema
 #
-# Includes "standard" schema items from:
+# Includes LDAPv3 schema items from:
 #      RFC2251-RFC2256 (LDAPv3)
+#
+# select standard track schema items:
 #      RFC2079 (URI)
+#      RFC1274 (uid/dc)
+#      RFC2247 (dc/dcObject)
+#      RFC2289 (Dynamic Directory Services)
+#
+# select informational schema items:
+#      RFC2377 (uidObject)
 #
+# select experimental IETF LDAPext items
+#   ldapSubentry draft
+#      ldapRootDSE
+#      named referrals draft
+#      alias draft
+
 
 # Standard X.501(93) Operational Attribute Types from RFC2252
 
-attribute ( 2.5.18.1 NAME 'createTimestamp' EQUALITY generalizedTimeMatch
+attributetype ( 2.5.18.1 NAME 'createTimestamp' EQUALITY generalizedTimeMatch
       ORDERING generalizedTimeOrderingMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
       SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )
 
-attribute ( 2.5.18.2 NAME 'modifyTimestamp' EQUALITY generalizedTimeMatch
+attributetype ( 2.5.18.2 NAME 'modifyTimestamp' EQUALITY generalizedTimeMatch
       ORDERING generalizedTimeOrderingMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
       SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )
 
-attribute ( 2.5.18.3 NAME 'creatorsName' EQUALITY distinguishedNameMatch
+attributetype ( 2.5.18.3 NAME 'creatorsName' EQUALITY distinguishedNameMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
       SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )
 
-attribute ( 2.5.18.4 NAME 'modifiersName' EQUALITY distinguishedNameMatch
+attributetype ( 2.5.18.4 NAME 'modifiersName' EQUALITY distinguishedNameMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
       SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )
 
-attribute ( 2.5.18.10 NAME 'subschemaSubentry'
+attributetype ( 2.5.18.10 NAME 'subschemaSubentry'
       EQUALITY distinguishedNameMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 NO-USER-MODIFICATION
       SINGLE-VALUE USAGE directoryOperation )
 
-attribute ( 2.5.21.5 NAME 'attributeTypes'
+attributetype ( 2.5.21.5 NAME 'attributeTypes'
       EQUALITY objectIdentifierFirstComponentMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.3 USAGE directoryOperation )
 
-attribute ( 2.5.21.6 NAME 'objectClasses'
+attributetype ( 2.5.21.6 NAME 'objectClasses'
       EQUALITY objectIdentifierFirstComponentMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.37 USAGE directoryOperation )
 
-attribute ( 2.5.21.4 NAME 'matchingRules'
+attributetype ( 2.5.21.4 NAME 'matchingRules'
       EQUALITY objectIdentifierFirstComponentMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.30 USAGE directoryOperation )
 
-attribute ( 2.5.21.8 NAME 'matchingRuleUse'
+attributetype ( 2.5.21.8 NAME 'matchingRuleUse'
       EQUALITY objectIdentifierFirstComponentMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.31 USAGE directoryOperation )
 
 # LDAP Operational Attributes from RFC2252
 
-attribute ( 1.3.6.1.4.1.1466.101.120.5 NAME 'namingContexts'
+attributetype ( 1.3.6.1.4.1.1466.101.120.5 NAME 'namingContexts'
      SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE dSAOperation )
 
-attribute ( 1.3.6.1.4.1.1466.101.120.6 NAME 'altServer'
+attributetype ( 1.3.6.1.4.1.1466.101.120.6 NAME 'altServer'
      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 USAGE dSAOperation )
 
-attribute ( 1.3.6.1.4.1.1466.101.120.7 NAME 'supportedExtension'
+attributetype ( 1.3.6.1.4.1.1466.101.120.7 NAME 'supportedExtension'
      SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation )
 
-attribute ( 1.3.6.1.4.1.1466.101.120.13 NAME 'supportedControl'
+attributetype ( 1.3.6.1.4.1.1466.101.120.13 NAME 'supportedControl'
      SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation )
 
-attribute ( 1.3.6.1.4.1.1466.101.120.14 NAME 'supportedSASLMechanisms'
+attributetype ( 1.3.6.1.4.1.1466.101.120.14 NAME 'supportedSASLMechanisms'
      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dSAOperation )
 
-attribute ( 1.3.6.1.4.1.1466.101.120.15 NAME 'supportedLDAPVersion'
+attributetype ( 1.3.6.1.4.1.1466.101.120.15 NAME 'supportedLDAPVersion'
      SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 USAGE dSAOperation )
 
 # LDAP Subschema Atrribute from RFC2252
 
-attribute ( 1.3.6.1.4.1.1466.101.120.16 NAME 'ldapSyntaxes'
+attributetype ( 1.3.6.1.4.1.1466.101.120.16 NAME 'ldapSyntaxes'
       EQUALITY objectIdentifierFirstComponentMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.54 USAGE directoryOperation )
 
 # X.500 Subschema attributes from RFC2252
 
-attribute ( 2.5.21.1 NAME 'dITStructureRules' EQUALITY integerFirstComponentMatch
+attributetype ( 2.5.21.1 NAME 'dITStructureRules' EQUALITY integerFirstComponentMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.17 USAGE directoryOperation )
 
-attribute ( 2.5.21.7 NAME 'nameForms'
+attributetype ( 2.5.21.7 NAME 'nameForms'
       EQUALITY objectIdentifierFirstComponentMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.35 USAGE directoryOperation )
 
-attribute ( 2.5.21.2 NAME 'dITContentRules'
+attributetype ( 2.5.21.2 NAME 'dITContentRules'
       EQUALITY objectIdentifierFirstComponentMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.16 USAGE directoryOperation )
 
@@ -99,121 +113,133 @@ objectclass ( 2.5.20.1 NAME 'subschema' AUXILIARY
 
 # Standard attribute types from RFC2256
 
-attribute ( 2.5.4.0 NAME 'objectClass' EQUALITY objectIdentifierMatch
+attributetype ( 2.5.4.0 NAME 'objectClass'
+      EQUALITY objectIdentifierMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )
 
-attribute ( 2.5.4.1 NAME 'aliasedObjectName' EQUALITY distinguishedNameMatch
+attributetype ( 2.5.4.1 NAME 'aliasedObjectName'
+      EQUALITY distinguishedNameMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
 
 # Defined, but no longer used
 
-attribute ( 2.5.4.2 NAME 'knowledgeInformation' EQUALITY caseIgnoreMatch
+attributetype ( 2.5.4.2 NAME 'knowledgeInformation'
+      EQUALITY caseIgnoreMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
 
 # Place here since other attribute types derive from it
 
-attribute ( 2.5.4.41 NAME 'name' EQUALITY caseIgnoreMatch
+attributetype ( 2.5.4.41 NAME 'name'
+      EQUALITY caseIgnoreMatch
       SUBSTR caseIgnoreSubstringsMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
 
-attribute ( 2.5.4.3 NAME ( 'cn' 'commonName' ) SUP name )
+attributetype ( 2.5.4.3 NAME ( 'cn' 'commonName' ) SUP name )
 
-attribute ( 2.5.4.4 NAME ( 'sn' 'surname' ) SUP name )
+attributetype ( 2.5.4.4 NAME ( 'sn' 'surname' ) SUP name )
 
-attribute ( 2.5.4.5 NAME 'serialNumber' EQUALITY caseIgnoreMatch
+attributetype ( 2.5.4.5 NAME 'serialNumber' EQUALITY caseIgnoreMatch
       SUBSTR caseIgnoreSubstringsMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{64} )
 
 # (2-letter code from ISO 3166)
 
-attribute ( 2.5.4.6 NAME ( 'c' 'countryName' ) SUP name SINGLE-VALUE )
+attributetype ( 2.5.4.6 NAME ( 'c' 'countryName' ) SUP name SINGLE-VALUE )
 
-attribute ( 2.5.4.7 NAME ( 'l' 'localityName' ) SUP name )
+attributetype ( 2.5.4.7 NAME ( 'l' 'localityName' ) SUP name )
 
-attribute ( 2.5.4.8 NAME ( 'st' 'stateOrProvinceName' ) SUP name )
+attributetype ( 2.5.4.8 NAME ( 'st' 'stateOrProvinceName' ) SUP name )
 
-attribute ( 2.5.4.9 NAME ( 'street' 'streetAddress' ) EQUALITY caseIgnoreMatch
+attributetype ( 2.5.4.9 NAME ( 'street' 'streetAddress' )
+      EQUALITY caseIgnoreMatch
       SUBSTR caseIgnoreSubstringsMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
 
-attribute ( 2.5.4.10 NAME ( 'o' 'organizationName' ) SUP name )
+attributetype ( 2.5.4.10 NAME ( 'o' 'organizationName' ) SUP name )
 
-attribute ( 2.5.4.11 NAME ( 'ou' 'organizationalUnitName' ) SUP name )
+attributetype ( 2.5.4.11 NAME ( 'ou' 'organizationalUnitName' ) SUP name )
 
-attribute ( 2.5.4.12 NAME 'title' SUP name )
+attributetype ( 2.5.4.12 NAME 'title' SUP name )
 
-attribute ( 2.5.4.13 NAME 'description' EQUALITY caseIgnoreMatch
+attributetype ( 2.5.4.13 NAME 'description'
+      EQUALITY caseIgnoreMatch
       SUBSTR caseIgnoreSubstringsMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024} )
 
 # Obsoleted by enhancedSearchGuide
 
-attribute ( 2.5.4.14 NAME 'searchGuide'
+attributetype ( 2.5.4.14 NAME 'searchGuide'
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.25 )
 
-attribute ( 2.5.4.15 NAME 'businessCategory' EQUALITY caseIgnoreMatch
+attributetype ( 2.5.4.15 NAME 'businessCategory'
+     EQUALITY caseIgnoreMatch
      SUBSTR caseIgnoreSubstringsMatch
      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
 
-# Show stopper: we don't have the definition of caseIgnoreListSubstringsMatch
-#attribute ( 2.5.4.16 NAME 'postalAddress' EQUALITY caseIgnoreListMatch
-#     SUBSTR caseIgnoreListSubstringsMatch
-#     SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )
-attribute ( 2.5.4.16 NAME 'postalAddress' EQUALITY caseIgnoreListMatch
+attribute ( 2.5.4.16 NAME 'postalAddress'
+     EQUALITY caseIgnoreListMatch
+     SUBSTR caseIgnoreListSubstringsMatch
      SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )
 
-attribute ( 2.5.4.17 NAME 'postalCode' EQUALITY caseIgnoreMatch
+attributetype ( 2.5.4.17 NAME 'postalCode'
+     EQUALITY caseIgnoreMatch
      SUBSTR caseIgnoreSubstringsMatch
      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{40} )
 
-attribute ( 2.5.4.18 NAME 'postOfficeBox' EQUALITY caseIgnoreMatch
+attributetype ( 2.5.4.18 NAME 'postOfficeBox'
+     EQUALITY caseIgnoreMatch
      SUBSTR caseIgnoreSubstringsMatch
      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{40} )
 
-attribute ( 2.5.4.19 NAME 'physicalDeliveryOfficeName' EQUALITY caseIgnoreMatch
+attributetype ( 2.5.4.19 NAME 'physicalDeliveryOfficeName'
+     EQUALITY caseIgnoreMatch
      SUBSTR caseIgnoreSubstringsMatch
      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
 
-attribute ( 2.5.4.20 NAME 'telephoneNumber' EQUALITY telephoneNumberMatch
+attributetype ( 2.5.4.20 NAME 'telephoneNumber'
+     EQUALITY telephoneNumberMatch
      SUBSTR telephoneNumberSubstringsMatch
      SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{32} )
 
-attribute ( 2.5.4.21 NAME 'telexNumber'
+attributetype ( 2.5.4.21 NAME 'telexNumber'
      SYNTAX 1.3.6.1.4.1.1466.115.121.1.52 )
 
-attribute ( 2.5.4.22 NAME 'teletexTerminalIdentifier'
+attributetype ( 2.5.4.22 NAME 'teletexTerminalIdentifier'
      SYNTAX 1.3.6.1.4.1.1466.115.121.1.51 )
 
-attribute ( 2.5.4.23 NAME ( 'facsimileTelephoneNumber' 'fax' )
+attributetype ( 2.5.4.23 NAME ( 'facsimileTelephoneNumber' 'fax' )
      SYNTAX 1.3.6.1.4.1.1466.115.121.1.22 )
 
-attribute ( 2.5.4.24 NAME 'x121Address' EQUALITY numericStringMatch
+attributetype ( 2.5.4.24 NAME 'x121Address'
+     EQUALITY numericStringMatch
      SUBSTR numericStringSubstringsMatch
      SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{15} )
 
-attribute ( 2.5.4.25 NAME 'internationaliSDNNumber' EQUALITY numericStringMatch
+attributetype ( 2.5.4.25 NAME 'internationaliSDNNumber'
+     EQUALITY numericStringMatch
      SUBSTR numericStringSubstringsMatch
      SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{16} )
 
-attribute ( 2.5.4.26 NAME 'registeredAddress' SUP postalAddress
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )
+attributetype ( 2.5.4.26 NAME 'registeredAddress' SUP postalAddress
+     SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )
 
-attribute ( 2.5.4.27 NAME 'destinationIndicator' EQUALITY caseIgnoreMatch
-      SUBSTR caseIgnoreSubstringsMatch
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{128} )
+attributetype ( 2.5.4.27 NAME 'destinationIndicator'
+     EQUALITY caseIgnoreMatch
+     SUBSTR caseIgnoreSubstringsMatch
+     SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{128} )
 
-attribute ( 2.5.4.28 NAME 'preferredDeliveryMethod'
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.14
-      SINGLE-VALUE )
+attributetype ( 2.5.4.28 NAME 'preferredDeliveryMethod'
+     SYNTAX 1.3.6.1.4.1.1466.115.121.1.14
+     SINGLE-VALUE )
 
-attribute ( 2.5.4.29 NAME 'presentationAddress'
-      EQUALITY presentationAddressMatch
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.43
-      SINGLE-VALUE )
+attributetype ( 2.5.4.29 NAME 'presentationAddress'
+     EQUALITY presentationAddressMatch
+     SYNTAX 1.3.6.1.4.1.1466.115.121.1.43
+     SINGLE-VALUE )
 
-attribute ( 2.5.4.30 NAME 'supportedApplicationContext'
-      EQUALITY objectIdentifierMatch
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )
+attributetype ( 2.5.4.30 NAME 'supportedApplicationContext'
+     EQUALITY objectIdentifierMatch
+     SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )
 
 # Placed here because others derive from it.
 
@@ -223,105 +249,112 @@ attribute ( 2.5.4.30 NAME 'supportedApplicationContext'
 # distinguished name of an entry.  On the other hand, the attribute
 # type distinguishedName is meant to be an "abstract" type and other
 # dn-valued attribute types derive from it.  So at most, 'dn' would
-# be a subtype of distinguishedName.
+# be a subtype of distinguishedName, something like:
+#      attributetype ( dnOID NAME 'dn' SUP distinguishedName
+#              SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )
 
-attribute ( 2.5.4.49 NAME 'distinguishedName'
+attributetype ( 2.5.4.49 NAME 'distinguishedName'
       EQUALITY distinguishedNameMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
 
-attribute ( 2.5.4.31 NAME 'member' SUP distinguishedName )
+attributetype ( 2.5.4.31 NAME 'member' SUP distinguishedName )
 
-attribute ( 2.5.4.32 NAME 'owner' SUP distinguishedName )
+attributetype ( 2.5.4.32 NAME 'owner' SUP distinguishedName )
 
-attribute ( 2.5.4.33 NAME 'roleOccupant' SUP distinguishedName )
+attributetype ( 2.5.4.33 NAME 'roleOccupant' SUP distinguishedName )
 
-attribute ( 2.5.4.34 NAME 'seeAlso' SUP distinguishedName )
+attributetype ( 2.5.4.34 NAME 'seeAlso' SUP distinguishedName )
 
-attribute ( 2.5.4.35 NAME 'userPassword' EQUALITY octetStringMatch
+attributetype ( 2.5.4.35 NAME 'userPassword'
+      EQUALITY octetStringMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} )
 
 # Must be stored and requested in the binary form, as
 # userCertificate;binary
-
-attribute ( 2.5.4.36 NAME 'userCertificate'
+attributetype ( 2.5.4.36 NAME 'userCertificate'
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 )
 
 # As above
-
-attribute ( 2.5.4.37 NAME 'cACertificate'
+attributetype ( 2.5.4.37 NAME 'cACertificate'
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 )
 
 # As above
-
-attribute ( 2.5.4.38 NAME 'authorityRevocationList'
+attributetype ( 2.5.4.38 NAME 'authorityRevocationList'
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 )
 
 # As above
-
-attribute ( 2.5.4.39 NAME 'certificateRevocationList'
+attributetype ( 2.5.4.39 NAME 'certificateRevocationList'
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 )
 
 # As above
-
-attribute ( 2.5.4.40 NAME 'crossCertificatePair'
+attributetype ( 2.5.4.40 NAME 'crossCertificatePair'
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.10 )
 
 # 2.5.4.41 is 'name', moved above since other attribute types derive from it
 
-attribute ( 2.5.4.42 NAME 'givenName' SUP name )
+attributetype ( 2.5.4.42 NAME ( 'givenName' 'gn' ) SUP name )
 
-attribute ( 2.5.4.43 NAME 'initials' SUP name )
+attributetype ( 2.5.4.43 NAME 'initials' SUP name )
 
-attribute ( 2.5.4.45 NAME 'x500UniqueIdentifier' EQUALITY bitStringMatch
+attributetype ( 2.5.4.45 NAME 'x500UniqueIdentifier'
+      EQUALITY bitStringMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )
 
-attribute ( 2.5.4.46 NAME 'dnQualifier' EQUALITY caseIgnoreMatch
-      ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch
+attributetype ( 2.5.4.46 NAME 'dnQualifier'
+      EQUALITY caseIgnoreMatch
+      ORDERING caseIgnoreOrderingMatch
+      SUBSTR caseIgnoreSubstringsMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )
 
-attribute ( 2.5.4.47 NAME 'enhancedSearchGuide'
+attributetype ( 2.5.4.47 NAME 'enhancedSearchGuide'
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.21 )
 
-attribute ( 2.5.4.48 NAME 'protocolInformation'
+attributetype ( 2.5.4.48 NAME 'protocolInformation'
       EQUALITY protocolInformationMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )
 
 # 2.5.4.49 is distinguishedName, moved up
 
-attribute ( 2.5.4.50 NAME 'uniqueMember' EQUALITY uniqueMemberMatch
+attributetype ( 2.5.4.50 NAME 'uniqueMember'
+      EQUALITY uniqueMemberMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )
 
-attribute ( 2.5.4.51 NAME 'houseIdentifier' EQUALITY caseIgnoreMatch
+attributetype ( 2.5.4.51 NAME 'houseIdentifier'
+      EQUALITY caseIgnoreMatch
       SUBSTR caseIgnoreSubstringsMatch
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
 
 # This attribute is to be stored and requested in the binary form, as
 # 'supportedAlgorithms;binary'.
 
-attribute ( 2.5.4.52 NAME 'supportedAlgorithms'
+attributetype ( 2.5.4.52 NAME 'supportedAlgorithms'
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.49 )
 
 # This attribute is to be stored and requested in the binary form, as
 # 'deltaRevocationList;binary'.
 
-attribute ( 2.5.4.53 NAME 'deltaRevocationList'
+attributetype ( 2.5.4.53 NAME 'deltaRevocationList'
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 )
 
-attribute ( 2.5.4.54 NAME 'dmdName' SUP name )
+attributetype ( 2.5.4.54 NAME 'dmdName' SUP name )
 
 # Standard object classes from RFC2256
 
-objectclass ( 2.5.6.0 NAME 'top' ABSTRACT MUST objectClass )
+objectclass ( 2.5.6.0 NAME 'top' ABSTRACT
+     MUST objectClass )
 
-objectclass ( 2.5.6.1 NAME 'alias' SUP top STRUCTURAL MUST aliasedObjectName )
+objectclass ( 2.5.6.1 NAME 'alias' SUP top STRUCTURAL
+     MUST aliasedObjectName )
 
-objectclass ( 2.5.6.2 NAME 'country' SUP top STRUCTURAL MUST c
+objectclass ( 2.5.6.2 NAME 'country' SUP top STRUCTURAL
+     MUST c
      MAY ( searchGuide $ description ) )
 
 objectclass ( 2.5.6.3 NAME 'locality' SUP top STRUCTURAL
      MAY ( street $ seeAlso $ searchGuide $ st $ l $ description ) )
 
-objectclass ( 2.5.6.4 NAME 'organization' SUP top STRUCTURAL MUST o
+objectclass ( 2.5.6.4 NAME 'organization' SUP top STRUCTURAL
+     MUST o
      MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $
      x121Address $ registeredAddress $ destinationIndicator $
      preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
@@ -330,7 +363,8 @@ objectclass ( 2.5.6.4 NAME 'organization' SUP top STRUCTURAL MUST o
      street $ postOfficeBox $ postalCode $ postalAddress $
      physicalDeliveryOfficeName $ st $ l $ description ) )
 
-objectclass ( 2.5.6.5 NAME 'organizationalUnit' SUP top STRUCTURAL MUST ou
+objectclass ( 2.5.6.5 NAME 'organizationalUnit' SUP top STRUCTURAL
+     MUST ou
      MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $
      x121Address $ registeredAddress $ destinationIndicator $
      preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
@@ -339,7 +373,8 @@ objectclass ( 2.5.6.5 NAME 'organizationalUnit' SUP top STRUCTURAL MUST ou
      street $ postOfficeBox $ postalCode $ postalAddress $
      physicalDeliveryOfficeName $ st $ l $ description ) )
 
-objectclass ( 2.5.6.6 NAME 'person' SUP top STRUCTURAL MUST ( sn $ cn )
+objectclass ( 2.5.6.6 NAME 'person' SUP top STRUCTURAL
+     MUST ( sn $ cn )
      MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) )
 
 objectclass ( 2.5.6.7 NAME 'organizationalPerson' SUP person STRUCTURAL
@@ -353,7 +388,8 @@ objectclass ( 2.5.6.7 NAME 'organizationalPerson' SUP person STRUCTURAL
 
 # Notice that preferredDeliveryMethod is duplicate
 
-objectclass ( 2.5.6.8 NAME 'organizationalRole' SUP top STRUCTURAL MUST cn
+objectclass ( 2.5.6.8 NAME 'organizationalRole' SUP top STRUCTURAL
+     MUST cn
      MAY ( x121Address $ registeredAddress $ destinationIndicator $
      preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
      telephoneNumber $ internationaliSDNNumber $
@@ -362,15 +398,17 @@ objectclass ( 2.5.6.8 NAME 'organizationalRole' SUP top STRUCTURAL MUST cn
      postOfficeBox $ postalCode $ postalAddress $
      physicalDeliveryOfficeName $ ou $ st $ l $ description ) )
 
-objectclass ( 2.5.6.9 NAME 'groupOfNames' SUP top STRUCTURAL MUST ( member $ cn )
+objectclass ( 2.5.6.9 NAME 'groupOfNames' SUP top STRUCTURAL
+     MUST ( member $ cn )
      MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description ) )
 
 # Notice that preferredDeliveryMethod is duplicate
-# It seems they could not agree on wheter telephoneNumber is MAY
+# It seems they could not agree on whether telephoneNumber is MAY
 # in person.  Probably it wasn't originally at was added as an
 # afterthought
 
-objectclass ( 2.5.6.10 NAME 'residentialPerson' SUP person STRUCTURAL MUST l
+objectclass ( 2.5.6.10 NAME 'residentialPerson' SUP person STRUCTURAL
+     MUST l
      MAY ( businessCategory $ x121Address $ registeredAddress $
      destinationIndicator $ preferredDeliveryMethod $ telexNumber $
      teletexTerminalIdentifier $ telephoneNumber $
@@ -379,7 +417,8 @@ objectclass ( 2.5.6.10 NAME 'residentialPerson' SUP person STRUCTURAL MUST l
      postOfficeBox $ postalCode $ postalAddress $
      physicalDeliveryOfficeName $ st $ l ) )
 
-objectclass ( 2.5.6.11 NAME 'applicationProcess' SUP top STRUCTURAL MUST cn
+objectclass ( 2.5.6.11 NAME 'applicationProcess' SUP top STRUCTURAL
+     MUST cn
      MAY ( seeAlso $ ou $ l $ description ) )
 
 objectclass ( 2.5.6.12 NAME 'applicationEntity' SUP top STRUCTURAL
@@ -394,7 +433,8 @@ objectclass ( 2.5.6.12 NAME 'applicationEntity' SUP top STRUCTURAL
 objectclass ( 2.5.6.13 NAME 'dSA' SUP applicationEntity STRUCTURAL
      MAY knowledgeInformation )
 
-objectclass ( 2.5.6.14 NAME 'device' SUP top STRUCTURAL MUST cn
+objectclass ( 2.5.6.14 NAME 'device' SUP top STRUCTURAL
+     MUST cn
      MAY ( serialNumber $ seeAlso $ owner $ ou $ o $ l $ description ) )
 
 objectclass ( 2.5.6.15 NAME 'strongAuthenticationUser' SUP top AUXILIARY
@@ -424,13 +464,14 @@ objectclass ( 2.5.6.16.2 NAME 'certificationAuthority-V2' SUP
 # New
 
 objectclass ( 2.5.6.19 NAME 'cRLDistributionPoint' SUP top STRUCTURAL
-     MUST ( cn ) MAY ( certificateRevocationList $
-     authorityRevocationList $
+     MUST ( cn )
+     MAY ( certificateRevocationList $ authorityRevocationList $
      deltaRevocationList ) )
 
 # New
 
-objectclass ( 2.5.6.20 NAME 'dmd' SUP top STRUCTURAL MUST ( dmdName )
+objectclass ( 2.5.6.20 NAME 'dmd' SUP top STRUCTURAL
+     MUST ( dmdName )
      MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $
      x121Address $ registeredAddress $ destinationIndicator $
      preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
@@ -442,34 +483,161 @@ objectclass ( 2.5.6.20 NAME 'dmd' SUP top STRUCTURAL MUST ( dmdName )
 # Next objectclass is defined in RFC2252, but has to be put after top
 
 objectclass ( 1.3.6.1.4.1.1466.101.120.111 NAME 'extensibleObject'
-      SUP top AUXILIARY )
+       DESC 'RFC2252 extensible object'
+       SUP top AUXILIARY )
 
 #
 # Standard Track URI label schema from RFC2079
 #
-attribute ( 1.3.6.1.4.1.250.1.57 NAME 'labeledURI'
+attributetype ( 1.3.6.1.4.1.250.1.57 NAME 'labeledURI'
        DESC 'Uniform Resource Identifier with optional label'
-       EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
 
 objectclass ( 1.3.6.1.4.1.250.3.15 NAME 'labeledURIObject'
        DESC 'object that contains the URI attribute type'
-       MAY ( labeledURI ) SUP top AUXILIARY )
+       MAY ( labeledURI )
+       SUP top AUXILIARY )
+
+#
+# Standard Track Dynamic Directory Services from RFC2589
+#
+objectclass ( 1.3.6.1.4.1.1466.101.119.2 NAME 'dynamicObject'
+       DESC 'RFC2589 Dynamic Object'
+       SUP top AUXILIARY )
+
+attributetype ( 1.3.6.1.4.1.1466.101.119.3 NAME 'entryTtl'
+       DESC 'RFC2589 entry time-to-live'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE
+       NO-USER-MODIFICATION USAGE dSAOperation )
+
+attributetype ( 1.3.6.1.4.1.1466.101.119.4 NAME 'dynamicSubtrees'
+       DESC 'RFC2589 dynamic subtrees'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 NO-USER-MODIFICATION
+       USAGE dSAOperation )
+
+# Derived from RFC1274, but with new "short names"
+attributetype ( 0.9.2342.19200300.100.1.1
+       NAME ( 'uid' 'userid' )
+       DESC 'RFC1274 user identifier'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+attributetype ( 0.9.2342.19200300.100.1.3 NAME ( 'mail' 'rfc822Mailbox' )
+       DESC 'rfc822 mail box'
+    EQUALITY caseIgnoreIA5Match
+    SUBSTR caseIgnoreIA5SubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+objectclass ( 0.9.2342.19200300.100.4.19 NAME 'simpleSecurityObject'
+       SUP top AUXILIARY
+       MUST userPassword )
+
+
+# RFC1274 + RFC2247
+attributetype ( 0.9.2342.19200300.100.1.25
+       NAME ( 'dc' 'domainComponent' )
+       DESC 'RFC1274/2247 domain component'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+# RFC2247
+objectclass ( 1.3.6.1.4.1.1466.344 NAME 'dcObject'
+       SUP top AUXILIARY MUST dc )
+
+
+# From RFC2377
+objectclass ( 1.3.6.1.1.3.1 NAME 'uidObject'
+       DESC 'RFC2377 uid object'
+       SUP top AUXILIARY MUST uid )
 
 #
 # From draft-ietf-ldapext-nameref-00.txt
 #      used to represent referrals in the directory
 #
-attribute ( 2.16.840.1.113730.3.1.34 NAME 'ref' DESC 'URL Reference'
+attributetype ( 2.16.840.1.113730.3.1.34 NAME 'ref'
+       DESC 'Named referral'
        EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
        USAGE distributedOperation )
 
 objectclass ( 2.16.840.1.113730.3.2.6 NAME 'referral'
-       SUP top STRUCTURAL MAY ( ref ) )
+       DESC 'Named referral object'
+       SUP top STRUCTURAL MAY ref )
 
 #
 # LDAPsubEntry
-#      OID not assigned (1.3.6.1.4.1.1466.115.121.1.??)
+#      likely to change!
+objectclass ( 2.16.840.1.113719.2.142.6.1.1 NAME 'LDAPsubEntry'
+       DESC 'LDAP Subentry'
+       SUP top STRUCTURAL MAY cn )
+
+#
+# OpenLDAProotDSE
+#      likely to change!
+objectclass ( 1.3.6.1.4.1.4203.666.3.2
+       NAME ( 'OpenLDAProotDSE' 'LDAProotDSE' )
+       DESC 'OpenLDAP Root DSE object'
+       SUP top STRUCTURAL MAY cn )
+
+
+#
+# From Cosine Pilot
+#
+attributetype ( 0.9.2342.19200300.100.1.37 NAME 'associatedDomain'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+#
+# From U-Mich
+#
+attributetype ( 1.3.6.1.4.1.250.1.32
+       NAME ( 'krbName' 'kerberosName' )
+       DESC 'Kerberos Name'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE )
+
+
+#
+# OpenLDAP specific schema items
 #
-objectclass ( NAME 'LDAPsubEntry'
-       DESC 'Limited X.501 Subentry class, named by cn'
-       SUP top STRUCTURAL MUST ( cn ) )
+attributetype ( 1.3.6.1.4.1.4203.666.1.1
+       NAME 'authPassword'
+       DESC 'OpenLDAP authPassword attribute'
+       EQUALITY authPasswordMatch
+       SYNTAX 1.3.6.1.4.1.4203.666.2.2
+       USAGE dSAOperation )
+
+attributetype ( 1.3.6.1.4.1.4203.666.1.2
+       NAME 'supportedAuthPasswordSchemes'
+       DESC 'OpenLDAP authPassword attribute'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32}
+       NO-USER-MODIFICATION USAGE dSAOperation )
+
+attributetype ( 1.3.6.1.4.1.4203.666.1.3
+       NAME 'entry'
+       DESC 'OpenLDAP ACL entry psuedo attribute'
+       SYNTAX 1.3.6.1.4.1.4203.666.2.3
+       SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation )
+
+attributetype ( 1.3.6.1.4.1.4203.666.1.4
+       NAME 'children'
+       DESC 'OpenLDAP ACL children psuedo attribute'
+       SYNTAX 1.3.6.1.4.1.4203.666.2.3
+       SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation )
+
+attributetype ( 1.3.6.1.4.1.4203.666.1.5
+       NAME 'OpenLDAPaci'
+       DESC 'OpenLDAP access control information'
+       EQUALITY OpenLDAPaciMatch
+       SYNTAX 1.3.6.1.4.1.4203.666.2.1
+       USAGE directoryOperation )
+
+objectclass ( 1.3.6.1.4.1.4203.666.3.1 NAME 'authPasswordObject'
+       DESC 'authentication password mixin class'
+       MAY authPassword
+       AUXILIARY )
diff --git a/servers/slapd/schema/cosine.schema b/servers/slapd/schema/cosine.schema
new file mode 100644 (file)
index 0000000..ff2d9f9
--- /dev/null
@@ -0,0 +1,2516 @@
+# $OpenLDAP$
+#
+# RFC1274: Cosine and Internet X.500 schema
+#
+# This file contains LDAPv3 schema derived from X.500 COSINE "pilot"
+# schema.  As this schema was defined for X.500(89), some
+# oddities were introduced in the mapping to LDAPv3.  The
+# mappings were based upon: draft-ietf-asid-ldapv3-attributes-03.txt
+# (a work in progress)
+#
+# It may be best to avoid use this schema.
+#
+# Note: It seems that the pilot schema evolved beyond what was
+# described in RFC1274.  However, this document attempts to describes
+# RFC1274 as published. 
+
+
+# Network Working Group                                          P. Barker
+# Request for Comments: 1274                                      S. Kille
+#                                              University College London
+#                                                          November 1991
+#
+#                 The COSINE and Internet X.500 Schema
+#
+# [trimmed]
+#
+# Abstract
+#
+#  This document suggests an X.500 Directory Schema, or Naming
+#  Architecture, for use in the COSINE and Internet X.500 pilots.  The
+#  schema is independent of any specific implementation.  As well as
+#  indicating support for the standard object classes and attributes, a
+#  large number of generally useful object classes and attributes are
+#  also defined.  An appendix to this document includes a machine
+#  processable version of the schema.
+#
+# [trimmed]
+
+# 7.  Object Identifiers
+#
+#  Some additional object identifiers are defined for this schema.
+#  These are also reproduced in Appendix C.
+#
+#    data OBJECT IDENTIFIER ::= {ccitt 9}
+#    pss OBJECT IDENTIFIER ::= {data 2342}
+#    ucl OBJECT IDENTIFIER ::= {pss 19200300}
+#    pilot OBJECT IDENTIFIER ::= {ucl 100}
+#
+#    pilotAttributeType OBJECT IDENTIFIER ::= {pilot 1}
+#    pilotAttributeSyntax OBJECT IDENTIFIER ::= {pilot 3}
+#    pilotObjectClass OBJECT IDENTIFIER ::= {pilot 4}
+#    pilotGroups OBJECT IDENTIFIER ::= {pilot 10}
+#
+#    iA5StringSyntax OBJECT IDENTIFIER ::= {pilotAttributeSyntax 4}
+#    caseIgnoreIA5StringSyntax OBJECT IDENTIFIER ::=
+#                                          {pilotAttributeSyntax 5}
+#
+# 8.  Object Classes
+# [relocated after 9]
+
+#
+# 9.  Attribute Types
+#
+# 9.1.  X.500 standard attribute types
+#
+#  A number of generally useful attribute types are defined in X.520,
+#  and these are supported.  Refer to that document for descriptions of
+#  the suggested usage of these attribute types.  The ASN.1 for these
+#  attribute types is reproduced for completeness in Appendix C.
+#
+# 9.2.  X.400 standard attribute types
+#
+#  The standard X.400 attribute types are supported.  See X.402 for full
+#  details.  The ASN.1 for these attribute types is reproduced in
+#  Appendix C.
+#
+# 9.3.  COSINE/Internet attribute types
+#
+#  This section describes all the attribute types defined for use in the
+#  COSINE and Internet pilots.  Descriptions are given as to the
+#  suggested usage of these attribute types.  The ASN.1 for these
+#  attribute types is reproduced in Appendix C.
+#
+# 9.3.1.  Userid
+#
+#  The Userid attribute type specifies a computer system login name.
+#
+#    userid ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-user-identifier))
+#    ::= {pilotAttributeType 1}
+#
+#(in core.schema)
+##attributetype ( 0.9.2342.19200300.100.1.1 NAME ( 'uid' 'userid' )
+##     EQUALITY caseIgnoreMatch
+##     SUBSTR caseIgnoreSubstringsMatch
+##     SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+# 9.3.2.  Text Encoded O/R Address
+#
+#  The Text Encoded O/R Address attribute type specifies a text encoding
+#  of an X.400 O/R address, as specified in RFC 987.  The use of this
+#  attribute is deprecated as the attribute is intended for interim use
+#  only.  This attribute will be the first candidate for the attribute
+#  expiry mechanisms!
+#
+#    textEncodedORAddress ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#        (SIZE (1 .. ub-text-encoded-or-address))
+#    ::= {pilotAttributeType 2}
+#
+attributetype ( 0.9.2342.19200300.100.1.2 NAME 'textEncodedORAddress'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+# 9.3.3.  RFC 822 Mailbox
+#
+#  The RFC822 Mailbox attribute type specifies an electronic mailbox
+#  attribute following the syntax specified in RFC 822.  Note that this
+#  attribute should not be used for greybook or other non-Internet order
+#  mailboxes.
+#
+#    rfc822Mailbox ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreIA5StringSyntax
+#            (SIZE (1 .. ub-rfc822-mailbox))
+#    ::= {pilotAttributeType 3}
+#
+#(in core.schema)
+##attributetype ( 0.9.2342.19200300.100.1.3 NAME ( 'mail' 'rfc822Mailbox' )
+##     EQUALITY caseIgnoreIA5Match
+##     SUBSTR caseIgnoreIA5SubstringsMatch
+##     SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+# 9.3.4.  Information
+#
+#  The Information attribute type specifies any general information
+#  pertinent to an object.  It is recommended that specific usage of
+#  this attribute type is avoided, and that specific requirements are
+#  met by other (possibly additional) attribute types.
+#
+#    info ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-information))
+#    ::= {pilotAttributeType 4}
+#
+attributetype ( 0.9.2342.19200300.100.1.4 NAME 'info'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{2048} )
+
+
+# 9.3.5.  Favourite Drink
+#
+#  The Favourite Drink attribute type specifies the favourite drink of
+#  an object (or person).
+#
+#    favouriteDrink ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-favourite-drink))
+#    ::= {pilotAttributeType 5}
+#
+attributetype ( 0.9.2342.19200300.100.1.5
+       NAME ( 'drink' 'favouriteDrink' )
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+# 9.3.6.  Room Number
+#
+#  The Room Number attribute type specifies the room number of an
+#  object.  Note that the commonName attribute should be used for naming
+#  room objects.
+#
+#    roomNumber ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-room-number))
+#    ::= {pilotAttributeType 6}
+#
+attributetype ( 0.9.2342.19200300.100.1.6 NAME 'roomNumber'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+# 9.3.7.  Photo
+#
+#  The Photo attribute type specifies a "photograph" for an object.
+#  This should be encoded in G3 fax as explained in recommendation T.4,
+#  with an ASN.1 wrapper to make it compatible with an X.400 BodyPart as
+#  defined in X.420.
+#
+#    IMPORT  G3FacsimileBodyPart  FROM  {   mhs-motis   ipms   modules
+#    information-objects }
+#
+#    photo ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            CHOICE {
+#                g3-facsimile [3] G3FacsimileBodyPart
+#                }
+#        (SIZE (1 .. ub-photo))
+#    ::= {pilotAttributeType 7}
+#
+attributetype ( 0.9.2342.19200300.100.1.7 NAME 'photo'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.23{25000} )
+
+# 9.3.8.  User Class
+#
+#  The User Class attribute type specifies a category of computer user.
+#  The semantics placed on this attribute are for local interpretation.
+#  Examples of current usage od this attribute in academia are
+#  undergraduate student, researcher, lecturer, etc.  Note that the
+#  organizationalStatus attribute may now often be preferred as it makes
+#  no distinction between computer users and others.
+#
+#    userClass ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-user-class))
+#    ::= {pilotAttributeType 8}
+#
+attributetype ( 0.9.2342.19200300.100.1.8 NAME 'userClass'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+# 9.3.9.  Host
+#
+#  The Host attribute type specifies a host computer.
+#
+#    host ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-host))
+#    ::= {pilotAttributeType 9}
+#
+attributetype ( 0.9.2342.19200300.100.1.9 NAME 'host'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+# 9.3.10.  Manager
+#
+#  The Manager attribute type specifies the manager of an object
+#  represented by an entry.
+#
+#    manager ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            distinguishedNameSyntax
+#    ::= {pilotAttributeType 10}
+#
+attributetype ( 0.9.2342.19200300.100.1.10 NAME 'manager'
+       EQUALITY distinguishedNameMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+# 9.3.11.  Document Identifier
+#
+#  The Document Identifier attribute type specifies a unique identifier
+#  for a document.
+#
+#    documentIdentifier ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-document-identifier))
+#    ::= {pilotAttributeType 11}
+#
+attributetype ( 0.9.2342.19200300.100.1.11 NAME 'documentIdentifier'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+# 9.3.12.  Document Title
+#
+#  The Document Title attribute type specifies the title of a document.
+#
+#    documentTitle ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#        (SIZE (1 .. ub-document-title))
+#    ::= {pilotAttributeType 12}
+#
+attributetype ( 0.9.2342.19200300.100.1.12 NAME 'documentTitle'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+# 9.3.13.  Document Version
+#
+#  The Document Version attribute type specifies the version number of a
+#  document.
+#
+#    documentVersion ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-document-version))
+#    ::= {pilotAttributeType 13}
+#
+attributetype ( 0.9.2342.19200300.100.1.13 NAME 'documentVersion'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+# 9.3.14.  Document Author
+#
+#  The Document Author attribute type specifies the distinguished name
+#  of the author of a document.
+#
+#    documentAuthor ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            distinguishedNameSyntax
+#    ::= {pilotAttributeType 14}
+#
+attributetype ( 0.9.2342.19200300.100.1.14 NAME 'documentAuthor'
+       EQUALITY distinguishedNameMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+# 9.3.15.  Document Location
+#
+#  The Document Location attribute type specifies the location of the
+#  document original.
+#
+#    documentLocation ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-document-location))
+#    ::= {pilotAttributeType 15}
+#
+attributetype ( 0.9.2342.19200300.100.1.15 NAME 'documentLocation'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+# 9.3.16.  Home Telephone Number
+#
+#  The Home Telephone Number attribute type specifies a home telephone
+#  number associated with a person.  Attribute values should follow the
+#  agreed format for international telephone numbers: i.e., "+44 71 123
+#  4567".
+#
+#    homeTelephoneNumber ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            telephoneNumberSyntax
+#    ::= {pilotAttributeType 20}
+#
+attributetype ( 0.9.2342.19200300.100.1.20
+       NAME ( 'homePhone' 'homeTelephoneNumber' )
+       EQUALITY telephoneNumberMatch
+       SUBSTR telephoneNumberSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )
+
+# 9.3.17.  Secretary
+#
+#  The Secretary attribute type specifies the secretary of a person.
+#  The attribute value for Secretary is a distinguished name.
+#
+#    secretary ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            distinguishedNameSyntax
+#    ::= {pilotAttributeType 21}
+#
+attributetype ( 0.9.2342.19200300.100.1.21 NAME 'secretary'
+       EQUALITY distinguishedNameMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+# 9.3.18.  Other Mailbox
+#
+#  The Other Mailbox attribute type specifies values for electronic
+#  mailbox types other than X.400 and rfc822.
+#
+#    otherMailbox ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            SEQUENCE {
+#                    mailboxType PrintableString, -- e.g. Telemail
+#                    mailbox IA5String  -- e.g. X378:Joe
+#            }
+#    ::= {pilotAttributeType 22}
+#
+attributetype ( 0.9.2342.19200300.100.1.22 NAME 'otherMailbox'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.39 )
+
+# 9.3.19.  Last Modified Time
+#
+#  The Last Modified Time attribute type specifies the last time, in UTC
+#  time, that an entry was modified.  Ideally, this attribute should be
+#  maintained by the DSA.
+#
+#    lastModifiedTime ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            uTCTimeSyntax
+#    ::= {pilotAttributeType 23}
+#
+## OBSOLETE
+attributetype ( 0.9.2342.19200300.100.1.23 NAME 'lastModifiedTime'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.53 )
+
+# 9.3.20.  Last Modified By
+#
+#  The Last Modified By attribute specifies the distinguished name of
+#  the last user to modify the associated entry.  Ideally, this
+#  attribute should be maintained by the DSA.
+#
+#    lastModifiedBy ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            distinguishedNameSyntax
+#    ::= {pilotAttributeType 24}
+#
+
+## OBSOLETE
+attributetype ( 0.9.2342.19200300.100.1.24 NAME 'lastModifiedBy'
+       EQUALITY distinguishedNameMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+# 9.3.21.  Domain Component
+#
+#  The Domain Component attribute type specifies a DNS/NRS domain.  For
+#  example, "uk" or "ac".
+#
+#    domainComponent ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreIA5StringSyntax
+#            SINGLE VALUE
+#    ::= {pilotAttributeType 25}
+#
+##(in core.schema)
+##attributetype ( 0.9.2342.19200300.100.1.25 NAME ( 'dc' 'domainComponent' )
+##     EQUALITY caseIgnoreIA5Match
+##     SUBSTR caseIgnoreIA5SubstringsMatch
+##     SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+# 9.3.22.  DNS ARecord
+#
+#  The A Record attribute type specifies a type A (Address) DNS resource
+#  record [6] [7].
+#
+#    aRecord ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            DNSRecordSyntax
+#    ::= {pilotAttributeType 26}
+#
+## incorrect syntax?
+attributetype ( 0.9.2342.19200300.100.1.26 NAME 'aRecord'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+## missing from RFC1274
+## incorrect syntax?
+attributetype ( 0.9.2342.19200300.100.1.27 NAME 'mDRecord'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+# 9.3.23.  MX Record
+#
+#  The MX Record attribute type specifies a type MX (Mail Exchange) DNS
+#  resource record [6] [7].
+#
+#    mXRecord ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            DNSRecordSyntax
+#    ::= {pilotAttributeType 28}
+#
+## incorrect syntax!!
+attributetype ( 0.9.2342.19200300.100.1.28 NAME 'mXRecord'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+# 9.3.24.  NS Record
+#
+#  The NS Record attribute type specifies an NS (Name Server) DNS
+#  resource record [6] [7].
+#
+#    nSRecord ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            DNSRecordSyntax
+#    ::= {pilotAttributeType 29}
+#
+## incorrect syntax!!
+attributetype ( 0.9.2342.19200300.100.1.29 NAME 'nSRecord'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+# 9.3.25.  SOA Record
+#
+#  The SOA Record attribute type specifies a type SOA (Start of
+#  Authority) DNS resorce record [6] [7].
+#
+#    sOARecord ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            DNSRecordSyntax
+#    ::= {pilotAttributeType 30}
+#
+## incorrect syntax!!
+attributetype ( 0.9.2342.19200300.100.1.30 NAME 'sOARecord'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+# 9.3.26.  CNAME Record
+#
+#  The CNAME Record attribute type specifies a type CNAME (Canonical
+#  Name) DNS resource record [6] [7].
+#
+#    cNAMERecord ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            iA5StringSyntax
+#    ::= {pilotAttributeType 31}
+#
+## incorrect syntax!!
+attributetype ( 0.9.2342.19200300.100.1.31 NAME 'cNAMERecord'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+# 9.3.27.  Associated Domain
+#
+#  The Associated Domain attribute type specifies a DNS or NRS domain
+#  which is associated with an object in the DIT. For example, the entry
+#  in the DIT with a distinguished name "C=GB, O=University College
+#  London" would have an associated domain of "UCL.AC.UK.  Note that all
+#  domains should be represented in rfc822 order.  See [3] for more
+#  details of usage of this attribute.
+#
+#    associatedDomain ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreIA5StringSyntax
+#    ::= {pilotAttributeType 37}
+#
+#attributetype ( 0.9.2342.19200300.100.1.37 NAME 'associatedDomain'
+#      EQUALITY caseIgnoreIA5Match
+#      SUBSTR caseIgnoreIA5SubstringsMatch
+#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+# 9.3.28.  Associated Name
+#
+#  The Associated Name attribute type specifies an entry in the
+#  organisational DIT associated with a DNS/NRS domain.  See [3] for
+#  more details of usage of this attribute.
+#
+#    associatedName ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            distinguishedNameSyntax
+#    ::= {pilotAttributeType 38}
+#
+attributetype ( 0.9.2342.19200300.100.1.38 NAME 'associatedName'
+       EQUALITY distinguishedNameMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+# 9.3.29.  Home postal address
+#
+#  The Home postal address attribute type specifies a home postal
+#  address for an object.  This should be limited to up to 6 lines of 30
+#  characters each.
+#
+#    homePostalAddress ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            postalAddress
+#            MATCHES FOR EQUALITY
+#    ::= {pilotAttributeType 39}
+#
+attributetype ( 0.9.2342.19200300.100.1.39 NAME 'homePostalAddress'
+       EQUALITY caseIgnoreListMatch
+       SUBSTR caseIgnoreListSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )
+
+# 9.3.30.  Personal Title
+#
+#  The Personal Title attribute type specifies a personal title for a
+#  person. Examples of personal titles are "Ms", "Dr", "Prof" and "Rev".
+#
+#    personalTitle ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-personal-title))
+#    ::= {pilotAttributeType 40}
+#
+attributetype ( 0.9.2342.19200300.100.1.40 NAME 'personalTitle'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+# 9.3.31.  Mobile Telephone Number
+#
+#  The Mobile Telephone Number attribute type specifies a mobile
+#  telephone number associated with a person.  Attribute values should
+#  follow the agreed format for international telephone numbers: i.e.,
+#  "+44 71 123 4567".
+#
+#    mobileTelephoneNumber ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            telephoneNumberSyntax
+#    ::= {pilotAttributeType 41}
+#
+attributetype ( 0.9.2342.19200300.100.1.41
+       NAME ( 'mobile' 'mobileTelephoneNumber' )
+       EQUALITY telephoneNumberMatch
+       SUBSTR telephoneNumberSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )
+
+# 9.3.32.  Pager Telephone Number
+#
+#  The Pager Telephone Number attribute type specifies a pager telephone
+#  number for an object. Attribute values should follow the agreed
+#  format for international telephone numbers: i.e., "+44 71 123 4567".
+#
+#    pagerTelephoneNumber ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            telephoneNumberSyntax
+#    ::= {pilotAttributeType 42}
+#
+attributetype ( 0.9.2342.19200300.100.1.42
+       NAME ( 'pager' 'pagerTelephoneNumber' )
+       EQUALITY telephoneNumberMatch
+       SUBSTR telephoneNumberSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )
+
+# 9.3.33.  Friendly Country Name
+#
+#  The Friendly Country Name attribute type specifies names of countries
+#  in human readable format.  The standard attribute country name must
+#  be one of the two-letter codes defined in ISO 3166.
+#
+#    friendlyCountryName ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#    ::= {pilotAttributeType 43}
+#
+attributetype ( 0.9.2342.19200300.100.1.43
+       NAME ( 'co' 'friendlyCountryName' )
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+# 9.3.34.  Unique Identifier
+#
+#  The Unique Identifier attribute type specifies a "unique identifier"
+#  for an object represented in the Directory.  The domain within which
+#  the identifier is unique, and the exact semantics of the identifier,
+#  are for local definition.  For a person, this might be an
+#  institution-wide payroll number.  For an organisational unit, it
+#  might be a department code.
+#
+#    uniqueIdentifier ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-unique-identifier))
+#    ::= {pilotAttributeType 44}
+#
+attributetype ( 0.9.2342.19200300.100.1.44 NAME 'uniqueIdentifier'
+       EQUALITY caseIgnoreMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+# 9.3.35.  Organisational Status
+#
+#  The Organisational Status attribute type specifies a category by
+#  which a person is often referred to in an organisation.  Examples of
+#  usage in academia might include undergraduate student, researcher,
+#  lecturer, etc.
+#
+#  A Directory administrator should probably consider carefully the
+#  distinctions between this and the title and userClass attributes.
+#
+#    organizationalStatus ATTRIBUTE
+#            WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-organizational-status))
+#    ::= {pilotAttributeType 45}
+#
+attributetype ( 0.9.2342.19200300.100.1.45 NAME 'organizationalStatus'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+# 9.3.36.  Janet Mailbox
+#
+#  The Janet Mailbox attribute type specifies an electronic mailbox
+#  attribute following the syntax specified in the Grey Book of the
+#  Coloured Book series.  This attribute is intended for the convenience
+#  of U.K users unfamiliar with rfc822 and little-endian mail addresses.
+#  Entries using this attribute MUST also include an rfc822Mailbox
+#  attribute.
+#
+#    janetMailbox ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreIA5StringSyntax
+#            (SIZE (1 .. ub-janet-mailbox))
+#    ::= {pilotAttributeType 46}
+#
+attributetype ( 0.9.2342.19200300.100.1.46 NAME 'janetMailbox'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+# 9.3.37.  Mail Preference Option
+#
+#  An attribute to allow users to indicate a preference for inclusion of
+#  their names on mailing lists (electronic or physical).  The absence
+#  of such an attribute should be interpreted as if the attribute was
+#  present with value "no-list-inclusion".  This attribute should be
+#  interpreted by anyone using the directory to derive mailing lists,
+#  and its value respected.
+#
+#    mailPreferenceOption ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX ENUMERATED {
+#                no-list-inclusion(0),
+#                any-list-inclusion(1),  -- may be added to any lists
+#                professional-list-inclusion(2)
+#                                        -- may be added to lists
+#                                        -- which the list provider
+#                                        -- views as related to the
+#                                        -- users professional inter-
+#                                        -- ests, perhaps evaluated
+#                                        -- from the business of the
+#                                        -- organisation or keywords
+#                                        -- in the entry.
+#                }
+#    ::= {pilotAttributeType 47}
+#
+attributetype ( 0.9.2342.19200300.100.1.47
+       NAME 'mailPreferenceOption'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
+
+# 9.3.38.  Building Name
+#
+#  The Building Name attribute type specifies the name of the building
+#  where an organisation or organisational unit is based.
+#
+#    buildingName ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-building-name))
+#    ::= {pilotAttributeType 48}
+#
+attributetype ( 0.9.2342.19200300.100.1.48 NAME 'buildingName'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+# 9.3.39.  DSA Quality
+#
+#  The DSA Quality attribute type specifies the purported quality of a
+#  DSA.  It allows a DSA manager to indicate the expected level of
+#  availability of the DSA. See [8] for details of the syntax.
+#
+#    dSAQuality ATTRIBUTE
+#            WITH ATTRIBUTE-SYNTAX DSAQualitySyntax
+#            SINGLE VALUE
+#    ::= {pilotAttributeType 49}
+#
+attributetype ( 0.9.2342.19200300.100.1.49 NAME 'dSAQuality'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.19 SINGLE-VALUE )
+
+# 9.3.40.  Single Level Quality
+#
+#  The Single Level Quality attribute type specifies the purported data
+#  quality at the level immediately below in the DIT.  See [8] for
+#  details of the syntax.
+#
+#    singleLevelQuality ATTRIBUTE
+#            WITH ATTRIBUTE-SYNTAX DataQualitySyntax
+#            SINGLE VALUE
+#    ::= {pilotAttributeType 50}
+#
+attributetype ( 0.9.2342.19200300.100.1.50 NAME 'singleLevelQuality'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.13 SINGLE-VALUE )
+
+# 9.3.41.  Subtree Minimum Quality
+#
+#  The Subtree Minimum Quality attribute type specifies the purported
+#  minimum data quality for a DIT subtree.  See [8] for more discussion
+#  and details of the syntax.
+#
+#    subtreeMinimumQuality ATTRIBUTE
+#            WITH ATTRIBUTE-SYNTAX DataQualitySyntax
+#            SINGLE VALUE
+#               -- Defaults to singleLevelQuality
+#    ::= {pilotAttributeType 51}
+#
+attributetype ( 0.9.2342.19200300.100.1.51 NAME 'subtreeMinimumQuality'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.13 SINGLE-VALUE )
+
+# 9.3.42.  Subtree Maximum Quality
+#
+#  The Subtree Maximum Quality attribute type specifies the purported
+#  maximum data quality for a DIT subtree.  See [8] for more discussion
+#  and details of the syntax.
+#
+#    subtreeMaximumQuality ATTRIBUTE
+#            WITH ATTRIBUTE-SYNTAX DataQualitySyntax
+#            SINGLE VALUE
+#               -- Defaults to singleLevelQuality
+#    ::= {pilotAttributeType 52}
+#
+attributetype ( 0.9.2342.19200300.100.1.52 NAME 'subtreeMaximumQuality'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.13 SINGLE-VALUE )
+
+# 9.3.43.  Personal Signature
+#
+#  The Personal Signature attribute type allows for a representation of
+#  a person's signature.  This should be encoded in G3 fax as explained
+#  in recommendation T.4, with an ASN.1 wrapper to make it compatible
+#  with an X.400 BodyPart as defined in X.420.
+#
+#    IMPORT  G3FacsimileBodyPart  FROM  {   mhs-motis   ipms   modules
+#    information-objects }
+#
+#    personalSignature ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            CHOICE {
+#                g3-facsimile [3] G3FacsimileBodyPart
+#                }
+#        (SIZE (1 .. ub-personal-signature))
+#    ::= {pilotAttributeType 53}
+#
+attributetype ( 0.9.2342.19200300.100.1.53 NAME 'personalSignature'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.23 )
+
+# 9.3.44.  DIT Redirect
+#
+#  The DIT Redirect attribute type is used to indicate that the object
+#  described by one entry now has a newer entry in the DIT.  The entry
+#  containing the redirection attribute should be expired after a
+#  suitable grace period.  This attribute may be used when an individual
+#  changes his/her place of work, and thus acquires a new organisational
+#  DN.
+#
+#    dITRedirect ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            distinguishedNameSyntax
+#    ::= {pilotAttributeType 54}
+#
+attributetype ( 0.9.2342.19200300.100.1.54 NAME 'dITRedirect'
+        EQUALITY distinguishedNameMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+# 9.3.45.  Audio
+#
+#  The Audio attribute type allows the storing of sounds in the
+#  Directory.  The attribute uses a u-law encoded sound file as used by
+#  the "play" utility on a Sun 4.  This is an interim format.
+#
+#    audio ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            Audio
+#        (SIZE (1 .. ub-audio))
+#    ::= {pilotAttributeType 55}
+#
+attributetype ( 0.9.2342.19200300.100.1.55 NAME 'audio'
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.4{25000} )
+
+# 9.3.46.  Publisher of Document
+#
+#
+#  The Publisher of Document attribute is the person and/or organization
+#  that published a document.
+#
+#    documentPublisher ATTRIBUTE
+#            WITH ATTRIBUTE SYNTAX caseIgnoreStringSyntax
+#    ::= {pilotAttributeType 56}
+#
+attributetype ( 0.9.2342.19200300.100.1.56 NAME 'documentPublisher'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+# 9.4.  Generally useful syntaxes
+#
+#    caseIgnoreIA5StringSyntax ATTRIBUTE-SYNTAX
+#            IA5String
+#            MATCHES FOR EQUALITY SUBSTRINGS
+#
+#    iA5StringSyntax ATTRIBUTE-SYNTAX
+#        IA5String
+#        MATCHES FOR EQUALITY SUBSTRINGS
+#
+#
+#    -- Syntaxes to support the DNS attributes
+#
+#    DNSRecordSyntax ATTRIBUTE-SYNTAX
+#            IA5String
+#            MATCHES FOR EQUALITY
+#
+#
+#    NRSInformationSyntax ATTRIBUTE-SYNTAX
+#            NRSInformation
+#            MATCHES FOR EQUALITY
+#
+#
+#    NRSInformation ::=  SET {
+#                    [0] Context,
+#                    [1] Address-space-id,
+#                    routes [2] SEQUENCE OF SEQUENCE {
+#                    Route-cost,
+#                    Addressing-info }
+#            }
+#
+#
+# 9.5.  Upper bounds on length of attribute values
+#
+#
+#    ub-document-identifier INTEGER ::= 256
+#
+#    ub-document-location INTEGER ::= 256
+#
+#    ub-document-title INTEGER ::= 256
+#
+#    ub-document-version INTEGER ::= 256
+#
+#    ub-favourite-drink INTEGER ::= 256
+#
+#    ub-host INTEGER ::= 256
+#
+#    ub-information INTEGER ::= 2048
+#
+#    ub-unique-identifier INTEGER ::= 256
+#
+#    ub-personal-title INTEGER ::= 256
+#
+#    ub-photo INTEGER ::= 250000
+#
+#    ub-rfc822-mailbox INTEGER ::= 256
+#
+#    ub-room-number INTEGER ::= 256
+#
+#    ub-text-or-address INTEGER ::= 256
+#
+#    ub-user-class INTEGER ::= 256
+#
+#    ub-user-identifier INTEGER ::= 256
+#
+#    ub-organizational-status INTEGER ::= 256
+#
+#    ub-janet-mailbox INTEGER ::= 256
+#
+#    ub-building-name INTEGER ::= 256
+#
+#    ub-personal-signature ::= 50000
+#
+#    ub-audio INTEGER ::= 250000
+#
+
+# [back to 8]
+# 8.  Object Classes
+#
+# 8.1.  X.500 standard object classes
+#
+#  A number of generally useful object classes are defined in X.521, and
+#  these are supported.  Refer to that document for descriptions of the
+#  suggested usage of these object classes.  The ASN.1 for these object
+#  classes is reproduced for completeness in Appendix C.
+#
+# 8.2.  X.400 standard object classes
+#
+#  A number of object classes defined in X.400 are supported.  Refer to
+#  X.402 for descriptions of the usage of these object classes.  The
+#  ASN.1 for these object classes is reproduced for completeness in
+#  Appendix C.
+#
+# 8.3.  COSINE/Internet object classes
+#
+#  This section attempts to fuse together the object classes designed
+#  for use in the COSINE and Internet pilot activities.  Descriptions
+#  are given of the suggested usage of these object classes.  The ASN.1
+#  for these object classes is also reproduced in Appendix C.
+#
+# 8.3.1.  Pilot Object
+#
+#  The PilotObject object class is used as a sub-class to allow some
+#  common, useful attributes to be assigned to entries of all other
+#  object classes.
+#
+#    pilotObject OBJECT-CLASS
+#        SUBCLASS OF top
+#        MAY CONTAIN {
+#            info,
+#            photo,
+#            manager,
+#            uniqueIdentifier,
+#            lastModifiedTime,
+#            lastModifiedBy,
+#            dITRedirect,
+#            audio}
+#    ::= {pilotObjectClass 3}
+#
+objectclass ( 0.9.2342.19200300.100.4.3 NAME 'pilotObject'
+       SUP top AUXILIARY
+       MAY ( info $ photo $ manager $ uniqueIdentifier $
+               lastModifiedTime $ lastModifiedBy $ dITRedirect $ audio )
+       )
+
+# 8.3.2.  Pilot Person
+#
+#  The PilotPerson object class is used as a sub-class of person, to
+#  allow the use of a number of additional attributes to be assigned to
+#  entries of object class person.
+#
+#    pilotPerson OBJECT-CLASS
+#        SUBCLASS OF person
+#        MAY CONTAIN {
+#                    userid,
+#                    textEncodedORAddress,
+#                    rfc822Mailbox,
+#                    favouriteDrink,
+#                    roomNumber,
+#                    userClass,
+#                    homeTelephoneNumber,
+#                    homePostalAddress,
+#                    secretary,
+#                    personalTitle,
+#                    preferredDeliveryMethod,
+#                    businessCategory,
+#                    janetMailbox,
+#                    otherMailbox,
+#                    mobileTelephoneNumber,
+#                    pagerTelephoneNumber,
+#                    organizationalStatus,
+#                    mailPreferenceOption,
+#                    personalSignature}
+#    ::= {pilotObjectClass 4}
+#
+objectclass ( 0.9.2342.19200300.100.4.4
+       NAME ( 'pilotPerson' 'newPilotPerson' )
+       SUP person STRUCTURAL
+       MAY ( userid $ textEncodedORAddress $ rfc822Mailbox $
+               favouriteDrink $ roomNumber $ userClass $
+               homeTelephoneNumber $ homePostalAddress $ secretary $
+               personalTitle $ preferredDeliveryMethod $ businessCategory $
+               janetMailbox $ otherMailbox $ mobileTelephoneNumber $
+               pagerTelephoneNumber $ organizationalStatus $
+               mailPreferenceOption $ personalSignature )
+       )
+
+# 8.3.3.  Account
+#
+#  The Account object class is used to define entries representing
+#  computer accounts.  The userid attribute should be used for naming
+#  entries of this object class.
+#
+#    account OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            userid}
+#        MAY CONTAIN {
+#            description,
+#            seeAlso,
+#            localityName,
+#            organizationName,
+#            organizationalUnitName,
+#            host}
+#    ::= {pilotObjectClass 5}
+#
+objectclass ( 0.9.2342.19200300.100.4.5 NAME 'account'
+       SUP top STRUCTURAL
+       MUST userid
+       MAY ( description $ seeAlso $ localityName $
+               organizationName $ organizationalUnitName $ host )
+       )
+
+# 8.3.4.  Document
+#
+#  The Document object class is used to define entries which represent
+#  documents.
+#
+#    document OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            documentIdentifier}
+#        MAY CONTAIN {
+#            commonName,
+#            description,
+#            seeAlso,
+#            localityName,
+#            organizationName,
+#            organizationalUnitName,
+#            documentTitle,
+#            documentVersion,
+#            documentAuthor,
+#            documentLocation,
+#            documentPublisher}
+#    ::= {pilotObjectClass 6}
+#
+objectclass ( 0.9.2342.19200300.100.4.6 NAME 'document'
+       SUP top STRUCTURAL
+       MUST documentIdentifier
+       MAY ( commonName $ description $ seeAlso $ localityName $
+               organizationName $ organizationalUnitName $
+               documentTitle $ documentVersion $ documentAuthor $
+               documentLocation $ documentPublisher )
+       )
+
+# 8.3.5.  Room
+#
+#  The Room object class is used to define entries representing rooms.
+#  The commonName attribute should be used for naming pentries of this
+#  object class.
+#
+#    room OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            commonName}
+#        MAY CONTAIN {
+#            roomNumber,
+#            description,
+#            seeAlso,
+#            telephoneNumber}
+#    ::= {pilotObjectClass 7}
+#
+objectclass ( 0.9.2342.19200300.100.4.7 NAME 'room'
+       SUP top STRUCTURAL
+       MUST commonName
+       MAY ( roomNumber $ description $ seeAlso $ telephoneNumber )
+       )
+
+# 8.3.6.  Document Series
+#
+#  The Document Series object class is used to define an entry which
+#  represents a series of documents (e.g., The Request For Comments
+#  papers).
+#
+#    documentSeries OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            commonName}
+#        MAY CONTAIN {
+#            description,
+#            seeAlso,
+#            telephoneNumber,
+#            localityName,
+#            organizationName,
+#            organizationalUnitName}
+#    ::= {pilotObjectClass 9}
+#
+objectclass ( 0.9.2342.19200300.100.4.9 NAME 'documentSeries'
+       SUP top STRUCTURAL
+       MUST commonName
+       MAY ( description $ seeAlso $ telephonenumber $
+               localityName $ organizationName $ organizationalUnitName )
+       )
+
+# 8.3.7.  Domain
+#
+#  The Domain object class is used to define entries which represent DNS
+#  or NRS domains.  The domainComponent attribute should be used for
+#  naming entries of this object class.  The usage of this object class
+#  is described in more detail in [3].
+#
+#    domain OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            domainComponent}
+#        MAY CONTAIN {
+#            associatedName,
+#            organizationName,
+#            organizationalAttributeSet}
+#    ::= {pilotObjectClass 13}
+#
+## from RFC 2247, we presume that organizationalAttributeSet
+## should be expanded as below.
+objectclass ( 0.9.2342.19200300.100.4.13 NAME 'domain'
+       SUP top STRUCTURAL
+       MUST domainComponent
+       MAY ( userPassword $ searchGuide $ seeAlso $
+               businessCategory $ x121Address $ registeredAddress $
+               destinationIndicator $ preferredDeliveryMethod $
+               telexNumber $ teletexTerminalIdentifier $  
+               telephoneNumber $ internationaliSDNNumber $
+               facsimileTelephoneNumber $ street $ postOfficeBox $
+               postalCode $ postalAddress $
+               physicalDeliveryOfficeName $
+               stateOrProvinceName $ localityName $ description )
+       )
+
+# 8.3.8.  RFC822 Local Part
+#
+#  The RFC822 Local Part object class is used to define entries which
+#  represent the local part of RFC822 mail addresses.  This treats this
+#  part of an RFC822 address as a domain.  The usage of this object
+#  class is described in more detail in [3].
+#
+#    rFC822localPart OBJECT-CLASS
+#        SUBCLASS OF domain
+#        MAY CONTAIN {
+#            commonName,
+#            surname,
+#            description,
+#            seeAlso,
+#            telephoneNumber,
+#            postalAttributeSet,
+#            telecommunicationAttributeSet}
+#    ::= {pilotObjectClass 14}
+#
+## not sure what to expand postalAttributeSet and
+## telecommunitionAttributeSet to, so they are trimmed
+objectclass ( 0.9.2342.19200300.100.4.14 NAME 'RFC822localPart'
+       SUP domain STRUCTURAL
+       MAY ( commonName $ surname $ description $ seeAlso $ telephonenumber )
+       )
+
+# 8.3.9.  DNS Domain
+#
+#  The DNS Domain (Domain NameServer) object class is used to define
+#  entries for DNS domains.  The usage of this object class is described
+#  in more detail in [3].
+#
+#    dNSDomain OBJECT-CLASS
+#        SUBCLASS OF domain
+#        MAY CONTAIN {
+#            ARecord,
+#            MDRecord,
+#            MXRecord,
+#            NSRecord,
+#            SOARecord,
+#            CNAMERecord}
+#    ::= {pilotObjectClass 15}
+#
+objectclass ( 0.9.2342.19200300.100.4.15 NAME 'dNSDomain'
+       SUP 'domain' STRUCTURAL
+       MAY ( ARecord $ MDRecord $ MXRecord $ NSRecord $ 
+               SOARecord $ CNAMERecord )
+       )
+
+# 8.3.10.  Domain Related Object
+#
+#  The Domain Related Object object class is used to define entries
+#  which represent DNS/NRS domains which are "equivalent" to an X.500
+#  domain: e.g., an organisation or organisational unit.  The usage of
+#  this object class is described in more detail in [3].
+#
+#    domainRelatedObject OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            associatedDomain}
+#    ::= {pilotObjectClass 17}
+#
+objectclass ( 0.9.2342.19200300.100.4.17 NAME 'domainRelatedObject'
+       SUP top AUXILIARY
+       MUST associatedDomain )
+
+# 8.3.11.  Friendly Country
+#
+#  The Friendly Country object class is used to define country entries
+#  in the DIT.  The object class is used to allow friendlier naming of
+#  countries than that allowed by the object class country.  The naming
+#  attribute of object class country, countryName, has to be a 2 letter
+#  string defined in ISO 3166.
+#
+#    friendlyCountry OBJECT-CLASS
+#        SUBCLASS OF country
+#        MUST CONTAIN {
+#            friendlyCountryName}
+#    ::= {pilotObjectClass 18}
+#
+objectclass ( 0.9.2342.19200300.100.4.18 NAME 'friendlyCountry'
+       SUP country STRUCTURAL
+       MUST friendlyCountryName )
+
+# 8.3.12.  Simple Security Object
+#
+#  The Simple Security Object object class is used to allow an entry to
+#  have a userPassword attribute when an entry's principal object
+#  classes do not allow userPassword as an attribute type.
+#
+#    simpleSecurityObject OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            userPassword }
+#    ::= {pilotObjectClass 19}
+#
+## (in core.schema)
+## objectclass ( 0.9.2342.19200300.100.4.19 NAME 'simpleSecurityObject'
+##     SUP top AUXILIARY
+##     MUST userPassword )
+
+# 8.3.13.  Pilot Organization
+#
+#  The PilotOrganization object class is used as a sub-class of
+#  organization and organizationalUnit to allow a number of additional
+#  attributes to be assigned to entries of object classes organization
+#  and organizationalUnit.
+#
+#    pilotOrganization OBJECT-CLASS
+#        SUBCLASS OF organization, organizationalUnit
+#        MAY CONTAIN {
+#                    buildingName}
+#    ::= {pilotObjectClass 20}
+#
+objectclass ( 0.9.2342.19200300.100.4.20 NAME 'pilotOrganization'
+       SUP ( organization $ organizationalUnit ) STRUCTURAL
+       MAY buildingName )
+
+# 8.3.14.  Pilot DSA
+#
+#  The PilotDSA object class is used as a sub-class of the dsa object
+#  class to allow additional attributes to be assigned to entries for
+#  DSAs.
+#
+#    pilotDSA OBJECT-CLASS
+#        SUBCLASS OF dsa
+#        MUST CONTAIN {
+#            dSAQuality}
+#    ::= {pilotObjectClass 21}
+#
+objectclass ( 0.9.2342.19200300.100.4.21 NAME 'pilotDSA'
+       SUP dsa STRUCTURAL
+       MAY dSAQuality )
+
+# 8.3.15.  Quality Labelled Data
+#
+#  The Quality Labelled Data object class is used to allow the
+#  assignment of the data quality attributes to subtrees in the DIT.
+#
+#  See [8] for more details.
+#
+#    qualityLabelledData OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            dSAQuality}
+#        MAY CONTAIN {
+#            subtreeMinimumQuality,
+#            subtreeMaximumQuality}
+#    ::= {pilotObjectClass 22}
+objectclass ( 0.9.2342.19200300.100.4.22 NAME 'qualityLabelledData'
+       SUP top AUXILIARY
+       MUST dsaQuality
+       MAY ( subtreeMinimumQuality $ subtreeMaximumQuality )
+       )
+
+
+# References
+#
+#    [1]  CCITT/ISO, "X.500, The Directory - overview of concepts,
+#         models and services, CCITT /ISO IS 9594.
+#
+#    [2]  Kille, S., "The THORN and RARE X.500 Naming Architecture, in
+#         University College London, Department of Computer Science
+#         Research Note 89/48, May 1989.
+#
+#    [3]  Kille, S., "X.500 and Domains", RFC 1279, University College
+#         London, November 1991.
+#
+#    [4]  Rose, M., "PSI/NYSERNet White Pages Pilot Project: Status
+#         Report", Technical Report 90-09-10-1, published by NYSERNet
+#         Inc, 1990.
+#
+#    [5]  Craigie, J., "UK Academic Community Directory Service Pilot
+#         Project, pp. 305-310 in Computer Networks and ISDN Systems
+#         17 (1989), published by North Holland.
+#
+#    [6]  Mockapetris, P., "Domain Names - Concepts and Facilities",
+#         RFC 1034, USC/Information Sciences Institute, November 1987.
+#
+#    [7]  Mockapetris, P., "Domain Names - Implementation and
+#         Specification, RFC 1035, USC/Information Sciences Institute,
+#         November 1987.
+#
+#    [8]  Kille, S., "Handling QOS (Quality of service) in the
+#         Directory," publication in process, March 1991.
+#
+#
+# APPENDIX C - Summary of all Object Classes and Attribute Types
+#
+#    -- Some Important Object Identifiers
+#
+#    data OBJECT IDENTIFIER ::= {ccitt 9}
+#    pss OBJECT IDENTIFIER ::= {data 2342}
+#    ucl OBJECT IDENTIFIER ::= {pss 19200300}
+#    pilot OBJECT IDENTIFIER ::= {ucl 100}
+#
+#    pilotAttributeType OBJECT IDENTIFIER ::= {pilot 1}
+#    pilotAttributeSyntax OBJECT IDENTIFIER ::= {pilot 3}
+#    pilotObjectClass OBJECT IDENTIFIER ::= {pilot 4}
+#    pilotGroups OBJECT IDENTIFIER ::= {pilot 10}
+#
+#    iA5StringSyntax OBJECT IDENTIFIER ::= {pilotAttributeSyntax 4}
+#    caseIgnoreIA5StringSyntax OBJECT IDENTIFIER ::=
+#                                          {pilotAttributeSyntax 5}
+#
+#    -- Standard Object Classes
+#
+#    top OBJECT-CLASS
+#        MUST CONTAIN {
+#            objectClass}
+#    ::= {objectClass 0}
+#
+#
+#    alias OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            aliasedObjectName}
+#    ::= {objectClass 1}
+#
+#
+#    country OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            countryName}
+#        MAY CONTAIN {
+#            description,
+#            searchGuide}
+#    ::= {objectClass 2}
+#
+#
+#    locality OBJECT-CLASS
+#        SUBCLASS OF top
+#        MAY CONTAIN {
+#            description,
+#            localityName,
+#            stateOrProvinceName,
+#            searchGuide,
+#            seeAlso,
+#            streetAddress}
+#    ::= {objectClass 3}
+#
+#
+#    organization OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            organizationName}
+#        MAY CONTAIN {
+#            organizationalAttributeSet}
+#    ::= {objectClass 4}
+#
+#
+#    organizationalUnit OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            organizationalUnitName}
+#        MAY CONTAIN {
+#            organizationalAttributeSet}
+#    ::= {objectClass 5}
+#
+#
+#    person OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            commonName,
+#            surname}
+#        MAY CONTAIN {
+#            description,
+#            seeAlso,
+#            telephoneNumber,
+#            userPassword}
+#    ::= {objectClass 6}
+#
+#
+#    organizationalPerson OBJECT-CLASS
+#        SUBCLASS OF person
+#        MAY CONTAIN {
+#            localeAttributeSet,
+#            organizationalUnitName,
+#            postalAttributeSet,
+#            telecommunicationAttributeSet,
+#            title}
+#    ::= {objectClass 7}
+#
+#
+#    organizationalRole OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            commonName}
+#        MAY CONTAIN {
+#            description,
+#            localeAttributeSet,
+#            organizationalUnitName,
+#            postalAttributeSet,
+#            preferredDeliveryMethod,
+#            roleOccupant,
+#            seeAlso,
+#            telecommunicationAttributeSet}
+#    ::= {objectClass 8}
+#
+#
+#    groupOfNames OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            commonName,
+#            member}
+#        MAY CONTAIN {
+#            description,
+#            organizationName,
+#            organizationalUnitName,
+#            owner,
+#            seeAlso,
+#            businessCategory}
+#    ::= {objectClass 9}
+#
+#
+#    residentialPerson OBJECT-CLASS
+#        SUBCLASS OF person
+#        MUST CONTAIN {
+#            localityName}
+#        MAY CONTAIN {
+#            localeAttributeSet,
+#            postalAttributeSet,
+#            preferredDeliveryMethod,
+#            telecommunicationAttributeSet,
+#            businessCategory}
+#    ::= {objectClass 10}
+#
+#
+#    applicationProcess OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            commonName}
+#        MAY CONTAIN {
+#            description,
+#            localityName,
+#            organizationalUnitName,
+#            seeAlso}
+#    ::= {objectClass 11}
+#
+#
+#    applicationEntity OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            commonName,
+#            presentationAddress}
+#        MAY CONTAIN {
+#            description,
+#            localityName,
+#            organizationName,
+#            organizationalUnitName,
+#            seeAlso,
+#            supportedApplicationContext}
+#    ::= {objectClass 12}
+#
+#
+#    dSA OBJECT-CLASS
+#        SUBCLASS OF applicationEntity
+#        MAY CONTAIN {
+#            knowledgeInformation}
+#    ::= {objectClass 13}
+#
+#
+#    device OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            commonName}
+#        MAY CONTAIN {
+#            description,
+#            localityName,
+#            organizationName,
+#            organizationalUnitName,
+#            owner,
+#            seeAlso,
+#            serialNumber}
+#    ::= {objectClass 14}
+#
+#
+#    strongAuthenticationUser OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            userCertificate}
+#    ::= {objectClass 15}
+#
+#
+#    certificationAuthority OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            cACertificate,
+#            certificateRevocationList,
+#            authorityRevocationList}
+#        MAY CONTAIN {
+#            crossCertificatePair}
+#    ::= {objectClass 16}
+#
+#    -- Standard MHS Object Classes
+#
+#    mhsDistributionList OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            commonName,
+#            mhsDLSubmitPermissions,
+#            mhsORAddresses}
+#        MAY CONTAIN {
+#            description,
+#            organizationName,
+#            organizationalUnitName,
+#            owner,
+#            seeAlso,
+#            mhsDeliverableContentTypes,
+#            mhsdeliverableEits,
+#            mhsDLMembers,
+#            mhsPreferredDeliveryMethods}
+#    ::= {mhsObjectClass 0}
+#
+#
+#    mhsMessageStore OBJECT-CLASS
+#        SUBCLASS OF applicationEntity
+#        MAY CONTAIN {
+#            description,
+#            owner,
+#            mhsSupportedOptionalAttributes,
+#            mhsSupportedAutomaticActions,
+#            mhsSupportedContentTypes}
+#    ::= {mhsObjectClass 1}
+#
+#
+#    mhsMessageTransferAgent OBJECT-CLASS
+#        SUBCLASS OF applicationEntity
+#        MAY CONTAIN {
+#            description,
+#            owner,
+#            mhsDeliverableContentLength}
+#    ::= {mhsObjectClass 2}
+#
+#
+#    mhsOrganizationalUser OBJECT-CLASS
+#        SUBCLASS OF organizationalPerson
+#        MUST CONTAIN {
+#            mhsORAddresses}
+#        MAY CONTAIN {
+#            mhsDeliverableContentLength,
+#            mhsDeliverableContentTypes,
+#            mhsDeliverableEits,
+#            mhsMessageStoreName,
+#            mhsPreferredDeliveryMethods }
+#    ::= {mhsObjectClass 3}
+#
+#
+#    mhsResidentialUser OBJECT-CLASS
+#        SUBCLASS OF residentialPerson
+#        MUST CONTAIN {
+#            mhsORAddresses}
+#        MAY CONTAIN {
+#            mhsDeliverableContentLength,
+#            mhsDeliverableContentTypes,
+#            mhsDeliverableEits,
+#            mhsMessageStoreName,
+#            mhsPreferredDeliveryMethods }
+#    ::= {mhsObjectClass 4}
+#
+#
+#    mhsUserAgent OBJECT-CLASS
+#        SUBCLASS OF applicationEntity
+#        MAY CONTAIN {
+#            mhsDeliverableContentLength,
+#            mhsDeliverableContentTypes,
+#            mhsDeliverableEits,
+#            mhsORAddresses,
+#            owner}
+#    ::= {mhsObjectClass 5}
+#
+#
+#
+#
+#    -- Pilot Object Classes
+#
+#    pilotObject OBJECT-CLASS
+#        SUBCLASS OF top
+#        MAY CONTAIN {
+#            info,
+#            photo,
+#            manager,
+#            uniqueIdentifier,
+#            lastModifiedTime,
+#            lastModifiedBy,
+#            dITRedirect,
+#            audio}
+#    ::= {pilotObjectClass 3}
+#    pilotPerson OBJECT-CLASS
+#        SUBCLASS OF person
+#        MAY CONTAIN {
+#                    userid,
+#                    textEncodedORAddress,
+#                    rfc822Mailbox,
+#                    favouriteDrink,
+#                    roomNumber,
+#                    userClass,
+#                    homeTelephoneNumber,
+#                    homePostalAddress,
+#                    secretary,
+#                    personalTitle,
+#                    preferredDeliveryMethod,
+#                    businessCategory,
+#                    janetMailbox,
+#                    otherMailbox,
+#                    mobileTelephoneNumber,
+#                    pagerTelephoneNumber,
+#                    organizationalStatus,
+#                    mailPreferenceOption,
+#                    personalSignature}
+#    ::= {pilotObjectClass 4}
+#
+#
+#    account OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            userid}
+#        MAY CONTAIN {
+#            description,
+#            seeAlso,
+#            localityName,
+#            organizationName,
+#            organizationalUnitName,
+#            host}
+#    ::= {pilotObjectClass 5}
+#
+#
+#    document OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            documentIdentifier}
+#        MAY CONTAIN {
+#            commonName,
+#            description,
+#            seeAlso,
+#            localityName,
+#            organizationName,
+#            organizationalUnitName,
+#            documentTitle,
+#            documentVersion,
+#            documentAuthor,
+#            documentLocation,
+#            documentPublisher}
+#    ::= {pilotObjectClass 6}
+#
+#
+#    room OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            commonName}
+#        MAY CONTAIN {
+#            roomNumber,
+#            description,
+#            seeAlso,
+#            telephoneNumber}
+#    ::= {pilotObjectClass 7}
+#
+#
+#    documentSeries OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            commonName}
+#        MAY CONTAIN {
+#            description,
+#            seeAlso,
+#            telephoneNumber,
+#            localityName,
+#            organizationName,
+#            organizationalUnitName}
+#    ::= {pilotObjectClass 9}
+#
+#
+#    domain OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            domainComponent}
+#        MAY CONTAIN {
+#            associatedName,
+#            organizationName,
+#            organizationalAttributeSet}
+#    ::= {pilotObjectClass 13}
+#
+#
+#    rFC822localPart OBJECT-CLASS
+#        SUBCLASS OF domain
+#        MAY CONTAIN {
+#            commonName,
+#            surname,
+#            description,
+#            seeAlso,
+#            telephoneNumber,
+#            postalAttributeSet,
+#            telecommunicationAttributeSet}
+#    ::= {pilotObjectClass 14}
+#
+#
+#    dNSDomain OBJECT-CLASS
+#        SUBCLASS OF domain
+#        MAY CONTAIN {
+#            ARecord,
+#            MDRecord,
+#            MXRecord,
+#            NSRecord,
+#            SOARecord,
+#            CNAMERecord}
+#    ::= {pilotObjectClass 15}
+#
+#
+#    domainRelatedObject OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            associatedDomain}
+#    ::= {pilotObjectClass 17}
+#
+#
+#    friendlyCountry OBJECT-CLASS
+#        SUBCLASS OF country
+#        MUST CONTAIN {
+#            friendlyCountryName}
+#    ::= {pilotObjectClass 18}
+#
+#
+#    simpleSecurityObject OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            userPassword }
+#    ::= {pilotObjectClass 19}
+#
+#
+#    pilotOrganization OBJECT-CLASS
+#        SUBCLASS OF organization, organizationalUnit
+#        MAY CONTAIN {
+#                    buildingName}
+#    ::= {pilotObjectClass 20}
+#
+#
+#    pilotDSA OBJECT-CLASS
+#        SUBCLASS OF dsa
+#        MUST CONTAIN {
+#            dSAQuality}
+#    ::= {pilotObjectClass 21}
+#
+#
+#    qualityLabelledData OBJECT-CLASS
+#        SUBCLASS OF top
+#        MUST CONTAIN {
+#            dSAQuality}
+#        MAY CONTAIN {
+#            subtreeMinimumQuality,
+#            subtreeMaximumQuality}
+#    ::= {pilotObjectClass 22}
+#
+#
+#
+#
+#    -- Standard Attribute Types
+#
+#    objectClass ObjectClass
+#        ::= {attributeType 0}
+#
+#
+#    aliasedObjectName AliasedObjectName
+#        ::= {attributeType 1}
+#
+#
+#    knowledgeInformation ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX caseIgnoreString
+#        ::= {attributeType 2}
+#
+#
+#    commonName ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX caseIgnoreStringSyntax
+#        (SIZE (1..ub-common-name))
+#        ::= {attributeType 3}
+#
+#
+#    surname ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX caseIgnoreStringSyntax
+#        (SIZE (1..ub-surname))
+#        ::= {attributeType 4}
+#
+#
+#    serialNumber ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX printableStringSyntax
+#        (SIZE (1..ub-serial-number))
+#        ::= {attributeType 5}
+#
+#
+#    countryName ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX PrintableString
+#        (SIZE (1..ub-country-code))
+#        SINGLE VALUE
+#        ::= {attributeType 6}
+#
+#
+#    localityName ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX caseIgnoreStringSyntax
+#        (SIZE (1..ub-locality-name))
+#        ::= {attributeType 7}
+#
+#
+#    stateOrProvinceName ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX caseIgnoreStringSyntax
+#        (SIZE (1..ub-state-name))
+#        ::= {attributeType 8}
+#
+#
+#    streetAddress ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX caseIgnoreStringSyntax
+#        (SIZE (1..ub-street-address))
+#        ::= {attributeType 9}
+#
+#
+#    organizationName ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX caseIgnoreStringSyntax
+#        (SIZE (1..ub-organization-name))
+#        ::= {attributeType 10}
+#
+#
+#    organizationalUnitName ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX caseIgnoreStringSyntax
+#        (SIZE (1..ub-organizational-unit-name))
+#        ::= {attributeType 11}
+#
+#
+#    title ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX caseIgnoreStringSyntax
+#        (SIZE (1..ub-title))
+#        ::= {attributeType 12}
+#
+#
+#    description ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX caseIgnoreStringSyntax
+#        (SIZE (1..ub-description))
+#        ::= {attributeType 13}
+#
+#
+#    searchGuide ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX Guide
+#        ::= {attributeType 14}
+#
+#
+#    businessCategory ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX caseIgnoreStringSyntax
+#        (SIZE (1..ub-business-category))
+#        ::= {attributeType 15}
+#
+#
+#    postalAddress ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX PostalAddress
+#        MATCHES FOR EQUALITY
+#        ::= {attributeType 16}
+#
+#
+#    postalCode ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX caseIgnoreStringSyntax
+#        (SIZE (1..ub-postal-code))
+#        ::= {attributeType 17}
+#
+#
+#    postOfficeBox ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX caseIgnoreStringSyntax
+#        (SIZE (1..ub-post-office-box))
+#        ::= {attributeType 18}
+#
+#
+#    physicalDeliveryOfficeName ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX caseIgnoreStringSyntax
+#        (SIZE (1..ub-physical-office-name))
+#        ::= {attributeType 19}
+#
+#
+#    telephoneNumber ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX telephoneNumberSyntax
+#        (SIZE (1..ub-telephone-number))
+#        ::= {attributeType 20}
+#
+#
+#    telexNumber ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX TelexNumber
+#        (SIZE (1..ub-telex))
+#        ::= {attributeType 21}
+#
+#
+#    teletexTerminalIdentifier ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX TeletexTerminalIdentifier
+#        (SIZE (1..ub-teletex-terminal-id))
+#        ::= {attributeType 22}
+#
+#
+#    facsimileTelephoneNumber ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX FacsimileTelephoneNumber
+#        ::= {attributeType 23}
+#
+#
+#    x121Address ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX NumericString
+#        (SIZE (1..ub-x121-address))
+#        ::= {attributeType 24}
+#
+#
+#    internationaliSDNNumber ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX NumericString
+#        (SIZE (1..ub-isdn-address))
+#        ::= {attributeType 25}
+#
+#
+#    registeredAddress ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX PostalAddress
+#        ::= {attributeType 26}
+#
+#
+#    destinationIndicator ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX PrintableString
+#        (SIZE (1..ub-destination-indicator))
+#        MATCHES FOR EQUALITY SUBSTRINGS
+#        ::= {attributeType 27}
+#
+#
+#    preferredDeliveryMethod ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX deliveryMethod
+#        ::= {attributeType 28}
+#
+#
+#    presentationAddress ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX PresentationAddress
+#        MATCHES FOR EQUALITY
+#        ::= {attributeType 29}
+#
+#
+#    supportedApplicationContext ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX objectIdentifierSyntax
+#        ::= {attributeType 30}
+#
+#
+#    member ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX distinguishedNameSyntax
+#        ::= {attributeType 31}
+#
+#
+#    owner ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX distinguishedNameSyntax
+#        ::= {attributeType 32}
+#
+#
+#    roleOccupant ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX distinguishedNameSyntax
+#        ::= {attributeType 33}
+#
+#
+#    seeAlso ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX distinguishedNameSyntax
+#        ::= {attributeType 34}
+#
+#
+#    userPassword ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX Userpassword
+#        ::= {attributeType 35}
+#
+#
+#    userCertificate ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX UserCertificate
+#        ::= {attributeType 36}
+#
+#
+#    cACertificate ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX cACertificate
+#        ::= {attributeType 37}
+#
+#
+#    authorityRevocationList ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX AuthorityRevocationList
+#        ::= {attributeType 38}
+#
+#
+#    certificateRevocationList ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX CertificateRevocationList
+#        ::= {attributeType 39}
+#
+#
+#    crossCertificatePair ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX CrossCertificatePair
+#        ::= {attributeType 40}
+#
+#
+#
+#
+#    -- Standard MHS Attribute Types
+#
+#    mhsDeliverableContentLength ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX integer
+#        ::= {mhsAttributeType 0}
+#
+#
+#    mhsDeliverableContentTypes ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX oID
+#        ::= {mhsAttributeType 1}
+#
+#
+#    mhsDeliverableEits ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX oID
+#        ::= {mhsAttributeType 2}
+#
+#
+#    mhsDLMembers ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX oRName
+#        ::= {mhsAttributeType 3}
+#
+#
+#    mhsDLSubmitPermissions ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX dLSubmitPermission
+#        ::= {mhsAttributeType 4}
+#
+#
+#    mhsMessageStoreName ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX dN
+#        ::= {mhsAttributeType 5}
+#
+#
+#    mhsORAddresses ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX oRAddress
+#        ::= {mhsAttributeType 6}
+#
+#
+#    mhsPreferredDeliveryMethods ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX deliveryMethod
+#        ::= {mhsAttributeType 7}
+#
+#
+#    mhsSupportedAutomaticActions ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX oID
+#        ::= {mhsAttributeType 8}
+#
+#
+#    mhsSupportedContentTypes ATTRIBUTE
+#
+#        WITH ATTRIBUTE-SYNTAX oID
+#        ::= {mhsAttributeType 9}
+#
+#
+#    mhsSupportedOptionalAttributes ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX oID
+#        ::= {mhsAttributeType 10}
+#
+#
+#
+#
+#    -- Pilot Attribute Types
+#
+#    userid ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-user-identifier))
+#    ::= {pilotAttributeType 1}
+#
+#
+#    textEncodedORAddress ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#        (SIZE (1 .. ub-text-encoded-or-address))
+#    ::= {pilotAttributeType 2}
+#
+#
+#    rfc822Mailbox ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreIA5StringSyntax
+#            (SIZE (1 .. ub-rfc822-mailbox))
+#    ::= {pilotAttributeType 3}
+#
+#
+#    info ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-information))
+#    ::= {pilotAttributeType 4}
+#
+#
+#    favouriteDrink ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-favourite-drink))
+#    ::= {pilotAttributeType 5}
+#
+#
+#    roomNumber ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-room-number))
+#    ::= {pilotAttributeType 6}
+#
+#
+#    photo ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            CHOICE {
+#                g3-facsimile [3] G3FacsimileBodyPart
+#                }
+#        (SIZE (1 .. ub-photo))
+#    ::= {pilotAttributeType 7}
+#
+#
+#    userClass ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-user-class))
+#    ::= {pilotAttributeType 8}
+#
+#
+#    host ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-host))
+#    ::= {pilotAttributeType 9}
+#
+#
+#    manager ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            distinguishedNameSyntax
+#    ::= {pilotAttributeType 10}
+#
+#
+#    documentIdentifier ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-document-identifier))
+#    ::= {pilotAttributeType 11}
+#
+#
+#    documentTitle ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#        (SIZE (1 .. ub-document-title))
+#    ::= {pilotAttributeType 12}
+#
+#
+#    documentVersion ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-document-version))
+#    ::= {pilotAttributeType 13}
+#
+#
+#    documentAuthor ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            distinguishedNameSyntax
+#    ::= {pilotAttributeType 14}
+#
+#
+#    documentLocation ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-document-location))
+#    ::= {pilotAttributeType 15}
+#
+#
+#    homeTelephoneNumber ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            telephoneNumberSyntax
+#    ::= {pilotAttributeType 20}
+#
+#
+#    secretary ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            distinguishedNameSyntax
+#    ::= {pilotAttributeType 21}
+#
+#
+#    otherMailbox ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            SEQUENCE {
+#                    mailboxType PrintableString, -- e.g. Telemail
+#                    mailbox IA5String  -- e.g. X378:Joe
+#            }
+#    ::= {pilotAttributeType 22}
+#
+#
+#    lastModifiedTime ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            uTCTimeSyntax
+#    ::= {pilotAttributeType 23}
+#
+#
+#    lastModifiedBy ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            distinguishedNameSyntax
+#    ::= {pilotAttributeType 24}
+#
+#
+#    domainComponent ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreIA5StringSyntax
+#            SINGLE VALUE
+#    ::= {pilotAttributeType 25}
+#
+#
+#    aRecord ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            DNSRecordSyntax
+#    ::= {pilotAttributeType 26}
+#
+#
+#    mXRecord ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            DNSRecordSyntax
+#    ::= {pilotAttributeType 28}
+#
+#
+#    nSRecord ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            DNSRecordSyntax
+#    ::= {pilotAttributeType 29}
+#
+#    sOARecord ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            DNSRecordSyntax
+#    ::= {pilotAttributeType 30}
+#
+#
+#    cNAMERecord ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            iA5StringSyntax
+#    ::= {pilotAttributeType 31}
+#
+#
+#    associatedDomain ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreIA5StringSyntax
+#    ::= {pilotAttributeType 37}
+#
+#
+#    associatedName ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            distinguishedNameSyntax
+#    ::= {pilotAttributeType 38}
+#
+#
+#    homePostalAddress ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            postalAddress
+#            MATCHES FOR EQUALITY
+#    ::= {pilotAttributeType 39}
+#
+#
+#    personalTitle ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-personal-title))
+#    ::= {pilotAttributeType 40}
+#
+#
+#    mobileTelephoneNumber ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            telephoneNumberSyntax
+#    ::= {pilotAttributeType 41}
+#
+#
+#    pagerTelephoneNumber ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            telephoneNumberSyntax
+#    ::= {pilotAttributeType 42}
+#
+#
+#    friendlyCountryName ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#    ::= {pilotAttributeType 43}
+#
+#
+#    uniqueIdentifier ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-unique-identifier))
+#    ::= {pilotAttributeType 44}
+#
+#
+#    organizationalStatus ATTRIBUTE
+#            WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-organizational-status))
+#    ::= {pilotAttributeType 45}
+#
+#
+#    janetMailbox ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreIA5StringSyntax
+#            (SIZE (1 .. ub-janet-mailbox))
+#    ::= {pilotAttributeType 46}
+#
+#
+#    mailPreferenceOption ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX ENUMERATED {
+#                no-list-inclusion(0),
+#                any-list-inclusion(1),  -- may be added to any lists
+#                professional-list-inclusion(2)
+#                                        -- may be added to lists
+#                                        -- which the list provider
+#                                        -- views as related to the
+#                                        -- users professional inter-
+#                                        -- ests, perhaps evaluated
+#                                        -- from the business of the
+#                                        -- organisation or keywords
+#                                        -- in the entry.
+#                }
+#    ::= {pilotAttributeType 47}
+#
+#
+#    buildingName ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            caseIgnoreStringSyntax
+#            (SIZE (1 .. ub-building-name))
+#    ::= {pilotAttributeType 48}
+#
+#
+#    dSAQuality ATTRIBUTE
+#            WITH ATTRIBUTE-SYNTAX DSAQualitySyntax
+#            SINGLE VALUE
+#    ::= {pilotAttributeType 49}
+#
+#
+#    singleLevelQuality ATTRIBUTE
+#            WITH ATTRIBUTE-SYNTAX DataQualitySyntax
+#            SINGLE VALUE
+#
+#
+#    subtreeMinimumQuality ATTRIBUTE
+#            WITH ATTRIBUTE-SYNTAX DataQualitySyntax
+#            SINGLE VALUE
+#               -- Defaults to singleLevelQuality
+#    ::= {pilotAttributeType 51}
+#
+#
+#    subtreeMaximumQuality ATTRIBUTE
+#            WITH ATTRIBUTE-SYNTAX DataQualitySyntax
+#            SINGLE VALUE
+#               -- Defaults to singleLevelQuality
+#    ::= {pilotAttributeType 52}
+#
+#
+#    personalSignature ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            CHOICE {
+#                g3-facsimile [3] G3FacsimileBodyPart
+#                }
+#        (SIZE (1 .. ub-personal-signature))
+#    ::= {pilotAttributeType 53}
+#
+#
+#    dITRedirect ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            distinguishedNameSyntax
+#    ::= {pilotAttributeType 54}
+#
+#
+#    audio ATTRIBUTE
+#        WITH ATTRIBUTE-SYNTAX
+#            Audio
+#        (SIZE (1 .. ub-audio))
+#    ::= {pilotAttributeType 55}
+#
+#    documentPublisher ATTRIBUTE
+#            WITH ATTRIBUTE SYNTAX caseIgnoreStringSyntax
+#    ::= {pilotAttributeType 56}
+#
+#
+#
+#    -- Generally useful syntaxes
+#
+#
+#    caseIgnoreIA5StringSyntax ATTRIBUTE-SYNTAX
+#            IA5String
+#            MATCHES FOR EQUALITY SUBSTRINGS
+#
+#
+#    iA5StringSyntax ATTRIBUTE-SYNTAX
+#        IA5String
+#        MATCHES FOR EQUALITY SUBSTRINGS
+#
+#
+#    -- Syntaxes to support the DNS attributes
+#
+#    DNSRecordSyntax ATTRIBUTE-SYNTAX
+#            IA5String
+#            MATCHES FOR EQUALITY
+#
+#
+#    NRSInformationSyntax ATTRIBUTE-SYNTAX
+#            NRSInformation
+#            MATCHES FOR EQUALITY
+#
+#
+#    NRSInformation ::=  SET {
+#                    [0] Context,
+#                    [1] Address-space-id,
+#                    routes [2] SEQUENCE OF SEQUENCE {
+#                    Route-cost,
+#                    Addressing-info }
+#            }
+#
+#
+#    -- Upper bounds on length of attribute values
+#
+#
+#    ub-document-identifier INTEGER ::= 256
+#
+#    ub-document-location INTEGER ::= 256
+#
+#    ub-document-title INTEGER ::= 256
+#
+#    ub-document-version INTEGER ::= 256
+#
+#    ub-favourite-drink INTEGER ::= 256
+#
+#    ub-host INTEGER ::= 256
+#
+#    ub-information INTEGER ::= 2048
+#
+#    ub-unique-identifier INTEGER ::= 256
+#
+#    ub-personal-title INTEGER ::= 256
+#
+#    ub-photo INTEGER ::= 250000
+#
+#    ub-rfc822-mailbox INTEGER ::= 256
+#
+#    ub-room-number INTEGER ::= 256
+#
+#    ub-text-or-address INTEGER ::= 256
+#
+#    ub-user-class INTEGER ::= 256
+#
+#    ub-user-identifier INTEGER ::= 256
+#
+#    ub-organizational-status INTEGER ::= 256
+#
+#    ub-janet-mailbox INTEGER ::= 256
+#
+#    ub-building-name INTEGER ::= 256
+#
+#    ub-personal-signature ::= 50000
+#
+#    ub-audio INTEGER ::= 250000
+#
+# [remainder of memo trimmed]
+
diff --git a/servers/slapd/schema/inetorgperson.schema b/servers/slapd/schema/inetorgperson.schema
new file mode 100644 (file)
index 0000000..98fed85
--- /dev/null
@@ -0,0 +1,145 @@
+# $OpenLDAP$
+#
+# InetOrgPerson (RFC 2798)
+#
+# Depends upon
+#   The COSINE and Internet X.500 Schema [RFC1274]
+#   
+#   Definition of an X.500 Attribute Type and an Object Class to Hold
+#   Uniform Resource Identifiers (URIs) [RFC2079]
+#      (core.schema)
+#   
+#   A Summary of the X.500(96) User Schema for use with LDAPv3 [RFC2256]
+#      (core.schema)
+#
+#   and X.500 pilot schema
+   
+
+# carLicense
+# This multivalued field is used to record the values of the license or
+# registration plate associated with an individual.
+attributetype ( 2.16.840.1.113730.3.1.1
+       NAME 'carLicense'
+       DESC 'vehicle license or registration plate'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+# departmentNumber
+# Code for department to which a person belongs.  This can also be
+# strictly numeric (e.g., 1234) or alphanumeric (e.g., ABC/123).
+attributetype ( 2.16.840.1.113730.3.1.2
+       NAME 'departmentNumber'
+       DESC 'identifies a department within an organization'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+# displayName
+# When displaying an entry, especially within a one-line summary list, it
+# is useful to be able to identify a name to be used.  Since other attri-
+# bute types such as 'cn' are multivalued, an additional attribute type is
+# needed.  Display name is defined for this purpose.
+attributetype ( 2.16.840.1.113730.3.1.241
+       NAME 'displayName'
+       DESC 'preferred name of a person to be used when displaying entries'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+       SINGLE-VALUE )
+
+# employeeNumber
+# Numeric or alphanumeric identifier assigned to a person, typically based
+# on order of hire or association with an organization.  Single valued.
+attributetype ( 2.16.840.1.113730.3.1.3
+       NAME 'employeeNumber'
+       DESC 'numerically identifies an employee within an organization'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+       SINGLE-VALUE )
+
+# employeeType
+# Used to identify the employer to employee relationship.  Typical values
+# used will be "Contractor", "Employee", "Intern", "Temp", "External", and
+# "Unknown" but any value may be used.
+attributetype ( 2.16.840.1.113730.3.1.4
+       NAME 'employeeType'
+       DESC 'type of employment for a person'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+# jpegPhoto
+# Used to store one or more images of a person using the JPEG File
+# Interchange Format [JFIF].
+# Note that the jpegPhoto attribute type was defined for use in the
+# Internet X.500 pilots but no referencable definition for it could be
+# located.    
+attributetype ( 0.9.2342.19200300.100.1.60
+       NAME 'jpegPhoto'
+       DESC 'a JPEG image'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.28 )
+       
+
+# preferredLanguage
+# Used to indicate an individual's preferred written or spoken
+# language.  This is useful for international correspondence or human-
+# computer interaction.  Values for this attribute type MUST conform to
+# the definition of the Accept-Language header field defined in
+# [RFC2068] with one exception:  the sequence "Accept-Language" ":"
+# should be omitted.  This is a single valued attribute type.
+
+attributetype ( 2.16.840.1.113730.3.1.39
+       NAME 'preferredLanguage'
+       DESC 'preferred written or spoken language for a person'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+       SINGLE-VALUE )
+
+# userSMIMECertificate
+# A PKCS#7 [RFC2315] SignedData, where the content that is signed is
+# ignored by consumers of userSMIMECertificate values.  It is
+# recommended that values have a `contentType' of data with an absent
+# `content' field.  Values of this attribute contain a person's entire
+# certificate chain and an smimeCapabilities field [RFC2633] that at a
+# minimum describes their SMIME algorithm capabilities.  Values for
+# this attribute are to be stored and requested in binary form, as
+# 'userSMIMECertificate;binary'.  If available, this attribute is
+# preferred over the userCertificate attribute for S/MIME applications.
+
+attributetype ( 2.16.840.1.113730.3.1.40
+       NAME 'userSMIMECertificate'
+       DESC 'PKCS#7 SignedData used to support S/MIME'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 )
+
+# userPKCS12
+# PKCS #12 [PKCS12] provides a format for exchange of personal identity
+# information.  When such information is stored in a directory service,
+# the userPKCS12 attribute should be used. This attribute is to be stored
+# and requested in binary form, as 'userPKCS12;binary'.  The attribute
+# values are PFX PDUs stored as binary data.
+attributetype ( 2.16.840.1.113730.3.1.216
+       NAME 'userPKCS12'
+       DESC 'PKCS #12 PFX PDU for exchange of personal identity information'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 )
+
+
+# inetOrgPerson
+# The inetOrgPerson represents people who are associated with an
+# organization in some way.  It is a structural class and is derived
+# from the organizationalPerson class which is defined in X.521 [X521].
+objectclass    ( 2.16.840.1.113730.3.2.2
+    NAME 'inetOrgPerson'
+    SUP organizationalPerson
+    STRUCTURAL
+       MAY (
+               audio $ businessCategory $ carLicense $ departmentNumber $
+               displayName $ employeeNumber $ employeeType $ givenName $
+               homePhone $ homePostalAddress $ initials $ jpegPhoto $
+               labeledURI $ mail $ manager $ mobile $ o $ pager $
+               photo $ roomNumber $ secretary $ uid $ userCertificate $
+               x500uniqueIdentifier $ preferredLanguage $
+               userSMIMECertificate $ userPKCS12
+       ) )  
diff --git a/servers/slapd/schema/internet_mail.at.conf b/servers/slapd/schema/internet_mail.at.conf
deleted file mode 100644 (file)
index e67ea79..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-# $OpenLDAP$
-#
-# By:          Juan C. Gomez / gomez@engr.sgi.com
-# Date:                May/1999
-# Source:      draft-lachman-ldap-mail-routing-03.txt
-# ---------------------------------------------------------
-#
-# Written by Juan C. Gomez and placed into the public domain.
-# This file is not subject to any license of SGI.
-#
-# ---------------------------------------------------------
-#
-# Attribute specifications for using LDAP as a back-end
-# for mail routing. As specified in:
-#
-# *********************************************************
-# draft-lachman-ldap-mail-routing-03.txt
-# By   :       H. Lachman @ Netscape Communications Corp.
-# Date :       October 1998
-#      "LDAP Schema Definitions for Intranet Mail Routing -
-#       The mailRecipient Object Class"
-# *********************************************************
-#
-
-
-
-
-#
-# This is here because, perhaps in the future, we will have
-# richer schema support in OpenLDAP.
-#
-# ----------------------FORMAL DESCRIPTION-----------------
-#
-# OID          0.9.2342.19200300.100.1.3
-# NAME         'mail'
-# DESC         'RFC 822 email address of this recipient'
-# EQUALITY     caseIgnoreIA5Match
-# SYNTAX       '1.3.6.1.4.1.1466.115.121.1.26{256}' SINGLE-VALUE
-#
-#
-# OID          2.16.840.1.113730.3.1.13
-# NAME         'mailAlternateAddress'
-# DESC         'alternate RFC 822 email address of this recipient'
-# EQUALITY     caseIgnoreIA5Match
-# SYNTAX       '1.3.6.1.4.1.1466.115.121.1.26{256}'
-#
-#
-# OID          2.16.840.1.113730.3.1.18
-# NAME         'mailHost'
-# DESC         'fully qualified hostname of the SMTP MTA that
-#               handles messages for this recipient'
-# EQUALITY     caseIgnoreIA5Match
-# SYNTAX       '1.3.6.1.4.1.1466.115.121.1.26{256}' SINGLE-VALUE
-#
-#
-# OID          2.16.840.1.113730.3.1.47
-# NAME         'mailRoutingAddress'
-# DESC         'RFC 822 address to use when routing messages to
-#                the SMTP MTA of this recipient'
-# EQUALITY     caseIgnoreIA5Match
-# SYNTAX       '1.3.6.1.4.1.1466.115.121.1.26{256}' SINGLE-VALUE
-#
-# ----------------------END FORMAL DESCRIPTION-----------------
-
-
-
-
-attribute      mail                    cis
-attribute      mailAlternateAddress    cis
-attribute      mailHost                cis
-attribute      mailRoutingAddress      cis
diff --git a/servers/slapd/schema/internet_mail.oc.conf b/servers/slapd/schema/internet_mail.oc.conf
deleted file mode 100644 (file)
index a707778..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-# $OpenLDAP$
-#
-# By:          Juan C. Gomez / gomez@engr.sgi.com
-# Date:                May/1999
-# Source:      draft-lachman-ldap-mail-routing-03.txt
-# ---------------------------------------------------------
-#
-# Written by Juan C. Gomez and placed into the public domain.
-# This file is not subject to any license of SGI.
-#
-# ---------------------------------------------------------
-#
-# Object class specifications for using LDAP as a back-end 
-# for mail routing. As specified in:
-#
-# *********************************************************
-# draft-lachman-ldap-mail-routing-03.txt
-# By   :       H. Lachman @ Netscape Communications Corp.
-# Date :       October 1998
-#      "LDAP Schema Definitions for Intranet Mail Routing -
-#       The mailRecipient Object Class"
-# *********************************************************
-#
-
-
-
-
-#
-# This is here because, perhaps in the future, we will have
-# richer schema support in OpenLDAP.
-#
-# ----------------------FORMAL DESCRIPTION-----------------
-#
-#
-# OID  2.16.840.1.113730.3.2.3
-# NAME  'mailRecipient' SUP top AUXILIARY
-# MAY  ( cn $ mail $ mailAlternateAddress $ mailHost $
-#      mailRoutingAddress )
-#
-# ----------------------END FORMAL DESCRIPTION-------------
-
-objectclass    mailRecipient
-       requires
-               objectClass
-       allows
-               cn,
-               mail,
-               mailAlternateAddress,
-               mailHost,
-               mailRoutingAddress
diff --git a/servers/slapd/schema/microsoft.ext.schema b/servers/slapd/schema/microsoft.ext.schema
new file mode 100644 (file)
index 0000000..44612c2
--- /dev/null
@@ -0,0 +1,5383 @@
+# $OpenLDAP$
+
+# This file is provided for informational purposes only.
+
+# These definitions are from Microsoft's Active Directory.
+# They were gathered using the subschemaSubentry object of
+# Windows 2000 Advanced Server Release Candidate 2.
+
+# These definitions are "extensions" to the subschemaSubentry
+# object.  Most just provide an OID/name to GUID mapping.
+
+dITContentRule ( 1.2.840.113556.1.5.24
+       NAME 'remoteMailRecipient'
+       AUX ( mailRecipient ))
+
+dITContentRule ( 1.2.840.113556.1.5.67
+       NAME 'domainDNS'
+       AUX ( samDomain ))
+
+dITContentRule ( 1.2.840.113556.1.5.3
+       NAME 'samDomain'
+       AUX ( samDomainBase ))
+
+dITContentRule ( 1.2.840.113556.1.5.15
+       NAME 'contact'
+       AUX ( mailRecipient ))
+
+dITContentRule ( 1.2.840.113556.1.5.8
+       NAME 'group'
+       AUX ( securityPrincipal $ mailRecipient ))
+
+dITContentRule ( 1.2.840.113556.1.5.9
+       NAME 'user'
+       AUX ( mailRecipient $ securityPrincipal ))
+
+dITContentRule ( 1.2.840.113556.1.5.4
+       NAME 'builtinDomain'
+       AUX ( samDomainBase ))
+
+extendedClassInfo ( 1.2.840.113556.1.5.24
+       NAME 'remoteMailRecipient'
+       CLASS-GUID 'A97A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.49
+       NAME 'packageRegistration'
+       CLASS-GUID 'A67A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.161
+       NAME 'mSMQQueue'
+       CLASS-GUID '43C30D9A00C1D111BBC50080C76670C0' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.81
+       NAME 'rpcServer'
+       CLASS-GUID 'E01B6188F48CD011AFDA00C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.5
+       NAME 'samServer'
+       CLASS-GUID 'AD7A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.156
+       NAME 'rRASAdministrationDictionary'
+       CLASS-GUID 'AE989BF38D93D111AEBD0000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.138
+       NAME 'aCSSubnet'
+       CLASS-GUID '8912567F0153D111A9C50000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.137
+       NAME 'aCSPolicy'
+       CLASS-GUID '8812567F0153D111A9C50000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.154
+       NAME 'nTFRSSubscriptions'
+       CLASS-GUID '8725132A7393D111AEBC0000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.176
+       NAME 'msExchConfigurationContainer'
+       CLASS-GUID '58683DD0F406D211AA5300C04FD7D83A' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.141
+       NAME 'interSiteTransport'
+       CLASS-GUID '7673D9267060D111A9C60000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.3.23
+       NAME 'container'
+       CLASS-GUID '8B7A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.67
+       NAME 'domainDNS'
+       CLASS-GUID '5B5A1919A06DD011AFD300C04FD930C9' )
+
+extendedClassInfo ( 2.5.20.1
+       NAME 'subSchema'
+       CLASS-GUID '61328B5A8DC3D111BBC90080C76670C0' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.3
+       NAME 'samDomain'
+       CLASS-GUID '907A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.152
+       NAME 'intellimirrorGroup'
+       CLASS-GUID '86303807DF91D111AEBC0000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.132
+       NAME 'dHCPClass'
+       CLASS-GUID '56273D96BE48D111A9C30000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.7000.56
+       NAME 'ipsecBase'
+       CLASS-GUID '25F80FB47A42D111A9C20000F80367C1' )
+
+extendedClassInfo ( 2.5.6.5
+       NAME 'organizationalUnit'
+       CLASS-GUID 'A57A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.11
+       NAME 'comConnectionPoint'
+       CLASS-GUID '857A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 2.5.6.8
+       NAME 'organizationalRole'
+       CLASS-GUID 'BF74DFA8EAC5D111BBCB0080C76670C0' )
+
+extendedClassInfo ( 2.5.6.11
+       NAME 'applicationProcess'
+       CLASS-GUID '0B25D45F6212D011A06000AA006C33ED' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.77
+       NAME 'controlAccessRight'
+       CLASS-GUID '1E939782D386D011AFDA00C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.130
+       NAME 'indexServerCatalog'
+       CLASS-GUID '8ACBFD7B0748D111A9C30000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.140
+       NAME 'interSiteTransportContainer'
+       CLASS-GUID '7573D9267060D111A9C60000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.27
+       NAME 'rpcEntry'
+       CLASS-GUID 'AC7A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.80
+       NAME 'rpcGroup'
+       CLASS-GUID 'DF1B6188F48CD011AFDA00C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.3.30
+       NAME 'computer'
+       CLASS-GUID '867A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.189
+       NAME 'mS-SQL-OLAPDatabase'
+       CLASS-GUID '1A03AF20EFCCD21199930000F87A57D4' )
+
+extendedClassInfo ( 1.2.840.113556.1.3.11
+       NAME 'crossRef'
+       CLASS-GUID '8D7A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.147
+       NAME 'siteLink'
+       CLASS-GUID 'DE2C0CD55189D111AEBC0000F80367C1' )
+
+extendedClassInfo ( 2.5.6.3
+       NAME 'locality'
+       CLASS-GUID 'A07A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.121
+       NAME 'ipsecNFA'
+       CLASS-GUID '29F80FB47A42D111A9C20000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.92
+       NAME 'linkTrackVolEntry'
+       CLASS-GUID 'F60CACDD8FAFD011AFEB00C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.93
+       NAME 'linkTrackOMTEntry'
+       CLASS-GUID 'F70CACDD8FAFD011AFEB00C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.6
+       NAME 'securityPrincipal'
+       CLASS-GUID 'B07A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.162
+       NAME 'mSMQConfiguration'
+       CLASS-GUID '44C30D9A00C1D111BBC50080C76670C0' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.10
+       NAME 'classRegistration'
+       CLASS-GUID '827A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 2.5.6.12
+       NAME 'applicationEntity'
+       CLASS-GUID '4FEEDF3FF447D111A9C30000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.191
+       NAME 'aCSResourceLimits'
+       CLASS-GUID '049B892E3428D31191D40000F87A57D4' )
+
+extendedClassInfo ( 2.5.6.10
+       NAME 'residentialPerson'
+       CLASS-GUID 'D674DFA8EAC5D111BBCB0080C76670C0' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.7000.53
+       NAME 'crossRefContainer'
+       CLASS-GUID 'E0609EEFF756D111A9C60000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.120
+       NAME 'ipsecISAKMPPolicy'
+       CLASS-GUID '28F80FB47A42D111A9C20000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.26
+       NAME 'rpcProfileElement'
+       CLASS-GUID 'CF5396F2D07AD011AFD600C04FD930C9' )
+
+extendedClassInfo ( 2.5.6.2
+       NAME 'country'
+       CLASS-GUID '8C7A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.188
+       NAME 'mS-SQL-SQLDatabase'
+       CLASS-GUID '4A69081DEFCCD21199930000F87A57D4' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.94
+       NAME 'serviceAdministrationPoint'
+       CLASS-GUID '2331B1B72EB8D011AFEE0000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.85
+       NAME 'dnsZone'
+       CLASS-GUID '8B1EFAE0459BD011AFDD00C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.33
+       NAME 'storage'
+       CLASS-GUID 'B57A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.7000.47
+       NAME 'nTDSDSA'
+       CLASS-GUID 'ABFFF8F09111D011A06000AA006C33ED' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.15
+       NAME 'contact'
+       CLASS-GUID 'D01EB45C4C0ED011A28600AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.86
+       NAME 'dnsNode'
+       CLASS-GUID '8C1EFAE0459BD011AFDD00C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.104
+       NAME 'meeting'
+       CLASS-GUID '94CCB611C448D111A9C30000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.69
+       NAME 'nTDSSiteSettings'
+       CLASS-GUID '5D5A1919A06DD011AFD300C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.151
+       NAME 'intellimirrorSCP'
+       CLASS-GUID '85303807DF91D111AEBC0000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.7000.48
+       NAME 'serversContainer'
+       CLASS-GUID 'C0AC80F7F056D111A9C60000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.185
+       NAME 'mS-SQL-OLAPServer'
+       CLASS-GUID 'EA187E0CEFCCD21199930000F87A57D4' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.179
+       NAME 'mSMQMigratedUser'
+       CLASS-GUID '976977503D3CD21190CC00C04FD91AB1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.73
+       NAME 'rpcServerElement'
+       CLASS-GUID 'D05396F2D07AD011AFD600C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.97
+       NAME 'physicalLocation'
+       CLASS-GUID '2231B1B72EB8D011AFEE0000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.42
+       NAME 'dfsConfiguration'
+       CLASS-GUID 'F2F947842710D011A05F00AA006C33ED' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.84
+       NAME 'displaySpecifier'
+       CLASS-GUID '8A1EFAE0459BD011AFDD00C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.52
+       NAME 'fileLinkTracking'
+       CLASS-GUID '292271DDE410D011A05F00AA006C33ED' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.146
+       NAME 'remoteStorageServicePoint'
+       CLASS-GUID 'BDC5392A6089D111AEBC0000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.36
+       NAME 'volume'
+       CLASS-GUID 'BB7A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.17
+       NAME 'server'
+       CLASS-GUID '927A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 2.5.6.6
+       NAME 'person'
+       CLASS-GUID 'A77A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.96
+       NAME 'subnet'
+       CLASS-GUID '2431B1B72EB8D011AFEE0000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.129
+       NAME 'rIDSet'
+       CLASS-GUID '89CBFD7B0748D111A9C30000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.28
+       NAME 'secret'
+       CLASS-GUID 'AE7A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.66
+       NAME 'domain'
+       CLASS-GUID '5A5A1919A06DD011AFD300C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.184
+       NAME 'mS-SQL-SQLServer'
+       CLASS-GUID '78C8F605EFCCD21199930000F87A57D4' )
+
+extendedClassInfo ( 2.5.6.14
+       NAME 'device'
+       CLASS-GUID '8E7A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.155
+       NAME 'nTFRSSubscriber'
+       CLASS-GUID '8825132A7393D111AEBC0000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.14
+       NAME 'connectionPoint'
+       CLASS-GUID 'CF1EB45C4C0ED011A28600AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.102
+       NAME 'nTFRSReplicaSet'
+       CLASS-GUID '3A8045526ACAD011AFFF0000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.95
+       NAME 'subnetContainer'
+       CLASS-GUID '2531B1B72EB8D011AFEE0000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.3.59
+       NAME 'displayTemplate'
+       CLASS-GUID '0C25D45F6212D011A06000AA006C33ED' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.30
+       NAME 'serviceInstance'
+       CLASS-GUID 'B27A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.3.14
+       NAME 'attributeSchema'
+       CLASS-GUID '807A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.3.58
+       NAME 'addressTemplate'
+       CLASS-GUID '0A25D45F6212D011A06000AA006C33ED' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.8
+       NAME 'group'
+       CLASS-GUID '9C7A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.76
+       NAME 'foreignSecurityPrincipal'
+       CLASS-GUID '121CE3893085D011AFDA00C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.43
+       NAME 'fTDfs'
+       CLASS-GUID 'F3F947842710D011A05F00AA006C33ED' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.91
+       NAME 'linkTrackObjectMoveTable'
+       CLASS-GUID 'F50CACDD8FAFD011AFEB00C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.150
+       NAME 'rRASAdministrationConnectionPoint'
+       CLASS-GUID 'BEC5392A6089D111AEBC0000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.1
+       NAME 'securityObject'
+       CLASS-GUID 'AF7A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.107
+       NAME 'sitesContainer'
+       CLASS-GUID 'DA17417A67CDD011AFFF0000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.71
+       NAME 'nTDSConnection'
+       CLASS-GUID '605A1919A06DD011AFD300C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.190
+       NAME 'mS-SQL-OLAPCube'
+       CLASS-GUID '6A50F00928CDD21199930000F87A57D4' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.148
+       NAME 'siteLinkBridge'
+       CLASS-GUID 'DF2C0CD55189D111AEBC0000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.9
+       NAME 'user'
+       CLASS-GUID 'BA7A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.68
+       NAME 'applicationSiteSettings'
+       CLASS-GUID '5C5A1919A06DD011AFD300C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.31
+       NAME 'site'
+       CLASS-GUID 'B37A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.89
+       NAME 'nTFRSSettings'
+       CLASS-GUID 'C2AC80F7F056D111A9C60000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.20
+       NAME 'leaf'
+       CLASS-GUID '9E7A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.34
+       NAME 'trustedDomain'
+       CLASS-GUID 'B87A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.12
+       NAME 'configuration'
+       CLASS-GUID '877A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.163
+       NAME 'mSMQEnterpriseSettings'
+       CLASS-GUID '45C30D9A00C1D111BBC50080C76670C0' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.4
+       NAME 'builtinDomain'
+       CLASS-GUID '817A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.3.46
+       NAME 'mailRecipient'
+       CLASS-GUID 'A17A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.2
+       NAME 'samDomainBase'
+       CLASS-GUID '917A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 2.5.6.0
+       NAME 'top'
+       CLASS-GUID 'B77A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 2.5.6.16
+       NAME 'certificationAuthority'
+       CLASS-GUID '50EEDF3FF447D111A9C30000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.126
+       NAME 'serviceConnectionPoint'
+       CLASS-GUID 'C10E6328D541D111A9C10000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.119
+       NAME 'ipsecNegotiationPolicy'
+       CLASS-GUID '27F80FB47A42D111A9C20000F80367C1' )
+
+extendedClassInfo ( 2.5.6.13
+       NAME 'dSA'
+       CLASS-GUID '52EEDF3FF447D111A9C30000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.3.9
+       NAME 'dMD'
+       CLASS-GUID '8F7A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.165
+       NAME 'mSMQSettings'
+       CLASS-GUID '47C30D9A00C1D111BBC50080C76670C0' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.183
+       NAME 'dSUISettings'
+       CLASS-GUID '140FB109936FD21199050000F87A57D4' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.177
+       NAME 'pKICertificateTemplate'
+       CLASS-GUID 'A29C20E5BA3BD21190CC00C04FD91AB1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.164
+       NAME 'mSMQSiteLink'
+       CLASS-GUID '46C30D9A00C1D111BBC50080C76670C0' )
+
+extendedClassInfo ( 2.5.6.9
+       NAME 'groupOfNames'
+       CLASS-GUID '9D7A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 2.5.6.4
+       NAME 'organization'
+       CLASS-GUID 'A37A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.139
+       NAME 'lostAndFound'
+       CLASS-GUID '7186AB520957D111A9C60000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.136
+       NAME 'rpcContainer'
+       CLASS-GUID '42282180DC4BD111A9C40000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.18
+       NAME 'domainPolicy'
+       CLASS-GUID '997A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.29
+       NAME 'serviceClass'
+       CLASS-GUID 'B17A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.78
+       NAME 'licensingSiteSettings'
+       CLASS-GUID '7DF1E81BFFA9D011AFE200C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.59
+       NAME 'fileLinkTrackingEntry'
+       CLASS-GUID 'EDB24E8E1247D011A1A000C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.106
+       NAME 'queryPolicy'
+       CLASS-GUID '7570CC83A7CCD011AFFF0000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.53
+       NAME 'typeLibrary'
+       CLASS-GUID 'E21614286819D011A28F00AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.72
+       NAME 'nTDSService'
+       CLASS-GUID '5F5A1919A06DD011AFD300C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.153
+       NAME 'nTFRSMember'
+       CLASS-GUID '8625132A7393D111AEBC0000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.98
+       NAME 'ipsecPolicy'
+       CLASS-GUID '2131B1B72EB8D011AFEE0000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.118
+       NAME 'ipsecFilter'
+       CLASS-GUID '26F80FB47A42D111A9C20000F80367C1' )
+
+extendedClassInfo ( 2.5.6.19
+       NAME 'cRLDistributionPoint'
+       CLASS-GUID 'CA587716F347D111A9C30000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.3.13
+       NAME 'classSchema'
+       CLASS-GUID '837A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.175
+       NAME 'infrastructureUpdate'
+       CLASS-GUID '890DF92D9F00D211AA4C00C04FD7D83A' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.157
+       NAME 'groupPolicyContainer'
+       CLASS-GUID 'C23B0EF3F09FD111B6030000F80367C1' )
+
+extendedClassInfo ( 2.5.6.7
+       NAME 'organizationalPerson'
+       CLASS-GUID 'A47A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.74
+       NAME 'categoryRegistration'
+       CLASS-GUID '9D0E6C7D207ED011AFD600C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.178
+       NAME 'pKIEnrollmentService'
+       CLASS-GUID '92A64AEEBA3BD21190CC00C04FD91AB1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.187
+       NAME 'mS-SQL-SQLPublication'
+       CLASS-GUID '4EF6C217EFCCD21199930000F87A57D4' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.90
+       NAME 'linkTrackVolumeTable'
+       CLASS-GUID 'F40CACDD8FAFD011AFEB00C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.125
+       NAME 'addressBookContainer'
+       CLASS-GUID '0FF6743E733ED111A9C00000F80367C1' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.23
+       NAME 'printQueue'
+       CLASS-GUID 'A87A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.44
+       NAME 'classStore'
+       CLASS-GUID '847A96BFE60DD011A28500AA003049E2' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.186
+       NAME 'mS-SQL-SQLRepository'
+       CLASS-GUID '5C3CD411EFCCD21199930000F87A57D4' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.82
+       NAME 'rpcProfile'
+       CLASS-GUID 'E11B6188F48CD011AFDA00C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.83
+       NAME 'rIDManager'
+       CLASS-GUID '8D1817663C8FD011AFDA00C04FD930C9' )
+
+extendedClassInfo ( 1.2.840.113556.1.5.7000.49
+       NAME 'applicationSettings'
+       CLASS-GUID 'C1AC80F7F056D111A9C60000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.856
+       NAME 'netbootNewMachineOU'
+       PROPERTY-GUID '7D303807DF91D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.13
+       NAME 'builtinCreationTime'
+       PROPERTY-GUID '2F7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1335
+       NAME 'pKIEnrollmentAccess'
+       PROPERTY-GUID '78E26B92F956D21190D000C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1333
+       NAME 'pKIExtendedKeyUsage'
+       PROPERTY-GUID 'F66A97189E3BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1123
+       NAME 'msNPCalledStationID'
+       PROPERTY-GUID '89900CDBF2C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.539
+       NAME 'initialAuthIncoming'
+       PROPERTY-GUID '238045526ACAD011AFFF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.44
+       NAME 'generationQualifier'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID '04587716F347D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.370
+       NAME 'objectClassCategory'
+       RANGE-LOWER '0'
+       RANGE-UPPER '3'
+       PROPERTY-GUID 'E67996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.41
+       NAME 'generatedConnection'
+       PROPERTY-GUID '7A7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.911
+       NAME 'allowedChildClasses'
+       PROPERTY-GUID '42D97A9A53CAD111BBD00080C76670C0'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.68
+       NAME 'machineArchitecture'
+       PROPERTY-GUID 'AF7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.767
+       NAME 'aCSMaxPeakBandwidth'
+       PROPERTY-GUID '8412567F0153D111A9C50000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.72
+       NAME 'marshalledInterface'
+       PROPERTY-GUID 'B97996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.368
+       NAME 'rIDManagerReference'
+       PROPERTY-GUID '861817663C8FD011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.770
+       NAME 'aCSEnableACSService'
+       PROPERTY-GUID '8712567F0153D111A9C50000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1237
+       NAME 'mSMQRoutingService'
+       PROPERTY-GUID '810DF92D9F00D211AA4C00C04FD7D83A'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1405
+       NAME 'mS-SQL-AllowQueuedUpdatingSubscription'
+       PROPERTY-GUID '80CA58C44BD3D211999A0000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.648
+       NAME 'primaryTelexNumber'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID '21C19602DA40D111A9C00000F80367C1'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.8
+       NAME 'userAccountControl'
+       PROPERTY-GUID '687A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '0042164CC020D011A76800AA006E0529'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.563
+       NAME 'shellPropertyPages'
+       PROPERTY-GUID '398045526ACAD011AFFF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.4
+       NAME 'replUpToDateVector'
+       PROPERTY-GUID '167A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.484
+       NAME 'fRSDirectoryFilter'
+       RANGE-LOWER '0'
+       RANGE-UPPER '2048'
+       PROPERTY-GUID '71F1E81BFFA9D011AFE200C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.230
+       NAME 'printSeparatorFile'
+       PROPERTY-GUID 'C61614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1329
+       NAME 'pKIMaxIssuingDepth'
+       PROPERTY-GUID 'FADEBFF09D3BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1307
+       NAME 'accountNameHistory'
+       PROPERTY-GUID 'EC521903723BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1386
+       NAME 'mS-SQL-GPSLongitude'
+       PROPERTY-GUID '947C57B7EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.562
+       NAME 'adminPropertyPages'
+       PROPERTY-GUID '388045526ACAD011AFFF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.121
+       NAME 'securityIdentifier'
+       PROPERTY-GUID '2F7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.166
+       NAME 'groupMembershipSAM'
+       PROPERTY-GUID '807996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.659
+       NAME 'serviceDNSNameType'
+       RANGE-LOWER '1'
+       RANGE-UPPER '256'
+       PROPERTY-GUID 'BA0E6328D541D111A9C10000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.585
+       NAME 'meetingIsEncrypted'
+       PROPERTY-GUID '8ECCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1400
+       NAME 'mS-SQL-Applications'
+       PROPERTY-GUID 'EAA2CDFBEECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.330
+       NAME 'lastUpdateSequence'
+       PROPERTY-GUID '9C0E6C7D207ED011AFD600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.50
+       NAME 'lastContentIndexed'
+       PROPERTY-GUID '957996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.567
+       NAME 'meetingDescription'
+       PROPERTY-GUID '7ECCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.880
+       NAME 'fRSTimeLastCommand'
+       PROPERTY-GUID '8325132A7393D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.83
+       NAME 'monikerDisplayName'
+       PROPERTY-GUID 'C87996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.321
+       NAME 'requiredCategories'
+       RANGE-LOWER '16'
+       RANGE-UPPER '16'
+       PROPERTY-GUID '930E6C7D207ED011AFD600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.813
+       NAME 'upgradeProductCode'
+       RANGE-LOWER '0'
+       RANGE-UPPER '16'
+       PROPERTY-GUID '1283E1D93989D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.774
+       NAME 'aCSMaxNoOfLogFiles'
+       PROPERTY-GUID '9C55B31CD056D111A9C60000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1370
+       NAME 'mS-SQL-CharacterSet'
+       PROPERTY-GUID 'A6776169EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.578
+       NAME 'meetingContactInfo'
+       PROPERTY-GUID '87CCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1397
+       NAME 'mS-SQL-CreationDate'
+       PROPERTY-GUID '5447E1EDEECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.32
+       NAME 'domainPolicyObject'
+       PROPERTY-GUID '5D7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.703
+       NAME 'dhcpObjDescription'
+       PROPERTY-GUID '44273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.573
+       NAME 'meetingApplication'
+       PROPERTY-GUID '83CCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.518
+       NAME 'defaultHidingValue'
+       PROPERTY-GUID '1631B1B72EB8D011AFEE0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.875
+       NAME 'fRSMemberReference'
+       PROPERTY-GUID '7E25132A7393D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.701
+       NAME 'dhcpIdentification'
+       PROPERTY-GUID '42273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.135
+       NAME 'trustAuthOutgoing'
+       RANGE-LOWER '0'
+       RANGE-UPPER '32767'
+       PROPERTY-GUID '5F7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.197
+       NAME 'systemMustContain'
+       PROPERTY-GUID '457A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1412
+       NAME 'primaryGroupToken'
+       PROPERTY-GUID '3887EDC0FD7E814484D966D2DB8BE369'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.118
+       NAME 'rpcNsProfileEntry'
+       PROPERTY-GUID '287A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.129
+       NAME 'trustAuthIncoming'
+       RANGE-LOWER '0'
+       RANGE-UPPER '32767'
+       PROPERTY-GUID '597A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1225
+       NAME 'mSMQPrevSiteGates'
+       PROPERTY-GUID '750DF92D9F00D211AA4C00C04FD7D83A'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.607
+       NAME 'queryPolicyObject'
+       PROPERTY-GUID '03A4AEE15BCDD011AFFF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.712
+       NAME 'optionDescription'
+       PROPERTY-GUID '4D273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1314
+       NAME 'aCSMaximumSDUSize'
+       PROPERTY-GUID 'F9D8A287903BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.530
+       NAME 'nonSecurityMember'
+       PROPERTY-GUID '188045526ACAD011AFFF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.31
+       NAME 'fRSReplicaSetType'
+       PROPERTY-GUID '6B73D9267060D111A9C60000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.763
+       NAME 'aCSTotalNoOfFlows'
+       PROPERTY-GUID '8012567F0153D111A9C50000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.18.10
+       NAME 'subSchemaSubEntry'
+       PROPERTY-GUID '4DD97A9A53CAD111BBD00080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.915
+       NAME 'possibleInferiors'
+       PROPERTY-GUID '4CD97A9A53CAD111BBD00080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.851
+       NAME 'netbootMaxClients'
+       PROPERTY-GUID '78303807DF91D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1385
+       NAME 'mS-SQL-GPSLatitude'
+       PROPERTY-GUID '0EBA22B2EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.765
+       NAME 'aCSPermissionBits'
+       PROPERTY-GUID '8212567F0153D111A9C50000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.926
+       NAME 'mSMQTransactional'
+       PROPERTY-GUID '29C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1390
+       NAME 'mS-SQL-Description'
+       PROPERTY-GUID '3C608683EFCCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.913
+       NAME 'allowedAttributes'
+       PROPERTY-GUID '40D97A9A53CAD111BBD00080C76670C0'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.491
+       NAME 'fRSFaultCondition'
+       RANGE-LOWER '1'
+       RANGE-UPPER '16'
+       PROPERTY-GUID '78F1E81BFFA9D011AFE200C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.54
+       NAME 'tombstoneLifetime'
+       PROPERTY-GUID '60A8C3167312D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.809
+       NAME 'remoteStorageGUID'
+       PROPERTY-GUID 'B0C5392A6089D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.644
+       NAME 'showInAddressBook'
+       PROPERTY-GUID '0EF6743E733ED111A9C00000F80367C1'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.213
+       NAME 'defaultClassStore'
+       PROPERTY-GUID '487996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.577
+       NAME 'meetingOriginator'
+       PROPERTY-GUID '86CCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.656
+       NAME 'userPrincipalName'
+       PROPERTY-GUID 'BB0E6328D541D111A9C10000F80367C1'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1316
+       NAME 'aCSMinimumLatency'
+       PROPERTY-GUID 'FBFE1795903BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.617
+       NAME 'homePostalAddress'
+       RANGE-LOWER '1'
+       RANGE-UPPER '4096'
+       PROPERTY-GUID '81577716F347D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.638
+       NAME 'isPrivilegeHolder'
+       PROPERTY-GUID '9C5B4019FA3CD111A9C00000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.533
+       NAME 'fRSReplicaSetGUID'
+       RANGE-LOWER '16'
+       RANGE-UPPER '16'
+       PROPERTY-GUID '1A8045526ACAD011AFFF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.371
+       NAME 'rIDAllocationPool'
+       PROPERTY-GUID '891817663C8FD011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1327
+       NAME 'pKIDefaultKeySpec'
+       PROPERTY-GUID '6EAE6C429D3BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.537
+       NAME 'dynamicLDAPServer'
+       PROPERTY-GUID '218045526ACAD011AFFF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.516
+       NAME 'serverReferenceBL'
+       PROPERTY-GUID '6E73D9267060D111A9C60000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.500
+       NAME 'fRSServiceCommand'
+       RANGE-LOWER '0'
+       RANGE-UPPER '512'
+       PROPERTY-GUID 'EE0CACDD8FAFD011AFEB00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1304
+       NAME 'sDRightsEffective'
+       PROPERTY-GUID 'A6AFDBC3DF33D21198B20000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.26
+       NAME 'registeredAddress'
+       RANGE-LOWER '1'
+       RANGE-UPPER '4096'
+       PROPERTY-GUID '107A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1249
+       NAME 'proxiedObjectName'
+       PROPERTY-GUID '02A4AEE15BCDD011AFFF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.586
+       NAME 'meetingRecurrence'
+       PROPERTY-GUID '8FCCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.251
+       NAME 'cOMTreatAsClassId'
+       RANGE-LOWER '36'
+       RANGE-UPPER '36'
+       PROPERTY-GUID 'DB1614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.49
+       NAME 'distinguishedName'
+       PROPERTY-GUID 'E47996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1245
+       NAME 'globalAddressList'
+       PROPERTY-GUID '48C754F7F406D211AA5300C04FD7D83A'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.908
+       NAME 'extendedClassInfo'
+       PROPERTY-GUID '48D97A9A53CAD111BBD00080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.459
+       NAME 'machineWidePolicy'
+       PROPERTY-GUID '4F7EA680229FD011AFDD00C04FD930C9'
+       PROPERTY-SET-GUID '018A9BA2E8C7D0119BAE00C04FD92EF5' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.356
+       NAME 'foreignIdentifier'
+       PROPERTY-GUID '1E89973E018CD011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1242
+       NAME 'dNReferenceUpdate'
+       PROPERTY-GUID '860DF92D9F00D211AA4C00C04FD7D83A'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.134
+       NAME 'trustPosixOffset'
+       PROPERTY-GUID '5E7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.36
+       NAME 'enabledConnection'
+       PROPERTY-GUID '637996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.627
+       NAME 'ipsecNFAReference'
+       PROPERTY-GUID '21F80FB47A42D111A9C20000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.86
+       NAME 'userWorkstations'
+       RANGE-LOWER '0'
+       RANGE-UPPER '1024'
+       PROPERTY-GUID 'D77996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.301
+       NAME 'garbageCollPeriod'
+       PROPERTY-GUID 'A124D45F6212D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.933
+       NAME 'mSMQComputerType'
+       PROPERTY-GUID '2EC30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.65
+       NAME 'logonWorkstation'
+       PROPERTY-GUID 'AC7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '1020205FA579D011902000C04FC2D4CF' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.921
+       NAME 'mSMQJournalQuota'
+       PROPERTY-GUID '24C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.108
+       NAME 'remoteSourceType'
+       PROPERTY-GUID '157A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.95
+       NAME 'pwdHistoryLength'
+       RANGE-LOWER '0'
+       RANGE-UPPER '65535'
+       PROPERTY-GUID '097A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '607340C7BF20D011A76800AA006E0529' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.920
+       NAME 'mSMQBasePriority'
+       PROPERTY-GUID '23C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.196
+       NAME 'systemMayContain'
+       PROPERTY-GUID '447A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1407
+       NAME 'mS-SQL-ThirdParty'
+       PROPERTY-GUID 'FC11E3C44BD3D211999A0000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1243
+       NAME 'mSMQQueueNameExt'
+       RANGE-LOWER '0'
+       RANGE-UPPER '92'
+       PROPERTY-GUID '870DF92D9F00D211AA4C00C04FD7D83A'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.485
+       NAME 'fRSUpdateTimeout'
+       PROPERTY-GUID '72F1E81BFFA9D011AFE200C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.924
+       NAME 'mSMQPrivacyLevel'
+       RANGE-LOWER '0'
+       RANGE-UPPER '2'
+       PROPERTY-GUID '27C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.615
+       NAME 'shellContextMenu'
+       PROPERTY-GUID '39D03F552EF3D011B0BC00C04FD8DCA6'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.618
+       NAME 'wellKnownObjects'
+       PROPERTY-GUID '838930058876D111ADED00C04FD8D5CD'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.789
+       NAME 'transportDLLName'
+       RANGE-LOWER '0'
+       RANGE-UPPER '1024'
+       PROPERTY-GUID '7273D9267060D111A9C60000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.458
+       NAME 'qualityOfService'
+       PROPERTY-GUID '4E7EA680229FD011AFDD00C04FD930C9'
+       PROPERTY-SET-GUID '018A9BA2E8C7D0119BAE00C04FD92EF5' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.73
+       NAME 'lockoutThreshold'
+       PROPERTY-GUID 'A67996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '607340C7BF20D011A76800AA006E0529' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.105
+       NAME 'remoteServerName'
+       PROPERTY-GUID '127A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.694
+       NAME 'previousParentCA'
+       PROPERTY-GUID '3D273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1345
+       NAME 'dSUIShellMaximum'
+       PROPERTY-GUID '6A76CAFC916FD21199050000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.15
+       NAME 'businessCategory'
+       RANGE-LOWER '1'
+       RANGE-UPPER '128'
+       PROPERTY-GUID '317996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.303
+       NAME 'notificationList'
+       PROPERTY-GUID '565A1919A06DD011AFD300C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1244
+       NAME 'addressBookRoots'
+       PROPERTY-GUID '486E0BF7F406D211AA5300C04FD7D83A'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.878
+       NAME 'fRSPrimaryMember'
+       PROPERTY-GUID '8125132A7393D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.587
+       NAME 'meetingStartTime'
+       PROPERTY-GUID '90CCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1310
+       NAME 'mSMQSiteGatesMig'
+       PROPERTY-GUID '524870E27B3BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.709
+       NAME 'dhcpReservations'
+       PROPERTY-GUID '4A273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.614
+       NAME 'adminContextMenu'
+       PROPERTY-GUID '38D03F552EF3D011B0BC00C04FD8DCA6'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1332
+       NAME 'pKIOverlapPeriod'
+       PROPERTY-GUID 'ECA319129E3BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.142
+       NAME 'winsockAddresses'
+       PROPERTY-GUID '797A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.923
+       NAME 'mSMQAuthenticate'
+       PROPERTY-GUID '26C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1344
+       NAME 'dSUIAdminMaximum'
+       PROPERTY-GUID 'E00A8DEE916FD21199050000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.848
+       NAME 'appSchemaVersion'
+       PROPERTY-GUID '65DDA7961891D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.123
+       NAME 'serviceClassInfo'
+       PROPERTY-GUID '367A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.769
+       NAME 'aCSEventLogLevel'
+       PROPERTY-GUID '8612567F0153D111A9C50000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.751
+       NAME 'userSharedFolder'
+       PROPERTY-GUID '1F029A9A5B4AD111A9C30000F80367C1'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.421
+       NAME 'domainWidePolicy'
+       PROPERTY-GUID '297EA680229FD011AFDD00C04FD930C9'
+       PROPERTY-SET-GUID 'FD899BA2E8C7D0119BAE00C04FD92EF5' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.669
+       NAME 'rIDSetReferences'
+       PROPERTY-GUID '7BCBFD7B0748D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.815
+       NAME 'canUpgradeScript'
+       PROPERTY-GUID '1483E1D93989D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.610
+       NAME 'classDisplayName'
+       PROPERTY-GUID '221C8E54A6DED011B0100000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.226
+       NAME 'adminDescription'
+       RANGE-LOWER '0'
+       RANGE-UPPER '1024'
+       PROPERTY-GUID '197996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '422FBA59A279D011902000C04FC2D3CF' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.67
+       NAME 'lSAModifiedCount'
+       PROPERTY-GUID 'AE7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.509
+       NAME 'serviceClassName'
+       PROPERTY-GUID '1D31B1B72EB8D011AFEE0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.56
+       NAME 'localPolicyFlags'
+       PROPERTY-GUID '9E7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.115
+       NAME 'rpcNsInterfaceID'
+       PROPERTY-GUID '257A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.194
+       NAME 'adminDisplayName'
+       RANGE-LOWER '1'
+       RANGE-UPPER '256'
+       PROPERTY-GUID '1A7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.753
+       NAME 'nameServiceFlags'
+       PROPERTY-GUID '40282180DC4BD111A9C40000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.589
+       NAME 'meetingBandwidth'
+       PROPERTY-GUID '92CCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.755
+       NAME 'domainIdentifier'
+       PROPERTY-GUID '7812567F0153D111A9C50000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.370
+       NAME 'rIDAvailablePool'
+       PROPERTY-GUID '881817663C8FD011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.655
+       NAME 'legacyExchangeDN'
+       PROPERTY-GUID 'BC0E6328D541D111A9C10000F80367C1'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.470
+       NAME 'trustAttributes'
+       PROPERTY-GUID '5A7EA680229FD011AFDD00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.535
+       NAME 'fRSRootSecurity'
+       RANGE-LOWER '0'
+       RANGE-UPPER '65535'
+       PROPERTY-GUID '1F8045526ACAD011AFFF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.532
+       NAME 'superiorDNSRoot'
+       PROPERTY-GUID '1D8045526ACAD011AFFF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.278
+       NAME 'printMaxYExtent'
+       PROPERTY-GUID '705F30BAE347D011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.277
+       NAME 'printMaxXExtent'
+       PROPERTY-GUID '6F5F30BAE347D011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.280
+       NAME 'printMinYExtent'
+       PROPERTY-GUID '725F30BAE347D011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.279
+       NAME 'printMinXExtent'
+       PROPERTY-GUID '715F30BAE347D011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.32
+       NAME 'attributeSyntax'
+       PROPERTY-GUID '257996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.247
+       NAME 'printAttributes'
+       PROPERTY-GUID 'D71614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.152
+       NAME 'groupAttributes'
+       PROPERTY-GUID '7E7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.816
+       NAME 'fileExtPriority'
+       PROPERTY-GUID '1583E1D93989D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.930
+       NAME 'mSMQServiceType'
+       PROPERTY-GUID '2DC30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.363
+       NAME 'operatingSystem'
+       PROPERTY-GUID '2589973E018CD011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1371
+       NAME 'mS-SQL-SortOrder'
+       PROPERTY-GUID 'C042DC6DEECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.329
+       NAME 'versionNumberLo'
+       PROPERTY-GUID '9B0E6C7D207ED011AFD600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.884
+       NAME 'msRRASAttribute'
+       PROPERTY-GUID 'AD989BF38D93D111AEBD0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.781
+       NAME 'lastKnownParent'
+       PROPERTY-GUID '7086AB520957D111A9C60000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1209
+       NAME 'shortServerName'
+       PROPERTY-GUID '0115B04519C4D111BBC90080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.60
+       NAME 'lockoutDuration'
+       PROPERTY-GUID 'A57996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '607340C7BF20D011A76800AA006E0529' )
+
+extendedAttributeInfo ( 2.5.21.2
+       NAME 'dITContentRules'
+       PROPERTY-GUID '46D97A9A53CAD111BBD00080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.232
+       NAME 'defaultPriority'
+       PROPERTY-GUID 'C81614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.754
+       NAME 'rpcNsEntryFlags'
+       PROPERTY-GUID '41282180DC4BD111A9C40000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.713
+       NAME 'optionsLocation'
+       PROPERTY-GUID '4E273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.328
+       NAME 'versionNumberHi'
+       PROPERTY-GUID '9A0E6C7D207ED011AFD600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.366
+       NAME 'rpcNsAnnotation'
+       PROPERTY-GUID 'DE1B6188F48CD011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.886
+       NAME 'purportedSearch'
+       RANGE-LOWER '0'
+       RANGE-UPPER '2048'
+       PROPERTY-GUID '504EB5B43A94D111AEBD0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.776
+       NAME 'aCSDSBMPriority'
+       PROPERTY-GUID '9E55B31CD056D111A9C60000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.961
+       NAME 'mSMQSiteForeign'
+       PROPERTY-GUID '8A9D12FD7ED5D11190A200C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.18.2
+       NAME 'modifyTimeStamp'
+       PROPERTY-GUID '4AD97A9A53CAD111BBD00080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.335
+       NAME 'currentLocation'
+       RANGE-LOWER '32'
+       RANGE-UPPER '32'
+       PROPERTY-GUID 'FC75001F407ED011AFD600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.570
+       NAME 'meetingProtocol'
+       PROPERTY-GUID '81CCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.420
+       NAME 'publicKeyPolicy'
+       PROPERTY-GUID '287EA680229FD011AFDD00C04FD930C9'
+       PROPERTY-SET-GUID 'FD899BA2E8C7D0119BAE00C04FD92EF5' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1402
+       NAME 'mS-SQL-Publisher'
+       PROPERTY-GUID '586867C14BD3D211999A0000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.812
+       NAME 'createWizardExt'
+       PROPERTY-GUID '8B95092B3189D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1373
+       NAME 'mS-SQL-Clustered'
+       PROPERTY-GUID '90BD7877EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.36
+       NAME 'userCertificate'
+       PROPERTY-GUID '7F7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.334
+       NAME 'volTableIdxGUID'
+       RANGE-LOWER '0'
+       RANGE-UPPER '16'
+       PROPERTY-GUID 'FB75001F407ED011AFD600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 2.5.4.20
+       NAME 'telephoneNumber'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID '497A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.696
+       NAME 'currentParentCA'
+       PROPERTY-GUID '3F273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.504
+       NAME 'seqNotification'
+       PROPERTY-GUID 'F20CACDD8FAFD011AFEB00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.515
+       NAME 'serverReference'
+       PROPERTY-GUID '6D73D9267060D111A9C60000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1119
+       NAME 'msNPAllowDialin'
+       PROPERTY-GUID '85900CDBF2C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID 'F8887003E10AD211B42200A0C968F939' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1387
+       NAME 'mS-SQL-GPSHeight'
+       PROPERTY-GUID '0E4FDDBCEECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1378
+       NAME 'mS-SQL-AppleTalk'
+       PROPERTY-GUID 'F489DA8FEECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.269
+       NAME 'linkTrackSecret'
+       RANGE-LOWER '0'
+       RANGE-UPPER '16'
+       PROPERTY-GUID 'E20FE82AB447D011A1A400C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.378
+       NAME 'dnsAllowDynamic'
+       PROPERTY-GUID '651EFAE0459BD011AFDD00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.49
+       NAME 'badPasswordTime'
+       PROPERTY-GUID '2D7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.18.1
+       NAME 'createTimeStamp'
+       PROPERTY-GUID '730DF92D9F00D211AA4C00C04FD7D83A'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.637
+       NAME 'privilegeHolder'
+       PROPERTY-GUID '9B5B4019FA3CD111A9C00000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.289
+       NAME 'printMediaReady'
+       PROPERTY-GUID 'F5FCCB3B3D4DD011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.288
+       NAME 'printMACAddress'
+       PROPERTY-GUID '7A5F30BAE347D011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.66
+       NAME 'lSACreationTime'
+       PROPERTY-GUID 'AD7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.569
+       NAME 'meetingLocation'
+       PROPERTY-GUID '80CCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.784
+       NAME 'aCSIdentityName'
+       PROPERTY-GUID 'B629B0DAF7DDD11190A500C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1410
+       NAME 'mS-DS-CreatorSID'
+       PROPERTY-GUID '3201E6C58014D31191C10000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1374
+       NAME 'mS-SQL-NamedPipe'
+       PROPERTY-GUID '40C8917BEECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.843
+       NAME 'lDAPAdminLimits'
+       PROPERTY-GUID '52A35973F790D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.460
+       NAME 'lDAPDisplayName'
+       RANGE-LOWER '1'
+       RANGE-UPPER '256'
+       PROPERTY-GUID '9A7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.218
+       NAME 'applicationName'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID '262271DDE410D011A05F00AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.695
+       NAME 'pendingParentCA'
+       PROPERTY-GUID '3E273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.779
+       NAME 'aCSCacheTimeout'
+       PROPERTY-GUID 'A155B31CD056D111A9C60000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.574
+       NAME 'meetingLanguage'
+       PROPERTY-GUID '84CCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.778
+       NAME 'aCSDSBMDeadTime'
+       PROPERTY-GUID 'A055B31CD056D111A9C60000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.697
+       NAME 'cACertificateDN'
+       PROPERTY-GUID '40273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.138
+       NAME 'userParameters'
+       RANGE-LOWER '0'
+       RANGE-UPPER '32767'
+       PROPERTY-GUID '6D7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '0042164CC020D011A76800AA006E0529' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.132
+       NAME 'trustDirection'
+       PROPERTY-GUID '5C7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.962
+       NAME 'mSMQQueueQuota'
+       PROPERTY-GUID '128E6B3F7FD5D11190A200C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.936
+       NAME 'mSMQEncryptKey'
+       PROPERTY-GUID '31C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.885
+       NAME 'terminalServer'
+       PROPERTY-GUID '1C9AB66D2294D111AEBD0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.233
+       NAME 'printStartTime'
+       PROPERTY-GUID 'C91614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.21.5
+       NAME 'attributeTypes'
+       PROPERTY-GUID '44D97A9A53CAD111BBD00080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.664
+       NAME 'syncWithObject'
+       PROPERTY-GUID 'E25176031D44D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.344
+       NAME 'groupsToIgnore'
+       PROPERTY-GUID '0459A6EEC68AD011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.665
+       NAME 'syncMembership'
+       PROPERTY-GUID 'E35176031D44D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.666
+       NAME 'syncAttributes'
+       PROPERTY-GUID 'E45176031D44D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.214
+       NAME 'nextLevelStore'
+       PROPERTY-GUID 'DA7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.302
+       NAME 'sAMAccountType'
+       PROPERTY-GUID '6C627B6EF264D011AFD200C04FD930C9'
+       PROPERTY-SET-GUID '422FBA59A279D011902000C04FC2D3CF'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1401
+       NAME 'mS-SQL-Keywords'
+       PROPERTY-GUID '8AA9E901EFCCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.210
+       NAME 'proxyAddresses'
+       RANGE-LOWER '1'
+       RANGE-UPPER '1123'
+       PROPERTY-GUID '067A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.284
+       NAME 'bytesPerMinute'
+       PROPERTY-GUID '765F30BAE347D011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.241
+       NAME 'printMaxCopies'
+       PROPERTY-GUID 'D11614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.98
+       NAME 'primaryGroupID'
+       PROPERTY-GUID '007A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '422FBA59A279D011902000C04FC2D3CF'
+       INDEXED )
+
+extendedAttributeInfo ( 2.16.840.1.113730.3.1.35
+       NAME 'thumbnailPhoto'
+       RANGE-LOWER '0'
+       RANGE-UPPER '102400'
+       PROPERTY-GUID '50CA3B8D7E1DD011A08100AA006C33ED'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.89
+       NAME 'nTGroupMembers'
+       PROPERTY-GUID 'DF7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1228
+       NAME 'mSMQDsServices'
+       PROPERTY-GUID '780DF92D9F00D211AA4C00C04FD7D83A'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.43
+       NAME 'fRSVersionGUID'
+       RANGE-LOWER '16'
+       RANGE-UPPER '16'
+       PROPERTY-GUID '6C73D9267060D111A9C60000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.486
+       NAME 'fRSWorkingPath'
+       RANGE-LOWER '0'
+       RANGE-UPPER '2048'
+       PROPERTY-GUID '73F1E81BFFA9D011AFE200C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.18
+       NAME 'otherTelephone'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID 'A5FFF8F09111D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.277
+       NAME 'otherHomePhone'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID 'A2FFF8F09111D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.151
+       NAME 'oEMInformation'
+       RANGE-LOWER '0'
+       RANGE-UPPER '32767'
+       PROPERTY-GUID 'EA7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.459
+       NAME 'networkAddress'
+       RANGE-LOWER '0'
+       RANGE-UPPER '256'
+       PROPERTY-GUID 'D97996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.966
+       NAME 'mSMQDigestsMig'
+       PROPERTY-GUID 'E0D8710F3BDAD11190A500C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.568
+       NAME 'meetingKeyword'
+       PROPERTY-GUID '7FCCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.844
+       NAME 'lDAPIPDenyList'
+       PROPERTY-GUID '53A35973F790D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.847
+       NAME 'installUiLevel'
+       PROPERTY-GUID '64DDA7961891D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.894
+       NAME 'gPCFileSysPath'
+       PROPERTY-GUID 'C13B0EF3F09FD111B6030000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.488
+       NAME 'fRSStagingPath'
+       RANGE-LOWER '0'
+       RANGE-UPPER '2048'
+       PROPERTY-GUID '75F1E81BFFA9D011AFE200C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.351
+       NAME 'auxiliaryClass'
+       PROPERTY-GUID '2C7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.159
+       NAME 'accountExpires'
+       PROPERTY-GUID '157996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '0042164CC020D011A76800AA006E0529' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.718
+       NAME 'dhcpProperties'
+       PROPERTY-GUID '53273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.346
+       NAME 'desktopProfile'
+       PROPERTY-GUID '0659A6EEC68AD011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.762
+       NAME 'aCSServiceType'
+       PROPERTY-GUID '7F12567F0153D111A9C50000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.610
+       NAME 'employeeNumber'
+       RANGE-LOWER '1'
+       RANGE-UPPER '512'
+       PROPERTY-GUID 'EF73DFA8EAC5D111BBCB0080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1213
+       NAME 'assocNTAccount'
+       PROPERTY-GUID 'C0638F3960CAD111BBD10000F81F10C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.498
+       NAME 'creationWizard'
+       PROPERTY-GUID 'ED01864D85ACD011AFE300C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.253
+       NAME 'cOMOtherProgId'
+       PROPERTY-GUID 'DD1614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.202
+       NAME 'auditingPolicy'
+       PROPERTY-GUID 'FEA4A86D520ED011A28600AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.635
+       NAME 'privilegeValue'
+       PROPERTY-GUID '995B4019FA3CD111A9C00000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1366
+       NAME 'mS-SQL-Location'
+       PROPERTY-GUID '44961C56EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1334
+       NAME 'pKIDefaultCSPs'
+       PROPERTY-GUID '6E33F61E9E3BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.270
+       NAME 'printShareName'
+       PROPERTY-GUID '685F30BAE347D011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.33
+       NAME 'isSingleValued'
+       PROPERTY-GUID '927996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.472
+       NAME 'domainCrossRef'
+       PROPERTY-GUID '7BEA00B086A0D011AFDD00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1240
+       NAME 'netbootSIFFile'
+       PROPERTY-GUID '840DF92D9F00D211AA4C00C04FD7D83A'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.250
+       NAME 'cOMUniqueLIBID'
+       RANGE-LOWER '36'
+       RANGE-UPPER '36'
+       PROPERTY-GUID 'DA1614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.657
+       NAME 'serviceDNSName'
+       PROPERTY-GUID 'B80E6328D541D111A9C10000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.782
+       NAME 'objectCategory'
+       PROPERTY-GUID '6973D9267060D111A9C60000F80367C1'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.122
+       NAME 'serviceClassID'
+       PROPERTY-GUID '357A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.720
+       NAME 'dhcpUpdateTime'
+       PROPERTY-GUID '55273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.221
+       NAME 'sAMAccountName'
+       RANGE-LOWER '0'
+       RANGE-UPPER '256'
+       PROPERTY-GUID 'D0BF0A3E6A12D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '422FBA59A279D011902000C04FC2D3CF'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.588
+       NAME 'meetingEndTime'
+       PROPERTY-GUID '91CCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1389
+       NAME 'mS-SQL-Language'
+       PROPERTY-GUID 'F4727FC5EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.777
+       NAME 'aCSDSBMRefresh'
+       PROPERTY-GUID '9F55B31CD056D111A9C60000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1393
+       NAME 'mS-SQL-Database'
+       PROPERTY-GUID 'DCDBA0D5EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.20
+       NAME 'cOMInterfaceID'
+       RANGE-LOWER '36'
+       RANGE-UPPER '36'
+       PROPERTY-GUID '3C7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1403
+       NAME 'mS-SQL-AllowKnownPullSubscription'
+       PROPERTY-GUID '5470BBC34BD3D211999A0000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1394
+       NAME 'mS-SQL-AllowAnonymousSubscription'
+       PROPERTY-GUID '4ABE77DBEECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.654
+       NAME 'managedObjects'
+       PROPERTY-GUID '24C19602DA40D111A9C00000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.8
+       NAME 'possSuperiors'
+       PROPERTY-GUID 'FA7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.791
+       NAME 'transportType'
+       PROPERTY-GUID '7473D9267060D111A9C60000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.345
+       NAME 'groupPriority'
+       PROPERTY-GUID '0559A6EEC68AD011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.117
+       NAME 'rpcNsPriority'
+       PROPERTY-GUID '277A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.917
+       NAME 'mSMQQueueType'
+       RANGE-LOWER '16'
+       RANGE-UPPER '16'
+       PROPERTY-GUID '20C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.141
+       NAME 'versionNumber'
+       PROPERTY-GUID '767A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.121
+       NAME 'uSNLastObjRem'
+       PROPERTY-GUID '737A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1346
+       NAME 'templateRoots'
+       PROPERTY-GUID 'A0E99DED4170D21199050000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.93
+       NAME 'pwdProperties'
+       PROPERTY-GUID '0B7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '607340C7BF20D011A76800AA006E0529' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.290
+       NAME 'printNumberUp'
+       PROPERTY-GUID 'F4FCCB3B3D4DD011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.536
+       NAME 'fRSExtensions'
+       RANGE-LOWER '0'
+       RANGE-UPPER '65536'
+       PROPERTY-GUID '208045526ACAD011AFFF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.286
+       NAME 'printRateUnit'
+       PROPERTY-GUID '785F30BAE347D011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.846
+       NAME 'msiScriptSize'
+       PROPERTY-GUID '63DDA7961891D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.274
+       NAME 'printSpooling'
+       PROPERTY-GUID '6C5F30BAE347D011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.608
+       NAME 'queryPolicyBL'
+       PROPERTY-GUID '04A4AEE15BCDD011AFFF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.103
+       NAME 'proxyLifetime'
+       PROPERTY-GUID '077A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.144
+       NAME 'operatorCount'
+       PROPERTY-GUID 'EE7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.860
+       NAME 'netbootServer'
+       PROPERTY-GUID '81303807DF91D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.369
+       NAME 'fSMORoleOwner'
+       PROPERTY-GUID '871817663C8FD011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.276
+       NAME 'driverVersion'
+       PROPERTY-GUID '6E5F30BAE347D011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1388
+       NAME 'mS-SQL-Version'
+       PROPERTY-GUID 'D0C17CC0EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.939
+       NAME 'mSMQNameStyle'
+       PROPERTY-GUID '33C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.471
+       NAME 'schemaVersion'
+       PROPERTY-GUID '2C7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.436
+       NAME 'directReports'
+       PROPERTY-GUID '1C7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.255
+       NAME 'addressSyntax'
+       RANGE-LOWER '1'
+       RANGE-UPPER '4096'
+       PROPERTY-GUID '6324D45F6212D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.235
+       NAME 'printFormName'
+       PROPERTY-GUID 'CB1614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.15
+       NAME 'msiScriptPath'
+       PROPERTY-GUID '377996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1312
+       NAME 'aCSServerList'
+       PROPERTY-GUID 'A559BD7C903BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.615
+       NAME 'personalTitle'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID '58587716F347D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1305
+       NAME 'moveTreeState'
+       PROPERTY-GUID 'C8C22A1F713BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.945
+       NAME 'mSMQSiteGates'
+       PROPERTY-GUID '39C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1238
+       NAME 'mSMQDsService'
+       PROPERTY-GUID '820DF92D9F00D211AA4C00C04FD7D83A'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.76
+       NAME 'objectVersion'
+       PROPERTY-GUID '48587716F347D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1414
+       NAME 'dNSTombstoned'
+       PROPERTY-GUID 'B72EEBD54EBE3B46A214634A44D7392E'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.941
+       NAME 'mSMQLongLived'
+       PROPERTY-GUID '35C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.534
+       NAME 'fRSLevelLimit'
+       PROPERTY-GUID '1E8045526ACAD011AFFF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.845
+       NAME 'msiScriptName'
+       PROPERTY-GUID '62DDA7961891D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.44
+       NAME 'homeDirectory'
+       PROPERTY-GUID '857996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '1020205FA579D011902000C04FC2D4CF' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.698
+       NAME 'dhcpUniqueKey'
+       PROPERTY-GUID '3A273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.227
+       NAME 'extensionName'
+       RANGE-LOWER '1'
+       RANGE-UPPER '255'
+       PROPERTY-GUID '727996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.256
+       NAME 'streetAddress'
+       RANGE-LOWER '1'
+       RANGE-UPPER '1024'
+       PROPERTY-GUID '84FFF8F09111D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.113
+       NAME 'rpcNsBindings'
+       PROPERTY-GUID '237A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.18
+       NAME 'postOfficeBox'
+       RANGE-LOWER '1'
+       RANGE-UPPER '40'
+       PROPERTY-GUID 'FB7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.237
+       NAME 'printBinNames'
+       PROPERTY-GUID 'CD1614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.16
+       NAME 'postalAddress'
+       RANGE-LOWER '1'
+       RANGE-UPPER '4096'
+       PROPERTY-GUID 'FC7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.109
+       NAME 'replicaSource'
+       PROPERTY-GUID '187A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.246
+       NAME 'printLanguage'
+       RANGE-LOWER '1'
+       RANGE-UPPER '256'
+       PROPERTY-GUID 'D61614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1365
+       NAME 'mS-SQL-Contact'
+       PROPERTY-GUID 'D8BD6C4FEECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.16.840.1.113730.3.1.36
+       NAME 'thumbnailLogo'
+       RANGE-LOWER '1'
+       RANGE-UPPER '32767'
+       PROPERTY-GUID 'A97996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.357
+       NAME 'nTMixedDomain'
+       PROPERTY-GUID '1F89973E018CD011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.483
+       NAME 'fRSFileFilter'
+       RANGE-LOWER '0'
+       RANGE-UPPER '2048'
+       PROPERTY-GUID '70F1E81BFFA9D011AFE200C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.332
+       NAME 'birthLocation'
+       RANGE-LOWER '32'
+       RANGE-UPPER '32'
+       PROPERTY-GUID 'F975001F407ED011AFD600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.682
+       NAME 'friendlyNames'
+       PROPERTY-GUID '88CBFD7B0748D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.622
+       NAME 'ipsecDataType'
+       PROPERTY-GUID '1EF80FB47A42D111A9C20000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.584
+       NAME 'meetingRating'
+       PROPERTY-GUID '8DCCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.681
+       NAME 'indexedScopes'
+       PROPERTY-GUID '87CBFD7B0748D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.312
+       NAME 'rpcNsObjectID'
+       PROPERTY-GUID '481C4029277AD011AFD600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.168
+       NAME 'modifiedCount'
+       PROPERTY-GUID 'C57996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.218
+       NAME 'oMObjectClass'
+       PROPERTY-GUID 'EC7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.772
+       NAME 'aCSPolicyName'
+       PROPERTY-GUID '9A55B31CD056D111A9C60000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.502
+       NAME 'timeVolChange'
+       PROPERTY-GUID 'F00CACDD8FAFD011AFEB00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 2.5.21.6
+       NAME 'objectClasses'
+       PROPERTY-GUID '4BD97A9A53CAD111BBD00080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.337
+       NAME 'currMachineId'
+       RANGE-LOWER '16'
+       RANGE-UPPER '16'
+       PROPERTY-GUID 'FE75001F407ED011AFD600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.120
+       NAME 'schemaFlagsEx'
+       PROPERTY-GUID '2B7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1356
+       NAME 'validAccesses'
+       PROPERTY-GUID '80A32F4D547FD211992A0000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.158
+       NAME 'domainReplica'
+       RANGE-LOWER '0'
+       RANGE-UPPER '32767'
+       PROPERTY-GUID '5E7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1309
+       NAME 'mSMQInterval2'
+       PROPERTY-GUID '528FB8997B3BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1308
+       NAME 'mSMQInterval1'
+       PROPERTY-GUID 'AA25A88E7B3BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.916
+       NAME 'canonicalName'
+       PROPERTY-GUID '45D97A9A53CAD111BBD00080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 2.5.4.37
+       NAME 'cACertificate'
+       RANGE-LOWER '1'
+       RANGE-UPPER '32768'
+       PROPERTY-GUID '327996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.94
+       NAME 'ntPwdHistory'
+       PROPERTY-GUID 'E27996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.133
+       NAME 'trustPartner'
+       RANGE-LOWER '1'
+       RANGE-UPPER '1024'
+       PROPERTY-GUID '5D7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.160
+       NAME 'lmPwdHistory'
+       PROPERTY-GUID '9D7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.35
+       NAME 'userPassword'
+       RANGE-LOWER '1'
+       RANGE-UPPER '128'
+       PROPERTY-GUID '6E7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1380
+       NAME 'mS-SQL-Status'
+       PROPERTY-GUID '70477D9AEECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.469
+       NAME 'USNIntersite'
+       PROPERTY-GUID '9874DFA8EAC5D111BBCB0080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.858
+       NAME 'netbootTools'
+       PROPERTY-GUID '7F303807DF91D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.99
+       NAME 'priorSetTime'
+       PROPERTY-GUID '017A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1367
+       NAME 'mS-SQL-Memory'
+       PROPERTY-GUID '8C445D5BEECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.950
+       NAME 'mSMQServices'
+       PROPERTY-GUID '3DC30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.613
+       NAME 'employeeType'
+       RANGE-LOWER '1'
+       RANGE-UPPER '256'
+       PROPERTY-GUID 'F073DFA8EAC5D111BBCB0080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.27
+       NAME 'currentValue'
+       PROPERTY-GUID '477996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.822
+       NAME 'siteLinkList'
+       PROPERTY-GUID 'DD2C0CD55189D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.107
+       NAME 'remoteSource'
+       RANGE-LOWER '1'
+       RANGE-UPPER '1024'
+       PROPERTY-GUID '147A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.325
+       NAME 'setupCommand'
+       PROPERTY-GUID '970E6C7D207ED011AFD600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.33
+       NAME 'roleOccupant'
+       PROPERTY-GUID '6574DFA8EAC5D111BBCB0080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.212
+       NAME 'dSHeuristics'
+       PROPERTY-GUID '86FFF8F09111D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1336
+       NAME 'replInterval'
+       PROPERTY-GUID '1A9DBA45FA56D21190D000C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.234
+       NAME 'printEndTime'
+       PROPERTY-GUID 'CA1614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.1
+       NAME 'instanceType'
+       PROPERTY-GUID '8C7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.722
+       NAME 'otherIpPhone'
+       PROPERTY-GUID '4B6E144DD448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.965
+       NAME 'mSMQSiteName'
+       PROPERTY-GUID 'B2B4ADFF39DED11190A500C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.579
+       NAME 'meetingOwner'
+       PROPERTY-GUID '88CCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.242
+       NAME 'printCollate'
+       PROPERTY-GUID 'D21614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.480
+       NAME 'defaultGroup'
+       PROPERTY-GUID 'E2C40B724AA5D011AFDF00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.79
+       NAME 'minPwdLength'
+       PROPERTY-GUID 'C37996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '607340C7BF20D011A76800AA006E0529' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.864
+       NAME 'netbootSCPBL'
+       PROPERTY-GUID '82303807DF91D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.650
+       NAME 'mhsORAddress'
+       PROPERTY-GUID '22C19602DA40D111A9C00000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.651
+       NAME 'otherMailbox'
+       PROPERTY-GUID '23C19602DA40D111A9C00000F80367C1'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.367
+       NAME 'rpcNsCodeset'
+       PROPERTY-GUID 'E0A00B7A988ED011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.14
+       NAME 'hasMasterNCs'
+       PROPERTY-GUID '827996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.952
+       NAME 'mSMQMigrated'
+       PROPERTY-GUID '3FC30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.74
+       NAME 'dSASignature'
+       PROPERTY-GUID 'BC577716F347D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.5
+       NAME 'serialNumber'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID '327A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.115
+       NAME 'invocationId'
+       PROPERTY-GUID '8E7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.254
+       NAME 'cOMTypelibId'
+       RANGE-LOWER '36'
+       RANGE-UPPER '36'
+       PROPERTY-GUID 'DE1614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.26
+       NAME 'creationTime'
+       PROPERTY-GUID '467996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.581
+       NAME 'meetingScope'
+       PROPERTY-GUID '8ACCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.336
+       NAME 'volTableGUID'
+       RANGE-LOWER '0'
+       RANGE-UPPER '16'
+       PROPERTY-GUID 'FD75001F407ED011AFD600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.513
+       NAME 'siteObjectBL'
+       PROPERTY-GUID '4D94103E54C3D011AFF80000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.756
+       NAME 'aCSTimeOfDay'
+       PROPERTY-GUID '7912567F0153D111A9C50000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.757
+       NAME 'aCSDirection'
+       PROPERTY-GUID '7A12567F0153D111A9C50000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.77
+       NAME 'maxTicketAge'
+       PROPERTY-GUID 'BE7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.481
+       NAME 'schemaUpdate'
+       PROPERTY-GUID 'B4062D1E8FACD011AFE300C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.80
+       NAME 'minTicketAge'
+       PROPERTY-GUID 'C47996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.628
+       NAME 'ipsecNegotiationPolicyReference'
+       PROPERTY-GUID '22F80FB47A42D111A9C20000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.327
+       NAME 'helpFileName'
+       RANGE-LOWER '1'
+       RANGE-UPPER '13'
+       PROPERTY-GUID 'A924D45F6212D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.148
+       NAME 'schemaIDGUID'
+       RANGE-LOWER '16'
+       RANGE-UPPER '16'
+       PROPERTY-GUID '237996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.810
+       NAME 'createDialog'
+       PROPERTY-GUID '8A95092B3189D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.964
+       NAME 'mSMQNt4Flags'
+       PROPERTY-GUID '58A138EB7FD5D11190A200C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.327
+       NAME 'packageFlags'
+       PROPERTY-GUID '990E6C7D207ED011AFD600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.464
+       NAME 'wWWHomePage'
+       RANGE-LOWER '1'
+       RANGE-UPPER '2048'
+       PROPERTY-GUID '7A7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID 'B39557E45594D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.507
+       NAME 'volumeCount'
+       PROPERTY-GUID '17A2AA3499B6D011AFEE0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.273
+       NAME 'printStatus'
+       PROPERTY-GUID '6B5F30BAE347D011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.890
+       NAME 'uPNSuffixes'
+       PROPERTY-GUID 'BF6021032498D111AEC00000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.471
+       NAME 'trustParent'
+       PROPERTY-GUID '7AEA00B086A0D011AFDD00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1301
+       NAME 'tokenGroups'
+       PROPERTY-GUID '6D9EC6B7C72CD211854E00A0C983F608'
+       PROPERTY-SET-GUID 'F8887003E10AD211B42200A0C968F939' )
+
+extendedAttributeInfo ( 2.5.4.21
+       NAME 'telexNumber'
+       RANGE-LOWER '1'
+       RANGE-UPPER '32'
+       PROPERTY-GUID '4B7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.375
+       NAME 'systemFlags'
+       PROPERTY-GUID '621EFAE0459BD011AFDD00C04FD930C9'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.667
+       NAME 'syncWithSID'
+       PROPERTY-GUID 'E55176031D44D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1306
+       NAME 'dNSProperty'
+       PROPERTY-GUID 'FE155A67703BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.710
+       NAME 'superScopes'
+       PROPERTY-GUID '4B273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1347
+       NAME 'sPNMappings'
+       PROPERTY-GUID '6CE7B02A4170D21199050000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.272
+       NAME 'printNotify'
+       PROPERTY-GUID '6A5F30BAE347D011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.282
+       NAME 'printMemory'
+       PROPERTY-GUID '745F30BAE347D011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.154
+       NAME 'serverState'
+       PROPERTY-GUID '347A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.942
+       NAME 'mSMQVersion'
+       PROPERTY-GUID '36C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.373
+       NAME 'rIDUsedPool'
+       PROPERTY-GUID '8B1817663C8FD011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1355
+       NAME 'queryFilter'
+       PROPERTY-GUID '260AF7CB787ED21199210000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.300
+       NAME 'printerName'
+       PROPERTY-GUID '6E294B24BD5AD011AFD200C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.97
+       NAME 'preferredOU'
+       PROPERTY-GUID 'FF7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.649
+       NAME 'primaryInternationalISDNNumber'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID '1FC19602DA40D111A9C00000F80367C1'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.333
+       NAME 'oMTIndxGuid'
+       RANGE-LOWER '0'
+       RANGE-UPPER '16'
+       PROPERTY-GUID 'FA75001F407ED011AFD600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1337
+       NAME 'mSMQUserSid'
+       RANGE-LOWER '0'
+       RANGE-UPPER '128'
+       PROPERTY-GUID '32AE8AC5F956D21190D000C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.487
+       NAME 'fRSRootPath'
+       RANGE-LOWER '0'
+       RANGE-UPPER '2048'
+       PROPERTY-GUID '74F1E81BFFA9D011AFE200C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.918
+       NAME 'mSMQJournal'
+       PROPERTY-GUID '21C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.499
+       NAME 'contextMenu'
+       PROPERTY-GUID 'EE01864D85ACD011AFE300C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.764
+       NAME 'aCSPriority'
+       PROPERTY-GUID '8112567F0153D111A9C50000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.937
+       NAME 'mSMQSignKey'
+       PROPERTY-GUID '32C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.359
+       NAME 'netbootGUID'
+       RANGE-LOWER '16'
+       RANGE-UPPER '16'
+       PROPERTY-GUID '2189973E018CD011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.925
+       NAME 'mSMQOwnerID'
+       RANGE-LOWER '16'
+       RANGE-UPPER '16'
+       PROPERTY-GUID '28C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.24
+       NAME 'mustContain'
+       PROPERTY-GUID 'D37996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.379
+       NAME 'dnsAllowXFR'
+       PROPERTY-GUID '661EFAE0459BD011AFDD00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1379
+       NAME 'mS-SQL-Vines'
+       PROPERTY-GUID '9463C594EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.948
+       NAME 'mSMQDigests'
+       RANGE-LOWER '16'
+       RANGE-UPPER '16'
+       PROPERTY-GUID '3CC30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.662
+       NAME 'lockoutTime'
+       PROPERTY-GUID 'BF0E6328D541D111A9C10000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.53
+       NAME 'lastSetTime'
+       PROPERTY-GUID '987996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.25
+       NAME 'countryCode'
+       PROPERTY-GUID '7124D45F6212D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '422FBA59A279D011902000C04FC2D3CF' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1377
+       NAME 'mS-SQL-TCPIP'
+       PROPERTY-GUID 'A663C28AEECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.934
+       NAME 'mSMQForeign'
+       PROPERTY-GUID '2FC30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.571
+       NAME 'meetingType'
+       PROPERTY-GUID '82CCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.714
+       NAME 'dhcpOptions'
+       PROPERTY-GUID '4F273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.704
+       NAME 'dhcpServers'
+       PROPERTY-GUID '45273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.283
+       NAME 'assetNumber'
+       PROPERTY-GUID '755F30BAE347D011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.350
+       NAME 'addressType'
+       RANGE-LOWER '1'
+       RANGE-UPPER '32'
+       PROPERTY-GUID '6424D45F6212D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.940
+       NAME 'mSMQCSPName'
+       PROPERTY-GUID '34C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.671
+       NAME 'msiFileList'
+       PROPERTY-GUID '7DCBFD7B0748D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.619
+       NAME 'dNSHostName'
+       RANGE-LOWER '0'
+       RANGE-UPPER '2048'
+       PROPERTY-GUID '4795E372187BD111ADEF00C04FD8D5CD'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.13
+       NAME 'description'
+       RANGE-LOWER '0'
+       RANGE-UPPER '1024'
+       PROPERTY-GUID '507996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.705
+       NAME 'dhcpSubnets'
+       PROPERTY-GUID '46273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1328
+       NAME 'pKIKeyUsage'
+       PROPERTY-GUID '7EA8B0E99D3BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.30
+       NAME 'attributeID'
+       PROPERTY-GUID '227996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.506
+       NAME 'objectCount'
+       PROPERTY-GUID '16A2AA3499B6D011AFEE0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.503
+       NAME 'timeRefresh'
+       PROPERTY-GUID 'F10CACDD8FAFD011AFEB00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.139
+       NAME 'profilePath'
+       PROPERTY-GUID '057A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '1020205FA579D011902000C04FC2D4CF' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.818
+       NAME 'productCode'
+       RANGE-LOWER '0'
+       RANGE-UPPER '16'
+       PROPERTY-GUID '1783E1D93989D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.647
+       NAME 'otherMobile'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID '1EC19602DA40D111A9C00000F80367C1'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.12
+       NAME 'badPwdCount'
+       PROPERTY-GUID '2E7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '1020205FA579D011902000C04FC2D4CF' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1368
+       NAME 'mS-SQL-Build'
+       PROPERTY-GUID 'C4943E60EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.13
+       NAME 'displayName'
+       RANGE-LOWER '0'
+       RANGE-UPPER '256'
+       PROPERTY-GUID '537996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '422FBA59A279D011902000C04FC2D3CF'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.87
+       NAME 'nETBIOSName'
+       RANGE-LOWER '1'
+       RANGE-UPPER '16'
+       PROPERTY-GUID 'D87996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1395
+       NAME 'mS-SQL-Alias'
+       PROPERTY-GUID 'AEBAC6E0EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.75
+       NAME 'maxRenewAge'
+       PROPERTY-GUID 'BC7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.806
+       NAME 'treatAsLeaf'
+       PROPERTY-GUID 'E344D08F1F77D111AEAE0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.960
+       NAME 'mSMQNt4Stub'
+       PROPERTY-GUID 'E64B916F7ED5D11190A200C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.324
+       NAME 'packageType'
+       PROPERTY-GUID '960E6C7D207ED011AFD600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.0
+       NAME 'objectClass'
+       PROPERTY-GUID 'E57996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1212
+       NAME 'isEphemeral'
+       PROPERTY-GUID 'F053C4F4F1C5D111BBCB0080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.36
+       NAME 'dMDLocation'
+       PROPERTY-GUID '8BFFF8F09111D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.715
+       NAME 'dhcpClasses'
+       PROPERTY-GUID '50273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.39
+       NAME 'forceLogoff'
+       PROPERTY-GUID '777996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.2
+       NAME 'whenCreated'
+       PROPERTY-GUID '787A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.566
+       NAME 'meetingName'
+       PROPERTY-GUID '7DCCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.786
+       NAME 'mailAddress'
+       PROPERTY-GUID '6F73D9267060D111A9C60000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.590
+       NAME 'meetingBlob'
+       PROPERTY-GUID '93CCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.71
+       NAME 'machineRole'
+       PROPERTY-GUID 'B27996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.14
+       NAME 'searchGuide'
+       PROPERTY-GUID '2E7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.334
+       NAME 'searchFlags'
+       RANGE-LOWER '0'
+       PROPERTY-GUID '2D7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.3
+       NAME 'whenChanged'
+       PROPERTY-GUID '777A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.702
+       NAME 'dhcpObjName'
+       PROPERTY-GUID '43273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.897
+       NAME 'aCSMaxAggregatePeakRatePerUser'
+       PROPERTY-GUID '0C2372F0F5AED111BDCF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.326
+       NAME 'packageName'
+       PROPERTY-GUID '980E6C7D207ED011AFD600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.170
+       NAME 'systemOnly'
+       PROPERTY-GUID '467A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.935
+       NAME 'mSMQOSType'
+       PROPERTY-GUID '30C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.680
+       NAME 'queryPoint'
+       PROPERTY-GUID '86CBFD7B0748D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.271
+       NAME 'printOwner'
+       PROPERTY-GUID '695F30BAE347D011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.19
+       NAME 'uSNCreated'
+       PROPERTY-GUID '707A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.494
+       NAME 'siteServer'
+       PROPERTY-GUID '7CF1E81BFFA9D011AFE200C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.114
+       NAME 'rpcNsGroup'
+       PROPERTY-GUID '247A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.609
+       NAME 'sIDHistory'
+       PROPERTY-GUID '7842EB1767D1D011B0020000F80367C1'
+       PROPERTY-SET-GUID '422FBA59A279D011902000C04FC2D3CF'
+       INDEXED
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.882
+       NAME 'fRSVersion'
+       RANGE-LOWER '0'
+       RANGE-UPPER '32'
+       PROPERTY-GUID '8525132A7393D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.64
+       NAME 'logonHours'
+       PROPERTY-GUID 'AB7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '1020205FA579D011902000C04FC2D4CF' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.854
+       NAME 'netbootAnswerOnlyValidClients'
+       PROPERTY-GUID '7B303807DF91D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.96
+       NAME 'pwdLastSet'
+       PROPERTY-GUID '0A7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '0042164CC020D011A76800AA006E0529' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.243
+       NAME 'printColor'
+       PROPERTY-GUID 'D31614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1391
+       NAME 'mS-SQL-Type'
+       PROPERTY-GUID 'A8EB48CAEECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.40
+       NAME 'fromServer'
+       PROPERTY-GUID '797996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.157
+       NAME 'serverRole'
+       PROPERTY-GUID '337A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.100
+       NAME 'priorValue'
+       PROPERTY-GUID '027A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.169
+       NAME 'logonCount'
+       PROPERTY-GUID 'AA7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '1020205FA579D011902000C04FC2D4CF' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.90
+       NAME 'unicodePwd'
+       PROPERTY-GUID 'E17996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.21
+       NAME 'subClassOf'
+       PROPERTY-GUID '3B7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1396
+       NAME 'mS-SQL-Size'
+       PROPERTY-GUID '848009E9EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.101
+       NAME 'privateKey'
+       PROPERTY-GUID '037A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.512
+       NAME 'siteObject'
+       PROPERTY-GUID '4C94103E54C3D011AFF80000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.62
+       NAME 'scriptPath'
+       PROPERTY-GUID 'A87996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.223
+       NAME 'serverName'
+       RANGE-LOWER '0'
+       RANGE-UPPER '1024'
+       PROPERTY-GUID 'A0B7DC095F16D011A06400AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.953
+       NAME 'mSMQSiteID'
+       PROPERTY-GUID '40C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.340
+       NAME 'rightsGuid'
+       RANGE-LOWER '36'
+       RANGE-UPPER '36'
+       PROPERTY-GUID '1C939782D386D011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.374
+       NAME 'rIDNextRID'
+       PROPERTY-GUID '8C1817663C8FD011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.583
+       NAME 'meetingURL'
+       PROPERTY-GUID '8CCCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.400
+       NAME 'addressEntryDisplayTableMSDOS'
+       RANGE-LOWER '1'
+       RANGE-UPPER '32768'
+       PROPERTY-GUID '6224D45F6212D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.76
+       NAME 'maxStorage'
+       PROPERTY-GUID 'BD7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.35
+       NAME 'rangeUpper'
+       PROPERTY-GUID '0D7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.34
+       NAME 'rangeLower'
+       PROPERTY-GUID '0C7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.17
+       NAME 'postalCode'
+       RANGE-LOWER '1'
+       RANGE-UPPER '40'
+       PROPERTY-GUID 'FD7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.118
+       NAME 'otherPager'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID 'A4FFF8F09111D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.639
+       NAME 'isMemberOfPartialAttributeSet'
+       PROPERTY-GUID '9D5B4019FA3CD111A9C00000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1224
+       NAME 'parentGUID'
+       PROPERTY-GUID '740DF92D9F00D211AA4C00C04FD7D83A'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.141
+       NAME 'department'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID '4F7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.25
+       NAME 'mayContain'
+       PROPERTY-GUID 'BF7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.150
+       NAME 'adminCount'
+       PROPERTY-GUID '187996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.51
+       NAME 'lastLogoff'
+       PROPERTY-GUID '967996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '1020205FA579D011902000C04FC2D4CF' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1409
+       NAME 'masteredBy'
+       PROPERTY-GUID 'E0648EE4C912D311910200C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.35
+       NAME 'employeeID'
+       RANGE-LOWER '0'
+       RANGE-UPPER '16'
+       PROPERTY-GUID '627996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.719
+       NAME 'dhcpMaxKey'
+       PROPERTY-GUID '54273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.229
+       NAME 'driverName'
+       PROPERTY-GUID 'C51614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1363
+       NAME 'mS-SQL-Name'
+       PROPERTY-GUID 'D8DF3235EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.322
+       NAME 'categoryId'
+       RANGE-LOWER '16'
+       RANGE-UPPER '16'
+       PROPERTY-GUID '940E6C7D207ED011AFD600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.889
+       NAME 'additionalTrustedServiceNames'
+       PROPERTY-GUID 'BE6021032498D111AEC00000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1354
+       NAME 'scopeFlags'
+       PROPERTY-GUID 'C2A4F316797ED21199210000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.672
+       NAME 'categories'
+       RANGE-LOWER '36'
+       RANGE-UPPER '36'
+       PROPERTY-GUID '7ECBFD7B0748D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.855
+       NAME 'netbootNewMachineNamingPolicy'
+       PROPERTY-GUID '7C303807DF91D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.19
+       NAME 'cOMClassID'
+       PROPERTY-GUID '3B7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.120
+       NAME 'uSNChanged'
+       PROPERTY-GUID '6F7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.2
+       NAME 'objectGUID'
+       RANGE-LOWER '16'
+       RANGE-UPPER '16'
+       PROPERTY-GUID 'E77996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       INDEXED
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.707
+       NAME 'dhcpRanges'
+       PROPERTY-GUID '48273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1358
+       NAME 'schemaInfo'
+       PROPERTY-GUID 'AE64FBF9B493D21199450000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.646
+       NAME 'otherFacsimileTelephoneNumber'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID '1DC19602DA40D111A9C00000F80367C1'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.520
+       NAME 'machinePasswordChangeInterval'
+       PROPERTY-GUID '8E35B6C938BBD011AFEF0000F80367C1'
+       PROPERTY-SET-GUID 'FE899BA2E8C7D0119BAE00C04FD92EF5' )
+
+extendedAttributeInfo ( 2.16.840.1.113730.3.1.34
+       NAME 'middleName'
+       RANGE-LOWER '0'
+       RANGE-UPPER '64'
+       PROPERTY-GUID 'F27996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.674
+       NAME 'rootTrust'
+       PROPERTY-GUID '80CBFD7B0748D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.136
+       NAME 'trustType'
+       PROPERTY-GUID '607A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.24
+       NAME 'x121Address'
+       RANGE-LOWER '1'
+       RANGE-UPPER '15'
+       PROPERTY-GUID '7B7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.750
+       NAME 'groupType'
+       PROPERTY-GUID '1E029A9A5B4AD111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.896
+       NAME 'uSNSource'
+       PROPERTY-GUID 'AD587716F347D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.919
+       NAME 'mSMQQuota'
+       PROPERTY-GUID '22C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.927
+       NAME 'mSMQSites'
+       RANGE-LOWER '16'
+       RANGE-UPPER '16'
+       PROPERTY-GUID '2AC30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.910
+       NAME 'fromEntry'
+       PROPERTY-GUID '49D97A9A53CAD111BBD00080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1376
+       NAME 'mS-SQL-SPX'
+       PROPERTY-GUID '0480B086EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.892
+       NAME 'gPOptions'
+       PROPERTY-GUID 'BF3B0EF3F09FD111B6030000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.814
+       NAME 'msiScript'
+       PROPERTY-GUID '1383E1D93989D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.285
+       NAME 'printRate'
+       PROPERTY-GUID '775F30BAE347D011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.683
+       NAME 'cRLPartitionedRevocationList'
+       PROPERTY-GUID '31273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.652
+       NAME 'assistant'
+       PROPERTY-GUID '1CC19602DA40D111A9C00000F80367C1'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.490
+       NAME 'fRSDSPoll'
+       PROPERTY-GUID '77F1E81BFFA9D011AFE200C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.663
+       NAME 'partialAttributeDeletionList'
+       PROPERTY-GUID 'C00E6328D541D111A9C10000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.52
+       NAME 'lastLogon'
+       PROPERTY-GUID '977996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '1020205FA579D011902000C04FC2D4CF' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.22
+       NAME 'governsID'
+       PROPERTY-GUID '7D7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.341
+       NAME 'appliesTo'
+       RANGE-LOWER '36'
+       RANGE-UPPER '36'
+       PROPERTY-GUID '1D939782D386D011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.268
+       NAME 'eFSPolicy'
+       PROPERTY-GUID 'ECB24E8E1247D011A1A000C04FD930C9'
+       PROPERTY-SET-GUID 'FD899BA2E8C7D0119BAE00C04FD92EF5' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.155
+       NAME 'uASCompat'
+       PROPERTY-GUID '617A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.538
+       NAME 'prefixMap'
+       PROPERTY-GUID '228045526ACAD011AFFF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 0.9.2342.19200300.100.1.20
+       NAME 'homePhone'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID 'A1FFF8F09111D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.661
+       NAME 'isDefunct'
+       PROPERTY-GUID 'BE0E6328D541D111A9C10000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.708
+       NAME 'dhcpSites'
+       PROPERTY-GUID '49273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.888
+       NAME 'iPSECNegotiationPolicyAction'
+       PROPERTY-GUID '75303807DF91D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.382
+       NAME 'dnsRecord'
+       PROPERTY-GUID '691EFAE0459BD011AFDD00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.21
+       NAME 'cOMProgID'
+       PROPERTY-GUID '3D7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.45
+       NAME 'homeDrive'
+       PROPERTY-GUID '867996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '1020205FA579D011902000C04FC2D4CF' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.580
+       NAME 'meetingIP'
+       PROPERTY-GUID '89CCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1321
+       NAME 'aCSNonReservedMinPolicedSize'
+       PROPERTY-GUID '173987B6903BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.717
+       NAME 'dhcpState'
+       PROPERTY-GUID '52273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.922
+       NAME 'mSMQLabel'
+       RANGE-LOWER '0'
+       RANGE-UPPER '124'
+       PROPERTY-GUID '25C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.74
+       NAME 'maxPwdAge'
+       PROPERTY-GUID 'BB7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '607340C7BF20D011A76800AA006E0529' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.78
+       NAME 'minPwdAge'
+       PROPERTY-GUID 'C27996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '607340C7BF20D011A76800AA006E0529' )
+
+extendedAttributeInfo ( 2.5.4.42
+       NAME 'givenName'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID '8EFFF8F09111D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.689
+       NAME 'cRLObject'
+       PROPERTY-GUID '37273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.146
+       NAME 'objectSid'
+       RANGE-LOWER '0'
+       RANGE-UPPER '28'
+       PROPERTY-GUID 'E87996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '422FBA59A279D011902000C04FC2D3CF'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.565
+       NAME 'meetingID'
+       PROPERTY-GUID '7CCCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.620
+       NAME 'ipsecName'
+       PROPERTY-GUID '1CF80FB47A42D111A9C20000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.48
+       NAME 'isDeleted'
+       PROPERTY-GUID '8F7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.760
+       NAME 'aCSAggregateTokenRatePerUser'
+       PROPERTY-GUID '7D12567F0153D111A9C50000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.623
+       NAME 'ipsecData'
+       PROPERTY-GUID '1FF80FB47A42D111A9C20000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.668
+       NAME 'domainCAs'
+       PROPERTY-GUID '7ACBFD7B0748D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.687
+       NAME 'cAConnect'
+       PROPERTY-GUID '35273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.238
+       NAME 'printMaxResolutionSupported'
+       PROPERTY-GUID 'CF1614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.700
+       NAME 'dhcpFlags'
+       PROPERTY-GUID '41273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.402
+       NAME 'helpData16'
+       RANGE-LOWER '1'
+       RANGE-UPPER '32768'
+       PROPERTY-GUID 'A724D45F6212D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.653
+       NAME 'managedBy'
+       PROPERTY-GUID '20C19602DA40D111A9C00000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.9
+       NAME 'helpData32'
+       RANGE-LOWER '1'
+       RANGE-UPPER '32768'
+       PROPERTY-GUID 'A824D45F6212D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.944
+       NAME 'mSMQSite2'
+       PROPERTY-GUID '38C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.943
+       NAME 'mSMQSite1'
+       PROPERTY-GUID '37C30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.677
+       NAME 'replTopologyStayOfExecution'
+       PROPERTY-GUID '83CBFD7B0748D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.912
+       NAME 'allowedChildClassesEffective'
+       PROPERTY-GUID '43D97A9A53CAD111BBD00080C76670C0'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.231
+       NAME 'oMSyntax'
+       PROPERTY-GUID 'ED7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.231
+       NAME 'priority'
+       PROPERTY-GUID 'C71614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.30
+       NAME 'supportedApplicationContext'
+       PROPERTY-GUID '8F587716F347D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.48
+       NAME 'keywords'
+       RANGE-LOWER '1'
+       RANGE-UPPER '256'
+       PROPERTY-GUID '937996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.946
+       NAME 'mSMQCost'
+       PROPERTY-GUID '3AC30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.821
+       NAME 'siteList'
+       PROPERTY-GUID 'DC2C0CD55189D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.145
+       NAME 'revision'
+       PROPERTY-GUID '217A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.91
+       NAME 'repsFrom'
+       PROPERTY-GUID '1D7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.645
+       NAME 'userCert'
+       RANGE-LOWER '0'
+       RANGE-UPPER '32767'
+       PROPERTY-GUID '697A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.951
+       NAME 'mSMQQMID'
+       RANGE-LOWER '16'
+       RANGE-UPPER '16'
+       PROPERTY-GUID '3EC30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.228
+       NAME 'portName'
+       PROPERTY-GUID 'C41614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.859
+       NAME 'netbootLocallyInstalledOSes'
+       PROPERTY-GUID '80303807DF91D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.261
+       NAME 'division'
+       RANGE-LOWER '0'
+       RANGE-UPPER '256'
+       PROPERTY-GUID 'A03661FE7320D011A9C200AA006C33ED'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.902
+       NAME 'aCSMaxSizeOfRSVPAccountFile'
+       PROPERTY-GUID '112372F0F5AED111BDCF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.699
+       NAME 'dhcpType'
+       PROPERTY-GUID '3B273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.301
+       NAME 'wbemPath'
+       PROPERTY-GUID '70294B24BD5AD011AFD200C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.362
+       NAME 'siteGUID'
+       RANGE-LOWER '16'
+       RANGE-UPPER '16'
+       PROPERTY-GUID '2489973E018CD011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.43
+       NAME 'initials'
+       RANGE-LOWER '1'
+       RANGE-UPPER '6'
+       PROPERTY-GUID '90FFF8F09111D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.26
+       NAME 'rDNAttID'
+       PROPERTY-GUID '0F7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.900
+       NAME 'aCSRSVPAccountFilesLocation'
+       PROPERTY-GUID '0F2372F0F5AED111BDCF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1226
+       NAME 'mSMQDependentClientServices'
+       PROPERTY-GUID '760DF92D9F00D211AA4C00C04FD7D83A'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.222
+       NAME 'location'
+       RANGE-LOWER '0'
+       RANGE-UPPER '1024'
+       PROPERTY-GUID '9FB7DC095F16D011A06400AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.874
+       NAME 'fRSFlags'
+       PROPERTY-GUID '7D25132A7393D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.219
+       NAME 'iconPath'
+       RANGE-LOWER '0'
+       RANGE-UPPER '2048'
+       PROPERTY-GUID '83FFF8F09111D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.688
+       NAME 'cAWEBURL'
+       PROPERTY-GUID '36273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.716
+       NAME 'mscopeId'
+       PROPERTY-GUID '51273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.660
+       NAME 'treeName'
+       PROPERTY-GUID 'BD0E6328D541D111A9C10000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.211
+       NAME 'schedule'
+       PROPERTY-GUID '242271DDE410D011A05F00AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.557
+       NAME 'parentCA'
+       PROPERTY-GUID '1B8045526ACAD011AFFF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.249
+       NAME 'cOMCLSID'
+       RANGE-LOWER '36'
+       RANGE-UPPER '36'
+       PROPERTY-GUID 'D91614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.675
+       NAME 'catalogs'
+       PROPERTY-GUID '81CBFD7B0748D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.102
+       NAME 'memberOf'
+       PROPERTY-GUID '917996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.690
+       NAME 'cAUsages'
+       PROPERTY-GUID '38273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.706
+       NAME 'dhcpMask'
+       PROPERTY-GUID '47273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.511
+       NAME 'flatName'
+       PROPERTY-GUID '1731B1B72EB8D011AFEE0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.686
+       NAME 'domainID'
+       PROPERTY-GUID '34273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.58
+       NAME 'localeID'
+       PROPERTY-GUID 'A17996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.16
+       NAME 'codePage'
+       PROPERTY-GUID '387996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '422FBA59A279D011902000C04FC2D3CF' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.768
+       NAME 'aCSEnableRSVPMessageLogging'
+       PROPERTY-GUID '8512567F0153D111A9C50000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.240
+       NAME 'printOrientationsSupported'
+       RANGE-LOWER '1'
+       RANGE-UPPER '256'
+       PROPERTY-GUID 'D01614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.883
+       NAME 'msRRASVendorAttributeEntry'
+       PROPERTY-GUID 'AC989BF38D93D111AEBD0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1246
+       NAME 'interSiteTopologyGenerator'
+       PROPERTY-GUID '5E9EC6B7C72CD211854E00A0C983F608'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.307
+       NAME 'options'
+       PROPERTY-GUID '535A1919A06DD011AFD300C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.28
+       NAME 'dnsRoot'
+       RANGE-LOWER '1'
+       RANGE-UPPER '255'
+       PROPERTY-GUID '597996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.887
+       NAME 'iPSECNegotiationPolicyType'
+       PROPERTY-GUID '74303807DF91D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1392
+       NAME 'mS-SQL-InformationDirectory'
+       PROPERTY-GUID '2EDBAED0EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.365
+       NAME 'operatingSystemServicePack'
+       PROPERTY-GUID '2789973E018CD011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.88
+       NAME 'nextRid'
+       PROPERTY-GUID 'DB7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.865
+       NAME 'pekList'
+       PROPERTY-GUID '83303807DF91D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.7
+       NAME 'subRefs'
+       PROPERTY-GUID '3C7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.505
+       NAME 'oMTGuid'
+       RANGE-LOWER '0'
+       RANGE-UPPER '16'
+       PROPERTY-GUID 'F30CACDD8FAFD011AFEB00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.205
+       NAME 'pKTGuid'
+       RANGE-LOWER '16'
+       RANGE-UPPER '16'
+       PROPERTY-GUID 'F0F947842710D011A05F00AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.146
+       NAME 'company'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID '88FFF8F09111D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.82
+       NAME 'moniker'
+       PROPERTY-GUID 'C77996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.156
+       NAME 'comment'
+       PROPERTY-GUID '6A7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '422FBA59A279D011902000C04FC2D3CF' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.721
+       NAME 'ipPhone'
+       PROPERTY-GUID '4A6E144DD448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1361
+       NAME 'mS-DS-ConsistencyChildCount'
+       PROPERTY-GUID 'C27B8B173AB6D21190E100C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.679
+       NAME 'creator'
+       PROPERTY-GUID '85CBFD7B0748D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.34
+       NAME 'seeAlso'
+       PROPERTY-GUID '317A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.137
+       NAME 'uNCName'
+       PROPERTY-GUID '647A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.55
+       NAME 'dBCSPwd'
+       PROPERTY-GUID '9C7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1239
+       NAME 'mSMQDependentClientService'
+       PROPERTY-GUID '830DF92D9F00D211AA4C00C04FD7D83A'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.684
+       NAME 'certificateAuthorityObject'
+       PROPERTY-GUID '32273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.621
+       NAME 'ipsecID'
+       PROPERTY-GUID '1DF80FB47A42D111A9C20000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.914
+       NAME 'allowedAttributesEffective'
+       PROPERTY-GUID '41D97A9A53CAD111BBD00080C76670C0'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 0.9.2342.19200300.100.1.10
+       NAME 'manager'
+       PROPERTY-GUID 'B57996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.598
+       NAME 'dmdName'
+       RANGE-LOWER '1'
+       RANGE-UPPER '1024'
+       PROPERTY-GUID 'B9577716F347D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.759
+       NAME 'aCSMaxPeakBandwidthPerFlow'
+       PROPERTY-GUID '7C12567F0153D111A9C50000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.19
+       NAME 'physicalDeliveryOfficeName'
+       RANGE-LOWER '1'
+       RANGE-UPPER '128'
+       PROPERTY-GUID 'F77996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.557
+       NAME 'Enabled'
+       PROPERTY-GUID 'F273DFA8EAC5D111BBCB0080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.326
+       NAME 'perRecipDialogDisplayTable'
+       RANGE-LOWER '1'
+       RANGE-UPPER '32768'
+       PROPERTY-GUID 'D424D45F6212D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1248
+       NAME 'interSiteTopologyFailover'
+       PROPERTY-GUID '609EC6B7C72CD211854E00A0C983F608'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.895
+       NAME 'transportAddressAttribute'
+       PROPERTY-GUID '7C86DCC161A2D111B6060000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.852
+       NAME 'netbootCurrentClientCount'
+       PROPERTY-GUID '79303807DF91D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.372
+       NAME 'rIDPreviousAllocationPool'
+       PROPERTY-GUID '8A1817663C8FD011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.83
+       NAME 'repsTo'
+       PROPERTY-GUID '1E7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.224
+       NAME 'defaultSecurityDescriptor'
+       RANGE-LOWER '0'
+       RANGE-UPPER '32767'
+       PROPERTY-GUID '306D7A806916D011A06400AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.9
+       NAME 'street'
+       RANGE-LOWER '1'
+       RANGE-UPPER '1024'
+       PROPERTY-GUID '3A7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.519
+       NAME 'lastBackupRestorationTime'
+       PROPERTY-GUID 'E80BBB1F63BAD011AFEF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.873
+       NAME 'fRSControlOutboundBacklog'
+       RANGE-LOWER '0'
+       RANGE-UPPER '32'
+       PROPERTY-GUID '7C25132A7393D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.255
+       NAME 'vendor'
+       RANGE-LOWER '0'
+       RANGE-UPPER '512'
+       PROPERTY-GUID 'DF1614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.891
+       NAME 'gPLink'
+       PROPERTY-GUID 'BE3B0EF3F09FD111B6030000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.22
+       NAME 'teletexTerminalIdentifier'
+       PROPERTY-GUID '4A7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 0.9.2342.19200300.100.1.41
+       NAME 'mobile'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID 'A3FFF8F09111D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.214
+       NAME 'originalDisplayTableMSDOS'
+       RANGE-LOWER '1'
+       RANGE-UPPER '32768'
+       PROPERTY-GUID 'CF24D45F6212D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.50
+       NAME 'linkID'
+       PROPERTY-GUID '9B7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1130
+       NAME 'msNPSavedCallingStationID'
+       PROPERTY-GUID '8E900CDBF2C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.39
+       NAME 'certificateRevocationList'
+       PROPERTY-GUID '9F577716F347D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.31
+       NAME 'member'
+       PROPERTY-GUID 'C07996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '40C20ABCA979D011902000C04FC2D4CF' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.49
+       NAME 'mAPIID'
+       PROPERTY-GUID 'B77996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.510
+       NAME 'serviceBindingInformation'
+       PROPERTY-GUID '1C31B1B72EB8D011AFEE0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.16
+       NAME 'nCName'
+       PROPERTY-GUID 'D67996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1303
+       NAME 'tokenGroupsNoGCAcceptable'
+       PROPERTY-GUID '92C30F04DF33D21198B20000F87A57D4'
+       PROPERTY-SET-GUID 'F8887003E10AD211B42200A0C968F939' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1190
+       NAME 'msRASSavedFramedIPAddress'
+       PROPERTY-GUID 'C6900CDBF2C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.766
+       NAME 'aCSAllocableRSVPBandwidth'
+       PROPERTY-GUID '8312567F0153D111A9C50000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.61
+       NAME 'lockOutObservationWindow'
+       PROPERTY-GUID 'A47996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '607340C7BF20D011A76800AA006E0529' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.857
+       NAME 'netbootIntelliMirrorOSes'
+       PROPERTY-GUID '7E303807DF91D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1320
+       NAME 'aCSNonReservedMaxSDUSize'
+       PROPERTY-GUID 'E3CFC2AE903BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.32
+       NAME 'owner'
+       PROPERTY-GUID 'F37996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.265
+       NAME 'notes'
+       PROPERTY-GUID '41FB056D6B24D011A9C800AA006C33ED'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050' )
+
+extendedAttributeInfo ( 2.5.4.12
+       NAME 'title'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID '557A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.673
+       NAME 'retiredReplDSASignatures'
+       PROPERTY-GUID '7FCBFD7B0748D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1313
+       NAME 'aCSMaxTokenBucketPerFlow'
+       PROPERTY-GUID 'DFE0F681903BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.324
+       NAME 'addressEntryDisplayTable'
+       RANGE-LOWER '1'
+       RANGE-UPPER '32768'
+       PROPERTY-GUID '6124D45F6212D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 0.9.2342.19200300.100.1.42
+       NAME 'pager'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID 'A6FFF8F09111D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1317
+       NAME 'aCSMinimumDelayVariation'
+       PROPERTY-GUID '9B32659C903BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.872
+       NAME 'fRSControlInboundBacklog'
+       RANGE-LOWER '0'
+       RANGE-UPPER '32'
+       PROPERTY-GUID '7B25132A7393D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.38
+       NAME 'flags'
+       PROPERTY-GUID '767996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1399
+       NAME 'mS-SQL-LastDiagnosticDate'
+       PROPERTY-GUID '88DDD6F6EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1348
+       NAME 'gPCMachineExtensionNames'
+       PROPERTY-GUID 'CC8EFF323F78D21199160000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1411
+       NAME 'ms-DS-MachineAccountQuota'
+       PROPERTY-GUID '68FB64D08014D31191C10000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.325
+       NAME 'perMsgDialogDisplayTable'
+       RANGE-LOWER '1'
+       RANGE-UPPER '32768'
+       PROPERTY-GUID 'D324D45F6212D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.23
+       NAME 'facsimileTelephoneNumber'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID '747996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.57
+       NAME 'defaultLocalPolicyObject'
+       PROPERTY-GUID '9F7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1189
+       NAME 'msRASSavedCallbackNumber'
+       PROPERTY-GUID 'C5900CDBF2C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.38
+       NAME 'authorityRevocationList'
+       PROPERTY-GUID '8D577716F347D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.685
+       NAME 'parentCACertificateChain'
+       PROPERTY-GUID '33273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.893
+       NAME 'gPCFunctionalityVersion'
+       PROPERTY-GUID 'C03B0EF3F09FD111B6030000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.879
+       NAME 'fRSServiceCommandStatus'
+       RANGE-LOWER '0'
+       RANGE-UPPER '512'
+       PROPERTY-GUID '8225132A7393D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1319
+       NAME 'aCSNonReservedTokenSize'
+       PROPERTY-GUID 'C9D716A9903BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.775
+       NAME 'aCSMaxSizeOfRSVPLogFile'
+       PROPERTY-GUID '9D55B31CD056D111A9C60000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.135
+       NAME 'cost'
+       PROPERTY-GUID '447996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.81
+       NAME 'modifiedCountAtLastProm'
+       PROPERTY-GUID 'C67996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.773
+       NAME 'aCSRSVPLogFilesLocation'
+       PROPERTY-GUID '9B55B31CD056D111A9C60000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.25
+       NAME 'internationalISDNNumber'
+       RANGE-LOWER '1'
+       RANGE-UPPER '16'
+       PROPERTY-GUID '8D7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.81
+       NAME 'info'
+       RANGE-LOWER '1'
+       RANGE-UPPER '1024'
+       PROPERTY-GUID '3E7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.125
+       NAME 'supplementalCredentials'
+       PROPERTY-GUID '3F7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.819
+       NAME 'bridgeheadTransportList'
+       PROPERTY-GUID 'DA2C0CD55189D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.28
+       NAME 'preferredDeliveryMethod'
+       PROPERTY-GUID 'FE7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 0.9.2342.19200300.100.1.3
+       NAME 'mail'
+       RANGE-LOWER '0'
+       RANGE-UPPER '256'
+       PROPERTY-GUID '617996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.967
+       NAME 'mSMQSignCertificatesMig'
+       PROPERTY-GUID 'EAB881383BDAD11190A500C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1
+       NAME 'name'
+       RANGE-LOWER '1'
+       RANGE-UPPER '255'
+       PROPERTY-GUID '0E7A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       INDEXED
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1153
+       NAME 'msRADIUSFramedIPAddress'
+       PROPERTY-GUID 'A4900CDBF2C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID 'F8887003E10AD211B42200A0C968F939' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1408
+       NAME 'mS-DS-ReplicatesNCReason'
+       PROPERTY-GUID '842BA10EB308D31191BC0000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.899
+       NAME 'aCSEnableRSVPAccounting'
+       PROPERTY-GUID '0E2372F0F5AED111BDCF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.881
+       NAME 'fRSTimeLastConfigChange'
+       PROPERTY-GUID '8425132A7393D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.281
+       NAME 'printStaplingSupported'
+       PROPERTY-GUID '735F30BAE347D011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1247
+       NAME 'interSiteTopologyRenew'
+       PROPERTY-GUID '5F9EC6B7C72CD211854E00A0C983F608'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.364
+       NAME 'operatingSystemVersion'
+       PROPERTY-GUID '2689973E018CD011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.91
+       NAME 'otherLoginWorkstations'
+       RANGE-LOWER '0'
+       RANGE-UPPER '1024'
+       PROPERTY-GUID 'F17996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.849
+       NAME 'netbootAllowNewClients'
+       PROPERTY-GUID '76303807DF91D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1372
+       NAME 'mS-SQL-UnicodeSortOrder'
+       PROPERTY-GUID '8A91DC72EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.749
+       NAME 'url'
+       PROPERTY-GUID '21029A9A5B4AD111A9C30000F80367C1'
+       PROPERTY-SET-GUID 'B39557E45594D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.206
+       NAME 'pKT'
+       PROPERTY-GUID 'F1F947842710D011A05F00AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.199
+       NAME 'serviceInstanceVersion'
+       RANGE-LOWER '0'
+       RANGE-UPPER '8'
+       PROPERTY-GUID '377A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.169
+       NAME 'showInAdvancedViewOnly'
+       PROPERTY-GUID '847996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '422FBA59A279D011902000C04FC2D3CF'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.758
+       NAME 'aCSMaxTokenRatePerFlow'
+       PROPERTY-GUID '7B12567F0153D111A9C50000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.868
+       NAME 'isCriticalSystemObject'
+       PROPERTY-GUID '0DF3FB00FE91D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.576
+       NAME 'meetingMaxParticipants'
+       PROPERTY-GUID '85CCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1208
+       NAME 'aNR'
+       PROPERTY-GUID '0015B04519C4D111BBC90080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.153
+       NAME 'rid'
+       PROPERTY-GUID '227A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.523
+       NAME 'proxyGenerationEnabled'
+       PROPERTY-GUID 'D624D45F6212D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.871
+       NAME 'fRSControlDataCreation'
+       RANGE-LOWER '0'
+       RANGE-UPPER '32'
+       PROPERTY-GUID '7A25132A7393D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.692
+       NAME 'previousCACertificates'
+       PROPERTY-GUID '39273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.24
+       NAME 'contentIndexingAllowed'
+       PROPERTY-GUID '437996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.633
+       NAME 'policyReplicationFlags'
+       PROPERTY-GUID '965B4019FA3CD111A9C00000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.870
+       NAME 'frsComputerReferenceBL'
+       PROPERTY-GUID '7925132A7393D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1318
+       NAME 'aCSNonReservedPeakRate'
+       PROPERTY-GUID '3FA731A3903BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.901
+       NAME 'aCSMaxNoOfAccountFiles'
+       PROPERTY-GUID '102372F0F5AED111BDCF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.514
+       NAME 'physicalLocationObject'
+       PROPERTY-GUID '1931B1B72EB8D011AFEE0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.928
+       NAME 'mSMQOutRoutingServers'
+       PROPERTY-GUID '2BC30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.820
+       NAME 'bridgeheadServerListBL'
+       PROPERTY-GUID 'DB2C0CD55189D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1145
+       NAME 'msRADIUSCallbackNumber'
+       PROPERTY-GUID '9C900CDBF2C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID 'F8887003E10AD211B42200A0C968F939' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.361
+       NAME 'netbootMachineFilePath'
+       PROPERTY-GUID '2389973E018CD011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.963
+       NAME 'mSMQQueueJournalQuota'
+       PROPERTY-GUID '6612448E7FD5D11190A200C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.853
+       NAME 'netbootAnswerRequests'
+       PROPERTY-GUID '7A303807DF91D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.415
+       NAME 'operatingSystemHotfix'
+       PROPERTY-GUID '3C1B95BD969CD011AFDD00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.149
+       NAME 'attributeSecurityGUID'
+       RANGE-LOWER '16'
+       RANGE-UPPER '16'
+       PROPERTY-GUID '247996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.711
+       NAME 'superScopeDescription'
+       PROPERTY-GUID '4C273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1359
+       NAME 'otherWellKnownObjects'
+       PROPERTY-GUID '5D4EA61E0FACD21190DF00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.780
+       NAME 'aCSNonReservedTxLimit'
+       PROPERTY-GUID 'A255B31CD056D111A9C60000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.11
+       NAME 'authenticationOptions'
+       PROPERTY-GUID '287996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.867
+       NAME 'altSecurityIdentities'
+       PROPERTY-GUID '0CF3FB00FE91D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1349
+       NAME 'gPCUserExtensionNames'
+       PROPERTY-GUID 'C65FA7423F78D21199160000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.8
+       NAME 'st'
+       RANGE-LOWER '1'
+       RANGE-UPPER '128'
+       PROPERTY-GUID '397A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 2.5.4.11
+       NAME 'ou'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID 'F07996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.358
+       NAME 'netbootInitialization'
+       PROPERTY-GUID '2089973E018CD011AFDA00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1364
+       NAME 'mS-SQL-RegisteredOwner'
+       PROPERTY-GUID 'EA44FD48EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.761
+       NAME 'aCSMaxDurationPerFlow'
+       PROPERTY-GUID '7E12567F0153D111A9C50000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.4
+       NAME 'sn'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID '417A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1330
+       NAME 'pKICriticalExtensions'
+       PROPERTY-GUID '06915AFC9D3BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.748
+       NAME 'attributeDisplayNames'
+       PROPERTY-GUID '803F84CBD948D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1404
+       NAME 'mS-SQL-AllowImmediateUpdatingSubscription'
+       PROPERTY-GUID '6E6B18C44BD3D211999A0000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1191
+       NAME 'msRASSavedFramedRoute'
+       PROPERTY-GUID 'C7900CDBF2C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.752
+       NAME 'userSharedFolderOther'
+       PROPERTY-GUID '20029A9A5B4AD111A9C30000F80367C1'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.131
+       NAME 'co'
+       RANGE-LOWER '1'
+       RANGE-UPPER '128'
+       PROPERTY-GUID 'A7FFF8F09111D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.909
+       NAME 'extendedAttributeInfo'
+       PROPERTY-GUID '47D97A9A53CAD111BBD00080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 2.5.4.3
+       NAME 'cn'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID '3F7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1241
+       NAME 'netbootMirrorDataFile'
+       PROPERTY-GUID '850DF92D9F00D211AA4C00C04FD7D83A'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1315
+       NAME 'aCSMinimumPolicedSize'
+       PROPERTY-GUID '95710E8D903BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1353
+       NAME 'localizationDisplayId'
+       PROPERTY-GUID 'D1F046A7D078D21199160000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.582
+       NAME 'meetingAdvertiseScope'
+       PROPERTY-GUID '8BCCB611C448D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 0.9.2342.19200300.100.1.25
+       NAME 'dc'
+       RANGE-LOWER '1'
+       RANGE-UPPER '255'
+       PROPERTY-GUID '555A1919A06DD011AFD300C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1343
+       NAME 'dSUIAdminNotification'
+       PROPERTY-GUID '940AEAF6916FD21199050000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1381
+       NAME 'mS-SQL-LastUpdatedDate'
+       PROPERTY-GUID 'D443CC9FEECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1357
+       NAME 'dSCorePropagationData'
+       PROPERTY-GUID '4BAA67D1088BD21199390000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.320
+       NAME 'implementedCategories'
+       RANGE-LOWER '16'
+       RANGE-UPPER '16'
+       PROPERTY-GUID '920E6C7D207ED011AFD600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.783
+       NAME 'defaultObjectCategory'
+       PROPERTY-GUID '6773D9267060D111A9C60000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.422
+       NAME 'domainPolicyReference'
+       PROPERTY-GUID '2A7EA680229FD011AFDD00C04FD930C9'
+       PROPERTY-SET-GUID 'FE899BA2E8C7D0119BAE00C04FD92EF5' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.929
+       NAME 'mSMQInRoutingServers'
+       PROPERTY-GUID '2CC30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1311
+       NAME 'printDuplexSupported'
+       PROPERTY-GUID 'CC1614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.693
+       NAME 'pendingCACertificates'
+       PROPERTY-GUID '3C273D96BE48D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.281
+       NAME 'nTSecurityDescriptor'
+       RANGE-LOWER '0'
+       RANGE-UPPER '132096'
+       PROPERTY-GUID 'E37996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.198
+       NAME 'systemAuxiliaryClass'
+       PROPERTY-GUID '437A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.898
+       NAME 'aCSNonReservedTxSize'
+       PROPERTY-GUID '0D2372F0F5AED111BDCF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1382
+       NAME 'mS-SQL-InformationURL'
+       PROPERTY-GUID '10D52CA4EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.3
+       NAME 'replPropertyMetaData'
+       PROPERTY-GUID 'C01614286819D011A28F00AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1384
+       NAME 'mS-SQL-PublicationURL'
+       PROPERTY-GUID 'B8110CAEEECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.275
+       NAME 'printKeepPrintedJobs'
+       PROPERTY-GUID '6D5F30BAE347D011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.267
+       NAME 'uSNDSALastObjRemoved'
+       PROPERTY-GUID '717A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 2.5.4.10
+       NAME 'o'
+       RANGE-LOWER '1'
+       RANGE-UPPER '64'
+       PROPERTY-GUID 'EF7996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.381
+       NAME 'dnsNotifySecondaries'
+       PROPERTY-GUID '681EFAE0459BD011AFDD00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1360
+       NAME 'mS-DS-ConsistencyGuid'
+       PROPERTY-GUID 'C23D77233AB6D21190E100C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.7
+       NAME 'l'
+       RANGE-LOWER '1'
+       RANGE-UPPER '128'
+       PROPERTY-GUID 'A27996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.869
+       NAME 'frsComputerReference'
+       PROPERTY-GUID '7825132A7393D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1369
+       NAME 'mS-SQL-ServiceAccount'
+       PROPERTY-GUID '3E3A9364EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1124
+       NAME 'msNPCallingStationID'
+       PROPERTY-GUID '8A900CDBF2C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID 'F8887003E10AD211B42200A0C968F939' )
+
+extendedAttributeInfo ( 2.5.4.2
+       NAME 'knowledgeInformation'
+       PROPERTY-GUID '1F587716F347D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.947
+       NAME 'mSMQSignCertificates'
+       PROPERTY-GUID '3BC30D9A00C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 2.5.4.6
+       NAME 'c'
+       RANGE-LOWER '1'
+       RANGE-UPPER '3'
+       PROPERTY-GUID '457996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.624
+       NAME 'ipsecOwnersReference'
+       PROPERTY-GUID '24F80FB47A42D111A9C20000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.14
+       NAME 'builtinModifiedCount'
+       PROPERTY-GUID '307996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 0.9.2342.19200300.100.1.2
+       NAME 'textEncodedORAddress'
+       RANGE-LOWER '1'
+       RANGE-UPPER '1024'
+       PROPERTY-GUID '8974DFA8EAC5D111BBCB0080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.27
+       NAME 'destinationIndicator'
+       RANGE-LOWER '1'
+       RANGE-UPPER '128'
+       PROPERTY-GUID '517996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.634
+       NAME 'privilegeDisplayName'
+       PROPERTY-GUID '985B4019FA3CD111A9C00000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.16.840.1.113730.3.140
+       NAME 'userSMIMECertificate'
+       PROPERTY-GUID 'B29D6AE13C40D111A9C00000F80367C1'
+       PROPERTY-SET-GUID '86B8B5774A94D111AEBD0000F80367C1' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.380
+       NAME 'dnsSecureSecondaries'
+       PROPERTY-GUID '671EFAE0459BD011AFDD00C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.817
+       NAME 'localizedDescription'
+       PROPERTY-GUID '1683E1D93989D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.195
+       NAME 'systemPossSuperiors'
+       PROPERTY-GUID '477A96BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 2.5.4.40
+       NAME 'crossCertificatePair'
+       PROPERTY-GUID 'B2577716F347D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.353
+       NAME 'displayNamePrintable'
+       RANGE-LOWER '1'
+       RANGE-UPPER '256'
+       PROPERTY-GUID '547996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.771
+       NAME 'servicePrincipalName'
+       PROPERTY-GUID '8847A6F30653D111A9C50000F80367C1'
+       PROPERTY-SET-GUID '54018DE4F8BCD111870200C04FB96050'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.866
+       NAME 'pekKeyChangeInterval'
+       PROPERTY-GUID '84303807DF91D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.445
+       NAME 'originalDisplayTable'
+       RANGE-LOWER '1'
+       RANGE-UPPER '32768'
+       PROPERTY-GUID 'CE24D45F6212D011A06000AA006C33ED'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1398
+       NAME 'mS-SQL-LastBackupDate'
+       PROPERTY-GUID 'CAABB6F2EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.517
+       NAME 'ipsecPolicyReference'
+       PROPERTY-GUID '1831B1B72EB8D011AFEE0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.823
+       NAME 'certificateTemplates'
+       PROPERTY-GUID 'B1C5392A6089D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.15
+       NAME 'hasPartialReplicaNCs'
+       PROPERTY-GUID '817996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.457
+       NAME 'localPolicyReference'
+       PROPERTY-GUID '4D7EA680229FD011AFDD00C04FD930C9'
+       PROPERTY-SET-GUID '018A9BA2E8C7D0119BAE00C04FD92EF5' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.2.380
+       NAME 'extendedCharsAllowed'
+       PROPERTY-GUID '667996BFE60DD011A28500AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.629
+       NAME 'ipsecFilterReference'
+       PROPERTY-GUID '23F80FB47A42D111A9C20000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.626
+       NAME 'ipsecISAKMPReference'
+       PROPERTY-GUID '20F80FB47A42D111A9C20000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.876
+       NAME 'fRSMemberReferenceBL'
+       PROPERTY-GUID '7F25132A7393D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.314
+       NAME 'rpcNsTransferSyntax'
+       PROPERTY-GUID '4A1C4029277AD011AFD600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       INDEXED )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1227
+       NAME 'mSMQRoutingServices'
+       PROPERTY-GUID '770DF92D9F00D211AA4C00C04FD7D83A'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1375
+       NAME 'mS-SQL-MultiProtocol'
+       PROPERTY-GUID '38FA5781EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.825
+       NAME 'enrollmentProviders'
+       PROPERTY-GUID 'B3C5392A6089D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.287
+       NAME 'printNetworkAddress'
+       PROPERTY-GUID '795F30BAE347D011A1A600C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1171
+       NAME 'msRADIUSServiceType'
+       PROPERTY-GUID 'B6900CDBF2C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID 'F8887003E10AD211B42200A0C968F939' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.631
+       NAME 'printPagesPerMinute'
+       PROPERTY-GUID '975B4019FA3CD111A9C00000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.299
+       NAME 'printMediaSupported'
+       PROPERTY-GUID '6F294B24BD5AD011AFD200C04FD930C9'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.824
+       NAME 'signatureAlgorithms'
+       PROPERTY-GUID 'B2C5392A6089D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.877
+       NAME 'fRSPartnerAuthLevel'
+       PROPERTY-GUID '8025132A7393D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.636
+       NAME 'privilegeAttributes'
+       PROPERTY-GUID '9A5B4019FA3CD111A9C00000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.640
+       NAME 'partialAttributeSet'
+       PROPERTY-GUID '9E5B4019FA3CD111A9C00000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.850
+       NAME 'netbootLimitClients'
+       PROPERTY-GUID '77303807DF91D111AEBC0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1383
+       NAME 'mS-SQL-ConnectionURL'
+       PROPERTY-GUID 'DA232DA9EECCD21199930000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1406
+       NAME 'mS-SQL-AllowSnapshotFilesFTPDownloading'
+       PROPERTY-GUID 'E88B9BC44BD3D211999A0000F87A57D4'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1331
+       NAME 'pKIExpirationPeriod'
+       PROPERTY-GUID 'D27015049E3BD21190CC00C04FD91AB1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.531
+       NAME 'nonSecurityMemberBL'
+       PROPERTY-GUID '198045526ACAD011AFFF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000'
+       SYSTEM-ONLY )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.540
+       NAME 'initialAuthOutgoing'
+       PROPERTY-GUID '248045526ACAD011AFFF0000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.1158
+       NAME 'msRADIUSFramedRoute'
+       PROPERTY-GUID 'A9900CDBF2C1D111BBC50080C76670C0'
+       PROPERTY-SET-GUID 'F8887003E10AD211B42200A0C968F939' )
+
+extendedAttributeInfo ( 1.2.840.113556.1.4.200
+       NAME 'controlAccessRights'
+       RANGE-LOWER '16'
+       RANGE-UPPER '16'
+       PROPERTY-GUID 'FCA4A86D520ED011A28600AA003049E2'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.29
+       NAME 'presentationAddress'
+       PROPERTY-GUID '4B74DFA8EAC5D111BBCB0080C76670C0'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
+extendedAttributeInfo ( 2.5.4.53
+       NAME 'deltaRevocationList'
+       PROPERTY-GUID 'B5577716F347D111A9C30000F80367C1'
+       PROPERTY-SET-GUID '00000000000000000000000000000000' )
+
diff --git a/servers/slapd/schema/microsoft.schema b/servers/slapd/schema/microsoft.schema
new file mode 100644 (file)
index 0000000..a2fe7a0
--- /dev/null
@@ -0,0 +1,4830 @@
+# $OpenLDAP$
+# This file is provided for informational purposes only.
+
+# These definitions are from Microsoft's Active Directory.
+# They were gathered using the subschemaSubentry object of
+# Windows 2000 Advanced Server Release Candidate 2.
+
+# These object classes and attributes are rooted at OID
+# 1.2.840.113556.1, Microsoft's Directory Enabled networks
+# OID.  Many of them rely on the modified "standard" objects
+# and attributes defined in "microsoft.std.schema".
+
+objectclass ( 1.2.840.113556.1.5.24
+       NAME 'remoteMailRecipient'
+       SUP top
+       STRUCTURAL 
+       MAY (remoteSource $ remoteSourceType $ managedBy ) )
+
+objectclass ( 1.2.840.113556.1.5.49
+       NAME 'packageRegistration'
+       SUP top
+       STRUCTURAL 
+       MAY (msiScriptPath $ cOMClassID $ cOMInterfaceID $ cOMProgID $
+               localeID $ machineArchitecture $ iconPath $ cOMTypelibId $
+               vendor $ packageType $ setupCommand $ packageName $
+               packageFlags $ versionNumberHi $ versionNumberLo $
+               lastUpdateSequence $ managedBy $ msiFileList $ categories $
+               upgradeProductCode $ msiScript $ canUpgradeScript $
+               fileExtPriority $ productCode $ msiScriptName $
+               msiScriptSize $ installUiLevel ) )
+
+objectclass ( 1.2.840.113556.1.5.161
+       NAME 'mSMQQueue'
+       SUP top
+       STRUCTURAL
+       MAY (mSMQQueueType $ mSMQJournal $ mSMQBasePriority $ mSMQLabel $
+               mSMQAuthenticate $ mSMQPrivacyLevel $ mSMQOwnerID $
+               mSMQTransactional $ mSMQQueueQuota $ mSMQQueueJournalQuota $
+               mSMQQueueNameExt ) )
+
+objectclass ( 1.2.840.113556.1.5.81
+       NAME 'rpcServer'
+       SUP rpcEntry
+       STRUCTURAL 
+       MAY (rpcNsObjectID $ rpcNsCodeset $ rpcNsEntryFlags ) )
+
+objectclass ( 1.2.840.113556.1.5.5
+       NAME 'samServer'
+       SUP securityObject
+       STRUCTURAL )
+
+objectclass ( 1.2.840.113556.1.5.156
+       NAME 'rRASAdministrationDictionary'
+       SUP top
+       STRUCTURAL 
+       MAY (msRRASVendorAttributeEntry ) )
+
+objectclass ( 1.2.840.113556.1.5.138
+       NAME 'aCSSubnet'
+       SUP top
+       STRUCTURAL 
+       MAY (aCSMaxTokenRatePerFlow $ aCSMaxPeakBandwidthPerFlow $
+               aCSMaxDurationPerFlow $ aCSAllocableRSVPBandwidth $
+               aCSMaxPeakBandwidth $ aCSEnableRSVPMessageLogging $
+               aCSEventLogLevel $ aCSEnableACSService $
+               aCSRSVPLogFilesLocation $ aCSMaxNoOfLogFiles $
+               aCSMaxSizeOfRSVPLogFile $ aCSDSBMPriority $ aCSDSBMRefresh $
+               aCSDSBMDeadTime $ aCSCacheTimeout $ aCSNonReservedTxLimit $
+               aCSNonReservedTxSize $ aCSEnableRSVPAccounting $
+               aCSRSVPAccountFilesLocation $ aCSMaxNoOfAccountFiles $
+               aCSMaxSizeOfRSVPAccountFile $ aCSServerList $
+               aCSNonReservedPeakRate $ aCSNonReservedTokenSize $
+               aCSNonReservedMaxSDUSize $ aCSNonReservedMinPolicedSize ) )
+
+objectclass ( 1.2.840.113556.1.5.137
+       NAME 'aCSPolicy'
+       SUP top
+       STRUCTURAL 
+       MAY (aCSTimeOfDay $ aCSDirection $ aCSMaxTokenRatePerFlow $
+               aCSMaxPeakBandwidthPerFlow $ aCSAggregateTokenRatePerUser $
+               aCSMaxDurationPerFlow $ aCSServiceType $ aCSTotalNoOfFlows $
+               aCSPriority $ aCSPermissionBits $ aCSIdentityName $
+               aCSMaxAggregatePeakRatePerUser $ aCSMaxTokenBucketPerFlow $
+               aCSMaximumSDUSize $ aCSMinimumPolicedSize $ aCSMinimumLatency $
+               aCSMinimumDelayVariation ) )
+
+objectclass ( 1.2.840.113556.1.5.154
+       NAME 'nTFRSSubscriptions'
+       SUP top
+       STRUCTURAL 
+       MAY (fRSWorkingPath $ fRSExtensions $ fRSVersion ) )
+
+objectclass ( 1.2.840.113556.1.5.176
+       NAME 'msExchConfigurationContainer'
+       SUP container
+       STRUCTURAL 
+       MAY (addressBookRoots $ globalAddressList $ templateRoots ) )
+
+objectclass ( 1.2.840.113556.1.5.141
+       NAME 'interSiteTransport'
+       SUP top
+       STRUCTURAL 
+       MUST (transportDLLName $ transportAddressAttribute )
+       MAY (options $ replInterval ) )
+
+objectclass ( 1.2.840.113556.1.3.23
+       NAME 'container'
+       SUP top
+       STRUCTURAL 
+       MUST (cn )
+       MAY (schemaVersion $ defaultClassStore ) )
+
+objectclass ( 1.2.840.113556.1.5.67
+       NAME 'domainDNS'
+       SUP domain
+       STRUCTURAL 
+       MAY (managedBy ) )
+
+objectclass ( 1.2.840.113556.1.5.3
+       NAME 'samDomain'
+       SUP top
+       AUXILIARY
+       MAY (description $ cACertificate $ builtinCreationTime $
+               builtinModifiedCount $ creationTime $ domainPolicyObject $
+               defaultLocalPolicyObject $ lockoutDuration $
+               lockOutObservationWindow $ lSACreationTime $ lSAModifiedCount $
+               lockoutThreshold $ maxPwdAge $ minPwdAge $ minPwdLength $
+               modifiedCountAtLastProm $ nETBIOSName $ nextRid $ pwdProperties $
+               pwdHistoryLength $ privateKey $ replicaSource $
+               controlAccessRights $ auditingPolicy $ eFSPolicy $
+               desktopProfile $ nTMixedDomain $ rIDManagerReference $ treeName $
+               pekList $ pekKeyChangeInterval $ gPLink $ gPOptions $
+               ms-DS-MachineAccountQuota ) )
+
+objectclass ( 1.2.840.113556.1.5.152
+       NAME 'intellimirrorGroup'
+       SUP top
+       STRUCTURAL )
+
+objectclass ( 1.2.840.113556.1.5.132
+       NAME 'dHCPClass'
+       SUP top
+       STRUCTURAL 
+       MUST (dhcpUniqueKey $ dhcpType $ dhcpFlags $ dhcpIdentification )
+       MAY (networkAddress $ dhcpObjName $ dhcpObjDescription $ dhcpServers $
+               dhcpSubnets $ dhcpMask $ dhcpRanges $ dhcpSites $ dhcpReservations $
+               superScopes $ superScopeDescription $ optionDescription $
+               optionsLocation $ dhcpOptions $ dhcpClasses $ mscopeId $ dhcpState $
+               dhcpProperties $ dhcpMaxKey $ dhcpUpdateTime ) )
+
+objectclass ( 1.2.840.113556.1.5.7000.56
+       NAME 'ipsecBase'
+       SUP top
+       ABSTRACT
+       MAY (ipsecName $ ipsecID $ ipsecDataType $ ipsecData $
+               ipsecOwnersReference ) )
+
+objectclass ( 1.2.840.113556.1.5.11
+       NAME 'comConnectionPoint'
+       SUP connectionPoint
+       STRUCTURAL 
+       MUST (cn )
+       MAY (marshalledInterface $ moniker $ monikerDisplayName ) )
+
+objectclass ( 1.2.840.113556.1.5.77
+       NAME 'controlAccessRight'
+       SUP top
+       STRUCTURAL 
+       MAY (rightsGuid $ appliesTo $ localizationDisplayId $ validAccesses ) )
+
+objectclass ( 1.2.840.113556.1.5.130
+       NAME 'indexServerCatalog'
+       SUP connectionPoint
+       STRUCTURAL 
+       MUST (creator )
+       MAY (uNCName $ queryPoint $ indexedScopes $ friendlyNames ) )
+
+objectclass ( 1.2.840.113556.1.5.140
+       NAME 'interSiteTransportContainer'
+       SUP top
+       STRUCTURAL )
+
+objectclass ( 1.2.840.113556.1.5.27
+       NAME 'rpcEntry'
+       SUP connectionPoint
+       ABSTRACT )
+
+objectclass ( 1.2.840.113556.1.5.80
+       NAME 'rpcGroup'
+       SUP rpcEntry
+       STRUCTURAL 
+       MAY (rpcNsGroup $ rpcNsObjectID ) )
+
+objectclass ( 1.2.840.113556.1.3.30
+       NAME 'computer'
+       SUP user
+       STRUCTURAL 
+       MAY (cn $ networkAddress $ localPolicyFlags $ defaultLocalPolicyObject $
+               machineRole $ location $ netbootInitialization $ netbootGUID $
+               netbootMachineFilePath $ siteGUID $ operatingSystem $
+               operatingSystemVersion $ operatingSystemServicePack $
+               operatingSystemHotfix $ volumeCount $ physicalLocationObject $
+               dNSHostName $ policyReplicationFlags $ managedBy $ rIDSetReferences $
+               catalogs $ netbootSIFFile $ netbootMirrorDataFile ) )
+
+objectclass ( 1.2.840.113556.1.5.189
+       NAME 'mS-SQL-OLAPDatabase'
+       SUP top
+       STRUCTURAL 
+       MAY (mS-SQL-Name $ mS-SQL-Contact $ mS-SQL-Status $
+               mS-SQL-LastUpdatedDate $ mS-SQL-InformationURL $ mS-SQL-ConnectionURL $
+                       mS-SQL-PublicationURL $ mS-SQL-Description $ mS-SQL-Type $
+                       mS-SQL-Size $ mS-SQL-LastBackupDate $ mS-SQL-Applications $
+                       mS-SQL-Keywords ) )
+
+objectclass ( 1.2.840.113556.1.3.11
+       NAME 'crossRef'
+       SUP top
+       STRUCTURAL 
+       MUST (cn $ nCName $ dnsRoot )
+       MAY (Enabled $ nETBIOSName $ trustParent $ superiorDNSRoot $ rootTrust ) )
+
+objectclass ( 1.2.840.113556.1.5.147
+       NAME 'siteLink'
+       SUP top
+       STRUCTURAL 
+       MUST (siteList )
+       MAY (cost $ schedule $ options $ replInterval ) )
+
+objectclass ( 1.2.840.113556.1.5.121
+       NAME 'ipsecNFA'
+       SUP ipsecBase
+       STRUCTURAL 
+       MAY (ipsecNegotiationPolicyReference $ ipsecFilterReference ) )
+
+objectclass ( 1.2.840.113556.1.5.92
+       NAME 'linkTrackVolEntry'
+       SUP leaf
+       STRUCTURAL 
+       MAY (linkTrackSecret $ volTableIdxGUID $ volTableGUID $ currMachineId $
+               timeVolChange $ timeRefresh $ seqNotification $ objectCount ) )
+
+objectclass ( 1.2.840.113556.1.5.93
+       NAME 'linkTrackOMTEntry'
+       SUP leaf
+       STRUCTURAL 
+       MAY (birthLocation $ oMTIndxGuid $ currentLocation $ timeRefresh $
+               oMTGuid ) )
+
+objectclass ( 1.2.840.113556.1.5.6
+       NAME 'securityPrincipal'
+       SUP top
+       AUXILIARY
+       MUST (objectSid $ sAMAccountName )
+       MAY (nTSecurityDescriptor $ securityIdentifier $ supplementalCredentials $
+               rid $ sAMAccountType $ sIDHistory $ altSecurityIdentities $ tokenGroups $
+               tokenGroupsNoGCAcceptable $ accountNameHistory ) )
+
+objectclass ( 1.2.840.113556.1.5.162
+       NAME 'mSMQConfiguration'
+       SUP top
+       STRUCTURAL 
+       MAY (mSMQQuota $ mSMQJournalQuota $ mSMQOwnerID $ mSMQSites $
+               mSMQOutRoutingServers $ mSMQInRoutingServers $ mSMQServiceType $
+               mSMQComputerType $ mSMQForeign $ mSMQOSType $ mSMQEncryptKey $
+               mSMQSignKey $ mSMQDependentClientServices $ mSMQRoutingServices $
+               mSMQDsServices ) )
+
+objectclass ( 1.2.840.113556.1.5.10
+       NAME 'classRegistration'
+       SUP leaf
+       STRUCTURAL 
+       MAY (cOMInterfaceID $ cOMProgID $ cOMCLSID $ cOMTreatAsClassId $
+               cOMOtherProgId $ implementedCategories $ requiredCategories $
+               managedBy ) )
+
+objectclass ( 1.2.840.113556.1.5.191
+       NAME 'aCSResourceLimits'
+       SUP top
+       STRUCTURAL 
+       MAY (aCSMaxTokenRatePerFlow $ aCSMaxPeakBandwidthPerFlow $ aCSServiceType $
+               aCSAllocableRSVPBandwidth $ aCSMaxPeakBandwidth ) )
+
+objectclass ( 1.2.840.113556.1.5.7000.53
+       NAME 'crossRefContainer'
+       SUP top
+       STRUCTURAL 
+       MAY (uPNSuffixes ) )
+
+objectclass ( 1.2.840.113556.1.5.120
+       NAME 'ipsecISAKMPPolicy'
+       SUP ipsecBase
+       STRUCTURAL )
+
+objectclass ( 1.2.840.113556.1.5.26
+       NAME 'rpcProfileElement'
+       SUP rpcEntry
+       STRUCTURAL 
+       MUST (rpcNsInterfaceID $ rpcNsPriority )
+       MAY (rpcNsProfileEntry $ rpcNsAnnotation ) )
+
+objectclass ( 1.2.840.113556.1.5.188
+       NAME 'mS-SQL-SQLDatabase'
+       SUP top
+       STRUCTURAL 
+       MAY (mS-SQL-Name $ mS-SQL-Contact $ mS-SQL-Status $ mS-SQL-InformationURL $
+               mS-SQL-Description $ mS-SQL-Alias $ mS-SQL-Size $ mS-SQL-CreationDate $
+               mS-SQL-LastBackupDate $ mS-SQL-LastDiagnosticDate $ mS-SQL-Applications $
+               mS-SQL-Keywords ) )
+
+objectclass ( 1.2.840.113556.1.5.94
+       NAME 'serviceAdministrationPoint'
+       SUP serviceConnectionPoint
+       STRUCTURAL )
+
+objectclass ( 1.2.840.113556.1.5.85
+       NAME 'dnsZone'
+       SUP top
+       STRUCTURAL 
+       MUST (dc )
+       MAY (dnsAllowDynamic $ dnsAllowXFR $ dnsSecureSecondaries $
+               dnsNotifySecondaries $ managedBy $ dNSProperty ) )
+
+objectclass ( 1.2.840.113556.1.5.33
+       NAME 'storage'
+       SUP connectionPoint
+       STRUCTURAL 
+       MAY (moniker $ monikerDisplayName $ iconPath ) )
+
+objectclass ( 1.2.840.113556.1.5.7000.47
+       NAME 'nTDSDSA'
+       SUP applicationSettings
+       STRUCTURAL 
+       MAY (hasMasterNCs $ hasPartialReplicaNCs $ dMDLocation $ invocationId $
+               networkAddress $ options $ fRSRootPath $ serverReference $
+               lastBackupRestorationTime $ queryPolicyObject $ managedBy $
+               retiredReplDSASignatures ) )
+
+objectclass ( 1.2.840.113556.1.5.15
+       NAME 'contact'
+       SUP organizationalPerson
+       STRUCTURAL 
+       MUST (cn )
+       MAY (notes ) )
+
+objectclass ( 1.2.840.113556.1.5.86
+       NAME 'dnsNode'
+       SUP top
+       STRUCTURAL 
+       MUST (dc )
+       MAY (dnsRecord $ dNSProperty $ dNSTombstoned ) )
+
+objectclass ( 1.2.840.113556.1.5.104
+       NAME 'meeting'
+       SUP top
+       STRUCTURAL 
+       MUST (meetingName )
+       MAY (meetingID $ meetingDescription $ meetingKeyword $ meetingLocation $
+               meetingProtocol $ meetingType $ meetingApplication $ meetingLanguage $
+               meetingMaxParticipants $ meetingOriginator $ meetingContactInfo $
+               meetingOwner $ meetingIP $ meetingScope $ meetingAdvertiseScope $
+               meetingURL $ meetingRating $ meetingIsEncrypted $ meetingRecurrence $
+               meetingStartTime $ meetingEndTime $ meetingBandwidth $ meetingBlob ) )
+
+objectclass ( 1.2.840.113556.1.5.69
+       NAME 'nTDSSiteSettings'
+       SUP applicationSiteSettings
+       STRUCTURAL 
+       MAY (schedule $ options $ queryPolicyObject $ managedBy $
+               interSiteTopologyGenerator $ interSiteTopologyRenew $
+               interSiteTopologyFailover ) )
+
+objectclass ( 1.2.840.113556.1.5.151
+       NAME 'intellimirrorSCP'
+       SUP serviceAdministrationPoint
+       STRUCTURAL 
+       MAY (netbootMachineFilePath $ netbootAllowNewClients $ netbootLimitClients $
+               netbootMaxClients $ netbootCurrentClientCount $ netbootAnswerRequests $
+               netbootAnswerOnlyValidClients $ netbootNewMachineNamingPolicy $
+               netbootNewMachineOU $ netbootIntelliMirrorOSes $ netbootTools $
+               netbootLocallyInstalledOSes $ netbootServer ) )
+
+objectclass ( 1.2.840.113556.1.5.7000.48
+       NAME 'serversContainer'
+       SUP top
+       STRUCTURAL )
+
+objectclass ( 1.2.840.113556.1.5.185
+       NAME 'mS-SQL-OLAPServer'
+       SUP serviceConnectionPoint
+       STRUCTURAL 
+       MAY (mS-SQL-Name $ mS-SQL-RegisteredOwner $ mS-SQL-Contact $ mS-SQL-Build $
+               mS-SQL-ServiceAccount $ mS-SQL-Status $ mS-SQL-InformationURL $
+               mS-SQL-PublicationURL $ mS-SQL-Version $ mS-SQL-Language $
+               mS-SQL-Keywords ) )
+
+objectclass ( 1.2.840.113556.1.5.179
+       NAME 'mSMQMigratedUser'
+       SUP top
+       STRUCTURAL 
+       MAY (objectSid $ mSMQSignCertificates $ mSMQDigests $ mSMQDigestsMig $
+               mSMQSignCertificatesMig $ mSMQUserSid ) )
+
+objectclass ( 1.2.840.113556.1.5.73
+       NAME 'rpcServerElement'
+       SUP rpcEntry
+       STRUCTURAL 
+       MUST (rpcNsBindings $ rpcNsInterfaceID $ rpcNsTransferSyntax ) )
+
+objectclass ( 1.2.840.113556.1.5.97
+       NAME 'physicalLocation'
+       SUP locality
+       STRUCTURAL 
+       MAY (managedBy ) )
+
+objectclass ( 1.2.840.113556.1.5.42
+       NAME 'dfsConfiguration'
+       SUP top
+       STRUCTURAL )
+
+objectclass ( 1.2.840.113556.1.5.84
+       NAME 'displaySpecifier'
+       SUP top
+       STRUCTURAL 
+       MAY (iconPath $ creationWizard $ contextMenu $ adminPropertyPages $
+               shellPropertyPages $ classDisplayName $ adminContextMenu $
+               shellContextMenu $ attributeDisplayNames $ treatAsLeaf $ createDialog $
+               createWizardExt $ scopeFlags $ queryFilter ) )
+
+objectclass ( 1.2.840.113556.1.5.52
+       NAME 'fileLinkTracking'
+       SUP top
+       STRUCTURAL )
+
+objectclass ( 1.2.840.113556.1.5.146
+       NAME 'remoteStorageServicePoint'
+       SUP serviceAdministrationPoint
+       STRUCTURAL 
+       MAY (remoteStorageGUID ) )
+
+objectclass ( 1.2.840.113556.1.5.36
+       NAME 'volume'
+       SUP connectionPoint
+       STRUCTURAL 
+       MUST (uNCName )
+       MAY (contentIndexingAllowed $ lastContentIndexed ) )
+
+objectclass ( 1.2.840.113556.1.5.17
+       NAME 'server'
+       SUP top
+       STRUCTURAL 
+       MAY (serialNumber $ serverReference $ dNSHostName $ managedBy $
+               mailAddress $ bridgeheadTransportList ) )
+
+objectclass ( 1.2.840.113556.1.5.96
+       NAME 'subnet'
+       SUP top
+       STRUCTURAL 
+       MAY (location $ siteObject $ physicalLocationObject ) )
+
+objectclass ( 1.2.840.113556.1.5.129
+       NAME 'rIDSet'
+       SUP top
+       STRUCTURAL 
+       MUST (rIDAllocationPool $ rIDPreviousAllocationPool $ rIDUsedPool $
+               rIDNextRID ) )
+
+objectclass ( 1.2.840.113556.1.5.28
+       NAME 'secret'
+       SUP leaf
+       STRUCTURAL 
+       MAY (currentValue $ lastSetTime $ priorSetTime $ priorValue ) )
+
+objectclass ( 1.2.840.113556.1.5.66
+       NAME 'domain'
+       SUP top
+       ABSTRACT
+       MUST (dc ) )
+
+objectclass ( 1.2.840.113556.1.5.184
+       NAME 'mS-SQL-SQLServer'
+       SUP serviceConnectionPoint
+       STRUCTURAL 
+       MAY (mS-SQL-Name $ mS-SQL-RegisteredOwner $ mS-SQL-Contact $
+               mS-SQL-Location $ mS-SQL-Memory $ mS-SQL-Build $
+               mS-SQL-ServiceAccount $ mS-SQL-CharacterSet $ mS-SQL-SortOrder $
+               mS-SQL-UnicodeSortOrder $ mS-SQL-Clustered $ mS-SQL-NamedPipe $
+               mS-SQL-MultiProtocol $ mS-SQL-SPX $ mS-SQL-TCPIP $ mS-SQL-AppleTalk $
+               mS-SQL-Vines $ mS-SQL-Status $ mS-SQL-LastUpdatedDate $
+               mS-SQL-InformationURL $ mS-SQL-GPSLatitude $ mS-SQL-GPSLongitude $
+               mS-SQL-GPSHeight $ mS-SQL-Keywords ) )
+
+objectclass ( 1.2.840.113556.1.5.155
+       NAME 'nTFRSSubscriber'
+       SUP top
+       STRUCTURAL 
+       MUST (fRSRootPath $ fRSStagingPath )
+       MAY (schedule $ fRSUpdateTimeout $ fRSFaultCondition $ fRSServiceCommand $
+               fRSExtensions $ fRSFlags $ fRSMemberReference $ fRSServiceCommandStatus $
+               fRSTimeLastCommand $ fRSTimeLastConfigChange ) )
+
+objectclass ( 1.2.840.113556.1.5.14
+       NAME 'connectionPoint'
+       SUP leaf
+       ABSTRACT
+       MUST (cn )
+       MAY (keywords $ managedBy ) )
+
+objectclass ( 1.2.840.113556.1.5.102
+       NAME 'nTFRSReplicaSet'
+       SUP top
+       STRUCTURAL 
+       MAY (fRSReplicaSetType $ fRSVersionGUID $ schedule $ fRSFileFilter $
+               fRSDirectoryFilter $ fRSDSPoll $ fRSServiceCommand $ fRSReplicaSetGUID $
+               fRSLevelLimit $ fRSRootSecurity $ fRSExtensions $ managedBy $ fRSFlags $
+               fRSPartnerAuthLevel $ fRSPrimaryMember ) )
+
+objectclass ( 1.2.840.113556.1.5.95
+       NAME 'subnetContainer'
+       SUP top
+       STRUCTURAL )
+
+objectclass ( 1.2.840.113556.1.3.59
+       NAME 'displayTemplate'
+       SUP top
+       STRUCTURAL 
+       MUST (cn )
+       MAY (helpData32 $ originalDisplayTableMSDOS $ addressEntryDisplayTable $
+               helpFileName $ addressEntryDisplayTableMSDOS $ helpData16 $
+               originalDisplayTable ) )
+
+objectclass ( 1.2.840.113556.1.5.30
+       NAME 'serviceInstance'
+       SUP connectionPoint
+       STRUCTURAL 
+       MUST (displayName $ serviceClassID )
+       MAY (winsockAddresses $ serviceInstanceVersion ) )
+
+objectclass ( 1.2.840.113556.1.3.14
+       NAME 'attributeSchema'
+       SUP top
+       STRUCTURAL 
+       MUST (cn $ attributeID $ attributeSyntax $ isSingleValued $ oMSyntax $
+               lDAPDisplayName $ schemaIDGUID )
+       MAY (rangeLower $ rangeUpper $ mAPIID $ linkID $ oMObjectClass $
+               searchFlags $ extendedCharsAllowed $ schemaFlagsEx $
+               attributeSecurityGUID $ systemOnly $ classDisplayName $
+               isMemberOfPartialAttributeSet $ isDefunct $ isEphemeral ) )
+
+objectclass ( 1.2.840.113556.1.3.58
+       NAME 'addressTemplate'
+       SUP displayTemplate
+       STRUCTURAL 
+       MUST (displayName )
+       MAY (addressSyntax $ perMsgDialogDisplayTable $
+               perRecipDialogDisplayTable $ addressType $
+               proxyGenerationEnabled ) )
+
+objectclass ( 1.2.840.113556.1.5.8
+       NAME 'group'
+       SUP top
+       STRUCTURAL 
+       MUST (groupType )
+       MAY (member $ nTGroupMembers $ operatorCount $ adminCount $
+               groupAttributes $ groupMembershipSAM $ controlAccessRights $
+               desktopProfile $ nonSecurityMember $ managedBy $
+               primaryGroupToken $ mail ) )
+
+objectclass ( 1.2.840.113556.1.5.76
+       NAME 'foreignSecurityPrincipal'
+       SUP top
+       STRUCTURAL 
+       MUST (objectSid )
+       MAY (foreignIdentifier ) )
+
+objectclass ( 1.2.840.113556.1.5.43
+       NAME 'fTDfs'
+       SUP top
+       STRUCTURAL 
+       MUST (remoteServerName $ pKTGuid $ pKT ) )
+
+objectclass ( 1.2.840.113556.1.5.91
+       NAME 'linkTrackObjectMoveTable'
+       SUP fileLinkTracking
+       STRUCTURAL )
+
+objectclass ( 1.2.840.113556.1.5.150
+       NAME 'rRASAdministrationConnectionPoint'
+       SUP serviceAdministrationPoint
+       STRUCTURAL 
+       MAY (msRRASAttribute ) )
+
+objectclass ( 1.2.840.113556.1.5.1
+       NAME 'securityObject'
+       SUP top
+       ABSTRACT
+       MUST (cn ) )
+
+objectclass ( 1.2.840.113556.1.5.107
+       NAME 'sitesContainer'
+       SUP top
+       STRUCTURAL )
+
+objectclass ( 1.2.840.113556.1.5.71
+       NAME 'nTDSConnection'
+       SUP leaf
+       STRUCTURAL 
+       MUST (enabledConnection $ fromServer $ options )
+       MAY (generatedConnection $ schedule $ transportType $
+               mS-DS-ReplicatesNCReason ) )
+
+objectclass ( 1.2.840.113556.1.5.190
+       NAME 'mS-SQL-OLAPCube'
+       SUP top
+       STRUCTURAL 
+       MAY (mS-SQL-Name $ mS-SQL-Contact $ mS-SQL-Status $
+               mS-SQL-LastUpdatedDate $ mS-SQL-InformationURL $
+               mS-SQL-PublicationURL $ mS-SQL-Description $ 
+               mS-SQL-Size $ mS-SQL-Keywords ) )
+
+objectclass ( 1.2.840.113556.1.5.148
+       NAME 'siteLinkBridge'
+       SUP top
+       STRUCTURAL 
+       MUST (siteLinkList ) )
+
+objectclass ( 1.2.840.113556.1.5.9
+       NAME 'user'
+       SUP organizationalPerson
+       STRUCTURAL 
+       MAY (userCertificate $ networkAddress $ userAccountControl $
+               badPwdCount $ codePage $ homeDirectory $ homeDrive $
+               badPasswordTime $ lastLogoff $ lastLogon $ dBCSPwd $
+               localeID $ scriptPath $ logonHours $ logonWorkstation $
+               maxStorage $ userWorkstations $ unicodePwd $
+               otherLoginWorkstations $ ntPwdHistory $ pwdLastSet $
+               preferredOU $ primaryGroupID $ userParameters $
+               profilePath $ operatorCount $ adminCount $ accountExpires $
+               lmPwdHistory $ groupMembershipSAM $ logonCount $
+               controlAccessRights $ defaultClassStore $ groupsToIgnore $
+               groupPriority $ desktopProfile $ dynamicLDAPServer $
+               userPrincipalName $ lockoutTime $ userSharedFolder $
+               userSharedFolderOther $ servicePrincipalName $
+               aCSPolicyName $ terminalServer $ mSMQSignCertificates $
+               mSMQDigests $ mSMQDigestsMig $ mSMQSignCertificatesMig $
+               msNPAllowDialin $ msNPCallingStationID $
+               msNPSavedCallingStationID $ msRADIUSCallbackNumber $
+               msRADIUSFramedIPAddress $ msRADIUSFramedRoute $
+               msRADIUSServiceType $ msRASSavedCallbackNumber $
+               msRASSavedFramedIPAddress $ msRASSavedFramedRoute $
+               mS-DS-CreatorSID ) )
+
+objectclass ( 1.2.840.113556.1.5.68
+       NAME 'applicationSiteSettings'
+       SUP top
+       ABSTRACT
+       MAY (applicationName $ notificationList ) )
+
+objectclass ( 1.2.840.113556.1.5.31
+       NAME 'site'
+       SUP top
+       STRUCTURAL 
+       MAY (location $ notificationList $ managedBy $ gPLink $
+               gPOptions $ mSMQSiteID $ mSMQNt4Stub $ mSMQSiteForeign $
+               mSMQInterval1 $ mSMQInterval2 ) )
+
+objectclass ( 1.2.840.113556.1.5.89
+       NAME 'nTFRSSettings'
+       SUP applicationSettings
+       STRUCTURAL 
+       MAY (fRSExtensions $ managedBy ) )
+
+objectclass ( 1.2.840.113556.1.5.20
+       NAME 'leaf'
+       SUP top
+       ABSTRACT )
+
+objectclass ( 1.2.840.113556.1.5.34
+       NAME 'trustedDomain'
+       SUP leaf
+       STRUCTURAL 
+       MAY (securityIdentifier $ trustAuthIncoming $ trustDirection $
+               trustPartner $ trustPosixOffset $ trustAuthOutgoing $ trustType
+               $ trustAttributes $ domainCrossRef $ flatName $
+               initialAuthIncoming $ initialAuthOutgoing $ domainIdentifier $
+               additionalTrustedServiceNames ) )
+
+objectclass ( 1.2.840.113556.1.5.12
+       NAME 'configuration'
+       SUP top
+       STRUCTURAL 
+       MUST (cn ) )
+
+objectclass ( 1.2.840.113556.1.5.163
+       NAME 'mSMQEnterpriseSettings'
+       SUP top
+       STRUCTURAL 
+       MAY (mSMQNameStyle $ mSMQCSPName $ mSMQLongLived $ mSMQVersion $
+               mSMQInterval1 $ mSMQInterval2 ) )
+
+objectclass ( 1.2.840.113556.1.5.4
+       NAME 'builtinDomain'
+       SUP top
+       STRUCTURAL )
+
+objectclass ( 1.2.840.113556.1.3.46
+       NAME 'mailRecipient'
+       SUP top
+       AUXILIARY
+       MUST (cn )
+       MAY (telephoneNumber $ userCertificate $ info $ garbageCollPeriod $
+               showInAddressBook $ userCert $ legacyExchangeDN $
+               userSMIMECertificate $ textEncodedORAddress ) )
+
+objectclass ( 1.2.840.113556.1.5.2
+       NAME 'samDomainBase'
+       SUP top
+       AUXILIARY
+       MAY (nTSecurityDescriptor $ creationTime $ forceLogoff $
+               lockoutDuration $ lockOutObservationWindow $ lockoutThreshold $
+               maxPwdAge $ minPwdAge $ minPwdLength $ modifiedCountAtLastProm $
+               nextRid $ pwdProperties $ pwdHistoryLength $ revision $
+               objectSid $ oEMInformation $ serverState $ uASCompat $
+               serverRole $ domainReplica $ modifiedCount ) )
+
+objectclass ( 1.2.840.113556.1.5.126
+       NAME 'serviceConnectionPoint'
+       SUP connectionPoint
+       STRUCTURAL 
+       MAY (serviceClassName $ serviceBindingInformation $ serviceDNSName $
+               serviceDNSNameType ) )
+
+objectclass ( 1.2.840.113556.1.5.119
+       NAME 'ipsecNegotiationPolicy'
+       SUP ipsecBase
+       STRUCTURAL 
+       MAY (iPSECNegotiationPolicyType $ iPSECNegotiationPolicyAction ) )
+
+objectclass ( 1.2.840.113556.1.3.9
+       NAME 'dMD'
+       SUP top
+       STRUCTURAL 
+       MUST (cn )
+       MAY (dmdName $ schemaUpdate $ prefixMap $ schemaInfo ) )
+
+objectclass ( 1.2.840.113556.1.5.165
+       NAME 'mSMQSettings'
+       SUP top
+       STRUCTURAL 
+       MAY (mSMQOwnerID $ mSMQServices $ mSMQQMID $ mSMQMigrated $ mSMQNt4Flags $
+               mSMQSiteName $ mSMQRoutingService $ mSMQDsService $
+               mSMQDependentClientService ) )
+
+objectclass ( 1.2.840.113556.1.5.183
+       NAME 'dSUISettings'
+       SUP top
+       STRUCTURAL 
+       MAY (dSUIAdminNotification $ dSUIAdminMaximum $ dSUIShellMaximum ) )
+
+objectclass ( 1.2.840.113556.1.5.177
+       NAME 'pKICertificateTemplate'
+       SUP top
+       STRUCTURAL 
+       MAY (displayName $ flags $ pKIDefaultKeySpec $ pKIKeyUsage $
+               pKIMaxIssuingDepth $ pKICriticalExtensions $ pKIExpirationPeriod $
+               pKIOverlapPeriod $ pKIExtendedKeyUsage $ pKIDefaultCSPs $
+               pKIEnrollmentAccess ) )
+
+objectclass ( 1.2.840.113556.1.5.164
+       NAME 'mSMQSiteLink'
+       SUP top
+       STRUCTURAL 
+       MUST (mSMQSite1 $ mSMQSite2 $ mSMQCost )
+       MAY (mSMQSiteGates $ mSMQSiteGatesMig ) )
+
+objectclass ( 1.2.840.113556.1.5.139
+       NAME 'lostAndFound'
+       SUP top
+       STRUCTURAL 
+       MAY (moveTreeState ) )
+
+objectclass ( 1.2.840.113556.1.5.136
+       NAME 'rpcContainer'
+       SUP container
+       STRUCTURAL 
+       MAY (nameServiceFlags ) )
+
+objectclass ( 1.2.840.113556.1.5.18
+       NAME 'domainPolicy'
+       SUP leaf
+       STRUCTURAL 
+       MAY (authenticationOptions $ forceLogoff $ defaultLocalPolicyObject $
+               lockoutDuration $ lockOutObservationWindow $ lockoutThreshold $
+               maxPwdAge $ maxRenewAge $ maxTicketAge $ minPwdAge $ minPwdLength $
+               minTicketAge $ pwdProperties $ pwdHistoryLength $ proxyLifetime $
+               eFSPolicy $ publicKeyPolicy $ domainWidePolicy $ domainPolicyReference $
+               qualityOfService $ ipsecPolicyReference $ managedBy $ domainCAs ) )
+
+objectclass ( 1.2.840.113556.1.5.29
+       NAME 'serviceClass'
+       SUP leaf
+       STRUCTURAL 
+       MUST (displayName $ serviceClassID )
+       MAY (serviceClassInfo ) )
+
+objectclass ( 1.2.840.113556.1.5.78
+       NAME 'licensingSiteSettings'
+       SUP applicationSiteSettings
+       STRUCTURAL 
+       MAY (siteServer ) )
+
+objectclass ( 1.2.840.113556.1.5.59
+       NAME 'fileLinkTrackingEntry'
+       SUP top
+       STRUCTURAL )
+
+objectclass ( 1.2.840.113556.1.5.106
+       NAME 'queryPolicy'
+       SUP top
+       STRUCTURAL 
+       MAY (lDAPAdminLimits $ lDAPIPDenyList ) )
+
+objectclass ( 1.2.840.113556.1.5.53
+       NAME 'typeLibrary'
+       SUP top
+       STRUCTURAL 
+       MAY (cOMClassID $ cOMInterfaceID $ cOMUniqueLIBID ) )
+
+objectclass ( 1.2.840.113556.1.5.72
+       NAME 'nTDSService'
+       SUP top
+       STRUCTURAL 
+       MAY (tombstoneLifetime $ dSHeuristics $ garbageCollPeriod $
+               replTopologyStayOfExecution $ sPNMappings ) )
+
+objectclass ( 1.2.840.113556.1.5.153
+       NAME 'nTFRSMember'
+       SUP top
+       STRUCTURAL 
+       MAY (fRSUpdateTimeout $ fRSServiceCommand $ serverReference $
+               fRSRootSecurity $ fRSExtensions $ frsComputerReference $
+               fRSControlDataCreation $ fRSControlInboundBacklog $
+               fRSControlOutboundBacklog $ fRSFlags $ fRSPartnerAuthLevel ) )
+
+objectclass ( 1.2.840.113556.1.5.98
+       NAME 'ipsecPolicy'
+       SUP ipsecBase
+       STRUCTURAL 
+       MAY (ipsecISAKMPReference $ ipsecNFAReference ) )
+
+objectclass ( 1.2.840.113556.1.5.118
+       NAME 'ipsecFilter'
+       SUP ipsecBase
+       STRUCTURAL )
+
+objectclass ( 1.2.840.113556.1.3.13
+       NAME 'classSchema'
+       SUP top
+       STRUCTURAL 
+       MUST (cn $ subClassOf $ governsID $ objectClassCategory $ schemaIDGUID $
+               defaultObjectCategory )
+       MAY (possSuperiors $ mustContain $ mayContain $ rDNAttID $ auxiliaryClass $
+               lDAPDisplayName $ schemaFlagsEx $ systemOnly $ systemPossSuperiors $
+               systemMayContain $ systemMustContain $ systemAuxiliaryClass $
+               defaultSecurityDescriptor $ defaultHidingValue $ classDisplayName $
+               isDefunct ) )
+
+objectclass ( 1.2.840.113556.1.5.175
+       NAME 'infrastructureUpdate'
+       SUP top
+       STRUCTURAL 
+       MAY (dNReferenceUpdate ) )
+
+objectclass ( 1.2.840.113556.1.5.157
+       NAME 'groupPolicyContainer'
+       SUP container
+       STRUCTURAL 
+       MAY (flags $ versionNumber $ gPCFunctionalityVersion $ gPCFileSysPath $
+               gPCMachineExtensionNames $ gPCUserExtensionNames ) )
+
+objectclass ( 1.2.840.113556.1.5.74
+       NAME 'categoryRegistration'
+       SUP leaf
+       STRUCTURAL 
+       MAY (localeID $ categoryId $ managedBy $ localizedDescription ) )
+
+objectclass ( 1.2.840.113556.1.5.178
+       NAME 'pKIEnrollmentService'
+       SUP top
+       STRUCTURAL 
+       MAY (cACertificate $ dNSHostName $ cACertificateDN $
+               certificateTemplates $ signatureAlgorithms $
+               enrollmentProviders ) )
+
+objectclass ( 1.2.840.113556.1.5.187
+       NAME 'mS-SQL-SQLPublication'
+       SUP top
+       STRUCTURAL 
+       MAY (mS-SQL-Name $ mS-SQL-Status $ mS-SQL-Description $ mS-SQL-Type $
+               mS-SQL-Database $ mS-SQL-AllowAnonymousSubscription $
+               mS-SQL-Publisher $ mS-SQL-AllowKnownPullSubscription $
+               mS-SQL-AllowImmediateUpdatingSubscription $
+               mS-SQL-AllowQueuedUpdatingSubscription $
+               mS-SQL-AllowSnapshotFilesFTPDownloading $ mS-SQL-ThirdParty ) )
+
+objectclass ( 1.2.840.113556.1.5.90
+       NAME 'linkTrackVolumeTable'
+       SUP fileLinkTracking
+       STRUCTURAL )
+
+objectclass ( 1.2.840.113556.1.5.125
+       NAME 'addressBookContainer'
+       SUP top
+       STRUCTURAL 
+       MUST (displayName )
+       MAY (purportedSearch ) )
+
+objectclass ( 1.2.840.113556.1.5.23
+       NAME 'printQueue'
+       SUP connectionPoint
+       STRUCTURAL 
+       MUST (uNCName $ versionNumber $ serverName $ printerName $
+               shortServerName )
+       MAY (location $ portName $ driverName $ printSeparatorFile $ priority $
+               defaultPriority $ printStartTime $ printEndTime $ printFormName $
+               printBinNames $ printMaxResolutionSupported $
+               printOrientationsSupported $ printMaxCopies $ printCollate $
+               printColor $ printLanguage $ printAttributes $ printShareName $
+               printOwner $ printNotify $ printStatus $ printSpooling $
+               printKeepPrintedJobs $ driverVersion $ printMaxXExtent $
+               printMaxYExtent $ printMinXExtent $ printMinYExtent $
+               printStaplingSupported $ printMemory $ assetNumber $
+               bytesPerMinute $ printRate $ printRateUnit $ printNetworkAddress $
+               printMACAddress $ printMediaReady $ printNumberUp $
+               printMediaSupported $ operatingSystem $ operatingSystemVersion $
+               operatingSystemServicePack $ operatingSystemHotfix $
+               physicalLocationObject $ printPagesPerMinute $
+               printDuplexSupported ) )
+
+objectclass ( 1.2.840.113556.1.5.44
+       NAME 'classStore'
+       SUP top
+       STRUCTURAL 
+       MAY (versionNumber $ nextLevelStore $ lastUpdateSequence $
+               appSchemaVersion ) )
+
+objectclass ( 1.2.840.113556.1.5.186
+       NAME 'mS-SQL-SQLRepository'
+       SUP top
+       STRUCTURAL 
+       MAY (mS-SQL-Name $ mS-SQL-Contact $ mS-SQL-Build $ mS-SQL-Status $
+               mS-SQL-Version $ mS-SQL-Description $ mS-SQL-InformationDirectory ) )
+
+objectclass ( 1.2.840.113556.1.5.82
+       NAME 'rpcProfile'
+       SUP rpcEntry
+       STRUCTURAL )
+
+objectclass ( 1.2.840.113556.1.5.83
+       NAME 'rIDManager'
+       SUP top
+       STRUCTURAL 
+       MUST (rIDAvailablePool ) )
+
+objectclass ( 1.2.840.113556.1.5.7000.49
+       NAME 'applicationSettings'
+       SUP top
+       ABSTRACT
+       MAY (applicationName $ notificationList ) )
+
+attributetype ( 1.2.840.113556.1.4.856
+       NAME 'netbootNewMachineOU'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.13
+       NAME 'builtinCreationTime'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1335
+       NAME 'pKIEnrollmentAccess'
+       SYNTAX '1.2.840.113556.1.4.907' )
+
+attributetype ( 1.2.840.113556.1.4.1333
+       NAME 'pKIExtendedKeyUsage'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.1123
+       NAME 'msNPCalledStationID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )
+
+attributetype ( 1.2.840.113556.1.4.539
+       NAME 'initialAuthIncoming'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.370
+       NAME 'objectClassCategory'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.41
+       NAME 'generatedConnection'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.911
+       NAME 'allowedChildClasses'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.38'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.68
+       NAME 'machineArchitecture'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' )
+
+attributetype ( 1.2.840.113556.1.4.767
+       NAME 'aCSMaxPeakBandwidth'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.72
+       NAME 'marshalledInterface'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.368
+       NAME 'rIDManagerReference'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.770
+       NAME 'aCSEnableACSService'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1237
+       NAME 'mSMQRoutingService'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1405
+       NAME 'mS-SQL-AllowQueuedUpdatingSubscription'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.648
+       NAME 'primaryTelexNumber'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.8
+       NAME 'userAccountControl'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.563
+       NAME 'shellPropertyPages'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.4
+       NAME 'replUpToDateVector'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.484
+       NAME 'fRSDirectoryFilter'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.230
+       NAME 'printSeparatorFile'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1329
+       NAME 'pKIMaxIssuingDepth'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1307
+       NAME 'accountNameHistory'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.1386
+       NAME 'mS-SQL-GPSLongitude'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.562
+       NAME 'adminPropertyPages'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.121
+       NAME 'securityIdentifier'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.166
+       NAME 'groupMembershipSAM'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.659
+       NAME 'serviceDNSNameType'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.585
+       NAME 'meetingIsEncrypted'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1400
+       NAME 'mS-SQL-Applications'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.330
+       NAME 'lastUpdateSequence'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.50
+       NAME 'lastContentIndexed'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.567
+       NAME 'meetingDescription'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.880
+       NAME 'fRSTimeLastCommand'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.53'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.83
+       NAME 'monikerDisplayName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.321
+       NAME 'requiredCategories'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.813
+       NAME 'upgradeProductCode'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.774
+       NAME 'aCSMaxNoOfLogFiles'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1370
+       NAME 'mS-SQL-CharacterSet'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.578
+       NAME 'meetingContactInfo'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1397
+       NAME 'mS-SQL-CreationDate'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.32
+       NAME 'domainPolicyObject'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.703
+       NAME 'dhcpObjDescription'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.573
+       NAME 'meetingApplication'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.518
+       NAME 'defaultHidingValue'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.875
+       NAME 'fRSMemberReference'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.701
+       NAME 'dhcpIdentification'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.135
+       NAME 'trustAuthOutgoing'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.197
+       NAME 'systemMustContain'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.38'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.1412
+       NAME 'primaryGroupToken'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.118
+       NAME 'rpcNsProfileEntry'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.129
+       NAME 'trustAuthIncoming'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1225
+       NAME 'mSMQPrevSiteGates'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.607
+       NAME 'queryPolicyObject'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.712
+       NAME 'optionDescription'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.1314
+       NAME 'aCSMaximumSDUSize'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.530
+       NAME 'nonSecurityMember'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.31
+       NAME 'fRSReplicaSetType'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.763
+       NAME 'aCSTotalNoOfFlows'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.915
+       NAME 'possibleInferiors'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.38'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.851
+       NAME 'netbootMaxClients'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1385
+       NAME 'mS-SQL-GPSLatitude'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.765
+       NAME 'aCSPermissionBits'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.926
+       NAME 'mSMQTransactional'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1390
+       NAME 'mS-SQL-Description'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.913
+       NAME 'allowedAttributes'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.38'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.491
+       NAME 'fRSFaultCondition'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.54
+       NAME 'tombstoneLifetime'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.809
+       NAME 'remoteStorageGUID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.644
+       NAME 'showInAddressBook'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.213
+       NAME 'defaultClassStore'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.577
+       NAME 'meetingOriginator'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.656
+       NAME 'userPrincipalName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1316
+       NAME 'aCSMinimumLatency'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.617
+       NAME 'homePostalAddress'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.638
+       NAME 'isPrivilegeHolder'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.533
+       NAME 'fRSReplicaSetGUID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.371
+       NAME 'rIDAllocationPool'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.1327
+       NAME 'pKIDefaultKeySpec'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.537
+       NAME 'dynamicLDAPServer'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.516
+       NAME 'serverReferenceBL'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.500
+       NAME 'fRSServiceCommand'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1304
+       NAME 'sDRightsEffective'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1249
+       NAME 'proxiedObjectName'
+       SYNTAX '1.2.840.113556.1.4.903'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.586
+       NAME 'meetingRecurrence'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.251
+       NAME 'cOMTreatAsClassId'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1245
+       NAME 'globalAddressList'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.908
+       NAME 'extendedClassInfo'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.459
+       NAME 'machineWidePolicy'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.356
+       NAME 'foreignIdentifier'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1242
+       NAME 'dNReferenceUpdate'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.134
+       NAME 'trustPosixOffset'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.36
+       NAME 'enabledConnection'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.627
+       NAME 'ipsecNFAReference'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.86
+       NAME 'userWorkstations'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.301
+       NAME 'garbageCollPeriod'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.933
+       NAME 'mSMQComputerType'
+       SYNTAX '1.2.840.113556.1.4.905'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.65
+       NAME 'logonWorkstation'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.921
+       NAME 'mSMQJournalQuota'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.108
+       NAME 'remoteSourceType'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.95
+       NAME 'pwdHistoryLength'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.920
+       NAME 'mSMQBasePriority'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.196
+       NAME 'systemMayContain'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.38'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.1407
+       NAME 'mS-SQL-ThirdParty'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1243
+       NAME 'mSMQQueueNameExt'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.485
+       NAME 'fRSUpdateTimeout'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.924
+       NAME 'mSMQPrivacyLevel'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.615
+       NAME 'shellContextMenu'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.618
+       NAME 'wellKnownObjects'
+       SYNTAX '1.2.840.113556.1.4.903'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.789
+       NAME 'transportDLLName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.458
+       NAME 'qualityOfService'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.73
+       NAME 'lockoutThreshold'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.105
+       NAME 'remoteServerName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.694
+       NAME 'previousParentCA'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.1345
+       NAME 'dSUIShellMaximum'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.303
+       NAME 'notificationList'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1244
+       NAME 'addressBookRoots'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.878
+       NAME 'fRSPrimaryMember'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.587
+       NAME 'meetingStartTime'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.53' )
+
+attributetype ( 1.2.840.113556.1.4.1310
+       NAME 'mSMQSiteGatesMig'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.709
+       NAME 'dhcpReservations'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )
+
+attributetype ( 1.2.840.113556.1.4.614
+       NAME 'adminContextMenu'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.1332
+       NAME 'pKIOverlapPeriod'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.142
+       NAME 'winsockAddresses'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.923
+       NAME 'mSMQAuthenticate'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1344
+       NAME 'dSUIAdminMaximum'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.848
+       NAME 'appSchemaVersion'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.123
+       NAME 'serviceClassInfo'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.769
+       NAME 'aCSEventLogLevel'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.751
+       NAME 'userSharedFolder'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.421
+       NAME 'domainWidePolicy'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.669
+       NAME 'rIDSetReferences'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.815
+       NAME 'canUpgradeScript'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.610
+       NAME 'classDisplayName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.2.226
+       NAME 'adminDescription'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.67
+       NAME 'lSAModifiedCount'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.509
+       NAME 'serviceClassName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.56
+       NAME 'localPolicyFlags'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.115
+       NAME 'rpcNsInterfaceID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.194
+       NAME 'adminDisplayName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.753
+       NAME 'nameServiceFlags'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.589
+       NAME 'meetingBandwidth'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' )
+
+attributetype ( 1.2.840.113556.1.4.755
+       NAME 'domainIdentifier'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.370
+       NAME 'rIDAvailablePool'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.655
+       NAME 'legacyExchangeDN'
+       SYNTAX '1.2.840.113556.1.4.905'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.470
+       NAME 'trustAttributes'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.535
+       NAME 'fRSRootSecurity'
+       SYNTAX '1.2.840.113556.1.4.907'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.532
+       NAME 'superiorDNSRoot'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.278
+       NAME 'printMaxYExtent'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.277
+       NAME 'printMaxXExtent'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.280
+       NAME 'printMinYExtent'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.279
+       NAME 'printMinXExtent'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.32
+       NAME 'attributeSyntax'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.38'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.247
+       NAME 'printAttributes'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.152
+       NAME 'groupAttributes'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.816
+       NAME 'fileExtPriority'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.930
+       NAME 'mSMQServiceType'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.363
+       NAME 'operatingSystem'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1371
+       NAME 'mS-SQL-SortOrder'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.329
+       NAME 'versionNumberLo'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.884
+       NAME 'msRRASAttribute'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.781
+       NAME 'lastKnownParent'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1209
+       NAME 'shortServerName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.60
+       NAME 'lockoutDuration'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.232
+       NAME 'defaultPriority'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.754
+       NAME 'rpcNsEntryFlags'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.713
+       NAME 'optionsLocation'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )
+
+attributetype ( 1.2.840.113556.1.4.328
+       NAME 'versionNumberHi'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.366
+       NAME 'rpcNsAnnotation'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.886
+       NAME 'purportedSearch'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.776
+       NAME 'aCSDSBMPriority'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.961
+       NAME 'mSMQSiteForeign'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7' )
+
+attributetype ( 1.2.840.113556.1.4.335
+       NAME 'currentLocation'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.570
+       NAME 'meetingProtocol'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.420
+       NAME 'publicKeyPolicy'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1402
+       NAME 'mS-SQL-Publisher'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.812
+       NAME 'createWizardExt'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.1373
+       NAME 'mS-SQL-Clustered'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.334
+       NAME 'volTableIdxGUID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.696
+       NAME 'currentParentCA'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.504
+       NAME 'seqNotification'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.515
+       NAME 'serverReference'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1119
+       NAME 'msNPAllowDialin'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1387
+       NAME 'mS-SQL-GPSHeight'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1378
+       NAME 'mS-SQL-AppleTalk'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.269
+       NAME 'linkTrackSecret'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.378
+       NAME 'dnsAllowDynamic'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.49
+       NAME 'badPasswordTime'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.637
+       NAME 'privilegeHolder'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.289
+       NAME 'printMediaReady'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.288
+       NAME 'printMACAddress'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.66
+       NAME 'lSACreationTime'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.569
+       NAME 'meetingLocation'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.784
+       NAME 'aCSIdentityName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.1410
+       NAME 'mS-DS-CreatorSID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.1374
+       NAME 'mS-SQL-NamedPipe'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.843
+       NAME 'lDAPAdminLimits'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.2.460
+       NAME 'lDAPDisplayName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.218
+       NAME 'applicationName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.695
+       NAME 'pendingParentCA'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.779
+       NAME 'aCSCacheTimeout'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.574
+       NAME 'meetingLanguage'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.778
+       NAME 'aCSDSBMDeadTime'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.697
+       NAME 'cACertificateDN'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.138
+       NAME 'userParameters'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.132
+       NAME 'trustDirection'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.962
+       NAME 'mSMQQueueQuota'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.936
+       NAME 'mSMQEncryptKey'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.885
+       NAME 'terminalServer'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.233
+       NAME 'printStartTime'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.664
+       NAME 'syncWithObject'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.344
+       NAME 'groupsToIgnore'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.665
+       NAME 'syncMembership'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.666
+       NAME 'syncAttributes'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.214
+       NAME 'nextLevelStore'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.302
+       NAME 'sAMAccountType'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1401
+       NAME 'mS-SQL-Keywords'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.2.210
+       NAME 'proxyAddresses'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.284
+       NAME 'bytesPerMinute'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.241
+       NAME 'printMaxCopies'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.98
+       NAME 'primaryGroupID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.89
+       NAME 'nTGroupMembers'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.1228
+       NAME 'mSMQDsServices'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.43
+       NAME 'fRSVersionGUID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.486
+       NAME 'fRSWorkingPath'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.18
+       NAME 'otherTelephone'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.2.277
+       NAME 'otherHomePhone'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.151
+       NAME 'oEMInformation'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.459
+       NAME 'networkAddress'
+       SYNTAX '1.2.840.113556.1.4.905' )
+
+attributetype ( 1.2.840.113556.1.4.966
+       NAME 'mSMQDigestsMig'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.568
+       NAME 'meetingKeyword'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.844
+       NAME 'lDAPIPDenyList'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.847
+       NAME 'installUiLevel'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.894
+       NAME 'gPCFileSysPath'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.488
+       NAME 'fRSStagingPath'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.351
+       NAME 'auxiliaryClass'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' )
+
+attributetype ( 1.2.840.113556.1.4.159
+       NAME 'accountExpires'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.718
+       NAME 'dhcpProperties'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.346
+       NAME 'desktopProfile'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.762
+       NAME 'aCSServiceType'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.610
+       NAME 'employeeNumber'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1213
+       NAME 'assocNTAccount'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.498
+       NAME 'creationWizard'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.253
+       NAME 'cOMOtherProgId'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.202
+       NAME 'auditingPolicy'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.635
+       NAME 'privilegeValue'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1366
+       NAME 'mS-SQL-Location'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1334
+       NAME 'pKIDefaultCSPs'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.270
+       NAME 'printShareName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.2.33
+       NAME 'isSingleValued'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.472
+       NAME 'domainCrossRef'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1240
+       NAME 'netbootSIFFile'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.250
+       NAME 'cOMUniqueLIBID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.657
+       NAME 'serviceDNSName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.782
+       NAME 'objectCategory'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.122
+       NAME 'serviceClassID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.720
+       NAME 'dhcpUpdateTime'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.221
+       NAME 'sAMAccountName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.588
+       NAME 'meetingEndTime'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.53' )
+
+attributetype ( 1.2.840.113556.1.4.1389
+       NAME 'mS-SQL-Language'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.777
+       NAME 'aCSDSBMRefresh'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1393
+       NAME 'mS-SQL-Database'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.20
+       NAME 'cOMInterfaceID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.1403
+       NAME 'mS-SQL-AllowKnownPullSubscription'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1394
+       NAME 'mS-SQL-AllowAnonymousSubscription'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.654
+       NAME 'managedObjects'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.2.8
+       NAME 'possSuperiors'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' )
+
+attributetype ( 1.2.840.113556.1.4.791
+       NAME 'transportType'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.345
+       NAME 'groupPriority'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.117
+       NAME 'rpcNsPriority'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' )
+
+attributetype ( 1.2.840.113556.1.4.917
+       NAME 'mSMQQueueType'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.141
+       NAME 'versionNumber'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.121
+       NAME 'uSNLastObjRem'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.1346
+       NAME 'templateRoots'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.93
+       NAME 'pwdProperties'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.290
+       NAME 'printNumberUp'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.536
+       NAME 'fRSExtensions'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.286
+       NAME 'printRateUnit'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.846
+       NAME 'msiScriptSize'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.274
+       NAME 'printSpooling'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.608
+       NAME 'queryPolicyBL'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.103
+       NAME 'proxyLifetime'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.144
+       NAME 'operatorCount'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.860
+       NAME 'netbootServer'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.369
+       NAME 'fSMORoleOwner'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.276
+       NAME 'driverVersion'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1388
+       NAME 'mS-SQL-Version'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.939
+       NAME 'mSMQNameStyle'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.471
+       NAME 'schemaVersion'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' )
+
+attributetype ( 1.2.840.113556.1.2.436
+       NAME 'directReports'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.2.255
+       NAME 'addressSyntax'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.235
+       NAME 'printFormName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.15
+       NAME 'msiScriptPath'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1312
+       NAME 'aCSServerList'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.2.615
+       NAME 'personalTitle'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1305
+       NAME 'moveTreeState'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.945
+       NAME 'mSMQSiteGates'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.1238
+       NAME 'mSMQDsService'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.76
+       NAME 'objectVersion'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1414
+       NAME 'dNSTombstoned'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.941
+       NAME 'mSMQLongLived'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.534
+       NAME 'fRSLevelLimit'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.845
+       NAME 'msiScriptName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.44
+       NAME 'homeDirectory'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.698
+       NAME 'dhcpUniqueKey'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.227
+       NAME 'extensionName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.2.256
+       NAME 'streetAddress'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.113
+       NAME 'rpcNsBindings'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.237
+       NAME 'printBinNames'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.109
+       NAME 'replicaSource'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.246
+       NAME 'printLanguage'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.1365
+       NAME 'mS-SQL-Contact'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.357
+       NAME 'nTMixedDomain'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.483
+       NAME 'fRSFileFilter'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.332
+       NAME 'birthLocation'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.682
+       NAME 'friendlyNames'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.622
+       NAME 'ipsecDataType'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.584
+       NAME 'meetingRating'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.681
+       NAME 'indexedScopes'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.312
+       NAME 'rpcNsObjectID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.168
+       NAME 'modifiedCount'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.218
+       NAME 'oMObjectClass'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.772
+       NAME 'aCSPolicyName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.502
+       NAME 'timeVolChange'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.337
+       NAME 'currMachineId'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.120
+       NAME 'schemaFlagsEx'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1356
+       NAME 'validAccesses'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.158
+       NAME 'domainReplica'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1309
+       NAME 'mSMQInterval2'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1308
+       NAME 'mSMQInterval1'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.916
+       NAME 'canonicalName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.94
+       NAME 'ntPwdHistory'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.133
+       NAME 'trustPartner'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.160
+       NAME 'lmPwdHistory'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.1380
+       NAME 'mS-SQL-Status'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.469
+       NAME 'USNIntersite'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.858
+       NAME 'netbootTools'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.99
+       NAME 'priorSetTime'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1367
+       NAME 'mS-SQL-Memory'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.950
+       NAME 'mSMQServices'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.613
+       NAME 'employeeType'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.27
+       NAME 'currentValue'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.822
+       NAME 'siteLinkList'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.107
+       NAME 'remoteSource'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.325
+       NAME 'setupCommand'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.212
+       NAME 'dSHeuristics'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1336
+       NAME 'replInterval'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.234
+       NAME 'printEndTime'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.1
+       NAME 'instanceType'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.722
+       NAME 'otherIpPhone'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.965
+       NAME 'mSMQSiteName'
+       SYNTAX '1.2.840.113556.1.4.905'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.579
+       NAME 'meetingOwner'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.242
+       NAME 'printCollate'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.480
+       NAME 'defaultGroup'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.79
+       NAME 'minPwdLength'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.864
+       NAME 'netbootSCPBL'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.650
+       NAME 'mhsORAddress'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.651
+       NAME 'otherMailbox'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.367
+       NAME 'rpcNsCodeset'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.2.14
+       NAME 'hasMasterNCs'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.952
+       NAME 'mSMQMigrated'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.74
+       NAME 'dSASignature'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.115
+       NAME 'invocationId'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.254
+       NAME 'cOMTypelibId'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.26
+       NAME 'creationTime'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.581
+       NAME 'meetingScope'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.336
+       NAME 'volTableGUID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.513
+       NAME 'siteObjectBL'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.756
+       NAME 'aCSTimeOfDay'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.757
+       NAME 'aCSDirection'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.77
+       NAME 'maxTicketAge'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.481
+       NAME 'schemaUpdate'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.24'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.80
+       NAME 'minTicketAge'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.628
+       NAME 'ipsecNegotiationPolicyReference'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.327
+       NAME 'helpFileName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.148
+       NAME 'schemaIDGUID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.810
+       NAME 'createDialog'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.964
+       NAME 'mSMQNt4Flags'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.327
+       NAME 'packageFlags'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.464
+       NAME 'wWWHomePage'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.507
+       NAME 'volumeCount'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.273
+       NAME 'printStatus'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.890
+       NAME 'uPNSuffixes'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.471
+       NAME 'trustParent'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1301
+       NAME 'tokenGroups'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.375
+       NAME 'systemFlags'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.667
+       NAME 'syncWithSID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1306
+       NAME 'dNSProperty'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.710
+       NAME 'superScopes'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )
+
+attributetype ( 1.2.840.113556.1.4.1347
+       NAME 'sPNMappings'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.272
+       NAME 'printNotify'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.282
+       NAME 'printMemory'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.154
+       NAME 'serverState'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.942
+       NAME 'mSMQVersion'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.373
+       NAME 'rIDUsedPool'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.1355
+       NAME 'queryFilter'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.300
+       NAME 'printerName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.97
+       NAME 'preferredOU'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.649
+       NAME 'primaryInternationalISDNNumber'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.333
+       NAME 'oMTIndxGuid'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1337
+       NAME 'mSMQUserSid'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.487
+       NAME 'fRSRootPath'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.918
+       NAME 'mSMQJournal'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.499
+       NAME 'contextMenu'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.764
+       NAME 'aCSPriority'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.937
+       NAME 'mSMQSignKey'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.359
+       NAME 'netbootGUID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.925
+       NAME 'mSMQOwnerID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.24
+       NAME 'mustContain'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' )
+
+attributetype ( 1.2.840.113556.1.4.379
+       NAME 'dnsAllowXFR'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1379
+       NAME 'mS-SQL-Vines'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.948
+       NAME 'mSMQDigests'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.662
+       NAME 'lockoutTime'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.53
+       NAME 'lastSetTime'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.25
+       NAME 'countryCode'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1377
+       NAME 'mS-SQL-TCPIP'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.934
+       NAME 'mSMQForeign'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.571
+       NAME 'meetingType'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.714
+       NAME 'dhcpOptions'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.704
+       NAME 'dhcpServers'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )
+
+attributetype ( 1.2.840.113556.1.4.283
+       NAME 'assetNumber'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.350
+       NAME 'addressType'
+       SYNTAX '1.2.840.113556.1.4.905'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.940
+       NAME 'mSMQCSPName'
+       SYNTAX '1.2.840.113556.1.4.905'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.671
+       NAME 'msiFileList'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.619
+       NAME 'dNSHostName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.705
+       NAME 'dhcpSubnets'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )
+
+attributetype ( 1.2.840.113556.1.4.1328
+       NAME 'pKIKeyUsage'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.30
+       NAME 'attributeID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.38'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.506
+       NAME 'objectCount'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.503
+       NAME 'timeRefresh'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.139
+       NAME 'profilePath'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.818
+       NAME 'productCode'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.647
+       NAME 'otherMobile'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.12
+       NAME 'badPwdCount'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1368
+       NAME 'mS-SQL-Build'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.13
+       NAME 'displayName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.87
+       NAME 'nETBIOSName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1395
+       NAME 'mS-SQL-Alias'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.75
+       NAME 'maxRenewAge'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.806
+       NAME 'treatAsLeaf'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.960
+       NAME 'mSMQNt4Stub'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' )
+
+attributetype ( 1.2.840.113556.1.4.324
+       NAME 'packageType'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1212
+       NAME 'isEphemeral'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.2.36
+       NAME 'dMDLocation'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.715
+       NAME 'dhcpClasses'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.39
+       NAME 'forceLogoff'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.2
+       NAME 'whenCreated'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.24'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.566
+       NAME 'meetingName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.786
+       NAME 'mailAddress'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.590
+       NAME 'meetingBlob'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.71
+       NAME 'machineRole'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.334
+       NAME 'searchFlags'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.3
+       NAME 'whenChanged'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.24'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.702
+       NAME 'dhcpObjName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.897
+       NAME 'aCSMaxAggregatePeakRatePerUser'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.326
+       NAME 'packageName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.170
+       NAME 'systemOnly'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.935
+       NAME 'mSMQOSType'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.680
+       NAME 'queryPoint'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.271
+       NAME 'printOwner'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.19
+       NAME 'uSNCreated'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.494
+       NAME 'siteServer'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.114
+       NAME 'rpcNsGroup'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.609
+       NAME 'sIDHistory'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.882
+       NAME 'fRSVersion'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.64
+       NAME 'logonHours'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.854
+       NAME 'netbootAnswerOnlyValidClients'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.96
+       NAME 'pwdLastSet'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.243
+       NAME 'printColor'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1391
+       NAME 'mS-SQL-Type'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.40
+       NAME 'fromServer'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.157
+       NAME 'serverRole'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.100
+       NAME 'priorValue'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.169
+       NAME 'logonCount'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.90
+       NAME 'unicodePwd'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.21
+       NAME 'subClassOf'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.38'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.1396
+       NAME 'mS-SQL-Size'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.101
+       NAME 'privateKey'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.512
+       NAME 'siteObject'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.62
+       NAME 'scriptPath'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.223
+       NAME 'serverName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.953
+       NAME 'mSMQSiteID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.340
+       NAME 'rightsGuid'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.374
+       NAME 'rIDNextRID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.583
+       NAME 'meetingURL'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.2.400
+       NAME 'addressEntryDisplayTableMSDOS'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.76
+       NAME 'maxStorage'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.35
+       NAME 'rangeUpper'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.34
+       NAME 'rangeLower'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.118
+       NAME 'otherPager'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.639
+       NAME 'isMemberOfPartialAttributeSet'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1224
+       NAME 'parentGUID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.2.141
+       NAME 'department'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.25
+       NAME 'mayContain'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' )
+
+attributetype ( 1.2.840.113556.1.4.150
+       NAME 'adminCount'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.51
+       NAME 'lastLogoff'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1409
+       NAME 'masteredBy'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.35
+       NAME 'employeeID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.719
+       NAME 'dhcpMaxKey'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.229
+       NAME 'driverName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1363
+       NAME 'mS-SQL-Name'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.322
+       NAME 'categoryId'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.889
+       NAME 'additionalTrustedServiceNames'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.1354
+       NAME 'scopeFlags'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.672
+       NAME 'categories'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.855
+       NAME 'netbootNewMachineNamingPolicy'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.19
+       NAME 'cOMClassID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.2.120
+       NAME 'uSNChanged'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.2
+       NAME 'objectGUID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.707
+       NAME 'dhcpRanges'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )
+
+attributetype ( 1.2.840.113556.1.4.1358
+       NAME 'schemaInfo'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.646
+       NAME 'otherFacsimileTelephoneNumber'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.520
+       NAME 'machinePasswordChangeInterval'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.674
+       NAME 'rootTrust'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.136
+       NAME 'trustType'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.750
+       NAME 'groupType'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.896
+       NAME 'uSNSource'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.919
+       NAME 'mSMQQuota'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.927
+       NAME 'mSMQSites'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.910
+       NAME 'fromEntry'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.1376
+       NAME 'mS-SQL-SPX'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.892
+       NAME 'gPOptions'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.814
+       NAME 'msiScript'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.285
+       NAME 'printRate'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.683
+       NAME 'cRLPartitionedRevocationList'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.652
+       NAME 'assistant'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.490
+       NAME 'fRSDSPoll'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.663
+       NAME 'partialAttributeDeletionList'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.52
+       NAME 'lastLogon'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.22
+       NAME 'governsID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.38'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.341
+       NAME 'appliesTo'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.268
+       NAME 'eFSPolicy'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.155
+       NAME 'uASCompat'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.538
+       NAME 'prefixMap'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.661
+       NAME 'isDefunct'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.708
+       NAME 'dhcpSites'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )
+
+attributetype ( 1.2.840.113556.1.4.888
+       NAME 'iPSECNegotiationPolicyAction'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.382
+       NAME 'dnsRecord'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.21
+       NAME 'cOMProgID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.45
+       NAME 'homeDrive'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.580
+       NAME 'meetingIP'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1321
+       NAME 'aCSNonReservedMinPolicedSize'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.717
+       NAME 'dhcpState'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )
+
+attributetype ( 1.2.840.113556.1.4.922
+       NAME 'mSMQLabel'
+       SYNTAX '1.2.840.113556.1.4.905'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.74
+       NAME 'maxPwdAge'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.78
+       NAME 'minPwdAge'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.689
+       NAME 'cRLObject'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.146
+       NAME 'objectSid'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.565
+       NAME 'meetingID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.620
+       NAME 'ipsecName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.48
+       NAME 'isDeleted'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.760
+       NAME 'aCSAggregateTokenRatePerUser'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.623
+       NAME 'ipsecData'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.668
+       NAME 'domainCAs'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.687
+       NAME 'cAConnect'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.238
+       NAME 'printMaxResolutionSupported'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.700
+       NAME 'dhcpFlags'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.402
+       NAME 'helpData16'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.653
+       NAME 'managedBy'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.9
+       NAME 'helpData32'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.944
+       NAME 'mSMQSite2'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.943
+       NAME 'mSMQSite1'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.677
+       NAME 'replTopologyStayOfExecution'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.912
+       NAME 'allowedChildClassesEffective'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.38'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.2.231
+       NAME 'oMSyntax'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.231
+       NAME 'priority'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.48
+       NAME 'keywords'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.946
+       NAME 'mSMQCost'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.821
+       NAME 'siteList'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.145
+       NAME 'revision'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.91
+       NAME 'repsFrom'
+       SYNTAX 'OctetString'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.645
+       NAME 'userCert'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.951
+       NAME 'mSMQQMID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.228
+       NAME 'portName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.859
+       NAME 'netbootLocallyInstalledOSes'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.261
+       NAME 'division'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.902
+       NAME 'aCSMaxSizeOfRSVPAccountFile'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.699
+       NAME 'dhcpType'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.301
+       NAME 'wbemPath'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.362
+       NAME 'siteGUID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.26
+       NAME 'rDNAttID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.38'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.900
+       NAME 'aCSRSVPAccountFilesLocation'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1226
+       NAME 'mSMQDependentClientServices'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.222
+       NAME 'location'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.874
+       NAME 'fRSFlags'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.219
+       NAME 'iconPath'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.688
+       NAME 'cAWEBURL'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.716
+       NAME 'mscopeId'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.44'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.660
+       NAME 'treeName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.211
+       NAME 'schedule'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.557
+       NAME 'parentCA'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.249
+       NAME 'cOMCLSID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.675
+       NAME 'catalogs'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.2.102
+       NAME 'memberOf'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.690
+       NAME 'cAUsages'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.706
+       NAME 'dhcpMask'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )
+
+attributetype ( 1.2.840.113556.1.4.511
+       NAME 'flatName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.686
+       NAME 'domainID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.58
+       NAME 'localeID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' )
+
+attributetype ( 1.2.840.113556.1.4.16
+       NAME 'codePage'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.768
+       NAME 'aCSEnableRSVPMessageLogging'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.240
+       NAME 'printOrientationsSupported'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.883
+       NAME 'msRRASVendorAttributeEntry'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.1246
+       NAME 'interSiteTopologyGenerator'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.307
+       NAME 'options'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.28
+       NAME 'dnsRoot'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.887
+       NAME 'iPSECNegotiationPolicyType'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1392
+       NAME 'mS-SQL-InformationDirectory'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.365
+       NAME 'operatingSystemServicePack'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.88
+       NAME 'nextRid'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.865
+       NAME 'pekList'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.7
+       NAME 'subRefs'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.505
+       NAME 'oMTGuid'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.205
+       NAME 'pKTGuid'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.146
+       NAME 'company'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.82
+       NAME 'moniker'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.156
+       NAME 'comment'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.721
+       NAME 'ipPhone'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1361
+       NAME 'mS-DS-ConsistencyChildCount'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.679
+       NAME 'creator'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.137
+       NAME 'uNCName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.55
+       NAME 'dBCSPwd'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1239
+       NAME 'mSMQDependentClientService'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.684
+       NAME 'certificateAuthorityObject'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.621
+       NAME 'ipsecID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.914
+       NAME 'allowedAttributesEffective'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.38'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.2.598
+       NAME 'dmdName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.759
+       NAME 'aCSMaxPeakBandwidthPerFlow'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.557
+       NAME 'Enabled'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.326
+       NAME 'perRecipDialogDisplayTable'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1248
+       NAME 'interSiteTopologyFailover'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.895
+       NAME 'transportAddressAttribute'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.38'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.852
+       NAME 'netbootCurrentClientCount'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.372
+       NAME 'rIDPreviousAllocationPool'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.2.83
+       NAME 'repsTo'
+       SYNTAX 'OctetString'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.224
+       NAME 'defaultSecurityDescriptor'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.519
+       NAME 'lastBackupRestorationTime'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.873
+       NAME 'fRSControlOutboundBacklog'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.255
+       NAME 'vendor'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.891
+       NAME 'gPLink'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.214
+       NAME 'originalDisplayTableMSDOS'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.50
+       NAME 'linkID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.1130
+       NAME 'msNPSavedCallingStationID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )
+
+attributetype ( 1.2.840.113556.1.2.49
+       NAME 'mAPIID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.510
+       NAME 'serviceBindingInformation'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.2.16
+       NAME 'nCName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.1303
+       NAME 'tokenGroupsNoGCAcceptable'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.1190
+       NAME 'msRASSavedFramedIPAddress'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.766
+       NAME 'aCSAllocableRSVPBandwidth'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.61
+       NAME 'lockOutObservationWindow'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.857
+       NAME 'netbootIntelliMirrorOSes'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.1320
+       NAME 'aCSNonReservedMaxSDUSize'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.265
+       NAME 'notes'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.673
+       NAME 'retiredReplDSASignatures'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.1313
+       NAME 'aCSMaxTokenBucketPerFlow'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.324
+       NAME 'addressEntryDisplayTable'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1317
+       NAME 'aCSMinimumDelayVariation'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.872
+       NAME 'fRSControlInboundBacklog'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.38
+       NAME 'flags'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1399
+       NAME 'mS-SQL-LastDiagnosticDate'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1348
+       NAME 'gPCMachineExtensionNames'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1411
+       NAME 'ms-DS-MachineAccountQuota'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.325
+       NAME 'perMsgDialogDisplayTable'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.57
+       NAME 'defaultLocalPolicyObject'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1189
+       NAME 'msRASSavedCallbackNumber'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.26'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.685
+       NAME 'parentCACertificateChain'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.893
+       NAME 'gPCFunctionalityVersion'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.879
+       NAME 'fRSServiceCommandStatus'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1319
+       NAME 'aCSNonReservedTokenSize'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.775
+       NAME 'aCSMaxSizeOfRSVPLogFile'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.135
+       NAME 'cost'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.81
+       NAME 'modifiedCountAtLastProm'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.773
+       NAME 'aCSRSVPLogFilesLocation'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.81
+       NAME 'info'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.125
+       NAME 'supplementalCredentials'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.819
+       NAME 'bridgeheadTransportList'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.967
+       NAME 'mSMQSignCertificatesMig'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1
+       NAME 'name'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.1153
+       NAME 'msRADIUSFramedIPAddress'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1408
+       NAME 'mS-DS-ReplicatesNCReason'
+       SYNTAX '1.2.840.113556.1.4.903' )
+
+attributetype ( 1.2.840.113556.1.4.899
+       NAME 'aCSEnableRSVPAccounting'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.881
+       NAME 'fRSTimeLastConfigChange'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.53'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.281
+       NAME 'printStaplingSupported'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1247
+       NAME 'interSiteTopologyRenew'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.364
+       NAME 'operatingSystemVersion'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.91
+       NAME 'otherLoginWorkstations'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.849
+       NAME 'netbootAllowNewClients'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1372
+       NAME 'mS-SQL-UnicodeSortOrder'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.749
+       NAME 'url'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.206
+       NAME 'pKT'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.199
+       NAME 'serviceInstanceVersion'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.169
+       NAME 'showInAdvancedViewOnly'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.758
+       NAME 'aCSMaxTokenRatePerFlow'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.868
+       NAME 'isCriticalSystemObject'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.576
+       NAME 'meetingMaxParticipants'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1208
+       NAME 'aNR'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.153
+       NAME 'rid'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.523
+       NAME 'proxyGenerationEnabled'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.871
+       NAME 'fRSControlDataCreation'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.692
+       NAME 'previousCACertificates'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.24
+       NAME 'contentIndexingAllowed'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.633
+       NAME 'policyReplicationFlags'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.870
+       NAME 'frsComputerReferenceBL'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.1318
+       NAME 'aCSNonReservedPeakRate'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.901
+       NAME 'aCSMaxNoOfAccountFiles'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.514
+       NAME 'physicalLocationObject'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.928
+       NAME 'mSMQOutRoutingServers'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.820
+       NAME 'bridgeheadServerListBL'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.1145
+       NAME 'msRADIUSCallbackNumber'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.26'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.361
+       NAME 'netbootMachineFilePath'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.963
+       NAME 'mSMQQueueJournalQuota'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.853
+       NAME 'netbootAnswerRequests'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.415
+       NAME 'operatingSystemHotfix'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.149
+       NAME 'attributeSecurityGUID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.711
+       NAME 'superScopeDescription'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.1359
+       NAME 'otherWellKnownObjects'
+       SYNTAX '1.2.840.113556.1.4.903' )
+
+attributetype ( 1.2.840.113556.1.4.780
+       NAME 'aCSNonReservedTxLimit'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.11
+       NAME 'authenticationOptions'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.867
+       NAME 'altSecurityIdentities'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.1349
+       NAME 'gPCUserExtensionNames'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.358
+       NAME 'netbootInitialization'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1364
+       NAME 'mS-SQL-RegisteredOwner'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.761
+       NAME 'aCSMaxDurationPerFlow'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1330
+       NAME 'pKICriticalExtensions'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.748
+       NAME 'attributeDisplayNames'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.1404
+       NAME 'mS-SQL-AllowImmediateUpdatingSubscription'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1191
+       NAME 'msRASSavedFramedRoute'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )
+
+attributetype ( 1.2.840.113556.1.4.752
+       NAME 'userSharedFolderOther'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.2.131
+       NAME 'co'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.909
+       NAME 'extendedAttributeInfo'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.1241
+       NAME 'netbootMirrorDataFile'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.1315
+       NAME 'aCSMinimumPolicedSize'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1353
+       NAME 'localizationDisplayId'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.582
+       NAME 'meetingAdvertiseScope'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1343
+       NAME 'dSUIAdminNotification'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.1381
+       NAME 'mS-SQL-LastUpdatedDate'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1357
+       NAME 'dSCorePropagationData'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.24'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.320
+       NAME 'implementedCategories'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 1.2.840.113556.1.4.783
+       NAME 'defaultObjectCategory'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.422
+       NAME 'domainPolicyReference'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.929
+       NAME 'mSMQInRoutingServers'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.1311
+       NAME 'printDuplexSupported'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.693
+       NAME 'pendingCACertificates'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.281
+       NAME 'nTSecurityDescriptor'
+       SYNTAX '1.2.840.113556.1.4.907'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.198
+       NAME 'systemAuxiliaryClass'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.38'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.898
+       NAME 'aCSNonReservedTxSize'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1382
+       NAME 'mS-SQL-InformationURL'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.3
+       NAME 'replPropertyMetaData'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.1384
+       NAME 'mS-SQL-PublicationURL'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.275
+       NAME 'printKeepPrintedJobs'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.267
+       NAME 'uSNDSALastObjRemoved'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.381
+       NAME 'dnsNotifySecondaries'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' )
+
+attributetype ( 1.2.840.113556.1.4.1360
+       NAME 'mS-DS-ConsistencyGuid'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.869
+       NAME 'frsComputerReference'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1369
+       NAME 'mS-SQL-ServiceAccount'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1124
+       NAME 'msNPCallingStationID'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )
+
+attributetype ( 1.2.840.113556.1.4.947
+       NAME 'mSMQSignCertificates'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.624
+       NAME 'ipsecOwnersReference'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.14
+       NAME 'builtinModifiedCount'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.634
+       NAME 'privilegeDisplayName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.380
+       NAME 'dnsSecureSecondaries'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' )
+
+attributetype ( 1.2.840.113556.1.4.817
+       NAME 'localizedDescription'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.195
+       NAME 'systemPossSuperiors'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.38'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.2.353
+       NAME 'displayNamePrintable'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.44'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.771
+       NAME 'servicePrincipalName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.866
+       NAME 'pekKeyChangeInterval'
+       SYNTAX '1.2.840.113556.1.4.906'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.445
+       NAME 'originalDisplayTable'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1398
+       NAME 'mS-SQL-LastBackupDate'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.517
+       NAME 'ipsecPolicyReference'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.823
+       NAME 'certificateTemplates'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.2.15
+       NAME 'hasPartialReplicaNCs'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.457
+       NAME 'localPolicyReference'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.2.380
+       NAME 'extendedCharsAllowed'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.629
+       NAME 'ipsecFilterReference'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 1.2.840.113556.1.4.626
+       NAME 'ipsecISAKMPReference'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.876
+       NAME 'fRSMemberReferenceBL'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.314
+       NAME 'rpcNsTransferSyntax'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1227
+       NAME 'mSMQRoutingServices'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1375
+       NAME 'mS-SQL-MultiProtocol'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.825
+       NAME 'enrollmentProviders'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.287
+       NAME 'printNetworkAddress'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1171
+       NAME 'msRADIUSServiceType'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.631
+       NAME 'printPagesPerMinute'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.299
+       NAME 'printMediaSupported'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 1.2.840.113556.1.4.824
+       NAME 'signatureAlgorithms'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.877
+       NAME 'fRSPartnerAuthLevel'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.636
+       NAME 'privilegeAttributes'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.640
+       NAME 'partialAttributeSet'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.850
+       NAME 'netbootLimitClients'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1383
+       NAME 'mS-SQL-ConnectionURL'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1406
+       NAME 'mS-SQL-AllowSnapshotFilesFTPDownloading'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.7'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1331
+       NAME 'pKIExpirationPeriod'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.531
+       NAME 'nonSecurityMemberBL'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       NO-USER-MODIFICATION )
+
+attributetype ( 1.2.840.113556.1.4.540
+       NAME 'initialAuthOutgoing'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 1.2.840.113556.1.4.1158
+       NAME 'msRADIUSFramedRoute'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )
+
+attributetype ( 1.2.840.113556.1.4.200
+       NAME 'controlAccessRights'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
diff --git a/servers/slapd/schema/microsoft.std.schema b/servers/slapd/schema/microsoft.std.schema
new file mode 100644 (file)
index 0000000..a808b7c
--- /dev/null
@@ -0,0 +1,480 @@
+# $OpenLDAP$
+# This file is for informational purposes only
+
+# These definitions are from Microsoft's Active Directory.
+# They were gathered using the subschemaSubentry object of
+# Windows 2000 Advanced Server Release Candidate 2.
+
+# These object classes and attributes are from the standard
+# OID arc 2.5.6 and from the directory pilot project RFC-1274.
+# Many of them have been modified in Active Directory.  To
+# adhere to the standard, DO NOT USE THIS FILE.  Instead, use
+# core.schema.
+
+objectclass ( 2.5.6.0
+       NAME 'top'
+       ABSTRACT
+       MUST (objectClass $ instanceType $ nTSecurityDescriptor $
+               objectCategory )
+       MAY (cn $ description $ distinguishedName $ whenCreated $
+               whenChanged $ subRefs $ displayName $ uSNCreated $ isDeleted $
+               dSASignature $ objectVersion $ repsTo $ repsFrom $ memberOf $
+               uSNChanged $ uSNLastObjRem $ showInAdvancedViewOnly $
+               adminDisplayName $ proxyAddresses $ adminDescription $
+               extensionName $ uSNDSALastObjRemoved $ displayNamePrintable $
+               directReports $ wWWHomePage $ USNIntersite $ name $ objectGUID $
+               replPropertyMetaData $ replUpToDateVector $ flags $ revision $
+               wbemPath $ fSMORoleOwner $ systemFlags $ siteObjectBL $
+               serverReferenceBL $ nonSecurityMemberBL $ queryPolicyBL $
+               wellKnownObjects $ isPrivilegeHolder $ partialAttributeSet $
+               managedObjects $ partialAttributeDeletionList $ url $
+               lastKnownParent $ bridgeheadServerListBL $ netbootSCPBL $
+               isCriticalSystemObject $ frsComputerReferenceBL $
+               fRSMemberReferenceBL $ uSNSource $ fromEntry $
+               allowedChildClasses $ allowedChildClassesEffective $
+               allowedAttributes $ allowedAttributesEffective $
+               possibleInferiors $ canonicalName $ proxiedObjectName $
+               sDRightsEffective $ dSCorePropagationData $
+               otherWellKnownObjects $ mS-DS-ConsistencyGuid $
+               mS-DS-ConsistencyChildCount $ masteredBy $ createTimeStamp $
+               modifyTimeStamp $ subSchemaSubEntry ) )
+
+objectclass ( 2.5.6.2
+       NAME 'country'
+       SUP top
+       ABSTRACT
+       MUST (c )
+       MAY (searchGuide $ co ) )
+
+objectclass ( 2.5.6.3
+       NAME 'locality'
+       SUP top
+       STRUCTURAL 
+       MUST (l )
+       MAY (st $ street $ searchGuide $ seeAlso ) )
+
+objectclass ( 2.5.6.4
+       NAME 'organization'
+       SUP top
+       STRUCTURAL 
+       MUST (o )
+       MAY (l $ st $ street $ searchGuide $ businessCategory $ postalAddress $
+               postalCode $ postOfficeBox $ physicalDeliveryOfficeName $
+               telephoneNumber $ telexNumber $ teletexTerminalIdentifier $
+               facsimileTelephoneNumber $ x121Address $ internationalISDNNumber $
+               registeredAddress $ destinationIndicator $ preferredDeliveryMethod $
+               seeAlso $ userPassword ) )
+
+objectclass ( 2.5.6.5
+       NAME 'organizationalUnit'
+       SUP top
+       STRUCTURAL 
+       MUST (ou )
+       MAY (c $ l $ st $ street $ searchGuide $ businessCategory $
+               postalAddress $ postalCode $ postOfficeBox $
+               physicalDeliveryOfficeName $ telephoneNumber $ telexNumber $
+               teletexTerminalIdentifier $ facsimileTelephoneNumber $ x121Address $
+               internationalISDNNumber $ registeredAddress $ destinationIndicator $
+               preferredDeliveryMethod $ seeAlso $ userPassword $ co $ countryCode $ 
+               desktopProfile $ defaultGroup $ managedBy $ uPNSuffixes $ gPLink $
+               gPOptions $ thumbnailLogo ) )
+
+objectclass ( 2.5.6.6
+       NAME 'person'
+       SUP top
+       ABSTRACT
+       MUST (cn )
+       MAY (sn $ telephoneNumber $ seeAlso $ userPassword ) )
+
+objectclass ( 2.5.6.7
+       NAME 'organizationalPerson'
+       SUP person
+       ABSTRACT
+       MAY (c $ l $ st $ street $ o $ ou $ title $ postalAddress $ postalCode $
+               postOfficeBox $ physicalDeliveryOfficeName $ telexNumber $
+               teletexTerminalIdentifier $ facsimileTelephoneNumber $ x121Address $
+               internationalISDNNumber $ registeredAddress $ destinationIndicator $
+               preferredDeliveryMethod $ givenName $ initials $ generationQualifier $
+               otherTelephone $ otherPager $ co $ department $ company $
+               streetAddress $ otherHomePhone $ personalTitle $ homePostalAddress $
+               countryCode $ employeeID $ comment $ division $
+               otherFacsimileTelephoneNumber $ otherMobile $ primaryTelexNumber $
+               primaryInternationalISDNNumber $ mhsORAddress $ otherMailbox $
+               assistant $ ipPhone $ otherIpPhone $ mail $ manager $ homePhone $
+               mobile $ pager $ middleName $ thumbnailPhoto $ thumbnailLogo ) )
+
+objectclass ( 2.5.6.8
+       NAME 'organizationalRole'
+       SUP top
+       STRUCTURAL 
+       MUST (cn )
+       MAY (l $ st $ street $ ou $ postalAddress $ postalCode $ postOfficeBox $
+               physicalDeliveryOfficeName $ telephoneNumber $ telexNumber $
+               teletexTerminalIdentifier $ facsimileTelephoneNumber $ x121Address $
+               internationalISDNNumber $ registeredAddress $ destinationIndicator $
+               preferredDeliveryMethod $ roleOccupant $ seeAlso ) )
+
+objectclass ( 2.5.6.9
+       NAME 'groupOfNames'
+       SUP top
+       ABSTRACT
+       MUST (cn $ member )
+       MAY (o $ ou $ businessCategory $ owner $ seeAlso ) )
+
+objectclass ( 2.5.6.10
+       NAME 'residentialPerson'
+       SUP person
+       STRUCTURAL 
+       MAY (l $ st $ street $ ou $ title $ businessCategory $ postalAddress $
+               postalCode $ postOfficeBox $ physicalDeliveryOfficeName $ telexNumber $
+               teletexTerminalIdentifier $ facsimileTelephoneNumber $ x121Address $
+               internationalISDNNumber $ registeredAddress $ destinationIndicator $
+               preferredDeliveryMethod ) )
+
+objectclass ( 2.5.6.11
+       NAME 'applicationProcess'
+       SUP top
+       STRUCTURAL 
+       MUST (cn )
+       MAY (l $ ou $ seeAlso ) )
+
+objectclass ( 2.5.6.12
+       NAME 'applicationEntity'
+       SUP top
+       STRUCTURAL 
+       MUST (cn $ presentationAddress )
+       MAY (l $ o $ ou $ supportedApplicationContext $ seeAlso ) )
+
+objectclass ( 2.5.6.13
+       NAME 'dSA'
+       SUP applicationEntity
+       STRUCTURAL 
+       MAY (knowledgeInformation ) )
+
+objectclass ( 2.5.6.14
+       NAME 'device'
+       SUP top
+       ABSTRACT
+       MUST (cn )
+       MAY (serialNumber $ l $ o $ ou $ owner $ seeAlso ) )
+
+objectclass ( 2.5.6.16
+       NAME 'certificationAuthority'
+       SUP top
+       STRUCTURAL 
+       MUST (cn $ cACertificate $ authorityRevocationList $
+               certificateRevocationList )
+       MAY (searchGuide $ teletexTerminalIdentifier $ supportedApplicationContext $
+               crossCertificatePair $ deltaRevocationList $ domainPolicyObject $
+               parentCA $ dNSHostName $ parentCACertificateChain $ domainID $
+               cAConnect $ cAWEBURL $ cRLObject $ cAUsages $ previousCACertificates $
+               pendingCACertificates $ previousParentCA $ pendingParentCA $
+               currentParentCA $ cACertificateDN $ certificateTemplates $
+               signatureAlgorithms $ enrollmentProviders ) )
+
+objectclass ( 2.5.6.19
+       NAME 'cRLDistributionPoint'
+       SUP top
+       STRUCTURAL 
+       MUST (cn )
+       MAY (authorityRevocationList $ certificateRevocationList $
+               deltaRevocationList $ cRLPartitionedRevocationList $
+               certificateAuthorityObject ) )
+
+objectclass ( 2.5.20.1
+       NAME 'subSchema'
+       SUP top
+       STRUCTURAL 
+       MAY (extendedClassInfo $ extendedAttributeInfo $ dITContentRules $
+               attributeTypes $ objectClasses $ modifyTimeStamp ) )
+
+#####################################################
+
+attributetype ( 2.5.4.0
+       NAME 'objectClass'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.38'
+       NO-USER-MODIFICATION )
+
+attributetype ( 2.5.4.2
+       NAME 'knowledgeInformation'
+       SYNTAX '1.2.840.113556.1.4.905' )
+
+attributetype ( 2.5.4.3
+       NAME 'cn'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 2.5.4.4
+       NAME 'sn'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 2.5.4.5
+       NAME 'serialNumber'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )
+
+attributetype ( 2.5.4.6
+       NAME 'c'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 2.5.4.7
+       NAME 'l'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 2.5.4.8
+       NAME 'st'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 2.5.4.9
+       NAME 'street'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 2.5.4.10
+       NAME 'o'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 2.5.4.11
+       NAME 'ou'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 2.5.4.12
+       NAME 'title'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 2.5.4.13
+       NAME 'description'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 2.5.4.14
+       NAME 'searchGuide'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 2.5.4.15
+       NAME 'businessCategory'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 2.5.4.16
+       NAME 'postalAddress'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 2.5.4.17
+       NAME 'postalCode'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 2.5.4.18
+       NAME 'postOfficeBox'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+
+attributetype ( 2.5.4.19
+       NAME 'physicalDeliveryOfficeName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 2.5.4.20
+       NAME 'telephoneNumber'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 2.5.4.21
+       NAME 'telexNumber'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 2.5.4.22
+       NAME 'teletexTerminalIdentifier'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 2.5.4.23
+       NAME 'facsimileTelephoneNumber'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 2.5.4.24
+       NAME 'x121Address'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.36' )
+
+attributetype ( 2.5.4.25
+       NAME 'internationalISDNNumber'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.36' )
+
+attributetype ( 2.5.4.26
+       NAME 'registeredAddress'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 2.5.4.27
+       NAME 'destinationIndicator'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.44' )
+
+attributetype ( 2.5.4.28
+       NAME 'preferredDeliveryMethod'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' )
+
+attributetype ( 2.5.4.29
+       NAME 'presentationAddress'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.43'
+       SINGLE-VALUE )
+
+attributetype ( 2.5.4.30
+       NAME 'supportedApplicationContext'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 2.5.4.31
+       NAME 'member'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 2.5.4.32
+       NAME 'owner'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 2.5.4.33
+       NAME 'roleOccupant'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 2.5.4.34
+       NAME 'seeAlso'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )
+
+attributetype ( 2.5.4.35
+       NAME 'userPassword'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 2.5.4.36
+       NAME 'userCertificate'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 2.5.4.37
+       NAME 'cACertificate'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 2.5.4.38
+       NAME 'authorityRevocationList'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 2.5.4.39
+       NAME 'certificateRevocationList'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 2.5.4.40
+       NAME 'crossCertificatePair'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 2.5.4.42
+       NAME 'givenName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 2.5.4.43
+       NAME 'initials'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 2.5.4.44
+       NAME 'generationQualifier'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 2.5.4.49
+       NAME 'distinguishedName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 2.5.4.53
+       NAME 'deltaRevocationList'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+attributetype ( 2.5.18.1
+       NAME 'createTimeStamp'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.24'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 2.5.18.2
+       NAME 'modifyTimeStamp'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.24'
+       SINGLE-VALUE
+       NO-USER-MODIFICATION )
+
+attributetype ( 2.5.18.10
+       NAME 'subSchemaSubEntry'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       NO-USER-MODIFICATION )
+
+attributetype ( 2.5.21.2
+       NAME 'dITContentRules'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       NO-USER-MODIFICATION )
+
+attributetype ( 2.5.21.5
+       NAME 'attributeTypes'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       NO-USER-MODIFICATION )
+
+attributetype ( 2.5.21.6
+       NAME 'objectClasses'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       NO-USER-MODIFICATION )
+
+attributetype ( 2.16.840.1.113730.3.1.34
+       NAME 'middleName'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113730.3.1.35
+       NAME 'thumbnailPhoto'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113730.3.1.36
+       NAME 'thumbnailLogo'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40'
+       SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113730.3.140
+       NAME 'userSMIMECertificate'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )
+
+#####################################################
+
+attributetype ( 0.9.2342.19200300.100.1.2
+       NAME 'textEncodedORAddress'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 0.9.2342.19200300.100.1.3
+       NAME 'mail'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 0.9.2342.19200300.100.1.10
+       NAME 'manager'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.12'
+       SINGLE-VALUE )
+
+attributetype ( 0.9.2342.19200300.100.1.20
+       NAME 'homePhone'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 0.9.2342.19200300.100.1.25
+       NAME 'dc'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 0.9.2342.19200300.100.1.41
+       NAME 'mobile'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
+attributetype ( 0.9.2342.19200300.100.1.42
+       NAME 'pager'
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
+       SINGLE-VALUE )
+
index c5cfb497bc90446e339e6741e199361c9f52f843..0a6ac6855e24ee75ac1867be93bf54726428b1c5 100644 (file)
@@ -1,24 +1,35 @@
-# Assorted definitions from several sources
 # $OpenLDAP$
-
 #
-# RFC2247
+# Assorted definitions from several sources
+#      depends on core.schema and pilot.schema
 #
-objectclass ( 1.3.6.1.4.1.1466.344 NAME 'dcObject' SUP top AUXILIARY MUST dc )
 
 #
-# This comes from RFC2377
+# draft-lachman-laser-ldap-mail-routing-01.txt
 #
-objectclass ( 1.3.6.1.1.3.1 NAME 'uidObject' SUP top AUXILIARY MUST uid )
+attributetype ( 2.16.840.1.113730.3.1.13
+       NAME 'mailLocalAddress'
+       DESC 'RFC 822 email address of this recipient'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.26{256}' )
 
-# Origin of this has not been identified.  We had it and Netscape has it
-# too.
+attributetype ( 2.16.840.1.113730.3.1.18
+       NAME 'mailHost'
+       DESC 'fully-qualified hostname of the MTA that is the final 
+               SMTP destination of messages to this recipient'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.26{256}'
+       SINGLE-VALUE )
 
-attribute ( 1.3.6.1.4.1.250.1.60 NAME ( 'timeToLive' 'ttl' )
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+attributetype ( 2.16.840.1.113730.3.1.47
+       NAME 'mailRoutingAddress'
+       DESC 'RFC 822 address to use when routing messages to
+               the SMTP MTA of this recipient'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX '1.3.6.1.4.1.1466.115.121.1.26{256}'
+       SINGLE-VALUE )
 
-objectclass ( 1.3.6.1.4.1.250.3.18 NAME 'cacheObject' SUP top MAY ttl )
+objectclass ( 2.16.840.1.113730.3.2.TBD NAME 'inetLocalMailRecipient'
+       SUP top AUXILIARY
+       MAY     ( mailLocalAddress $ mailHost $ mailRoutingAddress )
 
-#
-# RFC 2079
-#
index 2daca76f8d7a2aa599a3c1e46836023a0dc73edb..dc88d20914c53e700b2b09ceb9a9829ea102010a 100644 (file)
 # The spec says "leading zero is significant".  Is this really a
 # numeric string?
 
-attribute ( 2.6.6.5.2.4.1 NAME 'fipsStateNumericCode'
+attributetype ( 2.6.6.5.2.4.1 NAME 'fipsStateNumericCode'
        EQUALITY numericStringMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{2} )
 
 # It is probably inconvenient to give this attribute that syntax
 # (Printable String) instead of Directory String.
 
-attribute ( 2.6.6.5.2.4.2 NAME 'fipsStateAlphaCode'
+attributetype ( 2.6.6.5.2.4.2 NAME 'fipsStateAlphaCode'
        EQUALITY caseIgnoreMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{2} )
 
 # The spec says "leading zeros are significant".  Is this really a
 # numeric string?
 
-attribute ( 2.6.6.5.2.4.3 NAME 'fipsCountyNumericCode'
+attributetype ( 2.6.6.5.2.4.3 NAME 'fipsCountyNumericCode'
        EQUALITY numericStringMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{5} )
 
@@ -45,34 +45,34 @@ attribute ( 2.6.6.5.2.4.3 NAME 'fipsCountyNumericCode'
 # The spec says "leading zeros are significant".  Is this really a
 # numeric string?
 
-attribute ( 2.6.6.5.2.4.4 NAME ( 'fipsPlaceNumericCode' 'fips55' )
+attributetype ( 2.6.6.5.2.4.4 NAME ( 'fipsPlaceNumericCode' 'fips55' )
        EQUALITY numericStringMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{5} )
 
-attribute ( 2.6.6.5.2.4.5 NAME 'ansiOrgNumericCode'
+attributetype ( 2.6.6.5.2.4.5 NAME 'ansiOrgNumericCode'
        EQUALITY integerMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
 
 # Apparently, 'ad' is an alias for 'addmdName'
 
-attribute ( 2.6.6.5.2.4.6 NAME ( 'addmdName' 'ad' )
+attributetype ( 2.6.6.5.2.4.6 NAME ( 'addmdName' 'ad' )
        EQUALITY caseIgnoreMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
 # I don't know what syntax to give this.  I will use binary for the
 # time being.
 
-attribute ( 2.6.6.5.2.4.7 NAME 'nadfSearchGuide'
+attributetype ( 2.6.6.5.2.4.7 NAME 'nadfSearchGuide'
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 )
 
-attribute ( 2.6.6.5.2.4.8 NAME 'supplementaryInformation'
+attributetype ( 2.6.6.5.2.4.8 NAME 'supplementaryInformation'
        EQUALITY caseIgnoreMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{76} )
 
-attribute ( 2.6.6.5.2.4.9 NAME 'namingLink'
+attributetype ( 2.6.6.5.2.4.9 NAME 'namingLink'
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
 
-attribute ( 2.6.6.5.2.4.10 NAME 'reciprocalNamingLink'
+attributetype ( 2.6.6.5.2.4.10 NAME 'reciprocalNamingLink'
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
        SINGLE-VALUE )
 
@@ -83,11 +83,11 @@ attribute ( 2.6.6.5.2.4.10 NAME 'reciprocalNamingLink'
 # define the string with IA5 syntax and we don't have a
 # clear base for this.
 
-attribute ( 2.6.6.5.2.4.15 NAME 'logicalDSAReference'
+attributetype ( 2.6.6.5.2.4.15 NAME 'logicalDSAReference'
        EQUALITY caseIgnoreMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( 2.6.6.5.2.4.16 NAME 'multiMediaInformation'
+attributetype ( 2.6.6.5.2.4.16 NAME 'multiMediaInformation'
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 )
 
 # Number 17, 18 and 19 are EDI-related attributes for the nadfEDIUser
diff --git a/servers/slapd/schema/nis.at.conf b/servers/slapd/schema/nis.at.conf
deleted file mode 100644 (file)
index 1331c3c..0000000
+++ /dev/null
@@ -1,297 +0,0 @@
-# $OpenLDAP$
-#
-# By:          Juan C. Gomez / gomez@engr.sgi.com
-# Date:                May/1999
-# Source:      RFC-2307
-# ---------------------------------------------------------
-#
-# Written by Juan C. Gomez and placed into the public domain.
-# This file is not subject to any license of SGI.
-#
-# ---------------------------------------------------------
-#
-# Attribute definitions for using LDAP as a back-end for 
-# Network Information Services (NIS) with OpenLDAP server. 
-#
-# I am adding the whole description here because, perhaps,
-# we will move towards better schema support in the future
-# and will have all the keywords to express the attribute
-# description more accurately.
-#
-# nisSchema OID = 1.3.6.1.1.1
-#                iso.org.dod.internet.directory.nisSchema
-#
-# NOTES:
-#
-# 1.- Two attributes have as a super-type the name attribute
-#     described in RFC-2256. The 'name' attribute has the 
-#     following description: (see X.520 for further details)
-#
-#      OID             2.5.4.41
-#      NAME            name
-#      SUBSTRINGS      caseIgnoreSubstringsMatch
-#      SYNTAX          DirectoryString{32768}
-# 
-#     DirectoryString Syntax (OID=1.3.6.1.4.1.1466.115.121.1.15)
-#     is described in RFC-2252, basically a UTF-8 (Unicode
-#     Superset) encoded string.
-#
-# 2.- The syntax for nisNetgroupTriple is 'nisNetgroupTripleSyntax',
-#     defined as:
-#
-#      OID             nisSchema.0.0
-#      NAME            'nisNetgroupTripleSyntax'
-#      DESC            'NIS netgroup triple'
-#      
-#     Where values in this syntax can be described as:
-#
-#      nisNetgroupTripleSyntax ::= SEQUENCE {
-#              hostname        [0] IA5String OPTIONAL,
-#              username        [1] IA5String OPTIONAL,
-#              domainname      [2] IA5String OPTIONAL
-#      }
-#     
-#     (These values are encoded as strings in LDAP servers)
-#
-# 3.- The syntax for bootParameter is 'bootParameterSyntax',
-#     defined as :
-#
-#      OID             nisSchema.0.1
-#      NAME            'bootParameterSyntax'
-#      DESC            'Boot Parameter'
-# 
-#     Where values in this syntax can be described as:
-#
-#      bootParameterSyntax ::= SEQUENCE {
-#              key      IA5String,
-#              server   IA5String,
-#              path     IA5String
-#      }
-#
-#     (These values are encoded as strings in LDAP servers)
-#
-
-
-# ----------------------FORMAL DESCRIPTION--------------------
-# OID          nisSchema.1.0
-# NAME         uidNumber
-# DESC         'An integer uniquely identifying a user in an
-#              administrative domain'
-# EQUALITY     integerMatch
-# SYNTAX       'INTEGER'       SINGLE-VALUE
-#
-#
-# OID          nisSchema.1.1
-# NAME         gidNumber
-# DESC         'An integer uniquely identifying a group in an
-#              administrative domain'
-# EQUALITY     integerMatch
-# SYNTAX       'INTEGER'       SINGLE-VALUE
-#
-#
-# OID          nisSchema.1.2
-# NAME         gecos
-# DESC         'The GECOS field; the common name'
-# EQUALITY     caseIgnoreIA5Match
-# SUBSTRINGS   caseIgnoreIA5SubstringsMatch
-# SYNTAX       'IA5String'      SINGLE-VALUE
-#
-#
-# OID          nisSchema.1.3
-# NAME         homeDirectory
-# DESC         'The absolute path to the home directory'
-# EQUALITY     caseExactIA5Match
-# SYNTAX       'IA5String'      SINGLE-VALUE
-#
-#
-# OID          nisSchema.1.4
-# NAME         loginShell
-# DESC         'The path to the login shell'
-# EQUALITY     caseExactIA5Match
-# SYNTAX       'IA5String'      SINGLE-VALUE
-#
-#
-# OID          nisSchema.1.5
-# NAME         shadowLastChange
-# DESC         ''
-# EQUALITY     integerMatch
-# SYNTAX       'INTEGER'        SINGLE-VALUE
-#
-#
-# OID          nisSchema.1.6
-# NAME         shadowMin
-# DESC         ''
-# EQUALITY     integerMatch
-# SYNTAX       'INTEGER'        SINGLE-VALUE
-#
-#
-# OID          nisSchema.1.7
-# NAME         shadowMax
-# DESC         ''
-# EQUALITY     integerMatch
-# SYNTAX       'INTEGER'        SINGLE-VALUE
-#
-#
-# OID          nisSchema.1.8
-# NAME         shadowWarning
-# DESC         ''
-# EQUALITY     integerMatch
-# SYNTAX       'INTEGER'        SINGLE-VALUE
-#
-#
-# OID          nisSchema.1.9
-# NAME         shadowInactive
-# DESC         ''
-# EQUALITY     integerMatch
-# SYNTAX       'INTEGER'        SINGLE-VALUE
-#
-#
-# OID          nisSchema.1.10
-# NAME         shadowExpire
-# DESC         ''
-# EQUALITY     integerMatch
-# SYNTAX       'INTEGER'        SINGLE-VALUE
-#
-#
-# OID          nisSchema.1.11
-# NAME         shadowFlag
-# DESC         ''
-# EQUALITY     integerMatch
-# SYNTAX       'INTEGER'        SINGLE-VALUE
-#
-#
-# OID          nisSchema.1.12
-# NAME         memberUid
-# DESC         ''
-# EQUALITY     caseExactIA5Match
-# SUBSTRINGS   caseExactIA5SubstringsMatch
-# SYNTAX       'IA5String'
-#
-#
-# OID          nisSchema.1.13
-# NAME         memberNisNetgroup
-# DESC         ''
-# EQUALITY     caseExactIA5Match
-# SUBSTRINGS   caseExactIA5SubstringsMatch
-# SYNTAX       'IA5String'
-#
-#
-# OID          nisSchema.1.14
-# NAME         memberNisNetgroup
-# DESC         'Netgroup triple'
-# SYNTAX       'nisNetgroupTripleSyntax'
-#
-#
-# OID          nisSchema.1.15
-# NAME         ipServicePort
-# DESC         ''
-# EQUALITY     integerMatch
-# SYNTAX       'INSTEGER'      SINGLE-VALUE    
-#
-#
-# OID          nisSchema.1.16
-# NAME         ipServiceProtocol
-# SUP          name
-#
-#
-# OID          nisSchema.1.17
-# NAME         ipServiceNUmber
-# EQUALITY     integerMatch
-# SYNTAX       'INSTEGER'      SINGLE-VALUE
-#
-#
-# OID          nisSchema.1.18
-# NAME         oncRpcNumber
-# EQUALITY     integerMatch
-# SYNTAX       'INSTEGER'      SINGLE-VALUE
-#
-#
-# OID          nisSchema.1.19
-# NAME         ipHostNumber
-# DESC         'IP address as a dotted decimal, eg. 192.168.1.1
-#              omitting leading zeros'
-# EQUALITY     caseIgnoreIA5Match
-# SYNTAX       'IA5String{128}'
-#
-#
-# OID          nisSchema.1.20
-# NAME         ipNetworkNumber
-# DESC         'IP network as a dotted decimal, eg. 192.168,
-#              omitting leading zeros'
-# EQUALITY     caseIgnoreIA5Match
-# SYNTAX       'IA5String{128}'        SINGLE-VALUE
-#
-#
-# OID          nisSchema.1.21
-# NAME         ipNetmaskNumber
-# DESC         'IP netmask as a dotted decimal, eg. 255.255.255.0,
-#              omitting leading zeros'
-# EQUALITY     caseIgnoreIA5Match      
-# SYNTAX       'IA5String{128}'        SINGLE-VALUE    
-#
-#
-# OID          nisSchema.1.22
-# NAME         macAddress
-# DESC         'MAC address in maximal, colon separated hex notation, 
-#              eg. 00:00:92:90:ee:e2'
-# EQUALITY     caseIgnoreIA5Match
-# SYNTAX       'IA5String{128}'
-#
-#
-# OID          nisSchema.1.23
-# NAME         bootParameter
-# DESC         'rpc.bootparamd parameter'
-# SYNTAX       'bootParameterSyntax'
-#
-#
-# OID          nisSchema.1.24
-# NAME         bootFile
-# DESC         'Boot image name'
-# EQUALITY     caseExactIA5Match
-# SYNTAX       'IA5String'
-#
-#
-# OID          nisSchema.1.26
-# NAME         nisMapName
-# DESC         ''
-# SUP          name
-#
-#
-# OID          nisSchema.1.27
-# NAME         nisMapEntry
-# DESC         ''
-# EQUALITY     caseExactIA5Match
-# SUBSTRINGS   caseExactIA5SubstringMatch
-# SYNTAX       'IA5String{1024}'       SINGLE-VALUE
-#
-# ----------------------END FORMAL DESCRIPTION-------------
-
-
-
-attribute      uidNumber               ces
-attribute      gidNumber               ces
-attribute      gecos                   cis
-attribute      homeDirectory           ces
-attribute      loginShell              ces
-attribute      shadowLastChange        ces
-attribute      shadowMin               ces
-attribute      shadowMax               ces
-attribute      shadowWarning           ces
-attribute      shadowInactive          ces
-attribute      shadowExpire            ces
-attribute      shadowFlag              ces
-attribute      memberUid               ces
-attribute      memberNisNetgroup       ces
-attribute      nisNetgroupTriple       ces
-attribute      ipServicePort           ces
-attribute      ipServiceProtocol       cis
-attribute      ipProtocolNumber        ces
-attribute      oncRpcNumber            ces
-attribute      ipHostNumber            cis
-attribute      ipNetworkNumber         cis
-attribute      ipNetmaskNumber         cis
-attribute      macAddress              cis
-attribute      bootParameter           ces
-attribute      bootFile                ces
-attribute      nisMapName              cis
-attribute      nisMapEntry             ces
diff --git a/servers/slapd/schema/nis.oc.conf b/servers/slapd/schema/nis.oc.conf
deleted file mode 100644 (file)
index fe8a110..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-# $OpenLDAP$
-#
-# By:          Juan C. Gomez / gomez@engr.sgi.com
-# Date:                May/1999
-# Source:      RFC-2307
-# ---------------------------------------------------------
-#
-# Written by Juan C. Gomez and placed into the public domain.
-# This file is not subject to any license of SGI.
-#
-# ---------------------------------------------------------
-#
-# Object Classes for using LDAP as a backend for Network
-# Information Services (NIS).
-# (As Proposed in RFC-2307)
-# 
-
-
-
-
-# ----------------------FORMAL DESCRIPTION--------------------
-# OID  nisSchema.2.0 
-# NAME 'posixAccount' SUP top AUXILIARY
-# DESC 'Abstraction of an account with POSIX attributes'
-# MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory )
-# MAY  ( userPassword $ loginShell $ gecos $ description ) )
-#
-#
-# OID  nisSchema.2.1
-# NAME 'shadowAccount' SUP top AUXILIARY
-# DESC 'Additional attributes for shadow passwords'
-# MUST uid
-# MAY ( userPassword $ shadowLastChange $ shadowMin
-#       shadowMax $ shadowWarning $ shadowInactive $
-#       shadowExpire $ shadowFlag $ description )
-#
-#
-# OID  nisSchema.2.2 NAME 'posixGroup' SUP top STRUCTURAL
-# DESC  'Abstraction of a group of accounts'
-# MUST ( cn $ gidNumber )
-# MAY ( userPassword $ memberUid $ description ) )
-#
-#
-# OID          nisSchema.2.3 NAME 'ipService' SUP top STRUCTURAL
-# DESC         'Abstraction an Internet Protocol service.
-#               Maps an IP port and protocol (such as tcp or udp)
-#               to one or more names; the distinguished value of
-#               the cn attribute denotes the service's canonical
-#               name'
-# MUST         ( cn $ ipServicePort $ ipServiceProtocol )
-# MAY          ( description )
-#
-#
-# OID          nisSchema.2.4 NAME 'ipProtocol' SUP top STRUCTURAL
-# DESC         'Abstraction of an IP protocol. Maps a protocol number
-#               to one or more names. The distinguished value of the cn
-#               attribute denotes the protocol's canonical name'
-# MUST         ( cn $ ipProtocolNumber $ description )
-# MAY          description 
-#
-#
-# OID  nisSchema.2.5 NAME 'oncRpc' SUP top STRUCTURAL
-# DESC 'Abstraction of an Open Network Computing (ONC)
-#       [RFC1057] Remote Procedure Call (RPC) binding.
-#       This class maps an ONC RPC number to a name.
-#       The distinguished value of the cn attribute denotes
-#        the RPC service's canonical name'
-# MUST ( cn $ oncRpcNumber $ description )
-# MAY  description
-#
-#
-# OID  nisSchema.2.6 NAME 'ipHost' SUP top AUXILIARY
-# DESC 'Abstraction of a host, an IP device. The distinguished
-#        value of the cn attribute denotes the host's canonical
-#        name. Device SHOULD be used as a structural class'
-# MUST ( cn $ ipHostNumber )
-# MAY  ( l $ description $ manager ) )
-#
-#
-# OID  nisSchema.2.7 NAME 'ipNetwork' SUP top STRUCTURAL
-# DESC 'Abstraction of a network. The distinguished value of
-#       the cn attribute denotes the network's canonical name'
-# MUST ( cn $ ipNetworkNumber )
-# MAY  ( ipNetmaskNumber $ l $ description $ manager ) )
-#
-#
-# OID  nisSchema.2.8 NAME 'nisNetgroup' SUP top STRUCTURAL
-# DESC 'Abstraction of a netgroup. May refer to other netgroups'
-# MUST cn
-# MAY  ( nisNetgroupTriple $ memberNisNetgroup $ description )
-#
-#
-# OID  nisSchema.2.09 NAME 'nisMap' SUP top STRUCTURAL
-# DESC 'A generic abstraction of a NIS map'
-# MUST nisMapName
-# MAY  description
-#
-#
-# OID  nisSchema.2.10 NAME 'nisObject' SUP top STRUCTURAL
-# DESC 'An entry in a NIS map'
-# MUST ( cn $ nisMapEntry $ nisMapName )
-# MAY  description
-#
-#
-# OID  nisSchema.2.11 NAME 'ieee802Device' SUP top AUXILIARY
-# DESC 'A device with a MAC address; device SHOULD be
-#      used as a structural class'
-# MAY macAddress
-#
-#
-# OID  nisSchema.2.12 NAME 'bootableDevice' SUP top AUXILIARY
-# DESC 'A device with boot parameters; device SHOULD be
-#      used as a structural class'
-# MAY  ( bootFile $ bootParameter )
-#
-# ----------------------END FORMAL DESCRIPTION-------------
-
-
-
-
-objectclass    posixAccount
-       requires
-               objectClass,
-               cn,
-               uid,
-               uidNumber,
-               gidNumber,
-               homeDirectory
-       allows
-               userPassword,
-               loginShell,
-               gecos,
-               description
-       
-objectclass    shadowAccount
-       requires
-               objectClass,
-               uid
-       allows
-               userPassword,
-               shadowLastChange,
-               shadowMin,
-               shadowMax,
-               shadowWarning,
-               shadowInactive,
-               shadowExpire,
-               shadowFlag,
-               description
-
-objectclass    posixGroup
-       requires
-               objectClass,
-               cn,
-               gidNumber
-       allows
-               userPassword,
-               memberUid,
-               description
-
-objectclass    ipService
-       requires
-               objectClass,
-               cn,
-               ipServicePort,
-               ipServiceProtocol
-       allows
-               description
-
-objectclass    ipProtocol
-       requires
-               objectClass,
-               cn,
-               ipProtocolNumber,
-               description
-       allows
-               description
-
-objectclass    oncRpc
-       requires
-               objectClass,
-               cn,
-               oncRpcNumber,
-               description
-       allows
-               description
-
-objectclass    ipHost
-       requires
-               objectClass,
-               cn,
-               ipHostNumber
-       allows
-               l,
-               description,
-               manager
-
-objectclass    ipNetwork
-       requires
-               objectClass,
-               cn,
-               ipNetworkNumber
-       allows
-               ipNetmaskNumber,
-               l,
-               description,
-               manager
-
-objectclass    nisNetgroup
-       requires
-               objectClass,
-               cn
-       allows
-               nisNetgroupTriple,
-               memberNisNetgroup,
-               description
-
-objectclass    nisMap
-       requires
-               objectClass,
-               nisMapName
-       allows
-               description
-
-objectclass    nisObject
-       requires
-               objectClass,
-               cn,
-               nisMapEntry,
-               nisMapName
-       allows
-               description
-
-objectclass    ieee802Device
-       requires
-               objectClass
-       allows
-               macAddress
-
-objectclass    bootableDevice
-       requires
-               objectClass
-       allows
-               bootFile,
-               bootParameter
index 7c5ccf2b061f4a2045640d6b0282cf95abbb6025..525ee5c030466d8b883be01470dc4751e083bfb8 100644 (file)
 
 # Attribute Type Definitions
 
-attribute ( 1.3.6.1.1.1.1.0 NAME 'uidNumber'
+attributetype ( 1.3.6.1.1.1.1.0 NAME 'uidNumber'
        DESC 'An integer uniquely identifying a user in an administrative domain'
        EQUALITY integerMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
 
-attribute ( 1.3.6.1.1.1.1.1 NAME 'gidNumber'
+attributetype ( 1.3.6.1.1.1.1.1 NAME 'gidNumber'
        DESC 'An integer uniquely identifying a group in an administrative domain'
        EQUALITY integerMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
 
-# TBC: caseIgnoreIA5SubstringsMatch is not defined
-
-attribute ( 1.3.6.1.1.1.1.2 NAME 'gecos'
+attributetype ( 1.3.6.1.1.1.1.2 NAME 'gecos'
        DESC 'The GECOS field; the common name'
        EQUALITY caseIgnoreIA5Match
+       SUBSTRINGS caseIgnoreIA5SubstringsMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
 
-attribute ( 1.3.6.1.1.1.1.3 NAME 'homeDirectory'
+attributetype ( 1.3.6.1.1.1.1.3 NAME 'homeDirectory'
        DESC 'The absolute path to the home directory'
        EQUALITY caseExactIA5Match
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
 
-attribute ( 1.3.6.1.1.1.1.4 NAME 'loginShell'
+attributetype ( 1.3.6.1.1.1.1.4 NAME 'loginShell'
        DESC 'The path to the login shell'
        EQUALITY caseExactIA5Match
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
 
-attribute ( 1.3.6.1.1.1.1.5 NAME 'shadowLastChange'
+attributetype ( 1.3.6.1.1.1.1.5 NAME 'shadowLastChange'
        EQUALITY integerMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
 
-attribute ( 1.3.6.1.1.1.1.6 NAME 'shadowMin'
+attributetype ( 1.3.6.1.1.1.1.6 NAME 'shadowMin'
        EQUALITY integerMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
 
-attribute ( 1.3.6.1.1.1.1.7 NAME 'shadowMax'
+attributetype ( 1.3.6.1.1.1.1.7 NAME 'shadowMax'
        EQUALITY integerMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
 
-attribute ( 1.3.6.1.1.1.1.8 NAME 'shadowWarning'
+attributetype ( 1.3.6.1.1.1.1.8 NAME 'shadowWarning'
        EQUALITY integerMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
 
-attribute ( 1.3.6.1.1.1.1.9 NAME 'shadowInactive'
+attributetype ( 1.3.6.1.1.1.1.9 NAME 'shadowInactive'
        EQUALITY integerMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
 
-attribute ( 1.3.6.1.1.1.1.10 NAME 'shadowExpire'
+attributetype ( 1.3.6.1.1.1.1.10 NAME 'shadowExpire'
        EQUALITY integerMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
 
-attribute ( 1.3.6.1.1.1.1.11 NAME 'shadowFlag'
+attributetype ( 1.3.6.1.1.1.1.11 NAME 'shadowFlag'
        EQUALITY integerMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
 
-# TBC: caseIgnoreIA5SubstringsMatch is not defined
-
-attribute ( 1.3.6.1.1.1.1.12 NAME 'memberUid'
+attributetype ( 1.3.6.1.1.1.1.12 NAME 'memberUid'
        EQUALITY caseExactIA5Match
+       SUBSTRINGS caseExactIA5SubstringsMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
 
-# TBC: caseIgnoreIA5SubstringsMatch is not defined
-
-attribute ( 1.3.6.1.1.1.1.13 NAME 'memberNisNetgroup'
+attributetype ( 1.3.6.1.1.1.1.13 NAME 'memberNisNetgroup'
        EQUALITY caseExactIA5Match
+       SUBSTRINGS caseExactIA5SubstringsMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
 
-attribute ( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple'
+attributetype ( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple'
        DESC 'Netgroup triple'
        SYNTAX 1.3.6.1.1.1.0.0 )
 
-attribute ( 1.3.6.1.1.1.1.15 NAME 'ipServicePort'
+attributetype ( 1.3.6.1.1.1.1.15 NAME 'ipServicePort'
        EQUALITY integerMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
 
-attribute ( 1.3.6.1.1.1.1.16 NAME 'ipServiceProtocol'
+attributetype ( 1.3.6.1.1.1.1.16 NAME 'ipServiceProtocol'
        SUP name )
 
-attribute ( 1.3.6.1.1.1.1.17 NAME 'ipProtocolNumber'
+attributetype ( 1.3.6.1.1.1.1.17 NAME 'ipProtocolNumber'
        EQUALITY integerMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
 
-attribute ( 1.3.6.1.1.1.1.18 NAME 'oncRpcNumber'
+attributetype ( 1.3.6.1.1.1.1.18 NAME 'oncRpcNumber'
        EQUALITY integerMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
 
-attribute ( 1.3.6.1.1.1.1.19 NAME 'ipHostNumber'
+attributetype ( 1.3.6.1.1.1.1.19 NAME 'ipHostNumber'
        DESC 'IP address as a dotted decimal, eg. 192.168.1.1, omitting leading zeros'
        EQUALITY caseIgnoreIA5Match
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
 
-attribute ( 1.3.6.1.1.1.1.20 NAME 'ipNetworkNumber'
+attributetype ( 1.3.6.1.1.1.1.20 NAME 'ipNetworkNumber'
        DESC 'IP network as a dotted decimal, eg. 192.168, omitting leading zeros'
        EQUALITY caseIgnoreIA5Match
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} SINGLE-VALUE )
 
-attribute ( 1.3.6.1.1.1.1.21 NAME 'ipNetmaskNumber'
+attributetype ( 1.3.6.1.1.1.1.21 NAME 'ipNetmaskNumber'
        DESC 'IP netmask as a dotted decimal, eg. 255.255.255.0, omitting leading zeros'
        EQUALITY caseIgnoreIA5Match
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} SINGLE-VALUE )
 
-attribute ( 1.3.6.1.1.1.1.22 NAME 'macAddress'
+attributetype ( 1.3.6.1.1.1.1.22 NAME 'macAddress'
        DESC 'MAC address in maximal, colon separated hex notation, eg. 00:00:92:90:ee:e2'
        EQUALITY caseIgnoreIA5Match
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
 
-attribute ( 1.3.6.1.1.1.1.23 NAME 'bootParameter'
+attributetype ( 1.3.6.1.1.1.1.23 NAME 'bootParameter'
        DESC 'rpc.bootparamd parameter'
        SYNTAX 1.3.6.1.1.1.0.1 )
 
-attribute ( 1.3.6.1.1.1.1.24 NAME 'bootFile'
+attributetype ( 1.3.6.1.1.1.1.24 NAME 'bootFile'
        DESC 'Boot image name'
        EQUALITY caseExactIA5Match
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
 
-attribute ( 1.3.6.1.1.1.1.26 NAME 'nisMapName'
+attributetype ( 1.3.6.1.1.1.1.26 NAME 'nisMapName'
        SUP name )
 
-# TBC: caseIgnoreIA5SubstringsMatch is not defined
-
-attribute ( 1.3.6.1.1.1.1.27 NAME 'nisMapEntry'
+attributetype ( 1.3.6.1.1.1.1.27 NAME 'nisMapEntry'
        EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{1024} SINGLE-VALUE )
 
 # Object Class Definitions
@@ -158,8 +154,6 @@ objectclass ( 1.3.6.1.1.1.2.2 NAME 'posixGroup' SUP top STRUCTURAL
        MUST ( cn $ gidNumber )
        MAY ( userPassword $ memberUid $ description ) )
 
-# TBC: quotes in quoted strings
-
 objectclass ( 1.3.6.1.1.1.2.3 NAME 'ipService' SUP top STRUCTURAL
        DESC 'Abstraction an Internet Protocol service.
              Maps an IP port and protocol (such as tcp or udp)
@@ -169,8 +163,6 @@ objectclass ( 1.3.6.1.1.1.2.3 NAME 'ipService' SUP top STRUCTURAL
        MUST ( cn $ ipServicePort $ ipServiceProtocol )
        MAY ( description ) )
 
-# TBC: quotes in quoted strings
-
 objectclass ( 1.3.6.1.1.1.2.4 NAME 'ipProtocol' SUP top STRUCTURAL
        DESC 'Abstraction of an IP protocol. Maps a protocol number
              to one or more names. The distinguished value of the cn
@@ -178,8 +170,6 @@ objectclass ( 1.3.6.1.1.1.2.4 NAME 'ipProtocol' SUP top STRUCTURAL
        MUST ( cn $ ipProtocolNumber $ description )
        MAY description )
 
-# TBC: quotes in quoted strings
-
 objectclass ( 1.3.6.1.1.1.2.5 NAME 'oncRpc' SUP top STRUCTURAL
        DESC 'Abstraction of an Open Network Computing (ONC)
              [RFC1057] Remote Procedure Call (RPC) binding.
@@ -189,8 +179,6 @@ objectclass ( 1.3.6.1.1.1.2.5 NAME 'oncRpc' SUP top STRUCTURAL
        MUST ( cn $ oncRpcNumber $ description )
        MAY description )
 
-# TBC: quotes in quoted strings
-
 objectclass ( 1.3.6.1.1.1.2.6 NAME 'ipHost' SUP top AUXILIARY
        DESC 'Abstraction of a host, an IP device. The distinguished
              value of the cn attribute denotes the host"s canonical
@@ -198,8 +186,6 @@ objectclass ( 1.3.6.1.1.1.2.6 NAME 'ipHost' SUP top AUXILIARY
        MUST ( cn $ ipHostNumber )
        MAY ( l $ description $ manager ) )
 
-# TBC: quotes in quoted strings
-
 objectclass ( 1.3.6.1.1.1.2.7 NAME 'ipNetwork' SUP top STRUCTURAL
        DESC 'Abstraction of a network. The distinguished value of
              the cn attribute denotes the network"s canonical name'
diff --git a/servers/slapd/schema/openldap.schema b/servers/slapd/schema/openldap.schema
new file mode 100644 (file)
index 0000000..5b5da8f
--- /dev/null
@@ -0,0 +1,25 @@
+# $OpenLDAP$
+#
+# OpenLDAP Project's directory schema items
+#
+# depends upon:
+#      core.schema
+#      cosine.schema
+#      inetorgperson.schema
+#
+
+objectClass: ( 1.3.6.1.4.1.4203.666.3.3 NAME 'OpenLDAPorg'
+       DESC 'OpenLDAP Organizational Object'
+       SUP pilotOrganization 
+       MAY ( authPassword $ displayName $ labeledURI ) )
+
+objectClass: ( 1.3.6.1.4.1.4203.666.3.4 NAME 'OpenLDAPperson'
+       DESC 'OpenLDAP Person'
+       SUP ( pilotPerson inetOrgPerson ) 
+       MUST ( uid $ cn )
+       MAY ( authPassword $ givenName $ labeledURI $ o $ ou ) )
+
+objectClass: ( 1.3.6.1.4.1.4203.666.3.5 NAME 'displayableObject'
+       DESC 'A Displayable Object'
+       MAY displayName AUXILIARY )
+
diff --git a/servers/slapd/schema/others_nis.at.conf b/servers/slapd/schema/others_nis.at.conf
deleted file mode 100644 (file)
index 1c6d91e..0000000
+++ /dev/null
@@ -1,283 +0,0 @@
-# $OpenLDAP$
-#
-# By:          Juan C. Gomez / gomez@engr.sgi.com
-# Date:                May/1999
-# Source:      RFC-2307
-# ------------------------------------------------------------
-# Attribute definitions for using LDAP as a back-end for Network
-# Information Services (NIS) with an OpenLDAP server. 
-# This file holds the definitions of those attributes used in 
-# RFC-2307, which are defined in other RFCs or X500 standards. 
-# You may not need to include this file if you already have 
-# these definitions in your default configuration files (i.e. 
-# slapd.at.conf).
-#
-
-
-
-#
-# ----------------------FORMAL DESCRIPTION--------------------
-#
-# RFC-2256     ( 2.5.4.23 NAME 'facsimileTelephoneNumber'
-#              SYNTAX 1.3.6.1.4.1.1466.115.121.1.22 )
-# RFC-1274     facsimileTelephoneNumber ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX FacsimileTelephoneNumber
-#              ::= {attributeType 23}
-#
-#
-# RFC-2256     ( 2.5.4.14 NAME 'searchGuide'
-#              SYNTAX 1.3.6.1.4.1.1466.115.121.1.25 )
-# RFC-1274     searchGuide ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX Guide
-#              ::= {attributeType 14}
-#
-#
-# RFC-2256     ( 2.5.4.15 NAME 'businessCategory' EQUALITY caseIgnoreMatch
-#              SUBSTR caseIgnoreSubstringsMatch
-#              SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
-# RFC-1274     businessCategory ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX caseIgnoreStringSyntax
-#              (SIZE (1..ub-business-category))
-#              ::= {attributeType 15}
-#
-#  
-# RFC-2256     ( 2.5.4.24 NAME 'x121Address' EQUALITY numericStringMatch
-#              SUBSTR numericStringSubstringsMatch
-#              SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{15} )
-# RFC-1274     x121Address ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX NumericString
-#              (SIZE (1..ub-x121-address))
-#              ::= {attributeType 24}
-#
-# 
-# RFC-2256     ( 2.5.4.26 NAME 'registeredAddress' SUP postalAddress
-#              SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )
-# RFC-1274     registeredAddress ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX PostalAddress
-#              ::= {attributeType 26}
-#
-#
-# RFC-2256     ( 2.5.4.27 NAME 'destinationIndicator' EQUALITY caseIgnoreMatch
-#              SUBSTR caseIgnoreSubstringsMatch
-#              SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{128} )
-# RFC-1274     destinationIndicator ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX PrintableString
-#              (SIZE (1..ub-destination-indicator))
-#              MATCHES FOR EQUALITY SUBSTRINGS
-#              ::= {attributeType 27}
-#
-# 
-# RFC-2256     ( 2.5.4.28 NAME 'preferredDeliveryMethod'
-#              SYNTAX 1.3.6.1.4.1.1466.115.121.1.14
-#              SINGLE-VALUE )
-# RFC-1274     preferredDeliveryMethod ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX deliveryMethod
-#              ::= {attributeType 28}
-#
-# 
-# RFC-2256     ( 2.5.4.21 NAME 'telexNumber'
-#              SYNTAX 1.3.6.1.4.1.1466.115.121.1.52 )
-# RFC-1274     telexNumber ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX TelexNumber
-#              (SIZE (1..ub-telex))
-#              ::= {attributeType 21}
-#
-#
-# RFC-2256     ( 2.5.4.22 NAME 'teletexTerminalIdentifier'
-#              SYNTAX 1.3.6.1.4.1.1466.115.121.1.51 )
-# RFC-1274     teletexTerminalIdentifier ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX TeletexTerminalIdentifier
-#              (SIZE (1..ub-teletex-terminal-id))
-#              ::= {attributeType 22}
-#
-#
-# RFC-2256     ( 2.5.4.20 NAME 'telephoneNumber' EQUALITY telephoneNumberMatch
-#              SUBSTR telephoneNumberSubstringsMatch
-#              SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{32} )
-# RFC-1274      telephoneNumber ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX telephoneNumberSyntax
-#              (SIZE (1..ub-telephone-number))
-#
-# 
-# RFC-2256     ( 2.5.4.25 NAME 'internationaliSDNNumber' 
-#              EQUALITY numericStringMatch
-#              SUBSTR numericStringSubstringsMatch
-#              SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{16} )
-# RFC-1274      internationaliSDNNumber ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX NumericString
-#              (SIZE (1..ub-isdn-address))
-#              ::= {attributeType 2
-#
-#
-# RFC-2256     ( 2.5.4.9 NAME 'street' EQUALITY caseIgnoreMatch
-#              SUBSTR caseIgnoreSubstringsMatch
-#              SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
-# RFC-1274     streetAddress ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX caseIgnoreStringSyntax
-#              (SIZE (1..ub-street-address))
-#              ::= {attributeType 9}
-#
-# 
-#  RFC-2256    ( 2.5.4.18 NAME 'postOfficeBox' EQUALITY caseIgnoreMatch
-#              SUBSTR caseIgnoreSubstringsMatch
-#              SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{40} )
-#  RFC-1274     postOfficeBox ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX caseIgnoreStringSyntax
-#              (SIZE (1..ub-post-office-box))
-#              ::= {attributeType 18}
-# 
-#
-#  RFC-2256    ( 2.5.4.17 NAME 'postalCode' EQUALITY caseIgnoreMatch
-#              SUBSTR caseIgnoreSubstringsMatch
-#              SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{40} )
-#  RFC-1274    postalCode ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX caseIgnoreStringSyntax
-#              (SIZE (1..ub-postal-code))
-#              ::= {attributeType 17}
-#
-#
-#  RFC-2256    ( 2.5.4.16 NAME 'postalAddress' EQUALITY caseIgnoreListMatch
-#              SUBSTR caseIgnoreListSubstringsMatch
-#              SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )
-#  RFC-1274     postalAddress ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX PostalAddress
-#              MATCHES FOR EQUALITY
-#              ::= {attributeType 16}
-#
-#
-#  RFC-2256    ( 2.5.4.19 NAME 'physicalDeliveryOfficeName'
-#              EQUALITY caseIgnoreMatch
-#              SUBSTR caseIgnoreSubstringsMatch
-#              SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
-#  RFC-1274     physicalDeliveryOfficeName ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX caseIgnoreStringSyntax
-#              (SIZE (1..ub-physical-office-name))
-#              ::= {attributeType 19}
-#
-#
-#  RFC-2256    ( 2.5.4.8 NAME 'st' SUP name )
-#  RFC-1274    stateOrProvinceName ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX caseIgnoreStringSyntax
-#              (SIZE (1..ub-state-name))
-#              ::= {attributeType 8}
-#
-#
-#  RFC-2256    ( 2.5.4.0 NAME 'objectClass' EQUALITY objectIdentifierMatch
-#                SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )
-#  RFC-1274    objectClass ObjectClass
-#              ::= {attributeType 0}
-#
-#
-#  RFC-2256 ( 2.5.4.3 NAME 'cn' SUP name )
-#  RFC-1274    commonName ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX caseIgnoreStringSyntax
-#              (SIZE (1..ub-common-name))
-#              ::= {attributeType 3}
-#
-#
-# RFC-1274     userid ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX
-#              caseIgnoreStringSyntax
-#              (SIZE (1 .. ub-user-identifier))
-#              ::= {pilotAttributeType 1}
-#
-#
-#  RFC-2256    ( 2.5.4.35 NAME 'userPassword' EQUALITY octetStringMatch
-#              SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} )
-#  RFC-1274    userPassword ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX Userpassword
-#              ::= {attributeType 35}
-#
-#
-#  RFC-2256    ( 2.5.4.13 NAME 'description' EQUALITY caseIgnoreMatch
-#              SUBSTR caseIgnoreSubstringsMatch
-#              SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024} )
-#
-#
-#  RFC-2256    ( 2.5.4.7 NAME 'l' SUP name )
-#
-#
-#  RFC-1274    manager ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX
-#              distinguishedNameSyntax
-#              ::= {pilotAttributeType 10}
-#
-#
-#  RFC-2256    ( 2.5.4.5 NAME 'serialNumber' EQUALITY caseIgnoreMatch
-#              SUBSTR caseIgnoreSubstringsMatch
-#              SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{64} )
-#  RFC-1274    serialNumber ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX printableStringSyntax
-#              (SIZE (1..ub-serial-number))
-#              ::= {attributeType 5}
-#
-#
-#  RFC-2256    ( 2.5.4.10 NAME 'o' SUP name )
-#
-#
-#  RFC-2256    ( 2.5.4.11 NAME 'ou' SUP name )
-#
-#
-#  RFC-2256    ( 2.5.4.6 NAME 'c' SUP name SINGLE-VALUE )
-#  RFC-1274    countryName ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX PrintableString
-#              (SIZE (1..ub-country-code))
-#              SINGLE VALUE
-#              ::= {attributeType 6}
-#
-#
-#  RFC-2256    ( 2.5.4.34 NAME 'seeAlso' SUP distinguishedName )
-#  RFC-1274    seeAlso ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX distinguishedNameSyntax
-#              ::= {attributeType 34}
-#
-#
-#  RFC-1274     host ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX
-#              caseIgnoreStringSyntax
-#              (SIZE (1 .. ub-host))
-#              ::= {pilotAttributeType 9}
-#
-#
-#  RFC-2256    ( 2.5.4.32 NAME 'owner' SUP distinguishedName )
-#  RFC-1274    owner ATTRIBUTE
-#              WITH ATTRIBUTE-SYNTAX distinguishedNameSyntax
-#              ::= {attributeType 32}
-#
-# ----------------------END FORMAL DESCRIPTION-------------
-#
-
-
-
-
-attribute      facsimileTelephoneNumber        fax     tel
-attribute      searchGuide                             cis
-attribute      businessCategory                        cis
-attribute      x121Address                             cis
-attribute      registeredAddress                       cis
-attribute      destinationIndicator                    cis
-attribute      preferredDeliveryMethod                 cis
-attribute      telexNumber                             cis
-attribute      teletexTerminalIdentifier               cis
-attribute      telephoneNumber                         tel
-attribute      internationaliSDNNumber                 ces
-attribute      street                                  cis
-attribute      postOfficeBox                           cis
-attribute      postalCode                              cis
-attribute      postalAddress                           cis
-attribute      physicalDeliveryOfficeName              cis
-attribute      st                                      cis
-attribute      objectClass                             cis
-attribute      cn      commonName                      cis
-attribute      uid     userid                          cis
-attribute      userPassword                            ces
-attribute      description                             cis
-attribute      l       localityName                    cis
-attribute      manager                                 dn
-attribute      serialNumber                            cis
-attribute      o       organizationName                cis
-attribute      ou      organizationalUnitName          cis
-attribute      c       countryName                     cis
-attribute      seeAlso                                 dn
-attribute      host                                    cis
-attribute      owner                                   dn
diff --git a/servers/slapd/schema/others_nis.oc.conf b/servers/slapd/schema/others_nis.oc.conf
deleted file mode 100644 (file)
index ad3833e..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-# $OpenLDAP$
-#
-# By:          Juan C. Gomez
-# Date:                05/04/1999
-# Source:      RFC-2307
-# ------------------------------------------------------------
-# Object class definitions for using LDAP as a back-end for Network
-# Information Services (NIS) with an OpenLDAP server. 
-# This file holds the definitions of those attributes used in 
-# RFC-2307, which are defined in other RFCs or X500 standards. 
-# You may not need to include this file if you already have these 
-# definitions in your default configuration files (i.e. 
-# slapd.oc.conf).
-#
-
-
-
-
-#
-# ----------------------FORMAL DESCRIPTION--------------------
-#
-# RFC-2256     ( 2.5.6.0 NAME 'top' ABSTRACT MUST objectClass )
-# RFC-1274     top OBJECT-CLASS
-#              MUST CONTAIN {
-#              objectClass}
-#              ::= {objectClass 0}
-#
-#
-# RFC-2256     ( 2.5.6.4 NAME 'organization' SUP top STRUCTURAL MUST o
-#              MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $
-#              x121Address $ registeredAddress $ destinationIndicator $
-#              preferredDeliveryMethod $ telexNumber $ 
-#              teletexTerminalIdentifier $ telephoneNumber $
-#              internationaliSDNNumber $ facsimileTelephoneNumber $
-#              street $ postOfficeBox $ postalCode $ postalAddress $
-#              physicalDeliveryOfficeName $ st $ l $ description ) )
-# RFC-1274     organization OBJECT-CLASS
-#              SUBCLASS OF top
-#              MUST CONTAIN {
-#              organizationName}
-#              MAY CONTAIN {
-#              organizationalAttributeSet}
-#              ::= {objectClass 4}
-#  
-#
-# RFC-1274     account OBJECT-CLASS
-#              SUBCLASS OF top
-#              MUST CONTAIN {
-#              userid}
-#              MAY CONTAIN {
-#              description,
-#              seeAlso,
-#              localityName,
-#               organizationName,
-#               organizationalUnitName,
-#               host}
-#               ::= {pilotObjectClass 5}
-#
-#
-# RFC-2256     ( 2.5.6.14 NAME 'device' SUP top STRUCTURAL MUST cn
-#               MAY ( serialNumber $ seeAlso $ owner $ ou $ o $ l $
-#               description ) )
-# RFC-1274     device OBJECT-CLASS
-#              SUBCLASS OF top
-#              MUST CONTAIN {
-#               commonName}
-#               MAY CONTAIN {
-#               description,
-#              localityName,
-#               organizationName,
-#               organizationalUnitName,
-#               owner,
-#               seeAlso,
-#               serialNumber}
-#               ::= {objectClass 14}
-#
-# ----------------------END FORMAL DESCRIPTION-------------
-#
-
-
-
-
-objectclass    top
-       requires
-               objectClass
-
-objectclass    organization
-       requires
-               objectClass,
-               o
-       allows
-               userPassword,
-               searchGuide,
-               seeAlso,
-               businessCategory,
-               x121Address,
-               registeredAddress,
-               destinationIndicator,
-               preferredDeliveryMethod,
-               telexNumber,
-               teletexTerminalIdentifier,
-               telephoneNumber,
-               internationaliSDNNumber,
-               facsimileTelephoneNumber,
-               street,
-               postOfficeBox,
-               postalCode,
-               postalAddress,
-               physicalDeliveryOfficeName,
-               st,
-               l,
-               description
-
-objectclass    account
-       requires
-               objectClass,
-               uid
-       allows
-               description,
-               seeAlso,
-               l,
-               o,
-               ou,
-               host
-
-objectclass    device
-       requires
-               objectClass,
-               cn      
-       allows
-               description,
-               l,
-               o,
-                ou,
-                owner,
-                seeAlso,
-                serialNumber
index 2a205798b246b2c1d31aa666e785497d1193c548..05e9552af780098983cf6ab8fbad457c0248ade4 100644 (file)
@@ -11,7 +11,7 @@
 # seems that Netscape does not know either.  Searches on Altavista
 # have not shed any light, so we will have to ask for help.
 
-# This file uses definitions from slapd.std.schema
+# This file uses definitions from core.schema
 
 # ccitt.data.pss.ucl.pilot ( 0.9.2342.19200300.100 )
 #      1 pilotAttributeType
 
 # Believe it or not, this is case-insensitive
 
-attribute ( 0.9.2342.19200300.100.1.1 NAME ( 'uid' 'userid' )
+attributetype ( 0.9.2342.19200300.100.1.2 NAME 'textEncodedORAddress'
        EQUALITY caseIgnoreMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( 0.9.2342.19200300.100.1.2 NAME 'textEncodedORAddress'
-       EQUALITY caseIgnoreMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attribute ( 0.9.2342.19200300.100.1.3 NAME ( 'mail' 'rfc822Mailbox' )
+attributetype ( 0.9.2342.19200300.100.1.3 NAME ( 'mail' 'rfc822Mailbox' )
        EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
 
-attribute ( 0.9.2342.19200300.100.1.4 NAME 'info' EQUALITY caseIgnoreMatch
+attributetype ( 0.9.2342.19200300.100.1.4 NAME 'info' EQUALITY caseIgnoreMatch
         SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( 0.9.2342.19200300.100.1.5 NAME ( 'drink' 'favouriteDrink' )
+attributetype ( 0.9.2342.19200300.100.1.5 NAME ( 'drink' 'favouriteDrink' )
        EQUALITY caseIgnoreMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( 0.9.2342.19200300.100.1.6 NAME 'roomNumber'
+attributetype ( 0.9.2342.19200300.100.1.6 NAME 'roomNumber'
        EQUALITY caseIgnoreMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( 0.9.2342.19200300.100.1.7 NAME 'photo'
+attributetype ( 0.9.2342.19200300.100.1.7 NAME 'photo'
         SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 )
 
-attribute ( 0.9.2342.19200300.100.1.8 NAME 'userClass'
+attributetype ( 0.9.2342.19200300.100.1.8 NAME 'userClass'
        EQUALITY caseIgnoreMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( 0.9.2342.19200300.100.1.9 NAME 'host'
+attributetype ( 0.9.2342.19200300.100.1.9 NAME 'host'
        EQUALITY caseIgnoreMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( 0.9.2342.19200300.100.1.10 NAME 'manager'
+attributetype ( 0.9.2342.19200300.100.1.10 NAME 'manager'
        EQUALITY distinguishedNameMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
 
-attribute ( 0.9.2342.19200300.100.1.11 NAME 'documentIdentifier'
+attributetype ( 0.9.2342.19200300.100.1.11 NAME 'documentIdentifier'
        EQUALITY caseIgnoreMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( 0.9.2342.19200300.100.1.12 NAME 'documentTitle'
+attributetype ( 0.9.2342.19200300.100.1.12 NAME 'documentTitle'
        EQUALITY caseIgnoreMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( 0.9.2342.19200300.100.1.13 NAME 'documentVersion'
+attributetype ( 0.9.2342.19200300.100.1.13 NAME 'documentVersion'
        EQUALITY caseIgnoreMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( 0.9.2342.19200300.100.1.14 NAME 'documentAuthor'
+attributetype ( 0.9.2342.19200300.100.1.14 NAME 'documentAuthor'
        EQUALITY distinguishedNameMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
 
-attribute ( 0.9.2342.19200300.100.1.15 NAME 'documentLocation'
+attributetype ( 0.9.2342.19200300.100.1.15 NAME 'documentLocation'
        EQUALITY caseIgnoreMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( 0.9.2342.19200300.100.1.20 NAME ( 'homeTelephoneNumber' 'homePhone' )
+attributetype ( 0.9.2342.19200300.100.1.20 NAME ( 'homeTelephoneNumber' 'homePhone' )
        EQUALITY telephoneNumberMatch
        SUBSTR telephoneNumberSubstringsMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )
 
-attribute ( 0.9.2342.19200300.100.1.21 NAME 'secretary'
+attributetype ( 0.9.2342.19200300.100.1.21 NAME 'secretary'
        EQUALITY distinguishedNameMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
 
 # Netscape defines this with syntax 1.15 TBC
 
-attribute ( 0.9.2342.19200300.100.1.22 NAME 'otherMailbox'
+attributetype ( 0.9.2342.19200300.100.1.22 NAME 'otherMailbox'
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.39 )
 
 # Netscape defines this with syntax 1.15 TBC
 # Mathcing rules for this are unknown
 
-attribute ( 0.9.2342.19200300.100.1.23 NAME 'lastModifiedTime'
+attributetype ( 0.9.2342.19200300.100.1.23 NAME 'lastModifiedTime'
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.53 )
 
-attribute ( 0.9.2342.19200300.100.1.24 NAME 'lastModifiedBy'
+attributetype ( 0.9.2342.19200300.100.1.24 NAME 'lastModifiedBy'
        EQUALITY distinguishedNameMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
 
 # This is the definition as defined in RFC2247
 # Terrific, we don't know about caseIgnoreIA5SubstringsMatch
 
-#attribute ( 0.9.2342.19200300.100.1.25 NAME 'dc'
+# See RFC2247 define in core.schema
+#attributetype ( 0.9.2342.19200300.100.1.25 NAME 'dc'
 #      EQUALITY caseIgnoreIA5Match
-#      SUBSTR caseIgnoreIA5SubstringsMatch
 #      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attribute ( 0.9.2342.19200300.100.1.25 NAME 'dc'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
 
 # This is aRecord in RFC1274.  However, objectclass dNSDomain as we
 # and Netscape use it is very different.
 
-attribute ( 0.9.2342.19200300.100.1.26 NAME 'dNSRecord'
+attributetype ( 0.9.2342.19200300.100.1.26 NAME 'dNSRecord'
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
 # 0.9.2342.19200300.100.1.27 was probably intended to be mDRecord in
@@ -129,16 +122,12 @@ attribute ( 0.9.2342.19200300.100.1.26 NAME 'dNSRecord'
 # 0.9.2342.19200300.100.1.30 was sOARecord in RFC1274
 # 0.9.2342.19200300.100.1.31 was cNAMERecord in RFC1274
 
-# Terrific, we don't know about caseIgnoreIA5SubstringsMatch
 #attribute ( 0.9.2342.19200300.100.1.37 NAME 'associatedDomain'
 #      EQUALITY caseIgnoreIA5Match
 #      SUBSTR caseIgnoreIA5SubstringsMatch
 #      SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-attribute ( 0.9.2342.19200300.100.1.37 NAME 'associatedDomain'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( 0.9.2342.19200300.100.1.38 NAME 'associatedName'
+attributetype ( 0.9.2342.19200300.100.1.38 NAME 'associatedName'
        EQUALITY distinguishedNameMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
 
@@ -146,37 +135,37 @@ attribute ( 0.9.2342.19200300.100.1.38 NAME 'associatedName'
 # We take the matching rules from postalAddress in RFC2256
 # Show stopper: we don't have the definition of caseIgnoreListSubstringsMatch
 
-attribute ( 0.9.2342.19200300.100.1.39 NAME 'homePostalAddress'
+attributetype ( 0.9.2342.19200300.100.1.39 NAME 'homePostalAddress'
        EQUALITY caseIgnoreListMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )
 
-attribute ( 0.9.2342.19200300.100.1.40 NAME 'personalTitle'
+attributetype ( 0.9.2342.19200300.100.1.40 NAME 'personalTitle'
        EQUALITY caseIgnoreMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( 0.9.2342.19200300.100.1.41 NAME ( 'mobileTelephoneNumber' 'mobile' )
+attributetype ( 0.9.2342.19200300.100.1.41 NAME ( 'mobileTelephoneNumber' 'mobile' )
        EQUALITY telephoneNumberMatch
        SUBSTR telephoneNumberSubstringsMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )
 
-attribute ( 0.9.2342.19200300.100.1.42 NAME ( 'pagerTelephoneNumber' 'pager' )
+attributetype ( 0.9.2342.19200300.100.1.42 NAME ( 'pagerTelephoneNumber' 'pager' )
        EQUALITY telephoneNumberMatch
        SUBSTR telephoneNumberSubstringsMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )
 
-attribute ( 0.9.2342.19200300.100.1.43 NAME ( 'co' 'friendlyCountryName' )
+attributetype ( 0.9.2342.19200300.100.1.43 NAME ( 'co' 'friendlyCountryName' )
        EQUALITY caseIgnoreMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( 0.9.2342.19200300.100.1.44 NAME 'uniqueIdentifier'
+attributetype ( 0.9.2342.19200300.100.1.44 NAME 'uniqueIdentifier'
        EQUALITY caseIgnoreMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( 0.9.2342.19200300.100.1.45 NAME 'organizationalStatus'
+attributetype ( 0.9.2342.19200300.100.1.45 NAME 'organizationalStatus'
        EQUALITY caseIgnoreMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( 0.9.2342.19200300.100.1.46 NAME 'janetMailbox'
+attributetype ( 0.9.2342.19200300.100.1.46 NAME 'janetMailbox'
        EQUALITY caseIgnoreIA5Match
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
@@ -184,10 +173,10 @@ attribute ( 0.9.2342.19200300.100.1.46 NAME 'janetMailbox'
 # in RFC2252 without explanation.  The SINGLE-VALUE thing comes from
 # Netscape and is not backed by RFC1274.
 
-attribute ( 0.9.2342.19200300.100.1.47 NAME 'mailPreferenceOption'
+attributetype ( 0.9.2342.19200300.100.1.47 NAME 'mailPreferenceOption'
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.32 SINGLE-VALUE )
 
-attribute ( 0.9.2342.19200300.100.1.48 NAME 'buildingName'
+attributetype ( 0.9.2342.19200300.100.1.48 NAME 'buildingName'
        EQUALITY caseIgnoreMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
 
@@ -200,61 +189,61 @@ attribute ( 0.9.2342.19200300.100.1.48 NAME 'buildingName'
 # about this but RFC2252 does not seem to list a specific syntax.
 # We had this as 'bin'
 
-attribute ( 0.9.2342.19200300.100.1.53 NAME 'personalSignature'
+attributetype ( 0.9.2342.19200300.100.1.53 NAME 'personalSignature'
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 )
 
-attribute ( 0.9.2342.19200300.100.1.54 NAME 'dITRedirect'
+attributetype ( 0.9.2342.19200300.100.1.54 NAME 'dITRedirect'
         EQUALITY distinguishedNameMatch
         SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
 
 # Netscape gives syntax 1.5 to this.  We had it as 'bin'.
 
-attribute ( 0.9.2342.19200300.100.1.55 NAME 'audio'
+attributetype ( 0.9.2342.19200300.100.1.55 NAME 'audio'
         SYNTAX 1.3.6.1.4.1.1466.115.121.1.4 )
 
-attribute ( 0.9.2342.19200300.100.1.56 NAME 'documentPublisher'
+attributetype ( 0.9.2342.19200300.100.1.56 NAME 'documentPublisher'
        EQUALITY caseIgnoreMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-# This one is ripped from Netscape and is a pilot object.  It is not
-# in RFC1274, but we had it as 'bin'.
-
-attribute ( 0.9.2342.19200300.100.1.60 NAME 'jpegPhoto'
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 )
+# From RFC 2798 (inetOrgPerson)
+attributetype ( 0.9.2342.19200300.100.1.60
+       NAME 'jpegPhoto'
+       DESC 'a JPEG image'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.28 )
 
 # These attributes are pilot-related attributes that we had and Netscape
 # has too, however, the OID is unknown for them and Netscape uses a
 # string in place of the missing OID.  We will do the same until we
 # can make head or tails of this.
 
-attribute ( abstract-oid NAME 'abstract'
+attributetype ( abstract-oid NAME 'abstract'
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( authorcn-oid NAME ( 'documentAuthorCommonName' 'authorCn' )
+attributetype ( authorcn-oid NAME ( 'documentAuthorCommonName' 'authorCn' )
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( authorsn-oid NAME ( 'documentAuthorSurname' 'authorSn' )
+attributetype ( authorsn-oid NAME ( 'documentAuthorSurname' 'authorSn' )
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( documentStore-oid NAME 'documentStore'
+attributetype ( documentStore-oid NAME 'documentStore'
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( keyWords-oid NAME 'keyWords'
+attributetype ( keyWords-oid NAME 'keyWords'
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( obsoletedByDocument-oid NAME 'obsoletedByDocument'
+attributetype ( obsoletedByDocument-oid NAME 'obsoletedByDocument'
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
 
-attribute ( obsoletesDocument-oid NAME 'obsoletesDocument'
+attributetype ( obsoletesDocument-oid NAME 'obsoletesDocument'
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
 
-attribute ( subject-oid NAME 'subject'
+attributetype ( subject-oid NAME 'subject'
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
 
-attribute ( updatedByDocument-oid NAME 'updatedByDocument'
+attributetype ( updatedByDocument-oid NAME 'updatedByDocument'
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
 
-attribute ( updatesDocument-oid NAME 'updatesDocument'
+attributetype ( updatesDocument-oid NAME 'updatesDocument'
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
 
 # In classes, STRUCTURAL or AUXILIARY is chosen depending on the
@@ -317,7 +306,6 @@ objectclass ( 0.9.2342.19200300.100.4.9 NAME 'documentSeries' SUP top
        l $ o $ ou ) )
 
 # This definition is much longer than that in RFC1274 and is taken from RFC2247
-
 objectclass ( 0.9.2342.19200300.100.4.13 NAME 'domain' SUP top STRUCTURAL
      MUST dc
      MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $
diff --git a/servers/slapd/schema_check.c b/servers/slapd/schema_check.c
new file mode 100644 (file)
index 0000000..0d54333
--- /dev/null
@@ -0,0 +1,203 @@
+/* schema_check.c - routines to enforce schema definitions */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/ctype.h>
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "ldap_pvt.h"
+
+static char *  oc_check_required(Entry *e, struct berval *ocname);
+
+/*
+ * entry_schema_check - check that entry e conforms to the schema required
+ * by its object class(es).
+ *
+ * returns 0 if so, non-zero otherwise.
+ */
+
+int
+entry_schema_check( 
+       Entry *e, Attribute *oldattrs, const char** text )
+{
+       Attribute       *a, *aoc;
+       ObjectClass *oc;
+       int             i;
+       int             ret;
+       AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass;
+       int extensible = 0;
+
+       if( !global_schemacheck ) return LDAP_SUCCESS;
+
+       /* find the object class attribute - could error out here */
+       if ( (aoc = attr_find( e->e_attrs, ad_objectClass )) == NULL ) {
+               Debug( LDAP_DEBUG_ANY, "No object class for entry (%s)\n",
+                   e->e_dn, 0, 0 );
+               *text = "no objectclass attribute";
+               return oldattrs != NULL
+                       ? LDAP_OBJECT_CLASS_VIOLATION
+                       : LDAP_NO_OBJECT_CLASS_MODS;
+       }
+
+       ret = LDAP_SUCCESS;
+
+       /* check that the entry has required attrs for each oc */
+       for ( i = 0; aoc->a_vals[i] != NULL; i++ ) {
+               if ( (oc = oc_find( aoc->a_vals[i]->bv_val )) == NULL ) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "entry_check_schema(%s): objectclass \"%s\" not defined\n",
+                               e->e_dn, aoc->a_vals[i]->bv_val, 0 );
+
+               } else {
+                       char *s = oc_check_required( e, aoc->a_vals[i] );
+
+                       if (s != NULL) {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "Entry (%s), oc \"%s\" requires attr \"%s\"\n",
+                                       e->e_dn, aoc->a_vals[i]->bv_val, s );
+                               *text = "missing required attribute";
+                               ret = LDAP_OBJECT_CLASS_VIOLATION;
+                               break;
+                       }
+
+                       if( oc == slap_schema.si_oc_extensibleObject )
+                       {
+                               extensible=1;
+                       }
+
+               }
+       }
+
+       if ( ret != LDAP_SUCCESS ) {
+           return ret;
+       }
+
+       if( extensible ) {
+               return LDAP_SUCCESS;
+       }
+
+       /* check that each attr in the entry is allowed by some oc */
+       for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
+               ret = oc_check_allowed( a->a_desc->ad_type, aoc->a_vals );
+               if ( ret != 0 ) {
+                       char *type = a->a_desc->ad_cname->bv_val;
+                       Debug( LDAP_DEBUG_ANY,
+                           "Entry (%s), attr \"%s\" not allowed\n",
+                           e->e_dn, type, 0 );
+                       *text = "attribute not allowed";
+                       break;
+               }
+       }
+
+       return( ret );
+}
+
+static char *
+oc_check_required( Entry *e, struct berval *ocname )
+{
+       ObjectClass     *oc;
+       AttributeType   *at;
+       int             i;
+       Attribute       *a;
+
+       Debug( LDAP_DEBUG_TRACE,
+              "oc_check_required entry (%s), objectclass \"%s\"\n",
+              e->e_dn, ocname->bv_val, 0 );
+
+       /* find global oc defn. it we don't know about it assume it's ok */
+       if ( (oc = oc_find( ocname->bv_val )) == NULL ) {
+               return NULL;
+       }
+
+       /* check for empty oc_required */
+       if(oc->soc_required == NULL) {
+               return NULL;
+       }
+
+       /* for each required attribute */
+       for ( i = 0; oc->soc_required[i] != NULL; i++ ) {
+               at = oc->soc_required[i];
+               /* see if it's in the entry */
+               for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
+                       if( a->a_desc->ad_type == at ) {
+                               break;
+                       }
+               }
+               /* not there => schema violation */
+               if ( a == NULL ) {
+                       return at->sat_cname;
+               }
+       }
+
+       return( NULL );
+}
+
+int oc_check_allowed(
+       AttributeType *at,
+       struct berval **ocl )
+{
+       ObjectClass     *oc;
+       int             i, j;
+
+       Debug( LDAP_DEBUG_TRACE,
+               "oc_check_allowed type \"%s\"\n",
+               at->sat_cname, 0, 0 );
+
+       /* always allow objectclass attribute */
+       if ( strcasecmp( at->sat_cname, "objectclass" ) == 0 ) {
+               return LDAP_SUCCESS;
+       }
+
+
+       /*
+        * All operational attributions are allowed by schema rules.
+        */
+       if( is_at_operational(at) ) {
+               return LDAP_SUCCESS;
+       }
+
+       /* check that the type appears as req or opt in at least one oc */
+       for ( i = 0; ocl[i] != NULL; i++ ) {
+               /* if we know about the oc */
+               if ( (oc = oc_find( ocl[i]->bv_val )) != NULL ) {
+                       /* does it require the type? */
+                       for ( j = 0; oc->soc_required != NULL && 
+                               oc->soc_required[j] != NULL; j++ )
+                       {
+                               if( at == oc->soc_required[j] ) {
+                                       return LDAP_SUCCESS;
+                               }
+                       }
+                       /* does it allow the type? */
+                       for ( j = 0; oc->soc_allowed != NULL && 
+                               oc->soc_allowed[j] != NULL; j++ )
+                       {
+                               if( at == oc->soc_allowed[j] ) {
+                                       return LDAP_SUCCESS;
+                               }
+                       }
+                       /* maybe the next oc allows it */
+
+#ifdef OC_UNDEFINED_IMPLES_EXTENSIBLE
+               /* we don't know about the oc. assume it allows it */
+               } else {
+                       if ( t != type )
+                               ldap_memfree( t );
+                       return LDAP_SUCCESS;
+#endif
+               }
+       }
+
+
+       /* not allowed by any oc */
+       return LDAP_OBJECT_CLASS_VIOLATION;
+}
diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c
new file mode 100644 (file)
index 0000000..96e3fdb
--- /dev/null
@@ -0,0 +1,1368 @@
+/* schema_init.c - init builtin schema */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/ctype.h>
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "ldap_pvt.h"
+#include "lutil_md5.h"
+
+static int
+octetStringMatch(
+       int *matchp,
+       unsigned use,
+       Syntax *syntax,
+       MatchingRule *mr,
+       struct berval *value,
+       void *assertedValue )
+{
+       int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
+
+       if( match == 0 ) {
+               match = memcmp( value->bv_val,
+                       ((struct berval *) assertedValue)->bv_val,
+                       value->bv_len );
+       }
+
+       *matchp = match;
+       return LDAP_SUCCESS;
+}
+
+/* Index generation function */
+int octetStringIndexer(
+       unsigned use,
+       Syntax *syntax,
+       MatchingRule *mr,
+       struct berval *prefix,
+       struct berval **values,
+       struct berval ***keysp )
+{
+       int i;
+       size_t slen, mlen;
+       struct berval **keys;
+       lutil_MD5_CTX   MD5context;
+       unsigned char   MD5digest[16];
+       struct berval digest;
+       digest.bv_val = MD5digest;
+       digest.bv_len = sizeof(MD5digest);
+
+       for( i=0; values[i] != NULL; i++ ) {
+               /* just count them */
+       }
+
+       assert( i > 0 );
+
+       keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
+
+       slen = strlen( syntax->ssyn_oid );
+       mlen = strlen( mr->smr_oid );
+
+       for( i=0; values[i] != NULL; i++ ) {
+               lutil_MD5Init( &MD5context );
+               if( prefix != NULL && prefix->bv_len > 0 ) {
+                       lutil_MD5Update( &MD5context,
+                               prefix->bv_val, prefix->bv_len );
+               }
+               lutil_MD5Update( &MD5context,
+                       syntax->ssyn_oid, slen );
+               lutil_MD5Update( &MD5context,
+                       mr->smr_oid, mlen );
+               lutil_MD5Update( &MD5context,
+                       values[i]->bv_val, values[i]->bv_len );
+               lutil_MD5Final( MD5digest, &MD5context );
+
+               keys[i] = ber_bvdup( &digest );
+       }
+
+       keys[i] = NULL;
+
+       *keysp = keys;
+
+       return LDAP_SUCCESS;
+}
+
+/* Index generation function */
+int octetStringFilter(
+       unsigned use,
+       Syntax *syntax,
+       MatchingRule *mr,
+       struct berval *prefix,
+       void * assertValue,
+       struct berval ***keysp )
+{
+       size_t slen, mlen;
+       struct berval **keys;
+       lutil_MD5_CTX   MD5context;
+       unsigned char   MD5digest[LUTIL_MD5_BYTES];
+       struct berval *value = (struct berval *) assertValue;
+       struct berval digest;
+       digest.bv_val = MD5digest;
+       digest.bv_len = sizeof(MD5digest);
+
+       slen = strlen( syntax->ssyn_oid );
+       mlen = strlen( mr->smr_oid );
+
+       keys = ch_malloc( sizeof( struct berval * ) * 2 );
+
+       lutil_MD5Init( &MD5context );
+       if( prefix != NULL && prefix->bv_len > 0 ) {
+               lutil_MD5Update( &MD5context,
+                       prefix->bv_val, prefix->bv_len );
+       }
+       lutil_MD5Update( &MD5context,
+               syntax->ssyn_oid, slen );
+       lutil_MD5Update( &MD5context,
+               mr->smr_oid, mlen );
+       lutil_MD5Update( &MD5context,
+               value->bv_val, value->bv_len );
+       lutil_MD5Final( MD5digest, &MD5context );
+
+       keys[0] = ber_bvdup( &digest );
+       keys[1] = NULL;
+
+       *keysp = keys;
+
+       return LDAP_SUCCESS;
+}
+
+static int
+dnValidate(
+       Syntax *syntax,
+       struct berval *in )
+{
+       int rc;
+       char *dn;
+
+       if( in->bv_len == 0 ) return LDAP_SUCCESS;
+
+       dn = ch_strdup( in->bv_val );
+
+       rc = dn_validate( dn ) == NULL
+               ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
+
+       ch_free( dn );
+       return rc;
+}
+
+static int
+dnNormalize(
+       Syntax *syntax,
+       struct berval *val,
+       struct berval **normalized )
+{
+       struct berval *out = ber_bvdup( val );
+
+       if( out->bv_len != 0 ) {
+               char *dn;
+#ifdef USE_DN_NORMALIZE
+               dn = dn_normalize( out->bv_val );
+#else
+               dn = dn_validate( out->bv_val );
+#endif
+
+               if( dn == NULL ) {
+                       ber_bvfree( out );
+                       return LDAP_INVALID_SYNTAX;
+               }
+
+               out->bv_val = dn;
+               out->bv_len = strlen( dn );
+       }
+
+       *normalized = out;
+       return LDAP_SUCCESS;
+}
+
+static int
+dnMatch(
+       int *matchp,
+       unsigned use,
+       Syntax *syntax,
+       MatchingRule *mr,
+       struct berval *value,
+       void *assertedValue )
+{
+       int match;
+       struct berval *asserted = (struct berval *) assertedValue;
+       
+       match = value->bv_len - asserted->bv_len;
+
+       if( match == 0 ) {
+#ifdef USE_DN_NORMALIZE
+               match = strcmp( value->bv_val, asserted->bv_val );
+#else
+               match = strcasecmp( value->bv_val, asserted->bv_val );
+#endif
+       }
+
+       Debug( LDAP_DEBUG_ARGS, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n",
+           match, value->bv_val, asserted->bv_val );
+
+       *matchp = match;
+       return LDAP_SUCCESS;
+}
+       
+static int
+inValidate(
+       Syntax *syntax,
+       struct berval *in )
+{
+       /* any value allowed */
+       return LDAP_OTHER;
+}
+
+static int
+blobValidate(
+       Syntax *syntax,
+       struct berval *in )
+{
+       /* any value allowed */
+       return LDAP_SUCCESS;
+}
+
+#define berValidate blobValidate
+
+static int
+UTF8StringValidate(
+       Syntax *syntax,
+       struct berval *in )
+{
+       ber_len_t count;
+       int len;
+       unsigned char *u = in->bv_val;
+
+       for( count = in->bv_len; count > 0; count-=len, u+=len ) {
+               /* get the length indicated by the first byte */
+               len = LDAP_UTF8_CHARLEN( u );
+
+               /* should not be zero */
+               if( len == 0 ) return LDAP_INVALID_SYNTAX;
+
+               /* make sure len corresponds with the offset
+                       to the next character */
+               if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
+       }
+
+       if( count != 0 ) return LDAP_INVALID_SYNTAX;
+
+       return LDAP_SUCCESS;
+}
+
+static int
+UTF8StringNormalize(
+       Syntax *syntax,
+       struct berval *val,
+       struct berval **normalized )
+{
+       struct berval *newval;
+       char *p, *q, *s;
+
+       newval = ch_malloc( sizeof( struct berval ) );
+
+       p = val->bv_val;
+
+       /* Ignore initial whitespace */
+       while ( ldap_utf8_isspace( p ) ) {
+               LDAP_UTF8_INCR( p );
+       }
+
+       if( *p == '\0' ) {
+               ch_free( newval );
+               return LDAP_INVALID_SYNTAX;
+       }
+
+       newval->bv_val = ch_strdup( p );
+       p = q = newval->bv_val;
+       s = NULL;
+
+       while ( *p ) {
+               int len;
+
+               if ( ldap_utf8_isspace( p ) ) {
+                       len = LDAP_UTF8_COPY(q,p);
+                       s=q;
+                       p+=len;
+                       q+=len;
+
+                       /* Ignore the extra whitespace */
+                       while ( ldap_utf8_isspace( p ) ) {
+                               LDAP_UTF8_INCR( p );
+                       }
+               } else {
+                       len = LDAP_UTF8_COPY(q,p);
+                       s=NULL;
+                       p+=len;
+                       q+=len;
+               }
+       }
+
+       assert( *newval->bv_val );
+       assert( newval->bv_val < p );
+       assert( p <= q );
+
+       /* cannot start with a space */
+       assert( !ldap_utf8_isspace(newval->bv_val) );
+
+       /*
+        * If the string ended in space, backup the pointer one
+        * position.  One is enough because the above loop collapsed
+        * all whitespace to a single space.
+        */
+
+       if ( s != NULL ) {
+               q = s;
+       }
+
+       /* cannot end with a space */
+       assert( !ldap_utf8_isspace( LDAP_UTF8_PREV(q) ) );
+
+       /* null terminate */
+       *q = '\0';
+
+       newval->bv_len = q - newval->bv_val;
+       *normalized = newval;
+
+       return LDAP_SUCCESS;
+}
+
+static int
+oidValidate(
+       Syntax *syntax,
+       struct berval *val )
+{
+       ber_len_t i;
+
+       if( val->bv_len == 0 ) return 0;
+
+       if( isdigit(val->bv_val[0]) ) {
+               int dot = 0;
+               for(i=1; i < val->bv_len; i++) {
+                       if( val->bv_val[i] == '.' ) {
+                               if( dot++ ) return 1;
+                       } else if ( isdigit(val->bv_val[i]) ) {
+                               dot = 0;
+                       } else {
+                               return LDAP_INVALID_SYNTAX;
+                       }
+               }
+
+               return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
+
+       } else if( isalpha(val->bv_val[0]) ) {
+               for(i=1; i < val->bv_len; i++) {
+                       if( !isalpha(val->bv_val[i] ) ) {
+                               return LDAP_INVALID_SYNTAX;
+                       }
+               }
+
+               return LDAP_SUCCESS;
+       }
+       
+       return LDAP_INVALID_SYNTAX;
+}
+
+static int
+integerValidate(
+       Syntax *syntax,
+       struct berval *val )
+{
+       ber_len_t i;
+
+       for(i=0; i < val->bv_len; i++) {
+               if( !isdigit(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
+       }
+
+       return LDAP_SUCCESS;
+}
+
+static int
+printableStringValidate(
+       Syntax *syntax,
+       struct berval *val )
+{
+       ber_len_t i;
+
+       for(i=0; i < val->bv_len; i++) {
+               if( !isprint(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
+       }
+
+       return LDAP_SUCCESS;
+}
+
+static int
+IA5StringValidate(
+       Syntax *syntax,
+       struct berval *val )
+{
+       ber_len_t i;
+
+       for(i=0; i < val->bv_len; i++) {
+               if( !isascii(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
+       }
+
+       return LDAP_SUCCESS;
+}
+
+static int
+IA5StringConvert(
+       Syntax *syntax,
+       struct berval *in,
+       struct berval **out )
+{
+       ldap_unicode_t *u;
+       ber_len_t i, len = in->bv_len;
+       struct berval *bv = ch_malloc( sizeof(struct berval) );
+
+       bv->bv_len = len * sizeof( ldap_unicode_t );
+       bv->bv_val = (char *) u = ch_malloc( bv->bv_len + sizeof( ldap_unicode_t ) );;
+
+       for(i=0; i < len; i++ ) {
+               /*
+                * IA5StringValidate should have been called to ensure
+                * input is limited to IA5.
+                */
+               u[i] = in->bv_val[i];
+       }
+       u[i] = 0;
+
+       *out = bv;
+       return LDAP_SUCCESS;
+}
+
+static int
+IA5StringNormalize(
+       Syntax *syntax,
+       struct berval *val,
+       struct berval **normalized )
+{
+       struct berval *newval;
+       char *p, *q;
+
+       newval = ch_malloc( sizeof( struct berval ) );
+
+       p = val->bv_val;
+
+       /* Ignore initial whitespace */
+       while ( isspace( *p++ ) ) {
+               /* EMPTY */  ;
+       }
+
+       if( *p != '\0' ) {
+               ch_free( newval );
+               return LDAP_INVALID_SYNTAX;
+       }
+
+       newval->bv_val = ch_strdup( p );
+       p = q = newval->bv_val;
+
+       while ( *p ) {
+               if ( isspace( *p ) ) {
+                       *q++ = *p++;
+
+                       /* Ignore the extra whitespace */
+                       while ( isspace( *p++ ) ) {
+                               /* EMPTY */  ;
+                       }
+               } else {
+                       *q++ = *p++;
+               }
+       }
+
+       assert( *newval->bv_val );
+       assert( newval->bv_val < p );
+       assert( p <= q );
+
+       /* cannot start with a space */
+       assert( !isspace(*newval->bv_val) );
+
+       /*
+        * If the string ended in space, backup the pointer one
+        * position.  One is enough because the above loop collapsed
+        * all whitespace to a single space.
+        */
+
+       if ( isspace( q[-1] ) ) {
+               --q;
+       }
+
+       /* cannot end with a space */
+       assert( !isspace( q[-1] ) );
+
+       /* null terminate */
+       *q = '\0';
+
+       newval->bv_len = q - newval->bv_val;
+       *normalized = newval;
+
+       return LDAP_SUCCESS;
+}
+
+static int
+caseExactIA5Match(
+       int *match,
+       unsigned use,
+       Syntax *syntax,
+       MatchingRule *mr,
+       struct berval *value,
+       void *assertedValue )
+{
+       *match = strcmp( value->bv_val,
+               ((struct berval *) assertedValue)->bv_val );
+       return LDAP_SUCCESS;
+}
+
+static int
+caseExactIA5SubstringsMatch(
+       int *matchp,
+       unsigned use,
+       Syntax *syntax,
+       MatchingRule *mr,
+       struct berval *value,
+       void *assertedValue )
+{
+       int match = 0;
+       SubstringsAssertion *sub = assertedValue;
+       struct berval left = *value;
+       int i;
+       ber_len_t inlen=0;
+
+       if( sub->sa_initial ) {
+               inlen += sub->sa_initial->bv_len;
+       }
+       if( sub->sa_any ) {
+               for(i=0; sub->sa_any[i]; i++) {
+                       inlen += sub->sa_final->bv_len;
+               }
+       }
+       if( sub->sa_final ) {
+               inlen += sub->sa_final->bv_len;
+       }
+
+       if( inlen > value->bv_len ) {
+               match = 1;
+               goto done;
+       }
+
+       if( sub->sa_initial ) {
+               match = strncmp( sub->sa_initial->bv_val, left.bv_val,
+                       sub->sa_initial->bv_len );
+
+               if( match != 0 ) {
+                       goto done;
+               }
+
+               left.bv_val += sub->sa_initial->bv_len;
+               left.bv_len -= sub->sa_initial->bv_len;
+               inlen -= sub->sa_initial->bv_len;
+       }
+
+       if( sub->sa_final ) {
+               match = strncmp( sub->sa_final->bv_val,
+                       &left.bv_val[left.bv_len - sub->sa_final->bv_len],
+                       sub->sa_final->bv_len );
+
+               if( match != 0 ) {
+                       goto done;
+               }
+
+               left.bv_len -= sub->sa_final->bv_len;
+               inlen -= sub->sa_initial->bv_len;
+       }
+
+       if( sub->sa_any ) {
+               for(i=0; sub->sa_any[i]; i++) {
+                       ber_len_t idx;
+                       char *p;
+
+retry:
+                       if( inlen < left.bv_len ) {
+                               /* not enough length */
+                               match = 1;
+                               goto done;
+                       }
+
+                       if( sub->sa_any[i]->bv_len == 0 ) {
+                               continue;
+                       }
+
+                       p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
+
+                       if( p == NULL ) {
+                               match = 1;
+                               goto done;
+                       }
+
+                       idx = p - left.bv_val;
+                       assert( idx < left.bv_len );
+
+                       if( idx >= left.bv_len ) {
+                               /* this shouldn't happen */
+                               return LDAP_OTHER;
+                       }
+
+                       left.bv_val = p;
+                       left.bv_len -= idx;
+
+                       if( sub->sa_any[i]->bv_len > left.bv_len ) {
+                               /* not enough left */
+                               match = 1;
+                               goto done;
+                       }
+
+                       match = strncmp( left.bv_val,
+                               sub->sa_any[i]->bv_val,
+                               sub->sa_any[i]->bv_len );
+
+
+                       if( match != 0 ) {
+                               goto retry;
+                       }
+
+                       left.bv_val += sub->sa_any[i]->bv_len;
+                       left.bv_len -= sub->sa_any[i]->bv_len;
+               }
+       }
+
+done:
+       *matchp = match;
+       return LDAP_SUCCESS;
+}
+
+static int
+caseIgnoreIA5Match(
+       int *match,
+       unsigned use,
+       Syntax *syntax,
+       MatchingRule *mr,
+       struct berval *value,
+       void *assertedValue )
+{
+       *match = strcasecmp( value->bv_val,
+               ((struct berval *) assertedValue)->bv_val );
+       return LDAP_SUCCESS;
+}
+
+static char *strcasechr( const char *str, int c )
+{
+       char *lower = strchr( str, TOLOWER(c) );
+       char *upper = strchr( str, TOUPPER(c) );
+
+       if( lower && upper ) {
+               return lower < upper ? lower : upper;
+       } else if ( lower ) {
+               return lower;
+       } else {
+               return upper;
+       }
+}
+
+static int
+caseIgnoreIA5SubstringsMatch(
+       int *matchp,
+       unsigned use,
+       Syntax *syntax,
+       MatchingRule *mr,
+       struct berval *value,
+       void *assertedValue )
+{
+       int match = 0;
+       SubstringsAssertion *sub = assertedValue;
+       struct berval left = *value;
+       int i;
+       ber_len_t inlen=0;
+
+       if( sub->sa_initial ) {
+               inlen += sub->sa_initial->bv_len;
+       }
+       if( sub->sa_any ) {
+               for(i=0; sub->sa_any[i]; i++) {
+                       inlen += sub->sa_final->bv_len;
+               }
+       }
+       if( sub->sa_final ) {
+               inlen += sub->sa_final->bv_len;
+       }
+
+       if( inlen > value->bv_len ) {
+               match = 1;
+               goto done;
+       }
+
+       if( sub->sa_initial ) {
+               match = strncasecmp( sub->sa_initial->bv_val, left.bv_val,
+                       sub->sa_initial->bv_len );
+
+               if( match != 0 ) {
+                       goto done;
+               }
+
+               left.bv_val += sub->sa_initial->bv_len;
+               left.bv_len -= sub->sa_initial->bv_len;
+       }
+
+       if( sub->sa_final ) {
+               match = strncasecmp( sub->sa_final->bv_val,
+                       &left.bv_val[left.bv_len - sub->sa_final->bv_len],
+                       sub->sa_final->bv_len );
+
+               if( match != 0 ) {
+                       goto done;
+               }
+
+               left.bv_len -= sub->sa_final->bv_len;
+       }
+
+       if( sub->sa_any ) {
+               for(i=0; sub->sa_any[i]; i++) {
+                       ber_len_t idx;
+                       char *p;
+
+retry:
+                       if( inlen < left.bv_len ) {
+                               /* not enough length */
+                               match = 1;
+                               goto done;
+                       }
+
+                       if( sub->sa_any[i]->bv_len == 0 ) {
+                               continue;
+                       }
+
+                       p = strcasechr( left.bv_val, *sub->sa_any[i]->bv_val );
+
+                       if( p == NULL ) {
+                               match = 1;
+                               goto done;
+                       }
+
+                       idx = p - left.bv_val;
+                       assert( idx < left.bv_len );
+
+                       if( idx >= left.bv_len ) {
+                               /* this shouldn't happen */
+                               return LDAP_OTHER;
+                       }
+
+                       left.bv_val = p;
+                       left.bv_len -= idx;
+
+                       if( sub->sa_any[i]->bv_len > left.bv_len ) {
+                               /* not enough left */
+                               match = 1;
+                               goto done;
+                       }
+
+                       match = strncasecmp( left.bv_val,
+                               sub->sa_any[i]->bv_val,
+                               sub->sa_any[i]->bv_len );
+
+
+                       if( match != 0 ) {
+                               goto retry;
+                       }
+
+                       left.bv_val += sub->sa_any[i]->bv_len;
+                       left.bv_len -= sub->sa_any[i]->bv_len;
+               }
+       }
+
+done:
+       *matchp = match;
+       return LDAP_SUCCESS;
+}
+
+/* Index generation function */
+int caseIgnoreIA5Indexer(
+       unsigned use,
+       Syntax *syntax,
+       MatchingRule *mr,
+       struct berval *prefix,
+       struct berval **values,
+       struct berval ***keysp )
+{
+       int i;
+       size_t slen, mlen;
+       struct berval **keys;
+       lutil_MD5_CTX   MD5context;
+       unsigned char   MD5digest[16];
+       struct berval digest;
+       digest.bv_val = MD5digest;
+       digest.bv_len = sizeof(MD5digest);
+
+       for( i=0; values[i] != NULL; i++ ) {
+               /* just count them */
+       }
+
+       assert( i > 0 );
+
+       keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
+
+       slen = strlen( syntax->ssyn_oid );
+       mlen = strlen( mr->smr_oid );
+
+       for( i=0; values[i] != NULL; i++ ) {
+               struct berval *value = ber_bvdup( values[i] );
+               ldap_pvt_str2upper( value->bv_val );
+
+               lutil_MD5Init( &MD5context );
+               if( prefix != NULL && prefix->bv_len > 0 ) {
+                       lutil_MD5Update( &MD5context,
+                               prefix->bv_val, prefix->bv_len );
+               }
+               lutil_MD5Update( &MD5context,
+                       syntax->ssyn_oid, slen );
+               lutil_MD5Update( &MD5context,
+                       mr->smr_oid, mlen );
+               lutil_MD5Update( &MD5context,
+                       value->bv_val, value->bv_len );
+               lutil_MD5Final( MD5digest, &MD5context );
+
+               ber_bvfree( value );
+
+               keys[i] = ber_bvdup( &digest );
+       }
+
+       keys[i] = NULL;
+       *keysp = keys;
+       return LDAP_SUCCESS;
+}
+
+/* Index generation function */
+int caseIgnoreIA5Filter(
+       unsigned use,
+       Syntax *syntax,
+       MatchingRule *mr,
+       struct berval *prefix,
+       void * assertValue,
+       struct berval ***keysp )
+{
+       size_t slen, mlen;
+       struct berval **keys;
+       lutil_MD5_CTX   MD5context;
+       unsigned char   MD5digest[LUTIL_MD5_BYTES];
+       struct berval *value;
+       struct berval digest;
+       digest.bv_val = MD5digest;
+       digest.bv_len = sizeof(MD5digest);
+
+       slen = strlen( syntax->ssyn_oid );
+       mlen = strlen( mr->smr_oid );
+
+       value = ber_bvdup( (struct berval *) assertValue );
+       ldap_pvt_str2upper( value->bv_val );
+
+       keys = ch_malloc( sizeof( struct berval * ) * 2 );
+
+       lutil_MD5Init( &MD5context );
+       if( prefix != NULL && prefix->bv_len > 0 ) {
+               lutil_MD5Update( &MD5context,
+                       prefix->bv_val, prefix->bv_len );
+       }
+       lutil_MD5Update( &MD5context,
+               syntax->ssyn_oid, slen );
+       lutil_MD5Update( &MD5context,
+               mr->smr_oid, mlen );
+       lutil_MD5Update( &MD5context,
+               value->bv_val, value->bv_len );
+       lutil_MD5Final( MD5digest, &MD5context );
+
+       keys[0] = ber_bvdup( &digest );
+       keys[1] = NULL;
+
+       ber_bvfree( value );
+
+       *keysp = keys;
+       return LDAP_SUCCESS;
+}
+
+static int
+NumericStringNormalize(
+       Syntax *syntax,
+       struct berval *val,
+       struct berval **normalized )
+{
+       /* similiar to IA5StringNormalize except removes all spaces */
+       struct berval *newval;
+       char *p, *q;
+
+       newval = ch_malloc( sizeof( struct berval ) );
+
+       p = val->bv_val;
+
+       /* Ignore initial whitespace */
+       while ( isspace( *p++ ) ) {
+               /* EMPTY */  ;
+       }
+
+       if( *p != '\0' ) {
+               ch_free( newval );
+               return LDAP_INVALID_SYNTAX;
+       }
+
+       newval->bv_val = ch_strdup( p );
+       p = q = newval->bv_val;
+
+       while ( *p ) {
+               if ( isspace( *p ) ) {
+                       /* Ignore whitespace */
+                       p++;
+               } else {
+                       *q++ = *p++;
+               }
+       }
+
+       assert( *newval->bv_val );
+       assert( newval->bv_val < p );
+       assert( p <= q );
+
+       /* cannot start with a space */
+       assert( !isspace(*newval->bv_val) );
+
+       /* cannot end with a space */
+       assert( !isspace( q[-1] ) );
+
+       /* null terminate */
+       *q = '\0';
+
+       newval->bv_len = q - newval->bv_val;
+       *normalized = newval;
+
+       return LDAP_SUCCESS;
+}
+
+struct syntax_defs_rec {
+       char *sd_desc;
+       int sd_flags;
+       slap_syntax_validate_func *sd_validate;
+       slap_syntax_transform_func *sd_normalize;
+       slap_syntax_transform_func *sd_pretty;
+#ifdef SLAPD_BINARY_CONVERSION
+       slap_syntax_transform_func *sd_ber2str;
+       slap_syntax_transform_func *sd_str2ber;
+#endif
+};
+
+#define X_HIDE "X-HIDE 'TRUE' "
+#define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
+#define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
+
+struct syntax_defs_rec syntax_defs[] = {
+       {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' " X_BINARY X_NOT_H_R ")",
+               SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' " X_NOT_H_R ")",
+               SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' " X_BINARY X_NOT_H_R ")",
+               SLAP_SYNTAX_BER, berValidate, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
+               X_BINARY X_NOT_H_R ")",
+               SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
+               X_BINARY X_NOT_H_R ")",
+               SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
+               X_BINARY X_NOT_H_R ")",
+               SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
+               0, dnValidate, dnNormalize, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
+               0, UTF8StringValidate, UTF8StringNormalize, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
+               0, blobValidate, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
+               SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
+               0, IA5StringValidate, IA5StringNormalize, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
+               0, integerValidate, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
+               SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
+               0, IA5StringValidate, NumericStringNormalize, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
+               0, oidValidate, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
+               0, blobValidate, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
+               0, blobValidate, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
+               0, printableStringValidate, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
+               X_BINARY X_NOT_H_R ")",
+               SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
+               0, blobValidate, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
+               0, NULL, NULL, NULL},
+
+       /* OpenLDAP Experimental Syntaxes */
+       {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
+               0, NULL, NULL, NULL},
+       {"( 1.3.6.1.4.1.4203.666.2.3 DESC 'OpenLDAP void' " X_HIDE ")" ,
+               SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
+#if 0 /* not needed */
+       {"( 1.3.6.1.4.1.4203.666.2.4 DESC 'OpenLDAP DN' " X_HIDE ")" ,
+               SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
+#endif
+
+       {NULL, 0, NULL, NULL, NULL}
+};
+
+struct mrule_defs_rec {
+       char *                                          mrd_desc;
+       unsigned                                        mrd_usage;
+       slap_mr_convert_func *          mrd_convert;
+       slap_mr_normalize_func *        mrd_normalize;
+       slap_mr_match_func *            mrd_match;
+       slap_mr_indexer_func *          mrd_indexer;
+       slap_mr_filter_func *           mrd_filter;
+};
+
+/*
+ * Other matching rules in X.520 that we do not use:
+ *
+ * 2.5.13.9            numericStringOrderingMatch
+ * 2.5.13.13   booleanMatch
+ * 2.5.13.15   integerOrderingMatch
+ * 2.5.13.18   octetStringOrderingMatch
+ * 2.5.13.19   octetStringSubstringsMatch
+ * 2.5.13.25   uTCTimeMatch
+ * 2.5.13.26   uTCTimeOrderingMatch
+ * 2.5.13.31   directoryStringFirstComponentMatch
+ * 2.5.13.32   wordMatch
+ * 2.5.13.33   keywordMatch
+ * 2.5.13.34   certificateExactMatch
+ * 2.5.13.35   certificateMatch
+ * 2.5.13.36   certificatePairExactMatch
+ * 2.5.13.37   certificatePairMatch
+ * 2.5.13.38   certificateListExactMatch
+ * 2.5.13.39   certificateListMatch
+ * 2.5.13.40   algorithmIdentifierMatch
+ * 2.5.13.41   storedPrefixMatch
+ * 2.5.13.42   attributeCertificateMatch
+ * 2.5.13.43   readerAndKeyIDMatch
+ * 2.5.13.44   attributeIntegrityMatch
+ */
+
+
+/* recycled matching functions */
+#define caseIgnoreMatch caseIgnoreIA5Match
+#define caseIgnoreOrderingMatch caseIgnoreMatch
+#define caseIgnoreSubstringsMatch caseIgnoreIA5SubstringsMatch
+#define caseExactMatch caseExactIA5Match
+#define caseExactOrderingMatch caseExactMatch
+#define caseExactSubstringsMatch caseExactIA5SubstringsMatch
+
+/* unimplemented matching functions */
+#define objectIdentifierMatch NULL
+#define caseIgnoreListMatch NULL
+#define caseIgnoreListSubstringsMatch NULL
+#define integerMatch NULL
+#define bitStringMatch NULL
+#define octetStringMatch NULL
+#define telephoneNumberMatch NULL
+#define telephoneNumberSubstringsMatch NULL
+#define presentationAddressMatch NULL
+#define uniqueMemberMatch NULL
+#define protocolInformationMatch NULL
+#define generalizedTimeMatch NULL
+#define generalizedTimeOrderingMatch NULL
+#define integerFirstComponentMatch NULL
+#define objectIdentifierFirstComponentMatch NULL
+
+#define OpenLDAPaciMatch NULL
+#define authPasswordMatch NULL
+
+/* unimplied indexer/filter routines */
+#define dnIndexer NULL
+#define dnFilter NULL
+
+#define caseIgnoreIndexer              caseIgnoreIA5Indexer
+#define caseIgnoreFilter               caseIgnoreIA5Filter
+#define caseExactIndexer               caseExactIA5Indexer
+#define caseExactFilter                        caseExactIA5Filter
+#define caseExactIA5Indexer            caseIgnoreIA5Indexer
+#define caseExactIA5Filter             caseIgnoreIA5Filter
+
+struct mrule_defs_rec mrule_defs[] = {
+       {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
+               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               NULL, NULL, objectIdentifierMatch,
+               caseIgnoreIA5Indexer, caseIgnoreIA5Filter},
+
+       {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
+               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               NULL, NULL, dnMatch, dnIndexer, dnFilter},
+
+       {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
+               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               NULL, NULL, caseIgnoreMatch, caseIgnoreIndexer, caseIgnoreFilter},
+
+       {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
+               SLAP_MR_ORDERING,
+               NULL, NULL, caseIgnoreOrderingMatch, NULL, NULL},
+
+       {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
+               SLAP_MR_SUBSTR | SLAP_MR_EXT,
+               NULL, NULL, caseIgnoreSubstringsMatch, NULL, NULL},
+
+       /* Next three are not in the RFC's, but are needed for compatibility */
+       {"( 2.5.13.5 NAME 'caseExactMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
+               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               NULL, NULL, caseExactMatch, caseExactIndexer, caseExactFilter},
+
+       {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
+               SLAP_MR_ORDERING,
+               NULL, NULL, caseExactOrderingMatch, NULL, NULL},
+
+       {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
+               SLAP_MR_SUBSTR | SLAP_MR_EXT,
+               NULL, NULL, caseExactSubstringsMatch, NULL, NULL},
+
+       {"( 2.5.13.8 NAME 'numericStringMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
+               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               NULL, NULL, caseIgnoreIA5Match, NULL, NULL},
+
+       {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
+               SLAP_MR_SUBSTR | SLAP_MR_EXT,
+               NULL, NULL, caseIgnoreIA5SubstringsMatch, NULL, NULL},
+
+       {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
+               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               NULL, NULL, caseIgnoreListMatch, NULL, NULL},
+
+       {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
+               SLAP_MR_SUBSTR | SLAP_MR_EXT,
+               NULL, NULL, caseIgnoreListSubstringsMatch, NULL, NULL},
+
+       {"( 2.5.13.14 NAME 'integerMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
+               SLAP_MR_NONE | SLAP_MR_EXT,
+               NULL, NULL, integerMatch, NULL, NULL},
+
+       {"( 2.5.13.16 NAME 'bitStringMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
+               SLAP_MR_NONE | SLAP_MR_EXT,
+               NULL, NULL, bitStringMatch, NULL, NULL},
+
+       {"( 2.5.13.17 NAME 'octetStringMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
+               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               NULL, NULL, octetStringMatch, octetStringIndexer, octetStringFilter},
+
+       {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
+               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               NULL, NULL, telephoneNumberMatch, NULL, NULL},
+
+       {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
+               SLAP_MR_SUBSTR | SLAP_MR_EXT,
+               NULL, NULL, telephoneNumberSubstringsMatch, NULL, NULL},
+
+       {"( 2.5.13.22 NAME 'presentationAddressMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
+               SLAP_MR_NONE | SLAP_MR_EXT,
+               NULL, NULL, presentationAddressMatch, NULL, NULL},
+
+       {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
+               SLAP_MR_NONE | SLAP_MR_EXT,
+               NULL, NULL, uniqueMemberMatch, NULL, NULL},
+
+       {"( 2.5.13.24 NAME 'protocolInformationMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
+               SLAP_MR_NONE | SLAP_MR_EXT,
+               NULL, NULL, protocolInformationMatch, NULL, NULL},
+
+       {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
+               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               NULL, NULL, generalizedTimeMatch, NULL, NULL},
+
+       {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
+               SLAP_MR_ORDERING,
+               NULL, NULL, generalizedTimeOrderingMatch, NULL, NULL},
+
+       {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
+               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               NULL, NULL, integerFirstComponentMatch, NULL, NULL},
+
+       {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
+               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               NULL, NULL, objectIdentifierFirstComponentMatch, NULL, NULL},
+
+       {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
+               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               NULL, NULL, caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter},
+
+       {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
+               SLAP_MR_EQUALITY | SLAP_MR_EXT,
+               NULL, NULL, caseIgnoreIA5Match, caseExactIA5Indexer, caseExactIA5Filter},
+
+       {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
+               SLAP_MR_SUBSTR,
+               NULL, NULL, caseIgnoreIA5SubstringsMatch, NULL, NULL},
+
+       {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
+               SLAP_MR_EQUALITY,
+               NULL, NULL, authPasswordMatch, NULL, NULL},
+
+       {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
+               "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
+               SLAP_MR_EQUALITY,
+               NULL, NULL, OpenLDAPaciMatch, NULL, NULL},
+
+       {NULL, SLAP_MR_NONE, NULL, NULL, NULL}
+};
+
+int
+schema_init( void )
+{
+       int             res;
+       int             i;
+
+       /* we should only be called once (from main) */
+       assert( schema_init_done == 0 );
+
+       for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
+               res = register_syntax( syntax_defs[i].sd_desc,
+                   syntax_defs[i].sd_flags,
+                   syntax_defs[i].sd_validate,
+                   syntax_defs[i].sd_normalize,
+                       syntax_defs[i].sd_pretty
+#ifdef SLAPD_BINARY_CONVERSION
+                       ,
+                   syntax_defs[i].sd_ber2str,
+                       syntax_defs[i].sd_str2ber
+#endif
+               );
+
+               if ( res ) {
+                       fprintf( stderr, "schema_init: Error registering syntax %s\n",
+                                syntax_defs[i].sd_desc );
+                       return LDAP_OTHER;
+               }
+       }
+
+       for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
+               if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
+                       fprintf( stderr,
+                               "schema_init: Ingoring unusable matching rule %s\n",
+                                mrule_defs[i].mrd_desc );
+                       continue;
+               }
+
+               res = register_matching_rule(
+                       mrule_defs[i].mrd_desc,
+                       mrule_defs[i].mrd_usage,
+                       mrule_defs[i].mrd_convert,
+                       mrule_defs[i].mrd_normalize,
+                   mrule_defs[i].mrd_match,
+                       mrule_defs[i].mrd_indexer,
+                       mrule_defs[i].mrd_filter );
+
+               if ( res ) {
+                       fprintf( stderr,
+                               "schema_init: Error registering matching rule %s\n",
+                                mrule_defs[i].mrd_desc );
+                       return LDAP_OTHER;
+               }
+       }
+       schema_init_done = 1;
+       return LDAP_SUCCESS;
+}
diff --git a/servers/slapd/schema_prep.c b/servers/slapd/schema_prep.c
new file mode 100644 (file)
index 0000000..adcd6c7
--- /dev/null
@@ -0,0 +1,171 @@
+/* schema_init.c - init builtin schema */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/ctype.h>
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "ldap_pvt.h"
+
+int schema_init_done = 0;
+
+struct slap_internal_schema slap_schema;
+
+static int
+objectClassMatch(
+       int *match,
+       unsigned use,
+       Syntax *syntax,
+       MatchingRule *mr,
+       struct berval *value,
+       void *assertedValue )
+{
+       ObjectClass *oc = oc_find( value->bv_val );
+       ObjectClass *asserted = oc_find( ((struct berval *) assertedValue)->bv_val );
+
+       *match = ( oc == NULL || oc != asserted );
+       return LDAP_SUCCESS;
+}
+
+struct slap_schema_oc_map {
+       char *ssom_name;
+       size_t ssom_offset;
+} oc_map[] = {
+       { "top", offsetof(struct slap_internal_schema, si_oc_top) },
+       { "extensibleObject", offsetof(struct slap_internal_schema, si_oc_extensibleObject) },
+       { "alias", offsetof(struct slap_internal_schema, si_oc_alias) },
+       { "referral", offsetof(struct slap_internal_schema, si_oc_referral) },
+       { "LDAProotDSE", offsetof(struct slap_internal_schema, si_oc_rootdse) },
+       { "LDAPsubentry", offsetof(struct slap_internal_schema, si_oc_subentry) },
+       { "subschema", offsetof(struct slap_internal_schema, si_oc_subschema) },
+       { NULL, 0 }
+};
+
+struct slap_schema_ad_map {
+       char *ssam_name;
+       slap_mr_match_func *ssam_match;
+       size_t ssam_offset;
+} ad_map[] = {
+       { "objectClass", objectClassMatch,
+               offsetof(struct slap_internal_schema, si_ad_objectClass) },
+
+       /* user entry operational attributes */
+       { "creatorsName", NULL,
+               offsetof(struct slap_internal_schema, si_ad_creatorsName) },
+       { "createTimestamp", NULL,
+               offsetof(struct slap_internal_schema, si_ad_createTimestamp) },
+       { "modifiersName", NULL,
+               offsetof(struct slap_internal_schema, si_ad_modifiersName) },
+       { "modifyTimestamp", NULL,
+               offsetof(struct slap_internal_schema, si_ad_modifyTimestamp) },
+       { "subschemaSubentry", NULL,
+               offsetof(struct slap_internal_schema, si_ad_subschemaSubentry) },
+
+       /* root DSE attributes */
+       { "namingContexts", NULL,
+               offsetof(struct slap_internal_schema, si_ad_namingContexts) },
+       { "supportedControl", NULL,
+               offsetof(struct slap_internal_schema, si_ad_supportedControl) },
+       { "supportedExtension", NULL,
+               offsetof(struct slap_internal_schema, si_ad_supportedExtension) },
+       { "supportedLDAPVersion", NULL,
+               offsetof(struct slap_internal_schema, si_ad_supportedLDAPVersion) },
+       { "supportedSASLMechanisms", NULL,
+               offsetof(struct slap_internal_schema, si_ad_supportedSASLMechanisms) },
+
+       /* subschema subentry attributes */
+       { "attributeTypes", NULL,
+               offsetof(struct slap_internal_schema, si_ad_attributeTypes) },
+       { "ldapSyntaxes", NULL,
+               offsetof(struct slap_internal_schema, si_ad_ldapSyntaxes) },
+       { "matchingRules", NULL,
+               offsetof(struct slap_internal_schema, si_ad_matchingRules) },
+       { "objectClasses", NULL,
+               offsetof(struct slap_internal_schema, si_ad_objectClasses) },
+
+       /* knowledge information */
+       { "aliasedObjectName", NULL,
+               offsetof(struct slap_internal_schema, si_ad_aliasedObjectName) },
+       { "ref", NULL,
+               offsetof(struct slap_internal_schema, si_ad_ref) },
+
+       /* access control internals */
+       { "entry", NULL,
+               offsetof(struct slap_internal_schema, si_ad_entry) },
+       { "children", NULL,
+               offsetof(struct slap_internal_schema, si_ad_children) },
+#ifdef SLAPD_ACI_ENABLED
+       { "OpenLDAPaci", NULL,
+               offsetof(struct slap_internal_schema, si_ad_aci) },
+#endif
+
+       { "userPassword", NULL,
+               offsetof(struct slap_internal_schema, si_ad_userPassword) },
+       { "authPassword", NULL,
+               offsetof(struct slap_internal_schema, si_ad_authPassword) },
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
+       { "krbName", NULL,
+               offsetof(struct slap_internal_schema, si_ad_krbName) },
+#endif
+
+       { NULL, NULL, 0 }
+};
+
+
+int
+schema_prep( void )
+{
+       int i;
+       /* we should only be called once after schema_init() was called */
+       assert( schema_init_done == 1 );
+
+       for( i=0; oc_map[i].ssom_name; i++ ) {
+               ObjectClass ** ocp = (ObjectClass **)
+                       &(((char *) &slap_schema)[oc_map[i].ssom_offset]);
+
+               *ocp = oc_find( oc_map[i].ssom_name );
+
+               if( *ocp == NULL ) {
+                       fprintf( stderr,
+                               "No objectClass \"%s\" defined in schema\n",
+                               oc_map[i].ssom_name );
+                       return LDAP_OBJECT_CLASS_VIOLATION;
+               }
+       }
+
+       for( i=0; ad_map[i].ssam_name; i++ ) {
+               int rc;
+               const char *text;
+
+               AttributeDescription ** adp = (AttributeDescription **)
+                       &(((char *) &slap_schema)[ad_map[i].ssam_offset]);
+
+               *adp = NULL;
+
+               rc = slap_str2ad( ad_map[i].ssam_name, adp, &text );
+
+               if( rc != LDAP_SUCCESS ) {
+                       fprintf( stderr,
+                               "No attribute \"%s\" defined in schema\n",
+                               ad_map[i].ssam_name );
+                       return rc;
+               }
+
+               if( ad_map[i].ssam_match ) {
+                       /* install custom matching routine */
+                       (*adp)->ad_type->sat_equality->smr_match = ad_map[i].ssam_match;
+               }
+       }
+
+       ++schema_init_done;
+       return LDAP_SUCCESS;
+}
index 14fef80d1daefe081ed1b690c0ea45d13dbcf873..8350b877b7205be398de90cff19095a8190e1d68 100644 (file)
@@ -1,7 +1,7 @@
 /* schemaparse.c - routines to parse config file objectclass definitions */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 
 int    global_schemacheck = 1; /* schemacheck on is default */
 
-static void            oc_usage_old(void) LDAP_GCCATTR((noreturn));
 static void            oc_usage(void)     LDAP_GCCATTR((noreturn));
 static void            at_usage(void)     LDAP_GCCATTR((noreturn));
 
 static char *const err2text[] = {
-       "",
+       "Success",
        "Out of memory",
-       "Objectclass not found",
-       "Attribute type not found",
-       "Duplicate objectclass",
-       "Duplicate attributetype",
-       "Duplicate syntax",
-       "Duplicate matchingrule",
+       "ObjectClass not found",
+       "AttributeType not found",
+       "Duplicate objectClass",
+       "Duplicate attributeType",
+       "Duplicate ldapSyntax",
+       "Duplicate matchingRule",
        "OID or name required",
-       "Syntax or superior required",
-       "Matchingrule not found",
+       "SYNTAX or SUPerior required",
+       "MatchingRule not found",
        "Syntax not found",
        "Syntax required"
 };
@@ -41,109 +40,13 @@ static char *const err2text[] = {
 char *
 scherr2str(int code)
 {
-       if ( code < 1 || code >= (sizeof(err2text)/sizeof(char *)) ) {
+       if ( code < 0 || code >= (sizeof(err2text)/sizeof(char *)) ) {
                return "Unknown error";
        } else {
                return err2text[code];
        }
 }
 
-void
-parse_oc_old(
-    Backend    *be,
-    const char *fname,
-    int                lineno,
-    int                argc,
-    char       **argv
-)
-{
-       int             i;
-       char            last;
-       LDAP_OBJECT_CLASS       *oc;
-       int             code;
-       const char      *err;
-       char            **namep;
-
-       oc = (LDAP_OBJECT_CLASS *) ch_calloc( 1, sizeof(LDAP_OBJECT_CLASS) );
-       oc->oc_names = ch_calloc( 2, sizeof(char *) );
-       oc->oc_names[0] = ch_strdup( argv[1] );
-       oc->oc_names[1] = NULL;
-       if ( strcasecmp( oc->oc_names[0], "top" ) ) {
-               oc->oc_kind = LDAP_SCHEMA_STRUCTURAL;
-       }
-       for ( i = 2; i < argc; i++ ) {
-               /* required attributes */
-               if ( strcasecmp( argv[i], "requires" ) == 0 ) {
-                       do {
-                               i++;
-                               if ( i < argc ) {
-                                       char **s = str2charray( argv[i], "," );
-                                       last = argv[i][strlen( argv[i] ) - 1];
-                                       charray_merge( &oc->oc_at_oids_must, s );
-                                       charray_free( s );
-                               }
-                       } while ( i < argc && last == ',' );
-
-               /* optional attributes */
-               } else if ( strcasecmp( argv[i], "allows" ) == 0 ) {
-                       do {
-                               i++;
-                               if ( i < argc ) {
-                                       char **s = str2charray( argv[i], "," );
-                                       last = argv[i][strlen( argv[i] ) - 1];
-                                       
-                                       charray_merge( &oc->oc_at_oids_may, s );
-                                       charray_free( s );
-                               }
-                       } while ( i < argc && last == ',' );
-
-               } else {
-                       fprintf( stderr,
-           "%s: line %d: expecting \"requires\" or \"allows\" got \"%s\"\n",
-                           fname, lineno, argv[i] );
-                       oc_usage_old();
-               }
-       }
-
-       /*
-        * There was no requirement in the old schema that all attributes
-        * types were defined before use and they would just default to
-        * SYNTAX_CIS.  To support this, we need to make attribute types
-        * out of thin air.
-        */
-       if ( oc->oc_at_oids_must ) {
-               namep = oc->oc_at_oids_must;
-               while ( *namep ) {
-                       code = at_fake_if_needed( *namep );
-                       if ( code ) {
-                               fprintf( stderr, "%s: line %d: %s %s\n",
-                                        fname, lineno, scherr2str(code), *namep);
-                               exit( EXIT_FAILURE );
-                       }
-                       namep++;
-               }
-       }
-       if ( oc->oc_at_oids_may ) {
-               namep = oc->oc_at_oids_may;
-               while ( *namep ) {
-                       code = at_fake_if_needed( *namep );
-                       if ( code ) {
-                               fprintf( stderr, "%s: line %d: %s %s\n",
-                                        fname, lineno, scherr2str(code), *namep);
-                               exit( EXIT_FAILURE );
-                       }
-                       namep++;
-               }
-       }
-       
-       code = oc_add(oc,&err);
-       if ( code ) {
-               fprintf( stderr, "%s: line %d: %s %s\n",
-                        fname, lineno, scherr2str(code), err);
-               exit( EXIT_FAILURE );
-       }
-       ldap_memfree(oc);
-}
 
 /* OID Macros */
 
@@ -173,31 +76,38 @@ static char *
 find_oidm(char *oid)
 {
        OidMacro *om;
-       char *new;
-       int pos, suflen;
 
        /* OID macros must start alpha */
-       if ( !isdigit( *oid ) )
-       {
-           for (om = om_list; om; om=om->next)
-           {
-               if ((pos = dscompare(om->name, oid, ':')))
-               {
-                       suflen = strlen(oid + pos);
-                       new = ch_calloc(1, om->oidlen + suflen + 1);
-                       strcpy(new, om->oid);
-                       if (suflen)
-                       {
-                               suflen = om->oidlen;
-                               new[suflen++] = '.';
-                               strcpy(new+suflen, oid+pos+1);
+       if ( isdigit( *oid ) )  {
+               return oid;
+       }
+
+    for (om = om_list; om; om=om->som_next) {
+               char **names = om->som_names;
+
+               if( names == NULL ) {
+                       continue;
+               }
+
+               for( ; *names != NULL ; names++ ) {
+                       int pos = dscompare(*names, oid, ':');
+
+                       if( pos ) {
+                               int suflen = strlen(oid + pos);
+                               char *new = ch_calloc(1,
+                                       om->som_oid.bv_len + suflen + 1);
+                               strcpy(new, om->som_oid.bv_val);
+
+                               if( suflen ) {
+                                       suflen = om->som_oid.bv_len;
+                                       new[suflen++] = '.';
+                                       strcpy(new+suflen, oid+pos+1);
+                               }
+                               return new;
                        }
-                       return new;
                }
-           }
-           return NULL;
        }
-       return oid;
+       return NULL;
 }
 
 void
@@ -208,26 +118,43 @@ parse_oidm(
     char       **argv
 )
 {
+       char *oid;
        OidMacro *om;
 
-       if (argc != 3)
-       {
-usage:         fprintf( stderr, "ObjectIdentifier <name> <oid>\n");
+       if (argc != 3) {
+               fprintf( stderr, "%s: line %d: too many arguments\n",
+                       fname, lineno );
+usage: fprintf( stderr, "\tObjectIdentifier <name> <oid>\n");
                exit( EXIT_FAILURE );
        }
+
+       oid = find_oidm( argv[1] );
+       if( oid != NULL ) {
+               fprintf( stderr,
+                       "%s: line %d: "
+                       "ObjectIdentifier \"%s\" previously defined \"%s\"",
+                       fname, lineno, argv[1], oid );
+               exit( EXIT_FAILURE );
+       }
+
        om = (OidMacro *) ch_malloc( sizeof(OidMacro) );
-       om->name = ch_strdup( argv[1] );
-       om->oid = find_oidm( argv[2] );
-       if (!om->oid)
-       {
+
+       om->som_names = NULL;
+       charray_add( &om->som_names, argv[1] );
+       om->som_oid.bv_val = find_oidm( argv[2] );
+
+       if (!om->som_oid.bv_val) {
                fprintf( stderr, "%s: line %d: OID %s not recognized\n",
                        fname, lineno, argv[2] );
                goto usage;
        }
-       if (om->oid == argv[2])
-               om->oid = ch_strdup( argv[2] );
-       om->oidlen = strlen( om->oid );
-       om->next = om_list;
+
+       if (om->som_oid.bv_val == argv[2]) {
+               om->som_oid.bv_val = ch_strdup( argv[2] );
+       }
+
+       om->som_oid.bv_len = strlen( om->som_oid.bv_val );
+       om->som_next = om_list;
        om_list = om;
 }
 
@@ -244,39 +171,32 @@ parse_oc(
        const char      *err;
        char            *oid = NULL;
 
-       /* Kludge for OIDmacros. If the numericOid field starts nonnumeric
-        * look for and expand a macro. The macro's place in the input line
-        * will be replaced with a field of '0's to keep ldap_str2objectclass
-        * happy. The actual oid will be swapped into place afterward.
-        */
-       if ( !isdigit( *argv[2] ))
-       {
-               oid = find_oidm(argv[2]);
-               if (!oid)
-               {
-                       fprintf(stderr, "%s: line %d: OID %s not recognized\n",
-                               fname, lineno, argv[2]);
-                       exit( EXIT_FAILURE );
-               }
-               if (oid != argv[2])
-                       memset(strstr(line, argv[2]), '0', strlen(argv[2]));
-               else
-                       oid = NULL;
-       }
-       oc = ldap_str2objectclass(line,&code,&err);
+       oc = ldap_str2objectclass(line,&code,&err,LDAP_SCHEMA_ALLOW_ALL);
        if ( !oc ) {
                fprintf( stderr, "%s: line %d: %s before %s\n",
                         fname, lineno, ldap_scherr2str(code), err );
                oc_usage();
        }
-       if (oid)
-       {
-               ldap_memfree(oc->oc_oid);
-               oc->oc_oid = oid;
+       if ( oc->oc_oid ) {
+               if ( !isdigit( oc->oc_oid[0] )) {
+                       /* Expand OID macros */
+                       oid = find_oidm( oc->oc_oid );
+                       if ( !oid ) {
+                               fprintf(stderr,
+                                       "%s: line %d: OID %s not recognized\n",
+                                       fname, lineno, oc->oc_oid);
+                               exit( EXIT_FAILURE );
+                       }
+                       if ( oid != oc->oc_oid ) {
+                               ldap_memfree( oc->oc_oid );
+                               oc->oc_oid = oid;
+                       }
+               }
        }
+       /* oc->oc_oid == NULL will be an error someday */
        code = oc_add(oc,&err);
        if ( code ) {
-               fprintf( stderr, "%s: line %d: %s %s\n",
+               fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
                         fname, lineno, scherr2str(code), err);
                exit( EXIT_FAILURE );
        }
@@ -286,52 +206,46 @@ parse_oc(
 static void
 oc_usage( void )
 {
-       fprintf( stderr, "ObjectClassDescription = \"(\" whsp\n");
-       fprintf( stderr, "  numericoid whsp      ; ObjectClass identifier\n");
-       fprintf( stderr, "  [ \"NAME\" qdescrs ]\n");
-       fprintf( stderr, "  [ \"DESC\" qdstring ]\n");
-       fprintf( stderr, "  [ \"OBSOLETE\" whsp ]\n");
-       fprintf( stderr, "  [ \"SUP\" oids ]       ; Superior ObjectClasses\n");
-       fprintf( stderr, "  [ ( \"ABSTRACT\" / \"STRUCTURAL\" / \"AUXILIARY\" ) whsp ]\n");
-       fprintf( stderr, "                       ; default structural\n");
-       fprintf( stderr, "  [ \"MUST\" oids ]      ; AttributeTypes\n");
-       fprintf( stderr, "  [ \"MAY\" oids ]       ; AttributeTypes\n");
-       fprintf( stderr, "whsp \")\"\n");
+       fprintf( stderr,
+               "ObjectClassDescription = \"(\" whsp\n"
+               "  numericoid whsp                 ; ObjectClass identifier\n"
+               "  [ \"NAME\" qdescrs ]\n"
+               "  [ \"DESC\" qdstring ]\n"
+               "  [ \"OBSOLETE\" whsp ]\n"
+               "  [ \"SUP\" oids ]                ; Superior ObjectClasses\n"
+               "  [ ( \"ABSTRACT\" / \"STRUCTURAL\" / \"AUXILIARY\" ) whsp ]\n"
+               "                                  ; default structural\n"
+               "  [ \"MUST\" oids ]               ; AttributeTypes\n"
+               "  [ \"MAY\" oids ]                ; AttributeTypes\n"
+               "  whsp \")\"\n" );
        exit( EXIT_FAILURE );
 }
 
-static void
-oc_usage_old( void )
-{
-       fprintf( stderr, "<oc clause> ::= objectclass <ocname>\n" );
-       fprintf( stderr, "                [ requires <attrlist> ]\n" );
-       fprintf( stderr, "                [ allows <attrlist> ]\n" );
-       exit( EXIT_FAILURE );
-}
 
 static void
 at_usage( void )
 {
-       fprintf( stderr, "AttributeTypeDescription = \"(\" whsp\n");
-       fprintf( stderr, "  numericoid whsp      ; AttributeType identifier\n");
-       fprintf( stderr, "  [ \"NAME\" qdescrs ]             ; name used in AttributeType\n");
-       fprintf( stderr, "  [ \"DESC\" qdstring ]            ; description\n");
-       fprintf( stderr, "  [ \"OBSOLETE\" whsp ]\n");
-       fprintf( stderr, "  [ \"SUP\" woid ]                 ; derived from this other\n");
-       fprintf( stderr, "                                 ; AttributeType\n");
-       fprintf( stderr, "  [ \"EQUALITY\" woid ]            ; Matching Rule name\n");
-        fprintf( stderr, "  [ \"ORDERING\" woid ]            ; Matching Rule name\n");
-       fprintf( stderr, "  [ \"SUBSTR\" woid ]              ; Matching Rule name\n");
-       fprintf( stderr, "  [ \"SYNTAX\" whsp noidlen whsp ] ; see section 4.3\n");
-       fprintf( stderr, "  [ \"SINGLE-VALUE\" whsp ]        ; default multi-valued\n");
-       fprintf( stderr, "  [ \"COLLECTIVE\" whsp ]          ; default not collective\n");
-       fprintf( stderr, "  [ \"NO-USER-MODIFICATION\" whsp ]; default user modifiable\n");
-       fprintf( stderr, "  [ \"USAGE\" whsp AttributeUsage ]; default userApplications\n");
-       fprintf( stderr, "                                 ; userApplications\n");
-       fprintf( stderr, "                                 ; directoryOperation\n");
-       fprintf( stderr, "                                 ; distributedOperation\n");
-       fprintf( stderr, "                                 ; dSAOperation\n");
-       fprintf( stderr, "whsp \")\"\n");
+       fprintf( stderr,
+               "AttributeTypeDescription = \"(\" whsp\n"
+               "  numericoid whsp      ; AttributeType identifier\n"
+               "  [ \"NAME\" qdescrs ]             ; name used in AttributeType\n"
+               "  [ \"DESC\" qdstring ]            ; description\n"
+               "  [ \"OBSOLETE\" whsp ]\n"
+               "  [ \"SUP\" woid ]                 ; derived from this other\n"
+               "                                   ; AttributeType\n"
+               "  [ \"EQUALITY\" woid ]            ; Matching Rule name\n"
+               "  [ \"ORDERING\" woid ]            ; Matching Rule name\n"
+               "  [ \"SUBSTR\" woid ]              ; Matching Rule name\n"
+               "  [ \"SYNTAX\" whsp noidlen whsp ] ; see section 4.3\n"
+               "  [ \"SINGLE-VALUE\" whsp ]        ; default multi-valued\n"
+               "  [ \"COLLECTIVE\" whsp ]          ; default not collective\n"
+               "  [ \"NO-USER-MODIFICATION\" whsp ]; default user modifiable\n"
+               "  [ \"USAGE\" whsp AttributeUsage ]; default userApplications\n"
+               "                                   ; userApplications\n"
+               "                                   ; directoryOperation\n"
+               "                                   ; distributedOperation\n"
+               "                                   ; dSAOperation\n"
+               "  whsp \")\"\n");
        exit( EXIT_FAILURE );
 }
 
@@ -349,25 +263,12 @@ parse_at(
        char            *oid = NULL;
        char            *soid = NULL;
 
-       /* Kludge for OIDmacros. If the numericOid field starts nonnumeric
-        * look for and expand a macro. The macro's place in the input line
-        * will be replaced with a field of '0's to keep ldap_str2attr
-        * happy. The actual oid will be swapped into place afterward.
-        */
-       if ( !isdigit( *argv[2] ))
-       {
-               oid = find_oidm(argv[2]);
-               if (!oid)
-               {
-                       fprintf(stderr, "%s: line %d: OID %s not recognized\n",
-                               fname, lineno, argv[2]);
-                       exit( EXIT_FAILURE );
-               }
-               if (oid != argv[2])
-                       memset(strstr(line, argv[2]), '0', strlen(argv[2]));
-               else
-                       oid = NULL;
-       }
+       /* Kludge for OIDmacros for syntaxes. If the syntax field starts
+        * nonnumeric, look for and expand a macro. The macro's place in
+        * the input line will be replaced with a field of '0's to keep
+        * ldap_str2attributetype happy. The actual oid will be swapped
+        * into place afterwards.
+        */
        for (; argv[3]; argv++)
        {
                if (!strcasecmp(argv[3], "syntax") &&
@@ -387,17 +288,29 @@ parse_at(
                        break;
                }
        }
-       at = ldap_str2attributetype(line,&code,&err);
+       at = ldap_str2attributetype(line,&code,&err,LDAP_SCHEMA_ALLOW_ALL);
        if ( !at ) {
                fprintf( stderr, "%s: line %d: %s before %s\n",
                         fname, lineno, ldap_scherr2str(code), err );
                at_usage();
        }
-       if (oid)
-       {
-               ldap_memfree(at->at_oid);
-               at->at_oid = oid;
+       if ( at->at_oid ) {
+               if ( !isdigit( at->at_oid[0] )) {
+                       /* Expand OID macros */
+                       oid = find_oidm( at->at_oid );
+                       if ( !oid ) {
+                               fprintf(stderr,
+                                       "%s: line %d: OID %s not recognized\n",
+                                       fname, lineno, at->at_oid);
+                               exit( EXIT_FAILURE );
+                       }
+                       if ( oid != at->at_oid ) {
+                               ldap_memfree( at->at_oid );
+                               at->at_oid = oid;
+                       }
+               }
        }
+       /* at->at_oid == NULL will be an error someday */
        if (soid)
        {
                ldap_memfree(at->at_syntax_oid);
@@ -405,7 +318,7 @@ parse_at(
        }
        code = at_add(at,&err);
        if ( code ) {
-               fprintf( stderr, "%s: line %d: %s %s\n",
+               fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
                         fname, lineno, scherr2str(code), err);
                exit( EXIT_FAILURE );
        }
index 32a797d249da8f553f28b729d2562f73f285b5f0..51ed0057961a42eaab3f84f87c5749a94cbddf51 100644 (file)
@@ -1,5 +1,9 @@
 /* $OpenLDAP$ */
 /*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/* Portions
  * Copyright (c) 1995 Regents of the University of Michigan.
  * All rights reserved.
  *
@@ -18,6 +22,7 @@
 #include <ac/string.h>
 #include <ac/socket.h>
 
+#include "ldap_pvt.h"
 #include "slap.h"
 
 
@@ -27,25 +32,18 @@ do_search(
     Operation  *op     /* info about the op to which we're responding */
 )
 {
-       int             i, err;
+       int             i;
        ber_int_t               scope, deref, attrsonly;
        ber_int_t               sizelimit, timelimit;
-       char            *base = NULL, *fstr = NULL;
+       char            *base = NULL, *nbase = NULL, *fstr = NULL;
        Filter          *filter = NULL;
        char            **attrs = NULL;
        Backend         *be;
        int                     rc;
+       const char              *text;
 
        Debug( LDAP_DEBUG_TRACE, "do_search\n", 0, 0, 0 );
 
-       if( op->o_bind_in_progress ) {
-               Debug( LDAP_DEBUG_ANY, "do_search: SASL bind in progress.\n",
-                       0, 0, 0 );
-               send_ldap_result( conn, op, LDAP_SASL_BIND_IN_PROGRESS,
-                       NULL, "SASL bind in progress", NULL, NULL );
-               return LDAP_SASL_BIND_IN_PROGRESS;
-       }
-
        /*
         * Parse the search request.  It looks like this:
         *
@@ -71,12 +69,12 @@ do_search(
         */
 
        /* baseObject, scope, derefAliases, sizelimit, timelimit, attrsOnly */
-       if ( ber_scanf( op->o_ber, "{aiiiib",
+       if ( ber_scanf( op->o_ber, "{aiiiib" /*}*/,
                &base, &scope, &deref, &sizelimit,
            &timelimit, &attrsonly ) == LBER_ERROR ) {
                send_ldap_disconnect( conn, op,
                        LDAP_PROTOCOL_ERROR, "decoding error" );
-               rc = -1;
+               rc = SLAPD_DISCONNECT;
                goto return_results;
        }
 
@@ -86,9 +84,8 @@ do_search(
        case LDAP_SCOPE_SUBTREE:
                break;
        default:
-               send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR,
+               send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
                        NULL, "invalid scope", NULL, NULL );
-               rc = -1;
                goto return_results;
        }
 
@@ -99,16 +96,16 @@ do_search(
        case LDAP_DEREF_ALWAYS:
                break;
        default:
-               send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR,
+               send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
                        NULL, "invalid deref", NULL, NULL );
-               rc = -1;
                goto return_results;
        }
 
-       if( dn_normalize_case( base ) == NULL ) {
-               send_ldap_result( conn, op, LDAP_INVALID_DN_SYNTAX,
+       nbase = ch_strdup( base );
+
+       if( dn_normalize( nbase ) == NULL ) {
+               send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX,
                        NULL, "invalid DN", NULL, NULL );
-               rc = -1;
                goto return_results;
        }
 
@@ -117,15 +114,15 @@ do_search(
            attrsonly);
 
        /* filter - returns a "normalized" version */
-       if ( (err = get_filter( conn, op->o_ber, &filter, &fstr )) != 0 ) {
-               if( err == -1 ) {
+       rc = get_filter( conn, op->o_ber, &filter, &fstr, &text );
+       if( rc != LDAP_SUCCESS ) {
+               if( rc == SLAPD_DISCONNECT ) {
                        send_ldap_disconnect( conn, op,
-                               LDAP_PROTOCOL_ERROR, "decode error" );
+                               LDAP_PROTOCOL_ERROR, text );
                } else {
-                       send_ldap_result( conn, op, err,
-                               NULL, "Bad search filter", NULL, NULL );
+                       send_ldap_result( conn, op, rc,
+                               NULL, text, NULL, NULL );
                }
-               rc = -1;
                goto return_results;
        }
 
@@ -134,8 +131,8 @@ do_search(
        /* attributes */
        if ( ber_scanf( op->o_ber, /*{*/ "{v}}", &attrs ) == LBER_ERROR ) {
                send_ldap_disconnect( conn, op,
-                       LDAP_PROTOCOL_ERROR, "decoding error" );
-               rc = -1;
+                       LDAP_PROTOCOL_ERROR, "decoding attrs error" );
+               rc = SLAPD_DISCONNECT;
                goto return_results;
        }
 
@@ -150,7 +147,6 @@ do_search(
 
        if ( attrs != NULL ) {
                for ( i = 0; attrs[i] != NULL; i++ ) {
-                       attr_normalize( attrs[i] );
                        Debug( LDAP_DEBUG_ARGS, " %s", attrs[i], 0, 0 );
                }
        }
@@ -162,29 +158,48 @@ do_search(
            op->o_connid, op->o_opid, base, scope, fstr );
 
        if ( scope == LDAP_SCOPE_BASE ) {
+               Entry *entry = NULL;
+
+               if ( strcasecmp( nbase, LDAP_ROOT_DSE ) == 0 ) {
+                       rc = root_dse_info( &entry, &text );
+               }
+
 #if defined( SLAPD_MONITOR_DN )
-               if ( strcmp( base, SLAPD_MONITOR_DN ) == 0 ) {
-                       monitor_info( conn, op, attrs, attrsonly );
-                       goto return_results;
+               else if ( strcasecmp( nbase, SLAPD_MONITOR_DN ) == 0 ) {
+                       rc = monitor_info( &entry, &text );
                }
 #endif
 
 #if defined( SLAPD_CONFIG_DN )
-               if ( strcmp( base, SLAPD_CONFIG_DN ) == 0 ) {
-                       config_info( conn, op, attrs, attrsonly );
-                       goto return_results;
+               else if ( strcasecmp( nbase, SLAPD_CONFIG_DN ) == 0 ) {
+                       rc = config_info( &entry, &text );
                }
 #endif
 
 #if defined( SLAPD_SCHEMA_DN )
-               if ( strcmp( base, SLAPD_SCHEMA_DN ) == 0 ) {
-                       schema_info( conn, op, attrs, attrsonly );
-                       goto return_results;
+               else if ( strcasecmp( nbase, SLAPD_SCHEMA_DN ) == 0 ) {
+                       rc= schema_info( &entry, &text );
                }
 #endif
 
-               if ( strcmp( base, LDAP_ROOT_DSE ) == 0 ) {
-                       root_dse_info( conn, op, attrs, attrsonly );
+               if( rc != LDAP_SUCCESS ) {
+                       send_ldap_result( conn, op, rc,
+                               NULL, text, NULL, NULL );
+                       goto return_results;
+
+               } else if ( entry != NULL ) {
+                       rc = test_filter( NULL, conn, op,
+                               entry, filter );
+
+                       if( rc == LDAP_COMPARE_TRUE ) {
+                               send_search_entry( &backends[0], conn, op,
+                                       entry, attrs, attrsonly, NULL );
+                       }
+                       entry_free( entry );
+
+                       send_ldap_result( conn, op, LDAP_SUCCESS,
+                               NULL, NULL, NULL, NULL );
+
                        goto return_results;
                }
        }
@@ -194,27 +209,37 @@ do_search(
         * appropriate one, or send a referral to our "referral server"
         * if we don't hold it.
         */
-       if ( (be = select_backend( base )) == NULL ) {
+       if ( (be = select_backend( nbase )) == NULL ) {
                send_ldap_result( conn, op, rc = LDAP_REFERRAL,
                        NULL, NULL, default_referral, NULL );
 
                goto return_results;
        }
 
+       /* make sure this backend recongizes critical controls */
+       rc = backend_check_controls( be, conn, op, &text ) ;
+
+       if( rc != LDAP_SUCCESS ) {
+               send_ldap_result( conn, op, rc,
+                       NULL, text, NULL, NULL );
+               goto return_results;
+       }
+
        /* deref the base if needed */
-       base = suffix_alias( be, base );
+       nbase = suffix_alias( be, nbase );
 
        /* actually do the search and send the result(s) */
        if ( be->be_search ) {
-               (*be->be_search)( be, conn, op, base, scope, deref, sizelimit,
+               (*be->be_search)( be, conn, op, base, nbase, scope, deref, sizelimit,
                    timelimit, filter, fstr, attrs, attrsonly );
        } else {
                send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
-                       NULL, "Function not implemented", NULL, NULL );
+                       NULL, "operation not supported within namingContext", NULL, NULL );
        }
 
 return_results:;
        if( base != NULL) free( base );
+       if( nbase != NULL) free( nbase );
        if( fstr != NULL) free( fstr );
        if( filter != NULL) filter_free( filter );
        if ( attrs != NULL ) {
index 6935c5ffa214724cd66deb7dd2553b9fa846f5d3..09845972d3d183458eaab11ab55d328ce7c51023 100644 (file)
@@ -1,4 +1,6 @@
 # $OpenLDAP$
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 
 PROGRAMS = passwd-shell
 
index d7f7b191cfb807f45bf14a8960960f707f63afd5..ef3ab616dff185ae406f08ce12709991db70fcb5 100644 (file)
@@ -112,8 +112,8 @@ pwdfile_search( struct ldop *op, FILE *ofp )
                    write_entry( op, entry, ofp );
                    break;
                }
-           } else if ( test_filter( op, entry )) {
-               write_entry( op, entry, ofp );
+           } else if ( test_filter( op, entry ) == LDAP_COMPARE_TRUE ) {
+                       write_entry( op, entry, ofp );
            }
            free_entry( entry );
        }
diff --git a/servers/slapd/shell-backends/pwd-Version.c b/servers/slapd/shell-backends/pwd-Version.c
deleted file mode 100644 (file)
index 79a4766..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/* $OpenLDAP$ */
-/*
- * Copyright (c) 1995 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.
- */
-
-char Versionstr[] = "  shell passwd backend %VERSION% (%WHEN%)\n\t%WHOANDWHERE%\n";
index d05ec738959ea8f05eb941cf809f99f9fbb96e28..7a1cb7be852dae957752cee88bdf33d1d1411d43 100644 (file)
@@ -89,7 +89,8 @@ write_entry( struct ldop *op, struct ldentry *entry, FILE *ofp )
 int
 test_filter( struct ldop *op, struct ldentry *entry )
 {
-    return (( random() & 0x07 ) == 0x07 );     /* XXX random for now */
+    return ((random() & 0x07 ) == 0x07) /* XXX random for now */
+               ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE;
 }
 
 
index 7cec633145cf1b596dbef466c2eab059ff09f3ec..5a7bf3582e7d222863f17fb2ce6d34c8c4f74bca 100644 (file)
@@ -1,12 +1,12 @@
 /* slap.h - stand alone ldap server include file */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
-#ifndef _SLDAPD_H_
-#define _SLDAPD_H_
+#ifndef _SLAP_H_
+#define _SLAP_H_
 
 #include "ldap_defaults.h"
 
@@ -17,6 +17,7 @@
 #include <ac/regex.h>
 #include <ac/socket.h>
 #include <ac/time.h>
+#include <ac/param.h>
 
 #ifdef HAVE_CYRUS_SASL
 #include <sasl.h>
 
 LDAP_BEGIN_DECL
 
+#define SERVICE_NAME  OPENLDAP_PACKAGE "-slapd"
+#define SLAPD_ANONYMOUS "<anonymous>"
+
 #ifdef f_next
 #undef f_next /* name conflict between sys/file.h on SCO and struct filter */
 #endif
 
-#define SERVICE_NAME  OPENLDAP_PACKAGE "-slapd"
-
 /* LDAPMod.mod_op value ===> Must be kept in sync with ldap.h!
  *
  * This is a value used internally by the backends. It is needed to allow
@@ -52,12 +54,7 @@ LDAP_BEGIN_DECL
  * modrdn when the new rdn was already an attribute value itself.
  * JCG 05/1999 (gomez@engr.sgi.com)
  */
-#define LDAP_MOD_SOFTADD       0x1000
-
-#ifdef DNS_DN
-#define DN_DNS 0
-#define DN_X500        1
-#endif
+#define SLAP_MOD_SOFTADD       0x1000
 
 #define ON     1
 #define OFF    (-1)
@@ -65,27 +62,93 @@ LDAP_BEGIN_DECL
 
 #define MAXREMATCHES 10
 
-/* XXYYZ: these macros assume 'x' is an ASCII x */
-#define DNSEPARATOR(c) ((c) == ',' || (c) == ';')
-#define SEPARATOR(c)   ((c) == ',' || (c) == ';' || (c) == '+')
-#define SPACE(c)       ((c) == ' ' || (c) == '\n')
 
+/* psuedo error code indicating abandoned operation */
+#define SLAPD_ABANDON (-1)
+
+/* psuedo error code indicating disconnect */
+#define SLAPD_DISCONNECT (-2)
+
+
+/* We assume "C" locale, that is US-ASCII */
+#define ASCII_SPACE(c) ( (c) == ' ' )
 #define ASCII_LOWER(c) ( (c) >= 'a' && (c) <= 'z' )
 #define ASCII_UPPER(c) ( (c) >= 'A' && (c) <= 'Z' )
 #define ASCII_ALPHA(c) ( ASCII_LOWER(c) || ASCII_UPPER(c) )
 #define ASCII_DIGIT(c) ( (c) >= '0' && (c) <= '9' )
 #define ASCII_ALNUM(c) ( ASCII_ALPHA(c) || ASCII_DIGIT(c) )
 
-#define LEADKEYCHAR(c) ( ASCII_ALPHA(c) )
-#define KEYCHAR(c)     ( ASCII_ALNUM(c) || (c) == '-' )
-#define LEADOIDCHAR(c) ( ASCII_DIGIT(c) )
-#define OIDCHAR(c)     ( ASCII_DIGIT(c) || (c) == '.' )
+#define DN_SEPARATOR(c)        ((c) == ',' || (c) == ';')
+#define RDN_SEPARATOR(c)       ((c) == ',' || (c) == ';' || (c) == '+')
+#define RDN_NEEDSESCAPE(c)     ((c) == '\\' || (c) == '"')
+
+#define DESC_LEADCHAR(c)       ( ASCII_ALPHA(c) )
+#define DESC_CHAR(c)   ( ASCII_ALNUM(c) || (c) == '-' )
+#define OID_LEADCHAR(c)        ( ASCII_DIGIT(c) )
+#define OID_CHAR(c)    ( ASCII_DIGIT(c) || (c) == '.' )
+
+#define ATTR_LEADCHAR(c)       ( DESC_LEADCHAR(c) || OID_LEADCHAR(c) )
+#define ATTR_CHAR(c)   ( DESC_CHAR((c)) || (c) == '.' )
+
+#define AD_LEADCHAR(c) ( ATTR_CHAR(c) )
+#define AD_CHAR(c)             ( ATTR_CHAR(c) || (c) == ';' )
+
+/* must match in schema_init.c */
+#define SLAPD_DN_SYNTAX                        "1.3.6.1.4.1.1466.115.121.1.12"
+#define SLAPD_GROUP_ATTR               "member"
+#define SLAPD_GROUP_CLASS              "groupOfNames"
+#define SLAPD_ROLE_ATTR                        "roleOccupant"
+#define SLAPD_ROLE_CLASS               "organizationalRole"
+
+#define SLAPD_ACI_SYNTAX               "1.3.6.1.4.1.4203.666.2.1"
+#define SLAPD_ACI_ATTR                 "OpenLDAPaci"
+
+LIBSLAPD_F (int) slap_debug;
 
-#define LEADATTRCHAR(c)        ( LEADKEYCHAR(c) || LEADOIDCHAR(c) )
-#define ATTRCHAR(c)    ( KEYCHAR((c)) || (c) == '.' )
+/*
+ * Index types
+ */
+#define SLAP_INDEX_TYPE           0x00FFUL
+#define SLAP_INDEX_UNDEFINED      0x0001UL
+#define SLAP_INDEX_PRESENT        0x0002UL
+#define SLAP_INDEX_EQUALITY       0x0004UL
+#define SLAP_INDEX_APPROX         0x0008UL
+#define SLAP_INDEX_SUBSTR         0x0010UL
+#define SLAP_INDEX_EXTENDED              0x0020UL
+
+#define SLAP_INDEX_DEFAULT        SLAP_INDEX_EQUALITY
+
+#define IS_SLAP_INDEX(mask, type)      (((mask) & (type)) == (type) )
 
-#define NEEDSESCAPE(c) ((c) == '\\' || (c) == '"')
+#define SLAP_INDEX_SUBSTR_TYPE    0x0F00UL
 
+#define SLAP_INDEX_SUBSTR_INITIAL ( SLAP_INDEX_SUBSTR | 0x0100UL ) 
+#define SLAP_INDEX_SUBSTR_ANY     ( SLAP_INDEX_SUBSTR | 0x0200UL )
+#define SLAP_INDEX_SUBSTR_FINAL   ( SLAP_INDEX_SUBSTR | 0x0400UL )
+#define SLAP_INDEX_SUBSTR_DEFAULT ( SLAP_INDEX_SUBSTR \
+       | SLAP_INDEX_SUBSTR_INITIAL | SLAP_INDEX_SUBSTR_FINAL )
+
+#define SLAP_INDEX_FLAGS          0xF000UL
+#define SLAP_INDEX_SUBTYPES       0x1000UL /* use index with subtypes */
+#define SLAP_INDEX_AUTO_SUBTYPES  0x2000UL /* use mask with subtypes */
+#define SLAP_INDEX_LANG           0x4000UL /* use index with lang subtypes */
+#define SLAP_INDEX_AUTO_LANG      0x8000UL /* use mask with lang subtypes */
+
+typedef long slap_index;
+
+/*
+ * there is a single index for each attribute.  these prefixes ensure
+ * that there is no collision among keys.
+ */
+#define SLAP_INDEX_EQUALITY_PREFIX     '='     /* prefix for equality keys     */
+#define SLAP_INDEX_APPROX_PREFIX       '~'             /* prefix for approx keys       */
+#define SLAP_INDEX_SUBSTR_PREFIX       '*'             /* prefix for substring keys    */
+#define SLAP_INDEX_CONT_PREFIX         '.'             /* prefix for continuation keys */
+#define SLAP_INDEX_UNKNOWN_PREFIX      '?'             /* prefix for unknown keys */
+
+/*
+ * represents schema information for a database
+ */
 #define SLAP_SCHERR_OUTOFMEM           1
 #define SLAP_SCHERR_CLASS_NOT_FOUND    2
 #define SLAP_SCHERR_ATTR_NOT_FOUND     3
@@ -99,103 +162,344 @@ LDAP_BEGIN_DECL
 #define SLAP_SCHERR_SYN_NOT_FOUND      11
 #define SLAP_SCHERR_MR_INCOMPLETE      12
 
-#define SLAPD_ACI_DEFAULT_ATTR         "aci"
+typedef struct slap_oid_macro {
+       struct berval som_oid;
+       char **som_names;
+       struct slap_oid_macro *som_next;
+} OidMacro;
+
+/* forward declarations */
+struct slap_syntax;
+struct slap_matching_rule;
 
-extern int slap_debug;
+typedef int slap_syntax_validate_func LDAP_P((
+       struct slap_syntax *syntax,
+       struct berval * in));
 
-struct slap_op;
-struct slap_conn;
+typedef int slap_syntax_transform_func LDAP_P((
+       struct slap_syntax *syntax,
+       struct berval * in,
+       struct berval ** out));
+
+typedef struct slap_syntax {
+       LDAP_SYNTAX                     ssyn_syn;
+#define ssyn_oid               ssyn_syn.syn_oid
+#define ssyn_desc              ssyn_syn.syn_desc
+#define ssyn_extensions                ssyn_syn.syn_extensions
+
+       unsigned        ssyn_flags;
+
+#define SLAP_SYNTAX_NONE       0x00U
+#define SLAP_SYNTAX_BLOB       0x01U /* syntax treated as blob (audio) */
+#define SLAP_SYNTAX_BINARY     0x02U /* binary transfer required (certificate) */
+#define SLAP_SYNTAX_BER                0x04U /* stored using BER encoding (binary,certificate) */
+#define SLAP_SYNTAX_HIDE       0x80U /* hide (do not publish) */
+
+       slap_syntax_validate_func       *ssyn_validate;
+       slap_syntax_transform_func      *ssyn_normalize;
+       slap_syntax_transform_func      *ssyn_pretty;
+
+#ifdef SLAPD_BINARY_CONVERSION
+       /* convert to and from binary */
+       slap_syntax_transform_func      *ssyn_ber2str;
+       slap_syntax_transform_func      *ssyn_str2ber;
+#endif
+
+       struct slap_syntax              *ssyn_next;
+} Syntax;
+
+#define slap_syntax_is_flag(s,flag) ((int)((s)->ssyn_flags & (flag)) ? 1 : 0)
+#define slap_syntax_is_blob(s)         slap_syntax_is_flag((s),SLAP_SYNTAX_BLOB)
+#define slap_syntax_is_binary(s)       slap_syntax_is_flag((s),SLAP_SYNTAX_BINARY)
+#define slap_syntax_is_ber(s)          slap_syntax_is_flag((s),SLAP_SYNTAX_BER)
+#define slap_syntax_is_hidden(s)       slap_syntax_is_flag((s),SLAP_SYNTAX_HIDE)
+
+/* XXX -> UCS-2 Converter */
+typedef int slap_mr_convert_func LDAP_P((
+       struct berval * in,
+       struct berval ** out ));
+
+/* Normalizer */
+typedef int slap_mr_normalize_func LDAP_P((
+       unsigned use,
+       struct slap_syntax *syntax, /* NULL if in is asserted value */
+       struct slap_matching_rule *mr,
+       struct berval * in,
+       struct berval ** out ));
+
+/* Match (compare) function */
+typedef int slap_mr_match_func LDAP_P((
+       int *match,
+       unsigned use,
+       struct slap_syntax *syntax,     /* syntax of stored value */
+       struct slap_matching_rule *mr,
+       struct berval * value,
+       void * assertValue ));
+
+/* Index generation function */
+typedef int slap_mr_indexer_func LDAP_P((
+       unsigned use,
+       struct slap_syntax *syntax,     /* syntax of stored value */
+       struct slap_matching_rule *mr,
+       struct berval *prefix,
+       struct berval **values,
+       struct berval ***keys ));
+
+/* Filter index function */
+typedef int slap_mr_filter_func LDAP_P((
+       unsigned use,
+       struct slap_syntax *syntax,     /* syntax of stored value */
+       struct slap_matching_rule *mr,
+       struct berval *prefix,
+       void * assertValue,
+       struct berval ***keys ));
+
+typedef struct slap_matching_rule {
+       LDAP_MATCHING_RULE              smr_mrule;
+       unsigned                                smr_usage;
+
+#define SLAP_MR_TYPE_MASK              0xFF00U
+#define SLAP_MR_SUBTYPE_MASK   0x00FFU
+
+#define SLAP_MR_NONE                   0x0000U
+#define SLAP_MR_EQUALITY               0x0100U
+#define SLAP_MR_ORDERING               0x0200U
+#define SLAP_MR_SUBSTR                 0x0400U
+#define SLAP_MR_EXT                            0x0800U
+
+#define SLAP_MR_EQUALITY_APPROX        ( SLAP_MR_EQUALITY | 0x0001U )
+
+#define SLAP_MR_SUBSTR_INITIAL ( SLAP_MR_SUBSTR | 0x0001U )
+#define SLAP_MR_SUBSTR_ANY             ( SLAP_MR_SUBSTR | 0x0002U )
+#define SLAP_MR_SUBSTR_FINAL   ( SLAP_MR_SUBSTR | 0x0004U )
+
+       Syntax                                  *smr_syntax;
+       slap_mr_convert_func    *smr_convert;
+       slap_mr_normalize_func  *smr_normalize;
+       slap_mr_match_func              *smr_match;
+       slap_mr_indexer_func    *smr_indexer;
+       slap_mr_filter_func             *smr_filter;
+       struct slap_matching_rule       *smr_next;
+#define smr_oid                                smr_mrule.mr_oid
+#define smr_names                      smr_mrule.mr_names
+#define smr_desc                       smr_mrule.mr_desc
+#define smr_obsolete           smr_mrule.mr_obsolete
+#define smr_syntax_oid         smr_mrule.mr_syntax_oid
+#define smr_extensions         smr_mrule.mr_extensions
+} MatchingRule;
+
+typedef struct slap_attribute_type {
+       char                                    *sat_cname;
+       LDAP_ATTRIBUTE_TYPE             sat_atype;
+       struct slap_attribute_type      *sat_sup;
+       struct slap_attribute_type      **sat_subtypes;
+       MatchingRule                    *sat_equality;
+       MatchingRule                    *sat_approx;
+       MatchingRule                    *sat_ordering;
+       MatchingRule                    *sat_substr;
+       Syntax                          *sat_syntax;
+       struct slap_attribute_type      *sat_next;
+#define sat_oid                        sat_atype.at_oid
+#define sat_names              sat_atype.at_names
+#define sat_desc               sat_atype.at_desc
+#define sat_obsolete           sat_atype.at_obsolete
+#define sat_sup_oid            sat_atype.at_sup_oid
+#define sat_equality_oid       sat_atype.at_equality_oid
+#define sat_ordering_oid       sat_atype.at_ordering_oid
+#define sat_substr_oid         sat_atype.at_substr_oid
+#define sat_syntax_oid         sat_atype.at_syntax_oid
+#define sat_single_value       sat_atype.at_single_value
+#define sat_collective         sat_atype.at_collective
+#define sat_no_user_mod                sat_atype.at_no_user_mod
+#define sat_usage              sat_atype.at_usage
+#define sat_extensions         sat_atype.at_extensions
+} AttributeType;
+
+#define is_at_operational(at)  ((at)->sat_usage)
+#define is_at_single_value(at) ((at)->sat_single_value)
+#define is_at_collective(at)   ((at)->sat_collective)
+#define is_at_no_user_mod(at)  ((at)->sat_no_user_mod)
+
+typedef struct slap_object_class {
+       LDAP_OBJECT_CLASS               soc_oclass;
+       struct slap_object_class        **soc_sups;
+       AttributeType                   **soc_required;
+       AttributeType                   **soc_allowed;
+       struct slap_object_class        *soc_next;
+#define soc_oid                        soc_oclass.oc_oid
+#define soc_names              soc_oclass.oc_names
+#define soc_desc               soc_oclass.oc_desc
+#define soc_obsolete           soc_oclass.oc_obsolete
+#define soc_sup_oids           soc_oclass.oc_sup_oids
+#define soc_kind               soc_oclass.oc_kind
+#define soc_at_oids_must       soc_oclass.oc_at_oids_must
+#define soc_at_oids_may                soc_oclass.oc_at_oids_may
+#define soc_extensions         soc_oclass.oc_extensions
+} ObjectClass;
 
-struct replog_moddn {
-       char *newrdn;
-       int     deloldrdn;
-       char *newsup;
-};
 
 /*
- * represents an attribute value assertion (i.e., attr=value)
+ * represents a recognized attribute description ( type + options )
  */
-typedef struct slap_ava {
-       char            *ava_type;
-       struct berval   ava_value;
-} Ava;
-
-typedef struct slap_mra {
-       char    *mra_rule;
-       char    *mra_type;
-       char    *mra_value;
-       int             mra_dnattrs;
-} Mra;
+typedef struct slap_attr_desc {
+       struct berval *ad_cname;        /* canonical name */
+       AttributeType *ad_type;         /* NULL if unknown */
+       char *ad_lang;                          /* NULL if no language tags */
+       unsigned ad_flags;
+#define SLAP_DESC_NONE         0x0U
+#define SLAP_DESC_BINARY       0x1U
+} AttributeDescription;
+
+#define slap_ad_is_lang(ad)            ( (ad)->ad_lang != NULL )
+#define slap_ad_is_binary(ad)  ( (int)((ad)->ad_flags & SLAP_DESC_BINARY) ? 1 : 0 )
+
+/*
+ * pointers to schema elements used internally
+ */
+struct slap_internal_schema {
+       /* objectClass */
+       ObjectClass *si_oc_top;
+       ObjectClass *si_oc_extensibleObject;
+       ObjectClass *si_oc_alias;
+       ObjectClass *si_oc_referral;
+       ObjectClass *si_oc_subentry;
+       ObjectClass *si_oc_subschema;
+       ObjectClass *si_oc_rootdse;
+
+       /* objectClass attribute */
+       AttributeDescription *si_ad_objectClass;
+
+       /* operational attributes */
+       AttributeDescription *si_ad_creatorsName;
+       AttributeDescription *si_ad_createTimestamp;
+       AttributeDescription *si_ad_modifiersName;
+       AttributeDescription *si_ad_modifyTimestamp;
+       AttributeDescription *si_ad_subschemaSubentry;
+
+       /* root DSE attributes */
+       AttributeDescription *si_ad_namingContexts;
+       AttributeDescription *si_ad_supportedControl;
+       AttributeDescription *si_ad_supportedExtension;
+       AttributeDescription *si_ad_supportedLDAPVersion;
+       AttributeDescription *si_ad_supportedSASLMechanisms;
+
+       /* subschema subentry attributes */
+       AttributeDescription *si_ad_objectClasses;
+       AttributeDescription *si_ad_attributeTypes;
+       AttributeDescription *si_ad_ldapSyntaxes;
+       AttributeDescription *si_ad_matchingRules;
+       AttributeDescription *si_ad_matchingRulesUse;
+
+       /* Aliases & Referrals */
+       AttributeDescription *si_ad_aliasedObjectName;
+       AttributeDescription *si_ad_ref;
+
+       /* Access Control Internals */
+       AttributeDescription *si_ad_entry;
+       AttributeDescription *si_ad_children;
+#ifdef SLAPD_ACI_ENABLED
+       AttributeDescription *si_ad_aci;
+#endif
+
+       /* Other */
+       AttributeDescription *si_ad_userPassword;
+       AttributeDescription *si_ad_authPassword;
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
+       AttributeDescription *si_ad_krbName;
+#endif
+};
+
+typedef struct slap_attr_assertion {
+       AttributeDescription    *aa_desc;
+       struct berval *aa_value;
+} AttributeAssertion;
+
+typedef struct slap_ss_assertion {
+       AttributeDescription    *sa_desc;
+       struct berval                   *sa_initial;
+       struct berval                   **sa_any;
+       struct berval                   *sa_final;
+} SubstringsAssertion;
+
+typedef struct slap_mr_assertion {
+       char                                    *ma_rule;       /* optional */
+       AttributeDescription    *ma_desc;       /* optional */
+       int                                             ma_dnattrs; /* boolean */
+       struct berval                   *ma_value;      /* required */
+} MatchingRuleAssertion;
+
 
 /*
  * represents a search filter
  */
+
 typedef struct slap_filter {
-       ber_tag_t       f_choice;       /* values taken from ldap.h */
+       ber_tag_t       f_choice;       /* values taken from ldap.h, plus: */
+#define SLAPD_FILTER_COMPUTED  ((ber_tag_t) -1)
+#define SLAPD_FILTER_DN_ONE            ((ber_tag_t) -2)
+#define SLAPD_FILTER_DN_SUBTREE        ((ber_tag_t) -3)
+
 
        union f_un_u {
-               /* present */
-               char            *f_un_type;
+               /* precomputed result */
+               ber_int_t f_un_result;
 
-               /* equality, lessorequal, greaterorequal, approx */
-               Ava             f_un_ava;
+               /* DN */
+               char *f_un_dn;
 
-               /* extensible */
-               Mra             f_un_fra;       
+               /* present */
+               AttributeDescription *f_un_desc;
+
+               /* simple value assertion */
+               AttributeAssertion *f_un_ava;
+
+               /* substring assertion */
+               SubstringsAssertion *f_un_ssa;
+
+               /* matching rule assertion */
+               MatchingRuleAssertion *f_un_mra;
+
+#define f_dn                   f_un.f_un_dn
+#define f_desc                 f_un.f_un_desc
+#define f_ava                  f_un.f_un_ava
+#define f_av_desc              f_un.f_un_ava->aa_desc
+#define f_av_value             f_un.f_un_ava->aa_value
+#define f_sub                  f_un.f_un_ssa
+#define f_sub_desc             f_un.f_un_ssa->sa_desc
+#define f_sub_initial  f_un.f_un_ssa->sa_initial
+#define f_sub_any              f_un.f_un_ssa->sa_any
+#define f_sub_final            f_un.f_un_ssa->sa_final
+#define f_mra                  f_un.f_un_mra
+#define f_mr_rule              f_un.f_un_mra->ma_rule
+#define f_mr_desc              f_un.f_un_mra->ma_desc
+#define f_mr_value             f_un.f_un_mra->ma_value
+#define        f_mr_dnaddrs    f_un.f_un_mra->ma_dnattrs
 
                /* and, or, not */
-               struct slap_filter      *f_un_complex;
-
-               /* substrings */
-               struct sub {
-                       char    *f_un_sub_type;
-                       char    *f_un_sub_initial;
-                       char    **f_un_sub_any;
-                       char    *f_un_sub_final;
-               } f_un_sub;
+               struct slap_filter *f_un_complex;
        } f_un;
 
-#define f_dn           f_un.f_un_type  /* used for DN indices */
-#define f_type         f_un.f_un_type
-#define f_ava          f_un.f_un_ava
-#define f_avtype       f_un.f_un_ava.ava_type
-#define f_avvalue      f_un.f_un_ava.ava_value
-#define f_mra          f_un.f_un_mra
-#define f_mrtype       f_un.f_un_mra.mra_type
-#define f_mrvalue      f_un.f_un_mra.mra_value
-#define        f_mrdnaddrs     f_un.f_un_mra.mra_dnattrs
+#define f_result       f_un.f_un_result
 #define f_and          f_un.f_un_complex
 #define f_or           f_un.f_un_complex
 #define f_not          f_un.f_un_complex
 #define f_list         f_un.f_un_complex
-#define f_sub          f_un.f_un_sub
-#define f_sub_type     f_un.f_un_sub.f_un_sub_type
-#define f_sub_initial  f_un.f_un_sub.f_un_sub_initial
-#define f_sub_any      f_un.f_un_sub.f_un_sub_any
-#define f_sub_final    f_un.f_un_sub.f_un_sub_final
 
        struct slap_filter      *f_next;
 } Filter;
 
+/* compare routines can return undefined */
+#define SLAPD_COMPARE_UNDEFINED        ((ber_int_t) -1)
+
 /*
- * represents an attribute (type + values + syntax)
+ * represents an attribute (description + values)
  */
 typedef struct slap_attr {
-       char            *a_type;
+       AttributeDescription *a_desc;
        struct berval   **a_vals;
-       int             a_syntax;
        struct slap_attr        *a_next;
 } Attribute;
 
-/*
- * the attr_syntax() routine returns one of these values
- * telling what kind of syntax an attribute supports.
- */
-#define SYNTAX_CIS     0x01    /* case insensitive string              */
-#define SYNTAX_CES     0x02    /* case sensitive string                */
-#define SYNTAX_BIN     0x04    /* binary data                          */
-#define SYNTAX_TEL     0x08    /* telephone number string              */
-#define SYNTAX_DN      0x10    /* dn string                            */
 
 /*
  * the id used in the indexes to refer to an entry
@@ -222,68 +526,150 @@ typedef struct slap_entry {
        void*   e_private;
 } Entry;
 
+/*
+ * A list of LDAPMods
+ */
+typedef struct slap_mod {
+       int sm_op;
+       AttributeDescription *sm_desc;
+       struct berval **sm_bvalues;
+} Modification;
+
+typedef struct slap_mod_list {
+       Modification sml_mod;
+#define sml_op         sml_mod.sm_op
+#define sml_desc       sml_mod.sm_desc
+#define sml_bvalues    sml_mod.sm_bvalues
+       struct slap_mod_list *sml_next;
+} Modifications;
+
+typedef struct slap_ldap_modlist {
+       LDAPMod ml_mod;
+       struct slap_ldap_modlist *ml_next;
+#define ml_op          ml_mod.mod_op
+#define ml_type                ml_mod.mod_type
+#define ml_values      ml_mod.mod_values
+#define ml_bvalues     ml_mod.mod_bvalues
+} LDAPModList;
+
 /*
  * represents an access control list
  */
 
+typedef enum slap_access_e {
+       ACL_INVALID_ACCESS = -1,
+       ACL_NONE = 0,
+       ACL_AUTH,
+       ACL_COMPARE,
+       ACL_SEARCH,
+       ACL_READ,
+       ACL_WRITE
+} slap_access_t;
+
+typedef enum slap_control_e {
+       ACL_INVALID_CONTROL     = 0,
+       ACL_STOP,
+       ACL_CONTINUE,
+       ACL_BREAK
+} slap_control_t;
+
+typedef enum slap_style_e {
+       ACL_STYLE_REGEX,
+       ACL_STYLE_BASE,
+       ACL_STYLE_ONE,
+       ACL_STYLE_SUBTREE,
+       ACL_STYLE_CHILDREN
+} slap_style_t;
+
+typedef unsigned long slap_access_mask_t;
+
 /* the "by" part */
 typedef struct slap_access {
+       slap_control_t a_type;
+
+#define ACL_ACCESS2PRIV(access)        (0x01U << (access))
+
+#define ACL_PRIV_NONE                  ACL_ACCESS2PRIV( ACL_NONE )
+#define ACL_PRIV_AUTH                  ACL_ACCESS2PRIV( ACL_AUTH )
+#define ACL_PRIV_COMPARE               ACL_ACCESS2PRIV( ACL_COMPARE )
+#define ACL_PRIV_SEARCH                        ACL_ACCESS2PRIV( ACL_SEARCH )
+#define ACL_PRIV_READ                  ACL_ACCESS2PRIV( ACL_READ )
+#define ACL_PRIV_WRITE                 ACL_ACCESS2PRIV( ACL_WRITE )
+
+#define ACL_PRIV_MASK                  0x00ffUL
+
+/* priv flags */
+#define ACL_PRIV_LEVEL                 0x1000UL
+#define ACL_PRIV_ADDITIVE              0x2000UL
+#define ACL_PRIV_SUBSTRACTIVE  0x4000UL
+
+/* invalid privs */
+#define ACL_PRIV_INVALID               0x0UL
+
+#define ACL_PRIV_ISSET(m,p)            (((m) & (p)) == (p))
+#define ACL_PRIV_ASSIGN(m,p)   do { (m)  =  (p); } while(0)
+#define ACL_PRIV_SET(m,p)              do { (m) |=  (p); } while(0)
+#define ACL_PRIV_CLR(m,p)              do { (m) &= ~(p); } while(0)
 
-#define ACL_NONE               0x0001
-#define ACL_AUTH               0x0004
-#define ACL_COMPARE            0x0008
-#define ACL_SEARCH             0x0010
-#define ACL_READ               0x0020
-#define ACL_WRITE              0x0040
-#define ACL_PRIV_MASK  0x00ff
-
-#define ACL_SELF               0x4000
-#define ACL_INVALID            (-1)
-
-#define ACL_IS(a,lvl)  (((a) & (lvl)) == (lvl))
-
-#define ACL_IS_NONE(a)         ACL_IS((a),ACL_SELF)
-#define ACL_IS_AUTH(a)         ACL_IS((a),ACL_AUTH)
-#define ACL_IS_COMPARE(a)      ACL_IS((a),ACL_COMPARE)
-#define ACL_IS_SEARCH(a)       ACL_IS((a),ACL_SEARCH)
-#define ACL_IS_READ(a)         ACL_IS((a),ACL_READ)
-#define ACL_IS_WRITE(a)                ACL_IS((a),ACL_WRITE)
-#define ACL_IS_SELF(a)         ACL_IS((a),ACL_SELF)
-#define ACL_IS_INVALID(a)      ((a) == ACL_INVALID)
-
-#define ACL_CLR(a)                     ((a) = 0)
-#define ACL_SET(a,lvl)         ((a) |= (lvl))
-#define ACL_SET_NONE(a)                ACL_SET((a),ACL_SELF)
-#define ACL_SET_AUTH(a)                ACL_SET((a),ACL_AUTH)
-#define ACL_SET_COMPARE(a)     ACL_SET((a),ACL_COMPARE)
-#define ACL_SET_SEARCH(a)      ACL_SET((a),ACL_SEARCH)
-#define ACL_SET_READ(a)                ACL_SET((a),ACL_READ)
-#define ACL_SET_WRITE(a)       ACL_SET((a),ACL_WRITE)
-#define ACL_SET_SELF(a)                ACL_SET((a),ACL_SELF)
-#define ACL_SET_INVALID(a)     ((a) = ACL_INVALID)
-
-#define        ACL_PRIV(a)                     ((a) & ACL_PRIV_MASK)
-#define ACL_GRANT(a,lvl)       (ACL_PRIV(a) >= (lvl))
-
-       int                     a_access;
+#define ACL_INIT(m)                            ACL_PRIV_ASSIGN(m, ACL_PRIV_NONE)
+#define ACL_INVALIDATE(m)              ACL_PRIV_ASSIGN(m, ACL_PRIV_INVALID)
 
+#define ACL_GRANT(m,a)                 ACL_PRIV_ISSET((m),ACL_ACCESS2PRIV(a))
+
+#define ACL_IS_INVALID(m)              ((m) == ACL_PRIV_INVALID)
+
+#define ACL_IS_LEVEL(m)                        ACL_PRIV_ISSET((m),ACL_PRIV_LEVEL)
+#define ACL_IS_ADDITIVE(m)             ACL_PRIV_ISSET((m),ACL_PRIV_ADDITIVE)
+#define ACL_IS_SUBTRACTIVE(m)  ACL_PRIV_ISSET((m),ACL_PRIV_SUBSTRACTIVE)
+
+#define ACL_LVL_NONE                   (ACL_PRIV_NONE|ACL_PRIV_LEVEL)
+#define ACL_LVL_AUTH                   (ACL_PRIV_AUTH|ACL_LVL_NONE)
+#define ACL_LVL_COMPARE                        (ACL_PRIV_COMPARE|ACL_LVL_AUTH)
+#define ACL_LVL_SEARCH                 (ACL_PRIV_SEARCH|ACL_LVL_COMPARE)
+#define ACL_LVL_READ                   (ACL_PRIV_READ|ACL_LVL_SEARCH)
+#define ACL_LVL_WRITE                  (ACL_PRIV_WRITE|ACL_LVL_READ)
+
+#define ACL_LVL(m,l)                   (((m)&ACL_PRIV_MASK) == ((l)&ACL_PRIV_MASK))
+#define ACL_LVL_IS_NONE(m)             ACL_LVL((m),ACL_LVL_NONE)
+#define ACL_LVL_IS_AUTH(m)             ACL_LVL((m),ACL_LVL_AUTH)
+#define ACL_LVL_IS_COMPARE(m)  ACL_LVL((m),ACL_LVL_COMPARE)
+#define ACL_LVL_IS_SEARCH(m)   ACL_LVL((m),ACL_LVL_SEARCH)
+#define ACL_LVL_IS_READ(m)             ACL_LVL((m),ACL_LVL_READ)
+#define ACL_LVL_IS_WRITE(m)            ACL_LVL((m),ACL_LVL_WRITE)
+
+#define ACL_LVL_ASSIGN_NONE(m)         ACL_PRIV_ASSIGN((m),ACL_LVL_NONE)
+#define ACL_LVL_ASSIGN_AUTH(m)         ACL_PRIV_ASSIGN((m),ACL_LVL_AUTH)
+#define ACL_LVL_ASSIGN_COMPARE(m)      ACL_PRIV_ASSIGN((m),ACL_LVL_COMPARE)
+#define ACL_LVL_ASSIGN_SEARCH(m)       ACL_PRIV_ASSIGN((m),ACL_LVL_SEARCH)
+#define ACL_LVL_ASSIGN_READ(m)         ACL_PRIV_ASSIGN((m),ACL_LVL_READ)
+#define ACL_LVL_ASSIGN_WRITE(m)                ACL_PRIV_ASSIGN((m),ACL_LVL_WRITE)
+
+       slap_access_mask_t      a_mask;
+
+       slap_style_t a_dn_style;
        char            *a_dn_pat;
-       char            *a_dn_at;
+       AttributeDescription    *a_dn_at;
+       int                     a_dn_self;
 
+       slap_style_t a_peername_style;
        char            *a_peername_pat;
+       slap_style_t a_sockname_style;
        char            *a_sockname_pat;
 
+       slap_style_t a_domain_style;
        char            *a_domain_pat;
+       slap_style_t a_sockurl_style;
        char            *a_sockurl_pat;
 
 #ifdef SLAPD_ACI_ENABLED
-       char            *a_aci_at;
+       AttributeDescription    *a_aci_at;
 #endif
 
        /* ACL Groups */
+       slap_style_t a_group_style;
        char            *a_group_pat;
-       char            *a_group_oc;
-       char            *a_group_at;
+       ObjectClass                             *a_group_oc;
+       AttributeDescription    *a_group_at;
 
        struct slap_access      *a_next;
 } Access;
@@ -292,6 +678,7 @@ typedef struct slap_access {
 typedef struct slap_acl {
        /* "to" part: the entries this acl applies to */
        Filter          *acl_filter;
+       slap_style_t acl_dn_style;
        regex_t         acl_dn_re;
        char            *acl_dn_pat;
        char            **acl_attrs;
@@ -303,95 +690,13 @@ typedef struct slap_acl {
 } AccessControl;
 
 /*
- * A list of LDAPMods
- */
-typedef struct ldapmodlist {
-       struct ldapmod ml_mod;
-       struct ldapmodlist *ml_next;
-#define ml_op          ml_mod.mod_op
-#define ml_type                ml_mod.mod_type
-#define ml_values      ml_mod.mod_values
-#define ml_bvalues     ml_mod.mod_bvalues
-} LDAPModList;
-
-/*
- * represents schema information for a database
+ * replog moddn param structure
  */
-typedef struct slap_oid_macro {
-       struct slap_oid_macro *next;
-       char *name;
-       char *oid;
-       int oidlen;
-} OidMacro;
-
-typedef int slap_syntax_check_func LDAP_P((struct berval * val));
-
-typedef struct slap_syntax {
-       LDAP_SYNTAX                     ssyn_syn;
-       slap_syntax_check_func          *ssyn_check;
-       struct slap_syntax              *ssyn_next;
-} Syntax;
-#define ssyn_oid                       ssyn_syn.syn_oid
-#define ssyn_desc                      ssyn_syn.syn_desc
-
-typedef int slap_mr_normalize_func LDAP_P((struct berval * val, struct berval **normalized));
-typedef int slap_mr_compare_func LDAP_P((struct berval * val1, struct berval * val2));
-
-typedef struct slap_matching_rule {
-       LDAP_MATCHING_RULE              smr_mrule;
-       slap_mr_normalize_func          *smr_normalize;
-       slap_mr_compare_func            *smr_compare;
-       Syntax                          *smr_syntax;
-       struct slap_matching_rule       *smr_next;
-} MatchingRule;
-#define smr_oid                                smr_mrule.mr_oid
-#define smr_names                      smr_mrule.mr_names
-#define smr_desc                       smr_mrule.mr_desc
-#define smr_obsolete                   smr_mrule.mr_obsolete
-#define smr_syntax_oid                 smr_mrule.mr_syntax_oid
-
-typedef struct slap_attribute_type {
-       LDAP_ATTRIBUTE_TYPE             sat_atype;
-       struct slap_attribute_type      *sat_sup;
-       struct slap_attribute_type      **sat_subtypes;
-       MatchingRule                    *sat_equality;
-       MatchingRule                    *sat_ordering;
-       MatchingRule                    *sat_substr;
-       Syntax                          *sat_syntax;
-       /* The next one is created to help in the transition */
-       int                             sat_syntax_compat;
-       struct slap_attribute_type      *sat_next;
-} AttributeType;
-#define sat_oid                        sat_atype.at_oid
-#define sat_names              sat_atype.at_names
-#define sat_desc               sat_atype.at_desc
-#define sat_obsolete           sat_atype.at_obsolete
-#define sat_sup_oid            sat_atype.at_sup_oid
-#define sat_equality_oid       sat_atype.at_equality_oid
-#define sat_ordering_oid       sat_atype.at_ordering_oid
-#define sat_substr_oid         sat_atype.at_substr_oid
-#define sat_syntax_oid         sat_atype.at_syntax_oid
-#define sat_syntax_len         sat_atype.at_syntax_len
-#define sat_single_value       sat_atype.at_single_value
-#define sat_collective         sat_atype.at_collective
-#define sat_no_user_mods       sat_atype.at_no_user_mods
-#define sat_usage              sat_atype.at_usage
-
-typedef struct slap_object_class {
-       LDAP_OBJECT_CLASS               soc_oclass;
-       struct slap_object_class        **soc_sups;
-       AttributeType                   **soc_required;
-       AttributeType                   **soc_allowed;
-       struct slap_object_class        *soc_next;
-} ObjectClass;
-#define soc_oid                        soc_oclass.oc_oid
-#define soc_names              soc_oclass.oc_names
-#define soc_desc               soc_oclass.oc_desc
-#define soc_obsolete           soc_oclass.oc_obsolete
-#define soc_sup_oids           soc_oclass.oc_sup_oids
-#define soc_kind               soc_oclass.oc_kind
-#define soc_at_oids_must       soc_oclass.oc_at_oids_must
-#define soc_at_oids_may                soc_oclass.oc_at_oids_may
+struct replog_moddn {
+       char *newrdn;
+       int     deloldrdn;
+       char *newsup;
+};
 
 /*
  * Backend-info
@@ -401,22 +706,18 @@ typedef struct slap_object_class {
 typedef struct slap_backend_info BackendInfo;  /* per backend type */
 typedef struct slap_backend_db BackendDB;              /* per backend database */
 
-extern int nBackendInfo;
-extern int nBackendDB;
-extern BackendInfo     *backendInfo;
-extern BackendDB       *backendDB;
+LIBSLAPD_F (int) nBackendInfo;
+LIBSLAPD_F (int) nBackendDB;
+LIBSLAPD_F (BackendInfo        *) backendInfo;
+LIBSLAPD_F (BackendDB *) backendDB;
 
-extern int slapMode;   
+LIBSLAPD_F (int) slapMode;     
 #define SLAP_UNDEFINED_MODE    0x0000
 #define SLAP_SERVER_MODE       0x0001
 #define SLAP_TOOL_MODE         0x0002
 #define SLAP_MODE                      0x0003
 
 #define SLAP_TRUNCATE_MODE     0x0100
-#ifdef SLAPD_BDB2
-#define SLAP_TIMED_MODE                0x1000
-#endif
-#define SLAP_TOOLID_MODE    4
 
 /* temporary aliases */
 typedef BackendDB Backend;
@@ -439,9 +740,13 @@ struct slap_backend_db {
 #define                be_modrdn       bd_info->bi_op_modrdn
 #define                be_search       bd_info->bi_op_search
 
+#define                be_extended     bd_info->bi_extended
+
 #define                be_release      bd_info->bi_entry_release_rw
 #define                be_group        bd_info->bi_acl_group
 
+#define                be_controls     bd_info->bi_controls
+
 #define                be_connection_init      bd_info->bi_connection_init
 #define                be_connection_destroy   bd_info->bi_connection_destroy
 
@@ -455,6 +760,12 @@ struct slap_backend_db {
 #define                be_index_attr bd_info->bi_tool_index_attr
 #define                be_index_change bd_info->bi_tool_index_change
 #define                be_sync bd_info->bi_tool_sync
+#endif
+
+#ifdef HAVE_CYRUS_SASL
+#define                be_sasl_authorize bd_info->bi_sasl_authorize
+#define                be_sasl_getsecret bd_info->bi_sasl_getsecret
+#define                be_sasl_putsecret bd_info->bi_sasl_putsecret
 #endif
 
        /* these should be renamed from be_ to bd_ */
@@ -463,16 +774,16 @@ struct slap_backend_db {
        char    **be_suffixAlias; /* pairs of DN suffix aliases and deref values */
        char    *be_root_dn;    /* the magic "root" dn for this db      */
        char    *be_root_ndn;   /* the magic "root" normalized dn for this db   */
-       char    *be_root_pw;    /* the magic "root" password for this db        */
+       struct berval be_root_pw;       /* the magic "root" password for this db        */
        int     be_readonly;    /* 1 => db is in "read only" mode          */
        unsigned int be_max_deref_depth;       /* limit for depth of an alias deref  */
        int     be_sizelimit;   /* size limit for this backend             */
        int     be_timelimit;   /* time limit for this backend             */
        AccessControl *be_acl;  /* access control list for this backend    */
-       int     be_dfltaccess;  /* access given if no acl matches          */
+       slap_access_t   be_dfltaccess;  /* access given if no acl matches          */
        char    **be_replica;   /* replicas of this backend (in master)    */
        char    *be_replogfile; /* replication log file (in master)        */
-       char    *be_update_ndn; /* allowed to make changes (in replicas)   */
+       char    *be_update_ndn; /* allowed to make changes (in replicas) */
        struct berval **be_update_refs; /* where to refer modifying clients to */
        int     be_lastmod;     /* keep track of lastmodified{by,time}     */
 
@@ -481,6 +792,21 @@ struct slap_backend_db {
        void    *be_private;    /* anything the backend database needs     */
 };
 
+struct slap_conn;
+struct slap_op;
+
+typedef int (*SLAP_EXTENDED_FN) LDAP_P((
+    Backend            *be,
+    struct slap_conn           *conn,
+    struct slap_op             *op,
+       const char              *reqoid,
+    struct berval * reqdata,
+       char            **rspoid,
+    struct berval ** rspdata,
+       LDAPControl *** rspctrls,
+       const char **   text,
+       struct berval *** refs ));
+
 struct slap_backend_info {
        char    *bi_type;       /* type of backend */
 
@@ -542,42 +868,49 @@ struct slap_backend_info {
        /* LDAP Operations Handling Routines */
        int     (*bi_op_bind)  LDAP_P(( BackendDB *bd,
                struct slap_conn *c, struct slap_op *o,
-               char *dn, int method, char* mechanism,
+               const char *dn, const char *ndn, int method,
                struct berval *cred, char** edn ));
        int (*bi_op_unbind) LDAP_P((BackendDB *bd,
                struct slap_conn *c, struct slap_op *o ));
        int     (*bi_op_search) LDAP_P((BackendDB *bd,
                struct slap_conn *c, struct slap_op *o,
-               char *base, int scope, int deref,
+               const char *base, const char *nbase,
+               int scope, int deref,
                int slimit, int tlimit,
-               Filter *f, char *filterstr, char **attrs,
-               int attrsonly));
+               Filter *f, const char *filterstr,
+               char **attrs, int attrsonly));
        int     (*bi_op_compare)LDAP_P((BackendDB *bd,
                struct slap_conn *c, struct slap_op *o,
-               char *dn, Ava *ava));
+               const char *dn, const char *ndn,
+               AttributeAssertion *ava));
        int     (*bi_op_modify) LDAP_P((BackendDB *bd,
                struct slap_conn *c, struct slap_op *o,
-               char *dn, LDAPModList *m));
+               const char *dn, const char *ndn, Modifications *m));
        int     (*bi_op_modrdn) LDAP_P((BackendDB *bd,
                struct slap_conn *c, struct slap_op *o,
-               char *dn, char *newrdn, int deleteoldrdn,
-               char *newSuperior));
+               const char *dn, const char *ndn,
+               const char *newrdn, int deleteoldrdn,
+               const char *newSuperior));
        int     (*bi_op_add)    LDAP_P((BackendDB *bd,
                struct slap_conn *c, struct slap_op *o,
                Entry *e));
        int     (*bi_op_delete) LDAP_P((BackendDB *bd,
                struct slap_conn *c, struct slap_op *o,
-               char *dn));
+               const char *dn, const char *ndn));
        int     (*bi_op_abandon) LDAP_P((BackendDB *bd,
                struct slap_conn *c, struct slap_op *o,
                ber_int_t msgid));
 
+       /* Extended Operations Helper */
+       SLAP_EXTENDED_FN bi_extended;
+
        /* Auxilary Functions */
        int     (*bi_entry_release_rw) LDAP_P((BackendDB *bd, Entry *e, int rw));
 
        int     (*bi_acl_group)  LDAP_P((Backend *bd,
                Entry *e, const char *bdn, const char *edn,
-               const char *objectclassValue, const char *groupattrName ));
+               ObjectClass *group_oc,
+               AttributeDescription *group_at ));
 
        int     (*bi_connection_init) LDAP_P((BackendDB *bd,
                struct slap_conn *c));
@@ -591,14 +924,30 @@ struct slap_backend_info {
        ID (*bi_tool_entry_next) LDAP_P(( BackendDB *be ));
        Entry* (*bi_tool_entry_get) LDAP_P(( BackendDB *be, ID id ));
        ID (*bi_tool_entry_put) LDAP_P(( BackendDB *be, Entry *e ));
-       int (*bi_tool_index_attr) LDAP_P(( BackendDB *be, char* type ));
-       int (*bi_tool_index_change) LDAP_P(( BackendDB *be, char* type,
+       int (*bi_tool_index_attr) LDAP_P(( BackendDB *be,
+               AttributeDescription *desc ));
+       int (*bi_tool_index_change) LDAP_P(( BackendDB *be,
+               AttributeDescription *desc,
                struct berval **bv, ID id, int op ));
        int (*bi_tool_sync) LDAP_P(( BackendDB *be ));
 
+#ifdef HAVE_CYRUS_SASL
+       int (*bi_sasl_authorize) LDAP_P(( BackendDB *be,
+               const char *authnid, const char *authzid,
+               const char **canon_authzid, const char **errstr ));
+       int (*bi_sasl_getsecret) LDAP_P(( BackendDB *be,
+               const char *mechanism, const char *authzid,
+               const char *realm, sasl_secret_t **secret ));
+       int (*bi_sasl_putsecret) LDAP_P(( BackendDB *be,
+               const char *mechanism, const char *auth_identity,
+               const char *realm, const sasl_secret_t *secret ));
+#endif /* HAVE_CYRUS_SASL */
+
 #define SLAP_INDEX_ADD_OP              0x0001
 #define SLAP_INDEX_DELETE_OP   0x0002
 
+       char **bi_controls;             /* supported controls */
+
        unsigned int bi_nDB;    /* number of databases of this type */
        void    *bi_private;    /* anything the backend type needs */
 };
@@ -618,10 +967,19 @@ typedef struct slap_op {
        ber_tag_t       o_tag;          /* tag of the request             */
        time_t          o_time;         /* time op was initiated          */
 
-       int             o_bind_in_progress;     /* multi-step bind in progress */
+#ifdef SLAP_AUTHZID
+       /* should only be used for reporting purposes */
+       char    *o_authc_dn;    /* authentication DN */
 
+       /* should be used as the DN of the User */
+       char    *o_authz_dn;    /* authorization DN */
+       char    *o_authz_ndn;   /* authorizaiton NDN */
+
+#else
        char            *o_dn;          /* dn bound when op was initiated */
        char            *o_ndn;         /* normalized dn bound when op was initiated */
+#endif
+
        ber_int_t       o_protocol;     /* version of the LDAP protocol used by client */
        ber_tag_t       o_authtype;     /* auth method used to bind dn    */
                                        /* values taken from ldap.h       */
@@ -666,19 +1024,36 @@ typedef struct slap_conn {
        char            *c_peer_name;   /* peer name (trans=addr:port) */
        char            *c_sock_name;   /* sock name (trans=addr:port) */
 
+       /* only can be changed by binding thread */
+       int             c_sasl_bind_in_progress;        /* multi-op bind in progress */
+       char    *c_sasl_bind_mech;                      /* mech in progress */
 #ifdef HAVE_CYRUS_SASL
-       sasl_conn_t     *c_sasl_context;
+       sasl_conn_t     *c_sasl_bind_context;   /* Cyrus SASL state data */
 #endif
 
-       /* only can be changed by binding thread */
-       int             c_bind_in_progress;     /* multi-op bind in progress */
+       /* authentication backend */
+       Backend *c_authc_backend;
+
+       /* authorization backend - normally same as c_authc_backend */
+       Backend *c_authz_backend;
+
+#ifdef SLAP_AUTHZID
+       /* authentication backend */
+       /* should only be used for reporting purposes */
+       char    *c_authc_dn;    /* authentication DN */
+
+       /* should be used as the DN of the User */
+       char    *c_authz_dn;    /* authorization DN */
+       char    *c_authz_ndn;   /* authorization NDN */
 
+#else
        char    *c_cdn;         /* DN provided by the client */
        char    *c_dn;          /* DN bound to this conn  */
+#endif
+
        ber_int_t       c_protocol;     /* version of the LDAP protocol used by client */
        ber_tag_t       c_authtype;/* auth method used to bind c_dn  */
        char    *c_authmech;    /* SASL mechanism used to bind c_dn */
-       void    *c_authstate;   /* SASL state data */
 
        Operation       *c_ops;                 /* list of operations being processed */
        Operation       *c_pending_ops; /* list of pending operations */
@@ -721,4 +1096,4 @@ LDAP_END_DECL
 
 #include "proto-slap.h"
 
-#endif /* _slap_h_ */
+#endif /* _SLAP_H_ */
diff --git a/servers/slapd/slapd.at.conf b/servers/slapd/slapd.at.conf
deleted file mode 100644 (file)
index 0191d2b..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# $OpenLDAP$
-attribute      photo                                   bin
-attribute      personalsignature                       bin
-attribute      jpegphoto                               bin
-attribute      audio                                   bin
-attribute      labeledurl                              ces
-attribute      ref                                             ces
-attribute      userpassword                            ces
-attribute      telephonenumber                         tel
-attribute      facsimiletelephonenumber        fax     tel
-attribute      pagertelephonenumber            pager   tel
-attribute      homephone                               tel
-attribute      mobiletelephonenumber           mobile  tel
-attribute      aliasedObjectName                       dn
-attribute      member                                  dn
-attribute      owner                                   dn
-attribute      seealso                                 dn
-attribute      manager                                 dn
-attribute      documentauthor                          dn
-attribute      secretary                               dn
-attribute      lastmodifiedby                          dn
-attribute      associatedname                          dn
-attribute      naminglink                              dn
-attribute      reciprocalnaminglink                    dn
-attribute      dn                                      dn
index 59be805b5b31d073ccf51b40dd8718e53769d216..3f3a973e5e52e8025dee567cbd356f2c91565b6a 100644 (file)
@@ -3,27 +3,42 @@
 # See slapd.conf(5) for details on configuration options.
 # This file should NOT be world readable.
 #
-include                %SYSCONFDIR%/slapd.at.conf
-include                %SYSCONFDIR%/slapd.oc.conf
-schemacheck    off
+include                %SYSCONFDIR%/schema/core.schema
 
+# Define global ACLs to disable default read access.
+
+# Do not enable referrals until AFTER you have a working directory
+# service AND an understanding of referrals.
 #referral      ldap://root.openldap.org
 
 pidfile                %LOCALSTATEDIR%/slapd.pid
 argsfile       %LOCALSTATEDIR%/slapd.args
 
+# Load dynamic backend modules
+
+# modulepath   %MODULEDIR%
+# moduleload   back_bdb2.la
+# moduleload   back_ldap.la
+# moduleload   back_ldbm.la
+# moduleload   back_passwd.la
+# moduleload   back_perl.la
+# moduleload   back_shell.la
+# moduleload   back_bdb2.la
+# moduleload   back_tcl.la
+
 #######################################################################
 # ldbm database definitions
 #######################################################################
 
 database       ldbm
-suffix         "dc=your-domain, dc=com"
-#suffix                "o=Your Organization Name, c=US"
-directory      /usr/tmp
-rootdn         "cn=root, dc=your-domain, dc=com"
-#rootdn                "cn=root, o=Your Organization Name, c=US"
-rootpw         secret
+suffix         "dc=my-domain, dc=com"
+#suffix                "o=My Organization Name, c=US"
+rootdn         "cn=Manager, dc=my-domain, dc=com"
+#rootdn                "cn=Manager, o=My Organization Name, c=US"
 # cleartext passwords, especially for the rootdn, should
 # be avoid.  See slapd.conf(5) for details.
-
-
+rootpw         secret
+# database directory
+# this directory MUST exist prior to running slapd AND 
+# should only be accessable by the slapd/tools  Mode 700 recommended.
+directory      %LOCALSTATEDIR%/openldap-ldbm
diff --git a/servers/slapd/slapd.dsp b/servers/slapd/slapd.dsp
new file mode 100644 (file)
index 0000000..c0b8dc9
--- /dev/null
@@ -0,0 +1,161 @@
+# Microsoft Developer Studio Project File - Name="slapd" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=slapd - Win32 Single Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "slapd.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "slapd.mak" CFG="slapd - Win32 Single Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "slapd - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "slapd - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "slapd - Win32 Single Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "slapd - Win32 Single Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "slapd - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\Release"
+# PROP Intermediate_Dir "..\..\Release\slapd"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 advapi32.lib sasl.lib hs_regex.lib libdb.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\Release"
+
+!ELSEIF  "$(CFG)" == "slapd - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\Debug"
+# PROP Intermediate_Dir "..\..\Debug\slapd"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 advapi32.lib hs_regex.lib libdb.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\Debug"
+
+!ELSEIF  "$(CFG)" == "slapd - Win32 Single Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "slapd___"
+# PROP BASE Intermediate_Dir "slapd___"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\SDebug"
+# PROP Intermediate_Dir "..\..\SDebug\slapd"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 hs_regexd.lib libdbs.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 hs_regex.lib libdb.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\SDebug"
+
+!ELSEIF  "$(CFG)" == "slapd - Win32 Single Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "slapd__0"
+# PROP BASE Intermediate_Dir "slapd__0"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\SRelease"
+# PROP Intermediate_Dir "..\..\SRelease\slapd"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 hs_regex.lib libdb.lib wsock32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 sasl.lib hs_regex.lib libdb.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\SRelease"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "slapd - Win32 Release"
+# Name "slapd - Win32 Debug"
+# Name "slapd - Win32 Single Debug"
+# Name "slapd - Win32 Single Release"
+# Begin Source File
+
+SOURCE=.\main.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\nt_svc.c
+# End Source File
+# Begin Source File
+
+SOURCE=".\proto-slap.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\result.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\slap.h
+# End Source File
+# End Target
+# End Project
diff --git a/servers/slapd/slapd.oc.conf b/servers/slapd/slapd.oc.conf
deleted file mode 100644 (file)
index c74c1f8..0000000
+++ /dev/null
@@ -1,924 +0,0 @@
-# $OpenLDAP$
-
-objectclass top
-       requires
-               objectClass
-
-objectclass ldapsubentry
-       requires
-               objectclass
-
-objectclass alias
-       requires
-               aliasedObjectName,
-               objectClass
-
-objectclass referral
-       requires
-               ref,
-               objectClass
-
-objectclass dcobject
-       requires
-               objectClass,
-               dc
-
-objectclass uidobject
-       requires
-               objectClass,
-               uid
-
-objectclass country
-       requires
-               objectClass,
-               c
-       allows
-               searchGuide,
-               description
-
-objectclass locality
-       requires
-               objectClass
-       allows
-               description,
-               l,
-               searchGuide,
-               seeAlso,
-               st,
-               streetAddress
-
-objectclass organization
-       requires
-               objectClass,
-               o
-       allows
-               businessCategory,
-               description,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               l,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               searchGuide,
-               seeAlso,
-               st,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               userPassword,
-               x121Address
-
-objectclass organizationalUnit
-       requires
-               objectClass,
-               ou
-       allows
-               businessCategory,
-               description,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               l,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               searchGuide,
-               seeAlso,
-               st,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               userPassword,
-               x121Address
-
-objectclass person
-       requires
-               objectClass,
-               sn,
-               cn
-       allows
-               description,
-               seeAlso,
-               telephoneNumber,
-               userPassword
-
-objectclass organizationalPerson
-       requires
-               objectClass,
-               sn,
-               cn
-       allows
-               description,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               l,
-               ou,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               seeAlso,
-               st,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               title,
-               userPassword,
-               x121Address
-
-objectclass organizationalRole
-       requires
-               objectClass,
-               cn
-       allows
-               description,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               l,
-               ou,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               roleOccupant,
-               seeAlso,
-               st,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               x121Address
-
-objectclass groupOfNames
-       requires
-               objectClass,
-               member,
-               cn
-       allows
-               businessCategory,
-               description,
-               o,
-               ou,
-               owner,
-               seeAlso
-
-objectclass residentialPerson
-       requires
-               objectClass,
-               sn,
-               cn,
-               l
-       allows
-               businessCategory,
-               description,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               l,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               seeAlso,
-               st,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               userPassword,
-               x121Address
-
-objectclass applicationProcess
-       requires
-               objectClass,
-               cn
-       allows
-               description,
-               l,
-               ou,
-               seeAlso
-
-objectclass applicationEntity
-       requires
-               objectClass,
-               presentationAddress,
-               cn
-       allows
-               description,
-               l,
-               o,
-               ou,
-               seeAlso,
-               supportedApplicationContext
-
-objectclass dSA
-       requires
-               objectClass,
-               presentationAddress,
-               cn
-       allows
-               knowledgeInformation
-
-objectclass device
-       requires
-               objectClass,
-               cn
-       allows
-               description,
-               l,
-               o,
-               ou,
-               owner,
-               seeAlso,
-               serialNumber
-
-objectclass strongAuthenticationUser
-       requires
-               objectClass,
-               userCertificate
-
-objectclass certificationAuthority
-       requires
-               objectClass,
-               authorityRevocationList,
-               certificateRevocationList,
-               cACertificate
-       allows
-               crossCertificatePair
-
-objectclass pilotObject
-       requires
-               objectClass
-       allows
-               audio,
-               dITRedirect,
-               info,
-               jpegPhoto,
-               lastModifiedBy,
-               lastModifiedTime,
-               manager,
-               photo,
-               uniqueIdentifier
-
-objectclass newPilotPerson
-       requires
-               objectClass,
-               sn,
-               cn
-       allows
-               businessCategory,
-               description,
-               drink,
-               homePhone,
-               homePostalAddress,
-               janetMailbox,
-               mail,
-               mailPreferenceOption,
-               mobile,
-               organizationalStatus,
-               otherMailbox,
-               pager,
-               personalSignature,
-               personalTitle,
-               preferredDeliveryMethod,
-               roomNumber,
-               secretary,
-               seeAlso,
-               telephoneNumber,
-               textEncodedORaddress,
-               uid,
-               userClass,
-               userPassword
-
-objectclass account
-       requires
-               objectClass,
-               uid
-       allows
-               description,
-               host,
-               l,
-               o,
-               ou,
-               seeAlso
-
-objectclass document
-       requires
-               objectClass,
-               documentIdentifier
-       allows
-               abstract,
-               audio,
-               authorCN,
-               authorSN,
-               cn,
-               dITRedirect,
-               description,
-               documentAuthor,
-               documentLocation,
-               documentPublisher,
-               documentStore,
-               documentTitle,
-               documentVersion,
-               info,
-               jpegPhoto,
-               keywords,
-               l,
-               lastModifiedBy,
-               lastModifiedTime,
-               manager,
-               o,
-               obsoletedByDocument,
-               obsoletesDocument,
-               ou,
-               photo,
-               seeAlso,
-               subject,
-               uniqueIdentifier,
-               updatedByDocument,
-               updatesDocument
-
-objectclass room
-       requires
-               objectClass,
-               cn
-       allows
-               description,
-               roomNumber,
-               seeAlso,
-               telephoneNumber
-
-objectclass documentSeries
-       requires
-               objectClass,
-               cn
-       allows
-               description,
-               l,
-               o,
-               ou,
-               seeAlso,
-               telephoneNumber
-
-objectclass domain
-       requires
-               objectClass,
-               dc
-       allows
-               associatedName,
-               businessCategory,
-               description,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               l,
-               o,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               searchGuide,
-               seeAlso,
-               st,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               userPassword,
-               x121Address
-
-objectclass rFC822localPart
-       requires
-               objectClass,
-               dc
-       allows
-               associatedName,
-               businessCategory,
-               cn,
-               description,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               l,
-               o,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               searchGuide,
-               seeAlso,
-               sn,
-               st,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               userPassword,
-               x121Address
-
-objectclass dNSDomain
-       requires
-               objectClass,
-               dc
-       allows
-               associatedName,
-               businessCategory,
-               dNSRecord,
-               description,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               l,
-               o,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               searchGuide,
-               seeAlso,
-               st,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               userPassword,
-               x121Address
-
-objectclass domainRelatedObject
-       requires
-               objectClass,
-               associatedDomain
-
-objectclass friendlyCountry
-       requires
-               objectClass,
-               c,
-               co
-       allows
-               description,
-               searchGuide
-
-objectclass simpleSecurityObject
-       requires
-               objectClass,
-               userPassword
-
-objectclass pilotOrganization
-       requires
-               objectClass,
-               ou,
-               o
-       allows
-               buildingName,
-               businessCategory,
-               description,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               l,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               searchGuide,
-               seeAlso,
-               st,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               userPassword,
-               x121Address
-
-objectclass nadfObject
-       requires
-               objectClass
-       allows
-               lastModifiedTime,
-               nadfSearchGuide,
-               supplementaryInformation
-
-objectclass usStateOrEquivalent
-       requires
-               objectClass,
-               st,
-               fipsStateAlphaCode,
-               fipsStateNumericCode,
-               l
-       allows
-               description,
-               lastModifiedTime,
-               nadfSearchGuide,
-               searchGuide,
-               seeAlso,
-               streetAddress,
-               supplementaryInformation
-
-objectclass usPlace
-       requires
-               objectClass,
-               fips55,
-               l
-       allows
-               description,
-               lastModifiedTime,
-               nadfSearchGuide,
-               searchGuide,
-               seeAlso,
-               st,
-               streetAddress,
-               supplementaryInformation
-
-objectclass usCountyOrEquivalent
-       requires
-               objectClass,
-               fipsCountyNumericCode,
-               fips55,
-               l
-       allows
-               description,
-               lastModifiedTime,
-               nadfSearchGuide,
-               searchGuide,
-               seeAlso,
-               st,
-               streetAddress,
-               supplementaryInformation
-
-objectclass ansiOrgObject
-       requires
-               objectClass,
-               ansiOrgNumericCode
-
-objectclass nadfApplicationEntity
-       requires
-               objectClass,
-               supportedApplicationContext,
-               presentationAddress,
-               cn
-       allows
-               description,
-               l,
-               o,
-               ou,
-               seeAlso,
-               supportedApplicationContext
-
-objectclass nadfADDMD
-       requires
-               objectClass,
-               ad
-       allows
-               businessCategory,
-               description,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               l,
-               lastModifiedTime,
-               nadfSearchGuide,
-               o,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               searchGuide,
-               seeAlso,
-               st,
-               streetAddress,
-               supplementaryInformation,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               userPassword,
-               x121Address
-
-objectclass publicObject
-       requires
-               objectClass,
-               namingLink
-
-objectclass providerObject
-       requires
-               objectClass,
-               reciprocalNamingLink
-
-objectclass nationalObject
-       requires
-               objectClass,
-               c
-
-objectclass fips55Object
-       requires
-               objectClass,
-               fips55
-       allows
-               st
-
-objectclass restaurant
-       requires
-               objectClass,
-               description,
-               telephoneNumber,
-               streetAddress
-       allows
-               Ambiance,
-               Appearance,
-               Average-price,
-               Closed,
-               CreditCardsAccepted,
-               Kosher,
-               Max-price,
-               MaximumInParty,
-               Min-price,
-               Music,
-               NotRecommended,
-               OutdoorSeating,
-               Parking,
-               QualityOfService,
-               QualityPriceRatio,
-               Recommended,
-               RecommendedBy,
-               Reservation,
-               ServiceSpeed,
-               Specialty,
-               Taux-de-frequentation,
-               TransportationMeans,
-               facsimileTelephoneNumber,
-               postalAddress
-
-objectclass kerberosSecurityObject
-       requires
-               objectClass,
-               krbName
-
-objectclass umichPerson
-       requires
-               objectClass,
-               sn,
-               cn,
-               universityID
-       allows
-               affiliationCode,
-               audio,
-               businessCategory,
-               classStanding,
-               description,
-               destinationIndicator,
-               doNotDelete,
-               doNotMove,
-               drink,
-               expire,
-               facsimileTelephoneNumber,
-               homePhone,
-               homePostalAddress,
-               internationaliSDNNumber,
-               janetMailbox,
-               jpegPhoto,
-               keepNames,
-               krbName,
-               l,
-               labeledURL,
-               mail,
-               mailPreferenceOption,
-               memberOfGroup,
-               mobile,
-               multiLineDescription,
-               noBatchUpdates,
-               notRegistered,
-               notice,
-               onVacation,
-               organizationalStatus,
-               otherMailbox,
-               ou,
-               pager,
-               personalSignature,
-               personalTitle,
-               photo,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               proxy,
-               registeredAddress,
-               registrationStatus,
-               roomNumber,
-               secretary,
-               seeAlso,
-               st,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               textEncodedORaddress,
-               title,
-               uid,
-               updateSource,
-               userCertificate,
-               userClass,
-               userPassword,
-               vacationMessage,
-               x121Address,
-               xacl
-
-objectclass rfc822MailGroup
-       requires
-               objectClass,
-               owner,
-               cn
-       allows
-               associatedDomain,
-               autoMgt,
-               description,
-               destinationIndicator,
-               errorsTo,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               joinable,
-               krbName,
-               labeledURL,
-               mail,
-               member,
-               memberOfGroup,
-               moderator,
-               multiLineDescription,
-               notice,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               requestsTo,
-               rfc822ErrorsTo,
-               rfc822RequestsTo,
-               seeAlso,
-               streetAddress,
-               suppressNoEmailError,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               userPassword,
-               x121Address,
-               xacl
-
-objectclass image
-       requires
-               objectClass,
-               cn
-       allows
-               citation,
-               copyright,
-               imageFiles,
-               jpegPhoto,
-               keywords,
-               multiLineDescription,
-               owner,
-               predominantColor
-
-objectclass imageFile
-       requires
-               objectClass,
-               cn
-       allows
-               colorDepth,
-               documentLocation,
-               fileFormat,
-               fileSize,
-               height,
-               resolution,
-               seeAlso,
-               width
-
-objectclass service
-       requires
-               objectClass,
-               cn
-       allows
-               category,
-               dependentUpon,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               hoursOfOperation,
-               internationaliSDNNumber,
-               jpegPhoto,
-               keywords,
-               labeledURL,
-               mail,
-               multiLineDescription,
-               owner,
-               physicalDeliveryOfficeName,
-               platform,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               product,
-               provider,
-               ratingDescription,
-               ratingTime,
-               registeredAddress,
-               seeAlso,
-               serviceArea,
-               serviceRating,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               x121Address
-
-objectclass umichDocument
-       requires
-               objectClass,
-               documentIdentifier
-       allows
-               abstract,
-               audio,
-               authorCN,
-               authorSN,
-               category,
-               cn,
-               dITRedirect,
-               description,
-               documentAuthor,
-               documentAvailable,
-               documentLocation,
-               documentPublisher,
-               documentSeriesTitle,
-               documentStore,
-               documentTitle,
-               documentVersion,
-               info,
-               jpegPhoto,
-               keywords,
-               l,
-               labeledURL,
-               lastModifiedBy,
-               lastModifiedTime,
-               manager,
-               multiLineAbstract,
-               o,
-               obsoletedByDocument,
-               obsoletesDocument,
-               ou,
-               owner,
-               photo,
-               platform,
-               product,
-               seeAlso,
-               serviceArea,
-               subject,
-               uniqueIdentifier,
-               updatedByDocument,
-               updatesDocument
-
-objectclass documentDescription
-       requires
-               objectClass,
-               cn
-       allows
-               labeledURL,
-               multiLineDescription,
-               owner
-
-objectclass labeledURLObject
-       requires
-               objectClass
-       allows
-               labeledURL
-
-objectclass cacheObject
-       requires
-               objectClass
-       allows
-               ttl
diff --git a/servers/slapd/starttls.c b/servers/slapd/starttls.c
new file mode 100644 (file)
index 0000000..b607c68
--- /dev/null
@@ -0,0 +1,96 @@
+/* $OpenLDAP$ */
+/* 
+ * Copyright 1999-2000 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted only
+ * as authorized by the OpenLDAP Public License.  A copy of this
+ * license is available at http://www.OpenLDAP.org/license.html or
+ * in file LICENSE in the top-level directory of the distribution.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+
+#ifdef HAVE_TLS
+
+int
+starttls_extop (
+       SLAP_EXTOP_CALLBACK_FN cb,
+       Connection *conn,
+       Operation *op,
+       const char * reqoid,
+       struct berval * reqdata,
+       char ** rspoid,
+       struct berval ** rspdata,
+       LDAPControl ***rspctrls,
+       const char ** text,
+       struct berval *** refs )
+{
+       void *ctx;
+       int rc;
+
+       if ( reqdata != NULL ) {
+               /* no request data should be provided */
+               *text = "no request data expected";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       /* acquire connection lock */
+       ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+
+       /* can't start TLS if it is already started */
+       if (conn->c_is_tls != 0) {
+               *text = "TLS already started";
+               rc = LDAP_OPERATIONS_ERROR;
+               goto done;
+       }
+
+       /* fail if TLS could not be initialized */
+       if (ldap_pvt_tls_get_option(NULL, LDAP_OPT_X_TLS_CERT, &ctx) != 0
+               || ctx == NULL)
+       {
+               if (default_referral != NULL) {
+                       /* caller will put the referral in the result */
+                       rc = LDAP_REFERRAL;
+                       goto done;
+               }
+
+               *text = "Could not initialize TLS";
+               rc = LDAP_UNAVAILABLE;
+               goto done;
+       }
+
+       /* can't start TLS if there are other op's around */
+       if (( conn->c_ops != NULL &&
+                       (conn->c_ops != op || op->o_next != NULL)) ||
+               ( conn->c_pending_ops != NULL))
+       {
+               *text = "cannot start TLS when operations our outstanding";
+               rc = LDAP_OPERATIONS_ERROR;
+               goto done;
+       }
+
+    conn->c_is_tls = 1;
+    conn->c_needs_tls_accept = 1;
+
+    rc = LDAP_SUCCESS;
+
+done:
+       /* give up connection lock */
+       ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+
+       /*
+        * RACE CONDITION: we give up lock before sending result
+        * Should be resolved by reworking connection state, not
+        * by moving send here (so as to ensure proper TLS sequencing)
+        */
+
+       return rc;
+}
+
+#endif /* HAVE_TLS */
index cc98593519548c68ed085d21eaa82616b8157f37..f21ffd2d7fb13a47883c107b1ec0cb281fdaa894 100644 (file)
@@ -1,7 +1,7 @@
 /* str2filter.c - parse an rfc 1588 string filter */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 #include "slap.h"
 #include <ldap_pvt.h>
 
-static char    *find_matching_paren(char *s);
-static Filter  *str2list(char *str, long unsigned int ftype);
-static Filter  *str2simple(char *str);
-static int     str2subvals(char *val, Filter *f);
+static char    *find_matching_paren( const char *s );
+static Filter  *str2list( const char *str, long unsigned int ftype);
+static Filter  *str2simple( const char *str);
+static int     str2subvals( const char *val, Filter *f);
 
 Filter *
-str2filter( char *str )
+str2filter( const char *str )
 {
        Filter  *f = NULL;
        char    *end, *freeme;
@@ -97,7 +97,7 @@ str2filter( char *str )
  */
 
 static Filter *
-str2list( char *str, unsigned long ftype )
+str2list( const char *str, unsigned long ftype )
 {
        Filter  *f;
        Filter  **fp;
@@ -140,19 +140,22 @@ str2list( char *str, unsigned long ftype )
 }
 
 static Filter *
-str2simple( char *str )
+str2simple( const char *str )
 {
        Filter          *f;
        char            *s;
        char            *value, savechar;
+       int                     rc;
+       const char              *text;
 
        Debug( LDAP_DEBUG_FILTER, "str2simple \"%s\"\n", str, 0, 0 );
 
        if ( (s = strchr( str, '=' )) == NULL ) {
                return( NULL );
        }
-       value = s + 1;
-       *s-- = '\0';
+       value = &s[1];
+
+       *s-- = '\0';    /* we shouldn't be mucking with str */
        savechar = *s;
 
        f = (Filter *) ch_calloc( 1, sizeof(Filter) );
@@ -170,6 +173,12 @@ str2simple( char *str )
                f->f_choice = LDAP_FILTER_APPROX;
                *s = '\0';
                break;
+       case ':':
+               f->f_choice = LDAP_FILTER_EXT;
+               *s = '\0';
+               return NULL;
+               break;
+
        default:
                if ( ldap_pvt_find_wildcard( value ) == NULL ) {
                        f->f_choice = LDAP_FILTER_EQUALITY;
@@ -177,7 +186,13 @@ str2simple( char *str )
                        f->f_choice = LDAP_FILTER_PRESENT;
                } else {
                        f->f_choice = LDAP_FILTER_SUBSTRINGS;
-                       f->f_sub_type = ch_strdup( str );
+                       f->f_sub = ch_calloc( 1, sizeof( SubstringsAssertion ) );
+                       rc = slap_str2ad( str, &f->f_sub_desc, &text );
+                       if( rc != LDAP_SUCCESS ) {
+                               filter_free( f );
+                               *(value-1) = '=';
+                               return NULL;
+                       }
                        if ( str2subvals( value, f ) != 0 ) {
                                filter_free( f );
                                *(value-1) = '=';
@@ -190,40 +205,62 @@ str2simple( char *str )
        }
 
        if ( f->f_choice == LDAP_FILTER_PRESENT ) {
-               f->f_type = ch_strdup( str );
+               rc = slap_str2ad( str, &f->f_desc, &text );
+               if( rc != LDAP_SUCCESS ) {
+                       filter_free( f );
+                       *(value-1) = '=';
+                       return NULL;
+               }
        } else {
-               f->f_avtype = ch_strdup( str );
-               f->f_avvalue.bv_val = ch_strdup( value );
-               ldap_pvt_filter_value_unescape( f->f_avvalue.bv_val );
-               f->f_avvalue.bv_len = strlen( value );
+               char *tmp;
+
+               f->f_ava = ch_calloc( 1, sizeof( AttributeAssertion ) );
+               f->f_av_desc = NULL;
+               rc = slap_str2ad( str, &f->f_av_desc, &text );
+               if( rc != LDAP_SUCCESS ) {
+                       filter_free( f );
+                       *(value-1) = '=';
+                       return NULL;
+               }
+
+               tmp = ch_strdup( value );
+               ldap_pvt_filter_value_unescape( tmp );
+               f->f_av_value = ber_bvstr( tmp );
        }
 
        *s = savechar;
        *(value-1) = '=';
+
        return( f );
 }
 
 static int
-str2subvals( char *val, Filter *f )
+str2subvals( const char *in, Filter *f )
 {
-       char    *nextstar, *freeme;
+       char    *nextstar, *val, *freeme;
        int     gotstar;
 
-       Debug( LDAP_DEBUG_FILTER, "str2subvals \"%s\"\n", val, 0, 0 );
+       Debug( LDAP_DEBUG_FILTER, "str2subvals \"%s\"\n", in, 0, 0 );
 
-       val = freeme = ch_strdup( val );
+       if( in == NULL ) return 0;
+
+       val = freeme = ch_strdup( in );
        gotstar = 0;
-       while ( val != NULL && *val ) {
+
+       while ( *val ) {
                if ( (nextstar = ldap_pvt_find_wildcard( val )) != NULL )
                        *nextstar++ = '\0';
 
                ldap_pvt_filter_value_unescape( val );
+
                if ( gotstar == 0 ) {
-                       f->f_sub_initial = ch_strdup( val );
+                       f->f_sub_initial = ber_bvstrdup( val );
+
                } else if ( nextstar == NULL ) {
-                       f->f_sub_final = ch_strdup( val );
+                       f->f_sub_final = ber_bvstrdup( val );
+
                } else {
-                       charray_add( &f->f_sub_any, val );
+                       charray_add( (char ***) &f->f_sub_any, (char *) ber_bvstrdup( val ) );
                }
 
                gotstar = 1;
@@ -240,7 +277,7 @@ str2subvals( char *val, Filter *f )
  */
 
 static char *
-find_matching_paren( char *s )
+find_matching_paren( const char *s )
 {
        int     balance, escape;
 
@@ -254,7 +291,7 @@ find_matching_paren( char *s )
                                balance--;
                }
                if ( balance == 0 ) {
-                       return( s );
+                       return (char *) s;
                }
                if ( *s == '\\' && ! escape )
                        escape = 1;
@@ -262,5 +299,5 @@ find_matching_paren( char *s )
                        escape = 0;
        }
 
-       return( NULL );
+       return NULL;
 }
index 2e4120e8ddbb3fa5d4a69c18747c2bd3f15bd0a5..848364897b679808a6ff9db80f4ebd94d7cf57a2 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1999-2000 The OpenLDAP Foundation, All Rights Reserved.
  *
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file in the top level
  * directory of this package.
@@ -50,7 +50,7 @@ char *suffix_alias(
                        /* alias is longer than dn */
                        continue;
                } else if ( diff > 0 ) {
-                       if ( ! DNSEPARATOR(dn[diff-1]) ) {
+                       if ( ! DN_SEPARATOR(dn[diff-1]) ) {
                                /* boundary is not at a DN separator */
                                continue;
                        }
diff --git a/servers/slapd/syntax.c b/servers/slapd/syntax.c
new file mode 100644 (file)
index 0000000..52521da
--- /dev/null
@@ -0,0 +1,198 @@
+/* syntax.c - routines to manage syntax definitions */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/ctype.h>
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "ldap_pvt.h"
+
+
+struct sindexrec {
+       char            *sir_name;
+       Syntax          *sir_syn;
+};
+
+static Avlnode *syn_index = NULL;
+static Syntax *syn_list = NULL;
+
+static int
+syn_index_cmp(
+    struct sindexrec   *sir1,
+    struct sindexrec   *sir2
+)
+{
+       return (strcmp( sir1->sir_name, sir2->sir_name ));
+}
+
+static int
+syn_index_name_cmp(
+    char               *name,
+    struct sindexrec   *sir
+)
+{
+       return (strcmp( name, sir->sir_name ));
+}
+
+Syntax *
+syn_find( const char *synname )
+{
+       struct sindexrec        *sir = NULL;
+
+       if ( (sir = (struct sindexrec *) avl_find( syn_index, synname,
+            (AVL_CMP) syn_index_name_cmp )) != NULL ) {
+               return( sir->sir_syn );
+       }
+       return( NULL );
+}
+
+Syntax *
+syn_find_desc( const char *syndesc, int *len )
+{
+       Syntax          *synp;
+
+       for (synp = syn_list; synp; synp = synp->ssyn_next)
+               if ((*len = dscompare( synp->ssyn_syn.syn_desc, syndesc, '{')))
+                       return synp;
+       return( NULL );
+}
+
+static int
+syn_insert(
+    Syntax             *ssyn,
+    const char         **err
+)
+{
+       Syntax          **synp;
+       struct sindexrec        *sir;
+
+       synp = &syn_list;
+       while ( *synp != NULL ) {
+               synp = &(*synp)->ssyn_next;
+       }
+       *synp = ssyn;
+
+       if ( ssyn->ssyn_oid ) {
+               sir = (struct sindexrec *)
+                       ch_calloc( 1, sizeof(struct sindexrec) );
+               sir->sir_name = ssyn->ssyn_oid;
+               sir->sir_syn = ssyn;
+               if ( avl_insert( &syn_index, (caddr_t) sir,
+                                (AVL_CMP) syn_index_cmp,
+                                (AVL_DUP) avl_dup_error ) ) {
+                       *err = ssyn->ssyn_oid;
+                       ldap_memfree(sir);
+                       return SLAP_SCHERR_DUP_SYNTAX;
+               }
+               /* FIX: temporal consistency check */
+               syn_find(sir->sir_name);
+       }
+       return 0;
+}
+
+int
+syn_add(
+    LDAP_SYNTAX                *syn,
+       unsigned flags,
+    slap_syntax_validate_func  *validate,
+    slap_syntax_transform_func *normalize,
+    slap_syntax_transform_func *pretty,
+#ifdef SLAPD_BINARY_CONVERSION
+    slap_syntax_transform_func *ber2str,
+    slap_syntax_transform_func *str2ber,
+#endif
+    const char         **err
+)
+{
+       Syntax          *ssyn;
+       int             code;
+
+       ssyn = (Syntax *) ch_calloc( 1, sizeof(Syntax) );
+
+       memcpy( &ssyn->ssyn_syn, syn, sizeof(LDAP_SYNTAX) );
+
+       ssyn->ssyn_next = NULL;
+
+       ssyn->ssyn_flags = flags;
+       ssyn->ssyn_validate = validate;
+       ssyn->ssyn_normalize = normalize;
+       ssyn->ssyn_pretty = pretty;
+
+#ifdef SLAPD_BINARY_CONVERSION
+       ssyn->ssyn_ber2str = ber2str;
+       ssyn->ssyn_str2ber = str2ber;
+#endif
+
+       code = syn_insert(ssyn, err);
+       return code;
+}
+
+int
+register_syntax(
+       char * desc,
+       unsigned flags,
+       slap_syntax_validate_func *validate,
+       slap_syntax_transform_func *ber2str,
+       slap_syntax_transform_func *str2ber )
+{
+       LDAP_SYNTAX     *syn;
+       int             code;
+       const char      *err;
+
+       syn = ldap_str2syntax( desc, &code, &err, LDAP_SCHEMA_ALLOW_ALL);
+       if ( !syn ) {
+               Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s before %s in %s\n",
+                   ldap_scherr2str(code), err, desc );
+               return( -1 );
+       }
+
+       code = syn_add( syn, flags, validate, ber2str, str2ber, &err );
+       if ( code ) {
+               Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s %s in %s\n",
+                   scherr2str(code), err, desc );
+               return( -1 );
+       }
+
+       return( 0 );
+}
+
+#if defined( SLAPD_SCHEMA_DN )
+
+int
+syn_schema_info( Entry *e )
+{
+       struct berval   val;
+       struct berval   *vals[2];
+       Syntax          *syn;
+
+       AttributeDescription *ad_ldapSyntaxes = slap_schema.si_ad_ldapSyntaxes;
+
+       vals[0] = &val;
+       vals[1] = NULL;
+
+       for ( syn = syn_list; syn; syn = syn->ssyn_next ) {
+               val.bv_val = ldap_syntax2str( &syn->ssyn_syn );
+               if ( val.bv_val == NULL ) {
+                       return -1;
+               }
+               val.bv_len = strlen( val.bv_val );
+#if 0
+               Debug( LDAP_DEBUG_TRACE, "Merging syn [%ld] %s\n",
+              (long) val.bv_len, val.bv_val, 0 );
+#endif
+               attr_merge( e, ad_ldapSyntaxes, vals );
+               ldap_memfree( val.bv_val );
+       }
+       return 0;
+}
+
+#endif
index 5e6c8719ffb00761c615076bf7bdd04c459baa82..2eeff95e5c7f3644d87c4a66ba0f0e6b09e89b4c 100644 (file)
@@ -1,6 +1,8 @@
 # $OpenLDAP$
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 #-----------------------------------------------------------------------------
-# Copyright (c) 1995 Regents of the University of Michigan.
+# Portions Copyright (c) 1995 Regents of the University of Michigan.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms are permitted
@@ -14,7 +16,6 @@
 #
 #-----------------------------------------------------------------------------
 BUILD_LDBM = @BUILD_LDBM@
-BUILD_BDB2 = @BUILD_BDB2@
 BUILD_QUIPU = @BUILD_QUIPU@
 
 LDAP_INCDIR= ../../../include       
@@ -25,37 +26,45 @@ SLAPD_MODULES = @SLAPD_MODULES_LIST@
 XDEFS = $(MODULES_CPPFLAGS)
 XLDFLAGS = $(MODULES_LDFLAGS) $(SLAPD_MODULES)
 
-XLIBS = -lavl -lldif -lldbm -lldap_r -llber -llutil
-XXLIBS = $(LDAPD_LIBS) $(SLAPD_LIBS) \
-       $(PERL_LDFLAGS) $(LDBM_LIBS) $(SECURITY_LIBS) \
+XLIBS = -lavl -lldif -lldbm -llutil -lldap_r -llber
+XXLIBS = $(QUIPU_LIBS) $(SLAPD_LIBS) \
+       $(LDBM_LIBS) $(SECURITY_LIBS) \
        $(LDIF_LIBS) $(LUTIL_LIBS)
 XXXLIBS = $(LTHREAD_LIBS) $(MODULES_LIBS)
 
-PROGRAMS=ldif slapadd slapcat slapindex
+PROGRAMS=ldif slappasswd slapadd slapcat slapindex
 LDBMPROGRAMS=centipede sizecount
-BDB2PROGRAMS=
 QUIPUPROGRAMS=chlog2replog edb2ldif
 
-SRCS = ldif.c mimic.c slapcommon.c
+# CPPFLAGS will include the defines for dynamic libs in Mingw32.
+NT_DYN_DEFS = -DLIBLBER_DECL=dllimport -DLIBLDAP_DECL=dllimport
+CPPFLAGS = $(@PLAT@_@LIB_LINKAGE@_DEFS)
 
-XSRCS = edb2-vers.c
+SRCS = ldif.c mimic.c slapcommon.c slapadd.c slapcat.c slapindex.c
 
-LDBMSRCS = centipede.c sizecount.c
+XSRCS = edb2-vers.c
 
-BDB2SRCS =
+# LDBMSRCS = centipede.c sizecount.c
+LDBMSRCS =
 
 QUIPUSRCS      = edb2ldif.c ldapsyntax.c chlog2replog.c
 SLAPD_OBJS = ../config.o ../ch_malloc.o ../backend.o ../charray.o \
-               ../module.o ../aclparse.o ../schema.o ../filterentry.o \
+               ../module.o ../aclparse.o ../filterentry.o \
+               ../schema.o ../schema_check.o ../schema_init.o ../schema_prep.o \
+               ../schemaparse.o ../ad.o ../at.o ../mr.o ../oc.o ../syntax.o \
                ../acl.o ../phonetic.o ../attr.o ../value.o ../entry.o \
                ../dn.o ../filter.o ../str2filter.o ../ava.o ../init.o \
-               ../controls.o ../schemaparse.o
-SLAPOBJS = $(SLAPD_OBJS) slapcommon.o mimic.o 
+               ../controls.o ../kerberos.o ../passwd.o ../index.o \
+               ../extended.o ../starttls.o
+
+SLAPOBJS = $(SLAPD_OBJS) slapcommon.o mimic.o
 
 EDB2LDIFSRCS    = edb2ldif.c ldapsyntax.c
 EDB2LDIFOBJS    = edb2ldif.o ldapsyntax.o
 
-all-local: build-progs build-ldbm build-bdb2 build-quipu
+UNIX_PRGS = build-ldbm build-quipu
+
+all-local: build-progs $(@PLAT@_PRGS)
 
 build-progs: $(PROGRAMS)
 
@@ -65,12 +74,6 @@ ldbm-tools-no:
 
 ldbm-tools-yes ldbm-tools-mod: $(LDBMPROGRAMS)
 
-build-bdb2: bdb2-tools-$(BUILD_BDB2)
-bdb2-tools-no:
-       @echo "run configure with --enable-bdb2 to build BDB2 tools"
-
-bdb2-tools-yes bdb2-tools-mod: $(BDB2PROGRAMS)
-
 build-quipu: quipu-tools-$(BUILD_QUIPU)
 quipu-tools-no:
        @echo "run configure with --enable-quipu to build QUIPU tools"
@@ -92,19 +95,18 @@ slapindex:  slapindex.o ../libbackends.a $(SLAPOBJS) $(SLAPD_LIBDEPEND)
 ldif:          ldif.o $(SLAPD_LIBDEPEND) 
        $(LTLINK) -o $@ ldif.o $(LIBS)
 
+slappasswd:            slappasswd.o $(SLAPD_LIBDEPEND) 
+       $(LTLINK) -o $@ slappasswd.o $(LIBS)
+
 #
 # LDBM Specific Tools
-#
+#      (deprecated)
 centipede:     centipede.o $(SLAPD_LIBDEPEND) 
        $(LTLINK) -o $@ centipede.o $(LIBS)
 
 sizecount:     sizecount.o ../phonetic.o ../ch_malloc.o $(SLAPD_LIBDEPEND) 
        $(LTLINK) -o $@ sizecount.o ../phonetic.o ../ch_malloc.o $(LIBS)
 
-#
-# BDBM Specific Tools
-#
-
 #
 # QUIPU Specific Tools
 #
@@ -119,40 +121,34 @@ chlog2replog: chlog2replog.o ../lock.o ../ch_malloc.o $(SLAPD_LIBDEPEND)
        $(LTLINK) -o $@ chlog2replog.o ../lock.o ../ch_malloc.o $(LIBS)
 
 clean-local: FORCE
-       $(RM) $(PROGRAMS) $(LDBMPROGRAMS) $(BDB2PROGRAMS) $(QUIPUPROGRAMS) \
-               $(XPROGRAMS) $(XSRCS) *.o core .libs/*
+       $(RM) $(PROGRAMS) $(LDBMPROGRAMS) $(QUIPUPROGRAMS) \
+               $(XPROGRAMS) $(XSRCS) *.o core .libs/* *.exe
 
 depend-local: FORCE
-       @DEPEND_LDBM= ; DEPEND_BDB2= ; DEPEND_QUIPU= ; \
+       DEPEND_LDBM= ; DEPEND_QUIPU= ; \
        if [ "$(BUILD_LDBM)" != "no" ]; then \
                DEPEND_LDBM="$(LDBMSRCS)"; \
        fi; \
-       if [ "$(BUILD_BDB2)" != "no" ]; then \
-               DEPEND_BDB2="$(BDBMSRCS)"; \
-       fi; \
        if [ "$(BUILD_QUIPU)" != "no" ]; then \
                DEPEND_QUIPU="$(QUIPUINCLUDEFLAG) $(QUIPUSRCS)"; \
        fi; \
-       $(MKDEP) $(DEFS) $(DEFINES) $(SRCS) $$DEPEND_QUIPU \
-                       $$DEPEND_LDBM $$DEPEND_BDB2
+       $(MKDEP) $(DEFS) $(DEFINES) $(SRCS) $$DEPEND_QUIPU $$DEPEND_LDBM
 
-install-local: install-ldbm-$(BUILD_LDBM) install-bdb2-$(BUILD_BDB2) \
+install-local: install-ldbm-$(BUILD_LDBM) \
         install-quipu-$(BUILD_QUIPU)
 
-install-ldbm-no install-bdb2-no install-quipu-no:
+install-ldbm-no install-quipu-no:
 
 install-ldbm-yes install-ldbm-mod: FORCE
-       @-$(MKDIR) $(sbindir) 
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 slapadd $(sbindir)  ; \
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 slapcat $(sbindir)  ; \
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 slapindex $(sbindir)        ; \
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 ldif $(sbindir)     ; \
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 centipede $(sbindir)
-
-install-bdb2-yes install-bdb2-mod: FORCE
-       @-$(MKDIR) $(sbindir) 
+       -$(MKDIR) $(DESTDIR)$(sbindir) 
+       @for bin in $(PROGRAMS); do \
+               $(LTINSTALL) $(INSTALLFLAGS) -s -m 755 \
+                       $$bin$(EXEEXT) $(DESTDIR)$(sbindir); \
+       done
 
 install-quipu-yes: FORCE
-       @-$(MKDIR) $(sbindir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 edb2ldif $(sbindir); \
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 chlog2replog $(sbindir)
+       @-$(MKDIR) $(DESTDIR)$(sbindir)
+       for bin in edb2ldif chlog2replog; do \
+               $(LTINSTALL) $(INSTALLFLAGS) -s -m 755 \
+                       $$bin $(DESTDIR)$(sbindir); \
+       done
index 1897c0245b83721dc97f7148e26e8ccee9de4cae..39e6c7432a9cb970de8e17fa4c95c17c568ee86a 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 #include "portable.h"
@@ -298,7 +298,7 @@ main( int argc, char **argv )
                        } else {
                                buf[strlen( buf ) - 1] = '\0';
                        }
-                       (void) dn_normalize_case( buf );
+                       (void) dn_normalize( buf );
                        if ( (tbe = select_backend( buf )) == NULL ) {
                                fprintf( stderr, "unknown suffix \"%s\"\n",
                                    buf );
@@ -508,7 +508,7 @@ edit_entry( char c, Datum *data )
 
        strcpy( tmpname, "/tmp/dbtestXXXXXX" );
 #ifndef HAVE_MKSTEMP
-       if ( (fd = open( mktemp( tmpname ), O_RDWR, 0600 )) == -1 ) {
+       if ( (fd = open( mktemp( tmpname ), O_RDWR|O_CREAT|O_EXCL, 0600 )) == -1 ) {
                perror( tmpname );
                return;
        }
index b7202b6af54f9ac16650b32f1dfb035820d988cb..3f83351506ee0eda2b25bc257c277c4032367017 100644 (file)
@@ -41,8 +41,8 @@ RSC=rc.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\Release"
-# PROP Intermediate_Dir "..\Release\ldbmtest"
+# PROP Output_Dir "..\..\..\Release"
+# PROP Intermediate_Dir "..\..\..\Release\ldbmtest"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -54,7 +54,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 libdb.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 libdb.lib libsasl.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\Release"
 
 !ELSEIF  "$(CFG)" == "ldbmtest - Win32 Debug"
 
@@ -65,8 +65,8 @@ LINK32=link.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\Debug"
-# PROP Intermediate_Dir "..\Debug\ldbmtest"
+# PROP Output_Dir "..\..\..\Debug"
+# PROP Intermediate_Dir "..\..\..\Debug\ldbmtest"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -78,7 +78,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 libdb.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 libdb.lib libsasl.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\Debug"
 
 !ELSEIF  "$(CFG)" == "ldbmtest - Win32 Single Debug"
 
@@ -89,8 +89,8 @@ LINK32=link.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\SDebug"
-# PROP Intermediate_Dir "..\SDebug\ldbmtest"
+# PROP Output_Dir "..\..\..\SDebug"
+# PROP Intermediate_Dir "..\..\..\SDebug\ldbmtest"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -102,7 +102,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 libdbs.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 libdb.lib libsasl.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\SDebug"
 
 !ELSEIF  "$(CFG)" == "ldbmtest - Win32 Single Release"
 
@@ -113,8 +113,8 @@ LINK32=link.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\SRelease"
-# PROP Intermediate_Dir "..\SRelease\ldbmtest"
+# PROP Output_Dir "..\..\..\SRelease"
+# PROP Intermediate_Dir "..\..\..\SRelease\ldbmtest"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -126,7 +126,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 libdbs.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 libdbs.lib libsasl.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\SRelease"
 
 !ENDIF 
 
index 4618fc62aadd75e520bb014d28e6dfdbe84141f3..67124e0134c356306b3ac56a15f6a81562c5fe3b 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 #include "portable.h"
index 31928665b0eb8632d46c40aba722c85f51f42527..7b32bb1d41d0e4838f8298517989437b5435f820 100644 (file)
@@ -40,8 +40,8 @@ RSC=rc.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\Release"
-# PROP Intermediate_Dir "..\Release\ldif"
+# PROP Output_Dir "..\..\..\Release"
+# PROP Intermediate_Dir "..\..\..\Release\ldif"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -53,7 +53,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 hs_regex.lib libdb.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\libraries\Release"
+# ADD LINK32 libdb.lib hs_regex.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\Release"
 
 !ELSEIF  "$(CFG)" == "ldif - Win32 Debug"
 
@@ -64,8 +64,8 @@ LINK32=link.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\Debug"
-# PROP Intermediate_Dir "..\Debug\ldif"
+# PROP Output_Dir "..\..\..\Debug"
+# PROP Intermediate_Dir "..\..\..\Debug\ldif"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -77,7 +77,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 hs_regex.lib libdb.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\libraries\Debug"
+# ADD LINK32 libdb.lib hs_regex.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\Debug"
 
 !ELSEIF  "$(CFG)" == "ldif - Win32 Single Debug"
 
@@ -89,8 +89,8 @@ LINK32=link.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\SDebug"
-# PROP Intermediate_Dir "..\SDebug\ldif"
+# PROP Output_Dir "..\..\..\SDebug"
+# PROP Intermediate_Dir "..\..\..\SDebug\ldif"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -102,7 +102,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 oldif32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\libraries\Debug"
-# ADD LINK32 hs_regex.lib libdbs.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\libraries\Debug"
+# ADD LINK32 libdbs.lib hs_regex.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\SDebug"
 
 !ELSEIF  "$(CFG)" == "ldif - Win32 Single Release"
 
@@ -114,8 +114,8 @@ LINK32=link.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\SRelease"
-# PROP Intermediate_Dir "..\SRelease\ldif"
+# PROP Output_Dir "..\..\..\SRelease"
+# PROP Intermediate_Dir "..\..\..\SRelease\ldif"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -127,7 +127,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 oldif32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\libraries\Release"
-# ADD LINK32 hs_regex.lib libdbs.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\libraries\Release"
+# ADD LINK32 libdbs.lib hs_regex.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\SRelease"
 
 !ENDIF 
 
index 5aafbdbdae83822c5e9970d77ee35947318fe02c..a2d8f742a56215ae6963ceda385042d5bf03e554 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
@@ -39,11 +39,42 @@ send_ldap_disconnect(
        assert(0);
 }
 
+void
+send_ldap_extended(
+    Connection *conn,
+    Operation  *op,
+    ber_int_t  err,
+    const char *matched,
+    const char *text,
+       struct berval **refs,
+    const char *rspoid,
+       struct berval *rspdata,
+       LDAPControl **ctrls
+)
+{
+       assert(0);
+}
+
+void
+send_ldap_sasl(
+    Connection *conn,
+    Operation  *op,
+    ber_int_t  err,
+    const char *matched,
+    const char *text,
+       struct berval **refs,
+       LDAPControl **ctrls,
+       struct berval *cred
+)
+{
+       assert(0);
+}
+
 void
 send_ldap_result(
        Connection  *conn, 
        Operation   *op,
-       int     err,
+       ber_int_t     err,
        const char    *matched,
        const char    *text,
        struct berval **refs,
@@ -57,7 +88,7 @@ void
 send_search_result(
        Connection  *conn, 
        Operation   *op,
-       int     err,
+       ber_int_t     err,
        const char    *matched,
        const char    *text,
        struct berval **refs,
@@ -112,3 +143,17 @@ int sasl_init(void) {
 int sasl_destroy(void) {
        return 0;
 }
+
+#ifdef HAVE_CYRUS_SASL
+int sasl_bind(
+    Connection          *conn,
+    Operation           *op,
+    const char          *dn,
+    const char          *ndn,
+    const char          *mech,
+    struct berval       *cred,
+    char                **edn)
+{
+       return -1;
+}
+#endif
index 606a2f4aac5ee14c30ffac931c26cf05a568e643..c66cde05f3e4eccd4934719498cb3b7cb4a40d62 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 #include "portable.h"
@@ -57,21 +57,22 @@ main( int argc, char **argv )
                        break;
                }
 
-               if( !noschemacheck ) {
-                       /* make sure the DN is valid */
-                       if( dn_normalize_case( e->e_ndn ) == NULL ) {
-                               fprintf( stderr, "%s: bad dn=\"%s\" (line=%d)\n",
-                                       progname, e->e_dn, lineno );
-                               rc = EXIT_FAILURE;
-                               entry_free( e );
-                               if( continuemode ) continue;
-                               break;
-                       }
+               /* make sure the DN is valid */
+               if( dn_normalize( e->e_ndn ) == NULL ) {
+                       fprintf( stderr, "%s: bad dn=\"%s\" (line=%d)\n",
+                               progname, e->e_dn, lineno );
+                       rc = EXIT_FAILURE;
+                       entry_free( e );
+                       if( continuemode ) continue;
+                       break;
+               }
 
+               if( !noschemacheck ) {
                        /* check schema */
-                       if ( global_schemacheck && oc_schema_check( e ) != 0 ) {
-                               fprintf( stderr, "%s: schema violation in entry dn=\"%s\" (line=%d)\n",
-                                       progname, e->e_dn, lineno );
+                       const char *text;
+                       if ( entry_schema_check( e, NULL, &text ) != LDAP_SUCCESS ) {
+                               fprintf( stderr, "%s: dn=\"%s\" (line=%d): %s\n",
+                                       progname, e->e_dn, lineno, text );
                                rc = EXIT_FAILURE;
                                entry_free( e );
                                if( continuemode ) continue;
@@ -107,7 +108,7 @@ main( int argc, char **argv )
                entry_free( e );
        }
 
-       free( buf );
+       ch_free( buf );
 
        be->be_entry_close( be );
 
index d269441ae8d758c8e3fa9f9bba1add7614e77609..bc5a39369a008a75276ca509eef606d568b20cc7 100644 (file)
@@ -40,8 +40,8 @@ RSC=rc.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\Release"
-# PROP Intermediate_Dir "..\Release\slapadd"
+# PROP Output_Dir "..\..\..\Release"
+# PROP Intermediate_Dir "..\..\..\Release\slapadd"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -53,7 +53,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 hs_regex.lib libdb.lib ws2_32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 libdb.lib sasl.lib hs_regex.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\Release"
 
 !ELSEIF  "$(CFG)" == "slapadd - Win32 Debug"
 
@@ -64,8 +64,8 @@ LINK32=link.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\Debug"
-# PROP Intermediate_Dir "..\Debug\slapadd"
+# PROP Output_Dir "..\..\..\Debug"
+# PROP Intermediate_Dir "..\..\..\Debug\slapadd"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -77,7 +77,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 hs_regex.lib libdb.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 libdb.lib hs_regex.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\Debug"
 
 !ELSEIF  "$(CFG)" == "slapadd - Win32 Single Debug"
 
@@ -89,8 +89,8 @@ LINK32=link.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\SDebug"
-# PROP Intermediate_Dir "..\SDebug\slapadd"
+# PROP Output_Dir "..\..\..\SDebug"
+# PROP Intermediate_Dir "..\..\..\SDebug\slapadd"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -102,7 +102,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib hs_regexd.lib libdbs.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 hs_regexd.lib libdbs.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 libdb.lib hs_regex.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\SDebug"
 
 !ELSEIF  "$(CFG)" == "slapadd - Win32 Single Release"
 
@@ -114,8 +114,8 @@ LINK32=link.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\SRelease"
-# PROP Intermediate_Dir "..\SRelease\slapadd"
+# PROP Output_Dir "..\..\..\SRelease"
+# PROP Intermediate_Dir "..\..\..\SRelease\slapadd"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -127,7 +127,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 hs_regex.lib libdb.lib ws2_32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 hs_regex.lib libdbs.lib ws2_32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 libdbs.lib sasl.lib hs_regex.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\SRelease"
 
 !ENDIF 
 
index f2103878167937bed894a7d11c7e95dadb3ce025..905bcbb605d2ce835f00e2fe4397996d85dce742 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 #include "portable.h"
index 8a73d660666dce0688e715cf844cbdabf1ef8053..694beae96f49a5ad4964d667394635e044821442 100644 (file)
@@ -40,8 +40,8 @@ RSC=rc.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\Release"
-# PROP Intermediate_Dir "..\Release\slapcat"
+# PROP Output_Dir "..\..\..\Release"
+# PROP Intermediate_Dir "..\..\..\Release\slapcat"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -53,7 +53,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 hs_regex.lib libdb.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\libraries\Release"
+# ADD LINK32 libdb.lib sasl.lib hs_regex.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\Release"
 
 !ELSEIF  "$(CFG)" == "slapcat - Win32 Debug"
 
@@ -64,8 +64,8 @@ LINK32=link.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\Debug"
-# PROP Intermediate_Dir "..\Debug\slapcat"
+# PROP Output_Dir "..\..\..\Debug"
+# PROP Intermediate_Dir "..\..\..\Debug\slapcat"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -77,7 +77,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 hs_regex.lib libdb.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\libraries\Debug"
+# ADD LINK32 libdb.lib hs_regex.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\Debug"
 
 !ELSEIF  "$(CFG)" == "slapcat - Win32 Single Debug"
 
@@ -89,8 +89,8 @@ LINK32=link.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\Sdebug"
-# PROP Intermediate_Dir "..\SDebug\slapcat"
+# PROP Output_Dir "..\..\..\Sdebug"
+# PROP Intermediate_Dir "..\..\..\SDebug\slapcat"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -102,7 +102,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 oldbm32.lib libdb.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\libraries\Debug"
-# ADD LINK32 hs_regex.lib libdbs.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\libraries\Debug"
+# ADD LINK32 libdb.lib hs_regex.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\SDebug"
 
 !ELSEIF  "$(CFG)" == "slapcat - Win32 Single Release"
 
@@ -113,8 +113,8 @@ LINK32=link.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\SRelease"
-# PROP Intermediate_Dir "..\SRelease\slapcat"
+# PROP Output_Dir "..\..\..\SRelease"
+# PROP Intermediate_Dir "..\..\..\SRelease\slapcat"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -126,7 +126,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libdb.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\libraries\Release"
-# ADD LINK32 hs_regex.lib libdbs.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\libraries\Release"
+# ADD LINK32 libdbs.lib sasl.lib hs_regex.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\SRelease"
 
 !ENDIF 
 
index 8b41f223233c4f3bd28490914dac2b177892427b..45ba63a2d88e346a4886e5f611199e89fd3d9b6a 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* slapcommon.c - common routine for the slap tools */
@@ -188,6 +188,13 @@ slap_tool_init(
                exit( EXIT_FAILURE );
        }
 
+       rc = schema_init();
+
+       if (rc != 0 ) {
+               fprintf( stderr, "%s: slap_schema_init failed!\n", progname );
+               exit( EXIT_FAILURE );
+       }
+
        read_config( conffile );
 
        if ( !nbackends ) {
@@ -195,10 +202,17 @@ slap_tool_init(
                exit( EXIT_FAILURE );
        }
 
+       rc = schema_prep();
+
+       if (rc != 0 ) {
+               fprintf( stderr, "%s: slap_schema_prep failed!\n", progname );
+               exit( EXIT_FAILURE );
+       }
+
        if( base != NULL ) {
                char *tbase = ch_strdup( base );
 
-               if( dn_normalize_case( tbase ) == NULL ) {
+               if( dn_normalize( tbase ) == NULL ) {
                        fprintf( stderr, "%s: slap_init invalid suffix (\"%s\")\n",
                                progname, base );
                        exit( EXIT_FAILURE );
index d965bf754c3069c413f3aaffcdf53af78a07493f..dd0f1b1f55ab90eb8dd4b04f238a5d021bf8bfab 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* slapcommon.h - common definitions for the slap tools */
index ba63e7079950a4be29311b1b06d449d42d7f8499..efee55d7e873e23d39762d655dc7f338d29a3966 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 #include "portable.h"
@@ -20,6 +20,8 @@ int
 main( int argc, char **argv )
 {
        char            *type;
+       AttributeDescription *desc;
+       const char *text;
        ID id;
        int rc = EXIT_SUCCESS;
 
@@ -38,9 +40,17 @@ main( int argc, char **argv )
                exit( EXIT_FAILURE );
        }
 
-       type = attr_normalize( argv[argc - 1] );
+       type = argv[argc - 1];
 
-       if ( !be->be_index_attr( be, type ) ) {
+       rc = slap_str2ad( type, &desc, &text );
+
+       if( rc != LDAP_SUCCESS ) {
+               fprintf( stderr, "%s: unrecognized attribute type: %s\n",
+                       progname, text );
+               exit( EXIT_FAILURE );
+       }
+
+       if ( !be->be_index_attr( be, desc ) ) {
                fprintf( stderr, "attribute type \"%s\": no indices to generate\n",
                        type );
                exit( EXIT_FAILURE );
@@ -56,10 +66,7 @@ main( int argc, char **argv )
                id != NOID;
                id = be->be_entry_next( be ) )
        {
-               struct berval **values;
                Entry* e = be->be_entry_get( be, id );
-               struct berval bv;
-               struct berval *bvals[2];
 
                if ( e == NULL ) {
                        fprintf( stderr,
@@ -74,39 +81,31 @@ main( int argc, char **argv )
                                id, e->e_dn );
                }
 
-               if( strcasecmp( type, "dn" ) == 0 ) {
-                       bv.bv_val = e->e_ndn;
-                       bv.bv_len = strlen( bv.bv_val );
-                       bvals[0] = &bv;
-                       bvals[1] = NULL;
-
-                       values = bvals;
-
-               } else {
-                       Attribute *attr = attr_find( e->e_attrs, type );
-
-                       if( attr == NULL ) {
-                               entry_free( e );
-                               continue;
-                       }
-
-                       values = attr->a_vals;
-               }
-
-               if ( be->be_index_change( be,
-                       type, values, id, SLAP_INDEX_ADD_OP ) )
                {
-                       rc = EXIT_FAILURE;
-
-                       if( !continuemode ) {
-                               entry_free( e );
-                               break;
+                       Attribute *attr;
+                       
+                       for( attr = attrs_find( e->e_attrs, desc );
+                               attr != NULL;
+                               attr = attrs_find( attr->a_next, desc ) )
+                       {
+
+                               if ( be->be_index_change( be,
+                                       desc, attr->a_vals, id, SLAP_INDEX_ADD_OP ) )
+                               {
+                                       rc = EXIT_FAILURE;
+
+                                       if( !continuemode ) {
+                                               entry_free( e );
+                                               goto done;
+                                       }
+                               }
                        }
                }
 
                entry_free( e );
        }
 
+done:
        (void) be->be_entry_close( be );
 
        slap_tool_destroy();
index 7c935bf238fc9d964cd137b9e3fa35d03270d6b5..f0e4e386c922c11346194f17a504aa20ed0fd652 100644 (file)
@@ -41,8 +41,8 @@ RSC=rc.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\Release"
-# PROP Intermediate_Dir "..\Release\slapindex"
+# PROP Output_Dir "..\..\..\Release"
+# PROP Intermediate_Dir "..\..\..\Release\slapindex"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -54,7 +54,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 hs_regex.lib libdb.lib ws2_32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 libdb.lib sasl.lib hs_regex.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\Release"
 
 !ELSEIF  "$(CFG)" == "slapindex - Win32 Debug"
 
@@ -65,8 +65,8 @@ LINK32=link.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\Debug"
-# PROP Intermediate_Dir "..\Debug\slapindex"
+# PROP Output_Dir "..\..\..\Debug"
+# PROP Intermediate_Dir "..\..\..\Debug\slapindex"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -78,7 +78,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 hs_regex.lib libdb.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 libdb.lib hs_regex.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\Debug"
 
 !ELSEIF  "$(CFG)" == "slapindex - Win32 Single Debug"
 
@@ -90,8 +90,8 @@ LINK32=link.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\SDebug"
-# PROP Intermediate_Dir "..\SDebug\slapindex"
+# PROP Output_Dir "..\..\..\SDebug"
+# PROP Intermediate_Dir "..\..\..\SDebug\slapindex"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -103,7 +103,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib shell32.lib hs_regexd.lib libdbs.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 hs_regex.lib libdbs.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 libdb.lib hs_regex.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\SDebug"
 
 !ELSEIF  "$(CFG)" == "slapindex - Win32 Single Release"
 
@@ -115,8 +115,8 @@ LINK32=link.exe
 # PROP BASE Target_Dir ""
 # PROP Use_MFC 0
 # PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\SRelease"
-# PROP Intermediate_Dir "..\SRelease\slapindex"
+# PROP Output_Dir "..\..\..\SRelease"
+# PROP Intermediate_Dir "..\..\..\SRelease\slapindex"
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -128,7 +128,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 hs_regex.lib libdb.lib ws2_32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 hs_regex.lib libdbs.lib ws2_32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 libdbs.lib sasl.lib hs_regex.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\SRelease"
 
 !ENDIF 
 
diff --git a/servers/slapd/tools/slappasswd.c b/servers/slapd/tools/slappasswd.c
new file mode 100644 (file)
index 0000000..b7bedd6
--- /dev/null
@@ -0,0 +1,116 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/stdlib.h>
+
+#include <ac/ctype.h>
+#include <ac/signal.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/time.h>
+#include <ac/unistd.h>
+
+#include <ldap.h>
+#include <lutil.h>
+
+#include "ldap_defaults.h"
+
+static int     verbose = 0;
+
+static void
+usage(const char *s)
+{
+       fprintf(stderr,
+               "Usage: %s [options] dn\n"
+               "  -h hash\tpassword scheme\n"
+               "  -s secret\tnew password\n"
+               "  -v\t\tincrease verbosity\n"
+               , s );
+
+       exit( EXIT_FAILURE );
+}
+
+int
+main( int argc, char *argv[] )
+{
+       int rc;
+       char    *scheme = "{SSHA}";
+       char    *newpw = NULL;
+
+       int             i;
+       int             version = -1;
+       struct berval passwd;
+       struct berval *hash = NULL;
+
+       if (argc == 1)
+               usage (argv[0]);
+
+       while( (i = getopt( argc, argv,
+               "d:h:s:v" )) != EOF )
+       {
+               switch (i) {
+               case 'h':       /* scheme */
+                       scheme = strdup (optarg);
+
+               case 's':       /* new password (secret) */
+                       newpw = strdup (optarg);
+
+                       {
+                               char* p;
+
+                               for( p = optarg; *p == '\0'; p++ ) {
+                                       *p = '*';
+                               }
+                       }
+                       break;
+
+               case 'v':       /* verbose */
+                       verbose++;
+                       break;
+
+               default:
+                       usage (argv[0]);
+               }
+       }
+
+       if( argc - optind != 0 ) {
+               usage( argv[0] );
+       } 
+
+       if( newpw == NULL ) {
+               /* prompt for new password */
+               char *cknewpw;
+               newpw = strdup(getpass("New password: "));
+               cknewpw = getpass("Re-enter new password: ");
+
+               if( strncmp( newpw, cknewpw, strlen(newpw) )) {
+                       fprintf( stderr, "passwords do not match\n" );
+                       return EXIT_FAILURE;
+               }
+       }
+
+       passwd.bv_val = newpw;
+       passwd.bv_len = strlen(passwd.bv_val);
+
+       hash = lutil_passwd_hash( &passwd, scheme );
+
+       if( hash == NULL || hash->bv_val == NULL ) {
+               fprintf( stderr, "Password generation failed.\n");
+               return EXIT_FAILURE;
+       }
+
+       if( lutil_passwd( hash, &passwd, NULL ) ) {
+               fprintf( stderr, "Password verificaiton failed.\n");
+               return EXIT_FAILURE;
+       }
+
+       printf( "%s\n" , hash->bv_val );
+       return EXIT_SUCCESS;
+}
index 14619b8f740b669a547cbbf38f0cd650b558c00c..e4abaaed66068103ed3bf4cdf6a0fdf50b502d19 100644 (file)
@@ -1,7 +1,7 @@
 /* unbind.c - decode an ldap unbind operation and pass it to a backend db */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
index a309e0e80b89f585f60d23507f72cf066bd70a0b..3a3ecdff177fc8f8935e5c04662328eac7360332 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* user.c - set user id, group id and group access list
index 1405fd176e60d215bd548e13ca0b1e3a703d5b6e..74434b6126b21df36a150844e067272788f1c0a4 100644 (file)
@@ -1,7 +1,7 @@
 /* value.c - routines for dealing with values */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 
 #include "slap.h"
 
-int
-value_add_fast( 
-    struct berval      ***vals,
-    struct berval      **addvals,
-    int                        nvals,
-    int                        naddvals,
-    int                        *maxvals
-)
-{
-       int     need, i, j;
-
-       if ( *maxvals == 0 ) {
-               *maxvals = 1;
-       }
-       need = nvals + naddvals + 1;
-       while ( *maxvals < need ) {
-               *maxvals *= 2;
-               *vals = (struct berval **) ch_realloc( (char *) *vals,
-                   *maxvals * sizeof(struct berval *) );
-       }
-
-       for ( i = 0, j = 0; i < naddvals; i++, j++ ) {
-               if ( addvals[i]->bv_len > 0 ) {
-                       (*vals)[nvals + j] = ber_bvdup( addvals[i] );
-                       if( (*vals)[nvals + j] == NULL ) break;
-               }
-       }
-       (*vals)[nvals + j] = NULL;
-
-       return( 0 );
-}
-
 int
 value_add( 
     struct berval      ***vals,
@@ -80,99 +48,150 @@ value_add(
        }
        (*vals)[n + j] = NULL;
 
-       return( 0 );
+       return LDAP_SUCCESS;
 }
 
-void
+
+int
 value_normalize(
-    char       *s,
-    int                syntax
-)
+       AttributeDescription *ad,
+       unsigned usage,
+       struct berval *in,
+       struct berval **out,
+       const char **text )
 {
-       char    *d, *save;
+       int rc;
+       MatchingRule *mr;
 
-       if ( ! (syntax & SYNTAX_CIS) ) {
-               return;
+       switch( usage & SLAP_MR_TYPE_MASK ) {
+       case SLAP_MR_NONE:
+       case SLAP_MR_EQUALITY:
+               mr = ad->ad_type->sat_equality;
+               break;
+       case SLAP_MR_ORDERING:
+               mr = ad->ad_type->sat_ordering;
+               break;
+       case SLAP_MR_SUBSTR:
+               mr = ad->ad_type->sat_substr;
+               break;
+       case SLAP_MR_EXT:
+       default:
+               assert( 0 );
+               *text = "internal error";
+               return LDAP_OTHER;
+       }
+
+       if( mr == NULL ) {
+               *text = "inappropriate matching request";
+               return LDAP_INAPPROPRIATE_MATCHING;
        }
 
-       if ( syntax & SYNTAX_DN ) {
-               (void) dn_normalize_case( s );
-               return;
+       /* we only support equality matching of binary attributes */
+       if( slap_ad_is_binary( ad ) && usage != SLAP_MR_EQUALITY ) {
+               *text = "inappropriate binary matching";
+               return LDAP_INAPPROPRIATE_MATCHING;
        }
 
-       save = s;
-       for ( d = s; *s; s++ ) {
-               if ( (syntax & SYNTAX_TEL) && (*s == ' ' || *s == '-') ) {
-                       continue;
+       if( mr->smr_normalize ) {
+               rc = (mr->smr_normalize)( usage,
+                       ad->ad_type->sat_syntax,
+                       mr, in, out );
+
+               if( rc != LDAP_SUCCESS ) {
+                       *text = "unable to normalize value";
+                       return LDAP_INVALID_SYNTAX;
+               }
+
+       } else if ( mr->smr_syntax->ssyn_normalize ) {
+               rc = (mr->smr_syntax->ssyn_normalize)(
+                       ad->ad_type->sat_syntax,
+                       in, out );
+
+               if( rc != LDAP_SUCCESS ) {
+                       *text = "unable to normalize value";
+                       return LDAP_INVALID_SYNTAX;
                }
-               *d++ = TOUPPER( (unsigned char) *s );
+
+       } else {
+               *out = ber_bvdup( in );
        }
-       *d = '\0';
+
+       return LDAP_SUCCESS;
 }
 
+
 int
-value_cmp(
-    struct berval      *v1,
-    struct berval      *v2,
-    int                        syntax,
-    int                        normalize       /* 1 => arg 1; 2 => arg 2; 3 => both */
-)
+value_match(
+       int *match,
+       AttributeDescription *ad,
+       MatchingRule *mr,
+       struct berval *v1, /* stored value */
+       void *v2, /* assertion */
+       const char ** text )
 {
-       int             rc;
+       int rc;
+       int usage = 0;
+       struct berval *nv1 = NULL;
 
-       if ( normalize & 1 ) {
-               v1 = ber_bvdup( v1 );
-               value_normalize( v1->bv_val, syntax );
-       }
-       if ( normalize & 2 ) {
-               v2 = ber_bvdup( v2 );
-               value_normalize( v2->bv_val, syntax );
+       if( !mr->smr_match ) {
+               return LDAP_INAPPROPRIATE_MATCHING;
        }
 
-       switch ( syntax ) {
-       case SYNTAX_CIS:
-       case (SYNTAX_CIS | SYNTAX_TEL):
-       case (SYNTAX_CIS | SYNTAX_DN):
-               rc = strcasecmp( v1->bv_val, v2->bv_val );
-               break;
-
-       case SYNTAX_CES:
-               rc = strcmp( v1->bv_val, v2->bv_val );
-               break;
-
-       default:        /* Unknown syntax */
-       case SYNTAX_BIN:
-               rc = (v1->bv_len == v2->bv_len
-                     ? memcmp( v1->bv_val, v2->bv_val, v1->bv_len )
-                     : v1->bv_len > v2->bv_len ? 1 : -1);
-               break;
-       }
+       if( ad->ad_type->sat_syntax->ssyn_normalize ) {
+               rc = ad->ad_type->sat_syntax->ssyn_normalize(
+                       ad->ad_type->sat_syntax, v1, &nv1 );
 
-       if ( normalize & 1 ) {
-               ber_bvfree( v1 );
-       }
-       if ( normalize & 2 ) {
-               ber_bvfree( v2 );
+               if( rc != LDAP_SUCCESS ) {
+                       return LDAP_INAPPROPRIATE_MATCHING;
+               }
        }
 
-       return( rc );
+       rc = (mr->smr_match)( match, usage,
+               ad->ad_type->sat_syntax,
+               mr,
+               nv1 != NULL ? nv1 : v1,
+               v2 );
+       
+       ber_bvfree( nv1 );
+       return rc;
 }
 
-int
-value_find(
-    struct berval      **vals,
-    struct berval      *v,
-    int                        syntax,
-    int                        normalize
-)
+
+int value_find(
+       AttributeDescription *ad,
+       struct berval **vals,
+       struct berval *val )
 {
        int     i;
+       int rc;
+       struct berval *nval = NULL;
+       MatchingRule *mr = ad->ad_type->sat_equality;
+
+       if( mr == NULL || !mr->smr_match ) {
+               return LDAP_INAPPROPRIATE_MATCHING;
+       }
+
+       if( mr->smr_syntax->ssyn_normalize ) {
+               rc = mr->smr_syntax->ssyn_normalize(
+                       mr->smr_syntax, val, &nval );
+
+               if( rc != LDAP_SUCCESS ) {
+                       return LDAP_INAPPROPRIATE_MATCHING;
+               }
+       }
 
        for ( i = 0; vals[i] != NULL; i++ ) {
-               if ( value_cmp( vals[i], v, syntax, normalize ) == 0 ) {
-                       return( 0 );
+               int match;
+               const char *text;
+
+               rc = value_match( &match, ad, mr, vals[i],
+                       nval == NULL ? val : nval, &text );
+
+               if( rc == LDAP_SUCCESS && match == 0 )
+               {
+                       return LDAP_SUCCESS;
                }
        }
 
-       return( 1 );
+       return LDAP_NO_SUCH_ATTRIBUTE;
 }
index 3b244dace5d5cea7afc430f8a18952442f0149f4..6a1137eb161685499d4f128b2d58cc80b47a2a5b 100644 (file)
@@ -1,9 +1,13 @@
 # $OpenLDAP$
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 ##
 ## Makefile.in for slurpd
 ##
 
-PROGRAMS = slurpd
+UNIX_PRGS = slurpd
+
+PROGRAMS = $(@PLAT@_PRGS)
 XPROGRAMS = sslurpd
 
 XSRCS  = version.c
@@ -21,7 +25,7 @@ LDAP_LIBDIR= ../../libraries
 BUILD_OPT = "--enable-slurpd"
 BUILD_SRV = @BUILD_SLURPD@
 
-all-local-srv:         slurpd
+all-local-srv:         $(PROGRAMS)
 
 # $(LTHREAD_LIBS) must be last!
 XLIBS = -lldif -lldap_r -llber -llutil
@@ -40,5 +44,11 @@ version.c: $(OBJS) $(LDAP_LIBDEPEND) $(LDAP_LIBTHREAD_DEPEND)
        $(MKVERSION) slurpd > $@
 
 install-local-srv: FORCE
-       @-$(MKDIR) $(libexecdir)
-       $(LTINSTALL) $(INSTALLFLAGS) -m 755 slurpd $(libexecdir)
+       -$(MKDIR) $(DESTDIR)$(libexecdir)
+       @(                                                              \
+           for prg in $(PROGRAMS); do                                  \
+               $(LTINSTALL) $(INSTALLFLAGS) -s -m 755 $$prg$(EXEEXT)   \
+                   $(DESTDIR)$(libexecdir);                            \
+           done                                                        \
+       )
+
index 81b45df4eb68e2ae55afc5a711ec494d80a3e9f0..ff28e0bb4f215ef6c9460bad6b1a5f05a04eb134 100644 (file)
@@ -36,11 +36,11 @@ usage( char *name )
 {
     fprintf( stderr, "usage: %s\t[-d debug-level] [-s syslog-level]\n", name );
     fprintf( stderr, "\t\t[-f slapd-config-file] [-r replication-log-file]\n" );
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
     fprintf( stderr, "\t\t[-t tmp-dir] [-o] [-k srvtab-file]\n" );
-#else /* HAVE_KERBEROS */
+#else /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
     fprintf( stderr, "\t\t[-t tmp-dir] [-o]\n" );
-#endif /* HAVE_KERBEROS */
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
 }
 
 
@@ -111,14 +111,15 @@ doargs(
            rflag++;
            break;
        case 't':       /* dir to use for our copies of replogs */
-           g->slurpd_rdir = strdup( optarg );
+           g->slurpd_rdir = (char *)malloc (strlen(optarg) + strlen("/replica") + 1);
+           sprintf(g->slurpd_rdir, "%s/replica", optarg);
            break;
        case 'k':       /* name of kerberos srvtab file */
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
            g->default_srvtab = strdup( optarg );
-#else /* HAVE_KERBEROS */
+#else /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
            fprintf( stderr, "must compile with KERBEROS to use -k option\n" );
-#endif /* HAVE_KERBEROS */
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
            break;
        case 'h':
            usage( g->myname );
@@ -152,7 +153,7 @@ doargs(
 
 #ifdef LOG_LOCAL4
     openlog( g->myname, OPENLOG_OPTIONS, LOG_LOCAL4 );
-#else
+#elif LOG_DEBUG
     openlog( g->myname, OPENLOG_OPTIONS );
 #endif
 
index 8a12eec1fac3b984f2f19b12e9ede0fa1884fd53..1df612324005a4dfa56b056644991200f7cd96e6 100644 (file)
@@ -104,7 +104,7 @@ slurpd_read_config(
                        lineno, cargv[1] );
                    fprintf( stderr, "line (ignored)\n" );
                }
-               sprintf( sglob->slapd_replogfile, cargv[1] );
+               strcpy( sglob->slapd_replogfile, cargv[1] );
            }
        } else if ( strcasecmp( cargv[0], "replica" ) == 0 ) {
            add_replica( cargv, cargc );
@@ -355,13 +355,13 @@ parse_replica_line(
                strlen( BINDMETHSTR ))) {
            val = cargv[ i ] + strlen( BINDMETHSTR ) + 1;
            if ( !strcasecmp( val, KERBEROSSTR )) {
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
                ri->ri_bind_method = AUTH_KERBEROS;
                if ( ri->ri_srvtab == NULL ) {
                    ri->ri_srvtab = strdup( sglob->default_srvtab );
                }
                gots |= GOT_METHOD;
-#else /* HAVE_KERBEROS */
+#else /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
            fprintf( stderr, "Error: a bind method of \"kerberos\" was\n" );
            fprintf( stderr, "specified in the slapd configuration file,\n" );
            fprintf( stderr, "but slurpd was not built with kerberos.\n" );
@@ -369,7 +369,7 @@ parse_replica_line(
            fprintf( stderr, "kerberos support if you wish to use\n" );
            fprintf( stderr, "bindmethod=kerberos\n" );
            exit( EXIT_FAILURE );
-#endif /* HAVE_KERBEROS */
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
            } else if ( !strcasecmp( val, SIMPLESTR )) {
                ri->ri_bind_method = AUTH_SIMPLE;
                gots |= GOT_METHOD;
index 18f5a12fdb68d35d3245966a082650b25d36b363..9c7911ffd5aa73cab0eb0e0f57dd25ca5e9fdfb8 100644 (file)
@@ -50,7 +50,7 @@ init_globals( void )
     g->slurpd_shutdown = 0;
     g->num_replicas = 0;
     g->replicas = NULL;
-    g->slurpd_rdir = DEFAULT_SLURPD_REPLICA_DIR;
+    g->slurpd_rdir = DEFAULT_SLURPD_REPLICA_DIR "/replica";
     strcpy( g->slurpd_status_file, DEFAULT_SLURPD_STATUS_FILE );
     g->slapd_replogfile[ 0 ] = '\0';
     g->slurpd_replogfile[ 0 ] = '\0';
@@ -68,9 +68,9 @@ init_globals( void )
        fprintf( stderr, "Cannot initialize queue\n" );
        exit( EXIT_FAILURE );
     }
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
     g->default_srvtab = SRVTAB;
-#endif /* HAVE_KERBEROS */
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
 
     return g;
 }
index 645cf0593ab0887b16ebfbdc252b65aab66d4eda..a7ea523c683779af480d083cc04da7a691e0defa 100644 (file)
@@ -57,10 +57,10 @@ typedef struct globals {
     St *st;
     /* Pointer to replication queue */
     Rq *rq;
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
     /* Default name of kerberos srvtab file */
     char *default_srvtab;
-#endif /* HAVE_KERBEROS */
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
 } Globals;
 
 
index a6873045dabfefbaa19cec6371fd9d19392c86bb..dae3e8698a452191e1f464959591d794a9f011b5 100644 (file)
@@ -51,7 +51,7 @@ static void free_ldmarr LDAP_P(( LDAPMod ** ));
 static int getmodtype LDAP_P(( char * ));
 static void dump_ldm_array LDAP_P(( LDAPMod ** ));
 static char **read_krbnames LDAP_P(( Ri * ));
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
 static void upcase LDAP_P(( char * ));
 #endif
 static int do_bind LDAP_P(( Ri *, int * ));
@@ -89,8 +89,10 @@ do_ldap(
     while ( retry > 0 ) {
        if ( ri->ri_ldp == NULL ) {
            rc = do_bind( ri, &lderr );
+
            if ( rc != BIND_OK ) {
-               return DO_LDAP_ERR_RETRYABLE;
+                       (void) do_unbind( ri );
+                       return DO_LDAP_ERR_RETRYABLE;
            }
        }
 
@@ -471,7 +473,7 @@ op_ldap_modrdn(
 #endif /* LDAP_DEBUG */
 
     /* Do the modrdn */
-    rc = ldap_rename2_s( ri->ri_ldp, re->re_dn, mi->mi_val, drdnflag, newsup );
+    rc = ldap_rename2_s( ri->ri_ldp, re->re_dn, mi->mi_val, newsup, drdnflag );
 
        ldap_get_option( ri->ri_ldp, LDAP_OPT_ERROR_NUMBER, &lderr);
     return( lderr );
@@ -625,7 +627,7 @@ do_bind(
 )
 {
     int                ldrc;
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
     int rc;
     int retval = 0;
     int kni, got_tgt;
@@ -634,7 +636,7 @@ do_bind(
     char realm[ REALM_SZ ];
     char name[ ANAME_SZ ];
     char instance[ INST_SZ ];
-#endif /* HAVE_KERBEROS */
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
 
     *lderr = 0;
 
@@ -680,12 +682,12 @@ do_bind(
 
     switch ( ri->ri_bind_method ) {
     case AUTH_KERBEROS:
-#ifndef HAVE_KERBEROS
+#ifndef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
        Debug( LDAP_DEBUG_ANY,
            "Error: Kerberos bind for %s:%d, but not compiled w/kerberos\n",
            ri->ri_hostname, ri->ri_port, 0 );
        return( BIND_ERR_KERBEROS_FAILED );
-#else /* HAVE_KERBEROS */
+#else /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
        /*
         * Bind using kerberos.
         * If "bindprincipal" was given in the config file, then attempt
@@ -761,7 +763,7 @@ kexit:      if ( krbnames != NULL ) {
        }
        return( retval);
        break;
-#endif /* HAVE_KERBEROS */
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
     case AUTH_SIMPLE:
        /*
         * Bind with a plaintext password.
@@ -855,7 +857,7 @@ read_krbnames(
        return( NULL );
     }
     rc = ldap_search_st( ri->ri_ldp, ri->ri_bind_dn, LDAP_SCOPE_BASE,
-           "objectclass=*", kattrs, 0, &kst, &result );
+           NULL, kattrs, 0, &kst, &result );
     if ( rc != LDAP_SUCCESS ) {
        Debug( LDAP_DEBUG_ANY,
                "Error: search failed getting krbnames for %s:%d: %s\n",
@@ -888,7 +890,7 @@ read_krbnames(
 }
 
 
-#ifdef HAVE_KERBEROS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
 
 /*
  * upcase a string
@@ -905,4 +907,4 @@ upcase(
     }
 }
 
-#endif /* HAVE_KERBEROS */
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
index eb957c288b557d7975b4e6fd61e02e8358f84733..c863d4b9e82c85ecf9ed6b480a6562a97d7d51d1 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <stdio.h>
 
+#include <ac/param.h>
 #include <ac/string.h>
 #include <ac/socket.h>
 #include <ac/time.h>
@@ -27,9 +28,6 @@
 #ifdef HAVE_SYS_FILE_H
 #include <sys/file.h>
 #endif
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
 
 #include "slurp.h"
 
index 2aa86e75c9bb3789fd0c5d5a7198c741bfd46399..5a5a61fdb1d6fd146d4fd670a386de7db066792d 100644 (file)
@@ -70,6 +70,14 @@ main(
        exit( EXIT_FAILURE );
     }
 
+    /* 
+     * Make sure our directory exists
+     */
+    if ( mkdir(sglob->slurpd_rdir, 0755) == -1 && errno != EEXIST) {
+       perror(sglob->slurpd_rdir);
+       exit( 1 );
+    }
+
     /*
      * Get any saved state information off the disk.
      */
@@ -94,13 +102,6 @@ main(
     if ( ! (sglob->no_detach || sglob->one_shot_mode) )
        lutil_detach( 0, 0 );
 
-    /*
-     * Start threads - one thread for each replica
-     */
-    for ( i = 0; sglob->replicas[ i ] != NULL; i++ ) {
-       start_replica_thread( sglob->replicas[ i ]);
-    }
-
     /*
      * Start the main file manager thread (in fm.c).
      */
@@ -113,10 +114,26 @@ main(
 
     }
 
+    /*
+     * wait for fm to finish if in oneshot mode
+     */
+    if ( sglob->one_shot_mode ) {
+       ldap_pvt_thread_join( sglob->fm_tid, (void *) NULL );
+    }
+
+    /*
+     * Start threads - one thread for each replica
+     */
+    for ( i = 0; sglob->replicas[ i ] != NULL; i++ ) {
+       start_replica_thread( sglob->replicas[ i ]);
+    }
+
     /*
      * Wait for the fm thread to finish.
      */
-    ldap_pvt_thread_join( sglob->fm_tid, (void *) NULL );
+    if ( !sglob->one_shot_mode ) {
+       ldap_pvt_thread_join( sglob->fm_tid, (void *) NULL );
+    }
 
     /*
      * Wait for the replica threads to finish.
@@ -125,8 +142,8 @@ main(
        ldap_pvt_thread_join( sglob->replicas[ i ]->ri_tid, (void *) NULL );
     }
 
-       /* destroy the thread package */
-       ldap_pvt_thread_destroy();
+    /* destroy the thread package */
+    ldap_pvt_thread_destroy();
 
     Debug( LDAP_DEBUG_ANY, "slurpd: terminated.\n", 0, 0, 0 );
        return 0;
index f4c738061a339f47656ff3a62f3a3b18888b8ff1..d13ea4bb813c2f53704eda42cd644b2863576208 100644 (file)
@@ -21,6 +21,7 @@
 #include <stdio.h>
 
 #include <ac/errno.h>
+#include <ac/param.h>
 #include <ac/string.h>
 #include <ac/syslog.h>
 #include <ac/time.h>
 
 #include <sys/stat.h>
 
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
 #include <fcntl.h>
 
 #include "slurp.h"
index 0dd599ba6db120d5d278d2fd71eb5c698322cacd..1706ac0222a78db7f308cd7fa4762517109f9563 100644 (file)
 #include "portable.h"
 
 #include <stdio.h>
+#include <sys/stat.h>
 
 #include <ac/stdlib.h>
 #include <ac/string.h>
 #include <ac/unistd.h>         /* get ftruncate() */
 
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
 #include "slurp.h"
 #include "globals.h"
 
@@ -230,17 +238,28 @@ Rq_dump(
 {
     Re         *re;
     FILE       *fp;
+    int                tmpfd;
 
     if ( rq == NULL ) {
        Debug( LDAP_DEBUG_ANY, "Rq_dump: rq is NULL!\n", 0, 0, 0 );
        return;
     }
 
-    if (( fp = fopen( SLURPD_DUMPFILE, "w" )) == NULL ) {
+    if (unlink(SLURPD_DUMPFILE) == -1 && errno != ENOENT) {
+       Debug( LDAP_DEBUG_ANY, "Rq_dump: \"%s\" exists, and cannot unlink\n",
+               SLURPD_DUMPFILE, 0, 0 );
+       return;
+    }
+    if (( tmpfd = open(SLURPD_DUMPFILE, O_CREAT|O_RDWR|O_EXCL, 0600)) == -1) {
        Debug( LDAP_DEBUG_ANY, "Rq_dump: cannot open \"%s\" for write\n",
                SLURPD_DUMPFILE, 0, 0 );
        return;
     }
+    if (( fp = fdopen( tmpfd, "w" )) == NULL ) {
+       Debug( LDAP_DEBUG_ANY, "Rq_dump: cannot fdopen \"%s\" for write\n",
+               SLURPD_DUMPFILE, 0, 0 );
+       return;
+    }
 
     rq->rq_lock( rq );
     for ( re = rq->rq_gethead( rq ); re != NULL; re = rq->rq_getnext( re )) {
@@ -359,7 +378,7 @@ Rq_getcount(
        for ( re = rq->rq_gethead( rq ); re != NULL;
                re = rq->rq_getnext( re )) {
            if ( type == RQ_COUNT_NZRC ) {
-               if ( re->re_getrefcnt( re ) > 1 ) {
+               if ( re->re_getrefcnt( re ) > 0 ) {
                    count++;
                }
            }
index 56886ff420ccef02d05a09bdfbf58b8b59d49cb4..ab6880c0b0c09686d961372ed63d270b42db2e69 100644 (file)
@@ -174,7 +174,7 @@ filecheck(
     char               *p;
     unsigned int       ret = 0;
 
-    strcpy( dir, sglob->slapd_replogfile );
+    strcpy( dir, f );
     p = strrchr( dir, '/' );
     if ( p != NULL ) {
        *p = '\0';
index 19a6c9d58b9c26ee74d6f398794759c0903da2fd..26368bd4876fa2e1c4ffc08afedee795f49ceaf7 100644 (file)
 #endif
 
 #include <ac/errno.h>
+#include <ac/param.h>
 #include <ac/signal.h>
 #include <ac/syslog.h>
 #include <ac/time.h>
 
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
 #include <sys/types.h>
 
 #include <ldap.h>
index 8a76b0b181d04d239c82ada31e47b627dc3e38fd..f0addb7fa672b90499e45ae084d4eddb9960e6eb 100644 (file)
@@ -63,7 +63,7 @@ St_add(
 
     st->st_data[ ind ]->hostname = strdup( ri->ri_hostname );
     st->st_data[ ind ]->port = ri->ri_port;
-    memset( st->st_data[ ind ]->last, 0, sizeof( st->st_data[ ind ]->last )); 
+    memset( st->st_data[ ind ]->last, '\0', sizeof( st->st_data[ ind ]->last )); 
     st->st_data[ ind ]->seq = 0;
 
     ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
index d469c700ebde250d80f2f91fc3f901d9f786fd03..d75fad857c3605831b1467fdbd19238132437d89 100644 (file)
@@ -1,36 +1,30 @@
 # $OpenLDAP$
-## Copyright 1998 The OpenLDAP Foundation, All Rights Reserved.
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
 ## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 ##
 ## tests Makefile.in for OpenLDAP
 SUBDIRS= progs
-
-BUILD_BDB2 = @BUILD_BDB2@
+BUILD_LDBM=@BUILD_LDBM@
 
 test: tests
-tests: bdb2 ldbm
-
-bdb2: test-bdb2
-test-bdb2:     FORCE
-       @-$(LN_S) $(srcdir)/data . 
-       @if test "$(BUILD_BDB2)" = "yes" ; then \
-               echo "Initiating LDAP tests..." ; \
-               $(MKDIR) test-db test-repl || true; \
-               $(srcdir)/scripts/all $(srcdir) bdb2 ; \
-       else \
-               echo "run configure with --enable-bdb2" ; \
-       fi
+tests: ldbm
 
 ldbm: test-ldbm
 test-ldbm:     FORCE
        @-$(LN_S) $(srcdir)/data .
-       @echo "Initiating LDAP tests..."
-       @-$(MKDIR) test-db test-repl || true
-       @$(srcdir)/scripts/all $(srcdir) ldbm
+       @-$(LN_S) $(top_srcdir)/servers/slapd/schema .
+       @if test "$(BUILD_LDBM)" = "yes" ; then \
+               echo "Initiating LDAP tests for LDBM..." ; \
+               $(MKDIR) test-db test-repl || true; \
+               $(srcdir)/scripts/all $(srcdir) ldbm ; \
+       else \
+               echo "run configure with --enable-ldbm" ; \
+       fi
 
 passwd: test-passwd
 test-passwd: FORCE
        @-$(LN_S) $(srcdir)/data .
+       @-$(LN_S) $(top_srcdir)/servers/slapd/schema .
        @echo "Initiating LDAP tests..."
        @-$(MKDIR) test-db test-repl || true
        @$(srcdir)/scripts/passwd-search $(srcdir) passwd
@@ -38,25 +32,15 @@ test-passwd: FORCE
 test-nis-schema:        test-nis-schema-ldbm
 test-nis-schema-ldbm:
        @-$(LN_S) $(srcdir)/data .
+       @-$(LN_S) $(top_srcdir)/servers/slapd/schema .
        @echo "Initiating LDAP server with NIS schema & ldbm backend..."; \
        $(MKDIR) test-db test-repl ; \
        $(srcdir)/scripts/startup_nis_ldap_server.sh $(srcdir) ldbm
 
-test-nis-schema-bdb2:
-       @-$(LN_S) $(srcdir)/data .
-       @echo "Initiating LDAP server with NIS schema & DB2 backend..."; \
-       @if test "$(BUILD_BDB2)" = "yes" ; then \
-               echo "Initiating LDAP tests..." ; \
-               $(MKDIR) test-db test-repl ; \
-               $(srcdir)/scripts/startup_nis_ldap_server.sh $(srcdir) bdb2 ; \
-       else \
-               echo "run configure with --enable-bdb2" ; \
-       fi
-
 clean-local:   FORCE
        -$(RM) test-db/[!C]* test-repl/[!C]* *leak *gmon *core
 
 veryclean-local: FORCE
-       @-$(RM) data
-       $(RM) -r test-db test-repl
+       @-$(RM) data schema
+       -$(RM) -r test-db test-repl
 
index 1e4633b675cd68b0d8484f7efe34d534029f2482..d1fdfb7ae7e79e95b8b3b201648ab88b72f9d195 100644 (file)
@@ -1,3 +1,13 @@
 This directory contains a series of test scripts which are used to
 verify basic functionality of the LDAP libraries, slapd, and slurpd.
-To run the tests, type "make" in the ./tests directory.
+
+       To run all of the tests, type "make test".
+       To run LDBM tests, type "make ldbm".
+
+To modify the debug level the tests run slapd with, set the SLAPD_DEBUG
+environment variable.
+       env SLAPD_DEBUG=1 make test
+
+To test LDAPv3, set PROTO to "-P 3".
+       env PROTO="-P 3" make test
+
index d88eaa12451cfa70fd906269702432d6c1bc1b68..967a64073c4fa6ca605fe1453b096f0b4707b4fb 100644 (file)
@@ -4,20 +4,15 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: James A Jones 1
 cn: James Jones
 cn: Jim Jones
 sn: Jones
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jaj
-krbname: jaj@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 3882 Beverly Rd. $ Ann Arbor, MI 48105
 homephone: +1 313 555 4772
-multilinedescription: Outstanding
+description: Outstanding
 title: Mad Cow Researcher, UM Alumni Association
 pager: +1 313 555 3923
 mail: jaj@mail.alumni.umich.edu
@@ -45,14 +40,10 @@ member: cn=Ursula Hampster, ou=Alumni Association, ou=People, o=University of
  Michigan, c=US
 member: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, o=Univ
  ersity of Michigan, c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
 cn: All Staff
-joinable: FALSE
-multilinedescription: Everyone in the sample data
-objectclass: rfc822mailgroup
+description: Everyone in the sample data
+objectclass: groupofnames
 
 dn: cn=Alumni Assoc Staff,ou=Groups,o=University of Michigan,c=US
 member: cn=Manager, o=University of Michigan, c=US
@@ -68,14 +59,10 @@ member: cn=Mark Elliot, ou=Alumni Association, ou=People, o=University of Mich
  igan, c=US
 member: cn=Ursula Hampster, ou=Alumni Association, ou=People, o=University of 
  Michigan, c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
-multilinedescription: All Alumni Assoc Staff
+description: All Alumni Assoc Staff
 cn: Alumni Assoc Staff
-joinable: FALSE
-objectclass: rfc822mailgroup
+objectclass: groupofnames
 
 dn: ou=Alumni Association, ou=People, o=University of Michigan, c=US
 objectclass: top
@@ -88,7 +75,6 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Barbara Jensen
 cn: Babs Jensen
 sn: Jensen
@@ -96,15 +82,9 @@ title: Mythical Manager, Research Systems
 postaladdress: ITD Prod Dev & Deployment $ 535 W. William St. Room 4212 $ Ann 
  Arbor, MI 48103-4943
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: bjensen
 mail: bjensen@mailgw.umich.edu
 homepostaladdress: 123 Wesley $ Ann Arbor, MI 48103
-krbname: bjensen@umich.edu
-multilinedescription: Mythical manager of the rsdd unix project
-nobatchupdates: TRUE
-notice: Off sailing this month.
-onvacation: FALSE
-labeledurl: http://www.umich.edu/ U-M Home Page
+description: Mythical manager of the rsdd unix project
 drink: water
 homephone: +1 313 555 2333
 pager: +1 313 555 3233
@@ -117,18 +97,13 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Bjorn Jensen
 cn: Biiff Jensen
 sn: Jensen
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: bjorn
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 19923 Seven Mile Rd. $ South Lyon, MI 49999
 drink: Iced Tea
-multilinedescription: Hiker, biker
+description: Hiker, biker
 title: Director, Embedded Systems
 postaladdress: Info Tech Division $ 535 W. William St. $ Ann Arbor, MI 48103
 mail: bjorn@mailgw.umich.edu
@@ -149,14 +124,10 @@ objectclass: organizationalUnit
 ou: Information Technology Divisio
 
 dn: cn=ITD Staff,ou=Groups,o=University of Michigan,c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
-multilinedescription: All ITD Staff
+description: All ITD Staff
 cn: ITD Staff
-joinable: FALSE
-objectclass: rfc822mailgroup
+objectclass: groupofnames
 member: cn=Manager, o=University of Michigan, c=US
 member: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, o=Univ
  ersity of Michigan, c=US
@@ -166,8 +137,7 @@ member: cn=John Doe, ou=Information Technology Division, ou=People, o=Universi
  ty of Michigan, c=US
 member: cn=James A Jones 1, ou=Alumni Association, ou=People, o=University of 
  Michigan, c=US
-labeledurl: http://www.itd.umich.edu ITD Home Page
-telephonenumber: +1 810 555 1212
+ou: Groups
 
 dn: cn=James A Jones 2, ou=Information Technology Division, ou=People, o=Unive
  rsity of Michigan, c=US
@@ -175,20 +145,15 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: James A Jones 2
 cn: James Jones
 cn: Jim Jones
 sn: Doe
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jjones
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 933 Brooks $ Ann Arbor, MI 48104
 homephone: +1 313 555 8838
 title: Senior Manager, Information Technology Division
-multilinedescription: Not around very much
+description: Not around very much
 mail: jjones@mailgw.umich.edu
 postaladdress: Info Tech Division $ 535 W William $ Ann Arbor, MI 48103
 pager: +1 313 555 2833
@@ -201,19 +166,14 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: John Doe
 cn: Jonathon Doe
 sn: Doe
 postaladdress: ITD $ 535 W. William $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: johnd
-krbname: johnd@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 912 East Bllvd $ Ann Arbor, MI 48104
 title: System Administrator, Information Technology Division
-multilinedescription: overworked!
+description: overworked!
 mail: johnd@mailgw.umich.edu
 homephone: +1 313 555 3774
 pager: +1 313 555 6573
@@ -223,13 +183,11 @@ telephonenumber: +1 313 555 9394
 dn: cn=Manager, o=University of Michigan, c=US
 objectclass: top
 objectclass: person
-objectclass: kerberosSecurityObject
 cn: Manager
 cn: Directory Manager
 cn: Dir Man
 sn: Manager
 description: Manager of the directory
-krbname: bjensen@umich.edu
 
 dn: ou=People, o=University of Michigan, c=US
 objectclass: top
@@ -242,7 +200,6 @@ objectclass: organization
 objectclass: domainRelatedObject
 l: Ann Arbor, Michigan
 st: Michigan
-streetaddress: 535 West William St.
 o: University of Michigan
 o: UMICH
 o: UM
index d5c58ef83fe158ac0b406f6fd9dd628bad044d41..01196d8360cb52ebc2dc300650b988b8d61c9e0e 100644 (file)
@@ -3,21 +3,16 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: James A Jones 2
 cn: James Jones
 cn: Jim Jones
 sn: Jones
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jaj
-krbname: jaj@umich.edu
 userpassword:: amFq
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 3882 Beverly Rd. $ Ann Arbor, MI 48105
 homephone: +1 313 555 4772
-multilinedescription: Outstanding
+description: Outstanding
 title: Mad Cow Researcher, UM Alumni Association
 pager: +1 313 555 3923
 mail: jaj@mail.alumni.umich.edu
index 69e72cd274b0e1597adb41c587ff1cce74f2230a..429d901fa60bfa0959d55e57def0a1b470dfe17f 100644 (file)
@@ -1,12 +1,10 @@
 dn: cn=All Staff,ou=Groups,o=University of Michigan,c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
 cn: All Staff
-joinable: FALSE
-multilinedescription: Everyone in the sample data
-objectclass: rfc822mailgroup
+description: Everyone in the sample data
+objectclass: groupofnames
+member: cn=Dorothy Stevens, ou=Alumni Association, ou=People, o=University of 
+ Michigan, c=US
 
 dn: cn=Alumni Assoc Staff,ou=Groups,o=University of Michigan,c=US
 member: cn=Manager, o=University of Michigan, c=US
@@ -22,14 +20,10 @@ member: cn=Mark Elliot, ou=Alumni Association, ou=People, o=University of Mich
  igan, c=US
 member: cn=Ursula Hampster, ou=Alumni Association, ou=People, o=University of 
  Michigan, c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
-multilinedescription: All Alumni Assoc Staff
+description: All Alumni Assoc Staff
 cn: Alumni Assoc Staff
-joinable: FALSE
-objectclass: rfc822mailgroup
+objectclass: groupofnames
 
 dn: ou=Alumni Association, ou=People, o=University of Michigan, c=US
 objectclass: top
@@ -42,7 +36,6 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Barbara Jensen
 cn: Babs Jensen
 sn: Jensen
@@ -50,16 +43,10 @@ title: Mythical Manager, Research Systems
 postaladdress: ITD Prod Dev & Deployment $ 535 W. William St. Room 4212 $ Ann 
  Arbor, MI 48103-4943
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: bjensen
 userpassword:: YmplbnNlbg==
 mail: bjensen@mailgw.umich.edu
 homepostaladdress: 123 Wesley $ Ann Arbor, MI 48103
-krbname: bjensen@umich.edu
-multilinedescription: Mythical manager of the rsdd unix project
-nobatchupdates: TRUE
-notice: Off sailing this month.
-onvacation: FALSE
-labeledurl: http://www.umich.edu/ U-M Home Page
+description: Mythical manager of the rsdd unix project
 drink: water
 homephone: +1 313 555 2333
 pager: +1 313 555 3233
@@ -72,16 +59,11 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Bjorn Jensen
 cn: Biiff Jensen
 sn: Jensen
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: bjorn
 userpassword:: Ympvcm4=
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 19923 Seven Mile Rd. $ South Lyon, MI 49999
 title: Director, Embedded Systems
 postaladdress: Info Tech Division $ 535 W. William St. $ Ann Arbor, MI 48103
@@ -90,7 +72,7 @@ homephone: +1 313 555 5444
 pager: +1 313 555 4474
 facsimiletelephonenumber: +1 313 555 2177
 telephonenumber: +1 313 555 0355
-multilinedescription: The replaced multiLineDescription $ Blah Woof.
+description: The replaced multiLineDescription $ Blah Woof.
 drink: Iced Tea
 drink: Mad Dog 20/20
 
@@ -100,20 +82,15 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Dorothy Stevens
 cn: Dot Stevens
 sn: Stevens
 title: Secretary, UM Alumni Association
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: dots
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 drink: Lemonade
 homepostaladdress: 377 White St. Apt. 3 $ Ann Arbor, MI 48104
-multilinedescription: Very tall
+description: Very tall
 facsimiletelephonenumber: +1 313 555 3223
 telephonenumber: +1 313 555 3664
 mail: dots@mail.alumni.umich.edu
@@ -125,18 +102,14 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Gern Jensen
+sn: Jensen
 title: Chief Investigator, ITD
 postaladdress: ITD $ 535 W. William St $ Ann Arbor, MI 48103
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: gjensen
-krbname: gjensen@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 drink: Coffee
 homepostaladdress: 844 Brown St. Apt. 4 $ Ann Arbor, MI 48104
-multilinedescription: Very odd
+description: Very odd
 facsimiletelephonenumber: +1 313 555 7557
 telephonenumber: +1 313 555 8343
 mail: gjensen@mailgw.umich.edu
@@ -154,14 +127,10 @@ objectclass: organizationalUnit
 ou: Information Technology Divisio
 
 dn: cn=ITD Staff,ou=Groups,o=University of Michigan,c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
-multilinedescription: All ITD Staff
+description: All ITD Staff
 cn: ITD Staff
-joinable: FALSE
-objectclass: rfc822mailgroup
+objectclass: groupofnames
 member: cn=Manager, o=University of Michigan, c=US
 member: cn=John Doe, ou=Information Technology Division, ou=People, o=Universi
  ty of Michigan, c=US
@@ -169,7 +138,6 @@ member: cn=Dorothy Stevens, ou=Alumni Association, ou=People, o=University of
  Michigan, c=US
 member: cn=James A Jones 1, ou=Alumni Association, ou=People, o=University of 
  Michigan, c=US
-labeledurl: http://www.itd.umich.edu ITD Home Page
 
 dn: cn=James A Jones 1, ou=Alumni Association, ou=People, o=University of Mich
  igan, c=US
@@ -177,21 +145,16 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: James A Jones 1
 cn: James Jones
 cn: Jim Jones
 sn: Jones
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jaj
-krbname: jaj@umich.edu
 userpassword:: amFq
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 3882 Beverly Rd. $ Ann Arbor, MI 48105
 homephone: +1 313 555 4772
-multilinedescription: Outstanding
+description: Outstanding
 title: Mad Cow Researcher, UM Alumni Association
 pager: +1 313 555 3923
 mail: jaj@mail.alumni.umich.edu
@@ -205,20 +168,15 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Jane Doe
 cn: Jane Alverson
 sn: Doe
 title: Programmer Analyst, UM Alumni Association
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jdoe
 homepostaladdress: 123 Anystreet $ Ann Arbor, MI 48104
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 drink: diet coke
-multilinedescription: Enthusiastic
+description: Enthusiastic
 mail: jdoe@woof.net
 homephone: +1 313 555 5445
 pager: +1 313 555 1220
@@ -231,16 +189,11 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Jennifer Smith
 cn: Jen Smith
 sn: Smith
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jen
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 drink: Sam Adams
 homepostaladdress: 1000 Maple #44 $ Ann Arbor, MI 48103
 title: Telemarketer, UM Alumni Association
@@ -256,19 +209,14 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: John Doe
 cn: Jonathon Doe
 sn: Doe
 postaladdress: ITD $ 535 W. William $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: johnd
-krbname: johnd@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 912 East Bllvd $ Ann Arbor, MI 48104
 title: System Administrator, Information Technology Division
-multilinedescription: overworked!
+description: overworked!
 mail: johnd@mailgw.umich.edu
 homephone: +1 313 555 3774
 pager: +1 313 555 6573
@@ -278,14 +226,12 @@ telephonenumber: +1 313 555 9394
 dn: cn=Manager, o=University of Michigan, c=US
 objectclass: top
 objectclass: person
-objectclass: kerberosSecurityObject
 cn: Manager
 cn: Directory Manager
 cn: Dir Man
 sn: Manager
 description: Manager of the directory
 userpassword:: c2VjcmV0
-krbname: bjensen@umich.edu
 
 dn: cn=Mark Elliot, ou=Alumni Association, ou=People, o=University of Michigan
  , c=US
@@ -293,16 +239,11 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Mark Elliot
 cn: Mark A Elliot
 sn: Elliot
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: melliot
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 199 Outer Drive $ Ypsilanti, MI 48198
 homephone: +1 313 555 0388
 drink: Gasoline
@@ -323,7 +264,6 @@ objectclass: organization
 objectclass: domainRelatedObject
 l: Ann Arbor, Michigan
 st: Michigan
-streetaddress: 535 West William St.
 o: University of Michigan
 o: UMICH
 o: UM
@@ -341,17 +281,12 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Ursula Hampster
 sn: Hampster
 title: Secretary, UM Alumni Association
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: uham
 homepostaladdress: 123 Anystreet $ Ann Arbor, MI 48104
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 mail: uham@mail.alumni.umich.edu
 homephone: +1 313 555 8421
 pager: +1 313 555 2844
index 8ec913d040321bcd59b54502bf0e8c44d594e63a..3e794d32c4577dbef4c65bf9ff36bc4057752f9c 100644 (file)
@@ -20,14 +20,10 @@ member: cn=Ursula Hampster, ou=Alumni Association, ou=People, o=University of
  Michigan, c=US
 member: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, o=Univ
  ersity of Michigan, c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
 cn: All Staff
-joinable: FALSE
-multilinedescription: Everyone in the sample data
-objectclass: rfc822mailgroup
+description: Everyone in the sample data
+objectclass: groupofnames
 
 dn: cn=Alumni Assoc Staff,ou=Groups,o=University of Michigan,c=US
 member: cn=Manager, o=University of Michigan, c=US
@@ -43,14 +39,10 @@ member: cn=Mark Elliot, ou=Alumni Association, ou=People, o=University of Mich
  igan, c=US
 member: cn=Ursula Hampster, ou=Alumni Association, ou=People, o=University of 
  Michigan, c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
-multilinedescription: All Alumni Assoc Staff
+description: All Alumni Assoc Staff
 cn: Alumni Assoc Staff
-joinable: FALSE
-objectclass: rfc822mailgroup
+objectclass: groupofnames
 
 dn: ou=Alumni Association, ou=People, o=University of Michigan, c=US
 objectclass: top
@@ -63,7 +55,6 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Barbara Jensen
 cn: Babs Jensen
 sn: Jensen
@@ -71,16 +62,10 @@ title: Mythical Manager, Research Systems
 postaladdress: ITD Prod Dev & Deployment $ 535 W. William St. Room 4212 $ Ann 
  Arbor, MI 48103-4943
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: bjensen
 userpassword:: YmplbnNlbg==
 mail: bjensen@mailgw.umich.edu
 homepostaladdress: 123 Wesley $ Ann Arbor, MI 48103
-krbname: bjensen@umich.edu
-multilinedescription: Mythical manager of the rsdd unix project
-nobatchupdates: TRUE
-notice: Off sailing this month.
-onvacation: FALSE
-labeledurl: http://www.umich.edu/ U-M Home Page
+description: Mythical manager of the rsdd unix project
 drink: water
 homephone: +1 313 555 2333
 pager: +1 313 555 3233
@@ -93,19 +78,14 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Bjorn Jensen
 cn: Biiff Jensen
 sn: Jensen
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: bjorn
 userpassword:: Ympvcm4=
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 19923 Seven Mile Rd. $ South Lyon, MI 49999
 drink: Iced Tea
-multilinedescription: Hiker, biker
+description: Hiker, biker
 title: Director, Embedded Systems
 postaladdress: Info Tech Division $ 535 W. William St. $ Ann Arbor, MI 48103
 mail: bjorn@mailgw.umich.edu
@@ -120,20 +100,15 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Dorothy Stevens
 cn: Dot Stevens
 sn: Stevens
 title: Secretary, UM Alumni Association
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: dots
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 drink: Lemonade
 homepostaladdress: 377 White St. Apt. 3 $ Ann Arbor, MI 48104
-multilinedescription: Very tall
+description: Very tall
 facsimiletelephonenumber: +1 313 555 3223
 telephonenumber: +1 313 555 3664
 mail: dots@mail.alumni.umich.edu
@@ -151,14 +126,10 @@ objectclass: organizationalUnit
 ou: Information Technology Divisio
 
 dn: cn=ITD Staff,ou=Groups,o=University of Michigan,c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
-multilinedescription: All ITD Staff
+description: All ITD Staff
 cn: ITD Staff
-joinable: FALSE
-objectclass: rfc822mailgroup
+objectclass: groupofnames
 member: cn=Manager, o=University of Michigan, c=US
 member: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, o=Univ
  ersity of Michigan, c=US
@@ -166,7 +137,6 @@ member: cn=James A Jones 2, ou=Information Technology Division, ou=People, o=U
  niversity of Michigan, c=US
 member: cn=John Doe, ou=Information Technology Division, ou=People, o=Universi
  ty of Michigan, c=US
-labeledurl: http://www.itd.umich.edu ITD Home Page
 
 dn: cn=James A Jones II, ou=Information Technology Division, ou=People, o=Univ
  ersity of Michigan, c=US
@@ -174,20 +144,15 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: James Jones
 cn: Jim Jones
 cn: James A Jones II
 sn: Doe
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jjones
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 933 Brooks $ Ann Arbor, MI 48104
 homephone: +1 313 555 8838
 title: Senior Manager, Information Technology Division
-multilinedescription: Not around very much
+description: Not around very much
 mail: jjones@mailgw.umich.edu
 postaladdress: Info Tech Division $ 535 W William $ Ann Arbor, MI 48103
 pager: +1 313 555 2833
@@ -200,7 +165,6 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: James A Jones 1
 cn: James Jones
 cn: Jim Jones
@@ -208,14 +172,10 @@ cn: James A Jones III
 sn: Jones
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jaj
-krbname: jaj@umich.edu
 userpassword:: amFq
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 3882 Beverly Rd. $ Ann Arbor, MI 48105
 homephone: +1 313 555 4772
-multilinedescription: Outstanding
+description: Outstanding
 title: Mad Cow Researcher, UM Alumni Association
 pager: +1 313 555 3923
 mail: jaj@mail.alumni.umich.edu
@@ -228,20 +188,15 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Jane Doe
 cn: Jane Alverson
 sn: Doe
 title: Programmer Analyst, UM Alumni Association
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jdoe
 homepostaladdress: 123 Anystreet $ Ann Arbor, MI 48104
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 drink: diet coke
-multilinedescription: Enthusiastic
+description: Enthusiastic
 mail: jdoe@woof.net
 homephone: +1 313 555 5445
 pager: +1 313 555 1220
@@ -254,16 +209,11 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Jennifer Smith
 cn: Jen Smith
 sn: Smith
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jen
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 drink: Sam Adams
 homepostaladdress: 1000 Maple #44 $ Ann Arbor, MI 48103
 title: Telemarketer, UM Alumni Association
@@ -279,19 +229,14 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: John Doe
 cn: Jonathon Doe
 sn: Doe
 postaladdress: ITD $ 535 W. William $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: johnd
-krbname: johnd@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 912 East Bllvd $ Ann Arbor, MI 48104
 title: System Administrator, Information Technology Division
-multilinedescription: overworked!
+description: overworked!
 mail: johnd@mailgw.umich.edu
 homephone: +1 313 555 3774
 pager: +1 313 555 6573
@@ -301,14 +246,12 @@ telephonenumber: +1 313 555 9394
 dn: cn=Manager, o=University of Michigan, c=US
 objectclass: top
 objectclass: person
-objectclass: kerberosSecurityObject
 cn: Manager
 cn: Directory Manager
 cn: Dir Man
 sn: Manager
 description: Manager of the directory
 userpassword:: c2VjcmV0
-krbname: bjensen@umich.edu
 
 dn: cn=Mark Elliot, ou=Alumni Association, ou=People, o=University of Michigan
  , c=US
@@ -316,16 +259,11 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Mark Elliot
 cn: Mark A Elliot
 sn: Elliot
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: melliot
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 199 Outer Drive $ Ypsilanti, MI 48198
 homephone: +1 313 555 0388
 drink: Gasoline
@@ -346,7 +284,6 @@ objectclass: organization
 objectclass: domainRelatedObject
 l: Ann Arbor, Michigan
 st: Michigan
-streetaddress: 535 West William St.
 o: University of Michigan
 o: UMICH
 o: UM
@@ -364,17 +301,12 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Ursula Hampster
 sn: Hampster
 title: Secretary, UM Alumni Association
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: uham
 homepostaladdress: 123 Anystreet $ Ann Arbor, MI 48104
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 mail: uham@mail.alumni.umich.edu
 homephone: +1 313 555 8421
 pager: +1 313 555 2844
index 8ec913d040321bcd59b54502bf0e8c44d594e63a..3e794d32c4577dbef4c65bf9ff36bc4057752f9c 100644 (file)
@@ -20,14 +20,10 @@ member: cn=Ursula Hampster, ou=Alumni Association, ou=People, o=University of
  Michigan, c=US
 member: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, o=Univ
  ersity of Michigan, c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
 cn: All Staff
-joinable: FALSE
-multilinedescription: Everyone in the sample data
-objectclass: rfc822mailgroup
+description: Everyone in the sample data
+objectclass: groupofnames
 
 dn: cn=Alumni Assoc Staff,ou=Groups,o=University of Michigan,c=US
 member: cn=Manager, o=University of Michigan, c=US
@@ -43,14 +39,10 @@ member: cn=Mark Elliot, ou=Alumni Association, ou=People, o=University of Mich
  igan, c=US
 member: cn=Ursula Hampster, ou=Alumni Association, ou=People, o=University of 
  Michigan, c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
-multilinedescription: All Alumni Assoc Staff
+description: All Alumni Assoc Staff
 cn: Alumni Assoc Staff
-joinable: FALSE
-objectclass: rfc822mailgroup
+objectclass: groupofnames
 
 dn: ou=Alumni Association, ou=People, o=University of Michigan, c=US
 objectclass: top
@@ -63,7 +55,6 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Barbara Jensen
 cn: Babs Jensen
 sn: Jensen
@@ -71,16 +62,10 @@ title: Mythical Manager, Research Systems
 postaladdress: ITD Prod Dev & Deployment $ 535 W. William St. Room 4212 $ Ann 
  Arbor, MI 48103-4943
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: bjensen
 userpassword:: YmplbnNlbg==
 mail: bjensen@mailgw.umich.edu
 homepostaladdress: 123 Wesley $ Ann Arbor, MI 48103
-krbname: bjensen@umich.edu
-multilinedescription: Mythical manager of the rsdd unix project
-nobatchupdates: TRUE
-notice: Off sailing this month.
-onvacation: FALSE
-labeledurl: http://www.umich.edu/ U-M Home Page
+description: Mythical manager of the rsdd unix project
 drink: water
 homephone: +1 313 555 2333
 pager: +1 313 555 3233
@@ -93,19 +78,14 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Bjorn Jensen
 cn: Biiff Jensen
 sn: Jensen
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: bjorn
 userpassword:: Ympvcm4=
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 19923 Seven Mile Rd. $ South Lyon, MI 49999
 drink: Iced Tea
-multilinedescription: Hiker, biker
+description: Hiker, biker
 title: Director, Embedded Systems
 postaladdress: Info Tech Division $ 535 W. William St. $ Ann Arbor, MI 48103
 mail: bjorn@mailgw.umich.edu
@@ -120,20 +100,15 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Dorothy Stevens
 cn: Dot Stevens
 sn: Stevens
 title: Secretary, UM Alumni Association
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: dots
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 drink: Lemonade
 homepostaladdress: 377 White St. Apt. 3 $ Ann Arbor, MI 48104
-multilinedescription: Very tall
+description: Very tall
 facsimiletelephonenumber: +1 313 555 3223
 telephonenumber: +1 313 555 3664
 mail: dots@mail.alumni.umich.edu
@@ -151,14 +126,10 @@ objectclass: organizationalUnit
 ou: Information Technology Divisio
 
 dn: cn=ITD Staff,ou=Groups,o=University of Michigan,c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
-multilinedescription: All ITD Staff
+description: All ITD Staff
 cn: ITD Staff
-joinable: FALSE
-objectclass: rfc822mailgroup
+objectclass: groupofnames
 member: cn=Manager, o=University of Michigan, c=US
 member: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, o=Univ
  ersity of Michigan, c=US
@@ -166,7 +137,6 @@ member: cn=James A Jones 2, ou=Information Technology Division, ou=People, o=U
  niversity of Michigan, c=US
 member: cn=John Doe, ou=Information Technology Division, ou=People, o=Universi
  ty of Michigan, c=US
-labeledurl: http://www.itd.umich.edu ITD Home Page
 
 dn: cn=James A Jones II, ou=Information Technology Division, ou=People, o=Univ
  ersity of Michigan, c=US
@@ -174,20 +144,15 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: James Jones
 cn: Jim Jones
 cn: James A Jones II
 sn: Doe
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jjones
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 933 Brooks $ Ann Arbor, MI 48104
 homephone: +1 313 555 8838
 title: Senior Manager, Information Technology Division
-multilinedescription: Not around very much
+description: Not around very much
 mail: jjones@mailgw.umich.edu
 postaladdress: Info Tech Division $ 535 W William $ Ann Arbor, MI 48103
 pager: +1 313 555 2833
@@ -200,7 +165,6 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: James A Jones 1
 cn: James Jones
 cn: Jim Jones
@@ -208,14 +172,10 @@ cn: James A Jones III
 sn: Jones
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jaj
-krbname: jaj@umich.edu
 userpassword:: amFq
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 3882 Beverly Rd. $ Ann Arbor, MI 48105
 homephone: +1 313 555 4772
-multilinedescription: Outstanding
+description: Outstanding
 title: Mad Cow Researcher, UM Alumni Association
 pager: +1 313 555 3923
 mail: jaj@mail.alumni.umich.edu
@@ -228,20 +188,15 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Jane Doe
 cn: Jane Alverson
 sn: Doe
 title: Programmer Analyst, UM Alumni Association
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jdoe
 homepostaladdress: 123 Anystreet $ Ann Arbor, MI 48104
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 drink: diet coke
-multilinedescription: Enthusiastic
+description: Enthusiastic
 mail: jdoe@woof.net
 homephone: +1 313 555 5445
 pager: +1 313 555 1220
@@ -254,16 +209,11 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Jennifer Smith
 cn: Jen Smith
 sn: Smith
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jen
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 drink: Sam Adams
 homepostaladdress: 1000 Maple #44 $ Ann Arbor, MI 48103
 title: Telemarketer, UM Alumni Association
@@ -279,19 +229,14 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: John Doe
 cn: Jonathon Doe
 sn: Doe
 postaladdress: ITD $ 535 W. William $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: johnd
-krbname: johnd@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 912 East Bllvd $ Ann Arbor, MI 48104
 title: System Administrator, Information Technology Division
-multilinedescription: overworked!
+description: overworked!
 mail: johnd@mailgw.umich.edu
 homephone: +1 313 555 3774
 pager: +1 313 555 6573
@@ -301,14 +246,12 @@ telephonenumber: +1 313 555 9394
 dn: cn=Manager, o=University of Michigan, c=US
 objectclass: top
 objectclass: person
-objectclass: kerberosSecurityObject
 cn: Manager
 cn: Directory Manager
 cn: Dir Man
 sn: Manager
 description: Manager of the directory
 userpassword:: c2VjcmV0
-krbname: bjensen@umich.edu
 
 dn: cn=Mark Elliot, ou=Alumni Association, ou=People, o=University of Michigan
  , c=US
@@ -316,16 +259,11 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Mark Elliot
 cn: Mark A Elliot
 sn: Elliot
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: melliot
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 199 Outer Drive $ Ypsilanti, MI 48198
 homephone: +1 313 555 0388
 drink: Gasoline
@@ -346,7 +284,6 @@ objectclass: organization
 objectclass: domainRelatedObject
 l: Ann Arbor, Michigan
 st: Michigan
-streetaddress: 535 West William St.
 o: University of Michigan
 o: UMICH
 o: UM
@@ -364,17 +301,12 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Ursula Hampster
 sn: Hampster
 title: Secretary, UM Alumni Association
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: uham
 homepostaladdress: 123 Anystreet $ Ann Arbor, MI 48104
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 mail: uham@mail.alumni.umich.edu
 homephone: +1 313 555 8421
 pager: +1 313 555 2844
index c3b1782d6f7c5e0b0eeea86d74e15615922c0a55..dfd8633d2844ee57beaada2a155320071eb0e795 100644 (file)
@@ -4,7 +4,6 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: James A Jones 1
 cn: James Jones
 cn: Jim Jones
@@ -12,14 +11,10 @@ cn: James A Jones III
 sn: Jones
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jaj
-krbname: jaj@umich.edu
 userpassword:: amFq
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 3882 Beverly Rd. $ Ann Arbor, MI 48105
 homephone: +1 313 555 4772
-multilinedescription: Outstanding
+description: Outstanding
 title: Mad Cow Researcher, UM Alumni Association
 pager: +1 313 555 3923
 mail: jaj@mail.alumni.umich.edu
diff --git a/tests/data/modrdn.out.master.2 b/tests/data/modrdn.out.master.2
new file mode 100644 (file)
index 0000000..65279ea
--- /dev/null
@@ -0,0 +1,20 @@
+dn: cn=James A Jones II, ou=Information Technology Division, ou=People, o=Univ
+ ersity of Michigan, c=US
+objectclass: top
+objectclass: person
+objectclass: organizationalPerson
+objectclass: newPilotPerson
+cn: James Jones
+cn: Jim Jones
+cn: James A Jones II
+sn: Doe
+seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
+homepostaladdress: 933 Brooks $ Ann Arbor, MI 48104
+homephone: +1 313 555 8838
+title: Senior Manager, Information Technology Division
+description: Not around very much
+mail: jjones@mailgw.umich.edu
+postaladdress: Info Tech Division $ 535 W William $ Ann Arbor, MI 48103
+pager: +1 313 555 2833
+facsimiletelephonenumber: +1 313 555 8688
+telephonenumber: +1 313 555 7334
index f3aa8cf5d24d0889997be8629546e57d7849be1c..0345196c24c47fa9dc3619e5bd889baeab3d6294 100644 (file)
@@ -4,21 +4,16 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: James A Jones 1
 cn: James Jones
 cn: Jim Jones
 sn: Jones
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jaj
-krbname: jaj@umich.edu
 userpassword:: amFq
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 3882 Beverly Rd. $ Ann Arbor, MI 48105
 homephone: +1 313 555 4772
-multilinedescription: Outstanding
+description: Outstanding
 title: Mad Cow Researcher, UM Alumni Association
 pager: +1 313 555 3923
 mail: jaj@mail.alumni.umich.edu
diff --git a/tests/data/passwd.ldif b/tests/data/passwd.ldif
new file mode 100644 (file)
index 0000000..a405003
--- /dev/null
@@ -0,0 +1,28 @@
+dn: o=University of Michigan, c=US
+objectclass: top
+objectclass: organization
+o: University of Michigan
+
+dn: cn=md5, o=University of Michigan, c=US
+objectclass: top
+objectclass: person
+cn: md5
+userpassword:: e01ENX1YcjRpbE96UTRQQ09xM2FRMHFidWFRPT0=
+
+dn: cn=smd5, o=University of Michigan, c=US
+objectclass: top
+objectclass: person
+cn: smd5
+userpassword: secret
+
+dn: cn=sha, o=University of Michigan, c=US
+objectclass: top
+objectclass: person
+cn: sha
+userpassword:: e1NIQX01ZW42RzZNZXpScm9UM1hLcWtkUE9tWS9CZlE9
+
+dn: cn=ssha, o=University of Michigan, c=US
+objectclass: top
+objectclass: person
+cn: ssha
+userpassword: secret
index 4274c59fd0bb6d97e31230e280052a973720014c..ebadd3d27c9f5d9788424b249eee7bd69b5048d2 100644 (file)
@@ -4,7 +4,6 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Barbara Jensen
 cn: Babs Jensen
 sn: Jensen
@@ -12,16 +11,10 @@ title: Mythical Manager, Research Systems
 postaladdress: ITD Prod Dev & Deployment $ 535 W. William St. Room 4212 $ Ann 
  Arbor, MI 48103-4943
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: bjensen
 userpassword:: YmplbnNlbg==
 mail: bjensen@mailgw.umich.edu
 homepostaladdress: 123 Wesley $ Ann Arbor, MI 48103
-krbname: bjensen@umich.edu
-multilinedescription: Mythical manager of the rsdd unix project
-nobatchupdates: TRUE
-notice: Off sailing this month.
-onvacation: FALSE
-labeledurl: http://www.umich.edu/ U-M Home Page
+description: Mythical manager of the rsdd unix project
 drink: water
 homephone: +1 313 555 2333
 pager: +1 313 555 3233
@@ -34,19 +27,14 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Bjorn Jensen
 cn: Biiff Jensen
 sn: Jensen
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: bjorn
 userpassword:: Ympvcm4=
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 19923 Seven Mile Rd. $ South Lyon, MI 49999
 drink: Iced Tea
-multilinedescription: Hiker, biker
+description: Hiker, biker
 title: Director, Embedded Systems
 postaladdress: Info Tech Division $ 535 W. William St. $ Ann Arbor, MI 48103
 mail: bjorn@mailgw.umich.edu
@@ -76,14 +64,10 @@ member: cn=Ursula Hampster, ou=Alumni Association, ou=People, o=University of
  Michigan, c=US
 member: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, o=Univ
  ersity of Michigan, c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
 cn: All Staff
-joinable: FALSE
-multilinedescription: Everyone in the sample data
-objectclass: rfc822mailgroup
+description: Everyone in the sample data
+objectclass: groupofnames
 
 dn: cn=Alumni Assoc Staff,ou=Groups,o=University of Michigan,c=US
 member: cn=Manager, o=University of Michigan, c=US
@@ -99,24 +83,16 @@ member: cn=Mark Elliot, ou=Alumni Association, ou=People, o=University of Mich
  igan, c=US
 member: cn=Ursula Hampster, ou=Alumni Association, ou=People, o=University of 
  Michigan, c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
-multilinedescription: All Alumni Assoc Staff
+description: All Alumni Assoc Staff
 cn: Alumni Assoc Staff
-joinable: FALSE
-objectclass: rfc822mailgroup
+objectclass: groupofnames
 
 dn: cn=ITD Staff,ou=Groups,o=University of Michigan,c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
-multilinedescription: All ITD Staff
+description: All ITD Staff
 cn: ITD Staff
-joinable: FALSE
-objectclass: rfc822mailgroup
+objectclass: groupofnames
 member: cn=Manager, o=University of Michigan, c=US
 member: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, o=Univ
  ersity of Michigan, c=US
@@ -124,7 +100,6 @@ member: cn=James A Jones 2, ou=Information Technology Division, ou=People, o=U
  niversity of Michigan, c=US
 member: cn=John Doe, ou=Information Technology Division, ou=People, o=Universi
  ty of Michigan, c=US
-labeledurl: http://www.itd.umich.edu ITD Home Page
 
 dn: cn=James A Jones 1, ou=Alumni Association, ou=People, o=University of Mich
  igan, c=US
@@ -132,21 +107,16 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: James A Jones 1
 cn: James Jones
 cn: Jim Jones
 sn: Jones
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jaj
-krbname: jaj@umich.edu
 userpassword:: amFq
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 3882 Beverly Rd. $ Ann Arbor, MI 48105
 homephone: +1 313 555 4772
-multilinedescription: Outstanding
+description: Outstanding
 title: Mad Cow Researcher, UM Alumni Association
 pager: +1 313 555 3923
 mail: jaj@mail.alumni.umich.edu
@@ -174,14 +144,10 @@ member: cn=Ursula Hampster, ou=Alumni Association, ou=People, o=University of
  Michigan, c=US
 member: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, o=Univ
  ersity of Michigan, c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
 cn: All Staff
-joinable: FALSE
-multilinedescription: Everyone in the sample data
-objectclass: rfc822mailgroup
+description: Everyone in the sample data
+objectclass: groupofnames
 
 dn: cn=Alumni Assoc Staff,ou=Groups,o=University of Michigan,c=US
 member: cn=Manager, o=University of Michigan, c=US
@@ -197,14 +163,10 @@ member: cn=Mark Elliot, ou=Alumni Association, ou=People, o=University of Mich
  igan, c=US
 member: cn=Ursula Hampster, ou=Alumni Association, ou=People, o=University of 
  Michigan, c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
-multilinedescription: All Alumni Assoc Staff
+description: All Alumni Assoc Staff
 cn: Alumni Assoc Staff
-joinable: FALSE
-objectclass: rfc822mailgroup
+objectclass: groupofnames
 dn: cn=All Staff,ou=Groups,o=University of Michigan,c=US
 member: cn=Manager, o=University of Michigan, c=US
 member: cn=Barbara Jensen, ou=Information Technology Division, ou=People, o=Un
@@ -227,14 +189,10 @@ member: cn=Ursula Hampster, ou=Alumni Association, ou=People, o=University of
  Michigan, c=US
 member: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, o=Univ
  ersity of Michigan, c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
 cn: All Staff
-joinable: FALSE
-multilinedescription: Everyone in the sample data
-objectclass: rfc822mailgroup
+description: Everyone in the sample data
+objectclass: groupofnames
 
 dn: cn=Alumni Assoc Staff,ou=Groups,o=University of Michigan,c=US
 member: cn=Manager, o=University of Michigan, c=US
@@ -250,14 +208,10 @@ member: cn=Mark Elliot, ou=Alumni Association, ou=People, o=University of Mich
  igan, c=US
 member: cn=Ursula Hampster, ou=Alumni Association, ou=People, o=University of 
  Michigan, c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
-multilinedescription: All Alumni Assoc Staff
+description: All Alumni Assoc Staff
 cn: Alumni Assoc Staff
-joinable: FALSE
-objectclass: rfc822mailgroup
+objectclass: groupofnames
 
 dn: ou=Alumni Association, ou=People, o=University of Michigan, c=US
 objectclass: top
@@ -276,14 +230,10 @@ objectclass: organizationalUnit
 ou: Information Technology Divisio
 
 dn: cn=ITD Staff,ou=Groups,o=University of Michigan,c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
-multilinedescription: All ITD Staff
+description: All ITD Staff
 cn: ITD Staff
-joinable: FALSE
-objectclass: rfc822mailgroup
+objectclass: groupofnames
 member: cn=Manager, o=University of Michigan, c=US
 member: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, o=Univ
  ersity of Michigan, c=US
@@ -291,7 +241,6 @@ member: cn=James A Jones 2, ou=Information Technology Division, ou=People, o=U
  niversity of Michigan, c=US
 member: cn=John Doe, ou=Information Technology Division, ou=People, o=Universi
  ty of Michigan, c=US
-labeledurl: http://www.itd.umich.edu ITD Home Page
 
 dn: ou=People, o=University of Michigan, c=US
 objectclass: top
@@ -304,7 +253,6 @@ objectclass: organization
 objectclass: domainRelatedObject
 l: Ann Arbor, Michigan
 st: Michigan
-streetaddress: 535 West William St.
 o: University of Michigan
 o: UMICH
 o: UM
index feb3846ceab7779b845b6e344bc56ed29a6ba959..9e9db59baf92dc6999c0ffec6148a6fd7985bfcf 100644 (file)
@@ -2,8 +2,11 @@
 #
 # master slapd config -- for testing
 #
-include                ./data/slapd.at.conf
-include                ./data/slapd.oc.conf
+#include               ./data/slapd.at.conf
+#include               ./data/slapd.oc.conf
+include ./schema/core.schema
+include ./schema/cosine.schema
+include ./schema/inetorgperson.schema
 schemacheck    off
 pidfile     ./test-db/slapd.pid
 argsfile    ./test-db/slapd.args
@@ -18,8 +21,7 @@ suffix                "o=University of Michigan, c=US"
 directory      ./test-db
 rootdn         "cn=Manager, o=University of Michigan, c=US"
 rootpw         secret
-index          cn,sn,uid       pres,eq,approx
-index          default         none
+index          cn,sn,uid       pres,eq
 lastmod                on
 defaultaccess  none
 
@@ -29,24 +31,25 @@ defaultaccess       none
 #
 
 access         to attr=objectclass
-               by * read
+               by * =rsc stop
 
 access         to filter="objectclass=person" attr=userpassword
-               by self write
                by anonymous auth
-               by * none
+               by self write
 
-access         to dn="^.*,ou=Alumni Association,ou=People,o=University of Michigan,c=US$"
-               by dn="^.*,o=University of Michigan,c=US$" read
-               by anonymous auth
-               by * none
+access         to dn.children="ou=Alumni Association, ou=People, o=University of Michigan, c=US"
+               by dn="^$" +x continue
+               by dn.regex=".+,o=University of Michigan,c=US" +c continue
+               by dn.subtree="o=University of Michigan, c=US" +rs continue
+               by * stop
 
 access         to attr=member
                by dnattr=member selfwrite
                by * read
 
-access         to filter="objectclass=rfc822mailgroup"
-               by dn="Bjorn Jensen,ou=Information Technology Division,ou=People,o=University of Michigan,c=US" write
-               by * read
+access         to filter="objectclass=groupofnames"
+               by dn.base="cn=Bjorn Jensen, ou=Information Technology Division, ou=People, o=University of Michigan,c=US" =sc continue
+               by dn="^cn=Bjorn Jensen,ou=Information Technology Division,ou=People,o=University of Michigan,c=US$" +rw stop
+               by * break
 
 access         to * by * read
index 50769f3ad23b4c7cfc93fc584b549618ca228ffc..2768f50b34acf2b6ed052daacb85df2ac90760ae 100644 (file)
@@ -43,7 +43,7 @@ access                to attr=member
                by dnattr=member selfwrite
                by * read
 
-access         to filter="objectclass=rfc822mailgroup"
+access         to filter="objectclass=groupofnames"
                by dn="Bjorn Jensen,ou=Information Technology Division,ou=People,o=University of Michigan,c=US" write
                by * read
 
diff --git a/tests/data/slapd-bdb2-pw.conf b/tests/data/slapd-bdb2-pw.conf
new file mode 100644 (file)
index 0000000..bc8761f
--- /dev/null
@@ -0,0 +1,39 @@
+# $OpenLDAP$
+#
+# master slapd config -- for testing
+#
+include                ./data/slapd.at.conf
+include                ./data/slapd.oc.conf
+schemacheck    off
+pidfile     ./test-db/slapd.pid
+argsfile    ./test-db/slapd.args
+
+# password-hash        {md5}
+
+#######################################################################
+# ldbm database definitions
+#######################################################################
+
+database       ldbm
+cachesize      0
+suffix         "o=University of Michigan, c=US"
+directory      ./test-db
+rootdn         "cn=Manager, o=University of Michigan, c=US"
+rootpw         secret
+index          cn,sn,uid       pres,eq,approx
+index          default         none
+lastmod                on
+defaultaccess  none
+
+#
+# normal installations should protect root dse,
+# cn=monitor, cn=schema, and cn=config
+#
+
+access to attr=userpassword
+       by anonymous auth
+       by self write
+
+access to *
+       by self write
+       by * read
index 7e2ad2c6122450145f46d2aae3b227b4995b5fe7..a0554a20164ffd57414e5d91f01aa27866a18478 100644 (file)
@@ -29,4 +29,3 @@ index         cn,sn,uid       pres,eq,approx
 index          default         none
 # index                default         pres,eq,approx
 lastmod                on
-dbcachenowsync
diff --git a/tests/data/slapd-dnssrv.conf b/tests/data/slapd-dnssrv.conf
new file mode 100644 (file)
index 0000000..b95d393
--- /dev/null
@@ -0,0 +1,17 @@
+# $OpenLDAP$
+#
+# DNS SRV slapd config -- for testing
+#
+#include               ./data/slapd.at.conf
+#include               ./data/slapd.oc.conf
+include ./schema/core.schema
+schemacheck    on
+pidfile     ./test-db/slapd.pid
+argsfile    ./test-db/slapd.args
+
+#######################################################################
+# ldbm database definitions
+#######################################################################
+
+database       dnssrv
+suffix         ""
index d1c2387e20f6ec09c7365a2ae2d0a8a86644b8e2..a192c426f0cee3b1715c71a9346d88b8f306aa1b 100644 (file)
@@ -2,8 +2,11 @@
 #
 # master slapd config -- for testing
 #
-include                ./data/slapd.at.conf
-include                ./data/slapd.oc.conf
+#include               ./data/slapd.at.conf
+#include               ./data/slapd.oc.conf
+include ./schema/core.schema
+include ./schema/cosine.schema
+include ./schema/inetorgperson.schema
 schemacheck    on
 pidfile     ./test-db/slapd.pid
 argsfile    ./test-db/slapd.args
@@ -17,7 +20,6 @@ suffix                "o=University of Michigan, c=US"
 directory      ./test-db
 rootdn         "cn=Manager, o=University of Michigan, c=US"
 rootpw         secret
-index          cn,sn,uid       pres,eq,approx
-index          default         none
-lastmod                on
-dbcachenowsync
+index          cn,sn,uid       pres,eq
+dbnosync
+dbnolocking
index 10925e52d7c0f756d5299dc6d5afeb7009262ee0..78279e4f5da3379259009199a4054c83cea911e5 100644 (file)
@@ -2,8 +2,11 @@
 #
 # master slapd config -- for testing
 #
-include                ./data/slapd.at.conf
-include                ./data/slapd.oc.conf
+#include               ./data/slapd.at.conf
+#include               ./data/slapd.oc.conf
+include ./schema/core.schema
+include ./schema/cosine.schema
+include ./schema/inetorgperson.schema
 schemacheck    on
 pidfile     ./test-db/slapd.pid
 argsfile    ./test-db/slapd.args
diff --git a/tests/data/slapd-pw.conf b/tests/data/slapd-pw.conf
new file mode 100644 (file)
index 0000000..29fa8e2
--- /dev/null
@@ -0,0 +1,41 @@
+# $OpenLDAP$
+#
+# master slapd config -- for testing
+#
+#include               ./data/slapd.at.conf
+#include               ./data/slapd.oc.conf
+include ./schema/core.schema
+include ./schema/cosine.schema
+include ./schema/inetorgperson.schema
+schemacheck    off
+pidfile     ./test-db/slapd.pid
+argsfile    ./test-db/slapd.args
+
+# password-hash        {md5}
+
+#######################################################################
+# ldbm database definitions
+#######################################################################
+
+database       ldbm
+cachesize      0
+suffix         "o=University of Michigan, c=US"
+directory      ./test-db
+rootdn         "cn=Manager, o=University of Michigan, c=US"
+rootpw         secret
+index          cn,sn,uid       pres,eq
+lastmod                on
+defaultaccess  none
+
+#
+# normal installations should protect root dse,
+# cn=monitor, cn=schema, and cn=config
+#
+
+access to attr=userpassword
+       by anonymous auth
+       by self write
+
+access to *
+       by self write
+       by * read
index c10b036a498a715dd4f64e0d15ef83c522e6d2f9..9182fa48f6025f0efe01cb2bd5bca6349898174d 100644 (file)
@@ -2,9 +2,14 @@
 #
 # slave slapd config -- for default referral testing
 #
-include                ./data/slapd.at.conf
-include                ./data/slapd.oc.conf
+#include               ./data/slapd.at.conf
+#include               ./data/slapd.oc.conf
+include ./schema/core.schema
+include ./schema/cosine.schema
+include ./schema/inetorgperson.schema
+#
 schemacheck    off
+#
 pidfile     ./test-repl/slapd.pid
 argsfile    ./test-repl/slapd.args
 
@@ -20,7 +25,5 @@ suffix                "o=University of Mich, c=US"
 directory      ./test-repl
 rootdn         "cn=Manager, o=University of Mich, c=US"
 rootpw         secret
-index          cn,sn,uid       pres,eq,approx
-index          default         none
-# index                default         pres,eq,approx
+index          cn,sn,uid       pres,eq
 lastmod                on
index d4f702f78b8c0ace24d78f5abe5433e182a6b07d..76df58f818018320b39e4fcc8e9aa8b829bb23ea 100644 (file)
@@ -2,9 +2,14 @@
 #
 # master slapd config -- for testing of replication
 #
-include                ./data/slapd.at.conf
-include                ./data/slapd.oc.conf
+#include               ./data/slapd.at.conf
+#include               ./data/slapd.oc.conf
+include ./schema/core.schema
+include ./schema/cosine.schema
+include ./schema/inetorgperson.schema
+#
 schemacheck    off
+#
 pidfile     ./test-db/slapd.pid
 argsfile    ./test-db/slapd.args
 
@@ -18,9 +23,7 @@ suffix                "o=University of Michigan, c=US"
 directory      ./test-db
 rootdn         "cn=Manager, o=University of Michigan, c=US"
 rootpw         secret
-index          cn,sn,uid       pres,eq,approx
-index          default         none
-# index                default         pres,eq,approx
+index          cn,sn,uid       pres,eq
 lastmod                on
 
 replogfile     ./test-db/slapd.replog
index e9f0bb3ee76e8ddcc66023633cf523c94f160ce5..bc35f46d78144b40c0b0e98cca5fef0476bf4694 100644 (file)
@@ -2,8 +2,12 @@
 #
 # master slapd config -- for testing of replication
 #
-include                ./data/slapd.at.conf
-include                ./data/slapd.oc.conf
+#include               ./data/slapd.at.conf
+#include               ./data/slapd.oc.conf
+include ./schema/core.schema
+include ./schema/cosine.schema
+include ./schema/inetorgperson.schema
+#
 schemacheck    off
 pidfile     ./test-repl/slapd.pid
 argsfile    ./test-repl/slapd.args
@@ -22,7 +26,5 @@ rootdn                "cn=Replica, o=University of Michigan, c=US"
 rootpw         secret
 updatedn       "cn=Replica, o=University of Michigan, c=US"
 updateref      "ldap://localhost:9009/o=University%20of%20Michigan,c=US"
-index          cn,sn,uid       pres,eq,approx
-index          default         none
-# index                default         pres,eq,approx
+index          cn,sn,uid       pres,eq
 lastmod                on
diff --git a/tests/data/slapd.at.conf b/tests/data/slapd.at.conf
deleted file mode 100644 (file)
index 0191d2b..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# $OpenLDAP$
-attribute      photo                                   bin
-attribute      personalsignature                       bin
-attribute      jpegphoto                               bin
-attribute      audio                                   bin
-attribute      labeledurl                              ces
-attribute      ref                                             ces
-attribute      userpassword                            ces
-attribute      telephonenumber                         tel
-attribute      facsimiletelephonenumber        fax     tel
-attribute      pagertelephonenumber            pager   tel
-attribute      homephone                               tel
-attribute      mobiletelephonenumber           mobile  tel
-attribute      aliasedObjectName                       dn
-attribute      member                                  dn
-attribute      owner                                   dn
-attribute      seealso                                 dn
-attribute      manager                                 dn
-attribute      documentauthor                          dn
-attribute      secretary                               dn
-attribute      lastmodifiedby                          dn
-attribute      associatedname                          dn
-attribute      naminglink                              dn
-attribute      reciprocalnaminglink                    dn
-attribute      dn                                      dn
diff --git a/tests/data/slapd.oc.conf b/tests/data/slapd.oc.conf
deleted file mode 100644 (file)
index fc63fa4..0000000
+++ /dev/null
@@ -1,912 +0,0 @@
-# $OpenLDAP$
-
-objectclass top
-       requires
-               objectClass
-
-objectclass alias
-       requires
-               aliasedObjectName,
-               objectClass
-
-objectclass referral
-       requires
-               ref,
-               objectClass
-
-objectclass country
-       requires
-               objectClass,
-               c
-       allows
-               searchGuide,
-               description
-
-objectclass locality
-       requires
-               objectClass
-       allows
-               description,
-               l,
-               searchGuide,
-               seeAlso,
-               st,
-               streetAddress
-
-objectclass organization
-       requires
-               objectClass,
-               o
-       allows
-               businessCategory,
-               description,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               l,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               searchGuide,
-               seeAlso,
-               st,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               userPassword,
-               x121Address
-
-objectclass organizationalUnit
-       requires
-               objectClass,
-               ou
-       allows
-               businessCategory,
-               description,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               l,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               searchGuide,
-               seeAlso,
-               st,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               userPassword,
-               x121Address
-
-objectclass person
-       requires
-               objectClass,
-               cn
-       allows
-               description,
-               seeAlso,
-               sn,
-               telephoneNumber,
-               userPassword
-
-objectclass organizationalPerson
-       requires
-               objectClass,
-               cn
-       allows
-               description,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               l,
-               ou,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               seeAlso,
-               sn,
-               st,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               title,
-               userPassword,
-               x121Address
-
-objectclass organizationalRole
-       requires
-               objectClass,
-               cn
-       allows
-               description,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               l,
-               ou,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               roleOccupant,
-               seeAlso,
-               st,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               x121Address
-
-objectclass groupOfNames
-       requires
-               objectClass,
-               member,
-               cn
-       allows
-               businessCategory,
-               description,
-               o,
-               ou,
-               owner,
-               seeAlso
-
-objectclass residentialPerson
-       requires
-               objectClass,
-               cn,
-               l
-       allows
-               businessCategory,
-               description,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               l,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               seeAlso,
-               sn,
-               st,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               userPassword,
-               x121Address
-
-objectclass applicationProcess
-       requires
-               objectClass,
-               cn
-       allows
-               description,
-               l,
-               ou,
-               seeAlso
-
-objectclass applicationEntity
-       requires
-               objectClass,
-               presentationAddress,
-               cn
-       allows
-               description,
-               l,
-               o,
-               ou,
-               seeAlso,
-               supportedApplicationContext
-
-objectclass dSA
-       requires
-               objectClass,
-               presentationAddress,
-               cn
-       allows
-               knowledgeInformation
-
-objectclass device
-       requires
-               objectClass,
-               cn
-       allows
-               description,
-               l,
-               o,
-               ou,
-               owner,
-               seeAlso,
-               serialNumber
-
-objectclass strongAuthenticationUser
-       requires
-               objectClass,
-               userCertificate
-
-objectclass certificationAuthority
-       requires
-               objectClass,
-               authorityRevocationList,
-               certificateRevocationList,
-               cACertificate
-       allows
-               crossCertificatePair
-
-objectclass pilotObject
-       requires
-               objectClass
-       allows
-               audio,
-               dITRedirect,
-               info,
-               jpegPhoto,
-               lastModifiedBy,
-               lastModifiedTime,
-               manager,
-               photo,
-               uniqueIdentifier
-
-objectclass newPilotPerson
-       requires
-               objectClass,
-               cn
-       allows
-               businessCategory,
-               description,
-               drink,
-               homePhone,
-               homePostalAddress,
-               janetMailbox,
-               lastModifiedBy,
-               lastModifiedTime,
-               mail,
-               mailPreferenceOption,
-               mobile,
-               organizationalStatus,
-               otherMailbox,
-               pager,
-               personalSignature,
-               personalTitle,
-               preferredDeliveryMethod,
-               roomNumber,
-               secretary,
-               seeAlso,
-               sn,
-               telephoneNumber,
-               textEncodedORaddress,
-               uid,
-               userClass,
-               userPassword
-
-objectclass account
-       requires
-               objectClass,
-               uid
-       allows
-               description,
-               host,
-               l,
-               o,
-               ou,
-               seeAlso
-
-objectclass document
-       requires
-               objectClass,
-               documentIdentifier
-       allows
-               abstract,
-               audio,
-               authorCN,
-               authorSN,
-               cn,
-               dITRedirect,
-               description,
-               documentAuthor,
-               documentLocation,
-               documentPublisher,
-               documentStore,
-               documentTitle,
-               documentVersion,
-               info,
-               jpegPhoto,
-               keywords,
-               l,
-               lastModifiedBy,
-               lastModifiedTime,
-               manager,
-               o,
-               obsoletedByDocument,
-               obsoletesDocument,
-               ou,
-               photo,
-               seeAlso,
-               subject,
-               uniqueIdentifier,
-               updatedByDocument,
-               updatesDocument
-
-objectclass room
-       requires
-               objectClass,
-               cn
-       allows
-               description,
-               roomNumber,
-               seeAlso,
-               telephoneNumber
-
-objectclass documentSeries
-       requires
-               objectClass,
-               cn
-       allows
-               description,
-               l,
-               o,
-               ou,
-               seeAlso,
-               telephoneNumber
-
-objectclass domain
-       requires
-               objectClass,
-               dc
-       allows
-               associatedName,
-               businessCategory,
-               description,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               l,
-               o,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               searchGuide,
-               seeAlso,
-               st,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               userPassword,
-               x121Address
-
-objectclass rFC822localPart
-       requires
-               objectClass,
-               dc
-       allows
-               associatedName,
-               businessCategory,
-               cn,
-               description,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               l,
-               o,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               searchGuide,
-               seeAlso,
-               sn,
-               st,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               userPassword,
-               x121Address
-
-objectclass dNSDomain
-       requires
-               objectClass,
-               dc
-       allows
-               associatedName,
-               businessCategory,
-               dNSRecord,
-               description,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               l,
-               o,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               searchGuide,
-               seeAlso,
-               st,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               userPassword,
-               x121Address
-
-objectclass domainRelatedObject
-       requires
-               objectClass,
-               associatedDomain
-
-objectclass friendlyCountry
-       requires
-               objectClass,
-               c,
-               co
-       allows
-               description,
-               searchGuide
-
-objectclass simpleSecurityObject
-       requires
-               objectClass,
-               userPassword
-
-objectclass pilotOrganization
-       requires
-               objectClass,
-               ou,
-               o
-       allows
-               buildingName,
-               businessCategory,
-               description,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               l,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               searchGuide,
-               seeAlso,
-               st,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               userPassword,
-               x121Address
-
-objectclass nadfObject
-       requires
-               objectClass
-       allows
-               lastModifiedTime,
-               nadfSearchGuide,
-               supplementaryInformation
-
-objectclass usStateOrEquivalent
-       requires
-               objectClass,
-               st,
-               fipsStateAlphaCode,
-               fipsStateNumericCode,
-               l
-       allows
-               description,
-               lastModifiedTime,
-               nadfSearchGuide,
-               searchGuide,
-               seeAlso,
-               streetAddress,
-               supplementaryInformation
-
-objectclass usPlace
-       requires
-               objectClass,
-               fips55,
-               l
-       allows
-               description,
-               lastModifiedTime,
-               nadfSearchGuide,
-               searchGuide,
-               seeAlso,
-               st,
-               streetAddress,
-               supplementaryInformation
-
-objectclass usCountyOrEquivalent
-       requires
-               objectClass,
-               fipsCountyNumericCode,
-               fips55,
-               l
-       allows
-               description,
-               lastModifiedTime,
-               nadfSearchGuide,
-               searchGuide,
-               seeAlso,
-               st,
-               streetAddress,
-               supplementaryInformation
-
-objectclass ansiOrgObject
-       requires
-               objectClass,
-               ansiOrgNumericCode
-
-objectclass nadfApplicationEntity
-       requires
-               objectClass,
-               supportedApplicationContext,
-               presentationAddress,
-               cn
-       allows
-               description,
-               l,
-               o,
-               ou,
-               seeAlso,
-               supportedApplicationContext
-
-objectclass nadfADDMD
-       requires
-               objectClass,
-               ad
-       allows
-               businessCategory,
-               description,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               l,
-               lastModifiedTime,
-               nadfSearchGuide,
-               o,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               searchGuide,
-               seeAlso,
-               st,
-               streetAddress,
-               supplementaryInformation,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               userPassword,
-               x121Address
-
-objectclass publicObject
-       requires
-               objectClass,
-               namingLink
-
-objectclass providerObject
-       requires
-               objectClass,
-               reciprocalNamingLink
-
-objectclass nationalObject
-       requires
-               objectClass,
-               c
-
-objectclass fips55Object
-       requires
-               objectClass,
-               fips55
-       allows
-               st
-
-objectclass restaurant
-       requires
-               objectClass,
-               description,
-               telephoneNumber,
-               streetAddress
-       allows
-               Ambiance,
-               Appearance,
-               Average-price,
-               Closed,
-               CreditCardsAccepted,
-               Kosher,
-               Max-price,
-               MaximumInParty,
-               Min-price,
-               Music,
-               NotRecommended,
-               OutdoorSeating,
-               Parking,
-               QualityOfService,
-               QualityPriceRatio,
-               Recommended,
-               RecommendedBy,
-               Reservation,
-               ServiceSpeed,
-               Specialty,
-               Taux-de-frequentation,
-               TransportationMeans,
-               facsimileTelephoneNumber,
-               postalAddress
-
-objectclass kerberosSecurityObject
-       requires
-               objectClass,
-               krbName
-
-objectclass umichPerson
-       requires
-               objectClass,
-               cn
-       allows
-               affiliationCode,
-               audio,
-               businessCategory,
-               classStanding,
-               description,
-               destinationIndicator,
-               doNotDelete,
-               doNotMove,
-               drink,
-               expire,
-               facsimileTelephoneNumber,
-               homePhone,
-               homePostalAddress,
-               internationaliSDNNumber,
-               janetMailbox,
-               jpegPhoto,
-               keepNames,
-               krbName,
-               l,
-               labeledURL,
-               mail,
-               mailPreferenceOption,
-               memberOfGroup,
-               mobile,
-               multiLineDescription,
-               noBatchUpdates,
-               notRegistered,
-               notice,
-               onVacation,
-               organizationalStatus,
-               otherMailbox,
-               ou,
-               pager,
-               personalSignature,
-               personalTitle,
-               photo,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               proxy,
-               registeredAddress,
-               registrationStatus,
-               roomNumber,
-               secretary,
-               seeAlso,
-               sn,
-               st,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               textEncodedORaddress,
-               title,
-               uid,
-               universityID,
-               updateSource,
-               userCertificate,
-               userClass,
-               userPassword,
-               vacationMessage,
-               x121Address,
-               xacl
-
-objectclass rfc822MailGroup
-       requires
-               objectClass,
-               owner,
-               cn
-       allows
-               associatedDomain,
-               autoMgt,
-               description,
-               destinationIndicator,
-               errorsTo,
-               facsimileTelephoneNumber,
-               internationaliSDNNumber,
-               joinable,
-               krbName,
-               labeledURL,
-               mail,
-               member,
-               memberOfGroup,
-               moderator,
-               multiLineDescription,
-               notice,
-               physicalDeliveryOfficeName,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               registeredAddress,
-               requestsTo,
-               rfc822ErrorsTo,
-               rfc822RequestsTo,
-               seeAlso,
-               streetAddress,
-               suppressNoEmailError,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               userPassword,
-               x121Address,
-               xacl
-
-objectclass image
-       requires
-               objectClass,
-               cn
-       allows
-               citation,
-               copyright,
-               imageFiles,
-               jpegPhoto,
-               keywords,
-               multiLineDescription,
-               owner,
-               predominantColor
-
-objectclass imageFile
-       requires
-               objectClass,
-               cn
-       allows
-               colorDepth,
-               documentLocation,
-               fileFormat,
-               fileSize,
-               height,
-               resolution,
-               seeAlso,
-               width
-
-objectclass service
-       requires
-               objectClass,
-               cn
-       allows
-               category,
-               dependentUpon,
-               destinationIndicator,
-               facsimileTelephoneNumber,
-               hoursOfOperation,
-               internationaliSDNNumber,
-               jpegPhoto,
-               keywords,
-               labeledURL,
-               mail,
-               multiLineDescription,
-               owner,
-               physicalDeliveryOfficeName,
-               platform,
-               postOfficeBox,
-               postalAddress,
-               postalCode,
-               preferredDeliveryMethod,
-               product,
-               provider,
-               ratingDescription,
-               ratingTime,
-               registeredAddress,
-               seeAlso,
-               serviceArea,
-               serviceRating,
-               streetAddress,
-               telephoneNumber,
-               teletexTerminalIdentifier,
-               telexNumber,
-               x121Address
-
-objectclass umichDocument
-       requires
-               objectClass,
-               documentIdentifier
-       allows
-               abstract,
-               audio,
-               authorCN,
-               authorSN,
-               category,
-               cn,
-               dITRedirect,
-               description,
-               documentAuthor,
-               documentAvailable,
-               documentLocation,
-               documentPublisher,
-               documentSeriesTitle,
-               documentStore,
-               documentTitle,
-               documentVersion,
-               info,
-               jpegPhoto,
-               keywords,
-               l,
-               labeledURL,
-               lastModifiedBy,
-               lastModifiedTime,
-               manager,
-               multiLineAbstract,
-               o,
-               obsoletedByDocument,
-               obsoletesDocument,
-               ou,
-               owner,
-               photo,
-               platform,
-               product,
-               seeAlso,
-               serviceArea,
-               subject,
-               uniqueIdentifier,
-               updatedByDocument,
-               updatesDocument
-
-objectclass documentDescription
-       requires
-               objectClass,
-               cn
-       allows
-               labeledURL,
-               multiLineDescription,
-               owner
-
-objectclass labeledURLObject
-       requires
-               objectClass
-       allows
-               labeledURL
-
-objectclass cacheObject
-       requires
-               objectClass
-       allows
-               ttl
index 3db5bb98ec91db7634427fad8ee19b25502ca265..fdaab5d03c089b414d1c0d0591e9212349eb7adc 100644 (file)
@@ -4,7 +4,6 @@ objectclass: organization
 objectclass: domainRelatedObject
 l: Ann Arbor, Michigan
 st: Michigan
-streetaddress: 535 West William St.
 o: University of Michigan
 o: UMICH
 o: UM
@@ -59,14 +58,10 @@ member: cn=Ursula Hampster, ou=Alumni Association, ou=People, o=University of
  Michigan, c=US
 member: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, o=Univ
  ersity of Michigan, c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
 cn: All Staff
-joinable: FALSE
-multilinedescription: Everyone in the sample data
-objectclass: rfc822mailgroup
+description: Everyone in the sample data
+objectclass: groupofnames
 
 dn: cn=Alumni Assoc Staff,ou=Groups,o=University of Michigan,c=US
 member: cn=Manager, o=University of Michigan, c=US
@@ -82,14 +77,10 @@ member: cn=Mark Elliot, ou=Alumni Association, ou=People, o=University of Mich
  igan, c=US
 member: cn=Ursula Hampster, ou=Alumni Association, ou=People, o=University of 
  Michigan, c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
-multilinedescription: All Alumni Assoc Staff
+description: All Alumni Assoc Staff
 cn: Alumni Assoc Staff
-joinable: FALSE
-objectclass: rfc822mailgroup
+objectclass: groupofnames
 
 dn: cn=Barbara Jensen, ou=Information Technology Division, ou=People, o=Univer
  sity of Michigan, c=US
@@ -97,7 +88,6 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Barbara Jensen
 cn: Babs Jensen
 sn: Jensen
@@ -105,16 +95,10 @@ title: Mythical Manager, Research Systems
 postaladdress: ITD Prod Dev & Deployment $ 535 W. William St. Room 4212 $ Ann 
  Arbor, MI 48103-4943
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: bjensen
 userpassword:: YmplbnNlbg==
 mail: bjensen@mailgw.umich.edu
 homepostaladdress: 123 Wesley $ Ann Arbor, MI 48103
-krbname: bjensen@umich.edu
-multilinedescription: Mythical manager of the rsdd unix project
-nobatchupdates: TRUE
-notice: Off sailing this month.
-onvacation: FALSE
-labeledurl: http://www.umich.edu/ U-M Home Page
+description: Mythical manager of the rsdd unix project
 drink: water
 homephone: +1 313 555 2333
 pager: +1 313 555 3233
@@ -127,19 +111,14 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Bjorn Jensen
 cn: Biiff Jensen
 sn: Jensen
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: bjorn
 userpassword:: Ympvcm4=
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 19923 Seven Mile Rd. $ South Lyon, MI 49999
 drink: Iced Tea
-multilinedescription: Hiker, biker
+description: Hiker, biker
 title: Director, Embedded Systems
 postaladdress: Info Tech Division $ 535 W. William St. $ Ann Arbor, MI 48103
 mail: bjorn@mailgw.umich.edu
@@ -154,34 +133,25 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Dorothy Stevens
 cn: Dot Stevens
 sn: Stevens
 title: Secretary, UM Alumni Association
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: dots
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 drink: Lemonade
 homepostaladdress: 377 White St. Apt. 3 $ Ann Arbor, MI 48104
-multilinedescription: Very tall
+description: Very tall
 facsimiletelephonenumber: +1 313 555 3223
 telephonenumber: +1 313 555 3664
 mail: dots@mail.alumni.umich.edu
 homephone: +1 313 555 0454
 
 dn: cn=ITD Staff,ou=Groups,o=University of Michigan,c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
-multilinedescription: All ITD Staff
+description: All ITD Staff
 cn: ITD Staff
-joinable: FALSE
-objectclass: rfc822mailgroup
+objectclass: groupofnames
 member: cn=Manager, o=University of Michigan, c=US
 member: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, o=Univ
  ersity of Michigan, c=US
@@ -189,7 +159,6 @@ member: cn=James A Jones 2, ou=Information Technology Division, ou=People, o=U
  niversity of Michigan, c=US
 member: cn=John Doe, ou=Information Technology Division, ou=People, o=Universi
  ty of Michigan, c=US
-labeledurl: http://www.itd.umich.edu ITD Home Page
 
 dn: cn=James A Jones 1, ou=Alumni Association, ou=People, o=University of Mich
  igan, c=US
@@ -197,21 +166,16 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: James A Jones 1
 cn: James Jones
 cn: Jim Jones
 sn: Jones
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jaj
-krbname: jaj@umich.edu
 userpassword:: amFq
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 3882 Beverly Rd. $ Ann Arbor, MI 48105
 homephone: +1 313 555 4772
-multilinedescription: Outstanding
+description: Outstanding
 title: Mad Cow Researcher, UM Alumni Association
 pager: +1 313 555 3923
 mail: jaj@mail.alumni.umich.edu
@@ -224,20 +188,15 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: James A Jones 2
 cn: James Jones
 cn: Jim Jones
 sn: Doe
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jjones
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 933 Brooks $ Ann Arbor, MI 48104
 homephone: +1 313 555 8838
 title: Senior Manager, Information Technology Division
-multilinedescription: Not around very much
+description: Not around very much
 mail: jjones@mailgw.umich.edu
 postaladdress: Info Tech Division $ 535 W William $ Ann Arbor, MI 48103
 pager: +1 313 555 2833
@@ -250,20 +209,15 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Jane Doe
 cn: Jane Alverson
 sn: Doe
 title: Programmer Analyst, UM Alumni Association
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jdoe
 homepostaladdress: 123 Anystreet $ Ann Arbor, MI 48104
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 drink: diet coke
-multilinedescription: Enthusiastic
+description: Enthusiastic
 mail: jdoe@woof.net
 homephone: +1 313 555 5445
 pager: +1 313 555 1220
@@ -276,16 +230,11 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Jennifer Smith
 cn: Jen Smith
 sn: Smith
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jen
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 drink: Sam Adams
 homepostaladdress: 1000 Maple #44 $ Ann Arbor, MI 48103
 title: Telemarketer, UM Alumni Association
@@ -301,19 +250,14 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: John Doe
 cn: Jonathon Doe
 sn: Doe
 postaladdress: ITD $ 535 W. William $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: johnd
-krbname: johnd@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 912 East Bllvd $ Ann Arbor, MI 48104
 title: System Administrator, Information Technology Division
-multilinedescription: overworked!
+description: overworked!
 mail: johnd@mailgw.umich.edu
 homephone: +1 313 555 3774
 pager: +1 313 555 6573
@@ -323,14 +267,12 @@ telephonenumber: +1 313 555 9394
 dn: cn=Manager, o=University of Michigan, c=US
 objectclass: top
 objectclass: person
-objectclass: kerberosSecurityObject
 cn: Manager
 cn: Directory Manager
 cn: Dir Man
 sn: Manager
 description: Manager of the directory
 userpassword:: c2VjcmV0
-krbname: bjensen@umich.edu
 
 dn: cn=Mark Elliot, ou=Alumni Association, ou=People, o=University of Michigan
  , c=US
@@ -338,16 +280,11 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Mark Elliot
 cn: Mark A Elliot
 sn: Elliot
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: melliot
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 199 Outer Drive $ Ypsilanti, MI 48198
 homephone: +1 313 555 0388
 drink: Gasoline
@@ -363,17 +300,12 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Ursula Hampster
 sn: Hampster
 title: Secretary, UM Alumni Association
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: uham
 homepostaladdress: 123 Anystreet $ Ann Arbor, MI 48104
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 mail: uham@mail.alumni.umich.edu
 homephone: +1 313 555 8421
 pager: +1 313 555 2844
index e658ae0db10d8bcbfc48eda734f5a3f70fa69fb9..919bdd6726898becc57bd8eb285c24f2556037aa 100644 (file)
@@ -20,14 +20,10 @@ member: cn=Ursula Hampster, ou=Alumni Association, ou=People, o=University of
  Michigan, c=US
 member: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, o=Univ
  ersity of Michigan, c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
 cn: All Staff
-joinable: FALSE
-multilinedescription: Everyone in the sample data
-objectclass: rfc822mailgroup
+description: Everyone in the sample data
+objectclass: groupofnames
 
 dn: cn=Alumni Assoc Staff,ou=Groups,o=University of Michigan,c=US
 member: cn=Manager, o=University of Michigan, c=US
@@ -43,14 +39,10 @@ member: cn=Mark Elliot, ou=Alumni Association, ou=People, o=University of Mich
  igan, c=US
 member: cn=Ursula Hampster, ou=Alumni Association, ou=People, o=University of 
  Michigan, c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
-multilinedescription: All Alumni Assoc Staff
+description: All Alumni Assoc Staff
 cn: Alumni Assoc Staff
-joinable: FALSE
-objectclass: rfc822mailgroup
+objectclass: groupofnames
 
 dn: ou=Alumni Association, ou=People, o=University of Michigan, c=US
 objectclass: top
@@ -63,7 +55,6 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Barbara Jensen
 cn: Babs Jensen
 sn: Jensen
@@ -71,16 +62,10 @@ title: Mythical Manager, Research Systems
 postaladdress: ITD Prod Dev & Deployment $ 535 W. William St. Room 4212 $ Ann 
  Arbor, MI 48103-4943
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: bjensen
 userpassword:: YmplbnNlbg==
 mail: bjensen@mailgw.umich.edu
 homepostaladdress: 123 Wesley $ Ann Arbor, MI 48103
-krbname: bjensen@umich.edu
-multilinedescription: Mythical manager of the rsdd unix project
-nobatchupdates: TRUE
-notice: Off sailing this month.
-onvacation: FALSE
-labeledurl: http://www.umich.edu/ U-M Home Page
+description: Mythical manager of the rsdd unix project
 drink: water
 homephone: +1 313 555 2333
 pager: +1 313 555 3233
@@ -93,19 +78,14 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Bjorn Jensen
 cn: Biiff Jensen
 sn: Jensen
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: bjorn
 userpassword:: Ympvcm4=
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 19923 Seven Mile Rd. $ South Lyon, MI 49999
 drink: Iced Tea
-multilinedescription: Hiker, biker
+description: Hiker, biker
 title: Director, Embedded Systems
 postaladdress: Info Tech Division $ 535 W. William St. $ Ann Arbor, MI 48103
 mail: bjorn@mailgw.umich.edu
@@ -120,20 +100,15 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Dorothy Stevens
 cn: Dot Stevens
 sn: Stevens
 title: Secretary, UM Alumni Association
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: dots
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 drink: Lemonade
 homepostaladdress: 377 White St. Apt. 3 $ Ann Arbor, MI 48104
-multilinedescription: Very tall
+description: Very tall
 facsimiletelephonenumber: +1 313 555 3223
 telephonenumber: +1 313 555 3664
 mail: dots@mail.alumni.umich.edu
@@ -151,14 +126,10 @@ objectclass: organizationalUnit
 ou: Information Technology Divisio
 
 dn: cn=ITD Staff,ou=Groups,o=University of Michigan,c=US
-associateddomain: umich.edu
-requeststo: cn=Manager, o=University of Michigan, c=US
-errorsto: cn=Manager, o=University of Michigan, c=US
 owner: cn=Manager, o=University of Michigan, c=US
-multilinedescription: All ITD Staff
+description: All ITD Staff
 cn: ITD Staff
-joinable: FALSE
-objectclass: rfc822mailgroup
+objectclass: groupofnames
 member: cn=Manager, o=University of Michigan, c=US
 member: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, o=Univ
  ersity of Michigan, c=US
@@ -166,7 +137,6 @@ member: cn=James A Jones 2, ou=Information Technology Division, ou=People, o=U
  niversity of Michigan, c=US
 member: cn=John Doe, ou=Information Technology Division, ou=People, o=Universi
  ty of Michigan, c=US
-labeledurl: http://www.itd.umich.edu ITD Home Page
 
 dn: cn=James A Jones 1, ou=Alumni Association, ou=People, o=University of Mich
  igan, c=US
@@ -174,21 +144,16 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: James A Jones 1
 cn: James Jones
 cn: Jim Jones
 sn: Jones
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jaj
-krbname: jaj@umich.edu
 userpassword:: amFq
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 3882 Beverly Rd. $ Ann Arbor, MI 48105
 homephone: +1 313 555 4772
-multilinedescription: Outstanding
+description: Outstanding
 title: Mad Cow Researcher, UM Alumni Association
 pager: +1 313 555 3923
 mail: jaj@mail.alumni.umich.edu
@@ -201,20 +166,15 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: James A Jones 2
 cn: James Jones
 cn: Jim Jones
 sn: Doe
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jjones
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 933 Brooks $ Ann Arbor, MI 48104
 homephone: +1 313 555 8838
 title: Senior Manager, Information Technology Division
-multilinedescription: Not around very much
+description: Not around very much
 mail: jjones@mailgw.umich.edu
 postaladdress: Info Tech Division $ 535 W William $ Ann Arbor, MI 48103
 pager: +1 313 555 2833
@@ -227,20 +187,15 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Jane Doe
 cn: Jane Alverson
 sn: Doe
 title: Programmer Analyst, UM Alumni Association
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jdoe
 homepostaladdress: 123 Anystreet $ Ann Arbor, MI 48104
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 drink: diet coke
-multilinedescription: Enthusiastic
+description: Enthusiastic
 mail: jdoe@woof.net
 homephone: +1 313 555 5445
 pager: +1 313 555 1220
@@ -253,16 +208,11 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Jennifer Smith
 cn: Jen Smith
 sn: Smith
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: jen
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 drink: Sam Adams
 homepostaladdress: 1000 Maple #44 $ Ann Arbor, MI 48103
 title: Telemarketer, UM Alumni Association
@@ -278,19 +228,14 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: John Doe
 cn: Jonathon Doe
 sn: Doe
 postaladdress: ITD $ 535 W. William $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: johnd
-krbname: johnd@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 912 East Bllvd $ Ann Arbor, MI 48104
 title: System Administrator, Information Technology Division
-multilinedescription: overworked!
+description: overworked!
 mail: johnd@mailgw.umich.edu
 homephone: +1 313 555 3774
 pager: +1 313 555 6573
@@ -300,14 +245,12 @@ telephonenumber: +1 313 555 9394
 dn: cn=Manager, o=University of Michigan, c=US
 objectclass: top
 objectclass: person
-objectclass: kerberosSecurityObject
 cn: Manager
 cn: Directory Manager
 cn: Dir Man
 sn: Manager
 description: Manager of the directory
 userpassword:: c2VjcmV0
-krbname: bjensen@umich.edu
 
 dn: cn=Mark Elliot, ou=Alumni Association, ou=People, o=University of Michigan
  , c=US
@@ -315,16 +258,11 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Mark Elliot
 cn: Mark A Elliot
 sn: Elliot
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: melliot
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 homepostaladdress: 199 Outer Drive $ Ypsilanti, MI 48198
 homephone: +1 313 555 0388
 drink: Gasoline
@@ -345,7 +283,6 @@ objectclass: organization
 objectclass: domainRelatedObject
 l: Ann Arbor, Michigan
 st: Michigan
-streetaddress: 535 West William St.
 o: University of Michigan
 o: UMICH
 o: UM
@@ -363,17 +300,12 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Ursula Hampster
 sn: Hampster
 title: Secretary, UM Alumni Association
 postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: uham
 homepostaladdress: 123 Anystreet $ Ann Arbor, MI 48104
-krbname: jdoe@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 mail: uham@mail.alumni.umich.edu
 homephone: +1 313 555 8421
 pager: +1 313 555 2844
index 16c0a66dea2cd5de33baf04bb9468636b4e2c061..4cf2e2948c9aba5a2cd54f1fae88b8b38ae6bcc6 100644 (file)
@@ -1,10 +1,12 @@
 # $OpenLDAP$
-## Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
 ## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 ##
 ## tests Makefile.in for OpenLDAP
 
-PROGRAMS = slapd-tester slapd-search slapd-read slapd-addel
+UNIX_PRGS = slapd-tester slapd-search slapd-read slapd-addel
+PROGRAMS = $(@PLAT@_PRGS)
+
 SRCS     = slapd-tester.c slapd-search.c slapd-read.c slapd-addel.c
 
 LDAP_INCDIR= ../../include
index 3497439af3e4a05dc3f4570979ba92773a9fbc74..b555f71d64e5124a45c0b31b2743a4c0383e17ad 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 #include "portable.h"
 #include <ac/stdlib.h>
 
 #include <ac/ctype.h>
+#include <ac/param.h>
 #include <ac/socket.h>
 #include <ac/string.h>
 #include <ac/unistd.h>
 #include <ac/wait.h>
 
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
 #include <ldap.h>
 
 #define LOOPS  100
index 0446534f0d95c6f2619a692da944e5ffedefb3ff..94f3d2194093355cf6511bb3c554c3bb05191744 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 #include "portable.h"
 #include <ac/stdlib.h>
 
 #include <ac/ctype.h>
+#include <ac/param.h>
 #include <ac/socket.h>
 #include <ac/string.h>
 #include <ac/unistd.h>
 #include <ac/wait.h>
 
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
 #include <ldap.h>
 
 #define LOOPS  100
@@ -89,8 +86,7 @@ do_read( char *host, int port, char *entry, int maxloop )
 {
        LDAP    *ld;
        int     i;
-       char    *attrs[] = { "cn", "sn", NULL };
-       char    *filter = "(objectclass=*)";
+       char    *attrs[] = { "1.1", NULL };
        pid_t   pid = getpid();
 
        if (( ld = ldap_init( host, port )) == NULL ) {
@@ -112,7 +108,7 @@ do_read( char *host, int port, char *entry, int maxloop )
                int         rc;
 
                if (( rc = ldap_search_s( ld, entry, LDAP_SCOPE_BASE,
-                               filter, attrs, 0, &res )) != LDAP_SUCCESS ) {
+                               NULL, attrs, 1, &res )) != LDAP_SUCCESS ) {
 
                        ldap_perror( ld, "ldap_read" );
                        if ( rc != LDAP_NO_SUCH_OBJECT ) break;
index fc5745e797848297d67834ecbe5497e887fb7784..996ec68e2f3888fdc8be5a99b21e7e1aedf9bf25 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 #include "portable.h"
 #include <ac/stdlib.h>
 
 #include <ac/ctype.h>
+#include <ac/param.h>
 #include <ac/socket.h>
 #include <ac/string.h>
 #include <ac/unistd.h>
 #include <ac/wait.h>
 
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
 
 #include <ldap.h>
 
index d1a44e79b1a036f212243df33daa3b6fec1480cb..01052c4c99474d8a21680b9eaa5fe1b01d75dc31 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 #include "portable.h"
 
 #include <ac/ctype.h>
 #include <ac/dirent.h>
+#include <ac/param.h>
 #include <ac/socket.h>
 #include <ac/string.h>
 #include <ac/unistd.h>
 #include <ac/wait.h>
 
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
 
 #include "ldap_defaults.h"
 
index 383657603c1c54d06dfaacd28eabbcd508d005fa..f88faf8e964d1586da166fc2f4bdb29e876561c6 100755 (executable)
@@ -6,6 +6,7 @@ PROGDIR=./progs
 
 if test "$BACKEND" = "bdb2" ; then
        CONF=$DATADIR/slapd-bdb2-master.conf
+       PWCONF=$DATADIR/slapd-bdb2-pw.conf
        ACLCONF=$DATADIR/slapd-bdb2-acl.conf
        MASTERCONF=$DATADIR/slapd-bdb2-repl-master.conf
        SLAVECONF=$DATADIR/slapd-bdb2-repl-slave.conf
@@ -13,6 +14,7 @@ if test "$BACKEND" = "bdb2" ; then
        TIMING="-t"
 else
        CONF=$DATADIR/slapd-master.conf
+       PWCONF=$DATADIR/slapd-pw.conf
        ACLCONF=$DATADIR/slapd-acl.conf
        MASTERCONF=$DATADIR/slapd-repl-master.conf
        SLAVECONF=$DATADIR/slapd-repl-slave.conf
@@ -30,8 +32,11 @@ CLIENTDIR=../clients/tools
 
 LDIF2LDBM="../servers/slapd/tools/slapadd $LDAP_VERBOSE"
 
+#CMP=cmp
+CMP="diff -i -q"
 SLAPD=../servers/slapd/slapd
 SLURPD=../servers/slurpd/slurpd
+LDAPPASSWD="$CLIENTDIR/ldappasswd"
 LDAPSEARCH="$CLIENTDIR/ldapsearch $PROTO -LLL"
 LDAPMODIFY="$CLIENTDIR/ldapmodify $PROTO"
 LDAPADD="$CLIENTDIR/ldapadd $PROTO"
@@ -41,11 +46,15 @@ LVL=${SLAPD_DEBUG-5}
 ADDR=127.0.0.1
 PORT=9009
 SLAVEPORT=9010
+MASTERURI="ldap://localhost:$PORT/"
+SLAVEURI="ldap://localhost:$SLAVEPORT/"
 DBDIR=./test-db
 REPLDIR=./test-repl
 LDIF=$DATADIR/test.ldif
 LDIFORDERED=$DATADIR/test-ordered.ldif
-MONITOR="cn=monitor"
+LDIFPASSWD=$DATADIR/passwd.ldif
+LDIFPASSWDOUT=$DATADIR/passwd-out.ldif
+MONITOR=""
 BASEDN="o=University of Michigan, c=US"
 MANAGERDN="cn=Manager, o=University of Michigan, c=US"
 UPDATEDN="cn=Replica, o=University of Michigan, c=US"
@@ -73,3 +82,5 @@ MODRDNOUTMASTER3=$DATADIR/modrdn.out.master.3
 ACLOUTMASTER=$DATADIR/acl.out.master
 REPLOUTMASTER=$DATADIR/repl.out.master
 MODSRCHFILTERS=$DATADIR/modify.search.filters
+# Just in case we linked the binaries dynamically
+LD_LIBRARY_PATH=`pwd`/../libraries:${LD_LIBRARY_PATH} export LD_LIBRARY_PATH
index 529ad834570b147193de085dce0b66f08f4d10e9..c454146498379cb2526084f341fede492c4a5bc5 100755 (executable)
@@ -97,7 +97,7 @@ kill -HUP $PID
 
 echo "Assuming everything is fine."
 #echo "Comparing results"
-#cmp $TESTOUT $SEARCHOUTMASTER
+#$CMP $TESTOUT $SEARCHOUTMASTER
 #if test $? != 0 ; then
 #      echo "Comparison failed"
 #      exit 1
index 36b3b116cbc0f9ee93abe280e99b80c2fd43b6ea..9a2a28301927009882ef9dd0d6b61543a80c20c4 100755 (executable)
@@ -29,7 +29,7 @@ if test $RC != 0 ; then
 fi
 
 echo "Starting slapd on TCP/IP port $PORT..."
-$SLAPD -f $CONF -p $PORT -d $LVL $TIMING > $MASTERLOG 2>&1 &
+$SLAPD -f $CONF -h $MASTERURI -d $LVL $TIMING > $MASTERLOG 2>&1 &
 PID=$!
 
 echo "Using ldapsearch to retrieve all the entries..."
@@ -55,7 +55,7 @@ echo "Filtering ldapsearch results..."
 echo "Filtering original ldif used to create database..."
 . $SRCDIR/scripts/acfilter.sh < $LDIF > $LDIFFLT
 echo "Comparing filter output..."
-cmp $SEARCHFLT $LDIFFLT
+$CMP $SEARCHFLT $LDIFFLT
 
 if test $? != 0 ; then
        echo "comparison failed - database was not created correctly"
index dc358a980e651ef49dce047b40275d55d866a3d3..1f59703832b1efc995080c8483e61308fc062f7b 100755 (executable)
@@ -18,7 +18,7 @@ echo "Cleaning up in $DBDIR..."
 rm -f $DBDIR/[!C]*
 
 echo "Starting slapd on TCP/IP port $PORT..."
-$SLAPD -f $CONF -p $PORT -d $LVL $TIMING > $MASTERLOG 2>&1 &
+$SLAPD -f $CONF -h $MASTERURI -d $LVL $TIMING > $MASTERLOG 2>&1 &
 PID=$!
 
 echo "Using ldapsearch to check that slapd is running..."
@@ -58,7 +58,7 @@ echo "Filtering ldapsearch results..."
 echo "Filtering original ldif used to create database..."
 . $SRCDIR/scripts/acfilter.sh < $LDIF > $LDIFFLT
 echo "Comparing filter output..."
-cmp $SEARCHFLT $LDIFFLT
+$CMP $SEARCHFLT $LDIFFLT
 
 if test $? != 0 ; then
        echo "comparison failed - database was not created correctly"
index 9fcf18b711181ddfa70e28f1347ec771a18d81a3..eb79e876d36c206bc67175a14257815e2d68ceeb 100755 (executable)
@@ -26,7 +26,7 @@ if test $RC != 0 ; then
 fi
 
 echo "Starting slapd on TCP/IP port $PORT..."
-$SLAPD -f $CONF -p $PORT -d $LVL $TIMING > $MASTERLOG 2>&1 &
+$SLAPD -f $CONF -h $MASTERURI -d $LVL $TIMING > $MASTERLOG 2>&1 &
 PID=$!
 
 echo "Testing slapd searching..."
@@ -59,7 +59,7 @@ fi
 
 echo "Testing OR searching..."
 $LDAPSEARCH -S "" -b "$BASEDN" -h localhost -p $PORT \
-       '(|(objectclass=rfc822mailgroup)(sn=jones))' >> $SEARCHOUT 2>&1
+       '(|(objectclass=groupofnames)(sn=jones))' >> $SEARCHOUT 2>&1
 if test $RC != 0 ; then
        echo "ldapsearch failed!"
        kill -HUP $PID
@@ -68,7 +68,7 @@ fi
 
 echo "Testing AND matching and ends-with searching..."
 $LDAPSEARCH -S "" -b "$BASEDN" -h localhost -p $PORT \
-       '(&(objectclass=rfc822mailgroup)(cn=A*))' >> $SEARCHOUT 2>&1
+       '(&(objectclass=groupofnames)(cn=A*))' >> $SEARCHOUT 2>&1
 if test $RC != 0 ; then
        echo "ldapsearch failed!"
        kill -HUP $PID
@@ -93,7 +93,7 @@ echo "Filtering ldapsearch results..."
 echo "Filtering original ldif used to create database..."
 . $SRCDIR/scripts/acfilter.sh < $LDIF > $LDIFFLT
 echo "Comparing filter output..."
-cmp $SEARCHFLT $LDIFFLT
+$CMP $SEARCHFLT $LDIFFLT
 
 if test $? != 0 ; then
        echo "Comparison failed"
index beb69b038fb4b91324d4a24b76bc3207ba017c87..59db1498a6e8bde07fc419b8d04e93ce57de8bb4 100755 (executable)
@@ -26,7 +26,7 @@ if test $RC != 0 ; then
 fi
 
 echo "Starting slapd on TCP/IP port $PORT..."
-$SLAPD -f $CONF -p $PORT -d $LVL $TIMING > $MASTERLOG 2>&1 &
+$SLAPD -f $CONF -h $MASTERURI -d $LVL $TIMING > $MASTERLOG 2>&1 &
 PID=$!
 
 echo "Testing slapd modify operations..."
@@ -63,8 +63,8 @@ dn: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, o=University
 changetype: modify
 # EMBEDDED COMMENT
  CONTINUED
-replace: multilinedescription
-multilinedescription: The replaced multiLineDescription $ Blah Woof.
+replace: description
+description: The replaced multiLineDescription $ Blah Woof.
 -
 replace: drink
 drink: Iced Tea
@@ -82,6 +82,9 @@ member: cn=James A Jones 1, ou=Alumni Association, ou=People, o=University of Mi
 dn: cn=All Staff,ou=Groups,o=University of Michigan,c=US
 changetype: modify
 delete: member
+-
+add: member
+member: cn=Dorothy Stevens, ou=Alumni Association, ou=People, o=University of Michigan, c=US
 
 dn: cn=Gern Jensen, ou=Information Technology Division, ou=People, o=University of Michigan, c=US
 changetype: add
@@ -89,18 +92,14 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Gern Jensen
+sn: Jensen
 title: Chief Investigator, ITD
 postaladdress: ITD $ 535 W. William St $ Ann Arbor, MI 48103
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: gjensen
-krbname: gjensen@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 drink: Coffee
 homepostaladdress: 844 Brown St. Apt. 4 $ Ann Arbor, MI 48104
-multilinedescription: Very odd
+description: Very odd
 facsimiletelephonenumber: +1 313 555 7557
 telephonenumber: +1 313 555 8343
 mail: gjensen@mailgw.umich.edu
@@ -136,7 +135,7 @@ echo "Filtering ldapsearch results..."
 echo "Filtering original ldif used to create database..."
 . $SRCDIR/scripts/acfilter.sh < $LDIF > $LDIFFLT
 echo "Comparing filter output..."
-cmp $SEARCHFLT $LDIFFLT
+$CMP $SEARCHFLT $LDIFFLT
 
 if test $? != 0 ; then
        echo "comparison failed - modify operations did not complete correctly"
index d53673ed1ca0cfef16db2ec9472528d500f79804..ca5b98bea14b499620a5119bb6cc587e0278788e 100755 (executable)
@@ -26,7 +26,7 @@ if test $RC != 0 ; then
 fi
 
 echo "Starting slapd on TCP/IP port $PORT..."
-$SLAPD -f $CONF -p $PORT -d $LVL $TIMING > $MASTERLOG 2>&1 &
+$SLAPD -f $CONF -h $MASTERURI -d $LVL $TIMING > $MASTERLOG 2>&1 &
 PID=$!
 echo "Testing slapd modrdn operations..."
 
@@ -91,7 +91,7 @@ echo "Filtering ldapsearch results..."
 echo "Filtering original ldif used to create database..."
 . $SRCDIR/scripts/acfilter.sh < $LDIF > $LDIFFLT
 echo "Comparing filter output..."
-cmp $SEARCHFLT $LDIFFLT
+$CMP $SEARCHFLT $LDIFFLT
 
 if test $? != 0 ; then
        echo "comparison failed - modrdn operations did not complete correctly"
@@ -118,7 +118,7 @@ echo "Filtering ldapsearch results..."
 echo "Filtering original ldif used to create database..."
 . $SRCDIR/scripts/acfilter.sh < $LDIF > $LDIFFLT
 echo "Comparing filter output..."
-cmp $SEARCHFLT $LDIFFLT
+$CMP $SEARCHFLT $LDIFFLT
 
 if test $? != 0 ; then
        echo "comparison failed - modrdn operations did not complete correctly"
@@ -138,7 +138,7 @@ if test $RC != 0 ; then
        echo "ldapsearch failed!"
        exit $RC
 fi
-cmp $SEARCHOUT /dev/null
+$CMP $SEARCHOUT /dev/null
 if test $? != 0 ; then
        echo "failure: ldapsearch found attribute that was to be removed!"
        kill -HUP $PID
@@ -162,7 +162,7 @@ echo "Filtering ldapsearch results..."
 echo "Filtering original ldif used to create database..."
 . $SRCDIR/scripts/acfilter.sh < $LDIF > $LDIFFLT
 echo "Comparing filter output..."
-cmp $SEARCHFLT $LDIFFLT
+$CMP $SEARCHFLT $LDIFFLT
 
 if test $? != 0 ; then
        echo "comparison failed - modrdn operations did not complete correctly"
@@ -203,7 +203,7 @@ echo "Filtering ldapsearch results..."
 echo "Filtering original ldif used to create database..."
 . $SRCDIR/scripts/acfilter.sh < $LDIF > $LDIFFLT
 echo "Comparing filter output..."
-cmp $SEARCHFLT $LDIFFLT
+$CMP $SEARCHFLT $LDIFFLT
 
 kill -HUP $PID
 if test $? != 0 ; then
index 4b2f5b5fc0a7cb8feda5a5dfd610b4a9bcbd8df1..63557bd79ba918acd0515baf96b5c3404d4619b9 100755 (executable)
@@ -26,7 +26,7 @@ if test $RC != 0 ; then
 fi
 
 echo "Starting slapd on TCP/IP port $PORT..."
-$SLAPD -f $ACLCONF -p $PORT -d $LVL $TIMING > $MASTERLOG 2>&1 &
+$SLAPD -f $ACLCONF -h $MASTERURI -d $LVL $TIMING > $MASTERLOG 2>&1 &
 PID=$!
 
 echo "Testing slapd access control..."
@@ -108,9 +108,9 @@ dn: cn=ITD Staff, ou=Groups, o=University of Michigan, c=US
 # comment
 changetype: modify
 # comment
-add: telephonenumber
+add: ou
 # comment
-telephonenumber: +1 810 555 1212
+ou: Groups
 # comment
 EOMODS4
 
@@ -131,7 +131,7 @@ echo "Filtering ldapsearch results..."
 echo "Filtering original ldif used to create database..."
 . $SRCDIR/scripts/acfilter.sh < $LDIF > $LDIFFLT
 echo "Comparing filter output..."
-cmp $SEARCHFLT $LDIFFLT
+$CMP $SEARCHFLT $LDIFFLT
 
 if test $? != 0 ; then
        echo "comparison failed - modify operations did not complete correctly"
index 3dd64a892de511af1f43119d2f69859964bed663..32114d8abbc236c408576fe109878a2a71d2cf95 100755 (executable)
@@ -35,11 +35,11 @@ echo "Cleaning up in $REPLDIR..."
 rm -f $REPLDIR/[!C]*
 
 echo "Starting master slapd on TCP/IP port $PORT..."
-$SLAPD -f $MASTERCONF -p $PORT -d $LVL $TIMING > $MASTERLOG 2>&1 &
+$SLAPD -f $MASTERCONF -h $MASTERURI -d $LVL $TIMING > $MASTERLOG 2>&1 &
 PID=$!
 
 echo "Starting slave slapd on TCP/IP port $SLAVEPORT..."
-$SLAPD -f $SLAVECONF -p $SLAVEPORT -d $LVL $TIMING > $SLAVELOG 2>&1 &
+$SLAPD -f $SLAVECONF -h $SLAVEURI -d $LVL $TIMING > $SLAVELOG 2>&1 &
 SLAVEPID=$!
 
 echo "Using ldapsearch to check that master slapd is running..."
@@ -122,18 +122,14 @@ objectclass: top
 objectclass: person
 objectclass: organizationalPerson
 objectclass: newPilotPerson
-objectclass: umichPerson
 cn: Gern Jensen
+sn: Jensen
 title: Chief Investigator, ITD
 postaladdress: ITD $ 535 W. William St $ Ann Arbor, MI 48103
 seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
-uid: gjensen
-krbname: gjensen@umich.edu
-nobatchupdates: TRUE
-onvacation: FALSE
 drink: Coffee
 homepostaladdress: 844 Brown St. Apt. 4 $ Ann Arbor, MI 48104
-multilinedescription: Very odd
+description: Very odd
 facsimiletelephonenumber: +1 313 555 7557
 telephonenumber: +1 313 555 8343
 mail: gjensen@mailgw.umich.edu
@@ -178,7 +174,7 @@ echo "Filtering original ldif used to create database..."
 . $SRCDIR/scripts/acfilter.sh < $LDIF > $LDIFFLT
 
 echo "Comparing retrieved entries from master and slave..."
-cmp $SEARCHFLT $LDIFFLT
+$CMP $SEARCHFLT $LDIFFLT
 
 if test $? != 0 ; then
        echo "test failed - master and slave databases differ"
index ce874511aaf1bce9a7e2636ac3affcddbe2265d5..753bcc357a9fa03e0dcd3bd9cdb2a70f638e5d5e 100755 (executable)
@@ -32,7 +32,7 @@ echo "Waiting 5 seconds for slapadd to build slapd database..."
 sleep 5
 
 echo "Starting slapd on TCP/IP port $PORT..."
-$SLAPD -f $CONF -p $PORT -d $LVL $TIMING > $MASTERLOG 2>&1 &
+$SLAPD -f $CONF -h $MASTERURI -d $LVL $TIMING > $MASTERLOG 2>&1 &
 PID=$!
 
 echo "Using ldapsearch to check that slapd is running..."
@@ -72,7 +72,7 @@ echo "Filtering ldapsearch results..."
 echo "Filtering original ldif used to create database..."
 . $SRCDIR/scripts/acfilter.sh < $LDIF > $LDIFFLT
 echo "Comparing filter output..."
-cmp $SEARCHFLT $LDIFFLT
+$CMP $SEARCHFLT $LDIFFLT
 
 if test $? != 0 ; then
        echo "comparison failed - database was not created correctly"
index ccd848444e5682ad0117dee671e766b2c2748560..5273b5f2057571283493e33c463d1cc61ac64f14 100755 (executable)
@@ -31,11 +31,11 @@ if test $RC != 0 ; then
 fi
 
 echo "Starting master slapd on TCP/IP port $PORT..."
-$SLAPD -f $CONF -p $PORT -d $LVL $TIMING > $MASTERLOG 2>&1 &
+$SLAPD -n master -f $CONF -h $MASTERURI -d $LVL $TIMING > $MASTERLOG 2>&1 &
 PID=$!
 
 echo "Starting slave slapd on TCP/IP port $SLAVEPORT..."
-$SLAPD -f $REFSLAVECONF -p $SLAVEPORT -d $LVL $TIMING > $SLAVELOG 2>&1 &
+$SLAPD -n slave -f $REFSLAVECONF -h $SLAVEURI -d $LVL $TIMING > $SLAVELOG 2>&1 &
 SLAVEPID=$!
 
 echo "Testing for master slapd..."
@@ -79,7 +79,7 @@ fi
 
 echo "Testing OR searching..."
 $LDAPSEARCH -S "" -b "$BASEDN" -h localhost -p $SLAVEPORT \
-       '(|(objectclass=rfc822mailgroup)(sn=jones))' >> $SEARCHOUT 2>&1
+       '(|(objectclass=groupofnames)(sn=jones))' >> $SEARCHOUT 2>&1
 if test $RC != 0 ; then
        echo "ldapsearch failed!"
        kill -HUP $PID $SLAVEPID
@@ -88,7 +88,7 @@ fi
 
 echo "Testing AND matching and ends-with searching..."
 $LDAPSEARCH -S "" -b "$BASEDN" -h localhost -p $SLAVEPORT \
-       '(&(objectclass=rfc822mailgroup)(cn=A*))' >> $SEARCHOUT 2>&1
+       '(&(objectclass=groupofnames)(cn=A*))' >> $SEARCHOUT 2>&1
 if test $RC != 0 ; then
        echo "ldapsearch failed!"
        kill -HUP $PID $SLAVEPID
@@ -113,7 +113,7 @@ echo "Filtering ldapsearch results..."
 echo "Filtering original ldif used to create database..."
 . $SRCDIR/scripts/acfilter.sh < $LDIF > $LDIFFLT
 echo "Comparing filter output..."
-cmp $SEARCHFLT $LDIFFLT
+$CMP $SEARCHFLT $LDIFFLT
 
 if test $? != 0 ; then
        echo "Comparison failed"
diff --git a/tests/scripts/test010-passwd b/tests/scripts/test010-passwd
new file mode 100755 (executable)
index 0000000..3d71698
--- /dev/null
@@ -0,0 +1,131 @@
+#! /bin/sh
+# $OpenLDAP$
+
+if test $# -eq 0 ; then
+       SRCDIR="."
+else
+       SRCDIR=$1; shift
+fi
+if test $# -eq 1 ; then
+       BACKEND=$1; shift
+fi
+
+echo "running defines.sh $SRCDIR $BACKEND"
+. $SRCDIR/scripts/defines.sh
+
+echo "Cleaning up in $DBDIR..."
+
+rm -f $DBDIR/[!C]*
+
+echo "Starting slapd on TCP/IP port $PORT..."
+$SLAPD -f $PWCONF -h $MASTERURI -d $LVL $TIMING > $MASTERLOG 2>&1 &
+PID=$!
+
+echo "Using ldapsearch to check that slapd is running..."
+for i in 0 1 2 3 4 5; do
+       $LDAPSEARCH -s base -b "$MONITOR" -h localhost -p $PORT \
+               'objectclass=*' > /dev/null 2>&1
+       RC=$?
+       if test $RC = 1 ; then
+               echo "Waiting 5 seconds for slapd to start..."
+               sleep 5
+       fi
+done
+
+echo "Using ldapadd to populate the database..."
+$LDAPADD -D "$MANAGERDN" -h localhost -p $PORT -w $PASSWD < \
+       $LDIFPASSWD > $TESTOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+       echo "ldapadd failed!"
+       kill -HUP $PID
+       exit $RC
+fi
+
+echo > $SEARCHOUT
+echo > $TESTOUT
+
+echo "Using ldapsearch to verify population ..."
+echo "++ Initial search" >> $SEARCHOUT
+$LDAPSEARCH -h localhost -p $PORT \
+       -D "$MANAGERDN" -w $PASSWD \
+       -b "$BASEDN" \
+       'objectclass=*' >> $SEARCHOUT 2>&1
+
+echo "Using ldappasswd (PASS 1)  ..."
+echo "Pass 1" >> $TESTOUT
+$LDAPPASSWD -h localhost -p $PORT \
+       -w secret -s newsecret \
+       "cn=md5, $BASEDN" >> $TESTOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+       echo "ldappasswd failed!"
+       kill -HUP $PID
+       exit $RC
+fi
+$LDAPPASSWD -h localhost -p $PORT \
+       -w secret -s newsecret \
+       "cn=smd5, $BASEDN" >> $TESTOUT 2>&1
+if test $RC != 0 ; then
+       echo "ldappasswd failed!"
+       kill -HUP $PID
+       exit $RC
+fi
+$LDAPPASSWD -h localhost -p $PORT \
+       -w secret -s newsecret \
+       "cn=sha, $BASEDN" >> $TESTOUT 2>&1
+if test $RC != 0 ; then
+       echo "ldappasswd failed!"
+       kill -HUP $PID
+       exit $RC
+fi
+$LDAPPASSWD -h localhost -p $PORT \
+       -w secret -s newsecret \
+       "cn=ssha, $BASEDN" >> $TESTOUT 2>&1
+if test $RC != 0 ; then
+       echo "ldappasswd failed!"
+       kill -HUP $PID
+       exit $RC
+fi
+
+echo "" >> $TESTOUT
+echo "Pass 2" >> $TESTOUT
+echo "Using ldappasswd (PASS 2)  ..."
+$LDAPPASSWD -h localhost -p $PORT \
+       -w newsecret \
+       "cn=md5, $BASEDN" >> $TESTOUT 2>&1
+if test $RC != 0 ; then
+       echo "ldappasswd failed!"
+       kill -HUP $PID
+       exit $RC
+fi
+$LDAPPASSWD -h localhost -p $PORT \
+       -w newsecret \
+       "cn=smd5, $BASEDN" >> $TESTOUT 2>&1
+if test $RC != 0 ; then
+       echo "ldappasswd failed!"
+       kill -HUP $PID
+       exit $RC
+fi
+$LDAPPASSWD -h localhost -p $PORT \
+       -w newsecret \
+       "cn=sha, $BASEDN" >> $TESTOUT 2>&1
+if test $RC != 0 ; then
+       echo "ldappasswd failed!"
+       kill -HUP $PID
+       exit $RC
+fi
+$LDAPPASSWD -h localhost -p $PORT \
+       -w newsecret \
+       "cn=ssha, $BASEDN" >> $TESTOUT 2>&1
+if test $RC != 0 ; then
+       echo "ldappasswd failed!"
+       kill -HUP $PID
+       exit $RC
+fi
+
+kill -HUP $PID
+
+echo ">>>>> Test succeeded"
+
+exit 0