Message ID | 20220514103717.235-1-timo@rothenpieler.org |
---|---|
State | Accepted |
Delegated to: | Antonio Quartulli |
Headers | show |
Series | [Openvpn-devel,v5] platform: Retain CAP_NET_ADMIN when dropping privileges | expand |
On 14/05/2022 12:37, Timo Rothenpieler wrote: > On Linux, when dropping privileges, interaction with > the network configuration, such as tearing down routes > or ovpn-dco interfaces will fail when --user/--group are > used. > > This patch sets the CAP_NET_ADMIN capability, which grants > the needed privileges during the lifetime of the OpenVPN > process when dropping root privileges. > > Signed-off-by: Timo Rothenpieler <timo@rothenpieler.org> > Reviewed-By: David Sommerseth <davids@openvpn.net> With Linux DCO now fully merged, this patch is ready to land. It still applies cleanly for all I can tell.
On Sat, May 14, 2022 at 12:37:17PM +0200, Timo Rothenpieler wrote: > On Linux, when dropping privileges, interaction with > the network configuration, such as tearing down routes > or ovpn-dco interfaces will fail when --user/--group are > used. > > This patch sets the CAP_NET_ADMIN capability, which grants > the needed privileges during the lifetime of the OpenVPN > process when dropping root privileges. > > Signed-off-by: Timo Rothenpieler <timo@rothenpieler.org> > Reviewed-By: David Sommerseth <davids@openvpn.net> > --- > configure.ac | 19 +++ > distro/systemd/openvpn-client@.service.in | 2 +- > distro/systemd/openvpn-server@.service.in | 2 +- > src/openvpn/init.c | 5 +- > src/openvpn/platform.c | 146 +++++++++++++++++++++- > src/openvpn/platform.h | 10 +- > 6 files changed, 175 insertions(+), 9 deletions(-) I ran several t_client test runs with --user nobody on a DCO-enabled system. Without the patch: - errors on teardown in all tests (sitnl) - test 11 fails (which actually uses DCO, since no comp) With the patch: - errors on teardown gone - test 11 passes With the patch and --disable-dco --enable-iproute2: - no cap retained - errors on teardown (ip) Looks to me like it does what it is supposed to do. Acked-By: Frank Lichtenheld <frank@lichtenheld.com> That said, maybe we should add some hint about this behavior to the actual documentation? Maybe to --user documentation? Or at least Changes? Regards,
I have not tested this myself, but if I had, the test setup would have been very similar to what Frank did (so, big thanks) - run a DCO environment with "owner nobody", and see if things still work. I will add this to my DCO server test environment - run one of the iroute-using instances with "nobody", so it is continuously tested. I did have a stare-at-code a few weeks ago, and we did discuss this a few months ago, and the approach chosen seems to make sense. Uncrustify complained about two lines with tabs -> fixed. Your patch has been applied to the master branch. commit 2e359a088226ab1e5ee41fbab27d38d8a8d192ac Author: Timo Rothenpieler Date: Sat May 14 12:37:17 2022 +0200 platform: Retain CAP_NET_ADMIN when dropping privileges Signed-off-by: Timo Rothenpieler <timo@rothenpieler.org> Acked-by: Frank Lichtenheld <frank@lichtenheld.com> Message-Id: <20220514103717.235-1-timo@rothenpieler.org> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg24360.html Signed-off-by: Gert Doering <gert@greenie.muc.de> -- kind regards, Gert Doering
Hi,
On Thu, Aug 11, 2022 at 12:03:45PM +0200, Gert Doering wrote:
> Uncrustify complained about two lines with tabs -> fixed.
Turns out that it's actually 4 lines, and while I did "git apply $patch",
I forgot the "git commit --amend platform.c", so the whitespace errors
landed in the commit, and the *fix* was still sitting in my tree.
Since this is just whitespace, I'll merge the patch as follows,
into
commit 649874df9edb52a9d85bf9db690b6150fdb6dcc9 (HEAD -> master)
Author: Gert Doering <gert@greenie.muc.de>
Date: Thu Aug 11 13:26:58 2022 +0200
Apply uncrustify changes that forgotten in the last patch.
gert
HI, On Thu, Aug 11, 2022 at 12:03:45PM +0200, Gert Doering wrote: > I have not tested this myself, but if I had, the test setup would have > been very similar to what Frank did (so, big thanks) - run a DCO > environment with "owner nobody", and see if things still work. > > I will add this to my DCO server test environment - run one of the > iroute-using instances with "nobody", so it is continuously tested. [..] > commit 2e359a088226ab1e5ee41fbab27d38d8a8d192ac > Author: Timo Rothenpieler > Date: Sat May 14 12:37:17 2022 +0200 > > platform: Retain CAP_NET_ADMIN when dropping privileges Unfortunately, it seems that our approach to "if SITNL is used, we hard require that setting CAP_NET_ADMIN succeeds" is too strong for the twisted ways that people use openvpn. Namely, network-manager... https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1017379 ... runs openvpn with --ifconfig-noexec / --route-noexec, and insists on doing all that itself. I do not like NM's way of trying to control everything (up to the point that it defaults to redirecting a default route to OpenVPN even if config and server do not want that), but this is what Linux people seem to be stuck with, so we need to handle it. So I think we need to amend this patch twofold - if --ifconfig-noexec && --route-noexec are set, do not mandate success on CAP_NET_ADMIN (users might want it for using it in --up scripts, but if it fails, *openvpn* is not missing functionality) --> this should take care of the NM case - also, we might want to think long and hard about mandating it if --client (that is, --pull) is in use. We postpone dropping of privileges until after the initial ifconfig/route setup has been done, and on program end, closing tun/dco interface will (I hope) make the interface go away without needing privileges, and the system will remove the routes together with it. --redirect-gateway will break, --redirect-gateway def1 will not. Overlapping vpn routes with vpn gateway (= install a host route) will also be unable to clean up at program end. But this is no worse than 2.5.x with --user nobody. gert
On 15/08/2022 11:54, Gert Doering wrote: > HI, > > On Thu, Aug 11, 2022 at 12:03:45PM +0200, Gert Doering wrote: >> I have not tested this myself, but if I had, the test setup would have >> been very similar to what Frank did (so, big thanks) - run a DCO >> environment with "owner nobody", and see if things still work. >> >> I will add this to my DCO server test environment - run one of the >> iroute-using instances with "nobody", so it is continuously tested. > [..] >> commit 2e359a088226ab1e5ee41fbab27d38d8a8d192ac >> Author: Timo Rothenpieler >> Date: Sat May 14 12:37:17 2022 +0200 >> >> platform: Retain CAP_NET_ADMIN when dropping privileges > > Unfortunately, it seems that our approach to "if SITNL is used, we hard > require that setting CAP_NET_ADMIN succeeds" is too strong for the twisted > ways that people use openvpn. That's not how the patch operates. It only hard-requires the capability retention is dco_enabled() returns true. In all other cases, it will try to retain capabilities, but continue with a warning if it fails. Making the dco_enabled() case a "try but continue" would be a matter of changing a 1 to a -1. But given that DCO can't really work then, I'm not sure if that's desirable.
Hi, On Mon, Aug 15, 2022 at 12:14:23PM +0200, Timo Rothenpieler wrote: > > Unfortunately, it seems that our approach to "if SITNL is used, we hard > > require that setting CAP_NET_ADMIN succeeds" is too strong for the twisted > > ways that people use openvpn. > > That's not how the patch operates. > It only hard-requires the capability retention is dco_enabled() returns > true. > In all other cases, it will try to retain capabilities, but continue > with a warning if it fails. Yes, but we do have DCO here, setting CAP_NET_ADMIN fails, and we abort, instead of having a working client connect. > Making the dco_enabled() case a "try but continue" would be a matter of > changing a 1 to a -1. But given that DCO can't really work then, I'm not > sure if that's desirable. *DCO* can work fine, from the looks of that bug report (because all the DCO open happens before capability drop on a --client config). "Calling ifconfig and installing routes" cannot, but this is exactly what we are not doing if --ifconfig-noexec + --route-noexec are set. Please look closely at the log in the bug report, and keep in mind that NM will do all the "SITNL" stuff for the user in that scenaro, not OpenVPN itself. gert
On 15/08/2022 12:29, Gert Doering wrote: > Hi, > > On Mon, Aug 15, 2022 at 12:14:23PM +0200, Timo Rothenpieler wrote: >>> Unfortunately, it seems that our approach to "if SITNL is used, we hard >>> require that setting CAP_NET_ADMIN succeeds" is too strong for the twisted >>> ways that people use openvpn. >> >> That's not how the patch operates. >> It only hard-requires the capability retention is dco_enabled() returns >> true. >> In all other cases, it will try to retain capabilities, but continue >> with a warning if it fails. > > Yes, but we do have DCO here, setting CAP_NET_ADMIN fails, and we abort, > instead of having a working client connect. > >> Making the dco_enabled() case a "try but continue" would be a matter of >> changing a 1 to a -1. But given that DCO can't really work then, I'm not >> sure if that's desirable. > > *DCO* can work fine, from the looks of that bug report (because all > the DCO open happens before capability drop on a --client config). > > "Calling ifconfig and installing routes" cannot, but this is exactly what > we are not doing if --ifconfig-noexec + --route-noexec are set. > > Please look closely at the log in the bug report, and keep in mind > that NM will do all the "SITNL" stuff for the user in that scenaro, > not OpenVPN itself. > > gert There's basically two options then: Remove the dco_enabled() check entirely, and purely check for SITNL, but always only warn if it fails and carry on, hoping it works fine. Add checks for ifconfig-noexec + route-noexec being set, and either only warn in that case, or don't even try to retain capabilities, since they're not needed either way. I'd prefer the later, since fewer capabilities is generally better. The later of the two options seems nicer, will have a look at implementing them. Shouldn't be that hard, given the config is already there. I don't have a NM setup to test that on though.
Hi, On Mon, Aug 15, 2022 at 12:40:55PM +0200, Timo Rothenpieler wrote: > Add checks for ifconfig-noexec + route-noexec being set, and either only > warn in that case, ... this is what I suggested two mails upthread :-) > or don't even try to retain capabilities, since > they're not needed either way. I'd prefer the later, since fewer > capabilities is generally better. I could see arguments for "we want to do the ifconfig/route setup in an --up script" - for example to do VRF/NetNS stuff that OpenVPN can not do itself. So for these scenarios having the capability around would be useful (= thus, try-and-warn)... Different scenario, same options. We don't always know what users want. > implementing them. Shouldn't be that hard, given the config is already > there. > I don't have a NM setup to test that on though. Sending to the debian bug report referenced upthread and asking them to test might be an option here. Or ask David. I do not use NM either. gert
Hi, On Mon, 15 Aug 2022 at 12:50, Gert Doering <gert@greenie.muc.de> wrote: > On Mon, Aug 15, 2022 at 12:40:55PM +0200, Timo Rothenpieler wrote: > > or don't even try to retain capabilities, since > > they're not needed either way. I'd prefer the later, since fewer > > capabilities is generally better. > > I could see arguments for "we want to do the ifconfig/route setup in > an --up script" - for example to do VRF/NetNS stuff that OpenVPN can not > do itself. So for these scenarios having the capability around would > be useful (= thus, try-and-warn)... > > Different scenario, same options. We don't always know what users want. Let me just second the "fewer capabilities is generally better" argument. CAP_NET_ADMIN is a broad set of effective capabilties and has been a popular path for privilege escalation vulnerabilities in the past. See for example these two recent CVEs: CVE-2022-2586 A use-after-free in the Netfilter subsystem may result in local privilege escalation for a user with the CAP_NET_ADMIN capability in any user or network namespace. CVE-2022-2588 Zhenpeng Lin discovered a use-after-free flaw in the cls_route filter implementation which may result in local privilege escalation for a user with the CAP_NET_ADMIN capability in any user or network namespace. So I'm really not in favour of retaining CAP_NET_ADMIN "just in case". I would even like to be able to not retain it at all. -Steffan
Hi, On Mon, Aug 15, 2022 at 11:54:21AM +0200, Gert Doering wrote: > [..] > > commit 2e359a088226ab1e5ee41fbab27d38d8a8d192ac > > Author: Timo Rothenpieler > > Date: Sat May 14 12:37:17 2022 +0200 > > > > platform: Retain CAP_NET_ADMIN when dropping privileges > > Unfortunately, it seems that our approach to "if SITNL is used, we hard > require that setting CAP_NET_ADMIN succeeds" is too strong for the twisted > ways that people use openvpn. > > Namely, network-manager... > > https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1017379 > > ... runs openvpn with --ifconfig-noexec / --route-noexec, and insists > on doing all that itself. I do not like NM's way of trying to control > everything (up to the point that it defaults to redirecting a default > route to OpenVPN even if config and server do not want that), but this > is what Linux people seem to be stuck with, so we need to handle it. We've discussed this quite a bit in #openvpn-devel, and it's more complicated than "just ifconfig and route". Namely, there is more operations OpenVPN needs to do if running with the DCO kernel module, which all needs CAP_NET_ADMIN - renegotiate on TLS session expiry (control channel communication is done through kernel module, not directly on socket) - install / swap keys - reconfigure the kernel peer on reconnect (peer-id / remote IP) So, running in an environment that prevents use of CAP_NET_ADMIN (how does it do that, in the first place?) *and* forces a non-root user means "DCO will break". Not immediately, but openvpn will abort on each of these envents - NM might hide that by just restarting it, but it's still broken. So the discussion seems to run towards two options - disable DCO if CAP_NET_ADMIN can not be retained - fix this in NM Preferably, fix this in NM... gert
Hi, On Tue, Aug 16, 2022 at 11:16:50AM +0200, Steffan Karger wrote: > So I'm really not in favour of retaining CAP_NET_ADMIN "just in case". > I would even like to be able to not retain it at all. I hear what you say, and I support that line of thought. Alas, with current Linux-DCO, we need this for fiddling all the DCO bits (keys / key renewal! / peer-id / install/update peers), as this is done via netlink, and netlink requires CAP_NET_ADMIN. To get around that we'd need to find a communication channel to (Linux-)DCO that does not require privileges after initial setup ("hey, DCO, give me a socket that does not need privileges") and rewrite quite a bit... I'm sure that Antonio will be thrilled by that new challenge... :-) gert
Hi, On Mon, Aug 15, 2022 at 11:54:21AM +0200, Gert Doering wrote: > [..] > > commit 2e359a088226ab1e5ee41fbab27d38d8a8d192ac > > Author: Timo Rothenpieler > > Date: Sat May 14 12:37:17 2022 +0200 > > > > platform: Retain CAP_NET_ADMIN when dropping privileges > > Unfortunately, it seems that our approach to "if SITNL is used, we hard > require that setting CAP_NET_ADMIN succeeds" is too strong for the twisted > ways that people use openvpn. > > Namely, network-manager... > > https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1017379 For the sake of the list archives: *this* particular problem has been solved by commit da31c1654c8534658157cfe9c9de5750ee752608 Author: Timo Rothenpieler <timo@rothenpieler.org> Date: Wed Aug 17 15:18:17 2022 +0200 dco: disable DCO if --user specified but unable to retain capabilities so if we detect "the caller wants us to go to --user $notroot but we do not have the necessary capabilities to retain CAP_NET_ADMIN, disable DCO". This is basically the only thing we can do - if we have no CAP_NET_ADMIN, DCO will be unable to function today. Next steps are - talk to the NM maintainers to get them to call OpenVPN with something like "CAP_NET_ADMIN and uid != 0" (and no --user config) - so we can just do our thing, without root privs. David :-) - figure out if we can do Linux DCO without CAP_NET_ADMIN, at least "after startup" (open with privs, get a ticket, continue without privs, something mumble mumble). Antonio :-) Thanks for all the enlightenment that happened here. gert
diff --git a/configure.ac b/configure.ac index 85921ddb..d2eb3426 100644 --- a/configure.ac +++ b/configure.ac @@ -794,6 +794,25 @@ dnl esac fi +dnl +dnl Depend on libcap-ng on Linux +dnl +case "$host" in + *-*-linux*) + PKG_CHECK_MODULES([LIBCAPNG], + [libcap-ng], + [], + [AC_MSG_ERROR([libcap-ng package not found. Is the development package and pkg-config installed?])] + ) + AC_CHECK_HEADER([sys/prctl.h],,[AC_MSG_ERROR([sys/prctl.h not found!])]) + + CFLAGS="${CFLAGS} ${LIBCAPNG_CFALGS}" + LIBS="${LIBS} ${LIBCAPNG_LIBS}" + AC_DEFINE(HAVE_LIBCAPNG, 1, [Enable libcap-ng support]) + ;; +esac + + if test "${with_crypto_library}" = "openssl"; then AC_ARG_VAR([OPENSSL_CFLAGS], [C compiler flags for OpenSSL]) AC_ARG_VAR([OPENSSL_LIBS], [linker flags for OpenSSL]) diff --git a/distro/systemd/openvpn-client@.service.in b/distro/systemd/openvpn-client@.service.in index cbcef653..159fb4dc 100644 --- a/distro/systemd/openvpn-client@.service.in +++ b/distro/systemd/openvpn-client@.service.in @@ -11,7 +11,7 @@ Type=notify PrivateTmp=true WorkingDirectory=/etc/openvpn/client ExecStart=@sbindir@/openvpn --suppress-timestamps --nobind --config %i.conf -CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_OVERRIDE +CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SETPCAP CAP_SYS_CHROOT CAP_DAC_OVERRIDE LimitNPROC=10 DeviceAllow=/dev/null rw DeviceAllow=/dev/net/tun rw diff --git a/distro/systemd/openvpn-server@.service.in b/distro/systemd/openvpn-server@.service.in index d1cc72cb..6e8e7d94 100644 --- a/distro/systemd/openvpn-server@.service.in +++ b/distro/systemd/openvpn-server@.service.in @@ -11,7 +11,7 @@ Type=notify PrivateTmp=true WorkingDirectory=/etc/openvpn/server ExecStart=@sbindir@/openvpn --status %t/openvpn-server/status-%i.log --status-version 2 --suppress-timestamps --config %i.conf -CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_OVERRIDE CAP_AUDIT_WRITE +CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SETPCAP CAP_SYS_CHROOT CAP_DAC_OVERRIDE CAP_AUDIT_WRITE LimitNPROC=10 DeviceAllow=/dev/null rw DeviceAllow=/dev/net/tun rw diff --git a/src/openvpn/init.c b/src/openvpn/init.c index a6c93038..39b8f77a 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1163,8 +1163,9 @@ do_uid_gid_chroot(struct context *c, bool no_delay) { if (no_delay) { - platform_group_set(&c0->platform_state_group); - platform_user_set(&c0->platform_state_user); + platform_user_group_set(&c0->platform_state_user, + &c0->platform_state_group, + c); } else if (c->first_time) { diff --git a/src/openvpn/platform.c b/src/openvpn/platform.c index 61afee83..56dca6e6 100644 --- a/src/openvpn/platform.c +++ b/src/openvpn/platform.c @@ -29,6 +29,9 @@ #include "syshead.h" +#include "openvpn.h" +#include "options.h" + #include "buffer.h" #include "crypto.h" #include "error.h" @@ -43,6 +46,11 @@ #include <direct.h> #endif +#ifdef HAVE_LIBCAPNG +#include <cap-ng.h> +#include <sys/prctl.h> +#endif + /* Redefine the top level directory of the filesystem * to restrict access to files for security */ void @@ -91,7 +99,7 @@ platform_user_get(const char *username, struct platform_state_user *state) return ret; } -void +static void platform_user_set(const struct platform_state_user *state) { #if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID) @@ -130,7 +138,7 @@ platform_group_get(const char *groupname, struct platform_state_group *state) return ret; } -void +static void platform_group_set(const struct platform_state_group *state) { #if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID) @@ -155,6 +163,140 @@ platform_group_set(const struct platform_state_group *state) #endif } +/* + * Determine if we need to retain process capabilities. DCO and SITNL need it. + * Enforce it for DCO, but only try and soft-fail for SITNL to keep backwards compat. + * + * Returns the tri-state expected by platform_user_group_set. + * -1: try to keep caps, but continue if impossible + * 0: don't keep caps + * 1: keep caps, fail hard if impossible + */ +static int +need_keep_caps(struct context *c) +{ + if (!c) + { + return -1; + } + + if (dco_enabled(&c->options)) + { +#ifdef TARGET_LINUX + /* DCO on Linux does not work at all without CAP_NET_ADMIN */ + return 1; +#else + /* Windows/BSD/... has no equivalent capability mechanism */ + return -1; +#endif + } + +#ifdef ENABLE_SITNL + return -1; +#else + return 0; +#endif +} + +/* Set user and group, retaining neccesary capabilities required by the platform. + * + * The keep_caps argument has 3 possible states: + * >0: Retain capabilities, and fail hard on failure to do so. + * ==0: Don't attempt to retain any capabilities, just sitch user/group. + * <0: Try to retain capabilities, but continue on failure. + */ +void platform_user_group_set(const struct platform_state_user *user_state, + const struct platform_state_group *group_state, + struct context *c) +{ + int keep_caps = need_keep_caps(c); + unsigned int err_flags = (keep_caps > 0) ? M_FATAL : M_NONFATAL; +#ifdef HAVE_LIBCAPNG + int new_gid = -1, new_uid = -1; + int res; + + if (keep_caps == 0) + { + goto fallback; + } + + /* + * new_uid/new_gid defaults to -1, which will not make + * libcap-ng change the UID/GID unless configured + */ + if (group_state->groupname && group_state->gr) + { + new_gid = group_state->gr->gr_gid; + } + if (user_state->username && user_state->pw) + { + new_uid = user_state->pw->pw_uid; + } + + /* Prepare capabilities before dropping UID/GID */ + capng_clear(CAPNG_SELECT_BOTH); + res = capng_update(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, CAP_NET_ADMIN); + if (res < 0) + { + msg(err_flags, "capng_update(CAP_NET_ADMIN) failed: %d", res); + goto fallback; + } + + /* Change to new UID/GID. + * capng_change_id() internally calls capng_apply() to apply prepared capabilities. + */ + res = capng_change_id(new_uid, new_gid, CAPNG_DROP_SUPP_GRP | CAPNG_CLEAR_BOUNDING); + if (res == -4 || res == -6) + { + /* -4 and -6 mean failure of setuid/gid respectively. + There is no point for us to continue if those failed. */ + msg(M_ERR, "capng_change_id('%s','%s') failed: %d", + user_state->username, group_state->groupname, res); + } + else if (res == -3) + { + msg(M_NONFATAL | M_ERRNO, "capng_change_id() failed applying capabilities"); + msg(err_flags, "NOTE: previous error likely due to missing capability CAP_SETPCAP."); + goto fallback; + } + else if (res < 0) + { + msg(err_flags | M_ERRNO, "capng_change_id('%s','%s') failed retaining capabilities: %d", + user_state->username, group_state->groupname, res); + goto fallback; + } + + if (new_uid >= 0) + { + msg(M_INFO, "UID set to %s", user_state->username); + } + if (new_gid >= 0) + { + msg(M_INFO, "GID set to %s", group_state->groupname); + } + + msg(M_INFO, "Capabilities retained: CAP_NET_ADMIN"); + return; + +fallback: + /* capng_change_id() can leave this flag clobbered on failure + * This is working around a bug in libcap-ng, which can leave the flag set + * on failure: https://github.com/stevegrubb/libcap-ng/issues/33 */ + if (prctl(PR_GET_KEEPCAPS) && prctl(PR_SET_KEEPCAPS, 0) < 0) + { + msg(M_ERR, "Clearing KEEPCAPS flag failed"); + } +#endif /* HAVE_LIBCAPNG */ + + if (keep_caps) + { + msg(err_flags, "Unable to retain capabilities"); + } + + platform_group_set(group_state); + platform_user_set(user_state); +} + /* Change process priority */ void platform_nice(int niceval) diff --git a/src/openvpn/platform.h b/src/openvpn/platform.h index a3eec298..1ffd81e3 100644 --- a/src/openvpn/platform.h +++ b/src/openvpn/platform.h @@ -55,6 +55,9 @@ #include "basic.h" #include "buffer.h" +/* forward declared to avoid large amounts of extra includes */ +struct context; + /* Get/Set UID of process */ struct platform_state_user { @@ -79,11 +82,12 @@ struct platform_state_group { bool platform_user_get(const char *username, struct platform_state_user *state); -void platform_user_set(const struct platform_state_user *state); - bool platform_group_get(const char *groupname, struct platform_state_group *state); -void platform_group_set(const struct platform_state_group *state); +void platform_user_group_set(const struct platform_state_user *user_state, + const struct platform_state_group *group_state, + struct context *c); + /* * Extract UID or GID