X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fdnssrv.c;h=cc193e93582bef587dcfb15c511b60feaf00d18d;hb=fe86a81e251bda73f04841f765b2a93ac0354396;hp=3b87e3c9ccf7950eaefcb4f5cdc2f46f5565acaa;hpb=a466a643189d7a659da1d8331c53a9d54a021ab8;p=openldap diff --git a/libraries/libldap/dnssrv.c b/libraries/libldap/dnssrv.c index 3b87e3c9cc..cc193e9358 100644 --- a/libraries/libldap/dnssrv.c +++ b/libraries/libldap/dnssrv.c @@ -1,12 +1,12 @@ /* $OpenLDAP$ */ /* - * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ /* - * locate using DNS SRV records. Location code based on - * MIT Kerberos KDC location code. + * locate LDAP servers using DNS SRV records. + * Location code based on MIT Kerberos KDC location code. */ #include "portable.h" @@ -33,17 +33,125 @@ #define T_SRV 33 #endif /* T_SRV */ -int ldap_pvt_domain2dn(LDAP_CONST char *domain_in, char **dnp) +int ldap_dn2domain( + LDAP_CONST char *dn_in, + char **domainp) +{ + int i; + char *domain = NULL; + char **dn; + + assert( dn_in != NULL ); + assert( domainp != NULL ); + + dn = ldap_explode_dn( dn_in, 0 ); + + if( dn == NULL ) { + 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( rdn[1] == NULL ) { + /* + * single-valued RDN + */ + char *dc; + +#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 ) + { + dc = &rdn[0][sizeof(LDAP_DC)-1]; + + } else if( strncmp( rdn[0], + LDAP_DCOID, sizeof(LDAP_DCOID)-1 ) == 0 ) + { + dc = &rdn[0][sizeof(LDAP_DCOID)-1]; + + } else { + dc = NULL; + } + + if( dc != NULL ) { + char *ndomain; + + if( *dc == '\0' ) { + /* dc value is empty! */ + LDAP_FREE( rdn ); + LDAP_FREE( domain ); + LDAP_VFREE( dn ); + LDAP_VFREE( rdn ); + return -4; + } + + ndomain = LDAP_REALLOC( domain, + ( domain == NULL ? 0 : strlen(domain) ) + + strlen(dc) + sizeof(".") ); + + if( ndomain == NULL ) { + LDAP_FREE( rdn ); + LDAP_FREE( domain ); + LDAP_VFREE( dn ); + LDAP_VFREE( rdn ); + return -5; + } + + if( domain == NULL ) { + ndomain[0] = '\0'; + } else { + strcat( ndomain, "." ); + } + + strcat( ndomain, dc ); + + domain = ndomain; + continue; + } + } + + /* + * multi-valued RDN or fall thru + */ + + LDAP_VFREE( rdn ); + LDAP_FREE( domain ); + domain = NULL; + } + + if( domain != NULL && *domain == '\0' ) { + LDAP_FREE( domain ); + domain = NULL; + } + + *domainp = domain; + return 0; +} + +int ldap_domain2dn( + LDAP_CONST char *domain_in, + char **dnp) { char *domain, *s, *tok_r, *dn; size_t loc; - if (domain_in == NULL || dnp == NULL) { - return LDAP_NO_MEMORY; - } + assert( domain_in != NULL ); + assert( dnp != NULL ); + domain = LDAP_STRDUP(domain_in); if (domain == NULL) { - return LDAP_NO_MEMORY; + return LDAP_NO_MEMORY; } dn = NULL; loc = 0; @@ -53,7 +161,7 @@ int ldap_pvt_domain2dn(LDAP_CONST char *domain_in, char **dnp) s = ldap_pvt_strtok(NULL, ".", &tok_r)) { size_t len = strlen(s); - dn = (char *) LDAP_REALLOC(dn, loc + len + 4); + dn = (char *) LDAP_REALLOC(dn, loc + sizeof(",dc=") + len ); if (dn == NULL) { LDAP_FREE(domain); return LDAP_NO_MEMORY; @@ -64,7 +172,7 @@ int ldap_pvt_domain2dn(LDAP_CONST char *domain_in, char **dnp) loc++; } strcpy(dn + loc, "dc="); - loc += 3; + loc += sizeof("dc=")-1; strcpy(dn + loc, s); loc += len; @@ -78,25 +186,29 @@ int ldap_pvt_domain2dn(LDAP_CONST char *domain_in, char **dnp) } /* - * Lookup LDAP servers for domain (using the DNS - * SRV record _ldap._tcp.domain), set the default - * base using an algorithmic mapping of the domain, - * and return a session. + * Lookup and return LDAP servers for domain (using the DNS + * SRV record _ldap._tcp.domain). */ -int ldap_dnssrv_init(LDAP ** ldp, LDAP_CONST char *domain) +int ldap_domain2hostlist( + LDAP_CONST char *domain, + char **list ) { -#ifdef HAVE_RES_SEARCH +#ifdef HAVE_RES_QUERY char *request; - char *dn; char *hostlist = NULL; - LDAP *ld = NULL; int rc, len, cur = 0; unsigned char reply[1024]; + assert( domain != NULL ); + assert( 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); @@ -104,13 +216,14 @@ int ldap_dnssrv_init(LDAP ** ldp, LDAP_CONST char *domain) ldap_pvt_thread_mutex_lock(&ldap_int_resolv_mutex); #endif - len = res_search(request, C_IN, T_SRV, reply, sizeof(reply)); + rc = LDAP_UNAVAILABLE; + len = res_query(request, C_IN, T_SRV, reply, sizeof(reply)); if (len >= 0) { unsigned char *p; char host[1024]; int status; u_short port; - int priority, weight; + /* int priority, weight; */ /* Parse out query */ p = reply; @@ -143,11 +256,12 @@ int ldap_dnssrv_init(LDAP ** ldp, LDAP_CONST char *domain) if (status < 0) { goto out; } - priority = (p[0] << 8) | p[1]; - weight = (p[2] << 8) | p[3]; + /* ignore priority and weight for now */ + /* priority = (p[0] << 8) | p[1]; */ + /* weight = (p[2] << 8) | p[3]; */ port = (p[4] << 8) | p[5]; - buflen = strlen(host) + /* :XXXXX\0 */ 7; + buflen = strlen(host) + sizeof(":65355"); hostlist = (char *) LDAP_REALLOC(hostlist, cur + buflen); if (hostlist == NULL) { rc = LDAP_NO_MEMORY; @@ -167,26 +281,9 @@ int ldap_dnssrv_init(LDAP ** ldp, LDAP_CONST char *domain) rc = LDAP_UNAVAILABLE; goto out; } - rc = ldap_create(&ld); - if (rc != LDAP_SUCCESS) { - goto out; - } - rc = ldap_set_option(ld, LDAP_OPT_HOST_NAME, hostlist); - if (rc != LDAP_SUCCESS) { - goto out; - } - rc = ldap_pvt_domain2dn(domain, &dn); - if (rc != LDAP_SUCCESS) { - goto out; - } - if (ld->ld_options.ldo_defbase != NULL) { - LDAP_FREE(ld->ld_options.ldo_defbase); - } - ld->ld_options.ldo_defbase = dn; - - *ldp = ld; rc = LDAP_SUCCESS; + *list = hostlist; out: #ifdef LDAP_R_COMPILE @@ -196,14 +293,11 @@ int ldap_dnssrv_init(LDAP ** ldp, LDAP_CONST char *domain) if (request != NULL) { LDAP_FREE(request); } - if (hostlist != NULL) { + if (rc != LDAP_SUCCESS && hostlist != NULL) { LDAP_FREE(hostlist); } - if (rc != LDAP_SUCCESS && ld != NULL) { - ldap_ld_free(ld, 1, NULL, NULL); - } return rc; #else return LDAP_NOT_SUPPORTED; -#endif /* HAVE_RES_SEARCH */ +#endif /* HAVE_RES_QUERY */ }