/* $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"
#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;
+
+ if( dn_in == NULL || domainp == NULL ) {
+ return -1;
+ }
+
+ 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;
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;
loc++;
}
strcpy(dn + loc, "dc=");
- loc += 3;
+ loc += sizeof("dc=")-1;
strcpy(dn + loc, s);
loc += len;
}
/*
- * 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];
+ if( domain == NULL || *domain == '\0' ) {
+ return LDAP_PARAM_ERROR;
+ }
+
+ if( list == NULL ) {
+ 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);
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;
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;
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
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 */
}