X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fgetdn.c;h=3fe68f5466107aeab1045dcbe3099952ed9b541c;hb=dd733e163a74db2968107b75e14f8705417b02c5;hp=f434465058fa53df8126933bb97371352f2fdd16;hpb=1f52f6e43e678c8f77625f5c96105a1bb51cc1ce;p=openldap diff --git a/libraries/libldap/getdn.c b/libraries/libldap/getdn.c index f434465058..3fe68f5466 100644 --- a/libraries/libldap/getdn.c +++ b/libraries/libldap/getdn.c @@ -1,5 +1,6 @@ +/* $OpenLDAP$ */ /* - * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ /* Portions @@ -12,7 +13,8 @@ #include "portable.h" #include -#include + +#include #include #include @@ -21,7 +23,11 @@ #include "ldap-int.h" -static char **explode_name( LDAP_CONST char *name, int notypes, int is_dn ); +#define NAME_TYPE_LDAP_RDN 0 +#define NAME_TYPE_LDAP_DN 1 +#define NAME_TYPE_DCE_DN 2 + +static char **explode_name( const char *name, int notypes, int is_type ); char * ldap_get_dn( LDAP *ld, LDAPMessage *entry ) @@ -37,7 +43,7 @@ ldap_get_dn( LDAP *ld, LDAPMessage *entry ) } tmp = *entry->lm_ber; /* struct copy */ - if ( ber_scanf( &tmp, "{a", &dn ) == LBER_ERROR ) { + if ( ber_scanf( &tmp, "{a" /*}*/, &dn ) == LBER_ERROR ) { ld->ld_errno = LDAP_DECODING_ERROR; return( NULL ); } @@ -48,155 +54,160 @@ ldap_get_dn( LDAP *ld, LDAPMessage *entry ) char * ldap_dn2ufn( LDAP_CONST char *dn ) { - char *p, *ufn, *r; - int state; + char *ufn; + char **vals; Debug( LDAP_DEBUG_TRACE, "ldap_dn2ufn\n", 0, 0, 0 ); - if ( ldap_is_dns_dn( dn ) || ( p = strchr( dn, '=' )) == NULL ) - return( LDAP_STRDUP( dn ) ); + /* produces completely untyped UFNs */ - ufn = LDAP_STRDUP( ++p ); + if( dn == NULL ) { + return NULL; + } -#define INQUOTE 1 -#define OUTQUOTE 2 - state = OUTQUOTE; - for ( p = ufn, r = ufn; *p; p++ ) { - switch ( *p ) { - case '\\': - if ( *++p == '\0' ) - p--; - else { - *r++ = '\\'; - *r++ = *p; - } - break; - case '"': - if ( state == INQUOTE ) - state = OUTQUOTE; - else - state = INQUOTE; - *r++ = *p; - break; - case ';': - case ',': - if ( state == OUTQUOTE ) - *r++ = ','; - else - *r++ = *p; - break; - case '=': - if ( state == INQUOTE ) - *r++ = *p; - else { - char *rsave = r; - - *r-- = '\0'; - while ( !isspace( (unsigned char) *r ) - && *r != ';' && *r != ',' && r > ufn ) - r--; - r++; - - if ( strcasecmp( r, "c" ) - && strcasecmp( r, "o" ) - && strcasecmp( r, "ou" ) - && strcasecmp( r, "st" ) - && strcasecmp( r, "l" ) - && strcasecmp( r, "cn" ) ) { - r = rsave; - *r++ = '='; - } - } - break; - default: - *r++ = *p; - break; - } + vals = ldap_explode_dn( dn , 1 ); + if( vals == NULL ) { + return NULL; } - *r = '\0'; - return( ufn ); + ufn = ldap_charray2str( vals, ", " ); + + ldap_memvfree( vals ); + return ufn; } char ** -ldap_explode_dns( LDAP_CONST char *dn_in ) +ldap_explode_dn( LDAP_CONST char *dn, int notypes ) { - char *s; - char **rdns; - char *tok_r; - char *dn; + Debug( LDAP_DEBUG_TRACE, "ldap_explode_dn\n", 0, 0, 0 ); - int ncomps; - int maxcomps = 8; + return explode_name( dn, notypes, NAME_TYPE_LDAP_DN ); +} - if ( (dn = LDAP_STRDUP( dn_in )) == NULL ) { - return( NULL ); - } +char ** +ldap_explode_rdn( LDAP_CONST char *rdn, int notypes ) +{ + Debug( LDAP_DEBUG_TRACE, "ldap_explode_rdn\n", 0, 0, 0 ); + return explode_name( rdn, notypes, NAME_TYPE_LDAP_RDN ); +} - if ( (rdns = (char **) LDAP_MALLOC( maxcomps * sizeof(char *) )) == NULL ) { - LDAP_FREE( dn ); - return( NULL ); +char * +ldap_dn2dcedn( LDAP_CONST char *dn ) +{ + char *dce, *q, **rdns, **p; + int len = 0; + + Debug( LDAP_DEBUG_TRACE, "ldap_dn2dcedn\n", 0, 0, 0 ); + + rdns = explode_name( dn, 0, NAME_TYPE_LDAP_DN ); + if ( rdns == NULL ) { + return NULL; + } + + for ( p = rdns; *p != NULL; p++ ) { + len += strlen( *p ) + 1; } - ncomps = 0; - for ( s = ldap_pvt_strtok( dn, "@.", &tok_r ); s != NULL; - s = ldap_pvt_strtok( NULL, "@.", &tok_r ) ) - { - if ( ncomps == maxcomps ) { - maxcomps *= 2; - if ( (rdns = (char **) LDAP_REALLOC( rdns, maxcomps * - sizeof(char *) )) == NULL ) - { - LDAP_FREE( dn ); - return NULL; - } - } - rdns[ncomps++] = LDAP_STRDUP( s ); + q = dce = LDAP_MALLOC( len + 1 ); + if ( dce == NULL ) { + return NULL; } - LDAP_FREE(dn); - rdns[ncomps] = NULL; + p--; /* get back past NULL */ + + for ( ; p != rdns; p-- ) { + strcpy( q, "/" ); + q++; + strcpy( q, *p ); + q += strlen( *p ); + } - /* trim rdns */ - rdns = (char **) LDAP_REALLOC( rdns, (ncomps+1) * sizeof(char*) ); - return( rdns ); + strcpy( q, "/" ); + q++; + strcpy( q, *p ); + + return dce; } -char ** -ldap_explode_dn( LDAP_CONST char *dn, int notypes ) +char * +ldap_dcedn2dn( LDAP_CONST char *dce ) { - Debug( LDAP_DEBUG_TRACE, "ldap_explode_dn\n", 0, 0, 0 ); + char *dn, *q, **rdns, **p; + int len; + + Debug( LDAP_DEBUG_TRACE, "ldap_dcedn2dn\n", 0, 0, 0 ); - if ( ldap_is_dns_dn( dn ) ) { - return( ldap_explode_dns( dn ) ); + rdns = explode_name( dce, 0, NAME_TYPE_DCE_DN ); + if ( rdns == NULL ) { + return NULL; } - return explode_name( dn, notypes, 1 ); -} -char ** -ldap_explode_rdn( LDAP_CONST char *rdn, int notypes ) -{ - Debug( LDAP_DEBUG_TRACE, "ldap_explode_rdn\n", 0, 0, 0 ); - return explode_name( rdn, notypes, 0 ); + len = 0; + + for ( p = rdns; *p != NULL; p++ ) { + len += strlen( *p ) + 1; + } + + q = dn = LDAP_MALLOC( len ); + if ( dn == NULL ) { + return NULL; + } + + p--; + + for ( ; p != rdns; p-- ) { + strcpy( q, *p ); + q += strlen( *p ); + strcpy( q, "," ); + q++; + } + + if ( *dce == '/' ) { + /* the name was fully qualified, thus the most-significant + * RDN was empty. trash the last comma */ + q--; + *q = '\0'; + } else { + /* the name was relative. copy the most significant RDN */ + strcpy( q, *p ); + } + + return dn; } +#define INQUOTE 1 +#define OUTQUOTE 2 + static char ** -explode_name( LDAP_CONST char *name, int notypes, int is_dn ) +explode_name( const char *name, int notypes, int is_type ) { - const char *p, *q; + const char *p, *q, *rdn; char **parts = NULL; - int state, count = 0, endquote, len; + int offset, state, have_equals, count = 0, endquote, len; + + /* safe guard */ + if(name == NULL) name = ""; - p = name-1; + /* skip leading whitespace */ + while( ldap_utf8_isspace( name )) { + LDAP_UTF8_INCR( name ); + } + + p = rdn = name; + offset = 0; state = OUTQUOTE; + have_equals=0; do { + /* step forward */ + p += offset; + offset = 1; - ++p; switch ( *p ) { case '\\': - if ( *++p == '\0' ) - p--; + if ( p[1] != '\0' ) { + offset = LDAP_UTF8_OFFSET(++p); + } break; case '"': if ( state == INQUOTE ) @@ -204,19 +215,28 @@ explode_name( LDAP_CONST char *name, int notypes, int is_dn ) else state = INQUOTE; break; + case '=': + if( state == OUTQUOTE ) have_equals++; + break; case '+': - if (!is_dn) + if (is_type == NAME_TYPE_LDAP_RDN) + goto end_part; + break; + case '/': + if (is_type == NAME_TYPE_DCE_DN) goto end_part; break; case ';': case ',': - if (!is_dn) - break; - goto end_part; + if (is_type == NAME_TYPE_LDAP_DN) + goto end_part; + break; case '\0': end_part: if ( state == OUTQUOTE ) { ++count; + have_equals=0; + if ( parts == NULL ) { if (( parts = (char **)LDAP_MALLOC( 8 * sizeof( char *))) == NULL ) @@ -227,31 +247,45 @@ explode_name( LDAP_CONST char *name, int notypes, int is_dn ) == NULL ) return( NULL ); } + parts[ count ] = NULL; endquote = 0; + if ( notypes ) { - for ( q = name; - q < p && *q != '='; ++q ) { - ; + for ( q = rdn; q < p && *q != '='; ++q ) { + /* EMPTY */; } + if ( q < p ) { - name = ++q; + rdn = ++q; } - if ( *name == '"' ) { - ++name; + + if ( *rdn == '"' ) { + ++rdn; } - if ( *(p-1) == '"' ) { + if ( p[-1] == '"' ) { endquote = 1; --p; } } - len = p - name; + len = p - rdn; + if (( parts[ count-1 ] = (char *)LDAP_CALLOC( 1, - len + 1 )) != NULL ) { - SAFEMEMCPY( parts[ count-1 ], name, - len ); + len + 1 )) != NULL ) + { + AC_MEMCPY( parts[ count-1 ], rdn, len ); + + if( !endquote ) { + /* skip trailing spaces */ + while( len > 0 && ldap_utf8_isspace( + &parts[count-1][len-1] ) ) + { + --len; + } + } + parts[ count-1 ][ len ] = '\0'; } @@ -263,22 +297,12 @@ explode_name( LDAP_CONST char *name, int notypes, int is_dn ) if ( endquote == 1 ) p++; - name = *p ? p + 1 : p; - while ( isascii( *name ) && isspace( *name ) ) - ++name; - } - break; + rdn = *p ? &p[1] : p; + while ( ldap_utf8_isspace( rdn ) ) + ++rdn; + } break; } } while ( *p ); return( parts ); } - - -int -ldap_is_dns_dn( LDAP_CONST char *dn ) -{ - return( dn[ 0 ] != '\0' && strchr( dn, '=' ) == NULL && - strchr( dn, ',' ) == NULL ); -} -