From: Kurt Zeilenga Date: Fri, 6 Sep 2002 03:49:26 +0000 (+0000) Subject: New and improved response parsing X-Git-Tag: OPENLDAP_REL_ENG_2_1_5~38 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=1d4847314c52fb7a2b8327052b47268dd095e574;p=openldap New and improved response parsing --- diff --git a/clients/tools/ldapsearch.c b/clients/tools/ldapsearch.c index 05ebceb997..5c17c8e0a5 100644 --- a/clients/tools/ldapsearch.c +++ b/clients/tools/ldapsearch.c @@ -1218,6 +1218,8 @@ done: return( rc ); } +#if 1 +/* This is the original version, the old way of doing things. */ static void print_entry( LDAP *ld, @@ -1324,6 +1326,117 @@ print_entry( ber_free( ber, 0 ); } } +#else /* This is the proposed new way of doing things. */ +static void +print_entry( + LDAP *ld, + LDAPMessage *entry, + int attrsonly) +{ + char *ufn; + char tmpfname[ 256 ]; + char url[ 256 ]; + int i, rc; + BerElement *ber = NULL; + struct berval *bvals, bv; + LDAPControl **ctrls = NULL; + FILE *tmpfp; + + rc = ldap_get_dn_ber( ld, entry, &ber, &bv ); + ufn = NULL; + + if ( ldif < 2 ) { + ufn = ldap_dn2ufn( bv.bv_val ); + write_ldif( LDIF_PUT_COMMENT, NULL, ufn, ufn ? strlen( ufn ) : 0 ); + } + write_ldif( LDIF_PUT_VALUE, "dn", bv.bv_val, bv.bv_len ); + + rc = ldap_int_get_controls( ber, &ctrls ); + + if( rc != LDAP_SUCCESS ) { + fprintf(stderr, "print_entry: %d\n", rc ); + ldap_perror( ld, "ldap_get_entry_controls" ); + exit( EXIT_FAILURE ); + } + + if( ctrls ) { + print_ctrls( ctrls ); + ldap_controls_free( ctrls ); + } + + if ( includeufn ) { + if( ufn == NULL ) { + ufn = ldap_dn2ufn( bv.bv_val ); + } + write_ldif( LDIF_PUT_VALUE, "ufn", ufn, ufn ? strlen( ufn ) : 0 ); + } + + if( ufn != NULL ) ldap_memfree( ufn ); + + for ( rc = ldap_get_attribute_ber( ld, entry, ber, &bv ); rc == LDAP_SUCCESS; + rc = ldap_get_attribute_ber( ld, entry, ber, &bv ) ) + { + if (bv.bv_val == NULL) break; + + if ( attrsonly ) { + write_ldif( LDIF_PUT_NOVALUE, bv.bv_val, NULL, 0 ); + /* skip values */ + ber_scanf( ber, "x}" ); + + } else if (( rc = ldap_get_values_ber( ld, entry, ber, &bvals )) == LDAP_SUCCESS ) { + for ( i = 0; bvals[i].bv_val != NULL; i++ ) { + if ( vals2tmp > 1 || ( vals2tmp + && ldif_is_not_printable( bvals[i].bv_val, bvals[i].bv_len ) )) + { + int tmpfd; + /* write value to file */ + snprintf( tmpfname, sizeof tmpfname, + "%s" LDAP_DIRSEP "ldapsearch-%s-XXXXXX", + tmpdir, bv.bv_val ); + tmpfp = NULL; + + tmpfd = mkstemp( tmpfname ); + + if ( tmpfd < 0 ) { + perror( tmpfname ); + continue; + } + + if (( tmpfp = fdopen( tmpfd, "w")) == NULL ) { + perror( tmpfname ); + continue; + } + + if ( fwrite( bvals[ i ].bv_val, + bvals[ i ].bv_len, 1, tmpfp ) == 0 ) + { + perror( tmpfname ); + fclose( tmpfp ); + continue; + } + + fclose( tmpfp ); + + snprintf( url, sizeof url, "%s%s", urlpre, + &tmpfname[strlen(tmpdir) + sizeof(LDAP_DIRSEP) - 1] ); + + urlize( url ); + write_ldif( LDIF_PUT_URL, bv.bv_val, url, strlen( url )); + + } else { + write_ldif( LDIF_PUT_VALUE, bv.bv_val, + bvals[ i ].bv_val, bvals[ i ].bv_len ); + } + } + ber_memfree( bvals ); + } + } + + if( ber != NULL ) { + ber_free( ber, 0 ); + } +} +#endif static void print_reference( LDAP *ld, diff --git a/include/ldap.h b/include/ldap.h index 9bb9986f58..710f17e49e 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -1248,6 +1248,18 @@ ldap_dcedn2dn LDAP_P(( LDAP_CONST char *dce )); /* deprecated */ LDAP_F( char * ) ldap_dn2ad_canonical LDAP_P(( LDAP_CONST char *dn )); /* deprecated */ +LDAP_F( int ) +ldap_get_dn_ber LDAP_P(( + LDAP *ld, LDAPMessage *e, BerElement **berout, struct berval *dn )); + +LDAP_F( int ) +ldap_get_attribute_ber LDAP_P(( + LDAP *ld, LDAPMessage *e, BerElement *ber, struct berval *attr )); + +LDAP_F( int ) +ldap_get_values_ber LDAP_P(( + LDAP *ld, LDAPMessage *e, BerElement *ber, struct berval **bv )); + /* * in getattr.c */ diff --git a/libraries/libldap/getattr.c b/libraries/libldap/getattr.c index 91e37b2835..db690d13b1 100644 --- a/libraries/libldap/getattr.c +++ b/libraries/libldap/getattr.c @@ -120,3 +120,37 @@ ldap_next_attribute( LDAP *ld, LDAPMessage *entry, BerElement *ber ) return attr; } + +/* ARGSUSED */ +int +ldap_get_attribute_ber( LDAP *ld, LDAPMessage *entry, BerElement *ber, + BerValue *attr ) +{ + ber_tag_t tag; + int rc = LDAP_SUCCESS; + +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, ENTRY, "ldap_get_attribute_ber\n", 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "ldap_get_attribute_ber\n", 0, 0, 0 ); +#endif + + assert( ld != NULL ); + assert( LDAP_VALID( ld ) ); + assert( entry != NULL ); + assert( ber != NULL ); + assert( attr != NULL ); + + attr->bv_val = NULL; + attr->bv_len = 0; + + if ( ber_pvt_ber_remaining( ber ) ) { + /* skip sequence, snarf attribute type */ + tag = ber_scanf( ber, "{m", attr ); + if( tag == LBER_ERROR ) { + rc = ld->ld_errno = LDAP_DECODING_ERROR; + } + } + + return rc; +} diff --git a/libraries/libldap/getdn.c b/libraries/libldap/getdn.c index 781dca07af..761fc416f4 100644 --- a/libraries/libldap/getdn.c +++ b/libraries/libldap/getdn.c @@ -103,6 +103,57 @@ ldap_get_dn( LDAP *ld, LDAPMessage *entry ) return( dn ); } +int +ldap_get_dn_ber( LDAP *ld, LDAPMessage *entry, BerElement **berout, + BerValue *dn ) +{ + BerElement tmp, *ber; + ber_len_t len = 0; + int rc = LDAP_SUCCESS; + +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, ENTRY, "ldap_get_dn_ber\n", 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "ldap_get_dn_ber\n", 0, 0, 0 ); +#endif + + assert( ld != NULL ); + assert( LDAP_VALID(ld) ); + assert( entry != NULL ); + assert( dn != NULL ); + + dn->bv_val = NULL; + dn->bv_len = 0; + + if ( berout ) { + *berout = NULL; + ber = ldap_alloc_ber_with_options( ld ); + if( ber == NULL ) { + return LDAP_NO_MEMORY; + } + *berout = ber; + } else { + ber = &tmp; + } + + *ber = *entry->lm_ber; /* struct copy */ + if ( ber_scanf( ber, "{ml{" /*}*/, dn, &len ) == LBER_ERROR ) { + rc = ld->ld_errno = LDAP_DECODING_ERROR; + } + if ( rc == LDAP_SUCCESS ) { + /* set the length to avoid overrun */ + rc = ber_set_option( ber, LBER_OPT_REMAINING_BYTES, &len ); + if( rc != LBER_OPT_SUCCESS ) { + rc = ld->ld_errno = LDAP_LOCAL_ERROR; + } + } + if ( rc != LDAP_SUCCESS && berout ) { + ber_free( ber, 0 ); + *berout = NULL; + } + return rc; +} + /* * RFC 1823 ldap_dn2ufn */ @@ -3390,9 +3441,16 @@ ldap_X509dn2bv( void *x509_name, struct berval *bv, LDAPDN_rewrite_func *func, goto get_oid; newAVA->la_attr.bv_val = (char *)OBJ_nid2sn( n ); newAVA->la_attr.bv_len = strlen( newAVA->la_attr.bv_val ); +#ifdef HAVE_EBCDIC + newAVA->la_attr.bv_val = LDAP_STRDUP( newAVA->la_attr.bv_val ); + __etoa( newAVA->la_attr.bv_val ); +#endif } else { get_oid: newAVA->la_attr.bv_val = oidptr; newAVA->la_attr.bv_len = OBJ_obj2txt( oidptr, oidrem, obj, 1 ); +#ifdef HAVE_EBCDIC + __etoa( newAVA->la_attr.bv_val ); +#endif oidptr += newAVA->la_attr.bv_len + 1; oidrem -= newAVA->la_attr.bv_len + 1; @@ -3468,6 +3526,9 @@ to_utf8: rc = ldap_ucs_to_utf8s( &Val, csize, &newAVA->la_value ); nomem: for (;baseAVA < newAVA; baseAVA++) { LDAP_FREE( baseAVA->la_value.bv_val ); +#ifdef HAVE_EBCDIC + if ( !func ) LDAP_FREE( baseAVA->la_attr.bv_val ); +#endif } if ( oidsize != 0 ) diff --git a/libraries/libldap/getvalues.c b/libraries/libldap/getvalues.c index 34ee28da56..ee2962b7c3 100644 --- a/libraries/libldap/getvalues.c +++ b/libraries/libldap/getvalues.c @@ -144,6 +144,30 @@ ldap_get_values_len( LDAP *ld, LDAPMessage *entry, LDAP_CONST char *target ) return( vals ); } +int +ldap_get_values_ber( LDAP *ld, LDAPMessage *entry, BerElement *ber, BerVarray *bv ) +{ + int rc = LDAP_SUCCESS; + + assert( ld != NULL ); + assert( LDAP_VALID( ld ) ); + assert( entry != NULL ); + assert( ber != NULL ); + assert( bv != NULL ); + +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, ENTRY, "ldap_get_values_ber\n", 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "ldap_get_values_ber\n", 0, 0, 0 ); +#endif + + /* get the array of vals */ + if ( ber_scanf( ber, "W}" /* }}} */, bv ) == LBER_ERROR ) { + rc = ld->ld_errno = LDAP_DECODING_ERROR; + } + + return( rc ); +} int ldap_count_values( char **vals ) {