diff --git a/src/charon/charon.c b/src/charon/charon.c index 1d1e623c1..30f6ce2f6 100644 --- a/src/charon/charon.c +++ b/src/charon/charon.c @@ -231,9 +231,15 @@ static bool check_pidfile() DBG1(DBG_LIB, "setting FD_CLOEXEC for '"PID_FILE"' failed: %s", strerror(errno)); } - ignore_result(fchown(fd, - lib->caps->get_uid(lib->caps), - lib->caps->get_gid(lib->caps))); + /* Only fchown() the pidfile if we have CAP_CHOWN. Otherwise, + * directory permissions should allow pidfile to be accessed + * by the UID/GID under which the charon deamon will run. */ + if (lib->caps->check(lib->caps, CAP_CHOWN)) + { + ignore_result(fchown(fd, + lib->caps->get_uid(lib->caps), + lib->caps->get_gid(lib->caps))); + } fprintf(pidfile, "%d\n", getpid()); fflush(pidfile); return FALSE; diff --git a/src/libstrongswan/networking/streams/stream_service_unix.c b/src/libstrongswan/networking/streams/stream_service_unix.c index 1ed27c499..92640fc91 100644 --- a/src/libstrongswan/networking/streams/stream_service_unix.c +++ b/src/libstrongswan/networking/streams/stream_service_unix.c @@ -39,8 +39,9 @@ stream_service_t *stream_service_create_unix(char *uri, int backlog) } if (!lib->caps->check(lib->caps, CAP_CHOWN)) { /* required to chown(2) service socket */ - DBG1(DBG_NET, "socket '%s' requires CAP_CHOWN capability", uri); - return NULL; + DBG1(DBG_NET, "cannot change ownership of socket '%s' without " + "CAP_CHOWN capability. socket directory should be accessible to " + "UID/GID under which the deamon will run", uri); } fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd == -1) @@ -58,7 +59,9 @@ stream_service_t *stream_service_create_unix(char *uri, int backlog) return NULL; } umask(old); - if (chown(addr.sun_path, lib->caps->get_uid(lib->caps), + /* only attempt to chown() socket if we have CAP_CHOWN */ + if (lib->caps->check(lib->caps, CAP_CHOWN) && + chown(addr.sun_path, lib->caps->get_uid(lib->caps), lib->caps->get_gid(lib->caps)) != 0) { DBG1(DBG_NET, "changing socket permissions for '%s' failed: %s", diff --git a/src/libstrongswan/utils/capabilities.c b/src/libstrongswan/utils/capabilities.c index ce5f550b5..bd74e7ce7 100644 --- a/src/libstrongswan/utils/capabilities.c +++ b/src/libstrongswan/utils/capabilities.c @@ -422,7 +422,10 @@ METHOD(capabilities_t, drop, bool, { #ifndef WIN32 #ifdef HAVE_PRCTL - prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0); + if (has_capability(this, CAP_SETPCAP, NULL)) + { + prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0); + } #endif if (this->uid && !init_supplementary_groups(this)) diff --git a/src/libstrongswan/utils/capabilities.h b/src/libstrongswan/utils/capabilities.h index 20c18554b..385a337e5 100644 --- a/src/libstrongswan/utils/capabilities.h +++ b/src/libstrongswan/utils/capabilities.h @@ -47,6 +47,9 @@ typedef struct capabilities_t capabilities_t; #ifndef CAP_DAC_OVERRIDE # define CAP_DAC_OVERRIDE 1 #endif +#ifndef CAP_SETPCAP +# define CAP_SETPCAP 8 +#endif /** * POSIX capability dropping abstraction layer. diff --git a/src/starter/starter.c b/src/starter/starter.c index 6c0739340..8ca1af29c 100644 --- a/src/starter/starter.c +++ b/src/starter/starter.c @@ -477,6 +477,7 @@ int main (int argc, char **argv) } } +#ifndef STARTER_ALLOW_NON_ROOT /* verify that we can start */ if (getuid() != 0) { @@ -484,6 +485,7 @@ int main (int argc, char **argv) cleanup(); exit(LSB_RC_NOT_ALLOWED); } +#endif if (check_pid(pid_file)) { @@ -520,6 +522,7 @@ int main (int argc, char **argv) exit(LSB_RC_INVALID_ARGUMENT); } +#ifndef SKIP_KERNEL_IPSEC_MODPROBES /* determine if we have a native netkey IPsec stack */ if (!starter_netkey_init()) { @@ -530,6 +533,7 @@ int main (int argc, char **argv) DBG1(DBG_APP, "no known IPsec stack detected, ignoring!"); } } +#endif last_reload = time_monotonic(NULL);