X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=clients%2Ftools%2Fcommon.c;h=05430415fa8c3fd638abd3107d8f5153a6247ecc;hb=ea44e65a82eecb0eec29d2fcd07beb900b3e02da;hp=69ab796c3ea3284e5ba2151cc73aadf30f4773b8;hpb=0ad86cb23ad5a115f5b16649636c898060ac8292;p=openldap diff --git a/clients/tools/common.c b/clients/tools/common.c index 69ab796c3e..05430415fa 100644 --- a/clients/tools/common.c +++ b/clients/tools/common.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2008 The OpenLDAP Foundation. + * Copyright 1998-2012 The OpenLDAP Foundation. * Portions Copyright 2003 Kurt D. Zeilenga. * Portions Copyright 2003 IBM Corporation. * All rights reserved. @@ -62,9 +62,11 @@ int contoper = 0; int debug = 0; char *infile = NULL; int dont = 0; +int nocanon = 0; int referrals = 0; int verbose = 0; int ldif = 0; +ber_len_t ldif_wrap = LDIF_LINE_WIDTH; char *prog = NULL; /* connection */ @@ -119,6 +121,9 @@ static int chainingContinuation = -1; static int sessionTracking = 0; struct berval stValue; #endif /* LDAP_CONTROL_X_SESSION_TRACKING */ +ber_int_t vlvPos; +ber_int_t vlvCount; +struct berval *vlvContext; LDAPControl *unknown_ctrls = NULL; int unknown_ctrls_num = 0; @@ -135,6 +140,13 @@ static int print_paged_results( LDAP *ld, LDAPControl *ctrl ); static int print_ppolicy( LDAP *ld, LDAPControl *ctrl ); #endif static int print_sss( LDAP *ld, LDAPControl *ctrl ); +static int print_vlv( LDAP *ld, LDAPControl *ctrl ); +#ifdef LDAP_CONTROL_X_DEREF +static int print_deref( LDAP *ld, LDAPControl *ctrl ); +#endif +#ifdef LDAP_CONTROL_X_WHATFAILED +static int print_whatfailed( LDAP *ld, LDAPControl *ctrl ); +#endif static struct tool_ctrls_t { const char *oid; @@ -148,6 +160,13 @@ static struct tool_ctrls_t { { LDAP_CONTROL_PASSWORDPOLICYRESPONSE, TOOL_ALL, print_ppolicy }, #endif { LDAP_CONTROL_SORTRESPONSE, TOOL_SEARCH, print_sss }, + { LDAP_CONTROL_VLVRESPONSE, TOOL_SEARCH, print_vlv }, +#ifdef LDAP_CONTROL_X_DEREF + { LDAP_CONTROL_X_DEREF, TOOL_SEARCH, print_deref }, +#endif +#ifdef LDAP_CONTROL_X_WHATFAILED + { LDAP_CONTROL_X_WHATFAILED, TOOL_ALL, print_whatfailed }, +#endif { NULL, 0, NULL } }; @@ -220,6 +239,10 @@ tool_init( tool_type_t type ) void tool_destroy( void ) { + static int destroyed; + if ( destroyed++ ) + return; + #ifdef HAVE_CYRUS_SASL sasl_done(); #endif @@ -234,8 +257,47 @@ tool_destroy( void ) if ( pr_cookie.bv_val != NULL ) { ber_memfree( pr_cookie.bv_val ); - pr_cookie.bv_val = NULL; - pr_cookie.bv_len = 0; + BER_BVZERO( &pr_cookie ); + } + + if ( binddn != NULL ) { + ber_memfree( binddn ); + binddn = NULL; + } + + if ( passwd.bv_val != NULL ) { + ber_memfree( passwd.bv_val ); + BER_BVZERO( &passwd ); + } + + if ( infile != NULL ) { + ber_memfree( infile ); + infile = NULL; + } + + if ( assertion ) { + ber_memfree( assertion ); + assertion = NULL; + } + + if ( authzid ) { + ber_memfree( authzid ); + authzid = NULL; + } + + if ( proxydn ) { + ber_memfree( proxydn ); + proxydn = NULL; + } + + if ( preread_attrs ) { + ber_memfree( preread_attrs ); + preread_attrs = NULL; + } + + if ( postread_attrs ) { + ber_memfree( postread_attrs ); + postread_attrs = NULL; } } @@ -243,12 +305,11 @@ void tool_common_usage( void ) { static const char *const descriptions[] = { -N_(" -c continuous operation mode (do not stop on errors)\n"), N_(" -d level set LDAP debugging level to `level'\n"), N_(" -D binddn bind DN\n"), N_(" -e [!][=] general extensions (! indicates criticality)\n") -N_(" [!]assert= (a RFC 4515 Filter string)\n") -N_(" [!]authzid= (\"dn:\" or \"u:\")\n") +N_(" [!]assert= (RFC 4528; a RFC 4515 Filter string)\n") +N_(" [!]authzid= (RFC 4370; \"dn:\" or \"u:\")\n") #ifdef LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ #if 0 /* non-advertized support for proxyDN */ @@ -260,13 +321,13 @@ N_(" [!]chaining[=[/]]\n") N_(" one of \"chainingPreferred\", \"chainingRequired\",\n") N_(" \"referralsPreferred\", \"referralsRequired\"\n") #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ -N_(" [!]manageDSAit\n") +N_(" [!]manageDSAit (RFC 3296)\n") N_(" [!]noop\n") #ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST N_(" ppolicy\n") #endif -N_(" [!]postread[=] (a comma-separated attribute list)\n") -N_(" [!]preread[=] (a comma-separated attribute list)\n") +N_(" [!]postread[=] (RFC 4527; comma-separated attr list)\n") +N_(" [!]preread[=] (RFC 4527; comma-separated attr list)\n") N_(" [!]relax\n") #ifdef LDAP_CONTROL_X_SESSION_TRACKING N_(" [!]sessiontracking\n") @@ -274,17 +335,16 @@ N_(" [!]sessiontracking\n") N_(" abandon, cancel, ignore (SIGINT sends abandon/cancel,\n" " or ignores response; if critical, doesn't wait for SIGINT.\n" " not really controls)\n") -N_(" -f file read operations from `file'\n"), N_(" -h host LDAP server\n"), N_(" -H URI LDAP Uniform Resource Identifier(s)\n"), N_(" -I use SASL Interactive mode\n"), -N_(" -M enable Manage DSA IT control (-MM to make critical)\n"), N_(" -n show what would be done but don't actually do it\n"), +N_(" -N do not use reverse DNS to canonicalize SASL host name\n"), N_(" -O props SASL security properties\n"), -N_(" -o [=[=] general options\n"), N_(" nettimeout= (in seconds, or \"none\" or \"max\")\n"), +N_(" ldif-wrap= (in columns, or \"no\" for no wrapping)\n"), N_(" -p port port on LDAP server\n"), -N_(" -P version protocol version (default: 3)\n"), N_(" -Q use SASL Quiet mode\n"), N_(" -R realm SASL realm\n"), N_(" -U authcid SASL authentication identity\n"), @@ -307,6 +367,8 @@ NULL fputs( _(*cpp), stderr ); } } + + tool_destroy(); } void tool_perror( @@ -350,7 +412,7 @@ tool_args( int argc, char **argv ) case 'c': /* continuous operation mode */ contoper++; break; - case 'C': + case 'C': /* referrals: obsolete */ referrals++; break; case 'd': @@ -398,7 +460,7 @@ tool_args( int argc, char **argv ) assertctl = 1 + crit; assert( assertion == NULL ); - assertion = cvalue; + assertion = ber_strdup( cvalue ); } else if ( strcasecmp( control, "authzid" ) == 0 ) { if( authzid != NULL ) { @@ -421,7 +483,7 @@ tool_args( int argc, char **argv ) } assert( authzid == NULL ); - authzid = cvalue; + authzid = ber_strdup( cvalue ); #ifdef LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ } else if ( strcasecmp( control, "proxydn" ) == 0 ) { @@ -443,7 +505,7 @@ tool_args( int argc, char **argv ) } assert( proxydn == NULL ); - proxydn = cvalue; + proxydn = ber_strdup( cvalue ); #endif /* LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ */ } else if ( ( strcasecmp( control, "relax" ) == 0 ) || @@ -513,7 +575,7 @@ tool_args( int argc, char **argv ) } preread = 1 + crit; - preread_attrs = cvalue; + preread_attrs = ber_strdup( cvalue ); } else if ( strcasecmp( control, "postread" ) == 0 ) { if( postread ) { @@ -522,7 +584,7 @@ tool_args( int argc, char **argv ) } postread = 1 + crit; - postread_attrs = cvalue; + postread_attrs = ber_strdup( cvalue ); #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR } else if ( strcasecmp( control, "chaining" ) == 0 ) { @@ -570,6 +632,19 @@ tool_args( int argc, char **argv ) } #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ +#ifdef LDAP_CONTROL_X_SESSION_TRACKING + } else if ( strcasecmp( control, "sessiontracking" ) == 0 ) { + if ( sessionTracking ) { + fprintf( stderr, "%s: session tracking can be only specified once\n", prog ); + exit( EXIT_FAILURE ); + } + sessionTracking = 1; + if( crit ) { + fprintf( stderr, "sessiontracking: critical flag not allowed\n" ); + usage(); + } +#endif /* LDAP_CONTROL_X_SESSION_TRACKING */ + /* this shouldn't go here, really; but it's a feature... */ } else if ( strcasecmp( control, "abandon" ) == 0 ) { abcan = Intr_Abandon; @@ -589,19 +664,10 @@ tool_args( int argc, char **argv ) gotintr = abcan; } -#ifdef LDAP_CONTROL_X_SESSION_TRACKING - } else if ( strcasecmp( control, "sessiontracking" ) == 0 ) { - if ( sessionTracking ) { - fprintf( stderr, "%s: session tracking can be only specified once\n", prog ); - exit( EXIT_FAILURE ); - } - sessionTracking = 1; -#endif /* LDAP_CONTROL_X_SESSION_TRACKING */ - } else if ( tool_is_oid( control ) ) { LDAPControl *tmpctrls, ctrl; - tmpctrls = (LDAPControl *)realloc( unknown_ctrls, + tmpctrls = (LDAPControl *)ber_memrealloc( unknown_ctrls, (unknown_ctrls_num + 1)*sizeof( LDAPControl ) ); if ( tmpctrls == NULL ) { fprintf( stderr, "%s: no memory?\n", prog ); @@ -609,6 +675,8 @@ tool_args( int argc, char **argv ) } unknown_ctrls = tmpctrls; ctrl.ldctl_oid = control; + /* don't free it */ + control = NULL; ctrl.ldctl_value.bv_val = NULL; ctrl.ldctl_value.bv_len = 0; ctrl.ldctl_iscritical = crit; @@ -625,7 +693,7 @@ tool_args( int argc, char **argv ) (unsigned char *)bv.bv_val, bv.bv_len ); - if ( retcode == -1 || retcode > bv.bv_len ) { + if ( retcode == -1 || (unsigned) retcode > bv.bv_len ) { fprintf( stderr, "Unable to parse value of general control %s\n", control ); usage(); @@ -643,6 +711,10 @@ tool_args( int argc, char **argv ) control ); usage(); } + if ( control ) { + ber_memfree( control ); + control = NULL; + } break; case 'f': /* read from file */ if( infile != NULL ) { @@ -688,6 +760,9 @@ tool_args( int argc, char **argv ) case 'n': /* print operations, don't actually do them */ dont++; break; + case 'N': + nocanon++; + break; case 'o': control = ber_strdup( optarg ); if ( (cvalue = strchr( control, '=' )) != NULL ) { @@ -721,11 +796,30 @@ tool_args( int argc, char **argv ) prog, (long)nettimeout.tv_sec ); exit( EXIT_FAILURE ); } + + } else if ( strcasecmp( control, "ldif-wrap" ) == 0 ) { + if ( cvalue == 0 ) { + ldif_wrap = LDIF_LINE_WIDTH; + + } else if ( strcasecmp( cvalue, "no" ) == 0 ) { + ldif_wrap = LDIF_LINE_WIDTH_MAX; + + } else { + unsigned int u; + if ( lutil_atou( &u, cvalue ) ) { + fprintf( stderr, + _("Unable to parse ldif-wrap=\"%s\"\n"), cvalue ); + exit( EXIT_FAILURE ); + } + ldif_wrap = (ber_len_t)u; + } + } else { fprintf( stderr, "Invalid general option name: %s\n", control ); usage(); } + ber_memfree(control); break; case 'O': #ifdef HAVE_CYRUS_SASL @@ -981,7 +1075,11 @@ tool_args( int argc, char **argv ) if (authmethod == -1 && protocol > LDAP_VERSION2) { #ifdef HAVE_CYRUS_SASL - authmethod = LDAP_AUTH_SASL; + if ( binddn != NULL ) { + authmethod = LDAP_AUTH_SIMPLE; + } else { + authmethod = LDAP_AUTH_SASL; + } #else authmethod = LDAP_AUTH_SIMPLE; #endif @@ -1033,6 +1131,12 @@ tool_args( int argc, char **argv ) } #endif } + + if ( ( pw_file || want_bindpw ) && !BER_BVISNULL( &passwd ) ) { + fprintf( stderr, "%s: -%c incompatible with -w\n", + prog, ( pw_file ? 'y' : 'W' ) ); + exit( EXIT_FAILURE ); + } } @@ -1140,7 +1244,7 @@ tool_conn_setup( int dont, void (*private_setup)( LDAP * ) ) for ( i = 0; hosts[ i ] != NULL; i++ ) /* count'em */ ; - tmp = (char **)realloc( urls, sizeof( char * ) * ( nurls + i + 1 ) ); + tmp = (char **)ber_memrealloc( urls, sizeof( char * ) * ( nurls + i + 1 ) ); if ( tmp == NULL ) { fprintf( stderr, "DNS SRV: out of memory?\n" ); @@ -1174,7 +1278,7 @@ dnssrv_free:; ber_memfree( domain ); } else { - tmp = (char **)realloc( urls, sizeof( char * ) * ( nurls + 2 ) ); + tmp = (char **)ber_memrealloc( urls, sizeof( char * ) * ( nurls + 2 ) ); if ( tmp == NULL ) { fprintf( stderr, "DNS SRV: out of memory?\n" ); @@ -1225,29 +1329,43 @@ dnssrv_free:; if( private_setup ) private_setup( ld ); - /* referrals */ + /* referrals: obsolete */ 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 ); + tool_exit( ld, EXIT_FAILURE ); } +#ifdef HAVE_CYRUS_SASL + /* canon */ + if( nocanon ) { + if( ldap_set_option( ld, LDAP_OPT_X_SASL_NOCANON, + LDAP_OPT_ON ) != LDAP_OPT_SUCCESS ) + { + fprintf( stderr, "Could not set LDAP_OPT_X_SASL_NOCANON on\n" ); + tool_exit( ld, EXIT_FAILURE ); + } + } +#endif 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 ); + tool_exit( ld, EXIT_FAILURE ); } if ( use_tls ) { rc = ldap_start_tls_s( ld, NULL, NULL ); if ( rc != LDAP_SUCCESS ) { - tool_perror( "ldap_start_tls", rc, NULL, NULL, NULL, NULL ); + char *msg=NULL; + ldap_get_option( ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, (void*)&msg); + tool_perror( "ldap_start_tls", rc, NULL, NULL, msg, NULL ); + ldap_memfree(msg); if ( use_tls > 1 ) { - exit( EXIT_FAILURE ); + tool_exit( ld, EXIT_FAILURE ); } } } @@ -1258,7 +1376,7 @@ dnssrv_free:; { fprintf( stderr, "Could not set LDAP_OPT_NETWORK_TIMEOUT %ld\n", (long)nettimeout.tv_sec ); - exit( EXIT_FAILURE ); + tool_exit( ld, EXIT_FAILURE ); } } } @@ -1292,8 +1410,8 @@ tool_bind( LDAP *ld ) if ( sessionTracking ) { LDAPControl c; - if (stValue.bv_val == NULL && st_value( ld, &stValue ) ) { - exit( EXIT_FAILURE ); + if ( BER_BVISNULL( &stValue) && st_value( ld, &stValue ) ) { + tool_exit( ld, EXIT_FAILURE ); } c.ldctl_oid = LDAP_CONTROL_X_SESSION_TRACKING; @@ -1310,7 +1428,24 @@ tool_bind( LDAP *ld ) sctrlsp = sctrls; } - assert( nsctrls < sizeof(sctrls)/sizeof(sctrls[0]) ); + assert( nsctrls < (int) (sizeof(sctrls)/sizeof(sctrls[0])) ); + + if ( pw_file || want_bindpw ) { + assert( passwd.bv_val == NULL && passwd.bv_len == 0 ); + + if ( pw_file ) { + if ( lutil_get_filed_password( pw_file, &passwd ) ) { + tool_exit( ld, EXIT_FAILURE ); + } + + } else { + char *pw = getpassphrase( _("Enter LDAP Password: ") ); + if ( pw ) { + passwd.bv_val = ber_strdup( pw ); + passwd.bv_len = strlen( passwd.bv_val ); + } + } + } if ( authmethod == LDAP_AUTH_SASL ) { #ifdef HAVE_CYRUS_SASL @@ -1325,7 +1460,7 @@ tool_bind( LDAP *ld ) fprintf( stderr, "Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n", sasl_secprops ); - exit( LDAP_LOCAL_ERROR ); + tool_exit( ld, LDAP_LOCAL_ERROR ); } } @@ -1342,13 +1477,16 @@ tool_bind( LDAP *ld ) lutil_sasl_freedefs( defaults ); if( rc != LDAP_SUCCESS ) { + char *msg=NULL; + ldap_get_option( ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, (void*)&msg); tool_perror( "ldap_sasl_interactive_bind_s", - rc, NULL, NULL, NULL, NULL ); - exit( rc ); + rc, NULL, NULL, msg, NULL ); + ldap_memfree(msg); + tool_exit( ld, rc ); } #else fprintf( stderr, "%s: not compiled with SASL support\n", prog ); - exit( LDAP_NOT_SUPPORTED ); + tool_exit( ld, LDAP_NOT_SUPPORTED ); #endif } else { int msgid, err, rc; @@ -1368,20 +1506,26 @@ tool_bind( LDAP *ld ) if ( msgid == -1 ) { tool_perror( "ldap_sasl_bind(SIMPLE)", rc, NULL, NULL, NULL, NULL ); - exit( rc ); + tool_exit( ld, rc ); } } - if ( ldap_result( ld, msgid, LDAP_MSG_ALL, NULL, &result ) == -1 ) { + rc = ldap_result( ld, msgid, LDAP_MSG_ALL, NULL, &result ); + if ( rc == -1 ) { tool_perror( "ldap_result", -1, NULL, NULL, NULL, NULL ); - exit( LDAP_LOCAL_ERROR ); + tool_exit( ld, LDAP_LOCAL_ERROR ); + } + + if ( rc == 0 ) { + tool_perror( "ldap_result", LDAP_TIMEOUT, NULL, NULL, NULL, NULL ); + tool_exit( ld, LDAP_LOCAL_ERROR ); } rc = ldap_parse_result( ld, result, &err, &matched, &info, &refs, &ctrls, 1 ); if ( rc != LDAP_SUCCESS ) { tool_perror( "ldap_bind parse result", rc, NULL, matched, info, refs ); - exit( LDAP_LOCAL_ERROR ); + tool_exit( ld, LDAP_LOCAL_ERROR ); } #ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST @@ -1431,7 +1575,7 @@ tool_bind( LDAP *ld ) if( info ) ber_memfree( info ); if( refs ) ber_memvfree( (void **)refs ); - if ( err != LDAP_SUCCESS ) exit( err ); + if ( err != LDAP_SUCCESS ) tool_exit( ld, err ); } } } @@ -1448,6 +1592,16 @@ tool_unbind( LDAP *ld ) (void) ldap_unbind_ext( ld, NULL, NULL ); } +void +tool_exit( LDAP *ld, int status ) +{ + if ( ld != NULL ) { + tool_unbind( ld ); + } + tool_destroy(); + exit( status ); +} + /* Set server controls. Add controls extra_c[0..count-1], if set. */ void @@ -1484,7 +1638,7 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count ) ctrls = (LDAPControl**) malloc(sizeof(c) + (count + unknown_ctrls_num + 1)*sizeof(LDAPControl*)); if ( ctrls == NULL ) { fprintf( stderr, "No memory\n" ); - exit( EXIT_FAILURE ); + tool_exit( ld, EXIT_FAILURE ); } if ( assertctl ) { @@ -1523,12 +1677,12 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count ) ber_init2( ber, NULL, LBER_USE_DER ); - if ( ber_printf( ber, "s", proxydn ) == LBER_ERROR ) { - exit( EXIT_FAILURE ); + if ( ber_printf( ber, "s", proxydn ) == -1 ) { + tool_exit( ld, EXIT_FAILURE ); } if ( ber_flatten2( ber, &c[i].ldctl_value, 0 ) == -1 ) { - exit( EXIT_FAILURE ); + tool_exit( ld, EXIT_FAILURE ); } c[i].ldctl_oid = LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ; @@ -1573,8 +1727,8 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count ) #endif if ( preread ) { - char berbuf[LBER_ELEMENT_SIZEOF]; - BerElement *ber = (BerElement *)berbuf; + BerElementBuffer berbuf; + BerElement *ber = (BerElement *)&berbuf; char **attrs = NULL; if( preread_attrs ) { @@ -1585,13 +1739,13 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count ) if( ber_printf( ber, "{v}", attrs ) == -1 ) { fprintf( stderr, "preread attrs encode failed.\n" ); - exit( EXIT_FAILURE ); + tool_exit( ld, EXIT_FAILURE ); } err = ber_flatten2( ber, &c[i].ldctl_value, 0 ); if( err < 0 ) { fprintf( stderr, "preread flatten failed (%d)\n", err ); - exit( EXIT_FAILURE ); + tool_exit( ld, EXIT_FAILURE ); } c[i].ldctl_oid = LDAP_CONTROL_PRE_READ; @@ -1603,8 +1757,8 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count ) } if ( postread ) { - char berbuf[LBER_ELEMENT_SIZEOF]; - BerElement *ber = (BerElement *)berbuf; + BerElementBuffer berbuf; + BerElement *ber = (BerElement *)&berbuf; char **attrs = NULL; if( postread_attrs ) { @@ -1615,13 +1769,13 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count ) if( ber_printf( ber, "{v}", attrs ) == -1 ) { fprintf( stderr, "postread attrs encode failed.\n" ); - exit( EXIT_FAILURE ); + tool_exit( ld, EXIT_FAILURE ); } err = ber_flatten2( ber, &c[i].ldctl_value, 0 ); if( err < 0 ) { fprintf( stderr, "postread flatten failed (%d)\n", err ); - exit( EXIT_FAILURE ); + tool_exit( ld, EXIT_FAILURE ); } c[i].ldctl_oid = LDAP_CONTROL_POST_READ; @@ -1644,7 +1798,7 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count ) if ( err == -1 ) { ber_free( ber, 1 ); fprintf( stderr, _("Chaining behavior control encoding error!\n") ); - exit( EXIT_FAILURE ); + tool_exit( ld, EXIT_FAILURE ); } if ( chainingContinuation > -1 ) { @@ -1652,7 +1806,7 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count ) if ( err == -1 ) { ber_free( ber, 1 ); fprintf( stderr, _("Chaining behavior control encoding error!\n") ); - exit( EXIT_FAILURE ); + tool_exit( ld, EXIT_FAILURE ); } } @@ -1660,11 +1814,11 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count ) if ( err == -1 ) { ber_free( ber, 1 ); fprintf( stderr, _("Chaining behavior control encoding error!\n") ); - exit( EXIT_FAILURE ); + tool_exit( ld, EXIT_FAILURE ); } if ( ber_flatten2( ber, &c[i].ldctl_value, 0 ) == -1 ) { - exit( EXIT_FAILURE ); + tool_exit( ld, EXIT_FAILURE ); } } else { @@ -1680,8 +1834,8 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count ) #ifdef LDAP_CONTROL_X_SESSION_TRACKING if ( sessionTracking ) { - if ( stValue.bv_val == NULL && st_value( ld, &stValue ) ) { - exit( EXIT_FAILURE ); + if ( BER_BVISNULL( &stValue ) && st_value( ld, &stValue ) ) { + tool_exit( ld, EXIT_FAILURE ); } c[i].ldctl_oid = LDAP_CONTROL_X_SESSION_TRACKING; @@ -1713,7 +1867,7 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count ) free( ctrls ); if ( crit ) { - exit( EXIT_FAILURE ); + tool_exit( ld, EXIT_FAILURE ); } } @@ -1766,6 +1920,7 @@ print_prepostread( LDAP *ld, LDAPControl *ctrl, struct berval *what) while ( ber_scanf( ber, "{m" /*}*/, &bv ) != LBER_ERROR ) { int i; BerVarray vals = NULL; + char *str = NULL; if ( ber_scanf( ber, "[W]", &vals ) == LBER_ERROR || vals == NULL ) @@ -1773,14 +1928,25 @@ print_prepostread( LDAP *ld, LDAPControl *ctrl, struct berval *what) /* error? */ return 1; } + + if ( ldif ) { + char *ptr; + + str = malloc( bv.bv_len + STRLENOF(": ") + 1 ); + + ptr = str; + ptr = lutil_strncopy( ptr, bv.bv_val, bv.bv_len ); + ptr = lutil_strcopy( ptr, ": " ); + } for ( i = 0; vals[ i ].bv_val != NULL; i++ ) { tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE, - bv.bv_val, vals[ i ].bv_val, vals[ i ].bv_len ); + ldif ? str : bv.bv_val, vals[ i ].bv_val, vals[ i ].bv_len ); } ber_bvarray_free( vals ); + if ( str ) free( str ); } } @@ -1860,7 +2026,8 @@ print_paged_results( LDAP *ld, LDAPControl *ctrl ) } tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE, - "pagedresults", buf, ptr - buf ); + ldif ? "pagedresults: " : "pagedresults", + buf, ptr - buf ); } return 0; @@ -1876,15 +2043,179 @@ print_sss( LDAP *ld, LDAPControl *ctrl ) rc = ldap_parse_sortresponse_control( ld, ctrl, &err, &attr ); if ( rc == LDAP_SUCCESS ) { char buf[ BUFSIZ ]; - rc = snprintf( buf, sizeof(buf), "(%d) %s %s", - err, ldap_err2string(err), attr ? attr : "" ); + rc = snprintf( buf, sizeof(buf), "(%d) %s%s%s", + err, ldap_err2string(err), attr ? " " : "", attr ? attr : "" ); + + tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE, + ldif ? "sortResult: " : "sortResult", buf, rc ); + } + + return rc; +} + +static int +print_vlv( LDAP *ld, LDAPControl *ctrl ) +{ + int rc; + ber_int_t err; + struct berval bv; + + rc = ldap_parse_vlvresponse_control( ld, ctrl, &vlvPos, &vlvCount, + &vlvContext, &err ); + if ( rc == LDAP_SUCCESS ) { + char buf[ BUFSIZ ]; + + if ( vlvContext && vlvContext->bv_len > 0 ) { + bv.bv_len = LUTIL_BASE64_ENCODE_LEN( + vlvContext->bv_len ) + 1; + bv.bv_val = ber_memalloc( bv.bv_len + 1 ); + + bv.bv_len = lutil_b64_ntop( + (unsigned char *) vlvContext->bv_val, + vlvContext->bv_len, + bv.bv_val, bv.bv_len ); + } else { + bv.bv_val = ""; + bv.bv_len = 0; + } + + rc = snprintf( buf, sizeof(buf), "pos=%d count=%d context=%s (%d) %s", + vlvPos, vlvCount, bv.bv_val, + err, ldap_err2string(err)); + + if ( bv.bv_len ) + ber_memfree( bv.bv_val ); tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE, - "sortResult", buf, rc ); + ldif ? "vlvResult" : "vlvResult", buf, rc ); + } + + return rc; +} + +#ifdef LDAP_CONTROL_X_DEREF +static int +print_deref( LDAP *ld, LDAPControl *ctrl ) +{ + LDAPDerefRes *drhead = NULL, *dr; + int rc; + + rc = ldap_parse_derefresponse_control( ld, ctrl, &drhead ); + if ( rc != LDAP_SUCCESS ) { + return rc; } + for ( dr = drhead; dr != NULL; dr = dr->next ) { + LDAPDerefVal *dv; + ber_len_t len; + char *buf, *ptr; + + len = strlen( dr->derefAttr ) + STRLENOF(": "); + + for ( dv = dr->attrVals; dv != NULL; dv = dv->next ) { + if ( dv->vals != NULL ) { + int j; + ber_len_t tlen = strlen(dv->type); + + for ( j = 0; dv->vals[ j ].bv_val != NULL; j++ ) { + len += STRLENOF("<:=>;") + tlen + 4*((dv->vals[ j ].bv_len - 1)/3 + 1); + } + } + } + len += dr->derefVal.bv_len + STRLENOF("\n"); + buf = ldap_memalloc( len + 1 ); + if ( buf == NULL ) { + rc = LDAP_NO_MEMORY; + goto done; + } + + ptr = buf; + ptr = lutil_strcopy( ptr, dr->derefAttr ); + *ptr++ = ':'; + *ptr++ = ' '; + for ( dv = dr->attrVals; dv != NULL; dv = dv->next ) { + if ( dv->vals != NULL ) { + int j; + for ( j = 0; dv->vals[ j ].bv_val != NULL; j++ ) { + int k = ldif_is_not_printable( dv->vals[ j ].bv_val, dv->vals[ j ].bv_len ); + + *ptr++ = '<'; + ptr = lutil_strcopy( ptr, dv->type ); + if ( k ) { + *ptr++ = ':'; + } + *ptr++ = '='; + if ( k ) { + k = lutil_b64_ntop( + (unsigned char *) dv->vals[ j ].bv_val, + dv->vals[ j ].bv_len, + ptr, buf + len - ptr ); + assert( k >= 0 ); + ptr += k; + + } else { + ptr = lutil_memcopy( ptr, dv->vals[ j ].bv_val, dv->vals[ j ].bv_len ); + } + *ptr++ = '>'; + *ptr++ = ';'; + } + } + } + ptr = lutil_strncopy( ptr, dr->derefVal.bv_val, dr->derefVal.bv_len ); + *ptr++ = '\n'; + *ptr = '\0'; + assert( ptr <= buf + len ); + + tool_write_ldif( LDIF_PUT_COMMENT, NULL, buf, ptr - buf); + + ldap_memfree( buf ); + } + + rc = LDAP_SUCCESS; + +done:; + ldap_derefresponse_free( drhead ); + return rc; } +#endif + +#ifdef LDAP_CONTROL_X_WHATFAILED +static int +print_whatfailed( LDAP *ld, LDAPControl *ctrl ) +{ + BerElement *ber; + ber_tag_t tag; + ber_len_t siz; + BerVarray bva = NULL; + + /* Create a BerElement from the berval returned in the control. */ + ber = ber_init( &ctrl->ldctl_value ); + + if ( ber == NULL ) { + return LDAP_NO_MEMORY; + } + + siz = sizeof(struct berval); + tag = ber_scanf( ber, "[M]", &bva, &siz, 0 ); + if ( tag != LBER_ERROR ) { + int i; + + tool_write_ldif( LDIF_PUT_COMMENT, " what failed:", NULL, 0 ); + + for ( i = 0; bva[i].bv_val != NULL; i++ ) { + tool_write_ldif( LDIF_PUT_COMMENT, NULL, bva[i].bv_val, bva[i].bv_len ); + } + + ldap_memfree( bva ); + } + + ber_free( ber, 1 ); + + + return 0; +} +#endif #ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST static int @@ -1916,7 +2247,7 @@ print_ppolicy( LDAP *ld, LDAPControl *ctrl ) } tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE, - "ppolicy", buf, ptr - buf ); + ldif ? "ppolicy: " : "ppolicy", buf, ptr - buf ); } return rc; @@ -2012,7 +2343,7 @@ tool_write_ldif( int type, char *name, char *value, ber_len_t vallen ) { char *ldif; - if (( ldif = ldif_put( type, name, value, vallen )) == NULL ) { + if (( ldif = ldif_put_wrap( type, name, value, vallen, ldif_wrap )) == NULL ) { return( -1 ); } @@ -2052,4 +2383,3 @@ tool_is_oid( const char *s ) return 1; } -