The branch, master has been updated via 79b4874 nwrap: Use size_t for iterations, can't be negative via 19b9b95 nwrap: Try different backends for gethostbyname[2][_r] via 6b81c15 nwrap: Try different backends in gethostbyaddr from 9d72b6e pkgconfig: Fix path to library in nss_wrapper.pc
https://git.samba.org/?p=nss_wrapper.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 79b48745f55cc4947b437f0f1912cbad51eade63 Author: Samuel Cabrero <scabr...@suse.de> Date: Mon Nov 11 18:31:17 2019 +0100 nwrap: Use size_t for iterations, can't be negative Signed-off-by: Samuel Cabrero <scabr...@suse.de> Reviewed-by: Andreas Schneider <a...@samba.org> commit 19b9b95f1e91359c3e43e3136b4ba8b284807252 Author: Samuel Cabrero <scabr...@suse.de> Date: Thu Oct 10 18:12:08 2019 +0200 nwrap: Try different backends for gethostbyname[2][_r] Signed-off-by: Samuel Cabrero <scabr...@suse.de> Reviewed-by: Andreas Schneider <a...@samba.org> commit 6b81c152eae18b8cf9f4a80fb33b31ddf3af0a7f Author: Samuel Cabrero <scabr...@suse.de> Date: Thu Oct 10 13:47:06 2019 +0200 nwrap: Try different backends in gethostbyaddr Signed-off-by: Samuel Cabrero <scabr...@suse.de> Reviewed-by: Andreas Schneider <a...@samba.org> ----------------------------------------------------------------------- Summary of changes: src/nss_wrapper.c | 457 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 412 insertions(+), 45 deletions(-) Changeset truncated at 500 lines: diff --git a/src/nss_wrapper.c b/src/nss_wrapper.c index 1bcd3b1..ff41eeb 100644 --- a/src/nss_wrapper.c +++ b/src/nss_wrapper.c @@ -395,6 +395,14 @@ struct nwrap_module_nss_fns { NSS_STATUS (*_nss_getgrent_r)(struct group *result, char *buffer, size_t buflen, int *errnop); NSS_STATUS (*_nss_endgrent)(void); + NSS_STATUS (*_nss_gethostbyaddr_r)(const void *addr, socklen_t addrlen, + int af, struct hostent *result, + char *buffer, size_t buflen, + int *errnop, int *h_errnop); + NSS_STATUS (*_nss_gethostbyname2_r)(const char *name, int af, + struct hostent *result, + char *buffer, size_t buflen, + int *errnop, int *h_errnop); }; struct nwrap_backend { @@ -405,6 +413,8 @@ struct nwrap_backend { struct nwrap_module_nss_fns *fns; }; +struct nwrap_vector; + struct nwrap_ops { struct passwd * (*nw_getpwnam)(struct nwrap_backend *b, const char *name); @@ -440,6 +450,18 @@ struct nwrap_ops { struct group *grdst, char *buf, size_t buflen, struct group **grdstp); void (*nw_endgrent)(struct nwrap_backend *b); + struct hostent *(*nw_gethostbyaddr)(struct nwrap_backend *b, + const void *addr, + socklen_t len, int type); + struct hostent *(*nw_gethostbyname)(struct nwrap_backend *b, + const char *name); + struct hostent *(*nw_gethostbyname2)(struct nwrap_backend *b, + const char *name, int af); + int (*nw_gethostbyname2_r)(struct nwrap_backend *b, + const char *name, int af, + struct hostent *hedst, + char *buf, size_t buflen, + struct hostent **hedstp); }; /* Public prototypes */ @@ -485,6 +507,18 @@ static int nwrap_files_getgrent_r(struct nwrap_backend *b, struct group *grdst, char *buf, size_t buflen, struct group **grdstp); static void nwrap_files_endgrent(struct nwrap_backend *b); +static struct hostent *nwrap_files_gethostbyaddr(struct nwrap_backend *b, + const void *addr, + socklen_t len, int type); +static struct hostent *nwrap_files_gethostbyname(struct nwrap_backend *b, + const char *name); +static struct hostent *nwrap_files_gethostbyname2(struct nwrap_backend *b, + const char *name, int af); +static int nwrap_files_gethostbyname2_r(struct nwrap_backend *b, + const char *name, int af, + struct hostent *hedst, + char *buf, size_t buflen, + struct hostent **hedstp); /* prototypes for module backend */ @@ -522,6 +556,18 @@ static void nwrap_module_setgrent(struct nwrap_backend *b); static void nwrap_module_endgrent(struct nwrap_backend *b); static int nwrap_module_initgroups(struct nwrap_backend *b, const char *user, gid_t group); +static struct hostent *nwrap_module_gethostbyaddr(struct nwrap_backend *b, + const void *addr, + socklen_t len, int type); +static struct hostent *nwrap_module_gethostbyname(struct nwrap_backend *b, + const char *name); +static struct hostent *nwrap_module_gethostbyname2(struct nwrap_backend *b, + const char *name, int af); +static int nwrap_module_gethostbyname2_r(struct nwrap_backend *b, + const char *name, int af, + struct hostent *hedst, + char *buf, size_t buflen, + struct hostent **hedstp); struct nwrap_ops nwrap_files_ops = { .nw_getpwnam = nwrap_files_getpwnam, @@ -541,6 +587,10 @@ struct nwrap_ops nwrap_files_ops = { .nw_getgrent = nwrap_files_getgrent, .nw_getgrent_r = nwrap_files_getgrent_r, .nw_endgrent = nwrap_files_endgrent, + .nw_gethostbyaddr = nwrap_files_gethostbyaddr, + .nw_gethostbyname = nwrap_files_gethostbyname, + .nw_gethostbyname2 = nwrap_files_gethostbyname2, + .nw_gethostbyname2_r = nwrap_files_gethostbyname2_r, }; struct nwrap_ops nwrap_module_ops = { @@ -561,6 +611,10 @@ struct nwrap_ops nwrap_module_ops = { .nw_getgrent = nwrap_module_getgrent, .nw_getgrent_r = nwrap_module_getgrent_r, .nw_endgrent = nwrap_module_endgrent, + .nw_gethostbyaddr = nwrap_module_gethostbyaddr, + .nw_gethostbyname = nwrap_module_gethostbyname, + .nw_gethostbyname2 = nwrap_module_gethostbyname2, + .nw_gethostbyname2_r = nwrap_module_gethostbyname2_r, }; struct nwrap_libc { @@ -571,7 +625,7 @@ struct nwrap_libc { }; struct nwrap_main { - int num_backends; + size_t num_backends; struct nwrap_backend *backends; struct nwrap_libc *libc; }; @@ -1475,6 +1529,10 @@ static struct nwrap_module_nss_fns *nwrap_load_module_fns(struct nwrap_backend * nwrap_load_module_fn(b, "getgrent_r"); *(void **)(&fns->_nss_endgrent) = nwrap_load_module_fn(b, "endgrent"); + *(void **)(&fns->_nss_gethostbyaddr_r) = + nwrap_load_module_fn(b, "gethostbyaddr_r"); + *(void **)(&fns->_nss_gethostbyname2_r) = + nwrap_load_module_fn(b, "gethostbyname2_r"); return fns; } @@ -1501,7 +1559,7 @@ static void *nwrap_load_module(const char *so_path) static bool nwrap_module_init(const char *name, struct nwrap_ops *ops, const char *so_path, - int *num_backends, + size_t *num_backends, struct nwrap_backend **backends) { struct nwrap_backend *b; @@ -3513,9 +3571,9 @@ static void nwrap_files_endgrent(struct nwrap_backend *b) } /* hosts functions */ -static int nwrap_files_gethostbyname(const char *name, int af, - struct hostent *result, - struct nwrap_vector *addr_list) +static int nwrap_files_internal_gethostbyname(const char *name, int af, + struct hostent *result, + struct nwrap_vector *addr_list) { struct nwrap_entlist *el; struct hostent *he; @@ -3611,11 +3669,11 @@ no_ent: return -1; } -#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) +static int nwrap_files_gethostbyname2_r(struct nwrap_backend *b, + const char *name, int af, + struct hostent *hedst, + char *buf, size_t buflen, + struct hostent **hedstp) { struct nwrap_vector *addr_list = malloc(sizeof(struct nwrap_vector)); union { @@ -3624,6 +3682,9 @@ static int nwrap_gethostbyname_r(const char *name, } g; int rc; + (void) b; /* unused */ + (void) af; /* unused */ + if (addr_list == NULL) { NWRAP_LOG(NWRAP_LOG_ERROR, "Unable to allocate memory for address list"); @@ -3633,9 +3694,9 @@ static int nwrap_gethostbyname_r(const char *name, ZERO_STRUCTP(addr_list); - rc = nwrap_files_gethostbyname(name, AF_UNSPEC, ret, addr_list); + rc = nwrap_files_internal_gethostbyname(name, AF_UNSPEC, hedst, + addr_list); if (rc == -1) { - *h_errnop = h_errno; if (addr_list->items != NULL) { free(addr_list->items); } @@ -3659,11 +3720,32 @@ static int nwrap_gethostbyname_r(const char *name, free(addr_list); g.ptr = buf; - ret->h_addr_list = g.list; - *result = ret; + hedst->h_addr_list = g.list; + *hedstp = hedst; return 0; } +#ifdef HAVE_GETHOSTBYNAME_R +static int nwrap_gethostbyname_r(const char *name, + struct hostent *ret, + char *buf, size_t buflen, + struct hostent **result, int *h_errnop) +{ + int rc; + size_t i; + + for (i=0; i < nwrap_main_global->num_backends; i++) { + struct nwrap_backend *b = &nwrap_main_global->backends[i]; + rc = b->ops->nw_gethostbyname2_r(b, name, AF_UNSPEC, ret, + buf, buflen, result); + if (rc == 0) { + return 0; + } + } + *h_errnop = h_errno; + return ENOENT; +} + int gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, @@ -3682,6 +3764,42 @@ int gethostbyname_r(const char *name, } #endif +#ifdef HAVE_GETHOSTBYNAME2_R +static int nwrap_gethostbyname2_r(const char *name, int af, + struct hostent *ret, + char *buf, size_t buflen, + struct hostent **result, int *h_errnop) +{ + int rc; + size_t i; + + for (i=0; i < nwrap_main_global->num_backends; i++) { + struct nwrap_backend *b = &nwrap_main_global->backends[i]; + rc = b->ops->nw_gethostbyname2_r(b, name, af, ret, + buf, buflen, result); + if (rc == 0) { + return 0; + } + } + *h_errnop = h_errno; + return ENOENT; +} + +int gethostbyname2_r(const char *name, int af, + struct hostent *ret, + char *buf, size_t buflen, + struct hostent **result, int *h_errnop) +{ + if (!nss_wrapper_hosts_enabled()) { + return libc_gethostbyname2_r(name, af, ret, buf, buflen, + result, h_errnop); + } + + return nwrap_gethostbyname2_r(name, af, ret, buf, buflen, result, + h_errnop); +} +#endif + static int nwrap_files_getaddrinfo(const char *name, unsigned short port, const struct addrinfo *hints, @@ -3785,7 +3903,8 @@ static int nwrap_files_getaddrinfo(const char *name, return rc; } -static struct hostent *nwrap_files_gethostbyaddr(const void *addr, +static struct hostent *nwrap_files_gethostbyaddr(struct nwrap_backend *b, + const void *addr, socklen_t len, int type) { struct hostent *he; @@ -3795,6 +3914,7 @@ static struct hostent *nwrap_files_gethostbyaddr(const void *addr, size_t i; bool ok; + (void) b; /* unused */ (void) len; /* unused */ ok = nwrap_files_cache_reload(nwrap_he_global.cache); @@ -3831,15 +3951,23 @@ static int nwrap_gethostbyaddr_r(const void *addr, socklen_t len, int type, char *buf, size_t buflen, struct hostent **result, int *h_errnop) { - *result = nwrap_files_gethostbyaddr(addr, len, type); + size_t i; + for (i=0; i < nwrap_main_global->num_backends; i++) { + struct nwrap_backend *b = &nwrap_main_global->backends[i]; + *result = b->ops->nw_gethostbyaddr(b, addr, len, type); + if (*result != NULL) { + break; + } + } + if (*result != NULL) { memset(buf, '\0', buflen); *ret = **result; return 0; - } else { - *h_errnop = h_errno; - return -1; } + + *h_errnop = h_errno; + return -1; } int gethostbyaddr_r(const void *addr, socklen_t len, int type, @@ -4336,13 +4464,177 @@ static void nwrap_module_endgrent(struct nwrap_backend *b) b->fns->_nss_endgrent(); } +static struct hostent *nwrap_module_gethostbyaddr(struct nwrap_backend *b, + const void *addr, + socklen_t len, int type) +{ + static struct hostent he; + static char *buf = NULL; + static size_t buflen = 1000; + NSS_STATUS status; + + if (b->fns->_nss_gethostbyaddr_r == NULL) { + return NULL; + } + + if (buf == NULL) { + buf = (char *)malloc(buflen); + if (buf == NULL) { + return NULL; + } + } +again: + status = b->fns->_nss_gethostbyaddr_r(addr, len, type, &he, + buf, buflen, &errno, &h_errno); + if (status == NSS_STATUS_TRYAGAIN) { + buflen *= 2; + buf = (char *)realloc(buf, buflen); + if (buf == NULL) { + 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 &he; +} + +static int nwrap_module_gethostbyname2_r(struct nwrap_backend *b, + const char *name, int af, + struct hostent *hedst, + char *buf, size_t buflen, + struct hostent **hedstp) +{ + NSS_STATUS status; + + *hedstp = NULL; + + if (b->fns->_nss_gethostbyname2_r == NULL) { + return ENOENT; + } + + status = b->fns->_nss_gethostbyname2_r(name, af, hedst, + buf, buflen, &errno, &h_errno); + switch (status) { + case NSS_STATUS_SUCCESS: + *hedstp = hedst; + return 0; + case NSS_STATUS_NOTFOUND: + if (errno != 0) { + return errno; + } + return ENOENT; + case NSS_STATUS_TRYAGAIN: + if (errno != 0) { + return errno; + } + return ERANGE; + default: + if (errno != 0) { + return errno; + } + return status; + } +} + +static struct hostent *nwrap_module_gethostbyname(struct nwrap_backend *b, + const char *name) +{ + static struct hostent he; + static char *buf = NULL; + static size_t buflen = 1000; + NSS_STATUS status; + + if (b->fns->_nss_gethostbyname2_r == NULL) { + return NULL; + } + + if (buf == NULL) { + buf = (char *)malloc(buflen); + if (buf == NULL) { + return NULL; + } + } + +again: + status = b->fns->_nss_gethostbyname2_r(name, AF_UNSPEC, &he, + buf, buflen, &errno, &h_errno); + if (status == NSS_STATUS_TRYAGAIN) { + buflen *= 2; + buf = (char *)realloc(buf, buflen); + if (buf == NULL) { + 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 &he; +} + +static struct hostent *nwrap_module_gethostbyname2(struct nwrap_backend *b, + const char *name, int af) +{ + static struct hostent he; + static char *buf = NULL; + static size_t buflen = 1000; + NSS_STATUS status; + + if (b->fns->_nss_gethostbyname2_r == NULL) { + return NULL; + } + + if (buf == NULL) { + buf = (char *)malloc(buflen); + if (buf == NULL) { + return NULL; + } + } + +again: + status = b->fns->_nss_gethostbyname2_r(name, af, &he, + buf, buflen, &errno, &h_errno); + if (status == NSS_STATUS_TRYAGAIN) { + buflen *= 2; + buf = (char *)realloc(buf, buflen); + if (buf == NULL) { + 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 &he; +} + /**************************************************************************** * GETPWNAM ***************************************************************************/ static struct passwd *nwrap_getpwnam(const char *name) { - int i; + size_t i; struct passwd *pwd; for (i=0; i < nwrap_main_global->num_backends; i++) { @@ -4372,7 +4664,8 @@ struct passwd *getpwnam(const char *name) static int nwrap_getpwnam_r(const char *name, struct passwd *pwdst, char *buf, size_t buflen, struct passwd **pwdstp) { - int i,ret; + size_t i; + int ret; for (i=0; i < nwrap_main_global->num_backends; i++) { -- NSS Wrapper Repository