| Local change to use initgroups() instead of setgid() to set |
| the groups for the process as we are dropping privileges. |
| |
| TODO(pstew): Generalize and upstream this change. |
| |
| diff --git a/strongswan-5.0.2/src/libstrongswan/utils/capabilities.c-orig b/strongswan-5.0.2/src/libstrongswan/utils/capabilities.c |
| index c36a76e..38a6ff6 100644 |
| --- a/strongswan-5.0.2/src/libstrongswan/utils/capabilities.c-orig |
| +++ b/strongswan-5.0.2/src/libstrongswan/utils/capabilities.c |
| @@ -57,6 +57,12 @@ struct private_capabilities_t { |
| gid_t gid; |
| |
| /** |
| + * user name as retained from pw_name field from the password |
| + * entry retrieved from getwpwnam(). |
| + */ |
| + char *pw_name; |
| + |
| + /** |
| * capabilities to keep |
| */ |
| #ifdef CAPABILITIES_LIBCAP |
| @@ -145,8 +151,9 @@ METHOD(capabilities_t, resolve_uid, bool, |
| err = errno; |
| this->mutex->unlock(this->mutex); |
| #endif /* HAVE GETPWNAM_R */ |
| - if (pwp) |
| + if (pwp && pwp->pw_name != NULL) |
| { |
| + this->pw_name = strdup(pwp->pw_name); |
| return TRUE; |
| } |
| DBG1(DBG_LIB, "resolving user '%s' failed: %s", username, |
| @@ -195,10 +202,11 @@ METHOD(capabilities_t, drop, bool, |
| prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0); |
| #endif |
| |
| - if (this->gid && setgid(this->gid) != 0) |
| - { |
| - DBG1(DBG_LIB, "change to unprivileged group %u failed: %s", |
| - this->gid, strerror(errno)); |
| + if (this->gid && this->pw_name && |
| + initgroups(this->pw_name, this->gid) != 0) { |
| + DBG1(DBG_LIB, "Init groups for unprivileged user %s group %u " |
| + "failed: %s", |
| + this->pw_name, this->gid, strerror(errno)); |
| return FALSE; |
| } |
| if (this->uid && setuid(this->uid) != 0) |
| @@ -249,6 +257,7 @@ METHOD(capabilities_t, destroy, void, |
| #ifdef CAPABILITIES_LIBCAP |
| cap_free(this->caps); |
| #endif /* CAPABILITIES_LIBCAP */ |
| + free(this->pw_name); |
| free(this); |
| } |
| |
| @@ -283,6 +292,8 @@ capabilities_t *capabilities_create() |
| } |
| #endif /* CAPABILITIES */ |
| |
| + this->pw_name = NULL; |
| + |
| #ifdef EMULATE_R_FUNCS |
| this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); |
| #endif /* EMULATE_R_FUNCS */ |