X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fgetdn.c;h=781dca07afe6450849247111e1a12ed1e7caf525;hb=8c30114d847ff034dd9e9382d88e276fa7f82833;hp=4eec0896e838217cdda2a7bcd7b094bd748ef2c6;hpb=3921e1b0c29aa0a0a943fe3eac5c68c2ff4a98b9;p=openldap diff --git a/libraries/libldap/getdn.c b/libraries/libldap/getdn.c index 4eec0896e8..781dca07af 100644 --- a/libraries/libldap/getdn.c +++ b/libraries/libldap/getdn.c @@ -85,15 +85,14 @@ ldap_get_dn( LDAP *ld, LDAPMessage *entry ) BerElement tmp; #ifdef NEW_LOGGING - LDAP_LOG (( "getdn", LDAP_LEVEL_ENTRY, "ldap_get_dn\n" )); + LDAP_LOG ( OPERATION, ENTRY, "ldap_get_dn\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "ldap_get_dn\n", 0, 0, 0 ); #endif - if ( entry == NULL ) { - ld->ld_errno = LDAP_PARAM_ERROR; - return( NULL ); - } + assert( ld != NULL ); + assert( LDAP_VALID(ld) ); + assert( entry != NULL ); tmp = *entry->lm_ber; /* struct copy */ if ( ber_scanf( &tmp, "{a" /*}*/, &dn ) == LBER_ERROR ) { @@ -113,7 +112,7 @@ ldap_dn2ufn( LDAP_CONST char *dn ) char *out = NULL; #ifdef NEW_LOGGING - LDAP_LOG (( "getdn", LDAP_LEVEL_ENTRY, "ldap_dn2ufn\n" )); + LDAP_LOG ( OPERATION, ENTRY, "ldap_dn2ufn\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "ldap_dn2ufn\n", 0, 0, 0 ); #endif @@ -136,7 +135,7 @@ ldap_explode_dn( LDAP_CONST char *dn, int notypes ) unsigned flag = notypes ? LDAP_DN_FORMAT_UFN : LDAP_DN_FORMAT_LDAPV3; #ifdef NEW_LOGGING - LDAP_LOG (( "getdn", LDAP_LEVEL_ENTRY, "ldap_explode_dn\n" )); + LDAP_LOG ( OPERATION, ENTRY, "ldap_explode_dn\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "ldap_explode_dn\n", 0, 0, 0 ); #endif @@ -180,7 +179,7 @@ ldap_explode_rdn( LDAP_CONST char *rdn, int notypes ) int iAVA; #ifdef NEW_LOGGING - LDAP_LOG (( "getdn", LDAP_LEVEL_ENTRY, "ldap_explode_rdn\n" )); + LDAP_LOG ( OPERATION, ENTRY, "ldap_explode_rdn\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "ldap_explode_rdn\n", 0, 0, 0 ); #endif @@ -265,7 +264,7 @@ ldap_dn2dcedn( LDAP_CONST char *dn ) char *out = NULL; #ifdef NEW_LOGGING - LDAP_LOG (( "getdn", LDAP_LEVEL_ENTRY, "ldap_dn2dcedn\n" )); + LDAP_LOG ( OPERATION, ENTRY, "ldap_dn2dcedn\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "ldap_dn2dcedn\n", 0, 0, 0 ); #endif @@ -282,7 +281,7 @@ ldap_dcedn2dn( LDAP_CONST char *dce ) char *out = NULL; #ifdef NEW_LOGGING - LDAP_LOG (( "getdn", LDAP_LEVEL_ENTRY, "ldap_dcedn2dn\n" )); + LDAP_LOG ( OPERATION, ENTRY, "ldap_dcedn2dn\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "ldap_dcedn2dn\n", 0, 0, 0 ); #endif @@ -298,7 +297,7 @@ ldap_dn2ad_canonical( LDAP_CONST char *dn ) char *out = NULL; #ifdef NEW_LOGGING - LDAP_LOG (( "getdn", LDAP_LEVEL_ENTRY, "ldap_dn2ad_canonical\n" )); + LDAP_LOG ( OPERATION, ENTRY, "ldap_dn2ad_canonical\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "ldap_dn2ad_canonical\n", 0, 0, 0 ); #endif @@ -334,7 +333,7 @@ ldap_dn_normalize( LDAP_CONST char *dnin, LDAPDN *tmpDN = NULL; #ifdef NEW_LOGGING - LDAP_LOG (( "getdn", LDAP_LEVEL_ENTRY, "ldap_dn_normalize\n" )); + LDAP_LOG ( OPERATION, ENTRY, "ldap_dn_normalize\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "ldap_dn_normalize\n", 0, 0, 0 ); #endif @@ -661,8 +660,7 @@ ldap_bv2dn( struct berval *bv, LDAPDN **dn, unsigned flags ) assert( dn ); #ifdef NEW_LOGGING - LDAP_LOG (( "getdn", LDAP_LEVEL_ARGS, "ldap_bv2dn(%s,%u)\n%s", - str, flags, "" )); + LDAP_LOG ( OPERATION, ARGS, "ldap_bv2dn(%s,%u)\n%s", str, flags, "" ); #else Debug( LDAP_DEBUG_TRACE, "=> ldap_bv2dn(%s,%u)\n%s", str, flags, "" ); #endif @@ -838,8 +836,8 @@ return_result:; } #ifdef NEW_LOGGING - LDAP_LOG (( "getdn", LDAP_LEVEL_RESULTS, "<= ldap_bv2dn(%s,%u)=%d\n", - str, flags, rc )); + LDAP_LOG ( OPERATION, RESULTS, "<= ldap_bv2dn(%s,%u)=%d\n", + str, flags, rc ); #else Debug( LDAP_DEBUG_TRACE, "<= ldap_bv2dn(%s,%u)=%d\n", str, flags, rc ); #endif @@ -1753,7 +1751,7 @@ quotedIA52strval( const char *str, struct berval *val, const char **next, unsign } len = endPos - startPos - escapes; - assert( len >= 0 ); + assert( endPos >= startPos + escapes ); val->bv_len = len; if ( escapes == 0 ) { val->bv_val = LDAP_STRNDUP( startPos, len ); @@ -2878,7 +2876,7 @@ ldap_rdn2bv( LDAPRDN *rdn, struct berval *bv, unsigned flags ) break; default: - return( LDAP_PARAM_ERROR ); + return LDAP_PARAM_ERROR; } bv->bv_val = LDAP_MALLOC( l + 1 ); @@ -2968,8 +2966,8 @@ int ldap_dn2bv( LDAPDN *dn, struct berval *bv, unsigned flags ) bv->bv_val = NULL; #ifdef NEW_LOGGING - LDAP_LOG (( "getdn", LDAP_LEVEL_ARGS, "=> ldap_dn2bv(%u)\n%s%s", - flags, "", "" )); + LDAP_LOG ( OPERATION, ARGS, "=> ldap_dn2bv(%u)\n%s%s", + flags, "", "" ); #else Debug( LDAP_DEBUG_TRACE, "=> ldap_dn2bv(%u)\n%s%s", flags, "", "" ); #endif @@ -3280,8 +3278,8 @@ int ldap_dn2bv( LDAPDN *dn, struct berval *bv, unsigned flags ) } #ifdef NEW_LOGGING - LDAP_LOG (( "getdn", LDAP_LEVEL_RESULTS, "<= ldap_dn2bv(%s,%u)=%d\n", - bv->bv_val, flags, rc )); + LDAP_LOG ( OPERATION, RESULTS, "<= ldap_dn2bv(%s,%u)=%d\n", + bv->bv_val, flags, rc ); #else Debug( LDAP_DEBUG_TRACE, "<= ldap_dn2bv(%s,%u)=%d\n", bv->bv_val, flags, rc ); @@ -3291,3 +3289,192 @@ return_results:; return( rc ); } +#ifdef HAVE_TLS +#include +#include + +/* Convert a structured DN from an X.509 certificate into an LDAPV3 DN. + * x509_name must be an (X509_NAME *). If func is non-NULL, the + * constructed DN will use numeric OIDs to identify attributeTypes, + * and the func() will be invoked to rewrite the DN with the given + * flags. + * + * Otherwise the DN will use shortNames as defined in the OpenSSL + * library. + * + * It's preferable to let slapd do the OID to attributeType mapping, + * because the OpenSSL tables are known to have many typos in versions + * up to (at least) 0.9.6c. However, the LDAP client has no schema tables, + * so we're forced to use OpenSSL's mapping there. + * -- Howard Chu 2002-04-18 + */ + +int +ldap_X509dn2bv( void *x509_name, struct berval *bv, LDAPDN_rewrite_func *func, + unsigned flags ) +{ + LDAPDN *newDN; + LDAPRDN *newRDN; + LDAPAVA *newAVA, *baseAVA; + X509_NAME_ENTRY *ne; + ASN1_OBJECT *obj; + ASN1_STRING *str; + char oids[8192], *oidptr = oids, *oidbuf = NULL; + void *ptrs[2048]; + int i, j, k = 0, navas, nrdns, rc = LDAP_SUCCESS; + int set = -1; + size_t dnsize, oidrem = sizeof(oids), oidsize = 0; + int csize; + + struct berval Val; + + assert( bv ); + bv->bv_len = 0; + bv->bv_val = NULL; + + /* Get the number of AVAs. This is not necessarily the same as + * the number of RDNs. + */ + navas = X509_NAME_entry_count( x509_name ); + + /* Get the last element, to see how many RDNs there are */ + ne = X509_NAME_get_entry( x509_name, navas - 1 ); + nrdns = ne->set + 1; + + /* Allocate the DN/RDN/AVA stuff as a single block */ + dnsize = sizeof(LDAPDN) + sizeof(LDAPRDN *) * (nrdns+1); + dnsize += sizeof(LDAPRDN) * nrdns + sizeof(LDAPAVA *) * (navas+nrdns); + dnsize += sizeof(LDAPAVA) * navas; + if (dnsize > sizeof(ptrs)) { + newDN = (LDAPDN *)LDAP_MALLOC( dnsize ); + if ( newDN == NULL ) + return LDAP_NO_MEMORY; + } else { + newDN = (LDAPDN *)ptrs; + } + + newDN[0] = (LDAPRDN**)(newDN+1); + newDN[0][nrdns] = NULL; + newRDN = (LDAPRDN*)(newDN[0] + nrdns+1); + newAVA = (LDAPAVA*)(newRDN + navas + nrdns*2); + baseAVA = newAVA; + + /* Retrieve RDNs in reverse order; LDAP is backwards from X.500. */ + for ( i = nrdns - 1, j = 0; i >= 0; i-- ) { + ne = X509_NAME_get_entry( x509_name, i ); + obj = X509_NAME_ENTRY_get_object( ne ); + str = X509_NAME_ENTRY_get_data( ne ); + + /* If set changed, move to next RDN */ + if ( set != ne->set ) { + /* If this is not the first time, end the + * previous RDN and advance. + */ + if ( j > 0 ) { + newRDN[0][k] = NULL; + newRDN = (LDAPRDN*)(newRDN[0]+k+1); + } + newDN[0][j++] = newRDN; + + newRDN[0] = (LDAPAVA**)(newRDN+1); + k = 0; + set = ne->set; + } + newAVA->la_private = NULL; + newAVA->la_flags = LDAP_AVA_STRING; + + if ( !func ) { + int n = OBJ_obj2nid( obj ); + + if (n == NID_undef) + goto get_oid; + newAVA->la_attr.bv_val = (char *)OBJ_nid2sn( n ); + newAVA->la_attr.bv_len = strlen( newAVA->la_attr.bv_val ); + } else { +get_oid: newAVA->la_attr.bv_val = oidptr; + newAVA->la_attr.bv_len = OBJ_obj2txt( oidptr, oidrem, obj, 1 ); + oidptr += newAVA->la_attr.bv_len + 1; + oidrem -= newAVA->la_attr.bv_len + 1; + + /* Running out of OID buffer space? */ + if (oidrem < 128) { + if ( oidsize == 0 ) { + oidsize = sizeof(oids) * 2; + oidrem = oidsize; + oidbuf = LDAP_MALLOC( oidsize ); + if ( oidbuf == NULL ) goto nomem; + oidptr = oidbuf; + } else { + char *old = oidbuf; + oidbuf = LDAP_REALLOC( oidbuf, oidsize*2 ); + if ( oidbuf == NULL ) goto nomem; + /* Buffer moved! Fix AVA pointers */ + if ( old != oidbuf ) { + LDAPAVA *a; + long dif = oidbuf - old; + + for (a=baseAVA; a<=newAVA; a++){ + if (a->la_attr.bv_val >= old && + a->la_attr.bv_val <= (old + oidsize)) + a->la_attr.bv_val += dif; + } + } + oidptr = oidbuf + oidsize - oidrem; + oidrem += oidsize; + oidsize *= 2; + } + } + } + Val.bv_val = str->data; + Val.bv_len = str->length; + switch( str->type ) { + case V_ASN1_UNIVERSALSTRING: + /* This uses 32-bit ISO 10646-1 */ + csize = 4; goto to_utf8; + case V_ASN1_BMPSTRING: + /* This uses 16-bit ISO 10646-1 */ + csize = 2; goto to_utf8; + case V_ASN1_T61STRING: + /* This uses 8-bit, assume ISO 8859-1 */ + csize = 1; +to_utf8: rc = ldap_ucs_to_utf8s( &Val, csize, &newAVA->la_value ); + if (rc != LDAP_SUCCESS) goto nomem; + newAVA->la_flags = LDAP_AVA_NONPRINTABLE; + break; + case V_ASN1_UTF8STRING: + newAVA->la_flags = LDAP_AVA_NONPRINTABLE; + /* This is already in UTF-8 encoding */ + case V_ASN1_IA5STRING: + case V_ASN1_PRINTABLESTRING: + /* These are always 7-bit strings */ + ber_dupbv( &newAVA->la_value, &Val ); + default: + ; + } + newRDN[0][k] = newAVA; + newAVA++; + k++; + } + newRDN[0][k] = NULL; + + if ( func ) { + rc = func( newDN, flags ); + if ( rc != LDAP_SUCCESS ) + goto nomem; + } + + rc = ldap_dn2bv( newDN, bv, LDAP_DN_FORMAT_LDAPV3 ); + +nomem: + for (;baseAVA < newAVA; baseAVA++) { + LDAP_FREE( baseAVA->la_value.bv_val ); + } + + if ( oidsize != 0 ) + LDAP_FREE( oidbuf ); + if ( newDN != (LDAPDN*) ptrs ) + LDAP_FREE( newDN ); + return rc; +} +#endif /* HAVE_TLS */ +