diff options
author | Jeremy Allison <jra@samba.org> | 2008-11-19 11:22:50 -0800 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2008-11-19 11:22:50 -0800 |
commit | cd82c07943c329149572473546cae732c977308c (patch) | |
tree | f7aa01a3b1cc66ab95dbfe5f82f01214b2fc4f47 /source3 | |
parent | 42523498b9a65b5b585a5d1564e61a6528f52926 (diff) | |
download | samba-cd82c07943c329149572473546cae732c977308c.tar.gz samba-cd82c07943c329149572473546cae732c977308c.tar.bz2 samba-cd82c07943c329149572473546cae732c977308c.zip |
Fix bug #5904 - libnss_wins causes SIGABRT while servicing getaddrinfo() request.
Jeremy.
Diffstat (limited to 'source3')
-rw-r--r-- | source3/nsswitch/wins.c | 63 |
1 files changed, 48 insertions, 15 deletions
diff --git a/source3/nsswitch/wins.c b/source3/nsswitch/wins.c index 2f82997aaf..e028eb8cf2 100644 --- a/source3/nsswitch/wins.c +++ b/source3/nsswitch/wins.c @@ -24,6 +24,14 @@ #include <ns_daemon.h> #endif +#if HAVE_PTHREAD_H +#include <pthread.h> +#endif + +#if HAVE_PTHREAD +static pthread_mutex_t wins_nss_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + #ifndef INADDRSZ #define INADDRSZ 4 #endif @@ -320,11 +328,16 @@ NSS_STATUS _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he, char *buffer, size_t buflen, int *h_errnop) { + NSS_STATUS nss_status = NSS_STATUS_SUCCESS; struct in_addr *ip_list; int i, count; fstring name; size_t namelen; +#if HAVE_PTHREAD + pthread_mutex_lock(&wins_nss_mutex); +#endif + memset(he, '\0', sizeof(*he)); fstrcpy(name, hostname); @@ -332,8 +345,10 @@ _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he, ip_list = lookup_byname_backend(name, &count); - if (!ip_list) - return NSS_STATUS_NOTFOUND; + if (!ip_list) { + nss_status = NSS_STATUS_NOTFOUND; + goto out; + } /* Copy h_name */ @@ -341,7 +356,8 @@ _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he, if ((he->h_name = get_static(&buffer, &buflen, namelen)) == NULL) { free(ip_list); - return NSS_STATUS_TRYAGAIN; + nss_status = NSS_STATUS_TRYAGAIN; + goto out; } memcpy(he->h_name, name, namelen); @@ -353,20 +369,23 @@ _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he, if (get_static(&buffer, &buflen, i) == NULL) { free(ip_list); - return NSS_STATUS_TRYAGAIN; + nss_status = NSS_STATUS_TRYAGAIN; + goto out; } if ((he->h_addr_list = (char **)get_static( &buffer, &buflen, (count + 1) * sizeof(char *))) == NULL) { free(ip_list); - return NSS_STATUS_TRYAGAIN; + nss_status = NSS_STATUS_TRYAGAIN; + goto out; } for (i = 0; i < count; i++) { if ((he->h_addr_list[i] = get_static(&buffer, &buflen, INADDRSZ)) == NULL) { free(ip_list); - return NSS_STATUS_TRYAGAIN; + nss_status = NSS_STATUS_TRYAGAIN; + goto out; } memcpy(he->h_addr_list[i], &ip_list[i], INADDRSZ); } @@ -385,16 +404,27 @@ _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he, if ((i = (unsigned long)(buffer) % sizeof(char*)) != 0) i = sizeof(char*) - i; - if (get_static(&buffer, &buflen, i) == NULL) - return NSS_STATUS_TRYAGAIN; + if (get_static(&buffer, &buflen, i) == NULL) { + nss_status = NSS_STATUS_TRYAGAIN; + goto out; + } if ((he->h_aliases = (char **)get_static( - &buffer, &buflen, sizeof(char *))) == NULL) - return NSS_STATUS_TRYAGAIN; + &buffer, &buflen, sizeof(char *))) == NULL) { + nss_status = NSS_STATUS_TRYAGAIN; + goto out; + } he->h_aliases[0] = NULL; - return NSS_STATUS_SUCCESS; + nss_status = NSS_STATUS_SUCCESS; + + out: + +#if HAVE_PTHREAD + pthread_mutex_unlock(&wins_nss_mutex); +#endif + return nss_status; } @@ -402,12 +432,15 @@ NSS_STATUS _nss_wins_gethostbyname2_r(const char *name, int af, struct hostent *he, char *buffer, size_t buflen, int *h_errnop) { + NSS_STATUS nss_status; + if(af!=AF_INET) { *h_errnop = NO_DATA; - return NSS_STATUS_UNAVAIL; + nss_status = NSS_STATUS_UNAVAIL; + } else { + nss_status = _nss_wins_gethostbyname_r( + name, he, buffer, buflen, h_errnop); } - - return _nss_wins_gethostbyname_r( - name, he, buffer, buflen, h_errnop); + return nss_status; } #endif |