Place NeoSoft Inc. LDAP Tcl client code into OpenLDAP contrib tree.

This commit is contained in:
Randy Kunkee 1999-02-10 23:56:49 +00:00
parent f1f4127f59
commit ef123c1cec
12 changed files with 4134 additions and 0 deletions

23
contrib/ldaptcl/COPYRIGHT Normal file
View File

@ -0,0 +1,23 @@
NeoSoft Tcl client extensions to Lightweight Directory Access Protocol.
Copyright (c) 1998-1999 NeoSoft, Inc.
All Rights Reserved.
This software may be used, modified, copied, distributed, and sold,
in both source and binary form provided that these copyrights are
retained and their terms are followed.
Under no circumstances are the authors or NeoSoft Inc. responsible
for the proper functioning of this software, nor do the authors
assume any liability for damages incurred with its use.
Redistribution and use in source and binary forms are permitted
provided that this notice is preserved and that due credit is given
to NeoSoft, Inc.
NeoSoft, Inc. 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.
Requests for permission may be sent to NeoSoft Inc, 1770 St. James Place,
Suite 500, Houston, TX, 77056.

192
contrib/ldaptcl/Makefile.in Normal file
View File

@ -0,0 +1,192 @@
#
# This file is a Makefile for Neo, the NeoSoft extensions to Tcl.
# If it has the name "Makefile.in" then it is a template for a
# Makefile; to generate the actual Makefile, run "./configure",
# which is a configuration script generated by the "autoconf" program
# (constructs like "@foo@" will get replaced in the actual Makefile.
#
VERSION = @NEO_VERSION@
LIBNAME = @NEO_SHARED_LIB_FILE@
# Default top-level directories in which to install architecture-
# specific files (exec_prefix) and machine-independent files such
# as scripts (prefix). The values specified here may be overridden
# at configure-time with the --exec-prefix and --prefix options
# to the "configure" script.
prefix = @prefix@
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
# when installing files.
INSTALL_ROOT =
# 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
# Directory in which to install the .a or .so binary for the Neo library:
LIB_INSTALL_DIR = $(INSTALL_ROOT)$(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
# The symbols below provide support for dynamic loading and shared
# libraries. The values of the symbols are normally set by the
# configure script. You shouldn't normally need to modify any of
# these definitions by hand.
SHLIB_CFLAGS = @NEO_SHLIB_CFLAGS@
NEO_LIB_FILE = @NEO_LIB_FILE@
NEO_SHARED_LIB_FILE = @NEO_SHARED_LIB_FILE@
# The directory containing the Tcl sources and headers appropriate
# for this version of Neo ("srcdir" will be replaced or has already
# been replaced by the configure script):
TCL_GENERIC_DIR = @TCL_SRC_DIR@/generic
# The top of the TclX directory tree
TCLX_TOP_DIR = @TCLX_TOP_DIR@
# The directory where tclExtend.h will be:
TCLX_TCL_GEN_DIR = ${TCLX_TOP_DIR}/tcl/generic
# The directory where tclXunixPort.h will be:
TCLX_TCL_UNIX_DIR = ${TCLX_TOP_DIR}/tcl/unix
# The path to tclX the runtcl script:
TCLX_RUNTCL = ${TCLX_TOP_DIR}/unix/runtcl
# The directory containing the Tcl library archive file appropriate
# for this version of Neo:
TCL_BIN_DIR = @TCL_BIN_DIR@
# The symbol below provides support for dynamic loading and shared
# libraries. See configure.in for a description of what it means.
# The values of the symbolis normally set by the configure script.
SHLIB_LD = @SHLIB_LD@
# Set to the options to include libldap.a and liblber.a
# (eg. -L../tools/blah -lldap -llber)
LDAP_LIBFLAGS = @ldaplibflags@
LDAP_CFLAGS = @ldapinclude@
LDAP_BUILD = @ldapbuild@
LDAP_DIR = @ldapdir@
#----------------------------------------------------------------
# The information below is modified by the configure script when
# Makefile is generated from Makefile.in. You shouldn't normally
# modify any of this stuff by hand.
#----------------------------------------------------------------
AC_FLAGS = @DEFS@
INSTALL= @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
RANLIB = @RANLIB@
SRC_DIR = @srcdir@/..
TOP_DIR = @srcdir@/..
GENERIC_DIR = $(TOP_DIR)/generic
#----------------------------------------------------------------
# The information below should be usable as is. The configure
# script won't modify it and you shouldn't need to modify it
# either.
#----------------------------------------------------------------
OBJS= neoXldap.o
LIBDIR=$(exec_prefix)/lib
INCDIR=$(prefix)/include
LIBS= @LIBS@ @TCLX_LIB_SPEC@ @TCL_LIB_SPEC@ @TCL_LIBS@ $(LDAP_LIBFLAGS) -lc
TK_LIBS=@TKX_LIB_SPEC@ @TK_LIB_SPEC@ @TK_LIBS@
TK_VERSION=@TK_VERSION@
LDAPINCDIR=/usr/local/include
CC = @CC@
CC_SWITCHES = ${CFLAGS} @NEO_SHLIB_CFLAGS@ -I. \
-I@prefix@/include ${AC_FLAGS} ${PROTO_FLAGS} \
${SECURITY_FLAGS} ${MEM_DEBUG_FLAGS} ${KEYSYM_FLAGS} \
-DNEO_LIBRARY=\"${NEO_LIBRARY}\"
TK_SWITCHES = ${CC_SWITCHES} @TK_XINCLUDES@
.c.o:
$(CC) -c $(CC_SWITCHES) $<
all: @NEO_LIB_FILE@ ldaptclsh @LDAPWISH@
@NEO_LIB_FILE@: $(OBJS)
rm -f @NEO_LIB_FILE@
@MAKE_LIB@
$(RANLIB) @NEO_LIB_FILE@
neoXldap.o: neoXldap.c
$(CC) -c $(LDAP_CFLAGS) $(CC_SWITCHES) $<
clean:
-rm -f ldaptclsh ldapwish
-rm -f *.o *.a *.so*
distclean: clean
rm -f Makefile pkgIndex.tcl config.cache config.log config.status
install: install-binaries install-man
install-binaries: @NEO_LIB_FILE@ ldaptclsh @LDAPWISH@
@-mkdir -p $(BIN_INSTALL_DIR)
$(INSTALL_PROGRAM) ldaptclsh $(BIN_INSTALL_DIR)/ldaptclsh
@if [ -n "@LDAPWISH@" ] ; then \
echo $(INSTALL_PROGRAM) ldapwish $(BIN_INSTALL_DIR)/ldapwish; \
$(INSTALL_PROGRAM) ldapwish $(BIN_INSTALL_DIR)/ldapwish; \
fi
$(INSTALL_DATA) @NEO_LIB_FILE@ $(LIB_INSTALL_DIR)
@if [ "$(NEO_LIB_FILE)" = "$(NEO_SHARED_LIB_FILE)" ] ; then \
echo Installing pkgIndex.tcl in $(NEO_LIBRARY); \
mkdir -p $(NEO_LIBRARY); \
$(INSTALL_DATA) pkgIndex.tcl $(NEO_LIBRARY); \
fi
install-man:
@for i in ldap.n; \
do \
echo "Installing $$i"; \
rm -f $(MANN_INSTALL_DIR)/$$i; \
sed -e '/man\.macros/r man.macros' -e '/man\.macros/d' \
$$i > $(MANN_INSTALL_DIR)/$$i; \
chmod 444 $(MANN_INSTALL_DIR)/$$i; \
done;
TCLOFILES= tclAppInit.o
ldaptclsh:$(TCLOFILES) @NEO_LIB_FILE@
$(CC) @LD_FLAGS@ $(TCLOFILES) @NEO_BUILD_LIB_SPEC@ $(LIBS) \
@TCL_LD_SEARCH_FLAGS@ -o ldaptclsh
tkAppInit.o: tkAppInit.c
$(CC) -c ${TK_SWITCHES} tkAppInit.c
ldapwish:tkAppInit.o @NEO_LIB_FILE@
$(CC) @LD_FLAGS@ tkAppInit.o @NEO_BUILD_LIB_SPEC@ $(TK_LIBS) $(LIBS) \
@TCL_LD_SEARCH_FLAGS@ -o ldapwish

66
contrib/ldaptcl/README Normal file
View File

@ -0,0 +1,66 @@
Copyright (c) 1998-1999 NeoSoft, Inc.
For licensing information, see the file neoXldap.c and the COPYRIGHT
file contains in the directory you found this file.
This directory contains an extension to Tcl to interface with an
LDAP server. While this software is being released to the OpenLDAP
community, it is the authors' intention that support continue (and
be added) for other client libraries as well. As time goes on, it
is expected that code will converge rather than diverge.
Support is provided for University of Michigan LDAP version 3.3,
OpenLDAP, and Netscape.
It uses GNU autoconf. It builds and installs without requiring
parallel directories, but it does require that Tcl and Extended Tcl
are installed in the directory pointed to by --prefix (/usr/local
by default).
For further info, try "./configure --help".
For example, I run:
./configure --prefix=/opt/neosoft97 --enable-shared \
--with-ldap=/usr/isp2000/ldap
Remember that --prefix must be the same prefix used when building
and installint Tcl.
Netscape configuration has not been well tested, and you may have to
play with the resulting Makefile to get it to work. In particular,
you will probably need to modify the LDAP_LIBFLAGS. However, the
C code itself is reasonably well tested with Netscape.
This module will install a regular shell (ldaptclsh) a windowing
shell (ldapwish) a library, a pkgIndex.tcl, and a manpage (ldap.n).
If your Tcl installation has been configured with --enable-shared,
then it is highly recommended that you also use --enable-shared
here.
Shared libraries and Tcl packages.
If Tcl is built with --enable-shared, and OpenLDAP (or another version
for that matter) has been build to create -llber and -lldap as shared
libaries, and you build ldaptcl with --enable-shared, it should be
possible to run a plain Tcl interpreter (eg. tclsh8.0) and do
package require Ldaptcl
which will install the "ldap" command into the interpreter.
This may require that you set the LD_LIBRARY_PATH environment variable
appropriately, or use -R or -W,-rpath ld command options.
It also may require that you modify the
If you configure with --enable-shared, and you have shared libraries
for -lldap and -llber, then you might be able to
"package require Ldaptcl", provided that everything is set up
exactly right, ie. -R ld flags, LD_LIBRARY_PATH environment variables,
etc.
This package was test built on a Sparc Solaris 2.5 using the SUN Pro C
compiler.
You may email comments or bug fixes to openldap-devel@OpenLDAP.org,
or to kunkee@OpenLDAP.org.

1606
contrib/ldaptcl/configure vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,224 @@
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.15 1998/05/22 21:26:25 kunkee Exp $
NEO_VERSION=1.0
NEO_MAJOR_VERSION=1
NEO_MINOR_VERSION=0
VERSION=${NEO_VERSION}
if test "${prefix}" = "NONE"; then
prefix=/usr/local
fi
if test "${exec_prefix}" = "NONE"; then
exec_prefix=$prefix
fi
AC_ARG_ENABLE(gcc, [ --enable-gcc allow use of gcc if available],
[neo_ok=$enableval], [neo_ok=no])
if test "$neo_ok" = "yes"; then
AC_PROG_CC
else
CC=${CC-cc}
AC_SUBST(CC)
fi
AC_PROG_CPP
AC_ARG_ENABLE(gcc, [ --enable-gcc allow use of gcc if available],
[neo_ok=$enableval], [neo_ok=no])
if test "$neo_ok" = "yes"; then
AC_PROG_CC
else
CC=${CC-cc}
AC_SUBST(CC)
fi
AC_PROG_INSTALL(install-sh)
AC_PROG_RANLIB
if test ! -f $exec_prefix/lib/tclConfig.sh
then
AC_MSG_ERROR(Tcl must be installed first)
fi
. $exec_prefix/lib/tclConfig.sh
if test ! -f $exec_prefix/lib/tclxConfig.sh
then
AC_MSG_ERROR(Extended Tcl must be installed first)
fi
. $exec_prefix/lib/tclxConfig.sh
#--------------------------------------------------------------------
# See if there was a command-line option for where Tk is; if
# not, assume that its top-level directory is a sibling of ours.
#--------------------------------------------------------------------
AC_ARG_WITH(tk, [ --with-tk=DIR use Tk 8.0 binaries from DIR],
, with_tk=yes)
case "$with_tk" in
yes)
if test -f $exec_prefix/lib/tkConfig.sh -a $exec_prefix/lib/tkxConfig.sh
then
:
else
AC_MSG_ERROR(Tk does not appear to be installed at $exec_prefix)
fi
;;
no) ;;
*) AC_MSG_ERROR(Tk cannot be specified and must be in $exec_prefix)
;;
esac
AC_ARG_WITH(x, [ --without-x do not build/install ldapwish])
if test "$with_x" = "no"
then
with_tk=no
fi
if test "$with_tk" != "no"
then
LDAPWISH=ldapwish
. $exec_prefix/lib/tkConfig.sh
. $exec_prefix/lib/tkxConfig.sh
fi
AC_SUBST(TK_LIBS)
AC_SUBST(TK_LIB_SPEC)
AC_SUBST(TK_XINCLUDES)
AC_SUBST(TK_VERSION)
AC_SUBST(TKX_LIB_SPEC)
AC_SUBST(LDAPWISH)
#--------------------------------------------------------------------
# Read in configuration information generated by Tcl for shared
# libraries, and arrange for it to be substituted into our
# Makefile.
#--------------------------------------------------------------------
CC=$TCL_CC
SHLIB_CFLAGS=$TCL_SHLIB_CFLAGS
SHLIB_LD=$TCL_SHLIB_LD
SHLIB_LD_LIBS=$TCL_SHLIB_LD_LIBS
SHLIB_SUFFIX=$TCL_SHLIB_SUFFIX
SHLIB_VERSION=$TCL_SHLIB_VERSION
DL_LIBS=$TCL_DL_LIBS
LD_FLAGS=$TCL_LD_FLAGS
NEO_LD_SEARCH_FLAGS=$TCL_LD_SEARCH_FLAGS
eval "NEO_SHARED_LIB_FILE=libldap${TCL_SHARED_LIB_SUFFIX}"
eval "NEO_UNSHARED_LIB_FILE=libldap${TCL_UNSHARED_LIB_SUFFIX}"
#--------------------------------------------------------------------
# The statements below define a collection of symbols related to
# building libldap as a shared library instead of a static library.
#--------------------------------------------------------------------
# Warning: in order to use the following code for libldap and libdb versions,
# the VERSION shell variable is modified, and then is restored after.
AC_ARG_ENABLE(shared,
[ --enable-shared build libldaptcl as a shared library],
[ok=$enableval], [ok=no])
if test "$ok" = "yes" -a "${SHLIB_SUFFIX}" != ""; then
NEO_SHLIB_CFLAGS="${SHLIB_CFLAGS}"
eval "NEO_LIB_FILE=libldaptcl${TCL_SHARED_LIB_SUFFIX}"
MAKE_LIB="\${SHLIB_LD} $TCL_LIB_HNAME -o ${NEO_LIB_FILE} \${OBJS}"
RANLIB=":"
else
NEO_SHLIB_CFLAGS=""
eval "NEO_LIB_FILE=libldaptcl${TCL_UNSHARED_LIB_SUFFIX}"
MAKE_LIB="ar cr ${NEO_LIB_FILE} \${OBJS}"
fi
AC_ARG_WITH(ldap, [ --with-ldap=<dir> common parent of ldap include and lib dirs],
[neo_ldap=$withval
case $withval in
yes) ldapdir=/usr/local
;;
no) ;;
*) ldapdir=$withval
neo_ldap=yes
;;
esac
], [
neo_ldap=yes
ldapdir=/usr/local
])
ldapincdir=$ldapdir/include
AC_ARG_WITH(ldap-incdir, [ --with-ldap-incdir=<dir> path to ldap.h],
[ldapincdir=$withval])
ldaplibdir=$ldapdir/lib
AC_ARG_WITH(ldap-libdir, [ --with-ldap-libdir=<dir> path to ldap and lber libs],
[ldapincdir=$withval])
AC_ARG_WITH(ldap-libraries, [ --with-ldap-libflags=<libnames> -l flags for ldap libraries],
[ldaplibflags="-L$ldaplibdir $withval"],
[ldaplibflags="-L$ldaplibdir -lldap -llber"])
ldapinclude="-I$ldapincdir"
ldapbuild=yes
AC_SUBST(ldaplibflags)
AC_SUBST(ldapinclude)
AC_SUBST(ldapbuild)
AC_SUBST(ldapdir)
VERSION=${NEO_VERSION}
# Note: in the following variable, it's important to use the absolute
# path name of the Tcl directory rather than "..": this is because
# AIX remembers this path and will attempt to use it at run-time to look
# up the Tcl library.
if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
NEO_BUILD_LIB_SPEC="-L`pwd` -lldaptcl${VERSION}"
NEO_LIB_SPEC="-L${exec_prefix}/lib -lldaptcl${VERSION}"
else
NEO_BUILD_LIB_SPEC="-L`pwd` -lldaptcl`echo ${VERSION} | tr -d .`"
NEO_LIB_SPEC="-L${exec_prefix}/lib -lldaptcl`echo ${VERSION} | tr -d .`"
fi
AC_SUBST(CC)
AC_SUBST(LIBS)
AC_SUBST(DL_LIBS)
AC_SUBST(LD_FLAGS)
AC_SUBST(MATH_LIBS)
AC_SUBST(MAKE_LIB)
AC_SUBST(SHLIB_CFLAGS)
AC_SUBST(SHLIB_LD)
AC_SUBST(SHLIB_LD_LIBS)
AC_SUBST(SHLIB_SUFFIX)
AC_SUBST(SHLIB_VERSION)
AC_SUBST(TCLX_TOP_DIR)
AC_SUBST(TCLX_TCL_DIR)
AC_SUBST(TCLX_LIB_SPEC)
AC_SUBST(ITCL_LIB_SPEC)
AC_SUBST(TCL_LIBS)
AC_SUBST(TCL_SRC_DIR)
AC_SUBST(TCL_BIN_DIR)
AC_SUBST(TCL_LIB_SPEC)
AC_SUBST(TCL_LD_SEARCH_FLAGS)
AC_SUBST(TCL_LIB_HNAME)
AC_SUBST(TCL_SRC_DIR)
AC_SUBST(TCL_VERSION)
AC_SUBST(NEO_BUILD_LIB_SPEC)
AC_SUBST(NEO_LD_SEARCH_FLAGS)
AC_SUBST(NEO_SHARED_LIB_FILE)
AC_SUBST(NEO_UNSHARED_LIB_FILE)
AC_SUBST(NEO_LIB_FILE)
AC_SUBST(NEO_LIB_SPEC)
AC_SUBST(NEO_MAJOR_VERSION)
AC_SUBST(NEO_MINOR_VERSION)
AC_SUBST(NEO_SHLIB_CFLAGS)
AC_SUBST(NEO_VERSION)
dnl AC_SUBST(XINCLUDES)
dnl AC_SUBST(XLIBSW)
AC_OUTPUT(Makefile pkgIndex.tcl)

119
contrib/ldaptcl/install-sh Executable file
View File

@ -0,0 +1,119 @@
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5; it is not part of GNU.
#
# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
#
# This script is compatible with the BSD install script, but was written
# from scratch.
#
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
instcmd="$mvprog"
chmodcmd=""
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
fi
# Make a temp file name in the proper directory.
dstdir=`dirname $dst`
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp
# and set any options; do chmod last to preserve setuid bits
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
# Now rename the file to the real destination.
$doit $rmcmd $dst
$doit $mvcmd $dsttmp $dst
exit 0

365
contrib/ldaptcl/ldap.n Normal file
View File

@ -0,0 +1,365 @@
'\"
'\" 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.
.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".
Note: Karl is particularly dissatisfied with the syntax of this option,
so it is one of the most likely things to change in a subsequent release.
.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 UMich server, and hence
by this interface package.
Currently simple authentication, 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. Note that, right now, the sort of lowest-level pair
of the DN must also appear in the attributePairList, as in:
foo add "cn=karl, ou=People, o=NeoSoft Inc, c=US" {cn karl ...}
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.
A command error is 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 version does not.
.SH ADDING, DELETING, AND REPLACING OBJECT ATTRIBUTES
You can have multiple occurrences of the same attribute in a record.
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.
foo replace_attributes dn attributePairList
This replaces specified key-value pairs in an existing DN, leaving
unnamed ones untouched.
foo delete_attributes dn attributePairList
This deletes attributes in the list. If a pair is "foo {bar snap}" and
you delete "foo bar", "foo" will still have "snap".
If you provide an empty string ("") for the value part of the key-value
pair, the entire attribute will be deleted. To reiterate, if you provide
a non-empty string for the value part, only that value will be removed
from the value list.
.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.
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 LDAP library 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 fo 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.
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, an implementation 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 by Randy
Kunkee, also of NeoSoft, Inc., in 1998.
.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.

236
contrib/ldaptcl/man.macros Normal file
View File

@ -0,0 +1,236 @@
'\" The definitions below are for supplemental macros used in Tcl/Tk
'\" manual entries.
'\"
'\" .AP type name in/out ?indent?
'\" Start paragraph describing an argument to a library procedure.
'\" type is type of argument (int, etc.), in/out is either "in", "out",
'\" or "in/out" to describe whether procedure reads or modifies arg,
'\" and indent is equivalent to second arg of .IP (shouldn't ever be
'\" needed; use .AS below instead)
'\"
'\" .AS ?type? ?name?
'\" Give maximum sizes of arguments for setting tab stops. Type and
'\" name are examples of largest possible arguments that will be passed
'\" to .AP later. If args are omitted, default tab stops are used.
'\"
'\" .BS
'\" Start box enclosure. From here until next .BE, everything will be
'\" enclosed in one large box.
'\"
'\" .BE
'\" End of box enclosure.
'\"
'\" .CS
'\" Begin code excerpt.
'\"
'\" .CE
'\" End code excerpt.
'\"
'\" .VS ?version? ?br?
'\" Begin vertical sidebar, for use in marking newly-changed parts
'\" of man pages. The first argument is ignored and used for recording
'\" the version when the .VS was added, so that the sidebars can be
'\" found and removed when they reach a certain age. If another argument
'\" is present, then a line break is forced before starting the sidebar.
'\"
'\" .VE
'\" End of vertical sidebar.
'\"
'\" .DS
'\" Begin an indented unfilled display.
'\"
'\" .DE
'\" End of indented unfilled display.
'\"
'\" .SO
'\" Start of list of standard options for a Tk widget. The
'\" options follow on successive lines, in four columns separated
'\" by tabs.
'\"
'\" .SE
'\" End of list of standard options for a Tk widget.
'\"
'\" .OP cmdName dbName dbClass
'\" Start of description of a specific option. cmdName gives the
'\" option's name as specified in the class command, dbName gives
'\" the option's name in the option database, and dbClass gives
'\" the option's class in the option database.
'\"
'\" .UL arg1 arg2
'\" Print arg1 underlined, then print arg2 normally.
'\"
'\" SCCS: @(#) man.macros 1.9 97/08/22 18:50:59
'\"
'\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
.if t .wh -1.3i ^B
.nr ^l \n(.l
.ad b
'\" # Start an argument description
.de AP
.ie !"\\$4"" .TP \\$4
.el \{\
. ie !"\\$2"" .TP \\n()Cu
. el .TP 15
.\}
.ie !"\\$3"" \{\
.ta \\n()Au \\n()Bu
\&\\$1 \\fI\\$2\\fP (\\$3)
.\".b
.\}
.el \{\
.br
.ie !"\\$2"" \{\
\&\\$1 \\fI\\$2\\fP
.\}
.el \{\
\&\\fI\\$1\\fP
.\}
.\}
..
'\" # define tabbing values for .AP
.de AS
.nr )A 10n
.if !"\\$1"" .nr )A \\w'\\$1'u+3n
.nr )B \\n()Au+15n
.\"
.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
.nr )C \\n()Bu+\\w'(in/out)'u+2n
..
.AS Tcl_Interp Tcl_CreateInterp in/out
'\" # BS - start boxed text
'\" # ^y = starting y location
'\" # ^b = 1
.de BS
.br
.mk ^y
.nr ^b 1u
.if n .nf
.if n .ti 0
.if n \l'\\n(.lu\(ul'
.if n .fi
..
'\" # BE - end boxed text (draw box now)
.de BE
.nf
.ti 0
.mk ^t
.ie n \l'\\n(^lu\(ul'
.el \{\
.\" Draw four-sided box normally, but don't draw top of
.\" box if the box started on an earlier page.
.ie !\\n(^b-1 \{\
\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.el \}\
\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.\}
.fi
.br
.nr ^b 0
..
'\" # VS - start vertical sidebar
'\" # ^Y = starting y location
'\" # ^v = 1 (for troff; for nroff this doesn't matter)
.de VS
.if !"\\$2"" .br
.mk ^Y
.ie n 'mc \s12\(br\s0
.el .nr ^v 1u
..
'\" # VE - end of vertical sidebar
.de VE
.ie n 'mc
.el \{\
.ev 2
.nf
.ti 0
.mk ^t
\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
.sp -1
.fi
.ev
.\}
.nr ^v 0
..
'\" # Special macro to handle page bottom: finish off current
'\" # box/sidebar if in box/sidebar mode, then invoked standard
'\" # page bottom macro.
.de ^B
.ev 2
'ti 0
'nf
.mk ^t
.if \\n(^b \{\
.\" Draw three-sided box if this is the box's first page,
.\" draw two sides but no top otherwise.
.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
.\}
.if \\n(^v \{\
.nr ^x \\n(^tu+1v-\\n(^Yu
\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
.\}
.bp
'fi
.ev
.if \\n(^b \{\
.mk ^y
.nr ^b 2
.\}
.if \\n(^v \{\
.mk ^Y
.\}
..
'\" # DS - begin display
.de DS
.RS
.nf
.sp
..
'\" # DE - end display
.de DE
.fi
.RE
.sp
..
'\" # SO - start of list of standard options
.de SO
.SH "STANDARD OPTIONS"
.LP
.nf
.ta 4c 8c 12c
.ft B
..
'\" # SE - end of list of standard options
.de SE
.fi
.ft R
.LP
See the \\fBoptions\\fR manual entry for details on the standard options.
..
'\" # OP - start of full description for a single option
.de OP
.LP
.nf
.ta 4c
Command-Line Name: \\fB\\$1\\fR
Database Name: \\fB\\$2\\fR
Database Class: \\fB\\$3\\fR
.fi
.IP
..
'\" # CS - begin code excerpt
.de CS
.RS
.nf
.ta .25i .5i .75i 1i
..
'\" # CE - end code excerpt
.de CE
.fi
.RE
..
.de UL
\\$1\l'|0\(ul'\\$2
..

1043
contrib/ldaptcl/neoXldap.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
package ifneeded Neo @NEO_VERSION@ "package require Tclx 8.0; load [file join $dir .. @NEO_SHARED_LIB_FILE@] Ldaptcl"

View File

@ -0,0 +1,140 @@
/*
* tclAppInit.c --
*
* Provides a default version of the main program and Tcl_AppInit
* procedure for Tcl applications (without Tk).
*
* Copyright (c) 1993 The Regents of the University of California.
* Copyright (c) 1994-1995 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* SCCS: @(#) tclAppInit.c 1.17 96/03/26 12:45:29
*/
#include "tcl.h"
/*
* The following variable is a special hack that is needed in order for
* Sun shared libraries to be used for Tcl.
*/
extern int matherr();
int *tclDummyMathPtr = (int *) matherr;
#ifdef TCL_TEST
EXTERN int Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp));
#endif /* TCL_TEST */
/*
*----------------------------------------------------------------------
*
* main --
*
* This is the main program for the application.
*
* Results:
* None: Tcl_Main never returns here, so this procedure never
* returns either.
*
* Side effects:
* Whatever the application does.
*
*----------------------------------------------------------------------
*/
int
main(argc, argv)
int argc; /* Number of command-line arguments. */
char **argv; /* Values of command-line arguments. */
{
#ifdef USE_TCLX
TclX_Main(argc, argv, Tcl_AppInit);
#else
Tcl_Main(argc, argv, Tcl_AppInit);
#endif
return 0; /* Needed only to prevent compiler warning. */
}
/*
*----------------------------------------------------------------------
*
* 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.
*
* Side effects:
* Depends on the startup script.
*
*----------------------------------------------------------------------
*/
int
Tcl_AppInit(interp)
Tcl_Interp *interp; /* Interpreter for application. */
{
if (Tcl_Init(interp) == TCL_ERROR) {
return TCL_ERROR;
}
#ifdef USE_ITCL
if (Itcl_Init(interp) == TCL_ERROR) {
return TCL_ERROR;
}
Tcl_StaticPackage (interp, "Itcl", Itcl_Init, NULL);
#endif
#ifdef TCL_TEST
if (Tcltest_Init(interp) == TCL_ERROR) {
return TCL_ERROR;
}
Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init,
(Tcl_PackageInitProc *) NULL);
#endif /* TCL_TEST */
#ifdef USE_TCLX
if (Tclx_Init (interp) == TCL_ERROR) {
return TCL_ERROR;
}
Tcl_StaticPackage (interp, "Tclx", Tclx_Init, NULL);
#endif
if (Ldaptcl_Init(interp) == TCL_ERROR) {
return TCL_ERROR;
}
Tcl_StaticPackage(interp, "Ldaptcl", Ldaptcl_Init,
(Tcl_PackageInitProc *) NULL);
/*
* Call the init procedures for included packages. Each call should
* look like this:
*
* if (Mod_Init(interp) == TCL_ERROR) {
* return TCL_ERROR;
* }
*
* where "Mod" is the name of the module.
*/
/*
* 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", "~/.tclshrc", TCL_GLOBAL_ONLY);
return TCL_OK;
}

119
contrib/ldaptcl/tkAppInit.c Normal file
View File

@ -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.
*-----------------------------------------------------------------------------
* $Id: tkAppInit.c,v 1.1 1997/10/20 09:10:29 kunkee Exp $
*-----------------------------------------------------------------------------
*/
#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;
/*-----------------------------------------------------------------------------
* 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. */
}
/*-----------------------------------------------------------------------------
* 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;
}