From 56f73937adfbb3dfd7f69a6b08427d59e3be0e19 Mon Sep 17 00:00:00 2001 From: Jakub Jirutka Date: Tue, 14 Jun 2022 15:21:47 +0200 Subject: [PATCH] resolver: Add path to resolv.conf to config options --- doc/connman.conf.5.in | 8 ++++++++ src/main.c | 16 ++++++++++++++++ src/resolver.c | 33 ++++++++++++++++++++++++++------- 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/doc/connman.conf.5.in b/doc/connman.conf.5.in index 82cceb72..16158f94 100644 --- a/doc/connman.conf.5.in +++ b/doc/connman.conf.5.in @@ -205,6 +205,14 @@ address will be chosen instead (according to RFC3927). If an address conflict occurs for an address offered via DHCP, ConnMan send a DHCP DECLINE once and for the second conflict resort to finding an IPv4LL address. Default value is false. +.TP +.BI ResolvConf= string +Path to resolv.conf file. If the file does not exist, but intermediate +directories exist, it will be created. +If this option is not set, it tries to write into +@runstatedir@/connman/resolv.conf and fallbacks to @sysconfdir@/resolv.conf if +it fails (@runstatedir@/connman does not exist or is not writeable). +If you do not want to update resolv.conf, you can set /dev/null. .SH "EXAMPLE" The following example configuration disables hostname updates and enables ethernet tethering. diff --git a/src/main.c b/src/main.c index e209cf26..57d3d0d5 100644 --- a/src/main.c +++ b/src/main.c @@ -107,6 +107,7 @@ static struct { bool auto_connect_roaming_services; bool acd; bool use_gateways_as_timeservers; + char *resolv_conf; } connman_settings = { .bg_scan = true, .pref_timeservers = NULL, @@ -134,6 +135,7 @@ static struct { .auto_connect_roaming_services = false, .acd = false, .use_gateways_as_timeservers = false, + .resolv_conf = NULL, }; #define CONF_BG_SCAN "BackgroundScanning" @@ -162,6 +164,7 @@ static struct { #define CONF_AUTO_CONNECT_ROAMING_SERVICES "AutoConnectRoamingServices" #define CONF_ACD "AddressConflictDetection" #define CONF_USE_GATEWAYS_AS_TIMESERVERS "UseGatewaysAsTimeservers" +#define CONF_RESOLV_CONF "ResolvConf" static const char *supported_options[] = { CONF_BG_SCAN, @@ -190,6 +193,7 @@ static const char *supported_options[] = { CONF_AUTO_CONNECT_ROAMING_SERVICES, CONF_ACD, CONF_USE_GATEWAYS_AS_TIMESERVERS, + CONF_RESOLV_CONF, NULL }; @@ -565,6 +569,15 @@ static void parse_config(GKeyFile *config) connman_settings.use_gateways_as_timeservers = boolean; g_clear_error(&error); + + string = __connman_config_get_string(config, "General", + CONF_RESOLV_CONF, &error); + if (!error) + connman_settings.resolv_conf = string; + else + g_free(string); + + g_clear_error(&error); } static int config_init(const char *file) @@ -793,6 +806,9 @@ bool connman_setting_get_bool(const char *key) if (g_str_equal(key, CONF_USE_GATEWAYS_AS_TIMESERVERS)) return connman_settings.use_gateways_as_timeservers; + if (g_str_equal(key, CONF_RESOLV_CONF)) + return connman_settings.resolv_conf; + return false; } diff --git a/src/resolver.c b/src/resolver.c index 618353fd..4ab51d6b 100644 --- a/src/resolver.c +++ b/src/resolver.c @@ -103,6 +103,7 @@ static int resolvfile_export(void) int fd, err; unsigned int count; mode_t old_umask; + const char *resolv_conf; content = g_string_new("# Generated by Connection Manager\n"); @@ -161,15 +162,33 @@ static int resolvfile_export(void) old_umask = umask(022); - fd = open(RESOLV_CONF_STATEDIR, O_RDWR | O_CREAT | O_CLOEXEC, - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (fd < 0) { - connman_warn_once("Cannot create "RESOLV_CONF_STATEDIR" " - "falling back to "RESOLV_CONF_ETC); + resolv_conf = connman_setting_get_string("ResolvConf"); + /* + * TODO: This is mainly for backward compatibility. In some future version, + * "ResolvConf" setting should default to RESOLV_CONF_STATEDIR or + * RESOLV_CONF_ETC and this branch can be removed. + */ + if (resolv_conf == NULL) { + fd = open(RESOLV_CONF_STATEDIR, O_RDWR | O_CREAT | O_CLOEXEC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (fd < 0) { + connman_warn_once("Cannot create "RESOLV_CONF_STATEDIR" " + "falling back to "RESOLV_CONF_ETC); - fd = open(RESOLV_CONF_ETC, O_RDWR | O_CREAT | O_CLOEXEC, - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + fd = open(RESOLV_CONF_ETC, O_RDWR | O_CREAT | O_CLOEXEC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (fd < 0) { + err = -errno; + goto done; + } + } + } else if (resolv_conf[0] == '\0' || strcmp(resolv_conf, "/dev/null") == 0) { + err = 0; + goto done; + } else { + fd = open(resolv_conf, O_RDWR | O_CREAT | O_CLOEXEC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd < 0) { err = -errno; goto done; -- 2.16.4