diff --git a/src/config.c b/src/config.c index 8c6f0a16..4c481706 100644 --- a/src/config.c +++ b/src/config.c @@ -61,6 +61,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, @@ -325,6 +326,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); @@ -552,6 +562,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 445d89c3..a35cb025 100644 --- a/src/config.h +++ b/src/config.h @@ -108,6 +108,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 325d50eb..21269f11 100644 --- a/src/main.c +++ b/src/main.c @@ -164,6 +164,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" \ @@ -235,6 +237,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 @@ -304,6 +307,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}, @@ -722,8 +726,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; }