diff --git a/src/config.c b/src/config.c index 9c6d3c5d..671d7660 100644 --- a/src/config.c +++ b/src/config.c @@ -62,6 +62,7 @@ const struct vpn_config invalid_cfg = { .use_syslog = -1, .half_internet_routes = -1, .persistent = -1, + .allow_nonroot = -1, #if HAVE_USR_SBIN_PPPD .pppd_log = NULL, .pppd_plugin = NULL, @@ -331,6 +332,15 @@ int load_config(struct vpn_config *cfg, const char *filename) continue; } cfg->persistent = persistent; + } else if (strcmp(key, "allow-nonroot") == 0) { + int allow_nonroot = strtob(val); + + if (allow_nonroot < 0) { + log_warn("Bad allow-nonroot in configuration file: \"%s\".\n", + val); + continue; + } + cfg->allow_nonroot = allow_nonroot; #if HAVE_USR_SBIN_PPPD } else if (strcmp(key, "pppd-use-peerdns") == 0) { int pppd_use_peerdns = strtob(val); @@ -560,6 +570,8 @@ void merge_config(struct vpn_config *dst, struct vpn_config *src) dst->half_internet_routes = src->half_internet_routes; if (src->persistent != invalid_cfg.persistent) dst->persistent = src->persistent; + if (src->allow_nonroot != invalid_cfg.allow_nonroot) + dst->allow_nonroot = src->allow_nonroot; #if HAVE_USR_SBIN_PPPD if (src->pppd_log) { free(dst->pppd_log); diff --git a/src/config.h b/src/config.h index eaf7f825..2f21084a 100644 --- a/src/config.h +++ b/src/config.h @@ -109,6 +109,7 @@ struct vpn_config { int half_internet_routes; unsigned int persistent; + int allow_nonroot; #if HAVE_USR_SBIN_PPPD char *pppd_log; diff --git a/src/main.c b/src/main.c index c1fba334..a5bf1804 100644 --- a/src/main.c +++ b/src/main.c @@ -166,6 +166,8 @@ PPPD_USAGE \ " --seclevel-1 If --cipher-list is not specified, add @SECLEVEL=1 to\n" \ " (compiled in) list of ciphers. This lowers limits on\n" \ " dh key." help_seclevel_1 "\n" \ +" --allow-nonroot Permit running without root privileges.\n" \ +" Requires system/ppp configuration.\n" \ " --persistent= Run the vpn persistently in a loop and try to re-\n" \ " connect every seconds when dropping out.\n" \ " -v Increase verbosity. Can be used multiple times\n" \ @@ -238,6 +240,7 @@ int main(int argc, char *argv[]) .use_syslog = 0, .half_internet_routes = 0, .persistent = 0, + .allow_nonroot = 0, #if HAVE_RESOLVCONF .use_resolvconf = USE_RESOLVCONF, #endif @@ -308,6 +311,7 @@ int main(int argc, char *argv[]) {"cipher-list", required_argument, NULL, 0}, {"min-tls", required_argument, NULL, 0}, {"seclevel-1", no_argument, &cli_cfg.seclevel_1, 1}, + {"allow-nonroot", no_argument, &cli_cfg.allow_nonroot, 1}, #if HAVE_USR_SBIN_PPPD {"pppd-use-peerdns", required_argument, NULL, 0}, {"pppd-no-peerdns", no_argument, &cli_cfg.pppd_use_peerdns, 0}, @@ -732,8 +736,8 @@ int main(int argc, char *argv[]) if (cfg.otp[0] != '\0') log_debug("One-time password = \"%s\"\n", cfg.otp); - if (geteuid() != 0) { - log_error("This process was not spawned with root privileges, which are required.\n"); + if (!cfg.allow_nonroot && (geteuid() != 0)) { + log_error("This process was not spawned with root privileges, which are normally required. If your system is configured, use --allow-nonroot.\n"); ret = EXIT_FAILURE; goto exit; }