diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/devices/nm-device-utils.c | 49 | ||||
| -rw-r--r-- | src/core/settings/nm-agent-manager.c | 10 | ||||
| -rw-r--r-- | src/libnmt-newt/nmt-newt-utils.c | 15 | ||||
| -rw-r--r-- | src/nm-daemon-helper/nm-daemon-helper.c | 67 |
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 |