tests: Add test_initgroups
authorPavel Filipenský <pfilipensky@samba.org>
Thu, 19 Jan 2023 21:35:00 +0000 (22:35 +0100)
committerAndreas Schneider <asn@samba.org>
Tue, 24 Jan 2023 08:56:35 +0000 (09:56 +0100)
Signed-off-by: Pavel Filipenský <pfilipensky@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
tests/CMakeLists.txt
tests/test_initgroups.c [new file with mode: 0644]

index 24adbed80808096d9adb3848959c47bd298060b1..425395beeaa127f4778a6292e11e5cbc924a0307 100644 (file)
@@ -19,6 +19,10 @@ configure_file(group.in ${CMAKE_CURRENT_BINARY_DIR}/group @ONLY)
 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
@@ -26,7 +30,8 @@ set(NWRAP_TESTS
     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)
@@ -51,6 +56,9 @@ function(ADD_CMOCKA_TEST_ENVIRONMENT _TEST_NAME)
     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)
@@ -60,6 +68,10 @@ function(ADD_CMOCKA_TEST_ENVIRONMENT _TEST_NAME)
         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)
@@ -71,6 +83,9 @@ function(ADD_CMOCKA_TEST_ENVIRONMENT _TEST_NAME)
 
         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()
 
diff --git a/tests/test_initgroups.c b/tests/test_initgroups.c
new file mode 100644 (file)
index 0000000..959ae4d
--- /dev/null
@@ -0,0 +1,52 @@
+#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;
+}