44#include <netinet/in.h>
49#if HAVE_ARPA_NAMESER_H
50#include <arpa/nameser.h>
53void nsError(
int nserror,
char *
server);
56static void sort(
struct hstruct *array,
int nitems,
int (*cmp) (
struct hstruct *,
struct hstruct *),
int begin,
int end);
57static void msort(
struct hstruct *array,
size_t nitems,
int (*cmp) (
struct hstruct *,
struct hstruct *));
67nsError(
int nserror,
char *service)
71 error((
char *)
"%s| %s: ERROR: res_search: Unknown service record: %s\n",
LogTime(),
PROGRAM, service);
74 error((
char *)
"%s| %s: ERROR: res_search: No SRV record for %s\n",
LogTime(),
PROGRAM, service);
77 error((
char *)
"%s| %s: ERROR: res_search: No response for SRV query\n",
LogTime(),
PROGRAM);
101sort(
struct hstruct *array,
int nitems,
int (*cmp) (
struct hstruct *,
struct hstruct *),
int begin,
int end)
108 if (cmp(&array[l], &array[pivot]) <= 0) {
112 swap(&array[l], &array[r]);
116 swap(&array[begin], &array[l]);
117 sort(array, nitems, cmp, begin, l);
118 sort(array, nitems, cmp, r, end);
125 sort(array, (
int)nitems, cmp, 0, (
int)(nitems - 1));
161 for (i = 0; i < nhosts; ++i) {
173 struct addrinfo *hres =
nullptr, *hres_list;
181 rc = getaddrinfo((
const char *) name,
nullptr,
nullptr, &hres);
183 error((
char *)
"%s| %s: ERROR: Error while resolving hostname with getaddrinfo: %s\n",
LogTime(),
PROGRAM, gai_strerror(rc));
190 hres_list = hres_list->ai_next;
199 rc = getnameinfo(hres_list->ai_addr, hres_list->ai_addrlen,
host,
sizeof(
host),
nullptr, 0, 0);
201 error((
char *)
"%s| %s: ERROR: Error while resolving ip address with getnameinfo: %s\n",
LogTime(),
PROGRAM, gai_strerror(rc));
211 hp[nhosts].
port = -1;
216 hres_list = hres_list->ai_next;
232 char *service =
nullptr;
239 u_char *buffer =
nullptr;
249 hp[nhosts].
port = -1;
253 }
else if ( !ls->
domain || !strcasecmp(ls->
domain,
"") ) {
257 hp[nhosts].
port = -1;
270 service = (
char *)
xmalloc(strlen(
"_ldaps._tcp.") + strlen(domain) + 1);
271 strcpy(service,
"_ldaps._tcp.");
273 service = (
char *)
xmalloc(strlen(
"_ldap._tcp.") + strlen(domain) + 1);
274 strcpy(service,
"_ldap._tcp.");
276 strcat(service, domain);
283#define PACKETSZ_MULT 10
287 buffer = (u_char *)
xmalloc(PACKETSZ_MULT * NS_PACKETSZ);
288 if ((len = res_search(service, ns_c_in, ns_t_srv, (u_char *) buffer, PACKETSZ_MULT * NS_PACKETSZ)) < 0) {
289 error((
char *)
"%s| %s: ERROR: Error while resolving service record %s with res_search\n",
LogTime(),
PROGRAM, service);
290 nsError(h_errno, service);
293 service = (
char *)
xmalloc(strlen(
"_ldap._tcp.") + strlen(domain) + 1);
294 strcpy(service,
"_ldap._tcp.");
295 strcat(service, domain);
296 if ((len = res_search(service, ns_c_in, ns_t_srv, (u_char *) buffer, PACKETSZ_MULT * NS_PACKETSZ)) < 0) {
297 error((
char *)
"%s| %s: ERROR: Error while resolving service record %s with res_search\n",
LogTime(),
PROGRAM, service);
298 nsError(h_errno, service);
305 if (len > PACKETSZ_MULT * NS_PACKETSZ) {
307 buffer = (u_char *)
xrealloc(buffer, (
size_t)len);
308 if ((len = res_search(service, ns_c_in, ns_t_srv, (u_char *) buffer, len)) < 0) {
309 error((
char *)
"%s| %s: ERROR: Error while resolving service record %s with res_search\n",
LogTime(),
PROGRAM, service);
310 nsError(h_errno, service);
314 error((
char *)
"%s| %s: ERROR: Reply to big: buffer: %d reply length: %d\n",
LogTime(),
PROGRAM, olen, len);
320 if (p > buffer + len) {
321 error((
char *)
"%s| %s: ERROR: Message to small: %d < header size\n",
LogTime(),
PROGRAM, len);
324 if ((
size = dn_expand(buffer, buffer + len, p, name,
sizeof(name))) < 0) {
330 if (p > buffer + len) {
331 error((
char *)
"%s| %s: ERROR: Message to small: %d < header + query name,type,class \n",
LogTime(),
PROGRAM, len);
334 while (p < buffer + len) {
336 if ((
size = dn_expand(buffer, buffer + len, p, name,
sizeof(name))) < 0) {
341 if (p > buffer + len) {
342 error((
char *)
"%s| %s: ERROR: Message to small: %d < header + query name,type,class + answer name\n",
LogTime(),
PROGRAM, len);
346 p += NS_INT16SZ + NS_INT32SZ;
347 if (p > buffer + len) {
348 error((
char *)
"%s| %s: ERROR: Message to small: %d < header + query name,type,class + answer name + RR type,class,ttl\n",
LogTime(),
PROGRAM, len);
351 NS_GET16(rdlength, p);
353 if (type == ns_t_srv) {
356 if (p > buffer + len) {
357 error((
char *)
"%s| %s: ERROR: Message to small: %d < header + query name,type,class + answer name + RR type,class,ttl + RR data length\n",
LogTime(),
PROGRAM, len);
361 if (p > buffer + len) {
362 error((
char *)
"%s| %s: ERROR: Message to small: %d < SRV RR + priority\n",
LogTime(),
PROGRAM, len);
366 if (p > buffer + len) {
367 error((
char *)
"%s| %s: ERROR: Message to small: %d < SRV RR + priority + weight\n",
LogTime(),
PROGRAM, len);
371 if (p > buffer + len) {
372 error((
char *)
"%s| %s: ERROR: Message to small: %d < SRV RR + priority + weight + port\n",
LogTime(),
PROGRAM, len);
390 if (p > buffer + len) {
391 error((
char *)
"%s| %s: ERROR: Message to small: %d < SRV RR + priority + weight + port + name\n",
LogTime(),
PROGRAM, len);
395 if (p != buffer + len) {
396#if (SIZEOF_LONG == 8)
397 error(
"%s| %s: ERROR: Inconsistence message length: %ld!=0\n",
LogTime(),
PROGRAM, buffer + len - p);
399 error((
char *)
"%s| %s: ERROR: Inconsistence message length: %d!=0\n",
LogTime(),
PROGRAM, buffer + len - p);
411 hp[nhosts].
port = -1;
418 for (i = 0; i < nhosts; ++i) {
419 for (j = i + 1; j < nhosts; ++j) {
420 if (!strcasecmp(hp[i].
host, hp[j].
host)) {
422 (hp[i].
port == -1 && hp[j].
port == 389) ||
423 (hp[i].
port == 389 && hp[j].
port == -1)) {
425 for (k = j + 1; k < nhosts; ++k) {
440 msort(hp, (
size_t)nhosts, compare_hosts);
443 debug((
char *)
"%s| %s: DEBUG: Sorted ldap server names for domain %s:\n",
LogTime(),
PROGRAM, domain);
444 for (i = 0; i < nhosts; ++i) {
void error(char *format,...)
size_t get_hostname_list(struct hstruct **hlist, size_t nhosts, char *name)
const char * LogTime(void)
size_t free_hostname_list(struct hstruct **hlist, size_t nhosts)
size_t get_ldap_hostname_list(struct main_args *margs, struct hstruct **hlist, size_t nhosts, char *domain)
static char server[MAXLINE]
void debug(const char *format,...)
void * xrealloc(void *s, size_t sz)