From ee7b7de18f29e682b914422c85e55bed8ad71277 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 9 Jul 2012 17:49:18 +0200 Subject: [PATCH] getpwnam_r and getgrnam_r are not supported by the Android NDK --- configure.in | 2 +- src/libstrongswan/utils/capabilities.c | 93 +++++++++++++++++++++++++--------- 2 files changed, 70 insertions(+), 25 deletions(-) diff --git a/configure.in b/configure.in index 9191b1b..2b4c167 100644 --- a/configure.in +++ b/configure.in @@ -392,7 +392,7 @@ AC_CHECK_FUNC( )] ) -AC_CHECK_FUNCS(prctl mallinfo getpass closefrom) +AC_CHECK_FUNCS(prctl mallinfo getpass closefrom getpwnam_r getgrnam_r) AC_CHECK_HEADERS(sys/sockio.h glob.h) AC_CHECK_HEADERS(net/pfkeyv2.h netipsec/ipsec.h netinet6/ipsec.h linux/udp.h) diff --git a/src/libstrongswan/utils/capabilities.c b/src/libstrongswan/utils/capabilities.c index b396c6a..34128d0 100644 --- a/src/libstrongswan/utils/capabilities.c +++ b/src/libstrongswan/utils/capabilities.c @@ -1,4 +1,6 @@ /* + * Copyright (C) 2012 Tobias Brunner + * Hochschule fuer Technik Rapperswil * Copyright (C) 2012 Martin Willi * Copyright (C) 2012 revosec AG * @@ -27,6 +29,11 @@ #include +#if !defined(HAVE_GETPWNAM_R) || !defined(HAVE_GETGRNAM_R) +# include +# define EMULATE_R_FUNCS +#endif + typedef struct private_capabilities_t private_capabilities_t; /** @@ -58,6 +65,13 @@ struct private_capabilities_t { #ifdef CAPABILITIES_NATIVE struct __user_cap_data_struct caps[2]; #endif /* CAPABILITIES_NATIVE */ + +#ifdef EMULATE_R_FUNCS + /** + * mutex to emulate get(pw|gr)nam_r functions + */ + mutex_t *mutex; +#endif }; METHOD(capabilities_t, keep, void, @@ -109,45 +123,69 @@ METHOD(capabilities_t, set_gid, void, METHOD(capabilities_t, resolve_uid, bool, private_capabilities_t *this, char *username) { - const char *errstr = "user not found"; - struct passwd passwd, *pwp; - char buf[1024]; + struct passwd *pwp; int err; +#ifdef HAVE_GETPWNAM_R + struct passwd passwd; + char buf[1024]; + err = getpwnam_r(username, &passwd, buf, sizeof(buf), &pwp); - if (pwp == NULL) + if (pwp) { - if (err) - { - errstr = strerror(err); - } - DBG1(DBG_LIB, "resolving user '%s' failed: %s", username, errstr); - return FALSE; + this->uid = pwp->pw_uid; } - this->uid = pwp->pw_uid; - return TRUE; +#else /* HAVE GETPWNAM_R */ + this->mutex->lock(this->mutex); + pwp = getpwnam(username); + if (pwp) + { + this->uid = pwp->pw_uid; + } + err = errno; + this->mutex->unlock(this->mutex); +#endif /* HAVE GETPWNAM_R */ + if (pwp) + { + return TRUE; + } + DBG1(DBG_LIB, "resolving user '%s' failed: %s", username, + err ? strerror(err) : "user not found"); + return FALSE; } METHOD(capabilities_t, resolve_gid, bool, private_capabilities_t *this, char *groupname) { - const char *errstr = "group not found"; - struct group group, *grp; - char buf[1024]; + struct group *grp; int err; +#ifdef HAVE_GETGRNAM_R + struct group group; + char buf[1024]; + err = getgrnam_r(groupname, &group, buf, sizeof(buf), &grp); - if (grp == NULL) + if (grp) { - if (err) - { - errstr = strerror(err); - } - DBG1(DBG_LIB, "resolving user '%s' failed: %s", groupname, errstr); - return FALSE; + this->gid = grp->gr_gid; } - this->gid = grp->gr_gid; - return TRUE; +#else /* HAVE_GETGRNAM_R */ + this->mutex->lock(this->mutex); + grp = getgrnam(groupname); + if (grp) + { + this->gid = grp->gr_gid; + } + err = errno; + this->mutex->unlock(this->mutex); +#endif /* HAVE_GETGRNAM_R */ + if (grp) + { + return TRUE; + } + DBG1(DBG_LIB, "resolving user '%s' failed: %s", groupname, + err ? strerror(err) : "group not found"); + return FALSE; } METHOD(capabilities_t, drop, bool, @@ -205,6 +243,9 @@ METHOD(capabilities_t, drop, bool, METHOD(capabilities_t, destroy, void, private_capabilities_t *this) { +#ifdef EMULATE_R_FUNCS + this->mutex->destroy(this->mutex); +#endif /* EMULATE_R_FUNCS */ #ifdef CAPABILITIES_LIBCAP cap_free(this->caps); #endif /* CAPABILITIES_LIBCAP */ @@ -242,5 +283,9 @@ capabilities_t *capabilities_create() } #endif /* CAPABILITIES */ +#ifdef EMULATE_R_FUNCS + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); +#endif /* EMULATE_R_FUNCS */ + return &this->public; } -- 2.7.4