about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2024-07-05 18:15:13 +0200
committerMichael Biebl <biebl@debian.org>2024-07-05 18:15:13 +0200
commit58affb29b8386d6d26359da604a64fefe7ae0a60 (patch)
tree6c0c9b519e431ca178070c89f516dbaa660bbddb /src
parent8e2fde558a5af5c3b03a5112dbd8f9085c5a8369 (diff)
New upstream version 1.48.4 upstream/1.48.4
Diffstat (limited to 'src')
-rw-r--r--src/core/devices/nm-device-utils.c49
-rw-r--r--src/core/settings/nm-agent-manager.c10
-rw-r--r--src/libnmt-newt/nmt-newt-utils.c15
-rw-r--r--src/nm-daemon-helper/nm-daemon-helper.c67
4 files changed, 101 insertions, 40 deletions
diff --git a/src/core/devices/nm-device-utils.c b/src/core/devices/nm-device-utils.c
index 80909805..4597ba85 100644
--- a/src/core/devices/nm-device-utils.c
+++ b/src/core/devices/nm-device-utils.c
@@ -245,14 +245,36 @@ resolve_addr_helper_cb(GObject *source, GAsyncResult *result, gpointer user_data
     resolve_addr_complete(info, g_steal_pointer(&output), g_steal_pointer(&error));
 }
 
+typedef enum {
+    RESOLVE_ADDR_SERVICE_NONE  = 0x0,
+    RESOLVE_ADDR_SERVICE_DNS   = 0x1,
+    RESOLVE_ADDR_SERVICE_FILES = 0x2,
+} ResolveAddrService;
+
 static void
-resolve_addr_spawn_helper(ResolveAddrInfo *info)
+resolve_addr_spawn_helper(ResolveAddrInfo *info, ResolveAddrService services)
 {
-    char addr_str[NM_INET_ADDRSTRLEN];
+    char     addr_str[NM_INET_ADDRSTRLEN];
+    char     str[256];
+    char    *s     = str;
+    gsize    len   = sizeof(str);
+    gboolean comma = FALSE;
+
+    nm_assert(services != RESOLVE_ADDR_SERVICE_NONE);
+    nm_assert((services & ~(RESOLVE_ADDR_SERVICE_DNS | RESOLVE_ADDR_SERVICE_FILES)) == 0);
+
+    if (services & RESOLVE_ADDR_SERVICE_DNS) {
+        nm_strbuf_append(&s, &len, "%sdns", comma ? "," : "");
+        comma = TRUE;
+    }
+    if (services & RESOLVE_ADDR_SERVICE_FILES) {
+        nm_strbuf_append(&s, &len, "%sfiles", comma ? "," : "");
+        comma = TRUE;
+    }
 
     nm_inet_ntop(info->addr_family, &info->address, addr_str);
-    _LOG2D(info, "start lookup via nm-daemon-helper");
-    nm_utils_spawn_helper(NM_MAKE_STRV("resolve-address", addr_str),
+    _LOG2D(info, "start lookup via nm-daemon-helper using services: %s", str);
+    nm_utils_spawn_helper(NM_MAKE_STRV("resolve-address", addr_str, str),
                           g_task_get_cancellable(info->task),
                           resolve_addr_helper_cb,
                           info);
@@ -282,27 +304,28 @@ resolve_addr_resolved_cb(NMDnsSystemdResolved                    *resolved,
         dbus_error = g_dbus_error_get_remote_error(error);
         if (NM_STR_HAS_PREFIX(dbus_error, "org.freedesktop.resolve1.")) {
             /* systemd-resolved is enabled but it couldn't resolve the
-             * address via DNS.  Don't fall back to spawning the helper,
-             * because the helper will possibly ask again to
+             * address via DNS. Spawn again the helper to check if we
+             * can find a result in /etc/hosts. Don't enable the 'dns'
+             * service otherwise the helper will possibly ask again to
              * systemd-resolved (via /etc/resolv.conf), potentially using
              * other protocols than DNS or returning synthetic results.
              *
-             * Consider the error as the final indication that the address
-             * can't be resolved.
-             *
              * See: https://www.freedesktop.org/wiki/Software/systemd/resolved/#commonerrors
              */
-            resolve_addr_complete(info, NULL, g_error_copy(error));
+            resolve_addr_spawn_helper(info, RESOLVE_ADDR_SERVICE_FILES);
             return;
         }
 
-        resolve_addr_spawn_helper(info);
+        /* systemd-resolved couldn't be contacted, use the helper */
+        resolve_addr_spawn_helper(info, RESOLVE_ADDR_SERVICE_DNS | RESOLVE_ADDR_SERVICE_FILES);
         return;
     }
 
     if (names_len == 0) {
         _LOG2D(info, "systemd-resolved returned no result");
-        resolve_addr_complete(info, g_strdup(""), NULL);
+        /* We passed the NO_SYNTHESIZE flag and so systemd-resolved
+         * didn't look into /etc/hosts. Spawn the helper for that. */
+        resolve_addr_spawn_helper(info, RESOLVE_ADDR_SERVICE_FILES);
         return;
     }
 
@@ -366,7 +389,7 @@ nm_device_resolve_address(int                 addr_family,
         return;
     }
 
-    resolve_addr_spawn_helper(info);
+    resolve_addr_spawn_helper(info, RESOLVE_ADDR_SERVICE_DNS | RESOLVE_ADDR_SERVICE_FILES);
 }
 
 char *
diff --git a/src/core/settings/nm-agent-manager.c b/src/core/settings/nm-agent-manager.c
index 0a120649..19b3cfcb 100644
--- a/src/core/settings/nm-agent-manager.c
+++ b/src/core/settings/nm-agent-manager.c
@@ -327,11 +327,17 @@ validate_identifier(const char *identifier, GError **error)
     /* FIXME: do complete validation here */
     while (p && *p) {
         if (!g_ascii_isalnum(*p) && (*p != '_') && (*p != '-') && (*p != '.')) {
+            char invalid_char[5] = {*p};
+
+            if (!g_ascii_isprint(*p)) {
+                g_snprintf(invalid_char, sizeof(invalid_char), "\\x%02x", *p);
+            }
+
             g_set_error(error,
                         NM_AGENT_MANAGER_ERROR,
                         NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER,
-                        "Identifier contains invalid character '%c'",
-                        *p);
+                        "Identifier contains invalid character '%s'",
+                        invalid_char);
             return FALSE;
         }
 
diff --git a/src/libnmt-newt/nmt-newt-utils.c b/src/libnmt-newt/nmt-newt-utils.c
index 8eeee202..36a47b2b 100644
--- a/src/libnmt-newt/nmt-newt-utils.c
+++ b/src/libnmt-newt/nmt-newt-utils.c
@@ -416,9 +416,18 @@ nmt_newt_edit_string(const char *data)
 
     len = data ? strlen(data) : 0;
     while (len) {
-        do
-            nwrote = write(fd, data, len);
-        while (nwrote == -1 && errno == EINTR);
+        nwrote = write(fd, data, len);
+
+        if (nwrote == -1) {
+            if (errno == EINTR) {
+                continue;
+            }
+
+            nmt_newt_message_dialog(_("Could not write to temporary file: %s"),
+                                    nm_strerror_native(errno));
+            nm_close(fd);
+            goto done;
+        }
 
         len -= nwrote;
         data += nwrote;
diff --git a/src/nm-daemon-helper/nm-daemon-helper.c b/src/nm-daemon-helper/nm-daemon-helper.c
index 810ea5fa..32be93a4 100644
--- a/src/nm-daemon-helper/nm-daemon-helper.c
+++ b/src/nm-daemon-helper/nm-daemon-helper.c
@@ -55,26 +55,31 @@ cmd_version(void)
 static int
 cmd_resolve_address(void)
 {
-    nm_auto_free char *address = NULL;
+    nm_auto_free char *address  = NULL;
+    nm_auto_free char *services = NULL;
     union {
         struct sockaddr_in  in;
         struct sockaddr_in6 in6;
     } sockaddr;
     socklen_t sockaddr_size;
     char      name[NI_MAXHOST];
+    char     *saveptr = NULL;
+    char     *service;
+    char     *str;
     int       ret;
 
     address = read_arg();
     if (!address)
         return RETURN_INVALID_ARGS;
 
-    if (more_args())
-        return RETURN_INVALID_ARGS;
+    services = read_arg();
+    if (!services) {
+        /* Called by an old NM version which doesn't support the 'services'
+         * argument. Use both services. */
+        services = strdup("dns,files");
+    }
 
     memset(&sockaddr, 0, sizeof(sockaddr));
-#if defined(__GLIBC__)
-    __nss_configure_lookup("hosts", "dns");
-#endif
 
     if (inet_pton(AF_INET, address, &sockaddr.in.sin_addr) == 1) {
         sockaddr.in.sin_family = AF_INET;
@@ -85,33 +90,51 @@ cmd_resolve_address(void)
     } else
         return RETURN_INVALID_ARGS;
 
-    ret = getnameinfo((struct sockaddr *) &sockaddr,
-                      sockaddr_size,
-                      name,
-                      sizeof(name),
-                      NULL,
-                      0,
-                      NI_NAMEREQD);
-    if (ret != 0) {
-        if (ret == EAI_SYSTEM) {
-            int  errsv = errno;
+    for (str = services; (service = strtok_r(str, ",", &saveptr)); str = NULL) {
+        if (!NM_IN_STRSET(service, "dns", "files")) {
+            fprintf(stderr, "Unsupported resolver service '%s'\n", service);
+            continue;
+        }
+
+#if defined(__GLIBC__)
+        __nss_configure_lookup("hosts", service);
+#endif
+
+        ret = getnameinfo((struct sockaddr *) &sockaddr,
+                          sockaddr_size,
+                          name,
+                          sizeof(name),
+                          NULL,
+                          0,
+                          NI_NAMEREQD);
+
+        if (ret == 0) {
+            printf("%s", name);
+            return RETURN_SUCCESS;
+        } else if (ret == EAI_SYSTEM) {
             char buf[1024];
+            int  errsv = errno;
 
             fprintf(stderr,
-                    "getnameinfo() failed: %d (%s), system error: %d (%s)\n",
+                    "getnameinfo() via service '%s' failed: %d (%s), system error: %d (%s)\n",
+                    service,
                     ret,
                     gai_strerror(ret),
                     errsv,
                     _nm_strerror_r(errsv, buf, sizeof(buf)));
         } else {
-            fprintf(stderr, "getnameinfo() failed: %d (%s)\n", ret, gai_strerror(ret));
+            fprintf(stderr,
+                    "getnameinfo() via service '%s' failed: %d (%s)\n",
+                    service,
+                    ret,
+                    gai_strerror(ret));
         }
-        return RETURN_ERROR;
+#if !defined(__GLIBC__)
+        break;
+#endif
     }
 
-    printf("%s", name);
-
-    return RETURN_SUCCESS;
+    return RETURN_ERROR;
 }
 
 int