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;

Reply via email to