From patchwork Sat May 17 08:38:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gert Doering X-Patchwork-Id: 4254 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:a32a:b0:656:592e:a137 with SMTP id jh42csp2032369mab; Sat, 17 May 2025 01:38:53 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVhPQxB2sGe3o7RPgGUPVLs9uHRFdF/16KCIrzRgu1O76FC3P/Nom/r6zuxSyLURlDxlifRukGq7X8=@openvpn.net X-Google-Smtp-Source: AGHT+IGYZnzP0nK+QSmwHYftQvgg4J4LbwvP54O8HQmWV0lsQtSvR2IRrQrgUtBLZZmdNOcl6iTG X-Received: by 2002:a05:6e02:2592:b0:3da:71c7:5c7f with SMTP id e9e14a558f8ab-3db84324607mr73395495ab.15.1747471133358; Sat, 17 May 2025 01:38:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1747471133; cv=none; d=google.com; s=arc-20240605; b=lV8qCaR18URH8PVopTzepQpxjLMPrvEVLU2860rEcyJupibvp10mYo9KifGRVgwm/K 5+BZ9X36quqtIklW0rhuNd2Jp6+6hwDVBNXinft/lwmzEaUhisgLcsOid2lxZiXbpFbH /OaB/hUGiB5wU0R7VGwodnIjjma5A9TlcT02azs+W4cjBMCqVq7DTsbusCd+MruN+Alw tzQf1GPGFZbv6psWpWjHLN26C/PoKlEQJEFuZi7kBRJdNr8FLvlKR4C4yzYWAlif0vu9 WLHTjbRc3roQAlUVGuque6mF/LYrY4nK9AHyWb/QUetuuddVNBKGq3npmEGQWDByJi4e qtIQ== 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=EdpKNGKrD669nZwkSa5mB9dLa5uBUR7zspt+nkKnvtE=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=HdhT+U0WrozVflsCAHRrMkbsxTOgV8QBan98+SIsSDKIAiZcks4emkia/3Ksuob+29 jqn+kUEJJ65P2pCDgm/aK08J2K4fW22mcwlWu+4C/slqXCq6u5b9LSoOLFPbcEL4Z/tY 0nyj/bSUcNZ5fchZghZdUhjaUGlZCsSAZ0tofuLIYqtg6pqmVH+kj3NIgJO96NZ0/Nqq /fjhozmsR4By9TSV2Lk4hGHBVRKQgG00NnCKI5EBMZuCxznJ+g/T1kJQAfdWt3kSNcQU P2MnsW1zMcr4p6bwXaoqEjPZzbAI8sni3h94SgqSRJu48Z0a9fnpUovDrC/5QXyDCPnC JQuQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=TGQT6+bk; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=iI5bX6pf; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b="abd+/Q1t"; 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 8926c6da1cb9f-4fbcc4b39ebsi4129503173.119.2025.05.17.01.38.53 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 17 May 2025 01:38:53 -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=TGQT6+bk; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=iI5bX6pf; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b="abd+/Q1t"; 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=EdpKNGKrD669nZwkSa5mB9dLa5uBUR7zspt+nkKnvtE=; b=TGQT6+bkQltBU1pNk7LbrHgfSp auzvgc2AGsALRg8eQCOlrYXhmRFPnGfyTeeh/kLWdUFkT6FNjQv3WPLz/mKmgW5/CYErGPWuKY6bj IDFY/r/mWuPPfAt2uIOhcnL4ZMZf9jZ0aauj8YyQFe+m4ccY3QLErXEuAmNhff1uFvpc=; Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1uGD4D-00018T-JK; Sat, 17 May 2025 08:38:49 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1uGD4B-00017S-EZ for openvpn-devel@lists.sourceforge.net; Sat, 17 May 2025 08:38:47 +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=7xFXkK+EBX4zGHj8UC6qLH9nX+ADqXoZzuK2z9tWRzg=; b=iI5bX6pfWyyhmQWmkUdgCFtIVM d0jXcBtVmQv/kOovqBXSZta9X3HY6ymW6p3Yf8mVIaLC+3VvfL0dDW11dqar+BVvMnrdBrimMEr9d E1+LicMmMKYY/A4KN/cLQe7+VS6wa6JxnDRsq6UGy8CIa8GpAU077tqMt6NSTi5y9ACI=; 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=7xFXkK+EBX4zGHj8UC6qLH9nX+ADqXoZzuK2z9tWRzg=; b=abd+/Q1tUFlwtipVqMCfTHXv/5 tK6nvRArUay2hOWGKHx1K4ivF0kbY9XZZ9uFoKqGXEQumm0WdX6ZrTxLMiUjuEuHo6EZwYTlzJxGT VTBzy7Uwe24R6CAzAGgWoJA7BibwRlEeniwDUtCvwo4NvFMkAsKtPNw8hkEA9qK4i1qk=; 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 1uGD4A-0005B6-14 for openvpn-devel@lists.sourceforge.net; Sat, 17 May 2025 08:38:47 +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 54H8cYpl028751 for ; Sat, 17 May 2025 10:38:34 +0200 Received: (from gert@localhost) by blue.greenie.muc.de (8.17.1.9/8.17.1.9/Submit) id 54H8cY2C028750 for openvpn-devel@lists.sourceforge.net; Sat, 17 May 2025 10:38:34 +0200 From: Gert Doering To: openvpn-devel@lists.sourceforge.net Date: Sat, 17 May 2025 10:38:27 +0200 Message-ID: <20250517083833.28728-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: 1uGD4A-0005B6-14 Subject: [Openvpn-devel] [PATCH v27] 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?1832356291351512304?= 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 Acked-by: Gert Doering --- 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 27 of this Change. Acked-by according to Gerrit (reflected above): Gert Doering diff --git a/distro/dns-scripts/haikuos_file-dns-updown.sh b/distro/dns-scripts/haikuos_file-dns-updown.sh index 7239b70..777b72d 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 @@ conf=/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; };