Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package nss_wrapper for openSUSE:Factory 
checked in at 2023-01-26 13:57:02
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/nss_wrapper (Old)
 and      /work/SRC/openSUSE:Factory/.nss_wrapper.new.32243 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "nss_wrapper"

Thu Jan 26 13:57:02 2023 rev:16 rq:1060964 version:1.1.15

Changes:
--------
--- /work/SRC/openSUSE:Factory/nss_wrapper/nss_wrapper.changes  2022-11-10 
14:19:13.741320084 +0100
+++ /work/SRC/openSUSE:Factory/.nss_wrapper.new.32243/nss_wrapper.changes       
2023-01-26 14:04:29.726247774 +0100
@@ -1,0 +2,15 @@
+Wed Jan 25 15:45:26 UTC 2023 - Andreas Schneider <[email protected]>
+
+- Update to version 1.1.15
+  * Fixed linking issue in tests
+  * Fixed a memory leak in tests
+
+-------------------------------------------------------------------
+Wed Jan 25 11:13:12 UTC 2023 - Andreas Schneider <[email protected]>
+
+- Update to version 1.1.14
+  * Fixed implementation of initgroups()
+  * Fixed implementation of getgrouplist()
+  * Avoid dclose(RTLD_NEXT)
+
+-------------------------------------------------------------------

Old:
----
  nss_wrapper-1.1.13.tar.gz
  nss_wrapper-1.1.13.tar.gz.asc

New:
----
  nss_wrapper-1.1.15.tar.gz
  nss_wrapper-1.1.15.tar.gz.asc

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ nss_wrapper.spec ++++++
--- /var/tmp/diff_new_pack.9zP28N/_old  2023-01-26 14:04:30.182250213 +0100
+++ /var/tmp/diff_new_pack.9zP28N/_new  2023-01-26 14:04:30.186250235 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package nss_wrapper
 #
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -23,7 +23,7 @@
 #
 ############################# NOTE ##################################
 Name:           nss_wrapper
-Version:        1.1.13
+Version:        1.1.15
 Release:        0
 Summary:        A wrapper for the user, group and hosts NSS API
 License:        BSD-3-Clause

++++++ nss_wrapper-1.1.13.tar.gz -> nss_wrapper-1.1.15.tar.gz ++++++
Binary files 
old/nss_wrapper-1.1.13/.cache/clangd/index/nss_nwrap.c.6CD8D6240BEF45A7.idx and 
new/nss_wrapper-1.1.15/.cache/clangd/index/nss_nwrap.c.6CD8D6240BEF45A7.idx 
differ
Binary files 
old/nss_wrapper-1.1.13/.cache/clangd/index/nss_utils.c.D245051A87648149.idx and 
new/nss_wrapper-1.1.15/.cache/clangd/index/nss_utils.c.D245051A87648149.idx 
differ
Binary files 
old/nss_wrapper-1.1.13/.cache/clangd/index/nss_utils.h.BFE4622C993130F2.idx and 
new/nss_wrapper-1.1.15/.cache/clangd/index/nss_utils.h.BFE4622C993130F2.idx 
differ
Binary files 
old/nss_wrapper-1.1.13/.cache/clangd/index/nss_wrapper.c.496306141B70693D.idx 
and 
new/nss_wrapper-1.1.15/.cache/clangd/index/nss_wrapper.c.496306141B70693D.idx 
differ
Binary files 
old/nss_wrapper-1.1.13/.cache/clangd/index/test_initgroups.c.96654DF285FBEEBF.idx
 and 
new/nss_wrapper-1.1.15/.cache/clangd/index/test_initgroups.c.96654DF285FBEEBF.idx
 differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nss_wrapper-1.1.13/.clang-format 
new/nss_wrapper-1.1.15/.clang-format
--- old/nss_wrapper-1.1.13/.clang-format        1970-01-01 01:00:00.000000000 
+0100
+++ new/nss_wrapper-1.1.15/.clang-format        2023-01-25 12:09:01.000000000 
+0100
@@ -0,0 +1,26 @@
+# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
+BasedOnStyle: LLVM
+IndentWidth: 8
+ContinuationIndentWidth: 8
+UseTab: true
+BreakBeforeBraces: Custom
+BraceWrapping:
+    AfterEnum: false
+    AfterFunction: true
+    AfterStruct: false
+    AfterUnion: false
+    AfterExternBlock: true
+    BeforeElse: false
+    BeforeWhile: false
+AllowShortIfStatementsOnASingleLine: false
+ColumnLimit: 80
+IndentCaseLabels: false
+AlignAfterOpenBracket: Align
+BinPackParameters: false
+BinPackArguments: false
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowAllArgumentsOnNextLine: false
+AllowShortFunctionsOnASingleLine: Empty
+AlwaysBreakAfterReturnType: None
+AlignEscapedNewlines: Left
+SortIncludes: false
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nss_wrapper-1.1.13/CHANGELOG 
new/nss_wrapper-1.1.15/CHANGELOG
--- old/nss_wrapper-1.1.13/CHANGELOG    2022-11-09 07:45:15.000000000 +0100
+++ new/nss_wrapper-1.1.15/CHANGELOG    2023-01-25 16:41:17.000000000 +0100
@@ -1,6 +1,15 @@
 ChangeLog
 ==========
 
+version 1.1.15 (released 2023-01-25)
+  * Fixed linking issue in tests
+  * Fixed a memory leak in tests
+
+version 1.1.14 (released 2023-01-25)
+  * Fixed implementation of initgroups()
+  * Fixed implementation of getgrouplist()
+  * Avoid dclose(RTLD_NEXT)
+
 version 1.1.13 (released 2022-10-09)
   * Fixed possible mutex and threading issues
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nss_wrapper-1.1.13/CMakeLists.txt 
new/nss_wrapper-1.1.15/CMakeLists.txt
--- old/nss_wrapper-1.1.13/CMakeLists.txt       2022-11-09 07:45:15.000000000 
+0100
+++ new/nss_wrapper-1.1.15/CMakeLists.txt       2023-01-25 16:41:17.000000000 
+0100
@@ -11,7 +11,7 @@
 include(DefineCMakeDefaults)
 include(DefineCompilerFlags)
 
-project(nss_wrapper VERSION 1.1.13 LANGUAGES C)
+project(nss_wrapper VERSION 1.1.15 LANGUAGES C)
 
 # global needed variables
 set(APPLICATION_NAME ${PROJECT_NAME})
@@ -25,7 +25,7 @@
 #     Increment PATCH.
 set(LIBRARY_VERSION_MAJOR 0)
 set(LIBRARY_VERSION_MINOR 3)
-set(LIBRARY_VERSION_PATCH 3)
+set(LIBRARY_VERSION_PATCH 4)
 set(LIBRARY_VERSION 
"${LIBRARY_VERSION_MAJOR}.${LIBRARY_VERSION_MINOR}.${LIBRARY_VERSION_PATCH}")
 set(LIBRARY_SOVERSION ${LIBRARY_VERSION_MAJOR})
 
@@ -84,6 +84,9 @@
 )
 
 # cmake config files
+set(PACKAGE_NAME nss_wrapper)
+set(PACKAGE_NAME_UPPER NSS_WRAPPER)
+
 configure_file(nss_wrapper-config-version.cmake.in 
${CMAKE_CURRENT_BINARY_DIR}/nss_wrapper-config-version.cmake @ONLY)
 configure_file(nss_wrapper-config.cmake.in 
${CMAKE_CURRENT_BINARY_DIR}/nss_wrapper-config.cmake @ONLY)
 install(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nss_wrapper-1.1.13/nss_wrapper-config-version.cmake.in 
new/nss_wrapper-1.1.15/nss_wrapper-config-version.cmake.in
--- old/nss_wrapper-1.1.13/nss_wrapper-config-version.cmake.in  2020-03-17 
18:23:32.000000000 +0100
+++ new/nss_wrapper-1.1.15/nss_wrapper-config-version.cmake.in  2023-01-25 
12:09:01.000000000 +0100
@@ -1,11 +1,40 @@
 set(PACKAGE_VERSION @PROJECT_VERSION@)
 
-# Check whether the requested PACKAGE_FIND_VERSION is compatible
-if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
-    set(PACKAGE_VERSION_COMPATIBLE FALSE)
+if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
+  set(PACKAGE_VERSION_COMPATIBLE FALSE)
 else()
-    set(PACKAGE_VERSION_COMPATIBLE TRUE)
-    if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
-        set(PACKAGE_VERSION_EXACT TRUE)
+  if(${PACKAGE_VERSION} MATCHES "^([0-9]+)\\.")
+    set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}")
+    if(NOT CVF_VERSION_MAJOR VERSION_EQUAL 0)
+      string(REGEX REPLACE "^0+" "" CVF_VERSION_MAJOR "${CVF_VERSION_MAJOR}")
     endif()
+  else()
+    set(CVF_VERSION_MAJOR ${PACKAGE_VERSION})
+  endif()
+
+  if(PACKAGE_FIND_VERSION_RANGE)
+    # both endpoints of the range must have the expected major version
+    math (EXPR CVF_VERSION_MAJOR_NEXT "${CVF_VERSION_MAJOR} + 1")
+    if (NOT PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR
+        OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND NOT 
PACKAGE_FIND_VERSION_MAX_MAJOR STREQUAL CVF_VERSION_MAJOR)
+          OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND NOT 
PACKAGE_FIND_VERSION_MAX VERSION_LESS_EQUAL CVF_VERSION_MAJOR_NEXT)))
+      set(PACKAGE_VERSION_COMPATIBLE FALSE)
+    elseif(PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR
+        AND ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND 
PACKAGE_VERSION VERSION_LESS_EQUAL PACKAGE_FIND_VERSION_MAX)
+        OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND 
PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MAX)))
+      set(PACKAGE_VERSION_COMPATIBLE TRUE)
+    else()
+      set(PACKAGE_VERSION_COMPATIBLE FALSE)
+    endif()
+  else()
+    if(PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR)
+      set(PACKAGE_VERSION_COMPATIBLE TRUE)
+    else()
+      set(PACKAGE_VERSION_COMPATIBLE FALSE)
+    endif()
+
+    if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
+      set(PACKAGE_VERSION_EXACT TRUE)
+    endif()
+  endif()
 endif()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nss_wrapper-1.1.13/nss_wrapper-config.cmake.in 
new/nss_wrapper-1.1.15/nss_wrapper-config.cmake.in
--- old/nss_wrapper-1.1.13/nss_wrapper-config.cmake.in  2020-03-17 
18:23:32.000000000 +0100
+++ new/nss_wrapper-1.1.15/nss_wrapper-config.cmake.in  2023-01-25 
12:09:01.000000000 +0100
@@ -1 +1,14 @@
-set(NSS_WRAPPER_LIBRARY @CMAKE_INSTALL_FULL_LIBDIR@/@NSS_WRAPPER_LIB@)
+set(@PACKAGE_NAME_UPPER@_LIBRARY @CMAKE_INSTALL_FULL_LIBDIR@/@NSS_WRAPPER_LIB@)
+
+# Load information for each installed configuration.
+file(GLOB _cmake_config_files 
"${CMAKE_CURRENT_LIST_DIR}/@PACKAGE_NAME@-config-*.cmake")
+foreach(_cmake_config_file IN LISTS _cmake_config_files)
+    include("${_cmake_config_file}")
+endforeach()
+unset(_cmake_config_files)
+unset(_cmake_config_file)
+
+include(FindPackageMessage)
+find_package_message(@PACKAGE_NAME@
+                     "Found @PACKAGE_NAME@: ${@PACKAGE_NAME_UPPER@_LIBRARY} 
(version \"${PACKAGE_VERSION}\")"
+                     "[${@PACKAGE_NAME_UPPER@_LIBRARY}][${PACKAGE_VERSION}]")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nss_wrapper-1.1.13/src/CMakeLists.txt 
new/nss_wrapper-1.1.15/src/CMakeLists.txt
--- old/nss_wrapper-1.1.13/src/CMakeLists.txt   2020-03-17 18:23:32.000000000 
+0100
+++ new/nss_wrapper-1.1.15/src/CMakeLists.txt   2023-01-25 13:25:00.000000000 
+0100
@@ -1,5 +1,10 @@
 project(libnss_wrapper C)
 
+add_library(nss_utils STATIC nss_utils.c)
+target_compile_options(nss_utils
+                       PRIVATE
+                          ${DEFAULT_C_COMPILE_FLAGS})
+
 add_library(nss_wrapper SHARED nss_wrapper.c)
 target_compile_options(nss_wrapper
                        PRIVATE
@@ -12,7 +17,7 @@
 target_include_directories(nss_wrapper
                            PRIVATE
                                ${CMAKE_BINARY_DIR})
-target_link_libraries(nss_wrapper ${NWRAP_REQUIRED_LIBRARIES} 
${CMAKE_THREAD_LIBS_INIT})
+target_link_libraries(nss_wrapper nss_utils ${NWRAP_REQUIRED_LIBRARIES} 
${CMAKE_THREAD_LIBS_INIT})
 
 set_target_properties(
   nss_wrapper
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nss_wrapper-1.1.13/src/nss_utils.c 
new/nss_wrapper-1.1.15/src/nss_utils.c
--- old/nss_wrapper-1.1.13/src/nss_utils.c      1970-01-01 01:00:00.000000000 
+0100
+++ new/nss_wrapper-1.1.15/src/nss_utils.c      2023-01-25 12:09:01.000000000 
+0100
@@ -0,0 +1,131 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2007,      Stefan Metzmacher <[email protected]>
+ * Copyright (c) 2009,      Guenther Deschner <[email protected]>
+ * Copyright (c) 2014-2015, Michael Adam <[email protected]>
+ * Copyright (c) 2015,      Robin Hack <[email protected]>
+ * Copyright (c) 2013-2018, Andreas Schneider <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the author nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <grp.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "nss_utils.h"
+
+int nwrap_gr_copy_r(const struct group *src, struct group *dst,
+                   char *buf, size_t buflen, struct group **dstp)
+{
+       char *p = NULL;
+       uintptr_t align = 0;
+       unsigned int gr_mem_cnt = 0;
+       unsigned i;
+       size_t total_len;
+       size_t gr_name_len = strlen(src->gr_name) + 1;
+       size_t gr_passwd_len = strlen(src->gr_passwd) + 1;
+       union {
+               char *ptr;
+               char **data;
+       } g_mem;
+
+       for (i = 0; src->gr_mem[i] != NULL; i++) {
+               gr_mem_cnt++;
+       }
+
+       /* Align the memory for storing pointers */
+       align = __alignof__(char *) - ((p - (char *)0) % __alignof__(char *));
+       total_len = align +
+                   (1 + gr_mem_cnt) * sizeof(char *) +
+                   gr_name_len + gr_passwd_len;
+
+       if (total_len > buflen) {
+               errno = ERANGE;
+               return -1;
+       }
+       buflen -= total_len;
+
+       /* gr_mem */
+       p = buf + align;
+       g_mem.ptr = p;
+       dst->gr_mem = g_mem.data;
+
+       /* gr_name */
+       p += (1 + gr_mem_cnt) * sizeof(char *);
+       dst->gr_name = p;
+
+       /* gr_passwd */
+       p += gr_name_len;
+       dst->gr_passwd = p;
+
+       /* gr_mem[x] */
+       p += gr_passwd_len;
+
+       /* gr_gid */
+       dst->gr_gid = src->gr_gid;
+
+       memcpy(dst->gr_name, src->gr_name, gr_name_len);
+
+       memcpy(dst->gr_passwd, src->gr_passwd, gr_passwd_len);
+
+       /* Set the terminating entry */
+       dst->gr_mem[gr_mem_cnt] = NULL;
+
+       /* Now add the group members content */
+       total_len = 0;
+       for (i = 0; i < gr_mem_cnt; i++) {
+               size_t len = strlen(src->gr_mem[i]) + 1;
+
+               dst->gr_mem[i] = p;
+               total_len += len;
+               p += len;
+       }
+
+       if (total_len > buflen) {
+               errno = ERANGE;
+               return -1;
+       }
+
+       for (i = 0; i < gr_mem_cnt; i++) {
+               size_t len = strlen(src->gr_mem[i]) + 1;
+
+               memcpy(dst->gr_mem[i],
+                      src->gr_mem[i],
+                      len);
+       }
+
+       if (dstp != NULL) {
+               *dstp = dst;
+       }
+
+       return 0;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nss_wrapper-1.1.13/src/nss_utils.h 
new/nss_wrapper-1.1.15/src/nss_utils.h
--- old/nss_wrapper-1.1.13/src/nss_utils.h      1970-01-01 01:00:00.000000000 
+0100
+++ new/nss_wrapper-1.1.15/src/nss_utils.h      2023-01-25 12:09:01.000000000 
+0100
@@ -0,0 +1,46 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2007,      Stefan Metzmacher <[email protected]>
+ * Copyright (c) 2009,      Guenther Deschner <[email protected]>
+ * Copyright (c) 2014-2015, Michael Adam <[email protected]>
+ * Copyright (c) 2015,      Robin Hack <[email protected]>
+ * Copyright (c) 2013-2018, Andreas Schneider <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the author nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef NSS_UTILS_H
+#define NSS_UTILS_H
+#include <grp.h>
+
+int nwrap_gr_copy_r(const struct group *src, struct group *dst,
+                   char *buf, size_t buflen, struct group **dstp);
+
+#endif //NSS_UTILS_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nss_wrapper-1.1.13/src/nss_wrapper.c 
new/nss_wrapper-1.1.15/src/nss_wrapper.c
--- old/nss_wrapper-1.1.13/src/nss_wrapper.c    2022-11-09 07:45:15.000000000 
+0100
+++ new/nss_wrapper-1.1.15/src/nss_wrapper.c    2023-01-25 12:09:01.000000000 
+0100
@@ -54,12 +54,14 @@
 #include <string.h>
 #include <unistd.h>
 #include <ctype.h>
+#include <limits.h>
 
 #include <netinet/in.h>
 
 #include <search.h>
 #include <assert.h>
 
+#include "nss_utils.h"
 /*
  * Defining _POSIX_PTHREAD_SEMANTICS before including pwd.h and grp.h  gives us
  * the posix getpwnam_r(), getpwuid_r(), getgrnam_r and getgrgid_r calls on
@@ -177,6 +179,9 @@
 #define NWRAP_INET_ADDRSTRLEN INET_ADDRSTRLEN
 #endif
 
+#define MAX(a,b) ((a) < (b) ? (b) : (a))
+#define MIN(a,b) ((a) > (b) ? (b) : (a))
+
 static bool nwrap_initialized = false;
 static pthread_mutex_t nwrap_initialized_mutex = PTHREAD_MUTEX_INITIALIZER;
 
@@ -516,7 +521,7 @@
                                       size_t buflen,
                                       int *errnop);
 typedef NSS_STATUS (*__nss_endpwent)(void);
-typedef NSS_STATUS (*__nss_initgroups)(const char *user,
+typedef NSS_STATUS (*__nss_initgroups_dyn)(const char *user,
                                       gid_t group,
                                       long int *start,
                                       long int *size,
@@ -568,7 +573,7 @@
        NWRAP_NSS_MODULE_SYMBOL_ENTRY(getpwent_r);
        NWRAP_NSS_MODULE_SYMBOL_ENTRY(endpwent);
 
-       NWRAP_NSS_MODULE_SYMBOL_ENTRY(initgroups);
+       NWRAP_NSS_MODULE_SYMBOL_ENTRY(initgroups_dyn);
        NWRAP_NSS_MODULE_SYMBOL_ENTRY(getgrnam_r);
        NWRAP_NSS_MODULE_SYMBOL_ENTRY(getgrgid_r);
        NWRAP_NSS_MODULE_SYMBOL_ENTRY(setgrent);
@@ -606,8 +611,14 @@
                                         struct passwd *pwdst, char *buf,
                                         size_t buflen, struct passwd **pwdstp);
        void            (*nw_endpwent)(struct nwrap_backend *b);
-       int             (*nw_initgroups)(struct nwrap_backend *b,
-                                        const char *user, gid_t group);
+       int             (*nw_initgroups_dyn)(struct nwrap_backend *b,
+                                            const char *user,
+                                            gid_t group,
+                                            long int *start,
+                                            long int *size,
+                                            gid_t **groups,
+                                            long int limit,
+                                            int *errnop);
        struct group *  (*nw_getgrnam)(struct nwrap_backend *b,
                                       const char *name);
        int             (*nw_getgrnam_r)(struct nwrap_backend *b,
@@ -663,8 +674,14 @@
                                  struct passwd *pwdst, char *buf,
                                  size_t buflen, struct passwd **pwdstp);
 static void nwrap_files_endpwent(struct nwrap_backend *b);
-static int nwrap_files_initgroups(struct nwrap_backend *b,
-                                 const char *user, gid_t group);
+static int nwrap_files_initgroups_dyn(struct nwrap_backend *b,
+                                     const char *user,
+                                     gid_t group,
+                                     long int *start,
+                                     long int *size,
+                                     gid_t **groups,
+                                     long int limit,
+                                     int *errnop);
 static struct group *nwrap_files_getgrnam(struct nwrap_backend *b,
                                          const char *name);
 static int nwrap_files_getgrnam_r(struct nwrap_backend *b,
@@ -730,8 +747,14 @@
                                   char *buf, size_t buflen, struct group 
**grdstp);
 static void nwrap_module_setgrent(struct nwrap_backend *b);
 static void nwrap_module_endgrent(struct nwrap_backend *b);
-static int nwrap_module_initgroups(struct nwrap_backend *b,
-                                  const char *user, gid_t group);
+static int nwrap_module_initgroups_dyn(struct nwrap_backend *b,
+                                      const char *user,
+                                      gid_t group,
+                                      long int *start,
+                                      long int *size,
+                                      gid_t **groups,
+                                      long int limit,
+                                      int *errnop);
 static struct hostent *nwrap_module_gethostbyaddr(struct nwrap_backend *b,
                                                  const void *addr,
                                                  socklen_t len, int type);
@@ -754,7 +777,7 @@
        .nw_getpwent    = nwrap_files_getpwent,
        .nw_getpwent_r  = nwrap_files_getpwent_r,
        .nw_endpwent    = nwrap_files_endpwent,
-       .nw_initgroups  = nwrap_files_initgroups,
+       .nw_initgroups_dyn      = nwrap_files_initgroups_dyn,
        .nw_getgrnam    = nwrap_files_getgrnam,
        .nw_getgrnam_r  = nwrap_files_getgrnam_r,
        .nw_getgrgid    = nwrap_files_getgrgid,
@@ -780,7 +803,7 @@
        .nw_getpwent    = nwrap_module_getpwent,
        .nw_getpwent_r  = nwrap_module_getpwent_r,
        .nw_endpwent    = nwrap_module_endpwent,
-       .nw_initgroups  = nwrap_module_initgroups,
+       .nw_initgroups_dyn      = nwrap_module_initgroups_dyn,
        .nw_getgrnam    = nwrap_module_getgrnam,
        .nw_getgrnam_r  = nwrap_module_getgrnam_r,
        .nw_getgrgid    = nwrap_module_getgrgid,
@@ -820,6 +843,14 @@
                               struct addrinfo **pai,
                               bool skip_canonname);
 
+#ifdef HAVE_GETGROUPLIST
+static int nwrap_getgrouplist(const char *user,
+                             gid_t group,
+                             long int *size,
+                             gid_t **groupsp,
+                             long int limit);
+#endif
+
 /*
  * VECTORS
  */
@@ -1826,7 +1857,7 @@
        nwrap_nss_module_bind_symbol(setpwent);
        nwrap_nss_module_bind_symbol(getpwent_r);
        nwrap_nss_module_bind_symbol(endpwent);
-       nwrap_nss_module_bind_symbol2(initgroups, initgroups_dyn);
+       nwrap_nss_module_bind_symbol(initgroups_dyn);
        nwrap_nss_module_bind_symbol(getgrnam_r);
        nwrap_nss_module_bind_symbol(getgrgid_r);
        nwrap_nss_module_bind_symbol(setgrent);
@@ -2983,93 +3014,6 @@
        nwrap_gr->idx = 0;
 }
 
-static int nwrap_gr_copy_r(const struct group *src, struct group *dst,
-                          char *buf, size_t buflen, struct group **dstp)
-{
-       char *p = NULL;
-       uintptr_t align = 0;
-       unsigned int gr_mem_cnt = 0;
-       unsigned i;
-       size_t total_len;
-       size_t gr_name_len = strlen(src->gr_name) + 1;
-       size_t gr_passwd_len = strlen(src->gr_passwd) + 1;
-       union {
-               char *ptr;
-               char **data;
-       } g_mem;
-
-       for (i = 0; src->gr_mem[i] != NULL; i++) {
-               gr_mem_cnt++;
-       }
-
-       /* Align the memory for storing pointers */
-       align = __alignof__(char *) - ((p - (char *)0) % __alignof__(char *));
-       total_len = align +
-                   (1 + gr_mem_cnt) * sizeof(char *) +
-                   gr_name_len + gr_passwd_len;
-
-       if (total_len > buflen) {
-               errno = ERANGE;
-               return -1;
-       }
-       buflen -= total_len;
-
-       /* gr_mem */
-       p = buf + align;
-       g_mem.ptr = p;
-       dst->gr_mem = g_mem.data;
-
-       /* gr_name */
-       p += (1 + gr_mem_cnt) * sizeof(char *);
-       dst->gr_name = p;
-
-       /* gr_passwd */
-       p += gr_name_len;
-       dst->gr_passwd = p;
-
-       /* gr_mem[x] */
-       p += gr_passwd_len;
-
-       /* gr_gid */
-       dst->gr_gid = src->gr_gid;
-
-       memcpy(dst->gr_name, src->gr_name, gr_name_len);
-
-       memcpy(dst->gr_passwd, src->gr_passwd, gr_passwd_len);
-
-       /* Set the terminating entry */
-       dst->gr_mem[gr_mem_cnt] = NULL;
-
-       /* Now add the group members content */
-       total_len = 0;
-       for (i = 0; i < gr_mem_cnt; i++) {
-               size_t len = strlen(src->gr_mem[i]) + 1;
-
-               dst->gr_mem[i] = p;
-               total_len += len;
-               p += len;
-       }
-
-       if (total_len > buflen) {
-               errno = ERANGE;
-               return -1;
-       }
-
-       for (i = 0; i < gr_mem_cnt; i++) {
-               size_t len = strlen(src->gr_mem[i]) + 1;
-
-               memcpy(dst->gr_mem[i],
-                      src->gr_mem[i],
-                      len);
-       }
-
-       if (dstp != NULL) {
-               *dstp = dst;
-       }
-
-       return 0;
-}
-
 static struct nwrap_entlist *nwrap_entlist_init(struct nwrap_entdata *ed)
 {
        struct nwrap_entlist *el;
@@ -3691,27 +3635,21 @@
 #endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */
 
 /* misc functions */
-static int nwrap_files_initgroups(struct nwrap_backend *b,
-                                 const char *user,
-                                 gid_t group)
+static int nwrap_files_initgroups_dyn(struct nwrap_backend *b,
+                                     const char *user,
+                                     gid_t group,
+                                     long int *start,
+                                     long int *size,
+                                     gid_t **groups,
+                                     long int limit,
+                                     int *errnop)
 {
        struct group *grp;
-       gid_t *groups;
-       int size = 1;
-       int rc;
-
-       groups = (gid_t *)malloc(size * sizeof(gid_t));
-       if (groups == NULL) {
-               NWRAP_LOG(NWRAP_LOG_ERROR, "Out of memory");
-               errno = ENOMEM;
-               return -1;
-       }
-       groups[0] = group;
+       int i = 0;
 
+       (void)errnop; /* unused */
        nwrap_files_setgrent(b);
        while ((grp = nwrap_files_getgrent(b)) != NULL) {
-               int i = 0;
-
                NWRAP_LOG(NWRAP_LOG_DEBUG,
                          "Inspecting %s for group membership",
                          grp->gr_name);
@@ -3724,33 +3662,31 @@
                                          user,
                                          grp->gr_name);
 
-                               groups = (gid_t *)realloc(groups,
-                                                         (size + 1) * 
sizeof(gid_t));
-                               if (groups == NULL) {
-                                       NWRAP_LOG(NWRAP_LOG_ERROR,
-                                                 "Out of memory");
-                                       errno = ENOMEM;
-                                       return -1;
+                               if (*start == *size) {
+                                       long int newsize;
+                                       gid_t *newgroups;
+
+                                       newsize = 2 * (*size);
+                                       if (limit > 0 && newsize > limit) {
+                                               newsize = MAX(limit, *size);
+                                       }
+                                       newgroups = (gid_t *) realloc((*groups),
+                                                       newsize * 
sizeof(**groups));
+                                       if (!newgroups) {
+                                               errno = ENOMEM;
+                                               return -1;
+                                       }
+                                       *groups = newgroups;
+                                       *size = newsize;
                                }
-
-                               groups[size] = grp->gr_gid;
-                               size++;
+                               (*groups)[*start] = grp->gr_gid;
+                               (*start)++;
                        }
                }
        }
 
        nwrap_files_endgrent(b);
-
-       NWRAP_LOG(NWRAP_LOG_DEBUG,
-                 "%s is member of %d groups",
-                 user, size);
-
-       /* This really only works if uid_wrapper is loaded */
-       rc = setgroups(size, groups);
-
-       free(groups);
-
-       return rc;
+       return *start;
 }
 
 /* group functions */
@@ -4587,24 +4523,26 @@
        b->symbols->_nss_endpwent.f();
 }
 
-static int nwrap_module_initgroups(struct nwrap_backend *b,
-                                  const char *user, gid_t group)
+static int nwrap_module_initgroups_dyn(struct nwrap_backend *b,
+                                      const char *user,
+                                      gid_t group,
+                                      long int *start,
+                                      long int *size,
+                                      gid_t **groups,
+                                      long int limit,
+                                      int *errnop)
 {
-       gid_t *groups;
-       long int start;
-       long int size;
-
-       if (b->symbols->_nss_initgroups.f == NULL) {
+       if (b->symbols->_nss_initgroups_dyn.f == NULL) {
                return NSS_STATUS_UNAVAIL;
        }
 
-       return b->symbols->_nss_initgroups.f(user,
+       return b->symbols->_nss_initgroups_dyn.f(user,
                                             group,
-                                            &start,
-                                            &size,
-                                            &groups,
-                                            0,
-                                            &errno);
+                                            start,
+                                            size,
+                                            groups,
+                                            limit,
+                                            errnop);
 }
 
 static struct group *nwrap_module_getgrnam(struct nwrap_backend *b,
@@ -5305,20 +5243,49 @@
 
 static int nwrap_initgroups(const char *user, gid_t group)
 {
-       size_t i;
+#if defined(NGROUPS_MAX) && NGROUPS_MAX == 0
+       /* No extra groups allowed.  */
+       return 0;
+#elif !defined(HAVE_GETGROUPLIST)
+       return 0;
+#else
+       long int size;
+       long int limit;
+       gid_t *groups;
+       int ngroups;
+       int result;
+       const char *env = getenv("UID_WRAPPER");
 
-       for (i=0; i < nwrap_main_global->num_backends; i++) {
-               struct nwrap_backend *b = &nwrap_main_global->backends[i];
-               int rc;
+       if (env == NULL || env[0] != '1') {
+               NWRAP_LOG(NWRAP_LOG_WARN,
+                         "initgroups() requires uid_wrapper to work!");
+               return 0;
+       }
 
-               rc = b->ops->nw_initgroups(b, user, group);
-               if (rc == 0) {
-                       return 0;
-               }
+       limit = sysconf(_SC_NGROUPS_MAX);
+       if (limit > 0) {
+               size = MIN(limit, 64);
+       } else {
+               size = 16;
        }
 
-       errno = ENOENT;
-       return -1;
+       groups = (gid_t *)malloc(size * sizeof(gid_t));
+       if (groups == NULL) {
+               /* No more memory.  */
+               return -1;
+       }
+
+       ngroups = nwrap_getgrouplist(user, group, &size, &groups, limit);
+
+       /* Try to set the maximum number of groups the kernel can handle.  */
+       do {
+               result = setgroups(ngroups, groups);
+       } while (result == -1 && errno == EINVAL && --ngroups > 0);
+
+       free(groups);
+
+       return result;
+#endif
 }
 
 int initgroups(const char *user, gid_t group)
@@ -5616,81 +5583,85 @@
  ***************************************************************************/
 
 #ifdef HAVE_GETGROUPLIST
-static int nwrap_getgrouplist(const char *user, gid_t group,
-                             gid_t *groups, int *ngroups)
-{
-       struct group *grp;
-       gid_t *groups_tmp;
-       int count = 1;
-
-       NWRAP_LOG(NWRAP_LOG_DEBUG, "getgrouplist called for %s", user);
-
-       groups_tmp = (gid_t *)malloc(count * sizeof(gid_t));
-       if (!groups_tmp) {
-               NWRAP_LOG(NWRAP_LOG_ERROR, "Out of memory");
-               errno = ENOMEM;
-               return -1;
-       }
-       groups_tmp[0] = group;
-
-       nwrap_setgrent();
-       while ((grp = nwrap_getgrent()) != NULL) {
-               int i = 0;
-
-               NWRAP_LOG(NWRAP_LOG_DEBUG,
-                         "Inspecting %s for group membership",
-                         grp->gr_name);
-
-               for (i=0; grp->gr_mem && grp->gr_mem[i] != NULL; i++) {
+static int nwrap_getgrouplist(const char *user,
+                             gid_t group,
+                             long int *size,
+                             gid_t **groupsp,
+                             long int limit)
+{
+       enum nss_status status = NSS_STATUS_UNAVAIL;
+       /* Start is one, because we have the first group as parameter.  */
+       long int start = 1;
+       size_t i;
 
-                       if (group != grp->gr_gid &&
-                           (strcmp(user, grp->gr_mem[i]) == 0)) {
+       /* Never store more than the starting *SIZE number of elements.  */
+       assert(*size > 0);
+       (*groupsp)[0] = group;
 
-                               NWRAP_LOG(NWRAP_LOG_DEBUG,
-                                         "%s is member of %s",
-                                         user,
-                                         grp->gr_name);
+       for (i = 0; i < nwrap_main_global->num_backends; i++) {
+               struct nwrap_backend *b = &nwrap_main_global->backends[i];
+               long int prev_start = start;
+               long int cnt = prev_start;
 
-                               groups_tmp = (gid_t *)realloc(groups_tmp, 
(count + 1) * sizeof(gid_t));
-                               if (!groups_tmp) {
-                                       NWRAP_LOG(NWRAP_LOG_ERROR,
-                                                 "Out of memory");
-                                       errno = ENOMEM;
-                                       return -1;
-                               }
-                               groups_tmp[count] = grp->gr_gid;
+               status = b->ops->nw_initgroups_dyn(b,
+                                                  user,
+                                                  group,
+                                                  &start,
+                                                  size,
+                                                  groupsp,
+                                                  limit,
+                                                  &errno);
+
+               /* Remove duplicates.  */
+               while (cnt < start) {
+                       long int inner;
+                       for (inner = 0; inner < prev_start; ++inner)
+                               if ((*groupsp)[inner] == (*groupsp)[cnt])
+                                       break;
 
-                               count++;
-                       }
+                       if (inner < prev_start)
+                               (*groupsp)[cnt] = (*groupsp)[--start];
+                       else
+                               ++cnt;
                }
+               NWRAP_LOG(NWRAP_LOG_DEBUG,
+                         "Resource '%s' returned status=%d and increased "
+                         "count of groups to %ld",
+                         b->name,
+                         status,
+                         start);
        }
+       return start;
+}
 
-       nwrap_endgrent();
+int getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups)
+{
+       long int size;
+       int total, retval;
+       gid_t *newgroups;
 
-       NWRAP_LOG(NWRAP_LOG_DEBUG,
-                 "%s is member of %d groups",
-                 user, *ngroups);
+       if (!nss_wrapper_enabled()) {
+               return libc_getgrouplist(user, group, groups, ngroups);
+       }
 
-       if (*ngroups < count) {
-               *ngroups = count;
-               free(groups_tmp);
+       size = MAX(1, *ngroups);
+       newgroups = (gid_t *)malloc(size * sizeof(gid_t));
+       if (newgroups == NULL) {
                return -1;
        }
 
-       *ngroups = count;
-       memcpy(groups, groups_tmp, count * sizeof(gid_t));
-       free(groups_tmp);
+       total = nwrap_getgrouplist(user, group, &size, &newgroups, -1);
 
-       return count;
-}
-
-int getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups)
-{
-       if (!nss_wrapper_enabled()) {
-               return libc_getgrouplist(user, group, groups, ngroups);
+       if (groups != NULL) {
+               memcpy(groups, newgroups, MIN(*ngroups, total) * sizeof(gid_t));
        }
 
-       return nwrap_getgrouplist(user, group, groups, ngroups);
+       free(newgroups);
+
+       retval = total > *ngroups ? -1 : total;
+       *ngroups = total;
+
+       return retval;
 }
 #endif
 
@@ -6499,13 +6470,25 @@
 
                /* libc */
                if (m->libc != NULL) {
-                       if (m->libc->handle != NULL) {
+                       if (m->libc->handle != NULL
+#ifdef RTLD_NEXT
+                           && m->libc->handle != RTLD_NEXT
+#endif
+                          ) {
                                dlclose(m->libc->handle);
                        }
-                       if (m->libc->nsl_handle != NULL) {
+                       if (m->libc->nsl_handle != NULL
+#ifdef RTLD_NEXT
+                           && m->libc->nsl_handle != RTLD_NEXT
+#endif
+                          ) {
                                dlclose(m->libc->nsl_handle);
                        }
-                       if (m->libc->sock_handle != NULL) {
+                       if (m->libc->sock_handle != NULL
+#ifdef RTLD_NEXT
+                           && m->libc->sock_handle != RTLD_NEXT
+#endif
+                          ) {
                                dlclose(m->libc->sock_handle);
                        }
                        SAFE_FREE(m->libc);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nss_wrapper-1.1.13/tests/CMakeLists.txt 
new/nss_wrapper-1.1.15/tests/CMakeLists.txt
--- old/nss_wrapper-1.1.13/tests/CMakeLists.txt 2022-11-09 07:45:15.000000000 
+0100
+++ new/nss_wrapper-1.1.15/tests/CMakeLists.txt 2023-01-25 13:25:00.000000000 
+0100
@@ -1,6 +1,6 @@
 project(tests C)
 
-set(TESTSUITE_LIBRARIES ${NWRAP_REQUIRED_LIBRARIES} ${CMOCKA_LIBRARY})
+set(TESTSUITE_LIBRARIES nss_utils ${NWRAP_REQUIRED_LIBRARIES} 
${CMOCKA_LIBRARY})
 string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
 
 add_library(nss_nwrap SHARED nss_nwrap.c)
@@ -11,6 +11,7 @@
                            PRIVATE
                                ${CMAKE_BINARY_DIR}
                                ${CMOCKA_INCLUDE_DIR})
+target_link_libraries(nss_nwrap PRIVATE nss_utils)
 
 set(HOMEDIR ${CMAKE_CURRENT_BINARY_DIR})
 
@@ -19,6 +20,10 @@
 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 +31,8 @@
     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 +57,9 @@
     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 +69,10 @@
         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 +84,9 @@
 
         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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nss_wrapper-1.1.13/tests/group.in 
new/nss_wrapper-1.1.15/tests/group.in
--- old/nss_wrapper-1.1.13/tests/group.in       2019-02-15 16:39:32.000000000 
+0100
+++ new/nss_wrapper-1.1.15/tests/group.in       2023-01-25 12:09:01.000000000 
+0100
@@ -1,4 +1,5 @@
-users:x:1000:
+users:x:1000:alice,bob
+all:x:1002:alice,bob,nobody,root
 nobody:x:65533:
 nogroup:x:65534:nobody
 root:x:65532:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nss_wrapper-1.1.13/tests/nss_nwrap.c 
new/nss_wrapper-1.1.15/tests/nss_nwrap.c
--- old/nss_wrapper-1.1.13/tests/nss_nwrap.c    2020-04-02 13:37:22.000000000 
+0200
+++ new/nss_wrapper-1.1.15/tests/nss_nwrap.c    2023-01-25 12:09:01.000000000 
+0100
@@ -7,6 +7,9 @@
 #include <string.h>
 #include <pwd.h>
 #include <grp.h>
+#include <stdlib.h>
+
+#include "../src/nss_utils.h"
 
 #if defined(HAVE_NSS_H)
 /* Linux and BSD */
@@ -29,6 +32,14 @@
 # error "No nsswitch support detected"
 #endif
 
+#ifndef discard_const
+#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
+#endif
+
+#ifndef discard_const_p
+#define discard_const_p(type, ptr) ((type *)discard_const(ptr))
+#endif
+
 NSS_STATUS _nss_nwrap_setpwent(void);
 NSS_STATUS _nss_nwrap_endpwent(void);
 NSS_STATUS _nss_nwrap_getpwent_r(struct passwd *result, char *buffer,
@@ -39,12 +50,20 @@
                                   char *buffer, size_t buflen, int *errnop);
 NSS_STATUS _nss_nwrap_setgrent(void);
 NSS_STATUS _nss_nwrap_endgrent(void);
-NSS_STATUS _nss_nwrap_getgrent_r(struct group *result, char *buffer,
-                                size_t buflen, int *errnop);
-NSS_STATUS _nss_nwrap_getgrnam_r(const char *name, struct group *result,
-                                char *buffer, size_t buflen, int *errnop);
-NSS_STATUS _nss_nwrap_getgrgid_r(gid_t gid, struct group *result, char *buffer,
-                                size_t buflen, int *errnop);
+NSS_STATUS _nss_nwrap_getgrent_r(struct group *result,
+                                char *buffer,
+                                size_t buflen,
+                                struct group **grdstp);
+NSS_STATUS _nss_nwrap_getgrnam_r(const char *name,
+                                struct group *result,
+                                char *buffer,
+                                size_t buflen,
+                                struct group **grdstp);
+NSS_STATUS _nss_nwrap_getgrgid_r(gid_t gid,
+                                struct group *result,
+                                char *buffer,
+                                size_t buflen,
+                                struct group **grdstp);
 NSS_STATUS _nss_nwrap_initgroups_dyn(char *user, gid_t group, long int *start,
                                     long int *size, gid_t **groups,
                                     long int limit, int *errnop);
@@ -133,6 +152,7 @@
 NSS_STATUS _nss_nwrap_getpwuid_r(uid_t uid, struct passwd *result,
                                 char *buffer, size_t buflen, int *errnop)
 {
+       (void)errnop; /* unused */
        if (uid == 424242) {
                char buf[] = "hanswurst\0secret\0\0/home/hanswurst\0/bin/false";
                const struct passwd src = {
@@ -165,50 +185,116 @@
 
        return NSS_STATUS_UNAVAIL;
 }
+static int grent_idx = 0;
 
 NSS_STATUS _nss_nwrap_setgrent(void)
 {
-       return NSS_STATUS_UNAVAIL;
+       grent_idx = 0;
+       return NSS_STATUS_SUCCESS;
 }
 
 NSS_STATUS _nss_nwrap_endgrent(void)
 {
-       return NSS_STATUS_UNAVAIL;
+       grent_idx = 0;
+       return NSS_STATUS_SUCCESS;
 }
 
-NSS_STATUS _nss_nwrap_getgrent_r(struct group *result, char *buffer,
-                                size_t buflen, int *errnop)
-{
-       (void) result;
-       (void) buffer;
-       (void) buflen;
-       (void) errnop;
-
-       return NSS_STATUS_UNAVAIL;
+static const struct group gr0 = {
+       .gr_name = discard_const_p(char, "wb_group_0"),
+       .gr_passwd = discard_const_p(char, "x"),
+       .gr_gid = 100010,
+       .gr_mem = (char *[]) {
+               discard_const_p(char, "alice"),
+               discard_const_p(char, "bob"),
+               NULL
+       },
+};
+static const struct group gr1 = {
+       .gr_name = discard_const_p(char, "wb_group_1"),
+       .gr_passwd = discard_const_p(char, "x"),
+       .gr_gid = 100011,
+       .gr_mem = (char *[]) {
+               discard_const_p(char, "alice"),
+               discard_const_p(char, "bob"),
+               NULL
+       },
+};
+static const struct group gr2 = {
+       .gr_name = discard_const_p(char, "wb_group_2"),
+       .gr_passwd = discard_const_p(char, "x"),
+       .gr_gid = 100012,
+       .gr_mem = (char *[]) {
+               discard_const_p(char, "alice"),
+               NULL
+       },
+};
+
+NSS_STATUS _nss_nwrap_getgrent_r(struct group *result,
+                                char *buffer,
+                                size_t buflen,
+                                struct group **grdstp)
+{
+       switch (grent_idx) {
+               int ret;
+       case 0:
+               ret = nwrap_gr_copy_r(&gr0, result, buffer, buflen, grdstp);
+               grent_idx++;
+               return ret == 0 ? NSS_STATUS_SUCCESS : NSS_STATUS_TRYAGAIN;
+       case 1:
+               ret = nwrap_gr_copy_r(&gr1, result, buffer, buflen, grdstp);
+               grent_idx++;
+               return ret == 0 ? NSS_STATUS_SUCCESS : NSS_STATUS_TRYAGAIN;
+       case 2:
+               ret = nwrap_gr_copy_r(&gr2, result, buffer, buflen, grdstp);
+               grent_idx++;
+               return ret == 0 ? NSS_STATUS_SUCCESS : NSS_STATUS_TRYAGAIN;
+       default:
+               return NSS_STATUS_NOTFOUND;
+       }
 }
 
-NSS_STATUS _nss_nwrap_getgrnam_r(const char *name, struct group *result,
-                                char *buffer, size_t buflen, int *errnop)
-{
-       (void) name;
-       (void) result;
-       (void) buffer;
-       (void) buflen;
-       (void) errnop;
-
-       return NSS_STATUS_UNAVAIL;
+NSS_STATUS _nss_nwrap_getgrnam_r(const char *name,
+                                struct group *result,
+                                char *buffer,
+                                size_t buflen,
+                                struct group **grdstp)
+{
+       int ret;
+
+       if (strcmp(name, "wb_group_0") == 0) {
+               ret = nwrap_gr_copy_r(&gr0, result, buffer, buflen, grdstp);
+               return ret == 0 ? NSS_STATUS_SUCCESS : NSS_STATUS_TRYAGAIN;
+       } else if (strcmp(name, "wb_group_1") == 0) {
+               ret = nwrap_gr_copy_r(&gr1, result, buffer, buflen, grdstp);
+               return ret == 0 ? NSS_STATUS_SUCCESS : NSS_STATUS_TRYAGAIN;
+       } else if (strcmp(name, "wb_group_2") == 0) {
+               ret = nwrap_gr_copy_r(&gr2, result, buffer, buflen, grdstp);
+               return ret == 0 ? NSS_STATUS_SUCCESS : NSS_STATUS_TRYAGAIN;
+       } else {
+               return NSS_STATUS_NOTFOUND;
+       }
 }
 
-NSS_STATUS _nss_nwrap_getgrgid_r(gid_t gid, struct group *result, char *buffer,
-                                size_t buflen, int *errnop)
-{
-       (void) gid;
-       (void) result;
-       (void) buffer;
-       (void) buflen;
-       (void) errnop;
-
-       return NSS_STATUS_UNAVAIL;
+NSS_STATUS _nss_nwrap_getgrgid_r(gid_t gid,
+                                struct group *result,
+                                char *buffer,
+                                size_t buflen,
+                                struct group **grdstp)
+{
+       int ret;
+       switch (gid) {
+       case 100010:
+               ret = nwrap_gr_copy_r(&gr0, result, buffer, buflen, grdstp);
+               return ret == 0 ? NSS_STATUS_SUCCESS : NSS_STATUS_TRYAGAIN;
+       case 100011:
+               ret = nwrap_gr_copy_r(&gr1, result, buffer, buflen, grdstp);
+               return ret == 0 ? NSS_STATUS_SUCCESS : NSS_STATUS_TRYAGAIN;
+       case 100012:
+               ret = nwrap_gr_copy_r(&gr2, result, buffer, buflen, grdstp);
+               return ret == 0 ? NSS_STATUS_SUCCESS : NSS_STATUS_TRYAGAIN;
+       default:
+               return NSS_STATUS_NOTFOUND;
+       }
 }
 
 NSS_STATUS _nss_nwrap_initgroups_dyn(char *user, gid_t group, long int *start,
@@ -216,13 +302,40 @@
                                     long int limit, int *errnop)
 {
        (void) user;
-       (void) group;
-       (void) start;
-       (void) size;
-       (void) groups;
+       (void)group;
        (void) limit;
        (void) errnop;
 
-       return NSS_STATUS_UNAVAIL;
+       if (!(strcmp(user, "alice") == 0 || strcmp(user, "bob") == 0)) {
+               return NSS_STATUS_SUCCESS;
+       }
+
+       if (*start + 4 >= *size) {
+               long int newsize;
+               gid_t *newgroups;
+
+               newsize = *size + 4;
+               if (limit > 0) {
+                       if (newsize > limit) {
+                               return NSS_STATUS_NOTFOUND;
+                       }
+               }
+
+               newgroups =
+                       (gid_t *)realloc((*groups), newsize * sizeof(**groups));
+               if (!newgroups) {
+                       *errnop = ENOMEM;
+                       return NSS_STATUS_NOTFOUND;
+               }
+               *groups = newgroups;
+               *size = newsize;
+       }
+
+       (*groups)[(*start)++] = 100010;
+       (*groups)[(*start)++] = 100011;
+       if (strcmp(user, "alice") == 0) {
+               (*groups)[(*start)++] = 100012;
+       }
+       return NSS_STATUS_SUCCESS;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nss_wrapper-1.1.13/tests/test_initgroups.c 
new/nss_wrapper-1.1.15/tests/test_initgroups.c
--- old/nss_wrapper-1.1.13/tests/test_initgroups.c      1970-01-01 
01:00:00.000000000 +0100
+++ new/nss_wrapper-1.1.15/tests/test_initgroups.c      2023-01-25 
16:41:14.000000000 +0100
@@ -0,0 +1,53 @@
+#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]);
+               }
+               free(groups2);
+       }
+}
+
+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;
+}

Reply via email to