Merge branch 'master' of ssh://git.samba.org/data/git/abartlet/samba into extended...
[abartlet/samba.git/.git] / source3 / nsswitch / wins.c
index 2f82997aafbe4c1bdfe56ed2444c384d81531bf9..e028eb8cf2ba69fcdc4437fb43b84b742cd65ea8 100644 (file)
 #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