diff options
Diffstat (limited to 'source3/nsswitch')
-rw-r--r-- | source3/nsswitch/wins.c | 48 |
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; } |