Switch to libunbound as the resolver, primarily to get DNSSEC support.
[itkacl] / itkacl-2.1 / itkacl.c
index c50654ce2a97b39575c17e954d49db244848a8b5..f1cc09a8639d4c13a7b798051f8acc55e2806bfb 100644 (file)
@@ -11,7 +11,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <ctype.h>
-#include <netdb.h>
+#include <unbound.h>
 
 struct itkacl_config {
        char nszone[256];
@@ -94,11 +94,12 @@ int itkacl_check(const char * const realm, const char * const user,
                 char *errmsg, size_t errmsg_size)
 {
        struct itkacl_config config;
-       struct hostent he, *he_ptr;
-       int ret, host_errno;
+       int ret, nxdomain;
        const char *ptr;
        char nszone[256];
-       char temp[256], ns_temp[1024];
+       char temp[256];
+       struct ub_ctx* ctx;
+       struct ub_result* result;
 
        if (itkacl_read_config(CONFIG_FILENAME, &config, errmsg, errmsg_size) != 0) {
                return -1;
@@ -173,34 +174,53 @@ int itkacl_check(const char * const realm, const char * const user,
        strcpy(temp, nszone);
        sprintf(nszone, "%s.%s", user, temp);
 
-       ret = gethostbyname_r(nszone, &he, ns_temp, 1024, &he_ptr, &host_errno);
+       /* Create the DNS resolver context. */
+       ctx = ub_ctx_create();
+       if (ctx == NULL) {
+               if (errmsg)
+                       snprintf(errmsg, errmsg_size, "Host name lookup failure: Could not create DNS context");
+               return -1;
+       }
 
-       /*
-        * The man page for gethostbyname_r() specifies ret != 0 on failure, but
-        * that seemingly does not include HOST_NOT_FOUND failure.
-        */
-       if (he_ptr == NULL) {
-               // Not found => no access, but no error either.
-               if (host_errno == HOST_NOT_FOUND) {
-                       return 1;
-               }
+       ret = ub_ctx_resolvconf(ctx, "/etc/resolv.conf");
+       if (ret != 0) {
+               if (errmsg)
+                       snprintf(errmsg, errmsg_size,
+                                "Host name lookup failure: Could not read /etc/resolv.conf "
+                                "(resolver error: %s) (system error: %s)",
+                                ub_strerror(ret), strerror(errno));
+               ub_ctx_delete(ctx);
+               return -1;
+       }
 
-               switch (host_errno) {
-               case TRY_AGAIN:
-                       snprintf(errmsg, errmsg_size, "Host name lookup failure");
-                       break;
-               case NO_RECOVERY:
-                       snprintf(errmsg, errmsg_size, "Unknown server error");
-                       break;
-               case NO_ADDRESS:
-                       snprintf(errmsg, errmsg_size, "No address associated with name");
-                       break;
-               default:
-                       snprintf(errmsg, errmsg_size, "Unknown DNS error %d", host_errno);
-               }
+       ret = ub_ctx_hosts(ctx, "/etc/hosts");
+       if (ret != 0) {
+               if (errmsg)
+                       snprintf(errmsg, errmsg_size,
+                                "Host name lookup failure: Could not read /etc/hosts "
+                                "(resolver error: %s) (system error: %s)",
+                                ub_strerror(ret), strerror(errno));
+               ub_ctx_delete(ctx);
                return -1;
        }
 
-       // The lookup succeeded, so we're good.
-       return 0;
+       /* Do the actual DNS lookup (TYPE A, CLASS IN). */
+       ret = ub_resolve(ctx, nszone, 1, 1, &result);
+       if (ret != 0) {
+               if (errmsg)
+                       snprintf(errmsg, errmsg_size, "Host name lookup failure: %s",
+                                ub_strerror(ret));
+               ub_ctx_delete(ctx);
+               return -1;
+       }
+
+       nxdomain = result->nxdomain;
+
+       ub_resolve_free(result);
+       ub_ctx_delete(ctx);
+
+       if (nxdomain)
+               return 1;
+       else
+               return 0;
 }