]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/nss-resolve/nss-resolve.c
Merge pull request #31524 from poettering/secure-getenv-naming-fix
[thirdparty/systemd.git] / src / nss-resolve / nss-resolve.c
index e857d42db68186d43917325c3859625a5243bff2..3cefb6394c8336419e6aa843aba3bb85dc86ce47 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "env-util.h"
 #include "errno-util.h"
+#include "glyph-util.h"
 #include "in-addr-util.h"
 #include "macro.h"
 #include "nss-util.h"
@@ -19,7 +20,7 @@
 #include "strv.h"
 #include "varlink.h"
 
-static JsonDispatchFlags json_dispatch_flags = 0;
+static JsonDispatchFlags json_dispatch_flags = JSON_ALLOW_EXTENSIONS;
 
 static void setup_logging(void) {
         log_parse_environment_variables();
@@ -94,11 +95,10 @@ static uint32_t ifindex_to_scopeid(int family, const void *a, int ifindex) {
 }
 
 static int json_dispatch_ifindex(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
-        int *ifi = userdata;
+        int *ifi = ASSERT_PTR(userdata);
         int64_t t;
 
         assert(variant);
-        assert(ifi);
 
         if (!json_variant_is_integer(variant))
                 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an integer.", strna(name));
@@ -112,11 +112,10 @@ static int json_dispatch_ifindex(const char *name, JsonVariant *variant, JsonDis
 }
 
 static int json_dispatch_family(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
-        int *family = userdata;
+        int *family = ASSERT_PTR(userdata);
         int64_t t;
 
         assert(variant);
-        assert(family);
 
         if (!json_variant_is_integer(variant))
                 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an integer.", strna(name));
@@ -143,9 +142,9 @@ static void resolve_hostname_reply_destroy(ResolveHostnameReply *p) {
 }
 
 static const JsonDispatch resolve_hostname_reply_dispatch_table[] = {
-        { "addresses", JSON_VARIANT_ARRAY,    json_dispatch_variant, offsetof(ResolveHostnameReply, addresses), JSON_MANDATORY },
-        { "name",      JSON_VARIANT_STRING,   json_dispatch_string,  offsetof(ResolveHostnameReply, name),      0              },
-        { "flags",     JSON_VARIANT_UNSIGNED, json_dispatch_uint64,  offsetof(ResolveHostnameReply, flags),     0              },
+        { "addresses", JSON_VARIANT_ARRAY,         json_dispatch_variant, offsetof(ResolveHostnameReply, addresses), JSON_MANDATORY },
+        { "name",      JSON_VARIANT_STRING,        json_dispatch_string,  offsetof(ResolveHostnameReply, name),      0              },
+        { "flags",     _JSON_VARIANT_TYPE_INVALID, json_dispatch_uint64,  offsetof(ResolveHostnameReply, flags),     0              },
         {}
 };
 
@@ -157,13 +156,12 @@ typedef struct AddressParameters {
 } AddressParameters;
 
 static int json_dispatch_address(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
-        AddressParameters *p = userdata;
+        AddressParameters *p = ASSERT_PTR(userdata);
         union in_addr_union buf = {};
         JsonVariant *i;
         size_t n, k = 0;
 
         assert(variant);
-        assert(p);
 
         if (!json_variant_is_array(variant))
                 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an array.", strna(name));
@@ -180,7 +178,9 @@ static int json_dispatch_address(const char *name, JsonVariant *variant, JsonDis
 
                 b = json_variant_integer(i);
                 if (b < 0 || b > 0xff)
-                        return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "Element %zu of JSON field '%s' is out of range 0…255.", k, strna(name));
+                        return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL),
+                                        "Element %zu of JSON field '%s' is out of range 0%s255.",
+                                        k, strna(name), special_glyph(SPECIAL_GLYPH_ELLIPSIS));
 
                 buf.bytes[k++] = (uint8_t) b;
         }
@@ -202,9 +202,10 @@ static uint64_t query_flag(
                 const char *name,
                 const int value,
                 uint64_t flag) {
+
         int r;
 
-        r = getenv_bool_secure(name);
+        r = secure_getenv_bool(name);
         if (r >= 0)
                 return r == value ? flag : 0;
         if (r != -ENXIO)
@@ -261,7 +262,7 @@ enum nss_status _nss_resolve_gethostbyname4_r(
          * configuration can distinguish such executed but negative replies from complete failure to
          * talk to resolved). */
         const char *error_id;
-        r = varlink_call(link, "io.systemd.Resolve.ResolveHostname", cparams, &rparams, &error_id, NULL);
+        r = varlink_call(link, "io.systemd.Resolve.ResolveHostname", cparams, &rparams, &error_id);
         if (r < 0)
                 goto fail;
         if (!isempty(error_id)) {
@@ -269,10 +270,12 @@ enum nss_status _nss_resolve_gethostbyname4_r(
                         goto try_again;
                 if (error_shall_fallback(error_id))
                         goto fail;
+                if (streq(error_id, "io.systemd.Resolve.NoSuchResourceRecord"))
+                        goto no_data;
                 goto not_found;
         }
 
-        r = json_dispatch(rparams, resolve_hostname_reply_dispatch_table, NULL, json_dispatch_flags, &p);
+        r = json_dispatch(rparams, resolve_hostname_reply_dispatch_table, json_dispatch_flags, &p);
         if (r < 0)
                 goto fail;
         if (json_variant_is_blank_object(p.addresses))
@@ -282,7 +285,7 @@ enum nss_status _nss_resolve_gethostbyname4_r(
         JSON_VARIANT_ARRAY_FOREACH(entry, p.addresses) {
                 AddressParameters q = {};
 
-                r = json_dispatch(entry, address_parameters_dispatch_table, NULL, json_dispatch_flags, &q);
+                r = json_dispatch(entry, address_parameters_dispatch_table, json_dispatch_flags, &q);
                 if (r < 0)
                         goto fail;
 
@@ -320,7 +323,7 @@ enum nss_status _nss_resolve_gethostbyname4_r(
         JSON_VARIANT_ARRAY_FOREACH(entry, p.addresses) {
                 AddressParameters q = {};
 
-                r = json_dispatch(entry, address_parameters_dispatch_table, NULL, json_dispatch_flags, &q);
+                r = json_dispatch(entry, address_parameters_dispatch_table, json_dispatch_flags, &q);
                 if (r < 0)
                         goto fail;
 
@@ -367,6 +370,10 @@ not_found:
         *h_errnop = HOST_NOT_FOUND;
         return NSS_STATUS_NOTFOUND;
 
+no_data:
+        *h_errnop = NO_DATA;
+        return NSS_STATUS_NOTFOUND;
+
 try_again:
         UNPROTECT_ERRNO;
         *errnop = -r;
@@ -417,7 +424,7 @@ enum nss_status _nss_resolve_gethostbyname3_r(
                 goto fail;
 
         const char *error_id;
-        r = varlink_call(link, "io.systemd.Resolve.ResolveHostname", cparams, &rparams, &error_id, NULL);
+        r = varlink_call(link, "io.systemd.Resolve.ResolveHostname", cparams, &rparams, &error_id);
         if (r < 0)
                 goto fail;
         if (!isempty(error_id)) {
@@ -425,10 +432,12 @@ enum nss_status _nss_resolve_gethostbyname3_r(
                         goto try_again;
                 if (error_shall_fallback(error_id))
                         goto fail;
+                if (streq(error_id, "io.systemd.Resolve.NoSuchResourceRecord"))
+                        goto no_data;
                 goto not_found;
         }
 
-        r = json_dispatch(rparams, resolve_hostname_reply_dispatch_table, NULL, json_dispatch_flags, &p);
+        r = json_dispatch(rparams, resolve_hostname_reply_dispatch_table, json_dispatch_flags, &p);
         if (r < 0)
                 goto fail;
         if (json_variant_is_blank_object(p.addresses))
@@ -438,7 +447,7 @@ enum nss_status _nss_resolve_gethostbyname3_r(
         JSON_VARIANT_ARRAY_FOREACH(entry, p.addresses) {
                 AddressParameters q = {};
 
-                r = json_dispatch(entry, address_parameters_dispatch_table, NULL, json_dispatch_flags, &q);
+                r = json_dispatch(entry, address_parameters_dispatch_table, json_dispatch_flags, &q);
                 if (r < 0)
                         goto fail;
 
@@ -484,7 +493,7 @@ enum nss_status _nss_resolve_gethostbyname3_r(
         JSON_VARIANT_ARRAY_FOREACH(entry, p.addresses) {
                 AddressParameters q = {};
 
-                r = json_dispatch(entry, address_parameters_dispatch_table, NULL, json_dispatch_flags, &q);
+                r = json_dispatch(entry, address_parameters_dispatch_table, json_dispatch_flags, &q);
                 if (r < 0)
                         goto fail;
 
@@ -542,6 +551,10 @@ not_found:
         *h_errnop = HOST_NOT_FOUND;
         return NSS_STATUS_NOTFOUND;
 
+no_data:
+        *h_errnop = NO_DATA;
+        return NSS_STATUS_NOTFOUND;
+
 try_again:
         UNPROTECT_ERRNO;
         *errnop = -r;
@@ -561,8 +574,8 @@ static void resolve_address_reply_destroy(ResolveAddressReply *p) {
 }
 
 static const JsonDispatch resolve_address_reply_dispatch_table[] = {
-        { "names", JSON_VARIANT_ARRAY,    json_dispatch_variant, offsetof(ResolveAddressReply, names), JSON_MANDATORY },
-        { "flags", JSON_VARIANT_UNSIGNED, json_dispatch_uint64,  offsetof(ResolveAddressReply, flags), 0              },
+        { "names", JSON_VARIANT_ARRAY,         json_dispatch_variant, offsetof(ResolveAddressReply, names), JSON_MANDATORY },
+        { "flags", _JSON_VARIANT_TYPE_INVALID, json_dispatch_uint64,  offsetof(ResolveAddressReply, flags), 0              },
         {}
 };
 
@@ -629,7 +642,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
                 goto fail;
 
         const char* error_id;
-        r = varlink_call(link, "io.systemd.Resolve.ResolveAddress", cparams, &rparams, &error_id, NULL);
+        r = varlink_call(link, "io.systemd.Resolve.ResolveAddress", cparams, &rparams, &error_id);
         if (r < 0)
                 goto fail;
         if (!isempty(error_id)) {
@@ -640,7 +653,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
                 goto not_found;
         }
 
-        r = json_dispatch(rparams, resolve_address_reply_dispatch_table, NULL, json_dispatch_flags, &p);
+        r = json_dispatch(rparams, resolve_address_reply_dispatch_table, json_dispatch_flags, &p);
         if (r < 0)
                 goto fail;
         if (json_variant_is_blank_object(p.names))
@@ -651,7 +664,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
         JSON_VARIANT_ARRAY_FOREACH(entry, p.names) {
                 _cleanup_(name_parameters_destroy) NameParameters q = {};
 
-                r = json_dispatch(entry, name_parameters_dispatch_table, NULL, json_dispatch_flags, &q);
+                r = json_dispatch(entry, name_parameters_dispatch_table, json_dispatch_flags, &q);
                 if (r < 0)
                         goto fail;
 
@@ -692,7 +705,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
         JSON_VARIANT_ARRAY_FOREACH(entry, p.names) {
                 _cleanup_(name_parameters_destroy) NameParameters q = {};
 
-                r = json_dispatch(entry, name_parameters_dispatch_table, NULL, json_dispatch_flags, &q);
+                r = json_dispatch(entry, name_parameters_dispatch_table, json_dispatch_flags, &q);
                 if (r < 0)
                         goto fail;