configure_file(hosts.in ${CMAKE_CURRENT_BINARY_DIR}/hosts @ONLY)
configure_file(shadow.in ${CMAKE_CURRENT_BINARY_DIR}/shadow @ONLY)
+# If there is uid_wrapper, we can better test initgroups() since uid_wrapper
+# provides privilege for setgroups().
+find_package(uid_wrapper 1.3.0)
+
set(NWRAP_TESTS
testsuite
test_nwrap_vector
test_getnameinfo
test_gethostby_name_addr
test_gethostent
- test_getpwuid_module)
+ test_getpwuid_module
+ test_initgroups)
if (HAVE_SHADOW_H)
list(APPEND NWRAP_TESTS test_shadow)
if (ASAN_LIBRARY)
list(APPEND PRELOAD_LIBRARIES ${ASAN_LIBRARY})
endif()
+ if (uid_wrapper_FOUND)
+ list(APPEND PRELOAD_LIBRARIES ${UID_WRAPPER_LIBRARY})
+ endif()
list(APPEND PRELOAD_LIBRARIES ${NSS_WRAPPER_LOCATION})
if (OSX)
set(TORTURE_ENVIRONMENT "LD_PRELOAD=${_TMP_ENV}")
endif()
+ if (uid_wrapper_FOUND)
+ list(APPEND TORTURE_ENVIRONMENT UID_WRAPPER=1)
+ endif()
+
list(APPEND TORTURE_ENVIRONMENT NSS_WRAPPER_PASSWD=${CMAKE_CURRENT_BINARY_DIR}/passwd)
list(APPEND TORTURE_ENVIRONMENT NSS_WRAPPER_GROUP=${CMAKE_CURRENT_BINARY_DIR}/group)
list(APPEND TORTURE_ENVIRONMENT NSS_WRAPPER_SHADOW=${CMAKE_CURRENT_BINARY_DIR}/shadow)
if (CMAKE_BUILD_TYPE_LOWER STREQUAL "threadsanitizer")
list(APPEND TORTURE_ENVIRONMENT NSS_WRAPPER_DISABLE_DEEPBIND=1)
+ if (uid_wrapper_FOUND)
+ list(APPEND TORTURE_ENVIRONMENT UID_WRAPPER_DISABLE_DEEPBIND=1)
+ endif()
endif()
endif()
--- /dev/null
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <grp.h>
+#include <errno.h>
+
+static void test_nwrap_initgroups(void **state)
+{
+ gid_t gid = 10000;
+ int ret, i;
+ int ngroups;
+ const char *env = getenv("UID_WRAPPER");
+
+ (void)state; /* unused */
+
+ /* initgroups() sets {10000, 1000, 1002, 100010, 100011, 100012} */
+ ret = initgroups("alice", gid);
+ assert_return_code(ret, errno);
+
+ /*
+ * nss_wrapper() in nwrap_initgroups() makes early return if UID_WRAPPER
+ * is not present. The reason is that we need privilege for setgroups()
+ * called from initgroups() and we get it only with UID_WRAPPER
+ */
+ if (env != NULL && env[0] == '1') {
+ gid_t groups1[6] = {10000, 1000, 1002, 100010, 100011, 100012};
+ gid_t *groups2 = malloc(10 * sizeof(gid_t));
+
+ assert_non_null(groups2);
+ ngroups = getgroups(10, groups2); /* room for 10, expect 6 */
+ assert_int_equal(ngroups, 6);
+ for (i = 0; i < 6; i++) {
+ assert_int_equal(groups1[i], groups2[i]);
+ }
+ }
+}
+
+int main(void)
+{
+ int rc;
+
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test_nwrap_initgroups)
+ };
+
+ rc = cmocka_run_group_tests(tests, NULL, NULL);
+
+ return rc;
+}