backends: fix and refactor nsswitch module support
authorPavel Šimerda <psimerda@redhat.com>
Tue, 7 Oct 2014 15:46:43 +0000 (17:46 +0200)
committerPavel Šimerda <psimerda@redhat.com>
Wed, 8 Oct 2014 18:17:18 +0000 (20:17 +0200)
backends/nss.c
lib/netresolve-backend.h
tests/test-netresolve.sh

index 2ac46eedffb89fd89ad4f7cc4a9d2501dc157b25..b3636226d604494763e3d2f56b071a08bda807a5 100644 (file)
@@ -74,8 +74,8 @@ struct priv_nss {
 static int
 combine_statuses(int s4, int s6)
 {
-       /* NSS_STATUS_TRYAGAIN first, as it means something needs we don't have
-        * the final version of the information.
+       /* NSS_STATUS_TRYAGAIN first, as it means we don't have the final version
+        * of the information.
         */
        if (s4 == NSS_STATUS_TRYAGAIN || s6 == NSS_STATUS_TRYAGAIN)
                return NSS_STATUS_TRYAGAIN;
@@ -167,7 +167,6 @@ start(netresolve_query_t query, char **settings)
        const char *node = netresolve_backend_get_nodename(query);
        int family = netresolve_backend_get_family(query);
        struct priv_nss priv = { 0 };
-       enum nss_status status = NSS_STATUS_UNAVAIL;
 
        initialize(&priv, query, settings);
 
@@ -179,21 +178,23 @@ start(netresolve_query_t query, char **settings)
        /*if (priv->gethostbyname4_r) {
                TODO
        } else*/ if (node && (priv.gethostbyname3_r || priv.gethostbyname2_r)) {
-               char buffer4[SIZE], buffer6[SIZE];
+               char buffer4[SIZE] = { 0 };
+               char buffer6[SIZE] = { 0 };
                int status4 = NSS_STATUS_NOTFOUND, status6 = NSS_STATUS_NOTFOUND;
                struct hostent he4, he6;
                int errnop, h_errnop;
+               int32_t ttl4 = 0;
+               int32_t ttl6 = 0;
+               char *canonname4 = NULL;
+               char *canonname6 = NULL;
 
                if (priv.gethostbyname3_r) {
-                       int32_t ttl;
-                       char *canonname = NULL;
-
                        if (family == AF_INET || family == AF_UNSPEC)
                                status4 = DL_CALL_FCT(priv.gethostbyname3_r, (node, AF_INET,
-                                       &he4, buffer4, sizeof buffer4, &errnop, &h_errnop, &ttl, &canonname));
+                                       &he4, buffer4, sizeof buffer4, &errnop, &h_errnop, &ttl4, &canonname4));
                        if (family == AF_INET6 || family == AF_UNSPEC)
                                status6 = DL_CALL_FCT(priv.gethostbyname3_r, (node, AF_INET6,
-                                       &he6, buffer6, sizeof buffer6, &errnop, &h_errnop, &ttl, &canonname));
+                                       &he6, buffer6, sizeof buffer6, &errnop, &h_errnop, &ttl6, &canonname6));
                } else {
                        if (family == AF_INET || family == AF_UNSPEC)
                                status4 = DL_CALL_FCT(priv.gethostbyname2_r, (node, AF_INET,
@@ -203,30 +204,36 @@ start(netresolve_query_t query, char **settings)
                                        &he6, buffer6, sizeof buffer6, &errnop, &h_errnop));
                }
 
-               status = combine_statuses(status4, status6);
-               if (status == NSS_STATUS_SUCCESS) {
-                       if (status4 == NSS_STATUS_SUCCESS)
-                               netresolve_backend_apply_hostent(query, &he4, 0, 0, 0, 0, 0, 0);
+               if (combine_statuses(status4, status6) == NSS_STATUS_SUCCESS) {
+                       if (status6 == NSS_STATUS_SUCCESS && canonname6)
+                               netresolve_backend_set_canonical_name(query, canonname6);
+                       else if (status4 == NSS_STATUS_SUCCESS && canonname4)
+                               netresolve_backend_set_canonical_name(query, canonname4);
                        if (status6 == NSS_STATUS_SUCCESS)
-                               netresolve_backend_apply_hostent(query, &he6, 0, 0, 0, 0, 0, 0);
-               }
+                               netresolve_backend_apply_hostent(query, &he6, 0, 0, 0, 0, 0, ttl4);
+                       if (status4 == NSS_STATUS_SUCCESS)
+                               netresolve_backend_apply_hostent(query, &he4, 0, 0, 0, 0, 0, ttl6);
+                       netresolve_backend_finished(query);
+               } else
+                       netresolve_backend_failed(query);
        } else if (node && priv.gethostbyname_r) {
                char buffer[SIZE];
                int errnop, h_errnop;
                struct hostent he;
+               enum nss_status status;
 
                status = DL_CALL_FCT(priv.gethostbyname_r, (node,
                        &he, buffer, sizeof buffer, &errnop, &h_errnop));
 
                if (status == NSS_STATUS_SUCCESS) {
                        netresolve_backend_apply_hostent(query, &he, 0, 0, 0, 0, 0, 0);
-               }
+                       netresolve_backend_finished(query);
+               } else
+                       netresolve_backend_failed(query);
+       } else {
+               debug("no suitable backend found\n");
+               netresolve_backend_failed(query);
        }
 
        finalize(&priv);
-
-       if (status == NSS_STATUS_SUCCESS)
-               netresolve_backend_finished(query);
-       else
-               netresolve_backend_failed(query);
 }
index 80f8e496db1af89b397e19183b4ae67bd85c6cc8..16ee34c0718b4425dead514d21c742ff1fee33f6 100644 (file)
@@ -51,6 +51,12 @@ void netresolve_backend_add_path(netresolve_query_t query,
                int priority, int weight, int32_t ttl);
 void netresolve_backend_set_canonical_name(netresolve_query_t query, const char *canonical_name);
 
+/* Convenience output */
+void netresolve_backend_apply_hostent(netresolve_query_t query,
+               const struct hostent *he,
+               int socktype, int protocol, int port,
+               int priority, int weight, int32_t ttl);
+
 /* Tools */
 void *netresolve_backend_new_priv(netresolve_query_t query, size_t size);
 void *netresolve_backend_get_priv(netresolve_query_t query);
@@ -72,10 +78,6 @@ bool netresolve_backend_parse_address(const char *string_orig,
 bool netresolve_backend_parse_path(const char *str,
                Address *address, int *family, int *ifindex,
                int *socktype, int *protocol, int *port);
-void netresolve_backend_apply_hostent(netresolve_query_t query,
-               const struct hostent *he,
-               int socktype, int protocol, int port,
-               int priority, int weight, int32_t ttl);
 
 /* Backend function prototypes */
 void start(netresolve_query_t query, char **settings);
index 7e812b8d8e1d5442c66e4090a2d0b81a71f9d30c..5e039c830b27123eda3b6e625fb63cd555a6286e 100755 (executable)
@@ -18,9 +18,17 @@ $DIFF <($NR --node 1:2:3:4:5:6:7:8) $DATA/numeric6
 $DIFF <($NR --node 1:2:3:4:5:6:7:8%lo) $DATA/numeric6lo
 $DIFF <($NR --node 1:2:3:4:5:6:7:8%999999) $DATA/numeric6nines
 $DIFF <($NR --node 1:2:3:4:5:6:7:8%999999x) $DATA/empty
+# we don't require network connectivity
 #$DIFF <($NR a.root-servers.net) $DATA/dns
 $DIFF <($NR --service http) $DATA/services
 $DIFF <($NR --node /path/to/socket --family unix) $DATA/unix
 $DIFF <($NR --node /path/to/socket --family unix --socktype stream) $DATA/unix-stream
 $DIFF <($NR --node /path/to/socket --family unix --socktype dgram) $DATA/unix-dgram
 $DIFF <($NR --node x-x-x-x-x-x-x-x-x) $DATA/empty
+$DIFF <($NR --backends=nss:files:gethostbyname --node localhost) $DATA/localhost4
+$DIFF <($NR --backends=nss:files:gethostbyname2 --node localhost) $DATA/localhost
+$DIFF <($NR --backends=nss:files:gethostbyname2 --family ip4 --node localhost) $DATA/localhost4
+$DIFF <($NR --backends=nss:files:gethostbyname2 --family ip6 --node localhost) $DATA/localhost6
+$DIFF <($NR --backends=nss:files:gethostbyname3 --node localhost) $DATA/localhost
+$DIFF <($NR --backends=nss:files:gethostbyname3 --family ip4 --node localhost) $DATA/localhost4
+$DIFF <($NR --backends=nss:files:gethostbyname3 --family ip6 --node localhost) $DATA/localhost6
This page took 0.072931 seconds and 5 git commands to generate.