2007-11-05 18:38:36 +03:00
/*
2018-10-31 10:44:08 +03:00
* BSD 3 - Clause License
2007-11-05 18:38:36 +03:00
*
2018-10-31 10:44:08 +03:00
* Copyright ( c ) 2007 , Stefan Metzmacher < metze @ samba . org >
* Copyright ( c ) 2009 , Guenther Deschner < gd @ samba . org >
* Copyright ( c ) 2014 - 2015 , Michael Adam < obnox @ samba . org >
* Copyright ( c ) 2015 , Robin Hack < hack . robin @ gmail . com >
* Copyright ( c ) 2013 - 2018 , Andreas Schneider < asn @ samba . org >
2007-11-05 18:38:36 +03:00
* 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 .
*/
2014-01-31 18:57:43 +04:00
# include "config.h"
2015-03-24 19:54:34 +03:00
# include <pthread.h>
2014-01-31 18:57:43 +04:00
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/socket.h>
# include <errno.h>
# include <fcntl.h>
# include <stdarg.h>
# include <stdbool.h>
# include <stddef.h>
# include <stdio.h>
# include <stdint.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <ctype.h>
2023-01-24 13:20:49 +03:00
# include <limits.h>
2007-11-05 18:38:36 +03:00
2015-11-12 13:08:47 +03:00
# include <netinet/in.h>
2015-07-15 16:01:48 +03:00
# include <search.h>
2015-03-23 16:10:18 +03:00
# include <assert.h>
2023-01-24 13:20:49 +03:00
# include "nss_utils.h"
2014-01-31 18:57:43 +04:00
/*
* 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
*/
2011-05-05 01:57:37 +04:00
# ifndef _POSIX_PTHREAD_SEMANTICS
2010-03-22 10:40:44 +03:00
# define _POSIX_PTHREAD_SEMANTICS
2011-05-05 01:57:37 +04:00
# endif
2010-03-22 10:40:44 +03:00
2014-01-31 18:57:43 +04:00
# include <pwd.h>
# include <grp.h>
2015-10-06 11:19:48 +03:00
# ifdef HAVE_SHADOW_H
2015-09-17 11:33:58 +03:00
# include <shadow.h>
2015-10-06 11:19:48 +03:00
# endif /* HAVE_SHADOW_H */
2014-01-31 18:57:43 +04:00
# include <netdb.h>
# include <arpa/inet.h>
# include <netinet/in.h>
# include <dlfcn.h>
2007-11-05 18:38:36 +03:00
2014-01-31 18:57:43 +04:00
# if defined(HAVE_NSS_H)
/* Linux and BSD */
# include <nss.h>
2007-11-05 18:38:36 +03:00
2014-01-31 18:57:43 +04:00
typedef enum nss_status NSS_STATUS ;
# elif defined(HAVE_NSS_COMMON_H)
/* Solaris */
# include <nss_common.h>
# include <nss_dbdefs.h>
# include <nsswitch.h>
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
2007-11-05 18:38:36 +03:00
2014-01-31 18:57:43 +04:00
# ifndef PTR_DIFF
# define PTR_DIFF(p1, p2) ((ptrdiff_t)(((const char *)(p1)) - (const char *)(p2)))
2007-11-05 18:38:36 +03:00
# endif
# ifndef _PUBLIC_
# define _PUBLIC_
# endif
2014-01-31 18:57:43 +04:00
# ifndef EAI_NODATA
# define EAI_NODATA EAI_NONAME
2007-11-06 11:06:50 +03:00
# endif
2014-01-31 18:57:43 +04:00
# ifndef EAI_ADDRFAMILY
# define EAI_ADDRFAMILY EAI_FAMILY
2007-11-06 11:06:50 +03:00
# endif
2014-01-31 18:57:43 +04:00
# ifndef __STRING
# define __STRING(x) #x
2007-11-06 11:06:50 +03:00
# endif
2014-01-31 18:57:43 +04:00
# ifndef __STRINGSTRING
# define __STRINGSTRING(x) __STRING(x)
2007-11-06 11:06:50 +03:00
# endif
2014-01-31 18:57:43 +04:00
# ifndef __LINESTR__
# define __LINESTR__ __STRINGSTRING(__LINE__)
2007-11-06 11:06:50 +03:00
# endif
2014-01-31 18:57:43 +04:00
# ifndef __location__
# define __location__ __FILE__ ":" __LINESTR__
2009-05-31 00:43:17 +04:00
# endif
2014-10-09 11:16:33 +04:00
# ifndef DNS_NAME_MAX
# define DNS_NAME_MAX 255
# endif
2014-01-31 18:57:43 +04:00
/* 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 */
2007-11-05 18:38:36 +03:00
2018-10-31 10:44:08 +03:00
# ifdef HAVE_CONSTRUCTOR_ATTRIBUTE
# define CONSTRUCTOR_ATTRIBUTE __attribute__ ((constructor))
# else
# define CONSTRUCTOR_ATTRIBUTE
# endif /* HAVE_CONSTRUCTOR_ATTRIBUTE */
2014-01-31 18:57:43 +04:00
# ifdef HAVE_DESTRUCTOR_ATTRIBUTE
# define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor))
# else
# define DESTRUCTOR_ATTRIBUTE
# endif /* HAVE_DESTRUCTOR_ATTRIBUTE */
2007-11-05 18:38:36 +03:00
2014-01-31 18:57:43 +04:00
# define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0)
2007-11-05 18:38:36 +03:00
2014-11-29 15:22:46 +03:00
# ifndef SAFE_FREE
# define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0)
# endif
2016-03-18 14:03:28 +03:00
# 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
2015-03-25 11:36:10 +03:00
# ifdef HAVE_IPV6
# define NWRAP_INET_ADDRSTRLEN INET6_ADDRSTRLEN
# else
# define NWRAP_INET_ADDRSTRLEN INET_ADDRSTRLEN
# endif
2023-01-24 13:20:49 +03:00
# define MAX(a,b) ((a) < (b) ? (b) : (a))
# define MIN(a,b) ((a) > (b) ? (b) : (a))
2015-03-24 19:54:34 +03:00
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 ;
2022-11-08 13:01:44 +03:00
# define nss_wrapper_init_mutex(m) \
_nss_wrapper_init_mutex ( m , # m )
2015-03-24 19:54:34 +03:00
/* Add new global locks here please */
/* Also don't forget to add locks to
* nwrap_init ( ) function .
*/
2022-11-08 13:01:44 +03:00
# 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 )
2015-03-24 19:54:34 +03:00
# define NWRAP_LOCK_ALL do { \
2022-11-08 13:01:44 +03:00
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 ) ; \
2015-03-24 19:54:34 +03:00
} while ( 0 ) ;
# define NWRAP_UNLOCK_ALL do {\
2022-11-08 13:01:44 +03:00
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 ) ; \
2015-03-24 19:54:34 +03:00
} while ( 0 ) ;
2018-10-31 10:44:08 +03:00
static void nwrap_init ( void ) ;
2014-01-31 18:57:43 +04:00
enum nwrap_dbglvl_e {
NWRAP_LOG_ERROR = 0 ,
NWRAP_LOG_WARN ,
NWRAP_LOG_DEBUG ,
NWRAP_LOG_TRACE
} ;
2007-11-05 18:38:36 +03:00
2019-11-13 17:41:47 +03:00
# 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 ( ) ;
2014-01-31 18:57:43 +04:00
# else
2019-11-13 17:41:47 +03:00
return NULL ;
# endif /* HAVE_PROGRAM_INVOCATION_SHORT_NAME */
}
# endif /* HAVE_GETPROGNAME */
2007-11-05 18:38:36 +03:00
2014-01-31 18:57:43 +04:00
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__)
2007-11-05 18:38:36 +03:00
2014-01-31 18:57:43 +04:00
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 ;
2019-11-13 17:41:47 +03:00
const char * prefix = " NWRAP " ;
const char * progname = getprogname ( ) ;
2014-01-31 18:57:43 +04:00
d = getenv ( " NSS_WRAPPER_DEBUGLEVEL " ) ;
if ( d ! = NULL ) {
lvl = atoi ( d ) ;
}
2019-11-13 17:41:47 +03:00
if ( lvl < dbglvl ) {
return ;
}
2014-01-31 18:57:43 +04:00
va_start ( va , format ) ;
vsnprintf ( buffer , sizeof ( buffer ) , format , va ) ;
va_end ( va ) ;
2019-11-13 17:41:47 +03:00
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 = " <unknown> " ;
2014-01-31 18:57:43 +04:00
}
2019-11-13 17:41:47 +03:00
fprintf ( stderr ,
" %s[%s (%u)] - %s: %s \n " ,
prefix ,
progname ,
( unsigned int ) getpid ( ) ,
func ,
buffer ) ;
2014-01-31 18:57:43 +04:00
}
2020-04-02 14:43:44 +03:00
/*****************
* 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 ) ;
2018-10-31 10:44:08 +03:00
# ifdef HAVE_GETPWENT_R
2020-04-02 14:43:44 +03:00
# 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 */
2018-10-31 10:44:08 +03:00
# endif /* HAVE_GETPWENT_R */
2020-04-02 14:43:44 +03:00
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 ) ;
2018-10-31 10:44:08 +03:00
# ifdef HAVE_GETGRENT_R
2020-04-02 14:43:44 +03:00
# 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 */
2018-10-31 10:44:08 +03:00
# endif /* HAVE_GETGRENT_R */
2007-11-05 18:39:46 +03:00
2020-04-02 14:43:44 +03:00
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 ) ;
2014-01-31 18:57:43 +04:00
# ifdef HAVE_GETHOSTBYNAME2 /* GNU extension */
2020-04-02 14:43:44 +03:00
typedef struct hostent * ( * __libc_gethostbyname2 ) ( const char * name , int af ) ;
2020-03-16 19:00:16 +03:00
# endif
2020-04-02 14:43:44 +03:00
2020-03-16 19:00:16 +03:00
# ifdef HAVE_GETHOSTBYNAME2_R /* GNU extension */
2020-04-02 14:43:44 +03:00
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 ,
2020-03-16 19:00:16 +03:00
struct hostent * ret ,
char * buf ,
size_t buflen ,
struct hostent * * result ,
int * h_errnop ) ;
2014-01-31 18:57:43 +04:00
# endif
2020-04-02 14:43:44 +03:00
# 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 ) ;
2014-01-31 18:57:43 +04:00
# ifdef HAVE_GETHOSTBYNAME_R
2020-04-02 14:43:44 +03:00
NWRAP_SYMBOL_ENTRY ( gethostbyname_r ) ;
# endif
# ifdef HAVE_GETHOSTBYNAME2
NWRAP_SYMBOL_ENTRY ( gethostbyname2 ) ;
2014-01-31 18:57:43 +04:00
# endif
2020-04-02 14:43:44 +03:00
# ifdef HAVE_GETHOSTBYNAME2_R
NWRAP_SYMBOL_ENTRY ( gethostbyname2_r ) ;
# endif
NWRAP_SYMBOL_ENTRY ( gethostbyaddr ) ;
2014-01-31 18:57:43 +04:00
# ifdef HAVE_GETHOSTBYADDR_R
2020-04-02 14:43:44 +03:00
NWRAP_SYMBOL_ENTRY ( gethostbyaddr_r ) ;
2007-11-05 18:39:46 +03:00
# endif
2020-04-02 14:43:44 +03:00
NWRAP_SYMBOL_ENTRY ( getaddrinfo ) ;
NWRAP_SYMBOL_ENTRY ( getnameinfo ) ;
NWRAP_SYMBOL_ENTRY ( gethostname ) ;
2014-01-31 18:57:43 +04:00
} ;
2020-04-02 14:43:44 +03:00
# 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 ) ;
2023-01-24 13:20:49 +03:00
typedef NSS_STATUS ( * __nss_initgroups_dyn ) ( const char * user ,
2020-04-02 14:43:44 +03:00
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 ,
2020-03-16 19:00:16 +03:00
struct hostent * result ,
2020-04-02 14:43:44 +03:00
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 ) ;
2023-01-24 13:20:49 +03:00
NWRAP_NSS_MODULE_SYMBOL_ENTRY ( initgroups_dyn ) ;
2020-04-02 14:43:44 +03:00
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 ) ;
2009-06-04 13:59:32 +04:00
} ;
2009-06-03 13:10:13 +04:00
struct nwrap_backend {
2009-05-31 03:01:13 +04:00
const char * name ;
2009-06-04 13:59:32 +04:00
const char * so_path ;
void * so_handle ;
2009-06-03 13:10:13 +04:00
struct nwrap_ops * ops ;
2020-04-02 14:43:44 +03:00
struct nwrap_nss_module_symbols * symbols ;
2009-05-31 03:01:13 +04:00
} ;
2020-03-16 19:00:16 +03:00
struct nwrap_vector ;
2009-06-03 13:10:13 +04:00
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 ) ;
2023-01-24 13:20:49 +03:00
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 ) ;
2009-06-03 13:10:13 +04:00
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 ) ;
2020-03-16 19:00:16 +03:00
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 ) ;
2009-06-03 13:10:13 +04:00
} ;
2014-01-31 18:57:43 +04:00
/* Public prototypes */
bool nss_wrapper_enabled ( void ) ;
2015-09-17 11:37:50 +03:00
bool nss_wrapper_shadow_enabled ( void ) ;
2014-01-31 18:57:43 +04:00
bool nss_wrapper_hosts_enabled ( void ) ;
2010-02-21 08:32:29 +03:00
/* prototypes for files backend */
2009-06-03 13:10:13 +04:00
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 ,
2009-05-31 03:01:13 +04:00
char * buf , size_t buflen , struct passwd * * pwdstp ) ;
2009-06-03 13:10:13 +04:00
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 ,
2009-05-31 03:01:13 +04:00
char * buf , size_t buflen , struct passwd * * pwdstp ) ;
2009-06-03 13:10:13 +04:00
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 ,
2009-05-31 03:01:13 +04:00
size_t buflen , struct passwd * * pwdstp ) ;
2009-06-03 13:10:13 +04:00
static void nwrap_files_endpwent ( struct nwrap_backend * b ) ;
2023-01-24 13:20:49 +03:00
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 ) ;
2009-06-03 13:10:13 +04:00
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 ,
2009-05-31 03:01:13 +04:00
char * buf , size_t buflen , struct group * * grdstp ) ;
2009-06-03 13:10:13 +04:00
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 ,
2009-05-31 03:01:13 +04:00
char * buf , size_t buflen , struct group * * grdstp ) ;
2009-06-03 13:10:13 +04:00
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 ,
2009-05-31 03:01:13 +04:00
size_t buflen , struct group * * grdstp ) ;
2009-06-03 13:10:13 +04:00
static void nwrap_files_endgrent ( struct nwrap_backend * b ) ;
2020-03-16 19:00:16 +03:00
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 ) ;
2009-05-31 03:01:13 +04:00
2010-02-21 08:32:29 +03:00
/* prototypes for module backend */
2009-06-04 14:17:39 +04:00
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 ) ;
2023-01-24 13:20:49 +03:00
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 ) ;
2020-03-16 19:00:16 +03:00
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 ) ;
2009-06-04 14:17:39 +04:00
2009-05-31 03:01:13 +04:00
struct nwrap_ops nwrap_files_ops = {
2009-06-02 16:52:53 +04:00
. 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 ,
2023-01-24 13:20:49 +03:00
. nw_initgroups_dyn = nwrap_files_initgroups_dyn ,
2009-06-02 16:52:53 +04:00
. 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 ,
2020-03-16 19:00:16 +03:00
. 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 ,
2009-05-31 03:01:13 +04:00
} ;
2009-06-04 14:17:39 +04:00
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 ,
2023-01-24 13:20:49 +03:00
. nw_initgroups_dyn = nwrap_module_initgroups_dyn ,
2009-06-04 14:17:39 +04:00
. 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 ,
2020-03-16 19:00:16 +03:00
. nw_gethostbyaddr = nwrap_module_gethostbyaddr ,
. nw_gethostbyname = nwrap_module_gethostbyname ,
. nw_gethostbyname2 = nwrap_module_gethostbyname2 ,
. nw_gethostbyname2_r = nwrap_module_gethostbyname2_r ,
2009-06-04 14:17:39 +04:00
} ;
2014-01-31 18:57:43 +04:00
struct nwrap_libc {
void * handle ;
void * nsl_handle ;
void * sock_handle ;
2020-04-02 14:43:44 +03:00
struct nwrap_libc_symbols symbols ;
2014-01-31 18:57:43 +04:00
} ;
2009-05-31 03:01:13 +04:00
struct nwrap_main {
2020-03-16 19:00:16 +03:00
size_t num_backends ;
2009-06-03 13:10:13 +04:00
struct nwrap_backend * backends ;
2014-01-31 18:57:43 +04:00
struct nwrap_libc * libc ;
2009-05-31 03:01:13 +04:00
} ;
2015-07-16 17:10:20 +03:00
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 ) ;
2009-05-31 03:01:13 +04:00
2023-01-24 13:20:49 +03:00
# ifdef HAVE_GETGROUPLIST
static int nwrap_getgrouplist ( const char * user ,
gid_t group ,
long int * size ,
gid_t * * groupsp ,
long int limit ) ;
# endif
2015-03-23 16:10:18 +03:00
/*
* 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 ] )
2015-10-08 16:27:47 +03:00
# define nwrap_vector_is_initialized(vector) ((vector)->items != NULL)
2015-03-23 16:10:18 +03:00
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 ;
}
2015-10-08 15:09:11 +03:00
static bool nwrap_vector_add_item ( struct nwrap_vector * vector , void * const item )
2015-03-23 16:10:18 +03:00
{
2015-10-08 15:09:11 +03:00
assert ( vector ! = NULL ) ;
2015-03-23 16:10:18 +03:00
2015-10-08 15:09:11 +03:00
if ( vector - > items = = NULL ) {
nwrap_vector_init ( vector ) ;
2015-03-23 16:10:18 +03:00
}
2015-10-08 15:09:11 +03:00
if ( vector - > count = = vector - > capacity ) {
2015-03-23 16:10:18 +03:00
/* Items array _MUST_ be NULL terminated because it's passed
* as result to caller which expect NULL terminated array from libc .
*/
2015-10-08 15:09:11 +03:00
void * * items = realloc ( vector - > items , sizeof ( void * ) * ( ( vector - > capacity * 2 ) + 1 ) ) ;
2015-03-23 16:10:18 +03:00
if ( items = = NULL ) {
return false ;
}
2015-10-08 15:09:11 +03:00
vector - > items = items ;
2015-03-23 16:10:18 +03:00
/* Don't count ending NULL to capacity */
2015-10-08 15:09:11 +03:00
vector - > capacity * = 2 ;
2015-03-23 16:10:18 +03:00
}
2015-10-08 15:09:11 +03:00
vector - > items [ vector - > count ] = item ;
2015-03-23 16:10:18 +03:00
2015-10-08 15:09:11 +03:00
vector - > count + = 1 ;
vector - > items [ vector - > count ] = NULL ;
2015-03-23 16:10:18 +03:00
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 ;
}
2007-11-05 18:39:46 +03:00
struct nwrap_cache {
const char * path ;
int fd ;
2015-03-23 16:39:28 +03:00
FILE * fp ;
2007-11-05 18:39:46 +03:00
struct stat st ;
void * private_data ;
2015-03-23 16:39:28 +03:00
struct nwrap_vector lines ;
2007-11-05 18:39:46 +03:00
bool ( * parse_line ) ( struct nwrap_cache * , char * line ) ;
void ( * unload ) ( struct nwrap_cache * ) ;
} ;
2015-09-17 11:33:58 +03:00
/* passwd */
2007-11-05 18:39:46 +03:00
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 ) ;
2015-09-17 11:33:58 +03:00
/* shadow */
2015-10-06 11:34:20 +03:00
# if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM)
2015-09-17 11:33:58 +03:00
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 ) ;
2015-10-06 11:34:20 +03:00
# endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */
2015-09-17 11:33:58 +03:00
/* group */
2007-11-05 18:41:23 +03:00
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 ;
2015-09-17 11:33:58 +03:00
/* hosts */
2014-01-31 18:57:43 +04:00
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 */
} ;
2015-07-15 16:01:48 +03:00
static size_t max_hostents = 100 ;
2014-01-31 18:57:43 +04:00
struct nwrap_entdata {
2015-07-16 17:10:20 +03:00
struct nwrap_addrdata addr ;
2014-01-31 18:57:43 +04:00
struct hostent ht ;
2015-07-15 16:01:48 +03:00
struct nwrap_vector nwrap_addrdata ;
ssize_t aliases_count ;
2015-11-11 12:27:50 +03:00
} ;
2015-07-15 16:01:48 +03:00
2015-11-11 12:27:50 +03:00
struct nwrap_entlist {
struct nwrap_entlist * next ;
struct nwrap_entdata * ed ;
2014-01-31 18:57:43 +04:00
} ;
struct nwrap_he {
struct nwrap_cache * cache ;
2015-11-19 02:30:17 +03:00
struct nwrap_vector entries ;
2015-11-19 03:00:16 +03:00
struct nwrap_vector lists ;
2015-07-16 17:10:20 +03:00
2014-01-31 18:57:43 +04:00
int num ;
int idx ;
} ;
2015-07-16 17:10:20 +03:00
static struct nwrap_cache __nwrap_cache_he ;
static struct nwrap_he nwrap_he_global ;
2014-01-31 18:57:43 +04:00
/*********************************************************
* NWRAP PROTOTYPES
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-11-05 18:41:23 +03:00
static bool nwrap_gr_parse_line ( struct nwrap_cache * nwrap , char * line ) ;
static void nwrap_gr_unload ( struct nwrap_cache * nwrap ) ;
2022-06-24 11:39:57 +03:00
# if ! defined(HAVE_CONSTRUCTOR_ATTRIBUTE) && defined(HAVE_PRAGMA_INIT)
/* xlC and other oldschool compilers support (only) this */
# pragma init (nwrap_constructor)
# endif
2018-10-31 10:44:08 +03:00
void nwrap_constructor ( void ) CONSTRUCTOR_ATTRIBUTE ;
2022-06-24 11:39:57 +03:00
# if ! defined(HAVE_DESTRUCTOR_ATTRIBUTE) && defined(HAVE_PRAGMA_FINI)
# pragma fini (nwrap_destructor)
# endif
2014-01-31 18:57:43 +04:00
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
2019-11-13 17:41:47 +03:00
const char * env_preload = getenv ( " LD_PRELOAD " ) ;
const char * env_deepbind = getenv ( " NSS_WRAPPER_DISABLE_DEEPBIND " ) ;
bool enable_deepbind = true ;
2018-10-31 10:44:08 +03:00
/* Don't do a deepbind if we run with libasan */
2019-11-13 17:41:47 +03:00
if ( env_preload ! = NULL & & strlen ( env_preload ) < 1024 ) {
const char * p = strstr ( env_preload , " libasan.so " ) ;
if ( p ! = NULL ) {
enable_deepbind = false ;
2018-10-31 10:44:08 +03:00
}
}
2019-11-13 17:41:47 +03:00
if ( env_deepbind ! = NULL & & strlen ( env_deepbind ) > = 1 ) {
enable_deepbind = false ;
}
if ( enable_deepbind ) {
flags | = RTLD_DEEPBIND ;
}
2014-01-31 18:57:43 +04:00
# endif
switch ( lib ) {
case NWRAP_LIBNSL :
# ifdef HAVE_LIBNSL
handle = nwrap_main_global - > libc - > nsl_handle ;
if ( handle = = NULL ) {
2014-10-01 19:15:35 +04:00
for ( i = 10 ; i > = 0 ; i - - ) {
2014-01-31 18:57:43 +04:00
char soname [ 256 ] = { 0 } ;
snprintf ( soname , sizeof ( soname ) , " libnsl.so.%d " , i ) ;
handle = dlopen ( soname , flags ) ;
2014-10-01 19:15:35 +04:00
if ( handle ! = NULL ) {
break ;
}
2014-01-31 18:57:43 +04:00
}
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 ) {
2014-10-01 19:15:35 +04:00
for ( i = 10 ; i > = 0 ; i - - ) {
2014-01-31 18:57:43 +04:00
char soname [ 256 ] = { 0 } ;
snprintf ( soname , sizeof ( soname ) , " libsocket.so.%d " , i ) ;
handle = dlopen ( soname , flags ) ;
2014-10-01 19:15:35 +04:00
if ( handle ! = NULL ) {
break ;
}
2014-01-31 18:57:43 +04:00
}
nwrap_main_global - > libc - > sock_handle = handle ;
}
break ;
# endif
/* FALL TROUGH */
case NWRAP_LIBC :
handle = nwrap_main_global - > libc - > handle ;
if ( handle = = NULL ) {
2014-10-01 19:15:35 +04:00
for ( i = 10 ; i > = 0 ; i - - ) {
2014-01-31 18:57:43 +04:00
char soname [ 256 ] = { 0 } ;
snprintf ( soname , sizeof ( soname ) , " libc.so.%d " , i ) ;
handle = dlopen ( soname , flags ) ;
2014-10-01 19:15:35 +04:00
if ( handle ! = NULL ) {
break ;
}
2014-01-31 18:57:43 +04:00
}
nwrap_main_global - > libc - > handle = handle ;
}
break ;
}
if ( handle = = NULL ) {
2014-10-09 11:13:48 +04:00
# ifdef RTLD_NEXT
handle = nwrap_main_global - > libc - > handle
= nwrap_main_global - > libc - > sock_handle
= nwrap_main_global - > libc - > nsl_handle
= RTLD_NEXT ;
# else
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Failed to dlopen library: %s \n " ,
dlerror ( ) ) ;
exit ( - 1 ) ;
2014-10-09 11:13:48 +04:00
# endif
2014-01-31 18:57:43 +04:00
}
return handle ;
}
2020-04-02 14:43:44 +03:00
static void * _nwrap_bind_symbol ( enum nwrap_lib lib , const char * fn_name )
2014-01-31 18:57:43 +04:00
{
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 ;
}
2022-11-08 13:01:44 +03:00
# 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 ( ) ;
}
}
2020-04-02 14:43:44 +03:00
# 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 ) ; \
} \
2022-11-08 13:01:44 +03:00
static void nwrap_bind_symbol_all ( void ) ;
2014-01-31 18:57:43 +04:00
2015-03-23 16:39:28 +03:00
/* INTERNAL HELPER FUNCTIONS */
static void nwrap_lines_unload ( struct nwrap_cache * const nwrap )
{
size_t p ;
2015-10-08 15:00:38 +03:00
void * item ;
nwrap_vector_foreach ( item , nwrap - > lines , p ) {
2015-03-23 16:39:28 +03:00
/* Maybe some vectors were merged ... */
2015-10-08 15:00:38 +03:00
SAFE_FREE ( item ) ;
2015-03-23 16:39:28 +03:00
}
SAFE_FREE ( nwrap - > lines . items ) ;
2015-10-08 15:00:38 +03:00
ZERO_STRUCTP ( & nwrap - > lines ) ;
2015-03-23 16:39:28 +03:00
}
2014-01-31 18:57:43 +04:00
/*
* 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 )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_getpwnam . f ( name ) ;
2014-01-31 18:57:43 +04:00
}
# ifdef HAVE_GETPWNAM_R
static int libc_getpwnam_r ( const char * name ,
struct passwd * pwd ,
char * buf ,
size_t buflen ,
struct passwd * * result )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_getpwnam_r . f ( name ,
pwd ,
buf ,
buflen ,
result ) ;
2014-01-31 18:57:43 +04:00
}
# endif
static struct passwd * libc_getpwuid ( uid_t uid )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_getpwuid . f ( uid ) ;
2014-01-31 18:57:43 +04:00
}
# ifdef HAVE_GETPWUID_R
static int libc_getpwuid_r ( uid_t uid ,
struct passwd * pwd ,
char * buf ,
size_t buflen ,
struct passwd * * result )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_getpwuid_r . f ( uid ,
pwd ,
buf ,
buflen ,
result ) ;
2014-01-31 18:57:43 +04:00
}
# endif
2015-03-24 17:14:35 +03:00
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 ;
}
2014-01-31 18:57:43 +04:00
static void libc_setpwent ( void )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
nwrap_main_global - > libc - > symbols . _libc_setpwent . f ( ) ;
2014-01-31 18:57:43 +04:00
}
static struct passwd * libc_getpwent ( void )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_getpwent . f ( ) ;
2014-01-31 18:57:43 +04:00
}
2018-10-31 10:44:08 +03:00
# ifdef HAVE_GETPWENT_R
# ifdef HAVE_SOLARIS_GETPWENT_R
2014-01-31 18:57:43 +04:00
static struct passwd * libc_getpwent_r ( struct passwd * pwdst ,
char * buf ,
int buflen )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_getpwent_r . f ( pwdst ,
buf ,
buflen ) ;
2014-01-31 18:57:43 +04:00
}
2018-10-31 10:44:08 +03:00
# else /* HAVE_SOLARIS_GETPWENT_R */
2014-01-31 18:57:43 +04:00
static int libc_getpwent_r ( struct passwd * pwdst ,
char * buf ,
size_t buflen ,
struct passwd * * pwdstp )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_getpwent_r . f ( pwdst ,
buf ,
buflen ,
pwdstp ) ;
2014-01-31 18:57:43 +04:00
}
2018-10-31 10:44:08 +03:00
# endif /* HAVE_SOLARIS_GETPWENT_R */
# endif /* HAVE_GETPWENT_R */
2014-01-31 18:57:43 +04:00
static void libc_endpwent ( void )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
nwrap_main_global - > libc - > symbols . _libc_endpwent . f ( ) ;
2014-01-31 18:57:43 +04:00
}
static int libc_initgroups ( const char * user , gid_t gid )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_initgroups . f ( user , gid ) ;
2014-01-31 18:57:43 +04:00
}
static struct group * libc_getgrnam ( const char * name )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_getgrnam . f ( name ) ;
2014-01-31 18:57:43 +04:00
}
# ifdef HAVE_GETGRNAM_R
static int libc_getgrnam_r ( const char * name ,
struct group * grp ,
char * buf ,
size_t buflen ,
struct group * * result )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_getgrnam_r . f ( name ,
grp ,
buf ,
buflen ,
result ) ;
2014-01-31 18:57:43 +04:00
}
# endif
static struct group * libc_getgrgid ( gid_t gid )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_getgrgid . f ( gid ) ;
2014-01-31 18:57:43 +04:00
}
# ifdef HAVE_GETGRGID_R
static int libc_getgrgid_r ( gid_t gid ,
struct group * grp ,
char * buf ,
size_t buflen ,
struct group * * result )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_getgrgid_r . f ( gid ,
grp ,
buf ,
buflen ,
result ) ;
2014-01-31 18:57:43 +04:00
}
# endif
static void libc_setgrent ( void )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
nwrap_main_global - > libc - > symbols . _libc_setgrent . f ( ) ;
2014-01-31 18:57:43 +04:00
}
static struct group * libc_getgrent ( void )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_getgrent . f ( ) ;
2014-01-31 18:57:43 +04:00
}
# ifdef HAVE_GETGRENT_R
2018-10-31 10:44:08 +03:00
# ifdef HAVE_SOLARIS_GETGRENT_R
2014-01-31 18:57:43 +04:00
static struct group * libc_getgrent_r ( struct group * group ,
char * buf ,
size_t buflen )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_getgrent_r . f ( group ,
buf ,
buflen ) ;
2014-01-31 18:57:43 +04:00
}
2018-10-31 10:44:08 +03:00
# else /* HAVE_SOLARIS_GETGRENT_R */
2014-01-31 18:57:43 +04:00
static int libc_getgrent_r ( struct group * group ,
char * buf ,
size_t buflen ,
struct group * * result )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_getgrent_r . f ( group ,
buf ,
buflen ,
result ) ;
2014-01-31 18:57:43 +04:00
}
2018-10-31 10:44:08 +03:00
# endif /* HAVE_SOLARIS_GETGRENT_R */
2014-01-31 18:57:43 +04:00
# endif /* HAVE_GETGRENT_R */
static void libc_endgrent ( void )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
nwrap_main_global - > libc - > symbols . _libc_endgrent . f ( ) ;
2014-01-31 18:57:43 +04:00
}
# ifdef HAVE_GETGROUPLIST
static int libc_getgrouplist ( const char * user ,
gid_t group ,
gid_t * groups ,
int * ngroups )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_getgrouplist . f ( user ,
group ,
groups ,
ngroups ) ;
2014-01-31 18:57:43 +04:00
}
# endif
static void libc_sethostent ( int stayopen )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
nwrap_main_global - > libc - > symbols . _libc_sethostent . f ( stayopen ) ;
2014-01-31 18:57:43 +04:00
}
static struct hostent * libc_gethostent ( void )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_gethostent . f ( ) ;
2014-01-31 18:57:43 +04:00
}
static void libc_endhostent ( void )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
nwrap_main_global - > libc - > symbols . _libc_endhostent . f ( ) ;
2014-01-31 18:57:43 +04:00
}
static struct hostent * libc_gethostbyname ( const char * name )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_gethostbyname . f ( name ) ;
2014-01-31 18:57:43 +04:00
}
# ifdef HAVE_GETHOSTBYNAME2 /* GNU extension */
static struct hostent * libc_gethostbyname2 ( const char * name , int af )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_gethostbyname2 . f ( name , af ) ;
2014-01-31 18:57:43 +04:00
}
# endif
2020-03-16 19:00:16 +03:00
# 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 )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2020-03-16 19:00:16 +03:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_gethostbyname2_r . f ( name ,
af ,
ret ,
buf ,
buflen ,
result ,
h_errnop ) ;
2020-03-16 19:00:16 +03:00
}
# endif
2014-01-31 18:57:43 +04:00
static struct hostent * libc_gethostbyaddr ( const void * addr ,
socklen_t len ,
int type )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_gethostbyaddr . f ( addr ,
len ,
type ) ;
2014-01-31 18:57:43 +04:00
}
static int libc_gethostname ( char * name , size_t len )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_gethostname . f ( name , len ) ;
2014-01-31 18:57:43 +04:00
}
# 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 )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_gethostbyname_r . f ( name ,
ret ,
buf ,
buflen ,
result ,
h_errnop ) ;
2014-01-31 18:57:43 +04:00
}
# 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 )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_gethostbyaddr_r . f ( addr ,
len ,
type ,
ret ,
buf ,
buflen ,
result ,
h_errnop ) ;
2014-01-31 18:57:43 +04:00
}
# endif
static int libc_getaddrinfo ( const char * node ,
const char * service ,
const struct addrinfo * hints ,
struct addrinfo * * res )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_getaddrinfo . f ( node ,
service ,
hints ,
res ) ;
2014-01-31 18:57:43 +04:00
}
static int libc_getnameinfo ( const struct sockaddr * sa ,
socklen_t salen ,
char * host ,
size_t hostlen ,
char * serv ,
size_t servlen ,
int flags )
{
2022-11-08 13:01:44 +03:00
nwrap_bind_symbol_all ( ) ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
return nwrap_main_global - > libc - > symbols . _libc_getnameinfo . f ( sa ,
salen ,
host ,
hostlen ,
serv ,
servlen ,
flags ) ;
2014-01-31 18:57:43 +04:00
}
2022-11-08 13:01:44 +03:00
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 ) ;
}
2014-01-31 18:57:43 +04:00
/*********************************************************
* NWRAP NSS MODULE LOADER FUNCTIONS
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-11-05 18:41:23 +03:00
2020-04-02 14:43:44 +03:00
static void * _nwrap_bind_nss_module_symbol ( struct nwrap_backend * b ,
const char * fn_name )
2009-06-04 13:59:32 +04:00
{
2020-03-16 19:00:16 +03:00
void * res = NULL ;
char * s = NULL ;
int rc ;
2009-06-04 13:59:32 +04:00
2020-03-16 19:00:16 +03:00
if ( b - > so_handle = = NULL ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR , " No handle " ) ;
2009-06-04 13:59:32 +04:00
return NULL ;
}
2020-03-16 19:00:16 +03:00
rc = asprintf ( & s , " _nss_%s_%s " , b - > name , fn_name ) ;
if ( rc = = - 1 ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR , " Out of memory " ) ;
2009-06-04 13:59:32 +04:00
return NULL ;
}
res = dlsym ( b - > so_handle , s ) ;
2020-03-16 19:00:16 +03:00
if ( res = = NULL ) {
NWRAP_LOG ( NWRAP_LOG_WARN ,
2014-01-31 18:57:43 +04:00
" Cannot find function %s in %s " ,
s , b - > so_path ) ;
2009-06-04 13:59:32 +04:00
}
2014-11-29 15:22:46 +03:00
SAFE_FREE ( s ) ;
2009-06-04 13:59:32 +04:00
return res ;
}
2020-04-02 14:43:44 +03:00
# 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 ) ; \
2022-11-08 13:01:44 +03:00
}
2020-04-02 14:43:44 +03:00
# 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 ) ; \
2022-11-08 13:01:44 +03:00
}
2020-04-02 14:43:44 +03:00
static struct nwrap_nss_module_symbols *
nwrap_bind_nss_module_symbols ( struct nwrap_backend * b )
2009-06-04 13:59:32 +04:00
{
2020-04-02 14:43:44 +03:00
struct nwrap_nss_module_symbols * symbols ;
2009-06-04 13:59:32 +04:00
if ( ! b - > so_handle ) {
return NULL ;
}
2020-04-02 14:43:44 +03:00
symbols = calloc ( 1 , sizeof ( struct nwrap_nss_module_symbols ) ) ;
if ( symbols = = NULL ) {
2009-06-04 13:59:32 +04:00
return NULL ;
}
2020-04-02 14:43:44 +03:00
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 ) ;
2023-01-24 13:20:49 +03:00
nwrap_nss_module_bind_symbol ( initgroups_dyn ) ;
2020-04-02 14:43:44 +03:00
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 ;
2009-06-04 13:59:32 +04:00
}
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 ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Cannot open shared library %s " ,
so_path ) ;
2009-06-04 13:59:32 +04:00
return NULL ;
}
return h ;
}
2009-06-03 13:10:13 +04:00
static bool nwrap_module_init ( const char * name ,
struct nwrap_ops * ops ,
2009-06-04 13:59:32 +04:00
const char * so_path ,
2020-03-16 19:00:16 +03:00
size_t * num_backends ,
2009-06-03 13:10:13 +04:00
struct nwrap_backend * * backends )
{
2020-04-02 14:43:44 +03:00
struct nwrap_backend * b = NULL ;
size_t n = * num_backends + 1 ;
2011-02-24 01:17:58 +03:00
2020-04-02 14:43:44 +03:00
b = realloc ( * backends , sizeof ( struct nwrap_backend ) * n ) ;
if ( b = = NULL ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR , " Out of memory " ) ;
2009-06-06 01:10:58 +04:00
return false ;
2009-06-03 13:10:13 +04:00
}
2020-04-02 14:43:44 +03:00
* backends = b ;
2009-06-03 13:10:13 +04:00
2011-02-24 01:17:58 +03:00
b = & ( ( * backends ) [ * num_backends ] ) ;
2020-04-02 14:43:44 +03:00
* b = ( struct nwrap_backend ) {
. name = name ,
. ops = ops ,
. so_path = so_path ,
} ;
2011-02-24 01:20:27 +03:00
if ( so_path ! = NULL ) {
b - > so_handle = nwrap_load_module ( so_path ) ;
2020-04-02 14:43:44 +03:00
b - > symbols = nwrap_bind_nss_module_symbols ( b ) ;
if ( b - > symbols = = NULL ) {
2011-02-24 01:20:27 +03:00
return false ;
}
}
2009-06-03 13:10:13 +04:00
2020-04-02 14:43:44 +03:00
* num_backends = n ;
2009-06-03 13:10:13 +04:00
return true ;
}
2014-01-31 18:57:43 +04:00
static void nwrap_libc_init ( struct nwrap_main * r )
{
2018-10-31 10:44:08 +03:00
r - > libc = calloc ( 1 , sizeof ( struct nwrap_libc ) ) ;
2014-01-31 18:57:43 +04:00
if ( r - > libc = = NULL ) {
printf ( " Failed to allocate memory for libc " ) ;
exit ( - 1 ) ;
}
}
2009-06-03 13:10:13 +04:00
static void nwrap_backend_init ( struct nwrap_main * r )
{
2014-01-31 18:57:43 +04:00
const char * module_so_path = getenv ( " NSS_WRAPPER_MODULE_SO_PATH " ) ;
const char * module_fn_name = getenv ( " NSS_WRAPPER_MODULE_FN_PREFIX " ) ;
2009-06-04 14:26:55 +04:00
2009-06-03 13:10:13 +04:00
r - > num_backends = 0 ;
r - > backends = NULL ;
2009-06-04 13:59:32 +04:00
if ( ! nwrap_module_init ( " files " , & nwrap_files_ops , NULL ,
2009-06-03 13:10:13 +04:00
& r - > num_backends ,
& r - > backends ) ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Failed to initialize 'files' backend " ) ;
2009-06-03 13:10:13 +04:00
return ;
}
2009-06-04 14:26:55 +04:00
2014-01-31 18:57:43 +04:00
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 ,
2009-06-04 14:26:55 +04:00
& r - > num_backends ,
& r - > backends ) ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Failed to initialize '%s' backend " ,
module_fn_name ) ;
2009-06-04 14:26:55 +04:00
return ;
}
}
2009-06-03 13:10:13 +04:00
}
2022-11-08 13:01:44 +03:00
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 ;
}
2007-11-05 18:39:46 +03:00
static void nwrap_init ( void )
{
2015-07-15 16:01:48 +03:00
const char * env ;
char * endptr ;
size_t max_hostents_tmp ;
2018-10-31 10:44:08 +03:00
int ok ;
2007-11-05 18:39:46 +03:00
2022-11-08 13:01:44 +03:00
nwrap_mutex_lock ( & nwrap_initialized_mutex ) ;
2015-03-24 19:54:34 +03:00
if ( nwrap_initialized ) {
2022-11-08 13:01:44 +03:00
nwrap_mutex_unlock ( & nwrap_initialized_mutex ) ;
2015-03-24 19:54:34 +03:00
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 .
*/
2022-11-08 13:01:44 +03:00
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 ) ;
2015-03-24 19:54:34 +03:00
nwrap_initialized = true ;
2015-07-15 16:01:48 +03:00
env = getenv ( " NSS_WRAPPER_MAX_HOSTENTS " ) ;
if ( env ! = NULL ) {
2017-10-19 11:56:15 +03:00
max_hostents_tmp = ( size_t ) strtoul ( env , & endptr , 10 ) ;
if ( ( * env = = ' \0 ' ) | |
( * endptr ! = ' \0 ' ) | |
2015-07-15 16:01:48 +03:00
( 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. " ,
2015-11-16 12:19:27 +03:00
( unsigned long ) max_hostents ) ;
2015-07-15 16:01:48 +03:00
} else {
max_hostents = max_hostents_tmp ;
}
}
/* Initialize hash table */
NWRAP_LOG ( NWRAP_LOG_DEBUG ,
2015-11-16 12:19:27 +03:00
" Initializing hash table of size %lu items. " ,
( unsigned long ) max_hostents ) ;
2018-10-31 10:44:08 +03:00
ok = hcreate ( max_hostents ) ;
if ( ! ok ) {
2015-07-15 16:01:48 +03:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Failed to initialize hash table " ) ;
2018-10-31 10:44:08 +03:00
exit ( - 1 ) ;
2015-07-15 16:01:48 +03:00
}
2009-05-31 03:01:13 +04:00
nwrap_main_global = & __nwrap_main_global ;
2014-01-31 18:57:43 +04:00
nwrap_libc_init ( nwrap_main_global ) ;
2009-06-03 13:10:13 +04:00
nwrap_backend_init ( nwrap_main_global ) ;
2009-05-31 03:01:13 +04:00
2015-09-17 11:33:58 +03:00
/* passwd */
2007-11-05 18:39:46 +03:00
nwrap_pw_global . cache = & __nwrap_cache_pw ;
nwrap_pw_global . cache - > path = getenv ( " NSS_WRAPPER_PASSWD " ) ;
2015-03-23 16:39:28 +03:00
nwrap_pw_global . cache - > fp = NULL ;
2007-11-05 18:39:46 +03:00
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 ;
2007-11-05 18:41:23 +03:00
2015-09-17 11:33:58 +03:00
/* shadow */
2015-10-06 11:34:20 +03:00
# if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM)
2015-09-17 11:33:58 +03:00
nwrap_sp_global . cache = & __nwrap_cache_sp ;
nwrap_sp_global . cache - > path = getenv ( " NSS_WRAPPER_SHADOW " ) ;
2015-03-23 16:39:28 +03:00
nwrap_sp_global . cache - > fp = NULL ;
2015-09-17 11:33:58 +03:00
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 ;
2015-10-06 11:34:20 +03:00
# endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */
2015-09-17 11:33:58 +03:00
/* group */
2007-11-05 18:41:23 +03:00
nwrap_gr_global . cache = & __nwrap_cache_gr ;
nwrap_gr_global . cache - > path = getenv ( " NSS_WRAPPER_GROUP " ) ;
2015-03-23 16:39:28 +03:00
nwrap_gr_global . cache - > fp = NULL ;
2007-11-05 18:41:23 +03:00
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 ;
2014-01-31 18:57:43 +04:00
2015-09-17 11:33:58 +03:00
/* hosts */
2014-01-31 18:57:43 +04:00
nwrap_he_global . cache = & __nwrap_cache_he ;
nwrap_he_global . cache - > path = getenv ( " NSS_WRAPPER_HOSTS " ) ;
2015-03-23 16:39:28 +03:00
nwrap_he_global . cache - > fp = NULL ;
2014-01-31 18:57:43 +04:00
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 ;
2015-03-24 19:54:34 +03:00
/* We hold all locks here so we can use NWRAP_UNLOCK_ALL. */
2022-11-08 13:01:44 +03:00
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 ) ;
2007-11-05 18:39:46 +03:00
}
2014-01-31 18:57:43 +04:00
bool nss_wrapper_enabled ( void )
2007-11-05 18:39:46 +03:00
{
nwrap_init ( ) ;
2014-01-31 18:57:43 +04:00
if ( nwrap_pw_global . cache - > path = = NULL | |
nwrap_pw_global . cache - > path [ 0 ] = = ' \0 ' ) {
2007-11-05 18:41:23 +03:00
return false ;
}
2014-01-31 18:57:43 +04:00
if ( nwrap_gr_global . cache - > path = = NULL | |
nwrap_gr_global . cache - > path [ 0 ] = = ' \0 ' ) {
2007-11-05 18:41:23 +03:00
return false ;
}
2007-11-05 18:39:46 +03:00
return true ;
}
2015-10-06 11:34:20 +03:00
# if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM)
2015-09-17 11:37:50 +03:00
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 ;
}
2015-10-06 11:34:20 +03:00
# endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */
2015-09-17 11:37:50 +03:00
2014-01-31 18:57:43 +04:00
bool nss_wrapper_hosts_enabled ( void )
2007-11-05 18:39:46 +03:00
{
2014-01-31 18:57:43 +04:00
nwrap_init ( ) ;
2007-11-05 18:39:46 +03:00
2014-01-31 18:57:43 +04:00
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 )
{
2015-03-23 16:39:28 +03:00
char * line = NULL ;
ssize_t n ;
/* Unused but getline needs it */
size_t len ;
bool ok ;
2014-01-31 18:57:43 +04:00
if ( nwrap - > st . st_size = = 0 ) {
NWRAP_LOG ( NWRAP_LOG_DEBUG , " size == 0 " ) ;
2015-03-23 16:39:28 +03:00
return true ;
2007-11-05 18:39:46 +03:00
}
2015-03-23 16:39:28 +03:00
/* Support for 32-bit system I guess */
2007-11-05 18:39:46 +03:00
if ( nwrap - > st . st_size > INT32_MAX ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Size[%u] larger than INT32_MAX " ,
( unsigned ) nwrap - > st . st_size ) ;
2015-03-23 16:39:28 +03:00
return false ;
2007-11-05 18:39:46 +03:00
}
2015-03-23 16:39:28 +03:00
rewind ( nwrap - > fp ) ;
2007-11-05 18:39:46 +03:00
2015-03-23 16:39:28 +03:00
do {
n = getline ( & line , & len , nwrap - > fp ) ;
if ( n < 0 ) {
2015-10-08 12:36:33 +03:00
SAFE_FREE ( line ) ;
2015-03-23 16:39:28 +03:00
if ( feof ( nwrap - > fp ) ) {
break ;
}
2007-11-05 18:39:46 +03:00
2015-03-23 16:39:28 +03:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Unable to read line from file: %s " ,
nwrap - > path ) ;
return false ;
}
2007-11-05 18:39:46 +03:00
2015-03-23 16:39:28 +03:00
if ( line [ n - 1 ] = = ' \n ' ) {
line [ n - 1 ] = ' \0 ' ;
2007-11-05 18:39:46 +03:00
}
2015-03-23 16:39:28 +03:00
if ( line [ 0 ] = = ' \0 ' ) {
SAFE_FREE ( line ) ;
2007-11-05 18:39:46 +03:00
continue ;
}
ok = nwrap - > parse_line ( nwrap , line ) ;
if ( ! ok ) {
2015-03-23 16:39:28 +03:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Unable to parse line file: %s " ,
line ) ;
SAFE_FREE ( line ) ;
return false ;
2007-11-05 18:39:46 +03:00
}
2015-03-23 16:39:28 +03:00
/* 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 ) ) ;
2007-11-05 18:39:46 +03:00
2015-03-23 16:39:28 +03:00
return true ;
2007-11-05 18:39:46 +03:00
}
2009-06-06 03:14:04 +04:00
static void nwrap_files_cache_unload ( struct nwrap_cache * nwrap )
2007-11-05 18:39:46 +03:00
{
nwrap - > unload ( nwrap ) ;
2015-03-23 16:39:28 +03:00
nwrap_lines_unload ( nwrap ) ;
2007-11-05 18:39:46 +03:00
}
2015-11-11 14:33:12 +03:00
static bool nwrap_files_cache_reload ( struct nwrap_cache * nwrap )
2007-11-05 18:39:46 +03:00
{
struct stat st ;
int ret ;
bool ok ;
bool retried = false ;
2015-03-23 16:39:28 +03:00
assert ( nwrap ! = NULL ) ;
2007-11-05 18:39:46 +03:00
reopen :
if ( nwrap - > fd < 0 ) {
2015-03-23 16:39:28 +03:00
nwrap - > fp = fopen ( nwrap - > path , " re " ) ;
if ( nwrap - > fp = = NULL ) {
nwrap - > fd = - 1 ;
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Unable to open '%s' readonly %d:%s " ,
nwrap - > path , nwrap - > fd ,
strerror ( errno ) ) ;
2015-11-11 14:33:12 +03:00
return false ;
2015-03-23 16:39:28 +03:00
2007-11-05 18:39:46 +03:00
}
2015-03-23 16:39:28 +03:00
nwrap - > fd = fileno ( nwrap - > fp ) ;
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_DEBUG , " Open '%s' " , nwrap - > path ) ;
2007-11-05 18:39:46 +03:00
}
ret = fstat ( nwrap - > fd , & st ) ;
2022-06-24 11:39:57 +03:00
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 ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" fstat(%s) - %d:%s " ,
nwrap - > path ,
ret ,
strerror ( errno ) ) ;
2015-03-23 16:39:28 +03:00
fclose ( nwrap - > fp ) ;
nwrap - > fp = NULL ;
nwrap - > fd = - 1 ;
2015-11-11 14:33:12 +03:00
return false ;
2007-11-05 18:39:46 +03:00
}
if ( retried = = false & & st . st_nlink = = 0 ) {
/* maybe someone has replaced the file... */
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_TRACE ,
" st_nlink == 0, reopen %s " ,
nwrap - > path ) ;
2007-11-05 18:39:46 +03:00
retried = true ;
memset ( & nwrap - > st , 0 , sizeof ( nwrap - > st ) ) ;
2015-03-23 16:39:28 +03:00
fclose ( nwrap - > fp ) ;
nwrap - > fp = NULL ;
2007-11-05 18:39:46 +03:00
nwrap - > fd = - 1 ;
goto reopen ;
}
if ( st . st_mtime = = nwrap - > st . st_mtime ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_TRACE ,
" st_mtime[%u] hasn't changed, skip reload " ,
( unsigned ) st . st_mtime ) ;
2015-11-11 14:33:12 +03:00
return true ;
2007-11-05 18:39:46 +03:00
}
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_TRACE ,
" st_mtime has changed [%u] => [%u], start reload " ,
( unsigned ) st . st_mtime ,
( unsigned ) nwrap - > st . st_mtime ) ;
2007-11-05 18:39:46 +03:00
nwrap - > st = st ;
2009-06-06 03:14:04 +04:00
nwrap_files_cache_unload ( nwrap ) ;
2007-11-05 18:39:46 +03:00
ok = nwrap_parse_file ( nwrap ) ;
if ( ! ok ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR , " Failed to reload %s " , nwrap - > path ) ;
2009-06-06 03:14:04 +04:00
nwrap_files_cache_unload ( nwrap ) ;
2015-11-11 14:33:12 +03:00
return false ;
2007-11-05 18:39:46 +03:00
}
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_TRACE , " Reloaded %s " , nwrap - > path ) ;
2015-11-11 14:33:12 +03:00
return true ;
2007-11-05 18:39:46 +03:00
}
/*
* 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 ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" realloc(%u) failed " ,
( unsigned ) list_size ) ;
2007-11-05 18:39:46 +03:00
return false ;
}
nwrap_pw - > list = pw ;
pw = & nwrap_pw - > list [ nwrap_pw - > num ] ;
c = line ;
/* name */
p = strchr ( c , ' : ' ) ;
if ( ! p ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Invalid line[%s]: '%s' " ,
line ,
c ) ;
2007-11-05 18:39:46 +03:00
return false ;
}
* p = ' \0 ' ;
p + + ;
pw - > pw_name = c ;
c = p ;
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_TRACE , " name[%s] \n " , pw - > pw_name ) ;
2007-11-05 18:39:46 +03:00
/* password */
p = strchr ( c , ' : ' ) ;
if ( ! p ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR , " Invalid line[%s]: '%s' " , line , c ) ;
2007-11-05 18:39:46 +03:00
return false ;
}
* p = ' \0 ' ;
p + + ;
pw - > pw_passwd = c ;
c = p ;
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_TRACE , " password[%s] \n " , pw - > pw_passwd ) ;
2007-11-05 18:39:46 +03:00
/* uid */
p = strchr ( c , ' : ' ) ;
if ( ! p ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR , " Invalid line[%s]: '%s' " , line , c ) ;
2007-11-05 18:39:46 +03:00
return false ;
}
* p = ' \0 ' ;
p + + ;
e = NULL ;
pw - > pw_uid = ( uid_t ) strtoul ( c , & e , 10 ) ;
if ( c = = e ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Invalid line[%s]: '%s' - %s " ,
line , c , strerror ( errno ) ) ;
2007-11-05 18:39:46 +03:00
return false ;
}
if ( e = = NULL ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Invalid line[%s]: '%s' - %s " ,
line , c , strerror ( errno ) ) ;
2007-11-05 18:39:46 +03:00
return false ;
}
if ( e [ 0 ] ! = ' \0 ' ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Invalid line[%s]: '%s' - %s " ,
line , c , strerror ( errno ) ) ;
2007-11-05 18:39:46 +03:00
return false ;
}
c = p ;
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_TRACE , " uid[%u] " , pw - > pw_uid ) ;
2007-11-05 18:39:46 +03:00
/* gid */
p = strchr ( c , ' : ' ) ;
if ( ! p ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR , " Invalid line[%s]: '%s' " , line , c ) ;
2007-11-05 18:39:46 +03:00
return false ;
}
* p = ' \0 ' ;
p + + ;
e = NULL ;
pw - > pw_gid = ( gid_t ) strtoul ( c , & e , 10 ) ;
if ( c = = e ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Invalid line[%s]: '%s' - %s " ,
line , c , strerror ( errno ) ) ;
2007-11-05 18:39:46 +03:00
return false ;
}
if ( e = = NULL ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Invalid line[%s]: '%s' - %s " ,
line , c , strerror ( errno ) ) ;
2007-11-05 18:39:46 +03:00
return false ;
}
if ( e [ 0 ] ! = ' \0 ' ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Invalid line[%s]: '%s' - %s " ,
line , c , strerror ( errno ) ) ;
2007-11-05 18:39:46 +03:00
return false ;
}
c = p ;
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_TRACE , " gid[%u] \n " , pw - > pw_gid ) ;
2007-11-05 18:39:46 +03:00
2016-03-18 14:03:28 +03:00
# ifdef HAVE_STRUCT_PASSWD_PW_CLASS
pw - > pw_class = discard_const_p ( char , " " ) ;
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 */
2007-11-05 18:39:46 +03:00
/* gecos */
p = strchr ( c , ' : ' ) ;
if ( ! p ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR , " invalid line[%s]: '%s' " , line , c ) ;
2007-11-05 18:39:46 +03:00
return false ;
}
* p = ' \0 ' ;
p + + ;
pw - > pw_gecos = c ;
c = p ;
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_TRACE , " gecos[%s] " , pw - > pw_gecos ) ;
2007-11-05 18:39:46 +03:00
/* dir */
p = strchr ( c , ' : ' ) ;
if ( ! p ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR , " '%s' " , c ) ;
2007-11-05 18:39:46 +03:00
return false ;
}
* p = ' \0 ' ;
p + + ;
pw - > pw_dir = c ;
c = p ;
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_TRACE , " dir[%s] " , pw - > pw_dir ) ;
2007-11-05 18:39:46 +03:00
/* shell */
pw - > pw_shell = c ;
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_TRACE , " shell[%s] " , pw - > pw_shell ) ;
2007-11-05 18:39:46 +03:00
2014-01-31 18:57:43 +04:00
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 ) ;
2007-11-05 18:39:46 +03:00
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 ;
2014-11-29 15:22:46 +03:00
SAFE_FREE ( nwrap_pw - > list ) ;
2007-11-05 18:39:46 +03:00
nwrap_pw - > num = 0 ;
nwrap_pw - > idx = 0 ;
}
static int nwrap_pw_copy_r ( const struct passwd * src , struct passwd * dst ,
2007-11-06 15:11:35 +03:00
char * buf , size_t buflen , struct passwd * * dstp )
2007-11-05 18:39:46 +03:00
{
char * first ;
char * last ;
off_t ofs ;
first = src - > pw_name ;
last = src - > pw_shell ;
while ( * last ) last + + ;
ofs = PTR_DIFF ( last + 1 , first ) ;
2014-01-31 18:57:43 +04:00
if ( ofs > ( off_t ) buflen ) {
2007-11-05 18:39:46 +03:00
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 ;
2019-05-21 09:00:05 +03:00
# 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 */
2007-11-05 18:39:46 +03:00
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 ;
2007-11-06 15:11:35 +03:00
if ( dstp ) {
* dstp = dst ;
}
2007-11-05 18:39:46 +03:00
return 0 ;
}
2015-10-06 11:34:20 +03:00
# if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM)
2015-09-17 11:33:58 +03:00
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 ;
}
2015-10-06 11:34:20 +03:00
# endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */
2015-09-17 11:33:58 +03:00
2007-11-05 18:41:23 +03:00
/*
* 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 ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR , " realloc failed " ) ;
2007-11-05 18:41:23 +03:00
return false ;
}
nwrap_gr - > list = gr ;
gr = & nwrap_gr - > list [ nwrap_gr - > num ] ;
c = line ;
/* name */
p = strchr ( c , ' : ' ) ;
if ( ! p ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR , " Invalid line[%s]: '%s' " , line , c ) ;
2007-11-05 18:41:23 +03:00
return false ;
}
* p = ' \0 ' ;
p + + ;
gr - > gr_name = c ;
c = p ;
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_TRACE , " name[%s] " , gr - > gr_name ) ;
2007-11-05 18:41:23 +03:00
/* password */
p = strchr ( c , ' : ' ) ;
if ( ! p ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR , " Invalid line[%s]: '%s' " , line , c ) ;
2007-11-05 18:41:23 +03:00
return false ;
}
* p = ' \0 ' ;
p + + ;
gr - > gr_passwd = c ;
c = p ;
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_TRACE , " password[%s] " , gr - > gr_passwd ) ;
2007-11-05 18:41:23 +03:00
/* gid */
p = strchr ( c , ' : ' ) ;
if ( ! p ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR , " Invalid line[%s]: '%s' " , line , c ) ;
2007-11-05 18:41:23 +03:00
return false ;
}
* p = ' \0 ' ;
p + + ;
e = NULL ;
gr - > gr_gid = ( gid_t ) strtoul ( c , & e , 10 ) ;
if ( c = = e ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Invalid line[%s]: '%s' - %s " ,
line , c , strerror ( errno ) ) ;
2007-11-05 18:41:23 +03:00
return false ;
}
if ( e = = NULL ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Invalid line[%s]: '%s' - %s " ,
line , c , strerror ( errno ) ) ;
2007-11-05 18:41:23 +03:00
return false ;
}
if ( e [ 0 ] ! = ' \0 ' ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Invalid line[%s]: '%s' - %s " ,
line , c , strerror ( errno ) ) ;
2007-11-05 18:41:23 +03:00
return false ;
}
c = p ;
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_TRACE , " gid[%u] " , gr - > gr_gid ) ;
2007-11-05 18:41:23 +03:00
/* members */
gr - > gr_mem = ( char * * ) malloc ( sizeof ( char * ) ) ;
if ( ! gr - > gr_mem ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR , " Out of memory " ) ;
2007-11-05 18:41:23 +03:00
return false ;
}
gr - > gr_mem [ 0 ] = NULL ;
2019-05-21 09:00:05 +03:00
for ( nummem = 0 ; p ! = NULL & & p [ 0 ] ! = ' \0 ' ; nummem + + ) {
2007-11-05 18:41:23 +03:00
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 ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" realloc(%zd) failed " ,
m_size ) ;
2007-11-05 18:41:23 +03:00
return false ;
}
gr - > gr_mem = m ;
gr - > gr_mem [ nummem ] = c ;
gr - > gr_mem [ nummem + 1 ] = NULL ;
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_TRACE ,
" member[%u]: '%s' " ,
nummem , gr - > gr_mem [ nummem ] ) ;
2007-11-05 18:41:23 +03:00
}
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_DEBUG ,
" Added group[%s:%s:%u:] with %u members " ,
gr - > gr_name , gr - > gr_passwd , gr - > gr_gid , nummem ) ;
2007-11-05 18:41:23 +03:00
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 + + ) {
2014-11-29 15:22:46 +03:00
SAFE_FREE ( nwrap_gr - > list [ i ] . gr_mem ) ;
2007-11-05 18:41:23 +03:00
}
2014-11-29 15:22:46 +03:00
SAFE_FREE ( nwrap_gr - > list ) ;
2007-11-05 18:41:23 +03:00
}
nwrap_gr - > num = 0 ;
nwrap_gr - > idx = 0 ;
}
2015-11-11 12:27:50 +03:00
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 ;
}
2015-11-12 10:29:57 +03:00
static bool nwrap_ed_inventarize_add_new ( char * const h_name ,
struct nwrap_entdata * const ed )
2015-07-15 16:05:28 +03:00
{
ENTRY e ;
ENTRY * p ;
2015-11-11 12:27:50 +03:00
struct nwrap_entlist * el ;
2015-11-19 03:00:16 +03:00
bool ok ;
2015-11-11 12:27:50 +03:00
2015-11-11 14:25:30 +03:00
if ( h_name = = NULL ) {
NWRAP_LOG ( NWRAP_LOG_ERROR , " h_name NULL - can't add " ) ;
return false ;
}
2015-11-11 12:27:50 +03:00
el = nwrap_entlist_init ( ed ) ;
if ( el = = NULL ) {
return false ;
}
2015-07-15 16:05:28 +03:00
e . key = h_name ;
2015-11-11 12:27:50 +03:00
e . data = ( void * ) el ;
2015-07-15 16:05:28 +03:00
p = hsearch ( e , ENTER ) ;
if ( p = = NULL ) {
2018-10-31 10:44:08 +03:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Hash table is full (%s)! " ,
strerror ( errno ) ) ;
2015-07-15 16:05:28 +03:00
return false ;
}
2015-11-19 03:00:16 +03:00
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 ;
}
2015-07-15 16:05:28 +03:00
return true ;
}
2015-11-12 10:29:57 +03:00
static bool nwrap_ed_inventarize_add_to_existing ( struct nwrap_entdata * const ed ,
struct nwrap_entlist * const el )
2015-07-15 16:05:28 +03:00
{
2015-11-11 12:27:50 +03:00
struct nwrap_entlist * cursor ;
struct nwrap_entlist * el_new ;
2015-11-11 14:26:02 +03:00
if ( el = = NULL ) {
NWRAP_LOG ( NWRAP_LOG_ERROR , " list is NULL, can not add " ) ;
return false ;
}
2015-11-11 12:27:50 +03:00
for ( cursor = el ; cursor - > next ! = NULL ; cursor = cursor - > next )
{
if ( cursor - > ed = = ed ) {
2015-11-24 19:32:47 +03:00
/* The entry already exists in this list. */
return true ;
2015-07-15 16:05:28 +03:00
}
}
2015-11-11 12:27:50 +03:00
if ( cursor - > ed = = ed ) {
2015-11-24 19:32:47 +03:00
/* The entry already exists in this list. */
return true ;
2015-11-17 01:38:51 +03:00
}
el_new = nwrap_entlist_init ( ed ) ;
if ( el_new = = NULL ) {
2015-11-11 13:56:59 +03:00
return false ;
2015-11-11 12:27:50 +03:00
}
cursor - > next = el_new ;
2015-11-11 13:56:59 +03:00
return true ;
2015-07-15 16:05:28 +03:00
}
2015-11-12 10:29:57 +03:00
static bool nwrap_ed_inventarize ( char * const name ,
struct nwrap_entdata * const ed )
2015-07-15 16:05:28 +03:00
{
ENTRY e ;
ENTRY * p ;
2015-11-11 14:27:33 +03:00
bool ok ;
2015-07-15 16:05:28 +03:00
2015-11-12 10:29:57 +03:00
e . key = name ;
2015-07-15 16:05:28 +03:00
e . data = NULL ;
2015-11-12 10:29:57 +03:00
2015-07-15 16:05:28 +03:00
NWRAP_LOG ( NWRAP_LOG_DEBUG , " Searching name: %s " , e . key ) ;
2015-11-12 10:29:57 +03:00
2015-07-15 16:05:28 +03:00
p = hsearch ( e , FIND ) ;
if ( p = = NULL ) {
2015-11-12 10:29:57 +03:00
NWRAP_LOG ( NWRAP_LOG_DEBUG , " Name %s not found. Adding... " , name ) ;
ok = nwrap_ed_inventarize_add_new ( name , ed ) ;
2015-07-15 16:05:28 +03:00
} else {
2015-11-11 12:27:50 +03:00
struct nwrap_entlist * el = ( struct nwrap_entlist * ) p - > data ;
2015-07-15 16:05:28 +03:00
2015-11-12 10:29:57 +03:00
NWRAP_LOG ( NWRAP_LOG_DEBUG , " Name %s found. Add record to list. " , name ) ;
ok = nwrap_ed_inventarize_add_to_existing ( ed , el ) ;
2015-07-15 16:05:28 +03:00
}
2015-11-11 14:27:33 +03:00
return ok ;
2015-07-15 16:05:28 +03:00
}
2015-11-09 19:36:37 +03:00
static bool nwrap_add_hname ( struct nwrap_entdata * const ed )
2015-07-15 16:05:28 +03:00
{
2015-11-09 19:36:37 +03:00
char * const h_name = ( char * const ) ( ed - > ht . h_name ) ;
2015-07-15 16:05:28 +03:00
unsigned i ;
2015-11-11 14:28:58 +03:00
bool ok ;
2015-07-15 16:05:28 +03:00
2015-11-12 10:29:57 +03:00
ok = nwrap_ed_inventarize ( h_name , ed ) ;
2015-11-11 14:28:58 +03:00
if ( ! ok ) {
return false ;
2015-07-15 16:05:28 +03:00
}
if ( ed - > ht . h_aliases = = NULL ) {
return true ;
}
/* Itemize aliases */
for ( i = 0 ; ed - > ht . h_aliases [ i ] ! = NULL ; + + i ) {
2015-11-09 19:41:43 +03:00
char * h_name_alias ;
2015-07-15 16:05:28 +03:00
h_name_alias = ed - > ht . h_aliases [ i ] ;
NWRAP_LOG ( NWRAP_LOG_DEBUG , " Add alias: %s " , h_name_alias ) ;
2015-11-12 10:29:57 +03:00
if ( ! nwrap_ed_inventarize ( h_name_alias , ed ) ) {
2015-11-11 14:29:55 +03:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
2015-07-15 16:05:28 +03:00
" Unable to add alias: %s " , h_name_alias ) ;
2015-11-11 14:28:58 +03:00
return false ;
2015-07-15 16:05:28 +03:00
}
}
return true ;
}
2014-01-31 18:57:43 +04:00
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 ;
2015-07-15 16:00:02 +03:00
ssize_t aliases_count = 0 ;
2014-01-31 18:57:43 +04:00
char * p ;
char * i ;
char * n ;
2015-07-16 17:10:20 +03:00
char * ip ;
2015-11-11 14:30:36 +03:00
bool ok ;
2014-01-31 18:57:43 +04:00
2015-07-16 17:10:20 +03:00
struct nwrap_entdata * ed = ( struct nwrap_entdata * )
malloc ( sizeof ( struct nwrap_entdata ) ) ;
2014-01-31 18:57:43 +04:00
if ( ed = = NULL ) {
2015-07-16 17:10:20 +03:00
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Unable to allocate memory for nwrap_entdata " ) ;
2014-01-31 18:57:43 +04:00
return false ;
}
2015-07-16 17:10:20 +03:00
ZERO_STRUCTP ( ed ) ;
2014-01-31 18:57:43 +04:00
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 ) ;
2015-07-16 17:10:20 +03:00
free ( ed ) ;
2014-01-31 18:57:43 +04:00
return false ;
}
}
for ( i = p ; ! isspace ( ( int ) * p ) ; p + + ) {
if ( * p = = ' \0 ' ) {
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Invalid line[%s]: '%s' " ,
line , i ) ;
2015-07-16 17:10:20 +03:00
free ( ed ) ;
2014-01-31 18:57:43 +04:00
return false ;
}
}
* p = ' \0 ' ;
2015-07-16 17:10:20 +03:00
if ( inet_pton ( AF_INET , i , ed - > addr . host_addr ) ) {
2014-01-31 18:57:43 +04:00
ed - > ht . h_addrtype = AF_INET ;
ed - > ht . h_length = 4 ;
# ifdef HAVE_IPV6
2015-07-16 17:10:20 +03:00
} else if ( inet_pton ( AF_INET6 , i , ed - > addr . host_addr ) ) {
2014-01-31 18:57:43 +04:00
ed - > ht . h_addrtype = AF_INET6 ;
ed - > ht . h_length = 16 ;
# endif
} else {
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Invalid line[%s]: '%s' " ,
line , i ) ;
2015-07-16 17:10:20 +03:00
free ( ed ) ;
2014-01-31 18:57:43 +04:00
return false ;
}
2015-07-16 17:10:20 +03:00
ip = i ;
2014-01-31 18:57:43 +04:00
2015-11-19 02:34:54 +03:00
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 ;
}
2015-07-16 17:10:20 +03:00
ed - > ht . h_addr_list = nwrap_vector_head ( & ed - > nwrap_addrdata ) ;
2014-01-31 18:57:43 +04:00
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 ) ;
2015-07-16 17:10:20 +03:00
free ( ed ) ;
2014-01-31 18:57:43 +04:00
return false ;
}
}
for ( n = p ; ! isspace ( ( int ) * p ) ; p + + ) {
if ( * p = = ' \0 ' ) {
do_aliases = false ;
break ;
}
}
* p = ' \0 ' ;
2015-07-16 17:10:20 +03:00
/* Convert to lowercase. This operate on same memory region */
str_tolower ( n , n ) ;
2014-01-31 18:57:43 +04:00
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 ) {
2015-07-16 17:10:20 +03:00
free ( ed ) ;
2014-01-31 18:57:43 +04:00
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 ) {
2015-07-16 17:10:20 +03:00
free ( ed ) ;
2014-01-31 18:57:43 +04:00
return false ;
}
ed - > ht . h_aliases = aliases ;
2015-07-16 17:10:20 +03:00
str_tolower ( a , a ) ;
2014-01-31 18:57:43 +04:00
aliases [ aliases_count ] = a ;
aliases [ aliases_count + 1 ] = NULL ;
2015-07-16 17:10:20 +03:00
aliases_count + = 1 ;
2014-01-31 18:57:43 +04:00
}
2015-11-19 02:34:54 +03:00
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 ;
}
2015-07-16 17:10:20 +03:00
ed - > aliases_count = aliases_count ;
/* Inventarize item */
2015-11-11 14:30:36 +03:00
ok = nwrap_add_hname ( ed ) ;
if ( ! ok ) {
return false ;
}
2015-11-12 10:34:39 +03:00
ok = nwrap_ed_inventarize ( ip , ed ) ;
2015-11-11 14:30:36 +03:00
if ( ! ok ) {
return false ;
}
2015-07-16 17:10:20 +03:00
2014-01-31 18:57:43 +04:00
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 ;
2015-07-16 17:10:20 +03:00
struct nwrap_entdata * ed ;
2015-11-19 03:00:16 +03:00
struct nwrap_entlist * el ;
2015-07-16 17:10:20 +03:00
size_t i ;
2015-12-17 10:46:33 +03:00
int rc ;
2014-01-31 18:57:43 +04:00
2015-11-19 02:30:17 +03:00
nwrap_vector_foreach ( ed , nwrap_he - > entries , i )
2015-07-16 17:10:20 +03:00
{
2015-10-08 16:00:33 +03:00
SAFE_FREE ( ed - > nwrap_addrdata . items ) ;
2015-07-16 17:10:20 +03:00
SAFE_FREE ( ed - > ht . h_aliases ) ;
SAFE_FREE ( ed ) ;
2014-01-31 18:57:43 +04:00
}
2015-11-19 02:30:17 +03:00
SAFE_FREE ( nwrap_he - > entries . items ) ;
nwrap_he - > entries . count = nwrap_he - > entries . capacity = 0 ;
2014-01-31 18:57:43 +04:00
2015-11-19 03:00:16 +03:00
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 ;
2014-01-31 18:57:43 +04:00
nwrap_he - > num = 0 ;
nwrap_he - > idx = 0 ;
2015-12-17 10:46:33 +03:00
/*
* 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 ) ;
}
2014-01-31 18:57:43 +04:00
}
2007-11-05 18:38:36 +03:00
/* user functions */
2009-06-03 13:10:13 +04:00
static struct passwd * nwrap_files_getpwnam ( struct nwrap_backend * b ,
const char * name )
2007-11-05 18:38:36 +03:00
{
2007-11-05 18:39:46 +03:00
int i ;
2015-11-11 14:47:15 +03:00
bool ok ;
2007-11-05 18:39:46 +03:00
2014-01-31 18:57:43 +04:00
( void ) b ; /* unused */
NWRAP_LOG ( NWRAP_LOG_DEBUG , " Lookup user %s in files " , name ) ;
2015-11-11 14:47:15 +03:00
ok = nwrap_files_cache_reload ( nwrap_pw_global . cache ) ;
if ( ! ok ) {
NWRAP_LOG ( NWRAP_LOG_ERROR , " Error loading passwd file " ) ;
return NULL ;
}
2007-11-05 18:39:46 +03:00
for ( i = 0 ; i < nwrap_pw_global . num ; i + + ) {
if ( strcmp ( nwrap_pw_global . list [ i ] . pw_name , name ) = = 0 ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_DEBUG , " user[%s] found " , name ) ;
2007-11-05 18:39:46 +03:00
return & nwrap_pw_global . list [ i ] ;
}
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_DEBUG ,
" user[%s] does not match [%s] " ,
name ,
nwrap_pw_global . list [ i ] . pw_name ) ;
2007-11-05 18:39:46 +03:00
}
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_DEBUG , " user[%s] not found \n " , name ) ;
2007-11-05 18:39:46 +03:00
errno = ENOENT ;
return NULL ;
2007-11-05 18:38:36 +03:00
}
2009-06-03 13:10:13 +04:00
static int nwrap_files_getpwnam_r ( struct nwrap_backend * b ,
const char * name , struct passwd * pwdst ,
2009-05-27 20:38:10 +04:00
char * buf , size_t buflen , struct passwd * * pwdstp )
{
struct passwd * pw ;
2009-06-03 13:10:13 +04:00
pw = nwrap_files_getpwnam ( b , name ) ;
2007-11-05 18:39:46 +03:00
if ( ! pw ) {
if ( errno = = 0 ) {
return ENOENT ;
}
return errno ;
}
return nwrap_pw_copy_r ( pw , pwdst , buf , buflen , pwdstp ) ;
2007-11-05 18:38:36 +03:00
}
2009-06-03 13:10:13 +04:00
static struct passwd * nwrap_files_getpwuid ( struct nwrap_backend * b ,
uid_t uid )
2009-05-27 20:38:10 +04:00
{
int i ;
2015-11-11 14:47:15 +03:00
bool ok ;
2009-05-27 20:38:10 +04:00
2014-01-31 18:57:43 +04:00
( void ) b ; /* unused */
2015-11-11 14:47:15 +03:00
ok = nwrap_files_cache_reload ( nwrap_pw_global . cache ) ;
if ( ! ok ) {
NWRAP_LOG ( NWRAP_LOG_ERROR , " Error loading passwd file " ) ;
return NULL ;
}
2007-11-05 18:39:46 +03:00
for ( i = 0 ; i < nwrap_pw_global . num ; i + + ) {
if ( nwrap_pw_global . list [ i ] . pw_uid = = uid ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_DEBUG , " uid[%u] found " , uid ) ;
2007-11-05 18:39:46 +03:00
return & nwrap_pw_global . list [ i ] ;
}
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_DEBUG ,
" uid[%u] does not match [%u] " ,
uid ,
nwrap_pw_global . list [ i ] . pw_uid ) ;
2007-11-05 18:39:46 +03:00
}
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_DEBUG , " uid[%u] not found \n " , uid ) ;
2007-11-05 18:39:46 +03:00
errno = ENOENT ;
return NULL ;
2007-11-05 18:38:36 +03:00
}
2009-06-03 13:10:13 +04:00
static int nwrap_files_getpwuid_r ( struct nwrap_backend * b ,
uid_t uid , struct passwd * pwdst ,
2009-05-27 20:38:10 +04:00
char * buf , size_t buflen , struct passwd * * pwdstp )
{
struct passwd * pw ;
2009-06-03 13:10:13 +04:00
pw = nwrap_files_getpwuid ( b , uid ) ;
2007-11-05 18:39:46 +03:00
if ( ! pw ) {
if ( errno = = 0 ) {
return ENOENT ;
}
return errno ;
}
return nwrap_pw_copy_r ( pw , pwdst , buf , buflen , pwdstp ) ;
2007-11-05 18:38:36 +03:00
}
/* user enum functions */
2009-06-03 13:10:13 +04:00
static void nwrap_files_setpwent ( struct nwrap_backend * b )
2009-05-27 20:38:10 +04:00
{
2014-01-31 18:57:43 +04:00
( void ) b ; /* unused */
2009-05-27 20:38:10 +04:00
nwrap_pw_global . idx = 0 ;
}
2009-06-03 13:10:13 +04:00
static struct passwd * nwrap_files_getpwent ( struct nwrap_backend * b )
2007-11-05 18:38:36 +03:00
{
2007-11-05 18:39:46 +03:00
struct passwd * pw ;
2014-01-31 18:57:43 +04:00
( void ) b ; /* unused */
2007-11-05 18:39:46 +03:00
if ( nwrap_pw_global . idx = = 0 ) {
2015-11-11 14:47:15 +03:00
bool ok ;
ok = nwrap_files_cache_reload ( nwrap_pw_global . cache ) ;
if ( ! ok ) {
NWRAP_LOG ( NWRAP_LOG_ERROR , " Error loading passwd file " ) ;
return NULL ;
}
2007-11-05 18:39:46 +03:00
}
if ( nwrap_pw_global . idx > = nwrap_pw_global . num ) {
errno = ENOENT ;
return NULL ;
}
pw = & nwrap_pw_global . list [ nwrap_pw_global . idx + + ] ;
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_DEBUG ,
" return user[%s] uid[%u] " ,
pw - > pw_name , pw - > pw_uid ) ;
2007-11-05 18:39:46 +03:00
return pw ;
2007-11-05 18:38:36 +03:00
}
2009-06-03 13:10:13 +04:00
static int nwrap_files_getpwent_r ( struct nwrap_backend * b ,
struct passwd * pwdst , char * buf ,
2009-05-27 20:38:10 +04:00
size_t buflen , struct passwd * * pwdstp )
2007-11-05 18:38:36 +03:00
{
2007-11-05 18:39:46 +03:00
struct passwd * pw ;
2009-06-03 13:10:13 +04:00
pw = nwrap_files_getpwent ( b ) ;
2009-05-27 20:38:10 +04:00
if ( ! pw ) {
if ( errno = = 0 ) {
return ENOENT ;
}
return errno ;
}
return nwrap_pw_copy_r ( pw , pwdst , buf , buflen , pwdstp ) ;
}
2009-06-03 13:10:13 +04:00
static void nwrap_files_endpwent ( struct nwrap_backend * b )
2009-05-27 20:38:10 +04:00
{
2014-01-31 18:57:43 +04:00
( void ) b ; /* unused */
2009-05-27 20:38:10 +04:00
nwrap_pw_global . idx = 0 ;
2007-11-05 18:38:36 +03:00
}
2015-09-17 11:38:49 +03:00
/* shadow */
2015-10-06 11:34:20 +03:00
# if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM)
# ifdef HAVE_SETSPENT
2015-09-17 11:38:49 +03:00
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 ) {
2015-11-11 14:47:15 +03:00
bool ok ;
ok = nwrap_files_cache_reload ( nwrap_sp_global . cache ) ;
if ( ! ok ) {
NWRAP_LOG ( NWRAP_LOG_ERROR , " Error loading shadow file " ) ;
return NULL ;
}
2015-09-17 11:38:49 +03:00
}
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 ;
}
2015-10-06 11:34:20 +03:00
# endif /* HAVE_SETSPENT */
2015-09-17 11:38:49 +03:00
2015-09-17 11:39:15 +03:00
static struct spwd * nwrap_files_getspnam ( const char * name )
{
int i ;
2015-11-11 14:47:15 +03:00
bool ok ;
2015-09-17 11:39:15 +03:00
NWRAP_LOG ( NWRAP_LOG_DEBUG , " Lookup user %s in files " , name ) ;
2015-11-11 14:47:15 +03:00
ok = nwrap_files_cache_reload ( nwrap_sp_global . cache ) ;
if ( ! ok ) {
NWRAP_LOG ( NWRAP_LOG_ERROR , " Error loading shadow file " ) ;
return NULL ;
}
2015-09-17 11:39:15 +03:00
for ( i = 0 ; i < nwrap_sp_global . num ; i + + ) {
if ( strcmp ( nwrap_sp_global . list [ i ] . sp_namp , name ) = = 0 ) {
NWRAP_LOG ( NWRAP_LOG_DEBUG , " user[%s] found " , name ) ;
return & nwrap_sp_global . list [ i ] ;
}
NWRAP_LOG ( NWRAP_LOG_DEBUG ,
" user[%s] does not match [%s] " ,
name ,
nwrap_sp_global . list [ i ] . sp_namp ) ;
}
NWRAP_LOG ( NWRAP_LOG_DEBUG , " user[%s] not found \n " , name ) ;
errno = ENOENT ;
return NULL ;
}
2015-10-06 11:34:20 +03:00
# endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */
2015-09-17 11:39:15 +03:00
2007-11-05 18:38:36 +03:00
/* misc functions */
2023-01-24 13:20:49 +03:00
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 )
2009-05-27 20:38:10 +04:00
{
2015-09-11 14:37:57 +03:00
struct group * grp ;
2023-01-24 13:20:49 +03:00
int i = 0 ;
2015-09-11 14:37:57 +03:00
2023-01-24 13:20:49 +03:00
( void ) errnop ; /* unused */
2015-09-11 14:37:57 +03:00
nwrap_files_setgrent ( b ) ;
while ( ( grp = nwrap_files_getgrent ( b ) ) ! = NULL ) {
NWRAP_LOG ( NWRAP_LOG_DEBUG ,
" Inspecting %s for group membership " ,
grp - > gr_name ) ;
for ( i = 0 ; grp - > gr_mem & & grp - > gr_mem [ i ] ! = NULL ; i + + ) {
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 ) ;
2023-01-24 13:20:49 +03:00
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 ;
2015-09-11 14:37:57 +03:00
}
2023-01-24 13:20:49 +03:00
( * groups ) [ * start ] = grp - > gr_gid ;
( * start ) + + ;
2015-09-11 14:37:57 +03:00
}
}
}
nwrap_files_endgrent ( b ) ;
2023-01-24 13:20:49 +03:00
return * start ;
2009-05-27 20:38:10 +04:00
}
2007-11-05 18:38:36 +03:00
/* group functions */
2009-06-03 13:10:13 +04:00
static struct group * nwrap_files_getgrnam ( struct nwrap_backend * b ,
const char * name )
2007-11-05 18:38:36 +03:00
{
2007-11-05 18:41:23 +03:00
int i ;
2015-11-11 14:47:15 +03:00
bool ok ;
2007-11-05 18:41:23 +03:00
2014-01-31 18:57:43 +04:00
( void ) b ; /* unused */
2015-11-11 14:47:15 +03:00
ok = nwrap_files_cache_reload ( nwrap_gr_global . cache ) ;
if ( ! ok ) {
NWRAP_LOG ( NWRAP_LOG_ERROR , " Error loading group file " ) ;
return NULL ;
}
2007-11-05 18:41:23 +03:00
for ( i = 0 ; i < nwrap_gr_global . num ; i + + ) {
if ( strcmp ( nwrap_gr_global . list [ i ] . gr_name , name ) = = 0 ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_DEBUG , " group[%s] found " , name ) ;
2007-11-05 18:41:23 +03:00
return & nwrap_gr_global . list [ i ] ;
}
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_DEBUG ,
" group[%s] does not match [%s] " ,
name ,
nwrap_gr_global . list [ i ] . gr_name ) ;
2007-11-05 18:41:23 +03:00
}
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_DEBUG , " group[%s] not found " , name ) ;
2007-11-05 18:41:23 +03:00
errno = ENOENT ;
return NULL ;
2007-11-05 18:38:36 +03:00
}
2009-06-03 13:10:13 +04:00
static int nwrap_files_getgrnam_r ( struct nwrap_backend * b ,
const char * name , struct group * grdst ,
2009-05-27 20:38:10 +04:00
char * buf , size_t buflen , struct group * * grdstp )
{
struct group * gr ;
2009-06-03 13:10:13 +04:00
gr = nwrap_files_getgrnam ( b , name ) ;
2007-11-05 18:41:23 +03:00
if ( ! gr ) {
if ( errno = = 0 ) {
return ENOENT ;
}
return errno ;
}
return nwrap_gr_copy_r ( gr , grdst , buf , buflen , grdstp ) ;
2007-11-05 18:38:36 +03:00
}
2009-06-03 13:10:13 +04:00
static struct group * nwrap_files_getgrgid ( struct nwrap_backend * b ,
gid_t gid )
2009-05-27 20:38:10 +04:00
{
int i ;
2015-11-11 14:47:15 +03:00
bool ok ;
2009-05-27 20:38:10 +04:00
2014-01-31 18:57:43 +04:00
( void ) b ; /* unused */
2015-11-11 14:47:15 +03:00
ok = nwrap_files_cache_reload ( nwrap_gr_global . cache ) ;
if ( ! ok ) {
NWRAP_LOG ( NWRAP_LOG_ERROR , " Error loading group file " ) ;
return NULL ;
}
2007-11-05 18:41:23 +03:00
for ( i = 0 ; i < nwrap_gr_global . num ; i + + ) {
if ( nwrap_gr_global . list [ i ] . gr_gid = = gid ) {
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_DEBUG , " gid[%u] found " , gid ) ;
2007-11-05 18:41:23 +03:00
return & nwrap_gr_global . list [ i ] ;
}
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_DEBUG ,
" gid[%u] does not match [%u] " ,
gid ,
nwrap_gr_global . list [ i ] . gr_gid ) ;
2007-11-05 18:41:23 +03:00
}
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_DEBUG , " gid[%u] not found " , gid ) ;
2007-11-05 18:41:23 +03:00
errno = ENOENT ;
return NULL ;
2007-11-05 18:38:36 +03:00
}
2009-06-03 13:10:13 +04:00
static int nwrap_files_getgrgid_r ( struct nwrap_backend * b ,
gid_t gid , struct group * grdst ,
2009-05-27 20:38:10 +04:00
char * buf , size_t buflen , struct group * * grdstp )
{
struct group * gr ;
2009-06-03 13:10:13 +04:00
gr = nwrap_files_getgrgid ( b , gid ) ;
2007-11-05 18:41:23 +03:00
if ( ! gr ) {
if ( errno = = 0 ) {
return ENOENT ;
}
return errno ;
}
return nwrap_gr_copy_r ( gr , grdst , buf , buflen , grdstp ) ;
2007-11-05 18:38:36 +03:00
}
/* group enum functions */
2009-06-03 13:10:13 +04:00
static void nwrap_files_setgrent ( struct nwrap_backend * b )
2009-05-27 20:38:10 +04:00
{
2014-01-31 18:57:43 +04:00
( void ) b ; /* unused */
2009-05-27 20:38:10 +04:00
nwrap_gr_global . idx = 0 ;
}
2009-06-03 13:10:13 +04:00
static struct group * nwrap_files_getgrent ( struct nwrap_backend * b )
2007-11-05 18:38:36 +03:00
{
2007-11-05 18:41:23 +03:00
struct group * gr ;
2014-01-31 18:57:43 +04:00
( void ) b ; /* unused */
2007-11-05 18:41:23 +03:00
if ( nwrap_gr_global . idx = = 0 ) {
2015-11-11 14:47:15 +03:00
bool ok ;
ok = nwrap_files_cache_reload ( nwrap_gr_global . cache ) ;
if ( ! ok ) {
NWRAP_LOG ( NWRAP_LOG_ERROR , " Error loading group file " ) ;
return NULL ;
}
2007-11-05 18:41:23 +03:00
}
if ( nwrap_gr_global . idx > = nwrap_gr_global . num ) {
errno = ENOENT ;
return NULL ;
}
gr = & nwrap_gr_global . list [ nwrap_gr_global . idx + + ] ;
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_DEBUG ,
" return group[%s] gid[%u] " ,
gr - > gr_name , gr - > gr_gid ) ;
2007-11-05 18:41:23 +03:00
return gr ;
2007-11-05 18:38:36 +03:00
}
2009-06-03 13:10:13 +04:00
static int nwrap_files_getgrent_r ( struct nwrap_backend * b ,
struct group * grdst , char * buf ,
2009-05-27 20:38:10 +04:00
size_t buflen , struct group * * grdstp )
2007-11-05 18:38:36 +03:00
{
2007-11-05 18:41:23 +03:00
struct group * gr ;
2009-06-03 13:10:13 +04:00
gr = nwrap_files_getgrent ( b ) ;
2009-05-27 20:38:10 +04:00
if ( ! gr ) {
if ( errno = = 0 ) {
return ENOENT ;
}
return errno ;
}
return nwrap_gr_copy_r ( gr , grdst , buf , buflen , grdstp ) ;
}
2009-06-03 13:10:13 +04:00
static void nwrap_files_endgrent ( struct nwrap_backend * b )
2009-05-27 20:38:10 +04:00
{
2014-01-31 18:57:43 +04:00
( void ) b ; /* unused */
2009-05-27 20:38:10 +04:00
nwrap_gr_global . idx = 0 ;
2007-11-05 18:38:36 +03:00
}
2014-01-31 18:57:43 +04:00
/* hosts functions */
2020-03-16 19:00:16 +03:00
static int nwrap_files_internal_gethostbyname ( const char * name , int af ,
struct hostent * result ,
struct nwrap_vector * addr_list )
2014-01-31 18:57:43 +04:00
{
2015-11-11 12:36:07 +03:00
struct nwrap_entlist * el ;
2014-01-31 18:57:43 +04:00
struct hostent * he ;
2015-07-16 17:10:20 +03:00
char * h_name_lower ;
ENTRY e ;
ENTRY * e_p ;
2014-10-09 11:16:33 +04:00
char canon_name [ DNS_NAME_MAX ] = { 0 } ;
2014-10-09 11:14:57 +04:00
size_t name_len ;
2015-07-16 17:10:20 +03:00
bool he_found = false ;
2015-11-11 14:47:15 +03:00
bool ok ;
2014-01-31 18:57:43 +04:00
2020-03-16 19:00:16 +03:00
/*
* We need to make sure we have zeroed return pointer for consumers
* which don ' t check return values , e . g . OpenLDAP .
*/
ZERO_STRUCTP ( result ) ;
2015-11-11 14:47:15 +03:00
ok = nwrap_files_cache_reload ( nwrap_he_global . cache ) ;
if ( ! ok ) {
NWRAP_LOG ( NWRAP_LOG_ERROR , " error loading hosts file " ) ;
goto no_ent ;
}
2014-01-31 18:57:43 +04:00
2014-10-09 11:14:57 +04:00
name_len = strlen ( name ) ;
if ( name_len < sizeof ( canon_name ) & & name [ name_len - 1 ] = = ' . ' ) {
2019-05-21 09:00:05 +03:00
memcpy ( canon_name , name , name_len - 1 ) ;
canon_name [ name_len ] = ' \0 ' ;
2014-10-09 11:14:57 +04:00
name = canon_name ;
}
2015-07-16 17:10:20 +03:00
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 */
2015-10-08 16:27:47 +03:00
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 ;
2015-07-16 17:10:20 +03:00
}
2014-01-31 18:57:43 +04:00
2015-07-16 17:10:20 +03:00
/* Iterate through results */
2015-11-11 12:36:07 +03:00
for ( el = ( struct nwrap_entlist * ) e_p - > data ; el ! = NULL ; el = el - > next )
{
he = & ( el - > ed - > ht ) ;
2014-01-31 18:57:43 +04:00
/* Filter by address familiy if provided */
if ( af ! = AF_UNSPEC & & he - > h_addrtype ! = af ) {
continue ;
}
2015-07-16 17:10:20 +03:00
/*
* GLIBC HACK ?
* glibc doesn ' t return ipv6 addresses when AF_UNSPEC is used
*/
if ( af = = AF_UNSPEC & & he - > h_addrtype ! = AF_INET ) {
2014-01-31 18:57:43 +04:00
continue ;
}
2015-07-16 17:10:20 +03:00
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 ;
2014-01-31 18:57:43 +04:00
}
2015-11-11 12:36:07 +03:00
nwrap_vector_merge ( addr_list , & el - > ed - > nwrap_addrdata ) ;
2015-07-16 17:10:20 +03:00
result - > h_addr_list = nwrap_vector_head ( addr_list ) ;
2014-01-31 18:57:43 +04:00
}
2015-07-16 17:10:20 +03:00
if ( he_found ) {
return 0 ;
}
NWRAP_LOG ( NWRAP_LOG_DEBUG ,
" Name found in database. No records matches type. " ) ;
no_ent :
2014-01-31 18:57:43 +04:00
errno = ENOENT ;
2015-07-16 17:10:20 +03:00
return - 1 ;
2014-01-31 18:57:43 +04:00
}
2020-03-16 19:00:16 +03:00
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 )
2014-01-31 18:57:43 +04:00
{
2020-03-16 19:00:16 +03:00
struct nwrap_vector * addr_list = NULL ;
2019-05-21 09:00:05 +03:00
union {
char * ptr ;
char * * list ;
} g ;
2015-07-16 17:10:20 +03:00
int rc ;
2020-03-16 19:00:16 +03:00
( 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 ) ) ;
2015-07-16 17:10:20 +03:00
if ( addr_list = = NULL ) {
NWRAP_LOG ( NWRAP_LOG_ERROR ,
" Unable to allocate memory for address list " ) ;
errno = ENOENT ;
return - 1 ;
}
2020-03-16 19:00:16 +03:00
rc = nwrap_files_internal_gethostbyname ( name , af , hedst ,
addr_list ) ;
2015-07-16 17:10:20 +03:00
if ( rc = = - 1 ) {
2020-03-16 19:00:16 +03:00
SAFE_FREE ( addr_list - > items ) ;
2015-07-16 17:10:20 +03:00
SAFE_FREE ( addr_list ) ;
errno = ENOENT ;
2014-01-31 18:57:43 +04:00
return - 1 ;
}
2015-07-16 17:10:20 +03:00
2020-03-16 19:00:16 +03:00
/* +1 i for ending NULL pointer */
if ( buflen < ( ( addr_list - > count + 1 ) * sizeof ( void * ) ) ) {
2015-10-12 11:36:04 +03:00
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 * ) ) ;
2020-03-16 19:00:16 +03:00
SAFE_FREE ( addr_list - > items ) ;
SAFE_FREE ( addr_list ) ;
2015-10-12 11:36:04 +03:00
2019-05-21 09:00:05 +03:00
g . ptr = buf ;
2020-03-16 19:00:16 +03:00
hedst - > h_addr_list = g . list ;
* hedstp = hedst ;
2015-07-16 17:10:20 +03:00
return 0 ;
2014-01-31 18:57:43 +04:00
}
2020-03-16 19:00:16 +03:00
# 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 ;
}
2014-01-31 18:57:43 +04:00
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
2020-03-16 19:00:16 +03:00
# 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
2015-11-11 15:02:59 +03:00
static int nwrap_files_getaddrinfo ( const char * name ,
unsigned short port ,
const struct addrinfo * hints ,
2015-11-12 12:20:37 +03:00
struct addrinfo * * ai )
2015-07-16 17:10:20 +03:00
{
2015-11-11 12:38:31 +03:00
struct nwrap_entlist * el ;
2015-07-16 17:10:20 +03:00
struct hostent * he ;
struct addrinfo * ai_head = NULL ;
2015-11-12 11:45:50 +03:00
struct addrinfo * ai_cur = NULL ;
2015-07-16 17:10:20 +03:00
char * h_name_lower ;
size_t name_len ;
char canon_name [ DNS_NAME_MAX ] = { 0 } ;
bool skip_canonname = false ;
2015-11-16 12:17:39 +03:00
ENTRY e = {
. key = NULL ,
} ;
2015-11-09 19:35:29 +03:00
ENTRY * e_p = NULL ;
2015-11-12 10:01:57 +03:00
int rc ;
2015-11-11 14:47:15 +03:00
bool ok ;
2015-07-16 17:10:20 +03:00
2015-11-11 14:47:15 +03:00
ok = nwrap_files_cache_reload ( nwrap_he_global . cache ) ;
if ( ! ok ) {
NWRAP_LOG ( NWRAP_LOG_ERROR , " error loading hosts file " ) ;
2015-11-11 15:02:59 +03:00
return EAI_SYSTEM ;
2015-11-11 14:47:15 +03:00
}
2015-07-16 17:10:20 +03:00
name_len = strlen ( name ) ;
2022-06-24 11:39:57 +03:00
if ( name_len = = 0 ) {
return EAI_NONAME ;
}
2019-05-21 09:00:05 +03:00
if ( name_len < sizeof ( canon_name ) & & name [ name_len - 1 ] = = ' . ' ) {
memcpy ( canon_name , name , name_len - 1 ) ;
canon_name [ name_len ] = ' \0 ' ;
2015-07-16 17:10:20 +03:00
name = canon_name ;
}
if ( ! str_tolower_copy ( & h_name_lower , name ) ) {
NWRAP_LOG ( NWRAP_LOG_DEBUG ,
" Out of memory while converting to lower case " ) ;
2015-11-11 15:02:59 +03:00
return EAI_MEMORY ;
2015-07-16 17:10:20 +03:00
}
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 ;
2015-11-11 15:02:59 +03:00
return EAI_NONAME ;
2015-07-16 17:10:20 +03:00
}
NWRAP_LOG ( NWRAP_LOG_DEBUG , " Name: %s found. " , h_name_lower ) ;
SAFE_FREE ( h_name_lower ) ;
2015-11-12 10:01:57 +03:00
rc = EAI_NONAME ;
2015-11-11 12:38:31 +03:00
for ( el = ( struct nwrap_entlist * ) e_p - > data ; el ! = NULL ; el = el - > next )
{
2015-11-12 10:01:57 +03:00
int rc2 ;
2015-11-12 12:20:37 +03:00
struct addrinfo * ai_new = NULL ;
2015-07-16 17:10:20 +03:00
2015-11-11 12:38:31 +03:00
he = & ( el - > ed - > ht ) ;
2015-07-16 17:10:20 +03:00
if ( hints - > ai_family ! = AF_UNSPEC & &
2015-11-12 10:01:57 +03:00
he - > h_addrtype ! = hints - > ai_family )
{
NWRAP_LOG ( NWRAP_LOG_DEBUG ,
" Entry found but with wrong AF - "
" remembering EAI_ADDRINFO. " ) ;
rc = EAI_ADDRFAMILY ;
2015-07-16 17:10:20 +03:00
continue ;
}
/* Function allocates memory and returns it in ai. */
2015-11-12 10:01:57 +03:00
rc2 = nwrap_convert_he_ai ( he ,
2015-07-16 17:10:20 +03:00
port ,
hints ,
2015-11-12 11:47:59 +03:00
& ai_new ,
2015-07-16 17:10:20 +03:00
skip_canonname ) ;
2015-11-12 10:01:57 +03:00
if ( rc2 ! = 0 ) {
NWRAP_LOG ( NWRAP_LOG_ERROR , " Error converting he to ai " ) ;
2015-11-12 11:46:29 +03:00
if ( ai_head ! = NULL ) {
freeaddrinfo ( ai_head ) ;
}
2015-11-12 10:01:57 +03:00
return rc2 ;
2015-07-16 17:10:20 +03:00
}
skip_canonname = true ;
if ( ai_head = = NULL ) {
2015-11-12 11:47:59 +03:00
ai_head = ai_new ;
2015-07-16 17:10:20 +03:00
}
2015-11-12 11:45:50 +03:00
if ( ai_cur ! = NULL ) {
2015-11-12 11:47:59 +03:00
ai_cur - > ai_next = ai_new ;
2015-07-16 17:10:20 +03:00
}
2015-11-12 11:47:59 +03:00
ai_cur = ai_new ;
2015-07-16 17:10:20 +03:00
}
2015-11-12 10:01:57 +03:00
if ( ai_head ! = NULL ) {
rc = 0 ;
}
2015-11-11 15:02:59 +03:00
* ai = ai_head ;
2015-11-12 10:01:57 +03:00
return rc ;
2015-07-16 17:10:20 +03:00
}
2020-03-16 19:00:16 +03:00
static struct hostent * nwrap_files_gethostbyaddr ( struct nwrap_backend * b ,
const void * addr ,
2014-01-31 18:57:43 +04:00
socklen_t len , int type )
{
struct hostent * he ;
2015-03-25 11:36:10 +03:00
char ip [ NWRAP_INET_ADDRSTRLEN ] = { 0 } ;
2015-07-16 17:10:20 +03:00
struct nwrap_entdata * ed ;
2014-01-31 18:57:43 +04:00
const char * a ;
2015-07-16 17:10:20 +03:00
size_t i ;
2015-11-11 14:47:15 +03:00
bool ok ;
2014-01-31 18:57:43 +04:00
2020-03-16 19:00:16 +03:00
( void ) b ; /* unused */
2014-01-31 18:57:43 +04:00
( void ) len ; /* unused */
2015-11-11 14:47:15 +03:00
ok = nwrap_files_cache_reload ( nwrap_he_global . cache ) ;
if ( ! ok ) {
NWRAP_LOG ( NWRAP_LOG_ERROR , " error loading hosts file " ) ;
return NULL ;
}
2014-01-31 18:57:43 +04:00
a = inet_ntop ( type , addr , ip , sizeof ( ip ) ) ;
if ( a = = NULL ) {
errno = EINVAL ;
return NULL ;
}
2015-11-19 02:30:17 +03:00
nwrap_vector_foreach ( ed , nwrap_he_global . entries , i )
2015-07-16 17:10:20 +03:00
{
he = & ( ed - > ht ) ;
2014-01-31 18:57:43 +04:00
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 )
{
2020-03-16 19:00:16 +03:00
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 ;
}
}
2014-01-31 18:57:43 +04:00
if ( * result ! = NULL ) {
memset ( buf , ' \0 ' , buflen ) ;
* ret = * * result ;
return 0 ;
}
2020-03-16 19:00:16 +03:00
* h_errnop = h_errno ;
return - 1 ;
2014-01-31 18:57:43 +04:00
}
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 ) {
2015-11-11 14:47:15 +03:00
bool ok ;
ok = nwrap_files_cache_reload ( nwrap_he_global . cache ) ;
if ( ! ok ) {
NWRAP_LOG ( NWRAP_LOG_ERROR , " Error loading hosts file " ) ;
return NULL ;
}
2014-01-31 18:57:43 +04:00
}
if ( nwrap_he_global . idx > = nwrap_he_global . num ) {
errno = ENOENT ;
return NULL ;
}
2015-11-19 02:30:17 +03:00
he = & ( ( struct nwrap_entdata * ) nwrap_he_global . entries . items [ nwrap_he_global . idx + + ] ) - > ht ;
2014-01-31 18:57:43 +04:00
NWRAP_LOG ( NWRAP_LOG_DEBUG , " return hosts[%s] " , he - > h_name ) ;
return he ;
}
static void nwrap_files_endhostent ( void )
{
nwrap_he_global . idx = 0 ;
}
2009-06-04 14:17:39 +04:00
/*
* module backend
*/
2009-06-04 14:25:14 +04:00
2009-06-04 14:17:39 +04:00
static struct passwd * nwrap_module_getpwnam ( struct nwrap_backend * b ,
const char * name )
{
2009-06-04 14:25:14 +04:00
static struct passwd pwd ;
static char buf [ 1000 ] ;
NSS_STATUS status ;
2020-04-02 14:43:44 +03:00
if ( b - > symbols - > _nss_getpwnam_r . f = = NULL ) {
2009-06-04 14:25:14 +04:00
return NULL ;
}
2020-04-02 14:43:44 +03:00
status = b - > symbols - > _nss_getpwnam_r . f ( name ,
& pwd ,
buf ,
sizeof ( buf ) ,
& errno ) ;
2009-06-04 14:25:14 +04:00
if ( status = = NSS_STATUS_NOTFOUND ) {
return NULL ;
}
if ( status ! = NSS_STATUS_SUCCESS ) {
return NULL ;
}
2014-01-31 18:57:43 +04:00
2009-06-04 14:25:14 +04:00
return & pwd ;
2009-06-04 14:17:39 +04:00
}
static int nwrap_module_getpwnam_r ( struct nwrap_backend * b ,
const char * name , struct passwd * pwdst ,
char * buf , size_t buflen , struct passwd * * pwdstp )
{
2009-06-04 14:25:14 +04:00
int ret ;
2018-10-31 10:44:08 +03:00
* pwdstp = NULL ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
if ( b - > symbols - > _nss_getpwnam_r . f = = NULL ) {
2009-06-04 14:25:14 +04:00
return NSS_STATUS_NOTFOUND ;
}
2020-04-02 14:43:44 +03:00
ret = b - > symbols - > _nss_getpwnam_r . f ( name , pwdst , buf , buflen , & errno ) ;
2009-06-04 14:25:14 +04:00
switch ( ret ) {
case NSS_STATUS_SUCCESS :
2018-10-31 10:44:08 +03:00
* pwdstp = pwdst ;
2009-06-04 14:25:14 +04:00
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 ;
}
2009-06-04 14:17:39 +04:00
}
static struct passwd * nwrap_module_getpwuid ( struct nwrap_backend * b ,
uid_t uid )
{
2009-06-04 14:25:14 +04:00
static struct passwd pwd ;
static char buf [ 1000 ] ;
NSS_STATUS status ;
2020-04-02 14:43:44 +03:00
if ( b - > symbols - > _nss_getpwuid_r . f = = NULL ) {
2009-06-04 14:25:14 +04:00
return NULL ;
}
2020-04-02 14:43:44 +03:00
status = b - > symbols - > _nss_getpwuid_r . f ( uid ,
& pwd ,
buf ,
sizeof ( buf ) ,
& errno ) ;
2009-06-04 14:25:14 +04:00
if ( status = = NSS_STATUS_NOTFOUND ) {
return NULL ;
}
if ( status ! = NSS_STATUS_SUCCESS ) {
return NULL ;
}
return & pwd ;
2009-06-04 14:17:39 +04:00
}
static int nwrap_module_getpwuid_r ( struct nwrap_backend * b ,
uid_t uid , struct passwd * pwdst ,
char * buf , size_t buflen , struct passwd * * pwdstp )
{
2009-06-04 14:25:14 +04:00
int ret ;
2018-10-31 10:44:08 +03:00
* pwdstp = NULL ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
if ( b - > symbols - > _nss_getpwuid_r . f = = NULL ) {
2009-06-04 14:25:14 +04:00
return ENOENT ;
}
2020-04-02 14:43:44 +03:00
ret = b - > symbols - > _nss_getpwuid_r . f ( uid , pwdst , buf , buflen , & errno ) ;
2009-06-04 14:25:14 +04:00
switch ( ret ) {
case NSS_STATUS_SUCCESS :
2018-10-31 10:44:08 +03:00
* pwdstp = pwdst ;
2009-06-04 14:25:14 +04:00
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 ;
}
2009-06-04 14:17:39 +04:00
}
static void nwrap_module_setpwent ( struct nwrap_backend * b )
{
2020-04-02 14:43:44 +03:00
if ( b - > symbols - > _nss_setpwent . f = = NULL ) {
2009-06-04 14:25:14 +04:00
return ;
}
2020-04-02 14:43:44 +03:00
b - > symbols - > _nss_setpwent . f ( ) ;
2009-06-04 14:17:39 +04:00
}
static struct passwd * nwrap_module_getpwent ( struct nwrap_backend * b )
{
2009-06-04 14:25:14 +04:00
static struct passwd pwd ;
static char buf [ 1000 ] ;
NSS_STATUS status ;
2020-04-02 14:43:44 +03:00
if ( b - > symbols - > _nss_getpwent_r . f = = NULL ) {
2009-06-04 14:25:14 +04:00
return NULL ;
}
2020-04-02 14:43:44 +03:00
status = b - > symbols - > _nss_getpwent_r . f ( & pwd , buf , sizeof ( buf ) , & errno ) ;
2009-06-04 14:25:14 +04:00
if ( status = = NSS_STATUS_NOTFOUND ) {
return NULL ;
}
if ( status ! = NSS_STATUS_SUCCESS ) {
return NULL ;
}
return & pwd ;
2009-06-04 14:17:39 +04:00
}
static int nwrap_module_getpwent_r ( struct nwrap_backend * b ,
struct passwd * pwdst , char * buf ,
size_t buflen , struct passwd * * pwdstp )
{
2009-06-04 14:25:14 +04:00
int ret ;
2018-10-31 10:44:08 +03:00
* pwdstp = NULL ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
if ( b - > symbols - > _nss_getpwent_r . f = = NULL ) {
2009-06-04 14:25:14 +04:00
return ENOENT ;
}
2020-04-02 14:43:44 +03:00
ret = b - > symbols - > _nss_getpwent_r . f ( pwdst , buf , buflen , & errno ) ;
2009-06-04 14:25:14 +04:00
switch ( ret ) {
case NSS_STATUS_SUCCESS :
2018-10-31 10:44:08 +03:00
* pwdstp = pwdst ;
2009-06-04 14:25:14 +04:00
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 ;
}
2009-06-04 14:17:39 +04:00
}
static void nwrap_module_endpwent ( struct nwrap_backend * b )
{
2022-06-24 11:39:57 +03:00
if ( b - > symbols - > _nss_endpwent . f = = NULL ) {
2009-06-04 14:25:14 +04:00
return ;
}
2020-04-02 14:43:44 +03:00
b - > symbols - > _nss_endpwent . f ( ) ;
2009-06-04 14:17:39 +04:00
}
2023-01-24 13:20:49 +03:00
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 )
2009-06-04 14:17:39 +04:00
{
2023-01-24 13:20:49 +03:00
if ( b - > symbols - > _nss_initgroups_dyn . f = = NULL ) {
2009-06-04 14:25:14 +04:00
return NSS_STATUS_UNAVAIL ;
}
2023-01-24 13:20:49 +03:00
return b - > symbols - > _nss_initgroups_dyn . f ( user ,
2020-04-02 14:43:44 +03:00
group ,
2023-01-24 13:20:49 +03:00
start ,
size ,
groups ,
limit ,
errnop ) ;
2009-06-04 14:17:39 +04:00
}
static struct group * nwrap_module_getgrnam ( struct nwrap_backend * b ,
const char * name )
{
2009-06-04 14:25:14 +04:00
static struct group grp ;
static char * buf ;
static int buflen = 1000 ;
NSS_STATUS status ;
2020-04-02 14:43:44 +03:00
if ( b - > symbols - > _nss_getgrnam_r . f = = NULL ) {
2009-06-04 14:25:14 +04:00
return NULL ;
}
if ( ! buf ) {
buf = ( char * ) malloc ( buflen ) ;
}
again :
2020-04-02 14:43:44 +03:00
status = b - > symbols - > _nss_getgrnam_r . f ( name , & grp , buf , buflen , & errno ) ;
2009-06-04 14:25:14 +04:00
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 ;
2009-06-04 14:17:39 +04:00
}
static int nwrap_module_getgrnam_r ( struct nwrap_backend * b ,
const char * name , struct group * grdst ,
char * buf , size_t buflen , struct group * * grdstp )
{
2009-06-04 14:25:14 +04:00
int ret ;
2018-10-31 10:44:08 +03:00
* grdstp = NULL ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
if ( b - > symbols - > _nss_getgrnam_r . f = = NULL ) {
2009-06-04 14:25:14 +04:00
return ENOENT ;
}
2020-04-02 14:43:44 +03:00
ret = b - > symbols - > _nss_getgrnam_r . f ( name , grdst , buf , buflen , & errno ) ;
2009-06-04 14:25:14 +04:00
switch ( ret ) {
case NSS_STATUS_SUCCESS :
2018-10-31 10:44:08 +03:00
* grdstp = grdst ;
2009-06-04 14:25:14 +04:00
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 ;
}
2009-06-04 14:17:39 +04:00
}
static struct group * nwrap_module_getgrgid ( struct nwrap_backend * b ,
gid_t gid )
{
2009-06-04 14:25:14 +04:00
static struct group grp ;
static char * buf ;
static int buflen = 1000 ;
NSS_STATUS status ;
2020-04-02 14:43:44 +03:00
if ( b - > symbols - > _nss_getgrgid_r . f = = NULL ) {
2009-06-04 14:25:14 +04:00
return NULL ;
}
if ( ! buf ) {
buf = ( char * ) malloc ( buflen ) ;
}
again :
2020-04-02 14:43:44 +03:00
status = b - > symbols - > _nss_getgrgid_r . f ( gid , & grp , buf , buflen , & errno ) ;
2009-06-04 14:25:14 +04:00
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 ;
2009-06-04 14:17:39 +04:00
}
static int nwrap_module_getgrgid_r ( struct nwrap_backend * b ,
gid_t gid , struct group * grdst ,
char * buf , size_t buflen , struct group * * grdstp )
{
2009-06-04 14:25:14 +04:00
int ret ;
2018-10-31 10:44:08 +03:00
* grdstp = NULL ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
if ( b - > symbols - > _nss_getgrgid_r . f = = NULL ) {
2009-06-04 14:25:14 +04:00
return ENOENT ;
}
2020-04-02 14:43:44 +03:00
ret = b - > symbols - > _nss_getgrgid_r . f ( gid , grdst , buf , buflen , & errno ) ;
2009-06-04 14:25:14 +04:00
switch ( ret ) {
case NSS_STATUS_SUCCESS :
2018-10-31 10:44:08 +03:00
* grdstp = grdst ;
2009-06-04 14:25:14 +04:00
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 ;
}
2009-06-04 14:17:39 +04:00
}
static void nwrap_module_setgrent ( struct nwrap_backend * b )
{
2022-06-24 11:39:57 +03:00
if ( b - > symbols - > _nss_setgrent . f = = NULL ) {
2009-06-04 14:25:14 +04:00
return ;
}
2020-04-02 14:43:44 +03:00
b - > symbols - > _nss_setgrent . f ( ) ;
2009-06-04 14:17:39 +04:00
}
static struct group * nwrap_module_getgrent ( struct nwrap_backend * b )
{
2009-06-04 14:25:14 +04:00
static struct group grp ;
static char * buf ;
static int buflen = 1024 ;
NSS_STATUS status ;
2020-04-02 14:43:44 +03:00
if ( b - > symbols - > _nss_getgrent_r . f = = NULL ) {
2009-06-04 14:25:14 +04:00
return NULL ;
}
if ( ! buf ) {
buf = ( char * ) malloc ( buflen ) ;
}
again :
2020-04-02 14:43:44 +03:00
status = b - > symbols - > _nss_getgrent_r . f ( & grp , buf , buflen , & errno ) ;
2009-06-04 14:25:14 +04:00
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 ;
2009-06-04 14:17:39 +04:00
}
static int nwrap_module_getgrent_r ( struct nwrap_backend * b ,
struct group * grdst , char * buf ,
size_t buflen , struct group * * grdstp )
{
2009-06-04 14:25:14 +04:00
int ret ;
2018-10-31 10:44:08 +03:00
* grdstp = NULL ;
2014-01-31 18:57:43 +04:00
2020-04-02 14:43:44 +03:00
if ( b - > symbols - > _nss_getgrent_r . f = = NULL ) {
2009-06-04 14:25:14 +04:00
return ENOENT ;
}
2020-04-02 14:43:44 +03:00
ret = b - > symbols - > _nss_getgrent_r . f ( grdst , buf , buflen , & errno ) ;
2009-06-04 14:25:14 +04:00
switch ( ret ) {
case NSS_STATUS_SUCCESS :
2018-10-31 10:44:08 +03:00
* grdstp = grdst ;
2009-06-04 14:25:14 +04:00
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 ;
}
2009-06-04 14:17:39 +04:00
}
static void nwrap_module_endgrent ( struct nwrap_backend * b )
{
2020-04-02 14:43:44 +03:00
if ( b - > symbols - > _nss_endgrent . f = = NULL ) {
2009-06-04 14:25:14 +04:00
return ;
}
2020-04-02 14:43:44 +03:00
b - > symbols - > _nss_endgrent . f ( ) ;
2009-06-04 14:17:39 +04:00
}
2020-03-16 19:00:16 +03:00
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 ;
2020-04-02 14:43:44 +03:00
if ( b - > symbols - > _nss_gethostbyaddr_r . f = = NULL ) {
2020-03-16 19:00:16 +03:00
return NULL ;
}
if ( buf = = NULL ) {
buf = ( char * ) malloc ( buflen ) ;
if ( buf = = NULL ) {
return NULL ;
}
}
again :
2020-04-02 14:43:44 +03:00
status = b - > symbols - > _nss_gethostbyaddr_r . f ( addr ,
len ,
type ,
& he ,
buf ,
buflen ,
& errno ,
& h_errno ) ;
2020-03-16 19:00:16 +03:00
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 ;
2020-04-02 14:43:44 +03:00
if ( b - > symbols - > _nss_gethostbyname2_r . f = = NULL ) {
2020-03-16 19:00:16 +03:00
return ENOENT ;
}
2020-04-02 14:43:44 +03:00
status = b - > symbols - > _nss_gethostbyname2_r . f ( name ,
af ,
hedst ,
buf ,
buflen ,
& errno ,
& h_errno ) ;
2020-03-16 19:00:16 +03:00
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 ;
2020-04-02 14:43:44 +03:00
if ( b - > symbols - > _nss_gethostbyname2_r . f = = NULL ) {
2020-03-16 19:00:16 +03:00
return NULL ;
}
if ( buf = = NULL ) {
buf = ( char * ) malloc ( buflen ) ;
if ( buf = = NULL ) {
return NULL ;
}
}
again :
2020-04-02 14:43:44 +03:00
status = b - > symbols - > _nss_gethostbyname2_r . f ( name ,
AF_UNSPEC ,
& he ,
buf ,
buflen ,
& errno ,
& h_errno ) ;
2020-03-16 19:00:16 +03:00
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 ;
2020-04-02 14:43:44 +03:00
if ( b - > symbols - > _nss_gethostbyname2_r . f = = NULL ) {
2020-03-16 19:00:16 +03:00
return NULL ;
}
if ( buf = = NULL ) {
buf = ( char * ) malloc ( buflen ) ;
if ( buf = = NULL ) {
return NULL ;
}
}
again :
2020-04-02 14:43:44 +03:00
status = b - > symbols - > _nss_gethostbyname2_r . f ( name ,
af ,
& he ,
buf ,
buflen ,
& errno ,
& h_errno ) ;
2020-03-16 19:00:16 +03:00
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 ;
}
2014-01-31 18:57:43 +04:00
/****************************************************************************
* GETPWNAM
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-05-31 04:20:29 +04:00
2014-01-31 18:57:43 +04:00
static struct passwd * nwrap_getpwnam ( const char * name )
2009-05-31 04:20:29 +04:00
{
2020-03-16 19:00:16 +03:00
size_t i ;
2009-06-03 13:10:13 +04:00
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 ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
struct passwd * getpwnam ( const char * name )
2009-05-31 04:20:29 +04:00
{
2014-01-31 18:57:43 +04:00
if ( ! nss_wrapper_enabled ( ) ) {
return libc_getpwnam ( name ) ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
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 )
{
2020-03-16 19:00:16 +03:00
size_t i ;
int ret ;
2014-01-31 18:57:43 +04:00
2009-06-03 13:10:13 +04:00
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 ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
# 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 )
2009-05-31 04:20:29 +04:00
{
2020-03-16 19:00:16 +03:00
size_t i ;
2009-06-03 13:10:13 +04:00
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 ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
struct passwd * getpwuid ( uid_t uid )
2009-05-31 04:20:29 +04:00
{
2014-01-31 18:57:43 +04:00
if ( ! nss_wrapper_enabled ( ) ) {
return libc_getpwuid ( uid ) ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
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 )
{
2020-03-16 19:00:16 +03:00
size_t i ;
int ret ;
2014-01-31 18:57:43 +04:00
2009-06-03 13:10:13 +04:00
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 ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
# 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
2009-05-31 04:20:29 +04:00
{
2014-01-31 18:57:43 +04:00
if ( ! nss_wrapper_enabled ( ) ) {
return libc_getpwuid_r ( uid , pwdst , buf , buflen , pwdstp ) ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
return nwrap_getpwuid_r ( uid , pwdst , buf , buflen , pwdstp ) ;
}
/****************************************************************************
* SETPWENT
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void nwrap_setpwent ( void )
{
2020-03-16 19:00:16 +03:00
size_t i ;
2014-01-31 18:57:43 +04:00
2009-06-03 13:10:13 +04:00
for ( i = 0 ; i < nwrap_main_global - > num_backends ; i + + ) {
struct nwrap_backend * b = & nwrap_main_global - > backends [ i ] ;
b - > ops - > nw_setpwent ( b ) ;
}
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
void setpwent ( void )
{
if ( ! nss_wrapper_enabled ( ) ) {
libc_setpwent ( ) ;
return ;
}
nwrap_setpwent ( ) ;
}
/****************************************************************************
* GETPWENT
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static struct passwd * nwrap_getpwent ( void )
2009-05-31 04:20:29 +04:00
{
2020-03-16 19:00:16 +03:00
size_t i ;
2009-06-03 13:10:13 +04:00
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 ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
struct passwd * getpwent ( void )
2009-05-31 04:20:29 +04:00
{
2014-01-31 18:57:43 +04:00
if ( ! nss_wrapper_enabled ( ) ) {
return libc_getpwent ( ) ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
return nwrap_getpwent ( ) ;
}
/****************************************************************************
* GETPWENT_R
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2018-10-31 10:44:08 +03:00
# ifdef HAVE_GETPWENT_R
2014-01-31 18:57:43 +04:00
static int nwrap_getpwent_r ( struct passwd * pwdst , char * buf ,
size_t buflen , struct passwd * * pwdstp )
{
2020-03-16 19:00:16 +03:00
size_t i ;
int ret ;
2014-01-31 18:57:43 +04:00
2009-06-03 13:10:13 +04:00
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 ;
2009-05-31 04:20:29 +04:00
}
2018-10-31 10:44:08 +03:00
# ifdef HAVE_SOLARIS_GETPWENT_R
2014-01-31 18:57:43 +04:00
struct passwd * getpwent_r ( struct passwd * pwdst , char * buf , int buflen )
2009-05-31 04:20:29 +04:00
{
2014-01-31 18:57:43 +04:00
struct passwd * pwdstp = NULL ;
int rc ;
2009-06-03 13:10:13 +04:00
2014-01-31 18:57:43 +04:00
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 ;
}
2018-10-31 10:44:08 +03:00
# else /* HAVE_SOLARIS_GETPWENT_R */
2014-01-31 18:57:43 +04:00
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 ) ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
return nwrap_getpwent_r ( pwdst , buf , buflen , pwdstp ) ;
}
2018-10-31 10:44:08 +03:00
# endif /* HAVE_SOLARIS_GETPWENT_R */
# endif /* HAVE_GETPWENT_R */
2014-01-31 18:57:43 +04:00
/****************************************************************************
* ENDPWENT
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void nwrap_endpwent ( void )
{
2020-03-16 19:00:16 +03:00
size_t i ;
2014-01-31 18:57:43 +04:00
2009-06-03 13:10:13 +04:00
for ( i = 0 ; i < nwrap_main_global - > num_backends ; i + + ) {
struct nwrap_backend * b = & nwrap_main_global - > backends [ i ] ;
b - > ops - > nw_endpwent ( b ) ;
}
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
void endpwent ( void )
2009-05-31 04:20:29 +04:00
{
2014-01-31 18:57:43 +04:00
if ( ! nss_wrapper_enabled ( ) ) {
libc_endpwent ( ) ;
return ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
nwrap_endpwent ( ) ;
}
/****************************************************************************
* INITGROUPS
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int nwrap_initgroups ( const char * user , gid_t group )
{
2023-01-24 13:20:49 +03:00
# 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 " ) ;
2014-01-31 18:57:43 +04:00
2023-01-24 13:20:49 +03:00
if ( env = = NULL | | env [ 0 ] ! = ' 1 ' ) {
NWRAP_LOG ( NWRAP_LOG_WARN ,
" initgroups() requires uid_wrapper to work! " ) ;
return 0 ;
}
2014-01-31 18:57:43 +04:00
2023-01-24 13:20:49 +03:00
limit = sysconf ( _SC_NGROUPS_MAX ) ;
if ( limit > 0 ) {
size = MIN ( limit , 64 ) ;
} else {
size = 16 ;
2009-06-03 13:10:13 +04:00
}
2023-01-24 13:20:49 +03:00
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
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
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 )
2009-05-31 04:20:29 +04:00
{
2020-03-16 19:00:16 +03:00
size_t i ;
2009-06-03 13:10:13 +04:00
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 ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
struct group * getgrnam ( const char * name )
2009-05-31 04:20:29 +04:00
{
2014-01-31 18:57:43 +04:00
if ( ! nss_wrapper_enabled ( ) ) {
return libc_getgrnam ( name ) ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
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 )
{
2020-03-16 19:00:16 +03:00
size_t i ;
int ret ;
2014-01-31 18:57:43 +04:00
2009-06-03 13:10:13 +04:00
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 ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
# 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 )
2009-05-31 04:20:29 +04:00
{
2020-03-16 19:00:16 +03:00
size_t i ;
2009-06-03 13:10:13 +04:00
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 ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
struct group * getgrgid ( gid_t gid )
2009-05-31 04:20:29 +04:00
{
2014-01-31 18:57:43 +04:00
if ( ! nss_wrapper_enabled ( ) ) {
return libc_getgrgid ( gid ) ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
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 )
{
2020-03-16 19:00:16 +03:00
size_t i ;
int ret ;
2014-01-31 18:57:43 +04:00
2009-06-03 13:10:13 +04:00
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 ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
# 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 */
2009-05-31 04:20:29 +04:00
{
2014-01-31 18:57:43 +04:00
if ( ! nss_wrapper_enabled ( ) ) {
return libc_getgrgid_r ( gid , grdst , buf , buflen , grdstp ) ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
return nwrap_getgrgid_r ( gid , grdst , buf , buflen , grdstp ) ;
}
# endif
/****************************************************************************
* SETGRENT
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void nwrap_setgrent ( void )
{
2020-03-16 19:00:16 +03:00
size_t i ;
2014-01-31 18:57:43 +04:00
2009-06-03 13:10:13 +04:00
for ( i = 0 ; i < nwrap_main_global - > num_backends ; i + + ) {
struct nwrap_backend * b = & nwrap_main_global - > backends [ i ] ;
b - > ops - > nw_setgrent ( b ) ;
}
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
# 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 )
2009-05-31 04:20:29 +04:00
{
2020-03-16 19:00:16 +03:00
size_t i ;
2009-06-03 13:10:13 +04:00
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 ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
struct group * getgrent ( void )
2009-05-31 04:20:29 +04:00
{
2014-01-31 18:57:43 +04:00
if ( ! nss_wrapper_enabled ( ) ) {
return libc_getgrent ( ) ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
return nwrap_getgrent ( ) ;
}
/****************************************************************************
* GETGRENT_R
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2018-10-31 10:44:08 +03:00
# ifdef HAVE_GETGRENT_R
2014-01-31 18:57:43 +04:00
static int nwrap_getgrent_r ( struct group * grdst , char * buf ,
size_t buflen , struct group * * grdstp )
{
2020-03-16 19:00:16 +03:00
size_t i ;
int ret ;
2014-01-31 18:57:43 +04:00
2009-06-03 13:10:13 +04:00
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 ;
2009-05-31 04:20:29 +04:00
}
2018-10-31 10:44:08 +03:00
# ifdef HAVE_SOLARIS_GETGRENT_R
2014-01-31 18:57:43 +04:00
struct group * getgrent_r ( struct group * src , char * buf , int buflen )
2009-05-31 04:20:29 +04:00
{
2014-01-31 18:57:43 +04:00
struct group * grdstp = NULL ;
int rc ;
2009-06-03 13:10:13 +04:00
2014-01-31 18:57:43 +04:00
if ( ! nss_wrapper_enabled ( ) ) {
return libc_getgrent_r ( src , buf , buflen ) ;
}
rc = nwrap_getgrent_r ( src , buf , buflen , & grdstp ) ;
if ( rc < 0 ) {
return NULL ;
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
return grdstp ;
}
2018-10-31 10:44:08 +03:00
# else /* HAVE_SOLARIS_GETGRENT_R */
2014-01-31 18:57:43 +04:00
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 ) ;
}
2018-10-31 10:44:08 +03:00
# endif /* HAVE_SOLARIS_GETGRENT_R */
# endif /* HAVE_GETGRENT_R */
2014-01-31 18:57:43 +04:00
/****************************************************************************
* ENDGRENT
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void nwrap_endgrent ( void )
{
2020-03-16 19:00:16 +03:00
size_t i ;
2014-01-31 18:57:43 +04:00
2009-06-03 13:10:13 +04:00
for ( i = 0 ; i < nwrap_main_global - > num_backends ; i + + ) {
struct nwrap_backend * b = & nwrap_main_global - > backends [ i ] ;
b - > ops - > nw_endgrent ( b ) ;
}
2009-05-31 04:20:29 +04:00
}
2014-01-31 18:57:43 +04:00
void endgrent ( void )
{
if ( ! nss_wrapper_enabled ( ) ) {
libc_endgrent ( ) ;
return ;
}
nwrap_endgrent ( ) ;
}
/****************************************************************************
* GETGROUPLIST
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifdef HAVE_GETGROUPLIST
2023-01-24 13:20:49 +03:00
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 ;
2009-06-04 22:12:27 +04:00
2023-01-24 13:20:49 +03:00
/* Never store more than the starting *SIZE number of elements. */
assert ( * size > 0 ) ;
( * groupsp ) [ 0 ] = group ;
2009-06-04 22:12:27 +04:00
2023-01-24 13:20:49 +03:00
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 ;
2009-06-04 22:12:27 +04:00
2023-01-24 13:20:49 +03:00
if ( inner < prev_start )
( * groupsp ) [ cnt ] = ( * groupsp ) [ - - start ] ;
else
+ + cnt ;
2009-06-04 22:12:27 +04:00
}
2023-01-24 13:20:49 +03:00
NWRAP_LOG ( NWRAP_LOG_DEBUG ,
" Resource '%s' returned status=%d and increased "
" count of groups to %ld " ,
b - > name ,
status ,
start ) ;
2009-06-04 22:12:27 +04:00
}
2023-01-24 13:20:49 +03:00
return start ;
}
2009-06-03 13:10:13 +04:00
2023-01-24 13:20:49 +03:00
int getgrouplist ( const char * user , gid_t group , gid_t * groups , int * ngroups )
{
long int size ;
int total , retval ;
gid_t * newgroups ;
2009-06-04 22:12:27 +04:00
2023-01-24 13:20:49 +03:00
if ( ! nss_wrapper_enabled ( ) ) {
return libc_getgrouplist ( user , group , groups , ngroups ) ;
}
2009-06-04 22:12:27 +04:00
2023-01-24 13:20:49 +03:00
size = MAX ( 1 , * ngroups ) ;
newgroups = ( gid_t * ) malloc ( size * sizeof ( gid_t ) ) ;
if ( newgroups = = NULL ) {
2009-06-04 22:12:27 +04:00
return - 1 ;
}
2023-01-24 13:20:49 +03:00
total = nwrap_getgrouplist ( user , group , & size , & newgroups , - 1 ) ;
2009-06-04 22:12:27 +04:00
2023-01-24 13:20:49 +03:00
if ( groups ! = NULL ) {
memcpy ( groups , newgroups , MIN ( * ngroups , total ) * sizeof ( gid_t ) ) ;
2014-01-31 18:57:43 +04:00
}
2023-01-24 13:20:49 +03:00
free ( newgroups ) ;
retval = total > * ngroups ? - 1 : total ;
* ngroups = total ;
return retval ;
2014-01-31 18:57:43 +04:00
}
# endif
2015-09-17 11:38:49 +03:00
/**********************************************************
* SHADOW
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2015-10-06 11:34:20 +03:00
# if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM)
# ifdef HAVE_SETSPENT
2015-09-17 11:38:49 +03:00
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 ( ) ;
}
2015-10-06 11:34:20 +03:00
# endif /* HAVE_SETSPENT */
2015-09-17 11:38:49 +03:00
2015-09-17 11:39:15 +03:00
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 ) ;
}
2015-10-06 11:34:20 +03:00
# endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */
2014-01-31 18:57:43 +04:00
/**********************************************************
* 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 */
2020-03-16 19:00:16 +03:00
2015-03-27 17:51:11 +03:00
# 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
2015-07-16 17:10:20 +03:00
static struct hostent user_he ;
static struct nwrap_vector user_addrlist ;
2015-03-27 17:51:11 +03:00
# endif /* BSD */
2020-03-16 19:00:16 +03:00
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 ;
}
2014-01-31 18:57:43 +04:00
static struct hostent * nwrap_gethostbyname ( const char * name )
{
2020-03-16 19:00:16 +03:00
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 ;
}
2015-07-16 17:10:20 +03:00
}
2020-03-16 19:00:16 +03:00
return NULL ;
2014-01-31 18:57:43 +04:00
}
struct hostent * gethostbyname ( const char * name )
{
if ( ! nss_wrapper_hosts_enabled ( ) ) {
return libc_gethostbyname ( name ) ;
}
return nwrap_gethostbyname ( name ) ;
}
2015-03-27 17:51:11 +03:00
/* This is a GNU extension - Also can be found on BSD systems */
2014-01-31 18:57:43 +04:00
# ifdef HAVE_GETHOSTBYNAME2
2015-03-27 17:51:11 +03:00
# 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
2015-07-16 17:10:20 +03:00
static struct hostent user_he2 ;
static struct nwrap_vector user_addrlist2 ;
2015-03-27 17:51:11 +03:00
# endif /* BSD */
2020-03-16 19:00:16 +03:00
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 ;
}
2014-01-31 18:57:43 +04:00
static struct hostent * nwrap_gethostbyname2 ( const char * name , int af )
{
2020-03-16 19:00:16 +03:00
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 ;
}
2015-07-16 17:10:20 +03:00
}
2020-03-16 19:00:16 +03:00
return NULL ;
2014-01-31 18:57:43 +04:00
}
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 )
{
2020-03-16 19:00:16 +03:00
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 ;
2014-01-31 18:57:43 +04:00
}
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 ,
2015-07-16 17:10:20 +03:00
struct addrinfo * * pai ,
bool skip_canonname )
2014-01-31 18:57:43 +04:00
{
struct addrinfo * ai ;
socklen_t socklen ;
2015-07-16 17:10:20 +03:00
if ( he = = NULL ) {
return EAI_MEMORY ;
}
2014-01-31 18:57:43 +04:00
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 ;
}
2015-11-12 13:15:03 +03:00
ai - > ai_flags = hints - > ai_flags ;
2014-01-31 18:57:43 +04:00
ai - > ai_family = he - > h_addrtype ;
ai - > ai_socktype = hints - > ai_socktype ;
ai - > ai_protocol = hints - > ai_protocol ;
2015-07-16 17:10:20 +03:00
ai - > ai_canonname = NULL ;
2014-01-31 18:57:43 +04:00
2015-11-12 13:15:03 +03:00
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 ;
}
}
2014-01-31 18:57:43 +04:00
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 :
{
2019-05-21 09:00:05 +03:00
union {
struct sockaddr * sa ;
struct sockaddr_in * in ;
} addr ;
2014-01-31 18:57:43 +04:00
2019-05-21 09:00:05 +03:00
addr . sa = ai - > ai_addr ;
2014-01-31 18:57:43 +04:00
2019-05-21 09:00:05 +03:00
memset ( addr . in , 0 , sizeof ( struct sockaddr_in ) ) ;
2014-01-31 18:57:43 +04:00
2019-05-21 09:00:05 +03:00
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 ) ;
2014-01-31 18:57:43 +04:00
}
break ;
# ifdef HAVE_IPV6
case AF_INET6 :
{
2019-05-21 09:00:05 +03:00
union {
struct sockaddr * sa ;
struct sockaddr_in6 * in6 ;
} addr ;
2014-01-31 18:57:43 +04:00
2019-05-21 09:00:05 +03:00
addr . sa = ai - > ai_addr ;
2014-01-31 18:57:43 +04:00
2019-05-21 09:00:05 +03:00
memset ( addr . in6 , 0 , sizeof ( struct sockaddr_in6 ) ) ;
2014-01-31 18:57:43 +04:00
2019-05-21 09:00:05 +03:00
addr . in6 - > sin6_port = htons ( port ) ;
addr . in6 - > sin6_family = AF_INET6 ;
memcpy ( & addr . in6 - > sin6_addr ,
2015-07-16 17:10:20 +03:00
he - > h_addr_list [ 0 ] ,
he - > h_length ) ;
2014-01-31 18:57:43 +04:00
}
break ;
# endif
}
ai - > ai_next = NULL ;
2015-07-16 17:10:20 +03:00
if ( he - > h_name & & ! skip_canonname ) {
2014-01-31 18:57:43 +04:00
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 ;
2014-10-09 11:15:59 +04:00
struct {
int family ;
union {
struct in_addr v4 ;
# ifdef HAVE_IPV6
struct in6_addr v6 ;
} in ;
# endif
2014-10-09 11:17:07 +04:00
} addr = {
. family = AF_UNSPEC ,
} ;
2015-11-11 15:02:59 +03:00
int rc ;
2014-01-31 18:57:43 +04:00
if ( node = = NULL & & service = = NULL ) {
return EAI_NONAME ;
}
2015-07-16 17:10:20 +03:00
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 ;
}
2014-01-31 18:57:43 +04:00
/* If no node has been specified, let glibc deal with it */
if ( node = = NULL ) {
2015-11-06 13:43:04 +03:00
int ret ;
struct addrinfo * p = NULL ;
ret = libc_getaddrinfo ( node , service , hints , & p ) ;
if ( ret = = 0 ) {
* res = p ;
}
2014-01-31 18:57:43 +04:00
return ret ;
}
if ( service ! = NULL & & service [ 0 ] ! = ' \0 ' ) {
2015-10-13 15:41:14 +03:00
const char * proto = NULL ;
struct servent * s ;
char * end_ptr ;
long sl ;
errno = 0 ;
sl = strtol ( service , & end_ptr , 10 ) ;
2015-11-06 12:22:10 +03:00
if ( * end_ptr = = ' \0 ' ) {
2015-10-13 15:41:14 +03:00
port = sl ;
goto valid_port ;
} else if ( hints - > ai_flags & AI_NUMERICSERV ) {
2015-11-06 12:45:15 +03:00
return EAI_NONAME ;
2015-10-13 15:41:14 +03:00
}
2014-01-31 18:57:43 +04:00
2015-10-13 15:41:14 +03:00
if ( hints - > ai_protocol ! = 0 ) {
struct protoent * pent ;
2014-01-31 18:57:43 +04:00
2015-10-13 15:41:14 +03:00
pent = getprotobynumber ( hints - > ai_protocol ) ;
if ( pent ! = NULL ) {
proto = pent - > p_name ;
2014-01-31 18:57:43 +04:00
}
2015-10-13 15:41:14 +03:00
}
2014-01-31 18:57:43 +04:00
2015-10-13 15:41:14 +03:00
s = getservbyname ( service , proto ) ;
2015-11-09 02:55:00 +03:00
if ( s = = NULL ) {
2015-11-06 13:00:54 +03:00
return EAI_NONAME ;
2014-01-31 18:57:43 +04:00
}
2015-11-09 02:55:00 +03:00
port = ntohs ( s - > s_port ) ;
2014-01-31 18:57:43 +04:00
}
2015-10-13 15:41:14 +03:00
valid_port :
2015-11-12 10:16:18 +03:00
rc = inet_pton ( AF_INET , node , & addr . in . v4 ) ;
if ( rc = = 1 ) {
addr . family = AF_INET ;
2014-01-31 18:57:43 +04:00
}
# ifdef HAVE_IPV6
2015-11-06 13:52:08 +03:00
if ( addr . family = = AF_UNSPEC ) {
2015-11-11 15:02:59 +03:00
rc = inet_pton ( AF_INET6 , node , & addr . in . v6 ) ;
2014-01-31 18:57:43 +04:00
if ( rc = = 1 ) {
2014-10-09 11:15:59 +04:00
addr . family = AF_INET6 ;
2014-01-31 18:57:43 +04:00
}
}
2015-11-06 13:52:08 +03:00
# endif
2014-01-31 18:57:43 +04:00
2015-11-09 02:29:23 +03:00
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 ) )
2015-11-12 10:16:18 +03:00
{
return EAI_ADDRFAMILY ;
}
2015-11-12 12:20:37 +03:00
rc = nwrap_files_getaddrinfo ( node , port , hints , & ai ) ;
2015-11-11 15:02:59 +03:00
if ( rc ! = 0 ) {
2015-11-06 13:43:04 +03:00
int ret ;
struct addrinfo * p = NULL ;
ret = libc_getaddrinfo ( node , service , hints , & p ) ;
2015-11-06 13:31:09 +03:00
if ( ret = = 0 ) {
/*
* nwrap_files_getaddrinfo failed , but libc was
* successful - - use the result from libc .
*/
2015-11-06 13:43:04 +03:00
* res = p ;
2015-11-06 13:31:09 +03:00
return 0 ;
}
2015-11-11 15:02:59 +03:00
return rc ;
2014-01-31 18:57:43 +04:00
}
2015-11-12 13:17:21 +03:00
/*
* If the socktype was not specified , duplicate
* each ai returned , so that we have variants for
* both UDP and TCP .
*/
2014-01-31 18:57:43 +04:00
if ( hints - > ai_socktype = = 0 ) {
2015-11-12 13:35:07 +03:00
struct addrinfo * ai_cur ;
2015-07-16 17:10:20 +03:00
2015-11-12 13:35:07 +03:00
/* 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 ;
2015-07-16 17:10:20 +03:00
}
2014-01-31 18:57:43 +04:00
2015-11-12 13:35:07 +03:00
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 ) ;
2015-07-16 17:10:20 +03:00
}
2015-11-12 13:35:07 +03:00
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 ;
2015-07-16 17:10:20 +03:00
}
2015-11-12 13:35:07 +03:00
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 ;
2015-07-16 17:10:20 +03:00
}
2015-11-12 13:08:47 +03:00
2015-11-12 13:35:07 +03:00
/* now insert the new entry */
2015-07-16 17:10:20 +03:00
2015-11-12 13:35:07 +03:00
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 ;
}
2014-01-31 18:57:43 +04:00
}
* 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 ;
2020-03-16 19:00:16 +03:00
size_t i ;
2014-01-31 18:57:43 +04:00
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 ) {
2019-05-21 09:00:05 +03:00
case AF_INET : {
union {
const struct sockaddr * sa ;
const struct sockaddr_in * in ;
} a ;
if ( salen < sizeof ( struct sockaddr_in ) ) {
2014-06-21 12:47:28 +04:00
return EAI_FAMILY ;
2019-05-21 09:00:05 +03:00
}
a . sa = sa ;
addr = & ( a . in - > sin_addr ) ;
addrlen = sizeof ( a . in - > sin_addr ) ;
port = ntohs ( a . in - > sin_port ) ;
2014-06-21 12:47:28 +04:00
break ;
2019-05-21 09:00:05 +03:00
}
2014-01-31 18:57:43 +04:00
# ifdef HAVE_IPV6
2019-05-21 09:00:05 +03:00
case AF_INET6 : {
union {
const struct sockaddr * sa ;
const struct sockaddr_in6 * in6 ;
} a ;
if ( salen < sizeof ( struct sockaddr_in6 ) ) {
2014-01-31 18:57:43 +04:00
return EAI_FAMILY ;
2019-05-21 09:00:05 +03:00
}
a . sa = sa ;
addr = & ( a . in6 - > sin6_addr ) ;
addrlen = sizeof ( a . in6 - > sin6_addr ) ;
port = ntohs ( a . in6 - > sin6_port ) ;
2014-06-21 12:47:28 +04:00
break ;
2019-05-21 09:00:05 +03:00
}
2014-06-21 12:47:28 +04:00
# endif
default :
return EAI_FAMILY ;
2014-01-31 18:57:43 +04:00
}
if ( host ! = NULL ) {
he = NULL ;
if ( ( flags & NI_NUMERICHOST ) = = 0 ) {
2020-03-16 19:00:16 +03:00
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 ;
}
}
2014-01-31 18:57:43 +04:00
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 ;
2016-03-18 14:03:28 +03:00
snprintf ( host , hostlen , " %s " , he - > h_name ) ;
2014-01-31 18:57:43 +04:00
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 ;
2016-03-18 14:03:28 +03:00
snprintf ( serv , servlen , " %s " , service - > s_name ) ;
2014-01-31 18:57:43 +04:00
} 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 ) ;
}
2022-11-08 13:01:44 +03:00
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 ;
}
2018-10-31 10:44:08 +03:00
/****************************
* CONSTRUCTOR
* * * * * * * * * * * * * * * * * * * * * * * * * * */
void nwrap_constructor ( void )
{
2022-11-08 13:01:44 +03:00
NWRAP_REINIT_ALL ;
2018-10-31 10:44:08 +03:00
/*
* 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. */
}
2014-01-31 18:57:43 +04:00
/****************************
* 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 )
{
2020-03-16 19:00:16 +03:00
size_t i ;
2014-01-31 18:57:43 +04:00
2015-03-24 19:54:34 +03:00
NWRAP_LOCK_ALL ;
2014-01-31 18:57:43 +04:00
if ( nwrap_main_global ! = NULL ) {
struct nwrap_main * m = nwrap_main_global ;
/* libc */
2018-10-31 10:44:08 +03:00
if ( m - > libc ! = NULL ) {
2023-01-24 13:20:49 +03:00
if ( m - > libc - > handle ! = NULL
# ifdef RTLD_NEXT
& & m - > libc - > handle ! = RTLD_NEXT
# endif
) {
2018-10-31 10:44:08 +03:00
dlclose ( m - > libc - > handle ) ;
}
2023-01-24 13:20:49 +03:00
if ( m - > libc - > nsl_handle ! = NULL
# ifdef RTLD_NEXT
& & m - > libc - > nsl_handle ! = RTLD_NEXT
# endif
) {
2018-10-31 10:44:08 +03:00
dlclose ( m - > libc - > nsl_handle ) ;
}
2023-01-24 13:20:49 +03:00
if ( m - > libc - > sock_handle ! = NULL
# ifdef RTLD_NEXT
& & m - > libc - > sock_handle ! = RTLD_NEXT
# endif
) {
2018-10-31 10:44:08 +03:00
dlclose ( m - > libc - > sock_handle ) ;
}
SAFE_FREE ( m - > libc ) ;
2014-01-31 18:57:43 +04:00
}
/* backends */
2018-10-31 10:44:08 +03:00
if ( m - > backends ! = NULL ) {
for ( i = 0 ; i < m - > num_backends ; i + + ) {
struct nwrap_backend * b = & ( m - > backends [ i ] ) ;
2014-01-31 18:57:43 +04:00
2018-10-31 10:44:08 +03:00
if ( b - > so_handle ! = NULL ) {
dlclose ( b - > so_handle ) ;
}
2020-04-02 14:43:44 +03:00
SAFE_FREE ( b - > symbols ) ;
2014-01-31 18:57:43 +04:00
}
2018-10-31 10:44:08 +03:00
SAFE_FREE ( m - > backends ) ;
2014-01-31 18:57:43 +04:00
}
}
if ( nwrap_pw_global . cache ! = NULL ) {
struct nwrap_cache * c = nwrap_pw_global . cache ;
nwrap_files_cache_unload ( c ) ;
if ( c - > fd > = 0 ) {
2015-03-23 16:39:28 +03:00
fclose ( c - > fp ) ;
c - > fd = - 1 ;
2014-01-31 18:57:43 +04:00
}
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 ) {
2015-03-23 16:39:28 +03:00
fclose ( c - > fp ) ;
c - > fd = - 1 ;
2014-01-31 18:57:43 +04:00
}
SAFE_FREE ( nwrap_gr_global . list ) ;
nwrap_pw_global . num = 0 ;
}
2015-11-20 10:51:49 +03:00
# if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM)
2015-11-19 11:02:46 +03:00
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 ;
}
2015-11-20 11:01:01 +03:00
nwrap_sp_global . num = 0 ;
2015-11-19 11:02:46 +03:00
}
2015-11-20 10:51:49 +03:00
# endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */
2015-11-19 11:02:46 +03:00
2014-01-31 18:57:43 +04:00
if ( nwrap_he_global . cache ! = NULL ) {
struct nwrap_cache * c = nwrap_he_global . cache ;
nwrap_files_cache_unload ( c ) ;
if ( c - > fd > = 0 ) {
2015-03-23 16:39:28 +03:00
fclose ( c - > fp ) ;
c - > fd = - 1 ;
2014-01-31 18:57:43 +04:00
}
nwrap_he_global . num = 0 ;
}
2015-07-15 16:01:48 +03:00
2015-11-20 11:38:16 +03:00
free ( user_addrlist . items ) ;
2015-11-23 10:33:02 +03:00
# ifdef HAVE_GETHOSTBYNAME2
2015-11-20 11:38:16 +03:00
free ( user_addrlist2 . items ) ;
2015-11-23 10:33:02 +03:00
# endif
2015-11-20 11:38:16 +03:00
2015-07-15 16:01:48 +03:00
hdestroy ( ) ;
2015-03-24 19:54:34 +03:00
NWRAP_UNLOCK_ALL ;
2014-01-31 18:57:43 +04:00
}