]> git.sur5r.net Git - openldap/commitdiff
Changes
authorKurt Zeilenga <kurt@openldap.org>
Sun, 9 Feb 2003 00:28:49 +0000 (00:28 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Sun, 9 Feb 2003 00:28:49 +0000 (00:28 +0000)
    Updated libldap TLS certificate checking
    Updated client tool argument handling
    Updated test suite
    Updated liblutil detach handling
    Added libldap ldap_whoami routines
    Added liblber ber_flatten2 routine
    Added liblutil passwd sanity checks
    Fixed liblber PROTOS bugs
    Fixed ber_flush debug level
    Fixed libldap NULL cred bug
    Build Environment
        Check back-bdb requirement for BDB 4.1

46 files changed:
CHANGES
acconfig.h
build/openldap.m4
clients/tools/Makefile.in
clients/tools/common.c [new file with mode: 0644]
clients/tools/common.h [new file with mode: 0644]
clients/tools/ldapcompare.c
clients/tools/ldapcompare.dsp [new file with mode: 0644]
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/tools/ldapwhoami.c
clients/tools/ldapwhoami.dsp
include/ldap.h
include/portable.h.in
libraries/liblber/io.c
libraries/libldap/Makefile.in
libraries/libldap/dnssrv.c
libraries/libldap/error.c
libraries/libldap/extended.c
libraries/libldap/ldap-int.h
libraries/libldap/open.c
libraries/libldap/result.c
libraries/libldap/sasl.c
libraries/libldap/tls.c
libraries/libldap/url.c
libraries/libldap/whoami.c [new file with mode: 0644]
libraries/libldap_r/thr_cthreads.c [new file with mode: 0644]
libraries/libldap_r/thr_lwp.c [new file with mode: 0644]
libraries/libldap_r/thr_nt.c
libraries/libldap_r/thr_posix.c
libraries/libldap_r/thr_pth.c
libraries/libldap_r/thr_stub.c
libraries/libldap_r/thr_thr.c [new file with mode: 0644]
libraries/libldap_r/tpool.c
tests/data/slapd-repl-submaster.conf
tests/scripts/defines.sh
tests/scripts/test011-subtree-repl
tests/scripts/undiff.sh [new file with mode: 0755]

diff --git a/CHANGES b/CHANGES
index 6e3e5173887feffcc4b3a3cf44a4b030253e6cc9..445934a9fa542e49da39916da469baf6a4f72b1c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,19 @@
 OpenLDAP 2.1 Change Log
 
+OpenLDAP 2.1.13 Engineering
+       Updated libldap TLS certificate checking
+       Updated client tool argument handling
+       Updated test suite
+       Updated liblutil detach handling
+       Added libldap ldap_whoami routines
+       Added liblber ber_flatten2 routine
+       Added liblutil passwd sanity checks
+       Fixed liblber PROTOS bugs
+       Fixed ber_flush debug level
+       Fixed libldap NULL cred bug
+       Build Environment
+               Check back-bdb requirement for BDB 4.1
+
 OpenLDAP 2.1.12 Release
        Build Environment
                Update version number
index 37ec724e6dfd2cd5a8cb1f7be3434067ccd0cfce..dd00c4506dde06bb01317bc643cf003f940ee824 100644 (file)
 #      include <stddef.h>
 #endif
 
+#ifndef LDAP_REL_ENG
+#if (LDAP_VENDOR_VERSION == 000000) && !defined(LDAP_DEVEL)
+#define LDAP_DEVEL
+#endif
 #if defined(LDAP_DEVEL) && !defined(LDAP_TEST)
 #define LDAP_TEST
 #endif
 #if defined(LDAP_TEST) && !defined(LDAP_DEBUG)
 #define LDAP_DEBUG
 #endif
+#endif
 
 #ifdef HAVE_EBCDIC 
 /* ASCII/EBCDIC converting replacements for stdio funcs
index d37f062563faf341bfad81cc860ab37b15149e00..48d0c2bd038eab08b781e3ba325467d835eb8b29 100644 (file)
@@ -312,6 +312,8 @@ 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_db41,[-ldb41])
+OL_BERKELEY_DB_TRY(ol_cv_db_db_41,[-ldb-41])
 OL_BERKELEY_DB_TRY(ol_cv_db_db4,[-ldb4])
 OL_BERKELEY_DB_TRY(ol_cv_db_db_4,[-ldb-4])
 OL_BERKELEY_DB_TRY(ol_cv_db_db,[-ldb])
@@ -433,9 +435,12 @@ AC_DEFUN([OL_BDB_COMPAT],
 #ifndef DB_VERSION_MAJOR
 #      define DB_VERSION_MAJOR 1
 #endif
+#ifndef DB_VERSION_MINOR
+#      define DB_VERSION_MINOR 0
+#endif
 
 /* require 4.0 or later */
-#if DB_VERSION_MAJOR >= 4 
+#if (DB_VERSION_MAJOR >= 4) && (DB_VERSION_MINOR >= 1)
        __db_version_compat
 #endif
        ], [ol_cv_bdb_compat=yes], [ol_cv_bdb_compat=no])])
index cda849bacb388ef0a8c9342fb0a1c07292e76f3c..83c83d12fd9a1c293a7cd6f8f6561761ac6f630a 100644 (file)
@@ -3,13 +3,15 @@
 ## Makefile for LDAP tools
 ##
 SRCS   = ldapsearch.c ldapmodify.c ldapdelete.c ldapmodrdn.c \
-               ldappasswd.c ldapwhoami.c ldapcompare.c
+               ldappasswd.c ldapwhoami.c ldapcompare.c common.c
 OBJS   = ldapsearch.o ldapmodify.o ldapdelete.o ldapmodrdn.o \
-               ldappasswd.o ldapwhoami.o ldapcompare.o
+               ldappasswd.o ldapwhoami.o ldapcompare.o common.o
 
 LDAP_INCDIR= ../../include       
 LDAP_LIBDIR= ../../libraries
 
+MKVOPTS = -s
+
 XLIBS =  $(LDAP_LIBLDIF_A) $(LDAP_L)
 XXLIBS = $(SECURITY_LIBS) $(LDIF_LIBS) $(LUTIL_LIBS)
 
@@ -21,58 +23,58 @@ PROGRAMS = ldapsearch ldapmodify ldapdelete ldapmodrdn ldapadd \
 
 
 ldapsearch:    ldsversion.o
-       $(LTLINK) -o $@ ldapsearch.o ldsversion.o $(LIBS)
+       $(LTLINK) -o $@ ldapsearch.o common.o ldsversion.o $(LIBS)
 
 ldapmodify:    ldmversion.o
-       $(LTLINK) -o $@ ldapmodify.o ldmversion.o $(LIBS)
+       $(LTLINK) -o $@ ldapmodify.o common.o ldmversion.o $(LIBS)
 
 ldapdelete:    lddversion.o
-       $(LTLINK) -o $@ ldapdelete.o lddversion.o $(LIBS)
+       $(LTLINK) -o $@ ldapdelete.o common.o lddversion.o $(LIBS)
 
 ldapmodrdn:    ldrversion.o
-       $(LTLINK) -o $@ ldapmodrdn.o ldrversion.o $(LIBS)
+       $(LTLINK) -o $@ ldapmodrdn.o common.o ldrversion.o $(LIBS)
 
 ldappasswd:    ldpversion.o
-       $(LTLINK) -o $@ ldappasswd.o ldpversion.o $(LIBS)
+       $(LTLINK) -o $@ ldappasswd.o common.o ldpversion.o $(LIBS)
 
 ldapwhoami:    ldwversion.o
-       $(LTLINK) -o $@ ldapwhoami.o ldwversion.o $(LIBS)
+       $(LTLINK) -o $@ ldapwhoami.o common.o ldwversion.o $(LIBS)
 
 ldapcompare: ldcversion.o
-       $(LTLINK) -o $@ ldapcompare.o ldcversion.o $(LIBS)
+       $(LTLINK) -o $@ ldapcompare.o common.o ldcversion.o $(LIBS)
 
 ldapadd:       ldapmodify
        @-$(RM) $@$(EXEEXT)
        $(LN_H) ldapmodify$(EXEEXT) ldapadd$(EXEEXT)
 
 
-ldsversion.c: ldapsearch.o $(XLIBS)
+ldsversion.c: ldapsearch.o common.o $(XLIBS)
        @-$(RM) $@
-       $(MKVERSION) ldapsearch > $@
+       $(MKVERSION) $(MKVOPTS) ldapsearch > $@
 
-ldmversion.c: ldapmodify.o $(XLIBS)
+ldmversion.c: ldapmodify.o common.o $(XLIBS)
        @-$(RM) $@
-       $(MKVERSION) ldapmodify > $@
+       $(MKVERSION) $(MKVOPTS) ldapmodify > $@
 
-lddversion.c: ldapdelete.o $(XLIBS)
+lddversion.c: ldapdelete.o common.o $(XLIBS)
        @-$(RM) $@
-       $(MKVERSION) ldapdelete > $@
+       $(MKVERSION) $(MKVOPTS) ldapdelete > $@
 
-ldpversion.c: ldappasswd.o $(XLIBS)
+ldpversion.c: ldappasswd.o common.o $(XLIBS)
        @-$(RM) $@
-       $(MKVERSION) ldappasswd > $@
+       $(MKVERSION) $(MKVOPTS) ldappasswd > $@
 
-ldrversion.c: ldapmodrdn.o $(XLIBS)
+ldrversion.c: ldapmodrdn.o common.o $(XLIBS)
        @-$(RM) $@
-       $(MKVERSION) ldapmodrdn > $@
+       $(MKVERSION) $(MKVOPTS) ldapmodrdn > $@
 
-ldwversion.c: ldapwhoami.o $(XLIBS)
+ldwversion.c: ldapwhoami.o common.o $(XLIBS)
        @-$(RM) $@
-       $(MKVERSION) ldapwhoami > $@
+       $(MKVERSION) $(MKVOPTS) ldapwhoami > $@
 
-ldcversion.c: ldapcompare.o $(XLIBS)
+ldcversion.c: ldapcompare.o common.o $(XLIBS)
        @-$(RM) $@
-       $(MKVERSION) ldapcompare > $@
+       $(MKVERSION) $(MKVOPTS) ldapcompare > $@
 
 
 install-local: FORCE
diff --git a/clients/tools/common.c b/clients/tools/common.c
new file mode 100644 (file)
index 0000000..b477850
--- /dev/null
@@ -0,0 +1,707 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/* common.c - common routines for the ldap client tools */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/stdlib.h>
+#include <ac/signal.h>
+#include <ac/string.h>
+#include <ac/unistd.h>
+#include <ac/errno.h>
+
+#include <ldap.h>
+
+#include "lutil_ldap.h"
+
+#include "common.h"
+
+
+int   authmethod = -1;
+char *binddn = NULL;
+int   contoper = 0;
+int   debug = 0;
+char *infile = NULL;
+char *ldapuri = NULL;
+char *ldaphost = NULL;
+int   ldapport = 0;
+#ifdef HAVE_CYRUS_SASL
+unsigned sasl_flags = LDAP_SASL_AUTOMATIC;
+char   *sasl_realm = NULL;
+char   *sasl_authc_id = NULL;
+char   *sasl_authz_id = NULL;
+char   *sasl_mech = NULL;
+char   *sasl_secprops = NULL;
+#endif
+int   use_tls = 0;
+
+char *authzid = NULL;
+int   manageDSAit = 0;
+int   noop = 0;
+
+int   not = 0;
+int   want_bindpw = 0;
+struct berval passwd = { 0, NULL };
+char *pw_file = NULL;
+int   referrals = 0;
+int   protocol = -1;
+int   verbose = 0;
+int   version = 0;
+
+/* Set in main() */
+char *prog = NULL;
+
+void
+tool_common_usage( void )
+{
+       static const char *const descriptions[] = {
+"  -c         continuous operation mode (do not stop on errors)\n",
+"  -C         chase referrals\n",
+"  -d level   set LDAP debugging level to `level'\n",
+"  -D binddn  bind DN\n",
+"  -e [!]<ctrl>[=<ctrlparam>] general controls (! indicates criticality)\n"
+"             [!]authzid=<authzid> (\"dn:<dn>\" or \"u:<user>\")\n"
+"             [!]manageDSAit       (alternate form, see -M)\n"
+"             [!]noop\n",
+"  -f file    read operations from `file'\n",
+"  -h host    LDAP server\n",
+"  -H URI     LDAP Uniform Resource Indentifier(s)\n",
+"  -I         use SASL Interactive mode\n",
+"  -k         use Kerberos authentication\n",
+"  -K         like -k, but do only step 1 of the Kerberos bind\n",
+"  -M         enable Manage DSA IT control (-MM to make critical)\n",
+"  -n         show what would be done but don't actually do it\n",
+"  -O props   SASL security properties\n",
+"  -p port    port on LDAP server\n",
+"  -P version procotol version (default: 3)\n",
+"  -Q         use SASL Quiet mode\n",
+"  -R realm   SASL realm\n",
+"  -U authcid SASL authentication identity\n",
+"  -v         run in verbose mode (diagnostics to standard output)\n",
+"  -V         print version info (-VV only)\n",
+"  -w passwd  bind passwd (for simple authentication)\n",
+"  -W         prompt for bind passwd\n",
+"  -x         Simple authentication\n",
+"  -X authzid SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n",
+"  -y file    Read passwd from file\n",
+"  -Y mech    SASL mechanism\n",
+"  -Z         Start TLS request (-ZZ to require successful response)\n",
+NULL
+       };
+       const char *const *cpp;
+
+       fputs( "Common options:\n", stderr );
+       for( cpp = descriptions; *cpp != NULL; cpp++ ) {
+               if( strchr( options, (*cpp)[3] ) ) {
+                       fputs( *cpp, stderr );
+               }
+       }
+}
+
+
+void
+tool_args( int argc, char **argv )
+{
+       int i;
+    while (( i = getopt( argc, argv, options )) != EOF )
+       {
+               int crit;
+               char *control, *cvalue;
+               switch( i ) {
+               case 'c':       /* continuous operation mode */
+                       contoper = 1;
+                       break;
+               case 'C':
+                       referrals = 1;
+                       break;
+               case 'd':
+                       debug |= atoi( optarg );
+                       break;
+               case 'D':       /* bind DN */
+                       if( binddn != NULL ) {
+                               fprintf( stderr, "%s: -D previously specified\n", prog );
+                               exit( EXIT_FAILURE );
+                       }
+                       binddn = ber_strdup( optarg );
+                       break;
+               case 'e': /* general controls */
+                       /* should be extended to support comma separated list of
+                        *      [!]key[=value] parameters, e.g.  -e !foo,bar=567
+                        */
+
+                       crit = 0;
+                       cvalue = NULL;
+                       if( optarg[0] == '!' ) {
+                               crit = 1;
+                               optarg++;
+                       }
+
+                       control = ber_strdup( optarg );
+                       if ( (cvalue = strchr( control, '=' )) != NULL ) {
+                               *cvalue++ = '\0';
+                       }
+
+                       if ( strcasecmp( control, "authzid" ) == 0 ) {
+                               if( authzid != NULL ) {
+                                       fprintf( stderr, "authzid control previously specified\n");
+                                       exit( EXIT_FAILURE );
+                               }
+                               if( cvalue == NULL ) {
+                                       fprintf( stderr, "authzid: control value expected\n" );
+                                       usage();
+                               }
+                               if( !crit ) {
+                                       fprintf( stderr, "authzid: must be marked critical\n" );
+                                       usage();
+                               }
+
+                               assert( authzid == NULL );
+                               authzid = cvalue;
+
+                       } else if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
+                               if( manageDSAit ) {
+                                       fprintf( stderr,
+                                                "manageDSAit control previously specified\n");
+                                       exit( EXIT_FAILURE );
+                               }
+                               if( cvalue != NULL ) {
+                                       fprintf( stderr,
+                                                "manageDSAit: no control value expected\n" );
+                                       usage();
+                               }
+
+                               manageDSAit = 1 + crit;
+
+                       } else if ( strcasecmp( control, "noop" ) == 0 ) {
+                               if( noop ) {
+                                       fprintf( stderr, "noop control previously specified\n");
+                                       exit( EXIT_FAILURE );
+                               }
+                               if( cvalue != NULL ) {
+                                       fprintf( stderr, "noop: no control value expected\n" );
+                                       usage();
+                               }
+
+                               noop = 1 + crit;
+
+                       } else {
+                               fprintf( stderr, "Invalid general control name: %s\n",
+                                        control );
+                               usage();
+                       }
+                       break;
+               case 'f':       /* read from file */
+                       if( infile != NULL ) {
+                               fprintf( stderr, "%s: -f previously specified\n", prog );
+                               exit( EXIT_FAILURE );
+                       }
+                       infile = ber_strdup( optarg );
+                       break;
+               case 'h':       /* ldap host */
+                       if( ldaphost != NULL ) {
+                               fprintf( stderr, "%s: -h previously specified\n", prog );
+                               exit( EXIT_FAILURE );
+                       }
+                       ldaphost = ber_strdup( optarg );
+                       break;
+               case 'H':       /* ldap URI */
+                       if( ldapuri != NULL ) {
+                               fprintf( stderr, "%s: -H previously specified\n", prog );
+                               exit( EXIT_FAILURE );
+                       }
+                       ldapuri = ber_strdup( optarg );
+                       break;
+               case 'I':
+#ifdef HAVE_CYRUS_SASL
+                       if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                               fprintf( stderr, "%s: incompatible previous "
+                                                "authentication choice\n",
+                                                prog );
+                               exit( EXIT_FAILURE );
+                       }
+                       authmethod = LDAP_AUTH_SASL;
+                       sasl_flags = LDAP_SASL_INTERACTIVE;
+                       break;
+#else
+                       fprintf( stderr, "%s: was not compiled with SASL support\n",
+                                        prog );
+                       exit( EXIT_FAILURE );
+#endif
+               case 'k':       /* kerberos bind */
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
+                       if( authmethod != -1 ) {
+                               fprintf( stderr, "%s: -k incompatible with previous "
+                                                "authentication choice\n", prog );
+                               exit( EXIT_FAILURE );
+                       }
+                       authmethod = LDAP_AUTH_KRBV4;
+#else
+                       fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
+                       exit( EXIT_FAILURE );
+#endif
+                       break;
+               case 'K':       /* kerberos bind, part one only */
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
+                       if( authmethod != -1 ) {
+                               fprintf( stderr, "%s: incompatible with previous "
+                                                "authentication choice\n", prog );
+                               exit( EXIT_FAILURE );
+                       }
+                       authmethod = LDAP_AUTH_KRBV41;
+#else
+                       fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
+                       exit( EXIT_FAILURE );
+#endif
+                       break;
+               case 'M':
+                       /* enable Manage DSA IT */
+                       manageDSAit = 1;
+                       break;
+               case 'n':       /* print operations, don't actually do them */
+                       not = 1;
+                       break;
+               case 'O':
+#ifdef HAVE_CYRUS_SASL
+                       if( sasl_secprops != NULL ) {
+                               fprintf( stderr, "%s: -O previously specified\n", prog );
+                               exit( EXIT_FAILURE );
+                       }
+                       if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                               fprintf( stderr, "%s: incompatible previous "
+                                                "authentication choice\n", prog );
+                               exit( EXIT_FAILURE );
+                       }
+                       authmethod = LDAP_AUTH_SASL;
+                       sasl_secprops = ber_strdup( optarg );
+#else
+                       fprintf( stderr, "%s: not compiled with SASL support\n",
+                                        prog );
+                       exit( EXIT_FAILURE );
+#endif
+                       break;
+               case 'p':
+                       if( ldapport ) {
+                               fprintf( stderr, "%s: -p previously specified\n", prog );
+                               exit( EXIT_FAILURE );
+                       }
+                       ldapport = atoi( optarg );
+                       break;
+               case 'P':
+                       switch( atoi(optarg) ) {
+                       case 2:
+                               if( protocol == LDAP_VERSION3 ) {
+                                       fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
+                                                        prog, protocol );
+                                       exit( EXIT_FAILURE );
+                               }
+                               protocol = LDAP_VERSION2;
+                               break;
+                       case 3:
+                               if( protocol == LDAP_VERSION2 ) {
+                                       fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
+                                                        prog, protocol );
+                                       exit( EXIT_FAILURE );
+                               }
+                               protocol = LDAP_VERSION3;
+                               break;
+                       default:
+                               fprintf( stderr, "%s: protocol version should be 2 or 3\n",
+                                                prog );
+                               usage();
+                       }
+                       break;
+               case 'Q':
+#ifdef HAVE_CYRUS_SASL
+                       if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                               fprintf( stderr, "%s: incompatible previous "
+                                                "authentication choice\n",
+                                                prog );
+                               exit( EXIT_FAILURE );
+                       }
+                       authmethod = LDAP_AUTH_SASL;
+                       sasl_flags = LDAP_SASL_QUIET;
+                       break;
+#else
+                       fprintf( stderr, "%s: not compiled with SASL support\n",
+                                        prog );
+                       exit( EXIT_FAILURE );
+#endif
+               case 'R':
+#ifdef HAVE_CYRUS_SASL
+                       if( sasl_realm != NULL ) {
+                               fprintf( stderr, "%s: -R previously specified\n", prog );
+                               exit( EXIT_FAILURE );
+                       }
+                       if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                               fprintf( stderr, "%s: incompatible previous "
+                                                "authentication choice\n",
+                                                prog );
+                               exit( EXIT_FAILURE );
+                       }
+                       authmethod = LDAP_AUTH_SASL;
+                       sasl_realm = ber_strdup( optarg );
+#else
+                       fprintf( stderr, "%s: not compiled with SASL support\n",
+                                        prog );
+                       exit( EXIT_FAILURE );
+#endif
+                       break;
+               case 'U':
+#ifdef HAVE_CYRUS_SASL
+                       if( sasl_authc_id != NULL ) {
+                               fprintf( stderr, "%s: -U previously specified\n", prog );
+                               exit( EXIT_FAILURE );
+                       }
+                       if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                               fprintf( stderr, "%s: incompatible previous "
+                                                "authentication choice\n",
+                                                prog );
+                               exit( EXIT_FAILURE );
+                       }
+                       authmethod = LDAP_AUTH_SASL;
+                       sasl_authc_id = ber_strdup( optarg );
+#else
+                       fprintf( stderr, "%s: not compiled with SASL support\n",
+                                        prog );
+                       exit( EXIT_FAILURE );
+#endif
+                       break;
+               case 'v':       /* verbose mode */
+                       verbose = 1;
+                       break;
+               case 'V':       /* version */
+                       version++;
+                       break;
+               case 'w':       /* password */
+                       passwd.bv_val = ber_strdup( optarg );
+                       {
+                               char* p;
+
+                               for( p = optarg; *p != '\0'; p++ ) {
+                                       *p = '\0';
+                               }
+                       }
+                       passwd.bv_len = strlen( passwd.bv_val );
+                       break;
+               case 'W':
+                       want_bindpw = 1;
+                       break;
+               case 'y':
+                       pw_file = optarg;
+                       break;
+               case 'Y':
+#ifdef HAVE_CYRUS_SASL
+                       if( sasl_mech != NULL ) {
+                               fprintf( stderr, "%s: -Y previously specified\n", prog );
+                               exit( EXIT_FAILURE );
+                       }
+                       if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                               fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
+                               exit( EXIT_FAILURE );
+                       }
+                       authmethod = LDAP_AUTH_SASL;
+                       sasl_mech = ber_strdup( optarg );
+#else
+                       fprintf( stderr, "%s: not compiled with SASL support\n",
+                                        prog );
+                       exit( EXIT_FAILURE );
+#endif
+                       break;
+               case 'x':
+                       if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
+                               fprintf( stderr, "%s: incompatible with previous "
+                                                "authentication choice\n", prog );
+                               exit( EXIT_FAILURE );
+                       }
+                       authmethod = LDAP_AUTH_SIMPLE;
+                       break;
+               case 'X':
+#ifdef HAVE_CYRUS_SASL
+                       if( sasl_authz_id != NULL ) {
+                               fprintf( stderr, "%s: -X previously specified\n", prog );
+                               exit( EXIT_FAILURE );
+                       }
+                       if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                               fprintf( stderr, "%s: -X incompatible with "
+                                                "authentication choice\n", prog );
+                               exit( EXIT_FAILURE );
+                       }
+                       authmethod = LDAP_AUTH_SASL;
+                       sasl_authz_id = ber_strdup( optarg );
+#else
+                       fprintf( stderr, "%s: not compiled with SASL support\n", prog );
+                       exit( EXIT_FAILURE );
+#endif
+                       break;
+               case 'Z':
+#ifdef HAVE_TLS
+                       use_tls = 1;
+#else
+                       fprintf( stderr, "%s: not compiled with TLS support\n", prog );
+                       exit( EXIT_FAILURE );
+#endif
+                       break;
+               default:
+                       if( handle_private_option( i ) )
+                               break;
+                       fprintf( stderr, "%s: unrecognized option -%c\n",
+                                        prog, optopt );
+                       usage();
+               }
+    }
+
+       if (version) {
+               fprintf( stderr, "%s: %s", prog, __Version );
+               if (version > 1) exit( EXIT_SUCCESS );
+       }
+
+       if (protocol == -1)
+               protocol = LDAP_VERSION3;
+
+       if (authmethod == -1 && protocol > LDAP_VERSION2) {
+#ifdef HAVE_CYRUS_SASL
+               authmethod = LDAP_AUTH_SASL;
+#else
+               authmethod = LDAP_AUTH_SIMPLE;
+#endif
+       }
+
+       if( ldapuri != NULL ) {
+               if( ldaphost != NULL ) {
+                       fprintf( stderr, "%s: -H incompatible with -h\n", prog );
+                       exit( EXIT_FAILURE );
+               }
+               if( ldapport ) {
+                       fprintf( stderr, "%s: -H incompatible with -p\n", prog );
+                       exit( EXIT_FAILURE );
+               }
+       }
+       if( protocol == LDAP_VERSION2 ) {
+               if( authzid || manageDSAit || noop ) {
+                       fprintf( stderr, "%s: -e/-M incompatible with LDAPv2\n", prog );
+                       exit( EXIT_FAILURE );
+               }
+#ifdef HAVE_TLS
+               if( use_tls ) {
+                       fprintf( stderr, "%s: -Z incompatible with LDAPv2\n", prog );
+                       exit( EXIT_FAILURE );
+               }
+#endif
+#ifdef HAVE_CYRUS_SASL
+               if( authmethod == LDAP_AUTH_SASL ) {
+                       fprintf( stderr, "%s: -[IOQRUXY] incompatible with LDAPv2\n",
+                                prog );
+                       exit( EXIT_FAILURE );
+               }
+#endif
+       } else {
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
+               if ( authmethod = LDAP_AUTH_KRBV4 || authmethod == LDAP_AUTH_KRBV41 ) {
+                       fprintf( stderr, "%s: -k/-K incompatible with LDAPv%d\n",
+                                prog, protocol );
+                       exit( EXIT_FAILURE );
+               }
+#endif
+       }
+}
+
+
+LDAP *
+tool_conn_setup( int not, void (*private_setup)( LDAP * ) )
+{
+       LDAP *ld = NULL;
+
+       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 );
+               }
+               if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug )
+                   != LDAP_OPT_SUCCESS ) {
+                       fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
+               }
+       }
+
+#ifdef SIGPIPE
+       (void) SIGNAL( SIGPIPE, SIG_IGN );
+#endif
+
+       if ( !not ) {
+               /* connect to server */
+               if( ( ldaphost != NULL || ldapport ) && ( ldapuri == NULL ) ) {
+                       if ( verbose ) {
+                               fprintf( stderr, "ldap_init( %s, %d )\n",
+                                        ldaphost != NULL ? ldaphost : "<DEFAULT>",
+                                        ldapport );
+                       }
+
+                       ld = ldap_init( ldaphost, ldapport );
+                       if( ld == NULL ) {
+                               char buf[20 + sizeof(": ldap_init")];
+                               sprintf( buf, "%.20s: ldap_init", prog );
+                               perror( buf );
+                               exit( EXIT_FAILURE );
+                       }
+
+               } else {
+                       int rc;
+                       if ( verbose ) {
+                               fprintf( stderr, "ldap_initialize( %s )\n",
+                                        ldapuri != NULL ? ldapuri : "<DEFAULT>" );
+                       }
+                       rc = ldap_initialize( &ld, ldapuri );
+                       if( rc != LDAP_SUCCESS ) {
+                               fprintf( stderr, "Could not create LDAP session handle (%d): %s\n",
+                                        rc, ldap_err2string(rc) );
+                               exit( EXIT_FAILURE );
+                       }
+               }
+
+               if( private_setup )
+                       private_setup( ld );
+
+               /* referrals */
+               if( ldap_set_option( ld, LDAP_OPT_REFERRALS,
+                                        referrals ? LDAP_OPT_ON : LDAP_OPT_OFF )
+                       != LDAP_OPT_SUCCESS )
+               {
+                       fprintf( stderr, "Could not set LDAP_OPT_REFERRALS %s\n",
+                                referrals ? "on" : "off" );
+                       exit( EXIT_FAILURE );
+               }
+
+               if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &protocol )
+                   != LDAP_OPT_SUCCESS )
+               {
+                       fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
+                                protocol );
+                       exit( EXIT_FAILURE );
+               }
+
+               if ( use_tls &&
+                    ( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS )) {
+                       ldap_perror( ld, "ldap_start_tls" );
+                       if ( use_tls > 1 ) {
+                               exit( EXIT_FAILURE );
+                       }
+               }
+       }
+
+       return ld;
+}
+
+
+void
+tool_bind( LDAP *ld )
+{
+       if ( authmethod == LDAP_AUTH_SASL ) {
+#ifdef HAVE_CYRUS_SASL
+               void *defaults;
+               int rc;
+
+               if( sasl_secprops != NULL ) {
+                       rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
+                               (void *) sasl_secprops );
+
+                       if( rc != LDAP_OPT_SUCCESS ) {
+                               fprintf( stderr,
+                                       "Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
+                                       sasl_secprops );
+                               exit( EXIT_FAILURE );
+                       }
+               }
+
+               defaults = lutil_sasl_defaults( ld,
+                       sasl_mech,
+                       sasl_realm,
+                       sasl_authc_id,
+                       passwd.bv_val,
+                       sasl_authz_id );
+
+               rc = ldap_sasl_interactive_bind_s( ld, binddn,
+                       sasl_mech, NULL, NULL,
+                       sasl_flags, lutil_sasl_interact, defaults );
+
+               if( rc != LDAP_SUCCESS ) {
+                       ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
+                       exit( EXIT_FAILURE );
+               }
+#else
+               fprintf( stderr, "%s: not compiled with SASL support\n",
+                       prog );
+               exit( EXIT_FAILURE );
+#endif
+       } else {
+               if ( ldap_bind_s( ld, binddn, passwd.bv_val, authmethod )
+                    != LDAP_SUCCESS ) {
+                       ldap_perror( ld, "ldap_bind" );
+                       exit( EXIT_FAILURE );
+               }
+       }
+}
+
+
+/* Set server controls.  Add controls extra_c[0..count-1], if set. */
+void
+tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count )
+{
+       int i = 0, j, crit = 0, err;
+       LDAPControl c[3], **ctrls;
+
+       ctrls = (LDAPControl **)malloc( sizeof(c) + (count + 1)*sizeof(LDAPControl *) );
+       if ( ctrls == NULL ) {
+               fprintf( stderr, "No memory\n" );
+               exit( EXIT_FAILURE );
+       }
+
+       if ( authzid ) {
+               c[i].ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
+               c[i].ldctl_value.bv_val = authzid;
+               c[i].ldctl_value.bv_len = strlen( authzid );
+               c[i].ldctl_iscritical = 1;
+               ctrls[i] = &c[i];
+               i++;
+       }
+
+       if ( manageDSAit ) {
+               c[i].ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
+               c[i].ldctl_value.bv_val = NULL;
+               c[i].ldctl_value.bv_len = 0;
+               c[i].ldctl_iscritical = manageDSAit > 1;
+               ctrls[i] = &c[i];
+               i++;
+       }
+
+       if ( noop ) {
+               c[i].ldctl_oid = LDAP_CONTROL_NOOP;
+               c[i].ldctl_value.bv_val = NULL;
+               c[i].ldctl_value.bv_len = 0;
+               c[i].ldctl_iscritical = noop > 1;
+               ctrls[i] = &c[i];
+               i++;
+       }
+       
+       while ( count-- )
+               ctrls[i++] = extra_c++;
+       ctrls[i] = NULL;
+
+       err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
+
+       if ( err != LDAP_OPT_SUCCESS ) {
+               for ( j = 0; j < i; j++ )
+                       if ( ctrls[j]->ldctl_iscritical )
+                               crit = 1;
+               fprintf( stderr, "Could not set %scontrols\n",
+                                crit ? "critical " : "" );
+       }
+
+       free( ctrls );
+       if ( crit ) {
+               exit( EXIT_FAILURE );
+       }
+}
diff --git a/clients/tools/common.h b/clients/tools/common.h
new file mode 100644 (file)
index 0000000..2791dbe
--- /dev/null
@@ -0,0 +1,63 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 2002-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/* common.h - common definitions for the ldap client tools */
+
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+LDAP_BEGIN_DECL
+
+/* Defined and set in common.c */
+extern int   authmethod;
+extern char *binddn;
+extern int   contoper;
+extern int   debug;
+extern char *infile;
+extern char *ldapuri;
+extern char *ldaphost;
+extern int   ldapport;
+#ifdef HAVE_CYRUS_SASL
+extern unsigned sasl_flags;
+extern char    *sasl_realm;
+extern char    *sasl_authc_id;
+extern char    *sasl_authz_id;
+extern char    *sasl_mech;
+extern char    *sasl_secprops;
+#endif
+extern int   use_tls;
+
+extern char *authzid;
+extern int   manageDSAit;
+extern int   noop;
+
+extern int   not;
+extern int   want_bindpw;
+extern struct berval passwd;
+extern char *pw_file;
+extern int   referrals;
+extern int   protocol;
+extern int   verbose;
+extern int   version;
+
+/* Defined in common.c, set in main() */
+extern char *prog;
+extern const char __Version[];
+
+/* Defined in main program */
+extern const char options[];
+void usage LDAP_P(( void )) LDAP_GCCATTR((noreturn));
+int handle_private_option LDAP_P(( int i ));
+
+/* Defined in common.c */
+void tool_common_usage LDAP_P(( void ));
+void tool_args LDAP_P(( int, char ** ));
+LDAP *tool_conn_setup LDAP_P(( int dont, void (*private_setup)( LDAP * ) ));
+void tool_bind LDAP_P(( LDAP * ));
+void tool_server_controls LDAP_P(( LDAP *, LDAPControl *, int ));
+
+LDAP_END_DECL
+
+#endif /* _COMMON_H_ */
index 33185753244d6ac655f9fdac71bfe7932b9a84cd..18ea6efee7efa535efd181589a801297dab23932 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* $OpenLDAP$ */
@@ -11,7 +11,6 @@
 #include <ac/stdlib.h>
 
 #include <ac/ctype.h>
-#include <ac/signal.h>
 #include <ac/string.h>
 #include <ac/unistd.h>
 #include <ac/errno.h>
 #include "lutil_ldap.h"
 #include "ldap_defaults.h"
 
-static void
-usage( const char *s )
+#include "common.h"
+
+
+static int quiet = 0;
+
+
+void
+usage( void )
 {
        fprintf( stderr,
 "usage: %s [options] DN <attr:value|attr::b64value>\n"
@@ -45,36 +50,10 @@ usage( const char *s )
 "  value\tassertion value\n"
 "  b64value\tbase64 encoding of assertion value\n"
 
-"Common options:\n"
-"  -d level   set LDAP debugging level to `level'\n"
-"  -D binddn  bind DN\n"
-"  -e [!]<ctrl>[=<ctrlparam>] general controls (! indicates criticality)\n"
-"             [!]manageDSAit   (alternate form, see -M)\n"
-"             [!]noop\n"
-"  -h host    LDAP server\n"
-"  -H URI     LDAP Uniform Resource Indentifier(s)\n"
-"  -I         use SASL Interactive mode\n"
-"  -k         use Kerberos authentication\n"
-"  -K         like -k, but do only step 1 of the Kerberos bind\n"
-"  -M         enable Manage DSA IT control (-MM to make critical)\n"
-"  -n         show what would be done but don't actually compare\n"
-"  -O props   SASL security properties\n"
-"  -p port    port on LDAP server\n"
-"  -P version procotol version (default: 3)\n"
+"Compare options:\n"
 "  -z         Quiet mode, don't print anything, use return values\n"
-"  -Q         use SASL Quiet mode\n"
-"  -R realm   SASL realm\n"
-"  -U authcid SASL authentication identity\n"
-"  -v         run in verbose mode (diagnostics to standard output)\n"
-"  -w passwd  bind passwd (for simple authentication)\n"
-"  -W         prompt for bind passwd\n"
-"  -x         Simple authentication\n"
-"  -X authzid SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
-"  -y file    Read passwd from file\n"
-"  -Y mech    SASL mechanism\n"
-"  -Z         Start TLS request (-ZZ to require successful response)\n"
-, s );
-
+                , prog );
+       tool_common_usage();
        exit( EXIT_FAILURE );
 }
 
@@ -87,54 +66,22 @@ static int docompare LDAP_P((
        LDAPControl **sctrls,
        LDAPControl **cctrls));
 
-static char *prog = NULL;
-static char    *binddn = NULL;
-static struct berval passwd = { 0, NULL };
-static char    *ldaphost = NULL;
-static char *ldapuri = NULL;
-static int     ldapport = 0;
-#ifdef HAVE_CYRUS_SASL
-static unsigned sasl_flags = LDAP_SASL_AUTOMATIC;
-static char    *sasl_realm = NULL;
-static char    *sasl_authc_id = NULL;
-static char    *sasl_authz_id = NULL;
-static char    *sasl_mech = NULL;
-static char    *sasl_secprops = NULL;
-#endif
-static int     use_tls = 0;
-static int     verbose, not;
+
+const char options[] = "z"
+       "Cd:D:e:h:H:IkKMnO:p:P:QR:U:vVw:WxX:y:Y:Z";
 
 int
-main( int argc, char **argv )
+handle_private_option( int i )
 {
-       char    *compdn = NULL, *attrs = NULL;
-       char    *sep;
-       int             rc, i, crit, manageDSAit, noop, quiet;
-       int             referrals, debug;
-       int             authmethod, version, want_bindpw;
-       LDAP    *ld = NULL;
-       struct berval bvalue = { 0, NULL };
-       char    *pw_file = NULL;
-       char    *control, *cvalue;
-
-       debug = verbose = not = referrals = noop =
-               manageDSAit = want_bindpw = quiet = 0;
-
-       version = -1;
-
-       authmethod = -1;
-
-       prog = lutil_progname( "ldapcompare", argc, argv );
-
-       while (( i = getopt( argc, argv,
-               "Cd:D:e:h:H:IkKMnO:p:P:qQR:U:vw:WxX:y:Y:zZ")) != EOF )
-       {
-               switch( i ) {
+       switch ( i ) {
+#if 0
+               char    *control, *cvalue;
+               int             crit;
        case 'E': /* compare controls */
-               if( version == LDAP_VERSION2 ) {
+               if( protocol == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -E incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
+                               prog, protocol );
+                       exit( EXIT_FAILURE );
                }
 
                /* should be extended to support comma separated list of
@@ -153,419 +100,35 @@ main( int argc, char **argv )
                        *cvalue++ = '\0';
                }
                fprintf( stderr, "Invalid compare control name: %s\n", control );
-               usage(prog);
-               return EXIT_FAILURE;
-
-               /* Common Options */
-               case 'C':
-                       referrals++;
-                       break;
-               case 'd':
-                       debug |= atoi( optarg );
-                       break;
-               case 'D':       /* bind DN */
-                       if( binddn != NULL ) {
-                               fprintf( stderr, "%s: -D previously specified\n", prog );
-                               return EXIT_FAILURE;
-                       }
-                       binddn = strdup( optarg );
-                       break;
-
-       case 'e': /* general controls */
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -e incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
+               usage();
+#endif
 
-               /* should be extended to support comma separated list of
-                *      [!]key[=value] parameters, e.g.  -e !foo,bar=567
-                */
+       case 'z':
+               quiet = 1;
+               break;
 
-               crit = 0;
-               cvalue = NULL;
-               if( optarg[0] == '!' ) {
-                       crit = 1;
-                       optarg++;
-               }
+       default:
+               return 0;
+       }
+       return 1;
+}
 
-               control = strdup( optarg );
-               if ( (cvalue = strchr( control, '=' )) != NULL ) {
-                       *cvalue++ = '\0';
-               }
 
-               if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
-                       if( cvalue != NULL ) {
-                               fprintf( stderr, "manageDSAit: no control value expected\n" );
-                               usage(prog);
-                               return EXIT_FAILURE;
-                       }
-
-                       manageDSAit = 1 + crit;
-                       free( control );
-                       break;
-                       
-               } else if ( strcasecmp( control, "noop" ) == 0 ) {
-                       if( cvalue != NULL ) {
-                               fprintf( stderr, "noop: no control value expected\n" );
-                               usage(prog);
-                               return EXIT_FAILURE;
-                       }
-
-                       noop = 1 + crit;
-                       free( control );
-                       break;
+int
+main( int argc, char **argv )
+{
+       char    *compdn = NULL, *attrs = NULL;
+       char    *sep;
+       int             rc;
+       LDAP    *ld = NULL;
+       struct berval bvalue = { 0, NULL };
 
-               } else {
-                       fprintf( stderr, "Invalid general control name: %s\n", control );
-                       usage(prog);
-                       return EXIT_FAILURE;
-               }
-               case 'h':       /* ldap host */
-                       if( ldapuri != NULL ) {
-                               fprintf( stderr, "%s: -h incompatible with -H\n", prog );
-                               return EXIT_FAILURE;
-                       }
-                       if( ldaphost != NULL ) {
-                               fprintf( stderr, "%s: -h previously specified\n", prog );
-                               return EXIT_FAILURE;
-                       }
-                       ldaphost = strdup( optarg );
-                       break;
-               case 'H':       /* ldap URI */
-                       if( ldaphost != NULL ) {
-                               fprintf( stderr, "%s: -H incompatible with -h\n", prog );
-                               return EXIT_FAILURE;
-                       }
-                       if( ldapport ) {
-                               fprintf( stderr, "%s: -H incompatible with -p\n", prog );
-                               return EXIT_FAILURE;
-                       }
-                       if( ldapuri != NULL ) {
-                               fprintf( stderr, "%s: -H previously specified\n", prog );
-                               return EXIT_FAILURE;
-                       }
-                       ldapuri = strdup( optarg );
-                       break;
-               case 'I':
-#ifdef HAVE_CYRUS_SASL
-                       if( version == LDAP_VERSION2 ) {
-                               fprintf( stderr, "%s: -I incompatible with version %d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                               fprintf( stderr, "%s: incompatible previous "
-                                       "authentication choice\n",
-                                       prog );
-                               return EXIT_FAILURE;
-                       }
-                       authmethod = LDAP_AUTH_SASL;
-                       version = LDAP_VERSION3;
-                       sasl_flags = LDAP_SASL_INTERACTIVE;
-                       break;
-#else
-                       fprintf( stderr, "%s: was not compiled with SASL support\n",
-                               prog );
-                       return( EXIT_FAILURE );
-#endif
-               case 'k':       /* kerberos bind */
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-                       if( version > LDAP_VERSION2 ) {
-                               fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-
-                       if( authmethod != -1 ) {
-                               fprintf( stderr, "%s: -k incompatible with previous "
-                                       "authentication choice\n", prog );
-                               return EXIT_FAILURE;
-                       }
-
-                       authmethod = LDAP_AUTH_KRBV4;
-#else
-                       fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
-                       return EXIT_FAILURE;
-#endif
-                       break;
-               case 'K':       /* kerberos bind, part one only */
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-                       if( version > LDAP_VERSION2 ) {
-                               fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       if( authmethod != -1 ) {
-                               fprintf( stderr, "%s: incompatible with previous "
-                                       "authentication choice\n", prog );
-                               return EXIT_FAILURE;
-                       }
-
-                       authmethod = LDAP_AUTH_KRBV41;
-#else
-                       fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
-                       return( EXIT_FAILURE );
-#endif
-                       break;
-               case 'M':
-                       /* enable Manage DSA IT */
-                       if( version == LDAP_VERSION2 ) {
-                               fprintf( stderr, "%s: -M incompatible with LDAPv%d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       manageDSAit++;
-                       version = LDAP_VERSION3;
-                       break;
-               case 'n':       /* print compares, don't actually do them */
-                       ++not;
-                       break;
-               case 'O':
-#ifdef HAVE_CYRUS_SASL
-                       if( sasl_secprops != NULL ) {
-                               fprintf( stderr, "%s: -O previously specified\n", prog );
-                               return EXIT_FAILURE;
-                       }
-                       if( version == LDAP_VERSION2 ) {
-                               fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                               fprintf( stderr, "%s: incompatible previous "
-                                       "authentication choice\n", prog );
-                               return EXIT_FAILURE;
-                       }
-                       authmethod = LDAP_AUTH_SASL;
-                       version = LDAP_VERSION3;
-                       sasl_secprops = strdup( optarg );
-#else
-                       fprintf( stderr, "%s: not compiled with SASL support\n",
-                               prog );
-                       return( EXIT_FAILURE );
-#endif
-                       break;
-               case 'p':
-                       if( ldapport ) {
-                               fprintf( stderr, "%s: -p previously specified\n", prog );
-                               return EXIT_FAILURE;
-                       }
-                       ldapport = atoi( optarg );
-                       break;
-               case 'P':
-                       switch( atoi(optarg) ) {
-                       case 2:
-                               if( version == LDAP_VERSION3 ) {
-                                       fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
-                                               prog, version );
-                                       return EXIT_FAILURE;
-                               }
-                               version = LDAP_VERSION2;
-                               break;
-                       case 3:
-                               if( version == LDAP_VERSION2 ) {
-                                       fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
-                                               prog, version );
-                                       return EXIT_FAILURE;
-                               }
-                               version = LDAP_VERSION3;
-                               break;
-                       default:
-                               fprintf( stderr, "%s: protocol version should be 2 or 3\n",
-                                       prog );
-                               usage( prog );
-                               return( EXIT_FAILURE );
-                       } break;
-               case 'Q':
-#ifdef HAVE_CYRUS_SASL
-                       if( version == LDAP_VERSION2 ) {
-                               fprintf( stderr, "%s: -Q incompatible with version %d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                               fprintf( stderr, "%s: incompatible previous "
-                                       "authentication choice\n",
-                                       prog );
-                               return EXIT_FAILURE;
-                       }
-                       authmethod = LDAP_AUTH_SASL;
-                       version = LDAP_VERSION3;
-                       sasl_flags = LDAP_SASL_QUIET;
-                       break;
-#else
-                       fprintf( stderr, "%s: not compiled with SASL support\n",
-                               prog );
-                       return( EXIT_FAILURE );
-#endif
-               case 'R':
-#ifdef HAVE_CYRUS_SASL
-                       if( sasl_realm != NULL ) {
-                               fprintf( stderr, "%s: -R previously specified\n", prog );
-                               return EXIT_FAILURE;
-                       }
-                       if( version == LDAP_VERSION2 ) {
-                               fprintf( stderr, "%s: -R incompatible with version %d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                               fprintf( stderr, "%s: incompatible previous "
-                                       "authentication choice\n",
-                                       prog );
-                               return EXIT_FAILURE;
-                       }
-                       authmethod = LDAP_AUTH_SASL;
-                       version = LDAP_VERSION3;
-                       sasl_realm = strdup( optarg );
-#else
-                       fprintf( stderr, "%s: not compiled with SASL support\n",
-                               prog );
-                       return( EXIT_FAILURE );
-#endif
-                       break;
-       case 'U':
-#ifdef HAVE_CYRUS_SASL
-                       if( sasl_authc_id != NULL ) {
-                               fprintf( stderr, "%s: -U previously specified\n", prog );
-                               return EXIT_FAILURE;
-                       }
-                       if( version == LDAP_VERSION2 ) {
-                               fprintf( stderr, "%s: -U incompatible with version %d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                               fprintf( stderr, "%s: incompatible previous "
-                                       "authentication choice\n",
-                                       prog );
-                               return EXIT_FAILURE;
-                       }
-                       authmethod = LDAP_AUTH_SASL;
-                       version = LDAP_VERSION3;
-                       sasl_authc_id = strdup( optarg );
-#else
-                       fprintf( stderr, "%s: not compiled with SASL support\n",
-                               prog );
-                       return( EXIT_FAILURE );
-#endif
-                       break;
-               case 'v':       /* verbose mode */
-                       verbose++;
-                       break;
-               case 'w':       /* password */
-                       passwd.bv_val = strdup( optarg );
-                       {
-                               char* p;
-
-                               for( p = optarg; *p != '\0'; p++ ) {
-                                       *p = '\0';
-                               }
-                       }
-                       passwd.bv_len = strlen( passwd.bv_val );
-                       break;
-               case 'W':
-                       want_bindpw++;
-                       break;
-               case 'y':
-                       pw_file = optarg;
-                       break;
-               case 'Y':
-#ifdef HAVE_CYRUS_SASL
-                       if( sasl_mech != NULL ) {
-                               fprintf( stderr, "%s: -Y previously specified\n", prog );
-                               return EXIT_FAILURE;
-                       }
-                       if( version == LDAP_VERSION2 ) {
-                               fprintf( stderr, "%s: -Y incompatible with version %d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                               fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
-                               return EXIT_FAILURE;
-                       }
-                       authmethod = LDAP_AUTH_SASL;
-                       version = LDAP_VERSION3;
-                       sasl_mech = strdup( optarg );
-#else
-                       fprintf( stderr, "%s: not compiled with SASL support\n",
-                               prog );
-                       return( EXIT_FAILURE );
-#endif
-                       break;
-               case 'x':
-                       if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
-                               fprintf( stderr, "%s: incompatible with previous "
-                                       "authentication choice\n", prog );
-                               return EXIT_FAILURE;
-                       }
-                       authmethod = LDAP_AUTH_SIMPLE;
-                       break;
-               case 'X':
-#ifdef HAVE_CYRUS_SASL
-                       if( sasl_authz_id != NULL ) {
-                               fprintf( stderr, "%s: -X previously specified\n", prog );
-                               return EXIT_FAILURE;
-                       }
-                       if( version == LDAP_VERSION2 ) {
-                               fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                               fprintf( stderr, "%s: -X incompatible with "
-                                       "authentication choice\n", prog );
-                               return EXIT_FAILURE;
-                       }
-                       authmethod = LDAP_AUTH_SASL;
-                       version = LDAP_VERSION3;
-                       sasl_authz_id = strdup( optarg );
-#else
-                       fprintf( stderr, "%s: not compiled with SASL support\n",
-                               prog );
-                       return( EXIT_FAILURE );
-#endif
-                       break;
-               case 'z':
-                       quiet++;
-                       break;
-               case 'Z':
-#ifdef HAVE_TLS
-                       if( version == LDAP_VERSION2 ) {
-                               fprintf( stderr, "%s: -Z incompatible with version %d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       version = LDAP_VERSION3;
-                       use_tls++;
-#else
-                       fprintf( stderr, "%s: not compiled with TLS support\n",
-                               prog );
-                       return( EXIT_FAILURE );
-#endif
-                       break;
-               default:
-                       fprintf( stderr, "%s: unrecognized option -%c\n",
-                               prog, optopt );
-                       usage( argv[0] );
-               }
-       }
+       prog = lutil_progname( "ldapcompare", argc, argv );
 
-       if (version == -1) {
-               version = LDAP_VERSION3;
-       }
-       if (authmethod == -1 && version > LDAP_VERSION2) {
-#ifdef HAVE_CYRUS_SASL
-               authmethod = LDAP_AUTH_SASL;
-#else
-               authmethod = LDAP_AUTH_SIMPLE;
-#endif
-       }
+       tool_args( argc, argv );
 
        if ( argc - optind != 2 ) {
-               usage( argv[ 0 ] );
+               usage();
        }
 
        compdn = argv[optind++];
@@ -576,7 +139,7 @@ main( int argc, char **argv )
         */
        sep = strchr(attrs, ':');
        if (!sep) {
-               usage( argv[ 0 ] );
+               usage();
        }
 
        *sep++='\0';
@@ -590,88 +153,16 @@ main( int argc, char **argv )
                bvalue.bv_len = lutil_b64_pton( &sep[1],
                        bvalue.bv_val, strlen( &sep[1] ));
 
-               if (bvalue.bv_len == -1) {
+               if (bvalue.bv_len == (ber_len_t)-1) {
                        fprintf(stderr, "base64 decode error\n");
                        exit(-1);
                }
        }
 
-       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 );
-               }
-               if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug )
-                       != LDAP_OPT_SUCCESS )
-               {
-                       fprintf( stderr,
-                               "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
-               }
+       if ( debug )
                ldif_debug = debug;
-       }
-
-#ifdef SIGPIPE
-       (void) SIGNAL( SIGPIPE, SIG_IGN );
-#endif
-
-       if( ( ldaphost != NULL || ldapport ) && ( ldapuri == NULL ) ) {
-               if ( verbose ) {
-                       fprintf( stderr, "ldap_init( %s, %d )\n",
-                               ldaphost != NULL ? ldaphost : "<DEFAULT>",
-                               ldapport );
-               }
-
-               ld = ldap_init( ldaphost, ldapport );
-               if( ld == NULL ) {
-                       perror("ldapcompare: ldap_init");
-                       return EXIT_FAILURE;
-               }
-
-       } else {
-               if ( verbose ) {
-                       fprintf( stderr, "ldap_initialize( %s )\n",
-                               ldapuri != NULL ? ldapuri : "<DEFAULT>" );
-               }
-
-               rc = ldap_initialize( &ld, ldapuri );
-               if( rc != LDAP_SUCCESS ) {
-                       fprintf( stderr,
-                               "Could not create LDAP session handle (%d): %s\n",
-                               rc, ldap_err2string(rc) );
-                       return EXIT_FAILURE;
-               }
-       }
-
 
-       /* referrals */
-       if (ldap_set_option( ld, LDAP_OPT_REFERRALS,
-               referrals ? LDAP_OPT_ON : LDAP_OPT_OFF ) != LDAP_OPT_SUCCESS )
-       {
-               fprintf( stderr, "Could not set LDAP_OPT_REFERRALS %s\n",
-                       referrals ? "on" : "off" );
-               return EXIT_FAILURE;
-       }
-
-       if (version == -1 ) {
-               version = LDAP_VERSION3;
-       }
-
-       if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version )
-               != LDAP_OPT_SUCCESS )
-       {
-               fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
-                       version );
-               return EXIT_FAILURE;
-       }
-
-       if ( use_tls && ( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS )) {
-               ldap_perror( ld, "ldap_start_tls" );
-               if ( use_tls > 1 ) {
-                       return EXIT_FAILURE;
-               }
-       }
+       ld = tool_conn_setup( 0, 0 );
 
        if ( pw_file || want_bindpw ) {
                if ( pw_file ) {
@@ -683,85 +174,10 @@ main( int argc, char **argv )
                }
        }
 
-       if ( authmethod == LDAP_AUTH_SASL ) {
-#ifdef HAVE_CYRUS_SASL
-               void *defaults;
-
-               if( sasl_secprops != NULL ) {
-                       rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
-                               (void *) sasl_secprops );
-
-                       if( rc != LDAP_OPT_SUCCESS ) {
-                               fprintf( stderr,
-                                       "Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
-                                       sasl_secprops );
-                               return EXIT_FAILURE;
-                       }
-               }
-
-               defaults = lutil_sasl_defaults( ld,
-                       sasl_mech,
-                       sasl_realm,
-                       sasl_authc_id,
-                       passwd.bv_val,
-                       sasl_authz_id );
-
-               rc = ldap_sasl_interactive_bind_s( ld, binddn,
-                       sasl_mech, NULL, NULL,
-                       sasl_flags, lutil_sasl_interact, defaults );
+       tool_bind( ld );
 
-               if( rc != LDAP_SUCCESS ) {
-                       ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
-                       return EXIT_FAILURE;
-               }
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog, 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 || noop ) {
-               int err, i = 0;
-               LDAPControl c1, c2;
-               LDAPControl *ctrls[3];
-
-               if ( manageDSAit ) {
-                       ctrls[i++] = &c1;
-                       ctrls[i] = NULL;
-                       c1.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
-                       c1.ldctl_value.bv_val = NULL;
-                       c1.ldctl_value.bv_len = 0;
-                       c1.ldctl_iscritical = manageDSAit > 1;
-               }
-
-               if ( noop ) {
-                       ctrls[i++] = &c2;
-                       ctrls[i] = NULL;
-
-                       c2.ldctl_oid = LDAP_CONTROL_NOOP;
-                       c2.ldctl_value.bv_val = NULL;
-                       c2.ldctl_value.bv_len = 0;
-                       c2.ldctl_iscritical = noop > 1;
-               }
-       
-               err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
-
-               if( err != LDAP_OPT_SUCCESS ) {
-                       fprintf( stderr, "Could not set %scontrols\n",
-                               (c1.ldctl_iscritical || c2.ldctl_iscritical)
-                               ? "critical " : "" );
-                       if ( c1.ldctl_iscritical && c2.ldctl_iscritical ) {
-                               return EXIT_FAILURE;
-                       }
-               }
-       }
+       if ( authzid || manageDSAit || noop )
+               tool_server_controls( ld, NULL, 0 );
 
        if ( verbose ) {
                fprintf( stderr, "DN:%s, attr:%s, value:%s\n",
diff --git a/clients/tools/ldapcompare.dsp b/clients/tools/ldapcompare.dsp
new file mode 100644 (file)
index 0000000..ab31707
--- /dev/null
@@ -0,0 +1,153 @@
+# Microsoft Developer Studio Project File - Name="ldapcompare" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=ldapcompare - 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 "ldapcompare.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 "ldapcompare.mak" CFG="ldapcompare - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "ldapcompare - Win32 Single Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ldapcompare - Win32 Single Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ldapcompare - Win32 Debug" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "ldapcompare - 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)" == "ldapcompare - 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\ldapcompare"
+# 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)" == "ldapcompare - 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\ldapcompare"
+# 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/ldapcompare.exe" /libpath:"..\..\SRelease"
+
+!ELSEIF  "$(CFG)" == "ldapcompare - 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\ldapcompare"
+# 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)" == "ldapcompare - 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\ldapcompare"
+# 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/ldapcompare.exe" /libpath:"..\..\libraries\Release"
+# ADD LINK32 sasl.lib libsasl.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /out:"Release/ldapcompare.exe" /libpath:"..\..\Release"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "ldapcompare - Win32 Single Debug"
+# Name "ldapcompare - Win32 Single Release"
+# Name "ldapcompare - Win32 Debug"
+# Name "ldapcompare - Win32 Release"
+# Begin Source File
+
+SOURCE=.\common.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ldapcompare.c
+# End Source File
+# End Target
+# End Project
index e13cfd3773970c2920d1d319ed32ff60a83137e1..d3638404a58bacfb3552ee9f3ef538e9c1759000 100644 (file)
@@ -1,7 +1,7 @@
 /* ldapdelete.c - simple program to delete an entry using LDAP */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -11,8 +11,6 @@
 
 #include <ac/stdlib.h>
 #include <ac/ctype.h>
-
-#include <ac/signal.h>
 #include <ac/string.h>
 #include <ac/unistd.h>
 
 #include "lutil_ldap.h"
 #include "ldap_defaults.h"
 
-static char    *prog;
-static char    *binddn = NULL;
-static struct berval passwd = { 0, NULL };
-static char *ldapuri = NULL;
-static char    *ldaphost = NULL;
-static int     ldapport = 0;
+#include "common.h"
+
+
 static int     prune = 0;
-#ifdef HAVE_CYRUS_SASL
-static unsigned sasl_flags = LDAP_SASL_AUTOMATIC;
-static char    *sasl_mech = NULL;
-static char *sasl_realm = NULL;
-static char    *sasl_authc_id = NULL;
-static char    *sasl_authz_id = NULL;
-static char    *sasl_secprops = NULL;
-#endif
-static int     use_tls = 0;
-static int     not, verbose, contoper;
-static LDAP    *ld = NULL;
+
 
 static int dodelete LDAP_P((
     LDAP *ld,
@@ -48,8 +33,8 @@ static int deletechildren LDAP_P((
        LDAP *ld,
        const char *dn ));
 
-static void
-usage( const char *s )
+void
+usage( void )
 {
        fprintf( stderr,
 "Delete entries from an LDAP server\n\n"
@@ -58,73 +43,27 @@ usage( const char *s )
 "          or from the file specified with \"-f file\".\n"
 "Delete Options:\n"
 "  -r         delete recursively\n"
-
-"Common options:\n"
-"  -d level   set LDAP debugging level to `level'\n"
-"  -D binddn  bind DN\n"
-"  -e [!]<ctrl>[=<ctrlparam>] general controls (! indicates criticality)\n"
-"             [!]manageDSAit   (alternate form, see -M)\n"
-"             [!]noop\n"
-"  -f file    read operations from `file'\n"
-"  -h host    LDAP server\n"
-"  -H URI     LDAP Uniform Resource Indentifier(s)\n"
-"  -I         use SASL Interactive mode\n"
-"  -k         use Kerberos authentication\n"
-"  -K         like -k, but do only step 1 of the Kerberos bind\n"
-"  -M         enable Manage DSA IT control (-MM to make critical)\n"
-"  -n         show what would be done but don't actually do it\n"
-"  -O props   SASL security properties\n"
-"  -p port    port on LDAP server\n"
-"  -P version procotol version (default: 3)\n"
-"  -Q         use SASL Quiet mode\n"
-"  -R realm   SASL realm\n"
-"  -U authcid SASL authentication identity\n"
-"  -v         run in verbose mode (diagnostics to standard output)\n"
-"  -w passwd  bind passwd (for simple authentication)\n"
-"  -W         prompt for bind passwd\n"
-"  -x         Simple authentication\n"
-"  -X authzid SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
-"  -y file    Read passwd from file\n"
-"  -Y mech    SASL mechanism\n"
-"  -Z         Start TLS request (-ZZ to require successful response)\n"
-,              s );
-
+                        , prog );
+       tool_common_usage();
        exit( EXIT_FAILURE );
 }
 
 
+const char options[] = "r"
+       "cCd:D:e:f:h:H:IkKMnO:p:P:QR:U:vVw:WxX:y:Y:Z";
+
 int
-main( int argc, char **argv )
+handle_private_option( int i )
 {
-       char            buf[ 4096 ];
-       FILE            *fp;
-       int             i, rc, retval, authmethod, referrals, want_bindpw;
-       int             version, debug, manageDSAit, noop, crit;
-       char    *pw_file;
-       char    *control, *cvalue;
-
-    not = verbose = contoper = want_bindpw = debug
-               = manageDSAit = noop = referrals = 0;
-    fp = NULL;
-    authmethod = -1;
-       version = -1;
-       pw_file = NULL;
-
-    prog = lutil_progname( "ldapdelete", argc, argv );
-
-    while (( i = getopt( argc, argv, "cf:r"
-               "Cd:D:e:h:H:IkKMnO:p:P:QR:U:vw:WxX:y:Y:Z" )) != EOF )
-       {
-       switch( i ) {
-       /* Delete Specific Options */
-       case 'c':       /* continuous operation mode */
-           ++contoper;
-           break;
+       switch ( i ) {
+#if 0
+               int crit;
+               char *control, *cvalue;
        case 'E': /* delete controls */
-               if( version == LDAP_VERSION2 ) {
+               if( protocol == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -E incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
+                               prog, protocol );
+                       exit( EXIT_FAILURE );
                }
 
                /* should be extended to support comma separated list of
@@ -143,502 +82,55 @@ main( int argc, char **argv )
                        *cvalue++ = '\0';
                }
                fprintf( stderr, "Invalid delete control name: %s\n", control );
-               usage(prog);
-               return EXIT_FAILURE;
-       case 'f':       /* read DNs from a file */
-               if( fp != NULL ) {
-                       fprintf( stderr, "%s: -f previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           if (( fp = fopen( optarg, "r" )) == NULL ) {
-               perror( optarg );
-               exit( EXIT_FAILURE );
-           }
-           break;
+               usage();
+#endif
+
        case 'r':
                prune = 1;
                break;
 
-       /* Common Options */
-       case 'C':
-               referrals++;
-               break;
-       case 'd':
-           debug |= atoi( optarg );
-           break;
-       case 'D':       /* bind DN */
-               if( binddn != NULL ) {
-                       fprintf( stderr, "%s: -D previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           binddn = strdup( optarg );
-           break;
-       case 'e': /* general controls */
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -e incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-
-               /* should be extended to support comma separated list of
-                *      [!]key[=value] parameters, e.g.  -e !foo,bar=567
-                */
-
-               crit = 0;
-               cvalue = NULL;
-               if( optarg[0] == '!' ) {
-                       crit = 1;
-                       optarg++;
-               }
-
-               control = strdup( optarg );
-               if ( (cvalue = strchr( control, '=' )) != NULL ) {
-                       *cvalue++ = '\0';
-               }
-
-               if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
-                       if( cvalue != NULL ) {
-                               fprintf( stderr, "manageDSAit: no control value expected\n" );
-                               usage(prog);
-                               return EXIT_FAILURE;
-                       }
+       default:
+               return 0;
+       }
+       return 1;
+}
 
-                       manageDSAit = 1 + crit;
-                       free( control );
-                       break;
-                       
-               } else if ( strcasecmp( control, "noop" ) == 0 ) {
-                       if( cvalue != NULL ) {
-                               fprintf( stderr, "noop: no control value expected\n" );
-                               usage(prog);
-                               return EXIT_FAILURE;
-                       }
 
-                       noop = 1 + crit;
-                       free( control );
-                       break;
+static void
+private_conn_setup( LDAP *ld )
+{
+       /* this seems prudent for searches below */
+       int deref = LDAP_DEREF_NEVER;
+       ldap_set_option( ld, LDAP_OPT_DEREF, &deref );
+}
 
-               } else {
-                       fprintf( stderr, "Invalid general control name: %s\n", control );
-                       usage(prog);
-                       return EXIT_FAILURE;
-               }
-       case 'h':       /* ldap host */
-               if( ldapuri != NULL ) {
-                       fprintf( stderr, "%s: -h incompatible with -H\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( ldaphost != NULL ) {
-                       fprintf( stderr, "%s: -h previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           ldaphost = strdup( optarg );
-           break;
-       case 'H':       /* ldap URI */
-               if( ldaphost != NULL ) {
-                       fprintf( stderr, "%s: -H incompatible with -h\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( ldapport ) {
-                       fprintf( stderr, "%s: -H incompatible with -p\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( ldapuri != NULL ) {
-                       fprintf( stderr, "%s: -H previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           ldapuri = strdup( optarg );
-           break;
-       case 'I':
-#ifdef HAVE_CYRUS_SASL
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -I incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_flags = LDAP_SASL_INTERACTIVE;
-               break;
-#else
-               fprintf( stderr, "%s: was not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-       case 'k':       /* kerberos bind */
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-               if( version > LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
 
-               if( authmethod != -1 ) {
-                       fprintf( stderr, "%s: -k incompatible with previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-                       
-               authmethod = LDAP_AUTH_KRBV4;
-#else
-               fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
-               return EXIT_FAILURE;
-#endif
-           break;
-       case 'K':       /* kerberos bind, part one only */
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-               if( version > LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 ) {
-                       fprintf( stderr, "%s: incompatible with previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
+int
+main( int argc, char **argv )
+{
+       char            buf[ 4096 ];
+       FILE            *fp;
+       LDAP            *ld;
+       int             rc, retval;
 
-               authmethod = LDAP_AUTH_KRBV41;
-#else
-               fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
-               return( EXIT_FAILURE );
-#endif
-           break;
-       case 'M':
-               /* enable Manage DSA IT */
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -M incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               manageDSAit++;
-               version = LDAP_VERSION3;
-               break;
-       case 'n':       /* print deletes, don't actually do them */
-           ++not;
-           break;
-       case 'O':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_secprops != NULL ) {
-                       fprintf( stderr, "%s: -O previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_secprops = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'p':
-               if( ldapport ) {
-                       fprintf( stderr, "%s: -p previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           ldapport = atoi( optarg );
-           break;
-       case 'P':
-               switch( atoi(optarg) ) {
-               case 2:
-                       if( version == LDAP_VERSION3 ) {
-                               fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       version = LDAP_VERSION2;
-                       break;
-               case 3:
-                       if( version == LDAP_VERSION2 ) {
-                               fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       version = LDAP_VERSION3;
-                       break;
-               default:
-                       fprintf( stderr, "%s: protocol version should be 2 or 3\n",
-                               prog );
-                       usage( prog );
-                       return( EXIT_FAILURE );
-               } break;
-       case 'Q':
-#ifdef HAVE_CYRUS_SASL
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -Q incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_flags = LDAP_SASL_QUIET;
-               break;
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-       case 'R':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_realm != NULL ) {
-                       fprintf( stderr, "%s: -R previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -R incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_realm = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'U':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_authc_id != NULL ) {
-                       fprintf( stderr, "%s: -U previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -U incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_authc_id = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'v':       /* verbose mode */
-           verbose++;
-           break;
-       case 'w':       /* password */
-           passwd.bv_val = strdup( optarg );
-               {
-                       char* p;
+    fp = NULL;
 
-                       for( p = optarg; *p != '\0'; p++ ) {
-                               *p = '\0';
-                       }
-               }
-               passwd.bv_len = strlen( passwd.bv_val );
-           break;
-       case 'W':
-               want_bindpw++;
-               break;
-       case 'y':
-               pw_file = optarg;
-               break;
-       case 'Y':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_mech != NULL ) {
-                       fprintf( stderr, "%s: -Y previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -Y incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_mech = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'x':
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
-                       fprintf( stderr, "%s: incompatible with previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SIMPLE;
-               break;
-       case 'X':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_authz_id != NULL ) {
-                       fprintf( stderr, "%s: -X previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: -X incompatible with "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_authz_id = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'Z':
-#ifdef HAVE_TLS
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -Z incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               version = LDAP_VERSION3;
-               use_tls++;
-#else
-               fprintf( stderr, "%s: not compiled with TLS support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       default:
-               fprintf( stderr, "%s: unrecognized option -%c\n",
-                       prog, optopt );
-               usage( prog );
-               return( EXIT_FAILURE );
-       }
-    }
+    prog = lutil_progname( "ldapdelete", argc, argv );
 
-       if (version == -1) {
-               version = LDAP_VERSION3;
-       }
-       if (authmethod == -1 && version > LDAP_VERSION2) {
-#ifdef HAVE_CYRUS_SASL
-               authmethod = LDAP_AUTH_SASL;
-#else
-               authmethod = LDAP_AUTH_SIMPLE;
-#endif
-       }
+       tool_args( argc, argv );
 
-    if ( fp == NULL ) {
+       if ( infile != NULL ) {
+               if (( fp = fopen( infile, "r" )) == NULL ) {
+                       perror( optarg );
+                       exit( EXIT_FAILURE );
+           }
+       } else {
        if ( optind >= argc ) {
            fp = stdin;
        }
     }
 
-       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 );
-               }
-               if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
-                       fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
-               }
-       }
-
-#ifdef SIGPIPE
-       (void) SIGNAL( SIGPIPE, SIG_IGN );
-#endif
-
-       if( ( ldaphost != NULL || ldapport ) && ( ldapuri == NULL ) ) {
-               if ( verbose ) {
-                       fprintf( stderr, "ldap_init( %s, %d )\n",
-                               ldaphost != NULL ? ldaphost : "<DEFAULT>",
-                               ldapport );
-               }
-
-               ld = ldap_init( ldaphost, ldapport );
-               if( ld == NULL ) {
-                       perror("ldapdelete: ldap_init");
-                       return EXIT_FAILURE;
-               }
-
-       } else {
-               if ( verbose ) {
-                       fprintf( stderr, "ldap_initialize( %s )\n",
-                               ldapuri != NULL ? ldapuri : "<DEFAULT>" );
-               }
-
-               rc = ldap_initialize( &ld, ldapuri );
-               if( rc != LDAP_SUCCESS ) {
-                       fprintf( stderr, "Could not create LDAP session handle (%d): %s\n",
-                               rc, ldap_err2string(rc) );
-                       return EXIT_FAILURE;
-               }
-       }
-
-       {
-               /* this seems prudent for searches below */
-               int deref = LDAP_DEREF_NEVER;
-               ldap_set_option( ld, LDAP_OPT_DEREF, &deref );
-       }
-
-       /* chase referrals */
-       if( ldap_set_option( ld, LDAP_OPT_REFERRALS,
-               referrals ? LDAP_OPT_ON : LDAP_OPT_OFF ) != LDAP_OPT_SUCCESS )
-       {
-               fprintf( stderr, "Could not set LDAP_OPT_REFERRALS %s\n",
-                       referrals ? "on" : "off" );
-               return EXIT_FAILURE;
-       }
-
-       if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version )
-               != LDAP_OPT_SUCCESS )
-       {
-               fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
-                       version );
-               return EXIT_FAILURE;
-       }
-
-       if ( use_tls && ( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS )) {
-               ldap_perror( ld, "ldap_start_tls" );
-               if ( use_tls > 1 ) {
-                       return EXIT_FAILURE;
-               }
-       }
+       ld = tool_conn_setup( 0, &private_conn_setup );
 
        if ( pw_file || want_bindpw ) {
                if ( pw_file ) {
@@ -650,86 +142,10 @@ main( int argc, char **argv )
                }
        }
 
-       if ( authmethod == LDAP_AUTH_SASL ) {
-#ifdef HAVE_CYRUS_SASL
-               void *defaults;
+       tool_bind( ld );
 
-               if( sasl_secprops != NULL ) {
-                       rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
-                               (void *) sasl_secprops );
-                       
-                       if( rc != LDAP_OPT_SUCCESS ) {
-                               fprintf( stderr,
-                                       "Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
-                                       sasl_secprops );
-                               return( EXIT_FAILURE );
-                       }
-               }
-               
-               defaults = lutil_sasl_defaults( ld,
-                       sasl_mech,
-                       sasl_realm,
-                       sasl_authc_id,
-                       passwd.bv_val,
-                       sasl_authz_id );
-
-               rc = ldap_sasl_interactive_bind_s( ld, binddn,
-                       sasl_mech, NULL, NULL,
-                       sasl_flags, lutil_sasl_interact, defaults );
-
-               if( rc != LDAP_SUCCESS ) {
-                       ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
-                       return( EXIT_FAILURE );
-               }
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               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 || noop ) {
-               int err, i = 0;
-               LDAPControl c1, c2;
-               LDAPControl *ctrls[3];
-
-               if ( manageDSAit ) {
-                       ctrls[i++] = &c1;
-                       ctrls[i] = NULL;
-                       c1.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
-                       c1.ldctl_value.bv_val = NULL;
-                       c1.ldctl_value.bv_len = 0;
-                       c1.ldctl_iscritical = manageDSAit > 1;
-               }
-
-               if ( noop ) {
-                       ctrls[i++] = &c2;
-                       ctrls[i] = NULL;
-
-                       c2.ldctl_oid = LDAP_CONTROL_NOOP;
-                       c2.ldctl_value.bv_val = NULL;
-                       c2.ldctl_value.bv_len = 0;
-                       c2.ldctl_iscritical = noop > 1;
-               }
-       
-               err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
-
-               if( err != LDAP_OPT_SUCCESS ) {
-                       fprintf( stderr, "Could not set %scontrols\n",
-                               (c1.ldctl_iscritical || c2.ldctl_iscritical)
-                               ? "critical " : "" );
-                       if ( c1.ldctl_iscritical && c2.ldctl_iscritical ) {
-                               return EXIT_FAILURE;
-                       }
-               }
-       }
+       if ( authzid || manageDSAit || noop )
+               tool_server_controls( ld, NULL, 0 );
 
        retval = rc = 0;
 
diff --git a/clients/tools/ldapdelete.dsp b/clients/tools/ldapdelete.dsp
new file mode 100644 (file)
index 0000000..c136d67
--- /dev/null
@@ -0,0 +1,153 @@
+# 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=.\common.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ldapdelete.c
+# End Source File
+# End Target
+# End Project
index b53d7351a11bcc1ab9da8c2b4e2d61cdb79510d5..d4f452b95ed450a920f492b333ed114954dcfa3e 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* ldapmodify.c - generic program to modify or add entries using LDAP */
@@ -10,9 +10,7 @@
 #include <stdio.h>
 
 #include <ac/stdlib.h>
-
 #include <ac/ctype.h>
-#include <ac/signal.h>
 #include <ac/string.h>
 #include <ac/unistd.h>
 
 #include "ldap_log.h"
 #include "ldap_pvt.h"
 
-static char    *prog;
-static char    *binddn = NULL;
-static struct berval passwd = { 0, NULL };
-static char *ldapuri = NULL;
-static char    *ldaphost = NULL;
-static int     ldapport = 0;
-#ifdef HAVE_CYRUS_SASL
-static unsigned sasl_flags = LDAP_SASL_AUTOMATIC;
-static char *sasl_realm = NULL;
-static char    *sasl_authc_id = NULL;
-static char    *sasl_authz_id = NULL;
-static char    *sasl_mech = NULL;
-static char    *sasl_secprops = NULL;
-#endif
-static int     use_tls = 0;
-static int     ldapadd, not, verbose, contoper, force;
+#include "common.h"
+
+
+static int     ldapadd, force = 0;
+static char *rejfile = NULL;
 static LDAP    *ld = NULL;
 
 #define LDAPMOD_MAXLINE                4096
@@ -77,7 +64,6 @@ static LDAP   *ld = NULL;
 #define T_NEWSUPSTR            "newsuperior"
 
 
-static void usage LDAP_P(( const char *prog )) LDAP_GCCATTR((noreturn));
 static int process_ldif_rec LDAP_P(( char *rbuf, int count ));
 static int parse_ldif_control LDAP_P(( char *line, LDAPControl ***pctrls ));
 static void addmodifyop LDAP_P((
@@ -100,8 +86,8 @@ static int dorename LDAP_P((
     LDAPControl **pctrls ));
 static char *read_one_record LDAP_P(( FILE *fp ));
 
-static void
-usage( const char *prog )
+void
+usage( void )
 {
     fprintf( stderr,
 "Add or modify entries from an LDAP server\n\n"
@@ -110,87 +96,29 @@ usage( const char *prog )
 "      specified by \"-f file\".\n"
 "Add or modify options:\n"
 "  -a         add values (default%s)\n"
-"  -c         continuous operation mode (do not stop on errors)\n"
 "  -F         force all changes records to be used\n"
 "  -S file    write skipped modifications to `file'\n"
-
-"Common options:\n"
-"  -d level   set LDAP debugging level to `level'\n"
-"  -D binddn  bind DN\n"
-"  -e [!]<ctrl>[=<ctrlparam>] general controls (! indicates criticality)\n"
-"             [!]manageDSAit   (alternate form, see -M)\n"
-"             [!]noop\n"
-"  -f file    read operations from `file'\n"
-"  -h host    LDAP server\n"
-"  -H URI     LDAP Uniform Resource Indentifier(s)\n"
-"  -I         use SASL Interactive mode\n"
-"  -k         use Kerberos authentication\n"
-"  -K         like -k, but do only step 1 of the Kerberos bind\n"
-"  -M         enable Manage DSA IT control (-MM to make critical)\n"
-"  -n         show what would be done but don't actually update\n"
-"  -O props   SASL security properties\n"
-"  -p port    port on LDAP server\n"
-"  -P version procotol version (default: 3)\n"
-"  -Q         use SASL Quiet mode\n"
-"  -R realm   SASL realm\n"
-"  -U authcid SASL authentication identity\n"
-"  -v         run in verbose mode (diagnostics to standard output)\n"
-"  -w passwd  bind passwd (for simple authentication)\n"
-"  -W         prompt for bind passwd\n"
-"  -x         Simple authentication\n"
-"  -X authzid SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
-"  -y file    Read passwd from file\n"
-"  -Y mech    SASL mechanism\n"
-"  -Z         Start TLS request (-ZZ to require successful response)\n"
-            , prog, (strcmp( prog, "ldapadd" ) ? " is to replace" : "") );
-
+                , prog, (ldapadd ? "" : " is to replace") );
+       tool_common_usage();
     exit( EXIT_FAILURE );
 }
 
 
+const char options[] = "aFrS:"
+       "cCd:D:e:f:h:H:IkKMnO:p:P:QR:U:vVw:WxX:y:Y:Z";
+
 int
-main( int argc, char **argv )
+handle_private_option( int i )
 {
-    char               *infile, *rejfile, *rbuf, *start, *rejbuf = NULL;
-    FILE               *fp, *rejfp;
-       char            *matched_msg = NULL, *error_msg = NULL;
-       int             rc, retval, i, authmethod, version, want_bindpw;
-       int             debug, manageDSAit, noop, referrals;
-       int count, len;
-       char    *pw_file = NULL;
-       char    *control, *cvalue;
-       int             crit;
-
-    prog = lutil_progname( "ldapmodify", argc, argv );
-
-    /* Print usage when no parameters */
-    if( argc < 2 ) usage( prog );
-
-       /* strncmp instead of strcmp since NT binaries carry .exe extension */
-    ldapadd = ( strncmp( prog, "ldapadd", sizeof("ldapadd")-1 ) == 0 );
-
-    infile = NULL;
-    rejfile = NULL;
-    not = verbose = want_bindpw = debug = manageDSAit = noop = referrals = 0;
-    authmethod = -1;
-       version = -1;
-
-    while (( i = getopt( argc, argv, "acrf:E:F"
-               "Cd:D:e:h:H:IkKMnO:p:P:QR:S:U:vw:WxX:y:Y:Z" )) != EOF )
-       {
-       switch( i ) {
-       /* Modify Options */
-       case 'a':       /* add */
-           ldapadd = 1;
-           break;
-       case 'c':       /* continuous operation */
-           contoper = 1;
-           break;
+       switch ( i ) {
+#if 0
+               char    *control, *cvalue;
+               int             crit;
        case 'E': /* modify controls */
-               if( version == LDAP_VERSION2 ) {
+               if( protocol == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -E incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
+                               prog, protocol );
+                       exit( EXIT_FAILURE );
                }
 
                /* should be extended to support comma separated list of
@@ -209,435 +137,56 @@ main( int argc, char **argv )
                        *cvalue++ = '\0';
                }
                fprintf( stderr, "Invalid modify control name: %s\n", control );
-               usage(prog);
-               return EXIT_FAILURE;
-       case 'f':       /* read from file */
-               if( infile != NULL ) {
-                       fprintf( stderr, "%s: -f previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           infile = ber_strdup( optarg );
-           break;
-       case 'F':       /* force all changes records to be used */
-           force = 1;
-           break;
-
-       /* Common Options */
-       case 'C':
-               referrals++;
-               break;
-       case 'd':
-           debug |= atoi( optarg );
-           break;
-       case 'D':       /* bind DN */
-               if( binddn != NULL ) {
-                       fprintf( stderr, "%s: -D previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           binddn = ber_strdup( optarg );
-           break;
-       case 'e': /* general controls */
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -e incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-
-               /* should be extended to support comma separated list of
-                *      [!]key[=value] parameters, e.g.  -e !foo,bar=567
-                */
-
-               crit = 0;
-               cvalue = NULL;
-               if( optarg[0] == '!' ) {
-                       crit = 1;
-                       optarg++;
-               }
-
-               control = ber_strdup( optarg );
-               if ( (cvalue = strchr( control, '=' )) != NULL ) {
-                       *cvalue++ = '\0';
-               }
-
-               if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
-                       if( cvalue != NULL ) {
-                               fprintf( stderr, "manageDSAit: no control value expected\n" );
-                               usage(prog);
-                               return EXIT_FAILURE;
-                       }
-
-                       manageDSAit = 1 + crit;
-                       free( control );
-                       break;
-                       
-               } else if ( strcasecmp( control, "noop" ) == 0 ) {
-                       if( cvalue != NULL ) {
-                               fprintf( stderr, "noop: no control value expected\n" );
-                               usage(prog);
-                               return EXIT_FAILURE;
-                       }
-
-                       noop = 1 + crit;
-                       free( control );
-                       break;
-
-               } else {
-                       fprintf( stderr, "Invalid general control name: %s\n", control );
-                       usage(prog);
-                       return EXIT_FAILURE;
-               }
-       case 'h':       /* ldap host */
-               if( ldapuri != NULL ) {
-                       fprintf( stderr, "%s: -h incompatible with -H\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( ldaphost != NULL ) {
-                       fprintf( stderr, "%s: -h previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           ldaphost = ber_strdup( optarg );
-           break;
-       case 'H':       /* ldap URI */
-               if( ldaphost != NULL ) {
-                       fprintf( stderr, "%s: -H incompatible with -h\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( ldapport ) {
-                       fprintf( stderr, "%s: -H incompatible with -p\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( ldapuri != NULL ) {
-                       fprintf( stderr, "%s: -H previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           ldapuri = ber_strdup( optarg );
-           break;
-       case 'I':
-#ifdef HAVE_CYRUS_SASL
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -I incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_flags = LDAP_SASL_INTERACTIVE;
-               break;
-#else
-               fprintf( stderr, "%s: was not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
+               usage();
 #endif
-       case 'k':       /* kerberos bind */
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-               if( version > LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
 
-               if( authmethod != -1 ) {
-                       fprintf( stderr, "%s: -k incompatible with previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-                       
-               authmethod = LDAP_AUTH_KRBV4;
-#else
-               fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
-               return EXIT_FAILURE;
-#endif
+       case 'a':       /* add */
+           ldapadd = 1;
            break;
-       case 'K':       /* kerberos bind, part one only */
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-               if( version > LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 ) {
-                       fprintf( stderr, "%s: incompatible with previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
 
-               authmethod = LDAP_AUTH_KRBV41;
-#else
-               fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
-               return( EXIT_FAILURE );
-#endif
-           break;
-       case 'M':
-               /* enable Manage DSA IT */
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -M incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               manageDSAit++;
-               version = LDAP_VERSION3;
-               break;
-       case 'n':       /* print deletes, don't actually do them */
-           ++not;
-           break;
-       case 'O':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_secprops != NULL ) {
-                       fprintf( stderr, "%s: -O previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_secprops = ber_strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'p':
-               if( ldapport ) {
-                       fprintf( stderr, "%s: -p previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           ldapport = atoi( optarg );
+       case 'F':       /* force all changes records to be used */
+           force = 1;
            break;
-       case 'P':
-               switch( atoi(optarg) ) {
-               case 2:
-                       if( version == LDAP_VERSION3 ) {
-                               fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       version = LDAP_VERSION2;
-                       break;
-               case 3:
-                       if( version == LDAP_VERSION2 ) {
-                               fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       version = LDAP_VERSION3;
-                       break;
-               default:
-                       fprintf( stderr, "%s: protocol version should be 2 or 3\n",
-                               prog );
-                       usage( prog );
-                       return( EXIT_FAILURE );
-               } break;
-       case 'Q':
-#ifdef HAVE_CYRUS_SASL
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -Q incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_flags = LDAP_SASL_QUIET;
-               break;
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
+
        case 'r':       /* replace (obsolete) */
                break;
 
-       case 'R':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_realm != NULL ) {
-                       fprintf( stderr, "%s: -R previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -R incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_realm = ber_strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
        case 'S':       /* skipped modifications to file */
                if( rejfile != NULL ) {
                        fprintf( stderr, "%s: -S previously specified\n", prog );
-                       return EXIT_FAILURE;
+                       exit( EXIT_FAILURE );
                }
                rejfile = ber_strdup( optarg );
                break;
-       case 'U':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_authc_id != NULL ) {
-                       fprintf( stderr, "%s: -U previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -U incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_authc_id = ber_strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'v':       /* verbose mode */
-           verbose++;
-           break;
-       case 'w':       /* password */
-           passwd.bv_val = ber_strdup( optarg );
-               {
-                       char* p;
 
-                       for( p = optarg; *p != '\0'; p++ ) {
-                               *p = '\0';
-                       }
-               }
-               passwd.bv_len = strlen( passwd.bv_val );
-           break;
-       case 'W':
-               want_bindpw++;
-               break;
-       case 'y':
-               pw_file = optarg;
-               break;
-       case 'Y':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_mech != NULL ) {
-                       fprintf( stderr, "%s: -Y previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -Y incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_mech = ber_strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'x':
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
-                       fprintf( stderr, "%s: incompatible with previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SIMPLE;
-               break;
-       case 'X':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_authz_id != NULL ) {
-                       fprintf( stderr, "%s: -X previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: -X incompatible with "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_authz_id = ber_strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'Z':
-#ifdef HAVE_TLS
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -Z incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               version = LDAP_VERSION3;
-               use_tls++;
-#else
-               fprintf( stderr, "%s: not compiled with TLS support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
        default:
-               fprintf( stderr, "%s: unrecognized option -%c\n",
-                       prog, optopt );
-           usage( prog );
+               return 0;
        }
-    }
+       return 1;
+}
 
-       if (version == -1) {
-               version = LDAP_VERSION3;
-       }
-       if (authmethod == -1 && version > LDAP_VERSION2) {
-#ifdef HAVE_CYRUS_SASL
-               authmethod = LDAP_AUTH_SASL;
-#else
-               authmethod = LDAP_AUTH_SIMPLE;
-#endif
-       }
+
+int
+main( int argc, char **argv )
+{
+    char               *rbuf, *start, *rejbuf = NULL;
+    FILE               *fp, *rejfp;
+       char            *matched_msg, *error_msg;
+       int             rc, retval;
+       int count, len;
+
+    prog = lutil_progname( "ldapmodify", argc, argv );
+
+       /* strncmp instead of strcmp since NT binaries carry .exe extension */
+    ldapadd = ( strncasecmp( prog, "ldapadd", sizeof("ldapadd")-1 ) == 0 );
+
+    /* Print usage when no parameters */
+    if( argc < 2 ) usage();
+
+       tool_args( argc, argv );
 
        if ( argc != optind )
-       usage( prog );
+       usage();
 
     if ( rejfile != NULL ) {
        if (( rejfp = fopen( rejfile, "w" )) == NULL ) {
@@ -657,77 +206,12 @@ main( int argc, char **argv )
        fp = stdin;
     }
 
-       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 );
-               }
-               if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
-                       fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
-               }
+       if ( debug )
                ldif_debug = debug;
-       }
 
-#ifdef SIGPIPE
-       (void) SIGNAL( SIGPIPE, SIG_IGN );
-#endif
+       ld = tool_conn_setup( not, 0 );
 
     if ( !not ) {
-       if( ( ldaphost != NULL || ldapport ) && ( ldapuri == NULL ) ) {
-               if ( verbose ) {
-                       fprintf( stderr, "ldap_init( %s, %d )\n",
-                               ldaphost != NULL ? ldaphost : "<DEFAULT>",
-                               ldapport );
-               }
-
-               ld = ldap_init( ldaphost, ldapport );
-               if( ld == NULL ) {
-                       perror("ldapmodify: ldap_init");
-                       return EXIT_FAILURE;
-               }
-
-       } else {
-               if ( verbose ) {
-                       fprintf( stderr, "ldap_initialize( %s )\n",
-                               ldapuri != NULL ? ldapuri : "<DEFAULT>" );
-               }
-
-               rc = ldap_initialize( &ld, ldapuri );
-               if( rc != LDAP_SUCCESS ) {
-                       fprintf( stderr, "Could not create LDAP session handle (%d): %s\n",
-                               rc, ldap_err2string(rc) );
-                       return EXIT_FAILURE;
-               }
-       }
-
-       /* referrals */
-       if( ldap_set_option( ld, LDAP_OPT_REFERRALS,
-               referrals ? LDAP_OPT_ON : LDAP_OPT_OFF ) != LDAP_OPT_SUCCESS )
-       {
-               fprintf( stderr, "Could not set LDAP_OPT_REFERRALS %s\n",
-                       referrals ? "on" : "off" );
-               return EXIT_FAILURE;
-       }
-
-
-       if (version == -1 ) {
-               version = LDAP_VERSION3;
-       }
-
-       if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version )
-               != LDAP_OPT_SUCCESS )
-       {
-               fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
-                       version );
-               return EXIT_FAILURE;
-       }
-
-       if ( use_tls && ( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS )) {
-               ldap_perror( ld, "ldap_start_tls" );
-               if ( use_tls > 1 ) {
-                       return( EXIT_FAILURE );
-               }
-       }
-
        if ( pw_file || want_bindpw ) {
                if ( pw_file ) {
                        rc = lutil_get_filed_password( pw_file, &passwd );
@@ -738,91 +222,13 @@ main( int argc, char **argv )
                }
        }
 
-       if ( authmethod == LDAP_AUTH_SASL ) {
-#ifdef HAVE_CYRUS_SASL
-               void *defaults;
-
-               if( sasl_secprops != NULL ) {
-                       rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
-                               (void *) sasl_secprops );
-                       
-                       if( rc != LDAP_OPT_SUCCESS ) {
-                               fprintf( stderr,
-                                       "Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
-                                       sasl_secprops );
-                               return( EXIT_FAILURE );
-                       }
-               }
-               
-               defaults = lutil_sasl_defaults( ld,
-                       sasl_mech,
-                       sasl_realm,
-                       sasl_authc_id,
-                       passwd.bv_val,
-                       sasl_authz_id );
-
-               rc = ldap_sasl_interactive_bind_s( ld, binddn,
-                       sasl_mech, NULL, NULL,
-                       sasl_flags, lutil_sasl_interact, defaults );
-
-               if( rc != LDAP_SUCCESS ) {
-                       ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
-                       return( EXIT_FAILURE );
-               }
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               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 );
-               }
-
-       }
-
+       tool_bind( ld );
     }
 
     rc = 0;
 
-       if ( manageDSAit || noop ) {
-               int err, i = 0;
-               LDAPControl c1, c2;
-               LDAPControl *ctrls[3];
-
-               if ( manageDSAit ) {
-                       ctrls[i++] = &c1;
-                       ctrls[i] = NULL;
-                       c1.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
-                       c1.ldctl_value.bv_val = NULL;
-                       c1.ldctl_value.bv_len = 0;
-                       c1.ldctl_iscritical = manageDSAit > 1;
-               }
-
-               if ( noop ) {
-                       ctrls[i++] = &c2;
-                       ctrls[i] = NULL;
-
-                       c2.ldctl_oid = LDAP_CONTROL_NOOP;
-                       c2.ldctl_value.bv_val = NULL;
-                       c2.ldctl_value.bv_len = 0;
-                       c2.ldctl_iscritical = noop > 1;
-               }
-       
-               err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
-
-               if( err != LDAP_OPT_SUCCESS ) {
-                       fprintf( stderr, "Could not set %scontrols\n",
-                               (c1.ldctl_iscritical || c2.ldctl_iscritical)
-                               ? "critical " : "" );
-                       if ( c1.ldctl_iscritical && c2.ldctl_iscritical ) {
-                               return EXIT_FAILURE;
-                       }
-               }
-       }
+       if ( authzid || manageDSAit || noop )
+               tool_server_controls( ld, NULL, 0 );
 
        count = 0;
        retval = 0;
@@ -848,14 +254,20 @@ main( int argc, char **argv )
        if ( rc && rejfp ) {
                fprintf(rejfp, "# Error: %s (%d)", ldap_err2string(rc), rc);
 
+               matched_msg = NULL;
                ldap_get_option(ld, LDAP_OPT_MATCHED_DN, &matched_msg);
-               if ( matched_msg != NULL && *matched_msg != '\0' ) {
-                       fprintf( rejfp, ", matched DN: %s", matched_msg );
+               if ( matched_msg != NULL ) {
+                       if ( *matched_msg != '\0' )
+                               fprintf( rejfp, ", matched DN: %s", matched_msg );
+                       ldap_memfree( matched_msg );
                }
 
+               error_msg = NULL;
                ldap_get_option(ld, LDAP_OPT_ERROR_STRING, &error_msg);
-               if ( error_msg != NULL && *error_msg != '\0' ) {
-                       fprintf( rejfp, ", additional info: %s", error_msg );
+               if ( error_msg != NULL ) {
+                       if ( *error_msg != '\0' )
+                               fprintf( rejfp, ", additional info: %s", error_msg );
+                       ldap_memfree( error_msg );
                }
                fprintf( rejfp, "\n%s\n", rejbuf );
        }
@@ -936,12 +348,12 @@ process_ldif_rec( char *rbuf, int count )
                {
                        if( val.bv_len == 0 || atoi(val.bv_val) != 1 ) {
                        fprintf( stderr, "%s: invalid version %s, line %d (ignored)\n",
-                               prog, val.bv_val == NULL ? "(null)" : val.bv_val, linenum );
+                               prog, val.bv_val, linenum );
                        }
                        version++;
 
            } else if ( strcasecmp( type, T_DN_STR ) == 0 ) {
-               if (( dn = ber_strdup( val.bv_val ? val.bv_val : "" )) == NULL ) {
+               if (( dn = ber_strdup( val.bv_val )) == NULL ) {
                    perror( "strdup" );
                    exit( EXIT_FAILURE );
                }
@@ -1057,7 +469,7 @@ process_ldif_rec( char *rbuf, int count )
 
        if ( expect_newrdn ) {
            if ( strcasecmp( type, T_NEWRDNSTR ) == 0 ) {
-                       if (( newrdn = ber_strdup( val.bv_val ? val.bv_val : "" )) == NULL ) {
+                       if (( newrdn = ber_strdup( val.bv_val )) == NULL ) {
                    perror( "strdup" );
                    exit( EXIT_FAILURE );
                }
@@ -1081,7 +493,7 @@ process_ldif_rec( char *rbuf, int count )
            }
        } else if ( expect_newsup ) {
            if ( strcasecmp( type, T_NEWSUPSTR ) == 0 ) {
-               if (( newsup = ber_strdup( val.bv_val ? val.bv_val : "" )) == NULL ) {
+               if (( newsup = ber_strdup( val.bv_val )) == NULL ) {
                    perror( "strdup" );
                    exit( EXIT_FAILURE );
                }
@@ -1097,7 +509,7 @@ process_ldif_rec( char *rbuf, int count )
                    prog, linenum, dn );
            rc = LDAP_PARAM_ERROR;
        } else {
-               addmodifyop( &pmods, modop, type, val.bv_val == NULL ? NULL : &val );
+               addmodifyop( &pmods, modop, type, &val );
        }
 
 end_line:
@@ -1143,8 +555,8 @@ end_line:
                         }
                     }
                     pctrls[npc+ndefc] = NULL;
-                    ldap_controls_free(defctrls);  /* Must be freed by library */
                 }
+                ldap_controls_free(defctrls);  /* Must be freed by library */
             }
         }
     }
@@ -1208,17 +620,19 @@ parse_ldif_control( char *line,
     pcolon = s;                        /* Save this position for later */
     if (*s++ != ':')                   /* Make sure colon follows */
         return ( LDAP_PARAM_ERROR );
-    while (*s && isspace(*s))  s++;    /* Skip white space before OID */
+    while (*s && isspace((unsigned char)*s))
+               s++;                           /* Skip white space before OID */
 
     /* OID should come next. Validate and extract it. */
     if (*s == 0)
         return ( LDAP_PARAM_ERROR );
     oidStart = s;
-    while (isdigit(*s) || *s == '.')  s++;    /* OID should be digits or . */
+    while (isdigit((unsigned char)*s) || *s == '.')
+               s++;                           /* OID should be digits or . */
     if (s == oidStart) 
         return ( LDAP_PARAM_ERROR );   /* OID was not present */
     if (*s) {                          /* End of OID should be space or NULL */
-        if (!isspace(*s))
+        if (!isspace((unsigned char)*s))
             return ( LDAP_PARAM_ERROR ); /* else OID contained invalid chars */
         *s++ = 0;                    /* Replace space with null to terminate */
     }
@@ -1229,7 +643,8 @@ parse_ldif_control( char *line,
         return ( LDAP_NO_MEMORY );
 
     /* Optional Criticality field is next. */
-    while (*s && isspace(*s))  s++;   /* Skip white space before criticality */
+    while (*s && isspace((unsigned char)*s))
+               s++;                         /* Skip white space before criticality */
     if (strncasecmp(s, "true", 4) == 0) {
         criticality = 1;
         s += 4;
@@ -1240,7 +655,8 @@ parse_ldif_control( char *line,
     }
 
     /* Optional value field is next */
-    while (*s && isspace(*s))  s++;    /* Skip white space before value */
+    while (*s && isspace((unsigned char)*s))
+               s++;                         /* Skip white space before value */
     if (*s) {
         if (*s != ':') {           /* If value is present, must start with : */
             rc = LDAP_PARAM_ERROR;
diff --git a/clients/tools/ldapmodify.dsp b/clients/tools/ldapmodify.dsp
new file mode 100644 (file)
index 0000000..ffa4e68
--- /dev/null
@@ -0,0 +1,153 @@
+# 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=.\common.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ldapmodify.c
+# End Source File
+# End Target
+# End Project
index 47419fc320c1811156005aa699f15ae2f160c51b..225e536657547214e7e48d97090ce025c06e4f53 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* ldapmodrdn.c - generic program to modify an entry's RDN using LDAP.
@@ -24,7 +24,6 @@
 #include <ac/stdlib.h>
 
 #include <ac/ctype.h>
-#include <ac/signal.h>
 #include <ac/string.h>
 #include <ac/unistd.h>
 
 #include "lutil_ldap.h"
 #include "ldap_defaults.h"
 
-static char *prog = NULL;
-static char    *binddn = NULL;
-static struct berval passwd = { 0, NULL };
-static char    *ldapuri = NULL;
-static char    *ldaphost = NULL;
-static int     ldapport = 0;
-#ifdef HAVE_CYRUS_SASL
-static unsigned sasl_flags = LDAP_SASL_AUTOMATIC;
-static char *sasl_realm = NULL;
-static char    *sasl_authc_id = NULL;
-static char    *sasl_authz_id = NULL;
-static char    *sasl_mech = NULL;
-static char    *sasl_secprops = NULL;
-#endif
-static int     use_tls = 0;
-static int     not, verbose, contoper;
-static LDAP    *ld = NULL;
+#include "common.h"
+
+
+static char    *newSuperior = NULL;
+static int   remove_old_RDN = 0;
+
 
 static int domodrdn(
     LDAP       *ld,
@@ -58,8 +46,8 @@ static int domodrdn(
     char       *newSuperior,
     int                remove );       /* flag: remove old RDN */
 
-static void
-usage( const char *s )
+void
+usage( void )
 {
        fprintf( stderr,
 "Rename LDAP entries\n\n"
@@ -68,77 +56,29 @@ usage( const char *s )
 "              If not given, the list of modifications is read from stdin or\n"
 "              from the file specified by \"-f file\" (see man page).\n"
 "Rename options:\n"
-"  -c         continuous operation mode (do not stop on errors)\n"
-"  -f file    read operations from `file'\n"
 "  -r         remove old RDN\n"
 "  -s newsup  new superior entry\n"
-
-"Common options:\n"
-"  -d level   set LDAP debugging level to `level'\n"
-"  -D binddn  bind DN\n"
-"  -e [!]<ctrl>[=<ctrlparam>] general controls (! indicates criticality)\n"
-"             [!]manageDSAit   (alternate form, see -M)\n"
-"             [!]noop\n"
-"  -f file    read operations from `file'\n"
-"  -h host    LDAP server\n"
-"  -H URI     LDAP Uniform Resource Indentifier(s)\n"
-"  -I         use SASL Interactive mode\n"
-"  -k         use Kerberos authentication\n"
-"  -K         like -k, but do only step 1 of the Kerberos bind\n"
-"  -M         enable Manage DSA IT control (-MM to make critical)\n"
-"  -n         show what would be done but don't actually update\n"
-"  -O props   SASL security properties\n"
-"  -p port    port on LDAP server\n"
-"  -P version procotol version (default: 3)\n"
-"  -Q         use SASL Quiet mode\n"
-"  -R realm   SASL realm\n"
-"  -U authzid SASL authentication identity\n"
-"  -v         run in verbose mode (diagnostics to standard output)\n"
-"  -w passwd  bind passwd (for simple authentication)\n"
-"  -W         prompt for bind passwd\n"
-"  -x         Simple authentication\n"
-"  -X authzid SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
-"  -y file    Read passwd from file\n"
-"  -Y mech    SASL mechanism\n"
-"  -Z         Start TLS request (-ZZ to require successful response)\n"
-,              s );
-
+                , prog );
+       tool_common_usage();
        exit( EXIT_FAILURE );
 }
 
-int
-main(int argc, char **argv)
-{
-    char               *infile, *entrydn = NULL, *rdn = NULL, buf[ 4096 ];
-    FILE               *fp;
-       int             rc, retval, i, remove, havedn, authmethod, version;
-       int             want_bindpw, debug, manageDSAit, noop, crit;
-       int             referrals;
-    char       *newSuperior=NULL;
-       char    *pw_file = NULL;
-       char    *control, *cvalue;
-
-    infile = NULL;
-    not = contoper = verbose = remove = want_bindpw =
-               debug = manageDSAit = noop = referrals = 0;
-    authmethod = -1;
-       version = -1;
 
-    prog = lutil_progname( "ldapmodrdn", argc, argv );
+const char options[] = "rs:"
+       "cCd:D:e:f:h:H:IkKMnO:p:P:QR:U:vVw:WxX:y:Y:Z";
 
-    while (( i = getopt( argc, argv, "cf:rs:"
-               "Cd:D:e:h:H:IkKMnO:p:P:QR:U:vw:WxX:y:Y:Z" )) != EOF )
-       {
-       switch( i ) {
-       /* Modrdn Options */
-       case 'c':
-               contoper++;
-               break;
+int
+handle_private_option( int i )
+{
+       switch ( i ) {
+#if 0
+               int crit;
+               char *control, *cvalue;
        case 'E': /* modrdn controls */
-               if( version == LDAP_VERSION2 ) {
+               if( protocol == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -E incompatible with LDAPv%d\n",
                                prog, version );
-                       return EXIT_FAILURE;
+                       exit( EXIT_FAILURE );
                }
 
                /* should be extended to support comma separated list of
@@ -157,432 +97,41 @@ main(int argc, char **argv)
                        *cvalue++ = '\0';
                }
                fprintf( stderr, "Invalid modrdn control name: %s\n", control );
-               usage(prog);
-               return EXIT_FAILURE;
-       case 'f':       /* read from file */
-               if( infile != NULL ) {
-                       fprintf( stderr, "%s: -f previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           infile = strdup( optarg );
-           break;
+               usage();
+#endif
+
        case 'r':       /* remove old RDN */
-           remove++;
+           remove_old_RDN++;
            break;
+
        case 's':       /* newSuperior */
-               if( version == LDAP_VERSION2 ) {
+               if( protocol == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
+                               prog, protocol );
+                       exit( EXIT_FAILURE );
                }
            newSuperior = strdup( optarg );
-           version = LDAP_VERSION3;
-           break;
-
-       /* Common Options */
-       case 'C':
-               referrals++;
-               break;
-       case 'd':
-           debug |= atoi( optarg );
-           break;
-       case 'D':       /* bind DN */
-               if( binddn != NULL ) {
-                       fprintf( stderr, "%s: -D previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           binddn = strdup( optarg );
+           protocol = LDAP_VERSION3;
            break;
-       case 'e': /* general controls */
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -e incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
 
-               /* should be extended to support comma separated list of
-                *      [!]key[=value] parameters, e.g.  -e !foo,bar=567
-                */
-
-               crit = 0;
-               cvalue = NULL;
-               if( optarg[0] == '!' ) {
-                       crit = 1;
-                       optarg++;
-               }
-
-               control = strdup( optarg );
-               if ( (cvalue = strchr( control, '=' )) != NULL ) {
-                       *cvalue++ = '\0';
-               }
-
-               if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
-                       if( cvalue != NULL ) {
-                               fprintf( stderr, "manageDSAit: no control value expected\n" );
-                               usage(prog);
-                               return EXIT_FAILURE;
-                       }
-
-                       manageDSAit = 1 + crit;
-                       free( control );
-                       break;
-                       
-               } else if ( strcasecmp( control, "noop" ) == 0 ) {
-                       if( cvalue != NULL ) {
-                               fprintf( stderr, "noop: no control value expected\n" );
-                               usage(prog);
-                               return EXIT_FAILURE;
-                       }
-
-                       noop = 1 + crit;
-                       free( control );
-                       break;
-
-               } else {
-                       fprintf( stderr, "Invalid general control name: %s\n", control );
-                       usage(prog);
-                       return EXIT_FAILURE;
-               }
-       case 'h':       /* ldap host */
-               if( ldapuri != NULL ) {
-                       fprintf( stderr, "%s: -h incompatible with -H\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( ldaphost != NULL ) {
-                       fprintf( stderr, "%s: -h previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           ldaphost = strdup( optarg );
-           break;
-       case 'H':       /* ldap URI */
-               if( ldaphost != NULL ) {
-                       fprintf( stderr, "%s: -H incompatible with -h\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( ldapport ) {
-                       fprintf( stderr, "%s: -H incompatible with -p\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( ldapuri != NULL ) {
-                       fprintf( stderr, "%s: -H previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           ldapuri = strdup( optarg );
-           break;
-       case 'I':
-#ifdef HAVE_CYRUS_SASL
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -I incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_flags = LDAP_SASL_INTERACTIVE;
-               break;
-#else
-               fprintf( stderr, "%s: was not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-       case 'k':       /* kerberos bind */
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-               if( version > LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
+       default:
+               return 0;
+       }
+       return 1;
+}
 
-               if( authmethod != -1 ) {
-                       fprintf( stderr, "%s: -k incompatible with previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-                       
-               authmethod = LDAP_AUTH_KRBV4;
-#else
-               fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
-               return EXIT_FAILURE;
-#endif
-           break;
-       case 'K':       /* kerberos bind, part one only */
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-               if( version > LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 ) {
-                       fprintf( stderr, "%s: incompatible with previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
 
-               authmethod = LDAP_AUTH_KRBV41;
-#else
-               fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
-               return( EXIT_FAILURE );
-#endif
-           break;
-       case 'M':
-               /* enable Manage DSA IT */
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -M incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               manageDSAit++;
-               version = LDAP_VERSION3;
-               break;
-       case 'n':       /* print deletes, don't actually do them */
-           ++not;
-           break;
-       case 'O':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_secprops != NULL ) {
-                       fprintf( stderr, "%s: -O previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_secprops = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'p':
-               if( ldapport ) {
-                       fprintf( stderr, "%s: -p previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           ldapport = atoi( optarg );
-           break;
-       case 'P':
-               switch( atoi(optarg) ) {
-               case 2:
-                       if( version == LDAP_VERSION3 ) {
-                               fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       version = LDAP_VERSION2;
-                       break;
-               case 3:
-                       if( version == LDAP_VERSION2 ) {
-                               fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       version = LDAP_VERSION3;
-                       break;
-               default:
-                       fprintf( stderr, "%s: protocol version should be 2 or 3\n",
-                               prog );
-                       usage( prog );
-                       return( EXIT_FAILURE );
-               } break;
-       case 'Q':
-#ifdef HAVE_CYRUS_SASL
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -Q incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_flags = LDAP_SASL_QUIET;
-               break;
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-       case 'R':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_realm != NULL ) {
-                       fprintf( stderr, "%s: -R previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -R incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_realm = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'U':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_authc_id != NULL ) {
-                       fprintf( stderr, "%s: -U previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -U incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_authc_id = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'v':       /* verbose mode */
-           verbose++;
-           break;
-       case 'w':       /* password */
-           passwd.bv_val = strdup( optarg );
-               {
-                       char* p;
+int
+main(int argc, char **argv)
+{
+    char               *entrydn = NULL, *rdn = NULL, buf[ 4096 ];
+    FILE               *fp;
+    LDAP               *ld;
+       int             rc, retval, havedn;
 
-                       for( p = optarg; *p != '\0'; p++ ) {
-                               *p = '\0';
-                       }
-               }
-               passwd.bv_len = strlen( passwd.bv_val );
-           break;
-       case 'W':
-               want_bindpw++;
-               break;
-       case 'y':
-               pw_file = optarg;
-               break;
-       case 'Y':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_mech != NULL ) {
-                       fprintf( stderr, "%s: -Y previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -Y incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_mech = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'x':
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
-                       fprintf( stderr, "%s: incompatible with previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SIMPLE;
-               break;
-       case 'X':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_authz_id != NULL ) {
-                       fprintf( stderr, "%s: -X previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: -X incompatible with "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_authz_id = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'Z':
-#ifdef HAVE_TLS
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -Z incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               version = LDAP_VERSION3;
-               use_tls++;
-#else
-               fprintf( stderr, "%s: not compiled with TLS support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       default:
-               fprintf( stderr, "%s: unrecognized option -%c\n",
-                       prog, optopt );
-           usage( prog );
-           return( EXIT_FAILURE );
-       }
-    }
+    prog = lutil_progname( "ldapmodrdn", argc, argv );
 
-       if (version == -1) {
-               version = LDAP_VERSION3;
-       }
-       if (authmethod == -1 && version > LDAP_VERSION2) {
-#ifdef HAVE_CYRUS_SASL
-               authmethod = LDAP_AUTH_SASL;
-#else
-               authmethod = LDAP_AUTH_SIMPLE;
-#endif
-       }
+       tool_args( argc, argv );
 
     havedn = 0;
     if (argc - optind == 2) {
@@ -598,8 +147,7 @@ main(int argc, char **argv)
     } else if ( argc - optind != 0 ) {
        fprintf( stderr, "%s: invalid number of arguments (%d), "
                "only two allowed\n", prog, argc-optind );
-       usage( prog );
-       return( EXIT_FAILURE );
+       usage();
     }
 
     if ( infile != NULL ) {
@@ -611,69 +159,7 @@ main(int argc, char **argv)
        fp = stdin;
     }
 
-       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 );
-               }
-               if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
-                       fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
-               }
-       }
-
-#ifdef SIGPIPE
-       (void) SIGNAL( SIGPIPE, SIG_IGN );
-#endif
-
-       if( ( ldaphost != NULL || ldapport ) && ( ldapuri == NULL ) ) {
-               if ( verbose ) {
-                       fprintf( stderr, "ldap_init( %s, %d )\n",
-                               ldaphost != NULL ? ldaphost : "<DEFAULT>",
-                               ldapport );
-               }
-
-               ld = ldap_init( ldaphost, ldapport );
-               if( ld == NULL ) {
-                       perror("ldapmodify: ldap_init");
-                       return EXIT_FAILURE;
-               }
-
-       } else {
-               if ( verbose ) {
-                       fprintf( stderr, "ldap_initialize( %s )\n",
-                               ldapuri != NULL ? ldapuri : "<DEFAULT>" );
-               }
-
-               rc = ldap_initialize( &ld, ldapuri );
-               if( rc != LDAP_SUCCESS ) {
-                       fprintf( stderr, "Could not create LDAP session handle (%d): %s\n",
-                               rc, ldap_err2string(rc) );
-                       return EXIT_FAILURE;
-               }
-       }
-
-       /* referrals */
-       if( ldap_set_option( ld, LDAP_OPT_REFERRALS,
-               referrals ? LDAP_OPT_ON : LDAP_OPT_OFF ) != LDAP_OPT_SUCCESS )
-       {
-               fprintf( stderr, "Could not set LDAP_OPT_REFERRALS %s\n",
-                       referrals ? "on" : "off" );
-               return EXIT_FAILURE;
-       }
-
-       if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version )
-               != LDAP_OPT_SUCCESS )
-       {
-               fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
-                       version );
-               return EXIT_FAILURE;
-       }
-
-       if ( use_tls && ( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS )) {
-               ldap_perror( ld, "ldap_start_tls" );
-               if ( use_tls > 1 ) {
-                       return( EXIT_FAILURE );
-               }
-       }
+       ld = tool_conn_setup( 0, 0 );
 
        if ( pw_file || want_bindpw ) {
                if ( pw_file ) {
@@ -685,90 +171,14 @@ main(int argc, char **argv)
                }
        }
 
-       if ( authmethod == LDAP_AUTH_SASL ) {
-#ifdef HAVE_CYRUS_SASL
-               void *defaults;
-
-               if( sasl_secprops != NULL ) {
-                       rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
-                               (void *) sasl_secprops );
-                       
-                       if( rc != LDAP_OPT_SUCCESS ) {
-                               fprintf( stderr,
-                                       "Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
-                                       sasl_secprops );
-                               return( EXIT_FAILURE );
-                       }
-               }
-               
-               defaults = lutil_sasl_defaults( ld,
-                       sasl_mech,
-                       sasl_realm,
-                       sasl_authc_id,
-                       passwd.bv_val,
-                       sasl_authz_id );
-
-               rc = ldap_sasl_interactive_bind_s( ld, binddn,
-                       sasl_mech, NULL, NULL,
-                       sasl_flags, lutil_sasl_interact, defaults );
-
-               if( rc != LDAP_SUCCESS ) {
-                       ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
-                       return( EXIT_FAILURE );
-               }
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               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 || noop ) {
-               int err, i = 0;
-               LDAPControl c1, c2;
-               LDAPControl *ctrls[3];
-
-               if ( manageDSAit ) {
-                       ctrls[i++] = &c1;
-                       ctrls[i] = NULL;
-                       c1.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
-                       c1.ldctl_value.bv_val = NULL;
-                       c1.ldctl_value.bv_len = 0;
-                       c1.ldctl_iscritical = manageDSAit > 1;
-               }
-
-               if ( noop ) {
-                       ctrls[i++] = &c2;
-                       ctrls[i] = NULL;
+       tool_bind( ld );
 
-                       c2.ldctl_oid = LDAP_CONTROL_NOOP;
-                       c2.ldctl_value.bv_val = NULL;
-                       c2.ldctl_value.bv_len = 0;
-                       c2.ldctl_iscritical = noop > 1;
-               }
-       
-               err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
-
-               if( err != LDAP_OPT_SUCCESS ) {
-                       fprintf( stderr, "Could not set %scontrols\n",
-                               (c1.ldctl_iscritical || c2.ldctl_iscritical)
-                               ? "critical " : "" );
-                       if ( c1.ldctl_iscritical && c2.ldctl_iscritical ) {
-                               return EXIT_FAILURE;
-                       }
-               }
-       }
+       if ( authzid || manageDSAit || noop )
+               tool_server_controls( ld, NULL, 0 );
 
     retval = rc = 0;
     if (havedn)
-       retval = domodrdn( ld, entrydn, rdn, newSuperior, remove );
+       retval = domodrdn( ld, entrydn, rdn, newSuperior, remove_old_RDN );
     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 */
@@ -778,7 +188,7 @@ main(int argc, char **argv)
                     perror( "strdup" );
                     return( EXIT_FAILURE );
                }
-               rc = domodrdn(ld, entrydn, rdn, newSuperior, remove );
+               rc = domodrdn(ld, entrydn, rdn, newSuperior, remove_old_RDN );
                if ( rc != 0 )
                        retval = rc;
                havedn = 0;
diff --git a/clients/tools/ldapmodrdn.dsp b/clients/tools/ldapmodrdn.dsp
new file mode 100644 (file)
index 0000000..d1304ce
--- /dev/null
@@ -0,0 +1,153 @@
+# 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=.\common.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ldapmodrdn.c
+# End Source File
+# End Target
+# End Project
index 58fbfaf2a528a6c2da71f7150d7f0c6314ff6856..a0265f4ebdc5fa9b8e7dbc0b48898c7fe9c20d0a 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -11,7 +11,6 @@
 #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 "lutil_ldap.h"
 #include "ldap_defaults.h"
 
-static int     verbose = 0;
+#include "common.h"
 
-static void
-usage(const char *s)
+
+static char    *newpw = NULL;
+static char    *oldpw = NULL;
+static int   want_newpw = 0;
+static int   want_oldpw = 0;
+
+
+void
+usage( void )
 {
        fprintf(stderr,
 "Change password of an LDAP user\n\n"
@@ -36,111 +42,27 @@ usage(const char *s)
 "  -A         prompt for old password\n"
 "  -s secret  new password\n"
 "  -S         prompt for new password\n"
-
-"Common options:\n"
-"  -d level   set LDAP debugging level to `level'\n"
-"  -D binddn  bind DN\n"
-"  -e [!]<ctrl>[=<ctrlparam>] general controls (! indicates criticality)\n"
-"             [!]manageDSAit   (alternate form, see -M)\n"
-"             [!]noop\n"
-"  -f file    read operations from `file'\n"
-"  -h host    LDAP server(s)\n"
-"  -H URI     LDAP Uniform Resource Indentifier(s)\n"
-"  -I         use SASL Interactive mode\n"
-"  -n         show what would be done but don't actually update\n"
-"  -O props   SASL security properties\n"
-"  -p port    port on LDAP server\n"
-"  -Q         use SASL Quiet mode\n"
-"  -R realm   SASL realm\n"
-"  -U authcid SASL authentication identity\n"
-"  -v         run in verbose mode (diagnostics to standard output)\n"
-"  -w passwd  bind passwd (for simple authentication)\n"
-"  -W         prompt for bind passwd\n"
-"  -x         Simple authentication\n"
-"  -X authzid SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
-"  -Y mech    SASL mechanism\n"
-"  -Z         Start TLS request (-ZZ to require successful response)\n"
-               , s );
-
+               , prog );
+       tool_common_usage();
        exit( EXIT_FAILURE );
 }
 
-int
-main( int argc, char *argv[] )
-{
-       int rc;
-       char    *prog = NULL;
-       char    *ldaphost = NULL;
-       char    *ldapuri = NULL;
 
-       char    *user = NULL;
-       char    *binddn = NULL;
-
-       struct berval passwd = { 0, NULL };
-       char    *newpw = NULL;
-       char    *oldpw = NULL;
-
-       int             want_bindpw = 0;
-       int             want_newpw = 0;
-       int             want_oldpw = 0;
-
-       int             not = 0;
-       int             i;
-       int             ldapport = 0;
-       int             debug = 0;
-       int             version = -1;
-       int             authmethod = -1;
-       int             manageDSAit = 0;
-       int             noop = 0;
-       int             crit;
-       char    *control, *cvalue;
-#ifdef HAVE_CYRUS_SASL
-       unsigned        sasl_flags = LDAP_SASL_AUTOMATIC;
-       char            *sasl_realm = NULL;
-       char            *sasl_authc_id = NULL;
-       char            *sasl_authz_id = NULL;
-       char            *sasl_mech = NULL;
-       char            *sasl_secprops = NULL;
-#endif
-       int             use_tls = 0;
-       int             referrals = 0;
-       LDAP           *ld = NULL;
-       struct berval *bv = NULL;
-
-       int id, code = LDAP_OTHER;
-       LDAPMessage *res;
-       char *matcheddn = NULL, *text = NULL, **refs = NULL;
-       char    *retoid = NULL;
-       struct berval *retdata = NULL;
-
-    prog = lutil_progname( "ldappasswd", argc, argv );
-
-       while( (i = getopt( argc, argv, "Aa:Ss:"
-               "Cd:D:e:h:H:InO:p:QR:U:vw:WxX:Y:Z" )) != EOF )
-       {
-               switch (i) {
-               /* Password Options */
-               case 'A':       /* prompt for old password */
-                       want_oldpw++;
-                       break;
-
-               case 'a':       /* old password (secret) */
-                       oldpw = strdup (optarg);
-
-                       {
-                               char* p;
-
-                               for( p = optarg; *p != '\0'; p++ ) {
-                                       *p = '\0';
-                               }
-                       }
-                       break;
+const char options[] = "a:As:S"
+       "Cd:D:e:h:H:InO:p:QR:U:vVw:WxX:Y:Z";
 
+int
+handle_private_option( int i )
+{
+       switch ( i ) {
+#if 0
+               int             crit;
+               char    *control, *cvalue;
        case 'E': /* passwd controls */
-               if( version == LDAP_VERSION2 ) {
+               if( protocol == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -E incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
+                                prog, protocol );
+                       exit( EXIT_FAILURE );
                }
 
                /* should be extended to support comma separated list of
@@ -159,425 +81,70 @@ main( int argc, char *argv[] )
                        *cvalue++ = '\0';
                }
                fprintf( stderr, "Invalid passwd control name: %s\n", control );
-               usage(prog);
-               return EXIT_FAILURE;
-               case 'S':       /* prompt for user password */
-                       want_newpw++;
-                       break;
-
-               case 's':       /* new password (secret) */
-                       newpw = strdup (optarg);
-                       {
-                               char* p;
-
-                               for( p = optarg; *p != '\0'; p++ ) {
-                                       *p = '\0';
-                               }
-                       }
-                       break;
-
-       /* Common Options (including options we don't use) */
-       case 'C':
-               referrals++;
-               break;
-       case 'd':
-           debug |= atoi( optarg );
-           break;
-       case 'D':       /* bind DN */
-               if( binddn != NULL ) {
-                       fprintf( stderr, "%s: -D previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           binddn = strdup( optarg );
-           break;
-       case 'e': /* general controls */
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -e incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-
-               /* should be extended to support comma separated list of
-                *      [!]key[=value] parameters, e.g.  -e !foo,bar=567
-                */
-
-               crit = 0;
-               cvalue = NULL;
-               if( optarg[0] == '!' ) {
-                       crit = 1;
-                       optarg++;
-               }
-
-               control = strdup( optarg );
-               if ( (cvalue = strchr( control, '=' )) != NULL ) {
-                       *cvalue++ = '\0';
-               }
-
-               if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
-                       if( cvalue != NULL ) {
-                               fprintf( stderr, "manageDSAit: no control value expected\n" );
-                               usage(prog);
-                               return EXIT_FAILURE;
-                       }
-
-                       manageDSAit = 1 + crit;
-                       free( control );
-                       break;
-                       
-               } else if ( strcasecmp( control, "noop" ) == 0 ) {
-                       if( cvalue != NULL ) {
-                               fprintf( stderr, "noop: no control value expected\n" );
-                               usage(prog);
-                               return EXIT_FAILURE;
-                       }
-
-                       noop = 1 + crit;
-                       free( control );
-                       break;
-
-               } else {
-                       fprintf( stderr, "Invalid general control name: %s\n", control );
-                       usage(prog);
-                       return EXIT_FAILURE;
-               }
-       case 'h':       /* ldap host */
-               if( ldapuri != NULL ) {
-                       fprintf( stderr, "%s: -h incompatible with -H\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( ldaphost != NULL ) {
-                       fprintf( stderr, "%s: -h previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           ldaphost = strdup( optarg );
-           break;
-       case 'H':       /* ldap URI */
-               if( ldaphost != NULL ) {
-                       fprintf( stderr, "%s: -H incompatible with -h\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( ldapport ) {
-                       fprintf( stderr, "%s: -H incompatible with -p\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( ldapuri != NULL ) {
-                       fprintf( stderr, "%s: -H previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           ldapuri = strdup( optarg );
-           break;
-       case 'I':
-#ifdef HAVE_CYRUS_SASL
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -I incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_flags = LDAP_SASL_INTERACTIVE;
-               break;
-#else
-               fprintf( stderr, "%s: was not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
+               usage();
 #endif
-       case 'k':       /* kerberos bind */
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-               if( version > LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
 
-               if( authmethod != -1 ) {
-                       fprintf( stderr, "%s: -k incompatible with previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-                       
-               authmethod = LDAP_AUTH_KRBV4;
-#else
-               fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
-               return EXIT_FAILURE;
-#endif
-           break;
-       case 'K':       /* kerberos bind, part one only */
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-               if( version > LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 ) {
-                       fprintf( stderr, "%s: incompatible with previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
+       case 'a':       /* old password (secret) */
+               oldpw = strdup (optarg);
 
-               authmethod = LDAP_AUTH_KRBV41;
-#else
-               fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
-               return( EXIT_FAILURE );
-#endif
-           break;
-       case 'M':
-               /* enable Manage DSA IT */
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -M incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               manageDSAit++;
-               version = LDAP_VERSION3;
-               break;
-       case 'n':       /* print deletes, don't actually do them */
-           ++not;
-           break;
-       case 'O':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_secprops != NULL ) {
-                       fprintf( stderr, "%s: -O previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_secprops = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'p':
-               if( ldapport ) {
-                       fprintf( stderr, "%s: -p previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           ldapport = atoi( optarg );
-           break;
-       case 'P':
-               switch( atoi(optarg) ) {
-               case 2:
-                       if( version == LDAP_VERSION3 ) {
-                               fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       version = LDAP_VERSION2;
-                       break;
-               case 3:
-                       if( version == LDAP_VERSION2 ) {
-                               fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
+               {
+                       char* p;
+                       for( p = optarg; *p != '\0'; p++ ) {
+                               *p = '\0';
                        }
-                       version = LDAP_VERSION3;
-                       break;
-               default:
-                       fprintf( stderr, "%s: protocol version should be 2 or 3\n",
-                               prog );
-                       usage( prog );
-                       return( EXIT_FAILURE );
-               } break;
-       case 'Q':
-#ifdef HAVE_CYRUS_SASL
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -Q incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
                }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_flags = LDAP_SASL_QUIET;
                break;
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-       case 'R':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_realm != NULL ) {
-                       fprintf( stderr, "%s: -R previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -R incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_realm = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'U':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_authc_id != NULL ) {
-                       fprintf( stderr, "%s: -U previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -U incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_authc_id = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
+
+       case 'A':       /* prompt for old password */
+               want_oldpw++;
                break;
-       case 'v':       /* verbose mode */
-           verbose++;
-           break;
-       case 'w':       /* password */
-           passwd.bv_val = strdup( optarg );
+
+       case 's':       /* new password (secret) */
+               newpw = strdup (optarg);
                {
                        char* p;
-
                        for( p = optarg; *p != '\0'; p++ ) {
                                *p = '\0';
                        }
                }
-               passwd.bv_len = strlen( passwd.bv_val );
-           break;
-       case 'W':
-               want_bindpw++;
-               break;
-       case 'Y':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_mech != NULL ) {
-                       fprintf( stderr, "%s: -Y previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -Y incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_mech = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'x':
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
-                       fprintf( stderr, "%s: incompatible with previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SIMPLE;
-               break;
-       case 'X':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_authz_id != NULL ) {
-                       fprintf( stderr, "%s: -X previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: -X incompatible with "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_authz_id = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'Z':
-#ifdef HAVE_TLS
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -Z incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               version = LDAP_VERSION3;
-               use_tls++;
-#else
-               fprintf( stderr, "%s: not compiled with TLS support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
                break;
 
+       case 'S':       /* prompt for user password */
+               want_newpw++;
+               break;
 
-               default:
-                       fprintf( stderr, "%s: unrecognized option -%c\n",
-                               prog, optopt );
-                       usage (prog);
-               }
+       default:
+               return 0;
        }
+       return 1;
+}
 
-       if (authmethod == -1) {
-#ifdef HAVE_CYRUS_SASL
-               authmethod = LDAP_AUTH_SASL;
-#else
-               authmethod = LDAP_AUTH_SIMPLE;
-#endif
-       }
+
+int
+main( int argc, char *argv[] )
+{
+       int rc;
+       char    *user = NULL;
+
+       LDAP           *ld = NULL;
+       struct berval bv = {0, NULL};
+       BerElement  *ber = NULL;
+
+       int id, code = LDAP_OTHER;
+       LDAPMessage *res;
+       char *matcheddn = NULL, *text = NULL, **refs = NULL;
+       char    *retoid = NULL;
+       struct berval *retdata = NULL;
+
+       prog = lutil_progname( "ldappasswd", argc, argv );
+
+       /* LDAPv3 only */
+       protocol = LDAP_VERSION3;
+
+       tool_args( argc, argv );
 
        if( argc - optind > 1 ) {
-               usage( prog );
+               usage();
        } else if ( argc - optind == 1 ) {
                user = strdup( argv[optind] );
        } else {
@@ -618,156 +185,16 @@ main( int argc, char *argv[] )
                passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0;
        }
 
-       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 );
-               }
-               if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
-                       fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
-               }
-       }
+       ld = tool_conn_setup( 0, 0 );
 
-#ifdef SIGPIPE
-       (void) SIGNAL( SIGPIPE, SIG_IGN );
-#endif
+       tool_bind( ld );
 
-       /* connect to server */
-       if( ( ldaphost != NULL || ldapport ) && ( ldapuri == NULL ) ) {
-               if ( verbose ) {
-                       fprintf( stderr, "ldap_init( %s, %d )\n",
-                               ldaphost != NULL ? ldaphost : "<DEFAULT>",
-                               ldapport );
-               }
-
-               ld = ldap_init( ldaphost, ldapport );
-               if( ld == NULL ) {
-                       perror("ldapsearch: ldap_init");
-                       return EXIT_FAILURE;
-               }
-
-       } else {
-               if ( verbose ) {
-                       fprintf( stderr, "ldap_initialize( %s )\n",
-                               ldapuri != NULL ? ldapuri : "<DEFAULT>" );
-               }
-
-               rc = ldap_initialize( &ld, ldapuri );
-               if( rc != LDAP_SUCCESS ) {
-                       fprintf( stderr, "Could not create LDAP session handle (%d): %s\n",
-                               rc, ldap_err2string(rc) );
-                       return EXIT_FAILURE;
-               }
-       }
-
-       /* referrals */
-       if (ldap_set_option( ld, LDAP_OPT_REFERRALS,
-               referrals ? LDAP_OPT_ON : LDAP_OPT_OFF ) != LDAP_OPT_SUCCESS )
-       {
-               fprintf( stderr, "Could not set LDAP_OPT_REFERRALS %s\n",
-                       referrals ? "on" : "off" );
-               return EXIT_FAILURE;
-       }
-
-       /* LDAPv3 only */
-       version = LDAP_VERSION3;
-       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 );
-               return EXIT_FAILURE;
-       }
-
-       if ( use_tls && ( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS )) {
-               ldap_perror( ld, "ldap_start_tls" );
-               if ( use_tls > 1 ) {
-                       return( EXIT_FAILURE );
-               }
-       }
-
-       if ( authmethod == LDAP_AUTH_SASL ) {
-#ifdef HAVE_CYRUS_SASL
-               void *defaults;
-
-               if( sasl_secprops != NULL ) {
-                       rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
-                               (void *) sasl_secprops );
-                       
-                       if( rc != LDAP_OPT_SUCCESS ) {
-                               fprintf( stderr,
-                                       "Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
-                                       sasl_secprops );
-                               return( EXIT_FAILURE );
-                       }
-               }
-               
-               defaults = lutil_sasl_defaults( ld,
-                       sasl_mech,
-                       sasl_realm,
-                       sasl_authc_id,
-                       passwd.bv_val,
-                       sasl_authz_id );
-
-               rc = ldap_sasl_interactive_bind_s( ld, binddn,
-                       sasl_mech, NULL, NULL,
-                       sasl_flags, lutil_sasl_interact, defaults );
-
-               if( rc != LDAP_SUCCESS ) {
-                       ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
-                       return( EXIT_FAILURE );
-               }
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               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 || noop ) {
-               int err, i = 0;
-               LDAPControl c1, c2;
-               LDAPControl *ctrls[3];
-
-               if ( manageDSAit ) {
-                       ctrls[i++] = &c1;
-                       ctrls[i] = NULL;
-                       c1.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
-                       c1.ldctl_value.bv_val = NULL;
-                       c1.ldctl_value.bv_len = 0;
-                       c1.ldctl_iscritical = manageDSAit > 1;
-               }
-
-               if ( noop ) {
-                       ctrls[i++] = &c2;
-                       ctrls[i] = NULL;
-
-                       c2.ldctl_oid = LDAP_CONTROL_NOOP;
-                       c2.ldctl_value.bv_val = NULL;
-                       c2.ldctl_value.bv_len = 0;
-                       c2.ldctl_iscritical = noop > 1;
-               }
-       
-               err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
-
-               if( err != LDAP_OPT_SUCCESS ) {
-                       fprintf( stderr, "Could not set %scontrols\n",
-                               (c1.ldctl_iscritical || c2.ldctl_iscritical)
-                               ? "critical " : "" );
-                       if ( c1.ldctl_iscritical && c2.ldctl_iscritical ) {
-                               return EXIT_FAILURE;
-                       }
-               }
-       }
+       if ( authzid || manageDSAit || noop )
+               tool_server_controls( ld, NULL, 0 );
 
        if( user != NULL || oldpw != NULL || newpw != NULL ) {
                /* build change password control */
-               BerElement *ber = ber_alloc_t( LBER_USE_DER );
+               ber = ber_alloc_t( LBER_USE_DER );
 
                if( ber == NULL ) {
                        perror( "ber_alloc_t" );
@@ -797,15 +224,13 @@ main( int argc, char *argv[] )
 
                ber_printf( ber, /*{*/ "N}" );
 
-               rc = ber_flatten( ber, &bv );
+               rc = ber_flatten2( ber, &bv, 0 );
 
                if( rc < 0 ) {
-                       perror( "ber_flatten" );
+                       perror( "ber_flatten2" );
                        ldap_unbind( ld );
                        return EXIT_FAILURE;
                }
-
-               ber_free( ber, 1 );
        }
 
        if ( not ) {
@@ -814,10 +239,10 @@ main( int argc, char *argv[] )
        }
 
        rc = ldap_extended_operation( ld,
-               LDAP_EXOP_MODIFY_PASSWD, bv, 
+               LDAP_EXOP_MODIFY_PASSWD, bv.bv_val ? &bv : NULL
                NULL, NULL, &id );
 
-       ber_bvfree( bv );
+       ber_free( ber, 1 );
 
        if( rc != LDAP_SUCCESS ) {
                ldap_perror( ld, "ldap_extended_operation" );
@@ -848,7 +273,7 @@ main( int argc, char *argv[] )
        if( retdata != NULL ) {
                ber_tag_t tag;
                char *s;
-               BerElement *ber = ber_init( retdata );
+               ber = ber_init( retdata );
 
                if( ber == NULL ) {
                        perror( "ber_init" );
diff --git a/clients/tools/ldappasswd.dsp b/clients/tools/ldappasswd.dsp
new file mode 100644 (file)
index 0000000..7aa142c
--- /dev/null
@@ -0,0 +1,149 @@
+# 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=.\common.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ldappasswd.c
+# End Source File
+# End Target
+# End Project
index 4b18660b698410979e15dc07c4360a5db103ce3f..e65ca0ca3619c607b582299ea69c3e3355e42ab1 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -11,7 +11,6 @@
 #include <ac/stdlib.h>
 
 #include <ac/ctype.h>
-#include <ac/signal.h>
 #include <ac/string.h>
 #include <ac/unistd.h>
 #include <ac/errno.h>
 #include "ldap_defaults.h"
 #include "ldap_log.h"
 
+#include "common.h"
+
+
+static int scope = LDAP_SCOPE_SUBTREE;
+static int deref = -1;
+static int attrsonly;
+static int timelimit = -1;
+static int sizelimit = -1;
+
 static char *def_tmpdir;
 static char *def_urlpre;
 
-static void
-usage( const char *s )
+
+void
+usage( void )
 {
        fprintf( stderr,
 "usage: %s [options] [filter [attributes...]]\nwhere:\n"
@@ -55,7 +64,24 @@ usage( const char *s )
 "  -A         retrieve attribute names only (no values)\n"
 "  -b basedn  base dn for search\n"
 "  -E [!]<ctrl>[=<ctrlparam>] search controls (! indicates criticality)\n"
-"             [!]mv=<filter>   (matched values filter)\n"
+"             [!]mv=<filter>              (matched values filter)\n"
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+"             [!]pr=<size>                (paged results)\n"
+#endif
+#ifdef LDAP_CONTROL_SUBENTRIES
+"             [!]subentries[=true|false]  (subentries)\n"
+#endif
+#ifdef LDAP_CLIENT_UPDATE
+"             [!]lcup= p/<cint>/<cookie>/<slimit>  (client update)\n"
+/*
+ * "                      s/<cint>/<cookie>  (client update)\n"
+ * "                     sp/<cint>/<cookie>/<slimit>\n"
+ * */
+#endif
+#ifdef LDAP_SYNC
+"             [!]sync= ro[/<cookie>] (ldap sync - refreshOnly)\n"
+"                      rp[/<cookie>][/<slimit>] (ldap sync - refreshAndPersist)\n"
+#endif
 "  -F prefix  URL prefix for files (default: %s)\n"
 "  -l limit   time limit (in seconds) for search\n"
 "  -L         print responses in LDIFv1 format\n"
@@ -69,37 +95,8 @@ usage( const char *s )
 "  -T path    write files to directory specified by path (default: %s)\n"
 "  -u         include User Friendly entry names in the output\n"
 "  -z limit   size limit (in entries) for search\n"
-
-"Common options:\n"
-"  -d level   set LDAP debugging level to `level'\n"
-"  -D binddn  bind DN\n"
-"  -e [!]<ctrl>[=<ctrlparam>] general controls (! indicates criticality)\n"
-"             [!]manageDSAit   (alternate form, see -M)\n"
-"             [!]noop\n"
-"  -f file    read operations from `file'\n"
-"  -h host    LDAP server\n"
-"  -H URI     LDAP Uniform Resource Indentifier(s)\n"
-"  -I         use SASL Interactive mode\n"
-"  -k         use Kerberos authentication\n"
-"  -K         like -k, but do only step 1 of the Kerberos bind\n"
-"  -M         enable Manage DSA IT control (-MM to make critical)\n"
-"  -n         show what would be done but don't actually search\n"
-"  -O props   SASL security properties\n"
-"  -p port    port on LDAP server\n"
-"  -P version procotol version (default: 3)\n"
-"  -Q         use SASL Quiet mode\n"
-"  -R realm   SASL realm\n"
-"  -U authcid SASL authentication identity\n"
-"  -v         run in verbose mode (diagnostics to standard output)\n"
-"  -w passwd  bind passwd (for simple authentication)\n"
-"  -W         prompt for bind passwd\n"
-"  -x         Simple authentication\n"
-"  -X authzid SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
-"  -y file    Read passwd from file\n"
-"  -Y mech    SASL mechanism\n"
-"  -Z         Start TLS request (-ZZ to require successful response)\n"
-, s, def_urlpre, def_tmpdir );
-
+                , prog, def_urlpre, def_tmpdir );
+       tool_common_usage();
        exit( EXIT_FAILURE );
 }
 
@@ -149,24 +146,46 @@ static int dosearch LDAP_P((
 
 static char *tmpdir = NULL;
 static char *urlpre = NULL;
-static char *prog = NULL;
-static char    *binddn = NULL;
-static struct berval passwd = { 0, NULL };
 static char    *base = NULL;
-static char    *ldaphost = NULL;
-static char *ldapuri = NULL;
-static int     ldapport = 0;
-#ifdef HAVE_CYRUS_SASL
-static unsigned sasl_flags = LDAP_SASL_AUTOMATIC;
-static char    *sasl_realm = NULL;
-static char    *sasl_authc_id = NULL;
-static char    *sasl_authz_id = NULL;
-static char    *sasl_mech = NULL;
-static char    *sasl_secprops = NULL;
-#endif
-static int     use_tls = 0;
 static char    *sortattr = NULL;
-static int     verbose, not, includeufn, vals2tmp, ldif;
+static int  includeufn, vals2tmp = 0, ldif = 0;
+
+static int subentries = 0, valuesReturnFilter = 0;
+static char    *vrFilter = NULL;
+
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
+static int lcup = 0;
+static int ldapsync = 0;
+#endif
+
+#ifdef LDAP_CLIENT_UPDATE
+static int lcup_cint = 0;
+static struct berval lcup_cookie = { 0, NULL };
+static int lcup_slimit = -1;
+#endif
+
+#ifdef LDAP_SYNC
+static struct berval sync_cookie = { 0, NULL };
+static int sync_slimit = -1;
+#endif
+
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+static int pagedResults = 0;
+static ber_int_t pageSize = 0;
+static ber_int_t entriesLeft = 0;
+static ber_int_t morePagedResults = 1;
+static struct berval cookie = { 0, NULL };
+static int npagedresponses;
+static int npagedentries;
+static int npagedreferences;
+static int npagedextended;
+static int npagedpartial;
+
+static int parse_page_control(
+       LDAP *ld,
+       LDAPMessage *result,
+       struct berval *cookie );
+#endif
 
 static void
 urlize(char *url)
@@ -181,62 +200,16 @@ urlize(char *url)
        }
 }
 
-int
-main( int argc, char **argv )
-{
-       char            *infile, *filtpattern, **attrs = NULL, line[BUFSIZ];
-       FILE            *fp = NULL;
-       int                     rc, i, first, scope, deref, attrsonly, manageDSAit, noop, crit;
-       int                     referrals, timelimit, sizelimit, debug;
-       int             authmethod, version, want_bindpw;
-       LDAP            *ld = NULL;
-       int             valuesReturnFilter;
-       BerElement      *ber = NULL;
-       struct berval   *bvalp = NULL;
-       char    *vrFilter  = NULL, *control = NULL, *cvalue;
-       char    *pw_file = NULL;
-
 
-       infile = NULL;
-       debug = verbose = not = vals2tmp = referrals = valuesReturnFilter =
-               attrsonly = manageDSAit = noop = ldif = want_bindpw = 0;
+const char options[] = "a:Ab:E:F:l:Ls:S:tT:uz:"
+       "Cd:D:e:f:h:H:IkKMnO:p:P:QR:U:vVw:WxX:y:Y:Z";
 
-       prog = lutil_progname( "ldapsearch", argc, argv );
-
-       lutil_log_initialize(argc, argv);
-
-       deref = sizelimit = timelimit = version = -1;
-
-       scope = LDAP_SCOPE_SUBTREE;
-       authmethod = -1;
-
-       if((def_tmpdir = getenv("TMPDIR")) == NULL &&
-          (def_tmpdir = getenv("TMP")) == NULL &&
-          (def_tmpdir = getenv("TEMP")) == NULL )
-       {
-               def_tmpdir = LDAP_TMPDIR;
-       }
-
-       if ( !*def_tmpdir )
-               def_tmpdir = LDAP_TMPDIR;
-
-       def_urlpre = malloc( sizeof("file:////") + strlen(def_tmpdir) );
-
-       if( def_urlpre == NULL ) {
-               perror( "malloc" );
-               return EXIT_FAILURE;
-       }
-
-       sprintf( def_urlpre, "file:///%s/",
-               def_tmpdir[0] == *LDAP_DIRSEP ? &def_tmpdir[1] : def_tmpdir );
-
-       urlize( def_urlpre );
-
-       while (( i = getopt( argc, argv, "Aa:b:E:F:f:Ll:S:s:T:tuz:"
-               "Cd:e:D:h:H:IkKMnO:p:P:QR:U:vw:WxX:y:Y:Z")) != EOF )
-       {
-       switch( i ) {
-       /* Search Options */
+int
+handle_private_option( int i )
+{
+       int crit;
+       char *control, *cvalue;
+       switch ( i ) {
        case 'a':       /* set alias deref option */
                if ( strcasecmp( optarg, "never" ) == 0 ) {
                deref = LDAP_DEREF_NEVER;
@@ -248,7 +221,7 @@ main( int argc, char **argv )
                deref = LDAP_DEREF_ALWAYS;
                } else {
                fprintf( stderr, "alias deref should be never, search, find, or always\n" );
-               usage(prog);
+               usage();
                }
                break;
        case 'A':       /* retrieve attribute names only -- no values */
@@ -258,10 +231,10 @@ main( int argc, char **argv )
                base = strdup( optarg );
                break;
        case 'E': /* search controls */
-               if( version == LDAP_VERSION2 ) {
+               if( protocol == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -E incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
+                               prog, protocol );
+                       exit( EXIT_FAILURE );
                }
 
                /* should be extended to support comma separated list of
@@ -282,33 +255,172 @@ main( int argc, char **argv )
 
                if ( strcasecmp( control, "mv" ) == 0 ) {
                        /* ValuesReturnFilter control */
-                       if (valuesReturnFilter!=0) {
-                               fprintf( stderr, "ValuesReturnFilter previously specified\n" );
-                               return EXIT_FAILURE;
+                       if( valuesReturnFilter ) {
+                               fprintf( stderr, "ValuesReturnFilter previously specified\n");
+                               exit( EXIT_FAILURE );
                        }
                        valuesReturnFilter= 1 + crit;
 
                        if ( cvalue == NULL ) {
                                fprintf( stderr,
                                        "missing filter in ValuesReturnFilter control\n");
-                               return EXIT_FAILURE;
+                               exit( EXIT_FAILURE );
                        }
 
                        vrFilter = cvalue;
-                       version = LDAP_VERSION3;
-                       break;
+                       protocol = LDAP_VERSION3;
+
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+               } else if ( strcasecmp( control, "pr" ) == 0 ) {
+                       int num, tmp;
+                       /* PagedResults control */
+                       if ( pagedResults != 0 ) {
+                               fprintf( stderr, "PagedResultsControl previously specified\n" );
+                               exit( EXIT_FAILURE );
+                       }
+                       
+                       num = sscanf( cvalue, "%d", &tmp );
+                       if ( num != 1 ) {
+                               fprintf( stderr, "Invalid value for PagedResultsControl, %s.\n", cvalue);
+                               exit( EXIT_FAILURE );
+
+                       }
+                       pageSize = (ber_int_t) tmp;
+                       pagedResults = 1 + crit;
+
+#endif
+#ifdef LDAP_CONTROL_SUBENTRIES
+               } else if ( strcasecmp( control, "subentries" ) == 0 ) {
+                       if( subentries ) {
+                               fprintf( stderr, "subentries control previously specified\n");
+                               exit( EXIT_FAILURE );
+                       }
+                       if( cvalue == NULL || strcasecmp( cvalue, "true") == 0 ) {
+                               subentries = 2;
+                       } else if ( strcasecmp( cvalue, "false") == 0 ) {
+                               subentries = 1;
+                       } else {
+                               fprintf( stderr,
+                                       "subentries control value \"%s\" invalid\n",
+                                       cvalue );
+                               exit( EXIT_FAILURE );
+                       }
+                       if( crit ) subentries *= -1;
+#endif
+
+#ifdef LDAP_CLIENT_UPDATE
+                } else if ( strcasecmp( control, "lcup" ) == 0 ) {
+                        char *cookiep;
+                        char *slimitp;
+                        if ( lcup ) {
+                                fprintf( stderr, "client update control previously specified\n");
+                                exit( EXIT_FAILURE );
+                        }
+                        if ( ldapsync != -1 ) {
+                                fprintf( stderr, "ldap sync control previously specified\n");
+                                exit( EXIT_FAILURE );
+                        }
+                        if ( cvalue == NULL ) {
+                                fprintf( stderr,
+                                        "missing specification of client update control\n");
+                                exit( EXIT_FAILURE );
+                        }
+                        if ( strncasecmp( cvalue, "p", 1 ) == 0 ) {
+                                lcup = LDAP_CUP_PERSIST_ONLY;
+                                cvalue = strchr( cvalue, '/' );
+                                cvalue++;
+                                cookiep = strchr( cvalue, '/' );
+                                *cookiep++ = '\0';
+                                lcup_cint = atoi( cvalue );
+                                cvalue = cookiep;
+                                slimitp = strchr( cvalue, '/' );
+                                *slimitp++ = '\0';
+                                while ( isspace( *cookiep ) ) cookiep++;
+                                ber_str2bv( cookiep, 0, 0, &lcup_cookie );
+                                lcup_slimit = atoi( slimitp );
+/*
+                       } else if ( strncasecmp( cvalue, "s", 1 ) == 0 ) {
+                               lcup = LDAP_CUP_SYNC_ONLY;
+                               cvalue += 2;
+                               cookiep = strchr( cvalue, '/' );
+                               *cookiep++ = '\0';
+                               lcup_cint = atoi( cvalue );
+                               ber_str2bv( cookiep, 0, 0, &lcup_cookie );
+                       } else if ( strncasecmp( cvalue, "sp", 2 ) == 0 ) {
+                               lcup = LDAP_CUP_SYNC_AND_PERSIST;
+                               cvalue += 3;
+                               cookiep = strchr( cvalue, '/' );
+                               *cookiep++ = '\0';
+                               lcup_cint = atoi( cvalue );
+                               cvalue = cookiep;
+                               slimitp = strchr( cvalue, '/' );
+                               *slimitp++ = '\0';
+                               ber_str2bv( cookiep, 0, 0, &lcup_cookie );
+                               lcup_slimit = atoi( slimitp );
+*/
+                       } else {
+                               fprintf( stderr,
+                                       "client update control value \"%s\" invalid\n",
+                                       cvalue );
+                               exit( EXIT_FAILURE );
+                       }
+                       if ( crit ) lcup *= -1;
+#endif
+
+#ifdef LDAP_SYNC
+       } else if ( strcasecmp( control, "sync" ) == 0 ) {
+                       char *cookiep;
+                       char *slimitp;
+                       if ( ldapsync ) {
+                               fprintf( stderr, "ldap sync control previously specified\n" );
+                               exit( EXIT_FAILURE );
+                       }
+                       if ( lcup ) {
+                               fprintf( stderr, "client update control previously specified\n" );
+                               exit( EXIT_FAILURE );
+                       }
+                       if ( cvalue == NULL ) {
+                               fprintf( stderr,
+                                       "missing specification of ldap sync control\n");
+                               exit( EXIT_FAILURE );
+                       }
+                       if ( strncasecmp( cvalue, "ro", 2 ) == 0 ) {
+                               ldapsync = LDAP_SYNC_REFRESH_ONLY;
+                               cookiep = strchr( cvalue, '/' );
+                               if ( cookiep != NULL ) {
+                                       cookiep++;
+                                       if ( *cookiep != '\0' ) {
+                                               ber_str2bv( cookiep, 0, 0, &sync_cookie );
+                                       }
+                               }
+                       } else if ( strncasecmp( cvalue, "rp", 2 ) == 0 ) {
+                               ldapsync = LDAP_SYNC_REFRESH_AND_PERSIST;
+                               cookiep = strchr( cvalue, '/' );
+                               if ( cookiep != NULL ) {
+                                       *cookiep++ = '\0';      
+                                       cvalue = cookiep;
+                               }
+                               slimitp = strchr( cvalue, '/' );
+                               if ( slimitp != NULL ) {
+                                       *slimitp++ = '\0';
+                               }
+                               if ( cookiep != NULL && *cookiep != '\0' )
+                                       ber_str2bv( cookiep, 0, 0, &sync_cookie );
+                               if ( slimitp != NULL && *slimitp != '\0' )
+                                       sync_slimit = atoi( slimitp );
+                       } else {
+                               fprintf( stderr,
+                                       "ldap sync control value \"%s\" invalid\n",
+                                       cvalue );
+                               exit( EXIT_FAILURE );
+                       }
+                       if ( crit ) ldapsync *= -1;
+#endif
 
                } else {
                        fprintf( stderr, "Invalid control name: %s\n", control );
-                       usage(prog);
-                       return EXIT_FAILURE;
+                       usage();
                }
-       case 'f':       /* input file */
-               if( infile != NULL ) {
-                       fprintf( stderr, "%s: -f previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               infile = strdup( optarg );
                break;
        case 'F':       /* uri prefix */
                if( urlpre ) free( urlpre );
@@ -319,7 +431,7 @@ main( int argc, char **argv )
                if( timelimit < 0 ) {
                        fprintf( stderr, "%s: invalid timelimit (%d) specified\n",
                                prog, timelimit );
-                       return EXIT_FAILURE;
+                       exit( EXIT_FAILURE );
                }
                break;
        case 'L':       /* print entries in LDIF format */
@@ -334,15 +446,12 @@ main( int argc, char **argv )
                scope = LDAP_SCOPE_SUBTREE;
                } else {
                fprintf( stderr, "scope should be base, one, or sub\n" );
-               usage(prog);
+               usage();
                }
                break;
        case 'S':       /* sort attribute */
                sortattr = strdup( optarg );
                break;
-       case 'u':       /* include UFN */
-               ++includeufn;
-               break;
        case 't':       /* write attribute values to TMPDIR files */
                ++vals2tmp;
                break;
@@ -350,414 +459,94 @@ main( int argc, char **argv )
                if( tmpdir ) free( tmpdir );
                tmpdir = strdup( optarg );
                break;
+       case 'u':       /* include UFN */
+               ++includeufn;
+               break;
        case 'z':       /* size limit */
                sizelimit = atoi( optarg );
                break;
+       default:
+               return 0;
+       }
+       return 1;
+}
 
-       /* Common Options */
-       case 'C':
-               referrals++;
-               break;
-       case 'd':
-           debug |= atoi( optarg );
-           break;
-       case 'D':       /* bind DN */
-               if( binddn != NULL ) {
-                       fprintf( stderr, "%s: -D previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           binddn = strdup( optarg );
-           break;
-       case 'e': /* general controls */
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -e incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-
-               /* should be extended to support comma separated list of
-                *      [!]key[=value] parameters, e.g.  -e !foo,bar=567
-                */
-
-               crit = 0;
-               cvalue = NULL;
-               if( optarg[0] == '!' ) {
-                       crit = 1;
-                       optarg++;
-               }
-
-               control = strdup( optarg );
-               if ( (cvalue = strchr( control, '=' )) != NULL ) {
-                       *cvalue++ = '\0';
-               }
-
-               if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
-                       if( cvalue != NULL ) {
-                               fprintf( stderr, "manageDSAit: no control value expected\n" );
-                               usage(prog);
-                               return EXIT_FAILURE;
-                       }
 
-                       manageDSAit = 1 + crit;
-                       free( control );
-                       break;
-                       
-               } else if ( strcasecmp( control, "noop" ) == 0 ) {
-                       if( cvalue != NULL ) {
-                               fprintf( stderr, "noop: no control value expected\n" );
-                               usage(prog);
-                               return EXIT_FAILURE;
-                       }
+static void
+private_conn_setup( LDAP *ld )
+{
+       if (deref != -1 &&
+               ldap_set_option( ld, LDAP_OPT_DEREF, (void *) &deref ) != LDAP_OPT_SUCCESS )
+       {
+               fprintf( stderr, "Could not set LDAP_OPT_DEREF %d\n", deref );
+               exit( EXIT_FAILURE );
+       }
+       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 );
+               exit( EXIT_FAILURE );
+       }
+       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 );
+               exit( EXIT_FAILURE );
+       }
+}
 
-                       noop = 1 + crit;
-                       free( control );
-                       break;
 
-               } else {
-                       fprintf( stderr, "Invalid general control name: %s\n", control );
-                       usage(prog);
-                       return EXIT_FAILURE;
-               }
-       case 'h':       /* ldap host */
-               if( ldapuri != NULL ) {
-                       fprintf( stderr, "%s: -h incompatible with -H\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( ldaphost != NULL ) {
-                       fprintf( stderr, "%s: -h previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           ldaphost = strdup( optarg );
-           break;
-       case 'H':       /* ldap URI */
-               if( ldaphost != NULL ) {
-                       fprintf( stderr, "%s: -H incompatible with -h\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( ldapport ) {
-                       fprintf( stderr, "%s: -H incompatible with -p\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( ldapuri != NULL ) {
-                       fprintf( stderr, "%s: -H previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           ldapuri = strdup( optarg );
-           break;
-       case 'I':
-#ifdef HAVE_CYRUS_SASL
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -I incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_flags = LDAP_SASL_INTERACTIVE;
-               break;
-#else
-               fprintf( stderr, "%s: was not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
+int
+main( int argc, char **argv )
+{
+       char            *filtpattern, **attrs = NULL, line[BUFSIZ];
+       FILE            *fp = NULL;
+       int                     rc, i, first;
+       LDAP            *ld = NULL;
+       BerElement      *seber = NULL, *vrber = NULL, *prber = NULL;
+#ifdef LDAP_CLIENT_UPDATE
+       BerElement      *cuber = NULL;
+        struct berval   *cubvalp = NULL;
 #endif
-       case 'k':       /* kerberos bind */
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-               if( version > LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
 
-               if( authmethod != -1 ) {
-                       fprintf( stderr, "%s: -k incompatible with previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-                       
-               authmethod = LDAP_AUTH_KRBV4;
-#else
-               fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
-               return EXIT_FAILURE;
+#ifdef LDAP_SYNC
+       BerElement      *syncber = NULL;
+       struct berval   *syncbvalp = NULL;
 #endif
-           break;
-       case 'K':       /* kerberos bind, part one only */
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-               if( version > LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 ) {
-                       fprintf( stderr, "%s: incompatible with previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
 
-               authmethod = LDAP_AUTH_KRBV41;
-#else
-               fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
-               return( EXIT_FAILURE );
-#endif
-           break;
-       case 'M':
-               /* enable Manage DSA IT */
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -M incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               manageDSAit++;
-               version = LDAP_VERSION3;
-               break;
-       case 'n':       /* print deletes, don't actually do them */
-           ++not;
-           break;
-       case 'O':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_secprops != NULL ) {
-                       fprintf( stderr, "%s: -O previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_secprops = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+       npagedresponses = npagedentries = npagedreferences =
+               npagedextended = npagedpartial = 0;
 #endif
-               break;
-       case 'p':
-               if( ldapport ) {
-                       fprintf( stderr, "%s: -p previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           ldapport = atoi( optarg );
-           break;
-       case 'P':
-               switch( atoi(optarg) ) {
-               case 2:
-                       if( version == LDAP_VERSION3 ) {
-                               fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       version = LDAP_VERSION2;
-                       break;
-               case 3:
-                       if( version == LDAP_VERSION2 ) {
-                               fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       version = LDAP_VERSION3;
-                       break;
-               default:
-                       fprintf( stderr, "%s: protocol version should be 2 or 3\n",
-                               prog );
-                       usage( prog );
-                       return( EXIT_FAILURE );
-               } break;
-       case 'Q':
-#ifdef HAVE_CYRUS_SASL
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -Q incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_flags = LDAP_SASL_QUIET;
-               break;
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-       case 'R':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_realm != NULL ) {
-                       fprintf( stderr, "%s: -R previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -R incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_realm = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'U':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_authc_id != NULL ) {
-                       fprintf( stderr, "%s: -U previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -U incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_authc_id = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'v':       /* verbose mode */
-           verbose++;
-           break;
-       case 'w':       /* password */
-           passwd.bv_val = strdup( optarg );
-               {
-                       char* p;
 
-                       for( p = optarg; *p != '\0'; p++ ) {
-                               *p = '\0';
-                       }
-               }
-               passwd.bv_len = strlen( passwd.bv_val );
-           break;
-       case 'W':
-               want_bindpw++;
-               break;
-       case 'y':
-               pw_file = optarg;
-               break;
-       case 'Y':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_mech != NULL ) {
-                       fprintf( stderr, "%s: -Y previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -Y incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_mech = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'x':
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
-                       fprintf( stderr, "%s: incompatible with previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SIMPLE;
-               break;
-       case 'X':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_authz_id != NULL ) {
-                       fprintf( stderr, "%s: -X previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: -X incompatible with "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_authz_id = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'Z':
-#ifdef HAVE_TLS
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -Z incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               version = LDAP_VERSION3;
-               use_tls++;
-#else
-               fprintf( stderr, "%s: not compiled with TLS support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       default:
-               fprintf( stderr, "%s: unrecognized option -%c\n",
-                       prog, optopt );
-               usage(prog);
-       }
-       }
+       prog = lutil_progname( "ldapsearch", argc, argv );
+
+       lutil_log_initialize(argc, argv);
 
-       if (version == -1) {
-               version = LDAP_VERSION3;
+       if((def_tmpdir = getenv("TMPDIR")) == NULL &&
+          (def_tmpdir = getenv("TMP")) == NULL &&
+          (def_tmpdir = getenv("TEMP")) == NULL )
+       {
+               def_tmpdir = LDAP_TMPDIR;
        }
-       if (authmethod == -1 && version > LDAP_VERSION2) {
-#ifdef HAVE_CYRUS_SASL
-               authmethod = LDAP_AUTH_SASL;
-#else
-               authmethod = LDAP_AUTH_SIMPLE;
-#endif
+
+       if ( !*def_tmpdir )
+               def_tmpdir = LDAP_TMPDIR;
+
+       def_urlpre = malloc( sizeof("file:////") + strlen(def_tmpdir) );
+
+       if( def_urlpre == NULL ) {
+               perror( "malloc" );
+               return EXIT_FAILURE;
        }
 
+       sprintf( def_urlpre, "file:///%s/",
+               def_tmpdir[0] == *LDAP_DIRSEP ? &def_tmpdir[1] : def_tmpdir );
+
+       urlize( def_urlpre );
+
+       tool_args( argc, argv );
+
        if (( argc - optind < 1 ) ||
                ( *argv[optind] != '(' /*')'*/ &&
                ( strchr( argv[optind], '=' ) == NULL ) ) )
@@ -801,93 +590,10 @@ main( int argc, char **argv )
                urlize( urlpre );
        }
 
-       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 );
-               }
-               if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
-                       fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
-               }
+       if ( debug )
                ldif_debug = debug;
-       }
-
-#ifdef SIGPIPE
-       (void) SIGNAL( SIGPIPE, SIG_IGN );
-#endif
-
-       if( ( ldaphost != NULL || ldapport ) && ( ldapuri == NULL ) ) {
-               if ( verbose ) {
-                       fprintf( stderr, "ldap_init( %s, %d )\n",
-                               ldaphost != NULL ? ldaphost : "<DEFAULT>",
-                               ldapport );
-               }
 
-               ld = ldap_init( ldaphost, ldapport );
-               if( ld == NULL ) {
-                       perror("ldapsearch: ldap_init");
-                       return EXIT_FAILURE;
-               }
-
-       } else {
-               if ( verbose ) {
-                       fprintf( stderr, "ldap_initialize( %s )\n",
-                               ldapuri != NULL ? ldapuri : "<DEFAULT>" );
-               }
-
-               rc = ldap_initialize( &ld, ldapuri );
-               if( rc != LDAP_SUCCESS ) {
-                       fprintf( stderr, "Could not create LDAP session handle (%d): %s\n",
-                               rc, ldap_err2string(rc) );
-                       return EXIT_FAILURE;
-               }
-       }
-
-       if (deref != -1 &&
-               ldap_set_option( ld, LDAP_OPT_DEREF, (void *) &deref ) != LDAP_OPT_SUCCESS )
-       {
-               fprintf( stderr, "Could not set LDAP_OPT_DEREF %d\n", deref );
-               return EXIT_FAILURE;
-       }
-       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 );
-               return EXIT_FAILURE;
-       }
-       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 );
-               return EXIT_FAILURE;
-       }
-
-       /* referrals */
-       if (ldap_set_option( ld, LDAP_OPT_REFERRALS,
-               referrals ? LDAP_OPT_ON : LDAP_OPT_OFF ) != LDAP_OPT_SUCCESS )
-       {
-               fprintf( stderr, "Could not set LDAP_OPT_REFERRALS %s\n",
-                       referrals ? "on" : "off" );
-               return EXIT_FAILURE;
-       }
-
-       if (version == -1 ) {
-               version = LDAP_VERSION3;
-       }
-
-       if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version )
-               != LDAP_OPT_SUCCESS )
-       {
-               fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
-                       version );
-               return EXIT_FAILURE;
-       }
-
-       if ( use_tls && ( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS )) {
-               ldap_perror( ld, "ldap_start_tls" );
-               if ( use_tls > 1 ) {
-                       return EXIT_FAILURE;
-               }
-       }
+       ld = tool_conn_setup( 0, &private_conn_setup );
 
        if ( pw_file || want_bindpw ) {
                if ( pw_file ) {
@@ -899,113 +605,149 @@ main( int argc, char **argv )
                }
        }
 
-       if ( authmethod == LDAP_AUTH_SASL ) {
-#ifdef HAVE_CYRUS_SASL
-               void *defaults;
+       tool_bind( ld );
 
-               if( sasl_secprops != NULL ) {
-                       rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
-                               (void *) sasl_secprops );
-                       
-                       if( rc != LDAP_OPT_SUCCESS ) {
-                               fprintf( stderr,
-                                       "Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
-                                       sasl_secprops );
-                               return( EXIT_FAILURE );
-                       }
-               }
-               
-               defaults = lutil_sasl_defaults( ld,
-                       sasl_mech,
-                       sasl_realm,
-                       sasl_authc_id,
-                       passwd.bv_val,
-                       sasl_authz_id );
-
-               rc = ldap_sasl_interactive_bind_s( ld, binddn,
-                       sasl_mech, NULL, NULL,
-                       sasl_flags, lutil_sasl_interact, defaults );
-
-               if( rc != LDAP_SUCCESS ) {
-                       ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
-                       return( EXIT_FAILURE );
-               }
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog);
-               return( EXIT_FAILURE );
+getNextPage:
+       if ( manageDSAit || noop || subentries || valuesReturnFilter
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+                       || pageSize
 #endif
-       } else {
-               if ( ldap_bind_s( ld, binddn, passwd.bv_val, authmethod )
-                               != LDAP_SUCCESS ) {
-                       ldap_perror( ld, "ldap_bind" );
-                       return( EXIT_FAILURE );
-               }
-       }
-
-       if ( manageDSAit || noop || valuesReturnFilter ) {
+#ifdef LDAP_CLIENT_UPDATE
+                       || lcup
+#endif
+#ifdef LDAP_SYNC
+                       || ldapsync
+#endif
+                       ) {
                int err;
                int i=0;
-               LDAPControl c1,c2,c3;
-               LDAPControl *ctrls[4];
-               
-               if ( manageDSAit ) {
-                       ctrls[i++]=&c1;
-                       ctrls[i] = NULL;
+               LDAPControl c[3];
+
+#ifdef LDAP_CONTROL_SUBENTRIES
+               if ( subentries ) {
+               if (( seber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
+                               return EXIT_FAILURE;
+                       }
 
-                       c1.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
-                       c1.ldctl_value.bv_val = NULL;
-                       c1.ldctl_value.bv_len = 0;
-                       c1.ldctl_iscritical = manageDSAit > 1;
+                       err = ber_printf( seber, "{b}", abs(subentries) == 1 ? 0 : 1 );
+               if ( err == -1 ) {
+                               ber_free( seber, 1 );
+                               fprintf( stderr, "Subentries control encoding error!\n" );
+                               return EXIT_FAILURE;
+                       }
+
+                       if ( ber_flatten2( seber, &c[i].ldctl_value, 0 ) == -1 ) {
+                               return EXIT_FAILURE;
+                       }
+
+                       c[i].ldctl_oid = LDAP_CONTROL_SUBENTRIES;
+                       c[i].ldctl_iscritical = subentries < 1;
+                       i++;
                }
+#endif
 
-               if ( noop ) {
-                       ctrls[i++] = &c2;
-                       ctrls[i] = NULL;
+#ifdef LDAP_CLIENT_UPDATE
+                if ( lcup ) {
+                        if (( cuber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
+                                return EXIT_FAILURE;
+                        }
+
+                        if ( lcup_cookie.bv_len == 0 ) {
+                                err = ber_printf( cuber, "{ei}", abs(lcup), lcup_cint );
+                        } else {
+                                err = ber_printf( cuber, "{ei{sO}}", abs(lcup), lcup_cint,
+                                                LDAP_LCUP_COOKIE_OID, &lcup_cookie );
+                        }
+
+                        if ( err == LBER_ERROR ) {
+                                ber_free( cuber, 1 );
+                                fprintf( stderr, "client update control encoding error!\n" );
+                                return EXIT_FAILURE;
+                        }
+
+                        if ( ber_flatten( cuber, &cubvalp ) == LBER_ERROR ) {
+                                return EXIT_FAILURE;
+                        }
+
+                        c[i].ldctl_oid = LDAP_CONTROL_CLIENT_UPDATE;
+                        c[i].ldctl_value = (*cubvalp);
+                        c[i].ldctl_iscritical = lcup < 0;
+                        i++;
+                }
+#endif
 
-                       c2.ldctl_oid = LDAP_CONTROL_NOOP;
-                       c2.ldctl_value.bv_val = NULL;
-                       c2.ldctl_value.bv_len = 0;
-                       c2.ldctl_iscritical = noop > 1;
+#ifdef LDAP_SYNC
+               if ( ldapsync ) {
+                       if (( syncber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
+                               return EXIT_FAILURE;
+                       }
+
+                       if ( sync_cookie.bv_len == 0 ) {
+                               err = ber_printf( syncber, "{e}", abs(ldapsync) );
+                       } else {
+                               err = ber_printf( syncber, "{eO}", abs(ldapsync),
+                                                       &sync_cookie );
+                       }
+
+                       if ( err == LBER_ERROR ) {
+                               ber_free( syncber, 1 );
+                               fprintf( stderr, "ldap sync control encoding error!\n" );
+                               return EXIT_FAILURE;
+                       }
+
+                       if ( ber_flatten( syncber, &syncbvalp ) == LBER_ERROR ) {
+                               return EXIT_FAILURE;
+                       }
+
+                       c[i].ldctl_oid = LDAP_CONTROL_SYNC;
+                       c[i].ldctl_value = (*syncbvalp);
+                       c[i].ldctl_iscritical = ldapsync < 0;
+                       i++;
                }
+#endif
 
                if ( valuesReturnFilter ) {
-                       ctrls[i++]=&c3;
-                       ctrls[i] = NULL;
-
-                       c3.ldctl_oid = LDAP_CONTROL_VALUESRETURNFILTER;
-                       c3.ldctl_iscritical = valuesReturnFilter > 1;
-                   
-               if (( ber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
+               if (( vrber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
                                return EXIT_FAILURE;
                        }
 
-               if ( ( err = ldap_put_vrFilter( ber, vrFilter ) ) == -1 ) {
-                               ber_free( ber, 1 );
+               if ( ( err = ldap_put_vrFilter( vrber, vrFilter ) ) == -1 ) {
+                               ber_free( vrber, 1 );
                                fprintf( stderr, "Bad ValuesReturnFilter: %s\n", vrFilter );
                                return EXIT_FAILURE;
                        }
 
-                       if ( ber_flatten( ber, &bvalp ) == LBER_ERROR ) {
+                       if ( ber_flatten2( vrber, &c[i].ldctl_value, 0 ) == -1 ) {
                                return EXIT_FAILURE;
                        }
 
-                       c3.ldctl_value=(*bvalp);
+                       c[i].ldctl_oid = LDAP_CONTROL_VALUESRETURNFILTER;
+                       c[i].ldctl_iscritical = valuesReturnFilter > 1;
+                       i++;
                }
 
-               err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
-
-               ber_bvfree(bvalp);
-               ber_free( ber, 1 );
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+               if ( pagedResults ) {
+                       if (( prber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
+                               return EXIT_FAILURE;
+                       }
 
-               if( err != LDAP_OPT_SUCCESS ) {
-                       fprintf( stderr, "Could not set %scontrols\n",
-                               (c1.ldctl_iscritical || c2.ldctl_iscritical)
-                               ? "critical " : "" );
-                       if( c1.ldctl_iscritical && c2.ldctl_iscritical ) {
+                       ber_printf( prber, "{iO}", pageSize, &cookie );
+                       if ( ber_flatten2( prber, &c[i].ldctl_value, 0 ) == -1 ) {
                                return EXIT_FAILURE;
                        }
+                       
+                       c[i].ldctl_oid = LDAP_CONTROL_PAGEDRESULTS;
+                       c[i].ldctl_iscritical = pagedResults > 1;
+                       i++;
                }
+#endif
+
+               tool_server_controls( ld, c, i );
+
+               ber_free( seber, 1 );
+               ber_free( vrber, 1 );
+               ber_free( prber, 1 );
        }
        
        if ( verbose ) {
@@ -1035,7 +777,7 @@ main( int argc, char **argv )
                        "# base <%s> with scope %s\n"
                        "# filter%s: %s\n"
                        "# requesting: ",
-                       version,
+                       protocol,
                        base ? base : "", (scope == LDAP_SCOPE_BASE) ? "base"
                                : ((scope == LDAP_SCOPE_ONELEVEL) ? "one" : "sub"),
                        infile != NULL ? " pattern" : "",
@@ -1057,10 +799,22 @@ main( int argc, char **argv )
                        printf("\n# with noop %scontrol",
                                noop > 1 ? "critical " : "" );
                }
+               if ( subentries ) {
+                       printf("\n# with subentries %scontrol: %s",
+                               subentries < 0 ? "critical " : "",
+                               abs(subentries) == 1 ? "false" : "true" );
+               }
                if ( valuesReturnFilter ) {
                        printf("\n# with valuesReturnFilter %scontrol: %s",
                                valuesReturnFilter > 1 ? "critical " : "", vrFilter );
                }
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+               if ( pageSize ) {
+                       printf("\n# with pagedResults %scontrol: size=%d",
+                               (pagedResults > 1) ? "critical " : "", 
+                               pageSize );
+               }
+#endif
 
                printf( "\n#\n\n" );
        }
@@ -1087,6 +841,44 @@ main( int argc, char **argv )
                }
        }
 
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+       if ( ( pageSize != 0 ) && ( morePagedResults != 0 ) ) {
+               char    buf[6];
+               int     i, moreEntries, tmpSize;
+
+               /* Loop to get the next pages when 
+                * enter is pressed on the terminal.
+                */
+               if ( entriesLeft > 0 ) {
+                       printf( "Estimate entries: %d\n", entriesLeft );
+               }
+               printf( "Press [size] Enter for the next {%d|size} entries.\n",
+                       (int)pageSize ); 
+               i = 0;
+               moreEntries = getchar();
+               while ( moreEntries != EOF && moreEntries != '\n' ) { 
+                       if ( i < (int)sizeof(buf) - 1 ) {
+                               buf[i] = moreEntries;
+                               i++;
+                       }
+                       moreEntries = getchar();
+               }
+               buf[i] = '\0';
+
+               if ( i > 0 && isdigit( (unsigned char)buf[0] ) ) {
+                       int num = sscanf( buf, "%d", &tmpSize );
+                       if ( num != 1 ) {
+                               fprintf( stderr, "Invalid value for PagedResultsControl, %s.\n", buf);
+                               return EXIT_FAILURE;
+
+                       }
+                       pageSize = (ber_int_t)tmpSize;
+               }
+
+               goto getNextPage;       
+       }
+#endif
+
        ldap_unbind( ld );
        return( rc );
 }
@@ -1113,7 +905,13 @@ static int dosearch(
        int                     nextended;
        int                     npartial;
        LDAPMessage             *res, *msg;
-       ber_int_t       msgid;
+       ber_int_t               msgid;
+#ifdef LDAP_SYNC
+       char                    *retoid = NULL;
+       struct berval           *retdata = NULL;
+       int                     nresponses_psearch = -1;
+       int                     cancel_msgid = -1;
+#endif
 
        if( filtpatt != NULL ) {
                filter = malloc( strlen( filtpatt ) + strlen( value ) );
@@ -1170,7 +968,11 @@ static int dosearch(
                        msg != NULL;
                        msg = ldap_next_message( ld, msg ) )
                {
-                       if( nresponses++ ) putchar('\n');
+                       if ( nresponses++ ) putchar('\n');
+#if LDAP_SYNC
+                       if ( nresponses_psearch >= 0 ) 
+                               nresponses_psearch++;
+#endif
 
                        switch( ldap_msgtype( msg ) ) {
                        case LDAP_RES_SEARCH_ENTRY:
@@ -1191,6 +993,16 @@ static int dosearch(
                                        /* unsolicited extended operation */
                                        goto done;
                                }
+
+#ifdef LDAP_SYNC
+                               if ( cancel_msgid != -1 &&
+                                               cancel_msgid == ldap_msgid( msg ) ) {
+                                       printf("Cancelled \n");
+                                       printf("cancel_msgid = %d\n", cancel_msgid);
+                                       goto done;
+                               }
+#endif
+
                                break;
 
                        case LDAP_RES_EXTENDED_PARTIAL:
@@ -1200,8 +1012,68 @@ static int dosearch(
 
                        case LDAP_RES_SEARCH_RESULT:
                                rc = print_result( ld, msg, 1 );
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+                               if ( pageSize != 0 ) { 
+                                       rc = parse_page_control( ld, msg, &cookie );
+                               }
+#endif
+
+#ifdef LDAP_CLIENT_UPDATE
+                               if ( lcup == LDAP_CUP_PERSIST_ONLY ||
+                                    lcup == LDAP_CUP_SYNC_AND_PERSIST ) {
+                                       break;
+                               }
+#endif
+#if defined(LDAP_CLIENT_UPDATE) && defined(LDAP_SYNC)
+                               else
+#endif
+#ifdef LDAP_SYNC
+                               if ( ldapsync == LDAP_SYNC_REFRESH_AND_PERSIST ) {
+                                       break;
+                               }
+#endif
+
+                               goto done;
+
+#ifdef LDAP_SYNC
+                       case LDAP_RES_INTERMEDIATE_RESP:
+                               ldap_parse_intermediate_resp_result( ld, msg, &retoid, &retdata, 0 );
+                               nresponses_psearch = 0;
+
+                               if ( strcmp( retoid, LDAP_SYNC_INFO ) ) {
+                                       printf("Unexpected Intermediate Response\n");
+                                       ldap_memfree( retoid );
+                                       ber_bvfree( retdata );
+                                       goto done;
+                               } else {
+                                       printf("SyncInfo Received\n");
+                                       ldap_memfree( retoid );
+                                       ber_bvfree( retdata );
+                                       break;
+                               }
+#endif
+                       }
+
+#ifdef LDAP_CLIENT_UPDATE
+                       if ( lcup && lcup_slimit != -1 && nresponses >= lcup_slimit ) {
+                               ldap_abandon (ld, ldap_msgid(msg));
                                goto done;
                        }
+#endif
+#ifdef LDAP_SYNC
+                       if ( ldapsync && sync_slimit != -1 &&
+                                       nresponses_psearch >= sync_slimit ) {
+                               BerElement *msgidber = NULL;
+                               struct berval *msgidvalp = NULL;
+                               msgidber = ber_alloc_t(LBER_USE_DER);
+                               ber_printf(msgidber, "{i}", msgid);
+                               ber_flatten(msgidber, &msgidvalp);
+                               ldap_extended_operation(ld, LDAP_EXOP_X_CANCEL,
+                                               msgidvalp, NULL, NULL, &cancel_msgid);
+                               nresponses_psearch = -1;
+                       }
+#endif
+
                }
 
                ldap_msgfree( res );
@@ -1213,6 +1085,22 @@ static int dosearch(
        }
 
 done:
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+       if ( pageSize != 0 ) { 
+               npagedresponses = npagedresponses + nresponses;
+               npagedentries = npagedentries + nentries;
+               npagedreferences = npagedreferences + nreferences;
+               npagedextended = npagedextended + nextended;
+               npagedpartial = npagedpartial + npartial;
+               if ( ( morePagedResults == 0 ) && ( ldif < 2 ) ) {
+                       printf( "\n# numResponses: %d\n", npagedresponses );
+                       if( nentries ) printf( "# numEntries: %d\n", npagedentries );
+                       if( nextended ) printf( "# numExtended: %d\n", npagedextended );
+                       if( npartial ) printf( "# numPartial: %d\n", npagedpartial );
+                       if( nreferences ) printf( "# numReferences: %d\n", npagedreferences );
+               }
+       } else
+#endif
        if ( ldif < 2 ) {
                printf( "\n# numResponses: %d\n", nresponses );
                if( nentries ) printf( "# numEntries: %d\n", nentries );
@@ -1335,7 +1223,7 @@ print_entry(
 }
 #else
 /* This is the proposed new way of doing things.
- * It is more efficient, but the API is non-standard.
+ * It is more efficient, but the API is non-standard.
  */
 static void
 print_entry(
@@ -1384,7 +1272,8 @@ print_entry(
 
        if ( attrsonly ) bvp = NULL;
 
-       for ( rc = ldap_get_attribute_ber( ld, entry, ber, &bv, bvp ); rc == LDAP_SUCCESS;
+       for ( rc = ldap_get_attribute_ber( ld, entry, ber, &bv, bvp );
+               rc == LDAP_SUCCESS;
                rc = ldap_get_attribute_ber( ld, entry, ber, &bv, bvp ) )
        {
                if (bv.bv_val == NULL) break;
@@ -1713,3 +1602,72 @@ write_ldif( int type, char *name, char *value, ber_len_t vallen )
 
        return( 0 );
 }
+
+
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+static int 
+parse_page_control(
+       LDAP *ld,
+       LDAPMessage *result,
+       struct berval *cookie )
+{
+       int rc;
+       int err;
+       LDAPControl **ctrl = NULL;
+       LDAPControl *ctrlp = NULL;
+       BerElement *ber;
+       ber_tag_t tag;
+       struct berval servercookie = { 0, NULL };
+
+       rc = ldap_parse_result( ld, result,
+               &err, NULL, NULL, NULL, &ctrl, 0 );
+
+       if( rc != LDAP_SUCCESS ) {
+               ldap_perror(ld, "ldap_parse_result");
+               exit( EXIT_FAILURE );
+       }
+
+       if ( err != LDAP_SUCCESS ) {
+               fprintf( stderr, "%s (%d)\n", ldap_err2string(err), err );
+       }
+
+       if( ctrl ) {
+               /* Parse the control value
+                * searchResult ::= SEQUENCE {
+                *              size    INTEGER (0..maxInt),
+                *                              -- result set size estimate from server - unused
+                *              cookie  OCTET STRING
+                * }
+                */
+               ctrlp = *ctrl;
+               ber = ber_init( &ctrlp->ldctl_value );
+               if ( ber == NULL ) {
+                       fprintf( stderr, "Internal error.\n" );
+                       return EXIT_FAILURE;
+               }
+
+               tag = ber_scanf( ber, "{im}", &entriesLeft, &servercookie );
+               ber_dupbv( cookie, &servercookie );
+               (void) ber_free( ber, 1 );
+
+               if( tag == LBER_ERROR ) {
+                       fprintf( stderr,
+                               "Paged results response control could not be decoded.\n" );
+                       return EXIT_FAILURE;
+               }
+
+               if( entriesLeft < 0 ) {
+                       fprintf( stderr,
+                               "Invalid entries estimate in paged results response.\n" );
+                       return EXIT_FAILURE;
+               }
+
+               ldap_controls_free( ctrl );
+
+       } else {
+               morePagedResults = 0;
+       }
+
+       return err;
+}
+#endif
diff --git a/clients/tools/ldapsearch.dsp b/clients/tools/ldapsearch.dsp
new file mode 100644 (file)
index 0000000..de7f3e9
--- /dev/null
@@ -0,0 +1,153 @@
+# 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=.\common.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ldapsearch.c
+# End Source File
+# End Target
+# End Project
index 245467787bad7258c4a466ed4033e44a9308f5fd..4ccb11aea27992cfcc230538ecd3970cb0968e99 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -11,7 +11,6 @@
 #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 "lutil_ldap.h"
 #include "ldap_defaults.h"
 
-static int     verbose = 0;
+#include "common.h"
 
-static void
-usage(const char *s)
+
+void
+usage( void )
 {
        fprintf(stderr,
 "Issue LDAP Who am I? operation to request user's authzid\n\n"
 "usage: %s [options]\n"
-
-"Common options:\n"
-"  -d level   set LDAP debugging level to `level'\n"
-"  -D binddn  bind DN\n"
-"  -e [!]<ctrl>[=<ctrlparam>] general controls (! indicates criticality)\n"
-"             [!]manageDSAit   (alternate form, see -M)\n"
-"             [!]noop\n"
-"  -f file    read operations from `file'\n"
-"  -h host    LDAP server(s)\n"
-"  -H URI     LDAP Uniform Resource Indentifier(s)\n"
-"  -I         use SASL Interactive mode\n"
-"  -n         show what would be done but don't actually do it\n"
-"  -O props   SASL security properties\n"
-"  -p port    port on LDAP server\n"
-"  -Q         use SASL Quiet mode\n"
-"  -R realm   SASL realm\n"
-"  -U authcid SASL authentication identity\n"
-"  -v         run in verbose mode (diagnostics to standard output)\n"
-"  -w passwd  bind passwd (for simple authentication)\n"
-"  -W         prompt for bind passwd\n"
-"  -x         Simple authentication\n"
-"  -X authzid SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
-"  -y file    Read passwd from file\n"
-"  -Y mech    SASL mechanism\n"
-"  -Z         Start TLS request (-ZZ to require successful response)\n"
-               , s );
-
+               , prog);
+       tool_common_usage();
        exit( EXIT_FAILURE );
 }
 
-int
-main( int argc, char *argv[] )
-{
-       int rc;
-       char    *prog = NULL;
-       char    *ldaphost = NULL;
-       char    *ldapuri = NULL;
 
-       char    *user = NULL;
-       char    *binddn = NULL;
-
-       struct berval passwd = { 0, NULL };
-
-       char    *pw_file = NULL;
-       int             want_bindpw = 0;
-
-       int             not = 0;
-       int             i;
-       int             ldapport = 0;
-       int             debug = 0;
-       int             version = -1;
-       int             authmethod = -1;
-#ifdef HAVE_CYRUS_SASL
-       unsigned        sasl_flags = LDAP_SASL_AUTOMATIC;
-       char            *sasl_realm = NULL;
-       char            *sasl_authc_id = NULL;
-       char            *sasl_authz_id = NULL;
-       char            *sasl_mech = NULL;
-       char            *sasl_secprops = NULL;
-#endif
-       int             use_tls = 0;
-       int             referrals = 0;
-       LDAP           *ld = NULL;
-       int     manageDSAit=0;
-       int noop=0;
-       char    *control, *cvalue;
-       int             crit;
+const char options[] = ""
+       "Cd:D:e:h:H:InO:p:QR:U:vVw:WxX:y:Y:Z";
 
-       int id, code = LDAP_OTHER;
-       LDAPMessage *res;
-       char *matcheddn = NULL, *text = NULL, **refs = NULL;
-       char    *retoid = NULL;
-       struct berval *retdata = NULL;
-
-       prog = lutil_progname( "ldapwhoami", argc, argv );
-
-       while( (i = getopt( argc, argv, 
-               "Cd:D:e:h:H:InO:p:QR:U:vw:WxX:y:Y:Z" )) != EOF )
-       {
-               switch (i) {
+int
+handle_private_option( int i )
+{
+       switch ( i ) {
+#if 0
+               char    *control, *cvalue;
+               int             crit;
        case 'E': /* whoami controls */
-               if( version == LDAP_VERSION2 ) {
+               if( protocol == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -E incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
+                               prog, protocol );
+                       exit( EXIT_FAILURE );
                }
 
                /* should be extended to support comma separated list of
@@ -133,404 +69,37 @@ main( int argc, char *argv[] )
                        *cvalue++ = '\0';
                }
                fprintf( stderr, "Invalid whoami control name: %s\n", control );
-               usage(prog);
-               return EXIT_FAILURE;
-
-       /* Common Options (including options we don't use) */
-       case 'C':
-               referrals++;
-               break;
-       case 'd':
-           debug |= atoi( optarg );
-           break;
-       case 'D':       /* bind DN */
-               if( binddn != NULL ) {
-                       fprintf( stderr, "%s: -D previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           binddn = strdup( optarg );
-           break;
-       case 'e': /* general controls */
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -e incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-
-               /* should be extended to support comma separated list of
-                *      [!]key[=value] parameters, e.g.  -e !foo,bar=567
-                */
-
-               crit = 0;
-               cvalue = NULL;
-               if( optarg[0] == '!' ) {
-                       crit = 1;
-                       optarg++;
-               }
-
-               control = strdup( optarg );
-               if ( (cvalue = strchr( control, '=' )) != NULL ) {
-                       *cvalue++ = '\0';
-               }
-
-               if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
-                       if( cvalue != NULL ) {
-                               fprintf( stderr, "manageDSAit: no control value expected\n" );
-                               usage(prog);
-                               return EXIT_FAILURE;
-                       }
+               usage();
+#endif
 
-                       manageDSAit = 1 + crit;
-                       free( control );
-                       break;
-                       
-               } else if ( strcasecmp( control, "noop" ) == 0 ) {
-                       if( cvalue != NULL ) {
-                               fprintf( stderr, "noop: no control value expected\n" );
-                               usage(prog);
-                               return EXIT_FAILURE;
-                       }
+       default:
+               return 0;
+       }
+       return 1;
+}
 
-                       noop = 1 + crit;
-                       free( control );
-                       break;
 
-               } else {
-                       fprintf( stderr, "Invalid general control name: %s\n", control );
-                       usage(prog);
-                       return EXIT_FAILURE;
-               }
-       case 'h':       /* ldap host */
-               if( ldapuri != NULL ) {
-                       fprintf( stderr, "%s: -h incompatible with -H\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( ldaphost != NULL ) {
-                       fprintf( stderr, "%s: -h previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           ldaphost = strdup( optarg );
-           break;
-       case 'H':       /* ldap URI */
-               if( ldaphost != NULL ) {
-                       fprintf( stderr, "%s: -H incompatible with -h\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( ldapport ) {
-                       fprintf( stderr, "%s: -H incompatible with -p\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( ldapuri != NULL ) {
-                       fprintf( stderr, "%s: -H previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           ldapuri = strdup( optarg );
-           break;
-       case 'I':
-#ifdef HAVE_CYRUS_SASL
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -I incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_flags = LDAP_SASL_INTERACTIVE;
-               break;
-#else
-               fprintf( stderr, "%s: was not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-       case 'k':       /* kerberos bind */
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-               if( version > LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
+int
+main( int argc, char *argv[] )
+{
+       int rc;
+       char    *user = NULL;
 
-               if( authmethod != -1 ) {
-                       fprintf( stderr, "%s: -k incompatible with previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-                       
-               authmethod = LDAP_AUTH_KRBV4;
-#else
-               fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
-               return EXIT_FAILURE;
-#endif
-           break;
-       case 'K':       /* kerberos bind, part one only */
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-               if( version > LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 ) {
-                       fprintf( stderr, "%s: incompatible with previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
+       LDAP           *ld = NULL;
 
-               authmethod = LDAP_AUTH_KRBV41;
-#else
-               fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
-               return( EXIT_FAILURE );
-#endif
-           break;
-       case 'n':       /* print deletes, don't actually do them */
-           ++not;
-           break;
-       case 'O':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_secprops != NULL ) {
-                       fprintf( stderr, "%s: -O previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_secprops = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'p':
-               if( ldapport ) {
-                       fprintf( stderr, "%s: -p previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-           ldapport = atoi( optarg );
-           break;
-       case 'P':
-               switch( atoi(optarg) ) {
-               case 2:
-                       if( version == LDAP_VERSION3 ) {
-                               fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       version = LDAP_VERSION2;
-                       break;
-               case 3:
-                       if( version == LDAP_VERSION2 ) {
-                               fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
-                                       prog, version );
-                               return EXIT_FAILURE;
-                       }
-                       version = LDAP_VERSION3;
-                       break;
-               default:
-                       fprintf( stderr, "%s: protocol version should be 2 or 3\n",
-                               prog );
-                       usage( prog );
-                       return( EXIT_FAILURE );
-               } break;
-       case 'Q':
-#ifdef HAVE_CYRUS_SASL
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -Q incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_flags = LDAP_SASL_QUIET;
-               break;
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-       case 'R':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_realm != NULL ) {
-                       fprintf( stderr, "%s: -R previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -R incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_realm = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'U':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_authc_id != NULL ) {
-                       fprintf( stderr, "%s: -U previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -U incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible previous "
-                               "authentication choice\n",
-                               prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_authc_id = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'v':       /* verbose mode */
-           verbose++;
-           break;
-       case 'w':       /* password */
-           passwd.bv_val = strdup( optarg );
-               {
-                       char* p;
-
-                       for( p = optarg; *p != '\0'; p++ ) {
-                               *p = '\0';
-                       }
-               }
-               passwd.bv_len = strlen( passwd.bv_val );
-           break;
-       case 'W':
-               want_bindpw++;
-               break;
-       case 'y':
-               pw_file = optarg;
-               break;
-       case 'Y':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_mech != NULL ) {
-                       fprintf( stderr, "%s: -Y previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -Y incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_mech = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'x':
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
-                       fprintf( stderr, "%s: incompatible with previous "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SIMPLE;
-               break;
-       case 'X':
-#ifdef HAVE_CYRUS_SASL
-               if( sasl_authz_id != NULL ) {
-                       fprintf( stderr, "%s: -X previously specified\n", prog );
-                       return EXIT_FAILURE;
-               }
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
-                       fprintf( stderr, "%s: -X incompatible with "
-                               "authentication choice\n", prog );
-                       return EXIT_FAILURE;
-               }
-               authmethod = LDAP_AUTH_SASL;
-               version = LDAP_VERSION3;
-               sasl_authz_id = strdup( optarg );
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
-       case 'Z':
-#ifdef HAVE_TLS
-               if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s: -Z incompatible with version %d\n",
-                               prog, version );
-                       return EXIT_FAILURE;
-               }
-               version = LDAP_VERSION3;
-               use_tls++;
-#else
-               fprintf( stderr, "%s: not compiled with TLS support\n",
-                       prog );
-               return( EXIT_FAILURE );
-#endif
-               break;
+       char *matcheddn = NULL, *text = NULL, **refs = NULL;
+       char    *retoid = NULL;
+       struct berval *retdata = NULL;
 
+       prog = lutil_progname( "ldapwhoami", argc, argv );
 
-               default:
-                       fprintf( stderr, "%s: unrecognized option -%c\n",
-                               prog, optopt );
-                       usage (prog);
-               }
-       }
+       /* LDAPv3 only */
+       protocol = LDAP_VERSION3;
 
-       if (authmethod == -1) {
-#ifdef HAVE_CYRUS_SASL
-               authmethod = LDAP_AUTH_SASL;
-#else
-               authmethod = LDAP_AUTH_SIMPLE;
-#endif
-       }
+       tool_args( argc, argv );
 
        if( argc - optind > 1 ) {
-               usage( prog );
+               usage();
        } else if ( argc - optind == 1 ) {
                user = strdup( argv[optind] );
        } else {
@@ -547,187 +116,19 @@ main( int argc, char *argv[] )
                }
        }
 
-       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 );
-               }
-               if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
-                       fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
-               }
-       }
-
-#ifdef SIGPIPE
-       (void) SIGNAL( SIGPIPE, SIG_IGN );
-#endif
-
-       /* connect to server */
-       if( ( ldaphost != NULL || ldapport ) && ( ldapuri == NULL ) ) {
-               if ( verbose ) {
-                       fprintf( stderr, "ldap_init( %s, %d )\n",
-                               ldaphost != NULL ? ldaphost : "<DEFAULT>",
-                               ldapport );
-               }
+       ld = tool_conn_setup( 0, 0 );
 
-               ld = ldap_init( ldaphost, ldapport );
-               if( ld == NULL ) {
-                       perror("ldapwhoami: ldap_init");
-                       return EXIT_FAILURE;
-               }
-
-       } else {
-               if ( verbose ) {
-                       fprintf( stderr, "ldap_initialize( %s )\n",
-                               ldapuri != NULL ? ldapuri : "<DEFAULT>" );
-               }
-
-               rc = ldap_initialize( &ld, ldapuri );
-               if( rc != LDAP_SUCCESS ) {
-                       fprintf( stderr, "Could not create LDAP session handle (%d): %s\n",
-                               rc, ldap_err2string(rc) );
-                       return EXIT_FAILURE;
-               }
-       }
-
-       /* referrals */
-       if (ldap_set_option( ld, LDAP_OPT_REFERRALS,
-               referrals ? LDAP_OPT_ON : LDAP_OPT_OFF ) != LDAP_OPT_SUCCESS )
-       {
-               fprintf( stderr, "Could not set LDAP_OPT_REFERRALS %s\n",
-                       referrals ? "on" : "off" );
-               return EXIT_FAILURE;
-       }
-
-       /* LDAPv3 only */
-       version = LDAP_VERSION3;
-       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 );
-               return EXIT_FAILURE;
-       }
-
-       if ( use_tls && ( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS )) {
-               ldap_perror( ld, "ldap_start_tls" );
-               if ( use_tls > 1 ) {
-                       return( EXIT_FAILURE );
-               }
-       }
-
-       if ( authmethod == LDAP_AUTH_SASL ) {
-#ifdef HAVE_CYRUS_SASL
-               void *defaults;
-
-               if( sasl_secprops != NULL ) {
-                       rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
-                               (void *) sasl_secprops );
-                       
-                       if( rc != LDAP_OPT_SUCCESS ) {
-                               fprintf( stderr,
-                                       "Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
-                                       sasl_secprops );
-                               return( EXIT_FAILURE );
-                       }
-               }
-               
-               defaults = lutil_sasl_defaults( ld,
-                       sasl_mech,
-                       sasl_realm,
-                       sasl_authc_id,
-                       passwd.bv_val,
-                       sasl_authz_id );
-
-               rc = ldap_sasl_interactive_bind_s( ld, binddn,
-                       sasl_mech, NULL, NULL,
-                       sasl_flags, lutil_sasl_interact, defaults );
-
-               if( rc != LDAP_SUCCESS ) {
-                       ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
-                       return( EXIT_FAILURE );
-               }
-#else
-               fprintf( stderr, "%s: not compiled with SASL support\n",
-                       prog );
-               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 );
-               }
-       }
+       tool_bind( ld );
 
        if ( not ) {
                rc = LDAP_SUCCESS;
                goto skip;
        }
 
-       if ( manageDSAit || noop ) {
-               int err, i = 0;
-               LDAPControl c1, c2;
-               LDAPControl *ctrls[3];
-
-               if ( manageDSAit ) {
-                       ctrls[i++] = &c1;
-                       ctrls[i] = NULL;
-                       c1.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
-                       c1.ldctl_value.bv_val = NULL;
-                       c1.ldctl_value.bv_len = 0;
-                       c1.ldctl_iscritical = manageDSAit > 1;
-               }
-
-               if ( noop ) {
-                       ctrls[i++] = &c2;
-                       ctrls[i] = NULL;
-
-                       c2.ldctl_oid = LDAP_CONTROL_NOOP;
-                       c2.ldctl_value.bv_val = NULL;
-                       c2.ldctl_value.bv_len = 0;
-                       c2.ldctl_iscritical = noop > 1;
-               }
-       
-               err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
-
-               if( err != LDAP_OPT_SUCCESS ) {
-                       fprintf( stderr, "Could not set %scontrols\n",
-                               (c1.ldctl_iscritical || c2.ldctl_iscritical)
-                               ? "critical " : "" );
-                       if ( c1.ldctl_iscritical && c2.ldctl_iscritical ) {
-                               return EXIT_FAILURE;
-                       }
-               }
-       }
-
-       rc = ldap_extended_operation( ld,
-               LDAP_EXOP_X_WHO_AM_I, NULL, 
-               NULL, NULL, &id );
+       if ( authzid || manageDSAit || noop )
+               tool_server_controls( ld, NULL, 0 );
 
-       if( rc != LDAP_SUCCESS ) {
-               ldap_perror( ld, "ldap_extended_operation" );
-               ldap_unbind( ld );
-               return EXIT_FAILURE;
-       }
-
-       rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, NULL, &res );
-       if ( rc < 0 ) {
-               ldap_perror( ld, "ldappasswd: ldap_result" );
-               return rc;
-       }
-
-       rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, NULL, 0 );
-
-       if( rc != LDAP_SUCCESS ) {
-               ldap_perror( ld, "ldap_parse_result" );
-               return rc;
-       }
-
-       rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 );
-
-       if( rc != LDAP_SUCCESS ) {
-               ldap_perror( ld, "ldap_parse_result" );
-               return rc;
-       }
+       rc = ldap_whoami_s( ld, &retdata, NULL, NULL ); 
 
        if( retdata != NULL ) {
                if( retdata->bv_len == 0 ) {
@@ -737,8 +138,8 @@ main( int argc, char *argv[] )
                }
        }
 
-       if( verbose || ( code != LDAP_SUCCESS ) || matcheddn || text || refs ) {
-               printf( "Result: %s (%d)\n", ldap_err2string( code ), code );
+       if( verbose || ( rc != LDAP_SUCCESS ) || matcheddn || text || refs ) {
+               printf( "Result: %s (%d)\n", ldap_err2string( rc ), rc );
 
                if( text && *text ) {
                        printf( "Additional info: %s\n", text );
@@ -766,5 +167,5 @@ skip:
        /* disconnect from server */
        ldap_unbind (ld);
 
-       return code == LDAP_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;
+       return rc == LDAP_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index 5e44a4fc7c976bc1654c58aca8ec8aed87e3f803..c4bdaa014a9db5b18059ec48115808238347932b 100644 (file)
@@ -139,6 +139,10 @@ LINK32=link.exe
 # Name "ldapwhoami - Win32 Single Release"
 # Begin Source File
 
+SOURCE=.\common.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\ldapwhoami.c
 # End Source File
 # End Target
index e8bb29d46a1d5e47847d99ae3cad185a17527766..05468f43c82df654d5ae4a1aa1826b8ef4f2804d 100644 (file)
@@ -143,7 +143,6 @@ LDAP_BEGIN_DECL
 #define LDAP_OPT_X_SASL_SSF_MAX                        0x6108
 #define        LDAP_OPT_X_SASL_MAXBUFSIZE              0x6109
 
-
 /* on/off values */
 #define LDAP_OPT_ON            ((void *) 1)
 #define LDAP_OPT_OFF   ((void *) 0)
@@ -181,16 +180,59 @@ typedef struct ldapcontrol {
 } LDAPControl;
 
 /* LDAP Controls */
-
-#define LDAP_CONTROL_MANAGEDSAIT       "2.16.840.1.113730.3.4.2"
+#define LDAP_CONTROL_VALUESRETURNFILTER "1.2.826.0.1.334810.2.3"
+#define LDAP_CONTROL_SUBENTRIES                "1.3.6.1.4.1.4203.1.10.1"
 #define LDAP_CONTROL_NOOP                      "1.3.6.1.4.1.4203.1.10.2"
+#define LDAP_CONTROL_MANAGEDSAIT       "2.16.840.1.113730.3.4.2"
+#define LDAP_CONTROL_PROXY_AUTHZ       "2.16.840.1.113730.3.4.18"
+
+#if 0
+#define LDAP_CONTROL_DUPENT_REQUEST            "2.16.840.1.113719.1.27.101.1"
+#define LDAP_CONTROL_DUPENT_RESPONSE   "2.16.840.1.113719.1.27.101.2"
+#define LDAP_CONTROL_DUPENT_ENTRY              "2.16.840.1.113719.1.27.101.3"
+#define LDAP_CONTROL_DUPENT    LDAP_CONTROL_DUPENT_REQUEST
+#endif
+
+#ifdef LDAP_DEVEL
+#define LDAP_CONTROL_PAGEDRESULTS      "1.2.840.113556.1.4.319"
+#endif
+
+#ifdef LDAP_DEVEL
+#define LDAP_CLIENT_UPDATE 1
+#define LDAP_SYNC 2
+#endif
+
+#ifdef LDAP_CLIENT_UPDATE
+#define LDAP_CONTROL_CLIENT_UPDATE             "1.3.6.1.4.1.4203.666.5.3"
+#define LDAP_CONTROL_ENTRY_UPDATE              "1.3.6.1.4.1.4203.666.5.4"
+#define LDAP_CONTROL_CLIENT_UPDATE_DONE                "1.3.6.1.4.1.4203.666.5.5"
+#define LDAP_LCUP_COOKIE_OID                   "1.3.6.1.4.1.4203.666.10.1"
+#endif
+
+#ifdef LDAP_SYNC
+#define LDAP_CONTROL_SYNC                      "1.3.6.1.4.1.4203.666.5.6"
+#define LDAP_CONTROL_SYNC_STATE                        "1.3.6.1.4.1.4203.666.5.7"
+#define LDAP_CONTROL_SYNC_DONE                 "1.3.6.1.4.1.4203.666.5.8"
+#define LDAP_SYNC_INFO                         "1.3.6.1.4.1.4203.666.10.2"
+
+#define LDAP_SYNC_REFRESH_DONE         0
+#define LDAP_SYNC_NEW_COOKIE           1
+
+#define LDAP_SYNC_PRESENT              0
+#define LDAP_SYNC_ADD                  1
+#define LDAP_SYNC_MODIFY               2
+#define LDAP_SYNC_DELETE               3
+#endif
 
 #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"
 
-#define LDAP_CONTROL_VALUESRETURNFILTER "1.2.826.0.1.334810.2.3"
+#ifdef LDAP_DEVEL
+#define LDAP_CONTROL_PERMITMODIFY "1.2.840.113556.1.4.1413"
+#define LDAP_CONTROL_NOREFERRALS "1.2.840.113556.1.4.1339"
+#endif
 
 /* LDAP Unsolicited Notifications */
 #define        LDAP_NOTICE_OF_DISCONNECTION    "1.3.6.1.4.1.1466.20036"
@@ -205,6 +247,9 @@ typedef struct ldapcontrol {
 #define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW        ((ber_tag_t) 0x82U)
 #define LDAP_TAG_EXOP_MODIFY_PASSWD_GEN        ((ber_tag_t) 0x80U)
 
+#ifdef LDAP_DEVEL
+#define LDAP_EXOP_X_CANCEL             "1.3.6.1.4.1.4203.666.6.3"
+#endif
 #define LDAP_EXOP_X_WHO_AM_I   "1.3.6.1.4.1.4203.1.11.3"
 
 /* LDAP Features */
@@ -238,8 +283,10 @@ 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)     /* octet string */
 #define LDAP_TAG_LDAPCRED      ((ber_tag_t) 0x04U)     /* octet 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 */
 
@@ -252,6 +299,15 @@ typedef struct ldapcontrol {
 
 #define LDAP_TAG_SASL_RES_CREDS        ((ber_tag_t) 0x87U)     /* context specific + primitive */
 
+#ifdef LDAP_CLIENT_UPDATE
+#define LDAP_TAG_INTERVAL      ((ber_tag_t) 0x02U)     /* integer */
+#define LDAP_LCUP_TAG_COOKIE   ((ber_tag_t) 0x30U)     /* sequence */
+#endif
+
+#ifdef LDAP_SYNC
+#define LDAP_SYNC_TAG_COOKIE   ((ber_tag_t) 0x04U)     /* octet string */
+#endif
+
 
 /* possible operations a client can invoke */
 #define LDAP_REQ_BIND                  ((ber_tag_t) 0x60U)     /* application + constructed */
@@ -281,6 +337,9 @@ typedef struct ldapcontrol {
 #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 */
+#ifdef LDAP_DEVEL
+#define LDAP_RES_INTERMEDIATE_RESP     ((ber_tag_t) 0x7aU)
+#endif
 
 #define LDAP_RES_ANY                   (-1)
 #define LDAP_RES_UNSOLICITED   (0)
@@ -426,6 +485,47 @@ typedef struct ldapcontrol {
 #define LDAP_CLIENT_LOOP                               0x60    /* draft-ietf-ldap-c-api-xx */
 #define LDAP_REFERRAL_LIMIT_EXCEEDED   0x61    /* draft-ietf-ldap-c-api-xx */
 
+#ifdef LDAP_CLIENT_UPDATE
+/* resultCode for LCUP */
+#define LDAP_CUP_RESOURCES_EXHAUSTED   0x100
+#define LDAP_CUP_SECURITY_VIOLATION            0x101
+#define LDAP_CUP_INVALID_COOKIE                        0x102
+#define LDAP_CUP_UNSUPPORTED_SCHEME            0x103
+#define LDAP_CUP_CLIENT_DISCONNECT             0x104
+#define LDAP_CUP_RELOAD_REQUIRED               0x105
+#endif
+
+#ifdef LDAP_EXOP_X_CANCEL
+/* resultCode for Cancel Response */
+#define LDAP_CANCELLED                                 0x110
+#define LDAP_NO_SUCH_OPERATION                 0x111
+#define LDAP_TOO_LATE                                  0x112
+#define LDAP_CANNOT_CANCEL                             0x113
+
+#define LDAP_CANCEL_NONE                               0x00
+#define LDAP_CANCEL_REQ                                        0x01
+#define LDAP_CANCEL_ACK                                        0x02
+#define LDAP_CANCEL_DONE                               0x03
+#endif
+
+#ifdef LDAP_CLIENT_UPDATE
+/* LCUP update type */
+#define LDAP_CUP_NONE                                  0x00
+#define LDAP_CUP_SYNC_ONLY                             0x01
+#define LDAP_CUP_PERSIST_ONLY                  0x02
+#define LDAP_CUP_SYNC_AND_PERSIST              0x03
+
+/* LCUP default cookie interval */
+#define LDAP_CUP_DEFAULT_SEND_COOKIE_INTERVAL  0x01
+#endif /* LDAP_CLIENT_UPDATE */
+
+/* LDAP SYNC request type */
+#ifdef LDAP_SYNC
+#define LDAP_SYNC_NONE                                 0x00
+#define LDAP_SYNC_REFRESH_ONLY                 0x01
+#define LDAP_SYNC_REFRESH_AND_PERSIST  0x03
+#endif
+
 /*
  * This structure represents both ldap messages and ldap responses.
  * These are really the same, except in the case of search responses,
@@ -1131,9 +1231,9 @@ typedef struct ldap_ava {
        struct berval la_attr;
        struct berval la_value;
        unsigned la_flags;
-#define LDAP_AVA_STRING                0x0000U
-#define LDAP_AVA_BINARY                0x0001U
-#define LDAP_AVA_NONPRINTABLE  0x0002U
+#define LDAP_AVA_STRING                                0x0000U
+#define LDAP_AVA_BINARY                                0x0001U
+#define LDAP_AVA_NONPRINTABLE          0x0002U
 
        void *la_private;
 } LDAPAVA;
@@ -1142,28 +1242,25 @@ typedef LDAPAVA** LDAPRDN;
 typedef LDAPRDN** LDAPDN;
 
 /* DN formats */
-#define LDAP_DN_FORMAT_LDAP            0x0000U
+#define LDAP_DN_FORMAT_LDAP                    0x0000U
 #define LDAP_DN_FORMAT_LDAPV3          0x0010U
 #define LDAP_DN_FORMAT_LDAPV2          0x0020U
-#define LDAP_DN_FORMAT_DCE             0x0030U
-#define LDAP_DN_FORMAT_UFN             0x0040U /* dn2str only */
+#define LDAP_DN_FORMAT_DCE                     0x0030U
+#define LDAP_DN_FORMAT_UFN                     0x0040U /* dn2str only */
 #define LDAP_DN_FORMAT_AD_CANONICAL    0x0050U /* dn2str only */
-#define LDAP_DN_FORMAT_LBER            0x00F0U /* for testing only */
-#define LDAP_DN_FORMAT_MASK            0x00F0U
+#define LDAP_DN_FORMAT_LBER                    0x00F0U /* for testing only */
+#define LDAP_DN_FORMAT_MASK                    0x00F0U
 
 /* DN flags */
-#define LDAP_DN_PRETTY                 0x0100U
-#define LDAP_DN_SKIP                   0x0200U
+#define LDAP_DN_PRETTY                         0x0100U
+#define LDAP_DN_SKIP                           0x0200U
 #define LDAP_DN_P_NOLEADTRAILSPACES    0x1000U
 #define LDAP_DN_P_NOSPACEAFTERRDN      0x2000U
-#define LDAP_DN_PEDANTIC               0xF000U
+#define LDAP_DN_PEDANTIC                       0xF000U
 
-LDAP_F( void )
-ldap_avafree LDAP_P(( LDAPAVA *ava ));
-LDAP_F( void )
-ldap_rdnfree LDAP_P(( LDAPRDN *rdn ));
-LDAP_F( void )
-ldap_dnfree LDAP_P(( LDAPDN *dn ));
+LDAP_F( void ) ldap_avafree LDAP_P(( LDAPAVA *ava ));
+LDAP_F( void ) ldap_rdnfree LDAP_P(( LDAPRDN *rdn ));
+LDAP_F( void ) ldap_dnfree LDAP_P(( LDAPDN *dn ));
 
 LDAP_F( int )
 ldap_bv2dn LDAP_P(( 
index 93942cd0c8683c1b95288eac5f9b1242eb37a239..7efd54231b3bafbacbd0c392929c5e009178d3a6 100644 (file)
 #      include <stddef.h>
 #endif
 
+#ifndef LDAP_REL_ENG
+#if (LDAP_VENDOR_VERSION == 000000) && !defined(LDAP_DEVEL)
+#define LDAP_DEVEL
+#endif
 #if defined(LDAP_DEVEL) && !defined(LDAP_TEST)
 #define LDAP_TEST
 #endif
 #if defined(LDAP_TEST) && !defined(LDAP_DEBUG)
 #define LDAP_DEBUG
 #endif
+#endif
 
 #ifdef HAVE_EBCDIC 
 /* ASCII/EBCDIC converting replacements for stdio funcs
index 234744aaeb93ae202719eabb950ba35db78b2c46..7dc2fa82b537134f1334045ae10247094a35bbbd 100644 (file)
@@ -1,7 +1,7 @@
 /* io.c - ber general i/o routines */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* Portions
@@ -362,24 +362,21 @@ ber_init( struct berval *bv )
 
 /* New C-API ber_flatten routine */
 /* This routine allocates a struct berval whose contents are a BER
-** encoding taken from the ber argument.  The bvPtr pointer pointers to
+** encoding taken from the ber argument.  The bvPtr pointer points to
 ** the returned berval.
+**
+** ber_flatten2 is the same, but uses a struct berval passed by
+** the caller. If alloc is 0 the returned bv uses the ber buf directly.
 */
-int ber_flatten(
+int ber_flatten2(
        BerElement *ber,
-       struct berval **bvPtr)
+       struct berval *bv,
+       int alloc )
 {
-       struct berval *bv;
-       assert( bvPtr != NULL );
-
-    ber_int_options.lbo_valid = LBER_INITIALIZED;
+       assert( bv != NULL );
 
-       if(bvPtr == NULL) {
-               return -1;
-       }
+       ber_int_options.lbo_valid = LBER_INITIALIZED;
 
-       bv = LBER_MALLOC( sizeof(struct berval) );
        if ( bv == NULL ) {
                return -1;
        }
@@ -393,21 +390,49 @@ int ber_flatten(
                /* copy the berval */
                ber_len_t len = ber_pvt_ber_write( ber );
 
-               bv->bv_val = (char *) LBER_MALLOC( len + 1 );
-               if ( bv->bv_val == NULL ) {
-                       LBER_FREE( bv );
-                       return -1;
+               if ( alloc ) {
+                       bv->bv_val = (char *) LBER_MALLOC( len + 1 );
+                       if ( bv->bv_val == NULL ) {
+                               return -1;
+                       }
+                       AC_MEMCPY( bv->bv_val, ber->ber_buf, len );
+               } else {
+                       bv->bv_val = ber->ber_buf;
                }
-
-               AC_MEMCPY( bv->bv_val, ber->ber_buf, len );
                bv->bv_val[len] = '\0';
                bv->bv_len = len;
        }
-    
-       *bvPtr = bv;
        return 0;
 }
 
+int ber_flatten(
+       BerElement *ber,
+       struct berval **bvPtr)
+{
+       struct berval *bv;
+       int rc;
+       assert( bvPtr != NULL );
+
+       ber_int_options.lbo_valid = LBER_INITIALIZED;
+
+       if(bvPtr == NULL) {
+               return -1;
+       }
+
+       bv = LBER_MALLOC( sizeof(struct berval) );
+       if ( bv == NULL ) {
+               return -1;
+       }
+       rc = ber_flatten2(ber, bv, 1);
+       if (rc == -1) {
+               LBER_FREE(bv);
+       } else {
+               *bvPtr = bv;
+       }
+       return rc;
+}
+
 void
 ber_reset( BerElement *ber, int was_writing )
 {
index 5ffd498120e968fab8a00d57fb7f11318c394526..07a627249211196c8af4e741044f7a0aa1d27407 100644 (file)
@@ -14,7 +14,7 @@ SRCS  = bind.c open.c result.c error.c compare.c search.c \
        sasl.c sbind.c kbind.c unbind.c \
        filter.c free.c sort.c \
        getdn.c getentry.c getattr.c getvalues.c addentry.c \
-       request.c os-ip.c url.c sortctrl.c vlvctrl.c \
+       request.c os-ip.c url.c sortctrl.c vlvctrl.c whoami.c \
        init.c options.c print.c string.c util-int.c schema.c \
        charray.c tls.c os-local.c dnssrv.c utf-8.c utf-8-conv.c
 OBJS   = bind.lo open.lo result.lo error.lo compare.lo search.lo \
@@ -23,7 +23,7 @@ OBJS  = bind.lo open.lo result.lo error.lo compare.lo search.lo \
        sasl.lo sbind.lo kbind.lo unbind.lo \
        filter.lo free.lo sort.lo \
        getdn.lo getentry.lo getattr.lo getvalues.lo addentry.lo \
-       request.lo os-ip.lo url.lo sortctrl.lo vlvctrl.lo \
+       request.lo os-ip.lo url.lo sortctrl.lo vlvctrl.lo whoami.lo \
        init.lo options.lo print.lo string.lo util-int.lo schema.lo \
        charray.lo tls.lo os-local.lo dnssrv.lo utf-8.lo utf-8-conv.lo
 
index 69a7ec5bb39f4a3404b85027f4a4df7c504ab5c8..5c0a2cfe73064c15eca8c22cabf44822b5276e17 100644 (file)
@@ -43,8 +43,8 @@ int ldap_dn2domain(
        LDAPRDN *rdn = NULL;
        LDAPAVA *ava = NULL;
        struct berval domain = { 0, NULL };
-       const static struct berval DC = BER_BVC("DC");
-       const static struct berval DCOID = BER_BVC("0.9.2342.19200300.100.1.25");
+       static const struct berval DC = BER_BVC("DC");
+       static const struct berval DCOID = BER_BVC("0.9.2342.19200300.100.1.25");
 
        assert( dn_in != NULL );
        assert( domainp != NULL );
index 7aa9d4666701341d7585a3e20467c186e77a9751..faad577502ba9f9696972badc55ab00395f42603 100644 (file)
@@ -92,6 +92,22 @@ static struct ldaperror ldap_builtin_errlist[] = {
        {LDAP_CLIENT_LOOP,                              "Client Loop" },
        {LDAP_REFERRAL_LIMIT_EXCEEDED,  "Referral Limit Exceeded" },
 
+#ifdef LDAP_CLIENT_UPDATE
+       {LDAP_CUP_RESOURCES_EXHAUSTED,  "Client Update Resource Exhausted" },
+       {LDAP_CUP_SECURITY_VIOLATION,   "Client Update Security Violation" },
+       {LDAP_CUP_INVALID_COOKIE,               "Client Update Invalid Cookie" },
+       {LDAP_CUP_UNSUPPORTED_SCHEME,   "Client Update Unsupported Scheme" },
+       {LDAP_CUP_CLIENT_DISCONNECT,    "Client Update Client Disconnect" },
+       {LDAP_CUP_RELOAD_REQUIRED,              "Client Update Reload Required" },
+#endif
+
+#ifdef LDAP_EXOP_X_CANCEL
+       {LDAP_CANCELLED,                                "Cancelled" },
+       {LDAP_NO_SUCH_OPERATION,                "No Operation to Cancel" },
+       {LDAP_TOO_LATE,                                 "Too Late to Cancel" },
+       {LDAP_CANNOT_CANCEL,                    "Cannot Cancel" },
+#endif
+
        {-1, NULL}
 };
 
index 3789720d880d82b92df1cb470adef44aaae2341c..64463e59d8de6ed76999c47c792dd9bb7ad21586 100644 (file)
@@ -393,3 +393,120 @@ free_and_return:
 
        return LDAP_SUCCESS;
 }
+
+#ifdef LDAP_RES_INTERMEDIATE_RESP
+/* Parse an intermediate response result */
+int
+ldap_parse_intermediate_resp_result (
+       LDAP                    *ld,
+       LDAPMessage             *res,
+       char                    **retoidp,
+       struct berval           **retdatap,
+       int                     freeit )
+{
+       BerElement *ber;
+       ber_tag_t rc;
+       ber_tag_t tag;
+       ber_len_t len;
+       struct berval *resdata;
+       ber_int_t errcode;
+       char *resoid;
+
+       assert( ld != NULL );
+       assert( LDAP_VALID( ld ) );
+       assert( res != NULL );
+
+#ifdef NEW_LOGGING
+       LDAP_LOG ( OPERATION, ENTRY, "ldap_parse_intermediate_resp_result\n", 0,0,0 );
+#else
+       Debug( LDAP_DEBUG_TRACE, "ldap_parse_intermediate_resp_result\n", 0, 0, 0 );
+#endif
+
+       if( ld->ld_version < LDAP_VERSION3 ) {
+               ld->ld_errno = LDAP_NOT_SUPPORTED;
+               return ld->ld_errno;
+       }
+
+       if( res->lm_msgtype != LDAP_RES_INTERMEDIATE_RESP ) {
+               ld->ld_errno = LDAP_PARAM_ERROR;
+               return ld->ld_errno;
+       }
+
+       if( retoidp != NULL ) *retoidp = NULL;
+       if( retdatap != NULL ) *retdatap = NULL;
+
+       if ( ld->ld_error ) {
+               LDAP_FREE( ld->ld_error );
+               ld->ld_error = NULL;
+       }
+
+       if ( ld->ld_matched ) {
+               LDAP_FREE( ld->ld_matched );
+               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_error );
+
+       if( rc == LBER_ERROR ) {
+               ld->ld_errno = LDAP_DECODING_ERROR;
+               ber_free( ber, 0 );
+               return ld->ld_errno;
+       }
+
+       resoid = NULL;
+       resdata = NULL;
+
+       tag = ber_peek_tag( ber, &len );
+
+       if( tag == LDAP_TAG_EXOP_RES_OID ) {
+               /* we have a resoid */
+               if( ber_scanf( ber, "a", &resoid ) == 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_VALUE ) {
+               /* we have a resdata */
+               if( ber_scanf( ber, "O", &resdata ) == LBER_ERROR ) {
+                       ld->ld_errno = LDAP_DECODING_ERROR;
+                       ber_free( ber, 0 );
+                       if( resoid != NULL ) LDAP_FREE( resoid );
+                       return ld->ld_errno;
+               }
+       }
+
+       ber_free( ber, 0 );
+
+       if( retoidp != NULL ) {
+               *retoidp = resoid;
+       } else {
+               LDAP_FREE( resoid );
+       }
+
+       if( retdatap != NULL ) {
+               *retdatap = resdata;
+       } else {
+               ber_bvfree( resdata );
+       }
+
+       ld->ld_errno = errcode;
+
+       if( freeit ) {
+               ldap_msgfree( res );
+       }
+
+       return LDAP_SUCCESS;
+}
+#endif
index ec0aa4883e4fdb8614d34873dcaa2efdfe3458e9..e7ce4396740974f921edf5bf8d1590c0b2970ac9 100644 (file)
@@ -511,6 +511,11 @@ LDAP_F (int) ldap_url_parselist LDAP_P((
        LDAPURLDesc **ludlist,
        const char *url ));
 
+LDAP_F (int) ldap_url_parselist_ext LDAP_P((
+       LDAPURLDesc **ludlist,
+       const char *url,
+       const char *sep ));
+
 LDAP_F (int) ldap_url_parsehosts LDAP_P((
        LDAPURLDesc **ludlist,
        const char *hosts,
index 0c3f186f7c38dd69d82a9871383f843389592e3f..01e51e7ba8679bba367512fccda5d96f69cfec73 100644 (file)
@@ -340,8 +340,7 @@ ldap_int_open_connection(
 #endif
 
 #ifdef LDAP_CONNECTIONLESS
-       if( proto == LDAP_PROTO_UDP )
-               return 0;
+       if( proto == LDAP_PROTO_UDP ) return 0;
 #endif
 
 #ifdef HAVE_CYRUS_SASL
@@ -351,10 +350,17 @@ ldap_int_open_connection(
                ldap_int_sasl_open( ld, conn, sasl_host );
                LDAP_FREE( sasl_host );
        }
+#ifdef LDAP_PF_LOCAL
        if( proto == LDAP_PROTO_IPC ) {
-               ldap_int_sasl_external( ld, conn, "nobody", LDAP_PVT_SASL_LOCAL_SSF );
+               char authid[sizeof("uidNumber=4294967295,gidNumber=4294967295,"
+                       "cn=peercred,cn=external,cn=auth")];
+               sprintf( authid, "uidNumber=%d,gidNumber=%d,"
+                       "cn=peercred,cn=external,cn=auth",
+                       (int) geteuid(), (int) getegid() );
+               ldap_int_sasl_external( ld, conn, authid, LDAP_PVT_SASL_LOCAL_SSF );
        }
 #endif
+#endif
 
 #ifdef HAVE_TLS
        if (ld->ld_options.ldo_tls_mode == LDAP_OPT_X_TLS_HARD ||
index 2695143365a3252e83afc83e4e3db37c424ac21f..913a9cb80602ea93e4ffc5bda2c2aa5611f12573 100644 (file)
@@ -645,7 +645,11 @@ retry_ber:
         * 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) ) {
+       if ( (tag != LDAP_RES_SEARCH_ENTRY) && (v3ref > -1)
+#ifdef LDAP_RES_INTERMEDIATE_RESP
+               && (tag != LDAP_RES_INTERMEDIATE_RESP )
+#endif
+       ) {
                /* For a v3 search referral/reference, only come here if already chased it */
                if ( ld->ld_version >= LDAP_VERSION2 &&
                        ( lr->lr_parent != NULL ||
index 19cc3f6e942ffb23f39496ad9a799bf0766332bf..7a053dfeb875f36a44ad06bef2d61f904e1e043c 100644 (file)
@@ -105,7 +105,7 @@ ldap_sasl_bind(
                        ld->ld_version, dn, LDAP_AUTH_SIMPLE,
                        cred );
                
-       } else if ( cred == NULL ) {
+       } else if ( cred == NULL || cred->bv_val == NULL ) {
                /* SASL bind w/o creditials */
                rc = ber_printf( ber, "{it{ist{sN}N}" /*}*/,
                        ++ld->ld_msgid, LDAP_REQ_BIND,
index 4a38c3f5d4d5f3556b2f020891724e19aedbcf56..d093739a6d8d17c6db7d0d251ae32f2bef8bd39d 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  *
  * tls.c - Handle tls/ssl using SSLeay or OpenSSL.
@@ -15,6 +15,7 @@
 #include <ac/errno.h>
 #include <ac/socket.h>
 #include <ac/string.h>
+#include <ac/ctype.h>
 #include <ac/time.h>
 #include <ac/unistd.h>
 #include <ac/param.h>
@@ -950,12 +951,24 @@ ldap_pvt_tls_get_peer_hostname( void *s )
        return p;
 }
 
+/* what kind of hostname were we given? */
+#define        IS_DNS  0
+#define        IS_IP4  1
+#define        IS_IP6  2
+
 int
 ldap_pvt_tls_check_hostname( LDAP *ld, void *s, const char *name_in )
 {
        int i, ret = LDAP_LOCAL_ERROR;
        X509 *x;
        const char *name;
+       char *ptr;
+       int ntype = IS_DNS;
+#ifdef LDAP_PF_INET6
+       struct in6_addr addr;
+#else
+       struct in_addr addr;
+#endif
 
        if( ldap_int_hostname &&
                ( !name_in || !strcasecmp( name_in, "localhost" ) ) )
@@ -982,6 +995,20 @@ ldap_pvt_tls_check_hostname( LDAP *ld, void *s, const char *name_in )
                return LDAP_SUCCESS;
        }
 
+#ifdef LDAP_PF_INET6
+       if (name[0] == '[' && strchr(name, ']')) {
+               char *n2 = ldap_strdup(name+1);
+               *strchr(n2, ']') = 2;
+               if (inet_pton(AF_INET6, n2, &addr))
+                       ntype = IS_IP6;
+               LDAP_FREE(n2);
+       } else 
+#endif
+       if ((ptr = strrchr(name, '.')) && isdigit((unsigned char)ptr[1])) {
+               if (inet_aton(name, (struct in_addr *)&addr))
+                       ntype = IS_IP4;
+       }
+       
        i = X509_get_ext_by_NID(x, NID_subject_alt_name, -1);
        if (i >= 0) {
                X509_EXTENSION *ex;
@@ -990,21 +1017,27 @@ ldap_pvt_tls_check_hostname( LDAP *ld, void *s, const char *name_in )
                ex = X509_get_ext(x, i);
                alt = X509V3_EXT_d2i(ex);
                if (alt) {
-                       int n, len1, len2 = 0;
-                       char *domain;
+                       int n, len1 = 0, len2 = 0;
+                       char *domain = NULL;
                        GENERAL_NAME *gn;
 
-                       len1 = strlen(name);
-                       n = sk_GENERAL_NAME_num(alt);
-                       domain = strchr(name, '.');
-                       if (domain) {
-                               len2 = len1 - (domain-name);
+                       if (ntype == IS_DNS) {
+                               len1 = strlen(name);
+                               domain = strchr(name, '.');
+                               if (domain) {
+                                       len2 = len1 - (domain-name);
+                               }
                        }
+                       n = sk_GENERAL_NAME_num(alt);
                        for (i=0; i<n; i++) {
+                               char *sn;
+                               int sl;
                                gn = sk_GENERAL_NAME_value(alt, i);
                                if (gn->type == GEN_DNS) {
-                                       char *sn = ASN1_STRING_data(gn->d.ia5);
-                                       int sl = ASN1_STRING_length(gn->d.ia5);
+                                       if (ntype != IS_DNS) continue;
+
+                                       sn = ASN1_STRING_data(gn->d.ia5);
+                                       sl = ASN1_STRING_length(gn->d.ia5);
 
                                        /* Is this an exact match? */
                                        if ((len1 == sl) && !strncasecmp(name, sn, len1)) {
@@ -1013,19 +1046,34 @@ ldap_pvt_tls_check_hostname( LDAP *ld, void *s, const char *name_in )
 
                                        /* Is this a wildcard match? */
                                        if ((*sn == '*') && domain && (len2 == sl-1) &&
-                                               !strncasecmp(domain, sn+1, len2))
-                                       {
+                                               !strncasecmp(domain, sn+1, len2)) {
                                                break;
                                        }
 
 #if 0
-                                       /* Is this a RFC 2549 style wildcard match? */
+                                       /* Is this a RFC 2459 style wildcard match? */
                                        if ((*sn == '.') && domain && (len2 == sl) &&
-                                               !strncasecmp(domain, sn, len2))
-                                       {
+                                               !strncasecmp(domain, sn, len2)) {
                                                break;
                                        }
 #endif
+                               } else if (gn->type == GEN_IPADD) {
+                                       if (ntype == IS_DNS) continue;
+
+                                       sn = ASN1_STRING_data(gn->d.ia5);
+                                       sl = ASN1_STRING_length(gn->d.ia5);
+
+#ifdef LDAP_PF_INET6
+                                       if (ntype == IS_IP6 && sl != sizeof(struct in6_addr)) {
+                                               continue;
+                                       } else
+#endif
+                                       if (ntype == IS_IP4 && sl != sizeof(struct in_addr)) {
+                                               continue;
+                                       }
+                                       if (!memcmp(sn, &addr, sl)) {
+                                               break;
+                                       }
                                }
                        }
 
@@ -1345,9 +1393,11 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
        /* 
         * compare host with name(s) in certificate
         */
-       ld->ld_errno = ldap_pvt_tls_check_hostname( ld, ssl, host );
-       if (ld->ld_errno != LDAP_SUCCESS) {
-               return ld->ld_errno;
+       if (tls_opt_require_cert != LDAP_OPT_X_TLS_NEVER) {
+               ld->ld_errno = ldap_pvt_tls_check_hostname( ld, ssl, host );
+               if (ld->ld_errno != LDAP_SUCCESS) {
+                       return ld->ld_errno;
+               }
        }
 
        /*
@@ -1375,7 +1425,7 @@ tls_info_cb( const SSL *ssl, int where, int ret )
 {
        int w;
        char *op;
-       char *state = (char *) SSL_state_string_long( ssl );
+       char *state = (char *) SSL_state_string_long( (SSL *)ssl );
 
        w = where & ~SSL_ST_MASK;
        if ( w & SSL_ST_CONNECT ) {
index 8bf8bd56d56f7a9d86cb7d1c5f897c48a86f49af..06c06e5617db13a85c56e7034c2ec955da6586fa 100644 (file)
@@ -880,6 +880,12 @@ ldap_url_duplist (LDAPURLDesc *ludlist)
 
 int
 ldap_url_parselist (LDAPURLDesc **ludlist, const char *url )
+{
+       return ldap_url_parselist_ext( ludlist, url, ", " );
+}
+
+int
+ldap_url_parselist_ext (LDAPURLDesc **ludlist, const char *url, const char *sep )
 {
        int i, rc;
        LDAPURLDesc *ludp;
@@ -890,7 +896,7 @@ ldap_url_parselist (LDAPURLDesc **ludlist, const char *url )
 
        *ludlist = NULL;
 
-       urls = ldap_str2charray(url, ", ");
+       urls = ldap_str2charray(url, sep);
        if (urls == NULL)
                return LDAP_NO_MEMORY;
 
@@ -1042,9 +1048,13 @@ ldap_url_list2urls(
        /* 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);
-               if (strchr(ludp->lud_host, ':'))        /* will add [ ] below */
-                       size += 2;
+               size += strlen(ludp->lud_scheme);
+               if ( ludp->lud_host ) {
+                       size += strlen(ludp->lud_host);
+                       /* will add [ ] below */
+                       if (strchr(ludp->lud_host, ':'))
+                               size += 2;
+               }
                size += sizeof(":/// ");
 
                if (ludp->lud_port != 0) {
@@ -1059,9 +1069,11 @@ ldap_url_list2urls(
 
        p = s;
        for (ludp = ludlist; ludp != NULL; ludp = ludp->lud_next) {
-               p += sprintf(p,
-                            strchr(ludp->lud_host, ':') ? "%s://[%s]" : "%s://%s",
-                            ludp->lud_scheme, ludp->lud_host);
+               p += sprintf(p, "%s://", ludp->lud_scheme);
+               if ( ludp->lud_host ) {
+                       p += sprintf(p, strchr(ludp->lud_host, ':') 
+                                       ? "[%s]" : "%s", ludp->lud_host);
+               }
                if (ludp->lud_port != 0)
                        p += sprintf(p, ":%d", ludp->lud_port);
                *p++ = '/';
diff --git a/libraries/libldap/whoami.c b/libraries/libldap/whoami.c
new file mode 100644 (file)
index 0000000..4698199
--- /dev/null
@@ -0,0 +1,89 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/stdlib.h>
+#include <ac/string.h>
+#include <ac/time.h>
+
+#include "ldap-int.h"
+
+/*
+ * LDAP Who Am I? (Extended) Operation <draft-zeilenga-ldap-authzid-xx.txt>
+ */
+
+int ldap_parse_whoami(
+       LDAP *ld,
+       LDAPMessage *res,
+       struct berval **authzid )
+{
+       int rc;
+       char *retoid = NULL;
+
+       assert( ld != NULL );
+       assert( LDAP_VALID( ld ) );
+       assert( res != NULL );
+       assert( authzid != NULL );
+
+       *authzid = NULL;
+
+       rc = ldap_parse_extended_result( ld, res, &retoid, authzid, 0 );
+
+       if( rc != LDAP_SUCCESS ) {
+               ldap_perror( ld, "ldap_parse_whoami" );
+               return rc;
+       }
+
+       ber_memfree( retoid );
+       return rc;
+}
+
+int
+ldap_whoami( LDAP *ld,
+       LDAPControl             **sctrls,
+       LDAPControl             **cctrls,
+       int                             *msgidp )
+{
+       int rc;
+
+       assert( ld != NULL );
+       assert( LDAP_VALID( ld ) );
+       assert( msgidp != NULL );
+
+       rc = ldap_extended_operation( ld, LDAP_EXOP_X_WHO_AM_I,
+               NULL, sctrls, cctrls, msgidp );
+
+       return rc;
+}
+
+int
+ldap_whoami_s(
+       LDAP *ld,
+       struct berval **authzid,
+       LDAPControl **sctrls,
+       LDAPControl **cctrls )
+{
+       int             rc;
+       int             msgid;
+       LDAPMessage     *res;
+
+       rc = ldap_whoami( ld, sctrls, cctrls, &msgid );
+       if ( rc != LDAP_SUCCESS ) return rc;
+
+       if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 ) {
+               return ld->ld_errno;
+       }
+
+       rc = ldap_parse_whoami( ld, res, authzid );
+       if( rc != LDAP_SUCCESS ) {
+               ldap_msgfree( res );
+               return rc;
+       }
+
+       return( ldap_result2error( ld, res, 1 ) );
+}
diff --git a/libraries/libldap_r/thr_cthreads.c b/libraries/libldap_r/thr_cthreads.c
new file mode 100644 (file)
index 0000000..e4e7dbc
--- /dev/null
@@ -0,0 +1,155 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2002 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.
+ */
+
+/* thr_cthreads.c - wrapper for mach cthreads */
+
+#include "portable.h"
+
+#if defined( HAVE_MACH_CTHREADS )
+#include "ldap_pvt_thread.h"
+
+/***********************************************************************
+ *                                                                     *
+ * under NEXTSTEP or OPENSTEP use CThreads                             *
+ * lukeh@xedoc.com.au                                                  *
+ *                                                                     *
+ ***********************************************************************/
+
+int
+ldap_int_thread_initialize( void )
+{
+       return 0;
+}
+
+int
+ldap_int_thread_destroy( void )
+{
+       return 0;
+}
+
+int 
+ldap_pvt_thread_create( ldap_pvt_thread_t * thread, 
+       int detach,
+       void *(*start_routine)( void *), void *arg)
+{
+       *thread = cthread_fork( (cthread_fn_t) start_routine, arg);
+       return ( *thread == NULL ? -1 : 0 );    
+}
+
+void 
+ldap_pvt_thread_exit( void *retval )
+{
+       cthread_exit( (any_t) retval );
+}
+
+int 
+ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
+{
+       void *status;
+       status = (void *) cthread_join ( thread );
+       if (thread_return != NULL)
+               {
+               *thread_return = status;
+               }
+       return 0;
+}
+
+int 
+ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo )
+{
+       return 0;
+}
+
+int 
+ldap_pvt_thread_yield( void )
+{
+       cthread_yield();
+       return 0;
+}
+
+int 
+ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond )
+{
+       condition_init( cond );
+       return( 0 );
+}
+
+int 
+ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cond )
+{
+       condition_clear( cond );
+       return( 0 );
+}
+
+int 
+ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
+{
+       condition_signal( cond );
+       return( 0 );
+}
+
+int
+ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond )
+{
+       condition_broadcast( cond );
+       return( 0 );
+}
+
+int 
+ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, 
+                         ldap_pvt_thread_mutex_t *mutex )
+{
+       condition_wait( cond, mutex );
+       return( 0 );    
+}
+
+int 
+ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex )
+{
+       mutex_init( mutex );
+       mutex->name = NULL;
+       return ( 0 );
+}
+
+int 
+ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex )
+{
+       mutex_clear( mutex );
+       return ( 0 );   
+}
+       
+int 
+ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
+{
+       mutex_lock( mutex );
+       return ( 0 );
+}
+
+int 
+ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
+{
+       mutex_unlock( mutex );
+       return ( 0 );
+}
+
+int
+ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex )
+{
+       return mutex_try_lock( mutex );
+}
+
+ldap_pvt_thread_t
+ldap_pvt_thread_self( void )
+{
+       return cthread_self();
+}
+
+#endif /* HAVE_MACH_CTHREADS */
diff --git a/libraries/libldap_r/thr_lwp.c b/libraries/libldap_r/thr_lwp.c
new file mode 100644 (file)
index 0000000..d869213
--- /dev/null
@@ -0,0 +1,373 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2002 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.
+ */
+
+/* thr_lwp.c - wrappers around SunOS LWP threads */
+
+/* BUGS:
+ * - slurpd calls the get_stack/free_stack functions. Should be fixed, so
+ *   they can become static.
+ */
+
+#include "portable.h"
+
+#if defined( HAVE_LWP )
+
+/*************
+ *           *
+ * SunOS LWP *
+ *           *
+ *************/
+
+/* This implementation NEEDS WORK.   It currently does not compile */
+
+#include <stdio.h>
+
+#include <ac/time.h>
+#include <ac/socket.h>
+
+#include "ldap-int.h"
+
+#include "ldap_pvt_thread.h"
+
+#include <lwp/lwp.h>
+#include <lwp/stackdep.h>
+
+#define MAX_STACK      51200
+#define MAX_THREADS    20
+
+/*
+ * Initialize LWP by spinning of a schedular
+ */
+int
+ldap_int_thread_initialize( void )
+{
+       thread_t                tid;
+       stkalign_t              *stack;
+       int                     stackno;
+
+       if (( stack = get_stack( &stackno )) == NULL ) {
+               return -1;
+       }
+
+       lwp_create( &tid, lwp_scheduler, MINPRIO, 0, stack, 1, stackno );
+       return 0;
+}
+
+int
+ldap_int_thread_destroy( void )
+{
+       /* need to destory lwp_scheduler thread and clean up private
+               variables */
+       return 0;
+}
+
+struct stackinfo {
+       int             stk_inuse;
+       stkalign_t      *stk_stack;
+};
+
+static struct stackinfo        *stacks;
+
+static stkalign_t * ldap_int_thread_get_stack( int *stacknop )
+{
+       int     i;
+
+       if ( stacks == NULL ) {
+               stacks = (struct stackinfo *) LDAP_CALLOC( 1, MAX_THREADS *
+                   sizeof(struct stackinfo) );
+
+               if( stacks == NULL ) {
+                       Debug( LDAP_DEBUG_ANY, "stacks allocation failed",
+                               0, 0, 0 );
+                       return NULL;
+               }
+       }
+
+       for ( i = 0; i < MAX_THREADS; i++ ) {
+               if ( stacks[i].stk_inuse == 0 ) {
+                       break;
+               }
+       }
+
+       if ( i == MAX_THREADS ) {
+               Debug( LDAP_DEBUG_ANY,
+                   "no more stacks (max %d) - increase MAX_THREADS for more",
+                   MAX_THREADS, 0, 0 );
+               return( NULL );
+       }
+
+       if ( stacks[i].stk_stack == NULL ) {
+               stacks[i].stk_stack = (stkalign_t *) LDAP_MALLOC(
+                   (MAX_STACK / sizeof(stkalign_t) + 1 )
+                   * sizeof(stkalign_t) );
+
+               if( stacks[i].stk_stack == NULL ) {
+                       Debug( LDAP_DEBUG_ANY, "stack allocation failed",
+                               0, 0, 0 );
+                       return( NULL );
+               }
+       }
+
+       *stacknop = i;
+       stacks[i].stk_inuse = 1;
+       return( stacks[i].stk_stack + MAX_STACK / sizeof(stkalign_t) );
+}
+
+static void
+ldap_int_thread_free_stack( int        stackno )
+{
+       if ( stackno < 0 || stackno > MAX_THREADS ) {
+               Debug( LDAP_DEBUG_ANY, "free_stack of bogus stack %d\n",
+                   stackno, 0, 0 );
+       }
+
+       stacks[stackno].stk_inuse = 0;
+}
+
+static void
+lwp_create_stack( void *(*func)(), void *arg, int stackno )
+{
+       (*func)( arg );
+
+       ldap_int_thread_free_stack( stackno );
+}
+
+int 
+ldap_pvt_thread_create( ldap_pvt_thread_t * thread, 
+       int detach,
+       void *(*start_routine)( void *),
+       void *arg)
+{
+       stkalign_t      *stack;
+       int             stackno;
+
+       if ( (stack = ldap_int_thread_get_stack( &stackno )) == NULL ) {
+               return( -1 );
+       }
+       return( lwp_create( thread, lwp_create_stack, MINPRIO, 0, 
+                          stack, 3, start_routine, arg, stackno ) );
+}
+
+void 
+ldap_pvt_thread_exit( void *retval )
+{
+       lwp_destroy( SELF );
+}
+
+unsigned int
+ldap_pvt_thread_sleep(
+       unsigned int interval
+)
+{
+       thread_t                mylwp;
+       tl_t            *t, *nt;
+       time_t          now;
+
+
+       if ( lwp_self( &mylwp ) < 0 ) {
+               return -1;
+       }
+
+       time( &now );
+
+       mon_enter( &sglob->tsl_mon );
+
+       if ( sglob->tsl_list != NULL ) {
+               for ( t = sglob->tsl_list; t != NULL; t = t->tl_next ) {
+                       if ( SAMETHREAD( t->tl_tid, mylwp )) {
+                               /* We're already sleeping? */
+                               t->tl_wake = now + interval;
+                               mon_exit( &sglob->tsl_mon );
+                               lwp_suspend( mylwp );
+                               return 0;
+                       }
+               }
+       }
+
+       nt = (tl_t *) LDAP_MALLOC( sizeof( tl_t ));
+
+       if( nt == NULL ) return -1;
+
+       nt->tl_next = sglob->tsl_list;
+       nt->tl_wake = now + interval;
+       nt->tl_tid = mylwp;
+       sglob->tsl_list = nt;
+
+       mon_exit( &sglob->tsl_mon );
+
+       lwp_suspend( mylwp );
+       return 0;
+}
+
+/*
+ * The lwp_scheduler thread periodically checks to see if any threads
+ * are due to be resumed.  If there are, it resumes them.  Otherwise,
+ * it computes the lesser of ( 1 second ) or ( the minimum time until
+ * a thread need to be resumed ) and puts itself to sleep for that amount
+ * of time.
+ */
+static void
+lwp_scheduler(
+       int             stackno
+)
+{
+       time_t                  now, min;
+       struct timeval          interval;
+       tl_t                    *t;
+
+       while ( !sglob->slurpd_shutdown ) {
+               mon_enter( &sglob->tsl_mon );
+
+               time( &now );
+               min = 0L;
+               if ( sglob->tsl_list != NULL ) {
+                       for ( t = sglob->tsl_list; t != NULL; t = t->tl_next ) {
+                               if (( t->tl_wake  > 0L ) && ( t->tl_wake < now )) {
+                                       lwp_resume( t->tl_tid );
+                                       t->tl_wake = 0L;
+                               }
+
+                               if (( t->tl_wake > now ) && ( t->tl_wake < min )) {
+                                       min =  t->tl_wake;
+                               }
+                       }
+               }
+
+               mon_exit( &sglob->tsl_mon );
+
+               interval.tv_usec = 0L;
+               if ( min == 0L ) {
+                       interval.tv_sec = 1L;
+               } else {
+                       interval.tv_sec = min;
+               }
+
+               lwp_sleep( &interval );
+       }
+
+       mon_enter( &sglob->tsl_mon );
+
+       for ( t = sglob->tsl_list; t != NULL; t = t->tl_next ) {
+               lwp_resume( t->tl_tid );
+       }
+
+       mon_exit( &sglob->tsl_mon );
+
+       free_stack( stackno );
+}
+
+int 
+ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
+{
+       lwp_join( thread );
+       return 0;
+}
+
+int 
+ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo )
+{
+       return 0;
+}
+
+int 
+ldap_pvt_thread_yield( void )
+{
+       lwp_yield( SELF );
+       return 0;
+}
+
+int 
+ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond )
+{
+       /*
+        * lwp cv_create requires the monitor id be passed in
+        * when the cv is created, pthreads passes it when the
+        * condition is waited for.  so, we fake the creation
+        * here and actually do it when the cv is waited for
+        * later.
+        */
+
+       cond->lcv_created = 0;
+
+       return( 0 );
+}
+
+int 
+ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
+{
+       return( cond->lcv_created ? cv_notify( cv->lcv_cv ) : 0 );
+}
+
+int 
+ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, 
+       ldap_int_thread_mutex_t *mutex )
+{
+       if ( ! cond->lcv_created ) {
+               cv_create( &cond->lcv_cv, *mutex );
+               cond->lcv_created = 1;
+       }
+
+       return( cv_wait( cond->lcv_cv ) );      
+}
+
+int 
+ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex )
+{
+       return( mon_create( mutex ) );
+}
+
+int 
+ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex )
+{
+       return( mon_destroy( *mutex ) );
+}
+
+int 
+ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
+{
+       return( mon_enter( *mutex ) );
+}
+
+int 
+ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
+{
+       return( mon_exit( *mutex ) );
+}
+
+int
+ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mp )
+{
+       return( mon_cond_enter( *mp ) );
+}
+
+int
+ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cv )
+{
+       return( cv->lcv_created ? cv_destroy( cv->lcv_cv ) : 0 );
+}
+
+int
+ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cv )
+{
+       return( cv->lcv_created ? cv_broadcast( cv->lcv_cv ) : 0 );
+}
+
+ldap_pvt_thread_t
+ldap_pvt_thread_self( void )
+{
+       thread_t                mylwp;
+
+       lwp_self( &mylwp );
+
+       return mylwp;
+}
+
+#endif /* HAVE_LWP */
index b818538a859f0048cbc076420a0c825b26082560..8eedb75c2deaa4b3d930a457f365cdd841d8aff1 100644 (file)
@@ -41,7 +41,7 @@ ldap_pvt_thread_create( ldap_pvt_thread_t * thread,
        unsigned tid;
        HANDLE thd;
 
-       thd = (HANDLE) _beginthreadex(NULL, 0, (thrfunc_t *) start_routine,
+       thd = (HANDLE) _beginthreadex(NULL, LDAP_PVT_THREAD_STACK_SIZE, (thrfunc_t *) start_routine,
                                      arg, 0, &tid);
 
        *thread = (ldap_pvt_thread_t) thd;
@@ -152,4 +152,10 @@ ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mp )
                ? -1 : 0;
 }
 
+ldap_pvt_thread_t
+ldap_pvt_thread_self( void )
+{
+       return GetCurrentThread();
+}
+
 #endif
index 5ddc03a871f5393b6061076a4cd17e3ea9c55873..8673f13954f8a603eaed667618545456fb3df378 100644 (file)
@@ -311,6 +311,11 @@ ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
 #endif
 }
 
+ldap_pvt_thread_t ldap_pvt_thread_self( void )
+{
+       return pthread_self();
+}
+
 #ifdef LDAP_THREAD_HAVE_RDWR
 #ifdef HAVE_PTHREAD_RWLOCK_DESTROY
 int 
index 873d7d1a49404c7af313143850441356d01dcc4e..b4e05394417bc6c542d4f15968409a977af1d89f 100644 (file)
@@ -146,6 +146,12 @@ ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex )
        return( pth_mutex_acquire( mutex, 1, NULL ) ? 0 : errno );
 }
 
+ldap_pvt_thread_t
+ldap_pvt_thread_self( void )
+{
+       return pth_self();
+}
+
 #ifdef LDAP_THREAD_HAVE_RDWR
 int 
 ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw )
index f884558ec5e65b715b399839937531d1409d02a5..e88931b6be8feb2a6976a55b36ad63cc5a954946 100644 (file)
@@ -191,4 +191,11 @@ int ldap_pvt_thread_pool_setkey (
 {
        return(0);
 }
+
+ldap_pvt_thread_t
+ldap_pvt_thread_self( void )
+{
+       return(0);
+}
+
 #endif /* NO_THREADS */
diff --git a/libraries/libldap_r/thr_thr.c b/libraries/libldap_r/thr_thr.c
new file mode 100644 (file)
index 0000000..17e4ef8
--- /dev/null
@@ -0,0 +1,158 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2002 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.
+ */
+
+/* thr_thr.c - wrappers around solaris threads */
+
+#include "portable.h"
+
+#if defined( HAVE_THR )
+
+#include "ldap_pvt_thread.h"
+
+/*******************
+ *                 *
+ * Solaris Threads *
+ *                 *
+ *******************/
+
+int
+ldap_int_thread_initialize( void )
+{
+       return 0;
+}
+
+int
+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, 
+       int detach,
+       void *(*start_routine)( void *),
+       void *arg)
+{
+       return( thr_create( NULL, 0, start_routine, arg,
+               detach ? THR_DETACHED : 0,
+               thread ) );
+}
+
+void 
+ldap_pvt_thread_exit( void *retval )
+{
+       thr_exit( NULL );
+}
+
+int ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
+{
+       thr_join( thread, NULL, thread_return );
+       return 0;
+}
+
+int 
+ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo )
+{
+       thr_kill( thread, signo );
+       return 0;
+}
+       
+int 
+ldap_pvt_thread_yield( void )
+{
+       thr_yield();
+       return 0;
+}
+
+int 
+ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond )
+{
+       return( cond_init( cond, USYNC_THREAD, NULL ) );
+}
+
+int 
+ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
+{
+       return( cond_signal( cond ) );
+}
+
+int
+ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cv )
+{
+       return( cond_broadcast( cv ) );
+}
+
+int 
+ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, 
+       ldap_pvt_thread_mutex_t *mutex )
+{
+       return( cond_wait( cond, mutex ) );
+}
+
+int
+ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cv )
+{
+       return( cond_destroy( cv ) );
+}
+
+int 
+ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex )
+{
+       return( mutex_init( mutex, USYNC_THREAD, NULL ) );
+}
+
+int 
+ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex )
+{
+       return( mutex_destroy( mutex ) );
+}
+
+int 
+ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
+{
+       return( mutex_lock( mutex ) );
+}
+
+int 
+ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
+{
+       return( mutex_unlock( mutex ) );
+}
+
+int
+ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mp )
+{
+       return( mutex_trylock( mp ) );
+}
+
+ldap_pvt_thread_t
+ldap_pvt_thread_self( void )
+{
+       return thr_self();
+}
+
+#endif /* HAVE_THR */
index 4665f35a51a7cfa6b9be82ef94c9b4c06032f5a8..77aeb22606abd557feb420f10ec881405c8c5d38 100644 (file)
@@ -46,9 +46,11 @@ typedef struct ldap_int_thread_ctx_s {
        union {
        LDAP_STAILQ_ENTRY(ldap_int_thread_ctx_s) q;
        LDAP_SLIST_ENTRY(ldap_int_thread_ctx_s) l;
+       LDAP_SLIST_ENTRY(ldap_int_thread_ctx_s) al;
        } ltc_next;
        ldap_pvt_thread_start_t *ltc_start_routine;
        void *ltc_arg;
+       ldap_pvt_thread_t ltc_thread_id;
        ldap_int_thread_key_t ltc_key[MAXKEYS];
 } ldap_int_thread_ctx_t;
 
@@ -58,6 +60,7 @@ struct ldap_int_thread_pool_s {
        ldap_pvt_thread_cond_t ltp_cond;
        LDAP_STAILQ_HEAD(tcq, ldap_int_thread_ctx_s) ltp_pending_list;
        LDAP_SLIST_HEAD(tcl, ldap_int_thread_ctx_s) ltp_free_list;
+       LDAP_SLIST_HEAD(tclq, ldap_int_thread_ctx_s) ltp_active_list;
        long ltp_state;
        long ltp_max_count;
        long ltp_max_pending;
@@ -120,6 +123,7 @@ ldap_pvt_thread_pool_init (
        pool->ltp_max_pending = max_pending;
        LDAP_STAILQ_INIT(&pool->ltp_pending_list);
        LDAP_SLIST_INIT(&pool->ltp_free_list);
+       LDAP_SLIST_INIT(&pool->ltp_active_list);
        ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex);
        LDAP_STAILQ_INSERT_TAIL(&ldap_int_thread_pool_list, pool, ltp_next);
        ldap_pvt_thread_mutex_unlock(&ldap_pvt_thread_pool_mutex);
@@ -425,9 +429,11 @@ ldap_int_thread_pool_wrapper (
                }
 
                pool->ltp_pending_count--;
+               LDAP_SLIST_INSERT_HEAD(&pool->ltp_active_list, ctx, ltc_next.al);
                pool->ltp_active_count++;
                ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
 
+               ctx->ltc_thread_id = ldap_pvt_thread_self();
                ctx->ltc_start_routine(ctx, ctx->ltc_arg);
 
                ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
@@ -442,6 +448,10 @@ ldap_int_thread_pool_wrapper (
 
                ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
                pool->ltp_active_count--;
+               ctx = LDAP_SLIST_FIRST(&pool->ltp_active_list);
+               if (ctx) {
+                       LDAP_SLIST_REMOVE_HEAD(&pool->ltp_active_list, ltc_next.al);
+               }
        }
 
        pool->ltp_open_count--;
@@ -494,4 +504,36 @@ int ldap_pvt_thread_pool_setkey(
        }
        return ENOMEM;
 }
+
+/*
+ * This is necessary if the caller does not have access to the
+ * thread context handle (for example, a slapd plugin calling
+ * slapi_search_internal()). No doubt it is more efficient to
+ * for the application to keep track of the thread context
+ * handles itself.
+ */
+void *ldap_pvt_thread_pool_context( ldap_pvt_thread_pool_t *tpool )
+{
+       ldap_pvt_thread_pool_t pool;
+       ldap_pvt_thread_t tid;
+       ldap_int_thread_ctx_t *ptr;
+
+       pool = *tpool;
+       if (pool == NULL) {
+               return NULL;
+       }
+
+       tid = ldap_pvt_thread_self();
+
+       ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
+       LDAP_SLIST_FOREACH(ptr, &pool->ltp_active_list, ltc_next.al)
+               if (ptr != NULL && ptr->ltc_thread_id == tid) break;
+       if (ptr != NULL && ptr->ltc_thread_id != tid) {
+               ptr = NULL;
+       }
+       ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
+
+       return ptr;
+}
+
 #endif /* LDAP_HAVE_THREAD_POOL */
index 699dedbcc9a0ca4003aa1088660eea9d6a153312..fc76bc13c31746cecf8acee0cbb23737d65ab344 100644 (file)
@@ -30,6 +30,7 @@ replogfile    ./test-db/slapd.replog
 
 replica                host=localhost:9010
                suffix="ou=Groups,o=University of Michigan,c=US"
+               attr!=description
                binddn="cn=Replica,ou=Groups,o=University of Michigan,c=US"
                bindmethod=simple
                credentials=secret
index c08a9fa93d1c28895105879f929a7ea21149b149..ed726d12e582f927957d762a50b255b05a164529 100755 (executable)
@@ -35,6 +35,7 @@ LDIFFILTER=$SRCDIR/scripts/acfilter.sh
 SUBFILTER=$SRCDIR/scripts/subfilter.sh
 UNDIFFFILTER=$SRCDIR/scripts/undiff.sh
 CONFFILTER=$SRCDIR/scripts/conf.sh
+STRIPATTR=$SRCDIR/scripts/stripattr.sh
 
 SLAPADD="../servers/slapd/tools/slapadd $LDAP_VERBOSE"
 SLAPCAT="../servers/slapd/tools/slapcat $LDAP_VERBOSE"
@@ -43,6 +44,7 @@ SLAPINDEX="../servers/slapd/tools/slapindex $LDAP_VERBOSE"
 unset DIFF_OPTIONS
 DIFF="diff -iu"
 CMP="diff -i"
+BCMP="diff -iB"
 CMPOUT=/dev/null
 SLAPD="../servers/slapd/slapd -s0"
 SLURPD=../servers/slurpd/slurpd
index a8c9af5a8133227d2c6acbd6f3983340051c42d8..9b7f7a2910aa69e8484b695eedab945be693b120 100755 (executable)
@@ -41,6 +41,14 @@ if test ! -x $SLURPD ; then
        exit 0
 fi
 
+# quick hack to check for awk
+echo "looking for a POSIX compliant awk"
+awk -W version >$CMPOUT 2>&1
+if test $? != 0 ; then
+       echo "This test requires awk"
+       exit 0
+fi
+
 echo "Cleaning up in $DBDIR..."
 rm -f $DBDIR/[!C]*
 echo "Cleaning up in $REPLDIR..."
@@ -134,6 +142,10 @@ member: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, o=Univer
 add: member
 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
+-
+replace: description
+description: A very long description, that is very likely to cause line wrapping in a LDIF file
+-
 
 dn: cn=All Staff,ou=Groups,o=University of Michigan,c=US
 changetype: modify
@@ -224,7 +236,7 @@ SEARCHOUT=$SUBMASTEROUT
 LDIF=$SLAVEOUT
 
 echo "Filtering master ldapsearch results..."
-. $LDIFFILTER < $SEARCHOUT > $SEARCHFLT
+. $LDIFFILTER < $SEARCHOUT | $STRIPATTR "description" > $SEARCHFLT
 echo "Filtering slave ldapsearch results..."
 . $LDIFFILTER < $LDIF > $LDIFFLT
 
@@ -239,17 +251,17 @@ fi
 SEARCHOUT=$MASTEROUT
 
 echo "Filtering remaining data"
-. $LDIFFILTER < $SEARCHOUT > $SEARCHFLT
+. $LDIFFILTER < $SEARCHOUT | $STRIPATTR "description" > $SEARCHFLT
 
 echo "Stripping slave entries from master output..."
-$CMP $SEARCHFLT $LDIFFLT | $UNDIFFFILTER > $SUBFLT
+$DIFF $SEARCHFLT $LDIFFLT | $UNDIFFFILTER > $SUBFLT
 
 echo "Stripping subtree entries from master output..."
 . $SUBFILTER 'ou=Groups,[ ]?o=University of Michigan,[ ]?c=US' < $SEARCHOUT \
-       | $UNDIFFFILTER > $SUBFLT2
+       | $STRIPATTR "description" > $SUBFLT2
 
 echo "Comparing master minus subtree and master minus slave..."
-$CMP $SUBFLT $SUBFLT2 > $CMPOUT
+$BCMP $SUBFLT $SUBFLT2 > $CMPOUT
 
 if test $? != 0 ; then
        echo "test failed - master and slave databases differ"
diff --git a/tests/scripts/undiff.sh b/tests/scripts/undiff.sh
new file mode 100755 (executable)
index 0000000..a453993
--- /dev/null
@@ -0,0 +1,6 @@
+#! /bin/sh
+#
+# Expunge extra stuff resulting from diff -u
+# strip everything, including leading '-', except leading '+' to force errors
+#
+awk '/^-/ {if (substr($0,1,3) != "---") print substr($0,2,length($0))} /^+/ {if (substr($0,1,3) != "+++") print $0}'