libsmb: Add name_status_lmhosts
authorVolker Lendecke <vl@samba.org>
Mon, 19 Dec 2016 19:18:41 +0000 (20:18 +0100)
committerRalph Boehme <slow@samba.org>
Tue, 3 Jan 2017 15:04:27 +0000 (16:04 +0100)
Don't ask... Oh, you did? :-)

Try to figure out a hosts' name from lmhosts. This is for a setup I've
come across where for several reasons kerberos and ldap were unusable
(very organically grown but unchangeable Solaris 10 installation with
tons of ancient libs that ./configure incorrectly finds and where tar xf
samba-4.5.3.tar takes 5 minutes...), so I had to fall back to compile
with --without-ads. Unfortunately in that environment NetBIOS was also
turned off, but the "winbind rpc only" code relies on name_status to
get a DC's name from its IP address for the netlogon calls. This walks
the local lmhosts file to scan for the same information.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/libsmb/namequery.c

index 945fc644bb2e4982d759edbe31b1270088d49686..e39d76176cc6181d852eda7570b3aa25c7e3cc7b 100644 (file)
@@ -916,6 +916,42 @@ NTSTATUS node_status_query(TALLOC_CTX *mem_ctx, struct nmb_name *name,
        return status;
 }
 
+static bool name_status_lmhosts(const struct sockaddr_storage *paddr,
+                               int qname_type, fstring pname)
+{
+       FILE *f;
+       char *name;
+       int name_type;
+       struct sockaddr_storage addr;
+
+       if (paddr->ss_family != AF_INET) {
+               return false;
+       }
+
+       f = startlmhosts(get_dyn_LMHOSTSFILE());
+       if (f == NULL) {
+               return false;
+       }
+
+       while (getlmhostsent(talloc_tos(), f, &name, &name_type, &addr)) {
+               if (addr.ss_family != AF_INET) {
+                       continue;
+               }
+               if (name_type != qname_type) {
+                       continue;
+               }
+               if (memcmp(&((const struct sockaddr_in *)paddr)->sin_addr,
+                          &((const struct sockaddr_in *)&addr)->sin_addr,
+                          sizeof(struct in_addr)) == 0) {
+                       fstrcpy(pname, name);
+                       endlmhosts(f);
+                       return true;
+               }
+       }
+       endlmhosts(f);
+       return false;
+}
+
 /****************************************************************************
  Find the first type XX name in a node status reply - used for finding
  a servers name given its IP. Return the matched name in *name.
@@ -957,6 +993,13 @@ bool name_status_find(const char *q_name,
                return false;
        }
 
+       result = name_status_lmhosts(to_ss, type, name);
+       if (result) {
+               DBG_DEBUG("Found name %s in lmhosts\n", name);
+               namecache_status_store(q_name, q_type, type, to_ss, name);
+               return true;
+       }
+
        set_socket_addr_v4(&ss);
 
        /* W2K PDC's seem not to respond to '*'#0. JRA */