[Samba] nsswitch wins reverse lookup

Peter Eser Peter.Eser at heuft.com
Wed May 9 12:39:53 GMT 2007


For all interested:
We solved the issue for us with patching nsswitch/wins.c
Seems there is no gethostbyaddr support in the original (why not?).
Found an old solaris patch (lost the name originator) and modified it to run
with 3.0.24 for our purposes.

Here's the patch, mainly the new function  _nss_wins_gethostbyaddr_r against
3.0.24:

*** nsswitch/wins.c.org 2007-05-08 08:51:30.000000000 +0200
+++ nsswitch/wins.c 2007-05-08 11:42:14.000000000 +0200
@@ -125,8 +125,6 @@
  return ret;
 }

-#ifdef HAVE_NS_API_H
-
 static NODE_STATUS_STRUCT *lookup_byaddr_backend(char *addr, int *count)
 {
  int fd;
@@ -150,6 +148,8 @@
  return status;
 }

+#ifdef HAVE_NS_API_H
+
 /* IRIX version */

 int init(void)
@@ -375,4 +375,105 @@
  return _nss_wins_gethostbyname_r(
   name, he, buffer, buflen, h_errnop);
 }
+
+
/***************************************************************************
*
+  gethostbyaddr()
+
**************************************************************************/
+  NSS_STATUS
+  _nss_wins_gethostbyaddr_r(const char *addr, int length, int type,
+       struct hostent *he, char *buffer, size_t buflen,
+       int *errnop, int *h_errnop)
+  {
+   enum { AddressStringSize = 16 };
+   char **host_addresses, **host_aliases;
+   char address_string[AddressStringSize];
+   NODE_STATUS_STRUCT *status;
+   int i, rc, count, true_count;
+   size_t namelen;
+
+   memset(he, '\0', sizeof(*he));
+
+   /* I don't think you can do WINS over IPV6 - fv */
+   if (length != INADDRSZ || type != AF_INET) {
+    return NSS_STATUS_NOTFOUND;
+   }
+
+   rc = snprintf(address_string, AddressStringSize, "%d.%d.%d.%d",
+    (uchar) addr[0], (uchar) addr[1], (uchar) addr[2],
+    (uchar) addr[3]);
+   if (rc < 0 || rc > AddressStringSize) {
+    return NSS_STATUS_NOTFOUND;
+   }
+
+   status = lookup_byaddr_backend(address_string, &count);
+   if (!status) {
+    return NSS_STATUS_NOTFOUND;
+   }
+
+   true_count = 0;
+   for (i=0;i<count;i++) {
+    /* ignore group names */
+    if (status[i].flags & 0x80 || !(status[i].type == 0x20 ||
status[i].type == 0x00 ) ) continue;
+    ++true_count;
+   }
+
+   if (true_count < 1) {
+    return NSS_STATUS_NOTFOUND;
+   }
+   if (buflen < (true_count+3)*INADDRSZ) {
+    /* no ENOMEM error type?! */
+    return NSS_STATUS_NOTFOUND;
+   }
+   host_addresses = (char **)buffer;
+   he->h_addr_list = host_addresses;
+   buffer += 2 * INADDRSZ;
+   buflen -= 2 * INADDRSZ;
+   host_addresses[0] = buffer;
+   host_addresses[1] = NULL;
+   memcpy(buffer, addr, INADDRSZ);
+   buffer += INADDRSZ;
+   buflen -= INADDRSZ;
+   he->h_addrtype = AF_INET;
+   he->h_length = INADDRSZ;
+
+   if (true_count == 1) {
+    he->h_aliases = host_addresses + 1;
+   } else {
+    host_aliases = (char **)buffer;
+    he->h_aliases = host_aliases;
+    host_aliases[true_count-1] = NULL;
+    buffer += true_count * INADDRSZ;
+    buflen -= true_count * INADDRSZ;
+   }
+
+   true_count = 0;
+   for (i=0;i<count;i++) {
+    /* ignore group names */
+    if (status[i].flags & 0x80 || !(status[i].type == 0x20 ||
status[i].type == 0x00 ) ) continue;
+    /* assume first name is 'canonical' name */
+    if (true_count == 0) {
+     he->h_name = buffer;
+    } else {
+     *host_aliases = buffer;
+     host_aliases++;
+    }
+    namelen = strlen(status[i].name);
+    if (buflen < namelen + 1) {
+     /* no ENOMEM error type?! */
+     return NSS_STATUS_NOTFOUND;
+    }
+    memcpy(buffer, &status[i].name, namelen);
+    buffer += namelen;
+    *buffer = '\0';
+    buffer++;
+    buflen -= namelen + 1;
+    true_count++;
+   }
+
+   if (status)
+    free(status);
+
+   return NSS_STATUS_SUCCESS;
+  }
+
 #endif


Take care!!
The if:   (status[i].flags & 0x80 || !(status[i].type == 0x20 ||
status[i].type == 0x00 ) )
is modified for our purposes by try and error, I don't know what flags and
type
would be the correct ones (I think they come from windows (e.g. NetBios
Client type=)?).

Perhaps it helps someone....






> Nobody an idea, need more information from me?
>
> Getting reverse lookups to work is important for me.
> Has somebody reverse lookups over wins working?
>
> Many thanks
>
>
> >I don't get reverse lookups (gethostbyaddr) over winbind wins to work.
> >Normal lookups work and also wbinfo -I gives back a netbios name for an
IP.
> >
> >my entry in nsswitch.conf is  hosts:          files dns wins
> >(dns reverse lookups ar ok)
> >
> >The wins server is also samba and runs on another server.
> >
> >Many thanks for any help...



More information about the samba mailing list