summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2001-05-15 21:53:19 +0000
committerJeremy Allison <jra@samba.org>2001-05-15 21:53:19 +0000
commit199bb03916745ecf9ae514f011acff1d6ec63a10 (patch)
tree39dad541d32e0237d15437d731eff24ee428ccea
parent218f514d2701031de02e8560235a0cfcb75b56ae (diff)
downloadsamba-199bb03916745ecf9ae514f011acff1d6ec63a10.tar.gz
samba-199bb03916745ecf9ae514f011acff1d6ec63a10.tar.bz2
samba-199bb03916745ecf9ae514f011acff1d6ec63a10.zip
Fixed glibc crash problems with libnss_wins.so
Jeremy. (This used to be commit c38a465bef91bc54cd3f3ce81e5a9c818f429801)
-rw-r--r--source3/nsswitch/wins.c48
1 files changed, 44 insertions, 4 deletions
diff --git a/source3/nsswitch/wins.c b/source3/nsswitch/wins.c
index be76c2e54e..49edf3a88b 100644
--- a/source3/nsswitch/wins.c
+++ b/source3/nsswitch/wins.c
@@ -31,6 +31,39 @@ extern int DEBUGLEVEL;
#define INADDRSZ 4
#endif
+/* Use our own create socket code so we don't recurse.... */
+
+static int wins_lookup_open_socket_in(void)
+{
+ struct sockaddr_in sock;
+ int val=1;
+ int res;
+
+ memset((char *)&sock,'\0',sizeof(sock));
+
+#ifdef HAVE_SOCK_SIN_LEN
+ sock.sin_len = sizeof(sock);
+#endif
+ sock.sin_port = 0;
+ sock.sin_family = AF_INET;
+ sock.sin_addr.s_addr = interpret_addr("0.0.0.0");
+ res = socket(AF_INET, SOCK_DGRAM, 0);
+ if (res == -1)
+ return -1;
+
+ setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val));
+#ifdef SO_REUSEPORT
+ setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val));
+#endif /* SO_REUSEPORT */
+
+ /* now we've got a socket - we need to bind it */
+
+ if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
+ return(-1);
+
+ return res;
+}
+
struct in_addr *lookup_backend(const char *name, int *count)
{
int fd;
@@ -51,8 +84,9 @@ struct in_addr *lookup_backend(const char *name, int *count)
*count = 0;
- fd = open_socket_in(SOCK_DGRAM,0, 3, interpret_addr("0.0.0.0"), True);
- if (fd == -1) return NULL;
+ fd = wins_lookup_open_socket_in();
+ if (fd == -1)
+ return NULL;
set_socket_options(fd,"SO_BROADCAST");
@@ -85,6 +119,7 @@ struct in_addr *lookup_backend(const char *name, int *count)
}
out:
+
close(fd);
return ret;
}
@@ -102,13 +137,14 @@ _nss_wins_gethostbyname_r(const char *name, struct hostent *he,
char **host_addresses;
struct in_addr *ip_list;
int i, count;
+ size_t namelen = strlen(name) + 1;
ip_list = lookup_backend(name, &count);
if (!ip_list) {
return NSS_STATUS_NOTFOUND;
}
- if (buflen < (2*count+1)*INADDRSZ) {
+ if (buflen < namelen + (2*count+1)*INADDRSZ) {
/* no ENOMEM error type?! */
return NSS_STATUS_NOTFOUND;
}
@@ -130,7 +166,11 @@ _nss_wins_gethostbyname_r(const char *name, struct hostent *he,
host_addresses++;
}
- if (ip_list) free(ip_list);
+ if (ip_list)
+ free(ip_list);
+
+ memcpy(buffer, name, namelen);
+ he->h_name = buffer;
return NSS_STATUS_SUCCESS;
}