diff options
Diffstat (limited to 'source3/nsswitch/wins.c')
-rw-r--r-- | source3/nsswitch/wins.c | 151 |
1 files changed, 116 insertions, 35 deletions
diff --git a/source3/nsswitch/wins.c b/source3/nsswitch/wins.c index 0ab0954812..8f34222bbf 100644 --- a/source3/nsswitch/wins.c +++ b/source3/nsswitch/wins.c @@ -27,7 +27,6 @@ #undef VOLATILE #include <ns_daemon.h> -#define NSD_LOGLEVEL NSD_LOG_MIN #endif #ifndef INADDRSZ @@ -36,6 +35,7 @@ static int initialised; +extern BOOL AllowDebugChange; /* Use our own create socket code so we don't recurse.... */ @@ -64,8 +64,12 @@ static int wins_lookup_open_socket_in(void) /* now we've got a socket - we need to bind it */ - if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) + if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) { + close(res); return(-1); + } + + set_socket_options(res,"SO_BROADCAST"); return res; } @@ -75,13 +79,42 @@ static void nss_wins_init(void) { initialised = 1; DEBUGLEVEL = 0; + AllowDebugChange = False; + + /* needed for lp_xx() functions */ + charset_initialise(); + TimeInit(); setup_logging("nss_wins",False); lp_load(dyn_CONFIGFILE,True,False,False); load_interfaces(); + codepage_initialise(lp_client_code_page()); +} + +static struct node_status *lookup_byaddr_backend(char *addr, int *count) +{ + int fd; + struct in_addr ip; + struct nmb_name nname; + struct node_status *status; + + if (!initialised) { + nss_wins_init(); + } + + fd = wins_lookup_open_socket_in(); + if (fd == -1) + return NULL; + + make_nmb_name(&nname, "*", 0); + ip = *interpret_addr2(addr); + status = node_status_query(fd,&nname,ip, count); + + close(fd); + return status; } -static struct in_addr *lookup_backend(const char *name, int *count) +static struct in_addr *lookup_byname_backend(const char *name, int *count) { int fd; struct in_addr *ret = NULL; @@ -98,15 +131,6 @@ static struct in_addr *lookup_backend(const char *name, int *count) if (fd == -1) return NULL; - set_socket_options(fd,"SO_BROADCAST"); - -/* The next four lines commented out by JHT - and replaced with the four lines following */ -/* if( !is_zero_ip( wins_ip ) ) { - * ret = name_query( fd, name, 0x20, False, True, wins_src_ip(), count ); - * goto out; - * } - */ p = wins_srv_ip(); if( !is_zero_ip(p) ) { ret = name_query(fd,name,0x20,False,True, p, count); @@ -135,16 +159,12 @@ static struct in_addr *lookup_backend(const char *name, int *count) } -/**************************************************************************** -gethostbyname() - we ignore any domain portion of the name and only -handle names that are at most 15 characters long - **************************************************************************/ #ifdef HAVE_NS_API_H /* IRIX version */ int init(void) { - nsd_logprintf(NSD_LOGLEVEL, "init (wins)\n"); + nsd_logprintf(NSD_LOG_MIN, "entering init (wins)\n"); nss_wins_init(); return NSD_OK; } @@ -153,11 +173,14 @@ int lookup(nsd_file_t *rq) { char *map; char *key; + char *addr; struct in_addr *ip_list; - int count; - char response[80]; + struct node_status *status; + int i, count, len, size; + char response[1024]; + BOOL found = False; - nsd_logprintf(NSD_LOGLEVEL, "lookup (wins)\n"); + nsd_logprintf(NSD_LOG_MIN, "entering lookup (wins)\n"); if (! rq) return NSD_ERROR; @@ -167,31 +190,89 @@ int lookup(nsd_file_t *rq) return NSD_ERROR; } - if (strcasecmp(map,"hosts.byname") != 0) { - rq->f_status = NS_NOTFOUND; - return NSD_NEXT; - } - key = nsd_attr_fetch_string(rq->f_attrs, "key", (char*)0); if (! key || ! *key) { rq->f_status = NS_FATAL; return NSD_ERROR; } - ip_list = lookup_backend(key, &count); - - if (!ip_list) { - rq->f_status = NSS_STATUS_NOTFOUND; - return NSD_NEXT; + response[0] = '\0'; + len = sizeof(response) - 2; + + /* + * response needs to be a string of the following format + * ip_address[ ip_address]*\tname[ alias]* + */ + if (strcasecmp(map,"hosts.byaddr") == 0) { + if ( status = lookup_byaddr_backend(key, &count)) { + size = strlen(key) + 1; + if (size > len) { + free(status); + return NSD_ERROR; + } + len -= size; + strncat(response,key,size); + strncat(response,"\t",1); + for (i = 0; i < count; i++) { + /* ignore group names */ + if (status[i].flags & 0x80) continue; + if (status[i].type == 0x20) { + size = sizeof(status[i].name) + 1; + if (size > len) { + free(status); + return NSD_ERROR; + } + len -= size; + strncat(response, status[i].name, size); + strncat(response, " ", 1); + found = True; + } + } + response[strlen(response)-1] = '\n'; + free(status); + } + } else if (strcasecmp(map,"hosts.byname") == 0) { + if (ip_list = lookup_byname_backend(key, &count)) { + for (i = count; i ; i--) { + addr = inet_ntoa(ip_list[i-1]); + size = strlen(addr) + 1; + if (size > len) { + free(ip_list); + return NSD_ERROR; + } + len -= size; + if (i != 0) + response[strlen(response)-1] = ' '; + strncat(response,addr,size); + strncat(response,"\t",1); + } + size = strlen(key) + 1; + if (size > len) { + free(ip_list); + return NSD_ERROR; + } + strncat(response,key,size); + strncat(response,"\n",1); + found = True; + free(ip_list); + } } - snprintf(response,79,"%s %s\n",inet_ntoa(*ip_list),key); - free(ip_list); - nsd_set_result(rq,NS_SUCCESS,response,strlen(response),VOLATILE); - return NSD_OK; + if (found) { + nsd_logprintf(NSD_LOG_LOW, "lookup (wins %s) %s\n",map,response); + nsd_set_result(rq,NS_SUCCESS,response,strlen(response),VOLATILE); + return NSD_OK; + } + nsd_logprintf(NSD_LOG_LOW, "lookup (wins) not found\n"); + rq->f_status = NS_NOTFOUND; + return NSD_NEXT; } #else +/**************************************************************************** +gethostbyname() - we ignore any domain portion of the name and only +handle names that are at most 15 characters long + **************************************************************************/ NSS_STATUS _nss_wins_gethostbyname_r(const char *name, struct hostent *he, char *buffer, size_t buflen, int *errnop, @@ -204,7 +285,7 @@ _nss_wins_gethostbyname_r(const char *name, struct hostent *he, memset(he, '\0', sizeof(*he)); - ip_list = lookup_backend(name, &count); + ip_list = lookup_byname_backend(name, &count); if (!ip_list) { return NSS_STATUS_NOTFOUND; } |