RetroZilla/directory/c-sdk/ldap/libraries/libldap/test.c

1865 lines
45 KiB
C
Raw Normal View History

2015-10-21 05:03:22 +02:00
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* test.c - a simple test harness. */
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#ifdef MACOS
#ifdef THINK_C
#include <console.h>
#include <unix.h>
#include <fcntl.h>
#endif /* THINK_C */
#include "macos.h"
#else /* MACOS */
#if defined( DOS )
#include "msdos.h"
#if defined( WINSOCK )
#include "console.h"
#endif /* WINSOCK */
#else /* DOS */
#ifdef _WINDOWS
#include <windows.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
//#include "console.h"
#else /* _WINDOWS */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/file.h>
#ifndef VMS
#include <fcntl.h>
#include <unistd.h>
#endif /* VMS */
#endif /* _WINDOWS */
#endif /* DOS */
#endif /* MACOS */
#undef NET_SSL
#if defined(NET_SSL)
#include <sec.h>
static SECCertDBHandle certdbhandle;
#endif
#include "ldap.h"
#include "disptmpl.h"
#include "ldaplog.h"
#ifndef NO_LIBLCACHE
#include "lcache.h"
#endif /* !NO_LIBLCACHE */
#if !defined( PCNFS ) && !defined( WINSOCK ) && !defined( MACOS )
#define MOD_USE_BVALS
#endif /* !PCNFS && !WINSOCK && !MACOS */
static void handle_result( LDAP *ld, LDAPMessage *lm, int onlyone );
static void print_ldap_result( LDAP *ld, LDAPMessage *lm, char *s );
static void print_controls( LDAPControl **ctrls, int freeit );
static void print_referrals( char **refs, int freeit );
static void print_search_entry( LDAP *ld, LDAPMessage *res, int onlyone );
static char *changetype_num2string( int chgtype );
static void print_search_reference( LDAP *ld, LDAPMessage *res, int onlyone );
static void free_list( char **list );
static int entry2textwrite( void *fp, char *buf, int len );
static void bprint( char *data, int len );
static char **string2words( char *str, char *delims );
static const char * url_parse_err2string( int e );
char *dnsuffix;
#ifndef WINSOCK
static char *
getline( char *line, int len, FILE *fp, char *prompt )
{
printf(prompt);
if ( fgets( line, len, fp ) == NULL )
return( NULL );
line[ strlen( line ) - 1 ] = '\0';
return( line );
}
#endif /* WINSOCK */
static char **
get_list( char *prompt )
{
static char buf[256];
int num;
char **result;
num = 0;
result = (char **) 0;
while ( 1 ) {
getline( buf, sizeof(buf), stdin, prompt );
if ( *buf == '\0' )
break;
if ( result == (char **) 0 )
result = (char **) malloc( sizeof(char *) );
else
result = (char **) realloc( result,
sizeof(char *) * (num + 1) );
result[num++] = (char *) strdup( buf );
}
if ( result == (char **) 0 )
return( NULL );
result = (char **) realloc( result, sizeof(char *) * (num + 1) );
result[num] = NULL;
return( result );
}
static void
free_list( char **list )
{
int i;
if ( list != NULL ) {
for ( i = 0; list[ i ] != NULL; ++i ) {
free( list[ i ] );
}
free( (char *)list );
}
}
#ifdef MOD_USE_BVALS
static int
file_read( char *path, struct berval *bv )
{
FILE *fp;
long rlen;
int eof;
if (( fp = fopen( path, "r" )) == NULL ) {
perror( path );
return( -1 );
}
if ( fseek( fp, 0L, SEEK_END ) != 0 ) {
perror( path );
fclose( fp );
return( -1 );
}
bv->bv_len = ftell( fp );
if (( bv->bv_val = (char *)malloc( bv->bv_len )) == NULL ) {
perror( "malloc" );
fclose( fp );
return( -1 );
}
if ( fseek( fp, 0L, SEEK_SET ) != 0 ) {
perror( path );
fclose( fp );
return( -1 );
}
rlen = fread( bv->bv_val, 1, bv->bv_len, fp );
eof = feof( fp );
fclose( fp );
if ( (unsigned long)rlen != bv->bv_len ) {
perror( path );
free( bv->bv_val );
return( -1 );
}
return( bv->bv_len );
}
#endif /* MOD_USE_BVALS */
static LDAPMod **
get_modlist( char *prompt1, char *prompt2, char *prompt3 )
{
static char buf[256];
int num;
LDAPMod tmp;
LDAPMod **result;
#ifdef MOD_USE_BVALS
struct berval **bvals;
#endif /* MOD_USE_BVALS */
num = 0;
result = NULL;
while ( 1 ) {
if ( prompt1 ) {
getline( buf, sizeof(buf), stdin, prompt1 );
tmp.mod_op = atoi( buf );
if ( tmp.mod_op == -1 || buf[0] == '\0' )
break;
} else {
tmp.mod_op = 0;
}
getline( buf, sizeof(buf), stdin, prompt2 );
if ( buf[0] == '\0' )
break;
tmp.mod_type = strdup( buf );
tmp.mod_values = get_list( prompt3 );
#ifdef MOD_USE_BVALS
if ( tmp.mod_values != NULL ) {
int i;
for ( i = 0; tmp.mod_values[i] != NULL; ++i )
;
bvals = (struct berval **)calloc( i + 1,
sizeof( struct berval *));
for ( i = 0; tmp.mod_values[i] != NULL; ++i ) {
bvals[i] = (struct berval *)malloc(
sizeof( struct berval ));
if ( strncmp( tmp.mod_values[i], "{FILE}",
6 ) == 0 ) {
if ( file_read( tmp.mod_values[i] + 6,
bvals[i] ) < 0 ) {
return( NULL );
}
} else {
bvals[i]->bv_val = tmp.mod_values[i];
bvals[i]->bv_len =
strlen( tmp.mod_values[i] );
}
}
tmp.mod_bvalues = bvals;
tmp.mod_op |= LDAP_MOD_BVALUES;
}
#endif /* MOD_USE_BVALS */
if ( result == NULL )
result = (LDAPMod **) malloc( sizeof(LDAPMod *) );
else
result = (LDAPMod **) realloc( result,
sizeof(LDAPMod *) * (num + 1) );
result[num] = (LDAPMod *) malloc( sizeof(LDAPMod) );
*(result[num]) = tmp; /* struct copy */
num++;
}
if ( result == NULL )
return( NULL );
result = (LDAPMod **) realloc( result, sizeof(LDAPMod *) * (num + 1) );
result[num] = NULL;
return( result );
}
int LDAP_CALL LDAP_CALLBACK
bind_prompt( LDAP *ld, char **dnp, char **passwdp, int *authmethodp,
int freeit, void *dummy )
{
static char dn[256], passwd[256];
if ( !freeit ) {
#ifdef KERBEROS
getline( dn, sizeof(dn), stdin,
"re-bind method (0->simple, 1->krbv41, 2->krbv42, 3->krbv41&2)? " );
if (( *authmethodp = atoi( dn )) == 3 ) {
*authmethodp = LDAP_AUTH_KRBV4;
} else {
*authmethodp |= 0x80;
}
#else /* KERBEROS */
*authmethodp = LDAP_AUTH_SIMPLE;
#endif /* KERBEROS */
getline( dn, sizeof(dn), stdin, "re-bind dn? " );
strcat( dn, dnsuffix );
*dnp = dn;
if ( *authmethodp == LDAP_AUTH_SIMPLE && dn[0] != '\0' ) {
getline( passwd, sizeof(passwd), stdin,
"re-bind password? " );
} else {
passwd[0] = '\0';
}
*passwdp = passwd;
}
return( LDAP_SUCCESS );
}
#define HEX2BIN( h ) ( (h) >= '0' && (h) <='0' ? (h) - '0' : (h) - 'A' + 10 )
void
berval_from_hex( struct berval *bvp, char *hexstr )
{
char *src, *dst, c, abyte;
dst = bvp->bv_val;
bvp->bv_len = 0;
src = hexstr;
while ( *src != '\0' ) {
c = *src;
if ( isupper( c )) {
c = tolower( c );
}
abyte = HEX2BIN( c ) << 4;
++src;
c = *src;
if ( isupper( c )) {
c = tolower( c );
}
abyte |= HEX2BIN( c );
++src;
*dst++ = abyte;
++bvp->bv_len;
}
}
static void
add_control( LDAPControl ***ctrlsp, LDAPControl *newctrl )
{
int i;
if ( *ctrlsp == NULL ) {
*ctrlsp = (LDAPControl **) calloc( 2, sizeof(LDAPControl *) );
i = 0;
} else {
for ( i = 0; (*ctrlsp)[i] != NULL; i++ ) {
; /* NULL */
}
*ctrlsp = (LDAPControl **) realloc( *ctrlsp,
(i + 2) * sizeof(LDAPControl *) );
}
(*ctrlsp)[i] = newctrl;
(*ctrlsp)[i+1] = NULL;
}
#ifdef TEST_CUSTOM_MALLOC
typedef struct my_malloc_info {
long mmi_magic;
size_t mmi_actualsize;
} MyMallocInfo;
#define MY_MALLOC_MAGIC_NUMBER 0x19940618
#define MY_MALLOC_CHECK_MAGIC( p ) if ( ((MyMallocInfo *)( (p) - sizeof()
void *
my_malloc( size_t size )
{
void *p;
MyMallocInfo *mmip;
if (( p = malloc( size + sizeof( struct my_malloc_info ))) != NULL ) {
mmip = (MyMallocInfo *)p;
mmip->mmi_magic = MY_MALLOC_MAGIC_NUMBER;
mmip->mmi_actualsize = size;
}
fprintf( stderr, "my_malloc: allocated ptr 0x%x, size %ld\n",
p, mmip->mmi_actualsize );
return( (char *)p + sizeof( MyMallocInfo ));
}
void *
my_calloc( size_t nelem, size_t elsize )
{
void *p;
if (( p = my_malloc( nelem * elsize )) != NULL ) {
memset( p, 0, nelem * elsize );
}
return( p );
}
void
my_free( void *ptr )
{
char *p;
MyMallocInfo *mmip;
p = (char *)ptr;
p -= sizeof( MyMallocInfo );
mmip = (MyMallocInfo *)p;
if ( mmip->mmi_magic != MY_MALLOC_MAGIC_NUMBER ) {
fprintf( stderr,
"my_malloc_check_magic: ptr 0x%x bad magic number\n", ptr );
exit( 1 );
}
fprintf( stderr, "my_free: freeing ptr 0x%x, size %ld\n",
p, mmip->mmi_actualsize );
memset( p, 0, mmip->mmi_actualsize + sizeof( MyMallocInfo ));
free( p );
}
void *
my_realloc( void *ptr, size_t size )
{
void *p;
MyMallocInfo *mmip;
if ( ptr == NULL ) {
return( my_malloc( size ));
}
mmip = (MyMallocInfo *)( (char *)ptr - sizeof( MyMallocInfo ));
if ( mmip->mmi_magic != MY_MALLOC_MAGIC_NUMBER ) {
fprintf( stderr,
"my_malloc_check_magic: ptr 0x%x bad magic number\n", ptr );
exit( 1 );
}
if ( size <= mmip->mmi_actualsize ) { /* current block big enough? */
return( ptr );
}
if (( p = my_malloc( size )) != NULL ) {
memcpy( p, ptr, mmip->mmi_actualsize );
my_free( ptr );
}
return( p );
}
#endif /* TEST_CUSTOM_MALLOC */
int
#ifdef WINSOCK
ldapmain(
#else /* WINSOCK */
main(
#endif /* WINSOCK */
int argc, char **argv )
{
LDAP *ld;
int rc, i, c, port, cldapflg, errflg, method, id, msgtype;
int version;
char line[256], command1, command2, command3;
char passwd[64], dn[256], rdn[64], attr[64], value[256];
char filter[256], *host, **types;
char **exdn, *fnname;
int bound, all, scope, attrsonly, optval, ldapversion;
LDAPMessage *res;
LDAPMod **mods, **attrs;
struct timeval timeout, *tvp;
char *copyfname = NULL;
int copyoptions = 0;
LDAPURLDesc *ludp;
struct ldap_disptmpl *tmpllist = NULL;
int changetypes, changesonly, return_echg_ctls;
LDAPControl **tmpctrls, *newctrl, **controls = NULL;
char *usage = "usage: %s [-u] [-h host] [-d level] [-s dnsuffix] [-p port] [-t file] [-T file] [-V protocolversion]\n";
extern char *optarg;
extern int optind;
#ifdef MACOS
if (( argv = get_list( "cmd line arg?" )) == NULL ) {
exit( 1 );
}
for ( argc = 0; argv[ argc ] != NULL; ++argc ) {
;
}
#endif /* MACOS */
#ifdef TEST_CUSTOM_MALLOC
{
struct ldap_memalloc_fns memalloc_fns;
memalloc_fns.ldapmem_malloc = my_malloc;
memalloc_fns.ldapmem_calloc = my_calloc;
memalloc_fns.ldapmem_realloc = my_realloc;
memalloc_fns.ldapmem_free = my_free;
if ( ldap_set_option( NULL, LDAP_OPT_MEMALLOC_FN_PTRS,
&memalloc_fns ) != 0 ) {
fputs( "ldap_set_option failed\n", stderr );
exit( 1 );
}
}
#endif /* TEST_CUSTOM_MALLOC */
host = NULL;
port = LDAP_PORT;
dnsuffix = "";
cldapflg = errflg = 0;
ldapversion = 0; /* use default */
#ifndef _WIN32
#ifdef LDAP_DEBUG
ldap_debug = LDAP_DEBUG_ANY;
#endif
#endif
while (( c = getopt( argc, argv, "uh:d:s:p:t:T:V:" )) != -1 ) {
switch( c ) {
case 'u':
#ifdef CLDAP
cldapflg++;
#else /* CLDAP */
printf( "Compile with -DCLDAP for UDP support\n" );
#endif /* CLDAP */
break;
case 'd':
#ifndef _WIN32
#ifdef LDAP_DEBUG
ldap_debug = atoi( optarg ) | LDAP_DEBUG_ANY;
if ( ldap_debug & LDAP_DEBUG_PACKETS ) {
ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL,
&ldap_debug );
}
#else
printf( "Compile with -DLDAP_DEBUG for debugging\n" );
#endif
#endif
break;
case 'h':
host = optarg;
break;
case 's':
dnsuffix = optarg;
break;
case 'p':
port = atoi( optarg );
break;
#if !defined(MACOS) && !defined(DOS)
case 't': /* copy ber's to given file */
copyfname = strdup( optarg );
copyoptions = LBER_SOCKBUF_OPT_TO_FILE;
break;
case 'T': /* only output ber's to given file */
copyfname = strdup( optarg );
copyoptions = (LBER_SOCKBUF_OPT_TO_FILE |
LBER_SOCKBUF_OPT_TO_FILE_ONLY);
break;
#endif
case 'V': /* LDAP protocol version */
ldapversion = atoi( optarg );
break;
default:
++errflg;
}
}
if ( host == NULL && optind == argc - 1 ) {
host = argv[ optind ];
++optind;
}
if ( errflg || optind < argc - 1 ) {
fprintf( stderr, usage, argv[ 0 ] );
exit( 1 );
}
printf( "%sldap_init( %s, %d )\n", cldapflg ? "c" : "",
host == NULL ? "(null)" : host, port );
if ( cldapflg ) {
#ifdef CLDAP
ld = cldap_open( host, port );
#endif /* CLDAP */
} else {
ld = ldap_init( host, port );
}
if ( ld == NULL ) {
perror( "ldap_init" );
exit(1);
}
if ( ldapversion != 0 && ldap_set_option( ld,
LDAP_OPT_PROTOCOL_VERSION, (void *)&ldapversion ) != 0 ) {
ldap_perror( ld, "ldap_set_option (protocol version)" );
exit(1);
}
#ifdef notdef
#if !defined(MACOS) && !defined(DOS)
if ( copyfname != NULL ) {
int fd;
Sockbuf *sb;
if ( (fd = open( copyfname, O_WRONLY | O_CREAT, 0600 ))
== -1 ) {
perror( copyfname );
exit ( 1 );
}
ldap_get_option( ld, LDAP_OPT_SOCKBUF, &sb );
ber_sockbuf_set_option( sb, LBER_SOCKBUF_OPT_COPYDESC,
(void *) &fd );
ber_sockbuf_set_option( sb, copyoptions, LBER_OPT_ON );
}
#endif
#endif
bound = 0;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
tvp = &timeout;
(void) memset( line, '\0', sizeof(line) );
while ( getline( line, sizeof(line), stdin, "\ncommand? " ) != NULL ) {
command1 = line[0];
command2 = line[1];
command3 = line[2];
switch ( command1 ) {
case 'a': /* add or abandon */
switch ( command2 ) {
case 'd': /* add */
getline( dn, sizeof(dn), stdin, "dn? " );
strcat( dn, dnsuffix );
if ( (attrs = get_modlist( NULL, "attr? ",
"value? " )) == NULL )
break;
if ( (id = ldap_add( ld, dn, attrs )) == -1 )
ldap_perror( ld, "ldap_add" );
else
printf( "Add initiated with id %d\n",
id );
break;
case 'b': /* abandon */
getline( line, sizeof(line), stdin, "msgid? " );
id = atoi( line );
if ( ldap_abandon( ld, id ) != 0 )
ldap_perror( ld, "ldap_abandon" );
else
printf( "Abandon successful\n" );
break;
default:
printf( "Possibilities: [ad]d, [ab]ort\n" );
}
break;
case 'v': /* ldap protocol version */
getline( line, sizeof(line), stdin,
"ldap version? " );
version = atoi( line );
if ( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
(void *) &version ) != 0 ) {
ldap_perror( ld, "ldap_set_option" );
}
break;
case 'b': /* asynch bind */
getline( line, sizeof(line), stdin,
"method 0->simple 3->sasl? " );
method = atoi( line );
if ( method == 0 ) {
method = LDAP_AUTH_SIMPLE;
} else if ( method == 3 ) {
method = LDAP_AUTH_SASL;
}
getline( dn, sizeof(dn), stdin, "dn? " );
strcat( dn, dnsuffix );
if ( method == LDAP_AUTH_SIMPLE && dn[0] != '\0' ) {
} else {
passwd[0] = '\0';
}
if ( method == LDAP_AUTH_SIMPLE ) {
if ( dn[0] != '\0' ) {
getline( passwd, sizeof(passwd), stdin,
"password? " );
} else {
passwd[0] = '\0';
}
rc = ldap_simple_bind( ld, dn, passwd );
} else {
struct berval cred;
char mechanism[BUFSIZ];
getline( mechanism, sizeof(mechanism), stdin,
"mechanism? " );
getline( passwd, sizeof(passwd), stdin,
"credentials? " );
cred.bv_val = passwd;
cred.bv_len = strlen( passwd );
if ( ldap_sasl_bind( ld, dn, mechanism, &cred,
NULL, NULL, &rc ) != LDAP_SUCCESS ) {
rc = -1;
}
}
if ( rc == -1 ) {
fprintf( stderr, "ldap_bind failed\n" );
ldap_perror( ld, "ldap_bind" );
} else {
printf( "Bind initiated\n" );
bound = 1;
}
break;
case 'B': /* synch bind */
getline( line, sizeof(line), stdin,
"method 0->simple 3->sasl? " );
method = atoi( line );
if ( method == 0 ) {
method = LDAP_AUTH_SIMPLE;
} else if ( method == 3 ) {
method = LDAP_AUTH_SASL;
}
getline( dn, sizeof(dn), stdin, "dn? " );
strcat( dn, dnsuffix );
if ( method == LDAP_AUTH_SIMPLE && dn[0] != '\0' ) {
} else {
passwd[0] = '\0';
}
if ( method == LDAP_AUTH_SIMPLE ) {
if ( dn[0] != '\0' ) {
getline( passwd, sizeof(passwd), stdin,
"password? " );
} else {
passwd[0] = '\0';
}
rc = ldap_simple_bind_s( ld, dn, passwd );
fnname = "ldap_simple_bind_s";
} else {
struct berval cred;
char mechanism[BUFSIZ];
getline( mechanism, sizeof(mechanism), stdin,
"mechanism? " );
getline( passwd, sizeof(passwd), stdin,
"credentials? " );
cred.bv_val = passwd;
cred.bv_len = strlen( passwd );
rc = ldap_sasl_bind_s( ld, dn, mechanism,
&cred, NULL, NULL, NULL );
fnname = "ldap_sasl_bind_s";
}
if ( rc != LDAP_SUCCESS ) {
fprintf( stderr, "%s failed\n", fnname );
ldap_perror( ld, fnname );
} else {
printf( "Bind successful\n" );
bound = 1;
}
break;
case 'c': /* compare */
getline( dn, sizeof(dn), stdin, "dn? " );
strcat( dn, dnsuffix );
getline( attr, sizeof(attr), stdin, "attr? " );
getline( value, sizeof(value), stdin, "value? " );
if ( (id = ldap_compare( ld, dn, attr, value )) == -1 )
ldap_perror( ld, "ldap_compare" );
else
printf( "Compare initiated with id %d\n", id );
break;
case 'x': /* extended operation */
{
char oid[100];
struct berval val;
getline( oid, sizeof(oid), stdin, "oid? " );
getline( value, sizeof(value), stdin, "value? " );
val.bv_val = value;
val.bv_len = strlen( value );
if ( ldap_extended_operation( ld, oid, &val, NULL,
NULL, &id ) != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_extended_operation" );
} else {
printf( "Extended op initiated with id %d\n",
id );
}
}
break;
case 'C': /* set cache parameters */
#ifdef NO_LIBLCACHE
getline( line, sizeof(line), stdin,
"cache init (memcache 0)? " );
#else
getline( line, sizeof(line), stdin,
"cache init (memcache 0, lcache 1)? " );
#endif
i = atoi( line );
if ( i == 0 ) { /* memcache */
unsigned long ttl, size;
char **basedns, *dnarray[2];
LDAPMemCache *mc;
getline( line, sizeof(line), stdin,
"memcache ttl? " );
ttl = atoi( line );
getline( line, sizeof(line), stdin,
"memcache size? " );
size = atoi( line );
getline( line, sizeof(line), stdin,
"memcache baseDN? " );
if ( *line == '\0' ) {
basedns = NULL;
} else {
dnarray[0] = line;
dnarray[1] = NULL;
basedns = dnarray;
}
if (( rc = ldap_memcache_init( ttl, size,
basedns, NULL, &mc )) != LDAP_SUCCESS ) {
fprintf( stderr,
"ldap_memcache_init: %s\n",
ldap_err2string( rc ));
} else if (( rc = ldap_memcache_set( ld, mc ))
!= LDAP_SUCCESS ) {
fprintf( stderr,
"ldap_memcache_set: %s\n",
ldap_err2string( rc ));
}
#ifndef NO_LIBLCACHE
} else if ( i == 1 ) {
getline( line, sizeof(line), stdin,
"cache config file? " );
if ( line[0] != '\0' ) {
if ( lcache_init( ld, line ) != 0 ) {
perror( "ldap_cache_init" );
break;
}
}
getline( line, sizeof(line), stdin,
"cache on/off (on 1, off 0)? " );
if ( line[0] != '\0' ) {
i = atoi( line );
if ( ldap_set_option( ld,
LDAP_OPT_CACHE_ENABLE, &i ) != 0 ) {
ldap_perror( ld, "ldap_cache_enable" );
break;
}
}
getline( line, sizeof(line), stdin,
"cache strategy (check 0, populate 1, localdb 2)? " );
if ( line[0] != '\0' ) {
i = atoi( line );
if ( ldap_set_option( ld,
LDAP_OPT_CACHE_STRATEGY, &i )
!= 0 ) {
ldap_perror(ld, "ldap_cache_strategy");
break;
}
}
#endif /* !NO_LIBLCACHE */
} else {
fprintf( stderr, "unknown cachetype %d\n", i );
}
break;
case 'd': /* turn on debugging */
#ifndef _WIN32
#ifdef LDAP_DEBUG
getline( line, sizeof(line), stdin, "debug level? " );
ldap_debug = atoi( line ) | LDAP_DEBUG_ANY;
if ( ldap_debug & LDAP_DEBUG_PACKETS ) {
ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL,
&ldap_debug );
}
#else
printf( "Compile with -DLDAP_DEBUG for debugging\n" );
#endif
#endif
break;
case 'E': /* explode a dn */
getline( line, sizeof(line), stdin, "dn? " );
exdn = ldap_explode_dn( line, 0 );
for ( i = 0; exdn != NULL && exdn[i] != NULL; i++ ) {
printf( "\t\"%s\"\n", exdn[i] );
}
break;
case 'R': /* explode an rdn */
getline( line, sizeof(line), stdin, "rdn? " );
exdn = ldap_explode_rdn( line, 0 );
for ( i = 0; exdn != NULL && exdn[i] != NULL; i++ ) {
printf( "\t\"%s\"\n", exdn[i] );
}
break;
case 'm': /* modify or modifyrdn */
if ( strncmp( line, "modify", 4 ) == 0 ) {
getline( dn, sizeof(dn), stdin, "dn? " );
strcat( dn, dnsuffix );
if ( (mods = get_modlist(
"mod (0=>add, 1=>delete, 2=>replace -1=>done)? ",
"attribute type? ", "attribute value? " ))
== NULL )
break;
if ( (id = ldap_modify( ld, dn, mods )) == -1 )
ldap_perror( ld, "ldap_modify" );
else
printf( "Modify initiated with id %d\n",
id );
} else if ( strncmp( line, "modrdn", 4 ) == 0 ) {
getline( dn, sizeof(dn), stdin, "dn? " );
strcat( dn, dnsuffix );
getline( rdn, sizeof(rdn), stdin, "newrdn? " );
getline( line, sizeof(line), stdin,
"deleteoldrdn? " );
if ( (id = ldap_modrdn2( ld, dn, rdn,
atoi(line) )) == -1 )
ldap_perror( ld, "ldap_modrdn" );
else
printf( "Modrdn initiated with id %d\n",
id );
} else {
printf( "Possibilities: [modi]fy, [modr]dn\n" );
}
break;
case 'q': /* quit */
#ifdef CLDAP
if ( cldapflg )
cldap_close( ld );
#endif /* CLDAP */
if ( !cldapflg )
ldap_unbind( ld );
exit( 0 );
break;
case 'r': /* result or remove */
switch ( command3 ) {
case 's': /* result */
getline( line, sizeof(line), stdin,
"msgid (-1=>any)? " );
if ( line[0] == '\0' )
id = -1;
else
id = atoi( line );
getline( line, sizeof(line), stdin,
"all (0=>any, 1=>all)? " );
if ( line[0] == '\0' )
all = 1;
else
all = atoi( line );
if (( msgtype = ldap_result( ld, id, all,
tvp, &res )) < 1 ) {
ldap_perror( ld, "ldap_result" );
break;
}
printf( "\nresult: msgtype %d msgid %d\n",
msgtype, ldap_msgid( res ) );
handle_result( ld, res, 0 );
res = NULL;
break;
case 'm': /* remove */
getline( dn, sizeof(dn), stdin, "dn? " );
strcat( dn, dnsuffix );
if ( (id = ldap_delete( ld, dn )) == -1 )
ldap_perror( ld, "ldap_delete" );
else
printf( "Remove initiated with id %d\n",
id );
break;
default:
printf( "Possibilities: [rem]ove, [res]ult\n" );
break;
}
break;
case 's': /* search */
getline( dn, sizeof(dn), stdin, "searchbase? " );
strcat( dn, dnsuffix );
getline( line, sizeof(line), stdin,
"scope (0=Base, 1=One Level, 2=Subtree)? " );
scope = atoi( line );
getline( filter, sizeof(filter), stdin,
"search filter (e.g. sn=jones)? " );
types = get_list( "attrs to return? " );
getline( line, sizeof(line), stdin,
"attrsonly (0=attrs&values, 1=attrs only)? " );
attrsonly = atoi( line );
if ( cldapflg ) {
#ifdef CLDAP
getline( line, sizeof(line), stdin,
"Requestor DN (for logging)? " );
if ( cldap_search_s( ld, dn, scope, filter, types,
attrsonly, &res, line ) != 0 ) {
ldap_perror( ld, "cldap_search_s" );
} else {
printf( "\nresult: msgid %d\n",
res->lm_msgid );
handle_result( ld, res, 0 );
res = NULL;
}
#endif /* CLDAP */
} else {
if (( id = ldap_search( ld, dn, scope, filter,
types, attrsonly )) == -1 ) {
ldap_perror( ld, "ldap_search" );
} else {
printf( "Search initiated with id %d\n", id );
}
}
free_list( types );
break;
case 't': /* set timeout value */
getline( line, sizeof(line), stdin, "timeout (-1=infinite)? " );
timeout.tv_sec = atoi( line );
if ( timeout.tv_sec < 0 ) {
tvp = NULL;
} else {
tvp = &timeout;
}
break;
case 'U': /* set ufn search prefix */
getline( line, sizeof(line), stdin, "ufn prefix? " );
ldap_ufn_setprefix( ld, line );
break;
case 'u': /* user friendly search w/optional timeout */
getline( dn, sizeof(dn), stdin, "ufn? " );
strcat( dn, dnsuffix );
types = get_list( "attrs to return? " );
getline( line, sizeof(line), stdin,
"attrsonly (0=attrs&values, 1=attrs only)? " );
attrsonly = atoi( line );
if ( command2 == 't' ) {
id = ldap_ufn_search_c( ld, dn, types,
attrsonly, &res, ldap_ufn_timeout,
&timeout );
} else {
id = ldap_ufn_search_s( ld, dn, types,
attrsonly, &res );
}
if ( res == NULL )
ldap_perror( ld, "ldap_ufn_search" );
else {
printf( "\nresult: err %d\n", id );
handle_result( ld, res, 0 );
res = NULL;
}
free_list( types );
break;
case 'l': /* URL search */
getline( line, sizeof(line), stdin,
"attrsonly (0=attrs&values, 1=attrs only)? " );
attrsonly = atoi( line );
getline( line, sizeof(line), stdin, "LDAP URL? " );
if (( id = ldap_url_search( ld, line, attrsonly ))
== -1 ) {
ldap_perror( ld, "ldap_url_search" );
} else {
printf( "URL search initiated with id %d\n", id );
}
break;
case 'p': /* parse LDAP URL */
getline( line, sizeof(line), stdin, "LDAP URL? " );
if (( i = ldap_url_parse( line, &ludp )) != 0 ) {
fprintf( stderr, "ldap_url_parse: error %d (%s)\n", i,
url_parse_err2string( i ));
} else {
printf( "\t host: " );
if ( ludp->lud_host == NULL ) {
printf( "DEFAULT\n" );
} else {
printf( "<%s>\n", ludp->lud_host );
}
printf( "\t port: " );
if ( ludp->lud_port == 0 ) {
printf( "DEFAULT\n" );
} else {
printf( "%d\n", ludp->lud_port );
}
printf( "\tsecure: %s\n", ( ludp->lud_options &
LDAP_URL_OPT_SECURE ) != 0 ? "Yes" : "No" );
printf( "\t dn: " );
if ( ludp->lud_dn == NULL ) {
printf( "ROOT\n" );
} else {
printf( "%s\n", ludp->lud_dn );
}
printf( "\t attrs:" );
if ( ludp->lud_attrs == NULL ) {
printf( " ALL" );
} else {
for ( i = 0; ludp->lud_attrs[ i ] != NULL; ++i ) {
printf( " <%s>", ludp->lud_attrs[ i ] );
}
}
printf( "\n\t scope: %s\n", ludp->lud_scope == LDAP_SCOPE_ONELEVEL ?
"ONE" : ludp->lud_scope == LDAP_SCOPE_BASE ? "BASE" :
ludp->lud_scope == LDAP_SCOPE_SUBTREE ? "SUB" : "**invalid**" );
printf( "\tfilter: <%s>\n", ludp->lud_filter );
ldap_free_urldesc( ludp );
}
break;
case 'n': /* set dn suffix, for convenience */
getline( line, sizeof(line), stdin, "DN suffix? " );
strcpy( dnsuffix, line );
break;
case 'N': /* add an LDAPv3 control */
getline( line, sizeof(line), stdin,
"Control oid (. to clear list)? " );
if ( *line == '.' && *(line+1) == '\0' ) {
controls = NULL;
} else {
newctrl = (LDAPControl *) malloc(
sizeof(LDAPControl) );
newctrl->ldctl_oid = strdup( line );
getline( line, sizeof(line), stdin,
"Control value? " );
if ( strncmp( line, "0x", 2 ) == 0 ) {
newctrl->ldctl_value.bv_val =
(char *)malloc( strlen( line ) / 2 );
berval_from_hex( &(newctrl->ldctl_value),
line + 2 );
} else {
newctrl->ldctl_value.bv_val
= strdup( line );
}
newctrl->ldctl_value.bv_len = strlen( line );
getline( line, sizeof(line), stdin,
"Critical (0=no, 1=yes)? " );
newctrl->ldctl_iscritical = atoi( line );
add_control( &controls, newctrl );
}
ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS,
controls );
ldap_get_option( ld, LDAP_OPT_SERVER_CONTROLS,
&tmpctrls );
print_controls( tmpctrls, 0 );
break;
case 'P': /* add a persistent search control */
getline( line, sizeof(line), stdin, "Changetypes to "
" return (additive - add (1), delete (2), "
"modify (4), modDN (8))? " );
changetypes = atoi(line);
getline( line, sizeof(line), stdin,
"Return changes only (0=no, 1=yes)? " );
changesonly = atoi(line);
getline( line, sizeof(line), stdin, "Return entry "
"change controls (0=no, 1=yes)? " );
return_echg_ctls = atoi(line);
getline( line, sizeof(line), stdin,
"Critical (0=no, 1=yes)? " );
if ( ldap_create_persistentsearch_control( ld,
changetypes, changesonly, return_echg_ctls,
(char)atoi(line), &newctrl ) != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_create_persistent"
"search_control" );
} else {
add_control( &controls, newctrl );
ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS,
controls );
ldap_get_option( ld, LDAP_OPT_SERVER_CONTROLS,
&tmpctrls );
print_controls( tmpctrls, 0 );
}
break;
case 'o': /* set ldap options */
getline( line, sizeof(line), stdin, "alias deref (0=never, 1=searching, 2=finding, 3=always)?" );
i = atoi( line );
ldap_set_option( ld, LDAP_OPT_DEREF, &i );
getline( line, sizeof(line), stdin, "timelimit?" );
i = atoi( line );
ldap_set_option( ld, LDAP_OPT_TIMELIMIT, &i );
getline( line, sizeof(line), stdin, "sizelimit?" );
i = atoi( line );
ldap_set_option( ld, LDAP_OPT_SIZELIMIT, &i );
#ifdef STR_TRANSLATION
getline( line, sizeof(line), stdin,
"Automatic translation of T.61 strings (0=no, 1=yes)?" );
if ( atoi( line ) == 0 ) {
ld->ld_lberoptions &= ~LBER_OPT_TRANSLATE_STRINGS;
} else {
ld->ld_lberoptions |= LBER_OPT_TRANSLATE_STRINGS;
#ifdef LDAP_CHARSET_8859
getline( line, sizeof(line), stdin,
"Translate to/from ISO-8859 (0=no, 1=yes?" );
if ( atoi( line ) != 0 ) {
ldap_set_string_translators( ld,
ldap_8859_to_t61,
ldap_t61_to_8859 );
}
#endif /* LDAP_CHARSET_8859 */
}
#endif /* STR_TRANSLATION */
#ifdef LDAP_DNS
getline( line, sizeof(line), stdin,
"Use DN & DNS to determine where to send requests (0=no, 1=yes)?" );
optval = ( atoi( line ) != 0 );
ldap_set_option( ld, LDAP_OPT_DNS, (void *) optval );
#endif /* LDAP_DNS */
getline( line, sizeof(line), stdin,
"Recognize and chase referrals (0=no, 1=yes)?" );
optval = ( atoi( line ) != 0 );
ldap_set_option( ld, LDAP_OPT_REFERRALS,
(void *) optval );
if ( optval ) {
getline( line, sizeof(line), stdin,
"Prompt for bind credentials when chasing referrals (0=no, 1=yes)?" );
if ( atoi( line ) != 0 ) {
ldap_set_rebind_proc( ld, bind_prompt,
NULL );
}
}
#ifdef NET_SSL
getline( line, sizeof(line), stdin,
"Use Secure Sockets Layer - SSL (0=no, 1=yes)?" );
optval = ( atoi( line ) != 0 );
if ( optval ) {
getline( line, sizeof(line), stdin,
"security DB path?" );
if ( ldapssl_client_init( (*line == '\0') ?
NULL : line, &certdbhandle ) < 0 ) {
perror( "ldapssl_client_init" );
optval = 0; /* SSL not avail. */
} else if ( ldapssl_install_routines( ld )
< 0 ) {
ldap_perror( ld,
"ldapssl_install_routines" );
optval = 0; /* SSL not avail. */
}
}
ldap_set_option( ld, LDAP_OPT_SSL,
optval ? LDAP_OPT_ON : LDAP_OPT_OFF );
#endif
getline( line, sizeof(line), stdin, "Reconnect?" );
ldap_set_option( ld, LDAP_OPT_RECONNECT,
( atoi( line ) == 0 ) ? LDAP_OPT_OFF :
LDAP_OPT_ON );
break;
case 'I': /* initialize display templates */
getline( line, sizeof(line), stdin,
"Template file [ldaptemplates.conf]?" );
if (( i = ldap_init_templates( *line == '\0' ?
"ldaptemplates.conf" : line, &tmpllist ))
!= 0 ) {
fprintf( stderr, "ldap_init_templates: %s\n",
ldap_tmplerr2string( i ));
}
break;
case 'T': /* read & display using template */
getline( dn, sizeof(dn), stdin, "entry DN? " );
strcat( dn, dnsuffix );
if (( i = ldap_entry2text_search( ld, dn, NULL, NULL,
tmpllist, NULL, NULL, entry2textwrite, stdout,
"\n", 0, 0 )) != LDAP_SUCCESS ) {
fprintf( stderr, "ldap_entry2text_search: %s\n",
ldap_err2string( i ));
}
break;
case 'L': /* set preferred language */
getline( line, sizeof(line), stdin,
"Preferred language? " );
if ( *line == '\0' ) {
ldap_set_option( ld,
LDAP_OPT_PREFERRED_LANGUAGE, NULL );
} else {
ldap_set_option( ld,
LDAP_OPT_PREFERRED_LANGUAGE, line );
}
break;
case 'F': /* create filter */
{
char filtbuf[ 512 ], pattern[ 512 ];
char prefix[ 512 ], suffix[ 512 ];
char attr[ 512 ], value[ 512 ];
char *dupvalue, **words;
getline( pattern, sizeof(pattern), stdin,
"pattern? " );
getline( prefix, sizeof(prefix), stdin,
"prefix? " );
getline( suffix, sizeof(suffix), stdin,
"suffix? " );
getline( attr, sizeof(attr), stdin,
"attribute? " );
getline( value, sizeof(value), stdin,
"value? " );
if (( dupvalue = strdup( value )) != NULL ) {
words = string2words( value, " " );
} else {
words = NULL;
}
if ( ldap_create_filter( filtbuf,
sizeof(filtbuf), pattern, prefix, suffix,
attr, value, words) != 0 ) {
fprintf( stderr,
"ldap_create_filter failed\n" );
} else {
printf( "filter is \"%s\"\n", filtbuf );
}
if ( dupvalue != NULL ) free( dupvalue );
if ( words != NULL ) free( words );
}
break;
case '?': /* help */
case '\0': /* help */
printf( "Commands: [ad]d [ab]andon [b]ind\n" );
printf( " synch [B]ind [c]ompare [l]URL search\n" );
printf( " [modi]fy [modr]dn [rem]ove\n" );
printf( " [res]ult [s]earch [q]uit/unbind\n\n" );
printf( " [u]fn search [ut]fn search with timeout\n" );
printf( " [d]ebug [C]set cache parms[g]set msgid\n" );
printf( " d[n]suffix [t]imeout [v]ersion\n" );
printf( " [U]fn prefix [?]help [o]ptions\n" );
printf( " [E]xplode dn [p]arse LDAP URL [R]explode RDN\n" );
printf( " e[x]tended op [F]ilter create\n" );
printf( " set co[N]trols set preferred [L]anguage\n" );
printf( " add a [P]ersistent search control\n" );
printf( " [I]nitialize display templates\n" );
printf( " [T]read entry and display using template\n" );
break;
default:
printf( "Invalid command. Type ? for help.\n" );
break;
}
(void) memset( line, '\0', sizeof(line) );
}
return( 0 );
}
static void
handle_result( LDAP *ld, LDAPMessage *lm, int onlyone )
{
int msgtype;
switch ( (msgtype = ldap_msgtype( lm )) ) {
case LDAP_RES_COMPARE:
printf( "Compare result\n" );
print_ldap_result( ld, lm, "compare" );
break;
case LDAP_RES_SEARCH_RESULT:
printf( "Search result\n" );
print_ldap_result( ld, lm, "search" );
break;
case LDAP_RES_SEARCH_ENTRY:
printf( "Search entry\n" );
print_search_entry( ld, lm, onlyone );
break;
case LDAP_RES_SEARCH_REFERENCE:
printf( "Search reference\n" );
print_search_reference( ld, lm, onlyone );
break;
case LDAP_RES_ADD:
printf( "Add result\n" );
print_ldap_result( ld, lm, "add" );
break;
case LDAP_RES_DELETE:
printf( "Delete result\n" );
print_ldap_result( ld, lm, "delete" );
break;
case LDAP_RES_MODIFY:
printf( "Modify result\n" );
print_ldap_result( ld, lm, "modify" );
break;
case LDAP_RES_MODRDN:
printf( "ModRDN result\n" );
print_ldap_result( ld, lm, "modrdn" );
break;
case LDAP_RES_BIND:
printf( "Bind result\n" );
print_ldap_result( ld, lm, "bind" );
break;
case LDAP_RES_EXTENDED:
if ( ldap_msgid( lm ) == LDAP_RES_UNSOLICITED ) {
printf( "Unsolicited result\n" );
print_ldap_result( ld, lm, "unsolicited" );
} else {
printf( "ExtendedOp result\n" );
print_ldap_result( ld, lm, "extendedop" );
}
break;
default:
printf( "Unknown result type 0x%x\n", msgtype );
print_ldap_result( ld, lm, "unknown" );
}
if ( !onlyone ) {
ldap_msgfree( lm );
}
}
static void
print_ldap_result( LDAP *ld, LDAPMessage *lm, char *s )
{
int lderr;
char *matcheddn, *errmsg, *oid, **refs;
LDAPControl **ctrls;
struct berval *servercred, *data;
if ( ldap_parse_result( ld, lm, &lderr, &matcheddn, &errmsg, &refs,
&ctrls, 0 ) != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_parse_result" );
} else {
fprintf( stderr, "%s: %s", s, ldap_err2string( lderr ));
if ( lderr == LDAP_CONNECT_ERROR ) {
perror( " - " );
} else {
fputc( '\n', stderr );
}
if ( errmsg != NULL ) {
if ( *errmsg != '\0' ) {
fprintf( stderr, "Additional info: %s\n",
errmsg );
}
ldap_memfree( errmsg );
}
if ( matcheddn != NULL ) {
if ( NAME_ERROR( lderr )) {
fprintf( stderr, "Matched DN: %s\n",
matcheddn );
}
ldap_memfree( matcheddn );
}
print_referrals( refs, 1 );
print_controls( ctrls, 1 );
}
/* if SASL bind response, get and show server credentials */
if ( ldap_msgtype( lm ) == LDAP_RES_BIND &&
ldap_parse_sasl_bind_result( ld, lm, &servercred, 0 ) ==
LDAP_SUCCESS && servercred != NULL ) {
fputs( "\tSASL server credentials:\n", stderr );
bprint( servercred->bv_val, servercred->bv_len );
ber_bvfree( servercred );
}
/* if ExtendedOp response, get and show oid plus data */
if ( ldap_msgtype( lm ) == LDAP_RES_EXTENDED &&
ldap_parse_extended_result( ld, lm, &oid, &data, 0 ) ==
LDAP_SUCCESS ) {
if ( oid != NULL ) {
if ( strcmp ( oid, LDAP_NOTICE_OF_DISCONNECTION )
== 0 ) {
printf(
"\t%s Notice of Disconnection (OID: %s)\n",
s, oid );
} else {
printf( "\t%s OID: %s\n", s, oid );
}
ldap_memfree( oid );
}
if ( data != NULL ) {
printf( "\t%s data:\n", s );
bprint( data->bv_val, data->bv_len );
ber_bvfree( data );
}
}
}
static void
print_search_entry( LDAP *ld, LDAPMessage *res, int onlyone )
{
BerElement *ber;
char *a, *dn, *ufn;
struct berval **vals;
int i, count;
LDAPMessage *e, *msg;
LDAPControl **ectrls;
count = 0;
for ( msg = ldap_first_message( ld, res );
msg != NULL && ( !onlyone || count == 0 );
msg = ldap_next_message( ld, msg ), ++count ) {
if ( ldap_msgtype( msg ) != LDAP_RES_SEARCH_ENTRY ) {
handle_result( ld, msg, 1 ); /* something else */
continue;
}
e = msg;
dn = ldap_get_dn( ld, e );
printf( "\tDN: %s\n", dn );
ufn = ldap_dn2ufn( dn );
printf( "\tUFN: %s\n", ufn );
#ifdef WINSOCK
ldap_memfree( dn );
ldap_memfree( ufn );
#else /* WINSOCK */
free( dn );
free( ufn );
#endif /* WINSOCK */
for ( a = ldap_first_attribute( ld, e, &ber ); a != NULL;
a = ldap_next_attribute( ld, e, ber ) ) {
printf( "\t\tATTR: %s\n", a );
if ( (vals = ldap_get_values_len( ld, e, a ))
== NULL ) {
printf( "\t\t\t(no values)\n" );
} else {
for ( i = 0; vals[i] != NULL; i++ ) {
int nonascii = 0;
unsigned long j;
for ( j = 0; j < vals[i]->bv_len; j++ )
if ( !isascii( vals[i]->bv_val[j] ) ) {
nonascii = 1;
break;
}
if ( nonascii ) {
printf( "\t\t\tlength (%ld) (not ascii)\n", vals[i]->bv_len );
#ifdef BPRINT_NONASCII
bprint( vals[i]->bv_val,
vals[i]->bv_len );
#endif /* BPRINT_NONASCII */
continue;
}
printf( "\t\t\tlength (%ld) %s\n",
vals[i]->bv_len, vals[i]->bv_val );
}
ber_bvecfree( vals );
}
ldap_memfree( a );
}
if ( ldap_get_lderrno( ld, NULL, NULL ) != LDAP_SUCCESS ) {
ldap_perror( ld,
"ldap_first_attribute/ldap_next_attribute" );
}
if ( ber != NULL ) {
ber_free( ber, 0 );
}
if ( ldap_get_entry_controls( ld, e, &ectrls )
!= LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_get_entry_controls" );
} else {
int changetype, changenumpresent;
char *prevdn;
long changenum;
if ( ldap_parse_entrychange_control( ld, ectrls,
&changetype, &prevdn, &changenumpresent,
&changenum ) == LDAP_SUCCESS ) {
fprintf( stderr, "EntryChangeNotification\n"
"\tchangeType: %s\n",
changetype_num2string( changetype ));
if ( prevdn != NULL ) {
fprintf( stderr,
"\tpreviousDN: \"%s\"\n",
prevdn );
}
if ( changenumpresent ) {
fprintf( stderr, "\tchangeNumber: %d\n",
changenum );
}
if ( prevdn != NULL ) {
free( prevdn );
}
}
print_controls( ectrls, 1 );
}
}
}
static char *
changetype_num2string( int chgtype )
{
static char buf[ 25 ];
char *s;
switch( chgtype ) {
case LDAP_CHANGETYPE_ADD:
s = "add";
break;
case LDAP_CHANGETYPE_DELETE:
s = "delete";
break;
case LDAP_CHANGETYPE_MODIFY:
s = "modify";
break;
case LDAP_CHANGETYPE_MODDN:
s = "moddn";
break;
default:
s = buf;
sprintf( s, "unknown (%d)", chgtype );
}
return( s );
}
static void
print_search_reference( LDAP *ld, LDAPMessage *res, int onlyone )
{
LDAPMessage *msg;
LDAPControl **ctrls;
char **refs;
int count;
count = 0;
for ( msg = ldap_first_message( ld, res );
msg != NULL && ( !onlyone || count == 0 );
msg = ldap_next_message( ld, msg ), ++count ) {
if ( ldap_msgtype( msg ) != LDAP_RES_SEARCH_REFERENCE ) {
handle_result( ld, msg, 1 ); /* something else */
continue;
}
if ( ldap_parse_reference( ld, msg, &refs, &ctrls, 0 ) !=
LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_parse_reference" );
} else {
print_referrals( refs, 1 );
print_controls( ctrls, 1 );
}
}
}
static void
print_referrals( char **refs, int freeit )
{
int i;
if ( refs == NULL ) {
return;
}
fprintf( stderr, "Referrals:\n" );
for ( i = 0; refs[ i ] != NULL; ++i ) {
fprintf( stderr, "\t%s\n", refs[ i ] );
}
if ( freeit ) {
ldap_value_free( refs );
}
}
static void
print_controls( LDAPControl **ctrls, int freeit )
{
int i;
if ( ctrls == NULL ) {
return;
}
fprintf( stderr, "Controls:\n" );
for ( i = 0; ctrls[ i ] != NULL; ++i ) {
if ( i > 0 ) {
fputs( "\t-----------\n", stderr );
}
fprintf( stderr, "\toid: %s\n", ctrls[ i ]->ldctl_oid );
fprintf( stderr, "\tcritical: %s\n",
ctrls[ i ]->ldctl_iscritical ? "YES" : "NO" );
fputs( "\tvalue:\n", stderr );
bprint( ctrls[ i ]->ldctl_value.bv_val,
ctrls[ i ]->ldctl_value.bv_len );
}
if ( freeit ) {
ldap_controls_free( ctrls );
}
}
static int
entry2textwrite( void *fp, char *buf, int len )
{
return( fwrite( buf, len, 1, (FILE *)fp ) == 0 ? -1 : len );
}
/* similar to getfilter.c:break_into_words() */
static char **
string2words( char *str, char *delims )
{
char *word, **words;
int count;
char *lasts;
if (( words = (char **)calloc( 1, sizeof( char * ))) == NULL ) {
return( NULL );
}
count = 0;
words[ count ] = NULL;
word = ldap_utf8strtok_r( str, delims, &lasts );
while ( word != NULL ) {
if (( words = (char **)realloc( words,
( count + 2 ) * sizeof( char * ))) == NULL ) {
free( words );
return( NULL );
}
words[ count ] = word;
words[ ++count ] = NULL;
word = ldap_utf8strtok_r( NULL, delims, &lasts );
}
return( words );
}
static const char *
url_parse_err2string( int e )
{
const char *s = "unknown";
switch( e ) {
case LDAP_URL_ERR_NOTLDAP:
s = "URL doesn't begin with \"ldap://\"";
break;
case LDAP_URL_ERR_NODN:
s = "URL has no DN (required)";
break;
case LDAP_URL_ERR_BADSCOPE:
s = "URL scope string is invalid";
break;
case LDAP_URL_ERR_MEM:
s = "can't allocate memory space";
break;
case LDAP_URL_ERR_PARAM:
s = "bad parameter to an URL function";
break;
case LDAP_URL_UNRECOGNIZED_CRITICAL_EXTENSION:
s = "unrecognized critical URL extension";
break;
}
return( s );
}
/*
* Print arbitrary stuff, for debugging.
*/
#define BPLEN 48
static void
bprint( char *data, int len )
{
static char hexdig[] = "0123456789abcdef";
char out[ BPLEN ];
int i = 0;
memset( out, 0, BPLEN );
for ( ;; ) {
if ( len < 1 ) {
fprintf( stderr, "\t%s\n", ( i == 0 ) ? "(end)" : out );
break;
}
#ifndef HEX
if ( isgraph( (unsigned char)*data )) {
out[ i ] = ' ';
out[ i+1 ] = *data;
} else {
#endif
out[ i ] = hexdig[ ( *data & 0xf0 ) >> 4 ];
out[ i+1 ] = hexdig[ *data & 0x0f ];
#ifndef HEX
}
#endif
i += 2;
len--;
data++;
if ( i > BPLEN - 2 ) {
fprintf( stderr, "\t%s\n", out );
memset( out, 0, BPLEN );
i = 0;
continue;
}
out[ i++ ] = ' ';
}
fflush( stderr );
}