| From 01a44c96dbd04936e9cb2501745a834a0b09d504 Mon Sep 17 00:00:00 2001 |
| From: Amos Jeffries <yadij@users.noreply.github.com> |
| Date: Sun, 13 May 2018 06:57:41 +0000 |
| Subject: [PATCH] Bug 4843 pt1: ext_edirectory_userip_acl refactoring for GCC-8 |
| (#204) |
| |
| Proposed changes to this helper to fix strcat / strncat buffer |
| overread / overflow issues. |
| |
| The approach takes three parts: |
| |
| * adds a makeHexString function to replace many for-loops |
| catenating bits of strings together with hex conversion into a |
| second buffer. Replacing with a snprintf() and buffer overflow |
| handling. |
| |
| * a copy of Ip::Address::lookupHostIp to convert the input |
| string into IP address binary format, then generate the hex |
| string using the above new hex function instead of looped |
| sub-string concatenations across several buffers. |
| This removes all the "00" and "0000" strncat() calls and |
| allows far simpler code even with added buffer overflow |
| handling. |
| |
| * replace multiple string part concatenations with a few simpler |
| calls to snprintf() for all the search_ip buffer constructions. |
| Adding buffer overflow handling as needed for the new calls. |
| --- |
| Signed-off-by: Khem Raj <raj.khem@gmail.com> |
| Upstream-Status: Backport |
| |
| .../ext_edirectory_userip_acl.cc | 376 ++++++------------ |
| 1 file changed, 120 insertions(+), 256 deletions(-) |
| |
| diff --git a/helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.cc b/helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.cc |
| index 63609e4..ad16bfd 100644 |
| --- a/helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.cc |
| +++ b/helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.cc |
| @@ -67,6 +67,9 @@ |
| #ifdef HAVE_LDAP_H |
| #include <ldap.h> |
| #endif |
| +#ifdef HAVE_NETDB_H |
| +#include <netdb.h> |
| +#endif |
| |
| #ifdef HELPER_INPUT_BUFFER |
| #define EDUI_MAXLEN HELPER_INPUT_BUFFER |
| @@ -714,11 +717,14 @@ BindLDAP(edui_ldap_t *l, char *dn, char *pw, unsigned int t) |
| |
| /* Copy details - dn and pw CAN be NULL for anonymous and/or TLS */ |
| if (dn != NULL) { |
| + if (strlen(dn) >= sizeof(l->dn)) |
| + return LDAP_ERR_OOB; /* DN too large */ |
| + |
| if ((l->basedn[0] != '\0') && (strstr(dn, l->basedn) == NULL)) { |
| /* We got a basedn, but it's not part of dn */ |
| - xstrncpy(l->dn, dn, sizeof(l->dn)); |
| - strncat(l->dn, ",", 1); |
| - strncat(l->dn, l->basedn, strlen(l->basedn)); |
| + const int x = snprintf(l->dn, sizeof(l->dn)-1, "%s,%s", dn, l->basedn); |
| + if (x < 0 || static_cast<size_t>(x) >= sizeof(l->dn)) |
| + return LDAP_ERR_OOB; /* DN too large */ |
| } else |
| xstrncpy(l->dn, dn, sizeof(l->dn)); |
| } |
| @@ -778,24 +784,73 @@ BindLDAP(edui_ldap_t *l, char *dn, char *pw, unsigned int t) |
| } |
| } |
| |
| +// XXX: duplicate (partial) of Ip::Address::lookupHostIp |
| +/** |
| + * Convert the IP address string representation in src to |
| + * its binary representation. |
| + * |
| + * \return binary representation of the src IP address. |
| + * Must be free'd using freeaddrinfo(). |
| + */ |
| +static struct addrinfo * |
| +makeIpBinary(const char *src) |
| +{ |
| + struct addrinfo want; |
| + memset(&want, 0, sizeof(want)); |
| + want.ai_flags = AI_NUMERICHOST; // prevent actual DNS lookups! |
| + |
| + struct addrinfo *dst = nullptr; |
| + if (getaddrinfo(src, nullptr, &want, &dst) != 0) { |
| + // not an IP address |
| + /* free any memory getaddrinfo() dynamically allocated. */ |
| + if (dst) |
| + freeaddrinfo(dst); |
| + return nullptr; |
| + } |
| + |
| + return dst; |
| +} |
| + |
| +/** |
| + * Convert srcLen bytes from src into HEX and store into dst, which |
| + * has a maximum content size of dstSize including c-string terminator. |
| + * The dst value produced will be a 0-terminated c-string. |
| + * |
| + * \retval N length of dst written (excluding c-string terminator) |
| + * \retval -11 (LDAP_ERR_OOB) buffer overflow detected |
| + */ |
| +static int |
| +makeHexString(char *dst, const int dstSize, const char *src, const int srcLen) |
| +{ |
| + // HEX encoding doubles the amount of bytes/octets copied |
| + if ((srcLen*2) >= dstSize) |
| + return LDAP_ERR_OOB; // cannot copy that many |
| + |
| + *dst = 0; |
| + |
| + for (int k = 0; k < srcLen; ++k) { |
| + int c = static_cast<int>(src[k]); |
| + if (c < 0) |
| + c = c + 256; |
| + char hexc[4]; |
| + const int hlen = snprintf(hexc, sizeof(hexc), "%02X", c); |
| + if (hlen < 0 || static_cast<size_t>(hlen) > sizeof(hexc)) // should be impossible |
| + return LDAP_ERR_OOB; |
| + strcat(dst, hexc); |
| + } |
| + return strlen(dst); |
| +} |
| + |
| /* |
| * ConvertIP() - <edui_ldap_t> <ip> |
| * |
| * Take an IPv4 address in dot-decimal or IPv6 notation, and convert to 2-digit HEX stored in l->search_ip |
| * This is the networkAddress that we search LDAP for. |
| - * |
| - * PENDING -- CHANGE OVER TO inet*_pton, but inet6_pton does not provide the correct syntax |
| - * |
| */ |
| static int |
| ConvertIP(edui_ldap_t *l, char *ip) |
| { |
| - char bufa[EDUI_MAXLEN], bufb[EDUI_MAXLEN], obj[EDUI_MAXLEN]; |
| - char hexc[4], *p; |
| void *y, *z; |
| - size_t s; |
| - long x; |
| - int i, j, t, swi; /* IPv6 "::" cut over toggle */ |
| if (l == NULL) return LDAP_ERR_NULL; |
| if (ip == NULL) return LDAP_ERR_PARAM; |
| if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Not initalized */ |
| @@ -831,183 +886,22 @@ ConvertIP(edui_ldap_t *l, char *ip) |
| l->status |= (LDAP_IPV4_S); |
| z = NULL; |
| } |
| - s = strlen(ip); |
| - *(bufa) = '\0'; |
| - *(bufb) = '\0'; |
| - *(obj) = '\0'; |
| - /* StringSplit() will zero out bufa & obj at each call */ |
| - memset(l->search_ip, '\0', sizeof(l->search_ip)); |
| - xstrncpy(bufa, ip, sizeof(bufa)); /* To avoid segfaults, use bufa instead of ip */ |
| - swi = 0; |
| - if (l->status & LDAP_IPV6_S) { |
| - /* Search for :: in string */ |
| - if ((bufa[0] == ':') && (bufa[1] == ':')) { |
| - /* bufa starts with a ::, so just copy and clear */ |
| - xstrncpy(bufb, bufa, sizeof(bufb)); |
| - *(bufa) = '\0'; |
| - ++swi; /* Indicates that there is a bufb */ |
| - } else if ((bufa[0] == ':') && (bufa[1] != ':')) { |
| - /* bufa starts with a :, a typo so just fill in a ':', cat and clear */ |
| - bufb[0] = ':'; |
| - strncat(bufb, bufa, strlen(bufa)); |
| - *(bufa) = '\0'; |
| - ++swi; /* Indicates that there is a bufb */ |
| - } else { |
| - p = strstr(bufa, "::"); |
| - if (p != NULL) { |
| - /* Found it, break bufa down and split into bufb here */ |
| - *(bufb) = '\0'; |
| - i = strlen(p); |
| - memcpy(bufb, p, i); |
| - *p = '\0'; |
| - bufb[i] = '\0'; |
| - ++swi; /* Indicates that there is a bufb */ |
| - } |
| - } |
| - } |
| - s = strlen(bufa); |
| - if (s < 1) |
| - s = strlen(bufb); |
| - while (s > 0) { |
| - if ((l->status & LDAP_IPV4_S) && (swi == 0)) { |
| - /* Break down IPv4 address */ |
| - t = StringSplit(bufa, '.', obj, sizeof(obj)); |
| - if (t > 0) { |
| - errno = 0; |
| - x = strtol(obj, (char **)NULL, 10); |
| - if (((x < 0) || (x > 255)) || ((errno != 0) && (x == 0)) || ((obj[0] != '0') && (x == 0))) |
| - return LDAP_ERR_OOB; /* Out of bounds -- Invalid address */ |
| - memset(hexc, '\0', sizeof(hexc)); |
| - int hlen = snprintf(hexc, sizeof(hexc), "%02X", (int)x); |
| - strncat(l->search_ip, hexc, hlen); |
| - } else |
| - break; /* reached end of octet */ |
| - } else if (l->status & LDAP_IPV6_S) { |
| - /* Break down IPv6 address */ |
| - if (swi > 1) |
| - t = StringSplit(bufb, ':', obj, sizeof(obj)); /* After "::" */ |
| - else |
| - t = StringSplit(bufa, ':', obj, sizeof(obj)); /* Before "::" */ |
| - /* Convert octet by size (t) - and fill 0's */ |
| - switch (t) { /* IPv6 is already in HEX, copy contents */ |
| - case 4: |
| - hexc[0] = (char) toupper((int)obj[0]); |
| - i = (int)hexc[0]; |
| - if (!isxdigit(i)) |
| - return LDAP_ERR_OOB; /* Out of bounds */ |
| - hexc[1] = (char) toupper((int)obj[1]); |
| - i = (int)hexc[1]; |
| - if (!isxdigit(i)) |
| - return LDAP_ERR_OOB; /* Out of bounds */ |
| - hexc[2] = '\0'; |
| - strncat(l->search_ip, hexc, 2); |
| - hexc[0] = (char) toupper((int)obj[2]); |
| - i = (int)hexc[0]; |
| - if (!isxdigit(i)) |
| - return LDAP_ERR_OOB; /* Out of bounds */ |
| - hexc[1] = (char) toupper((int)obj[3]); |
| - i = (int)hexc[1]; |
| - if (!isxdigit(i)) |
| - return LDAP_ERR_OOB; /* Out of bounds */ |
| - hexc[2] = '\0'; |
| - strncat(l->search_ip, hexc, 2); |
| - break; |
| - case 3: |
| - hexc[0] = '0'; |
| - hexc[1] = (char) toupper((int)obj[0]); |
| - i = (int)hexc[1]; |
| - if (!isxdigit(i)) |
| - return LDAP_ERR_OOB; /* Out of bounds */ |
| - hexc[2] = '\0'; |
| - strncat(l->search_ip, hexc, 2); |
| - hexc[0] = (char) toupper((int)obj[1]); |
| - i = (int)hexc[0]; |
| - if (!isxdigit(i)) |
| - return LDAP_ERR_OOB; /* Out of bounds */ |
| - hexc[1] = (char) toupper((int)obj[2]); |
| - i = (int)hexc[1]; |
| - if (!isxdigit(i)) |
| - return LDAP_ERR_OOB; /* Out of bounds */ |
| - hexc[2] = '\0'; |
| - strncat(l->search_ip, hexc, 2); |
| - break; |
| - case 2: |
| - strncat(l->search_ip, "00", 2); |
| - hexc[0] = (char) toupper((int)obj[0]); |
| - i = (int)hexc[0]; |
| - if (!isxdigit(i)) |
| - return LDAP_ERR_OOB; /* Out of bounds */ |
| - hexc[1] = (char) toupper((int)obj[1]); |
| - i = (int)hexc[1]; |
| - if (!isxdigit(i)) |
| - return LDAP_ERR_OOB; /* Out of bounds */ |
| - hexc[2] = '\0'; |
| - strncat(l->search_ip, hexc, 2); |
| - break; |
| - case 1: |
| - strncat(l->search_ip, "00", 2); |
| - hexc[0] = '0'; |
| - hexc[1] = (char) toupper((int)obj[0]); |
| - i = (int)hexc[1]; |
| - if (!isxdigit(i)) |
| - return LDAP_ERR_OOB; /* Out of bounds */ |
| - hexc[2] = '\0'; |
| - strncat(l->search_ip, hexc, 2); |
| - break; |
| - default: |
| - if (t > 4) |
| - return LDAP_ERR_OOB; |
| - break; |
| - } |
| - /* Code to pad the address with 0's between a '::' */ |
| - if ((strlen(bufa) == 0) && (swi == 1)) { |
| - /* We are *AT* the split, pad in some 0000 */ |
| - t = strlen(bufb); |
| - /* How many ':' exist in bufb ? */ |
| - j = 0; |
| - for (i = 0; i < t; ++i) { |
| - if (bufb[i] == ':') |
| - ++j; |
| - } |
| - --j; /* Preceding "::" doesn't count */ |
| - t = 8 - (strlen(l->search_ip) / 4) - j; /* Remainder */ |
| - if (t > 0) { |
| - for (i = 0; i < t; ++i) |
| - strncat(l->search_ip, "0000", 4); |
| - } |
| - } |
| - } |
| - if ((bufa[0] == '\0') && (swi > 0)) { |
| - s = strlen(bufb); |
| - ++swi; |
| - } else |
| - s = strlen(bufa); |
| - } |
| - s = strlen(l->search_ip); |
| |
| - /* CHECK sizes of address, truncate or pad */ |
| - /* if "::" is at end of ip, then pad another block or two */ |
| - while ((l->status & LDAP_IPV6_S) && (s < 32)) { |
| - strncat(l->search_ip, "0000", 4); |
| - s = strlen(l->search_ip); |
| - } |
| - if ((l->status & LDAP_IPV6_S) && (s > 32)) { |
| - /* Too long, truncate */ |
| - l->search_ip[32] = '\0'; |
| - s = strlen(l->search_ip); |
| - } |
| - /* If at end of ip, and its not long enough, then pad another block or two */ |
| - while ((l->status & LDAP_IPV4_S) && (s < 8)) { |
| - strncat(l->search_ip, "00", 2); |
| - s = strlen(l->search_ip); |
| - } |
| - if ((l->status & LDAP_IPV4_S) && (s > 8)) { |
| - /* Too long, truncate */ |
| - l->search_ip[8] = '\0'; |
| - s = strlen(l->search_ip); |
| + size_t s = LDAP_ERR_INVALID; |
| + if (struct addrinfo *dst = makeIpBinary(ip)) { |
| + if (dst->ai_family == AF_INET6) { |
| + struct sockaddr_in6 *sia = reinterpret_cast<struct sockaddr_in6 *>(dst->ai_addr); |
| + const char *ia = reinterpret_cast<const char *>(sia->sin6_addr.s6_addr); |
| + s = makeHexString(l->search_ip, sizeof(l->search_ip), ia, 16); // IPv6 = 16-byte address |
| + |
| + } else if (dst->ai_family == AF_INET) { |
| + struct sockaddr_in *sia = reinterpret_cast<struct sockaddr_in *>(dst->ai_addr); |
| + const char *ia = reinterpret_cast<const char *>(&(sia->sin_addr)); |
| + s = makeHexString(l->search_ip, sizeof(l->search_ip), ia, 4); // IPv4 = 4-byte address |
| + } // else leave s with LDAP_ERR_INVALID value |
| + freeaddrinfo(dst); |
| } |
| |
| - /* Completed, s is length of address in HEX */ |
| return s; |
| } |
| |
| @@ -1099,48 +993,42 @@ SearchFilterLDAP(edui_ldap_t *l, char *group) |
| } |
| if (group == NULL) { |
| /* No groupMembership= to add, yay! */ |
| - xstrncpy(bufa, "(&", sizeof(bufa)); |
| - strncat(bufa, edui_conf.search_filter, strlen(edui_conf.search_filter)); |
| /* networkAddress */ |
| - snprintf(bufb, sizeof(bufb), "(|(networkAddress=1\\23%s)", bufc); |
| if (l->status & LDAP_IPV4_S) { |
| - int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=8\\23\\00\\00%s)(networkAddress=9\\23\\00\\00%s))", \ |
| - bufc, bufc); |
| - strncat(bufb, bufd, ln); |
| + const int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=8\\23\\00\\00%s)(networkAddress=9\\23\\00\\00%s)", bufc, bufc); |
| + if (ln < 0 || static_cast<size_t>(ln) >= sizeof(bufd)) |
| + return LDAP_ERR_OOB; |
| + |
| } else if (l->status & LDAP_IPV6_S) { |
| - int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=10\\23\\00\\00%s)(networkAddress=11\\23\\00\\00%s))", \ |
| - bufc, bufc); |
| - strncat(bufb, bufd, ln); |
| - } else |
| - strncat(bufb, ")", 1); |
| - strncat(bufa, bufb, strlen(bufb)); |
| - strncat(bufa, ")", 1); |
| + const int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=10\\23\\00\\00%s)(networkAddress=11\\23\\00\\00%s)", bufc, bufc); |
| + if (ln < 0 || static_cast<size_t>(ln) >= sizeof(bufd)) |
| + return LDAP_ERR_OOB; |
| + } |
| + const int x = snprintf(bufa, sizeof(bufa), "(&%s(|(networkAddress=1\\23%s)%s))", edui_conf.search_filter, bufc, bufd); |
| + if (x < 0 || static_cast<size_t>(x) >= sizeof(bufa)) |
| + return LDAP_ERR_OOB; |
| + |
| } else { |
| /* Needs groupMembership= to add... */ |
| - xstrncpy(bufa, "(&(&", sizeof(bufa)); |
| - strncat(bufa, edui_conf.search_filter, strlen(edui_conf.search_filter)); |
| /* groupMembership -- NOTE: Squid *MUST* provide "cn=" from squid.conf */ |
| - snprintf(bufg, sizeof(bufg), "(groupMembership=%s", group); |
| if ((l->basedn[0] != '\0') && (strstr(group, l->basedn) == NULL)) { |
| - strncat(bufg, ",", 1); |
| - strncat(bufg, l->basedn, strlen(l->basedn)); |
| + const int ln = snprintf(bufg, sizeof(bufg), ",%s", l->basedn); |
| + if (ln < 0 || static_cast<size_t>(ln) >= sizeof(bufd)) |
| + return LDAP_ERR_OOB; |
| } |
| - strncat(bufg, ")", 1); |
| - strncat(bufa, bufg, strlen(bufg)); |
| /* networkAddress */ |
| - snprintf(bufb, sizeof(bufb), "(|(networkAddress=1\\23%s)", bufc); |
| if (l->status & LDAP_IPV4_S) { |
| - int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=8\\23\\00\\00%s)(networkAddress=9\\23\\00\\00%s))", \ |
| - bufc, bufc); |
| - strncat(bufb, bufd, ln); |
| + const int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=8\\23\\00\\00%s)(networkAddress=9\\23\\00\\00%s)", bufc, bufc); |
| + if (ln < 0 || static_cast<size_t>(ln) >= sizeof(bufd)) |
| + return LDAP_ERR_OOB; |
| } else if (l->status & LDAP_IPV6_S) { |
| - int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=10\\23\\00\\00%s)(networkAddress=11\\23\\00\\00%s))", \ |
| - bufc, bufc); |
| - strncat(bufb, bufd, ln); |
| - } else |
| - strncat(bufb, ")", 1); |
| - strncat(bufa, bufb, strlen(bufb)); |
| - strncat(bufa, "))", 2); |
| + const int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=10\\23\\00\\00%s)(networkAddress=11\\23\\00\\00%s)", bufc, bufc); |
| + if (ln < 0 || static_cast<size_t>(ln) >= sizeof(bufd)) |
| + return LDAP_ERR_OOB; |
| + } |
| + const int x = snprintf(bufa, sizeof(bufa), "(&(&%s(groupMembership=%s%s)(|(networkAddress=1\\23%s)%s)))", edui_conf.search_filter, group, bufg, bufc, bufd); |
| + if (x < 0 || static_cast<size_t>(x) >= sizeof(bufa)) |
| + return LDAP_ERR_OOB; |
| } |
| s = strlen(bufa); |
| xstrncpy(l->search_filter, bufa, sizeof(l->search_filter)); |
| @@ -1212,10 +1100,10 @@ static int |
| SearchIPLDAP(edui_ldap_t *l) |
| { |
| ber_len_t i, x; |
| - ber_len_t j, k; |
| - ber_len_t y, z; |
| - int c; |
| - char bufa[EDUI_MAXLEN], bufb[EDUI_MAXLEN], hexc[4]; |
| + ber_len_t j; |
| + ber_len_t z; |
| + char bufa[EDUI_MAXLEN]; |
| + char bufb[EDUI_MAXLEN]; |
| LDAPMessage *ent; |
| if (l == NULL) return LDAP_ERR_NULL; |
| if (l->lp == NULL) return LDAP_ERR_POINTER; |
| @@ -1273,19 +1161,11 @@ SearchIPLDAP(edui_ldap_t *l) |
| /* bufa is the address, just compare it */ |
| if (!(l->status & LDAP_IPV4_S) || (l->status & LDAP_IPV6_S)) |
| break; /* Not looking for IPv4 */ |
| - for (k = 0; k < z; ++k) { |
| - c = (int) bufa[k]; |
| - if (c < 0) |
| - c = c + 256; |
| - int hlen = snprintf(hexc, sizeof(hexc), "%02X", c); |
| - if (k == 0) |
| - xstrncpy(bufb, hexc, sizeof(bufb)); |
| - else |
| - strncat(bufb, hexc, hlen); |
| - } |
| - y = strlen(bufb); |
| + const int blen = makeHexString(bufb, sizeof(bufb), bufa, z); |
| + if (blen < 0) |
| + return blen; |
| /* Compare value with IP */ |
| - if (memcmp(l->search_ip, bufb, y) == 0) { |
| + if (memcmp(l->search_ip, bufb, blen) == 0) { |
| /* We got a match! - Scan 'ber' for 'cn' values */ |
| z = ldap_count_values_len(ber); |
| for (j = 0; j < z; ++j) { |
| @@ -1308,19 +1188,11 @@ SearchIPLDAP(edui_ldap_t *l) |
| /* bufa + 2 is the address (skip 2 digit port) */ |
| if (!(l->status & LDAP_IPV4_S) || (l->status & LDAP_IPV6_S)) |
| break; /* Not looking for IPv4 */ |
| - for (k = 2; k < z; ++k) { |
| - c = (int) bufa[k]; |
| - if (c < 0) |
| - c = c + 256; |
| - int hlen = snprintf(hexc, sizeof(hexc), "%02X", c); |
| - if (k == 2) |
| - xstrncpy(bufb, hexc, sizeof(bufb)); |
| - else |
| - strncat(bufb, hexc, hlen); |
| - } |
| - y = strlen(bufb); |
| + const int blen = makeHexString(bufb, sizeof(bufb), &bufa[2], z); |
| + if (blen < 0) |
| + return blen; |
| /* Compare value with IP */ |
| - if (memcmp(l->search_ip, bufb, y) == 0) { |
| + if (memcmp(l->search_ip, bufb, blen) == 0) { |
| /* We got a match! - Scan 'ber' for 'cn' values */ |
| z = ldap_count_values_len(ber); |
| for (j = 0; j < z; ++j) { |
| @@ -1343,19 +1215,11 @@ SearchIPLDAP(edui_ldap_t *l) |
| /* bufa + 2 is the address (skip 2 digit port) */ |
| if (!(l->status & LDAP_IPV6_S)) |
| break; /* Not looking for IPv6 */ |
| - for (k = 2; k < z; ++k) { |
| - c = (int) bufa[k]; |
| - if (c < 0) |
| - c = c + 256; |
| - int hlen = snprintf(hexc, sizeof(hexc), "%02X", c); |
| - if (k == 2) |
| - xstrncpy(bufb, hexc, sizeof(bufb)); |
| - else |
| - strncat(bufb, hexc, hlen); |
| - } |
| - y = strlen(bufb); |
| + const int blen = makeHexString(bufb, sizeof(bufb), &bufa[2], z); |
| + if (blen < 0) |
| + return blen; |
| /* Compare value with IP */ |
| - if (memcmp(l->search_ip, bufb, y) == 0) { |
| + if (memcmp(l->search_ip, bufb, blen) == 0) { |
| /* We got a match! - Scan 'ber' for 'cn' values */ |
| z = ldap_count_values_len(ber); |
| for (j = 0; j < z; ++j) { |