3 * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
8 * locate LDAP servers using DNS SRV records.
9 * Location code based on MIT Kerberos KDC location code.
15 #include <ac/stdlib.h>
18 #include <ac/socket.h>
19 #include <ac/string.h>
24 #ifdef HAVE_ARPA_NAMESER_H
25 #include <arpa/nameser.h>
31 /* Sometimes this is not defined. */
37 LDAP_CONST char *dn_in,
40 /* not yet implemented */
41 return LDAP_NOT_SUPPORTED;
45 LDAP_CONST char *domain_in,
48 char *domain, *s, *tok_r, *dn;
51 if (domain_in == NULL || dnp == NULL) {
52 return LDAP_NO_MEMORY;
54 domain = LDAP_STRDUP(domain_in);
56 return LDAP_NO_MEMORY;
61 for (s = ldap_pvt_strtok(domain, ".", &tok_r);
63 s = ldap_pvt_strtok(NULL, ".", &tok_r)) {
64 size_t len = strlen(s);
66 dn = (char *) LDAP_REALLOC(dn, loc + sizeof(",dc=") + len );
69 return LDAP_NO_MEMORY;
73 strcpy(dn + loc, ",");
76 strcpy(dn + loc, "dc=");
77 loc += sizeof("dc=")-1;
91 * Lookup and return LDAP servers for domain (using the DNS
92 * SRV record _ldap._tcp.domain).
94 int ldap_domain2hostlist(
95 LDAP_CONST char *domain,
98 #ifdef HAVE_RES_SEARCH
101 char *hostlist = NULL;
102 int rc, len, cur = 0;
103 unsigned char reply[1024];
105 if( domain == NULL || *domain == '\0' ) {
106 return LDAP_PARAM_ERROR;
110 return LDAP_PARAM_ERROR;
113 request = LDAP_MALLOC(strlen(domain) + sizeof("_ldap._tcp."));
114 if (request == NULL) {
118 sprintf(request, "_ldap._tcp.%s", domain);
120 #ifdef LDAP_R_COMPILE
121 ldap_pvt_thread_mutex_lock(&ldap_int_resolv_mutex);
124 len = res_search(request, C_IN, T_SRV, reply, sizeof(reply));
130 /* int priority, weight; */
132 /* Parse out query */
135 status = dn_expand(reply, reply + len, p, host, sizeof(host));
142 while (p < reply + len) {
143 int type, class, ttl, size;
144 status = dn_expand(reply, reply + len, p, host, sizeof(host));
149 type = (p[0] << 8) | p[1];
151 class = (p[0] << 8) | p[1];
153 ttl = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
155 size = (p[0] << 8) | p[1];
159 status = dn_expand(reply, reply + len, p + 6, host, sizeof(host));
163 /* ignore priority and weight for now */
164 /* priority = (p[0] << 8) | p[1]; */
165 /* weight = (p[2] << 8) | p[3]; */
166 port = (p[4] << 8) | p[5];
168 buflen = strlen(host) + sizeof(":65355");
169 hostlist = (char *) LDAP_REALLOC(hostlist, cur + buflen);
170 if (hostlist == NULL) {
175 /* not first time around */
176 hostlist[cur++] = ' ';
178 cur += sprintf(&hostlist[cur], "%s:%hd", host, port);
183 if (hostlist == NULL) {
184 /* No LDAP servers found in DNS. */
185 rc = LDAP_UNAVAILABLE;
193 #ifdef LDAP_R_COMPILE
194 ldap_pvt_thread_mutex_unlock(&ldap_int_resolv_mutex);
197 if (request != NULL) {
200 if (rc != LDAP_SUCCESS && hostlist != NULL) {
205 return LDAP_NOT_SUPPORTED;
206 #endif /* HAVE_RES_SEARCH */