From patchwork Wed May 14 13:53:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gert Doering X-Patchwork-Id: 4250 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:a32a:b0:656:592e:a137 with SMTP id jh42csp344629mab; Wed, 14 May 2025 08:04:47 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVdd8Z5i+gB3JNzHt2QfQvaj0QWCmqFkcTPCDzpsX7HwkkhaZPw0ZF+C9lPi6IUi6Danw8JPXmScPU=@openvpn.net X-Google-Smtp-Source: AGHT+IEZrYSyQ3dWRP9MGu7DXteZv/HPX03BfnigGHoDe4bkva93VERxF7P+mCxYnT1cXYEeTRGe X-Received: by 2002:a05:6830:3c8c:b0:727:24c6:87e7 with SMTP id 46e09a7af769-734e154811bmr2082896a34.19.1747235075272; Wed, 14 May 2025 08:04:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1747235075; cv=none; d=google.com; s=arc-20240605; b=FcDGscWVAkyISEj+nX1DHoWapeU2XW30Ny1KeP0a4lbaN9MoZKyeHYP4fgWOWQdRCj DobtS97phOU//pgFsoGW7ICvA4jvvexDPvuqYh1nIaaI8XW3qQbVc2XzzqQtJGEzJfS5 DCYETG4zzF7tJ4505IuVavLd3Z04pDAOn3WYWcRFlHCS1ipmbV0qEbsSrTzwpbOUZdsv RP/I54wMCe7OjiA94aqCLZiBuYJKLST5zIGbsxt6aTj1vcb8uFcialfAc3FmAPAmQDeK znUDQjkSNY/ouFuzD3iQ2Q5FJhogZnPmvOcxGBDNCdq6Gi5iM7nEpostFBXXdOIUIK9m ygBA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:dkim-signature:dkim-signature; bh=PRg80cg9cfUtfXx/CFxXH8YEyC4anOkADYPNhtMsGbE=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=fLOgQK4gBywpxOBoAYxVbl/QG64DJ8m91r1jlAdOwSSWdu6CznenxZL8hBWJg4o9ja qkDhTxTr4CeEiS/Rpcxp2ZH09syZ6akowYqTynrXGZN3i/2dbsRpxpXPYJEmU5UuKQbP K3HNVt6+OB8x5hK28h1x2M8XbzFnBEjzaL5mVuP9gAPGF6TWE7dbEU8kYr9Ew4aBtZJf CdZQobRWUk2QhUVjKMwWVageHlfLA6QyHlOMvu5OJfm9MzDSRo1/sJx7UKhSah9J7Zlo 4sN2+wUIZqHPqfQXpBrDwH1nvXVyQUCOlyf83s4Dq0JpvWCl3e1MlkfJXh8U0yP3DYcB Hybw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=Y5rTxR2v; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=Rw6LxMID; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=Y6HUyG9A; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 46e09a7af769-73226659dd2si6596615a34.214.2025.05.14.08.04.34 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 14 May 2025 08:04:35 -0700 (PDT) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=Y5rTxR2v; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=Rw6LxMID; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=Y6HUyG9A; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Subject:MIME-Version:References:In-Reply-To:Message-ID:Date:To:From:Sender: Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=PRg80cg9cfUtfXx/CFxXH8YEyC4anOkADYPNhtMsGbE=; b=Y5rTxR2vrlr4sy0YMSDt6eIMr5 HmQ0mIv3HPw40WALo6JB9O9r7ApK3m0xOz3vXi5Cy5nWeR8/Px0rH5iEusONv2NqF51C5B3V23cn7 HvU21sVsFjHAsY0cJcrIxypfQFSRsnPFAy6QniZx/oswIAUoMp+MYi7KJjnQpUKDK0u0=; Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1uFDej-0003Sw-ME; Wed, 14 May 2025 15:04:25 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1uFDei-0003Sp-JX for openvpn-devel@lists.sourceforge.net; Wed, 14 May 2025 15:04:24 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=xb1iE8ZKXdoo536p/ELbKHhsoEjLZBm1muBEPwvw2Fc=; b=Rw6LxMIDbztOikccmEljz1vFX7 unNMxypIH9i0isJ24dJw7aKf15wLEkfXeVQCUkXLK3A0sAxuSwRSC4ZRjn4m7kA+ZodbziEsyCjV5 y3dszFlzy4j83VMu82IXW4CDFRQVl8fsn+6LmzxnVGK5PyJTcsuYlclM/llH9UmtwcZQ=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=xb1iE8ZKXdoo536p/ELbKHhsoEjLZBm1muBEPwvw2Fc=; b=Y6HUyG9ACW/7UYc/JQGUukjykZ smj09KVQJ7Xn+lq41RiUeZU+Vnv6pqkIZa9jLpJF1EDycXjNGw09BsnuerCvy3tpkZ03sSTHvBT3+ /RXg+pynywspz1JB8jkOozvgWjMHk749oc1RH2cSjNOCeKK3qKqS9o2D26O0RqU1CYfw=; Received: from [193.149.48.143] (helo=blue.greenie.muc.de) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1uFDeg-0006re-FP for openvpn-devel@lists.sourceforge.net; Wed, 14 May 2025 15:04:24 +0000 Received: from blue.greenie.muc.de (localhost [127.0.0.1]) by blue.greenie.muc.de (8.17.1.9/8.17.1.9) with ESMTP id 54EDslZZ014598 for ; Wed, 14 May 2025 15:54:47 +0200 Received: (from gert@localhost) by blue.greenie.muc.de (8.17.1.9/8.17.1.9/Submit) id 54EDsluf014596 for openvpn-devel@lists.sourceforge.net; Wed, 14 May 2025 15:54:47 +0200 From: Gert Doering To: openvpn-devel@lists.sourceforge.net Date: Wed, 14 May 2025 15:53:43 +0200 Message-ID: <20250514135446.14418-1-gert@greenie.muc.de> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Score: 1.3 (+) X-Spam-Report: Spam detection software, running on the system "6901ab67b84d", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: From: Heiko Hund With --user privileges are dropped after init. Unfortunately this affects --dns-updown when undoing previous modifications. To keep the privileges for just that, the concept of a dns updown runner in introduced. It's basically a fork of openvpn at the time the modifications to DNS are made. Its only capability is running t [...] Content analysis details: (1.3 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 1.3 RDNS_NONE Delivered to internal network by a host with no rDNS X-Headers-End: 1uFDeg-0006re-FP Subject: [Openvpn-devel] [PATCH v26] dns: support running up/down command with privsep X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1832108766530921288?= X-GMAIL-MSGID: =?utf-8?q?1832108766530921288?= From: Heiko Hund With --user privileges are dropped after init. Unfortunately this affects --dns-updown when undoing previous modifications. To keep the privileges for just that, the concept of a dns updown runner in introduced. It's basically a fork of openvpn at the time the modifications to DNS are made. Its only capability is running the --dns-updown command when asked to. The parent openvpn process signals this by writing to a pipe the runner is waiting on. Commands need to be ready to receive variables from a file instead of the process environment. A shameless and effective workaround to keep the protocol between the two processes simple. Change-Id: I6b67e3a00dd84bf348b6af28115ee11138c3a111 Signed-off-by: Heiko Hund --- This change was reviewed on Gerrit and approved by at least one developer. I request to merge it to master. Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/839 This mail reflects revision 26 of this Change. Acked-by according to Gerrit (reflected above): diff --git a/distro/dns-scripts/haikuos_file-dns-updown.sh b/distro/dns-scripts/haikuos_file-dns-updown.sh index 748804e..bc00e10 100644 --- a/distro/dns-scripts/haikuos_file-dns-updown.sh +++ b/distro/dns-scripts/haikuos_file-dns-updown.sh @@ -7,6 +7,10 @@ # # Example env from openvpn (most are not applied): # +# dns_vars_file /tmp/openvpn_dvf_58b95c0c97b2db43afb5d745f986c53c.tmp +# +# or +# # dev tun0 # script_type dns-up # dns_search_domain_1 mycorp.in @@ -39,6 +43,7 @@ onf=/boot/system/settings/network/resolv.conf test -e "$conf" || exit 1 +test -z "${dns_vars_file}" || . "${dns_vars_file}" case "${script_type}" in dns-up) n=1 diff --git a/distro/dns-scripts/openresolv-dns-updown.sh b/distro/dns-scripts/openresolv-dns-updown.sh index e50398c..1404819 100644 --- a/distro/dns-scripts/openresolv-dns-updown.sh +++ b/distro/dns-scripts/openresolv-dns-updown.sh @@ -8,6 +8,10 @@ # # Example env from openvpn (most are not applied): # +# dns_vars_file /tmp/openvpn_dvf_58b95c0c97b2db43afb5d745f986c53c.tmp +# +# or +# # dev tun0 # script_type dns-up # dns_search_domain_1 mycorp.in @@ -38,6 +42,7 @@ done } +[ -z "${dns_vars_file}" ] || . "${dns_vars_file}" : ${script_type:=dns-down} case "${script_type}" in dns-up) diff --git a/distro/dns-scripts/resolvconf_file-dns-updown.sh b/distro/dns-scripts/resolvconf_file-dns-updown.sh index 567b402..70872c7 100644 --- a/distro/dns-scripts/resolvconf_file-dns-updown.sh +++ b/distro/dns-scripts/resolvconf_file-dns-updown.sh @@ -7,6 +7,10 @@ # # Example env from openvpn (most are not applied): # +# dns_vars_file /tmp/openvpn_dvf_58b95c0c97b2db43afb5d745f986c53c.tmp +# +# or +# # dev tun0 # script_type dns-up # dns_search_domain_1 mycorp.in @@ -39,6 +43,7 @@ conf=/etc/resolv.conf test -e "$conf" || exit 1 +test -z "${dns_vars_file}" || . "${dns_vars_file}" case "${script_type}" in dns-up) n=1 diff --git a/distro/dns-scripts/systemd-dns-updown.sh b/distro/dns-scripts/systemd-dns-updown.sh index ecadd29..6eadabc 100644 --- a/distro/dns-scripts/systemd-dns-updown.sh +++ b/distro/dns-scripts/systemd-dns-updown.sh @@ -15,6 +15,10 @@ # # Example env from openvpn (not all are always applied): # +# dns_vars_file /tmp/openvpn_dvf_58b95c0c97b2db43afb5d745f986c53c.tmp +# +# or +# # dev tun0 # script_type dns-up # dns_search_domain_1 mycorp.in @@ -30,6 +34,8 @@ # dns_server_1_sni dns.mycorp.in # +[ -z "${dns_vars_file}" ] || . "${dns_vars_file}" + function do_resolved_servers { local sni="" local transport_var=dns_server_${n}_transport diff --git a/src/openvpn/dns.c b/src/openvpn/dns.c index 4da0747..19de321 100644 --- a/src/openvpn/dns.c +++ b/src/openvpn/dns.c @@ -562,13 +562,20 @@ } static int -do_run_up_down_command(bool up, const struct dns_options *o, const struct tuntap *tt) +do_run_up_down_command(bool up, const char *vars_file, const struct dns_options *o, const struct tuntap *tt) { struct gc_arena gc = gc_new(); struct argv argv = argv_new(); struct env_set *es = env_set_create(&gc); - updown_env_set(up, o, tt, es); + if (vars_file) + { + setenv_str(es, "dns_vars_file", vars_file); + } + else + { + updown_env_set(up, o, tt, es); + } argv_printf(&argv, "%s", o->updown); argv_msg(M_INFO, &argv); @@ -586,8 +593,115 @@ return res; } +static bool +run_updown_runner(bool up, struct options *o, const struct tuntap *tt, struct dns_updown_runner_info *updown_runner) +{ + int dns_pipe_fd[2]; + int ack_pipe_fd[2]; + if (pipe(dns_pipe_fd) != 0 + || pipe(ack_pipe_fd) != 0) + { + msg(M_ERR | M_ERRNO, "run_dns_up_down: unable to create pipes"); + return false; + } + updown_runner->pid = fork(); + if (updown_runner->pid == -1) + { + msg(M_ERR | M_ERRNO, "run_dns_up_down: unable to fork"); + close(dns_pipe_fd[0]); + close(dns_pipe_fd[1]); + close(ack_pipe_fd[0]); + close(ack_pipe_fd[1]); + return false; + } + else if (updown_runner->pid > 0) + { + /* Parent process */ + close(dns_pipe_fd[0]); + close(ack_pipe_fd[1]); + updown_runner->fds[0] = ack_pipe_fd[0]; + updown_runner->fds[1] = dns_pipe_fd[1]; + } + else + { + /* Script runner process, close unused FDs */ + for (int fd = 3; fd < 100; ++fd) + { + if (fd != dns_pipe_fd[0] + && fd != ack_pipe_fd[1]) + { + close(fd); + } + } + + /* Ignore signals */ + signal(SIGINT, SIG_IGN); + signal(SIGHUP, SIG_IGN); + signal(SIGTERM, SIG_IGN); + signal(SIGUSR1, SIG_IGN); + signal(SIGUSR2, SIG_IGN); + signal(SIGPIPE, SIG_IGN); + + while (1) + { + ssize_t rlen, wlen; + char path[PATH_MAX]; + + /* Block here until parent sends a path */ + rlen = read(dns_pipe_fd[0], &path, sizeof(path)); + if (rlen < 1) + { + if (rlen == -1 && errno == EINTR) + { + continue; + } + close(dns_pipe_fd[0]); + close(ack_pipe_fd[1]); + exit(0); + } + + path[sizeof(path) - 1] = '\0'; + int res = do_run_up_down_command(up, path, &o->dns_options, tt); + platform_unlink(path); + + /* Unblock parent process */ + while (1) + { + wlen = write(ack_pipe_fd[1], &res, sizeof(res)); + if ((wlen == -1 && errno != EINTR) || wlen < sizeof(res)) + { + /* Not much we can do about errors but exit */ + close(dns_pipe_fd[0]); + close(ack_pipe_fd[1]); + exit(0); + } + else if (wlen == sizeof(res)) + { + break; + } + } + + up = !up; /* do the opposite next time */ + } + } + + return true; +} + +static const char * +write_dns_vars_file(bool up, const struct options *o, const struct tuntap *tt, struct gc_arena *gc) +{ + struct env_set *es = env_set_create(gc); + const char *dvf = platform_create_temp_file(o->tmp_dir, "dvf", gc); + + updown_env_set(up, &o->dns_options, tt, es); + env_set_write_file(dvf, es); + + return dvf; +} + static void -run_up_down_command(bool up, struct options *o, const struct tuntap *tt) +run_up_down_command(bool up, struct options *o, const struct tuntap *tt, struct dns_updown_runner_info *updown_runner) { if (!o->dns_options.updown) { @@ -595,7 +709,60 @@ } int status; - status = do_run_up_down_command(up, &o->dns_options, tt); + + if (!updown_runner->required) + { + /* Run dns updown directly */ + status = do_run_up_down_command(up, NULL, &o->dns_options, tt); + } + else + { + if (updown_runner->pid < 1) + { + /* Need to set up privilege preserving child first */ + if (!run_updown_runner(up, o, tt, updown_runner)) + { + return; + } + } + + struct gc_arena gc = gc_new(); + int rfd = updown_runner->fds[0]; + int wfd = updown_runner->fds[1]; + const char *dvf = write_dns_vars_file(up, o, tt, &gc); + size_t dvf_size = strlen(dvf) + 1; + + while (1) + { + ssize_t len = write(wfd, dvf, dvf_size); + if (len < dvf_size) + { + if (len == -1 && errno == EINTR) + { + continue; + } + msg(M_ERR | M_ERRNO, "could not send dns vars filename"); + } + break; + } + + while (1) + { + ssize_t len = read(rfd, &status, sizeof(status)); + if (len < sizeof(status)) + { + if (len == -1 && errno == EINTR) + { + continue; + } + msg(M_ERR | M_ERRNO, "could not receive dns updown status"); + } + break; + } + + gc_free(&gc); + } + msg(M_INFO, "dns %s command exited with status %d", up ? "up" : "down", status); } @@ -681,7 +848,7 @@ } void -run_dns_up_down(bool up, struct options *o, const struct tuntap *tt) +run_dns_up_down(bool up, struct options *o, const struct tuntap *tt, struct dns_updown_runner_info *duri) { if (!o->dns_options.servers) { @@ -718,6 +885,6 @@ #ifdef _WIN32 run_up_down_service(up, o, tt); #else - run_up_down_command(up, o, tt); + run_up_down_command(up, o, tt, duri); #endif /* ifdef _WIN32 */ } diff --git a/src/openvpn/dns.h b/src/openvpn/dns.h index c4d19ff..4cc1e73 100644 --- a/src/openvpn/dns.h +++ b/src/openvpn/dns.h @@ -68,6 +68,14 @@ const char *sni; }; +struct dns_updown_runner_info { + bool required; + int fds[2]; +#if !defined(_WIN32) + pid_t pid; +#endif +}; + struct dns_options { struct dns_domain *search_domains; struct dns_server *servers_prepull; @@ -154,8 +162,10 @@ * @param up Boolean to set this call to "up" when true * @param o Pointer to the program options * @param tt Pointer to the connection's tuntap struct + * @param duri Pointer to the updown runner info struct */ -void run_dns_up_down(bool up, struct options *o, const struct tuntap *tt); +void run_dns_up_down(bool up, struct options *o, const struct tuntap *tt, + struct dns_updown_runner_info *duri); /** * Puts the DNS options into an environment set. diff --git a/src/openvpn/env_set.c b/src/openvpn/env_set.c index 81ab59e..3fe23fd 100644 --- a/src/openvpn/env_set.c +++ b/src/openvpn/env_set.c @@ -33,6 +33,7 @@ #include "env_set.h" #include "run_command.h" +#include "platform.h" /* * Set environmental variable (int or string). @@ -235,6 +236,30 @@ } void +env_set_write_file(const char *path, const struct env_set *es) +{ + FILE *fp = platform_fopen(path, "w"); + if (!fp) + { + msg(M_ERR, "could not write env set to '%s'", path); + return; + } + + if (es) + { + const struct env_item *item = es->list; + while (item) + { + fputs(item->string, fp); + fputc('\n', fp); + item = item->next; + } + } + + fclose(fp); +} + +void env_set_inherit(struct env_set *es, const struct env_set *src) { const struct env_item *e; diff --git a/src/openvpn/env_set.h b/src/openvpn/env_set.h index 4294d6e..70d01e2 100644 --- a/src/openvpn/env_set.h +++ b/src/openvpn/env_set.h @@ -91,6 +91,14 @@ void env_set_print(int msglevel, const struct env_set *es); +/** + * Write a struct env_set to a file. Each item on one line. + * + * @param path The filepath to write to. + * @param es Pointer to the env_set to write. + */ +void env_set_write_file(const char *path, const struct env_set *es); + void env_set_inherit(struct env_set *es, const struct env_set *src); /* returns true if environmental variable name starts with 'password' */ diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 187c0a9..e0ba255 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -2027,7 +2027,7 @@ c->c2.frame.tun_mtu, c->c2.es, &c->net_ctx); } - run_dns_up_down(true, &c->options, c->c1.tuntap); + run_dns_up_down(true, &c->options, c->c1.tuntap, &c->persist.duri); /* run the up script */ run_up_down(c->options.up_script, @@ -2067,7 +2067,7 @@ /* explicitly set the ifconfig_* env vars */ do_ifconfig_setenv(c->c1.tuntap, c->c2.es); - run_dns_up_down(true, &c->options, c->c1.tuntap); + run_dns_up_down(true, &c->options, c->c1.tuntap, &c->persist.duri); /* run the up script if user specified --up-restart */ if (c->options.up_restart) @@ -2157,7 +2157,7 @@ adapter_index = c->c1.tuntap->adapter_index; #endif - run_dns_up_down(false, &c->options, c->c1.tuntap); + run_dns_up_down(false, &c->options, c->c1.tuntap, &c->persist.duri); if (force || !(c->sig->signal_received == SIGUSR1 && c->options.persist_tun)) { @@ -3971,6 +3971,9 @@ c0->uid_gid_specified = user_defined || group_defined; + /* fork the dns script runner to preserve root? */ + c->persist.duri.required = user_defined; + /* perform postponed chdir if --daemon */ if (c->did_we_daemonize && c->options.cd_dir == NULL) { diff --git a/src/openvpn/openvpn.h b/src/openvpn/openvpn.h index 0bbd1a4..1023520 100644 --- a/src/openvpn/openvpn.h +++ b/src/openvpn/openvpn.h @@ -45,6 +45,7 @@ #include "pool.h" #include "plugin.h" #include "manage.h" +#include "dns.h" /* * Our global key schedules, packaged thusly @@ -120,6 +121,7 @@ struct context_persist { int restart_sleep_seconds; + struct dns_updown_runner_info duri; };