getpwnam_r and getgrnam_r are not supported by the Android NDK
authorTobias Brunner <tobias@strongswan.org>
Mon, 9 Jul 2012 15:49:18 +0000 (17:49 +0200)
committerTobias Brunner <tobias@strongswan.org>
Mon, 9 Jul 2012 15:52:01 +0000 (17:52 +0200)
configure.in
src/libstrongswan/utils/capabilities.c

index 9191b1b..2b4c167 100644 (file)
@@ -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)
 
 AC_CHECK_HEADERS(sys/sockio.h glob.h)
 AC_CHECK_HEADERS(net/pfkeyv2.h netipsec/ipsec.h netinet6/ipsec.h linux/udp.h)
index b396c6a..34128d0 100644 (file)
@@ -1,4 +1,6 @@
 /*
 /*
+ * Copyright (C) 2012 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
  * Copyright (C) 2012 Martin Willi
  * Copyright (C) 2012 revosec AG
  *
  * Copyright (C) 2012 Martin Willi
  * Copyright (C) 2012 revosec AG
  *
 
 #include <debug.h>
 
 
 #include <debug.h>
 
+#if !defined(HAVE_GETPWNAM_R) || !defined(HAVE_GETGRNAM_R)
+# include <threading/mutex.h>
+# define EMULATE_R_FUNCS
+#endif
+
 typedef struct private_capabilities_t private_capabilities_t;
 
 /**
 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 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,
 };
 
 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)
 {
 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;
 
        int err;
 
+#ifdef HAVE_GETPWNAM_R
+       struct passwd passwd;
+       char buf[1024];
+
        err = getpwnam_r(username, &passwd, buf, sizeof(buf), &pwp);
        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)
 {
 }
 
 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;
 
        int err;
 
+#ifdef HAVE_GETGRNAM_R
+       struct group group;
+       char buf[1024];
+
        err = getgrnam_r(groupname, &group, buf, sizeof(buf), &grp);
        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,
 }
 
 METHOD(capabilities_t, drop, bool,
@@ -205,6 +243,9 @@ METHOD(capabilities_t, drop, bool,
 METHOD(capabilities_t, destroy, void,
        private_capabilities_t *this)
 {
 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 */
 #ifdef CAPABILITIES_LIBCAP
        cap_free(this->caps);
 #endif /* CAPABILITIES_LIBCAP */
@@ -242,5 +283,9 @@ capabilities_t *capabilities_create()
        }
 #endif /* CAPABILITIES */
 
        }
 #endif /* CAPABILITIES */
 
+#ifdef EMULATE_R_FUNCS
+       this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
+#endif /* EMULATE_R_FUNCS */
+
        return &this->public;
 }
        return &this->public;
 }