43#include <netinet/in.h>
48#if HAVE_ARPA_NAMESER_H
49#include <arpa/nameser.h>
52void nsError(
int nserror,
char *
server);
55static void sort(
struct hstruct *array,
int nitems,
int (*cmp) (
struct hstruct *,
struct hstruct *),
int begin,
int end);
56static void msort(
struct hstruct *array,
size_t nitems,
int (*cmp) (
struct hstruct *,
struct hstruct *));
66nsError(
int nserror,
char *service)
70 error((
char *)
"%s| %s: ERROR: res_search: Unknown service record: %s\n",
LogTime(),
PROGRAM, service);
73 error((
char *)
"%s| %s: ERROR: res_search: No SRV record for %s\n",
LogTime(),
PROGRAM, service);
76 error((
char *)
"%s| %s: ERROR: res_search: No response for SRV query\n",
LogTime(),
PROGRAM);
100sort(
struct hstruct *array,
int nitems,
int (*cmp) (
struct hstruct *,
struct hstruct *),
int begin,
int end)
107 if (cmp(&array[l], &array[pivot]) <= 0) {
111 swap(&array[l], &array[r]);
115 swap(&array[begin], &array[l]);
116 sort(array, nitems, cmp, begin, l);
117 sort(array, nitems, cmp, r, end);
124 sort(array, (
int)nitems, cmp, 0, (
int)(nitems - 1));
160 for (i = 0; i < nhosts; ++i) {
172 struct addrinfo *hres =
nullptr, *hres_list;
180 rc = getaddrinfo((
const char *) name,
nullptr,
nullptr, &hres);
182 error((
char *)
"%s| %s: ERROR: Error while resolving hostname with getaddrinfo: %s\n",
LogTime(),
PROGRAM, gai_strerror(rc));
189 hres_list = hres_list->ai_next;
198 rc = getnameinfo(hres_list->ai_addr, hres_list->ai_addrlen,
host,
sizeof(
host),
nullptr, 0, 0);
200 error((
char *)
"%s| %s: ERROR: Error while resolving ip address with getnameinfo: %s\n",
LogTime(),
PROGRAM, gai_strerror(rc));
210 hp[nhosts].
port = -1;
215 hres_list = hres_list->ai_next;
231 char *service =
nullptr;
238 u_char *buffer =
nullptr;
248 hp[nhosts].
port = -1;
252 }
else if ( !ls->
domain || !strcasecmp(ls->
domain,
"") ) {
256 hp[nhosts].
port = -1;
269 service = (
char *)
xmalloc(strlen(
"_ldaps._tcp.") + strlen(domain) + 1);
270 strcpy(service,
"_ldaps._tcp.");
272 service = (
char *)
xmalloc(strlen(
"_ldap._tcp.") + strlen(domain) + 1);
273 strcpy(service,
"_ldap._tcp.");
275 strcat(service, domain);
282#define PACKETSZ_MULT 10
286 buffer = (u_char *)
xmalloc(PACKETSZ_MULT * NS_PACKETSZ);
287 if ((len = res_search(service, ns_c_in, ns_t_srv, (u_char *) buffer, PACKETSZ_MULT * NS_PACKETSZ)) < 0) {
288 error((
char *)
"%s| %s: ERROR: Error while resolving service record %s with res_search\n",
LogTime(),
PROGRAM, service);
289 nsError(h_errno, service);
292 service = (
char *)
xmalloc(strlen(
"_ldap._tcp.") + strlen(domain) + 1);
293 strcpy(service,
"_ldap._tcp.");
294 strcat(service, domain);
295 if ((len = res_search(service, ns_c_in, ns_t_srv, (u_char *) buffer, PACKETSZ_MULT * NS_PACKETSZ)) < 0) {
296 error((
char *)
"%s| %s: ERROR: Error while resolving service record %s with res_search\n",
LogTime(),
PROGRAM, service);
297 nsError(h_errno, service);
304 if (len > PACKETSZ_MULT * NS_PACKETSZ) {
306 buffer = (u_char *)
xrealloc(buffer, (
size_t)len);
307 if ((len = res_search(service, ns_c_in, ns_t_srv, (u_char *) buffer, len)) < 0) {
308 error((
char *)
"%s| %s: ERROR: Error while resolving service record %s with res_search\n",
LogTime(),
PROGRAM, service);
309 nsError(h_errno, service);
313 error((
char *)
"%s| %s: ERROR: Reply to big: buffer: %d reply length: %d\n",
LogTime(),
PROGRAM, olen, len);
319 if (p > buffer + len) {
320 error((
char *)
"%s| %s: ERROR: Message to small: %d < header size\n",
LogTime(),
PROGRAM, len);
323 if ((
size = dn_expand(buffer, buffer + len, p, name,
sizeof(name))) < 0) {
329 if (p > buffer + len) {
330 error((
char *)
"%s| %s: ERROR: Message to small: %d < header + query name,type,class \n",
LogTime(),
PROGRAM, len);
333 while (p < buffer + len) {
335 if ((
size = dn_expand(buffer, buffer + len, p, name,
sizeof(name))) < 0) {
340 if (p > buffer + len) {
341 error((
char *)
"%s| %s: ERROR: Message to small: %d < header + query name,type,class + answer name\n",
LogTime(),
PROGRAM, len);
345 p += NS_INT16SZ + NS_INT32SZ;
346 if (p > buffer + len) {
347 error((
char *)
"%s| %s: ERROR: Message to small: %d < header + query name,type,class + answer name + RR type,class,ttl\n",
LogTime(),
PROGRAM, len);
350 NS_GET16(rdlength, p);
352 if (type == ns_t_srv) {
355 if (p > buffer + len) {
356 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);
360 if (p > buffer + len) {
361 error((
char *)
"%s| %s: ERROR: Message to small: %d < SRV RR + priority\n",
LogTime(),
PROGRAM, len);
365 if (p > buffer + len) {
366 error((
char *)
"%s| %s: ERROR: Message to small: %d < SRV RR + priority + weight\n",
LogTime(),
PROGRAM, len);
370 if (p > buffer + len) {
371 error((
char *)
"%s| %s: ERROR: Message to small: %d < SRV RR + priority + weight + port\n",
LogTime(),
PROGRAM, len);
389 if (p > buffer + len) {
390 error((
char *)
"%s| %s: ERROR: Message to small: %d < SRV RR + priority + weight + port + name\n",
LogTime(),
PROGRAM, len);
394 if (p != buffer + len) {
395#if (SIZEOF_LONG == 8)
396 error(
"%s| %s: ERROR: Inconsistence message length: %ld!=0\n",
LogTime(),
PROGRAM, buffer + len - p);
398 error((
char *)
"%s| %s: ERROR: Inconsistence message length: %d!=0\n",
LogTime(),
PROGRAM, buffer + len - p);
410 hp[nhosts].
port = -1;
417 for (i = 0; i < nhosts; ++i) {
418 for (j = i + 1; j < nhosts; ++j) {
419 if (!strcasecmp(hp[i].
host, hp[j].
host)) {
421 (hp[i].
port == -1 && hp[j].
port == 389) ||
422 (hp[i].
port == 389 && hp[j].
port == -1)) {
424 for (k = j + 1; k < nhosts; ++k) {
439 msort(hp, (
size_t)nhosts, compare_hosts);
442 debug((
char *)
"%s| %s: DEBUG: Sorted ldap server names for domain %s:\n",
LogTime(),
PROGRAM, domain);
443 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)