spotted while reading Philipp' ldaps diff. it's really ugly to reach
into the struct sockaddrs when using getaddrinfo()...
however, I don't use ldap so this could use at least some testing :)
(would also be interesting to provide some more logging if socket/connect
fails somehow, and also aldap_parse_url could use some simplifying.
don't want to fall too much into this rabbit hole though)
diff /home/op/w/opensmtpd-extras
commit - 5715b1ff87eafd465592df5c2cf4b2f171e60bbc
path + /home/op/w/opensmtpd-extras
blob - 090cfb467a79c71c8d28ad9f75e6a0faf859cdd8
file + extras/tables/table-ldap/table_ldap.c
--- extras/tables/table-ldap/table_ldap.c
+++ extras/tables/table-ldap/table_ldap.c
@@ -85,8 +85,8 @@ ldap_connect(const char *addr)
{
struct aldap_url lu;
struct addrinfo hints, *res0, *res;
- char *buf;
- int error, fd = -1;
+ char *buf, port[32];
+ int error, r, fd = -1;
if ((buf = strdup(addr)) == NULL)
return NULL;
@@ -98,37 +98,32 @@ ldap_connect(const char *addr)
return NULL;
}
+ r = snprintf(port, sizeof(port), "%d", lu.port);
+ if (r < 0 || (size_t)r >= sizeof(port)) {
+ log_warnx("snprintf");
+ return NULL;
+ }
+
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM; /* DUMMY */
- error = getaddrinfo(lu.host, NULL, &hints, &res0);
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_NUMERICSERV;
+ error = getaddrinfo(lu.host, port, &hints, &res0);
if (error == EAI_AGAIN || error == EAI_NODATA || error == EAI_NONAME)
return NULL;
if (error) {
- log_warnx("warn: could not parse \"%s\": %s", lu.host,
- gai_strerror(error));
+ log_warnx("warn: could not parse \"%s:%s\": %s", lu.host,
+ port, gai_strerror(error));
return NULL;
}
for (res = res0; res; res = res->ai_next) {
- if (res->ai_family != AF_INET && res->ai_family != AF_INET6)
- continue;
-
fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (fd == -1)
continue;
- if (res->ai_family == AF_INET) {
- struct sockaddr_in sin4 = *(struct sockaddr_in
*)res->ai_addr;
- sin4.sin_port = htons(lu.port);
- if (connect(fd, (struct sockaddr *)&sin4,
res->ai_addrlen) == 0)
- return aldap_init(fd);
- } else if (res->ai_family == AF_INET6) {
- struct sockaddr_in6 sin6 = *(struct sockaddr_in6
*)res->ai_addr;
- sin6.sin6_port = htons(lu.port);
- if (connect(fd, (struct sockaddr *)&sin6,
res->ai_addrlen) == 0)
- return aldap_init(fd);
- }
+ if (connect(fd, res->ai_addr, res->ai_addrlen) == 0)
+ return aldap_init(fd);
close(fd);
fd = -1;