mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-09 09:20:15 +01:00
1865 lines
45 KiB
C
1865 lines
45 KiB
C
/* ***** 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 );
|
|
}
|