+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
/*
* -----------------------------------------------------------------------------
*
* -----------------------------------------------------------------------------
*/
-#include "config.h"
+#include "squid.h"
#include "util.h"
-#ifdef HAVE_LDAP
+#if HAVE_LDAP
#include "support.h"
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_NETDB_H
+#include <cerrno>
+#if HAVE_NETDB_H
#include <netdb.h>
#endif
-#ifdef HAVE_NETINET_IN_H
+#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
-#ifdef HAVE_RESOLV_H
+#if HAVE_RESOLV_H
#include <resolv.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
+#if HAVE_ARPA_NAMESER_H
#include <arpa/nameser.h>
#endif
sort(struct hstruct *array, int nitems, int (*cmp) (struct hstruct *, struct hstruct *), int begin, int end)
{
if (end > begin) {
- int pivot = begin;
int l = begin + 1;
int r = end;
while (l < r) {
+ int pivot = begin;
if (cmp(&array[l], &array[pivot]) <= 0) {
l += 1;
} else {
static void
msort(struct hstruct *array, size_t nitems, int (*cmp) (struct hstruct *, struct hstruct *))
{
- sort(array, nitems, cmp, 0, nitems - 1);
+ sort(array, (int)nitems, cmp, 0, (int)(nitems - 1));
}
static int
return 0;
}
-int
-free_hostname_list(struct hstruct **hlist, int nhosts)
+size_t
+free_hostname_list(struct hstruct **hlist, size_t nhosts)
{
struct hstruct *hp = NULL;
- int i;
+ size_t i;
hp = *hlist;
- for (i = 0; i < nhosts; i++) {
- if (hp[i].host)
- xfree(hp[i].host);
- hp[i].host = NULL;
+ for (i = 0; i < nhosts; ++i) {
+ xfree(hp[i].host);
}
-
- if (hp)
- xfree(hp);
- hp = NULL;
+ safe_free(hp);
*hlist = hp;
return 0;
}
-int
-get_hostname_list(struct main_args *margs, struct hstruct **hlist, int nhosts, char *name)
+size_t
+get_hostname_list(struct hstruct **hlist, size_t nhosts, char *name)
{
- /*
- * char host[sysconf(_SC_HOST_NAME_MAX)];
- */
- char host[1024];
struct addrinfo *hres = NULL, *hres_list;
int rc, count;
struct hstruct *hp = NULL;
hres_list = hres;
count = 0;
while (hres_list) {
- count++;
+ ++count;
hres_list = hres_list->ai_next;
}
hres_list = hres;
count = 0;
while (hres_list) {
+ /*
+ * char host[sysconf(_SC_HOST_NAME_MAX)];
+ */
+ char host[1024];
rc = getnameinfo(hres_list->ai_addr, hres_list->ai_addrlen, host, sizeof(host), NULL, 0, 0);
if (rc != 0) {
error((char *) "%s| %s: ERROR: Error while resolving ip address with getnameinfo: %s\n", LogTime(), PROGRAM, gai_strerror(rc));
*hlist = hp;
return (nhosts);
}
- count++;
+ ++count;
debug((char *) "%s| %s: DEBUG: Resolved address %d of %s to %s\n", LogTime(), PROGRAM, count, name, host);
hp = (struct hstruct *) xrealloc(hp, sizeof(struct hstruct) * (nhosts + 1));
hp[nhosts].port = -1;
hp[nhosts].priority = -1;
hp[nhosts].weight = -1;
- nhosts++;
+ ++nhosts;
hres_list = hres_list->ai_next;
}
return (nhosts);
}
-int
-get_ldap_hostname_list(struct main_args *margs, struct hstruct **hlist, int nh, char *domain)
+size_t
+get_ldap_hostname_list(struct main_args *margs, struct hstruct **hlist, size_t nh, char *domain)
{
/*
* char name[sysconf(_SC_HOST_NAME_MAX)];
*/
char name[1024];
- char host[NS_MAXDNAME];
char *service = NULL;
struct hstruct *hp = NULL;
struct lsstruct *ls = NULL;
- int nhosts = 0;
+ size_t nhosts = 0;
int size;
- int type, rdlength;
- int priority, weight, port;
int len, olen;
- int i, j, k;
+ size_t i, j, k;
u_char *buffer = NULL;
u_char *p;
if (ls->domain && !strcasecmp(ls->domain, domain)) {
debug((char *) "%s| %s: DEBUG: Found lserver@domain %s@%s\n", LogTime(), PROGRAM, ls->lserver, ls->domain);
hp = (struct hstruct *) xrealloc(hp, sizeof(struct hstruct) * (nhosts + 1));
- hp[nhosts].host = strdup(ls->lserver);
+ hp[nhosts].host = xstrdup(ls->lserver);
hp[nhosts].port = -1;
hp[nhosts].priority = -2;
hp[nhosts].weight = -2;
- nhosts++;
+ ++nhosts;
} else if ( !ls->domain || !strcasecmp(ls->domain, "") ) {
debug((char *) "%s| %s: DEBUG: Found lserver@domain %s@%s\n", LogTime(), PROGRAM, ls->lserver, ls->domain?ls->domain:"NULL");
hp = (struct hstruct *) xrealloc(hp, sizeof(struct hstruct) * (nhosts + 1));
- hp[nhosts].host = strdup(ls->lserver);
+ hp[nhosts].host = xstrdup(ls->lserver);
hp[nhosts].port = -1;
hp[nhosts].priority = -2;
hp[nhosts].weight = -2;
- nhosts++;
+ ++nhosts;
}
ls = ls->next;
if ((len = res_search(service, ns_c_in, ns_t_srv, (u_char *) buffer, PACKETSZ_MULT * NS_PACKETSZ)) < 0) {
error((char *) "%s| %s: ERROR: Error while resolving service record %s with res_search\n", LogTime(), PROGRAM, service);
nsError(h_errno, service);
- goto cleanup;
+ goto finalise;
}
} else {
- goto cleanup;
+ goto finalise;
}
}
if (len > PACKETSZ_MULT * NS_PACKETSZ) {
olen = len;
- buffer = (u_char *) xrealloc(buffer, len);
+ buffer = (u_char *) xrealloc(buffer, (size_t)len);
if ((len = res_search(service, ns_c_in, ns_t_srv, (u_char *) buffer, len)) < 0) {
error((char *) "%s| %s: ERROR: Error while resolving service record %s with res_search\n", LogTime(), PROGRAM, service);
nsError(h_errno, service);
- goto cleanup;
+ goto finalise;
}
if (len > olen) {
error((char *) "%s| %s: ERROR: Reply to big: buffer: %d reply length: %d\n", LogTime(), PROGRAM, olen, len);
- goto cleanup;
+ goto finalise;
}
}
p = buffer;
- p += 6 * NS_INT16SZ; /* Header(6*16bit) = id + flags + 4*section count */
+ p += 6 * NS_INT16SZ; /* Header(6*16bit) = id + flags + 4*section count */
if (p > buffer + len) {
error((char *) "%s| %s: ERROR: Message to small: %d < header size\n", LogTime(), PROGRAM, len);
- goto cleanup;
+ goto finalise;
}
- if ((size = dn_expand(buffer, buffer + len, p, name, sysconf(_SC_HOST_NAME_MAX))) < 0) {
+ if ((size = dn_expand(buffer, buffer + len, p, name, sizeof(name))) < 0) {
error((char *) "%s| %s: ERROR: Error while expanding query name with dn_expand: %s\n", LogTime(), PROGRAM, strerror(errno));
- goto cleanup;
+ goto finalise;
}
- p += size; /* Query name */
- p += 2 * NS_INT16SZ; /* Query type + class (2*16bit) */
+ p += size; /* Query name */
+ p += 2 * NS_INT16SZ; /* Query type + class (2*16bit) */
if (p > buffer + len) {
error((char *) "%s| %s: ERROR: Message to small: %d < header + query name,type,class \n", LogTime(), PROGRAM, len);
- goto cleanup;
+ goto finalise;
}
while (p < buffer + len) {
- if ((size = dn_expand(buffer, buffer + len, p, name, sysconf(_SC_HOST_NAME_MAX))) < 0) {
+ int type, rdlength;
+ if ((size = dn_expand(buffer, buffer + len, p, name, sizeof(name))) < 0) {
error((char *) "%s| %s: ERROR: Error while expanding answer name with dn_expand: %s\n", LogTime(), PROGRAM, strerror(errno));
- goto cleanup;
+ goto finalise;
}
- p += size; /* Resource Record name */
+ p += size; /* Resource Record name */
if (p > buffer + len) {
error((char *) "%s| %s: ERROR: Message to small: %d < header + query name,type,class + answer name\n", LogTime(), PROGRAM, len);
- goto cleanup;
+ goto finalise;
}
- NS_GET16(type, p); /* RR type (16bit) */
- p += NS_INT16SZ + NS_INT32SZ; /* RR class + ttl (16bit+32bit) */
+ NS_GET16(type, p); /* RR type (16bit) */
+ p += NS_INT16SZ + NS_INT32SZ; /* RR class + ttl (16bit+32bit) */
if (p > buffer + len) {
error((char *) "%s| %s: ERROR: Message to small: %d < header + query name,type,class + answer name + RR type,class,ttl\n", LogTime(), PROGRAM, len);
- goto cleanup;
+ goto finalise;
}
- NS_GET16(rdlength, p); /* RR data length (16bit) */
+ NS_GET16(rdlength, p); /* RR data length (16bit) */
- if (type == ns_t_srv) { /* SRV record */
+ if (type == ns_t_srv) { /* SRV record */
+ int priority, weight, port;
+ char host[NS_MAXDNAME];
if (p > buffer + len) {
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);
- goto cleanup;
+ goto finalise;
}
- NS_GET16(priority, p); /* Priority (16bit) */
+ NS_GET16(priority, p); /* Priority (16bit) */
if (p > buffer + len) {
error((char *) "%s| %s: ERROR: Message to small: %d < SRV RR + priority\n", LogTime(), PROGRAM, len);
- goto cleanup;
+ goto finalise;
}
- NS_GET16(weight, p); /* Weight (16bit) */
+ NS_GET16(weight, p); /* Weight (16bit) */
if (p > buffer + len) {
error((char *) "%s| %s: ERROR: Message to small: %d < SRV RR + priority + weight\n", LogTime(), PROGRAM, len);
- goto cleanup;
+ goto finalise;
}
- NS_GET16(port, p); /* Port (16bit) */
+ NS_GET16(port, p); /* Port (16bit) */
if (p > buffer + len) {
error((char *) "%s| %s: ERROR: Message to small: %d < SRV RR + priority + weight + port\n", LogTime(), PROGRAM, len);
- goto cleanup;
+ goto finalise;
}
if ((size = dn_expand(buffer, buffer + len, p, host, NS_MAXDNAME)) < 0) {
error((char *) "%s| %s: ERROR: Error while expanding SRV RR name with dn_expand: %s\n", LogTime(), PROGRAM, strerror(errno));
- goto cleanup;
+ goto finalise;
}
debug((char *) "%s| %s: DEBUG: Resolved SRV %s record to %s\n", LogTime(), PROGRAM, service, host);
hp = (struct hstruct *) xrealloc(hp, sizeof(struct hstruct) * (nh + 1));
hp[nh].port = port;
hp[nh].priority = priority;
hp[nh].weight = weight;
- nh++;
+ ++nh;
p += size;
} else {
p += rdlength;
}
if (p > buffer + len) {
error((char *) "%s| %s: ERROR: Message to small: %d < SRV RR + priority + weight + port + name\n", LogTime(), PROGRAM, len);
- goto cleanup;
+ goto finalise;
}
}
if (p != buffer + len) {
#else
error((char *) "%s| %s: ERROR: Inconsistence message length: %d!=0\n", LogTime(), PROGRAM, buffer + len - p);
#endif
- goto cleanup;
+ goto finalise;
}
-cleanup:
- nhosts = get_hostname_list(margs, &hp, nh, domain);
+finalise:
+ nhosts = get_hostname_list(&hp, nh, domain);
debug("%s| %s: DEBUG: Adding %s to list\n", LogTime(), PROGRAM, domain);
hp = (struct hstruct *) xrealloc(hp, sizeof(struct hstruct) * (nhosts + 1));
- hp[nhosts].host = strdup(domain);
+ hp[nhosts].host = xstrdup(domain);
hp[nhosts].port = -1;
hp[nhosts].priority = -2;
hp[nhosts].weight = -2;
- nhosts++;
+ ++nhosts;
+cleanup:
/* Remove duplicates */
- for (i = 0; i < nhosts; i++) {
- for (j = i + 1; j < nhosts; j++) {
+ for (i = 0; i < nhosts; ++i) {
+ for (j = i + 1; j < nhosts; ++j) {
if (!strcasecmp(hp[i].host, hp[j].host)) {
if (hp[i].port == hp[j].port ||
(hp[i].port == -1 && hp[j].port == 389) ||
(hp[i].port == 389 && hp[j].port == -1)) {
xfree(hp[j].host);
- for (k = j + 1; k < nhosts; k++) {
+ for (k = j + 1; k < nhosts; ++k) {
hp[k - 1].host = hp[k].host;
hp[k - 1].port = hp[k].port;
hp[k - 1].priority = hp[k].priority;
hp[k - 1].weight = hp[k].weight;
}
- j--;
- nhosts--;
+ --j;
+ --nhosts;
hp = (struct hstruct *) xrealloc(hp, sizeof(struct hstruct) * (nhosts + 1));
}
}
}
/* Sort by Priority / Weight */
- msort(hp, nhosts, compare_hosts);
+ msort(hp, (size_t)nhosts, compare_hosts);
if (debug_enabled) {
debug((char *) "%s| %s: DEBUG: Sorted ldap server names for domain %s:\n", LogTime(), PROGRAM, domain);
- for (i = 0; i < nhosts; i++) {
+ for (i = 0; i < nhosts; ++i) {
debug((char *) "%s| %s: DEBUG: Host: %s Port: %d Priority: %d Weight: %d\n", LogTime(), PROGRAM, hp[i].host, hp[i].port, hp[i].priority, hp[i].weight);
}
}
- if (buffer)
- xfree(buffer);
- if (service)
- xfree(service);
+ xfree(buffer);
+ xfree(service);
*hlist = hp;
return (nhosts);
}
#endif
+