nss_wrapper-1.1.16/CPackConfig.cmake000644 001750 000144 00000003366 13641347314 017252 0ustar00asnusers000000 000000 # For help take a look at: # http://www.cmake.org/Wiki/CMake:CPackConfiguration ### general settings set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "The NSS wrapper library") set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md") set(CPACK_PACKAGE_VENDOR "The Samba Team") set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME}) set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE") ### versions set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}") ### source generator set(CPACK_SOURCE_GENERATOR "TGZ") set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]svn/;/[.]git/;.gitignore;/build*;/obj*;tags;cscope.*;compile_commands.json") set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}") if (WIN32) set(CPACK_GENERATOR "ZIP") ### nsis generator find_package(NSIS) if (NSIS_MAKE) set(CPACK_GENERATOR "${CPACK_GENERATOR};NSIS") set(CPACK_NSIS_DISPLAY_NAME "The SSH Library") set(CPACK_NSIS_COMPRESSOR "/SOLID zlib") set(CPACK_NSIS_MENU_LINKS "http://www.libssh.org/" "libssh homepage") endif (NSIS_MAKE) endif (WIN32) set(CPACK_PACKAGE_INSTALL_DIRECTORY "libssh") set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}) set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries") set(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C/C++ Headers") set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION "Libraries used to build programs which use libssh") set(CPACK_COMPONENT_HEADERS_DESCRIPTION "C/C++ header files for use with libssh") set(CPACK_COMPONENT_HEADERS_DEPENDS libraries) #set(CPACK_COMPONENT_APPLICATIONS_GROUP "Runtime") set(CPACK_COMPONENT_LIBRARIES_GROUP "Development") set(CPACK_COMPONENT_HEADERS_GROUP "Development") include(CPack) nss_wrapper-1.1.16/CMakeLists.txt000644 001750 000144 00000006734 14641727522 016707 0ustar00asnusers000000 000000 # Required cmake version cmake_minimum_required(VERSION 3.5.0) cmake_policy(SET CMP0048 NEW) # Specify search path for CMake modules to be loaded by include() # and find_package() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules") # Add defaults for cmake # Those need to be set before the project() call. include(DefineCMakeDefaults) include(DefineCompilerFlags) project(nss_wrapper VERSION 1.1.16 LANGUAGES C) # global needed variables set(APPLICATION_NAME ${PROJECT_NAME}) # SOVERSION scheme: MAJOR.MINOR.PATCH # If there was an incompatible interface change: # Increment MAJOR. Set MINOR and PATCH to 0 # If there was a compatible interface change: # Increment MINOR. Set PATCH to 0 # If the source code was changed, but there were no interface changes: # Increment PATCH. set(LIBRARY_VERSION_MAJOR 0) set(LIBRARY_VERSION_MINOR 3) set(LIBRARY_VERSION_PATCH 5) set(LIBRARY_VERSION "${LIBRARY_VERSION_MAJOR}.${LIBRARY_VERSION_MINOR}.${LIBRARY_VERSION_PATCH}") set(LIBRARY_SOVERSION ${LIBRARY_VERSION_MAJOR}) # add definitions include(DefineCMakeDefaults) include(DefinePlatformDefaults) include(DefineOptions.cmake) include(CPackConfig.cmake) include(CompilerChecks.cmake) include(GNUInstallDirs) # disallow in-source build include(MacroEnsureOutOfSourceBuild) macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out of source build. Please create a separate build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there.") # Find out if we have threading available set(CMAKE_THREAD_PREFER_PTHREADS ON) find_package(Threads) # config.h checks include(ConfigureChecks.cmake) configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) # check subdirectories add_subdirectory(src) install(PROGRAMS nss_wrapper.pl DESTINATION ${CMAKE_INSTALL_BINDIR}) if (UNIT_TESTING) find_package(cmocka 1.1.0 REQUIRED) file(TO_CMAKE_PATH "${CMAKE_SOURCE_DIR}/tests/valgrind.supp" VALGRIND_SUPPRESSION_FILE) # add the valgrind suppressions set(MEMORYCHECK_SUPPRESSIONS_FILE ${VALGRIND_SUPPRESSION_FILE} CACHE FILEPATH "Path to the memory checking command, used for memory error detection.") include(AddCMockaTest) add_subdirectory(tests) endif (UNIT_TESTING) # pkg-config file get_filename_component(NSS_WRAPPER_LIB ${NSS_WRAPPER_LOCATION} NAME) configure_file(nss_wrapper.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/nss_wrapper.pc @ONLY) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/nss_wrapper.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT pkgconfig ) # 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( FILES ${CMAKE_CURRENT_BINARY_DIR}/nss_wrapper-config-version.cmake ${CMAKE_CURRENT_BINARY_DIR}/nss_wrapper-config.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/nss_wrapper COMPONENT devel ) add_subdirectory(doc) # Add 'make dist' target which makes sure to invoke cmake before add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source) # Link combile database for clangd execute_process(COMMAND cmake -E create_symlink "${CMAKE_BINARY_DIR}/compile_commands.json" "${CMAKE_SOURCE_DIR}/compile_commands.json") nss_wrapper-1.1.16/0002-cmake-Fix-cmocka-1.1.6-find_package-in-CONFIG-mode.patch000644 001750 000144 00000001370 14373730741 026117 0ustar00asnusers000000 000000 From 869ba407ce60d9f2d233b619acf95f90f515509b Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 17 Feb 2023 17:51:27 +0100 Subject: [PATCH 2/2] cmake: Fix cmocka >= 1.1.6 find_package() in CONFIG mode Signed-off-by: Andreas Schneider --- tests/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3b94076..733cc4e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,5 +1,9 @@ project(tests C) +if (TARGET cmocka::cmocka) + set(CMOCKA_LIBRARY cmocka::cmocka) +endif() + set(TESTSUITE_LIBRARIES nss_utils ${NWRAP_REQUIRED_LIBRARIES} ${CMOCKA_LIBRARY}) string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER) -- 2.39.2 nss_wrapper-1.1.16/.clang_complete000644 001750 000144 00000000067 12254017317 017105 0ustar00asnusers000000 000000 -DHAVE_IPV6 -DHAVE_LIBNSL -DHAVE_LIBSOCKET -Isrc -Iobj nss_wrapper-1.1.16/CTestConfig.cmake000644 001750 000144 00000000430 13634203624 017275 0ustar00asnusers000000 000000 set(UPDATE_TYPE "true") set(CTEST_PROJECT_NAME "nss_wrapper") set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC") set(CTEST_DROP_METHOD "https") set(CTEST_DROP_SITE "test.cmocka.org") set(CTEST_DROP_LOCATION "/submit.php?project=${CTEST_PROJECT_NAME}") set(CTEST_DROP_SITE_CDASH TRUE) nss_wrapper-1.1.16/nss_wrapper-config-version.cmake.in000644 001750 000144 00000003300 14460666462 023035 0ustar00asnusers000000 000000 set(PACKAGE_VERSION @PROJECT_VERSION@) if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) set(PACKAGE_VERSION_COMPATIBLE FALSE) else() 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() nss_wrapper-1.1.16/.clang-format000644 001750 000144 00000001275 14460666462 016521 0ustar00asnusers000000 000000 # 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 nss_wrapper-1.1.16/nss_wrapper-config.cmake.in000644 001750 000144 00000001174 14460666462 021361 0ustar00asnusers000000 000000 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}]") nss_wrapper-1.1.16/AUTHORS000644 001750 000144 00000000250 13634203624 015173 0ustar00asnusers000000 000000 Stefan Metzmacher Guenther Deschner Andreas Schneider Robin Hack Michael Adam nss_wrapper-1.1.16/LICENSE000644 001750 000144 00000003330 13634203624 015132 0ustar00asnusers000000 000000 BSD 3-Clause License Copyright (c) 2007, Stefan Metzmacher Copyright (c) 2009, Guenther Deschner Copyright (c) 2014-2015, Michael Adam Copyright (c) 2015, Robin Hack Copyright (c) 2013-2018, Andreas Schneider 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. nss_wrapper-1.1.16/.editorconfig000644 001750 000144 00000000472 14332646173 016614 0ustar00asnusers000000 000000 root = true [*] charset = utf-8 max_line_length = 80 end_of_line = lf trim_trailing_whitespace = true insert_final_newline = true [*.{c,h}] indent_style = tab indent_size = 8 tab_width = 8 [*.cmake] indent_style = space indent_size = 4 tab_width = 4 [CMake*] indent_style = space indent_size = 4 tab_width = 4 nss_wrapper-1.1.16/DefineOptions.cmake000644 001750 000144 00000000061 12247646107 017701 0ustar00asnusers000000 000000 option(UNIT_TESTING "Build with unit tests" OFF) nss_wrapper-1.1.16/nss_wrapper.pl000755 001750 000144 00000024141 13634203624 017033 0ustar00asnusers000000 000000 #!/usr/bin/env perl # use strict; use Getopt::Long; use Cwd qw(abs_path); my $opt_help = 0; my $opt_passwd_path = undef; my $opt_group_path = undef; my $opt_action = undef; my $opt_type = undef; my $opt_name = undef; my $opt_member = undef; my $opt_gid = 65534;# nogroup gid my $passwdfn = undef; my $groupfn = undef; my $memberfn = undef; my $actionfn = undef; sub passwd_add($$$$$); sub passwd_delete($$$$$); sub group_add($$$$$); sub group_delete($$$$$); sub member_add($$$$$); sub member_delete($$$$$); sub check_path($$); my $result = GetOptions( 'help|h|?' => \$opt_help, 'passwd_path=s' => \$opt_passwd_path, 'group_path=s' => \$opt_group_path, 'action=s' => \$opt_action, 'type=s' => \$opt_type, 'name=s' => \$opt_name, 'member=s' => \$opt_member, 'gid=i' => \$opt_gid ); sub usage($;$) { my ($ret, $msg) = @_; print $msg."\n\n" if defined($msg); print "usage: --help|-h|-? Show this help. --passwd_path Path of the 'passwd' file. --group_path Path of the 'group' file. --type 'passwd', 'group' and 'member' are supported. --action 'add' or 'delete'. --name The name of the object. --member The name of the member. --gid Primary Group ID for new users. "; exit($ret); } usage(1) if (not $result); usage(0) if ($opt_help); if (not defined($opt_action)) { usage(1, "missing: --action [add|delete]"); } if ($opt_action eq "add") { $passwdfn = \&passwd_add; $groupfn = \&group_add; $memberfn = \&member_add; } elsif ($opt_action eq "delete") { $passwdfn = \&passwd_delete; $groupfn = \&group_delete; $memberfn = \&member_delete; } else { usage(1, "invalid: --action [add|delete]: '$opt_action'"); } if (not defined($opt_type)) { usage(1, "missing: --type [passwd|group|member]"); } if ($opt_type eq "member" and not defined($opt_member)) { usage(1, "missing: --member "); } my $opt_fullpath_passwd; my $opt_fullpath_group; if ($opt_type eq "passwd") { $actionfn = $passwdfn; $opt_fullpath_passwd = check_path($opt_passwd_path, $opt_type); } elsif ($opt_type eq "group") { $actionfn = $groupfn; $opt_fullpath_group = check_path($opt_group_path, $opt_type); } elsif ($opt_type eq "member") { $actionfn = $memberfn; $opt_fullpath_passwd = check_path($opt_passwd_path, "passwd"); $opt_fullpath_group = check_path($opt_group_path, "group"); } else { usage(1, "invalid: --type [passwd|group]: '$opt_type'") } if (not defined($opt_name)) { usage(1, "missing: --name "); } if ($opt_name eq "") { usage(1, "invalid: --name "); } exit $actionfn->($opt_fullpath_passwd, $opt_member, $opt_fullpath_group, $opt_name, $opt_gid); sub check_path($$) { my ($path,$type) = @_; if (not defined($path)) { usage(1, "missing: --$type\_path "); } if ($path eq "" or $path eq "/") { usage(1, "invalid: --$type\_path : '$path'"); } my $fullpath = abs_path($path); if (not defined($fullpath)) { usage(1, "invalid: --$type\_path : '$path'"); } return $fullpath; } sub passwd_add_entry($$); sub passwd_load($) { my ($path) = @_; my @lines; my $passwd = undef; open(PWD, "<$path") or die("Unable to open '$path' for read"); @lines = ; close(PWD); $passwd->{array} = (); $passwd->{name} = {}; $passwd->{uid} = {}; $passwd->{path} = $path; foreach my $line (@lines) { passwd_add_entry($passwd, $line); } return $passwd; } sub group_add_entry($$); sub group_load($) { my ($path) = @_; my @lines; my $group = undef; open(GROUP, "<$path") or die("Unable to open '$path' for read"); @lines = ; close(GROUP); $group->{array} = (); $group->{name} = {}; $group->{gid} = {}; $group->{path} = $path; foreach my $line (@lines) { group_add_entry($group, $line); } return $group; } sub passwd_lookup_name($$) { my ($passwd, $name) = @_; return undef unless defined($passwd->{name}{$name}); return $passwd->{name}{$name}; } sub group_lookup_name($$) { my ($group, $name) = @_; return undef unless defined($group->{name}{$name}); return $group->{name}{$name}; } sub passwd_lookup_uid($$) { my ($passwd, $uid) = @_; return undef unless defined($passwd->{uid}{$uid}); return $passwd->{uid}{$uid}; } sub group_lookup_gid($$) { my ($group, $gid) = @_; return undef unless defined($group->{gid}{$gid}); return $group->{gid}{$gid}; } sub passwd_get_free_uid($) { my ($passwd) = @_; my $uid = 1000; while (passwd_lookup_uid($passwd, $uid)) { $uid++; } return $uid; } sub group_get_free_gid($) { my ($group) = @_; my $gid = 1000; while (group_lookup_gid($group, $gid)) { $gid++; } return $gid; } sub passwd_add_entry($$) { my ($passwd, $str) = @_; chomp $str; my @e = split(':', $str); push(@{$passwd->{array}}, \@e); $passwd->{name}{$e[0]} = \@e; $passwd->{uid}{$e[2]} = \@e; } sub group_add_entry($$) { my ($group, $str) = @_; chomp $str; my @e = split(':', $str); push(@{$group->{array}}, \@e); $group->{name}{$e[0]} = \@e; $group->{gid}{$e[2]} = \@e; } sub passwd_remove_entry($$) { my ($passwd, $eref) = @_; for (my $i = 0; defined($passwd->{array}[$i]); $i++) { if ($eref == $passwd->{array}[$i]) { $passwd->{array}[$i] = undef; } } delete $passwd->{name}{${$eref}[0]}; delete $passwd->{uid}{${$eref}[2]}; } sub group_remove_entry($$) { my ($group, $eref) = @_; for (my $i = 0; defined($group->{array}[$i]); $i++) { if ($eref == $group->{array}[$i]) { $group->{array}[$i] = undef; } } delete $group->{name}{${$eref}[0]}; delete $group->{gid}{${$eref}[2]}; } sub group_add_member($$$) { my ($group, $eref, $username) = @_; my @members; my $str = @$eref[3] || undef; if ($str) { @members = split(",", $str); } foreach my $member (@members) { if ($member and $member eq $username) { die("account[$username] is already member of '@$eref[0]'"); } } push(@members, $username); my $gwent = @$eref[0].":x:".@$eref[2].":".join(",", @members); group_remove_entry($group, $eref); group_add_entry($group, $gwent); } sub group_delete_member($$$) { my ($group, $eref, $username) = @_; my @members = undef; my $str = @$eref[3] || undef; if ($str) { @members = split(",", $str); } my @new_members; my $removed = 0; foreach my $member (@members) { if ($member and $member ne $username) { push(@new_members, $member); } else { $removed = 1; } } if ($removed != 1) { die("account[$username] is not member of '@$eref[0]'"); } my $gwent = @$eref[0].":x:".@$eref[2].":".join(",", @new_members); group_remove_entry($group, $eref); group_add_entry($group, $gwent); } sub passwd_save($) { my ($passwd) = @_; my @lines = (); my $path = $passwd->{path}; my $tmppath = $path.$$; foreach my $eref (@{$passwd->{array}}) { next unless defined($eref); my $line = join(':', @{$eref}); push(@lines, $line); } open(PWD, ">$tmppath") or die("Unable to open '$tmppath' for write"); print PWD join("\n", @lines)."\n"; close(PWD); rename($tmppath, $path) or die("Unable to rename $tmppath => $path"); } sub group_save($) { my ($group) = @_; my @lines = (); my $path = $group->{path}; my $tmppath = $path.$$; foreach my $eref (@{$group->{array}}) { next unless defined($eref); my $line = join(':', @{$eref}); if (scalar(@{$eref}) == 3) { $line .= ":"; } push(@lines, $line); } open(GROUP, ">$tmppath") or die("Unable to open '$tmppath' for write"); print GROUP join("\n", @lines)."\n"; close(GROUP); rename($tmppath, $path) or die("Unable to rename $tmppath => $path"); } sub passwd_add($$$$$) { my ($path, $dummy, $dummy2, $name, $gid) = @_; #print "passwd_add: '$name' in '$path'\n"; my $passwd = passwd_load($path); my $e = passwd_lookup_name($passwd, $name); die("account[$name] already exists in '$path'") if defined($e); my $uid = passwd_get_free_uid($passwd); my $pwent = $name.":x:".$uid.":".$gid.":".$name." gecos:/nodir:/bin/false"; passwd_add_entry($passwd, $pwent); passwd_save($passwd); return 0; } sub passwd_delete($$$$$) { my ($path, $dummy, $dummy2, $name, $dummy3) = @_; #print "passwd_delete: '$name' in '$path'\n"; my $passwd = passwd_load($path); my $e = passwd_lookup_name($passwd, $name); die("account[$name] does not exists in '$path'") unless defined($e); passwd_remove_entry($passwd, $e); passwd_save($passwd); return 0; } sub group_add($$$$$) { my ($dummy, $dummy2, $path, $name, $dummy3) = @_; #print "group_add: '$name' in '$path'\n"; my $group = group_load($path); my $e = group_lookup_name($group, $name); die("group[$name] already exists in '$path'") if defined($e); my $gid = group_get_free_gid($group); my $gwent = $name.":x:".$gid.":".""; group_add_entry($group, $gwent); group_save($group); #printf("%d\n", $gid); return 0; } sub group_delete($$$$$) { my ($dummy, $dummy2, $path, $name, $dummy3) = @_; #print "group_delete: '$name' in '$path'\n"; my $group = group_load($path); my $e = group_lookup_name($group, $name); die("group[$name] does not exists in '$path'") unless defined($e); group_remove_entry($group, $e); group_save($group); return 0; } sub member_add($$$$$) { my ($passwd_path, $username, $group_path, $groupname, $dummy) = @_; #print "member_add: adding '$username' in '$passwd_path' to '$groupname' in '$group_path'\n"; my $group = group_load($group_path); my $g = group_lookup_name($group, $groupname); die("group[$groupname] does not exists in '$group_path'") unless defined($g); my $passwd = passwd_load($passwd_path); my $u = passwd_lookup_name($passwd, $username); die("account[$username] does not exists in '$passwd_path'") unless defined($u); group_add_member($group, $g, $username); group_save($group); return 0; } sub member_delete($$$$$) { my ($passwd_path, $username, $group_path, $groupname, $dummy) = @_; #print "member_delete: removing '$username' in '$passwd_path' from '$groupname' in '$group_path'\n"; my $group = group_load($group_path); my $g = group_lookup_name($group, $groupname); die("group[$groupname] does not exists in '$group_path'") unless defined($g); my $passwd = passwd_load($passwd_path); my $u = passwd_lookup_name($passwd, $username); die("account[$username] does not exists in '$passwd_path'") unless defined($u); group_delete_member($group, $g, $username); group_save($group); return 0; } nss_wrapper-1.1.16/nss_wrapper.pc.cmake000644 001750 000144 00000000211 13634217552 020073 0ustar00asnusers000000 000000 Name: @PROJECT_NAME@ Description: The nss_wrapper library Version: @PROJECT_VERSION@ Libs: @CMAKE_INSTALL_FULL_LIBDIR@/@NSS_WRAPPER_LIB@ nss_wrapper-1.1.16/cmake/000755 001750 000144 00000000000 14641730071 015206 5ustar00asnusers000000 000000 nss_wrapper-1.1.16/cmake/Modules/000755 001750 000144 00000000000 14641730071 016616 5ustar00asnusers000000 000000 nss_wrapper-1.1.16/cmake/Modules/COPYING-CMAKE-SCRIPTS000644 001750 000144 00000002457 12247646107 021632 0ustar00asnusers000000 000000 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 copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. nss_wrapper-1.1.16/cmake/Modules/AddCMockaTest.cmake000644 001750 000144 00000006250 13634203624 022231 0ustar00asnusers000000 000000 # # Copyright (c) 2007 Daniel Gollub # Copyright (c) 2007-2018 Andreas Schneider # Copyright (c) 2018 Anderson Toshiyuki Sasaki # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. #.rst: # AddCMockaTest # ------------- # # This file provides a function to add a test # # Functions provided # ------------------ # # :: # # add_cmocka_test(target_name # SOURCES src1 src2 ... srcN # [COMPILE_OPTIONS opt1 opt2 ... optN] # [LINK_LIBRARIES lib1 lib2 ... libN] # [LINK_OPTIONS lopt1 lop2 .. loptN] # ) # # ``target_name``: # Required, expects the name of the test which will be used to define a target # # ``SOURCES``: # Required, expects one or more source files names # # ``COMPILE_OPTIONS``: # Optional, expects one or more options to be passed to the compiler # # ``LINK_LIBRARIES``: # Optional, expects one or more libraries to be linked with the test # executable. # # ``LINK_OPTIONS``: # Optional, expects one or more options to be passed to the linker # # # Example: # # .. code-block:: cmake # # add_cmocka_test(my_test # SOURCES my_test.c other_source.c # COMPILE_OPTIONS -g -Wall # LINK_LIBRARIES mylib # LINK_OPTIONS -Wl,--enable-syscall-fixup # ) # # Where ``my_test`` is the name of the test, ``my_test.c`` and # ``other_source.c`` are sources for the binary, ``-g -Wall`` are compiler # options to be used, ``mylib`` is a target of a library to be linked, and # ``-Wl,--enable-syscall-fixup`` is an option passed to the linker. # enable_testing() include(CTest) if (CMAKE_CROSSCOMPILING) if (WIN32) find_program(WINE_EXECUTABLE NAMES wine) set(TARGET_SYSTEM_EMULATOR ${WINE_EXECUTABLE} CACHE INTERNAL "") endif() endif() function(ADD_CMOCKA_TEST _TARGET_NAME) set(one_value_arguments ) set(multi_value_arguments SOURCES COMPILE_OPTIONS LINK_LIBRARIES LINK_OPTIONS ) cmake_parse_arguments(_add_cmocka_test "" "${one_value_arguments}" "${multi_value_arguments}" ${ARGN} ) if (NOT DEFINED _add_cmocka_test_SOURCES) message(FATAL_ERROR "No sources provided for target ${_TARGET_NAME}") endif() add_executable(${_TARGET_NAME} ${_add_cmocka_test_SOURCES}) if (DEFINED _add_cmocka_test_COMPILE_OPTIONS) target_compile_options(${_TARGET_NAME} PRIVATE ${_add_cmocka_test_COMPILE_OPTIONS} ) endif() if (DEFINED _add_cmocka_test_LINK_LIBRARIES) target_link_libraries(${_TARGET_NAME} PRIVATE ${_add_cmocka_test_LINK_LIBRARIES} ) endif() if (DEFINED _add_cmocka_test_LINK_OPTIONS) set_target_properties(${_TARGET_NAME} PROPERTIES LINK_FLAGS ${_add_cmocka_test_LINK_OPTIONS} ) endif() add_test(${_TARGET_NAME} ${TARGET_SYSTEM_EMULATOR} ${_TARGET_NAME} ) endfunction (ADD_CMOCKA_TEST) nss_wrapper-1.1.16/cmake/Modules/DefineCMakeDefaults.cmake000644 001750 000144 00000001250 13634203624 023401 0ustar00asnusers000000 000000 # Always include srcdir and builddir in include path # This saves typing ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY} in # about every subdir # since cmake 2.4.0 set(CMAKE_INCLUDE_CURRENT_DIR ON) # Put the include dirs which are in the source or build tree # before all other include dirs, so the headers in the sources # are prefered over the already installed ones # since cmake 2.4.1 set(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE ON) # Use colored output # since cmake 2.4.0 set(CMAKE_COLOR_MAKEFILE ON) # Create the compile command database for clang by default set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Always build with -fPIC set(CMAKE_POSITION_INDEPENDENT_CODE ON) nss_wrapper-1.1.16/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake000644 001750 000144 00000001227 12247646107 025171 0ustar00asnusers000000 000000 # - MACRO_ENSURE_OUT_OF_SOURCE_BUILD() # MACRO_ENSURE_OUT_OF_SOURCE_BUILD() # Copyright (c) 2006, Alexander Neundorf, # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. macro (MACRO_ENSURE_OUT_OF_SOURCE_BUILD _errorMessage) string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" _insource) if (_insource) message(SEND_ERROR "${_errorMessage}") message(FATAL_ERROR "Remove the file CMakeCache.txt in ${CMAKE_SOURCE_DIR} first.") endif (_insource) endmacro (MACRO_ENSURE_OUT_OF_SOURCE_BUILD) nss_wrapper-1.1.16/cmake/Modules/AddCCompilerFlag.cmake000644 001750 000144 00000001515 13634203624 022702 0ustar00asnusers000000 000000 # # add_c_compiler_flag("-Werror" SUPPORTED_CFLAGS) # # Copyright (c) 2018 Andreas Schneider # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. include(CheckCCompilerFlag) macro(add_c_compiler_flag _COMPILER_FLAG _OUTPUT_VARIABLE) string(TOUPPER ${_COMPILER_FLAG} _COMPILER_FLAG_NAME) string(REGEX REPLACE "^-" "" _COMPILER_FLAG_NAME "${_COMPILER_FLAG_NAME}") string(REGEX REPLACE "(-|=|\ )" "_" _COMPILER_FLAG_NAME "${_COMPILER_FLAG_NAME}") check_c_compiler_flag("${_COMPILER_FLAG}" WITH_${_COMPILER_FLAG_NAME}_FLAG) if (WITH_${_COMPILER_FLAG_NAME}_FLAG) #string(APPEND ${_OUTPUT_VARIABLE} "${_COMPILER_FLAG} ") list(APPEND ${_OUTPUT_VARIABLE} ${_COMPILER_FLAG}) endif() endmacro() nss_wrapper-1.1.16/cmake/Modules/DefineCompilerFlags.cmake000644 001750 000144 00000007340 14332646173 023474 0ustar00asnusers000000 000000 if (UNIX AND NOT WIN32) # Activate with: -DCMAKE_BUILD_TYPE=Profiling set(CMAKE_C_FLAGS_PROFILING "-O0 -g -fprofile-arcs -ftest-coverage" CACHE STRING "Flags used by the C compiler during PROFILING builds.") set(CMAKE_CXX_FLAGS_PROFILING "-O0 -g -fprofile-arcs -ftest-coverage" CACHE STRING "Flags used by the CXX compiler during PROFILING builds.") set(CMAKE_SHARED_LINKER_FLAGS_PROFILING "-fprofile-arcs -ftest-coverage" CACHE STRING "Flags used by the linker during the creation of shared libraries during PROFILING builds.") set(CMAKE_MODULE_LINKER_FLAGS_PROFILING "-fprofile-arcs -ftest-coverage" CACHE STRING "Flags used by the linker during the creation of shared libraries during PROFILING builds.") set(CMAKE_EXEC_LINKER_FLAGS_PROFILING "-fprofile-arcs -ftest-coverage" CACHE STRING "Flags used by the linker during PROFILING builds.") # Activate with: -DCMAKE_BUILD_TYPE=AddressSanitizer set(CMAKE_C_FLAGS_ADDRESSSANITIZER "-g -O1 -fsanitize=address -fno-omit-frame-pointer" CACHE STRING "Flags used by the C compiler during ADDRESSSANITIZER builds.") set(CMAKE_CXX_FLAGS_ADDRESSSANITIZER "-g -O1 -fsanitize=address -fno-omit-frame-pointer" CACHE STRING "Flags used by the CXX compiler during ADDRESSSANITIZER builds.") set(CMAKE_SHARED_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address" CACHE STRING "Flags used by the linker during the creation of shared libraries during ADDRESSSANITIZER builds.") set(CMAKE_MODULE_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address" CACHE STRING "Flags used by the linker during the creation of shared libraries during ADDRESSSANITIZER builds.") set(CMAKE_EXEC_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address" CACHE STRING "Flags used by the linker during ADDRESSSANITIZER builds.") # Activate with: -DCMAKE_BUILD_TYPE=UndefinedSanitizer set(CMAKE_C_FLAGS_UNDEFINEDSANITIZER "-g -O1 -fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover" CACHE STRING "Flags used by the C compiler during UNDEFINEDSANITIZER builds.") set(CMAKE_CXX_FLAGS_UNDEFINEDSANITIZER "-g -O1 -fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover" CACHE STRING "Flags used by the CXX compiler during UNDEFINEDSANITIZER builds.") set(CMAKE_SHARED_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined" CACHE STRING "Flags used by the linker during the creation of shared libraries during UNDEFINEDSANITIZER builds.") set(CMAKE_MODULE_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined" CACHE STRING "Flags used by the linker during the creation of shared libraries during UNDEFINEDSANITIZER builds.") set(CMAKE_EXEC_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined" CACHE STRING "Flags used by the linker during UNDEFINEDSANITIZER builds.") # Activate with: -DCMAKE_BUILD_TYPE=ThreadSanitizer set(CMAKE_C_FLAGS_THREADSANITIZER "-g -O1 -fsanitize=thread" CACHE STRING "Flags used by the C compiler during THREADSANITIZER builds.") set(CMAKE_CXX_FLAGS_THREADSANITIZER "-g -O1 -fsanitize=thread" CACHE STRING "Flags used by the CXX compiler during THREADSANITIZER builds.") set(CMAKE_SHARED_LINKER_FLAGS_THREADSANITIZER "-fsanitize=thread" CACHE STRING "Flags used by the linker during the creation of shared libraries during THREADSANITIZER builds.") set(CMAKE_MODULE_LINKER_FLAGS_THREADSANITIZER "-fsanitize=thread" CACHE STRING "Flags used by the linker during the creation of shared libraries during THREADSANITIZER builds.") set(CMAKE_EXEC_LINKER_FLAGS_THREADSANITIZER "-fsanitize=thread" CACHE STRING "Flags used by the linker during THREADSANITIZER builds.") endif() nss_wrapper-1.1.16/cmake/Modules/DefinePlatformDefaults.cmake000644 001750 000144 00000001312 12247646107 024212 0ustar00asnusers000000 000000 # Set system vars if (CMAKE_SYSTEM_NAME MATCHES "Linux") set(LINUX TRUE) endif(CMAKE_SYSTEM_NAME MATCHES "Linux") if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") set(FREEBSD TRUE) set(BSD TRUE) endif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") if (CMAKE_SYSTEM_NAME MATCHES "OpenBSD") set(OPENBSD TRUE) set(BSD TRUE) endif (CMAKE_SYSTEM_NAME MATCHES "OpenBSD") if (CMAKE_SYSTEM_NAME MATCHES "NetBSD") set(NETBSD TRUE) set(BSD TRUE) endif (CMAKE_SYSTEM_NAME MATCHES "NetBSD") if (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") set(SOLARIS TRUE) endif (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") if (CMAKE_SYSTEM_NAME MATCHES "OS2") set(OS2 TRUE) endif (CMAKE_SYSTEM_NAME MATCHES "OS2") nss_wrapper-1.1.16/cmake/Modules/CheckCCompilerFlagSSP.cmake000644 001750 000144 00000003560 13634203624 023617 0ustar00asnusers000000 000000 # - Check whether the C compiler supports a given flag in the # context of a stack checking compiler option. # CHECK_C_COMPILER_FLAG_SSP(FLAG VARIABLE) # # FLAG - the compiler flag # VARIABLE - variable to store the result # # This actually calls check_c_source_compiles. # See help for CheckCSourceCompiles for a listing of variables # that can modify the build. # Copyright (c) 2006, Alexander Neundorf, # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. # Requires cmake 3.10 #include_guard(GLOBAL) include(CheckCSourceCompiles) include(CMakeCheckCompilerFlagCommonPatterns) macro(CHECK_C_COMPILER_FLAG_SSP _FLAG _RESULT) set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") set(CMAKE_REQUIRED_FLAGS "${_FLAG}") # Normalize locale during test compilation. set(_CheckCCompilerFlag_LOCALE_VARS LC_ALL LC_MESSAGES LANG) foreach(v ${_CheckCCompilerFlag_LOCALE_VARS}) set(_CheckCCompilerFlag_SAVED_${v} "$ENV{${v}}") set(ENV{${v}} C) endforeach() CHECK_COMPILER_FLAG_COMMON_PATTERNS(_CheckCCompilerFlag_COMMON_PATTERNS) check_c_source_compiles("int main(int argc, char **argv) { char buffer[256]; return buffer[argc]=0;}" ${_RESULT} # Some compilers do not fail with a bad flag FAIL_REGEX "command line option .* is valid for .* but not for C" # GNU ${_CheckCCompilerFlag_COMMON_PATTERNS}) foreach(v ${_CheckCCompilerFlag_LOCALE_VARS}) set(ENV{${v}} ${_CheckCCompilerFlag_SAVED_${v}}) unset(_CheckCCompilerFlag_SAVED_${v}) endforeach() unset(_CheckCCompilerFlag_LOCALE_VARS) unset(_CheckCCompilerFlag_COMMON_PATTERNS) set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") endmacro(CHECK_C_COMPILER_FLAG_SSP) nss_wrapper-1.1.16/cmake/Toolchain-Debian-mips.cmake000644 001750 000144 00000001173 13634203624 022260 0ustar00asnusers000000 000000 include(CMakeForceCompiler) set(TOOLCHAIN_PREFIX mips-linux-gnu) set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_VERSION 1) set(CMAKE_SYSTEM_PROCESSOR mips) # This is the location of the mips toolchain set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) # This is the file system root of the target set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) # Search for programs in the build host directories set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # For libraries and headers in the target directories set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) nss_wrapper-1.1.16/README.install000644 001750 000144 00000003556 12342110056 016453 0ustar00asnusers000000 000000 Obtaining the sources ===================== Source tarballs for nss_wrapper can be downloaded from https://ftp.samba.org/pub/cwrap/ The source code repository for socket wrapper is located under git://git.samba.org/nss_wrapper.git To create a local copy, run $ git clone git://git.samba.org/nss_wrapper.git $ cd nss_wrapper Building from sources ===================== nss_wrapper uses cmake (www.cmake.org) as its build system. In an unpacked sources base directory, create a directory to contain the build results, e.g. $ mkdir obj $ cd obj Note that "obj" is just an example. The directory can be named arbitrarily. Next, run cmake to configure the build, e.g. $ cmake -DCMAKE_INSTALL_PREFIX= .. or on a 64 bit red hat system: $ cmake -DCMAKE_INSTALL_PREFIX= -DLIB_SUFFIX=64 .. The "" should be replaced by the intended installation target prefix directory, typically /usr or /usr/local. Note that the target directory does not have to be a direct or indirect subdirectory of the source base directory: It can be an arbitrary directory in the system. In the general case, ".." has to be replaced by a relative or absolute path of the source base directory in the "cmake" command line. One can control the build type with "-DCMAKE_BUILD_TYPE=" where can be one of Debug, Release, RelWithDebInfo, and some more (see cmake.org). The default is "RelWithDebInfo". After configuring with cmake, run the build with $ make Unit testing ============ In order to support running the test suite after building, the cmocka unit test framework needs to be installed (cmocka.org), and you need to specify -DUNIT_TESTING=ON in the cmake run. After running "make", $ make test runs the test suite. Installing ========== nss_wrapper is installed into the prefix directory after running "cmake" and "make" with $ make install nss_wrapper-1.1.16/tests/000755 001750 000144 00000000000 14641730071 015270 5ustar00asnusers000000 000000 nss_wrapper-1.1.16/tests/CMakeLists.txt000644 001750 000144 00000012416 14641705104 020033 0ustar00asnusers000000 000000 project(tests C) if (TARGET cmocka::cmocka) set(CMOCKA_LIBRARY cmocka::cmocka) endif() 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) target_compile_options(nss_nwrap PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_include_directories(nss_nwrap PRIVATE ${CMAKE_BINARY_DIR} ${CMOCKA_INCLUDE_DIR}) target_link_libraries(nss_nwrap PRIVATE nss_utils) set(HOMEDIR ${CMAKE_CURRENT_BINARY_DIR}) configure_file(passwd.in ${CMAKE_CURRENT_BINARY_DIR}/passwd @ONLY) 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 test_getaddrinfo test_getnameinfo test_gethostby_name_addr test_gethostent test_getpwuid_module test_initgroups) if (HAVE_SHADOW_H) list(APPEND NWRAP_TESTS test_shadow) endif (HAVE_SHADOW_H) function(ADD_CMOCKA_TEST_ENVIRONMENT _TEST_NAME) if (CMAKE_BUILD_TYPE) string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER) if (CMAKE_BUILD_TYPE_LOWER STREQUAL "addresssanitizer") find_library(ASAN_LIBRARY NAMES asan) if (NOT ASAN_LIBRARY) foreach(version RANGE 10 1) if (NOT ASAN_LIBRARY) find_library(ASAN_LIBRARY libasan.so.${version}) endif() endforeach() endif() endif() endif() 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 "DYLD_FORCE_FLAT_NAMESPACE=1;DYLD_INSERT_LIBRARIES=${NSS_WRAPPER_LOCATION}") else () string(REPLACE ";" ":" _TMP_ENV "${PRELOAD_LIBRARIES}") 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) list(APPEND TORTURE_ENVIRONMENT NSS_WRAPPER_HOSTS=${CMAKE_CURRENT_BINARY_DIR}/hosts) list(APPEND TORTURE_ENVIRONMENT NSS_WRAPPER_MODULE_SO_PATH=${CMAKE_CURRENT_BINARY_DIR}/libnss_nwrap.so) list(APPEND TORTURE_ENVIRONMENT NSS_WRAPPER_MODULE_FN_PREFIX=nwrap) if (CMAKE_BUILD_TYPE) string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER) 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() set_property(TEST ${_TEST_NAME} PROPERTY ENVIRONMENT "${TORTURE_ENVIRONMENT}") endfunction() foreach(_NWRAP_TEST ${NWRAP_TESTS}) add_cmocka_test(${_NWRAP_TEST} SOURCES ${_NWRAP_TEST}.c COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS} LINK_LIBRARIES ${TESTSUITE_LIBRARIES} LINK_OPTIONS ${DEFAULT_LINK_FLAGS}) if (BSD) target_compile_options(${_NWRAP_TEST} PRIVATE -DBSD) endif() target_include_directories(${_NWRAP_TEST} PRIVATE ${CMAKE_BINARY_DIR} ${CMOCKA_INCLUDE_DIR}) add_cmocka_test_environment(${_NWRAP_TEST}) endforeach() if (HAVE_SHADOW_H) # This is needed to check the hash in tests/shadow.in target_link_libraries(test_shadow PRIVATE crypt) endif (HAVE_SHADOW_H) target_link_libraries(test_nwrap_vector PRIVATE ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries(test_gethostby_name_addr PRIVATE ${CMAKE_THREAD_LIBS_INIT}) # Test nwrap without wrapping so the libc functions are called if (NOT CMAKE_BUILD_TYPE_LOWER MATCHES "sanitizer") add_cmocka_test(test_nwrap_disabled SOURCES test_nwrap_disabled.c COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS} LINK_LIBRARIES ${TESTSUITE_LIBRARIES} LINK_OPTIONS ${DEFAULT_LINK_FLAGS}) target_include_directories(test_nwrap_disabled PRIVATE ${CMAKE_BINARY_DIR} ${CMOCKA_INCLUDE_DIR}) set_property( TEST test_nwrap_disabled PROPERTY ENVIRONMENT LD_PRELOAD=${NSS_WRAPPER_LOCATION}) endif() nss_wrapper-1.1.16/tests/testsuite.c000644 001750 000144 00000047417 13634217552 017507 0ustar00asnusers000000 000000 #include "config.h" #include #include #include #include #include #include #include #include #include #include /* * 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 * Solaris */ #ifndef _POSIX_PTHREAD_SEMANTICS #define _POSIX_PTHREAD_SEMANTICS #endif #include #include #include #include #include #include #ifdef NDEBUG #define DEBUG(...) #else #define DEBUG(...) printf(__VA_ARGS__) #endif #ifndef SAFE_FREE #define SAFE_FREE(x) do { if ((x) != NULL) {free((x)); (x)=NULL;} } while(0) #endif static void assert_passwd_equal(const struct passwd *p1, const struct passwd *p2) { assert_string_equal(p1->pw_name, p2->pw_name); assert_string_equal(p1->pw_passwd, p2->pw_passwd); assert_int_equal(p1->pw_uid, p2->pw_uid); assert_int_equal(p1->pw_gid, p2->pw_gid); assert_string_equal(p1->pw_gecos, p2->pw_gecos); assert_string_equal(p1->pw_dir, p2->pw_dir); assert_string_equal(p1->pw_shell, p2->pw_shell); } static void assert_group_equal(const struct group *g1, const struct group *g2) { int i; assert_string_equal(g1->gr_name, g2->gr_name); assert_string_equal(g1->gr_passwd, g2->gr_passwd); assert_int_equal(g1->gr_gid, g2->gr_gid); assert_false(g1->gr_mem != NULL && g2->gr_mem == NULL); assert_false(g1->gr_mem == NULL && g2->gr_mem != NULL); if (g1->gr_mem == NULL && g2->gr_mem == NULL) { return; } for (i=0; g1->gr_mem[i] && g2->gr_mem[i]; i++) { assert_string_equal(g1->gr_mem[i], g2->gr_mem[i]); } } static bool copy_passwd(const struct passwd *pwd, struct passwd *p) { p->pw_name = strdup(pwd->pw_name); p->pw_passwd = strdup(pwd->pw_passwd); p->pw_uid = pwd->pw_uid; p->pw_gid = pwd->pw_gid; #ifdef HAVE_STRUCT_PASSWD_PW_CLASS p->pw_class = strdup(pwd->pw_class); #endif #ifdef HAVE_STRUCT_PASSWD_PW_CHANGE p->pw_change = pwd->pw_change; #endif #ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE p->pw_expire = pwd->pw_expire; #endif p->pw_gecos = strdup(pwd->pw_gecos); p->pw_dir = strdup(pwd->pw_dir); p->pw_shell = strdup(pwd->pw_shell); return true; } static void free_passwd(struct passwd *p) { SAFE_FREE(p->pw_name); SAFE_FREE(p->pw_passwd); #ifdef HAVE_STRUCT_PASSWD_PW_CLASS SAFE_FREE(p->pw_class); #endif SAFE_FREE(p->pw_gecos); SAFE_FREE(p->pw_dir); SAFE_FREE(p->pw_shell); } static void free_passwds(struct passwd *pwds, size_t num_pwds) { size_t i; for(i = 0; i < num_pwds; i++) { free_passwd(&pwds[i]); } free(pwds); } static void print_passwd(struct passwd *pwd) { (void)pwd; DEBUG("%s:%s:%lu:%lu:%s:%s:%s\n", pwd->pw_name, pwd->pw_passwd, (unsigned long)pwd->pw_uid, (unsigned long)pwd->pw_gid, pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell); } static bool test_nwrap_getpwnam(const char *name, struct passwd *pwd_p) { struct passwd *pwd = NULL; bool ok; DEBUG("Testing getpwnam: %s\n", name); pwd = getpwnam(name); if (pwd == NULL) { return false; } print_passwd(pwd); if (pwd_p == NULL) { return true; } ok = copy_passwd(pwd, pwd_p); return ok; } static void test_nwrap_getpwnam_r(const char *name, struct passwd *pwd_p) { struct passwd pwd, *pwdp; char buffer[4096]; int ret; DEBUG("Testing getpwnam_r: %s\n", name); ret = getpwnam_r(name, &pwd, buffer, sizeof(buffer), &pwdp); if (ret != 0) { if (ret != ENOENT) { DEBUG("got %d return code\n", ret); } assert_true(ret); } assert_ptr_equal(&pwd, pwdp); print_passwd(&pwd); if (pwd_p) { copy_passwd(&pwd, pwd_p); } } static bool test_nwrap_getpwuid(uid_t uid, struct passwd *pwd_p) { struct passwd *pwd = NULL; bool ok; DEBUG("Testing getpwuid: %lu\n", (unsigned long)uid); pwd = getpwuid(uid); if (pwd == NULL) { return false; } print_passwd(pwd); if (pwd_p == NULL) { return true; } ok = copy_passwd(pwd, pwd_p); return ok; } static bool test_nwrap_getpwuid_r(uid_t uid, struct passwd *pwd_p) { struct passwd pwd, *pwdp; char buffer[4096]; int ret; DEBUG("Testing getpwuid_r: %lu\n", (unsigned long)uid); ret = getpwuid_r(uid, &pwd, buffer, sizeof(buffer), &pwdp); if (ret != 0) { if (ret != ENOENT) { DEBUG("got %d return code\n", ret); } assert_true(ret); } assert_ptr_equal(&pwd, pwdp); print_passwd(&pwd); if (pwd_p) { copy_passwd(&pwd, pwd_p); } return true; } static bool copy_group(const struct group *grp, struct group *g) { int i; g->gr_name = strdup(grp->gr_name); g->gr_passwd = strdup(grp->gr_passwd); g->gr_gid = grp->gr_gid; g->gr_mem = NULL; for (i = 0; grp->gr_mem != NULL && grp->gr_mem[i] != NULL; i++) { char **mem; mem = realloc(g->gr_mem, sizeof(char *) * (i + 2)); assert_non_null(mem); g->gr_mem = mem; g->gr_mem[i] = strdup(grp->gr_mem[i]); assert_non_null(g->gr_mem[i]); g->gr_mem[i + 1] = NULL; } return true; } static void free_group(struct group *g) { SAFE_FREE(g->gr_name); SAFE_FREE(g->gr_passwd); if (g->gr_mem != NULL) { int i; for (i = 0; g->gr_mem[i] != NULL; i++) { SAFE_FREE(g->gr_mem[i]); } SAFE_FREE(g->gr_mem); } } static void free_groups(struct group *grps, size_t num_grps) { size_t i; for(i = 0; i < num_grps; i++) { free_group(&grps[i]); } free(grps); } static void print_group(struct group *grp) { int i; DEBUG("%s:%s:%lu:", grp->gr_name, grp->gr_passwd, (unsigned long)grp->gr_gid); if ((grp->gr_mem == NULL) || !grp->gr_mem[0]) { DEBUG("\n"); return; } for (i=0; grp->gr_mem[i+1]; i++) { DEBUG("%s,", grp->gr_mem[i]); } DEBUG("%s\n", grp->gr_mem[i]); } static bool test_nwrap_getgrnam(const char *name, struct group *grp_p) { struct group *grp = NULL; bool ok; DEBUG("Testing getgrnam: %s\n", name); grp = getgrnam(name); if (grp == NULL) { return false; } print_group(grp); if (grp_p == NULL) { return true; } ok = copy_group(grp, grp_p); return ok; } static bool test_nwrap_getgrnam_r(const char *name, struct group *grp_p) { struct group grp, *grpp; char buffer[4096]; int ret; DEBUG("Testing getgrnam_r: %s\n", name); ret = getgrnam_r(name, &grp, buffer, sizeof(buffer), &grpp); if (ret != 0) { if (ret != ENOENT) { DEBUG("got %d return code\n", ret); } assert_true(ret); } assert_ptr_equal(&grp, grpp); print_group(&grp); if (grp_p) { copy_group(&grp, grp_p); } return true; } static bool test_nwrap_getgrgid(gid_t gid, struct group *grp_p) { struct group *grp = NULL; bool ok; DEBUG("Testing getgrgid: %lu\n", (unsigned long)gid); grp = getgrgid(gid); if (grp == NULL) { return false; } print_group(grp); if (grp_p == NULL) { return true; } ok = copy_group(grp, grp_p); return ok; } static bool test_nwrap_getgrgid_r(gid_t gid, struct group *grp_p) { struct group grp, *grpp; char buffer[4096]; int ret; DEBUG("Testing getgrgid_r: %lu\n", (unsigned long)gid); ret = getgrgid_r(gid, &grp, buffer, sizeof(buffer), &grpp); if (ret != 0) { if (ret != ENOENT) { DEBUG("got %d return code\n", ret); } assert_true(ret); } assert_ptr_equal(&grp, grpp); print_group(&grp); if (grp_p) { copy_group(&grp, grp_p); } return true; } static bool test_nwrap_enum_passwd(struct passwd **pwd_array_p, size_t *num_pwd_p) { struct passwd *pwd; struct passwd *pwd_array = NULL; size_t num_pwd = 0; DEBUG("Testing setpwent\n"); setpwent(); while ((pwd = getpwent()) != NULL) { DEBUG("Testing getpwent\n"); print_passwd(pwd); if (pwd_array_p && num_pwd_p) { pwd_array = realloc(pwd_array, sizeof(struct passwd) * (num_pwd + 1)); assert_non_null(pwd_array); copy_passwd(pwd, &pwd_array[num_pwd]); num_pwd++; } } DEBUG("Testing endpwent\n"); endpwent(); if (pwd_array_p) { *pwd_array_p = pwd_array; } if (num_pwd_p) { *num_pwd_p = num_pwd; } return true; } static bool test_nwrap_enum_r_passwd(struct passwd **pwd_array_p, size_t *num_pwd_p) { struct passwd *pwd_array = NULL; size_t num_pwd = 0; /* Skip these tests if the platform does not provide getpwent_r() */ #ifdef HAVE_GETPWENT_R struct passwd pwd, *pwdp; char buffer[4096]; int ret; DEBUG("Testing setpwent\n"); setpwent(); while (1) { DEBUG("Testing getpwent_r\n"); #ifdef HAVE_SOLARIS_GETPWENT_R pwdp = getpwent_r(&pwd, buffer, sizeof(buffer)); if (pwdp == NULL) { break; } #else /* HAVE_SOLARIS_GETPWENT_R */ ret = getpwent_r(&pwd, buffer, sizeof(buffer), &pwdp); if (ret != 0) { if (ret != ENOENT) { DEBUG("got %d return code\n", ret); } break; } #endif /* HAVE_SOLARIS_GETPWENT_R */ print_passwd(&pwd); if (pwd_array_p && num_pwd_p) { pwd_array = realloc(pwd_array, sizeof(struct passwd) * (num_pwd + 1)); assert_non_null(pwd_array); copy_passwd(&pwd, &pwd_array[num_pwd]); num_pwd++; } } DEBUG("Testing endpwent\n"); endpwent(); #endif /* HAVE_GETPWENT_R */ if (pwd_array_p) { *pwd_array_p = pwd_array; } if (num_pwd_p) { *num_pwd_p = num_pwd; } return true; } static bool test_nwrap_passwd(void) { struct passwd *pwd, pwd1, pwd2; size_t i, num_pwd; test_nwrap_enum_passwd(&pwd, &num_pwd); for (i=0; i < num_pwd; i++) { test_nwrap_getpwnam(pwd[i].pw_name, &pwd1); assert_passwd_equal(&pwd[i], &pwd1); test_nwrap_getpwuid(pwd[i].pw_uid, &pwd2); assert_passwd_equal(&pwd[i], &pwd2); assert_passwd_equal(&pwd1, &pwd2); free_passwd(&pwd1); free_passwd(&pwd2); } free_passwds(pwd, num_pwd); return true; } static void test_nwrap_passwd_r(void) { struct passwd *pwd, pwd1, pwd2; size_t i, num_pwd; test_nwrap_enum_r_passwd(&pwd, &num_pwd); for (i=0; i < num_pwd; i++) { test_nwrap_getpwnam_r(pwd[i].pw_name, &pwd1); assert_passwd_equal(&pwd[i], &pwd1); test_nwrap_getpwuid_r(pwd[i].pw_uid, &pwd2); assert_passwd_equal(&pwd[i], &pwd2); assert_passwd_equal(&pwd1, &pwd2); free_passwd(&pwd1); free_passwd(&pwd2); } free_passwds(pwd, num_pwd); } static bool test_nwrap_passwd_r_cross(void) { struct passwd *pwd, pwd1, pwd2, pwd3, pwd4; size_t i, num_pwd; test_nwrap_enum_r_passwd(&pwd, &num_pwd); for (i=0; i < num_pwd; i++) { test_nwrap_getpwnam_r(pwd[i].pw_name, &pwd1); assert_passwd_equal(&pwd[i], &pwd1); test_nwrap_getpwuid_r(pwd[i].pw_uid, &pwd2); assert_passwd_equal(&pwd[i], &pwd2); assert_passwd_equal(&pwd1, &pwd2); test_nwrap_getpwnam(pwd[i].pw_name, &pwd3); assert_passwd_equal(&pwd[i], &pwd3); test_nwrap_getpwuid(pwd[i].pw_uid, &pwd4); assert_passwd_equal(&pwd[i], &pwd4); assert_passwd_equal(&pwd3, &pwd4); free_passwd(&pwd1); free_passwd(&pwd2); free_passwd(&pwd3); free_passwd(&pwd4); } free_passwds(pwd, num_pwd); return true; } static bool test_nwrap_enum_group(struct group **grp_array_p, size_t *num_grp_p) { struct group *grp; struct group *grp_array = NULL; size_t num_grp = 0; DEBUG("Testing setgrent\n"); setgrent(); while ((grp = getgrent()) != NULL) { DEBUG("Testing getgrent\n"); print_group(grp); if (grp_array_p && num_grp_p) { grp_array = realloc(grp_array, sizeof(struct group) * (num_grp + 1)); assert_non_null(grp_array); copy_group(grp, &grp_array[num_grp]); num_grp++; } } DEBUG("Testing endgrent\n"); endgrent(); if (grp_array_p) { *grp_array_p = grp_array; } if (num_grp_p) { *num_grp_p = num_grp; } return true; } static bool test_nwrap_enum_r_group(struct group **grp_array_p, size_t *num_grp_p) { struct group *grp_array = NULL; size_t num_grp = 0; /* Skip these tests if the platform does not provide getgrent_r() */ #ifdef HAVE_GETGRENT_R struct group grp, *grpp; char buffer[4096]; int ret; DEBUG("Testing setgrent\n"); setgrent(); while (1) { DEBUG("Testing getgrent_r\n"); #ifdef HAVE_SOLARIS_GETGRENT_R grpp = getgrent_r(&grp, buffer, sizeof(buffer)); if (grpp == NULL) { break; } #else /* HAVE_SOLARIS_GETGRENT_R */ ret = getgrent_r(&grp, buffer, sizeof(buffer), &grpp); if (ret != 0) { if (ret != ENOENT) { DEBUG("got %d return code\n", ret); } break; } #endif /* HAVE_SOLARIS_GETGRENT_R */ print_group(&grp); if (grp_array_p && num_grp_p) { grp_array = realloc(grp_array, sizeof(struct group) * (num_grp + 1)); assert_non_null(grp_array); copy_group(&grp, &grp_array[num_grp]); num_grp++; } } DEBUG("Testing endgrent\n"); endgrent(); #endif /* HAVE_GETGRENT_R */ if (grp_array_p) { *grp_array_p = grp_array; } if (num_grp_p) { *num_grp_p = num_grp; } return true; } static bool test_nwrap_group(void) { struct group *grp, grp1, grp2; size_t i, num_grp; test_nwrap_enum_group(&grp, &num_grp); for (i=0; i < num_grp; i++) { test_nwrap_getgrnam(grp[i].gr_name, &grp1); assert_group_equal(&grp[i], &grp1); test_nwrap_getgrgid(grp[i].gr_gid, &grp2); assert_group_equal(&grp[i], &grp2); assert_group_equal(&grp1, &grp2); free_group(&grp1); free_group(&grp2); } free_groups(grp, num_grp); return true; } static bool test_nwrap_group_r(void) { struct group *grp, grp1, grp2; size_t i, num_grp; test_nwrap_enum_r_group(&grp, &num_grp); for (i=0; i < num_grp; i++) { test_nwrap_getgrnam_r(grp[i].gr_name, &grp1); assert_group_equal(&grp[i], &grp1); test_nwrap_getgrgid_r(grp[i].gr_gid, &grp2); assert_group_equal(&grp[i], &grp2); assert_group_equal(&grp1, &grp2); free_group(&grp1); free_group(&grp2); } free_groups(grp, num_grp); return true; } static bool test_nwrap_group_r_cross(void) { struct group *grp, grp1, grp2, grp3, grp4; size_t i, num_grp; test_nwrap_enum_r_group(&grp, &num_grp); for (i=0; i < num_grp; i++) { test_nwrap_getgrnam_r(grp[i].gr_name, &grp1); assert_group_equal(&grp[i], &grp1); test_nwrap_getgrgid_r(grp[i].gr_gid, &grp2); assert_group_equal(&grp[i], &grp2); assert_group_equal(&grp1, &grp2); test_nwrap_getgrnam(grp[i].gr_name, &grp3); assert_group_equal(&grp[i], &grp3); test_nwrap_getgrgid(grp[i].gr_gid, &grp4); assert_group_equal(&grp[i], &grp4); assert_group_equal(&grp3, &grp4); free_group(&grp1); free_group(&grp2); free_group(&grp3); free_group(&grp4); } free_groups(grp, num_grp); return true; } #ifdef HAVE_GETGROUPLIST static bool test_nwrap_getgrouplist(const char *user, gid_t gid, gid_t **gids_p, int *num_gids_p) { int ret; int num_groups = 0; gid_t *groups = NULL; DEBUG("Testing getgrouplist: %s\n", user); ret = getgrouplist(user, gid, NULL, &num_groups); if (ret == -1 || num_groups != 0) { groups = malloc(sizeof(gid_t) * num_groups); assert_non_null(groups); ret = getgrouplist(user, gid, groups, &num_groups); } assert_false(ret == -1); DEBUG("%s is member in %d groups\n", user, num_groups); if (gids_p) { *gids_p = groups; } if (num_gids_p) { *num_gids_p = num_groups; } return true; } static bool test_nwrap_user_in_group(const struct passwd *pwd, const struct group *grp) { int i; for (i = 0; grp->gr_mem != NULL && grp->gr_mem[i] != NULL; i++) { if (strcmp(grp->gr_mem[i], pwd->pw_name) == 0) { return true; } } return false; } static bool test_nwrap_membership_user(const struct passwd *pwd, struct group *grp_array, size_t num_grp) { int num_user_groups = 0; size_t num_user_groups_from_enum = 0; gid_t *user_groups = NULL; size_t i; int g; bool primary_group_had_user_member = false; test_nwrap_getgrouplist(pwd->pw_name, pwd->pw_gid, &user_groups, &num_user_groups); for (g=0; g < num_user_groups; g++) { test_nwrap_getgrgid(user_groups[g], NULL); } free(user_groups); for (i=0; i < num_grp; i++) { struct group grp = grp_array[i]; if (test_nwrap_user_in_group(pwd, &grp)) { struct group current_grp = { .gr_name = NULL, }; num_user_groups_from_enum++; test_nwrap_getgrnam(grp.gr_name, ¤t_grp); if (current_grp.gr_gid == pwd->pw_gid) { DEBUG("primary group %s of user %s lists user as member\n", current_grp.gr_name, pwd->pw_name); primary_group_had_user_member = true; } free_group(¤t_grp); continue; } } if (!primary_group_had_user_member) { num_user_groups_from_enum++; } assert_int_equal(num_user_groups, num_user_groups_from_enum); return true; } static void test_nwrap_membership(void **state) { const char *old_pwd = getenv("NSS_WRAPPER_PASSWD"); const char *old_group = getenv("NSS_WRAPPER_GROUP"); struct passwd *pwd; size_t num_pwd; struct group *grp; size_t num_grp; size_t i; (void) state; /* unused */ if (!old_pwd || !old_group) { DEBUG("ENV NSS_WRAPPER_PASSWD or NSS_WRAPPER_GROUP not set\n"); return; } test_nwrap_enum_passwd(&pwd, &num_pwd); test_nwrap_enum_group(&grp, &num_grp); for (i=0; i < num_pwd; i++) { test_nwrap_membership_user(&pwd[i], grp, num_grp); } free_passwds(pwd, num_pwd); free_groups(grp, num_grp); } #endif /* HAVE_GETGROUPLIST */ static void test_nwrap_enumeration(void **state) { const char *old_pwd = getenv("NSS_WRAPPER_PASSWD"); const char *old_group = getenv("NSS_WRAPPER_GROUP"); (void) state; /* unused */ if (!old_pwd || !old_group) { DEBUG("ENV NSS_WRAPPER_PASSWD or NSS_WRAPPER_GROUP not set\n"); return; } test_nwrap_passwd(); test_nwrap_group(); } static void test_nwrap_reentrant_enumeration(void **state) { const char *old_pwd = getenv("NSS_WRAPPER_PASSWD"); const char *old_group = getenv("NSS_WRAPPER_GROUP"); (void) state; /* unused */ if (!old_pwd || !old_group) { DEBUG("ENV NSS_WRAPPER_PASSWD or NSS_WRAPPER_GROUP not set\n"); return; } DEBUG("Testing re-entrant calls\n"); test_nwrap_passwd_r(); test_nwrap_group_r(); } static void test_nwrap_reentrant_enumeration_crosschecks(void **state) { const char *old_pwd = getenv("NSS_WRAPPER_PASSWD"); const char *old_group = getenv("NSS_WRAPPER_GROUP"); (void) state; /* unused */ if (!old_pwd || !old_group) { DEBUG("ENV NSS_WRAPPER_PASSWD or NSS_WRAPPER_GROUP not set\n"); return; } DEBUG("Testing re-entrant calls with cross checks\n"); test_nwrap_passwd_r_cross(); test_nwrap_group_r_cross(); } static bool test_nwrap_passwd_duplicates(void) { struct passwd *pwd; size_t d, i, num_pwd; int duplicates = 0; test_nwrap_enum_passwd(&pwd, &num_pwd); for (i=0; i < num_pwd; i++) { const char *current_name = pwd[i].pw_name; for (d=0; d < num_pwd; d++) { const char *dup_name = pwd[d].pw_name; if (d == i) { continue; } if (strcmp(current_name, dup_name) != 0) { continue; } DEBUG("found duplicate names:"); print_passwd(&pwd[d]); print_passwd(&pwd[i]); duplicates++; } } free_passwds(pwd, num_pwd); assert_false(duplicates); return true; } static bool test_nwrap_group_duplicates(void) { struct group *grp; size_t d, i, num_grp; int duplicates = 0; test_nwrap_enum_group(&grp, &num_grp); for (i=0; i < num_grp; i++) { const char *current_name = grp[i].gr_name; for (d=0; d < num_grp; d++) { const char *dup_name = grp[d].gr_name; if (d == i) { continue; } if (strcmp(current_name, dup_name) != 0) { continue; } DEBUG("found duplicate names:"); print_group(&grp[d]); print_group(&grp[i]); duplicates++; } } free_groups(grp, num_grp); assert_false(duplicates); return true; } static void test_nwrap_duplicates(void **state) { const char *old_pwd = getenv("NSS_WRAPPER_PASSWD"); const char *old_group = getenv("NSS_WRAPPER_GROUP"); (void) state; /* unused */ if (!old_pwd || !old_group) { DEBUG("ENV NSS_WRAPPER_PASSWD or NSS_WRAPPER_GROUP not set\n"); return; } test_nwrap_passwd_duplicates(); test_nwrap_group_duplicates(); } int main(void) { int rc; const struct CMUnitTest tests[] = { cmocka_unit_test(test_nwrap_enumeration), cmocka_unit_test(test_nwrap_reentrant_enumeration), cmocka_unit_test(test_nwrap_reentrant_enumeration_crosschecks), #ifdef HAVE_GETGROUPLIST cmocka_unit_test(test_nwrap_membership), #endif cmocka_unit_test(test_nwrap_duplicates), }; rc = cmocka_run_group_tests(tests, NULL, NULL); return rc; } nss_wrapper-1.1.16/tests/shadow.in000644 001750 000144 00000000356 13634203624 017111 0ustar00asnusers000000 000000 alice:$6$0jWkA8VP$MvBUvtGy38jWCZ5KtqnZEKQWXvvImDkDhDQII1kTqtAp3/xH31b71c.AjGkBFle.2QwCJQH7OzB/NXiMprusr/:1:0:99999:7::: bob:$6$0jWkA8VP$MvBUvtGy38jWCZ5KtqnZEKQWXvvImDkDhDQII1kTqtAp3/xH31b71c.AjGkBFle.2QwCJQH7OzB/NXiMprusr/:2:0:99999:7::: nss_wrapper-1.1.16/tests/valgrind.supp000644 001750 000144 00000001026 13634203624 020006 0ustar00asnusers000000 000000 ### GLIBC { glibc_dlopen_worker_alloc Memcheck:Leak fun:*alloc ... fun:dl_open_worker fun:_dl_catch_error fun:_dl_open fun:dlopen_doit fun:_dl_catch_error fun:_dlerror_run fun:dlopen@@GLIBC_2.2.5 } { glibc_dlopen_alloc Memcheck:Leak fun:calloc fun:_dlerror_run fun:dlopen@@GLIBC_2.2.5 } { glibc_dlclose_alloc Memcheck:Leak fun:calloc fun:_dlerror_run fun:dlclose } { glibc___sha512_crypt_alloc Memcheck:Leak fun:malloc fun:realloc fun:__sha512_crypt } nss_wrapper-1.1.16/tests/test_nwrap_vector.c000644 001750 000144 00000007055 13634203624 021213 0ustar00asnusers000000 000000 #include "config.h" #include #include #include #include #include "../src/nss_wrapper.c" static void test_nwrap_vector_basic_add(void **state) { struct nwrap_vector v; char string[] = "string!"; char string2[] = "2string!"; (void) state; /* unused */ nwrap_vector_init(&v); assert_non_null(v.items); nwrap_vector_add_item(&v, string); assert_null(v.items[1]); assert_int_equal(v.count, 1); assert_string_equal(v.items[0], string); assert_int_equal(v.capacity, DEFAULT_VECTOR_CAPACITY); assert_string_equal(v.items[0], "string!"); nwrap_vector_add_item(&v, string2); assert_null(v.items[2]); assert_int_equal(v.count, 2); assert_string_equal(v.items[0], string); assert_string_equal(v.items[1], string2); free(v.items); } static void test_nwrap_vector_merge_empty(void **state) { struct nwrap_vector v1; struct nwrap_vector v2; char string[] = "string!"; char string2[] = "2string!"; (void) state; /* unused */ nwrap_vector_init(&v1); assert_non_null(v1.items); assert_int_equal(v1.count, 0); nwrap_vector_init(&v2); assert_non_null(v2.items); assert_int_equal(v2.count, 0); nwrap_vector_merge(&v1, &v2); assert_int_equal(v1.count, 0); assert_null(v1.items[0]); nwrap_vector_add_item(&v1, string); nwrap_vector_add_item(&v1, string2); assert_int_equal(v1.count, 2); nwrap_vector_merge(&v1, &v2); assert_int_equal(v1.count, 2); assert_string_equal(v1.items[0], string); assert_string_equal(v1.items[1], string2); assert_null(v1.items[2]); nwrap_vector_merge(&v2, &v1); assert_int_equal(v2.count, 2); assert_string_equal(v2.items[0], string); assert_string_equal(v2.items[1], string2); assert_null(v2.items[2]); free(v1.items); free(v2.items); } static void test_nwrap_vector_merge(void **state) { struct nwrap_vector v1; struct nwrap_vector v2; char string[] = "string!"; char string2[] = "2string!"; (void) state; /* unused */ nwrap_vector_init(&v1); assert_non_null(v1.items); nwrap_vector_add_item(&v1, string); nwrap_vector_add_item(&v1, string2); assert_int_equal(v1.count, 2); nwrap_vector_init(&v2); assert_non_null(v2.items); nwrap_vector_add_item(&v2, string2); nwrap_vector_add_item(&v2, string); assert_int_equal(v2.count, 2); nwrap_vector_merge(&v1, &v2); assert_int_equal(v1.count, 4); assert_string_equal(v1.items[0], string); assert_string_equal(v1.items[1], string2); assert_string_equal(v1.items[2], string2); assert_string_equal(v1.items[3], string); assert_null(v1.items[4]); free(v1.items); free(v2.items); } static void test_nwrap_vector_merge_max(void **state) { struct nwrap_vector v1; struct nwrap_vector v2; char string[] = "string!"; char string2[] = "2string!"; int p; (void) state; /* unused */ nwrap_vector_init(&v1); assert_non_null(v1.items); for (p = 0; p < 64; ++p) { nwrap_vector_add_item(&v1, string); } assert_int_equal(v1.count, 64); nwrap_vector_init(&v2); assert_non_null(v2.items); nwrap_vector_merge(&v2, &v1); assert_int_equal(v2.count, 64); for (p = 0; p < 64; ++p) { assert_string_equal(v2.items[p], string); } nwrap_vector_add_item(&v2, string2); assert_string_equal(v2.items[64], string2); assert_int_equal(v2.count, 65); assert_null(v2.items[65]); free(v1.items); free(v2.items); } int main(void) { int rc; const struct CMUnitTest tests[] = { cmocka_unit_test(test_nwrap_vector_basic_add), cmocka_unit_test(test_nwrap_vector_merge_empty), cmocka_unit_test(test_nwrap_vector_merge), cmocka_unit_test(test_nwrap_vector_merge_max), }; rc = cmocka_run_group_tests(tests, NULL, NULL); return rc; } nss_wrapper-1.1.16/tests/hosts.in000644 001750 000144 00000013004 13634203624 016756 0ustar00asnusers000000 000000 127.0.0.11 magrathea.galaxy.site magrathea 127.0.0.12 magrathea.galaxy.site magrathea ::29a magrathea.galaxy.site magrathea 127.0.0.12 maximegalon.galaxy.site ::13 beteigeuze.galaxy.site beteigeuze mail 127.0.0.14 krikkit.galaxy.site ::14 krikkit.galaxy.site 127.1.1.1 pumpkin.bunny.net pumpkin.bunny.net 127.0.0.66 pumpkin.bunny.net 2666::22 pumpkin.bunny.net DEAD:BEEF:1:2:3::4 pumpkin.bunny.net B00B:5::4 pumpkin.bunny.net 127.0.0.21 localdc.samba.example.com samba.example.com localdc fd00:0000:0000:0000:0000:0000:5357:5f15 localdc.samba.example.com samba.example.com localdc 127.0.0.3 localnt4dc2.samba.example.com localnt4dc2 fd00:0000:0000:0000:0000:0000:5357:5f03 localnt4dc2.samba.example.com localnt4dc2 127.0.0.5 localshare4.samba.example.com localshare4 fd00:0000:0000:0000:0000:0000:5357:5f05 localshare4.samba.example.com localshare4 127.0.0.4 localnt4member3.samba.example.com localnt4member3 fd00:0000:0000:0000:0000:0000:5357:5f04 localnt4member3.samba.example.com localnt4member3 127.0.0.29 localadmember.samba.example.com localadmember fd00:0000:0000:0000:0000:0000:5357:5f1d localadmember.samba.example.com localadmember 127.0.0.23 s4member.samba.example.com s4member fd00:0000:0000:0000:0000:0000:5357:5f17 s4member.samba.example.com s4member 127.0.0.7 localktest6.samba.example.com localktest6 fd00:0000:0000:0000:0000:0000:5357:5f07 localktest6.samba.example.com localktest6 127.0.0.8 maptoguest.samba.example.com maptoguest fd00:0000:0000:0000:0000:0000:5357:5f08 maptoguest.samba.example.com maptoguest 127.0.0.35 fileserver.samba.example.com fileserver fd00:0000:0000:0000:0000:0000:5357:5f23 fileserver.samba.example.com fileserver 127.0.0.30 addc.addc.samba.example.com addc fd00:0000:0000:0000:0000:0000:5357:5f1e addc.addc.samba.example.com addc 127.0.0.9 localnt4dc9.samba.example.com localnt4dc9 fd00:0000:0000:0000:0000:0000:5357:5f09 localnt4dc9.samba.example.com localnt4dc9 127.0.0.34 rfc2307member.samba.example.com rfc2307member fd00:0000:0000:0000:0000:0000:5357:5f22 rfc2307member.samba.example.com rfc2307member 127.0.0.25 dc5.samba2000.example.com dc5 fd00:0000:0000:0000:0000:0000:5357:5f19 dc5.samba2000.example.com dc5 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 127.0.0.26 dc6.samba2003.example.com dc6 fd00:0000:0000:0000:0000:0000:5357:5f1a dc6.samba2003.example.com dc6 nss_wrapper-1.1.16/tests/test_getpwuid_module.c000644 001750 000144 00000001766 14142230333 021672 0ustar00asnusers000000 000000 #include "config.h" #include #include #include #include #include #include static void test_nwrap_passwd(void **state) { struct passwd *pwd; uid_t id = 424242; (void) state; /* unused */ pwd = getpwuid(id); assert_non_null(pwd); assert_string_equal(pwd->pw_name, "hanswurst"); assert_int_equal(pwd->pw_uid, id); assert_int_equal(pwd->pw_gid, id); } static void test_nwrap_passwd_closed_handles(void **state) { struct passwd *pwd; uid_t id = 424242; long maxfd; (void) state; /* unused */ pwd = getpwuid(id); assert_non_null(pwd); maxfd = sysconf(_SC_OPEN_MAX); if (maxfd < 0) { maxfd = 1024; } for (long fd = 3; fd < maxfd; fd++) { close(fd); } pwd = getpwuid(id); assert_non_null(pwd); } int main(void) { int rc; const struct CMUnitTest tests[] = { cmocka_unit_test(test_nwrap_passwd), cmocka_unit_test(test_nwrap_passwd_closed_handles), }; rc = cmocka_run_group_tests(tests, NULL, NULL); return rc; } nss_wrapper-1.1.16/tests/nss_nwrap.c000644 001750 000144 00000017701 14460666462 017467 0ustar00asnusers000000 000000 #include "config.h" #include #include #include #include #include #include #include #include #include "../src/nss_utils.h" #if defined(HAVE_NSS_H) /* Linux and BSD */ #include typedef enum nss_status NSS_STATUS; #elif defined(HAVE_NSS_COMMON_H) /* Solaris */ #include #include #include typedef nss_status_t NSS_STATUS; # define NSS_STATUS_SUCCESS NSS_SUCCESS # define NSS_STATUS_NOTFOUND NSS_NOTFOUND # define NSS_STATUS_UNAVAIL NSS_UNAVAIL # define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN #else # 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, size_t buflen, int *errnop); NSS_STATUS _nss_nwrap_getpwuid_r(uid_t uid, struct passwd *result, char *buffer, size_t buflen, int *errnop); NSS_STATUS _nss_nwrap_getpwnam_r(const char *name, struct passwd *result, 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, 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); #ifndef PTR_DIFF #define PTR_DIFF(p1, p2) ((ptrdiff_t)(((const char *)(p1)) - (const char *)(p2))) #endif static int pw_copy_r(const struct passwd *src, struct passwd *dst, char *buf, size_t buflen, struct passwd **dstp) { char *first; char *last; off_t ofs; first = src->pw_name; last = src->pw_shell; while (*last) last++; ofs = PTR_DIFF(last + 1, first); if (ofs > (off_t) buflen) { return ERANGE; } memcpy(buf, first, ofs); ofs = PTR_DIFF(src->pw_name, first); dst->pw_name = buf + ofs; ofs = PTR_DIFF(src->pw_passwd, first); dst->pw_passwd = buf + ofs; dst->pw_uid = src->pw_uid; dst->pw_gid = src->pw_gid; #ifdef HAVE_STRUCT_PASSWD_PW_CLASS ofs = PTR_DIFF(src->pw_class, first); dst->pw_class = buf + ofs; #endif /* HAVE_STRUCT_PASSWD_PW_CLASS */ #ifdef HAVE_STRUCT_PASSWD_PW_CHANGE dst->pw_change = 0; #endif /* HAVE_STRUCT_PASSWD_PW_CHANGE */ #ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE dst->pw_expire = 0; #endif /* HAVE_STRUCT_PASSWD_PW_EXPIRE */ ofs = PTR_DIFF(src->pw_gecos, first); dst->pw_gecos = buf + ofs; ofs = PTR_DIFF(src->pw_dir, first); dst->pw_dir = buf + ofs; ofs = PTR_DIFF(src->pw_shell, first); dst->pw_shell = buf + ofs; if (dstp) { *dstp = dst; } return 0; } NSS_STATUS _nss_nwrap_setpwent(void) { return NSS_STATUS_UNAVAIL; } NSS_STATUS _nss_nwrap_endpwent(void) { return NSS_STATUS_UNAVAIL; } NSS_STATUS _nss_nwrap_getpwent_r(struct passwd *result, char *buffer, size_t buflen, int *errnop) { (void) result; (void) buffer; (void) buflen; (void) errnop; return NSS_STATUS_UNAVAIL; } 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 = { .pw_name = &buf[0], .pw_passwd = &buf[10], .pw_uid = 424242, .pw_gid = 424242, .pw_gecos = &buf[17], .pw_dir = &buf[18], .pw_shell = &buf[34], }; memset(buffer, '\0', buflen); pw_copy_r(&src, result, buffer, buflen, NULL); errnop = 0; return NSS_STATUS_SUCCESS; } return NSS_STATUS_UNAVAIL; } NSS_STATUS _nss_nwrap_getpwnam_r(const char *name, struct passwd *result, char *buffer, size_t buflen, int *errnop) { (void) name; (void) result; (void) buffer; (void) buflen; (void) errnop; return NSS_STATUS_UNAVAIL; } static int grent_idx = 0; NSS_STATUS _nss_nwrap_setgrent(void) { grent_idx = 0; return NSS_STATUS_SUCCESS; } NSS_STATUS _nss_nwrap_endgrent(void) { grent_idx = 0; return NSS_STATUS_SUCCESS; } 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, 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, 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, long int *size, gid_t **groups, long int limit, int *errnop) { (void) user; (void)group; (void) limit; (void) errnop; 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; } nss_wrapper-1.1.16/tests/test_nwrap_disabled.c000644 001750 000144 00000004527 13634203624 021461 0ustar00asnusers000000 000000 #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include static void test_nwrap_passwd_group(void **state) { struct passwd *pwd; struct group *grp; (void) state; /* unused */ pwd = getpwuid(getuid()); assert_non_null(pwd); pwd = getpwnam(pwd->pw_name); assert_non_null(pwd); grp = getgrgid(pwd->pw_gid); assert_non_null(grp); grp = getgrnam(grp->gr_name); assert_non_null(grp); } /* Test libnsl */ static void test_nwrap_hostent(void **state) { #ifdef HAVE_NONNULL_GETHOSTENT struct hostent *he; (void) state; /* unused */ sethostent(0); he = gethostent(); assert_non_null(he); endhostent(); #else (void) state; /* unused */ sethostent(0); gethostent(); endhostent(); #endif } static void test_nwrap_gethostname(void **state) { char host[256] = {0}; int rc; (void) state; /* unused */ rc = gethostname(host, sizeof(host)); assert_int_equal(rc, 0); assert_true(strlen(host) > 1); } static void test_nwrap_getaddrinfo_local(void **state) { struct addrinfo hints; struct addrinfo *res; union { struct sockaddr *sa; struct sockaddr_in *in; } addr; int rc; (void) state; /* unused */ /* IPv4 */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_ADDRCONFIG; rc = getaddrinfo("127.0.0.1", NULL, &hints, &res); assert_int_equal(rc, 0); assert_int_equal(res->ai_family, AF_INET); assert_int_equal(res->ai_socktype, SOCK_STREAM); #ifdef HAVE_GETADDRINFO_SETS_CANONNAME_FOR_IPADDRESSES assert_string_equal(res->ai_canonname, "127.0.0.1"); #else /* HAVE_GETADDRINFO_SETS_CANONNAME_FOR_IPADDRESSES */ assert_null(res->ai_canonname); #endif /* HAVE_GETADDRINFO_SETS_CANONNAME_FOR_IPADDRESSES */ addr.sa = res->ai_addr; assert_int_equal(ntohl(addr.in->sin_addr.s_addr), INADDR_LOOPBACK); freeaddrinfo(res); } int main(void) { int rc; const struct CMUnitTest tests[] = { cmocka_unit_test(test_nwrap_passwd_group), cmocka_unit_test(test_nwrap_hostent), cmocka_unit_test(test_nwrap_gethostname), cmocka_unit_test(test_nwrap_getaddrinfo_local), }; rc = cmocka_run_group_tests(tests, NULL, NULL); return rc; } nss_wrapper-1.1.16/tests/test_shadow.c000644 001750 000144 00000002457 13634203624 017770 0ustar00asnusers000000 000000 #include "config.h" #include #include #include #include #include #include #include #include static void test_nwrap_getspent(void **state) { struct spwd *sp; uint32_t i; (void)state; /* unused */ setspent(); for (sp = getspent(), i = 0; sp != NULL; sp = getspent(), i++) { if (i == 0) { assert_string_equal(sp->sp_namp, "alice"); } else { assert_string_equal(sp->sp_namp, "bob"); } } endspent(); } static void test_nwrap_getspnam(void **state) { char *encrypted_password; struct spwd *sp; (void)state; /* unused */ sp = getspnam("alice"); assert_non_null(sp); assert_string_equal(sp->sp_namp, "alice"); encrypted_password = crypt("secret", sp->sp_pwdp); assert_non_null(encrypted_password); assert_string_equal(encrypted_password, sp->sp_pwdp); sp = getspnam("bob"); assert_non_null(sp); assert_string_equal(sp->sp_namp, "bob"); encrypted_password = crypt("secret", sp->sp_pwdp); assert_non_null(encrypted_password); assert_string_equal(encrypted_password, sp->sp_pwdp); } int main(void) { int rc; const struct CMUnitTest tests[] = { cmocka_unit_test(test_nwrap_getspent), cmocka_unit_test(test_nwrap_getspnam), }; rc = cmocka_run_group_tests(tests, NULL, NULL); return rc; } nss_wrapper-1.1.16/tests/test_getaddrinfo.c000644 001750 000144 00000045461 14547751607 021010 0ustar00asnusers000000 000000 #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include static void test_nwrap_getaddrinfo(void **state) { struct addrinfo hints; struct addrinfo *res = NULL; union { struct sockaddr *sa; struct sockaddr_in *in; struct sockaddr_in6 *in6; } addr; char ip6[INET6_ADDRSTRLEN]; char *ip; int rc; (void) state; /* unused */ /* IPv4 */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ hints.ai_protocol = 0; /* Any protocol */ hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; rc = getaddrinfo("127.0.0.11", NULL, &hints, &res); assert_int_equal(rc, 0); assert_non_null(res); assert_non_null(res->ai_canonname); assert_string_equal(res->ai_canonname, "magrathea.galaxy.site"); assert_int_equal(res->ai_family, AF_INET); addr.sa = res->ai_addr; assert_int_equal(addr.in->sin_family, AF_INET); ip = inet_ntoa(addr.in->sin_addr); assert_string_equal(ip, "127.0.0.11"); freeaddrinfo(res); res = NULL; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ hints.ai_protocol = 0; /* Any protocol */ hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; rc = getaddrinfo("::13", NULL, &hints, &res); assert_non_null(res); assert_int_equal(rc, 0); assert_non_null(res->ai_canonname); assert_string_equal(res->ai_canonname, "beteigeuze.galaxy.site"); assert_int_equal(res->ai_family, AF_INET6); addr.sa = res->ai_addr; assert_int_equal(addr.in6->sin6_family, AF_INET6); inet_ntop(AF_INET6, (void *)&addr.in6->sin6_addr, ip6, sizeof(ip6)); assert_string_equal(ip6, "::13"); freeaddrinfo(res); } /* * The purpose of this test is to verify that reloading of the hosts * file (triggered by a timestamp change) correctly frees and re-creates * the internal data structures, so we do not end up using invalid memory. */ static void test_nwrap_getaddrinfo_reload(void **state) { struct addrinfo hints; struct addrinfo *res = NULL; const char *env; char touch_cmd[1024]; int rc; (void) state; /* unused */ /* IPv4 */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ hints.ai_protocol = 0; /* Any protocol */ hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; rc = getaddrinfo("127.0.0.11", NULL, &hints, &res); assert_int_equal(rc, 0); assert_non_null(res); freeaddrinfo(res); res = NULL; env = getenv("NSS_WRAPPER_HOSTS"); assert_non_null(env); snprintf(touch_cmd, sizeof(touch_cmd), "touch %s", env); rc = system(touch_cmd); assert_return_code(rc, errno); rc = getaddrinfo("127.0.0.11", NULL, &hints, &res); assert_int_equal(rc, 0); assert_non_null(res); freeaddrinfo(res); } static void test_nwrap_getaddrinfo_samba(void **state) { struct addrinfo hints; struct addrinfo *res = NULL; int rc; (void) state; /* unused */ /* IPv4 */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_STREAM; /* Stream socket */ hints.ai_flags = 0; /* For wildcard IP address */ hints.ai_protocol = IPPROTO_TCP; /* Any protocol */ hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; rc = getaddrinfo("127.0.0.21", NULL, &hints, &res); assert_int_equal(rc, 0); assert_non_null(res); freeaddrinfo(res); res = NULL; rc = getaddrinfo("samba.example.com", NULL, &hints, &res); assert_int_equal(rc, 0); assert_non_null(res); freeaddrinfo(res); res = NULL; rc = getaddrinfo("localdc", NULL, &hints, &res); assert_int_equal(rc, 0); assert_non_null(res); freeaddrinfo(res); res = NULL; rc = getaddrinfo("localdc.samba.example.com", NULL, &hints, &res); assert_int_equal(rc, 0); assert_non_null(res); freeaddrinfo(res); res = NULL; rc = getaddrinfo("fd00:0000:0000:0000:0000:0000:5357:5f15", NULL, &hints, &res); assert_int_equal(rc, 0); assert_non_null(res); freeaddrinfo(res); } static void test_nwrap_getaddrinfo_any(void **state) { struct addrinfo hints; struct addrinfo *res = NULL; union { struct sockaddr *sa; struct sockaddr_in *in; struct sockaddr_in6 *in6; } addr; char ip6[INET6_ADDRSTRLEN]; char *ip; int rc; (void) state; /* unused */ /* IPv4 */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV; rc = getaddrinfo("0.0.0.0", "389", &hints, &res); assert_int_equal(rc, 0); assert_non_null(res); assert_int_equal(res->ai_family, AF_INET); assert_int_equal(res->ai_socktype, SOCK_STREAM); #ifdef HAVE_GETADDRINFO_SETS_CANONNAME_FOR_IPADDRESSES assert_string_equal(res->ai_canonname, "0.0.0.0"); #else /* HAVE_GETADDRINFO_SETS_CANONNAME_FOR_IPADDRESSES */ assert_null(res->ai_canonname); #endif /* HAVE_GETADDRINFO_SETS_CANONNAME_FOR_IPADDRESSES */ addr.sa = res->ai_addr; assert_int_equal(389, htons(addr.in->sin_port)); ip = inet_ntoa(addr.in->sin_addr); assert_string_equal(ip, "0.0.0.0"); freeaddrinfo(res); res = NULL; /* IPv4 */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV; rc = getaddrinfo("::", "389", &hints, &res); assert_int_equal(rc, 0); assert_non_null(res); assert_int_equal(res->ai_family, AF_INET6); assert_int_equal(res->ai_socktype, SOCK_STREAM); #ifdef HAVE_GETADDRINFO_SETS_CANONNAME_FOR_IPADDRESSES assert_string_equal(res->ai_canonname, "::"); #else /* HAVE_GETADDRINFO_SETS_CANONNAME_FOR_IPADDRESSES */ assert_null(res->ai_canonname); #endif /* HAVE_GETADDRINFO_SETS_CANONNAME_FOR_IPADDRESSES */ addr.sa = res->ai_addr; assert_int_equal(389, htons(addr.in6->sin6_port)); inet_ntop(AF_INET6, (void *)&addr.in6->sin6_addr, ip6, sizeof(ip6)); assert_string_equal(ip6, "::"); freeaddrinfo(res); } static void test_nwrap_getaddrinfo_local(void **state) { struct addrinfo hints; struct addrinfo *res; union { struct sockaddr *sa; struct sockaddr_in *in; struct sockaddr_in6 *in6; } addr; char *ip; int rc; (void) state; /* unused */ /* IPv4 */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = 0; rc = getaddrinfo("127.0.0.1", NULL, &hints, &res); assert_int_equal(rc, 0); assert_int_equal(res->ai_family, AF_INET); assert_int_equal(res->ai_socktype, SOCK_STREAM); #ifdef HAVE_GETADDRINFO_SETS_CANONNAME_FOR_IPADDRESSES assert_string_equal(res->ai_canonname, "127.0.0.1"); #else /* HAVE_GETADDRINFO_SETS_CANONNAME_FOR_IPADDRESSES */ assert_null(res->ai_canonname); #endif /* HAVE_GETADDRINFO_SETS_CANONNAME_FOR_IPADDRESSES */ addr.sa = res->ai_addr; ip = inet_ntoa(addr.in->sin_addr); assert_string_equal(ip, "127.0.0.1"); freeaddrinfo(res); } static void test_nwrap_getaddrinfo_name(void **state) { struct addrinfo hints; struct addrinfo *res = NULL; union { struct sockaddr *sa; struct sockaddr_in *in; struct sockaddr_in6 *in6; } addr; char *ip; int rc; (void) state; /* unused */ /* IPv4 */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = 0; rc = getaddrinfo("maximegalon.galaxy.site", NULL, &hints, &res); assert_int_equal(rc, 0); assert_non_null(res); assert_non_null(res); assert_int_equal(res->ai_family, AF_INET); assert_int_equal(res->ai_socktype, SOCK_STREAM); assert_non_null(res->ai_canonname); assert_string_equal(res->ai_canonname, "maximegalon.galaxy.site"); addr.sa = res->ai_addr; ip = inet_ntoa(addr.in->sin_addr); assert_string_equal(ip, "127.0.0.12"); freeaddrinfo(res); res = NULL; /* IPv4 */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = 0; rc = getaddrinfo("MAGRATHEA", NULL, &hints, &res); assert_int_equal(rc, 0); assert_non_null(res); assert_int_equal(res->ai_family, AF_INET); assert_int_equal(res->ai_socktype, SOCK_STREAM); assert_non_null(res->ai_canonname); assert_string_equal(res->ai_canonname, "magrathea.galaxy.site"); addr.sa = res->ai_addr; ip = inet_ntoa(addr.in->sin_addr); assert_string_equal(ip, "127.0.0.11"); freeaddrinfo(res); } static void test_nwrap_getaddrinfo_service(void **state) { struct addrinfo hints; struct addrinfo *res = NULL; union { struct sockaddr *sa; struct sockaddr_in *in; struct sockaddr_in6 *in6; } addr; char *ip; int rc; (void) state; /* unused */ /* IPv4 */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = 0; rc = getaddrinfo("magrathea", "wurst", &hints, &res); assert_int_equal(rc, EAI_NONAME); /* Check ldap port */ rc = getaddrinfo("magrathea", "ldap", &hints, &res); assert_int_equal(rc, 0); assert_non_null(res); assert_int_equal(res->ai_family, AF_INET); assert_int_equal(res->ai_socktype, SOCK_STREAM); assert_non_null(res->ai_canonname); assert_string_equal(res->ai_canonname, "magrathea.galaxy.site"); assert_non_null(res->ai_addr); addr.sa = res->ai_addr; ip = inet_ntoa(addr.in->sin_addr); assert_string_equal(ip, "127.0.0.11"); assert_int_equal(ntohs(addr.in->sin_port), 389); freeaddrinfo(res); } static void test_nwrap_getaddrinfo_null(void **state) { struct addrinfo hints; struct addrinfo *res = NULL; union { struct sockaddr *sa; struct sockaddr_in *in; struct sockaddr_in6 *in6; } addr; char ip6[INET6_ADDRSTRLEN]; int rc; (void) state; /* unused */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = 17; hints.ai_flags = 0; rc = getaddrinfo(NULL, NULL, &hints, &res); assert_int_equal(rc, EAI_NONAME); /* Check dns service */ rc = getaddrinfo(NULL, "domain", &hints, &res); assert_int_equal(rc, 0); assert_non_null(res); assert_null(res->ai_canonname); assert_int_equal(res->ai_family, AF_INET6); assert_int_equal(res->ai_socktype, SOCK_DGRAM); assert_non_null(res->ai_addr); addr.sa = res->ai_addr; inet_ntop(AF_INET6, (void *)&addr.in6->sin6_addr, ip6, sizeof(ip6)); assert_string_equal(ip6, "::1"); freeaddrinfo(res); res = NULL; /* Check dns service */ rc = getaddrinfo("magrathea", "domain", NULL, &res); assert_non_null(res); assert_int_equal(rc, 0); assert_non_null(res->ai_canonname); freeaddrinfo(res); } static void test_nwrap_getaddrinfo_dot(void **state) { struct addrinfo hints = { .ai_family = AF_INET, }; struct addrinfo *res = NULL; union { struct sockaddr *sa; struct sockaddr_in *in; struct sockaddr_in6 *in6; } addr; char ip[INET_ADDRSTRLEN]; int rc; (void) state; /* unused */ /* Check with a dot at the end */ rc = getaddrinfo("magrathea.galaxy.site.", NULL, &hints, &res); assert_int_equal(rc, 0); assert_non_null(res); assert_non_null(res->ai_next); assert_int_equal(res->ai_family, AF_INET); addr.sa = res->ai_addr; assert_int_equal(addr.in->sin_family, AF_INET); inet_ntop(AF_INET, (void *)&addr.in->sin_addr, ip, sizeof(ip)); assert_string_equal(ip, "127.0.0.11"); freeaddrinfo(res); } static void test_nwrap_getaddrinfo_ipv6(void **state) { struct addrinfo hints; struct addrinfo *res = NULL; union { struct sockaddr *sa; struct sockaddr_in *in; struct sockaddr_in6 *in6; } addr; char ip6[INET6_ADDRSTRLEN]; int rc; (void) state; /* unused */ /* * krikkit.galaxy has an IPv4 and IPv6 address, this should only * return the IPv6 address. */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET6; rc = getaddrinfo("krikkit.galaxy.site", NULL, &hints, &res); assert_int_equal(rc, 0); assert_non_null(res); assert_non_null(res->ai_next); assert_int_equal(res->ai_family, AF_INET6); addr.sa = res->ai_addr; assert_int_equal(addr.in6->sin6_family, AF_INET6); inet_ntop(AF_INET6, (void *)&addr.in6->sin6_addr, ip6, sizeof(ip6)); assert_string_equal(ip6, "::14"); freeaddrinfo(res); } static void test_nwrap_getaddrinfo_multiple_mixed(void **state) { struct addrinfo *res, *res_head; struct addrinfo hints; unsigned int ipv6_count = 0; unsigned int ipv4_count = 0; int rc; int p; union { struct sockaddr *sa; struct sockaddr_in *in; struct sockaddr_in6 *in6; } r_addr; const char *result = NULL; const char *value = NULL; /* For inet_ntop call */ char buf[4096]; /* 2 - ipv4 and 3 ipv6 addresses */ const char *ipvX_results[] = {"127.1.1.1", "127.0.0.66", "2666::22", "B00B:5::4", "DEAD:BEEF:1:2:3::4", NULL}; (void) state; /* unused */ memset(&hints, '\0', sizeof(struct addrinfo)); hints.ai_protocol = IPPROTO_TCP; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; rc = getaddrinfo("pumpkin.bunny.net", NULL, &hints, &res_head); assert_return_code(rc, 0); assert_non_null(res_head); for (res = res_head; res != NULL; res = res->ai_next) { if (res->ai_family == AF_INET) { r_addr.sa = res->ai_addr; assert_non_null(r_addr.sa); ++ipv4_count; result = inet_ntop(AF_INET, &r_addr.in->sin_addr, buf, 4096); } else if (res->ai_family == AF_INET6) { r_addr.sa = res->ai_addr; assert_non_null(r_addr.sa); ++ipv6_count; result = inet_ntop(AF_INET6, &r_addr.in6->sin6_addr, buf, 4096); } else { /* Unknown family type */ assert_int_equal(1,0); } /* Important part */ assert_non_null(result); /* This could be part of cmocka library */ for (value = ipvX_results[0], p = 0; value != NULL; value = ipvX_results[++p]) { if (strcasecmp(value, result) == 0) { break; } } assert_non_null(value); } assert_int_equal(ipv6_count, 3); assert_int_equal(ipv4_count, 2); freeaddrinfo(res_head); } static void test_nwrap_getaddrinfo_flags_ai_numericserv(void **state) { struct addrinfo hints; struct addrinfo *res; int rc; (void) state; /* unused */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV; /* For wildcard IP address */ hints.ai_protocol = 0; /* Any protocol */ hints.ai_canonname = NULL; /* * Calls with NULL name are handled by libc, * even if nss_wrapper is enabled */ rc = getaddrinfo(NULL, "echo", &hints, &res); #ifdef HAVE_GETADDRINFO_USES_EAI_SERVICE assert_int_equal(rc, EAI_SERVICE); #else /* HAVE_GETADDRINFO_USES_EAI_SERVICE */ assert_int_equal(rc, EAI_NONAME); #endif /* HAVE_GETADDRINFO_USES_EAI_SERVICE */ rc = getaddrinfo(NULL, "80", &hints, &res); assert_int_equal(rc, 0); freeaddrinfo(res); res = NULL; /* Crippled input */ rc = getaddrinfo(NULL, "80a1", &hints, &res); #ifdef HAVE_GETADDRINFO_USES_EAI_SERVICE assert_int_equal(rc, EAI_SERVICE); #else /* HAVE_GETADDRINFO_USES_EAI_SERVICE */ assert_int_equal(rc, EAI_NONAME); #endif /* HAVE_GETADDRINFO_USES_EAI_SERVICE */ /* * Calls with non-NULL name are handled by nwrap */ rc = getaddrinfo("magrathea.galaxy.site", "echo", &hints, &res); assert_int_equal(rc, EAI_NONAME); rc = getaddrinfo("magrathea.galaxy.site", "80", &hints, &res); assert_int_equal(rc, 0); freeaddrinfo(res); res = NULL; /* Crippled input */ rc = getaddrinfo("magrathea.galaxy.site", "80a1", &hints, &res); assert_int_equal(rc, EAI_NONAME); } static void test_nwrap_getaddrinfo_flags_ai_numerichost(void **state) { struct addrinfo hints; struct addrinfo *res; int rc; (void) state; /* unused */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; /* For wildcard IP address */ hints.ai_protocol = 0; /* Any protocol */ hints.ai_canonname = NULL; /* IPv4 or IPv6 */ hints.ai_family = AF_UNSPEC; rc = getaddrinfo("127.0.0.11", NULL, &hints, &res); assert_int_equal(rc, 0); freeaddrinfo(res); rc = getaddrinfo("::1", NULL, &hints, &res); assert_int_equal(rc, 0); freeaddrinfo(res); rc = getaddrinfo(NULL, "echo", &hints, &res); assert_int_equal(rc, 0); freeaddrinfo(res); rc = getaddrinfo("magrathea.galaxy.site", NULL, &hints, &res); assert_int_equal(rc, EAI_NONAME); rc = getaddrinfo("", NULL, &hints, &res); assert_int_equal(rc, EAI_NONAME); rc = getaddrinfo("fail.me", "echo", &hints, &res); assert_int_equal(rc, EAI_NONAME); /* IPv4 */ hints.ai_family = AF_INET; rc = getaddrinfo("127.0.0.11", NULL, &hints, &res); assert_int_equal(rc, 0); freeaddrinfo(res); rc = getaddrinfo("::1", NULL, &hints, &res); #ifdef EAI_ADDRFAMILY assert_int_equal(rc, EAI_ADDRFAMILY); #else assert_int_equal(rc, EAI_FAMILY); #endif rc = getaddrinfo(NULL, "echo", &hints, &res); assert_int_equal(rc, 0); freeaddrinfo(res); rc = getaddrinfo("magrathea.galaxy.site", NULL, &hints, &res); assert_int_equal(rc, EAI_NONAME); rc = getaddrinfo("", NULL, &hints, &res); assert_int_equal(rc, EAI_NONAME); rc = getaddrinfo("fail.me", "echo", &hints, &res); assert_int_equal(rc, EAI_NONAME); /* IPv6 */ hints.ai_family = AF_INET6; rc = getaddrinfo("127.0.0.11", NULL, &hints, &res); #ifdef EAI_ADDRFAMILY assert_int_equal(rc, EAI_ADDRFAMILY); #else assert_int_equal(rc, EAI_FAMILY); #endif rc = getaddrinfo("::1", NULL, &hints, &res); assert_int_equal(rc, 0); freeaddrinfo(res); rc = getaddrinfo(NULL, "echo", &hints, &res); assert_int_equal(rc, 0); freeaddrinfo(res); rc = getaddrinfo("magrathea.galaxy.site", NULL, &hints, &res); assert_int_equal(rc, EAI_NONAME); rc = getaddrinfo("", NULL, &hints, &res); assert_int_equal(rc, EAI_NONAME); rc = getaddrinfo("fail.me", "echo", &hints, &res); assert_int_equal(rc, EAI_NONAME); } int main(void) { int rc; const struct CMUnitTest tests[] = { cmocka_unit_test(test_nwrap_getaddrinfo), cmocka_unit_test(test_nwrap_getaddrinfo_reload), cmocka_unit_test(test_nwrap_getaddrinfo_any), cmocka_unit_test(test_nwrap_getaddrinfo_local), cmocka_unit_test(test_nwrap_getaddrinfo_name), cmocka_unit_test(test_nwrap_getaddrinfo_service), cmocka_unit_test(test_nwrap_getaddrinfo_null), cmocka_unit_test(test_nwrap_getaddrinfo_dot), cmocka_unit_test(test_nwrap_getaddrinfo_ipv6), cmocka_unit_test(test_nwrap_getaddrinfo_multiple_mixed), cmocka_unit_test(test_nwrap_getaddrinfo_flags_ai_numericserv), cmocka_unit_test(test_nwrap_getaddrinfo_flags_ai_numerichost), cmocka_unit_test(test_nwrap_getaddrinfo_samba), }; rc = cmocka_run_group_tests(tests, NULL, NULL); return rc; } nss_wrapper-1.1.16/tests/test_gethostent.c000644 001750 000144 00000002051 13634203624 020655 0ustar00asnusers000000 000000 #include "config.h" #include #include #include #include #include #include #include #include #include #include #include static void test_nwrap_gethostent(void **state) { struct hostent *he; uint32_t i; (void)state; /* unused */ sethostent(0); for (he = gethostent(); he != NULL; he = gethostent()) { assert_non_null(he->h_addr_list); assert_non_null(he->h_aliases); for (i = 0; he->h_addr_list[i] != NULL; i++) { char buf[INET6_ADDRSTRLEN]; uint32_t j; const char *ip; ip = inet_ntop(he->h_addrtype, he->h_addr_list[i], buf, sizeof(buf)); printf("ip: %s\n", ip); for (j = 0; he->h_aliases[j] != NULL; j++) { printf("alias: %s\n", he->h_aliases[j]); } } } endhostent(); } int main(void) { int rc; const struct CMUnitTest tests[] = { cmocka_unit_test(test_nwrap_gethostent), }; rc = cmocka_run_group_tests(tests, NULL, NULL); return rc; } nss_wrapper-1.1.16/tests/test_gethostby_name_addr.c000644 001750 000144 00000023261 13634640264 022506 0ustar00asnusers000000 000000 #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define NSS_WRAPPER_HOSTNAME_ENV "NSS_WRAPPER_HOSTNAME" static void test_nwrap_gethostname(void **state) { const char *hostname = "milliways"; char sys_host[256] = {0}; char host[16] = {0}; int rc; (void) state; /* unused */ rc = setenv(NSS_WRAPPER_HOSTNAME_ENV, hostname, 1); assert_int_equal(rc, 0); rc = gethostname(host, sizeof(host)); assert_int_equal(rc, 0); assert_string_equal(host, hostname); rc = setenv(NSS_WRAPPER_HOSTNAME_ENV, "this_hostname_is_too_long", 1); assert_int_equal(rc, 0); rc = gethostname(host, sizeof(host)); assert_int_equal(rc, -1); assert_int_equal(errno, ENAMETOOLONG); unsetenv(NSS_WRAPPER_HOSTNAME_ENV); rc = gethostname(sys_host, sizeof(sys_host)); assert_int_equal(rc, 0); } static void *thread_test_gethostbyname(void *u) { struct hostent *he; (void) u; /* unused */ he = gethostbyname("magrathea"); assert_non_null(he); assert_non_null(he->h_name); assert_string_equal(he->h_name, "magrathea.galaxy.site"); pthread_exit(NULL); } static void test_nwrap_gethostbyname_thread(void **state) { struct hostent *he; pthread_t th; (void) state; /* unused */ he = gethostbyname("maximegalon.galaxy.site"); assert_non_null(he); assert_non_null(he->h_name); assert_string_equal(he->h_name, "maximegalon.galaxy.site"); pthread_create(&th, NULL, &thread_test_gethostbyname, NULL); pthread_join(th, NULL); assert_non_null(he); assert_non_null(he->h_name); #ifdef BSD /* * On *BSD (and Mac OS X) systems, * data is stored in thread local storage. */ assert_string_equal(he->h_name, "maximegalon.galaxy.site"); #else /* * Glibc doesn't store data in thread local storage, so calling * gethostbyname from a thread overwrites the parent thread's data. */ assert_string_equal(he->h_name, "magrathea.galaxy.site"); #endif } static void test_nwrap_gethostbyname(void **state) { char ip[INET_ADDRSTRLEN]; struct hostent *he; const char *a; (void) state; /* unused */ he = gethostbyname("magrathea.galaxy.site"); assert_non_null(he); assert_non_null(he->h_name); assert_non_null(he->h_addr_list); assert_string_equal(he->h_name, "magrathea.galaxy.site"); assert_int_equal(he->h_addrtype, AF_INET); a = inet_ntop(AF_INET, he->h_addr_list[0], ip, sizeof(ip)); assert_non_null(a); assert_string_equal(ip, "127.0.0.11"); } static void test_nwrap_gethostbyname_multiple(void **state) { struct hostent *he; char **list; /* For inet_ntop call */ char buf[4096]; const char *result; char *p = buf; /* List of ips in hosts file - order matters */ const char *const result_ips[] = { "127.0.0.11", "127.0.0.12", NULL }; const char *actual_ip = result_ips[0]; unsigned int ac; (void) state; /* unused */ he = gethostbyname("magrathea.galaxy.site"); assert_non_null(he); assert_non_null(he->h_name); assert_non_null(he->h_addr_list); list = he->h_addr_list; for (ac = 0; *list != NULL; ++ac, ++list) { actual_ip = result_ips[ac]; /* When test fails here more records are returned */ assert_non_null(actual_ip); result = inet_ntop(AF_INET, *list, p, 4096); assert_non_null(p); assert_string_equal(actual_ip, result); } } #ifdef HAVE_GETHOSTBYNAME2 static void test_nwrap_gethostbyname2(void **state) { char ip[INET6_ADDRSTRLEN]; struct hostent *he; const char *a; (void) state; /* unused */ he = gethostbyname2("magrathea.galaxy.site", AF_INET6); assert_non_null(he); he = gethostbyname2("magrathea.galaxy.site", AF_INET); assert_non_null(he); /* Check ipv6 he */ he = gethostbyname2("krikkit.galaxy.site", AF_INET6); assert_non_null(he); assert_non_null(he->h_name); assert_non_null(he->h_addr_list); assert_string_equal(he->h_name, "krikkit.galaxy.site"); assert_int_equal(he->h_addrtype, AF_INET6); a = inet_ntop(AF_INET6, he->h_addr_list[0], ip, sizeof(ip)); assert_non_null(a); assert_string_equal(ip, "::14"); /* Check ipv4 he */ he = gethostbyname2("krikkit.galaxy.site", AF_INET); assert_non_null(he); assert_non_null(he->h_name); assert_non_null(he->h_addr_list); assert_string_equal(he->h_name, "krikkit.galaxy.site"); assert_int_equal(he->h_addrtype, AF_INET); a = inet_ntop(AF_INET, he->h_addr_list[0], ip, sizeof(ip)); assert_non_null(a); assert_string_equal(ip, "127.0.0.14"); } #endif /* HAVE_GETHOSTBYNAME2 */ static void test_nwrap_gethostbyaddr(void **state) { struct hostent *he; struct in_addr in; int rc; (void) state; /* unused */ rc = inet_aton("127.0.0.11", &in); assert_int_equal(rc, 1); he = gethostbyaddr(&in, sizeof(struct in_addr), AF_INET); assert_non_null(he); assert_non_null(he->h_name); assert_non_null(he->h_addr_list); assert_string_equal(he->h_name, "magrathea.galaxy.site"); assert_int_equal(he->h_addrtype, AF_INET); assert_memory_equal(&in, he->h_addr_list[0], he->h_length); } #ifdef HAVE_GETHOSTBYNAME_R static void test_nwrap_gethostbyname_r(void **state) { char buf[1024] = {0}; char ip[INET_ADDRSTRLEN]; struct hostent hb, *he; const char *a; int herr = 0; int rc; (void) state; /* unused */ rc = gethostbyname_r("magrathea.galaxy.site", &hb, buf, sizeof(buf), &he, &herr); assert_int_equal(rc, 0); assert_non_null(he); assert_non_null(he->h_name); assert_non_null(he->h_addr_list); assert_string_equal(he->h_name, "magrathea.galaxy.site"); assert_int_equal(he->h_addrtype, AF_INET); a = inet_ntop(AF_INET, he->h_addr_list[0], ip, sizeof(ip)); assert_non_null(a); assert_string_equal(ip, "127.0.0.11"); } static void test_nwrap_gethostbyname_r_null(void **state) { char buf[2]; struct hostent hb, *he; int herr = 0; int rc; (void) state; /* unused */ buf[0] = 'A'; buf[1] = '\0'; /* Check that the returned buffer is zeroed */ rc = gethostbyname_r("wurst", &hb, buf, sizeof(buf), &he, &herr); assert_int_equal(rc, ENOENT); assert_null(he); assert_null(hb.h_name); assert_null(hb.h_addr_list); assert_string_equal(buf, ""); } #endif #ifdef HAVE_GETHOSTBYNAME2_R static void test_nwrap_gethostbyname2_r_v4(void **state) { char *buf = NULL; size_t buflen = 2; char ip[INET_ADDRSTRLEN]; struct hostent hb, *he; const char *a; int herr = 0; int rc; (void) state; /* unused */ for (rc = ERANGE, buflen = 2; rc == ERANGE; buflen *= 2) { if (buf != NULL) { free(buf); } buf = calloc(1, buflen); assert_non_null(buf); rc = gethostbyname2_r("magrathea.galaxy.site", AF_INET, &hb, buf, buflen, &he, &herr); } assert_int_equal(rc, 0); assert_int_equal(herr, 0); assert_non_null(he); assert_non_null(he->h_name); assert_non_null(he->h_addr_list); assert_string_equal(he->h_name, "magrathea.galaxy.site"); assert_int_equal(he->h_addrtype, AF_INET); assert_non_null(he->h_addr_list[0]); a = inet_ntop(AF_INET, he->h_addr_list[0], ip, sizeof(ip)); assert_non_null(a); assert_string_equal(a, "127.0.0.11"); assert_non_null(he->h_addr_list[1]); a = inet_ntop(AF_INET, he->h_addr_list[1], ip, sizeof(ip)); assert_non_null(a); assert_string_equal(a, "127.0.0.12"); assert_null(he->h_addr_list[2]); free(buf); } static void test_nwrap_gethostbyname2_r_v6(void **state) { char *buf = NULL; size_t buflen = 2; char ip[INET6_ADDRSTRLEN]; struct hostent hb, *he; const char *a; int herr = 0; int rc; (void) state; /* unused */ for (rc = ERANGE, buflen = 2; rc == ERANGE; buflen *= 2) { if (buf != NULL) { free(buf); } buf = calloc(1, buflen); assert_non_null(buf); rc = gethostbyname2_r("magrathea.galaxy.site", AF_INET6, &hb, buf, buflen, &he, &herr); } assert_int_equal(rc, 0); assert_int_equal(herr, 0); assert_non_null(he); assert_non_null(he->h_name); assert_non_null(he->h_addr_list); assert_string_equal(he->h_name, "magrathea.galaxy.site"); assert_int_equal(he->h_addrtype, AF_INET6); assert_non_null(he->h_addr_list[0]); a = inet_ntop(AF_INET6, he->h_addr_list[0], ip, sizeof(ip)); assert_non_null(a); assert_string_equal(a, "::29a"); assert_null(he->h_addr_list[1]); free(buf); } #endif #ifdef HAVE_GETHOSTBYADDR_R static void test_nwrap_gethostbyaddr_r(void **state) { char buf[1024] = {0}; struct hostent hb, *he; struct in_addr in; int herr = 0; int rc; (void) state; /* unused */ rc = inet_aton("127.0.0.11", &in); assert_int_equal(rc, 1); rc = gethostbyaddr_r(&in, sizeof(struct in_addr), AF_INET, &hb, buf, sizeof(buf), &he, &herr); assert_int_equal(rc, 0); assert_non_null(he); assert_non_null(he->h_name); assert_non_null(he->h_addr_list); assert_string_equal(he->h_name, "magrathea.galaxy.site"); assert_int_equal(he->h_addrtype, AF_INET); assert_memory_equal(&in, he->h_addr_list[0], he->h_length); } #endif int main(void) { int rc; const struct CMUnitTest tests[] = { cmocka_unit_test(test_nwrap_gethostname), cmocka_unit_test(test_nwrap_gethostbyname), cmocka_unit_test(test_nwrap_gethostbyname_thread), #ifdef HAVE_GETHOSTBYNAME2 cmocka_unit_test(test_nwrap_gethostbyname2), #endif cmocka_unit_test(test_nwrap_gethostbyaddr), #ifdef HAVE_GETHOSTBYNAME_R cmocka_unit_test(test_nwrap_gethostbyname_r), cmocka_unit_test(test_nwrap_gethostbyname_r_null), #endif #ifdef HAVE_GETHOSTBYNAME2_R cmocka_unit_test(test_nwrap_gethostbyname2_r_v4), cmocka_unit_test(test_nwrap_gethostbyname2_r_v6), #endif #ifdef HAVE_GETHOSTBYADDR_R cmocka_unit_test(test_nwrap_gethostbyaddr_r), #endif cmocka_unit_test(test_nwrap_gethostbyname_multiple), }; rc = cmocka_run_group_tests(tests, NULL, NULL); return rc; } nss_wrapper-1.1.16/tests/passwd.in000644 001750 000144 00000000311 13634203624 017114 0ustar00asnusers000000 000000 bob:x:1000:1000:bob gecos:@HOMEDIR@:/bin/false alice:x:1001:1000:alice gecos:@HOMEDIR@:/bin/false nobody:x:65533:65534:bob gecos:@HOMEDIR@:/bin/false root:x:65534:65532:root gecos:@HOMEDIR@:/bin/false nss_wrapper-1.1.16/tests/test_initgroups.c000644 001750 000144 00000002320 14464660771 020707 0ustar00asnusers000000 000000 #include #include #include #include #include #include #include #include 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; } nss_wrapper-1.1.16/tests/group.in000644 001750 000144 00000000155 14460666462 016770 0ustar00asnusers000000 000000 users:x:1000:alice,bob all:x:1002:alice,bob,nobody,root nobody:x:65533: nogroup:x:65534:nobody root:x:65532: nss_wrapper-1.1.16/tests/test_getnameinfo.c000644 001750 000144 00000016565 13634203624 021004 0ustar00asnusers000000 000000 #include "config.h" #include #include #include #include #include #include #include #include #include #include #include static void test_nwrap_getnameinfo(void **state) { char host[256] = {0}; char serv[256] = {0}; struct sockaddr_in sin; struct sockaddr_in6 sin6; int flags = 0; int rc; (void) state; /* unused */ /* IPv4 */ sin.sin_family = AF_INET; sin.sin_port = htons(53); rc = inet_pton(AF_INET, "127.0.0.11", &sin.sin_addr); assert_int_equal(rc, 1); rc = getnameinfo((const struct sockaddr *)&sin, sizeof(struct sockaddr_in), host, sizeof(host), serv, sizeof(serv), flags); assert_int_equal(rc, 0); assert_string_equal(host, "magrathea.galaxy.site"); assert_string_equal(serv, "domain"); /* IPv6 */ sin6.sin6_family = AF_INET6; sin6.sin6_port = htons(53); rc = inet_pton(AF_INET6, "::13", &sin6.sin6_addr); assert_int_equal(rc, 1); rc = getnameinfo((const struct sockaddr *)&sin6, sizeof(struct sockaddr_in6), host, sizeof(host), serv, sizeof(serv), flags); assert_int_equal(rc, 0); assert_string_equal(host, "beteigeuze.galaxy.site"); assert_string_equal(serv, "domain"); } static void test_nwrap_getnameinfo_numeric(void **state) { char host[256] = {0}; char serv[256] = {0}; struct sockaddr_in sin; struct sockaddr_in6 sin6; int flags = 0; int rc; (void) state; /* unused */ /* IPv4 */ sin.sin_family = AF_INET; sin.sin_port = htons(53); rc = inet_pton(AF_INET, "127.0.0.11", &sin.sin_addr); assert_int_equal(rc, 1); flags = NI_NUMERICHOST; rc = getnameinfo((const struct sockaddr *)&sin, sizeof(struct sockaddr_in), host, sizeof(host), serv, sizeof(serv), flags); assert_int_equal(rc, 0); assert_string_equal(host, "127.0.0.11"); assert_string_equal(serv, "domain"); /* IPv6 */ sin6.sin6_family = AF_INET6; sin6.sin6_port = htons(53); rc = inet_pton(AF_INET6, "::13", &sin6.sin6_addr); assert_int_equal(rc, 1); flags = NI_NUMERICSERV; rc = getnameinfo((const struct sockaddr *)&sin6, sizeof(struct sockaddr_in6), host, sizeof(host), serv, sizeof(serv), flags); assert_int_equal(rc, 0); assert_string_equal(host, "beteigeuze.galaxy.site"); assert_string_equal(serv, "53"); } static void test_nwrap_getnameinfo_any(void **state) { char host[256] = {0}; char serv[256] = {0}; struct sockaddr_in sin; struct sockaddr_in6 sin6; int flags = 0; int rc; (void) state; /* unused */ /* IPv4 */ sin.sin_family = AF_INET; sin.sin_port = htons(22); rc = inet_pton(AF_INET, "0.0.0.0", &sin.sin_addr); assert_int_equal(rc, 1); rc = getnameinfo((const struct sockaddr *)&sin, sizeof(struct sockaddr_in), host, sizeof(host), serv, sizeof(serv), flags); assert_int_equal(rc, 0); assert_string_equal(host, "0.0.0.0"); assert_string_equal(serv, "ssh"); /* IPv6 */ sin6.sin6_family = AF_INET6; sin6.sin6_port = htons(22); rc = inet_pton(AF_INET6, "::", &sin6.sin6_addr); assert_int_equal(rc, 1); rc = getnameinfo((const struct sockaddr *)&sin6, sizeof(struct sockaddr_in6), host, sizeof(host), serv, sizeof(serv), flags); assert_int_equal(rc, 0); assert_string_equal(host, "::"); assert_string_equal(serv, "ssh"); } static void test_nwrap_getnameinfo_local(void **state) { char host[256] = {0}; char serv[256] = {0}; struct sockaddr_in sin; struct sockaddr_in6 sin6; int flags = 0; int rc; (void) state; /* unused */ /* IPv4 */ sin.sin_family = AF_INET; sin.sin_port = htons(22); rc = inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr); assert_int_equal(rc, 1); rc = getnameinfo((const struct sockaddr *)&sin, sizeof(struct sockaddr_in), host, sizeof(host), serv, sizeof(serv), flags); assert_int_equal(rc, 0); assert_string_equal(host, "127.0.0.1"); assert_string_equal(serv, "ssh"); /* IPv6 */ sin6.sin6_family = AF_INET6; sin6.sin6_port = htons(22); rc = inet_pton(AF_INET6, "::1", &sin6.sin6_addr); assert_int_equal(rc, 1); rc = getnameinfo((const struct sockaddr *)&sin6, sizeof(struct sockaddr_in6), host, sizeof(host), serv, sizeof(serv), flags); assert_int_equal(rc, 0); assert_string_equal(host, "::1"); assert_string_equal(serv, "ssh"); } static void test_nwrap_getnameinfo_null(void **state) { char host[256] = {0}; char serv[256] = {0}; struct sockaddr_in sin; struct sockaddr_in6 sin6; int flags = 0; int rc; (void) state; /* unused */ rc = getnameinfo(NULL, 0, host, sizeof(host), serv, sizeof(serv), flags); assert_int_equal(rc, EAI_FAMILY); /* IPv4 */ sin.sin_family = AF_INET; sin.sin_port = htons(22); rc = inet_pton(AF_INET, "127.0.0.11", &sin.sin_addr); assert_int_equal(rc, 1); rc = getnameinfo((const struct sockaddr *)&sin, sizeof(struct sockaddr_in), NULL, 0, serv, sizeof(serv), flags); assert_int_equal(rc, 0); assert_string_equal(serv, "ssh"); /* IPv6 */ sin6.sin6_family = AF_INET6; sin6.sin6_port = htons(22); rc = inet_pton(AF_INET6, "::13", &sin6.sin6_addr); assert_int_equal(rc, 1); rc = getnameinfo((const struct sockaddr *)&sin6, sizeof(struct sockaddr_in6), host, sizeof(host), NULL, 0, flags); assert_int_equal(rc, 0); assert_string_equal(host, "beteigeuze.galaxy.site"); /* IPv6 */ sin6.sin6_family = AF_INET6; sin6.sin6_port = htons(22); rc = inet_pton(AF_INET6, "::13", &sin6.sin6_addr); assert_int_equal(rc, 1); rc = getnameinfo((const struct sockaddr *)&sin6, sizeof(struct sockaddr_in6), NULL, 0, NULL, 0, flags); assert_int_equal(rc, 0); assert_string_equal(host, "beteigeuze.galaxy.site"); } static void test_nwrap_getnameinfo_flags(void **state) { char host[256] = {0}; char serv[256] = {0}; struct sockaddr_in sin; int flags = 0; int rc; (void) state; /* unused */ /* NI_NAMEREQD */ sin.sin_family = AF_INET; sin.sin_port = htons(22); rc = inet_pton(AF_INET, "127.0.0.11", &sin.sin_addr); assert_int_equal(rc, 1); flags = NI_NAMEREQD; rc = getnameinfo((const struct sockaddr *)&sin, sizeof(struct sockaddr_in), NULL, 0, NULL, 0, flags); assert_int_equal(rc, EAI_NONAME); /* NI_DGRAM */ sin.sin_family = AF_INET; sin.sin_port = htons(513); rc = inet_pton(AF_INET, "127.0.0.11", &sin.sin_addr); assert_int_equal(rc, 1); flags = NI_DGRAM; rc = getnameinfo((const struct sockaddr *)&sin, sizeof(struct sockaddr_in), host, sizeof(host), serv, sizeof(serv), flags); assert_int_equal(rc, 0); assert_string_equal(serv, "who"); /* STREAM (port 513) */ flags = 0; rc = getnameinfo((const struct sockaddr *)&sin, sizeof(struct sockaddr_in), host, sizeof(host), serv, sizeof(serv), flags); assert_int_equal(rc, 0); assert_string_equal(serv, "login"); /* NI_NOFQDN */ flags = NI_NOFQDN; rc = getnameinfo((const struct sockaddr *)&sin, sizeof(struct sockaddr_in), host, sizeof(host), serv, sizeof(serv), flags); assert_int_equal(rc, 0); assert_string_equal(host, "magrathea"); } int main(void) { int rc; const struct CMUnitTest tests[] = { cmocka_unit_test(test_nwrap_getnameinfo), cmocka_unit_test(test_nwrap_getnameinfo_numeric), cmocka_unit_test(test_nwrap_getnameinfo_any), cmocka_unit_test(test_nwrap_getnameinfo_local), cmocka_unit_test(test_nwrap_getnameinfo_null), cmocka_unit_test(test_nwrap_getnameinfo_flags), }; rc = cmocka_run_group_tests(tests, NULL, NULL); return rc; } nss_wrapper-1.1.16/CompilerChecks.cmake000644 001750 000144 00000012335 14255266062 020034 0ustar00asnusers000000 000000 include(AddCCompilerFlag) include(CheckCCompilerFlagSSP) if (UNIX) # # Check for -Werror turned on if possible # # This will prevent that compiler flags are detected incorrectly. # check_c_compiler_flag("-Werror" REQUIRED_FLAGS_WERROR) if (REQUIRED_FLAGS_WERROR) set(CMAKE_REQUIRED_FLAGS "-Werror") if (PICKY_DEVELOPER) list(APPEND SUPPORTED_COMPILER_FLAGS "-Werror") endif() endif() add_c_compiler_flag("-std=gnu99" SUPPORTED_COMPILER_FLAGS) #add_c_compiler_flag("-Wpedantic" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Wall" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Wshadow" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Wmissing-prototypes" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Wcast-align" SUPPORTED_COMPILER_FLAGS) #add_c_compiler_flag("-Wcast-qual" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Werror=address" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Wstrict-prototypes" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Werror=strict-prototypes" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Wwrite-strings" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Werror=write-strings" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Werror-implicit-function-declaration" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Wpointer-arith" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Werror=pointer-arith" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Wdeclaration-after-statement" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Werror=declaration-after-statement" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Wreturn-type" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Werror=return-type" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Wuninitialized" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Werror=uninitialized" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Wimplicit-fallthrough" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Werror=strict-overflow" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Wstrict-overflow=2" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Wno-format-zero-length" SUPPORTED_COMPILER_FLAGS) check_c_compiler_flag("-Wformat" REQUIRED_FLAGS_WFORMAT) if (REQUIRED_FLAGS_WFORMAT) list(APPEND SUPPORTED_COMPILER_FLAGS "-Wformat") set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Wformat") endif() add_c_compiler_flag("-Wformat-security" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Werror=format-security" SUPPORTED_COMPILER_FLAGS) # Allow zero for a variadic macro argument string(TOLOWER "${CMAKE_C_COMPILER_ID}" _C_COMPILER_ID) if ("${_C_COMPILER_ID}" STREQUAL "clang") add_c_compiler_flag("-Wno-gnu-zero-variadic-macro-arguments" SUPPORTED_COMPILER_FLAGS) endif() add_c_compiler_flag("-fno-common" SUPPORTED_COMPILER_FLAGS) if (CMAKE_BUILD_TYPE) string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER) if (CMAKE_BUILD_TYPE_LOWER MATCHES (release|relwithdebinfo|minsizerel)) add_c_compiler_flag("-Wp,-D_FORTIFY_SOURCE=2" SUPPORTED_COMPILER_FLAGS) endif() endif() if (NOT SOLARIS) check_c_compiler_flag_ssp("-fstack-protector-strong" WITH_STACK_PROTECTOR_STRONG) if (WITH_STACK_PROTECTOR_STRONG) list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-protector-strong") # This is needed as Solaris has a seperate libssp if (SOLARIS) list(APPEND SUPPORTED_LINKER_FLAGS "-fstack-protector-strong") endif() else (WITH_STACK_PROTECTOR_STRONG) check_c_compiler_flag_ssp("-fstack-protector" WITH_STACK_PROTECTOR) if (WITH_STACK_PROTECTOR) list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-protector") # This is needed as Solaris has a seperate libssp if (SOLARIS) list(APPEND SUPPORTED_LINKER_FLAGS "-fstack-protector") endif() endif() endif (WITH_STACK_PROTECTOR_STRONG) check_c_compiler_flag_ssp("-fstack-clash-protection" WITH_STACK_CLASH_PROTECTION) if (WITH_STACK_CLASH_PROTECTION) list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-clash-protection") endif() endif() if (PICKY_DEVELOPER) add_c_compiler_flag("-Wno-error=deprecated-declarations" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("-Wno-error=tautological-compare" SUPPORTED_COMPILER_FLAGS) endif() # Unset CMAKE_REQUIRED_FLAGS unset(CMAKE_REQUIRED_FLAGS) endif() if (MSVC) add_c_compiler_flag("/D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("/D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("/D _CRT_NONSTDC_NO_WARNINGS=1" SUPPORTED_COMPILER_FLAGS) add_c_compiler_flag("/D _CRT_SECURE_NO_WARNINGS=1" SUPPORTED_COMPILER_FLAGS) endif() if (SUPPORTED_COMPILER_FLAGS) set(DEFAULT_C_COMPILE_FLAGS ${SUPPORTED_COMPILER_FLAGS} CACHE INTERNAL "Default C Compiler Flags" FORCE) endif() if (SUPPORTED_LINKER_FLAGS) set(DEFAULT_LINK_FLAGS ${SUPPORTED_LINKER_FLAGS} CACHE INTERNAL "Default C Linker Flags" FORCE) endif() nss_wrapper-1.1.16/.clangd/000750 001750 000144 00000000000 14641730071 015427 5ustar00asnusers000000 000000 nss_wrapper-1.1.16/.clangd/index/000750 001750 000144 00000000000 14641730071 016536 5ustar00asnusers000000 000000 nss_wrapper-1.1.16/.clangd/index/test_gethostent.c.FDE119456A174D8F.idx000644 001750 000144 00000004502 13622466757 024663 0ustar00asnusers000000 000000 RIFF: CdIxmeta stri-DNDEBUG-D_GNU_SOURCE-I/home/asn/workspace/projects/nss_wrapper/obj-I/home/asn/workspace/projects/nss_wrapper/obj/tests-I/home/asn/workspace/projects/nss_wrapper/tests-O2-Wall-Wcast-align-Wdeclaration-after-statement-Werror-Werror-implicit-function-declaration-Werror=address-Werror=declaration-after-statement-Werror=format-security-Werror=pointer-arith-Werror=return-type-Werror=strict-overflow-Werror=strict-prototypes-Werror=uninitialized-Werror=write-strings-Wformat-Wformat-security-Wimplicit-fallthrough-Wmissing-prototypes-Wno-error=deprecated-declarations-Wno-error=tautological-compare-Wno-format-zero-length-Wpointer-arith-Wreturn-type-Wshadow-Wstrict-overflow=2-Wstrict-prototypes-Wuninitialized-Wwrite-strings-c-fPIE-fno-common-fstack-clash-protection-fstack-protector-strong-fsyntax-only-g-o-resource-dir=/home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0-std=gnu99/home/asn/workspace/projects/nss_wrapper/obj/tests/home/asn/workspace/projects/nss_wrapper/tests/test_gethostent.c/usr/bin/ccCMakeFiles/test_gethostent.dir/test_gethostent.c.ofile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stdarg.hfile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stddef.hfile:///home/asn/workspace/projects/nss_wrapper/obj/config.hfile:///home/asn/workspace/projects/nss_wrapper/tests/test_gethostent.cfile:///usr/include/arpa/inet.hfile:///usr/include/cmocka.hfile:///usr/include/netdb.hfile:///usr/include/netinet/in.hfile:///usr/include/setjmp.hfile:///usr/include/stdio.hfile:///usr/include/string.hfile:///usr/include/sys/socket.hfile:///usr/include/unistd.hmaintest_nwrap_gethostentsymb@\Sc! ?4 !4 !W{ >422422refs8S袹4 G!'4 <4 4 N(og44))4**'Y?N"X4"" Z,g@w4""VF 4553n7xĐ4!44##7 M̦4// 46MQ4 4*4:w4'' 4** relasrcs34: I 31296:;=<8577619;=<8:52cmdl1-//)$ , "  !%'&*0#.(+nss_wrapper-1.1.16/.clangd/index/nss_wrapper.c.496306141B70693D.idx000644 001750 000144 00000125006 13641330102 023646 0ustar00asnusers000000 000000 RIFFCdIxmeta stri3(${1:__gid_t __gid})(${1:__gid_t __gid}, ${2:struct group *restrict __resultbuf}, ${3:char *restrict __buffer}, ${4:size_t __buflen}, ${5:struct group **restrict __result})(${1:__uid_t __uid})(${1:__uid_t __uid}, ${2:struct passwd *restrict __resultbuf}, ${3:char *restrict __buffer}, ${4:size_t __buflen}, ${5:struct passwd **restrict __result})(${1:char *__name}, ${2:size_t __len})(${1:const char *__name})(${1:const char *__name}, ${2:int __af})(${1:const char *__user}, ${2:__gid_t __group})(${1:const char *__user}, ${2:__gid_t __group}, ${3:__gid_t *__groups}, ${4:int *__ngroups})(${1:const char *restrict __name}, ${2:const char *restrict __service}, ${3:const struct addrinfo *restrict __req}, ${4:struct addrinfo **restrict __pai})(${1:const char *restrict __name}, ${2:int __af}, ${3:struct hostent *restrict __result_buf}, ${4:char *restrict __buf}, ${5:size_t __buflen}, ${6:struct hostent **restrict __result}, ${7:int *restrict __h_errnop})(${1:const char *restrict __name}, ${2:struct group *restrict __resultbuf}, ${3:char *restrict __buffer}, ${4:size_t __buflen}, ${5:struct group **restrict __result})(${1:const char *restrict __name}, ${2:struct hostent *restrict __result_buf}, ${3:char *restrict __buf}, ${4:size_t __buflen}, ${5:struct hostent **restrict __result}, ${6:int *restrict __h_errnop})(${1:const char *restrict __name}, ${2:struct passwd *restrict __resultbuf}, ${3:char *restrict __buffer}, ${4:size_t __buflen}, ${5:struct passwd **restrict __result})(${1:const struct sockaddr *restrict __sa}, ${2:socklen_t __salen}, ${3:char *restrict __host}, ${4:socklen_t __hostlen}, ${5:char *restrict __serv}, ${6:socklen_t __servlen}, ${7:int __flags})(${1:const void *__addr}, ${2:__socklen_t __len}, ${3:int __type})(${1:const void *restrict __addr}, ${2:__socklen_t __len}, ${3:int __type}, ${4:struct hostent *restrict __result_buf}, ${5:char *restrict __buf}, ${6:size_t __buflen}, ${7:struct hostent **restrict __result}, ${8:int *restrict __h_errnop})(${1:int __stay_open})(${1:struct group *restrict __resultbuf}, ${2:char *restrict __buffer}, ${3:size_t __buflen}, ${4:struct group **restrict __result})(${1:struct passwd *restrict __resultbuf}, ${2:char *restrict __buffer}, ${3:size_t __buflen}, ${4:struct passwd **restrict __result})()(__gid_t __gid)(__gid_t __gid, struct group *restrict __resultbuf, char *restrict __buffer, size_t __buflen, struct group **restrict __result)(__uid_t __uid)(__uid_t __uid, struct passwd *restrict __resultbuf, char *restrict __buffer, size_t __buflen, struct passwd **restrict __result)(char *__name, size_t __len)(const char *__name)(const char *__name, int __af)(const char *__user, __gid_t __group)(const char *__user, __gid_t __group, __gid_t *__groups, int *__ngroups)(const char *restrict __name, const char *restrict __service, const struct addrinfo *restrict __req, struct addrinfo **restrict __pai)(const char *restrict __name, int __af, struct hostent *restrict __result_buf, char *restrict __buf, size_t __buflen, struct hostent **restrict __result, int *restrict __h_errnop)(const char *restrict __name, struct group *restrict __resultbuf, char *restrict __buffer, size_t __buflen, struct group **restrict __result)(const char *restrict __name, struct hostent *restrict __result_buf, char *restrict __buf, size_t __buflen, struct hostent **restrict __result, int *restrict __h_errnop)(const char *restrict __name, struct passwd *restrict __resultbuf, char *restrict __buffer, size_t __buflen, struct passwd **restrict __result)(const struct sockaddr *restrict __sa, socklen_t __salen, char *restrict __host, socklen_t __hostlen, char *restrict __serv, socklen_t __servlen, int __flags)(const void *__addr, __socklen_t __len, int __type)(const void *restrict __addr, __socklen_t __len, int __type, struct hostent *restrict __result_buf, char *restrict __buf, size_t __buflen, struct hostent **restrict __result, int *restrict __h_errnop)(int __stay_open)(struct group *restrict __resultbuf, char *restrict __buffer, size_t __buflen, struct group **restrict __result)(struct passwd *restrict __resultbuf, char *restrict __buffer, size_t __buflen, struct passwd **restrict __result)-D_GNU_SOURCE-Dnss_wrapper_EXPORTS-I/home/asn/workspace/projects/nss_wrapper/obj-asan-I/home/asn/workspace/projects/nss_wrapper/obj-asan/src-I/home/asn/workspace/projects/nss_wrapper/src-O0-Wall-Wcast-align-Wdeclaration-after-statement-Werror-Werror-implicit-function-declaration-Werror=address-Werror=declaration-after-statement-Werror=format-security-Werror=pointer-arith-Werror=return-type-Werror=strict-overflow-Werror=strict-prototypes-Werror=uninitialized-Werror=write-strings-Wformat-Wformat-security-Wimplicit-fallthrough-Wmissing-prototypes-Wno-error=deprecated-declarations-Wno-error=tautological-compare-Wno-format-zero-length-Wpointer-arith-Wreturn-type-Wshadow-Wstrict-overflow=2-Wstrict-prototypes-Wuninitialized-Wwrite-strings-c-fPIC-fno-common-fno-omit-frame-pointer-fsanitize=address-fstack-clash-protection-fstack-protector-strong-fsyntax-only-g-ggdb-o-resource-dir=/home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0-std=gnu99/home/asn/workspace/projects/nss_wrapper/obj-asan/src/home/asn/workspace/projects/nss_wrapper/src/nss_wrapper.c/usr/bin/ccCMakeFiles/nss_wrapper.dir/nss_wrapper.c.oNSS_STATUSNWRAP_LIBCNWRAP_LIBNSLNWRAP_LIBSOCKETNWRAP_LOG_DEBUGNWRAP_LOG_ERRORNWRAP_LOG_TRACENWRAP_LOG_WARN__libc_endgrent__libc_endhostent__libc_endpwent__libc_getaddrinfo__libc_getgrent__libc_getgrent_r__libc_getgrgid__libc_getgrgid_r__libc_getgrnam__libc_getgrnam_r__libc_getgrouplist__libc_gethostbyaddr__libc_gethostbyaddr_r__libc_gethostbyname__libc_gethostbyname2__libc_gethostbyname2_r__libc_gethostbyname_r__libc_gethostent__libc_gethostname__libc_getnameinfo__libc_getpwent__libc_getpwent_r__libc_getpwnam__libc_getpwnam_r__libc_getpwuid__libc_getpwuid_r__libc_initgroups__libc_setgrent__libc_sethostent__libc_setpwent__nwrap_cache_gr__nwrap_cache_he__nwrap_cache_pw__nwrap_cache_sp__nwrap_main_global_libc_endgrent_libc_endhostent_libc_endpwent_libc_getaddrinfo_libc_getgrent_libc_getgrent_r_libc_getgrgid_libc_getgrgid_r_libc_getgrnam_libc_getgrnam_r_libc_getgrouplist_libc_gethostbyaddr_libc_gethostbyaddr_r_libc_gethostbyname_libc_gethostbyname2_libc_gethostbyname2_r_libc_gethostbyname_r_libc_gethostent_libc_gethostname_libc_getnameinfo_libc_getpwent_libc_getpwent_r_libc_getpwnam_libc_getpwnam_r_libc_getpwuid_libc_getpwuid_r_libc_initgroups_libc_setgrent_libc_sethostent_libc_setpwent_nss_endgrent_nss_endpwent_nss_getgrent_r_nss_getgrgid_r_nss_getgrnam_r_nss_gethostbyaddr_r_nss_gethostbyname2_r_nss_getpwent_r_nss_getpwnam_r_nss_getpwuid_r_nss_initgroups_nss_setgrent_nss_setpwent_nwrap_bind_symboladdraliases_countbackendsc:*$@S@groupc:*$@S@hostentc:*$@S@passwdc:*$@S@spwdc:Ic:vcachecapacitycountdefault_hintsedendgrentendhostentendpwentendspententriesffdfile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stdarg.hfile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stdbool.hfile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stddef.hfile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stdint.hfile:///home/asn/workspace/projects/nss_wrapper/obj-asan/config.hfile:///home/asn/workspace/projects/nss_wrapper/src/nss_wrapper.cfile:///usr/include/arpa/inet.hfile:///usr/include/assert.hfile:///usr/include/ctype.hfile:///usr/include/dlfcn.hfile:///usr/include/errno.hfile:///usr/include/fcntl.hfile:///usr/include/grp.hfile:///usr/include/netdb.hfile:///usr/include/netinet/in.hfile:///usr/include/nss.hfile:///usr/include/pthread.hfile:///usr/include/pwd.hfile:///usr/include/search.hfile:///usr/include/shadow.hfile:///usr/include/stdio.hfile:///usr/include/stdlib.hfile:///usr/include/string.hfile:///usr/include/sys/socket.hfile:///usr/include/sys/stat.hfile:///usr/include/sys/types.hfile:///usr/include/unistd.hfnsfpgetaddrinfogetgrentgetgrent_rgetgrgidgetgrgid_rgetgrnamgetgrnam_rgetgrouplistgethostbyaddrgethostbyaddr_rgethostbynamegethostbyname2gethostbyname2_rgethostbyname_rgethostentgethostnamegetnameinfogetprognamegetpwentgetpwent_rgetpwnamgetpwnam_rgetpwuidgetpwuid_rgetspentgetspnamhandlehost_addrhtidxinitgroupsintitemslibclibc_endgrentlibc_endhostentlibc_endpwentlibc_getaddrinfolibc_getgrentlibc_getgrent_rlibc_getgrgidlibc_getgrgid_rlibc_getgrnamlibc_getgrnam_rlibc_getgrouplistlibc_gethostbyaddrlibc_gethostbyaddr_rlibc_gethostbynamelibc_gethostbyname2libc_gethostbyname2_rlibc_gethostbyname_rlibc_gethostentlibc_gethostnamelibc_getnameinfolibc_getpwentlibc_getpwent_rlibc_getpwnamlibc_getpwnam_rlibc_getpwuidlibc_getpwuid_rlibc_initgroupslibc_setgrentlibc_sethostentlibc_setpwentlibc_symbol_binding_mutexlineslistlistsmax_hostentsnamenextnsl_handlenss_wrapper_enablednss_wrapper_hosts_enablednss_wrapper_shadow_enablednumnum_backendsnw_endgrentnw_endpwentnw_getgrentnw_getgrent_rnw_getgrgidnw_getgrgid_rnw_getgrnamnw_getgrnam_rnw_gethostbyaddrnw_gethostbynamenw_gethostbyname2nw_gethostbyname2_rnw_getpwentnw_getpwent_rnw_getpwnamnw_getpwnam_rnw_getpwuidnw_getpwuid_rnw_initgroupsnw_setgrentnw_setpwentnwrap_add_hnamenwrap_addrdatanwrap_addrdata::nwrap_backendnwrap_backend::nwrap_backend_initnwrap_cachenwrap_cache::nwrap_constructornwrap_convert_he_ainwrap_dbglvl_enwrap_destructornwrap_ed_inventarizenwrap_ed_inventarize_add_newnwrap_ed_inventarize_add_to_existingnwrap_endgrentnwrap_endhostentnwrap_endpwentnwrap_endspentnwrap_entdatanwrap_entdata::nwrap_entlistnwrap_entlist::nwrap_entlist_initnwrap_files_cache_reloadnwrap_files_cache_unloadnwrap_files_endgrentnwrap_files_endhostentnwrap_files_endpwentnwrap_files_endspentnwrap_files_getaddrinfonwrap_files_getgrentnwrap_files_getgrent_rnwrap_files_getgrgidnwrap_files_getgrgid_rnwrap_files_getgrnamnwrap_files_getgrnam_rnwrap_files_gethostbyaddrnwrap_files_gethostbynamenwrap_files_gethostbyname2nwrap_files_gethostbyname2_rnwrap_files_gethostentnwrap_files_getpwentnwrap_files_getpwent_rnwrap_files_getpwnamnwrap_files_getpwnam_rnwrap_files_getpwuidnwrap_files_getpwuid_rnwrap_files_getspentnwrap_files_getspnamnwrap_files_initgroupsnwrap_files_internal_gethostbynamenwrap_files_opsnwrap_files_setgrentnwrap_files_sethostentnwrap_files_setpwentnwrap_files_setspentnwrap_getaddrinfonwrap_getgrentnwrap_getgrent_rnwrap_getgrgidnwrap_getgrgid_rnwrap_getgrnamnwrap_getgrnam_rnwrap_getgrouplistnwrap_gethostbyaddrnwrap_gethostbyaddr_rnwrap_gethostbynamenwrap_gethostbyname2nwrap_gethostbyname2_rnwrap_gethostbyname_rnwrap_gethostentnwrap_gethostnamenwrap_getnameinfonwrap_getpwentnwrap_getpwent_rnwrap_getpwnamnwrap_getpwnam_rnwrap_getpwuidnwrap_getpwuid_rnwrap_getspentnwrap_getspnamnwrap_global_mutexnwrap_grnwrap_gr::nwrap_gr_copy_rnwrap_gr_globalnwrap_gr_global_mutexnwrap_gr_parse_linenwrap_gr_unloadnwrap_henwrap_he::nwrap_he_globalnwrap_he_global_mutexnwrap_he_parse_linenwrap_he_unloadnwrap_hostname_enablednwrap_initnwrap_initgroupsnwrap_initializednwrap_initialized_mutexnwrap_libnwrap_libcnwrap_libc::nwrap_libc_initnwrap_libc_symbolsnwrap_libc_symbols::nwrap_libc_symbols::(anonymous union)::nwrap_lines_unloadnwrap_load_lib_handlenwrap_load_modulenwrap_load_module_fnnwrap_load_module_fnsnwrap_lognwrap_mainnwrap_main::nwrap_main_globalnwrap_module_endgrentnwrap_module_endpwentnwrap_module_getgrentnwrap_module_getgrent_rnwrap_module_getgrgidnwrap_module_getgrgid_rnwrap_module_getgrnamnwrap_module_getgrnam_rnwrap_module_gethostbyaddrnwrap_module_gethostbynamenwrap_module_gethostbyname2nwrap_module_gethostbyname2_rnwrap_module_getpwentnwrap_module_getpwent_rnwrap_module_getpwnamnwrap_module_getpwnam_rnwrap_module_getpwuidnwrap_module_getpwuid_rnwrap_module_initnwrap_module_initgroupsnwrap_module_nss_fnsnwrap_module_nss_fns::nwrap_module_opsnwrap_module_setgrentnwrap_module_setpwentnwrap_opsnwrap_ops::nwrap_parse_filenwrap_pwnwrap_pw::nwrap_pw_copy_rnwrap_pw_globalnwrap_pw_global_mutexnwrap_pw_parse_linenwrap_pw_unloadnwrap_setgrentnwrap_sethostentnwrap_setpwentnwrap_setspentnwrap_spnwrap_sp::nwrap_sp_globalnwrap_sp_global_mutexnwrap_sp_parse_linenwrap_sp_unloadnwrap_str_libnwrap_thread_childnwrap_thread_parentnwrap_thread_preparenwrap_vectornwrap_vector::nwrap_vector_add_itemnwrap_vector_initnwrap_vector_mergeobjopsparse_linepathprivate_datasetgrentsethostentsetpwentsetspentso_handleso_pathsock_handleststr_tolowerstr_tolower_copystruct group *struct hostent *struct passwd *struct spwd *symbolsunloaduser_addrlistuser_addrlist2user_heuser_he2voidsymbE׮ŬILz ##** ƫ]WueE#r4?y,  0 01y:   M( y%%'Gdi8S袹 ++r r ']jDž$h=   Z_>_ ((#((#L%bCSA""~ /%LЃ x//Q dW   v#p   ;BI   i`  ** ($Ah Ӿ!     &&$&&$ } &&  #^ 5Ϥ_ }   Sy#Ӳ   E && i쥶p +Α~GɈj5yS  m'p;ў ) )) )6y.1*gcrY% % %% %>< \A8 q_> //   ]ĵ &&mm ^f|3d  ms'y ( (( (&<@Y)   ժQh   4s剕   V     !%d.k %%$%%$09B " "" ":*Mz //J~ p''EM ((6[ v$$x`   &  &դ\ $ $( (pr   ` UsiUs\ + ++ +fYnG + +YY _BzQ  B`^ US     C ?'$   DJ[y  D;q * ** *G߻0HxO'8 && G G ^H &p\@  J&#ӼIJ J   JA. %%11Kj3j4q  L>(N    L`f  M+J#MȋLTNW/  Oh7 ,,*,,*OA_ض 00  `OܭST  Qv3   Rlne  R5yYfRC$SFV*  S[>ĖT^AМi  U-E  Uw*Uڂ қ  U   VX5W ,,$ ]VX,sVtW-,   WElarWNPEPWP7*8!!XTl &&  ^Xy[o  Y $  YbxVR% Z3 ((Zkx  ZN5TZJ9=ek  [;4   [g7\Tx ]NQZ ##]rI֌ ^/OIU ,,,,^0a ** B B \^35dT`6lU> ++"++"` } ! !" "a-{ad1 jaY * ** *b}=JESX   c^]z-  eRxU+  ! !e   eD  fY0a  ! !fwTg#ՁZ !!gB l ((g>Mg%eyV%@   iDFQC   jɑ^k ?hro     l8Wf  l63P`  ! !m֡  n #}l ""**n4  " "oz<+ p}pH䕴U ''  )^q A  qb=`q47   q)/~y   rwtQY  tT ( ,,*,,*u']^4   u z%Q   uvVLvv#y(O ' '' 'wn.wE,G  xMwr   z;x n''z 2   |䨕  ! !|Gt5`| bYY"YY"}=Gс   )  )~#^n{` ''SS ^~fͱr  $ $~:Hm  CfR  ! !oP{ ))  (\c>@h'i     NR  3k" %%ss ^9x  ZIN> ,,?   "  "b5###s  $ $8w(5n>K  ;fp   ''x%  ' '^8N  ! !aov" '' M M ^<\A-Q\   A Yu !!++E㦰L'oI.iu=   #  #z!]a45u     +r lrx^  kw ,,(,,( _   #  #ܻSlm$ ++'++'w?/Pp  d+j  |f#UٮzRue]’    ]*ĴIaw  ! !?8,)a       H ٞsM / // /Q=Wݷ,.x" Fskb׫ 00 ~((ZG/^ ##**dso3;[j  v * ,,׀x__ Vm+b  &ݒTS8  T`ekK4;^   )  )J39v   ?-  *Q ,,Wѓ 00f<N 00k(  " "g6e m  :hzy *7w'  3%t w..f ))UdE 6CxJ $ $" "& -R$$],N9ܔ  b">G ((  ! \ Z   +Ly!c ɵ7   φ눛  |~   G{6~, )) < < \ #  PՎYyXGLh:b݉5lij< . .. .H;7W {++MX>Ci'ybBٯ0 # #" "+## - k  0::j $$11dK;c & && &^)|8hSJ   "  "6,%F  QyY ,,*,,*5>   6%h.\0si#z ))  \9qx~U ,,11ƖOtm   Օ3~f##e [>mb ** A A _qEf] **"   ++-?$     E8  ʥ  ʿRˮ"{ t!!˲~fNF ,,̆E;G ))gLxU   ͋x?  " "t-@Y0 $$my/Y~ 3   -  -ѝok<   #!E@ |  HgUe " "! !ֶLfR  du? **   \u E     ȉ9T ((dd \&zzFB ,,00׳qGԝ 00؇$ + ++ +أx/B ,,),,)@   `ګ ++ I I _j^_weqL - -  p ++"++"یֹrP $ $! !(<E   ܦ&Q ))(TWi9?* 0 00 0Vh# **ݡ &ݦ{%  " "$_   ߡS6Gߙ(ev efZ^ ' '' 'oeWa   z2`}  cu5̦  t    4 %%22(߷!dU ! !" "_5S 00  $])01k X  - -Yܛg>i   *  *6?4(     蒐~-|5Z  ꒺fCM ++.:""iƁs  ۑˆ$ɭ7% dw#K_z:%P ,,7 M̦ ++x x ]VEs({)  vUhz~;? " "" "Mdd   X?Q   #  #h?  nz@ ) )) )򚰅gRp:  " "̤/##WQ] ))3! ,,+,,+,՞*j   9x譗   "  "KcE   ~  ( (Ekm[@ **~ϰR$ E o ]Ys) # #! !gev ((jj \ h: ,,,,lگ  b#  혩 ,,% ]Har@refss/8S袹++ !f %ľS?3Oນ -- ----%- -----. ..".-/// ///!/ /cr -3  =  -5 o2&%.. }&& RKaM8<(,(,g`Bf .5%,$N(og  ! $ ؀-.. ID$bĵ&&z _>//Ӝ  ޕ>+ % , ""####$$%%%%**! b,  !vo=11 11 11 11 !b\`X  #ԥ  $SG))&k b)OqD00*$|/----#+b}}.lvy5!!!!!!!!!!""!""""!""##!####!$$$$!$$%%!%%!0Eru- -//3A,0****111146MQ++4= yZ         .4                               ( .                   !!!!"" ""##$$ $$$$%%%%%%%%&&&&&&&&&&&&&&'''' ''''''''(((((((((((((()))))))) ))))**,,,,,,//////0)0/00"006Nȭf+ +4 ˊ  6?        3 < & /$$,,, ,-- /8/A// 0+0400005C}DW  3_x].4  -- -- -- :.29. .:w  <Ƭ;eS!_7Y Y?G$F<>nG+ +B6|A// G!'V    ,3              $+                  $$$$$ $$ $%%%%%%%%++++,,,,,,,,,,,,,,,,,,,,,,,,,,-,-3//HxO'8&& I.K@  --// L%NX)`U OA_ض00Qd P\ -- ----%- ---- ---/ //// ///!/ /QF  TH +1  4 :- -- -&030900000%0+TUVUO6+*/!&$       $ )    ! !!! &%&*&&&&!&&VX5W,,XBWl~!!"! !!!!!"!!""""""""""##"####"$$$$"$$%%"%%"XTl&&Z,g@w  00\⟇ & ,$ ""####$$%%%%**--/ /^0a** _[Cx   + 3----adV(YJW -5"* e7ҢE   **gݍY      ,,---------.-6....... .. ./ // //!/)/(/0/// /Y?N"X   ''  - -----(- -k< go +1 l:BΤӉ--//m\܂d    (. 8>17&,%'-'- "%'-'- "# &(.(.           " ( (.<B'-%'-'- "  !!! !&!(!.!!!!!!!(!.!!!!""""#%%%%%% %5%;%(%.&(&.&)&/&&&&&& &.&4&(&.&!&'&)&/&&'''' '#')''#''''$np)({--'- --%-1////(oAb|0 0pH䕴U''pŰ{^y  sD k tZߴh  uTǙ̒--/ /s o|ems[v  xMڇ{6_d--////#{O0 /A-- -- -- ----~zƚl ,3")  "  %,$* ** *$oNkk${))ڇ<,, ꡛm8''21B  +1$* $#****#Θp8 !!!!"""""""##"####"$$$$"$$%%"%%"3k" %%mR-- --u+d%^O'' ~C311 11 11 11 /gGŨ  .5 %,$ S  Ӿ@U 11 8000*00e]’EfcK  !QH  **-- -- // HoQp  !"  $  $ %%%% 00lC (-- --... . G --////!}s5|B438).!&  16$       - 2 # (        (-"  """"## ## '.'3'!'&($()((((!))*0*5* ******-*2***C*H*+*0*#*(*0*5zdK !uFho..7Qt/" "b">G(((WS#- -J^~6 ='ҏ09$- &{6~,)) N47y1%0 05Q. ./ // /䇲(3   "ʿ$- 00 00 0000 "*  ~#^n{`''öJ$G&,------- -/// /// 9YBy2;\ c|$si#z))mb** . .BeX    减 ɞi  _Ú --&- --$-/////'JD "#     00 00 00 9@-V +1 $#Ђ X, du?**ȉ9T((։3eel    ++++ ++++ ׂԻz----00 `ګ++ X] // /"/-ۅ׾    fr2p`tn|`                  ްH'_mLT ....ߐ$#f    (- 8=16&+ $', ',  !$',', !" %(-(-            " '  (-;@', $', ',   ! """"" "%"("-#######(#-####$$$$"(((( (( (5(:(((-(((-()(.(((( (( (.(3(((-)!)&))).)))) )) )#)())"))))#** 3n7xĐ   "----*,1   !   %  ! ! & *** *&** _5S00G4za\. .DssT*X]I-- -- --. .....* Ob/7 ) 1- -- -/*/2////00%h6=..7 M̦++q m! -- -- /5/</ // ///$/ /N&A$[". .F%@- -  v((4@-. u. .//Ҁ- -//혩,,relasrcsz+iIcmdl4Y2[*+-.,TU/POM3X0GA15I;K=4E826F9J<@:HD>?7NRQBCVaLZSWnss_wrapper-1.1.16/.clangd/index/test_nwrap_disabled.c.59E63F9B2D58E517.idx000644 001750 000144 00000005524 13622466757 025454 0ustar00asnusers000000 000000 RIFFL CdIxmeta stri-DNDEBUG-D_GNU_SOURCE-I/home/asn/workspace/projects/nss_wrapper/obj-I/home/asn/workspace/projects/nss_wrapper/obj/tests-I/home/asn/workspace/projects/nss_wrapper/tests-O2-Wall-Wcast-align-Wdeclaration-after-statement-Werror-Werror-implicit-function-declaration-Werror=address-Werror=declaration-after-statement-Werror=format-security-Werror=pointer-arith-Werror=return-type-Werror=strict-overflow-Werror=strict-prototypes-Werror=uninitialized-Werror=write-strings-Wformat-Wformat-security-Wimplicit-fallthrough-Wmissing-prototypes-Wno-error=deprecated-declarations-Wno-error=tautological-compare-Wno-format-zero-length-Wpointer-arith-Wreturn-type-Wshadow-Wstrict-overflow=2-Wstrict-prototypes-Wuninitialized-Wwrite-strings-c-fPIE-fno-common-fstack-clash-protection-fstack-protector-strong-fsyntax-only-g-o-resource-dir=/home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0-std=gnu99/home/asn/workspace/projects/nss_wrapper/obj/tests/home/asn/workspace/projects/nss_wrapper/tests/test_nwrap_disabled.c/usr/bin/ccCMakeFiles/test_nwrap_disabled.dir/test_nwrap_disabled.c.ofile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stdarg.hfile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stddef.hfile:///home/asn/workspace/projects/nss_wrapper/obj/config.hfile:///home/asn/workspace/projects/nss_wrapper/tests/test_nwrap_disabled.cfile:///usr/include/arpa/inet.hfile:///usr/include/cmocka.hfile:///usr/include/grp.hfile:///usr/include/netdb.hfile:///usr/include/netinet/in.hfile:///usr/include/pwd.hfile:///usr/include/setjmp.hfile:///usr/include/string.hfile:///usr/include/sys/socket.hfile:///usr/include/sys/types.hfile:///usr/include/unistd.hmaintest_nwrap_getaddrinfo_localtest_nwrap_gethostnametest_nwrap_hostenttest_nwrap_passwd_groupsymbc3;e B4< <"4< <"t4 D4 #4 #qK C4& &4& &{5B A4I I(4I I(W{ @4nn4nnrefsöJ$G&,4dd8S袹4-- cr43k" 4G!'4))/gGŨ4OA_ض4CC _Ú 4O OQd P\4XX4__"JD4F Fĵ4\S 4ȉ9T4_>4[[VF 4qq G 4i!i)ߐ$#4 lC4WW4^^ gݍY4KK4LL4V!V)* Ob4N Nl:BΤӉ4kk m\܂4X]I4YY7 M̦422 3_x]4VV46MQ4//v4!!{O0 /A4ggmE4i*i0~zƚl4!!relasrcs37:861;=<?94aPsN 312;6>=598:752cmdl1-//)$ , "  !%'&*0#.(+nss_wrapper-1.1.16/.clangd/index/test_getnameinfo.c.779E41D17A149E05.idx000644 001750 000144 00000006500 13622466757 024731 0ustar00asnusers000000 000000 RIFF8 CdIxmeta stri-DNDEBUG-D_GNU_SOURCE-I/home/asn/workspace/projects/nss_wrapper/obj-I/home/asn/workspace/projects/nss_wrapper/obj/tests-I/home/asn/workspace/projects/nss_wrapper/tests-O2-Wall-Wcast-align-Wdeclaration-after-statement-Werror-Werror-implicit-function-declaration-Werror=address-Werror=declaration-after-statement-Werror=format-security-Werror=pointer-arith-Werror=return-type-Werror=strict-overflow-Werror=strict-prototypes-Werror=uninitialized-Werror=write-strings-Wformat-Wformat-security-Wimplicit-fallthrough-Wmissing-prototypes-Wno-error=deprecated-declarations-Wno-error=tautological-compare-Wno-format-zero-length-Wpointer-arith-Wreturn-type-Wshadow-Wstrict-overflow=2-Wstrict-prototypes-Wuninitialized-Wwrite-strings-c-fPIE-fno-common-fstack-clash-protection-fstack-protector-strong-fsyntax-only-g-o-resource-dir=/home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0-std=gnu99/home/asn/workspace/projects/nss_wrapper/obj/tests/home/asn/workspace/projects/nss_wrapper/tests/test_getnameinfo.c/usr/bin/ccCMakeFiles/test_getnameinfo.dir/test_getnameinfo.c.ofile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stdarg.hfile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stddef.hfile:///home/asn/workspace/projects/nss_wrapper/obj/config.hfile:///home/asn/workspace/projects/nss_wrapper/tests/test_getnameinfo.cfile:///usr/include/arpa/inet.hfile:///usr/include/cmocka.hfile:///usr/include/netdb.hfile:///usr/include/netinet/in.hfile:///usr/include/setjmp.hfile:///usr/include/stdio.hfile:///usr/include/string.hfile:///usr/include/sys/socket.hfile:///usr/include/unistd.hmaintest_nwrap_getnameinfotest_nwrap_getnameinfo_anytest_nwrap_getnameinfo_flagstest_nwrap_getnameinfo_localtest_nwrap_getnameinfo_nulltest_nwrap_getnameinfo_numericsymb;{*` @4l l&4l l&2-ز C4 '4 '(P{G D4< <*4< <*T 7 ?4 "4 "8vx A4 (4 (Χz B4 (4 (W{ >44refs _Ú 44""4@@4PP4pp4~~444444444mLT 44..4JJ4\\4zz44444444VF 4 G 4,44J,J44z)z14+34,44,44,4_5S4!!4114OO4aa4}}44444444444(WS#44HH4xx4444* Ob4! !(41 1(4O O(4a a(4} }(4 (4 (4 (4 (4 (4 (4 (4 (4 (4 (np)({ 44224AA4bb4qq4444440Eru4 4II 4yy 4 4 4 4 F%@4,,4ZZ4444{6_d4.(.14\(\14&/4'04(14(1Ҁ4--4[[4444relasrcs3764,0\d 31296:;=<85719;=<8:52cmdl1-//)$ , "  !%'&*0#.(+nss_wrapper-1.1.16/.clangd/index/test_nwrap_vector.c.6DA36926E43E358A.idx000644 001750 000144 00000005324 13622466757 025172 0ustar00asnusers000000 000000 RIFF CdIxmeta stri-DNDEBUG-D_GNU_SOURCE-I/home/asn/workspace/projects/nss_wrapper/obj-I/home/asn/workspace/projects/nss_wrapper/obj/tests-I/home/asn/workspace/projects/nss_wrapper/tests-O2-Wall-Wcast-align-Wdeclaration-after-statement-Werror-Werror-implicit-function-declaration-Werror=address-Werror=declaration-after-statement-Werror=format-security-Werror=pointer-arith-Werror=return-type-Werror=strict-overflow-Werror=strict-prototypes-Werror=uninitialized-Werror=write-strings-Wformat-Wformat-security-Wimplicit-fallthrough-Wmissing-prototypes-Wno-error=deprecated-declarations-Wno-error=tautological-compare-Wno-format-zero-length-Wpointer-arith-Wreturn-type-Wshadow-Wstrict-overflow=2-Wstrict-prototypes-Wuninitialized-Wwrite-strings-c-fPIE-fno-common-fstack-clash-protection-fstack-protector-strong-fsyntax-only-g-o-resource-dir=/home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0-std=gnu99/home/asn/workspace/projects/nss_wrapper/obj/tests/home/asn/workspace/projects/nss_wrapper/tests/test_nwrap_vector.c/usr/bin/ccCMakeFiles/test_nwrap_vector.dir/test_nwrap_vector.c.ofile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stdarg.hfile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stddef.hfile:///home/asn/workspace/projects/nss_wrapper/obj/config.hfile:///home/asn/workspace/projects/nss_wrapper/src/nss_wrapper.cfile:///home/asn/workspace/projects/nss_wrapper/tests/test_nwrap_vector.cfile:///usr/include/cmocka.hfile:///usr/include/setjmp.hmaintest_nwrap_vector_basic_addtest_nwrap_vector_mergetest_nwrap_vector_merge_emptytest_nwrap_vector_merge_maxsymbm L 95 '5 'L& :5N N#5N N#yV=J <5o o'5o o'Kò ;5% %)5% %)W{ 855refswc>@5 555005445775<<5??5EE5[[5aa5dd555;5  5''5((5PP5QQ5qq5rrY055..5225WW5]]5yy5Zkx#5555555  5"" 5//5335885@@5AA5BB5FF5GG5HH5J J5K K5XX5^^5ee5ff5gg5hh5ii5k k5l l5zz55555 5 [;45665>>5DD5cc5VF 5l63P` 555::5;;5YY5ZZ5__5``5}}53A5""5JJ5KK5kk5ll55relasrcsS3458q{Y3127646172cmdl1-//)$ , "  !%'&*0#.(+nss_wrapper-1.1.16/.clangd/index/testsuite.c.AF64C06B860D31A7.idx000644 001750 000144 00000015172 13634217564 023451 0ustar00asnusers000000 000000 RIFFrCdIxmeta stri -DNDEBUG-D_GNU_SOURCE-I/home/asn/workspace/projects/nss_wrapper/obj-I/home/asn/workspace/projects/nss_wrapper/obj/tests-I/home/asn/workspace/projects/nss_wrapper/tests-O2-Wall-Wcast-align-Wdeclaration-after-statement-Werror-Werror-implicit-function-declaration-Werror=address-Werror=declaration-after-statement-Werror=format-security-Werror=pointer-arith-Werror=return-type-Werror=strict-overflow-Werror=strict-prototypes-Werror=uninitialized-Werror=write-strings-Wformat-Wformat-security-Wimplicit-fallthrough-Wmissing-prototypes-Wno-error=deprecated-declarations-Wno-error=tautological-compare-Wno-format-zero-length-Wpointer-arith-Wreturn-type-Wshadow-Wstrict-overflow=2-Wstrict-prototypes-Wuninitialized-Wwrite-strings-c-fPIE-fno-common-fstack-clash-protection-fstack-protector-strong-fsyntax-only-g-o-resource-dir=/home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0-std=gnu99/home/asn/workspace/projects/nss_wrapper/obj/tests/home/asn/workspace/projects/nss_wrapper/tests/testsuite.c/usr/bin/ccCMakeFiles/testsuite.dir/testsuite.c.oassert_group_equalassert_passwd_equalcopy_groupcopy_passwdfile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stdarg.hfile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stdbool.hfile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stddef.hfile:///home/asn/workspace/projects/nss_wrapper/obj/config.hfile:///home/asn/workspace/projects/nss_wrapper/tests/testsuite.cfile:///usr/include/arpa/inet.hfile:///usr/include/cmocka.hfile:///usr/include/errno.hfile:///usr/include/grp.hfile:///usr/include/netdb.hfile:///usr/include/netinet/in.hfile:///usr/include/pwd.hfile:///usr/include/setjmp.hfile:///usr/include/stdio.hfile:///usr/include/stdlib.hfile:///usr/include/string.hfile:///usr/include/sys/types.hfile:///usr/include/unistd.hfree_groupfree_groupsfree_passwdfree_passwdsmainprint_groupprint_passwdtest_nwrap_duplicatestest_nwrap_enum_grouptest_nwrap_enum_passwdtest_nwrap_enum_r_grouptest_nwrap_enum_r_passwdtest_nwrap_enumerationtest_nwrap_getgrgidtest_nwrap_getgrgid_rtest_nwrap_getgrnamtest_nwrap_getgrnam_rtest_nwrap_getgrouplisttest_nwrap_getpwnamtest_nwrap_getpwnam_rtest_nwrap_getpwuidtest_nwrap_getpwuid_rtest_nwrap_grouptest_nwrap_group_duplicatestest_nwrap_group_rtest_nwrap_group_r_crosstest_nwrap_membershiptest_nwrap_membership_usertest_nwrap_passwdtest_nwrap_passwd_duplicatestest_nwrap_passwd_rtest_nwrap_passwd_r_crosstest_nwrap_reentrant_enumerationtest_nwrap_reentrant_enumeration_crosscheckstest_nwrap_user_in_groupsymbd8Ay a9 !9 ! vK"y ^9 '9 ' s PD 29) )9) )r"^B H9 9 #5U5 V9 9 K _9 9 "%/r Z9 !9 !24`DH P9 "9 "?.A `9 $9 $Fciɂ T9 9 HT g9 ,9 ,Ru? ]9 9 T0tv؁+ L9 9 U6~ \9 !9 !cl5 R9 $9 $f^wd f9 %9 %m>0 d9 (9 (s=> N9 !9 !tv gl X9 #9 #u{,> c9 9 |u 49G G9G Gt Y9 9 ~*| 195 595 5>s0Z e9 9 3zp W9 !9 !8 G9 9 qVd\ [9 9 ju M9s s9s s&w! b9 &9 &DŽM h9 89 8I_FC I9] ]9] ]Ҟ?7 J9i i9i iҾc O9 !9 !swS_+A 39 9 ,Oe Q9 #9 #ITc#N S9 "9 "oԾ U9 !9 !=m  i9 $9 $W{ K99refs{921B 9<<9<"<(9 99#9%9%9#9cr9//9/"/(9LL 9LL9 9"(9YBy9--"9-(-19JJ 9JJ%9``3k" 9HxO'89 9 I.K@9II9JJ9VV9W W9XX999 = 900!90'0/9VV 9VV#9dd/gGŨ 9,, 9,&,-9II 9II!9__9$9&9&9$9")9%9$+9!(9 9 }99@-V9..9.".(9KK 9KK9#9%9%9#ĵ9du?99VUO6+9 %9"'ȉ9T9XTl9YJW922!92'2/9XX 9XX#9ff\⟇9 ޕ>+99999^0a9 9 HoQp 9999999999VF 9ߐ$# 95,519669$)99#9$9$9 9 9 9 9 9 9 9 9).9 9 9059+09 9 9059 9 9 999 9 9 9 $SG9e7ҢE9 9 9 *,19==9=(=.9>>9>(>.9? ?9??%9BB9B B&9CC 9C)C/9 99)/99 9 9#99 99999 9$*999)/9}s5|B9 %9"'9 9 999k< go91191%1+9WW 9WW9eeb">G9m\܂9)-)39**9G%G+9G9G?9]]%9i i&9s s&99?99 99 99 99*0999069,29990699992894:99pH䕴U9='ҏ9;;"9;(;19 9%9{6~,9 9 3A9&,&09pp994= yZ9i.i49kk9,299 99 99999 9999999 9999999v9si#z9~#^n{`9~zƚl 9:: 9:&:-9 9!99$9&9&9$9 9"9$+9!(relasrcs8<=@>9k»n<857A;?:;5:ADF?6EBC7cmdl2-0/%)$ , "  !%'&*0#.(+nss_wrapper-1.1.16/.clangd/index/test_getpwuid_module.c.13413495523E694E.idx000644 001750 000144 00000003752 13641320060 025550 0ustar00asnusers000000 000000 RIFFCdIxmeta striq-DNDEBUG-D_GNU_SOURCE-I/home/asn/workspace/projects/nss_wrapper/obj-I/home/asn/workspace/projects/nss_wrapper/obj/tests-I/home/asn/workspace/projects/nss_wrapper/tests-O2-Wall-Wcast-align-Wdeclaration-after-statement-Werror-Werror-implicit-function-declaration-Werror=address-Werror=declaration-after-statement-Werror=format-security-Werror=pointer-arith-Werror=return-type-Werror=strict-overflow-Werror=strict-prototypes-Werror=uninitialized-Werror=write-strings-Wformat-Wformat-security-Wimplicit-fallthrough-Wmissing-prototypes-Wno-error=deprecated-declarations-Wno-error=tautological-compare-Wno-format-zero-length-Wpointer-arith-Wreturn-type-Wshadow-Wstrict-overflow=2-Wstrict-prototypes-Wuninitialized-Wwrite-strings-c-fPIE-fno-common-fstack-clash-protection-fstack-protector-strong-fsyntax-only-g-o-resource-dir=/home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0-std=gnu99/home/asn/workspace/projects/nss_wrapper/obj/tests/home/asn/workspace/projects/nss_wrapper/tests/test_getpwuid_module.c/usr/bin/ccCMakeFiles/test_getpwuid_module.dir/test_getpwuid_module.c.ofile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stdarg.hfile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stddef.hfile:///home/asn/workspace/projects/nss_wrapper/obj/config.hfile:///home/asn/workspace/projects/nss_wrapper/tests/test_getpwuid_module.cfile:///usr/include/cmocka.hfile:///usr/include/pwd.hfile:///usr/include/setjmp.hmaintest_nwrap_passwdsymb@R( 94 4 W{ 844refsicr4/gGŨ4!9@-V4ĵ4VUO6+4  VF 4m\܂4  relasrcsS36514* 431275672cmdl2-0/%)$ , "  !%'&*0#.(+nss_wrapper-1.1.16/.clangd/index/test_gethostby_name_addr.c.C9C460E7372D7C61.idx000644 001750 000144 00000007516 13640404461 026447 0ustar00asnusers000000 000000 RIFFFCdIxmeta stri-DNDEBUG-D_GNU_SOURCE-I/home/asn/workspace/projects/nss_wrapper/obj-I/home/asn/workspace/projects/nss_wrapper/obj/tests-I/home/asn/workspace/projects/nss_wrapper/tests-O2-Wall-Wcast-align-Wdeclaration-after-statement-Werror-Werror-implicit-function-declaration-Werror=address-Werror=declaration-after-statement-Werror=format-security-Werror=pointer-arith-Werror=return-type-Werror=strict-overflow-Werror=strict-prototypes-Werror=uninitialized-Werror=write-strings-Wformat-Wformat-security-Wimplicit-fallthrough-Wmissing-prototypes-Wno-error=deprecated-declarations-Wno-error=tautological-compare-Wno-format-zero-length-Wpointer-arith-Wreturn-type-Wshadow-Wstrict-overflow=2-Wstrict-prototypes-Wuninitialized-Wwrite-strings-c-fPIE-fno-common-fstack-clash-protection-fstack-protector-strong-fsyntax-only-g-o-resource-dir=/home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0-std=gnu99/home/asn/workspace/projects/nss_wrapper/obj/tests/home/asn/workspace/projects/nss_wrapper/tests/test_gethostby_name_addr.c/usr/bin/ccCMakeFiles/test_gethostby_name_addr.dir/test_gethostby_name_addr.c.ofile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stdarg.hfile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stddef.hfile:///home/asn/workspace/projects/nss_wrapper/obj/config.hfile:///home/asn/workspace/projects/nss_wrapper/tests/test_gethostby_name_addr.cfile:///usr/include/arpa/inet.hfile:///usr/include/cmocka.hfile:///usr/include/errno.hfile:///usr/include/netdb.hfile:///usr/include/netinet/in.hfile:///usr/include/pthread.hfile:///usr/include/setjmp.hfile:///usr/include/stdio.hfile:///usr/include/stdlib.hfile:///usr/include/string.hfile:///usr/include/sys/socket.hfile:///usr/include/unistd.hmaintest_nwrap_gethostbyaddrtest_nwrap_gethostbyaddr_rtest_nwrap_gethostbynametest_nwrap_gethostbyname2_r_v4test_nwrap_gethostbyname2_r_v6test_nwrap_gethostbyname_multipletest_nwrap_gethostbyname_rtest_nwrap_gethostbyname_r_nulltest_nwrap_gethostbyname_threadtest_nwrap_gethostnamethread_test_gethostbynamesymbmYm C4 &4 &$kR F4 *4 *Rݩ0 G4x x-4x x-]> M K4 "4 "zHd4܊ H4 &4 &}Nk u E4 *4 *AC D4b b$4b b$K|# L45 5&45 5&G9 B4 $4 $>e? J4B B+4B B+?N9 I4 +4 +W{ A44refsڇ<4G!' 4774DD4ee4zz44444444'.44)0Nzf4?? OA_ض4""4**400e]’44TH4==4>>4KK4LL4RR4^^4ll4oo444444444444Uxt44VX5W4;;4II4jj4Y?N"X4pp 4 4 4 4 4 Z,g@w4rr4 4444*'9w_4 4'' _[Cx42:42: b,4VF 4#ԥ443n7xĐ4mm 4rr'4 4 4 4)4 4'44 4 4'4 4'44 4 4(44 4)&k b44kCn4.. oY\V4EE e輚(s4OO 3A44444= yZ44ז|04NNrelasrcs3:861;4j fi3:12;67<>=@?958>@?9=<527cmdl2-0/%)$ , "  !%'&*0#.(+nss_wrapper-1.1.16/.clangd/index/nss_nwrap.c.6CD8D6240BEF45A7.idx000644 001750 000144 00000006466 13641330102 023447 0ustar00asnusers000000 000000 RIFF. CdIxmeta stri-D_GNU_SOURCE-Dnss_nwrap_EXPORTS-I/home/asn/workspace/projects/nss_wrapper/obj-asan-I/home/asn/workspace/projects/nss_wrapper/obj-asan/tests-I/home/asn/workspace/projects/nss_wrapper/tests-O0-Wall-Wcast-align-Wdeclaration-after-statement-Werror-Werror-implicit-function-declaration-Werror=address-Werror=declaration-after-statement-Werror=format-security-Werror=pointer-arith-Werror=return-type-Werror=strict-overflow-Werror=strict-prototypes-Werror=uninitialized-Werror=write-strings-Wformat-Wformat-security-Wimplicit-fallthrough-Wmissing-prototypes-Wno-error=deprecated-declarations-Wno-error=tautological-compare-Wno-format-zero-length-Wpointer-arith-Wreturn-type-Wshadow-Wstrict-overflow=2-Wstrict-prototypes-Wuninitialized-Wwrite-strings-c-fPIC-fno-common-fno-omit-frame-pointer-fsanitize=address-fstack-clash-protection-fstack-protector-strong-fsyntax-only-g-ggdb-o-resource-dir=/home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0-std=gnu99/home/asn/workspace/projects/nss_wrapper/obj-asan/tests/home/asn/workspace/projects/nss_wrapper/tests/nss_nwrap.c/usr/bin/ccCMakeFiles/nss_nwrap.dir/nss_nwrap.c.oNSS_STATUS_nss_nwrap_endgrent_nss_nwrap_endpwent_nss_nwrap_getgrent_r_nss_nwrap_getgrgid_r_nss_nwrap_getgrnam_r_nss_nwrap_getpwent_r_nss_nwrap_getpwnam_r_nss_nwrap_getpwuid_r_nss_nwrap_initgroups_dyn_nss_nwrap_setgrent_nss_nwrap_setpwentfile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stddef.hfile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stdint.hfile:///home/asn/workspace/projects/nss_wrapper/obj-asan/config.hfile:///home/asn/workspace/projects/nss_wrapper/tests/nss_nwrap.cfile:///usr/include/errno.hfile:///usr/include/fcntl.hfile:///usr/include/grp.hfile:///usr/include/nss.hfile:///usr/include/pwd.hfile:///usr/include/string.hpw_copy_rsymb B%؎S ?Co oC  ]Hi? 4C"C"1v4d% ;C  C% % 2C C' 'refscrCSS CSSC 9YByCPPCQQC = CaaCbbC /gGŨCAACNNCOO C QF C??CH H9@-VCRR CRRC VUO6+C#!#&C!&YJWCC CCeeCffC !QHCLLߐ$#C)()-C+:+?C-3-8C(-C:?C387Qt/ CqqCvvCCCCCCCCC}s5|BC-!-&C/1/6C00C!&C16Ck< goCccCdd C m\܂ C!(!.C#3#9C%:%@C7"7(C88C;;Cy(y.C39CC:@.lvy5C 3_x]C4= yZ C"" C$$C&&C** C,,C.. C:: Czz CCC CC ;eS!_7C $oNC44$relasrcswBEFIHC 46 BDE@AIHFGAG@Dcmdl4022+,'&$ / "  !%)(-3#1*.nss_wrapper-1.1.16/.clangd/index/test_getaddrinfo.c.641BB471F444137A.idx000644 001750 000144 00000013130 13622466757 024703 0ustar00asnusers000000 000000 RIFFPCdIxmeta stri-DNDEBUG-D_GNU_SOURCE-I/home/asn/workspace/projects/nss_wrapper/obj-I/home/asn/workspace/projects/nss_wrapper/obj/tests-I/home/asn/workspace/projects/nss_wrapper/tests-O2-Wall-Wcast-align-Wdeclaration-after-statement-Werror-Werror-implicit-function-declaration-Werror=address-Werror=declaration-after-statement-Werror=format-security-Werror=pointer-arith-Werror=return-type-Werror=strict-overflow-Werror=strict-prototypes-Werror=uninitialized-Werror=write-strings-Wformat-Wformat-security-Wimplicit-fallthrough-Wmissing-prototypes-Wno-error=deprecated-declarations-Wno-error=tautological-compare-Wno-format-zero-length-Wpointer-arith-Wreturn-type-Wshadow-Wstrict-overflow=2-Wstrict-prototypes-Wuninitialized-Wwrite-strings-c-fPIE-fno-common-fstack-clash-protection-fstack-protector-strong-fsyntax-only-g-o-resource-dir=/home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0-std=gnu99/home/asn/workspace/projects/nss_wrapper/obj/tests/home/asn/workspace/projects/nss_wrapper/tests/test_getaddrinfo.c/usr/bin/ccCMakeFiles/test_getaddrinfo.dir/test_getaddrinfo.c.ofile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stdarg.hfile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stddef.hfile:///home/asn/workspace/projects/nss_wrapper/obj/config.hfile:///home/asn/workspace/projects/nss_wrapper/tests/test_getaddrinfo.cfile:///usr/include/arpa/inet.hfile:///usr/include/cmocka.hfile:///usr/include/errno.hfile:///usr/include/netdb.hfile:///usr/include/netinet/in.hfile:///usr/include/setjmp.hfile:///usr/include/stdio.hfile:///usr/include/stdlib.hfile:///usr/include/string.hfile:///usr/include/sys/socket.hfile:///usr/include/unistd.hmaintest_nwrap_getaddrinfotest_nwrap_getaddrinfo_anytest_nwrap_getaddrinfo_dottest_nwrap_getaddrinfo_flags_ai_numerichosttest_nwrap_getaddrinfo_flags_ai_numericservtest_nwrap_getaddrinfo_ipv6test_nwrap_getaddrinfo_localtest_nwrap_getaddrinfo_multiple_mixedtest_nwrap_getaddrinfo_nametest_nwrap_getaddrinfo_nulltest_nwrap_getaddrinfo_reloadtest_nwrap_getaddrinfo_sambatest_nwrap_getaddrinfo_servicesymb  D4 74 7 =@ A4 "4 "7* L4 (4 (%*C/ I4 '4 '&~Ƃ G4 (4 (eU_l C4 &4 &n})>r M4 *4 *yt5S K4_ _)4_ _)}Zg E4 74 7%  J4 '4 'xA):n H4 14 1ІO B4 &4 &[e F4 '4 'W{ @44refsa öJ$G&,4''4//"400&4CC4KK"4LL&4oo44444"4&4"4&4"4&44"443Oນ4&&4BB4nn44444 _Ú 4 4 4 4 4 4 4 4 4 Qd P\4$$4@@4ll444"44"44"44"44"44"44"444_>.4++4GG4ss4444444444444444444444444444444444444444444Z,g@w4SS 4 4 4 4 4 4 HoQp4zz lC4##422 4??4NN 4kk444 44 44 44 44 44 44 4 4 44 44 44444 G 477!4!4!4!4!4!4&.4VF 4(WS#466%4%gݍY)444"!")4>!>)4aa4bb4j!j)444!)444!)4!)444!)444!)4!)444!)444!)44444!)444%-444!)444!)ãL'f4 X]I 4%%4AA4mm4444444444l:BΤӉ4;; 4WW 4ww 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 q m!4))4EE4qq4444.5* Ob 4 4 4 4 4 4 4 4 4 np)({ 4 4 4 4 4 4 4 4 4 0Eru4&.4!)3_x]4""4>>4jj444444444444&Sw4F%@4RR'4'j-747744444{6_d4S(S14(14(14(14{O0 /A4((4444DD4PP4pp44444444444444-4}} Ҁ4'0relasrcs34+J312:67;=958861:=?>9<;527cmdl1-//)$ , "  !%'&*0#.(+nss_wrapper-1.1.16/.clangd/index/test_shadow.c.85DFA55943F2551B.idx000644 001750 000144 00000004472 13622466757 023751 0ustar00asnusers000000 000000 RIFF2 CdIxmeta stri-DNDEBUG-D_GNU_SOURCE-I/home/asn/workspace/projects/nss_wrapper/obj-I/home/asn/workspace/projects/nss_wrapper/obj/tests-I/home/asn/workspace/projects/nss_wrapper/tests-O2-Wall-Wcast-align-Wdeclaration-after-statement-Werror-Werror-implicit-function-declaration-Werror=address-Werror=declaration-after-statement-Werror=format-security-Werror=pointer-arith-Werror=return-type-Werror=strict-overflow-Werror=strict-prototypes-Werror=uninitialized-Werror=write-strings-Wformat-Wformat-security-Wimplicit-fallthrough-Wmissing-prototypes-Wno-error=deprecated-declarations-Wno-error=tautological-compare-Wno-format-zero-length-Wpointer-arith-Wreturn-type-Wshadow-Wstrict-overflow=2-Wstrict-prototypes-Wuninitialized-Wwrite-strings-c-fPIE-fno-common-fstack-clash-protection-fstack-protector-strong-fsyntax-only-g-o-resource-dir=/home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0-std=gnu99/home/asn/workspace/projects/nss_wrapper/obj/tests/home/asn/workspace/projects/nss_wrapper/tests/test_shadow.c/usr/bin/ccCMakeFiles/test_shadow.dir/test_shadow.c.ofile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stdarg.hfile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stddef.hfile:///home/asn/.cache/dein/.cache/init.vim/.dein/third_party/ycmd/third_party/clang/lib/clang/9.0.0/include/stdint.hfile:///home/asn/workspace/projects/nss_wrapper/obj/config.hfile:///home/asn/workspace/projects/nss_wrapper/tests/test_shadow.cfile:///usr/include/cmocka.hfile:///usr/include/crypt.hfile:///usr/include/setjmp.hfile:///usr/include/shadow.hfile:///usr/include/unistd.hmaintest_nwrap_getspenttest_nwrap_getspnamsymb`wՃol =5! !5! !; <5 5 W{ ;5==5==refsmb5 <5 _z5--577NX)`U5-*-150-0457*715:-:4g`Bf5"5"5++ 555 ։3eel5 5$$ `ګ5 VF 5@@6Nȭf5 5/7>nG5((522relasrcsw4:5Z7Zף 4128693:76137829cmdl1-//)$ , "  !%'&*0#.(+nss_wrapper-1.1.16/src/000755 001750 000144 00000000000 14641730071 014715 5ustar00asnusers000000 000000 nss_wrapper-1.1.16/src/CMakeLists.txt000644 001750 000144 00000002227 14464660771 017474 0ustar00asnusers000000 000000 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 ${DEFAULT_C_COMPILE_FLAGS}) if (BSD) target_compile_options(nss_wrapper PRIVATE -DBSD) endif() target_include_directories(nss_wrapper PRIVATE ${CMAKE_BINARY_DIR}) target_link_libraries(nss_wrapper nss_utils ${NWRAP_REQUIRED_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) set_target_properties( nss_wrapper PROPERTIES VERSION ${LIBRARY_VERSION} SOVERSION ${LIBRARY_SOVERSION} ) install(TARGETS nss_wrapper RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_L_LIBDIR}) set(NSS_WRAPPER_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}nss_wrapper${CMAKE_SHARED_LIBRARY_SUFFIX}" PARENT_SCOPE) nss_wrapper-1.1.16/src/nss_wrapper.c000644 001750 000144 00000437766 14641727506 017464 0ustar00asnusers000000 000000 /* * BSD 3-Clause License * * Copyright (c) 2007, Stefan Metzmacher * Copyright (c) 2009, Guenther Deschner * Copyright (c) 2014-2015, Michael Adam * Copyright (c) 2015, Robin Hack * Copyright (c) 2013-2018, Andreas Schneider * 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 "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_GNU_LIB_NAMES_H #include #endif #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 * Solaris */ #ifndef _POSIX_PTHREAD_SEMANTICS #define _POSIX_PTHREAD_SEMANTICS #endif #include #include #ifdef HAVE_SHADOW_H #include #endif /* HAVE_SHADOW_H */ #include #include #include #include #if defined(HAVE_NSS_H) /* Linux and BSD */ #include typedef enum nss_status NSS_STATUS; #elif defined(HAVE_NSS_COMMON_H) /* Solaris */ #include #include #include typedef nss_status_t NSS_STATUS; # define NSS_STATUS_SUCCESS NSS_SUCCESS # define NSS_STATUS_NOTFOUND NSS_NOTFOUND # define NSS_STATUS_UNAVAIL NSS_UNAVAIL # define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN #else # error "No nsswitch support detected" #endif #ifndef PTR_DIFF #define PTR_DIFF(p1, p2) ((ptrdiff_t)(((const char *)(p1)) - (const char *)(p2))) #endif #ifndef _PUBLIC_ #define _PUBLIC_ #endif #ifndef EAI_NODATA #define EAI_NODATA EAI_NONAME #endif #ifndef EAI_ADDRFAMILY #define EAI_ADDRFAMILY EAI_FAMILY #endif #ifndef __STRING #define __STRING(x) #x #endif #ifndef __STRINGSTRING #define __STRINGSTRING(x) __STRING(x) #endif #ifndef __LINESTR__ #define __LINESTR__ __STRINGSTRING(__LINE__) #endif #ifndef __location__ #define __location__ __FILE__ ":" __LINESTR__ #endif #ifndef DNS_NAME_MAX #define DNS_NAME_MAX 255 #endif /* GCC have printf type attribute check. */ #ifdef HAVE_ATTRIBUTE_PRINTF_FORMAT #define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b))) #else #define PRINTF_ATTRIBUTE(a,b) #endif /* HAVE_ATTRIBUTE_PRINTF_FORMAT */ #ifdef HAVE_CONSTRUCTOR_ATTRIBUTE #define CONSTRUCTOR_ATTRIBUTE __attribute__ ((constructor)) #else #define CONSTRUCTOR_ATTRIBUTE #endif /* HAVE_CONSTRUCTOR_ATTRIBUTE */ #ifdef HAVE_DESTRUCTOR_ATTRIBUTE #define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor)) #else #define DESTRUCTOR_ATTRIBUTE #endif /* HAVE_DESTRUCTOR_ATTRIBUTE */ #define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0) #ifndef SAFE_FREE #define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0) #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 #ifdef HAVE_IPV6 #define NWRAP_INET_ADDRSTRLEN INET6_ADDRSTRLEN #else #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; /* The mutex or accessing the id */ static pthread_mutex_t nwrap_global_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t nwrap_gr_global_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t nwrap_he_global_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t nwrap_pw_global_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t nwrap_sp_global_mutex = PTHREAD_MUTEX_INITIALIZER; #define nss_wrapper_init_mutex(m) \ _nss_wrapper_init_mutex(m, #m) /* Add new global locks here please */ /* Also don't forget to add locks to * nwrap_init() function. */ # define NWRAP_REINIT_ALL do { \ int ret; \ ret = nss_wrapper_init_mutex(&nwrap_initialized_mutex); \ if (ret != 0) exit(-1); \ ret = nss_wrapper_init_mutex(&nwrap_global_mutex); \ if (ret != 0) exit(-1); \ ret = nss_wrapper_init_mutex(&nwrap_gr_global_mutex); \ if (ret != 0) exit(-1); \ ret = nss_wrapper_init_mutex(&nwrap_he_global_mutex); \ if (ret != 0) exit(-1); \ ret = nss_wrapper_init_mutex(&nwrap_pw_global_mutex); \ if (ret != 0) exit(-1); \ ret = nss_wrapper_init_mutex(&nwrap_sp_global_mutex); \ if (ret != 0) exit(-1); \ } while(0) # define NWRAP_LOCK_ALL do { \ nwrap_mutex_lock(&nwrap_initialized_mutex); \ nwrap_mutex_lock(&nwrap_global_mutex); \ nwrap_mutex_lock(&nwrap_gr_global_mutex); \ nwrap_mutex_lock(&nwrap_he_global_mutex); \ nwrap_mutex_lock(&nwrap_pw_global_mutex); \ nwrap_mutex_lock(&nwrap_sp_global_mutex); \ } while (0); # define NWRAP_UNLOCK_ALL do {\ nwrap_mutex_unlock(&nwrap_sp_global_mutex); \ nwrap_mutex_unlock(&nwrap_pw_global_mutex); \ nwrap_mutex_unlock(&nwrap_he_global_mutex); \ nwrap_mutex_unlock(&nwrap_gr_global_mutex); \ nwrap_mutex_unlock(&nwrap_global_mutex); \ nwrap_mutex_unlock(&nwrap_initialized_mutex); \ } while (0); static void nwrap_init(void); enum nwrap_dbglvl_e { NWRAP_LOG_ERROR = 0, NWRAP_LOG_WARN, NWRAP_LOG_DEBUG, NWRAP_LOG_TRACE }; #ifndef HAVE_GETPROGNAME static const char *getprogname(void) { #if defined(HAVE_PROGRAM_INVOCATION_SHORT_NAME) return program_invocation_short_name; #elif defined(HAVE_GETEXECNAME) return getexecname(); #else return NULL; #endif /* HAVE_PROGRAM_INVOCATION_SHORT_NAME */ } #endif /* HAVE_GETPROGNAME */ static void nwrap_log(enum nwrap_dbglvl_e dbglvl, const char *func, const char *format, ...) PRINTF_ATTRIBUTE(3, 4); # define NWRAP_LOG(dbglvl, ...) nwrap_log((dbglvl), __func__, __VA_ARGS__) static void nwrap_log(enum nwrap_dbglvl_e dbglvl, const char *func, const char *format, ...) { char buffer[1024]; va_list va; const char *d; unsigned int lvl = 0; const char *prefix = "NWRAP"; const char *progname = getprogname(); d = getenv("NSS_WRAPPER_DEBUGLEVEL"); if (d != NULL) { lvl = atoi(d); } if (lvl < dbglvl) { return; } va_start(va, format); vsnprintf(buffer, sizeof(buffer), format, va); va_end(va); switch (dbglvl) { case NWRAP_LOG_ERROR: prefix = "NWRAP_ERROR"; break; case NWRAP_LOG_WARN: prefix = "NWRAP_WARN"; break; case NWRAP_LOG_DEBUG: prefix = "NWRAP_DEBUG"; break; case NWRAP_LOG_TRACE: prefix = "NWRAP_TRACE"; break; } if (progname == NULL) { progname = ""; } fprintf(stderr, "%s[%s (%u)] - %s: %s\n", prefix, progname, (unsigned int)getpid(), func, buffer); } /***************** * LIBC *****************/ #define LIBC_NAME "libc.so" typedef struct passwd *(*__libc_getpwnam)(const char *name); typedef int (*__libc_getpwnam_r)(const char *name, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result); typedef struct passwd *(*__libc_getpwuid)(uid_t uid); typedef int (*__libc_getpwuid_r)(uid_t uid, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result); typedef void (*__libc_setpwent)(void); typedef struct passwd *(*__libc_getpwent)(void); #ifdef HAVE_GETPWENT_R # ifdef HAVE_SOLARIS_GETPWENT_R typedef struct passwd *(*__libc_getpwent_r)(struct passwd *pwbuf, char *buf, size_t buflen); # else /* HAVE_SOLARIS_GETPWENT_R */ typedef int (*__libc_getpwent_r)(struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp); # endif /* HAVE_SOLARIS_GETPWENT_R */ #endif /* HAVE_GETPWENT_R */ typedef void (*__libc_endpwent)(void); typedef int (*__libc_initgroups)(const char *user, gid_t gid); typedef struct group *(*__libc_getgrnam)(const char *name); typedef int (*__libc_getgrnam_r)(const char *name, struct group *grp, char *buf, size_t buflen, struct group **result); typedef struct group *(*__libc_getgrgid)(gid_t gid); typedef int (*__libc_getgrgid_r)(gid_t gid, struct group *grp, char *buf, size_t buflen, struct group **result); typedef void (*__libc_setgrent)(void); typedef struct group *(*__libc_getgrent)(void); #ifdef HAVE_GETGRENT_R # ifdef HAVE_SOLARIS_GETGRENT_R typedef struct group *(*__libc_getgrent_r)(struct group *group, char *buf, size_t buflen); # else /* HAVE_SOLARIS_GETGRENT_R */ typedef int (*__libc_getgrent_r)(struct group *group, char *buf, size_t buflen, struct group **result); # endif /* HAVE_SOLARIS_GETGRENT_R */ #endif /* HAVE_GETGRENT_R */ typedef void (*__libc_endgrent)(void); typedef int (*__libc_getgrouplist)(const char *user, gid_t group, gid_t *groups, int *ngroups); typedef void (*__libc_sethostent)(int stayopen); typedef struct hostent *(*__libc_gethostent)(void); typedef void (*__libc_endhostent)(void); typedef struct hostent *(*__libc_gethostbyname)(const char *name); #ifdef HAVE_GETHOSTBYNAME2 /* GNU extension */ typedef struct hostent *(*__libc_gethostbyname2)(const char *name, int af); #endif #ifdef HAVE_GETHOSTBYNAME2_R /* GNU extension */ typedef int (*__libc_gethostbyname2_r)(const char *name, int af, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop); #endif typedef struct hostent *(*__libc_gethostbyaddr)(const void *addr, socklen_t len, int type); typedef int (*__libc_getaddrinfo)(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); typedef int (*__libc_getnameinfo)(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags); typedef int (*__libc_gethostname)(char *name, size_t len); #ifdef HAVE_GETHOSTBYNAME_R typedef int (*__libc_gethostbyname_r)(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop); #endif #ifdef HAVE_GETHOSTBYADDR_R typedef int (*__libc_gethostbyaddr_r)(const void *addr, socklen_t len, int type, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop); #endif #define NWRAP_SYMBOL_ENTRY(i) \ union { \ __libc_##i f; \ void *obj; \ } _libc_##i struct nwrap_libc_symbols { NWRAP_SYMBOL_ENTRY(getpwnam); NWRAP_SYMBOL_ENTRY(getpwnam_r); NWRAP_SYMBOL_ENTRY(getpwuid); NWRAP_SYMBOL_ENTRY(getpwuid_r); NWRAP_SYMBOL_ENTRY(setpwent); NWRAP_SYMBOL_ENTRY(getpwent); #ifdef HAVE_GETPWENT_R NWRAP_SYMBOL_ENTRY(getpwent_r); #endif NWRAP_SYMBOL_ENTRY(endpwent); NWRAP_SYMBOL_ENTRY(initgroups); NWRAP_SYMBOL_ENTRY(getgrnam); NWRAP_SYMBOL_ENTRY(getgrnam_r); NWRAP_SYMBOL_ENTRY(getgrgid); NWRAP_SYMBOL_ENTRY(getgrgid_r); NWRAP_SYMBOL_ENTRY(setgrent); NWRAP_SYMBOL_ENTRY(getgrent); #ifdef HAVE_GETGRENT_R NWRAP_SYMBOL_ENTRY(getgrent_r); #endif NWRAP_SYMBOL_ENTRY(endgrent); NWRAP_SYMBOL_ENTRY(getgrouplist); NWRAP_SYMBOL_ENTRY(sethostent); NWRAP_SYMBOL_ENTRY(gethostent); NWRAP_SYMBOL_ENTRY(endhostent); NWRAP_SYMBOL_ENTRY(gethostbyname); #ifdef HAVE_GETHOSTBYNAME_R NWRAP_SYMBOL_ENTRY(gethostbyname_r); #endif #ifdef HAVE_GETHOSTBYNAME2 NWRAP_SYMBOL_ENTRY(gethostbyname2); #endif #ifdef HAVE_GETHOSTBYNAME2_R NWRAP_SYMBOL_ENTRY(gethostbyname2_r); #endif NWRAP_SYMBOL_ENTRY(gethostbyaddr); #ifdef HAVE_GETHOSTBYADDR_R NWRAP_SYMBOL_ENTRY(gethostbyaddr_r); #endif NWRAP_SYMBOL_ENTRY(getaddrinfo); NWRAP_SYMBOL_ENTRY(getnameinfo); NWRAP_SYMBOL_ENTRY(gethostname); }; #undef NWRAP_SYMBOL_ENTRY typedef NSS_STATUS (*__nss_getpwnam_r)(const char *name, struct passwd *result, char *buffer, size_t buflen, int *errnop); typedef NSS_STATUS (*__nss_getpwuid_r)(uid_t uid, struct passwd *result, char *buffer, size_t buflen, int *errnop); typedef NSS_STATUS (*__nss_setpwent)(void); typedef NSS_STATUS (*__nss_getpwent_r)(struct passwd *result, char *buffer, size_t buflen, int *errnop); typedef NSS_STATUS (*__nss_endpwent)(void); typedef NSS_STATUS (*__nss_initgroups_dyn)(const char *user, gid_t group, long int *start, long int *size, gid_t **groups, long int limit, int *errnop); typedef NSS_STATUS (*__nss_getgrnam_r)(const char *name, struct group *result, char *buffer, size_t buflen, int *errnop); typedef NSS_STATUS (*__nss_getgrgid_r)(gid_t gid, struct group *result, char *buffer, size_t buflen, int *errnop); typedef NSS_STATUS (*__nss_setgrent)(void); typedef NSS_STATUS (*__nss_getgrent_r)(struct group *result, char *buffer, size_t buflen, int *errnop); typedef NSS_STATUS (*__nss_endgrent)(void); typedef NSS_STATUS (*__nss_gethostbyaddr_r)(const void *addr, socklen_t addrlen, int af, struct hostent *result, char *buffer, size_t buflen, int *errnop, int *h_errnop); typedef NSS_STATUS (*__nss_gethostbyname2_r)(const char *name, int af, struct hostent *result, char *buffer, size_t buflen, int *errnop, int *h_errnop); #define NWRAP_NSS_MODULE_SYMBOL_ENTRY(i) \ union { \ __nss_##i f; \ void *obj; \ } _nss_##i struct nwrap_nss_module_symbols { NWRAP_NSS_MODULE_SYMBOL_ENTRY(getpwnam_r); NWRAP_NSS_MODULE_SYMBOL_ENTRY(getpwuid_r); NWRAP_NSS_MODULE_SYMBOL_ENTRY(setpwent); NWRAP_NSS_MODULE_SYMBOL_ENTRY(getpwent_r); NWRAP_NSS_MODULE_SYMBOL_ENTRY(endpwent); 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); NWRAP_NSS_MODULE_SYMBOL_ENTRY(getgrent_r); NWRAP_NSS_MODULE_SYMBOL_ENTRY(endgrent); NWRAP_NSS_MODULE_SYMBOL_ENTRY(gethostbyaddr_r); NWRAP_NSS_MODULE_SYMBOL_ENTRY(gethostbyname2_r); }; struct nwrap_backend { const char *name; const char *so_path; void *so_handle; struct nwrap_ops *ops; struct nwrap_nss_module_symbols *symbols; }; struct nwrap_vector; struct nwrap_ops { struct passwd * (*nw_getpwnam)(struct nwrap_backend *b, const char *name); int (*nw_getpwnam_r)(struct nwrap_backend *b, const char *name, struct passwd *pwdst, char *buf, size_t buflen, struct passwd **pwdstp); struct passwd * (*nw_getpwuid)(struct nwrap_backend *b, uid_t uid); int (*nw_getpwuid_r)(struct nwrap_backend *b, uid_t uid, struct passwd *pwdst, char *buf, size_t buflen, struct passwd **pwdstp); void (*nw_setpwent)(struct nwrap_backend *b); struct passwd * (*nw_getpwent)(struct nwrap_backend *b); int (*nw_getpwent_r)(struct nwrap_backend *b, struct passwd *pwdst, char *buf, size_t buflen, struct passwd **pwdstp); void (*nw_endpwent)(struct nwrap_backend *b); 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, const char *name, struct group *grdst, char *buf, size_t buflen, struct group **grdstp); struct group * (*nw_getgrgid)(struct nwrap_backend *b, gid_t gid); int (*nw_getgrgid_r)(struct nwrap_backend *b, gid_t gid, struct group *grdst, char *buf, size_t buflen, struct group **grdstp); void (*nw_setgrent)(struct nwrap_backend *b); struct group * (*nw_getgrent)(struct nwrap_backend *b); int (*nw_getgrent_r)(struct nwrap_backend *b, struct group *grdst, char *buf, size_t buflen, struct group **grdstp); void (*nw_endgrent)(struct nwrap_backend *b); struct hostent *(*nw_gethostbyaddr)(struct nwrap_backend *b, const void *addr, socklen_t len, int type); struct hostent *(*nw_gethostbyname)(struct nwrap_backend *b, const char *name); struct hostent *(*nw_gethostbyname2)(struct nwrap_backend *b, const char *name, int af); int (*nw_gethostbyname2_r)(struct nwrap_backend *b, const char *name, int af, struct hostent *hedst, char *buf, size_t buflen, struct hostent **hedstp); }; /* Public prototypes */ bool nss_wrapper_enabled(void); bool nss_wrapper_shadow_enabled(void); bool nss_wrapper_hosts_enabled(void); /* prototypes for files backend */ static struct passwd *nwrap_files_getpwnam(struct nwrap_backend *b, const char *name); static int nwrap_files_getpwnam_r(struct nwrap_backend *b, const char *name, struct passwd *pwdst, char *buf, size_t buflen, struct passwd **pwdstp); static struct passwd *nwrap_files_getpwuid(struct nwrap_backend *b, uid_t uid); static int nwrap_files_getpwuid_r(struct nwrap_backend *b, uid_t uid, struct passwd *pwdst, char *buf, size_t buflen, struct passwd **pwdstp); static void nwrap_files_setpwent(struct nwrap_backend *b); static struct passwd *nwrap_files_getpwent(struct nwrap_backend *b); static int nwrap_files_getpwent_r(struct nwrap_backend *b, 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_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, const char *name, struct group *grdst, char *buf, size_t buflen, struct group **grdstp); static struct group *nwrap_files_getgrgid(struct nwrap_backend *b, gid_t gid); static int nwrap_files_getgrgid_r(struct nwrap_backend *b, gid_t gid, struct group *grdst, char *buf, size_t buflen, struct group **grdstp); static void nwrap_files_setgrent(struct nwrap_backend *b); static struct group *nwrap_files_getgrent(struct nwrap_backend *b); static int nwrap_files_getgrent_r(struct nwrap_backend *b, struct group *grdst, char *buf, size_t buflen, struct group **grdstp); static void nwrap_files_endgrent(struct nwrap_backend *b); static struct hostent *nwrap_files_gethostbyaddr(struct nwrap_backend *b, const void *addr, socklen_t len, int type); static struct hostent *nwrap_files_gethostbyname(struct nwrap_backend *b, const char *name); #ifdef HAVE_GETHOSTBYNAME2 static struct hostent *nwrap_files_gethostbyname2(struct nwrap_backend *b, const char *name, int af); #endif /* HAVE_GETHOSTBYNAME2 */ static int nwrap_files_gethostbyname2_r(struct nwrap_backend *b, const char *name, int af, struct hostent *hedst, char *buf, size_t buflen, struct hostent **hedstp); /* prototypes for module backend */ static struct passwd *nwrap_module_getpwent(struct nwrap_backend *b); static int nwrap_module_getpwent_r(struct nwrap_backend *b, struct passwd *pwdst, char *buf, size_t buflen, struct passwd **pwdstp); static struct passwd *nwrap_module_getpwnam(struct nwrap_backend *b, const char *name); static int nwrap_module_getpwnam_r(struct nwrap_backend *b, const char *name, struct passwd *pwdst, char *buf, size_t buflen, struct passwd **pwdstp); static struct passwd *nwrap_module_getpwuid(struct nwrap_backend *b, uid_t uid); static int nwrap_module_getpwuid_r(struct nwrap_backend *b, uid_t uid, struct passwd *pwdst, char *buf, size_t buflen, struct passwd **pwdstp); static void nwrap_module_setpwent(struct nwrap_backend *b); static void nwrap_module_endpwent(struct nwrap_backend *b); static struct group *nwrap_module_getgrent(struct nwrap_backend *b); static int nwrap_module_getgrent_r(struct nwrap_backend *b, struct group *grdst, char *buf, size_t buflen, struct group **grdstp); static struct group *nwrap_module_getgrnam(struct nwrap_backend *b, const char *name); static int nwrap_module_getgrnam_r(struct nwrap_backend *b, const char *name, struct group *grdst, char *buf, size_t buflen, struct group **grdstp); static struct group *nwrap_module_getgrgid(struct nwrap_backend *b, gid_t gid); static int nwrap_module_getgrgid_r(struct nwrap_backend *b, gid_t gid, struct group *grdst, 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_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); static struct hostent *nwrap_module_gethostbyname(struct nwrap_backend *b, const char *name); static struct hostent *nwrap_module_gethostbyname2(struct nwrap_backend *b, const char *name, int af); static int nwrap_module_gethostbyname2_r(struct nwrap_backend *b, const char *name, int af, struct hostent *hedst, char *buf, size_t buflen, struct hostent **hedstp); struct nwrap_ops nwrap_files_ops = { .nw_getpwnam = nwrap_files_getpwnam, .nw_getpwnam_r = nwrap_files_getpwnam_r, .nw_getpwuid = nwrap_files_getpwuid, .nw_getpwuid_r = nwrap_files_getpwuid_r, .nw_setpwent = nwrap_files_setpwent, .nw_getpwent = nwrap_files_getpwent, .nw_getpwent_r = nwrap_files_getpwent_r, .nw_endpwent = nwrap_files_endpwent, .nw_initgroups_dyn = nwrap_files_initgroups_dyn, .nw_getgrnam = nwrap_files_getgrnam, .nw_getgrnam_r = nwrap_files_getgrnam_r, .nw_getgrgid = nwrap_files_getgrgid, .nw_getgrgid_r = nwrap_files_getgrgid_r, .nw_setgrent = nwrap_files_setgrent, .nw_getgrent = nwrap_files_getgrent, .nw_getgrent_r = nwrap_files_getgrent_r, .nw_endgrent = nwrap_files_endgrent, .nw_gethostbyaddr = nwrap_files_gethostbyaddr, .nw_gethostbyname = nwrap_files_gethostbyname, #ifdef HAVE_GETHOSTBYNAME2 .nw_gethostbyname2 = nwrap_files_gethostbyname2, #endif /* HAVE_GETHOSTBYNAME2 */ .nw_gethostbyname2_r = nwrap_files_gethostbyname2_r, }; struct nwrap_ops nwrap_module_ops = { .nw_getpwnam = nwrap_module_getpwnam, .nw_getpwnam_r = nwrap_module_getpwnam_r, .nw_getpwuid = nwrap_module_getpwuid, .nw_getpwuid_r = nwrap_module_getpwuid_r, .nw_setpwent = nwrap_module_setpwent, .nw_getpwent = nwrap_module_getpwent, .nw_getpwent_r = nwrap_module_getpwent_r, .nw_endpwent = nwrap_module_endpwent, .nw_initgroups_dyn = nwrap_module_initgroups_dyn, .nw_getgrnam = nwrap_module_getgrnam, .nw_getgrnam_r = nwrap_module_getgrnam_r, .nw_getgrgid = nwrap_module_getgrgid, .nw_getgrgid_r = nwrap_module_getgrgid_r, .nw_setgrent = nwrap_module_setgrent, .nw_getgrent = nwrap_module_getgrent, .nw_getgrent_r = nwrap_module_getgrent_r, .nw_endgrent = nwrap_module_endgrent, .nw_gethostbyaddr = nwrap_module_gethostbyaddr, .nw_gethostbyname = nwrap_module_gethostbyname, .nw_gethostbyname2 = nwrap_module_gethostbyname2, .nw_gethostbyname2_r = nwrap_module_gethostbyname2_r, }; struct nwrap_libc { void *handle; void *nsl_handle; void *sock_handle; struct nwrap_libc_symbols symbols; }; struct nwrap_main { size_t num_backends; struct nwrap_backend *backends; struct nwrap_libc *libc; }; static struct nwrap_main *nwrap_main_global; static struct nwrap_main __nwrap_main_global; /* * PROTOTYPES */ static int nwrap_convert_he_ai(const struct hostent *he, unsigned short port, const struct addrinfo *hints, 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 */ #define DEFAULT_VECTOR_CAPACITY 16 struct nwrap_vector { void **items; size_t count; size_t capacity; }; /* Macro returns pointer to first element of vector->items array. * * nwrap_vector is used as a memory backend which take care of * memory allocations and other stuff like memory growing. * nwrap_vectors should not be considered as some abstract structures. * On this level, vectors are more handy than direct realloc/malloc * calls. * * nwrap_vector->items is array inside nwrap_vector which can be * directly pointed by libc structure assembled by cwrap itself. * * EXAMPLE: * * 1) struct hostent contains char **h_addr_list element. * 2) nwrap_vector holds array of pointers to addresses. * It's easier to use vector to store results of * file parsing etc. * * Now, pretend that cwrap assembled struct hostent and * we need to set h_addr_list to point to nwrap_vector. * Idea behind is to shield users from internal nwrap_vector * implementation. * (Yes, not fully - array terminated by NULL is needed because * it's result expected by libc function caller.) * * * CODE EXAMPLE: * * struct hostent he; * struct nwrap_vector *vector = malloc(sizeof(struct nwrap_vector)); * ... don't care about failed allocation now ... * * ... fill nwrap vector ... * * struct hostent he; * he.h_addr_list = nwrap_vector_head(vector); * */ #define nwrap_vector_head(vect) ((void *)((vect)->items)) #define nwrap_vector_foreach(item, vect, iter) \ for (iter = 0, (item) = (vect).items == NULL ? NULL : (vect).items[0]; \ item != NULL; \ (item) = (vect).items[++iter]) #define nwrap_vector_is_initialized(vector) ((vector)->items != NULL) static inline bool nwrap_vector_init(struct nwrap_vector *const vector) { if (vector == NULL) { return false; } /* count is initialized by ZERO_STRUCTP */ ZERO_STRUCTP(vector); vector->items = malloc(sizeof(void *) * (DEFAULT_VECTOR_CAPACITY + 1)); if (vector->items == NULL) { return false; } vector->capacity = DEFAULT_VECTOR_CAPACITY; memset(vector->items, '\0', sizeof(void *) * (DEFAULT_VECTOR_CAPACITY + 1)); return true; } static bool nwrap_vector_add_item(struct nwrap_vector *vector, void *const item) { assert (vector != NULL); if (vector->items == NULL) { nwrap_vector_init(vector); } if (vector->count == vector->capacity) { /* Items array _MUST_ be NULL terminated because it's passed * as result to caller which expect NULL terminated array from libc. */ void **items = realloc(vector->items, sizeof(void *) * ((vector->capacity * 2) + 1)); if (items == NULL) { return false; } vector->items = items; /* Don't count ending NULL to capacity */ vector->capacity *= 2; } vector->items[vector->count] = item; vector->count += 1; vector->items[vector->count] = NULL; return true; } static bool nwrap_vector_merge(struct nwrap_vector *dst, struct nwrap_vector *src) { void **dst_items = NULL; size_t count; if (src->count == 0) { return true; } count = dst->count + src->count; /* We don't need reallocation if we have enough capacity. */ if (src->count > (dst->capacity - dst->count)) { dst_items = (void **)realloc(dst->items, (count + 1) * sizeof(void *)); if (dst_items == NULL) { return false; } dst->items = dst_items; dst->capacity = count; } memcpy((void *)(((long *)dst->items) + dst->count), src->items, src->count * sizeof(void *)); dst->count = count; return true; } struct nwrap_cache { const char *path; int fd; FILE *fp; struct stat st; void *private_data; struct nwrap_vector lines; bool (*parse_line)(struct nwrap_cache *, char *line); void (*unload)(struct nwrap_cache *); }; /* passwd */ struct nwrap_pw { struct nwrap_cache *cache; struct passwd *list; int num; int idx; }; struct nwrap_cache __nwrap_cache_pw; struct nwrap_pw nwrap_pw_global; static bool nwrap_pw_parse_line(struct nwrap_cache *nwrap, char *line); static void nwrap_pw_unload(struct nwrap_cache *nwrap); /* shadow */ #if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) struct nwrap_sp { struct nwrap_cache *cache; struct spwd *list; int num; int idx; }; struct nwrap_cache __nwrap_cache_sp; struct nwrap_sp nwrap_sp_global; static bool nwrap_sp_parse_line(struct nwrap_cache *nwrap, char *line); static void nwrap_sp_unload(struct nwrap_cache *nwrap); #endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */ /* group */ struct nwrap_gr { struct nwrap_cache *cache; struct group *list; int num; int idx; }; struct nwrap_cache __nwrap_cache_gr; struct nwrap_gr nwrap_gr_global; /* hosts */ static bool nwrap_he_parse_line(struct nwrap_cache *nwrap, char *line); static void nwrap_he_unload(struct nwrap_cache *nwrap); struct nwrap_addrdata { unsigned char host_addr[16]; /* IPv4 or IPv6 address */ }; static size_t max_hostents = 100; struct nwrap_entdata { struct nwrap_addrdata addr; struct hostent ht; struct nwrap_vector nwrap_addrdata; ssize_t aliases_count; }; struct nwrap_entlist { struct nwrap_entlist *next; struct nwrap_entdata *ed; }; struct nwrap_he { struct nwrap_cache *cache; struct nwrap_vector entries; struct nwrap_vector lists; int num; int idx; }; static struct nwrap_cache __nwrap_cache_he; static struct nwrap_he nwrap_he_global; /********************************************************* * NWRAP PROTOTYPES *********************************************************/ static bool nwrap_gr_parse_line(struct nwrap_cache *nwrap, char *line); static void nwrap_gr_unload(struct nwrap_cache *nwrap); #if ! defined(HAVE_CONSTRUCTOR_ATTRIBUTE) && defined(HAVE_PRAGMA_INIT) /* xlC and other oldschool compilers support (only) this */ #pragma init (nwrap_constructor) #endif void nwrap_constructor(void) CONSTRUCTOR_ATTRIBUTE; #if ! defined(HAVE_DESTRUCTOR_ATTRIBUTE) && defined(HAVE_PRAGMA_FINI) #pragma fini (nwrap_destructor) #endif void nwrap_destructor(void) DESTRUCTOR_ATTRIBUTE; /********************************************************* * NWRAP LIBC LOADER FUNCTIONS *********************************************************/ enum nwrap_lib { NWRAP_LIBC, NWRAP_LIBNSL, NWRAP_LIBSOCKET, }; static const char *nwrap_str_lib(enum nwrap_lib lib) { switch (lib) { case NWRAP_LIBC: return "libc"; case NWRAP_LIBNSL: return "libnsl"; case NWRAP_LIBSOCKET: return "libsocket"; } /* Compiler would warn us about unhandled enum value if we get here */ return "unknown"; } static void *nwrap_load_lib_handle(enum nwrap_lib lib) { int flags = RTLD_LAZY; void *handle = NULL; int i; #ifdef RTLD_DEEPBIND const char *env_preload = getenv("LD_PRELOAD"); const char *env_deepbind = getenv("NSS_WRAPPER_DISABLE_DEEPBIND"); bool enable_deepbind = true; /* Don't do a deepbind if we run with libasan */ if (env_preload != NULL && strlen(env_preload) < 1024) { const char *p = strstr(env_preload, "libasan.so"); if (p != NULL) { enable_deepbind = false; } } if (env_deepbind != NULL && strlen(env_deepbind) >= 1) { enable_deepbind = false; } if (enable_deepbind) { flags |= RTLD_DEEPBIND; } #endif switch (lib) { case NWRAP_LIBNSL: #ifdef HAVE_LIBNSL handle = nwrap_main_global->libc->nsl_handle; #ifdef LIBNSL_SO if (handle == NULL) { handle = dlopen(LIBNSL_SO, flags); nwrap_main_global->libc->nsl_handle = handle; } #endif if (handle == NULL) { for (i = 10; i >= 0; i--) { char soname[256] = {0}; snprintf(soname, sizeof(soname), "libnsl.so.%d", i); handle = dlopen(soname, flags); if (handle != NULL) { break; } } nwrap_main_global->libc->nsl_handle = handle; } break; #endif /* FALL TROUGH */ case NWRAP_LIBSOCKET: #ifdef HAVE_LIBSOCKET handle = nwrap_main_global->libc->sock_handle; if (handle == NULL) { for (i = 10; i >= 0; i--) { char soname[256] = {0}; snprintf(soname, sizeof(soname), "libsocket.so.%d", i); handle = dlopen(soname, flags); if (handle != NULL) { break; } } nwrap_main_global->libc->sock_handle = handle; } break; #endif /* FALL TROUGH */ case NWRAP_LIBC: handle = nwrap_main_global->libc->handle; #ifdef LIBC_SO if (handle == NULL) { handle = dlopen(LIBC_SO, flags); nwrap_main_global->libc->handle = handle; } #endif if (handle == NULL) { for (i = 10; i >= 0; i--) { char soname[256] = {0}; snprintf(soname, sizeof(soname), "libc.so.%d", i); handle = dlopen(soname, flags); if (handle != NULL) { break; } } nwrap_main_global->libc->handle = handle; } break; } if (handle == NULL) { #ifdef RTLD_NEXT handle = nwrap_main_global->libc->handle = nwrap_main_global->libc->sock_handle = nwrap_main_global->libc->nsl_handle = RTLD_NEXT; #else NWRAP_LOG(NWRAP_LOG_ERROR, "Failed to dlopen library: %s\n", dlerror()); exit(-1); #endif } return handle; } static void *_nwrap_bind_symbol(enum nwrap_lib lib, const char *fn_name) { void *handle; void *func; nwrap_init(); handle = nwrap_load_lib_handle(lib); func = dlsym(handle, fn_name); if (func == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "Failed to find %s: %s\n", fn_name, dlerror()); exit(-1); } NWRAP_LOG(NWRAP_LOG_TRACE, "Loaded %s from %s", fn_name, nwrap_str_lib(lib)); return func; } #define nwrap_mutex_lock(m) _nwrap_mutex_lock(m, #m, __func__, __LINE__) static void _nwrap_mutex_lock(pthread_mutex_t *mutex, const char *name, const char *caller, unsigned line) { int ret; ret = pthread_mutex_lock(mutex); if (ret != 0) { NWRAP_LOG(NWRAP_LOG_ERROR, "PID(%d):PPID(%d): %s(%u): Couldn't lock pthread mutex(%s) - %s", getpid(), getppid(), caller, line, name, strerror(ret)); abort(); } } #define nwrap_mutex_unlock(m) _nwrap_mutex_unlock(m, #m, __func__, __LINE__) static void _nwrap_mutex_unlock(pthread_mutex_t *mutex, const char *name, const char *caller, unsigned line) { int ret; ret = pthread_mutex_unlock(mutex); if (ret != 0) { NWRAP_LOG(NWRAP_LOG_ERROR, "PID(%d):PPID(%d): %s(%u): Couldn't unlock pthread mutex(%s) - %s", getpid(), getppid(), caller, line, name, strerror(ret)); abort(); } } #define nwrap_bind_symbol_libc(sym_name) \ if (nwrap_main_global->libc->symbols._libc_##sym_name.obj == NULL) { \ nwrap_main_global->libc->symbols._libc_##sym_name.obj = \ _nwrap_bind_symbol(NWRAP_LIBC, #sym_name); \ } \ #define nwrap_bind_symbol_libc_posix(sym_name) \ if (nwrap_main_global->libc->symbols._libc_##sym_name.obj == NULL) { \ nwrap_main_global->libc->symbols._libc_##sym_name.obj = \ _nwrap_bind_symbol(NWRAP_LIBC, "__posix_" #sym_name); \ } \ #define nwrap_bind_symbol_libnsl(sym_name) \ if (nwrap_main_global->libc->symbols._libc_##sym_name.obj == NULL) { \ nwrap_main_global->libc->symbols._libc_##sym_name.obj = \ _nwrap_bind_symbol(NWRAP_LIBNSL, #sym_name); \ } \ #define nwrap_bind_symbol_libsocket(sym_name) \ if (nwrap_main_global->libc->symbols._libc_##sym_name.obj == NULL) { \ nwrap_main_global->libc->symbols._libc_##sym_name.obj = \ _nwrap_bind_symbol(NWRAP_LIBSOCKET, #sym_name); \ } \ static void nwrap_bind_symbol_all(void); /* INTERNAL HELPER FUNCTIONS */ static void nwrap_lines_unload(struct nwrap_cache *const nwrap) { size_t p; void *item; nwrap_vector_foreach(item, nwrap->lines, p) { /* Maybe some vectors were merged ... */ SAFE_FREE(item); } SAFE_FREE(nwrap->lines.items); ZERO_STRUCTP(&nwrap->lines); } /* * IMPORTANT * * Functions expeciall from libc need to be loaded individually, you can't load * all at once or gdb will segfault at startup. The same applies to valgrind and * has probably something todo with with the linker. * So we need load each function at the point it is called the first time. */ static struct passwd *libc_getpwnam(const char *name) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_getpwnam.f(name); } #ifdef HAVE_GETPWNAM_R static int libc_getpwnam_r(const char *name, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_getpwnam_r.f(name, pwd, buf, buflen, result); } #endif static struct passwd *libc_getpwuid(uid_t uid) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_getpwuid.f(uid); } #ifdef HAVE_GETPWUID_R static int libc_getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_getpwuid_r.f(uid, pwd, buf, buflen, result); } #endif static inline void str_tolower(char *dst, char *src) { register char *src_tmp = src; register char *dst_tmp = dst; while (*src_tmp != '\0') { *dst_tmp = tolower(*src_tmp); ++src_tmp; ++dst_tmp; } } static bool str_tolower_copy(char **dst_name, const char *const src_name) { char *h_name_lower; if ((dst_name == NULL) || (src_name == NULL)) { return false; } h_name_lower = strdup(src_name); if (h_name_lower == NULL) { NWRAP_LOG(NWRAP_LOG_DEBUG, "Out of memory while strdup"); return false; } str_tolower(h_name_lower, h_name_lower); *dst_name = h_name_lower; return true; } static void libc_setpwent(void) { nwrap_bind_symbol_all(); nwrap_main_global->libc->symbols._libc_setpwent.f(); } static struct passwd *libc_getpwent(void) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_getpwent.f(); } #ifdef HAVE_GETPWENT_R # ifdef HAVE_SOLARIS_GETPWENT_R static struct passwd *libc_getpwent_r(struct passwd *pwdst, char *buf, int buflen) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_getpwent_r.f(pwdst, buf, buflen); } # else /* HAVE_SOLARIS_GETPWENT_R */ static int libc_getpwent_r(struct passwd *pwdst, char *buf, size_t buflen, struct passwd **pwdstp) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_getpwent_r.f(pwdst, buf, buflen, pwdstp); } # endif /* HAVE_SOLARIS_GETPWENT_R */ #endif /* HAVE_GETPWENT_R */ static void libc_endpwent(void) { nwrap_bind_symbol_all(); nwrap_main_global->libc->symbols._libc_endpwent.f(); } static int libc_initgroups(const char *user, gid_t gid) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_initgroups.f(user, gid); } static struct group *libc_getgrnam(const char *name) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_getgrnam.f(name); } #ifdef HAVE_GETGRNAM_R static int libc_getgrnam_r(const char *name, struct group *grp, char *buf, size_t buflen, struct group **result) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_getgrnam_r.f(name, grp, buf, buflen, result); } #endif static struct group *libc_getgrgid(gid_t gid) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_getgrgid.f(gid); } #ifdef HAVE_GETGRGID_R static int libc_getgrgid_r(gid_t gid, struct group *grp, char *buf, size_t buflen, struct group **result) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_getgrgid_r.f(gid, grp, buf, buflen, result); } #endif static void libc_setgrent(void) { nwrap_bind_symbol_all(); nwrap_main_global->libc->symbols._libc_setgrent.f(); } static struct group *libc_getgrent(void) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_getgrent.f(); } #ifdef HAVE_GETGRENT_R # ifdef HAVE_SOLARIS_GETGRENT_R static struct group *libc_getgrent_r(struct group *group, char *buf, size_t buflen) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_getgrent_r.f(group, buf, buflen); } # else /* HAVE_SOLARIS_GETGRENT_R */ static int libc_getgrent_r(struct group *group, char *buf, size_t buflen, struct group **result) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_getgrent_r.f(group, buf, buflen, result); } # endif /* HAVE_SOLARIS_GETGRENT_R */ #endif /* HAVE_GETGRENT_R */ static void libc_endgrent(void) { nwrap_bind_symbol_all(); nwrap_main_global->libc->symbols._libc_endgrent.f(); } #ifdef HAVE_GETGROUPLIST static int libc_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_getgrouplist.f(user, group, groups, ngroups); } #endif static void libc_sethostent(int stayopen) { nwrap_bind_symbol_all(); nwrap_main_global->libc->symbols._libc_sethostent.f(stayopen); } static struct hostent *libc_gethostent(void) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_gethostent.f(); } static void libc_endhostent(void) { nwrap_bind_symbol_all(); nwrap_main_global->libc->symbols._libc_endhostent.f(); } static struct hostent *libc_gethostbyname(const char *name) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_gethostbyname.f(name); } #ifdef HAVE_GETHOSTBYNAME2 /* GNU extension */ static struct hostent *libc_gethostbyname2(const char *name, int af) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_gethostbyname2.f(name, af); } #endif #ifdef HAVE_GETHOSTBYNAME2_R /* GNU extension */ static int libc_gethostbyname2_r(const char *name, int af, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_gethostbyname2_r.f(name, af, ret, buf, buflen, result, h_errnop); } #endif static struct hostent *libc_gethostbyaddr(const void *addr, socklen_t len, int type) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_gethostbyaddr.f(addr, len, type); } static int libc_gethostname(char *name, size_t len) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_gethostname.f(name, len); } #ifdef HAVE_GETHOSTBYNAME_R static int libc_gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_gethostbyname_r.f(name, ret, buf, buflen, result, h_errnop); } #endif #ifdef HAVE_GETHOSTBYADDR_R static int libc_gethostbyaddr_r(const void *addr, socklen_t len, int type, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_gethostbyaddr_r.f(addr, len, type, ret, buf, buflen, result, h_errnop); } #endif static int libc_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_getaddrinfo.f(node, service, hints, res); } static int libc_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) { nwrap_bind_symbol_all(); return nwrap_main_global->libc->symbols._libc_getnameinfo.f(sa, salen, host, hostlen, serv, servlen, flags); } static void __nwrap_bind_symbol_all_once(void) { nwrap_bind_symbol_libc(getpwnam); #ifdef HAVE_GETPWNAM_R # ifdef HAVE___POSIX_GETPWNAM_R nwrap_bind_symbol_libc_posix(getpwnam_r); # else nwrap_bind_symbol_libc(getpwnam_r); # endif #endif nwrap_bind_symbol_libc(getpwuid); #ifdef HAVE_GETPWUID_R # ifdef HAVE___POSIX_GETPWUID_R nwrap_bind_symbol_libc_posix(getpwuid_r); # else nwrap_bind_symbol_libc(getpwuid_r); # endif #endif nwrap_bind_symbol_libc(setpwent); nwrap_bind_symbol_libc(getpwent); #ifdef HAVE_GETPWENT_R nwrap_bind_symbol_libc(getpwent_r); #endif nwrap_bind_symbol_libc(endpwent); nwrap_bind_symbol_libc(initgroups); nwrap_bind_symbol_libc(getgrnam); #ifdef HAVE_GETGRNAM_R # ifdef HAVE___POSIX_GETGRNAM_R nwrap_bind_symbol_libc_posix(getgrnam_r); # else nwrap_bind_symbol_libc(getgrnam_r); # endif #endif nwrap_bind_symbol_libc(getgrgid); #ifdef HAVE_GETGRGID_R # ifdef HAVE___POSIX_GETGRGID_R nwrap_bind_symbol_libc_posix(getgrgid_r); # else nwrap_bind_symbol_libc(getgrgid_r); # endif #endif nwrap_bind_symbol_libc(setgrent); nwrap_bind_symbol_libc(getgrent); nwrap_bind_symbol_libc(getgrent_r); nwrap_bind_symbol_libc(endgrent); nwrap_bind_symbol_libc(getgrouplist); nwrap_bind_symbol_libnsl(sethostent); nwrap_bind_symbol_libnsl(gethostent); nwrap_bind_symbol_libnsl(endhostent); nwrap_bind_symbol_libnsl(gethostbyname); #ifdef HAVE_GETHOSTBYNAME2 /* GNU extension */ nwrap_bind_symbol_libnsl(gethostbyname2); #endif #ifdef HAVE_GETHOSTBYNAME2_R /* GNU extension */ nwrap_bind_symbol_libnsl(gethostbyname2_r); #endif nwrap_bind_symbol_libnsl(gethostbyaddr); nwrap_bind_symbol_libnsl(gethostname); #ifdef HAVE_GETHOSTBYNAME_R nwrap_bind_symbol_libnsl(gethostbyname_r); #endif #ifdef HAVE_GETHOSTBYADDR_R nwrap_bind_symbol_libnsl(gethostbyaddr_r); #endif nwrap_bind_symbol_libsocket(getaddrinfo); nwrap_bind_symbol_libsocket(getnameinfo); } static void nwrap_bind_symbol_all(void) { static pthread_once_t all_symbol_binding_once = PTHREAD_ONCE_INIT; pthread_once(&all_symbol_binding_once, __nwrap_bind_symbol_all_once); } /********************************************************* * NWRAP NSS MODULE LOADER FUNCTIONS *********************************************************/ static void *_nwrap_bind_nss_module_symbol(struct nwrap_backend *b, const char *fn_name) { void *res = NULL; char *s = NULL; int rc; if (b->so_handle == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "No handle"); return NULL; } rc = asprintf(&s, "_nss_%s_%s", b->name, fn_name); if (rc == -1) { NWRAP_LOG(NWRAP_LOG_ERROR, "Out of memory"); return NULL; } res = dlsym(b->so_handle, s); if (res == NULL) { NWRAP_LOG(NWRAP_LOG_WARN, "Cannot find function %s in %s", s, b->so_path); } SAFE_FREE(s); return res; } #define nwrap_nss_module_bind_symbol(sym_name) \ if (symbols->_nss_##sym_name.obj == NULL) { \ symbols->_nss_##sym_name.obj = \ _nwrap_bind_nss_module_symbol(b, #sym_name); \ } #define nwrap_nss_module_bind_symbol2(sym_name, alt_name) \ if (symbols->_nss_##sym_name.obj == NULL) { \ symbols->_nss_##sym_name.obj = \ _nwrap_bind_nss_module_symbol(b, #alt_name); \ } static struct nwrap_nss_module_symbols * nwrap_bind_nss_module_symbols(struct nwrap_backend *b) { struct nwrap_nss_module_symbols *symbols; if (!b->so_handle) { return NULL; } symbols = calloc(1, sizeof(struct nwrap_nss_module_symbols)); if (symbols == NULL) { return NULL; } nwrap_nss_module_bind_symbol(getpwnam_r); nwrap_nss_module_bind_symbol(getpwuid_r); nwrap_nss_module_bind_symbol(setpwent); nwrap_nss_module_bind_symbol(getpwent_r); nwrap_nss_module_bind_symbol(endpwent); 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); nwrap_nss_module_bind_symbol(getgrent_r); nwrap_nss_module_bind_symbol(endgrent); nwrap_nss_module_bind_symbol(gethostbyaddr_r); nwrap_nss_module_bind_symbol(gethostbyname2_r); return symbols; } static void *nwrap_load_module(const char *so_path) { void *h; if (!so_path || !strlen(so_path)) { return NULL; } h = dlopen(so_path, RTLD_LAZY); if (!h) { NWRAP_LOG(NWRAP_LOG_ERROR, "Cannot open shared library %s", so_path); return NULL; } return h; } static bool nwrap_module_init(const char *name, struct nwrap_ops *ops, const char *so_path, size_t *num_backends, struct nwrap_backend **backends) { struct nwrap_backend *b = NULL; size_t n = *num_backends + 1; b = realloc(*backends, sizeof(struct nwrap_backend) * n); if (b == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "Out of memory"); return false; } *backends = b; b = &((*backends)[*num_backends]); *b = (struct nwrap_backend) { .name = name, .ops = ops, .so_path = so_path, }; if (so_path != NULL) { b->so_handle = nwrap_load_module(so_path); b->symbols = nwrap_bind_nss_module_symbols(b); if (b->symbols == NULL) { return false; } } *num_backends = n; return true; } static void nwrap_libc_init(struct nwrap_main *r) { r->libc = calloc(1, sizeof(struct nwrap_libc)); if (r->libc == NULL) { printf("Failed to allocate memory for libc"); exit(-1); } } static void nwrap_backend_init(struct nwrap_main *r) { const char *module_so_path = getenv("NSS_WRAPPER_MODULE_SO_PATH"); const char *module_fn_name = getenv("NSS_WRAPPER_MODULE_FN_PREFIX"); r->num_backends = 0; r->backends = NULL; if (!nwrap_module_init("files", &nwrap_files_ops, NULL, &r->num_backends, &r->backends)) { NWRAP_LOG(NWRAP_LOG_ERROR, "Failed to initialize 'files' backend"); return; } if (module_so_path != NULL && module_so_path[0] != '\0' && module_fn_name != NULL && module_fn_name[0] != '\0') { if (!nwrap_module_init(module_fn_name, &nwrap_module_ops, module_so_path, &r->num_backends, &r->backends)) { NWRAP_LOG(NWRAP_LOG_ERROR, "Failed to initialize '%s' backend", module_fn_name); return; } } } static int _nss_wrapper_init_mutex(pthread_mutex_t *m, const char *name) { pthread_mutexattr_t ma; bool need_destroy = false; int ret = 0; #define __CHECK(cmd) do { \ ret = cmd; \ if (ret != 0) { \ NWRAP_LOG(NWRAP_LOG_ERROR, \ "%s: %s - failed %d", \ name, #cmd, ret); \ goto done; \ } \ } while(0) *m = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; __CHECK(pthread_mutexattr_init(&ma)); need_destroy = true; __CHECK(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK)); __CHECK(pthread_mutex_init(m, &ma)); done: if (need_destroy) { pthread_mutexattr_destroy(&ma); } return ret; } static void nwrap_init(void) { const char *env; char *endptr; size_t max_hostents_tmp; int ok; nwrap_mutex_lock(&nwrap_initialized_mutex); if (nwrap_initialized) { nwrap_mutex_unlock(&nwrap_initialized_mutex); return; } /* * Still holding nwrap_initialized lock here. * We don't use NWRAP_(UN)LOCK_ALL macros here because we * want to avoid overhead when other threads do their job. */ nwrap_mutex_lock(&nwrap_global_mutex); nwrap_mutex_lock(&nwrap_gr_global_mutex); nwrap_mutex_lock(&nwrap_he_global_mutex); nwrap_mutex_lock(&nwrap_pw_global_mutex); nwrap_mutex_lock(&nwrap_sp_global_mutex); nwrap_initialized = true; env = getenv("NSS_WRAPPER_MAX_HOSTENTS"); if (env != NULL) { max_hostents_tmp = (size_t)strtoul(env, &endptr, 10); if ((*env == '\0') || (*endptr != '\0') || (max_hostents_tmp == 0)) { NWRAP_LOG(NWRAP_LOG_DEBUG, "Error parsing NSS_WRAPPER_MAX_HOSTENTS " "value or value is too small. " "Using default value: %lu.", (unsigned long)max_hostents); } else { max_hostents = max_hostents_tmp; } } /* Initialize hash table */ NWRAP_LOG(NWRAP_LOG_DEBUG, "Initializing hash table of size %lu items.", (unsigned long)max_hostents); ok = hcreate(max_hostents); if (!ok) { NWRAP_LOG(NWRAP_LOG_ERROR, "Failed to initialize hash table"); exit(-1); } nwrap_main_global = &__nwrap_main_global; nwrap_libc_init(nwrap_main_global); nwrap_backend_init(nwrap_main_global); /* passwd */ nwrap_pw_global.cache = &__nwrap_cache_pw; nwrap_pw_global.cache->path = getenv("NSS_WRAPPER_PASSWD"); nwrap_pw_global.cache->fp = NULL; nwrap_pw_global.cache->fd = -1; nwrap_pw_global.cache->private_data = &nwrap_pw_global; nwrap_pw_global.cache->parse_line = nwrap_pw_parse_line; nwrap_pw_global.cache->unload = nwrap_pw_unload; /* shadow */ #if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) nwrap_sp_global.cache = &__nwrap_cache_sp; nwrap_sp_global.cache->path = getenv("NSS_WRAPPER_SHADOW"); nwrap_sp_global.cache->fp = NULL; nwrap_sp_global.cache->fd = -1; nwrap_sp_global.cache->private_data = &nwrap_sp_global; nwrap_sp_global.cache->parse_line = nwrap_sp_parse_line; nwrap_sp_global.cache->unload = nwrap_sp_unload; #endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */ /* group */ nwrap_gr_global.cache = &__nwrap_cache_gr; nwrap_gr_global.cache->path = getenv("NSS_WRAPPER_GROUP"); nwrap_gr_global.cache->fp = NULL; nwrap_gr_global.cache->fd = -1; nwrap_gr_global.cache->private_data = &nwrap_gr_global; nwrap_gr_global.cache->parse_line = nwrap_gr_parse_line; nwrap_gr_global.cache->unload = nwrap_gr_unload; /* hosts */ nwrap_he_global.cache = &__nwrap_cache_he; nwrap_he_global.cache->path = getenv("NSS_WRAPPER_HOSTS"); nwrap_he_global.cache->fp = NULL; nwrap_he_global.cache->fd = -1; nwrap_he_global.cache->private_data = &nwrap_he_global; nwrap_he_global.cache->parse_line = nwrap_he_parse_line; nwrap_he_global.cache->unload = nwrap_he_unload; /* We hold all locks here so we can use NWRAP_UNLOCK_ALL. */ nwrap_mutex_unlock(&nwrap_sp_global_mutex); nwrap_mutex_unlock(&nwrap_pw_global_mutex); nwrap_mutex_unlock(&nwrap_he_global_mutex); nwrap_mutex_unlock(&nwrap_gr_global_mutex); nwrap_mutex_unlock(&nwrap_global_mutex); nwrap_mutex_unlock(&nwrap_initialized_mutex); } bool nss_wrapper_enabled(void) { nwrap_init(); if (nwrap_pw_global.cache->path == NULL || nwrap_pw_global.cache->path[0] == '\0') { return false; } if (nwrap_gr_global.cache->path == NULL || nwrap_gr_global.cache->path[0] == '\0') { return false; } return true; } #if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) bool nss_wrapper_shadow_enabled(void) { nwrap_init(); if (nwrap_sp_global.cache->path == NULL || nwrap_sp_global.cache->path[0] == '\0') { return false; } return true; } #endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */ bool nss_wrapper_hosts_enabled(void) { nwrap_init(); if (nwrap_he_global.cache->path == NULL || nwrap_he_global.cache->path[0] == '\0') { return false; } return true; } static bool nwrap_hostname_enabled(void) { nwrap_init(); if (getenv("NSS_WRAPPER_HOSTNAME") == NULL) { return false; } return true; } static bool nwrap_parse_file(struct nwrap_cache *nwrap) { char *line = NULL; ssize_t n; /* Unused but getline needs it */ size_t len; bool ok; if (nwrap->st.st_size == 0) { NWRAP_LOG(NWRAP_LOG_DEBUG, "size == 0"); return true; } /* Support for 32-bit system I guess */ if (nwrap->st.st_size > INT32_MAX) { NWRAP_LOG(NWRAP_LOG_ERROR, "Size[%u] larger than INT32_MAX", (unsigned)nwrap->st.st_size); return false; } rewind(nwrap->fp); do { n = getline(&line, &len, nwrap->fp); if (n < 0) { SAFE_FREE(line); if (feof(nwrap->fp)) { break; } NWRAP_LOG(NWRAP_LOG_ERROR, "Unable to read line from file: %s", nwrap->path); return false; } if (line[n - 1] == '\n') { line[n - 1] = '\0'; } if (line[0] == '\0') { SAFE_FREE(line); continue; } ok = nwrap->parse_line(nwrap, line); if (!ok) { NWRAP_LOG(NWRAP_LOG_ERROR, "Unable to parse line file: %s", line); SAFE_FREE(line); return false; } /* Line is parsed without issues so add it to list */ ok = nwrap_vector_add_item(&(nwrap->lines), (void *const) line); if (!ok) { NWRAP_LOG(NWRAP_LOG_ERROR, "Unable to add line to vector"); return false; } /* This forces getline to allocate new memory for line. */ line = NULL; } while (!feof(nwrap->fp)); return true; } static void nwrap_files_cache_unload(struct nwrap_cache *nwrap) { nwrap->unload(nwrap); nwrap_lines_unload(nwrap); } static bool nwrap_files_cache_reload(struct nwrap_cache *nwrap) { struct stat st; int ret; bool ok; bool retried = false; assert(nwrap != NULL); reopen: if (nwrap->fd < 0) { nwrap->fp = fopen(nwrap->path, "re"); if (nwrap->fp == NULL) { nwrap->fd = -1; NWRAP_LOG(NWRAP_LOG_ERROR, "Unable to open '%s' readonly %d:%s", nwrap->path, nwrap->fd, strerror(errno)); return false; } nwrap->fd = fileno(nwrap->fp); NWRAP_LOG(NWRAP_LOG_DEBUG, "Open '%s'", nwrap->path); } ret = fstat(nwrap->fd, &st); if (ret != 0 && errno == EBADF && retried == false) { /* maybe something closed the fd on our behalf */ NWRAP_LOG(NWRAP_LOG_TRACE, "fstat(%s) - %d:%s - reopen", nwrap->path, ret, strerror(errno)); retried = true; memset(&nwrap->st, 0, sizeof(nwrap->st)); fclose(nwrap->fp); nwrap->fp = NULL; nwrap->fd = -1; goto reopen; } else if (ret != 0) { NWRAP_LOG(NWRAP_LOG_ERROR, "fstat(%s) - %d:%s", nwrap->path, ret, strerror(errno)); fclose(nwrap->fp); nwrap->fp = NULL; nwrap->fd = -1; return false; } if (retried == false && st.st_nlink == 0) { /* maybe someone has replaced the file... */ NWRAP_LOG(NWRAP_LOG_TRACE, "st_nlink == 0, reopen %s", nwrap->path); retried = true; memset(&nwrap->st, 0, sizeof(nwrap->st)); fclose(nwrap->fp); nwrap->fp = NULL; nwrap->fd = -1; goto reopen; } if (st.st_mtime == nwrap->st.st_mtime) { NWRAP_LOG(NWRAP_LOG_TRACE, "st_mtime[%u] hasn't changed, skip reload", (unsigned)st.st_mtime); return true; } NWRAP_LOG(NWRAP_LOG_TRACE, "st_mtime has changed [%u] => [%u], start reload", (unsigned)st.st_mtime, (unsigned)nwrap->st.st_mtime); nwrap->st = st; nwrap_files_cache_unload(nwrap); ok = nwrap_parse_file(nwrap); if (!ok) { NWRAP_LOG(NWRAP_LOG_ERROR, "Failed to reload %s", nwrap->path); nwrap_files_cache_unload(nwrap); return false; } NWRAP_LOG(NWRAP_LOG_TRACE, "Reloaded %s", nwrap->path); return true; } /* * the caller has to call nwrap_unload() on failure */ static bool nwrap_pw_parse_line(struct nwrap_cache *nwrap, char *line) { struct nwrap_pw *nwrap_pw; char *c; char *p; char *e; struct passwd *pw; size_t list_size; nwrap_pw = (struct nwrap_pw *)nwrap->private_data; list_size = sizeof(*nwrap_pw->list) * (nwrap_pw->num+1); pw = (struct passwd *)realloc(nwrap_pw->list, list_size); if (!pw) { NWRAP_LOG(NWRAP_LOG_ERROR, "realloc(%u) failed", (unsigned)list_size); return false; } nwrap_pw->list = pw; pw = &nwrap_pw->list[nwrap_pw->num]; c = line; /* name */ p = strchr(c, ':'); if (!p) { NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, c); return false; } *p = '\0'; p++; pw->pw_name = c; c = p; NWRAP_LOG(NWRAP_LOG_TRACE, "name[%s]\n", pw->pw_name); /* password */ p = strchr(c, ':'); if (!p) { NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, c); return false; } *p = '\0'; p++; pw->pw_passwd = c; c = p; NWRAP_LOG(NWRAP_LOG_TRACE, "password[%s]\n", pw->pw_passwd); /* uid */ p = strchr(c, ':'); if (!p) { NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, c); return false; } *p = '\0'; p++; e = NULL; pw->pw_uid = (uid_t)strtoul(c, &e, 10); if (c == e) { NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } if (e == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } if (e[0] != '\0') { NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } c = p; NWRAP_LOG(NWRAP_LOG_TRACE, "uid[%u]", pw->pw_uid); /* gid */ p = strchr(c, ':'); if (!p) { NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, c); return false; } *p = '\0'; #ifdef HAVE_STRUCT_PASSWD_PW_CLASS /* * We don't support pw_class, so just let it point to * an '\0' byte (empty string). */ pw->pw_class = p; #endif /* HAVE_STRUCT_PASSWD_PW_CLASS */ p++; e = NULL; pw->pw_gid = (gid_t)strtoul(c, &e, 10); if (c == e) { NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } if (e == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } if (e[0] != '\0') { NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } c = p; NWRAP_LOG(NWRAP_LOG_TRACE, "gid[%u]\n", pw->pw_gid); #ifdef HAVE_STRUCT_PASSWD_PW_CLASS NWRAP_LOG(NWRAP_LOG_TRACE, "class[%s]", pw->pw_class); #endif /* HAVE_STRUCT_PASSWD_PW_CLASS */ #ifdef HAVE_STRUCT_PASSWD_PW_CHANGE pw->pw_change = 0; NWRAP_LOG(NWRAP_LOG_TRACE, "change[%lu]", (unsigned long)pw->pw_change); #endif /* HAVE_STRUCT_PASSWD_PW_CHANGE */ #ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE pw->pw_expire = 0; NWRAP_LOG(NWRAP_LOG_TRACE, "expire[%lu]", (unsigned long)pw->pw_expire); #endif /* HAVE_STRUCT_PASSWD_PW_EXPIRE */ /* gecos */ p = strchr(c, ':'); if (!p) { NWRAP_LOG(NWRAP_LOG_ERROR, "invalid line[%s]: '%s'", line, c); return false; } *p = '\0'; p++; pw->pw_gecos = c; c = p; NWRAP_LOG(NWRAP_LOG_TRACE, "gecos[%s]", pw->pw_gecos); /* dir */ p = strchr(c, ':'); if (!p) { NWRAP_LOG(NWRAP_LOG_ERROR, "'%s'", c); return false; } *p = '\0'; p++; pw->pw_dir = c; c = p; NWRAP_LOG(NWRAP_LOG_TRACE, "dir[%s]", pw->pw_dir); /* shell */ pw->pw_shell = c; NWRAP_LOG(NWRAP_LOG_TRACE, "shell[%s]", pw->pw_shell); NWRAP_LOG(NWRAP_LOG_DEBUG, "Added user[%s:%s:%u:%u:%s:%s:%s]", pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid, pw->pw_gecos, pw->pw_dir, pw->pw_shell); nwrap_pw->num++; return true; } static void nwrap_pw_unload(struct nwrap_cache *nwrap) { struct nwrap_pw *nwrap_pw; nwrap_pw = (struct nwrap_pw *)nwrap->private_data; SAFE_FREE(nwrap_pw->list); nwrap_pw->num = 0; nwrap_pw->idx = 0; } static int nwrap_pw_copy_r(const struct passwd *src, struct passwd *dst, char *buf, size_t buflen, struct passwd **dstp) { char *first; char *last; off_t ofs; first = src->pw_name; last = src->pw_shell; while (*last) last++; ofs = PTR_DIFF(last + 1, first); if (ofs > (off_t) buflen) { return ERANGE; } memcpy(buf, first, ofs); ofs = PTR_DIFF(src->pw_name, first); dst->pw_name = buf + ofs; ofs = PTR_DIFF(src->pw_passwd, first); dst->pw_passwd = buf + ofs; dst->pw_uid = src->pw_uid; dst->pw_gid = src->pw_gid; #ifdef HAVE_STRUCT_PASSWD_PW_CLASS ofs = PTR_DIFF(src->pw_class, first); dst->pw_class = buf + ofs; #endif /* HAVE_STRUCT_PASSWD_PW_CLASS */ #ifdef HAVE_STRUCT_PASSWD_PW_CHANGE dst->pw_change = 0; #endif /* HAVE_STRUCT_PASSWD_PW_CHANGE */ #ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE dst->pw_expire = 0; #endif /* HAVE_STRUCT_PASSWD_PW_EXPIRE */ ofs = PTR_DIFF(src->pw_gecos, first); dst->pw_gecos = buf + ofs; ofs = PTR_DIFF(src->pw_dir, first); dst->pw_dir = buf + ofs; ofs = PTR_DIFF(src->pw_shell, first); dst->pw_shell = buf + ofs; if (dstp) { *dstp = dst; } return 0; } #if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) static bool nwrap_sp_parse_line(struct nwrap_cache *nwrap, char *line) { struct nwrap_sp *nwrap_sp; struct spwd *sp; size_t list_size; char *c; char *e; char *p; nwrap_sp = (struct nwrap_sp *)nwrap->private_data; list_size = sizeof(*nwrap_sp->list) * (nwrap_sp->num+1); sp = (struct spwd *)realloc(nwrap_sp->list, list_size); if (sp == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "realloc(%u) failed", (unsigned)list_size); return false; } nwrap_sp->list = sp; sp = &nwrap_sp->list[nwrap_sp->num]; c = line; /* name */ p = strchr(c, ':'); if (p == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "name -- Invalid line[%s]: '%s'", line, c); return false; } *p = '\0'; p++; sp->sp_namp = c; c = p; NWRAP_LOG(NWRAP_LOG_TRACE, "name[%s]\n", sp->sp_namp); /* pwd */ p = strchr(c, ':'); if (p == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "pwd -- Invalid line[%s]: '%s'", line, c); return false; } *p = '\0'; p++; sp->sp_pwdp = c; c = p; /* lstchg (long) */ if (c[0] == ':') { sp->sp_lstchg = -1; p++; } else { p = strchr(c, ':'); if (p == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "lstchg -- Invalid line[%s]: '%s'", line, c); return false; } *p = '\0'; p++; sp->sp_lstchg = strtol(c, &e, 10); if (c == e) { NWRAP_LOG(NWRAP_LOG_ERROR, "lstchg -- Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } if (e == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "lstchg -- Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } if (e[0] != '\0') { NWRAP_LOG(NWRAP_LOG_ERROR, "lstchg -- Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } } c = p; /* min (long) */ if (c[0] == ':') { sp->sp_min = -1; p++; } else { p = strchr(c, ':'); if (p == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "min -- Invalid line[%s]: '%s'", line, c); return false; } *p = '\0'; p++; sp->sp_min = strtol(c, &e, 10); if (c == e) { NWRAP_LOG(NWRAP_LOG_ERROR, "min -- Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } if (e == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "min -- Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } if (e[0] != '\0') { NWRAP_LOG(NWRAP_LOG_ERROR, "min -- Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } } c = p; /* max (long) */ if (c[0] == ':') { sp->sp_max = -1; p++; } else { p = strchr(c, ':'); if (p == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "max -- Invalid line[%s]: '%s'", line, c); return false; } *p = '\0'; p++; sp->sp_max = strtol(c, &e, 10); if (c == e) { NWRAP_LOG(NWRAP_LOG_ERROR, "max -- Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } if (e == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "max -- Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } if (e[0] != '\0') { NWRAP_LOG(NWRAP_LOG_ERROR, "max -- Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } } c = p; /* warn (long) */ if (c[0] == ':') { sp->sp_warn = -1; p++; } else { p = strchr(c, ':'); if (p == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "warn -- Invalid line[%s]: '%s'", line, c); return false; } *p = '\0'; p++; sp->sp_warn = strtol(c, &e, 10); if (c == e) { NWRAP_LOG(NWRAP_LOG_ERROR, "warn -- Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } if (e == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "warn -- Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } if (e[0] != '\0') { NWRAP_LOG(NWRAP_LOG_ERROR, "warn -- Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } } c = p; /* inact (long) */ if (c[0] == ':') { sp->sp_inact = -1; p++; } else { p = strchr(c, ':'); if (p == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "inact -- Invalid line[%s]: '%s'", line, c); return false; } *p = '\0'; p++; sp->sp_inact = strtol(c, &e, 10); if (c == e) { NWRAP_LOG(NWRAP_LOG_ERROR, "inact -- Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } if (e == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "inact -- Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } if (e[0] != '\0') { NWRAP_LOG(NWRAP_LOG_ERROR, "inact -- Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } } c = p; /* expire (long) */ if (c[0] == ':') { sp->sp_expire = -1; p++; } else { p = strchr(c, ':'); if (p == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "expire -- Invalid line[%s]: '%s'", line, c); return false; } *p = '\0'; p++; sp->sp_expire = strtol(c, &e, 10); if (c == e) { NWRAP_LOG(NWRAP_LOG_ERROR, "expire -- Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } if (e == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "expire -- Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } if (e[0] != '\0') { NWRAP_LOG(NWRAP_LOG_ERROR, "expire -- Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } } c = p; nwrap_sp->num++; return true; } static void nwrap_sp_unload(struct nwrap_cache *nwrap) { struct nwrap_sp *nwrap_sp; nwrap_sp = (struct nwrap_sp *)nwrap->private_data; SAFE_FREE(nwrap_sp->list); nwrap_sp->num = 0; nwrap_sp->idx = 0; } #endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */ /* * the caller has to call nwrap_unload() on failure */ static bool nwrap_gr_parse_line(struct nwrap_cache *nwrap, char *line) { struct nwrap_gr *nwrap_gr; char *c; char *p; char *e; struct group *gr; size_t list_size; unsigned nummem; nwrap_gr = (struct nwrap_gr *)nwrap->private_data; list_size = sizeof(*nwrap_gr->list) * (nwrap_gr->num+1); gr = (struct group *)realloc(nwrap_gr->list, list_size); if (!gr) { NWRAP_LOG(NWRAP_LOG_ERROR, "realloc failed"); return false; } nwrap_gr->list = gr; gr = &nwrap_gr->list[nwrap_gr->num]; c = line; /* name */ p = strchr(c, ':'); if (!p) { NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, c); return false; } *p = '\0'; p++; gr->gr_name = c; c = p; NWRAP_LOG(NWRAP_LOG_TRACE, "name[%s]", gr->gr_name); /* password */ p = strchr(c, ':'); if (!p) { NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, c); return false; } *p = '\0'; p++; gr->gr_passwd = c; c = p; NWRAP_LOG(NWRAP_LOG_TRACE, "password[%s]", gr->gr_passwd); /* gid */ p = strchr(c, ':'); if (!p) { NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, c); return false; } *p = '\0'; p++; e = NULL; gr->gr_gid = (gid_t)strtoul(c, &e, 10); if (c == e) { NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } if (e == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } if (e[0] != '\0') { NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s' - %s", line, c, strerror(errno)); return false; } c = p; NWRAP_LOG(NWRAP_LOG_TRACE, "gid[%u]", gr->gr_gid); /* members */ gr->gr_mem = (char **)malloc(sizeof(char *)); if (!gr->gr_mem) { NWRAP_LOG(NWRAP_LOG_ERROR, "Out of memory"); return false; } gr->gr_mem[0] = NULL; for(nummem = 0; p != NULL && p[0] != '\0'; nummem++) { char **m; size_t m_size; c = p; p = strchr(c, ','); if (p) { *p = '\0'; p++; } if (strlen(c) == 0) { break; } m_size = sizeof(char *) * (nummem+2); m = (char **)realloc(gr->gr_mem, m_size); if (!m) { NWRAP_LOG(NWRAP_LOG_ERROR, "realloc(%zd) failed", m_size); return false; } gr->gr_mem = m; gr->gr_mem[nummem] = c; gr->gr_mem[nummem+1] = NULL; NWRAP_LOG(NWRAP_LOG_TRACE, "member[%u]: '%s'", nummem, gr->gr_mem[nummem]); } NWRAP_LOG(NWRAP_LOG_DEBUG, "Added group[%s:%s:%u:] with %u members", gr->gr_name, gr->gr_passwd, gr->gr_gid, nummem); nwrap_gr->num++; return true; } static void nwrap_gr_unload(struct nwrap_cache *nwrap) { int i; struct nwrap_gr *nwrap_gr; nwrap_gr = (struct nwrap_gr *)nwrap->private_data; if (nwrap_gr->list) { for (i=0; i < nwrap_gr->num; i++) { SAFE_FREE(nwrap_gr->list[i].gr_mem); } SAFE_FREE(nwrap_gr->list); } nwrap_gr->num = 0; nwrap_gr->idx = 0; } static struct nwrap_entlist *nwrap_entlist_init(struct nwrap_entdata *ed) { struct nwrap_entlist *el; if (ed == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "entry is NULL, can't create list item"); return NULL; } el = (struct nwrap_entlist *)malloc(sizeof(struct nwrap_entlist)); if (el == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "malloc failed"); return NULL; } el->next = NULL; el->ed = ed; return el; } static bool nwrap_ed_inventarize_add_new(char *const h_name, struct nwrap_entdata *const ed) { ENTRY e; ENTRY *p; struct nwrap_entlist *el; bool ok; if (h_name == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "h_name NULL - can't add"); return false; } el = nwrap_entlist_init(ed); if (el == NULL) { return false; } e.key = h_name; e.data = (void *)el; p = hsearch(e, ENTER); if (p == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "Hash table is full (%s)!", strerror(errno)); return false; } ok = nwrap_vector_add_item(&(nwrap_he_global.lists), (void *)el); if (!ok) { NWRAP_LOG(NWRAP_LOG_ERROR, "Failed to add list entry to vector."); return false; } return true; } static bool nwrap_ed_inventarize_add_to_existing(struct nwrap_entdata *const ed, struct nwrap_entlist *const el) { struct nwrap_entlist *cursor; struct nwrap_entlist *el_new; if (el == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "list is NULL, can not add"); return false; } for (cursor = el; cursor->next != NULL; cursor = cursor->next) { if (cursor->ed == ed) { /* The entry already exists in this list. */ return true; } } if (cursor->ed == ed) { /* The entry already exists in this list. */ return true; } el_new = nwrap_entlist_init(ed); if (el_new == NULL) { return false; } cursor->next = el_new; return true; } static bool nwrap_ed_inventarize(char *const name, struct nwrap_entdata *const ed) { ENTRY e; ENTRY *p; bool ok; e.key = name; e.data = NULL; NWRAP_LOG(NWRAP_LOG_DEBUG, "Searching name: %s", e.key); p = hsearch(e, FIND); if (p == NULL) { NWRAP_LOG(NWRAP_LOG_DEBUG, "Name %s not found. Adding...", name); ok = nwrap_ed_inventarize_add_new(name, ed); } else { struct nwrap_entlist *el = (struct nwrap_entlist *)p->data; NWRAP_LOG(NWRAP_LOG_DEBUG, "Name %s found. Add record to list.", name); ok = nwrap_ed_inventarize_add_to_existing(ed, el); } return ok; } static bool nwrap_add_hname(struct nwrap_entdata *const ed) { char *const h_name = (char *const)(ed->ht.h_name); unsigned i; bool ok; ok = nwrap_ed_inventarize(h_name, ed); if (!ok) { return false; } if (ed->ht.h_aliases == NULL) { return true; } /* Itemize aliases */ for (i = 0; ed->ht.h_aliases[i] != NULL; ++i) { char *h_name_alias; h_name_alias = ed->ht.h_aliases[i]; NWRAP_LOG(NWRAP_LOG_DEBUG, "Add alias: %s", h_name_alias); if (!nwrap_ed_inventarize(h_name_alias, ed)) { NWRAP_LOG(NWRAP_LOG_ERROR, "Unable to add alias: %s", h_name_alias); return false; } } return true; } static bool nwrap_he_parse_line(struct nwrap_cache *nwrap, char *line) { struct nwrap_he *nwrap_he = (struct nwrap_he *)nwrap->private_data; bool do_aliases = true; ssize_t aliases_count = 0; char *p; char *i; char *n; char *ip; bool ok; struct nwrap_entdata *ed = (struct nwrap_entdata *) malloc(sizeof(struct nwrap_entdata)); if (ed == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "Unable to allocate memory for nwrap_entdata"); return false; } ZERO_STRUCTP(ed); i = line; /* * IP */ /* Walk to first char */ for (p = i; *p != '.' && *p != ':' && !isxdigit((int) *p); p++) { if (*p == '\0') { NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, i); free(ed); return false; } } for (i = p; !isspace((int)*p); p++) { if (*p == '\0') { NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, i); free(ed); return false; } } *p = '\0'; if (inet_pton(AF_INET, i, ed->addr.host_addr)) { ed->ht.h_addrtype = AF_INET; ed->ht.h_length = 4; #ifdef HAVE_IPV6 } else if (inet_pton(AF_INET6, i, ed->addr.host_addr)) { ed->ht.h_addrtype = AF_INET6; ed->ht.h_length = 16; #endif } else { NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, i); free(ed); return false; } ip = i; ok = nwrap_vector_add_item(&(ed->nwrap_addrdata), (void *const)ed->addr.host_addr); if (!ok) { NWRAP_LOG(NWRAP_LOG_ERROR, "Unable to add addrdata to vector"); free(ed); return false; } ed->ht.h_addr_list = nwrap_vector_head(&ed->nwrap_addrdata); p++; /* * FQDN */ /* Walk to first char */ for (n = p; *p != '_' && !isalnum((int) *p); p++) { if (*p == '\0') { NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, n); free(ed); return false; } } for (n = p; !isspace((int)*p); p++) { if (*p == '\0') { do_aliases = false; break; } } *p = '\0'; /* Convert to lowercase. This operate on same memory region */ str_tolower(n, n); ed->ht.h_name = n; /* glib's getent always dereferences he->h_aliases */ ed->ht.h_aliases = malloc(sizeof(char *)); if (ed->ht.h_aliases == NULL) { free(ed); return false; } ed->ht.h_aliases[0] = NULL; /* * Aliases */ while (do_aliases) { char **aliases; char *a; p++; /* Walk to first char */ for (a = p; *p != '_' && !isalnum((int) *p); p++) { if (*p == '\0') { do_aliases = false; break; } } /* Only trailing spaces are left */ if (!do_aliases) { break; } for (a = p; !isspace((int)*p); p++) { if (*p == '\0') { do_aliases = false; break; } } *p = '\0'; aliases = realloc(ed->ht.h_aliases, sizeof(char *) * (aliases_count + 2)); if (aliases == NULL) { free(ed); return false; } ed->ht.h_aliases = aliases; str_tolower(a, a); aliases[aliases_count] = a; aliases[aliases_count + 1] = NULL; aliases_count += 1; } ok = nwrap_vector_add_item(&(nwrap_he->entries), (void *const)ed); if (!ok) { NWRAP_LOG(NWRAP_LOG_ERROR, "Unable to add entry to vector"); free(ed); return false; } ed->aliases_count = aliases_count; /* Inventarize item */ ok = nwrap_add_hname(ed); if (!ok) { return false; } ok = nwrap_ed_inventarize(ip, ed); if (!ok) { return false; } nwrap_he->num++; return true; } static void nwrap_he_unload(struct nwrap_cache *nwrap) { struct nwrap_he *nwrap_he = (struct nwrap_he *)nwrap->private_data; struct nwrap_entdata *ed; struct nwrap_entlist *el; size_t i; int rc; nwrap_vector_foreach (ed, nwrap_he->entries, i) { SAFE_FREE(ed->nwrap_addrdata.items); SAFE_FREE(ed->ht.h_aliases); SAFE_FREE(ed); } SAFE_FREE(nwrap_he->entries.items); nwrap_he->entries.count = nwrap_he->entries.capacity = 0; nwrap_vector_foreach(el, nwrap_he->lists, i) { while (el != NULL) { struct nwrap_entlist *el_next; el_next = el->next; SAFE_FREE(el); el = el_next; } } SAFE_FREE(nwrap_he->lists.items); nwrap_he->lists.count = nwrap_he->lists.capacity = 0; nwrap_he->num = 0; nwrap_he->idx = 0; /* * If we unload the file, the pointers in the hash table point to * invalid memory. So we need to destroy the hash table and recreate * it. */ hdestroy(); rc = hcreate(max_hostents); if (rc == 0) { NWRAP_LOG(NWRAP_LOG_ERROR, "Failed to initialize hash table"); exit(-1); } } /* user functions */ static struct passwd *nwrap_files_getpwnam(struct nwrap_backend *b, const char *name) { int i; bool ok; (void) b; /* unused */ NWRAP_LOG(NWRAP_LOG_DEBUG, "Lookup user %s in files", name); ok = nwrap_files_cache_reload(nwrap_pw_global.cache); if (!ok) { NWRAP_LOG(NWRAP_LOG_ERROR, "Error loading passwd file"); return NULL; } for (i=0; i= nwrap_pw_global.num) { errno = ENOENT; return NULL; } pw = &nwrap_pw_global.list[nwrap_pw_global.idx++]; NWRAP_LOG(NWRAP_LOG_DEBUG, "return user[%s] uid[%u]", pw->pw_name, pw->pw_uid); return pw; } static int nwrap_files_getpwent_r(struct nwrap_backend *b, struct passwd *pwdst, char *buf, size_t buflen, struct passwd **pwdstp) { struct passwd *pw; pw = nwrap_files_getpwent(b); if (!pw) { if (errno == 0) { return ENOENT; } return errno; } return nwrap_pw_copy_r(pw, pwdst, buf, buflen, pwdstp); } static void nwrap_files_endpwent(struct nwrap_backend *b) { (void) b; /* unused */ nwrap_pw_global.idx = 0; } /* shadow */ #if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) #ifdef HAVE_SETSPENT static void nwrap_files_setspent(void) { nwrap_sp_global.idx = 0; } static struct spwd *nwrap_files_getspent(void) { struct spwd *sp; if (nwrap_sp_global.idx == 0) { bool ok; ok = nwrap_files_cache_reload(nwrap_sp_global.cache); if (!ok) { NWRAP_LOG(NWRAP_LOG_ERROR, "Error loading shadow file"); return NULL; } } if (nwrap_sp_global.idx >= nwrap_sp_global.num) { errno = ENOENT; return NULL; } sp = &nwrap_sp_global.list[nwrap_sp_global.idx++]; NWRAP_LOG(NWRAP_LOG_DEBUG, "return user[%s]", sp->sp_namp); return sp; } static void nwrap_files_endspent(void) { nwrap_sp_global.idx = 0; } #endif /* HAVE_SETSPENT */ static struct spwd *nwrap_files_getspnam(const char *name) { int i; bool ok; NWRAP_LOG(NWRAP_LOG_DEBUG, "Lookup user %s in files", name); ok = nwrap_files_cache_reload(nwrap_sp_global.cache); if (!ok) { NWRAP_LOG(NWRAP_LOG_ERROR, "Error loading shadow file"); return NULL; } for (i=0; igr_name); for (i=0; grp->gr_mem && grp->gr_mem[i] != NULL; i++) { if (group != grp->gr_gid && (strcmp(user, grp->gr_mem[i]) == 0)) { NWRAP_LOG(NWRAP_LOG_DEBUG, "%s is member of %s", user, grp->gr_name); 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)[*start] = grp->gr_gid; (*start)++; } } } nwrap_files_endgrent(b); return *start; } /* group functions */ static struct group *nwrap_files_getgrnam(struct nwrap_backend *b, const char *name) { int i; bool ok; (void) b; /* unused */ ok = nwrap_files_cache_reload(nwrap_gr_global.cache); if (!ok) { NWRAP_LOG(NWRAP_LOG_ERROR, "Error loading group file"); return NULL; } for (i=0; i= nwrap_gr_global.num) { errno = ENOENT; return NULL; } gr = &nwrap_gr_global.list[nwrap_gr_global.idx++]; NWRAP_LOG(NWRAP_LOG_DEBUG, "return group[%s] gid[%u]", gr->gr_name, gr->gr_gid); return gr; } static int nwrap_files_getgrent_r(struct nwrap_backend *b, struct group *grdst, char *buf, size_t buflen, struct group **grdstp) { struct group *gr; gr = nwrap_files_getgrent(b); if (!gr) { if (errno == 0) { return ENOENT; } return errno; } return nwrap_gr_copy_r(gr, grdst, buf, buflen, grdstp); } static void nwrap_files_endgrent(struct nwrap_backend *b) { (void) b; /* unused */ nwrap_gr_global.idx = 0; } /* hosts functions */ static int nwrap_files_internal_gethostbyname(const char *name, int af, struct hostent *result, struct nwrap_vector *addr_list) { struct nwrap_entlist *el; struct hostent *he; char *h_name_lower; ENTRY e; ENTRY *e_p; char canon_name[DNS_NAME_MAX] = { 0 }; size_t name_len; bool he_found = false; bool ok; /* * We need to make sure we have zeroed return pointer for consumers * which don't check return values, e.g. OpenLDAP. */ ZERO_STRUCTP(result); ok = nwrap_files_cache_reload(nwrap_he_global.cache); if (!ok) { NWRAP_LOG(NWRAP_LOG_ERROR, "error loading hosts file"); goto no_ent; } name_len = strlen(name); if (name_len < sizeof(canon_name) && name[name_len - 1] == '.') { memcpy(canon_name, name, name_len - 1); canon_name[name_len] = '\0'; name = canon_name; } if (!str_tolower_copy(&h_name_lower, name)) { NWRAP_LOG(NWRAP_LOG_DEBUG, "Out of memory while converting to lower case"); goto no_ent; } /* Look at hash table for element */ NWRAP_LOG(NWRAP_LOG_DEBUG, "Searching for name: %s", h_name_lower); e.key = h_name_lower; e.data = NULL; e_p = hsearch(e, FIND); if (e_p == NULL) { NWRAP_LOG(NWRAP_LOG_DEBUG, "Name %s not found.", h_name_lower); SAFE_FREE(h_name_lower); goto no_ent; } SAFE_FREE(h_name_lower); /* Always cleanup vector and results */ if (!nwrap_vector_is_initialized(addr_list)) { if (!nwrap_vector_init(addr_list)) { NWRAP_LOG(NWRAP_LOG_DEBUG, "Unable to initialize memory for addr_list vector"); goto no_ent; } } else { /* When vector is initialized data are valid no more. * Quick way how to free vector is: */ addr_list->count = 0; } /* Iterate through results */ for (el = (struct nwrap_entlist *)e_p->data; el != NULL; el = el->next) { he = &(el->ed->ht); /* Filter by address familiy if provided */ if (af != AF_UNSPEC && he->h_addrtype != af) { continue; } /* * GLIBC HACK? * glibc doesn't return ipv6 addresses when AF_UNSPEC is used */ if (af == AF_UNSPEC && he->h_addrtype != AF_INET) { continue; } if (!he_found) { memcpy(result, he, sizeof(struct hostent)); NWRAP_LOG(NWRAP_LOG_DEBUG, "Name found. Returning record for %s", he->h_name); he_found = true; } nwrap_vector_merge(addr_list, &el->ed->nwrap_addrdata); result->h_addr_list = nwrap_vector_head(addr_list); } if (he_found) { return 0; } NWRAP_LOG(NWRAP_LOG_DEBUG, "Name found in database. No records matches type."); no_ent: errno = ENOENT; return -1; } static int nwrap_files_gethostbyname2_r(struct nwrap_backend *b, const char *name, int af, struct hostent *hedst, char *buf, size_t buflen, struct hostent **hedstp) { struct nwrap_vector *addr_list = NULL; union { char *ptr; char **list; } g; int rc; (void) b; /* unused */ (void) af; /* unused */ if (name == NULL || hedst == NULL || buf == NULL || buflen == 0) { errno = EINVAL; return -1; } *hedstp = NULL; buf[0] = '\0'; addr_list = calloc(1, sizeof(struct nwrap_vector)); if (addr_list == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "Unable to allocate memory for address list"); errno = ENOENT; return -1; } rc = nwrap_files_internal_gethostbyname(name, af, hedst, addr_list); if (rc == -1) { SAFE_FREE(addr_list->items); SAFE_FREE(addr_list); errno = ENOENT; return -1; } /* +1 i for ending NULL pointer */ if (buflen < ((addr_list->count + 1) * sizeof(void *))) { SAFE_FREE(addr_list->items); SAFE_FREE(addr_list); return ERANGE; } /* Copy all to user provided buffer and change * pointers in returned structure. * +1 is for ending NULL pointer. */ memcpy(buf, addr_list->items, (addr_list->count + 1) * sizeof(void *)); SAFE_FREE(addr_list->items); SAFE_FREE(addr_list); g.ptr = buf; hedst->h_addr_list = g.list; *hedstp = hedst; return 0; } #ifdef HAVE_GETHOSTBYNAME_R static int nwrap_gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) { int rc; size_t i; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; rc = b->ops->nw_gethostbyname2_r(b, name, AF_UNSPEC, ret, buf, buflen, result); if (rc == 0) { return 0; } else if (rc == ERANGE) { return ERANGE; } } *h_errnop = h_errno; return ENOENT; } int gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) { if (!nss_wrapper_hosts_enabled()) { return libc_gethostbyname_r(name, ret, buf, buflen, result, h_errnop); } return nwrap_gethostbyname_r(name, ret, buf, buflen, result, h_errnop); } #endif #ifdef HAVE_GETHOSTBYNAME2_R static int nwrap_gethostbyname2_r(const char *name, int af, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) { int rc; size_t i; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; rc = b->ops->nw_gethostbyname2_r(b, name, af, ret, buf, buflen, result); if (rc == 0) { return 0; } else if (rc == ERANGE) { return ERANGE; } } *h_errnop = h_errno; return ENOENT; } int gethostbyname2_r(const char *name, int af, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) { if (!nss_wrapper_hosts_enabled()) { return libc_gethostbyname2_r(name, af, ret, buf, buflen, result, h_errnop); } return nwrap_gethostbyname2_r(name, af, ret, buf, buflen, result, h_errnop); } #endif static int nwrap_files_getaddrinfo(const char *name, unsigned short port, const struct addrinfo *hints, struct addrinfo **ai) { struct nwrap_entlist *el; struct hostent *he; struct addrinfo *ai_head = NULL; struct addrinfo *ai_cur = NULL; char *h_name_lower; size_t name_len; char canon_name[DNS_NAME_MAX] = { 0 }; bool skip_canonname = false; ENTRY e = { .key = NULL, }; ENTRY *e_p = NULL; int rc; bool ok; ok = nwrap_files_cache_reload(nwrap_he_global.cache); if (!ok) { NWRAP_LOG(NWRAP_LOG_ERROR, "error loading hosts file"); return EAI_SYSTEM; } name_len = strlen(name); if (name_len == 0) { return EAI_NONAME; } if (name_len < sizeof(canon_name) && name[name_len - 1] == '.') { memcpy(canon_name, name, name_len - 1); canon_name[name_len] = '\0'; name = canon_name; } if (!str_tolower_copy(&h_name_lower, name)) { NWRAP_LOG(NWRAP_LOG_DEBUG, "Out of memory while converting to lower case"); return EAI_MEMORY; } NWRAP_LOG(NWRAP_LOG_DEBUG, "Searching for name: %s", h_name_lower); e.key = h_name_lower; e.data = NULL; e_p = hsearch(e, FIND); if (e_p == NULL) { NWRAP_LOG(NWRAP_LOG_DEBUG, "Name %s not found.", h_name_lower); SAFE_FREE(h_name_lower); errno = ENOENT; return EAI_NONAME; } NWRAP_LOG(NWRAP_LOG_DEBUG, "Name: %s found.", h_name_lower); SAFE_FREE(h_name_lower); rc = EAI_NONAME; for (el = (struct nwrap_entlist *)e_p->data; el != NULL; el = el->next) { int rc2; struct addrinfo *ai_new = NULL; he = &(el->ed->ht); if (hints->ai_family != AF_UNSPEC && he->h_addrtype != hints->ai_family) { NWRAP_LOG(NWRAP_LOG_DEBUG, "Entry found but with wrong AF - " "remembering EAI_ADDRINFO."); rc = EAI_ADDRFAMILY; continue; } /* Function allocates memory and returns it in ai. */ rc2 = nwrap_convert_he_ai(he, port, hints, &ai_new, skip_canonname); if (rc2 != 0) { NWRAP_LOG(NWRAP_LOG_ERROR, "Error converting he to ai"); if (ai_head != NULL) { freeaddrinfo(ai_head); } return rc2; } skip_canonname = true; if (ai_head == NULL) { ai_head = ai_new; } if (ai_cur != NULL) { ai_cur->ai_next = ai_new; } ai_cur = ai_new; } if (ai_head != NULL) { rc = 0; } *ai = ai_head; return rc; } static struct hostent *nwrap_files_gethostbyaddr(struct nwrap_backend *b, const void *addr, socklen_t len, int type) { struct hostent *he; char ip[NWRAP_INET_ADDRSTRLEN] = {0}; struct nwrap_entdata *ed; const char *a; size_t i; bool ok; (void) b; /* unused */ (void) len; /* unused */ ok = nwrap_files_cache_reload(nwrap_he_global.cache); if (!ok) { NWRAP_LOG(NWRAP_LOG_ERROR, "error loading hosts file"); return NULL; } a = inet_ntop(type, addr, ip, sizeof(ip)); if (a == NULL) { errno = EINVAL; return NULL; } nwrap_vector_foreach(ed, nwrap_he_global.entries, i) { he = &(ed->ht); if (he->h_addrtype != type) { continue; } if (memcmp(addr, he->h_addr_list[0], he->h_length) == 0) { return he; } } errno = ENOENT; return NULL; } #ifdef HAVE_GETHOSTBYADDR_R static int nwrap_gethostbyaddr_r(const void *addr, socklen_t len, int type, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) { size_t i; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; *result = b->ops->nw_gethostbyaddr(b, addr, len, type); if (*result != NULL) { break; } } if (*result != NULL) { memset(buf, '\0', buflen); *ret = **result; return 0; } *h_errnop = h_errno; return -1; } int gethostbyaddr_r(const void *addr, socklen_t len, int type, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) { if (!nss_wrapper_hosts_enabled()) { return libc_gethostbyaddr_r(addr, len, type, ret, buf, buflen, result, h_errnop); } return nwrap_gethostbyaddr_r(addr, len, type, ret, buf, buflen, result, h_errnop); } #endif /* hosts enum functions */ static void nwrap_files_sethostent(void) { nwrap_he_global.idx = 0; } static struct hostent *nwrap_files_gethostent(void) { struct hostent *he; if (nwrap_he_global.idx == 0) { bool ok; ok = nwrap_files_cache_reload(nwrap_he_global.cache); if (!ok) { NWRAP_LOG(NWRAP_LOG_ERROR, "Error loading hosts file"); return NULL; } } if (nwrap_he_global.idx >= nwrap_he_global.num) { errno = ENOENT; return NULL; } he = &((struct nwrap_entdata *)nwrap_he_global.entries.items[nwrap_he_global.idx++])->ht; NWRAP_LOG(NWRAP_LOG_DEBUG, "return hosts[%s]", he->h_name); return he; } static void nwrap_files_endhostent(void) { nwrap_he_global.idx = 0; } /* * module backend */ static struct passwd *nwrap_module_getpwnam(struct nwrap_backend *b, const char *name) { static struct passwd pwd; static char buf[1000]; NSS_STATUS status; if (b->symbols->_nss_getpwnam_r.f == NULL) { return NULL; } status = b->symbols->_nss_getpwnam_r.f(name, &pwd, buf, sizeof(buf), &errno); if (status == NSS_STATUS_NOTFOUND) { return NULL; } if (status != NSS_STATUS_SUCCESS) { return NULL; } return &pwd; } static int nwrap_module_getpwnam_r(struct nwrap_backend *b, const char *name, struct passwd *pwdst, char *buf, size_t buflen, struct passwd **pwdstp) { int ret; *pwdstp = NULL; if (b->symbols->_nss_getpwnam_r.f == NULL) { return NSS_STATUS_NOTFOUND; } ret = b->symbols->_nss_getpwnam_r.f(name, pwdst, buf, buflen, &errno); switch (ret) { case NSS_STATUS_SUCCESS: *pwdstp = pwdst; return 0; case NSS_STATUS_NOTFOUND: if (errno != 0) { return errno; } return ENOENT; case NSS_STATUS_TRYAGAIN: if (errno != 0) { return errno; } return ERANGE; default: if (errno != 0) { return errno; } return ret; } } static struct passwd *nwrap_module_getpwuid(struct nwrap_backend *b, uid_t uid) { static struct passwd pwd; static char buf[1000]; NSS_STATUS status; if (b->symbols->_nss_getpwuid_r.f == NULL) { return NULL; } status = b->symbols->_nss_getpwuid_r.f(uid, &pwd, buf, sizeof(buf), &errno); if (status == NSS_STATUS_NOTFOUND) { return NULL; } if (status != NSS_STATUS_SUCCESS) { return NULL; } return &pwd; } static int nwrap_module_getpwuid_r(struct nwrap_backend *b, uid_t uid, struct passwd *pwdst, char *buf, size_t buflen, struct passwd **pwdstp) { int ret; *pwdstp = NULL; if (b->symbols->_nss_getpwuid_r.f == NULL) { return ENOENT; } ret = b->symbols->_nss_getpwuid_r.f(uid, pwdst, buf, buflen, &errno); switch (ret) { case NSS_STATUS_SUCCESS: *pwdstp = pwdst; return 0; case NSS_STATUS_NOTFOUND: if (errno != 0) { return errno; } return ENOENT; case NSS_STATUS_TRYAGAIN: if (errno != 0) { return errno; } return ERANGE; default: if (errno != 0) { return errno; } return ret; } } static void nwrap_module_setpwent(struct nwrap_backend *b) { if (b->symbols->_nss_setpwent.f == NULL) { return; } b->symbols->_nss_setpwent.f(); } static struct passwd *nwrap_module_getpwent(struct nwrap_backend *b) { static struct passwd pwd; static char buf[1000]; NSS_STATUS status; if (b->symbols->_nss_getpwent_r.f == NULL) { return NULL; } status = b->symbols->_nss_getpwent_r.f(&pwd, buf, sizeof(buf), &errno); if (status == NSS_STATUS_NOTFOUND) { return NULL; } if (status != NSS_STATUS_SUCCESS) { return NULL; } return &pwd; } static int nwrap_module_getpwent_r(struct nwrap_backend *b, struct passwd *pwdst, char *buf, size_t buflen, struct passwd **pwdstp) { int ret; *pwdstp = NULL; if (b->symbols->_nss_getpwent_r.f == NULL) { return ENOENT; } ret = b->symbols->_nss_getpwent_r.f(pwdst, buf, buflen, &errno); switch (ret) { case NSS_STATUS_SUCCESS: *pwdstp = pwdst; return 0; case NSS_STATUS_NOTFOUND: if (errno != 0) { return errno; } return ENOENT; case NSS_STATUS_TRYAGAIN: if (errno != 0) { return errno; } return ERANGE; default: if (errno != 0) { return errno; } return ret; } } static void nwrap_module_endpwent(struct nwrap_backend *b) { if (b->symbols->_nss_endpwent.f == NULL) { return; } b->symbols->_nss_endpwent.f(); } 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) { if (b->symbols->_nss_initgroups_dyn.f == NULL) { return NSS_STATUS_UNAVAIL; } return b->symbols->_nss_initgroups_dyn.f(user, group, start, size, groups, limit, errnop); } static struct group *nwrap_module_getgrnam(struct nwrap_backend *b, const char *name) { static struct group grp; static char *buf; static int buflen = 1000; NSS_STATUS status; if (b->symbols->_nss_getgrnam_r.f == NULL) { return NULL; } if (!buf) { buf = (char *)malloc(buflen); } again: status = b->symbols->_nss_getgrnam_r.f(name, &grp, buf, buflen, &errno); if (status == NSS_STATUS_TRYAGAIN) { buflen *= 2; buf = (char *)realloc(buf, buflen); if (!buf) { return NULL; } goto again; } if (status == NSS_STATUS_NOTFOUND) { SAFE_FREE(buf); return NULL; } if (status != NSS_STATUS_SUCCESS) { SAFE_FREE(buf); return NULL; } return &grp; } static int nwrap_module_getgrnam_r(struct nwrap_backend *b, const char *name, struct group *grdst, char *buf, size_t buflen, struct group **grdstp) { int ret; *grdstp = NULL; if (b->symbols->_nss_getgrnam_r.f == NULL) { return ENOENT; } ret = b->symbols->_nss_getgrnam_r.f(name, grdst, buf, buflen, &errno); switch (ret) { case NSS_STATUS_SUCCESS: *grdstp = grdst; return 0; case NSS_STATUS_NOTFOUND: if (errno != 0) { return errno; } return ENOENT; case NSS_STATUS_TRYAGAIN: if (errno != 0) { return errno; } return ERANGE; default: if (errno != 0) { return errno; } return ret; } } static struct group *nwrap_module_getgrgid(struct nwrap_backend *b, gid_t gid) { static struct group grp; static char *buf; static int buflen = 1000; NSS_STATUS status; if (b->symbols->_nss_getgrgid_r.f == NULL) { return NULL; } if (!buf) { buf = (char *)malloc(buflen); } again: status = b->symbols->_nss_getgrgid_r.f(gid, &grp, buf, buflen, &errno); if (status == NSS_STATUS_TRYAGAIN) { buflen *= 2; buf = (char *)realloc(buf, buflen); if (!buf) { return NULL; } goto again; } if (status == NSS_STATUS_NOTFOUND) { SAFE_FREE(buf); return NULL; } if (status != NSS_STATUS_SUCCESS) { SAFE_FREE(buf); return NULL; } return &grp; } static int nwrap_module_getgrgid_r(struct nwrap_backend *b, gid_t gid, struct group *grdst, char *buf, size_t buflen, struct group **grdstp) { int ret; *grdstp = NULL; if (b->symbols->_nss_getgrgid_r.f == NULL) { return ENOENT; } ret = b->symbols->_nss_getgrgid_r.f(gid, grdst, buf, buflen, &errno); switch (ret) { case NSS_STATUS_SUCCESS: *grdstp = grdst; return 0; case NSS_STATUS_NOTFOUND: if (errno != 0) { return errno; } return ENOENT; case NSS_STATUS_TRYAGAIN: if (errno != 0) { return errno; } return ERANGE; default: if (errno != 0) { return errno; } return ret; } } static void nwrap_module_setgrent(struct nwrap_backend *b) { if (b->symbols->_nss_setgrent.f == NULL) { return; } b->symbols->_nss_setgrent.f(); } static struct group *nwrap_module_getgrent(struct nwrap_backend *b) { static struct group grp; static char *buf; static int buflen = 1024; NSS_STATUS status; if (b->symbols->_nss_getgrent_r.f == NULL) { return NULL; } if (!buf) { buf = (char *)malloc(buflen); } again: status = b->symbols->_nss_getgrent_r.f(&grp, buf, buflen, &errno); if (status == NSS_STATUS_TRYAGAIN) { buflen *= 2; buf = (char *)realloc(buf, buflen); if (!buf) { return NULL; } goto again; } if (status == NSS_STATUS_NOTFOUND) { SAFE_FREE(buf); return NULL; } if (status != NSS_STATUS_SUCCESS) { SAFE_FREE(buf); return NULL; } return &grp; } static int nwrap_module_getgrent_r(struct nwrap_backend *b, struct group *grdst, char *buf, size_t buflen, struct group **grdstp) { int ret; *grdstp = NULL; if (b->symbols->_nss_getgrent_r.f == NULL) { return ENOENT; } ret = b->symbols->_nss_getgrent_r.f(grdst, buf, buflen, &errno); switch (ret) { case NSS_STATUS_SUCCESS: *grdstp = grdst; return 0; case NSS_STATUS_NOTFOUND: if (errno != 0) { return errno; } return ENOENT; case NSS_STATUS_TRYAGAIN: if (errno != 0) { return errno; } return ERANGE; default: if (errno != 0) { return errno; } return ret; } } static void nwrap_module_endgrent(struct nwrap_backend *b) { if (b->symbols->_nss_endgrent.f == NULL) { return; } b->symbols->_nss_endgrent.f(); } static struct hostent *nwrap_module_gethostbyaddr(struct nwrap_backend *b, const void *addr, socklen_t len, int type) { static struct hostent he; static char *buf = NULL; static size_t buflen = 1000; NSS_STATUS status; if (b->symbols->_nss_gethostbyaddr_r.f == NULL) { return NULL; } if (buf == NULL) { buf = (char *)malloc(buflen); if (buf == NULL) { return NULL; } } again: status = b->symbols->_nss_gethostbyaddr_r.f(addr, len, type, &he, buf, buflen, &errno, &h_errno); if (status == NSS_STATUS_TRYAGAIN) { char *p = NULL; buflen *= 2; p = (char *)realloc(buf, buflen); if (p == NULL) { SAFE_FREE(buf); return NULL; } buf = p; goto again; } if (status == NSS_STATUS_NOTFOUND) { SAFE_FREE(buf); return NULL; } if (status != NSS_STATUS_SUCCESS) { SAFE_FREE(buf); return NULL; } return &he; } static int nwrap_module_gethostbyname2_r(struct nwrap_backend *b, const char *name, int af, struct hostent *hedst, char *buf, size_t buflen, struct hostent **hedstp) { NSS_STATUS status; *hedstp = NULL; if (b->symbols->_nss_gethostbyname2_r.f == NULL) { return ENOENT; } status = b->symbols->_nss_gethostbyname2_r.f(name, af, hedst, buf, buflen, &errno, &h_errno); switch (status) { case NSS_STATUS_SUCCESS: *hedstp = hedst; return 0; case NSS_STATUS_NOTFOUND: if (errno != 0) { return errno; } return ENOENT; case NSS_STATUS_TRYAGAIN: if (errno != 0) { return errno; } return ERANGE; default: if (errno != 0) { return errno; } return status; } } static struct hostent *nwrap_module_gethostbyname(struct nwrap_backend *b, const char *name) { static struct hostent he; static char *buf = NULL; static size_t buflen = 1000; NSS_STATUS status; if (b->symbols->_nss_gethostbyname2_r.f == NULL) { return NULL; } if (buf == NULL) { buf = (char *)malloc(buflen); if (buf == NULL) { return NULL; } } again: status = b->symbols->_nss_gethostbyname2_r.f(name, AF_UNSPEC, &he, buf, buflen, &errno, &h_errno); if (status == NSS_STATUS_TRYAGAIN) { char *p = NULL; buflen *= 2; p = (char *)realloc(buf, buflen); if (p == NULL) { SAFE_FREE(buf); return NULL; } buf = p; goto again; } if (status == NSS_STATUS_NOTFOUND) { SAFE_FREE(buf); return NULL; } if (status != NSS_STATUS_SUCCESS) { SAFE_FREE(buf); return NULL; } return &he; } static struct hostent *nwrap_module_gethostbyname2(struct nwrap_backend *b, const char *name, int af) { static struct hostent he; static char *buf = NULL; static size_t buflen = 1000; NSS_STATUS status; if (b->symbols->_nss_gethostbyname2_r.f == NULL) { return NULL; } if (buf == NULL) { buf = (char *)malloc(buflen); if (buf == NULL) { return NULL; } } again: status = b->symbols->_nss_gethostbyname2_r.f(name, af, &he, buf, buflen, &errno, &h_errno); if (status == NSS_STATUS_TRYAGAIN) { char *p = NULL; buflen *= 2; p = (char *)realloc(buf, buflen); if (p == NULL) { SAFE_FREE(buf); return NULL; } buf = p; goto again; } if (status == NSS_STATUS_NOTFOUND) { SAFE_FREE(buf); return NULL; } if (status != NSS_STATUS_SUCCESS) { SAFE_FREE(buf); return NULL; } return &he; } /**************************************************************************** * GETPWNAM ***************************************************************************/ static struct passwd *nwrap_getpwnam(const char *name) { size_t i; struct passwd *pwd; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; pwd = b->ops->nw_getpwnam(b, name); if (pwd) { return pwd; } } return NULL; } struct passwd *getpwnam(const char *name) { if (!nss_wrapper_enabled()) { return libc_getpwnam(name); } return nwrap_getpwnam(name); } /**************************************************************************** * GETPWNAM_R ***************************************************************************/ static int nwrap_getpwnam_r(const char *name, struct passwd *pwdst, char *buf, size_t buflen, struct passwd **pwdstp) { size_t i; int ret; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; ret = b->ops->nw_getpwnam_r(b, name, pwdst, buf, buflen, pwdstp); if (ret == ENOENT) { continue; } return ret; } return ENOENT; } #ifdef HAVE_GETPWNAM_R # ifdef HAVE_SOLARIS_GETPWNAM_R int getpwnam_r(const char *name, struct passwd *pwdst, char *buf, int buflen, struct passwd **pwdstp) # else /* HAVE_SOLARIS_GETPWNAM_R */ int getpwnam_r(const char *name, struct passwd *pwdst, char *buf, size_t buflen, struct passwd **pwdstp) # endif /* HAVE_SOLARIS_GETPWNAM_R */ { if (!nss_wrapper_enabled()) { return libc_getpwnam_r(name, pwdst, buf, buflen, pwdstp); } return nwrap_getpwnam_r(name, pwdst, buf, buflen, pwdstp); } #endif /**************************************************************************** * GETPWUID ***************************************************************************/ static struct passwd *nwrap_getpwuid(uid_t uid) { size_t i; struct passwd *pwd; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; pwd = b->ops->nw_getpwuid(b, uid); if (pwd) { return pwd; } } return NULL; } struct passwd *getpwuid(uid_t uid) { if (!nss_wrapper_enabled()) { return libc_getpwuid(uid); } return nwrap_getpwuid(uid); } /**************************************************************************** * GETPWUID_R ***************************************************************************/ static int nwrap_getpwuid_r(uid_t uid, struct passwd *pwdst, char *buf, size_t buflen, struct passwd **pwdstp) { size_t i; int ret; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; ret = b->ops->nw_getpwuid_r(b, uid, pwdst, buf, buflen, pwdstp); if (ret == ENOENT) { continue; } return ret; } return ENOENT; } #ifdef HAVE_SOLARIS_GETPWUID_R int getpwuid_r(uid_t uid, struct passwd *pwdst, char *buf, int buflen, struct passwd **pwdstp) #else int getpwuid_r(uid_t uid, struct passwd *pwdst, char *buf, size_t buflen, struct passwd **pwdstp) #endif { if (!nss_wrapper_enabled()) { return libc_getpwuid_r(uid, pwdst, buf, buflen, pwdstp); } return nwrap_getpwuid_r(uid, pwdst, buf, buflen, pwdstp); } /**************************************************************************** * SETPWENT ***************************************************************************/ static void nwrap_setpwent(void) { size_t i; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; b->ops->nw_setpwent(b); } } void setpwent(void) { if (!nss_wrapper_enabled()) { libc_setpwent(); return; } nwrap_setpwent(); } /**************************************************************************** * GETPWENT ***************************************************************************/ static struct passwd *nwrap_getpwent(void) { size_t i; struct passwd *pwd; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; pwd = b->ops->nw_getpwent(b); if (pwd) { return pwd; } } return NULL; } struct passwd *getpwent(void) { if (!nss_wrapper_enabled()) { return libc_getpwent(); } return nwrap_getpwent(); } /**************************************************************************** * GETPWENT_R ***************************************************************************/ #ifdef HAVE_GETPWENT_R static int nwrap_getpwent_r(struct passwd *pwdst, char *buf, size_t buflen, struct passwd **pwdstp) { size_t i; int ret; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; ret = b->ops->nw_getpwent_r(b, pwdst, buf, buflen, pwdstp); if (ret == ENOENT) { continue; } return ret; } return ENOENT; } # ifdef HAVE_SOLARIS_GETPWENT_R struct passwd *getpwent_r(struct passwd *pwdst, char *buf, int buflen) { struct passwd *pwdstp = NULL; int rc; if (!nss_wrapper_enabled()) { return libc_getpwent_r(pwdst, buf, buflen); } rc = nwrap_getpwent_r(pwdst, buf, buflen, &pwdstp); if (rc < 0) { return NULL; } return pwdstp; } # else /* HAVE_SOLARIS_GETPWENT_R */ int getpwent_r(struct passwd *pwdst, char *buf, size_t buflen, struct passwd **pwdstp) { if (!nss_wrapper_enabled()) { return libc_getpwent_r(pwdst, buf, buflen, pwdstp); } return nwrap_getpwent_r(pwdst, buf, buflen, pwdstp); } # endif /* HAVE_SOLARIS_GETPWENT_R */ #endif /* HAVE_GETPWENT_R */ /**************************************************************************** * ENDPWENT ***************************************************************************/ static void nwrap_endpwent(void) { size_t i; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; b->ops->nw_endpwent(b); } } void endpwent(void) { if (!nss_wrapper_enabled()) { libc_endpwent(); return; } nwrap_endpwent(); } /**************************************************************************** * INITGROUPS ***************************************************************************/ static int nwrap_initgroups(const char *user, gid_t group) { #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"); if (env == NULL || env[0] != '1') { NWRAP_LOG(NWRAP_LOG_WARN, "initgroups() requires uid_wrapper to work!"); return 0; } limit = sysconf(_SC_NGROUPS_MAX); if (limit > 0) { size = MIN(limit, 64); } else { size = 16; } 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) { if (!nss_wrapper_enabled()) { return libc_initgroups(user, group); } return nwrap_initgroups(user, group); } /**************************************************************************** * GETGRNAM ***************************************************************************/ static struct group *nwrap_getgrnam(const char *name) { size_t i; struct group *grp; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; grp = b->ops->nw_getgrnam(b, name); if (grp) { return grp; } } return NULL; } struct group *getgrnam(const char *name) { if (!nss_wrapper_enabled()) { return libc_getgrnam(name); } return nwrap_getgrnam(name); } /**************************************************************************** * GETGRNAM_R ***************************************************************************/ static int nwrap_getgrnam_r(const char *name, struct group *grdst, char *buf, size_t buflen, struct group **grdstp) { size_t i; int ret; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; ret = b->ops->nw_getgrnam_r(b, name, grdst, buf, buflen, grdstp); if (ret == ENOENT) { continue; } return ret; } return ENOENT; } #ifdef HAVE_GETGRNAM_R # ifdef HAVE_SOLARIS_GETGRNAM_R int getgrnam_r(const char *name, struct group *grp, char *buf, int buflen, struct group **pgrp) # else /* HAVE_SOLARIS_GETGRNAM_R */ int getgrnam_r(const char *name, struct group *grp, char *buf, size_t buflen, struct group **pgrp) # endif /* HAVE_SOLARIS_GETGRNAM_R */ { if (!nss_wrapper_enabled()) { return libc_getgrnam_r(name, grp, buf, buflen, pgrp); } return nwrap_getgrnam_r(name, grp, buf, buflen, pgrp); } #endif /* HAVE_GETGRNAM_R */ /**************************************************************************** * GETGRGID ***************************************************************************/ static struct group *nwrap_getgrgid(gid_t gid) { size_t i; struct group *grp; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; grp = b->ops->nw_getgrgid(b, gid); if (grp) { return grp; } } return NULL; } struct group *getgrgid(gid_t gid) { if (!nss_wrapper_enabled()) { return libc_getgrgid(gid); } return nwrap_getgrgid(gid); } /**************************************************************************** * GETGRGID_R ***************************************************************************/ static int nwrap_getgrgid_r(gid_t gid, struct group *grdst, char *buf, size_t buflen, struct group **grdstp) { size_t i; int ret; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; ret = b->ops->nw_getgrgid_r(b, gid, grdst, buf, buflen, grdstp); if (ret == ENOENT) { continue; } return ret; } return ENOENT; } #ifdef HAVE_GETGRGID_R # ifdef HAVE_SOLARIS_GETGRGID_R int getgrgid_r(gid_t gid, struct group *grdst, char *buf, int buflen, struct group **grdstp) # else /* HAVE_SOLARIS_GETGRGID_R */ int getgrgid_r(gid_t gid, struct group *grdst, char *buf, size_t buflen, struct group **grdstp) # endif /* HAVE_SOLARIS_GETGRGID_R */ { if (!nss_wrapper_enabled()) { return libc_getgrgid_r(gid, grdst, buf, buflen, grdstp); } return nwrap_getgrgid_r(gid, grdst, buf, buflen, grdstp); } #endif /**************************************************************************** * SETGRENT ***************************************************************************/ static void nwrap_setgrent(void) { size_t i; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; b->ops->nw_setgrent(b); } } #ifdef HAVE_BSD_SETGRENT int setgrent(void) #else void setgrent(void) #endif { if (!nss_wrapper_enabled()) { libc_setgrent(); goto out; } nwrap_setgrent(); out: #ifdef HAVE_BSD_SETGRENT return 0; #else return; #endif } /**************************************************************************** * GETGRENT ***************************************************************************/ static struct group *nwrap_getgrent(void) { size_t i; struct group *grp; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; grp = b->ops->nw_getgrent(b); if (grp) { return grp; } } return NULL; } struct group *getgrent(void) { if (!nss_wrapper_enabled()) { return libc_getgrent(); } return nwrap_getgrent(); } /**************************************************************************** * GETGRENT_R ***************************************************************************/ #ifdef HAVE_GETGRENT_R static int nwrap_getgrent_r(struct group *grdst, char *buf, size_t buflen, struct group **grdstp) { size_t i; int ret; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; ret = b->ops->nw_getgrent_r(b, grdst, buf, buflen, grdstp); if (ret == ENOENT) { continue; } return ret; } return ENOENT; } # ifdef HAVE_SOLARIS_GETGRENT_R struct group *getgrent_r(struct group *src, char *buf, int buflen) { struct group *grdstp = NULL; int rc; if (!nss_wrapper_enabled()) { return libc_getgrent_r(src, buf, buflen); } rc = nwrap_getgrent_r(src, buf, buflen, &grdstp); if (rc < 0) { return NULL; } return grdstp; } # else /* HAVE_SOLARIS_GETGRENT_R */ int getgrent_r(struct group *src, char *buf, size_t buflen, struct group **grdstp) { if (!nss_wrapper_enabled()) { return libc_getgrent_r(src, buf, buflen, grdstp); } return nwrap_getgrent_r(src, buf, buflen, grdstp); } # endif /* HAVE_SOLARIS_GETGRENT_R */ #endif /* HAVE_GETGRENT_R */ /**************************************************************************** * ENDGRENT ***************************************************************************/ static void nwrap_endgrent(void) { size_t i; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; b->ops->nw_endgrent(b); } } void endgrent(void) { if (!nss_wrapper_enabled()) { libc_endgrent(); return; } nwrap_endgrent(); } /**************************************************************************** * GETGROUPLIST ***************************************************************************/ #ifdef HAVE_GETGROUPLIST 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; /* Never store more than the starting *SIZE number of elements. */ assert(*size > 0); (*groupsp)[0] = group; 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; 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; 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; } int getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups) { long int size; int total, retval; gid_t *newgroups; if (!nss_wrapper_enabled()) { return libc_getgrouplist(user, group, groups, ngroups); } size = MAX(1, *ngroups); newgroups = (gid_t *)malloc(size * sizeof(gid_t)); if (newgroups == NULL) { return -1; } total = nwrap_getgrouplist(user, group, &size, &newgroups, -1); if (groups != NULL) { memcpy(groups, newgroups, MIN(*ngroups, total) * sizeof(gid_t)); } free(newgroups); retval = total > *ngroups ? -1 : total; *ngroups = total; return retval; } #endif /********************************************************** * SHADOW **********************************************************/ #if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) #ifdef HAVE_SETSPENT static void nwrap_setspent(void) { nwrap_files_setspent(); } void setspent(void) { if (!nss_wrapper_shadow_enabled()) { return; } nwrap_setspent(); } static struct spwd *nwrap_getspent(void) { return nwrap_files_getspent(); } struct spwd *getspent(void) { if (!nss_wrapper_shadow_enabled()) { return NULL; } return nwrap_getspent(); } static void nwrap_endspent(void) { nwrap_files_endspent(); } void endspent(void) { if (!nss_wrapper_shadow_enabled()) { return; } nwrap_endspent(); } #endif /* HAVE_SETSPENT */ static struct spwd *nwrap_getspnam(const char *name) { return nwrap_files_getspnam(name); } struct spwd *getspnam(const char *name) { if (!nss_wrapper_shadow_enabled()) { return NULL; } return nwrap_getspnam(name); } #endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */ /********************************************************** * NETDB **********************************************************/ static void nwrap_sethostent(int stayopen) { (void) stayopen; /* ignored */ nwrap_files_sethostent(); } #ifdef HAVE_SOLARIS_SETHOSTENT int sethostent(int stayopen) { if (!nss_wrapper_hosts_enabled()) { libc_sethostent(stayopen); return 0; } nwrap_sethostent(stayopen); return 0; } #else /* HAVE_SOLARIS_SETHOSTENT */ void sethostent(int stayopen) { if (!nss_wrapper_hosts_enabled()) { libc_sethostent(stayopen); return; } nwrap_sethostent(stayopen); } #endif /* HAVE_SOLARIS_SETHOSTENT */ static struct hostent *nwrap_gethostent(void) { return nwrap_files_gethostent(); } struct hostent *gethostent(void) { if (!nss_wrapper_hosts_enabled()) { return libc_gethostent(); } return nwrap_gethostent(); } static void nwrap_endhostent(void) { nwrap_files_endhostent(); } #ifdef HAVE_SOLARIS_ENDHOSTENT int endhostent(void) { if (!nss_wrapper_hosts_enabled()) { libc_endhostent(); return 0; } nwrap_endhostent(); return 0; } #else /* HAVE_SOLARIS_ENDHOSTENT */ void endhostent(void) { if (!nss_wrapper_hosts_enabled()) { libc_endhostent(); return; } nwrap_endhostent(); } #endif /* HAVE_SOLARIS_ENDHOSTENT */ #ifdef BSD /* BSD implementation stores data in thread local storage but GLIBC does not */ static __thread struct hostent user_he; static __thread struct nwrap_vector user_addrlist; #else static struct hostent user_he; static struct nwrap_vector user_addrlist; #endif /* BSD */ static struct hostent *nwrap_files_gethostbyname(struct nwrap_backend *b, const char *name) { int ret; (void) b; /* unused */ ret = nwrap_files_internal_gethostbyname(name, AF_UNSPEC, &user_he, &user_addrlist); if (ret == 0) { return &user_he; } return NULL; } static struct hostent *nwrap_gethostbyname(const char *name) { size_t i; struct hostent *he = NULL; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; he = b->ops->nw_gethostbyname(b, name); if (he != NULL) { return he; } } return NULL; } struct hostent *gethostbyname(const char *name) { if (!nss_wrapper_hosts_enabled()) { return libc_gethostbyname(name); } return nwrap_gethostbyname(name); } /* This is a GNU extension - Also can be found on BSD systems */ #ifdef HAVE_GETHOSTBYNAME2 #ifdef BSD /* BSD implementation stores data in thread local storage but GLIBC not */ static __thread struct hostent user_he2; static __thread struct nwrap_vector user_addrlist2; #else static struct hostent user_he2; static struct nwrap_vector user_addrlist2; #endif /* BSD */ static struct hostent *nwrap_files_gethostbyname2(struct nwrap_backend *b, const char *name, int af) { int ret; (void) b; /* unused */ ret = nwrap_files_internal_gethostbyname(name, af, &user_he2, &user_addrlist2); if (ret == 0) { return &user_he2; } return NULL; } static struct hostent *nwrap_gethostbyname2(const char *name, int af) { size_t i; struct hostent *he = NULL; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; he = b->ops->nw_gethostbyname2(b, name, af); if (he != NULL) { return he; } } return NULL; } struct hostent *gethostbyname2(const char *name, int af) { if (!nss_wrapper_hosts_enabled()) { return libc_gethostbyname2(name, af); } return nwrap_gethostbyname2(name, af); } #endif static struct hostent *nwrap_gethostbyaddr(const void *addr, socklen_t len, int type) { size_t i; struct hostent *he = NULL; for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; he = b->ops->nw_gethostbyaddr(b, addr, len, type); if (he != NULL) { return he; } } return NULL; } struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type) { if (!nss_wrapper_hosts_enabled()) { return libc_gethostbyaddr(addr, len, type); } return nwrap_gethostbyaddr(addr, len, type); } static const struct addrinfo default_hints = { .ai_flags = AI_ADDRCONFIG|AI_V4MAPPED, .ai_family = AF_UNSPEC, .ai_socktype = 0, .ai_protocol = 0, .ai_addrlen = 0, .ai_addr = NULL, .ai_canonname = NULL, .ai_next = NULL }; static int nwrap_convert_he_ai(const struct hostent *he, unsigned short port, const struct addrinfo *hints, struct addrinfo **pai, bool skip_canonname) { struct addrinfo *ai; socklen_t socklen; if (he == NULL) { return EAI_MEMORY; } switch (he->h_addrtype) { case AF_INET: socklen = sizeof(struct sockaddr_in); break; #ifdef HAVE_IPV6 case AF_INET6: socklen = sizeof(struct sockaddr_in6); break; #endif default: return EAI_FAMILY; } ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) + socklen); if (ai == NULL) { return EAI_MEMORY; } ai->ai_flags = hints->ai_flags; ai->ai_family = he->h_addrtype; ai->ai_socktype = hints->ai_socktype; ai->ai_protocol = hints->ai_protocol; ai->ai_canonname = NULL; if (ai->ai_socktype == 0) { ai->ai_socktype = SOCK_DGRAM; } if (ai->ai_protocol == 0) { if (ai->ai_socktype == SOCK_DGRAM) { ai->ai_protocol = IPPROTO_UDP; } else if (ai->ai_socktype == SOCK_STREAM) { ai->ai_protocol = IPPROTO_TCP; } } ai->ai_addrlen = socklen; ai->ai_addr = (void *)(ai + 1); #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN ai->ai_addr->sa_len = socklen; #endif ai->ai_addr->sa_family = he->h_addrtype; switch (he->h_addrtype) { case AF_INET: { union { struct sockaddr *sa; struct sockaddr_in *in; } addr; addr.sa = ai->ai_addr; memset(addr.in, 0, sizeof(struct sockaddr_in)); addr.in->sin_port = htons(port); addr.in->sin_family = AF_INET; memset(addr.in->sin_zero, '\0', sizeof (addr.in->sin_zero)); memcpy(&(addr.in->sin_addr), he->h_addr_list[0], he->h_length); } break; #ifdef HAVE_IPV6 case AF_INET6: { union { struct sockaddr *sa; struct sockaddr_in6 *in6; } addr; addr.sa = ai->ai_addr; memset(addr.in6, 0, sizeof(struct sockaddr_in6)); addr.in6->sin6_port = htons(port); addr.in6->sin6_family = AF_INET6; memcpy(&addr.in6->sin6_addr, he->h_addr_list[0], he->h_length); } break; #endif } ai->ai_next = NULL; if (he->h_name && !skip_canonname) { ai->ai_canonname = strdup(he->h_name); if (ai->ai_canonname == NULL) { freeaddrinfo(ai); return EAI_MEMORY; } } *pai = ai; return 0; } static int nwrap_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { struct addrinfo *ai = NULL; unsigned short port = 0; struct { int family; union { struct in_addr v4; #ifdef HAVE_IPV6 struct in6_addr v6; } in; #endif } addr = { .family = AF_UNSPEC, }; int rc; if (node == NULL && service == NULL) { return EAI_NONAME; } if (hints == NULL) { hints = &default_hints; } /* EAI_BADFLAGS hints.ai_flags contains invalid flags; or, hints.ai_flags included AI_CANONNAME and name was NULL. */ if ((hints->ai_flags & AI_CANONNAME) && (node == NULL)) { return EAI_BADFLAGS; } /* If no node has been specified, let glibc deal with it */ if (node == NULL) { int ret; struct addrinfo *p = NULL; ret = libc_getaddrinfo(node, service, hints, &p); if (ret == 0) { *res = p; } return ret; } if (service != NULL && service[0] != '\0') { const char *proto = NULL; struct servent *s; char *end_ptr; long sl; errno = 0; sl = strtol(service, &end_ptr, 10); if (*end_ptr == '\0') { port = sl; goto valid_port; } else if (hints->ai_flags & AI_NUMERICSERV) { return EAI_NONAME; } if (hints->ai_protocol != 0) { struct protoent *pent; pent = getprotobynumber(hints->ai_protocol); if (pent != NULL) { proto = pent->p_name; } } s = getservbyname(service, proto); if (s == NULL) { return EAI_NONAME; } port = ntohs(s->s_port); } valid_port: rc = inet_pton(AF_INET, node, &addr.in.v4); if (rc == 1) { addr.family = AF_INET; } #ifdef HAVE_IPV6 if (addr.family == AF_UNSPEC) { rc = inet_pton(AF_INET6, node, &addr.in.v6); if (rc == 1) { addr.family = AF_INET6; } } #endif if (addr.family == AF_UNSPEC) { if (hints->ai_flags & AI_NUMERICHOST) { return EAI_NONAME; } } else if ((hints->ai_family != AF_UNSPEC) && (hints->ai_family != addr.family)) { return EAI_ADDRFAMILY; } rc = nwrap_files_getaddrinfo(node, port, hints, &ai); if (rc != 0) { int ret; struct addrinfo *p = NULL; ret = libc_getaddrinfo(node, service, hints, &p); if (ret == 0) { /* * nwrap_files_getaddrinfo failed, but libc was * successful -- use the result from libc. */ *res = p; return 0; } return rc; } /* * If the socktype was not specified, duplicate * each ai returned, so that we have variants for * both UDP and TCP. */ if (hints->ai_socktype == 0) { struct addrinfo *ai_cur; /* freeaddrinfo() frees ai_canonname and ai so allocate them */ for (ai_cur = ai; ai_cur != NULL; ai_cur = ai_cur->ai_next) { struct addrinfo *ai_new; /* duplicate the current entry */ ai_new = malloc(sizeof(struct addrinfo)); if (ai_new == NULL) { freeaddrinfo(ai); return EAI_MEMORY; } memcpy(ai_new, ai_cur, sizeof(struct addrinfo)); ai_new->ai_next = NULL; /* We need a deep copy or freeaddrinfo() will blow up */ if (ai_cur->ai_canonname != NULL) { ai_new->ai_canonname = strdup(ai_cur->ai_canonname); } if (ai_cur->ai_socktype == SOCK_DGRAM) { ai_new->ai_socktype = SOCK_STREAM; } else if (ai_cur->ai_socktype == SOCK_STREAM) { ai_new->ai_socktype = SOCK_DGRAM; } if (ai_cur->ai_protocol == IPPROTO_TCP) { ai_new->ai_protocol = IPPROTO_UDP; } else if (ai_cur->ai_protocol == IPPROTO_UDP) { ai_new->ai_protocol = IPPROTO_TCP; } /* now insert the new entry */ ai_new->ai_next = ai_cur->ai_next; ai_cur->ai_next = ai_new; /* and move on (don't duplicate the new entry) */ ai_cur = ai_new; } } *res = ai; return 0; } int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { if (!nss_wrapper_hosts_enabled()) { return libc_getaddrinfo(node, service, hints, res); } return nwrap_getaddrinfo(node, service, hints, res); } static int nwrap_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) { struct hostent *he; struct servent *service; const char *proto; const void *addr; socklen_t addrlen; uint16_t port; sa_family_t type; size_t i; if (sa == NULL || salen < sizeof(sa_family_t)) { return EAI_FAMILY; } if ((flags & NI_NAMEREQD) && host == NULL && serv == NULL) { return EAI_NONAME; } type = sa->sa_family; switch (type) { case AF_INET: { union { const struct sockaddr *sa; const struct sockaddr_in *in; } a; if (salen < sizeof(struct sockaddr_in)) { return EAI_FAMILY; } a.sa = sa; addr = &(a.in->sin_addr); addrlen = sizeof(a.in->sin_addr); port = ntohs(a.in->sin_port); break; } #ifdef HAVE_IPV6 case AF_INET6: { union { const struct sockaddr *sa; const struct sockaddr_in6 *in6; } a; if (salen < sizeof(struct sockaddr_in6)) { return EAI_FAMILY; } a.sa = sa; addr = &(a.in6->sin6_addr); addrlen = sizeof(a.in6->sin6_addr); port = ntohs(a.in6->sin6_port); break; } #endif default: return EAI_FAMILY; } if (host != NULL) { he = NULL; if ((flags & NI_NUMERICHOST) == 0) { for (i=0; i < nwrap_main_global->num_backends; i++) { struct nwrap_backend *b = &nwrap_main_global->backends[i]; he = b->ops->nw_gethostbyaddr(b, addr, addrlen, type); if (he != NULL) { break; } } if ((flags & NI_NAMEREQD) && (he == NULL || he->h_name == NULL)) return EAI_NONAME; } if (he != NULL && he->h_name != NULL) { if (strlen(he->h_name) >= hostlen) return EAI_OVERFLOW; snprintf(host, hostlen, "%s", he->h_name); if (flags & NI_NOFQDN) host[strcspn(host, ".")] = '\0'; } else { if (inet_ntop(type, addr, host, hostlen) == NULL) return (errno == ENOSPC) ? EAI_OVERFLOW : EAI_FAIL; } } if (serv != NULL) { service = NULL; if ((flags & NI_NUMERICSERV) == 0) { proto = (flags & NI_DGRAM) ? "udp" : "tcp"; service = getservbyport(htons(port), proto); } if (service != NULL) { if (strlen(service->s_name) >= servlen) return EAI_OVERFLOW; snprintf(serv, servlen, "%s", service->s_name); } else { if (snprintf(serv, servlen, "%u", port) >= (int) servlen) return EAI_OVERFLOW; } } return 0; } #ifdef HAVE_LINUX_GETNAMEINFO int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags) #elif defined(HAVE_LINUX_GETNAMEINFO_UNSIGNED) int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, unsigned int flags) #else int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) #endif { if (!nss_wrapper_hosts_enabled()) { return libc_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); } return nwrap_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); } static int nwrap_gethostname(char *name, size_t len) { const char *hostname = getenv("NSS_WRAPPER_HOSTNAME"); if (strlen(hostname) >= len) { errno = ENAMETOOLONG; return -1; } snprintf(name, len, "%s", hostname); return 0; } #ifdef HAVE_SOLARIS_GETHOSTNAME int gethostname(char *name, int len) #else /* HAVE_SOLARIS_GETHOSTNAME */ int gethostname(char *name, size_t len) #endif /* HAVE_SOLARIS_GETHOSTNAME */ { if (!nwrap_hostname_enabled()) { return libc_gethostname(name, len); } return nwrap_gethostname(name, len); } static void nwrap_thread_prepare(void) { nwrap_init(); NWRAP_LOCK_ALL; } static void nwrap_thread_parent(void) { NWRAP_UNLOCK_ALL; } static void nwrap_thread_child(void) { NWRAP_REINIT_ALL; } /**************************** * CONSTRUCTOR ***************************/ void nwrap_constructor(void) { NWRAP_REINIT_ALL; /* * If we hold a lock and the application forks, then the child * is not able to unlock the mutex and we are in a deadlock. * * Setting these handlers should prevent such deadlocks. */ pthread_atfork(&nwrap_thread_prepare, &nwrap_thread_parent, &nwrap_thread_child); /* Do not call nwrap_init() here. */ } /**************************** * DESTRUCTOR ***************************/ /* * This function is called when the library is unloaded and makes sure that * sockets get closed and the unix file for the socket are unlinked. */ void nwrap_destructor(void) { size_t i; NWRAP_LOCK_ALL; if (nwrap_main_global != NULL) { struct nwrap_main *m = nwrap_main_global; /* libc */ if (m->libc != 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 #ifdef RTLD_NEXT && m->libc->nsl_handle != RTLD_NEXT #endif ) { dlclose(m->libc->nsl_handle); } 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); } /* backends */ if (m->backends != NULL) { for (i = 0; i < m->num_backends; i++) { struct nwrap_backend *b = &(m->backends[i]); if (b->so_handle != NULL) { dlclose(b->so_handle); } SAFE_FREE(b->symbols); } SAFE_FREE(m->backends); } } if (nwrap_pw_global.cache != NULL) { struct nwrap_cache *c = nwrap_pw_global.cache; nwrap_files_cache_unload(c); if (c->fd >= 0) { fclose(c->fp); c->fd = -1; } SAFE_FREE(nwrap_pw_global.list); nwrap_pw_global.num = 0; } if (nwrap_gr_global.cache != NULL) { struct nwrap_cache *c = nwrap_gr_global.cache; nwrap_files_cache_unload(c); if (c->fd >= 0) { fclose(c->fp); c->fd = -1; } SAFE_FREE(nwrap_gr_global.list); nwrap_gr_global.num = 0; } #if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) if (nwrap_sp_global.cache != NULL) { struct nwrap_cache *c = nwrap_sp_global.cache; nwrap_files_cache_unload(c); if (c->fd >= 0) { fclose(c->fp); c->fd = -1; } nwrap_sp_global.num = 0; } #endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */ if (nwrap_he_global.cache != NULL) { struct nwrap_cache *c = nwrap_he_global.cache; nwrap_files_cache_unload(c); if (c->fd >= 0) { fclose(c->fp); c->fd = -1; } nwrap_he_global.num = 0; } free(user_addrlist.items); #ifdef HAVE_GETHOSTBYNAME2 free(user_addrlist2.items); #endif hdestroy(); NWRAP_UNLOCK_ALL; } nss_wrapper-1.1.16/src/nss_utils.h000644 001750 000144 00000004011 14460666462 017120 0ustar00asnusers000000 000000 /* * BSD 3-Clause License * * Copyright (c) 2007, Stefan Metzmacher * Copyright (c) 2009, Guenther Deschner * Copyright (c) 2014-2015, Michael Adam * Copyright (c) 2015, Robin Hack * Copyright (c) 2013-2018, Andreas Schneider * 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 int nwrap_gr_copy_r(const struct group *src, struct group *dst, char *buf, size_t buflen, struct group **dstp); #endif //NSS_UTILS_H nss_wrapper-1.1.16/src/nss_utils.c000644 001750 000144 00000007042 14460666462 017122 0ustar00asnusers000000 000000 /* * BSD 3-Clause License * * Copyright (c) 2007, Stefan Metzmacher * Copyright (c) 2009, Guenther Deschner * Copyright (c) 2014-2015, Michael Adam * Copyright (c) 2015, Robin Hack * Copyright (c) 2013-2018, Andreas Schneider * 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 #include #include #include #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; } nss_wrapper-1.1.16/README.md000644 001750 000144 00000000731 13634203624 015406 0ustar00asnusers000000 000000 NSS_WRAPPER =========== This is a wrapper for the user, group and hosts NSS API. DESCRIPTION ----------- More details can be found in the manpage: man -l ./doc/nss_wrapper.1 or the raw text version: less ./doc/nss_wrapper.1.txt For installation instructions please take a look at the README.install file. MAILINGLIST ----------- As the mailing list samba-technical is used and can be found here: * https://lists.samba.org/mailman/listinfo/samba-technical nss_wrapper-1.1.16/17.patch000644 001750 000144 00000002513 14464661003 015400 0ustar00asnusers000000 000000 From dbfc9e2c2f53041e10b470ed29cab9af784ae00b Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Thu, 10 Nov 2022 18:38:17 +0000 Subject: [PATCH] Avoid dclose(RTLD_NEXT) In case the libc was not found and RTLD_NEXT is used instead, we should not dlclose it, otherwise mayhem happens. Signed-off-by: Samuel Thibault https://bugzilla.samba.org/show_bug.cgi?id=15228 --- src/nss_wrapper.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/nss_wrapper.c b/src/nss_wrapper.c index 07c9757..b95afdf 100644 --- a/src/nss_wrapper.c +++ b/src/nss_wrapper.c @@ -6499,13 +6499,25 @@ void nwrap_destructor(void) /* 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); -- GitLab nss_wrapper-1.1.16/.cache/000750 001750 000144 00000000000 14641730071 015242 5ustar00asnusers000000 000000 nss_wrapper-1.1.16/.cache/clangd/000750 001750 000144 00000000000 14641730071 016472 5ustar00asnusers000000 000000 nss_wrapper-1.1.16/.cache/clangd/index/000750 001750 000144 00000000000 14641730071 017601 5ustar00asnusers000000 000000 nss_wrapper-1.1.16/.cache/clangd/index/test_gethostent.c.FDE119456A174D8F.idx000644 001750 000144 00000003032 14460665461 025715 0ustar00asnusers000000 000000 RIFFCdIxmetastrixRk@ rlBr'ۗ'# _?M III2eӯ޻ p; \K 2@mnwW _C:o,שjO^f ,^,"$N!-Z ;* Ƌe%9S^%c cRC'uu9$I q؞l3xS*®56Yɗ-3Sg 5r047xi+/3wE`lxgYMӯu%q5TS~o4Vh.; `c\7ʥpcenouG=|7%H,zY`I۔]÷T[K^)ٹE*W%uz+)ZZIi>4~!]e`].%%&\\Sc! :- !- !W{ 9-22-22refsY?N"X -"" \Sc!\Sc! - ! -66(W{VF  -55W{Ђ X,-\Sc!-\Sc!4= yZ-\Sc!-\Sc!9)'` -66G!' -\Sc!+}E-99W{3DܖPG -99Z,g@w -""\Sc!W{ -223n7xĐ -!\Sc! -\Sc! -##\Sc!7 M̦ -// \Sc!}pʹ -# -$( -)#)' -9$9( -9*9.8S袹 - \Sc!46MQ - \Sc! -*4\Sc!N(og -\Sc! -))\Sc! -**'\Sc!Nb{O -  < - \Sc! - \Sc!+V-\Sc!-\Sc!ѢF  - -:w -'' \Sc! -** \Sc!relasrcs,-: I ,782/34651.00/2846517.3cmdl,(**$ '     !#"%+&)nss_wrapper-1.1.16/.cache/clangd/index/nss_wrapper.c.496306141B70693D.idx000644 001750 000144 00000334742 14547751205 024743 0ustar00asnusers000000 000000 RIFFڹCdIxmetastri Ex[oFgPm`EKMܜqm~bWJbCry\ҊR~3(wS\Df3")%_}7GY.O_'t~!cC>(%p1TrXaYl`h'xώxfh#y Bp [EN(mHM% #5:紻)s5C>(Y1RvnjZRU$\-af=>tǃþMFa]Gn5lLۅoa?YZ \x8f?<{jSXQ=FD x^V30 6hH~Ё4!#gU' +(1ĸ(!w-M6R}';񁺚<4~#dvLw{ۈ?cb YKYOR$hK/$v5KƹSր}n&Ldx?z,'{Z[BSo/E4k ϘUL:r0Kh^w m =JLxE u#FR[f}% kjj0cYMVR)(F~ Nѓñyg_B|_efWo/_pm;ҶN~8J構 fe{ޒ.ڎN/) 3E G >s9uDAt/Y3'vs8pceݼ۪~\fQ/;)熾/VI?4eG01hGkg3g7[Ul`Q)/ia-D8YX)E7k.9 >ҎB!_AW5!9:yٯ.N_'ȓc[qpH|#VGQ0 SR?ʮ_x_S>Cvc ܐ6Ì)!,D|OYa9XBլ9 dVBv7xJg?|'tjjB [##kAD r 7Āu3b*|vn|:ִ^BN3P6/^|&?ʮ^%g./7?/Ϯތ\kuǷ-Ң/wǗg .q:B p:%\bN |=#)l )C5O.W)߯əX#ZLT`Sؑ)t+<7`7 r׃0Z&k#{CUAl@z#Ձ[Sȇ 439sFrr k%hp` *},?![W4AoJI`]KZg}Е,&J;j,>h⺻z@SJ5\pٖqӳ8TPq=\N6۰"|&AaYo0Wm"\Wt~ k?`G+h?Xr.^2>td2VmyÎPªg*CʛeU3kl-ZQvkkW,suY7UPEYѣaX"] 턤g7ߴvVnU zOe΋Q2|my"msЧk-#r boQiFb(R[F |؞-^*R1.Iٺ?zo P[*/>/B/)UzIӚ'Xc;, ++{+;UѶ*UŚxOm*h~mnm^mNo>o.319|PM}}r$A p6rdYC3p4CYנЙk洮 ro}->LM{`Շ%-vq yQ*ytedBd_ɓ=_bݹfW%FHbnL/QPoE oXW~QPif2| 4:"u6iK5[WQh]smW#Eݻ0m h%A;{x,#4cce܄`8։ p+WDАN&jcn!4٘-8zn``lV/m=c-whsى9Y^c.9SFN/anC-CEk¯AMOaTĶn>y[glߒc IuN?hof֒ s)1V}gvV~6[jF@?;@r(b9vk iXS+d8h\oDe7.@ֺ4j"8 CS<4:zt]ϲ3:Nj6 n"vrC]ZHP;o WW&{ːa,ƚQ.2X45-4hǯ 7A~̉66AIޚ #+o]x4'6 0WR|囲*\EXGV vIy%)zq|࢖)ݚ&3*< %P ,,r4?y,  0 0vUhz~1ڱU a-{D@1Z_>_ **#**#1K<   ! !cA  \A8 k"   ;ў * ** *9?* 2 22 2jɑ^-aLL ..[s[  cWGk aw  ! ! i`  **EM (((N      ''$''$ |~   1duOd!  {vX"  * *䩃"  eE#Vh# **b5###lm$ --'--'H$  ! !ۑˆ$YbxVR% rY% ' '' ']jtZ%  ''x%  ' '(O`,&    T'  MX>Ci'*7w'  k( ! !"! !"M( %%tT ( ..*..*8w(P$R)  &<@Y)    ]Ys) $ $! !Y@hy1+  eRxU+  ! !_5”+  {6~, ** < < p~$P4,   b, !!  &W-,   蒐~-;92x-ӥ(-  c^]z-  JA. &&11̤/##~ /l/  6%h.\0)0ybBٯ0 $ $" "ad1 xf^01    z 2   u']^4   ֟l6Oh7 --*--*HxO'8 (( G G qsڑf8* 8  yXGLh:w#K_z:1y:   ڇ< ..$ %olij< / // /jDž$h=   ZIN> ,,qY>  % %͋x?  " "g%eyV%@   t-@ #!E@   Ekm[@ **;W @ ((Har@CSA"" ($Ad8V?'A 2 22 209B # #" "BxiB  iDFQC   eD  ϰR$ E }   E &&KcE   Iq"eG  ћ G  #'H  hBH  Q2]I %%*ĴIJ&#ӼIL'oIJ J   ^&*J  ^J  K L  g>M꒺fCM ++v#y(O ( (( (Dw] XP %%یֹrP % %! !WNPEP5w8Q  ( (' 5RQ ..X?Q   #  #u z%Q   ʿR򚰅gR^)|8hSB`^ US      &ݒT^35dTȉ9T **dd r(߷!dU " "" "pH䕴U ((  )uw,V  b}=JESX   tQY  my/Y¤YeeI!Z <\A-Q\   siUs\ - -- -z!]WQ] ))qלIq]  qEf] **ZG/^ $$**fZ^ ( (( (4;^   )  )x2_   5Ϥ_    _   #  #l63P`  ! !qb=`|Gt5`3R\<a?8,)a   Vm+b +Ly!c dK;c ( (( ()|Pd **#**#'GdeD@e ))#))#j^_we*g_}fg  ʣ2\h  ժQh   h'ii   *  *_\-i    A0j~GɈj„Ak  I Dl ##gB l ((3)n    @o    'LE|    ֑+ I|  /.}  ` } " "" "E[_ }  v * ,,wx|  #    xc7BY  Uyjh     u E     ÿnX ) )) )}=Gс   )  )]NQZ ##VX,sVt]=B6  &k b   | ^]]"]]"MȋLTM+J#$SG ++HH i9qĖ1k X  - - - ]rI֌ VX5W --$ m.>p=J~ ~''0::j %%11̆E;G ))h5Fm' %%'kw g   ~:Hm  ߐ}+r z:"j!0    oPnz@ + ++ +-?$  8 2 2 2 2 %Tݺ   ꡛm8 ))  " ]ĵ ''mm kO9d> %%VU:  " "b݉5 Ӿ!   `6lU> ,,",,"J   #d ''46MQ --! [+##n4  " "ˮ"{ !!_> 00  wHgUe # #! !ߡS6(T F  ! !$5wr ##؞a " !!++w^&  Q dW 2 22 2kjr+X6  ;>x~U ..11XTl ''  7f@ c>@3! ..+..+x`   &  &'R  b5Zq # #& &` U諓jx  gL|     6@  (<E   Z3 (( HO  Mdd 4 &&22ܦ&Q ))+k  6Nȭf , ,QQ Z@   gE/>~ ))xMwr   aY + + !%d.k ''$''$s  $ $9x譗   "  " C  *Q ,,˲~fQ0!$ ##^0a ++ B B XfY0a  ! !#X9    >   g#ՁZ !!9O@,c׀x__ BL  si#z **  re [>&zzFB --001X5 * ** *6[ $$ٞsM 1 11 1qL . . >nG , ,YY \Q=W?   "  "5n>K  n #}l ##**ϖ  ;FԵm , ,, ,ݷ,wn.b">G ))   sf<N 22V     R5yYb~ 3 !!-!!-NF ,,GP } ''  ! \Tx UdE 6?4(     ɵ7   [;4   j ++fwTMO'j b1      t   շ= **.x" C ?'$   G}H   >  >  >RC$ $:*Mz  <\A-Q\ <\A-Q\ ##n #}l $$ZG/^ $$Lz %%0::j &&JA. && 4 ))ÿnX ,,du? ..qL 0 0lij~  gE/>~ ',Dw] XP      *ĴI  [g7  qY>  qY>  f  ^8N  ZG/^  ybBٯ0  b5Zq  b5Zq  aY  aY  - 2xMwr  # (J   ɵ7   ,՞*j   ,՞*j (<E >  qY>  qY>  qY> qY>  f  ^8N # #b5Zq # #b5Zq $$ ZG/^ $$ ybBٯ0 ).)3ÿnX ))ÿnX ) )ÿnX )()-ÿnX )!)& ꡛm8 *$*)Z_>_ **ȉ9T **!1X5 **si#z + +aY + +aY ,#,(du? ,0,5du? ,,du? ,,du? ,+,0du? ,:,?du?\ c| $s֮ Z   #hs  #hs ɴ/       Y?N"X  <\A-Q\  <\A-Q\ '1k X '1k X  ͋x? ! !kb׫ . .qL ..qL //(qL / /qL$Zܰ> vvYJW  (<E -5(<E "*(<E  z 2 z 2 z 2xJ  " )g#ՁZ % %"\( 1.16VUO6+ */Z3 !&]rI֌ ',űP  WElar  m'p  qEf]  H$  A Yu  (߷!dU  $ ).iu=   q47 (<E  qEf]  H$ " "A Yu "" (߷!dU '%'*  ''ĵ ''! ''XTl˻űP %f^01BeX   J J  {vX"u z!]  $ /n4 22f<N 22f<N 22 f<NΘp8 ""` } ""(߷!dU ##;? ##"n #}l $$09B $$"ZG/^ $$ybBٯ0 $$"Lz %%xJ %%"0::j &&դ\ &&"JA. &&" 4Ҿp}SB  !   X?Q   b}=JESX   .iu=   q47   @    _   u z%Q   t   xMwr   9x譗   Qv3   J   ɵ7   <‗   ?   'j b1   !+,q   ,՞*j   ժQh   x`   'kw g   4;^   g>i   jDž$h=   }=Gс   KcE   C ?'$   iDFQC   fp   4s剕  !e([2  3ThcWGk  #!#"" `C #&#'" `C #!#";? ###$;?v*  # # G  //qL 11ٞsM 11!ٞsM _Ú  ..&qL / /qL /$//qL 11ٞsM 11'ٞsM3k"  '' h:  -- -<-C&zzFB - -&zzFB X]  11 ٞsM 1"1-ٞsMev  .14| 9q<  # %P , )#hs r4?y,  0 +YǶ*vG   ++vUhz~ oP  <\A-Q\  1y: !,!/~ 3 33f<N1ڱU  #hs  #hs  #hs  #hs  #hs  (7#hs  #hs  #hs  ׀x__ ׀x__ .̆E;G  ̆E;G  ̆E;G  ̆E;G ̆E;G .f  f f  f f '. ܦ&Q  /ܦ&Q ܦ&Q +ܦ&Q ܦ&Q +ܦ&Q k ?hro 33f<N 33)f<N 3 3f<Nt{-      a-{_ **# **ȉ9T1K<   ! (u']^4  !ci  5w8QA22f<N;ў * * **{6~,9?* 2 2 22OA_ض-   n4 11 ٞsM 11 ٞsM 11ٞsM 22 9?*z     k"   (O`,&jɑ^ 蒐~- :*Mz r4?y,  r4?y,  1k X %'1k X  ͋x?4= yZ  +Ly!c  ]rI֌  YbxVR%  eeI!Z  \A8  ϰR$ E  M(  5Ϥ_  5Ϥ_ .4 #!E@ 1+@sea  6[  ^T#CK  űP  Q2]I  O9d>  Dw] XP  h5Fm'  շ=  j M+J# m'p  ݷ, 򚰅gR [g7  |Gt5` wn. (T F H$  fY0a 1K<  ^8N  eRxU+ ''x%  ;? ` } (߷!dU  xJ 09B ybBٯ0 դ\ ;92x-   c>@ [;4  \Tx   ?8,)a   b}=JESX   q47   u z%Q   Qv3   ɵ7   'j b1   jDž$h=  ( .KcE   C ?'$   iDFQC   4s剕   4s剕  pr pr #hs  #hs  q)/~y (<E z 2 gLxU > > 1y: (T F H$  fY0a 1K<  ^8N  eRxU+ 1k X ''x% gL| gL| &k b aw aw   e]’   ͋x? !!kb׫ !!%szB !!%szB !! b, ""` } ""(߷!dU ## ;? ##09B $$ybBٯ0 %% xJ %%0::j %%դ\ &&JA. && 4 ''!%d.k ''rY% ''rY% '' } ''  '' '' ''XTl ((dK;c ((&7';TK (( fZ^ ((fZ^ ((pH䕴U ((v#y(O ))D@e ))ms'y ))ms'y ))b">G **Z_>_ **1X5 **1X5 **si#z **;ў **)|Pd ++ nz@ ++nz@ ++{ ++3l ++aY --Oh7 ..3! ..tT ( 11ٞsM 11ٞsM 11ٞsM 2)2/9?* 22"OA_ض 22f<N-aLL . *#hs  -#hs  ,#hs 22N>228V?'A22Q dW22Wѓ22f<N33f<N[s[  #>  >  |~   |~  ̆E;G  f ,/ܦ&Qө& -R $~ u']^4 g#ՁZ .. 3!oeWa   <\A-Q\m        / / 0 0 0 0 0 0 1 1 1 1&7';TK (($ ((~#^n{`(TWi(N    !0#hs     ''$ ''ĵ |~   !0#hs   q m!  ͋x? .. yY // qL 050 Dw] XP .3h5Fm'  Uw* $򚰅gR ',򚰅gR  *ĴI [g7 ',[g7  8w(  |Gt5` !|Gt5` ̆E;G $1K<  ',1K<  f ^8N ',^8N ܦ&Q  eRxU+ !eRxU+ Lz xJ "xJ n #}l  %09B (-09B ZG/^ ybBٯ0 (-ybBٯ0  ~GɈj   9x譗  Qv3  Qv3   J  ɵ7  ɵ7   ?  " ''j b1  'j b1  > >  qY> ̆E;G $1K<  ',1K<   1K<  f ^8N ',^8N  ^8N ܦ&Q  ܦ&Q  eRxU+ !eRxU+  eRxU+ ##n #}l ##n #}l # #%09B #(#-09B $$ZG/^ $$ZG/^ $$ybBٯ0 $($-ybBٯ0 $$Lz $$Lz %%xJ %%"xJ ))D@e )) D@e )) v )5):ms'y )()-ms'y )()-b">G ))).b">G **Z_>_ ** Z_>_ ** ȉ9T *.*31X5 *(*-1X5 *!*&si#z *)*.si#z **)|Pd ** )|Pd ++ $SG +#+(nz@ ++"nz@ ++{ ++#{$ЌZ.8# 11(WS# / /qLVh# * $u']^4 * fY0a܉b5# #6%h.\0 "0<\A-Q\ -;<\A-Q\ 1y: )71k X;Xhlo# # # zz    0 0lm$ --' --46MQH$  ! (u']^4  !ۑˆ$Ci' ~  u']^4  g#ՁZ ((&7';TK*7w'  ֟l6 #hs  #hs  #hs  #hs  q)/~y "$q)/~y q)/~y q)/~y   s  s s s   s s   s s   s 3 3f<N 3 3f<N 3 3f<N 3 3f<NG!'V H;7W 3%t %LЃ M( M( ' 5RQ 1+@sea 1+@sea 6[ 6[ շ= j ̤/ + & -R wn. wn. kb׫ &zzFB >x~U  ''x%  ''x% 0::j JA.  4  դ\  դ\ ,3qL ],N9   x`   4;^   g>i  jDž$h=  jDž$h=   }=Gс  C ?'$  C ?'$  iDFQC  iDFQC 1k X 1k X $+1k X  ''x%  ''x%  gL|  gL|  &k b  &k b  aw  aw   e]’   e]’   ͋x?   kb׫ !!kb׫ ! !%szB ! !%szB ! ! b, ! ! b, !!~ 3 !!~ 3 %%0::j %%0::j % %դ\ % %դ\ &&JA. &&JA. && 4 && 4 --lm$ --46MQ -- h: --&zzFB --Oh7 --Oh7 --VX5W --^/OIU ..>x~U ..3! ..3! ..혩 ..tT ( ..tT ( ..ڇ< .,.3qL 11ٞsMk( ! !" ,,؇$M( %#'HtT ( ..* ..ڇ<8w( ~  u']^4  g#ՁZ **)|PdP$R)+ l63P` [;4  pr (<E gLxU > >  <\A-Q\ "qY> ##n #}l $$ZG/^ %%Lz %%0::j &&JA. && 4eRxU+  ! (u']^4  !_5”+cWGk ؞aöJ$G&, ..yY ..qL //qL / /qL 00lij< 0 0lij< 00 lij<{6~, ** ~$P4,_ *"*.1X5 *"*.;ў *"*.)|Pd +"+.nz@ +"+.3l +$+0aY -"-.Oh7 ."..3! ."..tT ( 1$10ٞsM 22"f<Nӥ(-cWGk ؞ac^]z-  ֟l6 #hs  #hs  #hs  #hs   ׀x__  ׀x__  ׀x__  ׀x__  -  -  Vm+b  Vm+b  q)/~y s  s 15s  s  s  s ;?s 26sJA. 1 /g#ՁZ &&1ag{/   7Qt/ # #b5Zq ++,aY̤/ #~ u']^4 g#ՁZ !!$%szB ..tT ( 11!ٞsM~ / 6%h.\0 #<\A-Q\ '+<\A-Q\ <\A-Q\l/cWGk ؞aƽ6%h.\0  jɑ^ 7D:*Mz  ~ 8Er4?y,  YǶ #0oeWa <\A-Q\ $1<\A-Q\ )<\A-Q\ 1y: !!kb׫ !!~ 3)0 w#K_z: #hs  #hs  #hs  #hs  #hs  #hs  #hs  ׀x__ ׀x__ /4̆E;G /4f 05ܦ&Q 33f<N 3*3/f<NybBٯ0  " )g#ՁZ $ $"ad1 3)nf^01cWGk  "!""A Yu "&"'A Yu "!""(߷!dU "#"$(߷!dUz 2   (T F H$ fY0a=m2  "*ל:u3/&(3 11 11䇲(3  n4  g%eyV%@~C3 s s s 33 f<N 33 f<N 33 f<N 33 f<Nu']^4  "1 ֟l6#  &p} "L'oI 4 0!$ '2(<E #.L>(N  eE# ]NQZ '2gLxU #.J39v )0 $5wr '2<\A-Q\ #.1y: ge Ekm[@ '2> #. |~  & 1?8,)a $/q)/~y ,7~fͱr ,7s '2(<E #.L>(N  '2gLxU #.J39v '2> #. |~ '2<\A-Q\ #.1y: 3 3f<N 3 3f<N 3 3f<N 3 3f<N?7d  %                                         .3                                                                                                                                                    ;eS!_7 ] ]| ++aYOh7 --* --VX5WHxO'8 (( sڑf8cWGk ؞a ""2O'z{K " "2O'z{K* 8i   jDž$h=   }=Gс   KcE   C ?'$   iDFQC   fp   4s剕  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q5w8Q5w8Q5w8Q5w8Q5w8Q5w8Q5w8Q W-,  W-, 2 2 f<N 2 2f<N 2 2f<N 22f<N 2 2f<N 2 2f<N 22f<N 2 2f<N 2 2f<N 22f<N 22f<Nw#K_z:  1ڱU > >  |~  |~1y:   !0#hs   ڇ< ..lij< / / 11_>?G$F< gLxU gLxUjDž$h=   e]’!vo= 22 f<N 22 f<N 22 f<N 22 f<NZIN> , (#hs  *#hs 22N>228V?'A22Q dW22Wѓ22f<N33f<NqY>  % 0u']^4  %%ľS? s͋x?  " 00liji  ! (jDž$h=  ! (}=Gс  ! (KcE  ! (C ?'$  ! (iDFQC  ! (fp  ! (4s剕  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q5w8Q5w8Q5w8Q5w8Q5w8Q5w8Q5w8Q ($A G߻0   J J  s  s  s  s  s  (<E  (<E  (<E  (<E  (<E  (<E  (<E  gLxU  >  >  >  >8V?'A 2 2 2 2WѓB6|A 11 ٞsM09B  " )g#ՁZ # #"BxiB}=Gсzj3Cs&sss siDFQC   ! ! b,eD  r7  {vX"  prϰR$ E P$R)   E & #hs  #hs  #hs  #hs  #hs  (7#hs  #hs  #hs  Vm+b Vm+b -~ .1k X   .͋x? !!.kb׫ !!)kb׫ !!k( !!~ 3 ! !/~ 3 !!~ 3 !!+~ 3 ! !/~ 3 !>!M~ 3 !!ݦ{% 33f<N 33)f<N 33f<NKcE   2 2OA_ضWnE       ''epQE           -- 33Q fF . .+ 00% 0%00uggF 5EIq"eG_J&#ӼIMiDFQC5w8Q꒺fCMw +  n4   n4  n4  n4  n4   X?Q   b}=JESX   .iu=   q47   @    _   u z%Q   t   xMwr   9x譗   Qv3   J   ɵ7   <‗   ?   'j b1   !+,q   ,՞*j   ժQh   x`   'kw g   4;^   g>i   jDž$h=   }=Gс   KcE   C ?'$   iDFQC   fp   4s剕  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q  5w8Q5w8Q5w8Q5w8Q5w8Q5w8Q5w8Q5w8Q #hs  "#hs  %#hs   gL| .gL|  aw .aw !! %szB !!.%szB '' !%d.k ''.!%d.k '' rY% ''.rY% ''  ''.  ''  ''. (( dK;c ((.dK;c (( &7';TK ((.&7';TK (( fZ^ ((.fZ^ (( v#y(O ((.v#y(O )) D@e )).D@e )) ms'y )).ms'y ** Z_>_ **.Z_>_ ** 1X5 **.1X5 ** ;ў **.;ў ** )|Pd **.)|Pd ++ nz@ ++.nz@ ++ 3l ++.3l ++"aY ++.aY -- Oh7 --.Oh7 .. 3! ...3! .. tT ( ...tT ( 11"ٞsM 110ٞsM 22f<N 22*f<N RKaM ~ YǶ 8<YǶ 1k X (,1k X   ͋x?  ( ,͋x?$oNz 2z 2z 2z 2z 2z 2N 1 1 11+ 1 1 1 12"1N   v#y(O ( ( ))0㰬~O     )) ++Dw] XP %_\-iیֹrP  ! %g#ՁZ % %!WNPEP 0 0_>¤Y 蒐~-  :*Mz r4?y, :>r4?y,   r4?y, 1y: CG1k X  C G͋x?eeI!Z y^GI4'2[ . . 1 1 1 1 1 1 1 1<\A-Q\   %8#hs   siUs\ - - --7 M̦Qd P\ .. yY ..qL ..%qL . .qL ..qL . .qL ..qL 0 0lij< 00lij< 0 0lij< 00!lij< 0 0lij228V?'A22Q dW22Wѓ22f<N33f<NqלIq] ?g>iqEf] * $u']^4 * H$3_x]  Y0 Y0  ?8,)a s s <\A-Q\ 1k X !!%szB // qL // qL // qLZG/^ * %g#ՁZ $$*fZ^ ( ( ((pH䕴U4;^   ) - -VX5WްH'_  x2_4;^ 5Ϥ_  Uyjh _   # ( (~#^n{`l63P`  ! q)/~y ~ <\A-Q\ <\A-Q\qb=` *Q NF   -k"  /(O`,& #2*ל:u *ל:u3R\<a p +Α 25(<E  #(<E  (<E  L>(N   i`   qEf] ,/Vh# 33f<N 33f<N?8,)a   ~fͱrVm+b   &k b   e]’ !! b, --8S袹 --46MQ --7 M̦ --VX5W ..혩 ..ڇ< 00_> 22_5S* Ob /7 5Ϥ_  ) 14s剕 / /qL / /qL 1*12ٞsM 11ٞsM 11ٞsM 11%_5SID$b gLxU gLxU@Mb   .. // //# 00 00 11+Ly!c kjr+X6ʷdK;c ( ( ((HxO'8Efc s)|Pd **# ++$SG_-ix%d *ל:uwd .. qL 00%lij< 0%00liji   * . .혩_\-icWGk  $!$"ZG/^ $&$'ZG/^ $!$"ybBٯ0 $#$$ybBٯ0 A0jcWGk ؞a $$ ]Ys) $ $ ]Ys)~GɈj w#K_z: #> (,>  > >  |~  |~  |~ !̆E;G ̆E;G ̆E;G f f f ܦ&Q 33 f<N껀„AkcWGk ؞a։3eel  6y.1  gLxU gLxU EM  EM gB l ,,`6lU> ,, 6Nȭf ,, p ,, >nGI Dl #:"j!0gB l ( ,, p~zƚl  > ,3> >  qY>  qY> %,̆E;G $̆E;G ܦ&Q3)nnGm'p ~ u']^4 g#ՁZ ''D;q , , ,,mb زO3rC ?'$5w8QehKw   k"   (O`,&Z,g@w !!kb׫ 11ٞsM]|?x "_[Cx  <\A-Q\  <\A-Q\ !+!3kb׫ //qL //qLd\x . .+qL 00%lij< 0%00lijGLz * %g#ՁZ $$*Շ>E|cWGk  #!#"n #}l #&#'n #}l $!$"09B $#$$09B֑+ I|228V?'A22Q dW22Wѓ22f<N33f<Nwx|cWGk ؞a #cWGk  ## HgUe ##HgUexc7BY > > > > > > > > > > > > > :*Mz :*Mz ~ ~ ~ r4?y, YǶ YǶ YǶ oeWa oeWa <\A-Q\ <\A-Q\ <\A-Q\ <\A-Q\ <\A-Q\ <\A-Q\ <\A-Q\ 1y: i`  i`  i`  i`  i`  qEf] qEf] qEf] qEf] Vh# Vh# EM EM gB l gB l gB l gB l gB l qY> qY> ̆E;G ̆E;G ̆E;G ̆E;G f f f f ܦ&Q ܦ&Q 1k X 1k X 1k X 1k X 1k X 1k X 1k X ''x%  ͋x?  ͋x?  ͋x?  ͋x?  ͋x?  ͋x?  ͋x?!! kb׫!! ~ 3!! ~ 3)) ÿnX,, aYu E   ,,;FԵmÿnX ) ) )) ꡛm8}=Gс   ) . .ڇ<]NQZ # *#hs VX,sVt ~  u']^4  g#ՁZ ''!%d.k]=B6~ O9d> Dw] XP 8(N  ! i`   i`   i`  qEf] qEf] qEf] Vh# 33 f<NׂԻz //qL //qL 11 ٞsMM+J# ~ u']^4 g#ՁZ ''rY%$SG ++ j?… p}SB9q/H*Q/HNF0*ל:u6y.1  &ݒT #gLxU '+gLxU  gLxU gLxU J39v EM !gB l gB l gB l{ ++xMڇ q)/~y3l + + ++^0a܂~6E " #PՎY oP  1y: !!k( !!~ 3 !!~ 3 !N!Q~ 3 !!ݦ{% / /lij<؇$ , , --8S袹DssT* ~ ~ YǶ YǶ 1k X 1k X   ͋x?   ͋x?Qv3   * *b">GY0 $ l63P` 1k XVEs p +Α  L>(N  a45u Vh# Vh# ,/Vh# V ^T#CK %L'wajVی //$"F .. ..# 00( 00$ZN5T  &ݒT  J39v 6?4( EM EM ,/EM u E -  Iq"eG,՞*j   , ,du?*0o^8N  ! (u']^4  !z5B(N  L>(N &  .. 00) 00%r7  '4VX,sVt +M+J# '4WElar +m'p *~:Hm '4MX>Ci' +ݷ, *tQY "/ &3Uw* +򚰅gR &3*ĴI +[g7 *'r@ʫ &38w( +|Gt5` *-?$ ,9̤/ ,9+ -:& -R $1wn. 2? i`  )6(T F 2?qEf] )6H$ (5a45u 2?Vh# )6fY0a (5V -:qY> 1>̆E;G )61K<  1>f )6^8N (5'. 1>ܦ&Q )6eRxU+ (5k ?hro 8Ekb׫ 8E&zzFB 9F>x~U /<''x% 3@" `C *7;? 3@" *7` } 3@A Yu *7(߷!dU )62O'z{K )6HgUe 2?Lz *7xJ 2?n #}l *709B 2?ZG/^ *7ybBٯ0 )6 ]Ys) )6یֹrP .;b5Zq 9F0::j 9FJA. :G 4 0=դ\ Q=W 2?{vX" %2؞a pr pr &3pr pr 2? i`  )6(T F 2?qEf] )6H$ (5a45u 2?Vh# )6fY0a (5V -:qY> 1>̆E;G )61K<  1>f )6^8N (5'. 1>ܦ&Q )6eRxU+ (5k ?hro /<''x%  gL|  aw  8 Ekb׫ ! !%szB !3!@" "*"7` } "3"@A Yu "*"7(߷!dU ")"62O'z{K "3"@" `C #*#7;? #)#6HgUe #.#;b5Zq #2#?n #}l #*#709B $2$?ZG/^ $*$7ybBٯ0 $)$6 ]Ys) $2$?Lz %*%7xJ %)%6یֹrP %9%F0::j %0%=դ\ &9&FJA. &:&G 4 ' '!%d.k ' 'rY% ' '  ' ' ( (dK;c ( (&7';TK ( (fZ^ ( (v#y(O ) )D@e ) )ms'y * *Z_>_ * *1X5 * *;ў * *)|Pd + +nz@ + +3l + +aY -8-E&zzFB - -Oh7 .9.F>x~U . .3! . .tT ( 1 1ٞsM 2 2f<Nkw --( --&zzFB 33f<N꓌e]’   uTǙ̒ //qL 1 1ٞsMgLxU   %8#hs   f ) $u']^4 ) ^8N (BL<‗   **{6~,"*  #hs   1y:sD k  q)/~y4s剕   2 2_5Sφ눛  #hs  #hs  #hs  #hs  #hs  (7#hs  #hs  #hs   -  - 6?4( EM  /EM EM +EM EM +EM u E .gB l  gB l  gB l  gB l gB l 33f<N 33)f<N 33f<N{|^Ėx~U -   ,, mb ,, 6Nȭf ,, `ګ ,, >nG]rI֌ K LVX5W --w{ 1J ,E /H /H /H /H 0%^O   k"3Oນ .. yY ..qL ..%qL . .qL ..qL ..qL 0 0lij< 0"0-lij< 00lij< 0 0lij< 00!lij< 0 0lij<.>p=cWGk ؞a ## " `C ##%" `C ## ;? ##";?J~ 'J 减   0::j 1 0g#ՁZ %%1g`Bf  gLxU .5gLxU EM %,gB l $gB l̆E;G ) $u']^4 ) 1K< h5Fm' %  @o'kw g   --7 M̦<Ƭ gLxU gLxU~:Hm  ~  u']^4  g#ՁZ ( (dK;cߐ}cWGk ؞a "" A Yu ""%A Yu "" (߷!dU """(߷!dU+r [b7:"j!0cWGk  "" 2O'z{K ""2O'z{KoP     E <\A-Q\ %-<\A-Q\ 1y:  1y:nz@ + + ++{؀- gLxU gLxU gLxU gLxU gLxU gLxU // lij<-?$  ~  u']^4  g#ՁZ + +3l!   .. // // 00 114z,|                                                                   !! !! !! " " "@"E "" " " "" " " "" " " " " "?"D "" " " "" " " "" " " #A#F #:#? ## # # ## # # ## # # #B#G $@$E $$ $ $ $$ $ $ $$ $ $ $A$F $?$D $$ $ $ $$ $ $ $$ $ $ $<$A %:%? %% % % %% % % %% % % % % & & && & & && & & && & & & & & & )) + + // 1 1 228K q)/~y <\A-Q\/gGŨ  (<E .5(<E (<E z 2 z 2  z 2 %, i`  $ i`  Vh#L8O #Fm혩 ..{o%   3A:  ?8,)a  ?8,)a {vX" q)/~y q)/~y q)/~y L>(N  J39v |~ |~ <\A-Q\ <\A-Q\ <\A-Q\ <\A-Q\ <\A-Q\ <\A-Q\ <\A-Q\ <\A-Q\ 1y: 1y: 1y: 1y: 1y: 1y: 1k X 1k X ''x% ''x% ''x% ''x% ''x% ''x%  ͋x?  ͋x?## n #}l## n #}l$$ ZG/^$$ ZG/^%% Lz%% Lz%% 0::j%% 0::j%% 0::j&& JA.&& JA.&& JA.&& 4&& 4&& 4 ))ÿnX ,,du?22 f<N22 f<N22 f<N33 f<N33 f<N 33f<N 33f<N}pʹ           $                       ( ,                               37     ! ! ! ! $( $( $( $( '+                                                                    #'       $(      #                   +/ -1               48 "&   " -1                  4 8               ! ! ! ! ! ! !! !! !! ! ! ! ! "&"* " " " " " " " " "&"* "&"* " " " " " " " " "&"* "$"( #&#* # # # # # # # # #&#* #$#( #*#. #&#* # # # # # # # # # # $&$* $&$* $ $ $ $ $ $ $ $ $ $ $&$* $$$( $&$* $ $ % % % % % % % % %&%* %$%( %% %+%/ % % % % % % % % % % % % % % % % % % % % %,%0 && &,&0 & & & & & & & & & & & & & & & & & & && &,&0 & & & & & & & & & & & & & & & & & & '' '' (( ) ) )) )) ** ++ ,, ,, , , , , -- -- - - -- .. .. . . .. .. . . .. . . .. . . . . . . .. // // // / / / /$ // /2/6 / / // // // 00 0 0 00 00" 00 00 00# 1 1 1&1* 161: 1 1 11 11 1'1+ 1=1A 1 1 1"1& 1/13 1 1 1 1 11 22 22 22 22" 22# 22 22 33" 33" 33" 33"!+,q   ++^0a`ګ ,, O8p1Ĥ3%t .x2_QF  z 2  z 2 ' ' ((XTlp} ֟l6 "#hs  "#hs  "#hs  "#hs  q)/~yҀ / /qL 11ٞsM/.Z 2 2 22%Wѓ貅%Tݺ %Շ>E|VUx["׿ ~~ Ӿ!  z5BoAb| 1 1ٞsM`6lU> ,," ,,6NȭfF%@ / /qLp 2 2J   1k X  ͋x? 11 ٞsM 11 ٞsM 22 9?*#d '֑+ I|9YBy (<E 2;(<E (<E z 2 z 246MQ --+ #~ u']^4 g#ՁZ --Oh7n4   "  J Jˮ"{ ! ^J*,1  >  >  > !>  >  >  > > % |~ qY>  &qY>  qY>_> 00HgUe  ! %g#ՁZ # #!ߡS6 z!]  $ .n4 22f<N 22f<N 22f<N(T F  ! (u']^4  !$5wr # *#hs ؞a  ,pr" + %g#ՁZ !!+ ..&lVB͚           " " " " # # $ $ $ $ % % & &w^&cWGk ؞aơlC  ͋x?   (͋x? .. yY ..qL 00lij< 0 0lij<4 ˊ  ' 5RQ  5Ϥ_  6[  շ=  ̤/ kb׫ 0::j   }=Gс   iDFQC   4s剕   kb׫ !3!<%szB !&!/ b, %%0::j ..tT ( . .ڇ< .. qL 181AٞsM 11 ٞsM 1+14_5S 11_5S 11_5S ֟l6 $#hs  $#hs  $#hs  $#hs  &2(<E &2L>(N  &2gLxU &2J39v &2> &2 |~ 7C<\A-Q\ (1y:Q dW 2 2 2 2Wѓ`3       ))21B  > +1> $*> qY> #qY> $f #f ܦ&Qkjr+X6x~U 1 0u']^4 ..1j6 . .XTl ''7f@ @ ;  Y0 &l63P` CKl63P`  l63P`  [;4 [;4 -51y: )11y:r7Lk   . . . . / / 0 03! ..+ ..혩x`   & - -46MQÌ> .. 00% 0%00'R > >  ~Z3 (ʣ2\h8 11ٞsM 1*10ٞsM HO ) eRxU++k~ )L4NxMwr   ) ) ꡛm8aY   ) )ÿnX + + , ,du?𱲈mR .. yY //qL!%d.k ''$ ''3k" 5C}DW  q)/~y  q)/~ys  $  i`  qEf] Vh# EM gB l ̆E;G f ܦ&Q 1k X   ͋x? !!kb׫ !!~ 3뚘K  gLxU  gLxUq_3?     ,5   # & & -0-9 .. / / 00 00 0!0*9x譗   " ) )v CCi'  ݷ, "ݷ,  i`  %(T F '-(T F qEf] H$ '-H$ Vh#  fY0a "fY0a " `C ;? #;? "  &` } (.` } A Yu (߷!dU (.(߷!dU MȋLT   X?Q  b}=JESX  b}=JESX   .iu=  q47  q47    _  " (u z%Q  u z%Q (<E (<E (.z 2 <Bz 2 '-z 2  i`  %(T F '-(T F (T F qEf] H$ '-H$ H$ Vh# Vh#  fY0a "fY0a fY0a !!" """ " "&` } "(".` } ""A Yu ""A Yu ""(߷!dU "(".(߷!dU """ `C ##" `C ##;? ###;? ''!%d.k ''!%d.k '' 3k" '5';rY% '('.rY% '('. } ')'/ } ''  ''  '' ĵ '.'4 '('. '!''XTl ')'/XTl ((&7';TK ((&7';TK (( ~#^n{` (#()fZ^ ((#fZ^ ((pH䕴U (($pH䕴U{{+J       ***Q , (#hs  *#hs 22N>228V?'A22Q dW22Wѓ22f<N33f<NꟉ92 ) )ÿnX˲~f w#K_z:   |~ '. ܦ&Q ܦ&Q ,/ܦ&Q k ?hroQ   %8#hs   g#ՁZ !   9O@,d G߻0   J J  k"  (O`,&  {vX"  {vX"  g%eyV%@  pr      *ל:u*ל:u*ל:u  #hs   q)/~y  q)/~y  q)/~y  q)/~y  s  s  s  (<E  (<E  (<E  (<E  (<E  (<E  (<E  (<E  (<E  (<E  (<E  (<E  (<E  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  gLxU  >  >  >  >  >  >  >  >  >  :*Mz  :*Mz  ~  ~  ~  r4?y,  oeWa  <\A-Q\  <\A-Q\  <\A-Q\  <\A-Q\  <\A-Q\  <\A-Q\  <\A-Q\  1y:   i`   qEf]  Vh#  EM  gB l  ̆E;G  f  ܦ&Q  1k X  ''x%  ͋x?  ͋x? ! !kb׫ ! !~ 3׀x__   ''3k" '' } ''ĵ ((XTl ((HxO'8 ((~#^n{` ((pH䕴U )) )) ꡛm8 ))v **b">G **ȉ9T **si#z **{6~, ++$SG ++{ ++^0a ,,du?BLnG , ,Q=W ^)|8hS        08gL| 08aw !0!8%szB '0'8!%d.k '0'8rY% '0'8  '0'8 (0(8dK;c (0(8&7';TK (0(8fZ^ (0(8v#y(O )0)8D@e )0)8ms'y *0*8Z_>_ *0*81X5 *0*8;ў *0*8)|Pd +0+8nz@ +0+83l +0+8aY -0-8Oh7 .0.83! .0.8tT ( 121:ٞsM 2 2f<N 2#2+f<N 22f<N![ 00-LU; 11)OqD 22Wѓ貉?   " + +$SG5n>K  6%h.\0 <\A-Q\n #}l * %g#ՁZ ##*ϖG ))f<N  22l:BΤӉ   ͋x? //qL 00lij<V    $u']^4   R5yY0 G߻0   &<@Y)  #hs   #hs   q)/~y  s  (<E  >  YǶ  YǶ  YǶ  oeWa   i`    i`    i`    i`   qEf]  qEf]  qEf]  Vh#  EM  gB l  gB l  gB l  gB l  qY> qY>  ̆E;G  ̆E;G  ̆E;G  f  f  f  ܦ&Q  1k X  1k X  1k X  1k X  1k X  1k X  ͋x?  ͋x?  ͋x?  ͋x?  ͋x? ! !~ 3 , ,aYɞi  J J~ 3 !!- --lm$NF , (#hs  *#hs 22N>228V?'A22Q dW22Wѓ22f<N33f<NGPcWGk ؞a ## n #}l ##%n #}l $$ 09B $$"09BCc h6= 00lij< } ''\Tx  !#hs  #hs  #hs  #hs  1y:UdE E[_ }ݱ[r6  *ל:u6?4(   ,,D;qɵ7   * *si#z[;4   1k XH j +##jqFf/: (@*ל:ufwT  ̆E;GMOcWGk ؞a %%&դ\ %%+դ\ &&&JA. &&+JA. &&& 4 &&+ 4'j b1   + +{   ;  l63P` l63P`  l63P` l63P`  [;4 [;4  [;4  [;4 (-[;4 -2[;4  [;4  [;4 1y: 1y:  1k X  ''x% +0''x%t   ))շ= *'L_ * *1X5 **;ў * *)|Pd + +nz@ ++3l ++aY - - Oh7 . . 3! . . tT ( 1 1ٞsM}Hx~U . .>x~U?Շ   %szB ! ! !! b,v ))KHQ  *ל:u,1;x~U 33f<Np ֟l6 #hs  #hs  #hs  #hs   s   s s   s s   s   s   s 3 3 f<N 33f<N 3 3 f<N 33f<N 3 3 f<N 33f<N 3 3 f<N 33f<N:`I / /s Aе       FmcWGk  %% یֹrP %%یֹrPrelasrcsLձcmdl-R+T+,./-NJQ0D@14F:H<3B725C8G;?9EA=>6KMLOUIP*Snss_wrapper-1.1.16/.cache/clangd/index/nss_utils.c.D245051A87648149.idx000644 001750 000144 00000002724 14460665460 024420 0ustar00asnusers000000 000000 RIFFCdIxmetastrilxRMo0 O񡇶* 4@Nr6;LjlѠI>Ce z#$./^nMH $מ$xfjJM2~Ґ0P밷#nKn^剆^oaqrWJH)oB.T5(Z#| LyI7 bP4+[8d`*M:XtRHGIںAљ.s5YF}ʳAz0lxֵ h٣!a@r 8/#`K8:,/` YȖ6wJ<Jh5{&t(@(=@GκYFQLib'1X׭m9aVMeW }`a+d1YIUvp+lV(~< [!K1bIRXpL"笩Reo[gDDdg(x 7ǹ| jK J 6/vqsymb!_li 5.--/** 4-/refsЂ X, .11 _li4= yZ ..._li .44_li .55_li .66_li .ii_li .vv_liߐ$# .-!-&_li .-4-9_li ..'.,_li!QH .___li .aa_li .xx_li_li .--~zƚl .5"5)_li .SS _li ._ __li .__"_li='ҏ .6$6-_li .WW_li .a a_li .aa&_li4z, .GG .qq}pʹ .0 0 .<<# .dd .} }JD .55_li .66_li .ii_li .vv_li*,1 .<<_li .OO _li .dd _li .ii!_li .kk _li .vv!_li .xx_li .yy_lilVB͚ .G G .q q21B .]] _li .]]_lirelasrcsG21.EP0123/3/0cmdl+))+%!(    "$#&, '*nss_wrapper-1.1.16/.cache/clangd/index/test_thread_getaddrinfo.c.17665B73698D65D5.idx000644 001750 000144 00000004526 14332201737 027301 0ustar00asnusers000000 000000 RIFFN CdIxmetastri.xSn0 )Zw: O6a밡cH ^|h<<Ͼ~z|yī܀G0-Kv)ٚi͗V2p`| sOx1JXb  $RP5&Q6M}[5s>ô AlFr1PL48Fde1K֗qF#t)(Qb8F mJeSv|J<١ʂ-;uY-ك мV2zװE&[a*{O.=:w'/ v\4}{)olAP=*nTjB"~eu-؇[T?2V7ZhCk3*?wZ(QN5|l7۬DV<&197XX8A/6!S(s׏),9cU,7A!k+u`Z2DZG4,f { du\A|Y ͯ!&3<J=^symb]Rf @2 2 i ?2F F$2F F$W{ >2^^2^^refs3Oນ 2,,Rf+}E2eeW{jzk% 255 2>>_> 211Rf}pʹ 2 2$ $ 2-- 2.. 2// 21!1% 2CC 2T T 2XX 2e+e/ 2e1e53_x] 2((Rf3DܖPG 2ee4= yZ244Rf9)'` 2bbFRdX. 2NNi Qd P\ 2Rf 2**RfejLmF 2[[i gݍY 2 Rf 2 Rf 2("(*Rfl:BΤӉ 2@@Rfnp)({ 2" "RfoY\V 2II i q_3? 2 2)){O0 /A 2..Rf 299Rf멁Rf 2  2S Si +V244Rf멟W҆3 2HHi lC 2 Rf 2))Rf 277!Rf멢 G  2<<"Rf멥"F 2 2** (WS# 2;;&Rf며e輚(s 2XXi ז|0 2QQi j-7 2<<RföJ$G&, 2--Rf 244#Rf 255'Rfi 2 2++i  2F F$ 2bb+W{ _Ú  2! !Rf[% <255Rf2>>RfѢF  244AZ  222 277 2;;ԽO? 27#7* 2;(;/Ђ X,244RfVF  2aaW{X]I 2 Rf 2++Rf* Ob 2 Rfq m! 2//Rf~]s5" 2Rf 2** RfSĆ222Rf277Rf2;;RfW{ 2^^relasrcs8164=9;:7<2_D 1<=9435678:;35cmdl1-//)&$ , "  !%('*0#+.nss_wrapper-1.1.16/.cache/clangd/index/test_nwrap_disabled.c.59E63F9B2D58E517.idx000644 001750 000144 00000005504 14460665461 026507 0ustar00asnusers000000 000000 RIFF< CdIxmetastridxTۊ0),l!O -K"m% ٯ&YLtΙьVCSӏJ?;0#LO$jO n7M|K)Qr6&l3l3t@CBܨD{2kf p{ DXA3JJ:z8c)7Pq?:2K_C )  =vv3mrr%c%dB}J :BjFCsָ~2s~{=8jic6pyenQZ~ r}L wFƼS& ?U*XMrjlkqN=|;".'Y%17pЬڛ%W[9@ԚC dC# f+ ~anqQ+F`|xy9d#gN:,k=ԢlHj2rTc8#[lS`8z˼U#^OTsymbc3;e =-< <"-< <"{5B <-I I(-I I(qK >-& &-& &W{ ;-nn-nnt4 ?- #- #refsb'"KB -FF c3;e -< <" -tt)W{ G  -i!i){5B _Ú  -O O{5B 3k"  -t4VF  -qqW{AZ  -DD -\\ -^^ -__ -ii{5B  -I I( -uu/W{Ђ X,-t4-t4-t4-""t4-00qK-dd {5B 4= yZ-t4-t4-t4-""t4-00qK-dd {5B ԽO? -^"^)NV.HO -ii{5B 9)'` -rr -ss -tt -uuߐ$# - t4G!' -))qKöJ$G&, -dd{5B +}E-xxW{Q fF -XX -_$_/3DܖPG -xxX]I -YY{5B qK -& & -ss%W{ȉ9T -t4gݍY -KK{5B -LL{5B -V!V){5B Qd P\ -XX{5B -__"{5B 3_x] -VV{5B * Ob -N N{5B d[ #h-i3iB{5B ~zƚl -!!t4d\x -XX {5B -_$_/{5B \S  -t4W{ -nn7 M̦ -22 qKDqUh -dd /gGŨ -t4{O0 /A -gg{5B }pʹ -[[# -x$x( -x*x.8S袹 --- qKĵ -t4JD -F Fc3;e46MQ -//qK_> -[[{5B lC -WW{5B -^^ {5B j6 -YYmE -i*i0{5B l1} -((q_3? -WWm\܂ -t4t4 - # -rr*W{+V-t4-t4-t4-""t4-00qK-FF c3;e-dd {5B l:BΤӉ -kk {5B I، -i3iBѢF  - - - -"" -00cr -t4OA_ض -CCc3;ev -!!t4SĆ-DDc3;e-\\{5B -^^{5B -__{5B -ii{5B relasrcs,031/4:65829-aPsN ,9:4/76.213058.7cmdl,(**$ '     !#"%+&)nss_wrapper-1.1.16/.cache/clangd/index/test_getnameinfo.c.779E41D17A149E05.idx000644 001750 000144 00000013230 14460665461 025764 0ustar00asnusers000000 000000 RIFFCdIxmetastri hxSn0 †@䩻`C@)GD n8F5, 9<i֟>~{qQf4}1l0m쮤kD'/EZC.Z%j HEP`&!u1Pэ̙ꅵMÐt+Ol\ϡxGv2QcS,h #qBǀ'hA*Tgg:>˖o),˒H tldž ^{Ytz{]Y)?Zz(al^Zc6p< scViyHi2@7Wlbܾ3[V YݩXz|[(hti8=| ^aW7syGC{Z\m%M@FqgeVhDno+ȚMʹBPv Tņ%lX6$-]X^VsM6ogP -kV X?1Ysymb;{*` ;-l l&-l l&(P{G ?-< <*-< <*8vx <- (- (W{ 9--2-ز >- '- 'T 7 :- "- "Χz =- (- (refs G  -,4T 7 -J,J4(P{G -z)z1;{*` -+3Χz -,42-ز -,48vx -,48vx _Ú  -T 7 -""T 7 -@@(P{G -PP(P{G -pp;{*` -~~;{*` -Χz -Χz -2-ز -2-ز -8vx -8vx -8vx -8vx -8vxVF  -W{AZ  - -&& -// -66 -KK -TT -]] -ff -{{ - - - - - - - - - - - - - - - - - - - -;{*` -l l& --W{ԽO? - - -HH -JJ -xx -zz - - - - - - - -m - 9)'` - - - - - -$ЌZ.8# - (WS# -T 7 -HH(P{G -xx;{*` -Χz -2-ز -8vx -8vx"L(, -_ _3/&(3 - [% <-((T 7-))T 7-88T 7-99T 7-VV(P{G-WW(P{G-hh(P{G-ii(P{G-;{*`-;{*`-;{*`-;{*`-Χz-Χz-Χz-Χz-2-ز-2-ز-2-ز-8vx-8vx-8vx+}E-W{(P{G -< <* -1W{3DܖPG -:{ݦPQ -M MmLT -T 7 -..T 7 -JJ(P{G -\\(P{G -zz;{*` -;{*` -Χz -Χz -2-ز -2-ز -2-ز -8vx -8vx4'2[ - * Ob -! !(T 7 -1 1(T 7 -O O((P{G -a a((P{G -} }(;{*` - (;{*` - (Χz - (Χz - (2-ز - (2-ز - (2-ز - (8vx - (8vx - (8vx - (8vx@Mb -,, -.. -ZZ -\\ - - - - - - - -{6_d -.(.1T 7 -\(\1(P{G -&/;{*` -'0Χz -(12-ز -(12-ز8vx - ( -/W{ׂԻz -T 7 ---T 7 -II(P{G -[[(P{G -yy;{*` -;{*` -Χz -Χz -2-ز -2-ز -2-ز -8vx -8vxW{ -jzk% -(( -)) -88 -99 -VV -WW -hh -ii - - - - - - - - - - - - - -_5S -!!T 7 -11T 7 -OO(P{G -aa(P{G -}};{*` -;{*` -Χz -Χz -2-ز -2-ز -2-ز -2-ز -8vx -8vx -8vx -8vx0Eru - T 7 -II (P{G -yy ;{*` - Χz - 2-ز - 8vx - 8vx2-ز - ' -.W{}pʹ - - - - - - - -$( -*.Ҁ ---T 7 -[[(P{G -;{*` -Χz -2-ز -2-زnp)({ -T 7 -22T 7 -AA(P{G -bb(P{G -qq;{*` -;{*` -Χz -Χz -2-ز -2-ز -2-ز̓c - F%@ -,,T 7 -ZZ(P{G -;{*` -Χz -2-ز -2-زT 7 - " -)W{Χz - ( -/W{SĆ-T 7-&&T 7-//T 7-66T 7-KK(P{G-TT(P{G-]](P{G-ff(P{G-{{;{*`-;{*`-;{*`-;{*`-Χz-Χz-Χz-Χz-2-ز-2-ز-2-ز-2-ز-2-ز-2-ز-2-ز-8vx-8vx-8vx-8vx-8vx-8vxrelasrcs,0/-,0\d ,782/34651.02846517.3cmdl,(**$ '     !#"%+&)nss_wrapper-1.1.16/.cache/clangd/index/test_nwrap_vector.c.6DA36926E43E358A.idx000644 001750 000144 00000010236 14460665461 026225 0ustar00asnusers000000 000000 RIFFCdIxmetastrixTn0 †@䩻`CGCi[%ܬn$n :@ .m LyV=J .o o' ..W{z .5+V.m L. m L. m L.//Kò.33Kò.88 Kò.BB Kò.HH Kò.XXL&.^^L&.ii L&.zzyV=J.yV=J. yV=J[;4 .66Kò .>>Kò .DDKò .ccL& .yV=J  .m L .m L .00Kò .44Kò .77Kò .<<Kò .??Kò .EEKò .[[L& .aaL& .ddL& .yV=J .yV=J .yV=JѢF  . .// .33 .XX .^^ .zz .SĆ.m L.m L.m L.00Kò.44Kò.77Kò.<<Kò.??Kò.EEKò.[[L&.aaL&.ddL&.yV=J.yV=J.yV=JrelasrcsS,.8q{Y,120/-/1-02cmdl,(**$ '     !#"%+&)nss_wrapper-1.1.16/.cache/clangd/index/test_getnetent.c.130F78FDACE3893D.idx000644 001750 000144 00000002166 14460667224 025553 0ustar00asnusers000000 000000 RIFFnCdIxmetastrixRn0 †@䩻`C@h[M Qn$. 4#"!!i5?nO˽z-s^=JȒ! |7,ַF}Dg/Jm/fئoSHbÈF**΋Nr=%, f2h)UKy\!T']&LtO^;-, Y\i:OihRJldɶhhnZn|ܭޟbmfn=J꺲JvV}1amX]2 +7dvm~pZk(>juG=~5a3*$t!o~_R pL؏]%;Vi&/x)S|$ ^ gm󡣰 Ir l~))1bR]Vɋ,yyg*<;-c#T|B3>N0bsymb>e;S :-  -  W{ 9--refs5VF  -!!W{9)'` -""4l?% - e;S+}E-%%W{3DܖPG -%%e;S -  -""'W{duX] -e;SW{ -}v - e;S}pʹ -" -%$%( -%*%.6ֽX - e;S -)2e;Srelasrcs,0/-0tmK ,782/34651.02846517.3cmdl,(**$ '     !#"%+&)nss_wrapper-1.1.16/.cache/clangd/index/testsuite.c.AF64C06B860D31A7.idx000644 001750 000144 00000033244 14460665461 024515 0ustar00asnusers000000 000000 RIFF6CdIxmetastri^ xUێ Vj޴ժ:@wIFT807HX>V_=U?`ekz(`,PZ4 +sՀZow%߼[pTi#AtWF3^{@<ЃAz)<rfuRΝ 3"3nтڞQP3pƜG%<3 KM4+* 3:Inv켘x)ӷhBcsd|}6,9x4݌ -N͵\,۽`W,sZd# Vx)a>v&vbg"db`1&T+òSw%9M 5:<<1ַ (;Q.(>|:K()sj?w' &=Ni9EMߗMY kܵ7=yi+- ZN8 IWA נ0t 3; ?3iT.Rh"d9HW*5# zQp\^-PG-,ݴ> e튞+]XJ?{Z'iJadn}2\k#9f |[X+T~ P k#`jef 4JCthS뒧n;Dn؊L{4M>n &?qCNx|symb=m>0 _1 (1 ( s PD -1) )1) )|u /1G G1G G=m  d1 $1 $&w! ]1 &1 &T0tv؁+ G1 1 cl5 M1 $1 $#5U5 Q1 1 Ҟ?7 E1i i1i is=> I1 !1 !swS_+A .1 1 ?.A [1 $1 $r"^B C1 1 ITc#N N1 "1 ">s0Z `1 1 qVd\ V1 1 ,Oe L1 #1 #tv gl S1 #1 #"%/r U1 !1 !~*| ,15 515 5u{,> ^1 1 8 B1 1 W{ F11I_FC D1] ]1] ] vK"y Y1 '1 'Ru? X1 1 f^wd a1 %1 %t T1 1 8Ay \1 !1 !U6~ W1 !1 !HT b1 ,1 ,Fciɂ O1 1 3zp R1 !1 !ju H1s s1s soԾ P1 !1 !Ҿc J1 !1 !DŽM c1 81 8K Z1 1 24`DH K1 "1 "refs]-\⟇ 1 tv gl}s5|B 1 %Fciɂ 1"'oԾ 1 tv gl 1 tv gl 1tv gl 1tv gl 1&w!'"KB 1 1 1 1 m>0 1 ( 1s=>YJW 122! s PD 12'2/ s PD 1XX |u 1XX#|u 1ffI_FC 1~ ~juVUO6+ 1 %qVd\ 1"'U6~3k"  1tVF  1W{AZ  1.. 1// 1<< 1]â吴  1GG 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 Ђ X, 1"%/r1U6~1swS_+A1swS_+A13zp1oԾ124`DH1cl51Ҿc1,Oe1tv gl s PD 1) ) 1u{,> 1u{,> 1u{,> 1>s0Z 1>s0Z 1>s0Z 1f^wd 1f^wd 1f^wd 1f^wd 1f^wd 1f^wd|u 1G G 1t 1 "%/r 1qVd\ 1 U6~ 124`DH 1cl54= yZ% 1i.i4Ҟ?7 1kkҞ?71"%/r1U6~1swS_+A1swS_+A 1,2r"^B 1r"^B13zp1oԾ 1 24`DH 124`DH124`DH 1 cl5 1cl51cl5 1u{,> 1>s0Z 1f^wd 1 Ҿc 1Ҿc1Ҿc 1,Oe 1,Oe1,Oe 1Ru? 1K 1?.A1tv gl 1 &w! 1&w! 1&w! 18Ay 18Ay 18Ay 1m>0 1 vK"y=m  1 $ 1&w!X$ 1  1  1  1  1 1 =  100! s PD 10'0/ s PD 1VV |u 1VV#|u 1ddI_FC 1| |juԋ 1 24`DH 1 cl59)'` 1 1 1 1 1&w! 1 & 18Ayߐ$# 15,51~*| 166~*| 1$)swS_+A 1swS_+A 1#8 1$r"^B 1$T0tv؁+ 1 #5U5 1 #5U5 1 3zp 1 3zp 1 Fciɂ 1 Fciɂ 1 oԾ 1 oԾ 1).Ҿc 1 Ҿc 1 Ҿc 105Ҿc 1+0,Oe 1 ,Oe 1 ,Oe 105,Oe 1 Ru? 1 K 1 ?.A 1=m  1&w! 1 &w! 1 &w! 1 8Ay 1 vK"yޕ>+ 1swS_+A 124`DH 1cl5 1Ҿc 1,OeT0tv؁+ 1  1 #5U5 1 3zp 1 Fciɂ 1 oԾ 1 Ҿc 1 ,Oe 1 vK"y 1 vK"y{6~, 1 Ҿc 1 ,Oecl5 1 $ 1>s0Z 1f^wd#5U5 1  1Ru? 1?.A 1&w!Ҟ?7 1i i 1 u{,> 1 >s0Z 1 f^wd 1 8Ay 1 m>0?7 1  1  1  1  1 1&+HxO'8 1 24`DH 1 cl5[% <1,, s PD1-- s PD100 s PD111 s PD122 s PD1::~*|1;;~*|1CC~*|s=> 1 ! 1(W{swS_+A 1  1#5U5 1 3zp 1Fciɂ 1 oԾ 1 Ҿc 1 ,Oe?.A 1 $ 1DŽMr"^B 1  1 Ru? 1 K 1 ?.A 1 8Ay 1 vK"y+}E1W{3DܖPG 1ITc#N 1 " 1)W{0㰬~O 1 1-S 1 1 1 1ȉ9T 1FciɂpH䕴U 1cl59@-V 1.. s PD 1.".( s PD 1KK |u 1KK|u 1zz"ju 1#u{,> 1%>s0Z 1%f^wd 1#f^wd>s0Z 1  1HTqVd\ 1  1u{,> 1f^wd,Oe 1 # 1K 1?.A~zƚl 1:: ~*| 1:&:-~*| 1 swS_+A 1!swS_+A 18 1 T0tv؁+ 1$Ru? 1&K 1&?.A 1$?.A 1 &w! 1"&w! 1&w! 1$+ vK"y 1!( vK"ytv gl 1 # 1&w!"%/r 1 ! 1>s0Z 1f^wdsߢE/Hv 1ZZ 1  1  1 1 1  1 1  1 1 1 1 1 1 1 1 1 1 1 1  1$( 1 1 1 ~*| 15 5 1Ru? 1Ru? 1Ru? 1K 1K 1K 1?.A 1?.A 1?.A 1?.A 1?.A 1?.AOW 1== 1>> 1 1 1 u{,> 1  1ITc#N$SG 1Ҿcפ8 1  1 r"^B 1 Ru? 1 Ru? 1 K 1 K 1 ?.A 1 ?.A 1 ?.A 1 ?.A 1 &w!W{ 1{ 1,Oe='ҏ 1;;"~*| 1;(;1~*| 1 swS_+A 1%swS_+A 18 1 T0tv؁+I_FC 1] ] 1nn Ҟ?7 1 u{,> 1 u{,> 1 >s0Z 1 >s0Z 1 f^wd 1 f^wd 1 f^wd 1 f^wd~#^n{` 124`DH vK"y 1 ' 1s=>Ru? 1  1ITc#Nf^wd 1 % 1DŽM\t:9 1/gGŨ 1,, s PD 1,&,- s PD 1II |u 1II!|u 1__I_FC 1x xju 1$u{,> 1&>s0Z 1&f^wd 1$f^wd 1")=m  1%&w! 1&w! 1$+m>0 1!(m>0jzk% 1,, 1-- 100 111 122 1:: 1;; 1CCHoQp 18Ay 18Ay 1ITc#N 1ITc#N 1HT 1HT 1DŽM 1DŽM 1s=> 1s=>du? 1tv gl 1tv gl3A 1__ I_FC1`` I_FC1dd I_FC1ee I_FC1ff I_FC 1ppҞ?71 81 81 81 8 1r"^B 1&w!}pʹ( 1== 1=2=6 1>> 1>2>6 1?? 1?)?- 1 1  1 1 1  1 1  1 16: 1 1 1" 1 1 1  1 1 1  1 1 1" 1 1 1" 1 1 1# 1 16: 1 1&* 1 1$( 1*.t 1  1u{,> 1f^wd8Ay 1 ! 1(W{u8 pt 1ĵ 1qVd\U6~ 1 ! 1>s0Z 1f^wdHT 1 , 13W{9YBy 1--" s PD 1-(-1 s PD 1JJ |u 1JJ%|u 1``I_FC 1y yju*,1 1==~*| 1=(=.~*| 1>>~*| 1>(>.~*| 1? ?~*| 1??%~*| 1BB~*| 1B B&~*| 1CC ~*| 1C)C/~*| 1 swS_+A 1swS_+A 1)/swS_+A 1swS_+A 1 swS_+A 1 swS_+A 1#swS_+A 1swS_+A 1 swS_+A 18 18 18 18 1 T0tv؁+ 1$*T0tv؁+ 1T0tv؁+ 1T0tv؁+ 1T0tv؁+ 1=m  1)/=m  1=m Fciɂ 1  1Ru? 1?.A 1&w!21B 1<<~*| 1<"<(~*| 1 swS_+A 1swS_+A 1"T0tv؁+ 1#Ru? 1%K 1%?.A 1#?.A 1&w!XTl 1U6~3zp 1 ! 1K 1?.Aju 1s s 1 t 1 "%/r 1 qVd\ 1 U6~ 124`DH 1cl5 1m>0 1m>0oԾ 1 ! 1K 1?.AҾc 1 ! 1Ru? 18Ay 1 vK"ym\܂ 1)-)3 s PD 1** s PD 1G%G+|u 1G9G?|u 1]]%I_FC 1i i&Ҟ?7 1s s&ju 19?t 1t 1 "%/r 1"%/r 1 qVd\ 1qVd\ 1 U6~ 1U6~ 1*024`DH 124`DH 124`DH 10624`DH 1,2cl5 1cl5 1cl5 106cl5 1u{,> 1>s0Z 1f^wd 128=m  14:&w! 18Ay 1m>0DŽM 1 8 1?W{^0a 1 Ҿc 1 ,OeK 1  1HTsi#z 1oԾ24`DH 1 " 1u{,> 18Ay 1m>0+V1== ~*|1>> ~*|1 "%/r1 U6~1swS_+A1swS_+A1 3zp1 oԾ124`DH1cl51Ҿc1,Oe1tv gl1 tv gl1 m>01 vK"yb">G 13zp } 1"%/re7ҢE 1 =m  1 m>0 1 vK"yk< go 111 s PD 11%1+ s PD 1WW |u 1WW|u 1eeI_FC 1} }juѢF  1 1 1 1 1 1 1cr 1// s PD 1/"/( s PD 1LL |u 1LL|u 1{{"ju 1 &w! 1"(&w!v 1#5U5:w+1wwju1t1"%/r1"%/r1qVd\1U6~1U6~1T0tv؁+1T0tv؁+1T0tv؁+1T0tv؁+1#5U513zp13zp1Fciɂ1oԾ1oԾ124`DH124`DH124`DH1cl51cl51 cl51cl51Ҿc1Ҿc1Ҿc1,Oe1,Oe1 ,Oe1,Oe1tv gl1tv gl1 &w!18Ay1ITc#N1HT1HT1DŽM1DŽM1m>01 vK"y1s=>I.K@ 1II|u 1JJ|u 1VV|u 1W W|u 1XX|u 1swS_+A 1swS_+A 1swS_+ASĆ1.. s PD1// s PD1<<~*|1"%/r1U6~13zp1oԾ1&w!relasrcs05861k»n<0?A934;:<@>=856723@29A<>7?;:=4cmdl,(**$ '     !#"%+&)nss_wrapper-1.1.16/.cache/clangd/index/test_initgroups.c.96654DF285FBEEBF.idx000644 001750 000144 00000002536 14460665461 026015 0ustar00asnusers000000 000000 RIFFVCdIxmetastri2xR]o0 R CS>6{ XA _?M]f #Zc??~~{q[P t>68,ecu֛ NH$i˷MRAh={Ilx (3MkSHbDoLՏUJt}aצ0wWF2b}ma/[\ G+`FI.ss%_'/x3Iھ2_4u`3H䳠TPwFxjq! jfЌaXG1ZBsymb>W{ 5,)),))'k 6, !, !refsj\⟇ ,'k}s5|B ,  'k ,'k ,'k ,&+'k@ , 'kVF  ,--W{AZ  ,!! ,##Ђ X,,'k4= yZ,'k9)'` ,..;I1g=$ ,+}E,11W{3DܖPG ,11W{ ,))(ai,'k4z, ,HoQp ,'k3A ,%%'k}pʹ ,  ,1$1( ,1*1. ꡛm8 ,'k얼+V,'k'k , ! ,..(W{ѢF  ,SĆ,!!'k,##'krelasrcsk,=X_340-21/.2/-3104.cmdl,(**$ '     !#"%+&)nss_wrapper-1.1.16/.cache/clangd/index/test_getpwuid_module.c.13413495523E694E.idx000644 001750 000144 00000003130 14460665460 026621 0ustar00asnusers000000 000000 RIFFPCdIxmetastrigxRn0 )†@`CGCh[$ 4n$24 :!yx$CCÏBޫ(9i*bH:% ݕ@.ҁK{ϧѹH]bxM8RwH @$]HWdW3OX/Y MtL%W<C3:,(AeyL`3Eoy'q]t.ȝ@NOϓ-?#,a˙-#C' b? Z <mg-+u#vfi}g<CllRj`<N^HPH6+Qj&BWonۦVdzQgCIcu h\[1'B6Pfc{b0v W)ؤEe>tLPv!][bWsԿ:BǹA(fq&hFZ1m-'p_symb]R( 5- - c`L@ 6- ,- ,W{ 4-00-00refs;VUO6+ -  R( -c`L@VF  -44W{AZ  - -R(  -  -55$W{Ђ X,-R( -""c`L@---c`L@c`L@ - , -663W{4= yZ-R( -""c`L@---c`L@9)'` -55 -66[% <-R( +}E-99W{3DܖPG -999@-V -R( _2g} -$$ ϛE -))c`L@W{ -00/gGŨ -!R( jzk% -}pʹ -9$9( -9*9.ĵ -R( -!!c`L@ -,,c`L@m\܂ -  R( -c`L@92 -$ $c`L@+V-R( -""c`L@---c`L@ѢF  - -"" ---cr -R( SĆ-R( -R( relasrcs_,1/.2-@'>},230.1/03cmdl,(**$ '     !#"%+&)nss_wrapper-1.1.16/.cache/clangd/index/test_gethostby_name_addr.c.C9C460E7372D7C61.idx000644 001750 000144 00000023374 14460665461 027524 0ustar00asnusers000000 000000 RIFF&CdIxmetastri?xj1Bh|E^.vvWh6y^"7.c7_3BJ!?U_?U`FM64@L1wXyut~Gek ̀v6n"ЀAҮɖ!s;_pk6X|/PO-WB}M?N[<^'u6mJ|^2DyHЎϥNףvVfi|lckxf#yH1B' Cť*gW;ʼnB>,6 ?V*hU#V6(c7/s!M T*Q&ƶ70k>z~$M@kߗ ն3޼"̻_D=q<_64+}khk8ܐ~qnToEp[&Vw+?8+W-~c{#H]PPsymbAC ?-b b$-b b$G9 =- $- $K|# H-5 5&-5 5&$kR B- *- *mYm >- &- &}Nk u A- *- *W{ <--Rݩ0 C-x x--x x-?N9 E- +- +zHd4܊ D- &- &d{Xxk @- %- %]> M G- "- ">e? F-B B+-B B+refs!ɴ/ - -Y?N"X -pp AC - d{Xxk - d{Xxk - G9 - zHd4܊ - }Nk u - $kR - mYmVF  -W{AZ  -   -## -(( -++ -,, -11 -pp - - - - - - - - - - - - - - - -AC  -b b$ -+W{Ђ X,6-<<K|#-==K|#-JJ>e?-KK>e?-QQ>e?-RR>e?-kkAC -llAC -mmAC -ssAC -Rݩ0-Rݩ0-Rݩ0-Rݩ0-Rݩ0-d{Xxk-d{Xxk-d{Xxk-d{Xxk-d{Xxk-d{Xxk-d{Xxk-d{Xxk-d{Xxk-d{Xxk-G9-G9-G9-zHd4܊-zHd4܊-zHd4܊-zHd4܊- ?N9- ?N9- ?N9-}Nk u-}Nk u-}Nk u-}Nk u-}Nk u-}Nk u-}Nk u-}Nk u- }Nk u-$kR-$kR-$kR-$kR-$kR-$kR- $kR-mYm-mYm-mYmG9 - $ -+W{4= yZ8-<<K|#-==K|#-JJ>e?-KK>e?-QQ>e?-RR>e?-kkAC -llAC -mmAC -ssAC -Rݩ0-Rݩ0-Rݩ0-Rݩ0-Rݩ0-d{Xxk-d{Xxk-d{Xxk-d{Xxk-d{Xxk-d{Xxk-d{Xxk-d{Xxk-d{Xxk-d{Xxk-G9-G9-G9-zHd4܊-zHd4܊-zHd4܊-zHd4܊- ?N9- ?N9- ?N9 -}Nk u-}Nk u-}Nk u-}Nk u-}Nk u-}Nk u-}Nk u-}Nk u-}Nk u- }Nk u -$kR-$kR-$kR-$kR-$kR-$kR-$kR- $kR-mYm-mYm-mYmԽO? -p"p) -rr - -.5 -,3 -") - -18 -") -") - -18 -") - - - -")X$ -eRM - -TH -==K|# ->>K|# -KK>e? -LL>e? -RR>e? -^^>e? -llAC -ooAC -Rݩ0 -d{Xxk -d{Xxk -d{Xxk -d{Xxk -G9 -G9 -zHd4܊ -zHd4܊ -?N9 -}Nk u -}Nk u -$kR -$kR -mYm -mYm9)'` - - - - - - - - - - -K|# -5 5& -NN5>e?G!' -77K|# -DD>e? -eeAC -zzRݩ0 -d{Xxk -G9 -zHd4܊ -?N9 -}Nk u -$kR -mYm b, -mYmז|0 -NN>e?[% <-%%]> M->>K|#-LL>e?-^^>e?-ooAC -uuAC -Rݩ0-d{Xxk-d{Xxk-d{Xxk-d{Xxk-G9-zHd4܊-zHd4܊-?N9-}Nk u-}Nk u-}Nk u-$kR-$kR-mYmڇ< -G9epQE - -+}E-W{3DܖPG -$kR - * -1W{oY\V -EE >e?*'9w_ - ]> M -'' ]> M6)rf` -d d -  - @Mb -.6 -,4 -"* - -19 -"* -Nzf -?? K|#mYm - & --W{e輚(s -OO >e?}Nk u - * -1W{Z,g@w -rrAC - Rݩ0 -d{Xxk -d{Xxk -zHd4܊ -}Nk u -}Nk u -$kR_[Cx -2:G9 -2:mYm j--G9-mYm&k b -zHd4܊ -?N9W{ - -G9 -'.G9 -mYm -)0mYmRݩ0 -x x- -4W{3n7xĐ -mm AC -rr'AC - Rݩ0 - Rݩ0 - d{Xxk -(d{Xxk - d{Xxk -'d{Xxk - G9 -)G9 - zHd4܊ -'zHd4܊ -?N9 - }Nk u - }Nk u -'}Nk u - }Nk u -'}Nk u -}Nk u - $kR - $kR -($kR -$kR - mYm -)mYme]’ -}Nk u -$kRVX5W -;;K|# -II>e? -jjAC -Rݩ04z, -,,#ԥ -}Nk u -$kRDqUh - - - - - jzk% -%% ->> -LL -^^ -oo -uu - - - - - - - - - - - - - - -혩 -d{Xxk -d{Xxk -d{Xxk -d{XxkUxt -G9 -mYm3A -}Nk u -}Nk u -$kR -$kR}pʹ -?? -NN -N7N; -OO -@D - -  -  -  -  -$( -*.?N9 - + -2W{X:; - -p -,,%lVB͚ -  -%+ -  -%+Nb{O -  - zHd4܊ - & --W{d{Xxk - % -,W{kCn -.. ]> M]> M - " -)W{+V6-<<K|#-==K|#-JJ>e?-KK>e?-QQ>e?-RR>e?-kkAC -llAC -mmAC -ssAC -Rݩ0-Rݩ0-Rݩ0-Rݩ0-Rݩ0-d{Xxk-d{Xxk-d{Xxk-d{Xxk-d{Xxk-d{Xxk-d{Xxk-d{Xxk-d{Xxk-d{Xxk-G9-G9-G9-zHd4܊-zHd4܊-zHd4܊-zHd4܊- ?N9- ?N9- ?N9-}Nk u-}Nk u-}Nk u-}Nk u-}Nk u-}Nk u-}Nk u-}Nk u- }Nk u-$kR-$kR-$kR-$kR-$kR-$kR- $kR-mYm-mYm-mYm>e? -B B+ -2W{ѢF 1 -<< -== -JJ -KK -QQ -RR -kk -ll -mm -ss - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -OA_ض -""]> M -**]> M -00]> M䔸s Aе - -SĆ-  ]> M-##]> M-((]> M-++]> M-,,]> M-11]> M-ppAC -d{Xxk-d{Xxk-G9-G9-zHd4܊-zHd4܊-?N9-}Nk u-}Nk u-}Nk u-$kR-$kR-$kR-mYm-mYm-mYmrelasrcs,31/4;-j fi,3:;4/0576982.17892:65.0cmdl,(**$ '     !#"%+&)nss_wrapper-1.1.16/.cache/clangd/index/nss_nwrap.c.6CD8D6240BEF45A7.idx000644 001750 000144 00000012326 14460665461 024525 0ustar00asnusers000000 000000 RIFFCdIxmetastri>xT]O0r=ЄĤ>LL< mEƾqMۺv_봤iJ%D\0Q_N.µ(Cqi1gN| BF'ZпJQdA@_Τ1sD;oYUV2&.+k4JL;.c jp:TVƩ9PRk >=%# ;A A=%# ;Ǧ ;4ex#+ ;zLI, ;(-#mlh ; #mlh ; e ; e ; =%# ; =%#ޕ>+ ; 2J(v7`}aۯss1#l䏫/Ծ@7X}8[0ѠHh11xf}!%%^}fqȭ8tGCjqsymb!_li ** refsx4= yZ ++_liߐ$# *!*&_li *4*9_li +'+,_li_li **~s檆 ''relasrcs\i/yinss_wrapper-1.1.16/.cache/clangd/index/test_getaddrinfo.c.641BB471F444137A.idx000644 001750 000144 00000037510 14547751404 025747 0ustar00asnusers000000 000000 RIFF@?CdIxmetastriGxT]o0 R CS}6{4HA_?MĨf@`D'Ү__*sk{h!Ee٤A]N6ToL͘r:'iק xt2q4f2d (b( eӎ̣g F0 ʫ%@6 (w h Qɻ\6z.zH2-QxlhiZꡙ,ܭ޿N,=-ܸʴ?ou-[qZRg5tOOs]eǕ!(MCci}P컏Uǫ?uy>-_jiM:W] ސW+\dY;-uEBΏz|Tw .zͺM%\ $a(RUtwഽ%plRś7BT6*7j[Fyr H- *- *%*C/ D- '- 'xA):n C- 1- 1ІO =- &- &W{ ;--}Zg @- 7- 7  ?- 7- 7eU_l >- &- &&~Ƃ B- (- ( =@ <- "- "[e A- '- '7* G- (- (yt5S F-_ _)-_ _)refs9%  - ' -.W{ G  -77! =@ -!ІO -!&~Ƃ -!%*C/ -!%*C/ -!n})>r -&.eU_l -xA):n _Ú -  =@ - ІO - &~Ƃ - %*C/ - n})>r - %  - eU_l - [e - xA):nVF  -W{AZ I -,, -22 -66 -II -NN -RR -tt - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Ђ X,'--- =@-// =@-HH =@-KK =@-uuyt5S-{{yt5S-yt5S-7*-7*-7*-7*-7*-ІO- ІO-ІO- ІO- &~Ƃ-%*C/-%*C/-%*C/-%*C/-%*C/-n})>r-n})>r-n})>r-% - % -% -% -% -eU_l-eU_l-[e-[e-xA):n-xA):n-xA):n-xA):n-xA):n- -}} yt5S4= yZ'--- =@-// =@-HH =@-KK =@-uuyt5S-{{yt5S-yt5S-7*-7*-7*-7*-7*-ІO- ІO-ІO- ІO- &~Ƃ-%*C/-%*C/-%*C/-%*C/-%*C/-n})>r-n})>r-n})>r-% - % -% -% -% -eU_l-eU_l-[e-[e-xA):n-xA):n-xA):n-xA):n-xA):nԽO? -2"2) -6'6. - -") -") -") -") -") - -") -'. -  - - -n})>r - * -1W{m - - - - - - - - - - - - - - - 9)'` - - - - - - - - - - - - -q m! -)) =@ -EE =@ -qqyt5S -7* -eU_l -[e -.5xA):n~]s5" -$$ =@ -@@ =@ -llyt5S -%  -$.%  -}Zg - (WS# -66% =@ -%eU_l # - -$ - -$;I1g=$ - -öJ$G&, -'' =@ -//" =@ -00& =@ -CC =@ -KK" =@ -LL& =@ -ooyt5S -7* -ІO -ІO -&~Ƃ -"%*C/ -&%*C/ -"%*C/ -&%*C/ -"n})>r -&n})>r -%  -"%  -}Zg - %*C/ - ' -.W{j-7 -77 =@ -ІO -&~Ƃ -%*C/ -%*C/ -n})>r[% <-00 =@-99 =@-LL =@-UU =@-ІO-ІO-&~Ƃ-%*C/-%*C/-%*C/-%*C/-n})>r-n})>r-% -eU_l-[e+}E-W{Q fF - - -$/ - -$/ - -$/ - -$/ - -$/ - -$/ -'3DܖPG -X]I -%% =@ -AA =@ -mmyt5S -7* -ІO -ІO -&~Ƃ -%*C/ -%*C/ -n})>r -%  -}Zg - 5Q -n})>rgݍY) - =@ - =@ -"!") =@ ->!>) =@ -aayt5S -bbyt5S -j!j)yt5S -7* -7* -!)7* -ІO -ІO -!)ІO -!)ІO -&~Ƃ -&~Ƃ -!)&~Ƃ -%*C/ -%*C/ -!)%*C/ -!)%*C/ -n})>r -n})>r -!)n})>r -%  -%  -!)%  -eU_l -eU_l -[e -[e -!)[e -xA):n -xA):n -%-xA):n -}Zg -}Zg -!)}Zg -  -  -!) Qd P\ -$$ =@ -@@ =@ -llyt5S -7* -ІO -"ІO -ІO -"ІO -&~Ƃ -"&~Ƃ -%*C/ -"%*C/ -%*C/ -"%*C/ -n})>r -"n})>r -%  -"%  -xA):n -}Zg - 3_x] -"" =@ ->> =@ -jjyt5S -7* -ІO -ІO -&~Ƃ -%*C/ -%*C/ -n})>r -%  -[e -xA):n -}Zg - 6)rf` - * Ob -  =@ - ІO - &~Ƃ - %*C/ - n})>r - %  - eU_l - [e - xA):n@Mb -N"N* -R)R1 -S S - -"* -  - -"* -  - -"* -)1 -  -' - -{6_d -S(S1 =@ -(1ІO -(1%  -(1[e -xA):ni -%% -AA -mm - -xA):n - 1 -8W{Z,g@w -SS =@ - ІO - %  - eU_l - [e - xA):n - xA):nd\x - 7* - ІO -$/ІO - ІO -$/ІO - &~Ƃ -$/&~Ƃ - %*C/ -$/%*C/ - %*C/ -$/%*C/ - n})>r -$/n})>r -'xA):nІO - & --W{ׂԻz -ІO -ІOW{ -"F -$$ -@@ -ll - -$. - -&  - -'ãL'f - yt5S3Oນ -&& =@ -BB =@ -nnyt5S -7* -%  -xA):n -}Zg - (ai-yt5S-xA):n4z, -DqUh - - - - &Sw -xA):njzk% -00 -99 -LL -UU - - - - - - - - - - - -{O0 /A -(( =@ -44 =@ -DD =@ -PP =@ -ppyt5S -7* -ІO -ІO -&~Ƃ -%*C/ -%*C/ -n})>r -n})>r -%  -%  -eU_l -[e -xA):n -xA):nKǁ - - --HoQp -zz yt5S0Eru -&.ІO -!)n})>r}Zg - 7 ->W{  - 7 ->W{}pʹN - -'' -(( -)) -+ +$ -<< -CC -DD -EE -GG -bb -oo -pp -qq -s s$ -xx - $ - - - - - $ - -'+ - -! - -/3 - -=A - - -# - --1 - -# - - - - - - -)- - -,0 - -)- - - -im -'+ -! -04 - - - - - - - - $ - - -+/ - - $ - - -+/ - - $ - - -+/ - -$( -*.Ҁ -'0ІOnp)({ -  =@ - ІO - &~Ƃ - %*C/ - n})>r - %  - eU_l - [e - xA):nF%@ -RR' =@ -'[eeU_l - & --W{_>. -++ =@ -GG =@ -ssyt5S -yt5S -7* -7* -7* -7* -7* -ІO -ІO -&~Ƃ -%*C/ -%*C/ -n})>r -n})>r -%  -%  -%  -eU_l -[e -xA):n -}Zg -}Zg -}Zg -}Zg -}Zg -}Zg -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -lC -## =@ -22 =@ -?? =@ -NN =@ -kkyt5S -7* -ІO - ІO -ІO - ІO -&~Ƃ - &~Ƃ -%*C/ - %*C/ -%*C/ - %*C/ -n})>r - n})>r -%  - %  - eU_l - eU_l -[e - [e -xA):n - xA):n -xA):n -}Zg -  -  - Nb{O -  -  -  - q_3? -## -?? -kk - - - - - -# - -&~Ƃ - ( -/W{F* - 7* -'xA):n![ -#1 -#1 --+V'--- =@-// =@-HH =@-KK =@-uuyt5S-{{yt5S-yt5S-7*-7*-7*-7*-7*-ІO- ІO-ІO- ІO- &~Ƃ-%*C/-%*C/-%*C/-%*C/-%*C/-n})>r-n})>r-n})>r-% - % -% -% -% -eU_l-eU_l-[e-[e-xA):n-xA):n-xA):n-xA):n-xA):nl:BΤӉ -;; =@ -WW =@ -ww yt5S - yt5S - 7* - 7* - 7* - 7* - 7* - ІO - ІO - &~Ƃ - %*C/ - %*C/ - n})>r - %  - %  - eU_l - [e - xA):n - }Zg - }Zg -  -  -  -  -  -  -  =@ - " -)W{[e - ' -.W{7* - ( -/W{ѢF # --- -// -HH -KK -uu -{{ - - - - - - - - - - - - - - - - - - - - - - - - - - - - -yt5S -_ _) -0W{SĆI-,, =@-22 =@-66 =@-II =@-NN =@-RR =@-ttyt5S-yt5S-7*-7*-7*-7*-7*-ІO-ІO-ІO-ІO-ІO-ІO-ІO-ІO-&~Ƃ-&~Ƃ-&~Ƃ-%*C/-%*C/-%*C/-%*C/-%*C/-%*C/-n})>r-n})>r-n})>r-n})>r-n})>r-% -% -% -% -% -eU_l-eU_l-eU_l-[e-[e-[e-xA):n-xA):n-xA):n-}Zg-}Zg-}Zg-}Zg-}Zg-}Zg- - - - - - - - - - - - - - - - - - relasrcs,3/.:6057-;3֝+,9:3/0465872.119482cmdl,(**$ '     !#"%+&)nss_wrapper-1.1.16/.cache/clangd/index/test_shadow.c.85DFA55943F2551B.idx000644 001750 000144 00000003510 14460665460 024775 0ustar00asnusers000000 000000 RIFF@CdIxmetastrixTۊ@  -ea y^؇^hY&cٞ#ܐN։.cs#ilc6_?m~xGWS3>>kv$;ys`߶t'%/|=,7B}) 4DBKY@3mbbR־(roȼ.!t8-E^zDcrlaIJp b/pa8zWD3#zJ`{V=l|xSj=%93078m-׾zu~&e=ͺ Ɩ?X'PJJ]G[]RlN<{cXX]2u׮울4VݝQ~7q9k`gх`=| LIz*Z)ѹEnaUX p!Q [y#Av}+x*zPnnH ʛi(7fT s }2%1symb]W{ 6-==-==wՃol 8-! !-! !; 7- - refsVF  -@@W{Ђ X,-))wՃol-..wՃol-33wՃol-88wՃol4= yZ-))wՃol-..wՃol-33wՃol-88wՃolmb - ;9)'` -AA -BB[% <-;-;-++wՃol-00wՃol-55wՃol-::wՃol+}E-EEW{3DܖPG -EE։3eel - ; -$$ wՃolލ_z ---wՃol -77wՃolW{ -==g`Bf -"; -"; -++ wՃol -55 wՃoljzk% - - -++ -00 -55 -::}pʹ -$( -E$E( -E*E.`ګ - ;6Nȭf - ; -/7;wՃol -! ! -BB&W{NX)`U --*-1wՃol -0-04wՃol -7*71wՃol -:-:4wՃol>nG -((wՃol -22wՃol < - ;+V-))wՃol-..wՃol-33wՃol-88wՃol; -  -AA&W{ѢF  -)) -.. -33 -88relasrcsw,2-Z7Zף ,340.152/.35/041cmdl,(**$ '     !#"%+&)nss_wrapper-1.1.16/.gitlab-ci.yml000644 001750 000144 00000013565 14641705701 016576 0ustar00asnusers000000 000000 --- variables: BUILD_IMAGES_PROJECT: cmocka/gitlab-build-images FEDORA_BUILD: buildenv-fedora CENTOS7_BUILD: buildenv-centos7 TUMBLEWEED_BUILD: buildenv-tumbleweed MINGW_BUILD: buildenv-mingw UBUNTU_BUILD: buildenv-ubuntu stages: - build - test - analysis centos7/x86_64: stage: test image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS7_BUILD script: - mkdir -p obj && cd obj && cmake3 -DCMAKE_BUILD_TYPE=RelWithDebInfo -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON .. && make -j$(nproc) && ctest --output-on-failure except: - tags artifacts: expire_in: 1 week when: on_failure paths: - obj/ fedora/x86_64: stage: test image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD script: - mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON .. && make -j$(nproc) && ctest --output-on-failure except: - tags artifacts: expire_in: 1 week when: on_failure paths: - obj/ fedora/address-sanitizer: stage: build image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD script: - mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=AddressSanitizer -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON .. && make -j$(nproc) && ctest --output-on-failure except: - tags artifacts: expire_in: 1 week when: on_failure paths: - obj/ fedora/undefined-sanitizer: stage: analysis image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD script: - mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=UndefinedSanitizer -DUNIT_TESTING=ON .. && make -j$(nproc) && ctest --output-on-failure except: - tags artifacts: expire_in: 1 week when: on_failure paths: - obj/ fedora/thread-sanitizer: stage: analysis image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD script: # Workaround for TSAN with ASLR on newer kernel # https://github.com/google/sanitizers/issues/1716 - export TSAN_OPTIONS=second_deadlock_stack=1 - mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=ThreadSanitizer -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON .. && make -j$(nproc) && setarch --addr-no-randomize -- ctest --output-on-failure except: - tags artifacts: expire_in: 1 week when: on_failure paths: - obj/ fedora/csbuild: stage: analysis image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD script: - | if [[ -z "$CI_COMMIT_BEFORE_SHA" ]]; then export CI_COMMIT_BEFORE_SHA=$(git rev-parse "${CI_COMMIT_SHA}~20") fi # Check if the commit exists in this branch # This is not the case for a force push git branch --contains $CI_COMMIT_BEFORE_SHA 2>/dev/null || export CI_COMMIT_BEFORE_SHA=$(git rev-parse "${CI_COMMIT_SHA}~20") export CI_COMMIT_RANGE="$CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA" - csbuild --build-dir=obj-csbuild --prep-cmd="cmake -DCMAKE_BUILD_TYPE=Debug -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON @SRCDIR@" --build-cmd "make clean && make -j$(nproc)" --git-commit-range $CI_COMMIT_RANGE --color --print-current --print-fixed except: - tags artifacts: expire_in: 1 week when: on_failure paths: - obj-csbuild/ freebsd/x86_64: stage: test image: script: - mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON .. && make && ctest --output-on-failure tags: - freebsd except: - tags only: - branches@cwrap/nss_wrapper - branches@cryptomilk/nss_wrapper artifacts: expire_in: 1 week when: on_failure paths: - obj/ tumbleweed/x86_64/gcc: stage: test image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD script: - mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON .. && make -j$(nproc) && ctest --output-on-failure except: - tags artifacts: expire_in: 1 week when: on_failure paths: - obj/ tumbleweed/x86_64/gcc7: stage: test image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD script: - mkdir -p obj && cd obj && cmake -DCMAKE_C_COMPILER=gcc-7 -DCMAKE_CXX_COMPILER=g++-7 -DCMAKE_BUILD_TYPE=RelWithDebInfo -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON .. && make -j$(nproc) && ctest --output-on-failure except: - tags artifacts: expire_in: 1 week when: on_failure paths: - obj/ tumbleweed/x86_64/clang: stage: test image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD script: - mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON .. && make -j$(nproc) && ctest --output-on-failure except: - tags artifacts: expire_in: 1 week when: on_failure paths: - obj/ tumbleweed/static-analysis: stage: analysis image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD script: - export CCC_CC=clang - export CCC_CXX=clang++ - mkdir -p obj && cd obj && scan-build cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON .. && scan-build --status-bugs -o scan make -j$(nproc) except: - tags artifacts: expire_in: 1 week when: on_failure paths: - obj/scan ubuntu/x86_64: stage: test image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$UBUNTU_BUILD script: - mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON .. && make -j$(nproc) && ctest --output-on-failure except: - tags artifacts: expire_in: 1 week when: on_failure paths: - obj/ nss_wrapper-1.1.16/0001-Bump-version-to-1.1.15.patch000644 001750 000144 00000002437 14373730741 021270 0ustar00asnusers000000 000000 From db887c00d35b1504abe72a30fe386111e9a25ed2 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 25 Jan 2023 12:43:23 +0100 Subject: [PATCH 1/2] Bump version to 1.1.15 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Schneider Reviewed-by: Pavel Filipenský --- CHANGELOG | 4 ++++ CMakeLists.txt | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index aed76b3..2cd0423 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,10 @@ 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() diff --git a/CMakeLists.txt b/CMakeLists.txt index bd3b663..2f7c91a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules") include(DefineCMakeDefaults) include(DefineCompilerFlags) -project(nss_wrapper VERSION 1.1.14 LANGUAGES C) +project(nss_wrapper VERSION 1.1.15 LANGUAGES C) # global needed variables set(APPLICATION_NAME ${PROJECT_NAME}) -- 2.39.2 nss_wrapper-1.1.16/0001-cmake-Fix-cmocka-1.1.6-find_package-in-CONFIG-mode.patch000644 001750 000144 00000001364 14373730743 026123 0ustar00asnusers000000 000000 From 869ba407ce60d9f2d233b619acf95f90f515509b Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 17 Feb 2023 17:51:27 +0100 Subject: [PATCH] cmake: Fix cmocka >= 1.1.6 find_package() in CONFIG mode Signed-off-by: Andreas Schneider --- tests/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3b94076..733cc4e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,5 +1,9 @@ project(tests C) +if (TARGET cmocka::cmocka) + set(CMOCKA_LIBRARY cmocka::cmocka) +endif() + set(TESTSUITE_LIBRARIES nss_utils ${NWRAP_REQUIRED_LIBRARIES} ${CMOCKA_LIBRARY}) string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER) -- 2.39.2 nss_wrapper-1.1.16/ConfigureChecks.cmake000644 001750 000144 00000025273 14641705104 020202 0ustar00asnusers000000 000000 include(CheckIncludeFile) include(CheckSymbolExists) include(CheckFunctionExists) include(CheckLibraryExists) include(CheckTypeSize) include(CheckStructHasMember) include(CheckPrototypeDefinition) include(TestBigEndian) include(CheckCSourceRuns) set(PACKAGE ${PROJECT_NAME}) set(VERSION ${PROJECT_VERSION}) set(DATADIR ${DATA_INSTALL_DIR}) set(LIBDIR ${LIB_INSTALL_DIR}) set(PLUGINDIR "${PLUGIN_INSTALL_DIR}-${LIBRARY_SOVERSION}") set(SYSCONFDIR ${SYSCONF_INSTALL_DIR}) set(BINARYDIR ${CMAKE_BINARY_DIR}) set(SOURCEDIR ${CMAKE_SOURCE_DIR}) function(COMPILER_DUMPVERSION _OUTPUT_VERSION) # Remove whitespaces from the argument. # This is needed for CC="ccache gcc" cmake .. string(REPLACE " " "" _C_COMPILER_ARG "${CMAKE_C_COMPILER_ARG1}") execute_process( COMMAND ${CMAKE_C_COMPILER} ${_C_COMPILER_ARG} -dumpversion OUTPUT_VARIABLE _COMPILER_VERSION ) string(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2" _COMPILER_VERSION "${_COMPILER_VERSION}") set(${_OUTPUT_VERSION} ${_COMPILER_VERSION} PARENT_SCOPE) endfunction() if(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2) compiler_dumpversion(GNUCC_VERSION) if (NOT GNUCC_VERSION EQUAL 34) set(CMAKE_REQUIRED_FLAGS "-fvisibility=hidden") check_c_source_compiles( "void __attribute__((visibility(\"default\"))) test() {} int main(void){ return 0; } " WITH_VISIBILITY_HIDDEN) set(CMAKE_REQUIRED_FLAGS "") endif (NOT GNUCC_VERSION EQUAL 34) endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2) # HEADERS check_include_file(sys/types.h HAVE_SYS_TYPES_H) check_include_file(pwd.h HAVE_PWD_H) check_include_file(shadow.h HAVE_SHADOW_H) check_include_file(grp.h HAVE_GRP_H) check_include_file(nss.h HAVE_NSS_H) check_include_file(nss_common.h HAVE_NSS_COMMON_H) check_include_file(gnu/lib-names.h HAVE_GNU_LIB_NAMES_H) # FUNCTIONS check_function_exists(strncpy HAVE_STRNCPY) check_function_exists(vsnprintf HAVE_VSNPRINTF) check_function_exists(snprintf HAVE_SNPRINTF) check_function_exists(getpwnam_r HAVE_GETPWNAM_R) check_function_exists(getpwuid_r HAVE_GETPWUID_R) check_function_exists(getpwent_r HAVE_GETPWENT_R) check_function_exists(setspent HAVE_SETSPENT) check_function_exists(getspnam HAVE_GETSPNAM) check_function_exists(getgrnam_r HAVE_GETGRNAM_R) check_function_exists(getgrgid_r HAVE_GETGRGID_R) check_function_exists(getgrent_r HAVE_GETGRENT_R) check_function_exists(getgrouplist HAVE_GETGROUPLIST) check_function_exists(gethostbyaddr_r HAVE_GETHOSTBYADDR_R) check_function_exists(gethostbyname_r HAVE_GETHOSTBYNAME_R) check_function_exists(gethostbyname2 HAVE_GETHOSTBYNAME2) check_function_exists(gethostbyname2_r HAVE_GETHOSTBYNAME2_R) check_function_exists(getprogname HAVE_GETPROGNAME) check_function_exists(getexecname HAVE_GETEXECNAME) if (WIN32) check_function_exists(_vsnprintf_s HAVE__VSNPRINTF_S) check_function_exists(_vsnprintf HAVE__VSNPRINTF) check_function_exists(_snprintf HAVE__SNPRINTF) check_function_exists(_snprintf_s HAVE__SNPRINTF_S) endif (WIN32) if (UNIX) if (NOT LINUX) # libsocket (Solaris) check_library_exists(socket getaddrinfo "" HAVE_LIBSOCKET) if (HAVE_LIBSOCKET) list(APPEND _REQUIRED_LIBRARIES socket) endif (HAVE_LIBSOCKET) # libnsl/inet_pton (Solaris) check_library_exists(nsl inet_pton "" HAVE_LIBNSL) if (HAVE_LIBNSL) list(APPEND _REQUIRED_LIBRARIES nsl) endif (HAVE_LIBNSL) endif (NOT LINUX) check_function_exists(getaddrinfo HAVE_GETADDRINFO) endif (UNIX) if (SOLARIS) check_function_exists(__posix_getpwnam_r HAVE___POSIX_GETPWNAM_R) check_function_exists(__posix_getpwuid_r HAVE___POSIX_GETPWUID_R) check_function_exists(__posix_getgrgid_r HAVE___POSIX_GETGRGID_R) check_function_exists(__posix_getgrnam_r HAVE___POSIX_GETGRNAM_R) endif (SOLARIS) check_function_exists(asprintf HAVE_ASPRINTF) if (UNIX AND HAVE_ASPRINTF) add_definitions(-D_GNU_SOURCE) endif (UNIX AND HAVE_ASPRINTF) set(CMAKE_REQUIRED_DEFINITIONS -D_POSIX_PTHREAD_SEMANTICS) check_prototype_definition(getpwent_r "struct passwd *getpwent_r(struct passwd *src, char *buf, int buflen)" "NULL" "unistd.h;pwd.h" HAVE_SOLARIS_GETPWENT_R) check_prototype_definition(getpwnam_r "int getpwnam_r(const char *name, struct passwd *pwd, char *buf, int buflen, struct passwd **ppwd)" "-1" "unistd.h;pwd.h" HAVE_SOLARIS_GETPWNAM_R) check_prototype_definition(getpwuid_r "int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, int buflen, struct passwd **ppwd)" "-1" "unistd.h;pwd.h" HAVE_SOLARIS_GETPWUID_R) check_prototype_definition(getgrent_r "struct group *getgrent_r(struct group *src, char *buf, int buflen)" "NULL" "unistd.h;grp.h" HAVE_SOLARIS_GETGRENT_R) check_prototype_definition(getgrnam_r "int getgrnam_r(const char *name, struct group *grp, char *buf, int buflen, struct group **pgrp)" "-1" "unistd.h;grp.h" HAVE_SOLARIS_GETGRNAM_R) check_prototype_definition(getgrgid_r "int getgrgid_r(gid_t gid, struct group *grp, char *buf, int buflen, struct group **pgrp)" "-1" "unistd.h;grp.h" HAVE_SOLARIS_GETGRGID_R) check_prototype_definition(sethostent "int sethostent(int stayopen)" "-1" "unistd.h;netdb.h" HAVE_SOLARIS_SETHOSTENT) check_prototype_definition(endhostent "int endhostent(void)" "-1" "unistd.h;netdb.h" HAVE_SOLARIS_ENDHOSTENT) check_prototype_definition(gethostname "int gethostname(char *name, int len)" "-1" "unistd.h;netdb.h" HAVE_SOLARIS_GETHOSTNAME) set(CMAKE_REQUIRED_DEFINITIONS) check_prototype_definition(setgrent "int setgrent(void)" "-1" "unistd.h;grp.h" HAVE_BSD_SETGRENT) check_prototype_definition(getnameinfo "int getnameinfo (const struct sockaddr *sa, socklen_t salen, char *host, socklen_t __hostlen, char *serv, socklen_t servlen, int flags)" "-1" "unistd.h;netdb.h" HAVE_LINUX_GETNAMEINFO) check_prototype_definition(getnameinfo "int getnameinfo (const struct sockaddr *sa, socklen_t salen, char *host, socklen_t __hostlen, char *serv, socklen_t servlen, unsigned int flags)" "-1" "unistd.h;netdb.h" HAVE_LINUX_GETNAMEINFO_UNSIGNED) # STRUCT MEMBERS check_struct_has_member("struct sockaddr" sa_len "sys/socket.h netinet/in.h" HAVE_STRUCT_SOCKADDR_SA_LEN) check_struct_has_member("struct passwd" pw_class "pwd.h" HAVE_STRUCT_PASSWD_PW_CLASS) check_struct_has_member("struct passwd" pw_change "pwd.h" HAVE_STRUCT_PASSWD_PW_CHANGE) check_struct_has_member("struct passwd" pw_expire "pwd.h" HAVE_STRUCT_PASSWD_PW_EXPIRE) # IPV6 check_c_source_compiles(" #include #include #include #include #include int main(void) { struct sockaddr_storage sa_store; struct addrinfo *ai = NULL; struct in6_addr in6addr; int idx = if_nametoindex(\"iface1\"); int s = socket(AF_INET6, SOCK_STREAM, 0); int ret = getaddrinfo(NULL, NULL, NULL, &ai); if (ret != 0) { const char *es = gai_strerror(ret); } freeaddrinfo(ai); { int val = 1; #ifdef HAVE_LINUX_IPV6_V6ONLY_26 #define IPV6_V6ONLY 26 #endif ret = setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (const void *)&val, sizeof(val)); } return 0; }" HAVE_IPV6) check_c_source_compiles(" void log_fn(const char *format, ...) __attribute__ ((format (printf, 1, 2))); int main(void) { return 0; }" HAVE_ATTRIBUTE_PRINTF_FORMAT) check_c_source_compiles(" void test_constructor_attribute(void) __attribute__ ((constructor)); void test_constructor_attribute(void) { return; } int main(void) { return 0; }" HAVE_CONSTRUCTOR_ATTRIBUTE) check_c_source_compiles(" void test_destructor_attribute(void) __attribute__ ((destructor)); void test_destructor_attribute(void) { return; } int main(void) { return 0; }" HAVE_DESTRUCTOR_ATTRIBUTE) check_c_source_compiles(" #pragma init (test_constructor) void test_constructor(void); void test_constructor(void) { return; } int main(void) { return 0; }" HAVE_PRAGMA_INIT) check_c_source_compiles(" #pragma fini (test_destructor) void test_destructor(void); void test_destructor(void) { return; } int main(void) { return 0; }" HAVE_PRAGMA_FINI) find_library(DLFCN_LIBRARY dl) if (DLFCN_LIBRARY) list(APPEND _REQUIRED_LIBRARIES ${DLFCN_LIBRARY}) else() check_function_exists(dlopen HAVE_DLOPEN) if (NOT HAVE_DLOPEN) message(FATAL_ERROR "FATAL: No dlopen() function detected") endif() endif() # ENDIAN if (NOT WIN32) test_big_endian(WORDS_BIGENDIAN) endif (NOT WIN32) if (NOT CMAKE_CROSSCOMPILING) # check whether getaddrinfo() returns "node" in "ai_canonname" for IP-addresses check_c_source_runs("#include #include #include #include #include int main(void) { struct addrinfo hints; struct addrinfo *res = NULL; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV; if (getaddrinfo(\"0.0.0.0\", \"389\", &hints, &res) != 0) { return 2; } if (res == NULL) { return 3; } return strncmp(res->ai_canonname, \"0.0.0.0\", sizeof(\"0.0.0.0\")) != 0; }" HAVE_GETADDRINFO_SETS_CANONNAME_FOR_IPADDRESSES) # Check whether getaddrinfo() returns EAI_SERVICE when the requested # service is not available for the requested socket type. check_c_source_runs("#include #include #include #include #include int main(void) { struct addrinfo hints; struct addrinfo *res = NULL; int rc; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV; /* For wildcard IP address */ hints.ai_protocol = 0; /* Any protocol */ hints.ai_canonname = NULL; rc = getaddrinfo(NULL, \"echo\", &hints, &res); return rc != EAI_SERVICE; }" HAVE_GETADDRINFO_USES_EAI_SERVICE) # Check for non-NULL gethostent() check_c_source_runs("#include #include int main(void) { struct hostent *hostent = NULL; sethostent(0); hostent = gethostent(); endhostent(); return hostent == NULL; }" HAVE_NONNULL_GETHOSTENT) endif (NOT CMAKE_CROSSCOMPILING) set(NWRAP_REQUIRED_LIBRARIES ${_REQUIRED_LIBRARIES} CACHE INTERNAL "nss_wrapper required system libraries") nss_wrapper-1.1.16/TODO000644 001750 000144 00000000453 13634203624 014620 0ustar00asnusers000000 000000 TODO ===== Library -------- * Replace hcreate() as it messes with applications also using it. Testing -------- * Split the testsuite in several tests. * Add missing tests. Check the code coverage on http://mock.cryptomilk.org/index.php?project=nsswrapper to see what tests are still needed. nss_wrapper-1.1.16/CHANGELOG000644 001750 000144 00000006436 14641727522 015360 0ustar00asnusers000000 000000 ChangeLog ========== version 1.1.16 (released 2024-07-05) * Fixed segfault on FreeBSD * Fixed copy&paste error in the destructor * Fixed thread sanitizer on modern Linux Kernels * Fixed building with newer cmocka versions 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 version 1.1.12 (released 2022-06-24) * Added (de)contructor support on AIX with pragma init/finish * Fixed possible crash in getaddrinfo() * Fixed issues with processes closing all fds when forking * Fixed issues with setgrent() and endpwent() nss module support version 1.1.11 (released 2020-04-02) * Fixed strict aliasing issues on armv7hl (32bit) version 1.1.10 (released 2020-03-19) * Fixed crash bug in OpenLDAP libraries with gethostbyname_r() * Code cleanup in gethostbyname(2)(_r) functions version 1.1.9 (released 2020-03-16) * Fixed log spam when loading modules version 1.1.8 (released 2020-02-17) * Fixed path to library in nss_wrapper.pc * Try different backends for gethostbyaddr nd gethostbyname version 1.1.7 (released 2019-11-11) * Added NSS_WRAPPER_DISABLE_DEEPBIND env variable * Improvded logging * Fixed location in cmake config version 1.1.6 (released 2019-05-19) * Fixed issues with memory alignment of getgrnam() * Fixed getpwnam() on FreeBSD * Started to use modern cmake (>= 3.5.0) version 1.1.5 (released 2018-10-31) * Fixed running on older distributions version 1.1.4 (released 2018-10-31) * Fixed module getpw* functions * Fixed nss_wrapper.pl to use correct perl binary * Fixed compatibility with musl-libc version 1.1.3 (released 2015-03-18) * Added support for BSD 'struct passwd' members * Replaced strcpy() with snprintf() version 1.1.2 (released 2015-12-17) * Fixed segfault while reloading hosts file * Fixed issue where are not fault tolerant if an alias has already been added version 1.1.1 (released 2015-11-23) * Fixed nss_wrapper build on Solaris version 1.1.0 (released 2015-11-20) * Added support for initgroups() * Added support for shadow files (getspnam(), etc.) * Improved support for multi address handling in getaddrinfo() * Improved file parser * Fixed compilation on machines without IPv4 support * Fixed service string sanity check in getaddrinfo() (bso #11501) * Fixed AI_NUMERICHOST handling in getaddrinfo() (bso # 11477) version 1.0.3 (released 2014-09-11) * Added a nss_wrapper manpage. * Fixed cmake find_package configs. * Fixed resolving hostnames with a trailing dot. * Fixed an overflow when checking if a IPv6 address is IPv4. * Fall back to RTLD_NEXT for symbol binding if we can't find libc. version 1.0.2 (released 2014-04-08) * Added public nss_wrapper_enabled(). * Added public nss_wrapper_hosts_enabled(). * Fixed segfault in 'getent hosts' without aliases. * Fixed IPv4 and IPv6 resolving with 'getent ahosts'. version 1.0.1 (released 2014-02-04) * Added --libs to pkg-config. * Added nss_wrapper-config.cmake * Fixed a bug packaging the obj directory. version 1.0.0 (released 2014-02-02) * Initial release nss_wrapper-1.1.16/doc/000755 001750 000144 00000000000 14641730071 014673 5ustar00asnusers000000 000000 nss_wrapper-1.1.16/doc/CMakeLists.txt000644 001750 000144 00000000146 13634203624 017434 0ustar00asnusers000000 000000 install(FILES nss_wrapper.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) nss_wrapper-1.1.16/doc/nss_wrapper.1.adoc000644 001750 000144 00000007720 14641727522 020242 0ustar00asnusers000000 000000 nss_wrapper(1) ============== :revdate: 2019-05-21 :author: Samba Team NAME ---- nss_wrapper - A wrapper for the user, group and hosts NSS API SYNOPSIS -------- LD_PRELOAD=libnss_wrapper.so NSS_WRAPPER_PASSWD=/path/to/passwd NSS_WRAPPER_GROUP=/path/to/group NSS_WRAPPER_HOSTS=/path/to/host *./myapplication* DESCRIPTION ----------- There are projects which provide daemons needing to be able to create, modify and delete Unix users. Or just switch user ids to interact with the system e.g. a user space file server. To be able to test that you need the privilege to modify the passwd and groups file. With nss_wrapper it is possible to define your own passwd and groups file which will be used by software to act correctly while under test. If you have a client and server under test they normally use functions to resolve network names to addresses (dns) or vice versa. The nss_wrappers allow you to create a hosts file to setup name resolution for the addresses you use with socket_wrapper. - Provides information for user and group accounts. - Network name resolution using a hosts file. - Loading and testing of NSS modules. LIMITATIONS ----------- Some calls in nss_wrapper will only work if uid_wrapper is loaded and active. One of this functions is initgroups() which needs to run setgroups() to set the groups for the user. setgroups() is wrapped by uid_wrapper. ENVIRONMENT VARIABLES --------------------- *NSS_WRAPPER_PASSWD*:: *NSS_WRAPPER_GROUP*:: For user and group accounts you need to create two files: 'passwd' and 'group'. The format of the passwd file we support is: name:password:UID:GID:GECOS:directory:shell The format of the group file we support is: group_name:password:GID:user_list They are also described in 'man passwd.5' and 'man group.5' on Linux. You can fill these files with made up accounts. You point nss_wrapper to them using the two variables NSS_WRAPPER_PASSWD=/path/to/your/passwd and NSS_WRAPPER_GROUP=/path/to/your/group. *NSS_WRAPPER_HOSTS*:: If you also need to emulate network name resolution in your environment, especially with socket_wrapper, you can write a hosts file. The format is described in 'man 5 hosts'. Then you can point nss_wrapper to your hosts file using: NSS_WRAPPER_HOSTS=/path/to/your/hosts *NSS_WRAPPER_HOSTNAME*:: If you need to return a hostname which is different from the one of your machine is using you can use: NSS_WRAPPER_HOSTNAME=test.example.org *NSS_WRAPPER_MODULE_SO_PATH*:: *NSS_WRAPPER_MODULE_FN_PREFIX*:: If you have a project which also provides user and group information out of a database, you normally write your own nss modules. nss_wrapper is able to load nss modules and ask them first before looking into the faked passwd and group file. To point nss_wrapper to the module you can do that using NSS_WRAPPER_MODULE_SO_PATH=/path/to/libnss_yourmodule.so. As each nss module has a special prefix like _nss_winbind_getpwnam() you need to set the prefix too so nss_wrapper can load the functions with NSS_WRAPPER_MODULE_FN_PREFIX=. For _nss_winbind_getpwnam() this would be: NSS_WRAPPER_MODULE_FN_PREFIX=winbind *NSS_WRAPPER_DEBUGLEVEL*:: If you need to see what is going on in nss_wrapper itself or try to find a bug, you can enable logging support in nss_wrapper if you built it with debug symbols. - 0 = ERROR - 1 = WARNING - 2 = DEBUG - 3 = TRACE *NSS_WRAPPER_DISABLE_DEEPBIND*:: This allows you to disable deep binding in nss_wrapper. This is useful for running valgrind tools or sanitizers like (address, undefined, thread). EXAMPLE ------- $ echo "bob:x:1000:1000:bob gecos:/home/test/bob:/bin/false" > passwd $ echo "root:x:65534:65532:root gecos:/home/test/root:/bin/false" >> passwd $ echo "users:x:1000:" > group $ echo "root:x:65532:" >> group $ LD_PRELOAD=libnss_wrapper.so NSS_WRAPPER_PASSWD=passwd \ NSS_WRAPPER_GROUP=group getent passwd bob bob:x:1000:1000:bob gecos:/home/test/bob:/bin/false $ LD_PRELOAD=libnss_wrapper.so NSS_WRAPPER_HOSTNAME=test.example.org hostname test.example.org nss_wrapper-1.1.16/doc/nss_wrapper.1000644 001750 000144 00000012136 14641727522 017332 0ustar00asnusers000000 000000 '\" t .\" Title: nss_wrapper .\" Author: Samba Team .\" Generator: Asciidoctor 2.0.23 .\" Date: 2024-07-05 .\" Manual: \ \& .\" Source: \ \& .\" Language: English .\" .TH "NSS_WRAPPER" "1" "2024-07-05" "\ \&" "\ \&" .ie \n(.g .ds Aq \(aq .el .ds Aq ' .ss \n[.ss] 0 .nh .ad l .de URL \fI\\$2\fP <\\$1>\\$3 .. .als MTO URL .if \n[.g] \{\ . mso www.tmac . am URL . ad l . . . am MTO . ad l . . . LINKSTYLE blue R < > .\} .SH "NAME" nss_wrapper \- A wrapper for the user, group and hosts NSS API .SH "SYNOPSIS" .sp LD_PRELOAD=libnss_wrapper.so NSS_WRAPPER_PASSWD=/path/to/passwd NSS_WRAPPER_GROUP=/path/to/group NSS_WRAPPER_HOSTS=/path/to/host \fB./myapplication\fP .SH "DESCRIPTION" .sp There are projects which provide daemons needing to be able to create, modify and delete Unix users. Or just switch user ids to interact with the system e.g. a user space file server. To be able to test that you need the privilege to modify the passwd and groups file. With nss_wrapper it is possible to define your own passwd and groups file which will be used by software to act correctly while under test. .sp If you have a client and server under test they normally use functions to resolve network names to addresses (dns) or vice versa. The nss_wrappers allow you to create a hosts file to setup name resolution for the addresses you use with socket_wrapper. .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ . sp -1 . IP \(bu 2.3 .\} Provides information for user and group accounts. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ . sp -1 . IP \(bu 2.3 .\} Network name resolution using a hosts file. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ . sp -1 . IP \(bu 2.3 .\} Loading and testing of NSS modules. .RE .SH "LIMITATIONS" .sp Some calls in nss_wrapper will only work if uid_wrapper is loaded and active. One of this functions is initgroups() which needs to run setgroups() to set the groups for the user. setgroups() is wrapped by uid_wrapper. .SH "ENVIRONMENT VARIABLES" .sp \fBNSS_WRAPPER_PASSWD\fP, \fBNSS_WRAPPER_GROUP\fP .RS 4 For user and group accounts you need to create two files: \fIpasswd\fP and \fIgroup\fP. The format of the passwd file we support is: .RE .sp name:password:UID:GID:GECOS:directory:shell .sp The format of the group file we support is: .sp group_name:password:GID:user_list .sp They are also described in \fIman passwd.5\fP and \fIman group.5\fP on Linux. You can fill these files with made up accounts. You point nss_wrapper to them using the two variables NSS_WRAPPER_PASSWD=/path/to/your/passwd and NSS_WRAPPER_GROUP=/path/to/your/group. .sp \fBNSS_WRAPPER_HOSTS\fP .RS 4 If you also need to emulate network name resolution in your environment, especially with socket_wrapper, you can write a hosts file. The format is described in \fIman 5 hosts\fP. Then you can point nss_wrapper to your hosts file using: NSS_WRAPPER_HOSTS=/path/to/your/hosts .RE .sp \fBNSS_WRAPPER_HOSTNAME\fP .RS 4 If you need to return a hostname which is different from the one of your machine is using you can use: NSS_WRAPPER_HOSTNAME=test.example.org .RE .sp \fBNSS_WRAPPER_MODULE_SO_PATH\fP, \fBNSS_WRAPPER_MODULE_FN_PREFIX\fP .RS 4 If you have a project which also provides user and group information out of a database, you normally write your own nss modules. nss_wrapper is able to load nss modules and ask them first before looking into the faked passwd and group file. To point nss_wrapper to the module you can do that using NSS_WRAPPER_MODULE_SO_PATH=/path/to/libnss_yourmodule.so. As each nss module has a special prefix like _nss_winbind_getpwnam() you need to set the prefix too so nss_wrapper can load the functions with NSS_WRAPPER_MODULE_FN_PREFIX=. .RE .sp For _nss_winbind_getpwnam() this would be: .sp .if n .RS 4 .nf .fam C NSS_WRAPPER_MODULE_FN_PREFIX=winbind .fam .fi .if n .RE .sp \fBNSS_WRAPPER_DEBUGLEVEL\fP .RS 4 If you need to see what is going on in nss_wrapper itself or try to find a bug, you can enable logging support in nss_wrapper if you built it with debug symbols. .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ . sp -1 . IP \(bu 2.3 .\} 0 = ERROR .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ . sp -1 . IP \(bu 2.3 .\} 1 = WARNING .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ . sp -1 . IP \(bu 2.3 .\} 2 = DEBUG .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ . sp -1 . IP \(bu 2.3 .\} 3 = TRACE .RE .RE .sp \fBNSS_WRAPPER_DISABLE_DEEPBIND\fP .RS 4 This allows you to disable deep binding in nss_wrapper. This is useful for running valgrind tools or sanitizers like (address, undefined, thread). .RE .SH "EXAMPLE" .sp .if n .RS 4 .nf .fam C $ echo "bob:x:1000:1000:bob gecos:/home/test/bob:/bin/false" > passwd $ echo "root:x:65534:65532:root gecos:/home/test/root:/bin/false" >> passwd $ echo "users:x:1000:" > group $ echo "root:x:65532:" >> group $ LD_PRELOAD=libnss_wrapper.so NSS_WRAPPER_PASSWD=passwd \(rs NSS_WRAPPER_GROUP=group getent passwd bob bob:x:1000:1000:bob gecos:/home/test/bob:/bin/false $ LD_PRELOAD=libnss_wrapper.so NSS_WRAPPER_HOSTNAME=test.example.org hostname test.example.org .fam .fi .if n .RE .SH "AUTHOR" .sp Samba Teamnss_wrapper-1.1.16/doc/README000644 001750 000144 00000000275 14641727522 015566 0ustar00asnusers000000 000000 The manpage is written with asciidoc. To generate the manpage use: asciidoctor -b manpage doc/nss_wrapper.1.adoc or a2x --doctype manpage --format manpage doc/nss_wrapper.1.adoc nss_wrapper-1.1.16/config.h.cmake000644 001750 000144 00000007050 14641705104 016624 0ustar00asnusers000000 000000 /* Name of package */ #cmakedefine PACKAGE "${PROJECT_NAME}" /* Version number of package */ #cmakedefine VERSION "${PROJECT_VERSION}" #cmakedefine LOCALEDIR "${LOCALE_INSTALL_DIR}" #cmakedefine DATADIR "${DATADIR}" #cmakedefine LIBDIR "${LIBDIR}" #cmakedefine PLUGINDIR "${PLUGINDIR}" #cmakedefine SYSCONFDIR "${SYSCONFDIR}" #cmakedefine BINARYDIR "${BINARYDIR}" #cmakedefine SOURCEDIR "${SOURCEDIR}" /************************** HEADER FILES *************************/ #cmakedefine HAVE_SYS_TYPES_H 1 #cmakedefine HAVE_PWD_H 1 #cmakedefine HAVE_SHADOW_H 1 #cmakedefine HAVE_GRP_H 1 #cmakedefine HAVE_NSS_H 1 #cmakedefine HAVE_NSS_COMMON_H 1 #cmakedefine HAVE_GNU_LIB_NAMES_H 1 /*************************** FUNCTIONS ***************************/ /* Define to 1 if you have the `getpwnam_r' function. */ #cmakedefine HAVE_GETPWNAM_R 1 /* Define to 1 if you have the `getpwuid_r' function. */ #cmakedefine HAVE_GETPWUID_R 1 /* Define to 1 if you have the `getpwent_r' function. */ #cmakedefine HAVE_GETPWENT_R 1 /* Define to 1 if you have the `setspent' function. */ #cmakedefine HAVE_SETSPENT 1 /* Define to 1 if you have the `getspnam' function. */ #cmakedefine HAVE_GETSPNAM 1 /* Define to 1 if you have the `getgrnam_r' function. */ #cmakedefine HAVE_GETGRNAM_R 1 /* Define to 1 if you have the `getgrgid_r' function. */ #cmakedefine HAVE_GETGRGID_R 1 /* Define to 1 if you have the `getgrent_r' function. */ #cmakedefine HAVE_GETGRENT_R 1 /* Define to 1 if you have the `getgrouplist' function. */ #cmakedefine HAVE_GETGROUPLIST 1 /* Define to 1 if you have the `gethostbyaddr_r' function. */ #cmakedefine HAVE_GETHOSTBYADDR_R 1 /* Define to 1 if you have the `gethostbyname_r' function. */ #cmakedefine HAVE_GETHOSTBYNAME_R 1 /* Define to 1 if you have the `gethostbyname2' function. */ #cmakedefine HAVE_GETHOSTBYNAME2 1 /* Define to 1 if you have the `gethostbyname2_r' function. */ #cmakedefine HAVE_GETHOSTBYNAME2_R 1 #cmakedefine HAVE_GETPROGNAME 1 #cmakedefine HAVE_GETEXECNAME 1 #cmakedefine HAVE___POSIX_GETPWNAM_R 1 #cmakedefine HAVE___POSIX_GETPWUID_R 1 #cmakedefine HAVE___POSIX_GETGRGID_R 1 #cmakedefine HAVE___POSIX_GETGRNAM_R 1 /*************************** LIBRARIES ***************************/ #cmakedefine HAVE_LIBNSL 1 #cmakedefine HAVE_LIBSOCKET 1 /**************************** OPTIONS ****************************/ #cmakedefine HAVE_SOLARIS_GETPWENT_R 1 #cmakedefine HAVE_SOLARIS_GETPWNAM_R 1 #cmakedefine HAVE_SOLARIS_GETPWUID_R 1 #cmakedefine HAVE_SOLARIS_GETGRENT_R 1 #cmakedefine HAVE_SOLARIS_GETGRNAM_R 1 #cmakedefine HAVE_SOLARIS_GETGRGID_R 1 #cmakedefine HAVE_SOLARIS_SETHOSTENT 1 #cmakedefine HAVE_SOLARIS_ENDHOSTENT 1 #cmakedefine HAVE_SOLARIS_GETHOSTNAME 1 #cmakedefine HAVE_BSD_SETGRENT 1 #cmakedefine HAVE_LINUX_GETNAMEINFO 1 #cmakedefine HAVE_LINUX_GETNAMEINFO_UNSIGNED 1 #cmakedefine HAVE_GETADDRINFO_SETS_CANONNAME_FOR_IPADDRESSES 1 #cmakedefine HAVE_GETADDRINFO_USES_EAI_SERVICE 1 #cmakedefine HAVE_NONNULL_GETHOSTENT 1 #cmakedefine HAVE_STRUCT_SOCKADDR_SA_LEN 1 #cmakedefine HAVE_STRUCT_PASSWD_PW_CLASS 1 #cmakedefine HAVE_STRUCT_PASSWD_PW_CHANGE 1 #cmakedefine HAVE_STRUCT_PASSWD_PW_EXPIRE 1 #cmakedefine HAVE_IPV6 1 #cmakedefine HAVE_ATTRIBUTE_PRINTF_FORMAT 1 #cmakedefine HAVE_CONSTRUCTOR_ATTRIBUTE 1 #cmakedefine HAVE_DESTRUCTOR_ATTRIBUTE 1 #cmakedefine HAVE_PRAGMA_INIT 1 #cmakedefine HAVE_PRAGMA_FINI 1 /*************************** ENDIAN *****************************/ /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #cmakedefine WORDS_BIGENDIAN 1