]> git.sur5r.net Git - openldap/blobdiff - libraries/libldap/dnssrv.c
VLV clean
[openldap] / libraries / libldap / dnssrv.c
index 3b87e3c9ccf7950eaefcb4f5cdc2f46f5565acaa..cc193e93582bef587dcfb15c511b60feaf00d18d 100644 (file)
@@ -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"
 
 #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 */
 }