From: Kurt Zeilenga Date: Sun, 9 Feb 2003 00:28:49 +0000 (+0000) Subject: Changes X-Git-Tag: OPENLDAP_REL_ENG_2_1_13~50 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=96e453e9817e22700efedc155ee263ee33d5a4af;p=openldap Changes 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 --- diff --git a/CHANGES b/CHANGES index 6e3e517388..445934a9fa 100644 --- 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 diff --git a/acconfig.h b/acconfig.h index 37ec724e6d..dd00c4506d 100644 --- a/acconfig.h +++ b/acconfig.h @@ -88,12 +88,17 @@ # include #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 diff --git a/build/openldap.m4 b/build/openldap.m4 index d37f062563..48d0c2bd03 100644 --- a/build/openldap.m4 +++ b/build/openldap.m4 @@ -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])]) diff --git a/clients/tools/Makefile.in b/clients/tools/Makefile.in index cda849bacb..83c83d12fd 100644 --- a/clients/tools/Makefile.in +++ b/clients/tools/Makefile.in @@ -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 index 0000000000..b477850942 --- /dev/null +++ b/clients/tools/common.c @@ -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 + +#include +#include +#include +#include +#include + +#include + +#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 [!][=] general controls (! indicates criticality)\n" +" [!]authzid= (\"dn:\" or \"u:\")\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:\" or \"u:\")\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 : "", + 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 : "" ); + } + 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 index 0000000000..2791dbe2fb --- /dev/null +++ b/clients/tools/common.h @@ -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_ */ diff --git a/clients/tools/ldapcompare.c b/clients/tools/ldapcompare.c index 3318575324..18ea6efee7 100644 --- a/clients/tools/ldapcompare.c +++ b/clients/tools/ldapcompare.c @@ -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 #include -#include #include #include #include @@ -34,8 +33,14 @@ #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 \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 [!][=] 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:\" or \"u:\")\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 : "", - 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 : "" ); - } - - 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 index 0000000000..ab31707cdc --- /dev/null +++ b/clients/tools/ldapcompare.dsp @@ -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 diff --git a/clients/tools/ldapdelete.c b/clients/tools/ldapdelete.c index e13cfd3773..d3638404a5 100644 --- a/clients/tools/ldapdelete.c +++ b/clients/tools/ldapdelete.c @@ -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 #include - -#include #include #include @@ -21,24 +19,11 @@ #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 [!][=] 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:\" or \"u:\")\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 : "", - 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 : "" ); - } - - 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 index 0000000000..c136d67c8a --- /dev/null +++ b/clients/tools/ldapdelete.dsp @@ -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 diff --git a/clients/tools/ldapmodify.c b/clients/tools/ldapmodify.c index b53d7351a1..d4f452b95e 100644 --- a/clients/tools/ldapmodify.c +++ b/clients/tools/ldapmodify.c @@ -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 #include - #include -#include #include #include @@ -36,22 +34,11 @@ #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 [!][=] 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:\" or \"u:\")\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 : "", - 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 : "" ); - } - - 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 index 0000000000..ffa4e68df8 --- /dev/null +++ b/clients/tools/ldapmodify.dsp @@ -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 diff --git a/clients/tools/ldapmodrdn.c b/clients/tools/ldapmodrdn.c index 47419fc320..225e536657 100644 --- a/clients/tools/ldapmodrdn.c +++ b/clients/tools/ldapmodrdn.c @@ -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 #include -#include #include #include @@ -33,23 +32,12 @@ #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 [!][=] 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:\" or \"u:\")\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 : "", - 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 : "" ); - } - - 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 index 0000000000..d1304ce84c --- /dev/null +++ b/clients/tools/ldapmodrdn.dsp @@ -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 diff --git a/clients/tools/ldappasswd.c b/clients/tools/ldappasswd.c index 58fbfaf2a5..a0265f4ebd 100644 --- a/clients/tools/ldappasswd.c +++ b/clients/tools/ldappasswd.c @@ -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 #include -#include #include #include #include @@ -22,10 +21,17 @@ #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 [!][=] 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:\" or \"u:\")\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 : "", - 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 : "" ); - } - - 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 index 0000000000..7aa142c7d4 --- /dev/null +++ b/clients/tools/ldappasswd.dsp @@ -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 diff --git a/clients/tools/ldapsearch.c b/clients/tools/ldapsearch.c index 4b18660b69..e65ca0ca36 100644 --- a/clients/tools/ldapsearch.c +++ b/clients/tools/ldapsearch.c @@ -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 #include -#include #include #include #include @@ -35,11 +34,21 @@ #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 [!][=] search controls (! indicates criticality)\n" -" [!]mv= (matched values filter)\n" +" [!]mv= (matched values filter)\n" +#ifdef LDAP_CONTROL_PAGEDRESULTS +" [!]pr= (paged results)\n" +#endif +#ifdef LDAP_CONTROL_SUBENTRIES +" [!]subentries[=true|false] (subentries)\n" +#endif +#ifdef LDAP_CLIENT_UPDATE +" [!]lcup= p/// (client update)\n" +/* + * " s// (client update)\n" + * " sp///\n" + * */ +#endif +#ifdef LDAP_SYNC +" [!]sync= ro[/] (ldap sync - refreshOnly)\n" +" rp[/][/] (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 [!][=] 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:\" or \"u:\")\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 : "", - 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 : "" ); - } - - 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 index 0000000000..de7f3e9723 --- /dev/null +++ b/clients/tools/ldapsearch.dsp @@ -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 diff --git a/clients/tools/ldapwhoami.c b/clients/tools/ldapwhoami.c index 245467787b..4ccb11aea2 100644 --- a/clients/tools/ldapwhoami.c +++ b/clients/tools/ldapwhoami.c @@ -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 #include -#include #include #include #include @@ -22,99 +21,36 @@ #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 [!][=] 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:\" or \"u:\")\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 : "", - 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 : "" ); - } - - 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; } diff --git a/clients/tools/ldapwhoami.dsp b/clients/tools/ldapwhoami.dsp index 5e44a4fc7c..c4bdaa014a 100644 --- a/clients/tools/ldapwhoami.dsp +++ b/clients/tools/ldapwhoami.dsp @@ -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 diff --git a/include/ldap.h b/include/ldap.h index e8bb29d46a..05468f43c8 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -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(( diff --git a/include/portable.h.in b/include/portable.h.in index 93942cd0c8..7efd54231b 100644 --- a/include/portable.h.in +++ b/include/portable.h.in @@ -1012,12 +1012,17 @@ # include #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 diff --git a/libraries/liblber/io.c b/libraries/liblber/io.c index 234744aaeb..7dc2fa82b5 100644 --- a/libraries/liblber/io.c +++ b/libraries/liblber/io.c @@ -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 ) { diff --git a/libraries/libldap/Makefile.in b/libraries/libldap/Makefile.in index 5ffd498120..07a6272492 100644 --- a/libraries/libldap/Makefile.in +++ b/libraries/libldap/Makefile.in @@ -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 diff --git a/libraries/libldap/dnssrv.c b/libraries/libldap/dnssrv.c index 69a7ec5bb3..5c0a2cfe73 100644 --- a/libraries/libldap/dnssrv.c +++ b/libraries/libldap/dnssrv.c @@ -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 ); diff --git a/libraries/libldap/error.c b/libraries/libldap/error.c index 7aa9d46667..faad577502 100644 --- a/libraries/libldap/error.c +++ b/libraries/libldap/error.c @@ -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} }; diff --git a/libraries/libldap/extended.c b/libraries/libldap/extended.c index 3789720d88..64463e59d8 100644 --- a/libraries/libldap/extended.c +++ b/libraries/libldap/extended.c @@ -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 diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h index ec0aa4883e..e7ce439674 100644 --- a/libraries/libldap/ldap-int.h +++ b/libraries/libldap/ldap-int.h @@ -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, diff --git a/libraries/libldap/open.c b/libraries/libldap/open.c index 0c3f186f7c..01e51e7ba8 100644 --- a/libraries/libldap/open.c +++ b/libraries/libldap/open.c @@ -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 || diff --git a/libraries/libldap/result.c b/libraries/libldap/result.c index 2695143365..913a9cb806 100644 --- a/libraries/libldap/result.c +++ b/libraries/libldap/result.c @@ -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 || diff --git a/libraries/libldap/sasl.c b/libraries/libldap/sasl.c index 19cc3f6e94..7a053dfeb8 100644 --- a/libraries/libldap/sasl.c +++ b/libraries/libldap/sasl.c @@ -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, diff --git a/libraries/libldap/tls.c b/libraries/libldap/tls.c index 4a38c3f5d4..d093739a6d 100644 --- a/libraries/libldap/tls.c +++ b/libraries/libldap/tls.c @@ -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 #include #include +#include #include #include #include @@ -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; itype == 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 ) { diff --git a/libraries/libldap/url.c b/libraries/libldap/url.c index 8bf8bd56d5..06c06e5617 100644 --- a/libraries/libldap/url.c +++ b/libraries/libldap/url.c @@ -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 index 0000000000..46981995d7 --- /dev/null +++ b/libraries/libldap/whoami.c @@ -0,0 +1,89 @@ +/* $OpenLDAP$ */ +/* + * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. + * COPYING RESTRICTIONS APPLY, see COPYRIGHT file + */ + +#include "portable.h" + +#include +#include +#include +#include + +#include "ldap-int.h" + +/* + * LDAP Who Am I? (Extended) Operation + */ + +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 index 0000000000..e4e7dbcadb --- /dev/null +++ b/libraries/libldap_r/thr_cthreads.c @@ -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 index 0000000000..d869213bf5 --- /dev/null +++ b/libraries/libldap_r/thr_lwp.c @@ -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 + +#include +#include + +#include "ldap-int.h" + +#include "ldap_pvt_thread.h" + +#include +#include + +#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 */ diff --git a/libraries/libldap_r/thr_nt.c b/libraries/libldap_r/thr_nt.c index b818538a85..8eedb75c2d 100644 --- a/libraries/libldap_r/thr_nt.c +++ b/libraries/libldap_r/thr_nt.c @@ -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 diff --git a/libraries/libldap_r/thr_posix.c b/libraries/libldap_r/thr_posix.c index 5ddc03a871..8673f13954 100644 --- a/libraries/libldap_r/thr_posix.c +++ b/libraries/libldap_r/thr_posix.c @@ -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 diff --git a/libraries/libldap_r/thr_pth.c b/libraries/libldap_r/thr_pth.c index 873d7d1a49..b4e0539441 100644 --- a/libraries/libldap_r/thr_pth.c +++ b/libraries/libldap_r/thr_pth.c @@ -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 ) diff --git a/libraries/libldap_r/thr_stub.c b/libraries/libldap_r/thr_stub.c index f884558ec5..e88931b6be 100644 --- a/libraries/libldap_r/thr_stub.c +++ b/libraries/libldap_r/thr_stub.c @@ -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 index 0000000000..17e4ef8d9d --- /dev/null +++ b/libraries/libldap_r/thr_thr.c @@ -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 */ diff --git a/libraries/libldap_r/tpool.c b/libraries/libldap_r/tpool.c index 4665f35a51..77aeb22606 100644 --- a/libraries/libldap_r/tpool.c +++ b/libraries/libldap_r/tpool.c @@ -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 */ diff --git a/tests/data/slapd-repl-submaster.conf b/tests/data/slapd-repl-submaster.conf index 699dedbcc9..fc76bc13c3 100644 --- a/tests/data/slapd-repl-submaster.conf +++ b/tests/data/slapd-repl-submaster.conf @@ -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 diff --git a/tests/scripts/defines.sh b/tests/scripts/defines.sh index c08a9fa93d..ed726d12e5 100755 --- a/tests/scripts/defines.sh +++ b/tests/scripts/defines.sh @@ -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 diff --git a/tests/scripts/test011-subtree-repl b/tests/scripts/test011-subtree-repl index a8c9af5a81..9b7f7a2910 100755 --- a/tests/scripts/test011-subtree-repl +++ b/tests/scripts/test011-subtree-repl @@ -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 index 0000000000..a4539938d6 --- /dev/null +++ b/tests/scripts/undiff.sh @@ -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}'