X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fdnssrv.c;h=16b15447cac2bfefc717104998aa5b065cb6fb87;hb=8fd5fa0ed82c3a9e980f75a84933e3c3ae0cd5f0;hp=243e16aa68ad0a858b2cfddd898873556d5acb57;hpb=1bc5314d620f79a27d9b15d6e5ba2e1e51a3bd9a;p=openldap diff --git a/libraries/libldap/dnssrv.c b/libraries/libldap/dnssrv.c index 243e16aa68..16b15447ca 100644 --- a/libraries/libldap/dnssrv.c +++ b/libraries/libldap/dnssrv.c @@ -1,7 +1,16 @@ /* $OpenLDAP$ */ -/* - * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2011 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . */ /* @@ -28,159 +37,141 @@ #include #endif -/* Sometimes this is not defined. */ -#ifndef T_SRV -#define T_SRV 33 -#endif /* T_SRV */ - int ldap_dn2domain( LDAP_CONST char *dn_in, char **domainp) { - int i; - char *domain = NULL; - char **dn; + int i, j; + char *ndomain; + LDAPDN dn = NULL; + LDAPRDN rdn = NULL; + LDAPAVA *ava = NULL; + struct berval domain = BER_BVNULL; + static const struct berval DC = BER_BVC("DC"); + static const struct berval DCOID = BER_BVC("0.9.2342.19200300.100.1.25"); - if( dn_in == NULL || domainp == NULL ) { - return -1; - } + assert( dn_in != NULL ); + assert( domainp != NULL ); - dn = ldap_explode_dn( dn_in, 0 ); + *domainp = NULL; - if( dn == NULL ) { + if ( ldap_str2dn( dn_in, &dn, LDAP_DN_FORMAT_LDAP ) != LDAP_SUCCESS ) { return -2; } - for( i=0; dn[i] != NULL; i++ ) { - char ** rdn = ldap_explode_rdn( dn[i], 0 ); - - if( rdn == NULL || *rdn == NULL ) { - LDAP_FREE( rdn ); - LDAP_FREE( domain ); - LDAP_VFREE( dn ); - return -3; - } - + if( dn ) for( i=0; dn[i] != NULL; i++ ) { + rdn = dn[i]; - if( rdn[1] == NULL ) { - /* - * single-valued RDN - */ - char *dc; + for( j=0; rdn[j] != NULL; j++ ) { + ava = rdn[j]; -#define LDAP_DC "dc=" -#define LDAP_DCOID "0.9.2342.19200300.100.1.25=" - - if( strncasecmp( rdn[0], - LDAP_DC, sizeof(LDAP_DC)-1 ) == 0 ) + if( rdn[j+1] == NULL && + (ava->la_flags & LDAP_AVA_STRING) && + ava->la_value.bv_len && + ( ber_bvstrcasecmp( &ava->la_attr, &DC ) == 0 + || ber_bvcmp( &ava->la_attr, &DCOID ) == 0 ) ) { - dc = &rdn[0][sizeof(LDAP_DC)-1]; + if( domain.bv_len == 0 ) { + ndomain = LDAP_REALLOC( domain.bv_val, + ava->la_value.bv_len + 1); - } else if( strncmp( rdn[0], - LDAP_DCOID, sizeof(LDAP_DCOID)-1 ) == 0 ) - { - dc = &rdn[0][sizeof(LDAP_DCOID)-1]; + if( ndomain == NULL ) { + goto return_error; + } - } else { - dc = NULL; - } + domain.bv_val = ndomain; - if( dc != NULL ) { - char *ndomain; + AC_MEMCPY( domain.bv_val, ava->la_value.bv_val, + ava->la_value.bv_len ); - if( *dc == '\0' ) { - /* dc value is empty! */ - LDAP_FREE( rdn ); - LDAP_FREE( domain ); - LDAP_VFREE( dn ); - LDAP_VFREE( rdn ); - return -4; - } + domain.bv_len = ava->la_value.bv_len; + domain.bv_val[domain.bv_len] = '\0'; - ndomain = LDAP_REALLOC( domain, - ( domain == NULL ? 0 : strlen(domain) ) - + strlen(dc) + sizeof(".") ); + } else { + ndomain = LDAP_REALLOC( domain.bv_val, + ava->la_value.bv_len + sizeof(".") + domain.bv_len ); - if( ndomain == NULL ) { - LDAP_FREE( rdn ); - LDAP_FREE( domain ); - LDAP_VFREE( dn ); - LDAP_VFREE( rdn ); - return -5; - } - - if( domain == NULL ) ndomain[0] = '\0'; - - strcat( ndomain, dc ); - strcat( ndomain, "." ); + if( ndomain == NULL ) { + goto return_error; + } - domain = ndomain; - continue; + domain.bv_val = ndomain; + domain.bv_val[domain.bv_len++] = '.'; + AC_MEMCPY( &domain.bv_val[domain.bv_len], + ava->la_value.bv_val, ava->la_value.bv_len ); + domain.bv_len += ava->la_value.bv_len; + domain.bv_val[domain.bv_len] = '\0'; + } + } else { + domain.bv_len = 0; } - } - - /* - * multi-valued RDN or fall thru - */ + } + } - LDAP_VFREE( rdn ); - LDAP_FREE( domain ); - domain = NULL; - } - if( domain != NULL && *domain == '\0' ) { - LDAP_FREE( domain ); - domain = NULL; + if( domain.bv_len == 0 && domain.bv_val != NULL ) { + LDAP_FREE( domain.bv_val ); + domain.bv_val = NULL; } - *domainp = domain; + ldap_dnfree( dn ); + *domainp = domain.bv_val; return 0; + +return_error: + ldap_dnfree( dn ); + LDAP_FREE( domain.bv_val ); + return -1; } int ldap_domain2dn( LDAP_CONST char *domain_in, char **dnp) { - char *domain, *s, *tok_r, *dn; - size_t loc; + char *domain, *s, *tok_r, *dn, *dntmp; + size_t loc; - if (domain_in == NULL || dnp == NULL) { - return LDAP_NO_MEMORY; - } - domain = LDAP_STRDUP(domain_in); - if (domain == NULL) { - return LDAP_NO_MEMORY; - } - dn = NULL; - loc = 0; - - for (s = ldap_pvt_strtok(domain, ".", &tok_r); - s != NULL; - s = ldap_pvt_strtok(NULL, ".", &tok_r)) { - size_t len = strlen(s); - - dn = (char *) LDAP_REALLOC(dn, loc + sizeof(",dc=") + len ); - if (dn == NULL) { - LDAP_FREE(domain); - return LDAP_NO_MEMORY; - } - if (loc > 0) { - /* not first time. */ - strcpy(dn + loc, ","); - loc++; + assert( domain_in != NULL ); + assert( dnp != NULL ); + + domain = LDAP_STRDUP(domain_in); + if (domain == NULL) { + return LDAP_NO_MEMORY; } - strcpy(dn + loc, "dc="); - loc += sizeof("dc=")-1; + dn = NULL; + loc = 0; + + for (s = ldap_pvt_strtok(domain, ".", &tok_r); + s != NULL; + s = ldap_pvt_strtok(NULL, ".", &tok_r)) + { + size_t len = strlen(s); + + dntmp = (char *) LDAP_REALLOC(dn, loc + sizeof(",dc=") + len ); + if (dntmp == NULL) { + if (dn != NULL) + LDAP_FREE(dn); + LDAP_FREE(domain); + return LDAP_NO_MEMORY; + } - strcpy(dn + loc, s); - loc += len; - } + dn = dntmp; - LDAP_FREE(domain); + if (loc > 0) { + /* not first time. */ + strcpy(dn + loc, ","); + loc++; + } + strcpy(dn + loc, "dc="); + loc += sizeof("dc=")-1; - *dnp = dn; + strcpy(dn + loc, s); + loc += len; + } - return LDAP_SUCCESS; + LDAP_FREE(domain); + *dnp = dn; + return LDAP_SUCCESS; } /* @@ -191,43 +182,64 @@ int ldap_domain2hostlist( LDAP_CONST char *domain, char **list ) { -#ifdef HAVE_RES_SEARCH +#ifdef HAVE_RES_QUERY +#define DNSBUFSIZ (64*1024) char *request; - char *dn; char *hostlist = NULL; int rc, len, cur = 0; - unsigned char reply[1024]; + unsigned char reply[DNSBUFSIZ]; - if( domain == NULL || *domain == '\0' ) { - return LDAP_PARAM_ERROR; - } + assert( domain != NULL ); + assert( list != NULL ); - if( list == NULL ) { + if( *domain == '\0' ) { return LDAP_PARAM_ERROR; } request = LDAP_MALLOC(strlen(domain) + sizeof("_ldap._tcp.")); if (request == NULL) { - rc = LDAP_NO_MEMORY; - goto out; + return LDAP_NO_MEMORY; } sprintf(request, "_ldap._tcp.%s", domain); -#ifdef LDAP_R_COMPILE - ldap_pvt_thread_mutex_lock(&ldap_int_resolv_mutex); -#endif + LDAP_MUTEX_LOCK(&ldap_int_resolv_mutex); - len = res_search(request, C_IN, T_SRV, reply, sizeof(reply)); + rc = LDAP_UNAVAILABLE; +#ifdef NS_HFIXEDSZ + /* Bind 8/9 interface */ + len = res_query(request, ns_c_in, ns_t_srv, reply, sizeof(reply)); +# ifndef T_SRV +# define T_SRV ns_t_srv +# endif +#else + /* Bind 4 interface */ +# ifndef T_SRV +# define T_SRV 33 +# endif + + len = res_query(request, C_IN, T_SRV, reply, sizeof(reply)); +#endif if (len >= 0) { unsigned char *p; - char host[1024]; + char host[DNSBUFSIZ]; int status; u_short port; /* int priority, weight; */ /* Parse out query */ p = reply; + +#ifdef NS_HFIXEDSZ + /* Bind 8/9 interface */ + p += NS_HFIXEDSZ; +#elif defined(HFIXEDSZ) + /* Bind 4 interface w/ HFIXEDSZ */ + p += HFIXEDSZ; +#else + /* Bind 4 interface w/o HFIXEDSZ */ p += sizeof(HEADER); +#endif + status = dn_expand(reply, reply + len, p, host, sizeof(host)); if (status < 0) { goto out; @@ -261,8 +273,12 @@ int ldap_domain2hostlist( /* weight = (p[2] << 8) | p[3]; */ port = (p[4] << 8) | p[5]; - buflen = strlen(host) + sizeof(":65355"); - hostlist = (char *) LDAP_REALLOC(hostlist, cur + buflen); + if ( port == 0 || host[ 0 ] == '\0' ) { + goto add_size; + } + + buflen = strlen(host) + STRLENOF(":65355 "); + hostlist = (char *) LDAP_REALLOC(hostlist, cur + buflen + 1); if (hostlist == NULL) { rc = LDAP_NO_MEMORY; goto out; @@ -271,8 +287,9 @@ int ldap_domain2hostlist( /* not first time around */ hostlist[cur++] = ' '; } - cur += sprintf(&hostlist[cur], "%s:%hd", host, port); + cur += sprintf(&hostlist[cur], "%s:%hu", host, port); } +add_size:; p += size; } } @@ -286,9 +303,7 @@ int ldap_domain2hostlist( *list = hostlist; out: -#ifdef LDAP_R_COMPILE - ldap_pvt_thread_mutex_unlock(&ldap_int_resolv_mutex); -#endif + LDAP_MUTEX_UNLOCK(&ldap_int_resolv_mutex); if (request != NULL) { LDAP_FREE(request); @@ -299,5 +314,5 @@ int ldap_domain2hostlist( return rc; #else return LDAP_NOT_SUPPORTED; -#endif /* HAVE_RES_SEARCH */ +#endif /* HAVE_RES_QUERY */ }