From 6a903bc1e54ce7fcf5b2fd06a390b33706be0cb1 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Thu, 5 Sep 2002 11:33:32 +0000 Subject: [PATCH] Added new ldap_get_{dn,attribute,values}_ber functions for linearly processing a search entry. Avoids O(n^2) ldap_get_values() behavior. --- include/ldap.h | 12 +++++++++ libraries/libldap/getattr.c | 34 +++++++++++++++++++++++ libraries/libldap/getdn.c | 51 +++++++++++++++++++++++++++++++++++ libraries/libldap/getvalues.c | 24 +++++++++++++++++ 4 files changed, 121 insertions(+) diff --git a/include/ldap.h b/include/ldap.h index 9ec4c5664c..8d68efa84e 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -1301,6 +1301,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 3e5f488bcc..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 */ 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 ) { -- 2.39.5