r4891: - added a generic resolve_name() async interface in libcli/resolve/,
authorAndrew Tridgell <tridge@samba.org>
Fri, 21 Jan 2005 11:18:56 +0000 (11:18 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:09:03 +0000 (13:09 -0500)
   which will eventually try all resolution methods setup in smb.conf

 - only resolution backend at the moment is bcast, which does a
   parallel broadcast to all configured network interfaces, and takes
   the first reply that comes in (this nicely demonstrates how to do
   parallel requests using the async APIs)

 - converted all the existing code to use the new resolve_name() api

 - removed all the old nmb code (yay!)
(This used to be commit 239c310f255e43dd2d1c2433f666c9faaacbdce3)

20 files changed:
source4/client/client.c
source4/libcli/cliconnect.c
source4/libcli/composite/connect.c
source4/libcli/config.mk
source4/libcli/namequery.c [deleted file]
source4/libcli/namequery_dc.c [deleted file]
source4/libcli/nbt/libnbt.h
source4/libcli/nbt/namequery.c
source4/libcli/nbt/nbtname.c
source4/libcli/nbt/nbtsocket.c
source4/libcli/nmblib.c [deleted file]
source4/libcli/raw/clisocket.c
source4/libcli/raw/clitransport.c
source4/libcli/raw/libcliraw.h
source4/libcli/resolve/bcast.c [new file with mode: 0644]
source4/libcli/resolve/resolve.c [new file with mode: 0644]
source4/libcli/unexpected.c [deleted file]
source4/libnet/libnet_rpc.c
source4/torture/rpc/xplogin.c
source4/torture/torture.c

index 6c777bca5092543448c2e872cfc3f6e88c4dd4bd..a3631fd710a403dbc182bb28ffde120c5385d82f 100644 (file)
@@ -3105,11 +3105,14 @@ handle a message operation
 ****************************************************************************/
 static int do_message_op(void)
 {
-       struct nmb_name called, calling;
+       struct nbt_name called, calling;
        const char *server_name;
 
-       make_nmb_name(&calling, lp_netbios_name(), 0x0);
-       choose_called_name(&called, desthost, name_type);
+       calling.name = lp_netbios_name();
+       calling.type = NBT_NAME_CLIENT;
+       calling.scope = NULL;
+
+       nbt_choose_called_name(NULL, &called, desthost, name_type);
 
        server_name = dest_ip ? dest_ip : desthost;
 
index 0f916d1eb11f40f595430040622158ecf73127d4..aaed36eb05b1eb682a9d06aa0afa727c736e7e0b 100644 (file)
@@ -1,7 +1,9 @@
 /*
    Unix SMB/CIFS implementation.
+
    client connect/disconnect routines
-   Copyright (C) Andrew Tridgell 2003
+
+   Copyright (C) Andrew Tridgell 2003-2005
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -49,8 +51,8 @@ BOOL smbcli_socket_connect(struct smbcli_state *cli, const char *server)
 
 /* wrapper around smbcli_transport_connect() */
 BOOL smbcli_transport_establish(struct smbcli_state *cli, 
-                            struct nmb_name *calling,
-                            struct nmb_name *called)
+                               struct nbt_name *calling,
+                               struct nbt_name *called)
 {
        return smbcli_transport_connect(cli->transport, calling, called);
 }
index 891d16b4e6438045423a2fe6d11acea554890881..7e08aab0d5ff8b36b2cfa4dd7e9b099defc9ab7a 100644 (file)
@@ -26,7 +26,8 @@
 #include "libcli/composite/composite.h"
 
 /* the stages of this call */
-enum connect_stage {CONNECT_SOCKET, 
+enum connect_stage {CONNECT_RESOLVE, 
+                   CONNECT_SOCKET, 
                    CONNECT_SESSION_REQUEST, 
                    CONNECT_NEGPROT,
                    CONNECT_SESSION_SETUP,
@@ -209,7 +210,7 @@ static NTSTATUS connect_socket(struct smbcli_composite *c,
 {
        struct connect_state *state = talloc_get_type(c->private, struct connect_state);
        NTSTATUS status;
-       struct nmb_name calling, called;
+       struct nbt_name calling, called;
 
        status = smbcli_sock_connect_recv(state->creq);
        NT_STATUS_NOT_OK_RETURN(status);
@@ -225,8 +226,11 @@ static NTSTATUS connect_socket(struct smbcli_composite *c,
                return connect_send_negprot(c, io);
        }
 
-       make_nmb_name(&calling, io->in.calling_name, 0x0);
-       choose_called_name(&called, io->in.called_name, 0x20);
+       calling.name = io->in.calling_name;
+       calling.type = NBT_NAME_CLIENT;
+       calling.scope = NULL;
+
+       nbt_choose_called_name(state, &called, io->in.called_name, NBT_NAME_SERVER);
 
        state->req = smbcli_transport_connect_send(state->transport, &calling, &called);
        NT_STATUS_HAVE_NO_MEMORY(state->req);
@@ -239,6 +243,29 @@ static NTSTATUS connect_socket(struct smbcli_composite *c,
 }
 
 
+/*
+  called when name resolution is finished
+*/
+static NTSTATUS connect_resolve(struct smbcli_composite *c, 
+                               struct smb_composite_connect *io)
+{
+       struct connect_state *state = talloc_get_type(c->private, struct connect_state);
+       NTSTATUS status;
+       const char *address;
+
+       status = resolve_name_recv(state->creq, state, &address);
+       NT_STATUS_NOT_OK_RETURN(status);
+
+       state->creq = smbcli_sock_connect_send(state->sock, address, state->io->in.port);
+       NT_STATUS_HAVE_NO_MEMORY(state->creq);
+
+       c->stage = CONNECT_SOCKET;
+       state->creq->async.private = c;
+       state->creq->async.fn = composite_handler;
+
+       return NT_STATUS_OK;
+}
+
 
 /*
   handle and dispatch state transitions
@@ -248,6 +275,9 @@ static void state_handler(struct smbcli_composite *c)
        struct connect_state *state = talloc_get_type(c->private, struct connect_state);
 
        switch (c->stage) {
+       case CONNECT_RESOLVE:
+               c->status = connect_resolve(c, state->io);
+               break;
        case CONNECT_SOCKET:
                c->status = connect_socket(c, state->io);
                break;
@@ -301,6 +331,7 @@ struct smbcli_composite *smb_composite_connect_send(struct smb_composite_connect
 {
        struct smbcli_composite *c;
        struct connect_state *state;
+       struct nbt_name name;
 
        c = talloc_zero(NULL, struct smbcli_composite);
        if (c == NULL) goto failed;
@@ -314,11 +345,15 @@ struct smbcli_composite *smb_composite_connect_send(struct smb_composite_connect
        state->io = io;
 
        c->state = SMBCLI_REQUEST_SEND;
-       c->stage = CONNECT_SOCKET;
+       c->stage = CONNECT_RESOLVE;
        c->event_ctx = state->sock->event.ctx;
        c->private = state;
 
-       state->creq = smbcli_sock_connect_send(state->sock, io->in.dest_host, io->in.port);
+       name.name = io->in.dest_host;
+       name.type = NBT_NAME_SERVER;
+       name.scope = NULL;
+
+       state->creq = resolve_name_send(&name, c->event_ctx);
        if (state->creq == NULL) goto failed;
 
        state->creq->async.private = c;
index 87866db66d7ad3142667fed8e5a79a3822d5f9e6..21cfed898781d7f24cbfeb365a82962f08f48a11 100644 (file)
@@ -8,15 +8,9 @@ ADD_OBJ_FILES = libcli/util/asn1.o \
                libcli/util/smbdes.o \
                libcli/util/smbencrypt.o
 
-[SUBSYSTEM::LIBCLI_NMB]
-ADD_OBJ_FILES = libcli/unexpected.o \
-               libcli/namecache.o \
-               libcli/nmblib.o \
-               libcli/namequery.o
-REQUIRED_SUBSYSTEMS = RPC_NDR_LSA
-
 [SUBSYSTEM::LIBCLI_LSA]
 ADD_OBJ_FILES = libcli/util/clilsa.o
+REQUIRED_SUBSYSTEMS = RPC_NDR_LSA
 
 [SUBSYSTEM::LIBCLI_COMPOSITE]
 ADD_OBJ_FILES = \
@@ -33,6 +27,12 @@ ADD_OBJ_FILES = \
        libcli/nbt/namequery.o
 REQUIRED_SUBSYSTEMS = NDR_NBT
 
+[SUBSYSTEM::LIBCLI_RESOLVE]
+ADD_OBJ_FILES = \
+       libcli/resolve/resolve.o \
+       libcli/resolve/bcast.o
+REQUIRED_SUBSYSTEMS = LIBCLI_NBT
+
 [SUBSYSTEM::LIBCLI]
-REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH LIBCLI_NMB \
-       LIBCLI_COMPOSITE LIBCLI_NBT
+REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBCLI_UTILS LIBCLI_AUTH \
+       LIBCLI_COMPOSITE LIBCLI_NBT LIBCLI_RESOLVE
diff --git a/source4/libcli/namequery.c b/source4/libcli/namequery.c
deleted file mode 100644 (file)
index c440a60..0000000
+++ /dev/null
@@ -1,1104 +0,0 @@
-/* 
-   Unix SMB/CIFS implementation.
-   name query routines
-   Copyright (C) Andrew Tridgell 1994-1998
-   
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-   
-*/
-
-#include "includes.h"
-#include "system/network.h"
-#include "system/time.h"
-
-/* A netbios node status array element. */
-struct node_status {
-       char name[16];
-       uint8_t type;
-       uint8_t flags;
-};
-
-
-/* nmbd.c sets this to True. */
-BOOL global_in_nmbd = False;
-
-/****************************************************************************
-generate a random trn_id
-****************************************************************************/
-static int generate_trn_id(void)
-{
-       static int trn_id;
-
-       if (trn_id == 0) {
-               sys_srandom(getpid());
-       }
-
-       trn_id = sys_random();
-
-       return trn_id % (uint_t)0x7FFF;
-}
-
-
-/****************************************************************************
- parse a node status response into an array of structures
-****************************************************************************/
-static struct node_status *parse_node_status(char *p, int *num_names)
-{
-       struct node_status *ret;
-       int i;
-
-       *num_names = CVAL(p,0);
-
-       if (*num_names == 0) return NULL;
-
-       ret = malloc_array_p(struct node_status, *num_names);
-       if (!ret) return NULL;
-
-       p++;
-       for (i=0;i< *num_names;i++) {
-               StrnCpy(ret[i].name,p,15);
-               trim_string(ret[i].name,NULL," ");
-               ret[i].type = CVAL(p,15);
-               ret[i].flags = p[16];
-               p += 18;
-               DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name, 
-                          ret[i].type, ret[i].flags));
-       }
-       return ret;
-}
-
-
-/****************************************************************************
-do a NBT node status query on an open socket and return an array of
-structures holding the returned names or NULL if the query failed
-**************************************************************************/
-struct node_status *node_status_query(int fd,struct nmb_name *name,
-                                     struct ipv4_addr to_ip, int *num_names)
-{
-       BOOL found=False;
-       int retries = 2;
-       int retry_time = 2000;
-       struct timeval tval;
-       struct packet_struct p;
-       struct packet_struct *p2;
-       struct nmb_packet *nmb = &p.packet.nmb;
-       struct node_status *ret;
-
-       ZERO_STRUCT(p);
-
-       nmb->header.name_trn_id = generate_trn_id();
-       nmb->header.opcode = 0;
-       nmb->header.response = False;
-       nmb->header.nm_flags.bcast = False;
-       nmb->header.nm_flags.recursion_available = False;
-       nmb->header.nm_flags.recursion_desired = False;
-       nmb->header.nm_flags.trunc = False;
-       nmb->header.nm_flags.authoritative = False;
-       nmb->header.rcode = 0;
-       nmb->header.qdcount = 1;
-       nmb->header.ancount = 0;
-       nmb->header.nscount = 0;
-       nmb->header.arcount = 0;
-       nmb->question.question_name = *name;
-       nmb->question.question_type = 0x21;
-       nmb->question.question_class = 0x1;
-
-       p.ip = to_ip;
-       p.port = NMB_PORT;
-       p.fd = fd;
-       p.timestamp = time(NULL);
-       p.packet_type = NMB_PACKET;
-       
-       GetTimeOfDay(&tval);
-  
-       if (!send_packet(&p)) 
-               return NULL;
-
-       retries--;
-
-       while (1) {
-               struct timeval tval2;
-               GetTimeOfDay(&tval2);
-               if (TvalDiff(&tval,&tval2) > retry_time) {
-                       if (!retries)
-                               break;
-                       if (!found && !send_packet(&p))
-                               return NULL;
-                       GetTimeOfDay(&tval);
-                       retries--;
-               }
-
-               if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {     
-                       struct nmb_packet *nmb2 = &p2->packet.nmb;
-                       debug_nmb_packet(p2);
-                       
-                       if (nmb2->header.opcode != 0 ||
-                           nmb2->header.nm_flags.bcast ||
-                           nmb2->header.rcode ||
-                           !nmb2->header.ancount ||
-                           nmb2->answers->rr_type != 0x21) {
-                               /* XXXX what do we do with this? could be a
-                                  redirect, but we'll discard it for the
-                                  moment */
-                               free_packet(p2);
-                               continue;
-                       }
-
-                       ret = parse_node_status(&nmb2->answers->rdata[0], num_names);
-                       free_packet(p2);
-                       return ret;
-               }
-       }
-       
-       return NULL;
-}
-
-
-/****************************************************************************
-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
-**************************************************************************/
-
-BOOL name_status_find(const char *q_name, int q_type, int type, struct ipv4_addr to_ip, char *name)
-{
-       struct node_status *status = NULL;
-       struct nmb_name nname;
-       int count, i;
-       int sock;
-       BOOL result = False;
-
-       if (lp_disable_netbios()) {
-               DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type));
-               return False;
-       }
-
-       DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name, 
-                  q_type, sys_inet_ntoa(to_ip)));
-
-       sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
-       if (sock == -1)
-               goto done;
-
-       /* W2K PDC's seem not to respond to '*'#0. JRA */
-       make_nmb_name(&nname, q_name, q_type);
-       status = node_status_query(sock, &nname, to_ip, &count);
-       close(sock);
-       if (!status)
-               goto done;
-
-       for (i=0;i<count;i++) {
-               if (status[i].type == type)
-                       break;
-       }
-       if (i == count)
-               goto done;
-
-       pull_ascii(name, status[i].name, 16, 15, STR_TERMINATE);
-       result = True;
-
- done:
-       SAFE_FREE(status);
-
-       DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
-
-       if (result)
-               DEBUGADD(10, (", ip address is %s", sys_inet_ntoa(to_ip)));
-
-       DEBUG(10, ("\n"));      
-
-       return result;
-}
-
-
-/*
-  comparison function used by sort_ip_list
-*/
-int ip_compare(struct ipv4_addr *ip1, struct ipv4_addr *ip2)
-{
-       int max_bits1=0, max_bits2=0;
-       int num_interfaces = iface_count();
-       int i;
-
-       for (i=0;i<num_interfaces;i++) {
-               struct ipv4_addr ip;
-               int bits1, bits2;
-               ip = *iface_n_bcast(i);
-               bits1 = matching_quad_bits((uint8_t *)&ip1->addr, (uint8_t *)&ip.addr);
-               bits2 = matching_quad_bits((uint8_t *)&ip2->addr, (uint8_t *)&ip.addr);
-               max_bits1 = MAX(bits1, max_bits1);
-               max_bits2 = MAX(bits2, max_bits2);
-       }       
-       
-       /* bias towards directly reachable IPs */
-       if (iface_local(*ip1)) {
-               max_bits1 += 32;
-       }
-       if (iface_local(*ip2)) {
-               max_bits2 += 32;
-       }
-
-       return max_bits2 - max_bits1;
-}
-
-/*
-  sort an IP list so that names that are close to one of our interfaces 
-  are at the top. This prevents the problem where a WINS server returns an IP that
-  is not reachable from our subnet as the first match
-*/
-static void sort_ip_list(struct ipv4_addr *iplist, int count)
-{
-       if (count <= 1) {
-               return;
-       }
-
-       qsort(iplist, count, sizeof(struct ipv4_addr), QSORT_CAST ip_compare);  
-}
-
-
-/****************************************************************************
- Do a netbios name query to find someones IP.
- Returns an array of IP addresses or NULL if none.
- *count will be set to the number of addresses returned.
- *timed_out is set if we failed by timing out
-****************************************************************************/
-struct ipv4_addr *name_query(int fd,const char *name,int name_type, 
-                          BOOL bcast,BOOL recurse,
-                          struct ipv4_addr to_ip, int *count, int *flags,
-                          BOOL *timed_out)
-{
-       BOOL found=False;
-       int i, retries = 3;
-       int retry_time = bcast?250:2000;
-       struct timeval tval;
-       struct packet_struct p;
-       struct packet_struct *p2;
-       struct nmb_packet *nmb = &p.packet.nmb;
-       struct ipv4_addr *ip_list = NULL;
-
-       if (lp_disable_netbios()) {
-               DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type));
-               return NULL;
-       }
-
-       if (timed_out) {
-               *timed_out = False;
-       }
-       
-       memset((char *)&p,'\0',sizeof(p));
-       (*count) = 0;
-       (*flags) = 0;
-       
-       nmb->header.name_trn_id = generate_trn_id();
-       nmb->header.opcode = 0;
-       nmb->header.response = False;
-       nmb->header.nm_flags.bcast = bcast;
-       nmb->header.nm_flags.recursion_available = False;
-       nmb->header.nm_flags.recursion_desired = recurse;
-       nmb->header.nm_flags.trunc = False;
-       nmb->header.nm_flags.authoritative = False;
-       nmb->header.rcode = 0;
-       nmb->header.qdcount = 1;
-       nmb->header.ancount = 0;
-       nmb->header.nscount = 0;
-       nmb->header.arcount = 0;
-       
-       make_nmb_name(&nmb->question.question_name,name,name_type);
-       
-       nmb->question.question_type = 0x20;
-       nmb->question.question_class = 0x1;
-       
-       p.ip = to_ip;
-       p.port = NMB_PORT;
-       p.fd = fd;
-       p.timestamp = time(NULL);
-       p.packet_type = NMB_PACKET;
-       
-       GetTimeOfDay(&tval);
-       
-       if (!send_packet(&p)) 
-               return NULL;
-       
-       retries--;
-       
-       while (1) {
-               struct timeval tval2;
-               struct ipv4_addr *tmp_ip_list;
-               
-               GetTimeOfDay(&tval2);
-               if (TvalDiff(&tval,&tval2) > retry_time) {
-                       if (!retries)
-                               break;
-                       if (!found && !send_packet(&p))
-                               return NULL;
-                       GetTimeOfDay(&tval);
-                       retries--;
-               }
-               
-               if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {     
-                       struct nmb_packet *nmb2 = &p2->packet.nmb;
-                       debug_nmb_packet(p2);
-                       
-                       /* If we get a Negative Name Query Response from a WINS
-                        * server, we should report it and give up.
-                        */
-                       if( 0 == nmb2->header.opcode            /* A query response   */
-                           && !(bcast)                 /* from a WINS server */
-                           && nmb2->header.rcode               /* Error returned     */
-                               ) {
-                               
-                               if (DEBUGLVL(3)) {
-                                       /* Only executed if DEBUGLEVEL >= 3 */
-                                       DEBUG(3,("Negative name query response, rcode 0x%02x: ", nmb2->header.rcode ));
-                                       switch( nmb2->header.rcode ) {
-                                       case 0x01:
-                                               DEBUG(3,("Request was invalidly formatted.\n" ));
-                                               break;
-                                       case 0x02:
-                                               DEBUG(3,("Problem with NBNS, cannot process name.\n"));
-                                               break;
-                                       case 0x03:
-                                               DEBUG(3,("The name requested does not exist.\n" ));
-                                               break;
-                                       case 0x04:
-                                               DEBUG(3,("Unsupported request error.\n" ));
-                                               break;
-                                       case 0x05:
-                                               DEBUG(3,("Query refused error.\n" ));
-                                               break;
-                                       default:
-                                               DEBUG(3,("Unrecognized error code.\n" ));
-                                               break;
-                                       }
-                               }
-                               free_packet(p2);
-                               return( NULL );
-                       }
-                       
-                       if (nmb2->header.opcode != 0 ||
-                           nmb2->header.nm_flags.bcast ||
-                           nmb2->header.rcode ||
-                           !nmb2->header.ancount) {
-                               /* 
-                                * XXXX what do we do with this? Could be a
-                                * redirect, but we'll discard it for the
-                                * moment.
-                                */
-                               free_packet(p2);
-                               continue;
-                       }
-                       
-                       tmp_ip_list = realloc_p(ip_list, 
-                                               struct ipv4_addr,
-                                               (*count) + nmb2->answers->rdlength/6);
-                       
-                       if (!tmp_ip_list) {
-                               DEBUG(0,("name_query: realloc_p failed.\n"));
-                               SAFE_FREE(ip_list);
-                       }
-                       
-                       ip_list = tmp_ip_list;
-                       
-                       if (ip_list) {
-                               DEBUG(2,("Got a positive name query response from %s ( ", sys_inet_ntoa(p2->ip)));
-                               for (i=0;i<nmb2->answers->rdlength/6;i++) {
-                                       putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
-                                       DEBUGADD(2,("%s ",sys_inet_ntoa(ip_list[(*count)])));
-                                       (*count)++;
-                               }
-                               DEBUGADD(2,(")\n"));
-                       }
-                       
-                       found=True;
-                       retries=0;
-                       /* We add the flags back ... */
-                       if (nmb2->header.response)
-                               (*flags) |= NM_FLAGS_RS;
-                       if (nmb2->header.nm_flags.authoritative)
-                               (*flags) |= NM_FLAGS_AA;
-                       if (nmb2->header.nm_flags.trunc)
-                               (*flags) |= NM_FLAGS_TC;
-                       if (nmb2->header.nm_flags.recursion_desired)
-                               (*flags) |= NM_FLAGS_RD;
-                       if (nmb2->header.nm_flags.recursion_available)
-                               (*flags) |= NM_FLAGS_RA;
-                       if (nmb2->header.nm_flags.bcast)
-                               (*flags) |= NM_FLAGS_B;
-                       free_packet(p2);
-                       /*
-                        * If we're doing a unicast lookup we only
-                        * expect one reply. Don't wait the full 2
-                        * seconds if we got one. JRA.
-                        */
-                       if(!bcast && found)
-                               break;
-               }
-       }
-
-       if (timed_out) {
-               *timed_out = True;
-       }
-
-       /* sort the ip list so we choose close servers first if possible */
-       sort_ip_list(ip_list, *count);
-
-       return ip_list;
-}
-
-/********************************************************
- Resolve via "bcast" method.
-*********************************************************/
-
-BOOL name_resolve_bcast(const char *name, int name_type,
-                       struct ipv4_addr **return_ip_list, int *return_count)
-{
-       int sock, i;
-       int num_interfaces = iface_count();
-
-       if (lp_disable_netbios()) {
-               DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
-               return False;
-       }
-
-       *return_ip_list = NULL;
-       *return_count = 0;
-       
-       /*
-        * "bcast" means do a broadcast lookup on all the local interfaces.
-        */
-
-       DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
-
-       sock = open_socket_in( SOCK_DGRAM, 0, 3,
-                              interpret_addr(lp_socket_address()), True );
-
-       if (sock == -1) return False;
-
-       set_socket_options(sock,"SO_BROADCAST");
-       /*
-        * Lookup the name on all the interfaces, return on
-        * the first successful match.
-        */
-       for( i = num_interfaces-1; i >= 0; i--) {
-               struct ipv4_addr sendto_ip;
-               int flags;
-               /* Done this way to fix compiler error on IRIX 5.x */
-               sendto_ip = *iface_n_bcast(i);
-               *return_ip_list = name_query(sock, name, name_type, True, 
-                                   True, sendto_ip, return_count, &flags, NULL);
-               if(*return_ip_list != NULL) {
-                       close(sock);
-                       return True;
-               }
-       }
-
-       close(sock);
-       return False;
-}
-
-/********************************************************
- Resolve via "wins" method.
-*********************************************************/
-BOOL resolve_wins(TALLOC_CTX *mem_ctx, const char *name, int name_type,
-                 struct ipv4_addr **return_iplist, int *return_count)
-{
-       int sock, t, i;
-       char **wins_tags;
-       struct ipv4_addr src_ip;
-
-       if (lp_disable_netbios()) {
-               DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
-               return False;
-       }
-
-       *return_iplist = NULL;
-       *return_count = 0;
-       
-       DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
-
-       if (wins_srv_count() < 1) {
-               DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
-               return False;
-       }
-
-       /* we try a lookup on each of the WINS tags in turn */
-       wins_tags = wins_srv_tags();
-
-       if (!wins_tags) {
-               /* huh? no tags?? give up in disgust */
-               return False;
-       }
-
-       /* the address we will be sending from */
-       src_ip = interpret_addr2(lp_socket_address());
-
-       /* in the worst case we will try every wins server with every
-          tag! */
-       for (t=0; wins_tags && wins_tags[t]; t++) {
-               int srv_count = wins_srv_count_tag(wins_tags[t]);
-               for (i=0; i<srv_count; i++) {
-                       struct ipv4_addr wins_ip;
-                       int flags;
-                       BOOL timed_out;
-
-                       wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
-
-                       if (global_in_nmbd && ismyip(wins_ip)) {
-                               /* yikes! we'll loop forever */
-                               continue;
-                       }
-
-                       /* skip any that have been unresponsive lately */
-                       if (wins_srv_is_dead(wins_ip, src_ip)) {
-                               continue;
-                       }
-
-                       DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", sys_inet_ntoa(wins_ip), wins_tags[t]));
-
-                       sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.addr, True);
-                       if (sock == -1) {
-                               continue;
-                       }
-
-                       *return_iplist = name_query(sock,name,name_type, False, 
-                                                   True, wins_ip, return_count, &flags, 
-                                                   &timed_out);
-                       if (*return_iplist != NULL) {
-                               goto success;
-                       }
-                       close(sock);
-
-                       if (timed_out) {
-                               /* Timed out wating for WINS server to respond.  Mark it dead. */
-                               wins_srv_died(wins_ip, src_ip);
-                       } else {
-                               /* The name definately isn't in this
-                                  group of WINS servers. goto the next group  */
-                               break;
-                       }
-               }
-       }
-
-       wins_srv_tags_free(wins_tags);
-       return False;
-
-success:
-       wins_srv_tags_free(wins_tags);
-       close(sock);
-       return True;
-}
-
-/********************************************************
- Resolve via "hosts" method.
-*********************************************************/
-
-static BOOL resolve_hosts(const char *name,
-                         struct ipv4_addr **return_iplist, int *return_count)
-{
-       /*
-        * "host" means do a localhost, or dns lookup.
-        */
-       struct hostent *hp;
-
-       *return_iplist = NULL;
-       *return_count = 0;
-
-       DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name));
-       
-       if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
-               struct ipv4_addr return_ip;
-               putip((char *)&return_ip,(char *)hp->h_addr);
-               *return_iplist = malloc_p(struct ipv4_addr);
-               if(*return_iplist == NULL) {
-                       DEBUG(3,("resolve_hosts: malloc fail !\n"));
-                       return False;
-               }
-               **return_iplist = return_ip;
-               *return_count = 1;
-               return True;
-       }
-       return False;
-}
-
-/********************************************************
- Internal interface to resolve a name into an IP address.
- Use this function if the string is either an IP address, DNS
- or host name or NetBIOS name. This uses the name switch in the
- smb.conf to determine the order of name resolution.
-*********************************************************/
-
-static BOOL internal_resolve_name(TALLOC_CTX *mem_ctx, const char *name, int name_type,
-                                 struct ipv4_addr **return_iplist, int *return_count)
-{
-  char *name_resolve_list;
-  fstring tok;
-  const char *ptr;
-  BOOL allones = (strcmp(name,"255.255.255.255") == 0);
-  BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
-  BOOL is_address = is_ipaddress(name);
-  BOOL result = False;
-  struct ipv4_addr *nodupes_iplist;
-  int i;
-
-  *return_iplist = NULL;
-  *return_count = 0;
-
-  DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
-
-  if (allzeros || allones || is_address) {
-       *return_iplist = malloc_p(struct ipv4_addr);
-       if(*return_iplist == NULL) {
-               DEBUG(3,("internal_resolve_name: malloc fail !\n"));
-               return False;
-       }
-       if(is_address) { 
-               /* if it's in the form of an IP address then get the lib to interpret it */
-               if (((*return_iplist)->addr = inet_addr(name)) == 0xFFFFFFFF ){
-                       DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name));
-                       return False;
-               }
-       } else {
-               (*return_iplist)->addr = allones ? 0xFFFFFFFF : 0;
-               *return_count = 1;
-       }
-    return True;
-  }
-  
-  /* Check netbios name cache */
-
-  if (namecache_fetch(mem_ctx, name, name_type, return_iplist, return_count)) {
-
-         /* This could be a negative response */
-
-         return (*return_count > 0);
-  }
-
-  name_resolve_list = talloc_strdup(mem_ctx, lp_name_resolve_order());
-  ptr = name_resolve_list;
-  if (!ptr || !*ptr)
-    ptr = "host";
-
-  while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
-         if((strequal(tok, "host") || strequal(tok, "hosts"))) {
-                 if (name_type == 0x20) {
-                         if (resolve_hosts(name, return_iplist, return_count)) {
-                                 result = True;
-                                 goto done;
-                         }
-                 }
-         } else if(strequal( tok, "lmhosts")) {
-                       /* REWRITE: add back in? */
-                       DEBUG(2,("resolve_name: REWRITE: add lmhosts back?? %s\n", tok));
-         } else if(strequal( tok, "wins")) {
-                 /* don't resolve 1D via WINS */
-                 if (name_type != 0x1D &&
-                     resolve_wins(mem_ctx, name, name_type, return_iplist, return_count)) {
-                   result = True;
-                   goto done;
-                 }
-         } else if(strequal( tok, "bcast")) {
-                 if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
-                   result = True;
-                   goto done;
-                 }
-         } else {
-                 DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
-         }
-  }
-
-  /* All of the resolve_* functions above have returned false. */
-
-  SAFE_FREE(*return_iplist);
-  *return_count = 0;
-
-  return False;
-
- done:
-
-  /* Remove duplicate entries.  Some queries, notably #1c (domain
-     controllers) return the PDC in iplist[0] and then all domain
-     controllers including the PDC in iplist[1..n].  Iterating over
-     the iplist when the PDC is down will cause two sets of timeouts. */
-
-  if (*return_count && (nodupes_iplist = malloc_array_p(struct ipv4_addr, *return_count))) {
-         int nodupes_count = 0;
-
-         /* Iterate over return_iplist looking for duplicates */
-
-         for (i = 0; i < *return_count; i++) {
-                 BOOL is_dupe = False;
-                 int j;
-
-                 for (j = i + 1; j < *return_count; j++) {
-                         if (ipv4_equal((*return_iplist)[i], 
-                                      (*return_iplist)[j])) {
-                                 is_dupe = True;
-                                 break;
-                         }
-                 }
-
-                 if (!is_dupe) {
-
-                         /* This one not a duplicate */
-
-                         nodupes_iplist[nodupes_count] = (*return_iplist)[i];
-                         nodupes_count++;
-                 }
-         }
-         
-         /* Switcheroo with original list */
-         
-         free(*return_iplist);
-
-         *return_iplist = nodupes_iplist;
-         *return_count = nodupes_count;
-  }
-  /* Save in name cache */
-  for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
-    DEBUG(100, ("Storing name %s of type %d (ip: %s)\n", name,
-                name_type, sys_inet_ntoa((*return_iplist)[i])));
-    
-  namecache_store(mem_ctx, name, name_type, *return_count, *return_iplist);
-
-  /* Display some debugging info */
-
-  DEBUG(10, ("internal_resolve_name: returning %d addresses: ", 
-            *return_count));
-
-  for (i = 0; i < *return_count; i++)
-         DEBUGADD(10, ("%s ", sys_inet_ntoa((*return_iplist)[i])));
-
-  DEBUG(10, ("\n"));
-
-  return result;
-}
-
-/********************************************************
- Internal interface to resolve a name into one IP address.
- Use this function if the string is either an IP address, DNS
- or host name or NetBIOS name. This uses the name switch in the
- smb.conf to determine the order of name resolution.
-*********************************************************/
-BOOL resolve_name(TALLOC_CTX *mem_ctx, const char *name, struct ipv4_addr *return_ip, int name_type)
-{
-       struct ipv4_addr *ip_list = NULL;
-       int count = 0;
-
-       if (is_ipaddress(name)) {
-               *return_ip = interpret_addr2(name);
-               return True;
-       }
-
-       if (internal_resolve_name(mem_ctx, name, name_type, &ip_list, &count)) {
-               int i;
-               /* only return valid addresses for TCP connections */
-               for (i=0; i<count; i++) {
-                       const char *ip_str = sys_inet_ntoa(ip_list[i]);
-                       if (ip_str &&
-                           strcmp(ip_str, "255.255.255.255") != 0 &&
-                           strcmp(ip_str, "0.0.0.0") != 0) {
-                               *return_ip = ip_list[i];
-                               SAFE_FREE(ip_list);
-                               return True;
-                       }
-               }
-       }
-       SAFE_FREE(ip_list);
-       return False;
-}
-
-/********************************************************
- Find the IP address of the master browser or DMB for a workgroup.
-*********************************************************/
-
-BOOL find_master_ip(TALLOC_CTX *mem_ctx, const char *group, struct ipv4_addr *master_ip)
-{
-       struct ipv4_addr *ip_list = NULL;
-       int count = 0;
-
-       if (lp_disable_netbios()) {
-               DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
-               return False;
-       }
-
-       if (internal_resolve_name(mem_ctx, group, 0x1D, &ip_list, &count)) {
-               *master_ip = ip_list[0];
-               SAFE_FREE(ip_list);
-               return True;
-       }
-       if(internal_resolve_name(mem_ctx, group, 0x1B, &ip_list, &count)) {
-               *master_ip = ip_list[0];
-               SAFE_FREE(ip_list);
-               return True;
-       }
-
-       SAFE_FREE(ip_list);
-       return False;
-}
-
-/********************************************************
- Lookup a DC name given a Domain name and IP address.
-*********************************************************/
-
-BOOL lookup_dc_name(const char *srcname, const char *domain, 
-                   struct ipv4_addr *dc_ip, char *ret_name)
-{
-#if !defined(I_HATE_WINDOWS_REPLY_CODE)        
-       fstring dc_name;
-       BOOL ret;
-
-       if (lp_disable_netbios()) {
-               DEBUG(5,("lookup_dc_name(%s): netbios is disabled\n", domain));
-               return False;
-       }
-       
-       /*
-        * Due to the fact win WinNT *sucks* we must do a node status
-        * query here... JRA.
-        */
-       
-       *dc_name = '\0';
-       
-       ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name);
-
-       if(ret && *dc_name) {
-               fstrcpy(ret_name, dc_name);
-               return True;
-       }
-       
-       return False;
-
-#else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
-
-JRA - This code is broken with BDC rollover - we need to do a full
-NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
-
-       int retries = 3;
-       int retry_time = 2000;
-       struct timeval tval;
-       struct packet_struct p;
-       struct dgram_packet *dgram = &p.packet.dgram;
-       char *ptr,*p2;
-       char tmp[4];
-       int len;
-       struct sockaddr_in sock_name;
-       int sock_len = sizeof(sock_name);
-       const char *mailslot = NET_LOGON_MAILSLOT;
-       char *mailslot_name;
-       char buffer[1024];
-       char *bufp;
-       int dgm_id = generate_trn_id();
-       int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
-       
-       if(sock == -1)
-               return False;
-       
-       /* Find out the transient UDP port we have been allocated. */
-       if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
-               DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
-                        strerror(errno)));
-               close(sock);
-               return False;
-       }
-
-       /*
-        * Create the request data.
-        */
-
-       memset(buffer,'\0',sizeof(buffer));
-       bufp = buffer;
-       SSVAL(bufp,0,QUERYFORPDC);
-       bufp += 2;
-       fstrcpy(bufp,srcname);
-       bufp += (strlen(bufp) + 1);
-       slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
-       mailslot_name = bufp;
-       bufp += (strlen(bufp) + 1);
-       bufp = ALIGN2(bufp, buffer);
-       bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE);        
-       
-       SIVAL(bufp,0,1);
-       SSVAL(bufp,4,0xFFFF); 
-       SSVAL(bufp,6,0xFFFF); 
-       bufp += 8;
-       len = PTR_DIFF(bufp,buffer);
-
-       memset((char *)&p,'\0',sizeof(p));
-
-       /* DIRECT GROUP or UNIQUE datagram. */
-       dgram->header.msg_type = 0x10;
-       dgram->header.flags.node_type = M_NODE;
-       dgram->header.flags.first = True;
-       dgram->header.flags.more = False;
-       dgram->header.dgm_id = dgm_id;
-       dgram->header.source_ip = *iface_ip(*pdc_ip);
-       dgram->header.source_port = ntohs(sock_name.sin_port);
-       dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
-       dgram->header.packet_offset = 0;
-       
-       make_nmb_name(&dgram->source_name,srcname,0);
-       make_nmb_name(&dgram->dest_name,domain,0x1C);
-       
-       ptr = &dgram->data[0];
-       
-       /* Setup the smb part. */
-       ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
-       memcpy(tmp,ptr,4);
-       set_message(ptr,17,17 + len,True);
-       memcpy(ptr,tmp,4);
-
-       CVAL(ptr,smb_com) = SMBtrans;
-       SSVAL(ptr,smb_vwv1,len);
-       SSVAL(ptr,smb_vwv11,len);
-       SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
-       SSVAL(ptr,smb_vwv13,3);
-       SSVAL(ptr,smb_vwv14,1);
-       SSVAL(ptr,smb_vwv15,1);
-       SSVAL(ptr,smb_vwv16,2);
-       p2 = smb_buf(ptr);
-       pstrcpy(p2,mailslot);
-       p2 = skip_string(p2,1);
-       
-       memcpy(p2,buffer,len);
-       p2 += len;
-       
-       dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
-       
-       p.ip = *pdc_ip;
-       p.port = DGRAM_PORT;
-       p.fd = sock;
-       p.timestamp = time(NULL);
-       p.packet_type = DGRAM_PACKET;
-       
-       GetTimeOfDay(&tval);
-       
-       if (!send_packet(&p)) {
-               DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
-               close(sock);
-               return False;
-       }
-       
-       retries--;
-       
-       while (1) {
-               struct timeval tval2;
-               struct packet_struct *p_ret;
-               
-               GetTimeOfDay(&tval2);
-               if (TvalDiff(&tval,&tval2) > retry_time) {
-                       if (!retries)
-                               break;
-                       if (!send_packet(&p)) {
-                               DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
-                               close(sock);
-                               return False;
-                       }
-                       GetTimeOfDay(&tval);
-                       retries--;
-               }
-
-               if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
-                       struct dgram_packet *dgram2 = &p_ret->packet.dgram;
-                       char *buf;
-                       char *buf2;
-
-                       buf = &dgram2->data[0];
-                       buf -= 4;
-
-                       if (CVAL(buf,smb_com) != SMBtrans) {
-                               DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (uint_t)
-                                        CVAL(buf,smb_com), (uint_t)SMBtrans ));
-                               free_packet(p_ret);
-                               continue;
-                       }
-                       
-                       len = SVAL(buf,smb_vwv11);
-                       buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
-                       
-                       if (len <= 0) {
-                               DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
-                               free_packet(p_ret);
-                               continue;
-                       }
-
-                       DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
-                                nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
-                                sys_inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
-
-                       if(SVAL(buf2,0) != QUERYFORPDC_R) {
-                               DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
-                                        (uint_t)SVAL(buf,0), (uint_t)QUERYFORPDC_R ));
-                               free_packet(p_ret);
-                               continue;
-                       }
-
-                       buf2 += 2;
-                       /* Note this is safe as it is a bounded strcpy. */
-                       fstrcpy(ret_name, buf2);
-                       ret_name[sizeof(fstring)-1] = '\0';
-                       close(sock);
-                       free_packet(p_ret);
-                       return True;
-               }
-       }
-       
-       close(sock);
-       return False;
-#endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
-}
-
-/********************************************************
- Get the IP address list of the primary domain controller
- for a domain.
-*********************************************************/
-
-BOOL get_pdc_ip(TALLOC_CTX *mem_ctx, const char *domain, struct ipv4_addr *ip)
-{
-       struct ipv4_addr *ip_list;
-       int count;
-       int i = 0;
-
-       /* Look up #1B name */
-
-       if (!internal_resolve_name(mem_ctx, domain, 0x1b, &ip_list, &count))
-               return False;
-
-       /* if we get more than 1 IP back we have to assume it is a
-          multi-homed PDC and not a mess up */
-          
-       if ( count > 1 ) {
-               DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
-                               
-               /* look for a local net */
-               for ( i=0; i<count; i++ ) {
-                       if ( is_local_net( ip_list[i] ) )
-                               break;
-               }
-               
-               /* if we hit then end then just grab the first 
-                  one from the list */
-                  
-               if ( i == count )
-                       i = 0;
-       }
-
-       *ip = ip_list[i];
-       
-       SAFE_FREE(ip_list);
-
-       return True;
-}
-
diff --git a/source4/libcli/namequery_dc.c b/source4/libcli/namequery_dc.c
deleted file mode 100644 (file)
index 49aa42a..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* 
-   Unix SMB/CIFS implementation.
-
-   Winbind daemon connection manager
-
-   Copyright (C) Tim Potter 2001
-   Copyright (C) Andrew Bartlett 2002
-   
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-
-#include "includes.h"
-
-
index 3658f1dd777afb4be289693c400032c8f7f9a01c..a7788f791bf593de1b7ea8c7e18e6d4afba1ee5e 100644 (file)
@@ -62,6 +62,12 @@ struct nbt_name_request {
                const char *reply_addr;
                int reply_port;
        } *replies;
+
+       /* information on what to do on completion */
+       struct {
+               void (*fn)(struct nbt_name_request *);
+               void *private;
+       } async;
 };
 
 
index 23a63ede11c4a03e2265891a19b7179b388349dc..05d5e554911e22464fca38c4e59debff55b69ce0 100644 (file)
@@ -209,69 +209,3 @@ NTSTATUS nbt_name_status(struct nbt_name_socket *nbtsock,
 }
 
 
-/*
-  some test functions - will be removed when nbt is hooked in everywhere
-*/
-void test_name_status(const char *name, const char *addr)
-{
-       struct nbt_name_status io;
-       NTSTATUS status;
-       TALLOC_CTX *tmp_ctx = talloc_new(NULL);
-       struct nbt_name_socket *nbtsock;
-       int i;
-
-       nbtsock = nbt_name_socket_init(tmp_ctx, NULL);
-       
-       io.in.name.name = name;
-       io.in.name.scope = NULL;
-       io.in.name.type = NBT_NAME_CLIENT;
-       io.in.dest_addr = addr;
-       io.in.timeout = 5;
-
-       status = nbt_name_status(nbtsock, tmp_ctx, &io);
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("status failed for %s - %s\n", name, nt_errstr(status));
-               talloc_free(tmp_ctx);   
-               exit(1);
-               return;
-       }
-
-       printf("Received %d names for %s\n", io.out.status.num_names, io.out.name.name);
-       for (i=0;i<io.out.status.num_names;i++) {
-               printf("\t%s#%02x  0x%04x\n",
-                      io.out.status.names[i].name,
-                      io.out.status.names[i].type,
-                      io.out.status.names[i].nb_flags);
-       }
-       talloc_free(tmp_ctx);   
-}
-
-
-void test_name_query(const char *name)
-{
-       struct nbt_name_query io;
-       NTSTATUS status;
-       TALLOC_CTX *tmp_ctx = talloc_new(NULL);
-       struct nbt_name_socket *nbtsock;
-
-       nbtsock = nbt_name_socket_init(tmp_ctx, NULL);
-       
-       io.in.name.name = name;
-       io.in.name.scope = NULL;
-       io.in.name.type = NBT_NAME_SERVER;
-       io.in.dest_addr = "255.255.255.255";
-       io.in.broadcast = True;
-       io.in.wins_lookup = False;
-       io.in.timeout = 5;
-
-       status = nbt_name_query(nbtsock, tmp_ctx, &io);
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("query failed for %s - %s\n", name, nt_errstr(status));
-       } else {
-               printf("response %s is at %s\n", io.out.name.name, io.out.reply_addr);
-               test_name_status("*", io.out.reply_addr);
-       }
-
-       talloc_free(tmp_ctx);   
-}
-
index c2da1a0ab4fbf5544bc56be91122213ac1edcc43..8c46379f0b8abba832b208cd7435f26860a27c60 100644 (file)
@@ -283,3 +283,57 @@ NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, struct nbt_name
 
        return NT_STATUS_OK;
 }
+
+
+/*
+  copy a nbt name structure
+*/
+NTSTATUS nbt_name_dup(TALLOC_CTX *mem_ctx, struct nbt_name *name, struct nbt_name *newname)
+{
+       *newname = *name;
+       newname->name = talloc_strdup(mem_ctx, newname->name);
+       NT_STATUS_HAVE_NO_MEMORY(newname->name);
+       newname->scope = talloc_strdup(mem_ctx, newname->scope);
+       if (name->scope) {
+               NT_STATUS_HAVE_NO_MEMORY(newname->scope);
+       }
+       return NT_STATUS_OK;
+}
+
+/*
+  push a nbt name into a blob
+*/
+NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct nbt_name *name)
+{
+       return ndr_push_struct_blob(blob, mem_ctx, name, 
+                                   (ndr_push_flags_fn_t)ndr_push_nbt_name);
+}
+
+/*
+  choose a name to use when calling a server in a NBT session request.
+  we use heuristics to see if the name we have been given is a IP
+  address, or a too-long name. If it is then use *SMBSERVER, or a
+  truncated name
+*/
+void nbt_choose_called_name(TALLOC_CTX *mem_ctx,
+                           struct nbt_name *n, const char *name, int type)
+{
+       n->scope = NULL;
+       n->type = type;
+
+       if (is_ipaddress(name)) {
+               n->name = "*SMBSERVER";
+               return;
+       }
+       if (strlen(name) > 15) {
+               const char *p = strchr(name, '.');
+               if (p - name > 15) {
+                       n->name = "*SMBSERVER";
+                       return;
+               }
+               n->name = talloc_strndup(mem_ctx, name, PTR_DIFF(p, name));
+               return;
+       }
+
+       n->name = talloc_strdup(mem_ctx, name);
+}
index 896ed68e9873dba5bb86359e39a3d0c58c49e26c..6d5b450a31fae43ddbb421f2efde174eeec7f983 100644 (file)
 #define NBT_MAX_PACKET_SIZE 2048
 #define NBT_MAX_REPLIES 1000
 
+/*
+  destroy a nbt socket
+*/
+static int nbtsock_destructor(void *ptr)
+{
+       struct nbt_name_socket *nbtsock = talloc_get_type(ptr, struct nbt_name_socket);
+       event_remove_fd(nbtsock->event_ctx, nbtsock->fde);
+       return 0;
+}
+
 /*
   destroy a pending request
 */
@@ -111,6 +121,9 @@ failed:
        nbt_name_request_destructor(req);
        req->status = status;
        req->state = NBT_REQUEST_ERROR;
+       if (req->async.fn) {
+               req->async.fn(req);
+       }
        talloc_free(tmp_ctx);
        return;
 }
@@ -184,6 +197,9 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock)
                req->state = NBT_REQUEST_DONE;
                req->status = NT_STATUS_NO_MEMORY;
                talloc_free(tmp_ctx);
+               if (req->async.fn) {
+                       req->async.fn(req);
+               }
                return;
        }
 
@@ -192,15 +208,18 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock)
        req->replies[req->num_replies].packet = talloc_steal(req, packet);
        req->num_replies++;
 
+       talloc_free(tmp_ctx);
+
        /* if we don't want multiple replies then we are done */
        if (!req->allow_multiple_replies ||
            req->num_replies == NBT_MAX_REPLIES) {
                nbt_name_request_destructor(req);
                req->state = NBT_REQUEST_DONE;
                req->status = NT_STATUS_OK;
+               if (req->async.fn) {
+                       req->async.fn(req);
+               }
        }
-
-       talloc_free(tmp_ctx);
 }
 
 /*
@@ -257,6 +276,8 @@ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx,
        fde.private = nbtsock;
        nbtsock->fde = event_add_fd(nbtsock->event_ctx, &fde);
 
+       talloc_set_destructor(nbtsock, nbtsock_destructor);
+       
        return nbtsock;
 
 failed:
@@ -273,8 +294,16 @@ static void nbt_name_socket_timeout(struct event_context *ev, struct timed_event
        struct nbt_name_request *req = talloc_get_type(te->private, 
                                                       struct nbt_name_request);
        nbt_name_request_destructor(req);
-       req->state = NBT_REQUEST_TIMEOUT;
-       req->status = NT_STATUS_IO_TIMEOUT;
+       if (req->num_replies == 0) {
+               req->state = NBT_REQUEST_TIMEOUT;
+               req->status = NT_STATUS_IO_TIMEOUT;
+       } else {
+               req->state = NBT_REQUEST_DONE;
+               req->status = NT_STATUS_OK;
+       }
+       if (req->async.fn) {
+               req->async.fn(req);
+       }
 }
 
 /*
@@ -300,14 +329,20 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock,
        req->allow_multiple_replies = allow_multiple_replies;
        req->state = NBT_REQUEST_SEND;
 
+       /* we select a random transaction id unless the user supplied one */
        if (req->request->name_trn_id == 0) {
                req->request->name_trn_id = random() % UINT16_MAX;
        }
 
+       /* choose the next available transaction id >= the one asked for.
+          The strange 2nd call is to try to make the ids less guessable
+          and less likely to collide. It's not possible to make NBT secure 
+          to ID guessing, but this at least makes accidential collisions
+          less likely */
        id = idr_get_new_above(req->nbtsock->idr, req, 
                               req->request->name_trn_id, UINT16_MAX);
        if (id == -1) {
-               id = idr_get_new_above(req->nbtsock->idr, req, 1+(random()%10000),
+               id = idr_get_new_above(req->nbtsock->idr, req, 1+(random()%(UINT16_MAX/2)),
                                       UINT16_MAX);
        }
        if (id == -1) goto failed;
@@ -341,6 +376,9 @@ NTSTATUS nbt_name_request_recv(struct nbt_name_request *req)
                if (event_loop_once(req->nbtsock->event_ctx) != 0) {
                        req->state = NBT_REQUEST_ERROR;
                        req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
+                       if (req->async.fn) {
+                               req->async.fn(req);
+                       }
                }
        }
        return req->status;
diff --git a/source4/libcli/nmblib.c b/source4/libcli/nmblib.c
deleted file mode 100644 (file)
index 0a3f72b..0000000
+++ /dev/null
@@ -1,1316 +0,0 @@
-/* 
-   Unix SMB/CIFS implementation.
-   NBT netbios library routines
-   Copyright (C) Andrew Tridgell 1994-1998
-   
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-   
-*/
-
-#include "includes.h"
-#include "system/network.h"
-#include "system/time.h"
-#include "system/iconv.h"
-
-static const struct opcode_names {
-       const char *nmb_opcode_name;
-       int opcode;
-} nmb_header_opcode_names[] = {
-       {"Query",           0 },
-       {"Registration",      5 },
-       {"Release",           6 },
-       {"WACK",              7 },
-       {"Refresh",           8 },
-       {"Refresh(altcode)",  9 },
-       {"Multi-homed Registration", 15 },
-       {0, -1 }
-};
-
-/****************************************************************************
- * Lookup a nmb opcode name.
- ****************************************************************************/
-static const char *lookup_opcode_name( int opcode )
-{
-  const struct opcode_names *op_namep;
-  int i;
-
-  for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
-    op_namep = &nmb_header_opcode_names[i];
-    if(opcode == op_namep->opcode)
-      return op_namep->nmb_opcode_name;
-  }
-  return "<unknown opcode>";
-}
-
-/****************************************************************************
-  print out a res_rec structure
-  ****************************************************************************/
-static void debug_nmb_res_rec(struct res_rec *res, const char *hdr)
-{
-  int i, j;
-
-  DEBUGADD( 4, ( "    %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
-                 hdr,
-                 nmb_namestr(&res->rr_name),
-                 res->rr_type,
-                 res->rr_class,
-                 res->ttl ) );
-
-  if( res->rdlength == 0 || res->rdata == NULL )
-    return;
-
-  for (i = 0; i < res->rdlength; i+= 16)
-    {
-      DEBUGADD(4, ("    %s %3x char ", hdr, i));
-
-      for (j = 0; j < 16; j++)
-       {
-         uint8_t x = res->rdata[i+j];
-         if (x < 32 || x > 127) x = '.';
-         
-         if (i+j >= res->rdlength) break;
-         DEBUGADD(4, ("%c", x));
-       }
-      
-      DEBUGADD(4, ("   hex "));
-
-      for (j = 0; j < 16; j++)
-       {
-         if (i+j >= res->rdlength) break;
-         DEBUGADD(4, ("%02X", (uint8_t)res->rdata[i+j]));
-       }
-      
-      DEBUGADD(4, ("\n"));
-    }
-}
-
-/****************************************************************************
-  process a nmb packet
-  ****************************************************************************/
-void debug_nmb_packet(struct packet_struct *p)
-{
-  struct nmb_packet *nmb = &p->packet.nmb;
-
-  if (DEBUGLVL(4)) {
-         DEBUG(4, ("nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n",
-                   sys_inet_ntoa(p->ip), p->port,
-                   nmb->header.name_trn_id,
-                   lookup_opcode_name(nmb->header.opcode),
-                   nmb->header.opcode,
-                   BOOLSTR(nmb->header.response)));
-         DEBUG(4, ("    header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n",
-                   BOOLSTR(nmb->header.nm_flags.bcast),
-                   BOOLSTR(nmb->header.nm_flags.recursion_available),
-                   BOOLSTR(nmb->header.nm_flags.recursion_desired),
-                   BOOLSTR(nmb->header.nm_flags.trunc),
-                   BOOLSTR(nmb->header.nm_flags.authoritative)));
-         DEBUG(4, ("    header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n",
-                   nmb->header.rcode,
-                   nmb->header.qdcount,
-                   nmb->header.ancount,
-                   nmb->header.nscount,
-                   nmb->header.arcount));
-    }
-
-  if (nmb->header.qdcount)
-    {
-      DEBUGADD( 4, ( "    question: q_name=%s q_type=%d q_class=%d\n",
-                     nmb_namestr(&nmb->question.question_name),
-                     nmb->question.question_type,
-                     nmb->question.question_class) );
-    }
-
-  if (nmb->answers && nmb->header.ancount)
-    {
-      debug_nmb_res_rec(nmb->answers,"answers");
-    }
-  if (nmb->nsrecs && nmb->header.nscount)
-    {
-      debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
-    }
-  if (nmb->additional && nmb->header.arcount)
-    {
-      debug_nmb_res_rec(nmb->additional,"additional");
-    }
-}
-
-/*******************************************************************
-  handle "compressed" name pointers
-  ******************************************************************/
-static BOOL handle_name_ptrs(uint8_t *ubuf,int *offset,int length,
-                            BOOL *got_pointer,int *ret)
-{
-  int loop_count=0;
-  
-  while ((ubuf[*offset] & 0xC0) == 0xC0) {
-    if (!*got_pointer) (*ret) += 2;
-    (*got_pointer)=True;
-    (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
-    if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
-      return(False);
-    }
-  }
-  return(True);
-}
-
-/*******************************************************************
-  parse a nmb name from "compressed" format to something readable
-  return the space taken by the name, or 0 if the name is invalid
-  ******************************************************************/
-static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
-{
-  int m,n=0;
-  uint8_t *ubuf = (uint8_t *)inbuf;
-  int ret = 0;
-  BOOL got_pointer=False;
-  int loop_count=0;
-  int offset = ofs;
-
-  if (length - offset < 2)
-    return(0);  
-
-  /* handle initial name pointers */
-  if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
-    return(0);
-  
-  m = ubuf[offset];
-
-  if (!m)
-    return(0);
-  if ((m & 0xC0) || offset+m+2 > length)
-    return(0);
-
-  memset((char *)name,'\0',sizeof(*name));
-
-  /* the "compressed" part */
-  if (!got_pointer)
-    ret += m + 2;
-  offset++;
-  while (m > 0) {
-    uint8_t c1,c2;
-    c1 = ubuf[offset++]-'A';
-    c2 = ubuf[offset++]-'A';
-    if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
-      return(0);
-    name->name[n++] = (c1<<4) | c2;
-    m -= 2;
-  }
-  name->name[n] = 0;
-
-  if (n==16) {
-    /* parse out the name type, 
-       its always in the 16th byte of the name */
-    name->name_type = ((uint8_t)name->name[15]) & 0xff;
-  
-    /* remove trailing spaces */
-    name->name[15] = 0;
-    n = 14;
-    while (n && name->name[n]==' ')
-      name->name[n--] = 0;  
-  }
-
-  /* now the domain parts (if any) */
-  n = 0;
-  while (ubuf[offset]) {
-    /* we can have pointers within the domain part as well */
-    if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
-      return(0);
-
-    m = ubuf[offset];
-    /*
-     * Don't allow null domain parts.
-     */
-    if (!m)
-      return(0);
-    if (!got_pointer)
-      ret += m+1;
-    if (n)
-      name->scope[n++] = '.';
-    if (m+2+offset>length || n+m+1>sizeof(name->scope))
-      return(0);
-    offset++;
-    while (m--)
-      name->scope[n++] = (char)ubuf[offset++];
-
-    /*
-     * Watch for malicious loops.
-     */
-    if (loop_count++ == 10)
-      return 0;
-  }
-  name->scope[n++] = 0;  
-
-  return(ret);
-}
-
-
-/*******************************************************************
-  put a compressed nmb name into a buffer. return the length of the
-  compressed name
-
-  compressed names are really weird. The "compression" doubles the
-  size. The idea is that it also means that compressed names conform
-  to the doman name system. See RFC1002.
-  ******************************************************************/
-static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
-{
-  int ret,m;
-  fstring buf1;
-  char *p;
-
-  if (strcmp(name->name,"*") == 0) {
-    /* special case for wildcard name */
-    memset(buf1,'\0',20);
-    buf1[0] = '*';
-    buf1[15] = name->name_type;
-  } else {
-    slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type);
-  }
-
-  buf[offset] = 0x20;
-
-  ret = 34;
-
-  for (m=0;m<16;m++) {
-    buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
-    buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
-  }
-  offset += 33;
-
-  buf[offset] = 0;
-
-  if (name->scope[0]) {
-    /* XXXX this scope handling needs testing */
-    ret += strlen(name->scope) + 1;
-    pstrcpy(&buf[offset+1],name->scope);  
-  
-    p = &buf[offset+1];
-    while ((p = strchr_m(p,'.'))) {
-      buf[offset] = PTR_DIFF(p,&buf[offset+1]);
-      offset += (buf[offset] + 1);
-      p = &buf[offset+1];
-    }
-    buf[offset] = strlen(&buf[offset+1]);
-  }
-
-  return(ret);
-}
-
-/*******************************************************************
-  useful for debugging messages
-  ******************************************************************/
-char *nmb_namestr(struct nmb_name *n)
-{
-  static int i=0;
-  static fstring ret[4];
-  char *p = ret[i];
-
-  if (!n->scope[0])
-    slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type);
-  else
-    slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
-
-  i = (i+1)%4;
-  return(p);
-}
-
-/*******************************************************************
-  allocate and parse some resource records
-  ******************************************************************/
-static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
-                               struct res_rec **recs, int count)
-{
-  int i;
-  *recs = malloc_array_p(struct res_rec, count);
-  if (!*recs) return(False);
-
-  memset((char *)*recs,'\0',sizeof(**recs)*count);
-
-  for (i=0;i<count;i++) {
-    int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
-    (*offset) += l;
-    if (!l || (*offset)+10 > length) {
-      SAFE_FREE(*recs);
-      return(False);
-    }
-    (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
-    (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
-    (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
-    (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
-    (*offset) += 10;
-    if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || 
-       (*offset)+(*recs)[i].rdlength > length) {
-      SAFE_FREE(*recs);
-      return(False);
-    }
-    memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
-    (*offset) += (*recs)[i].rdlength;    
-  }
-  return(True);
-}
-
-/*******************************************************************
-  put a resource record into a packet
-  ******************************************************************/
-static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
-{
-  int ret=0;
-  int i;
-
-  for (i=0;i<count;i++) {
-    int l = put_nmb_name(buf,offset,&recs[i].rr_name);
-    offset += l;
-    ret += l;
-    RSSVAL(buf,offset,recs[i].rr_type);
-    RSSVAL(buf,offset+2,recs[i].rr_class);
-    RSIVAL(buf,offset+4,recs[i].ttl);
-    RSSVAL(buf,offset+8,recs[i].rdlength);
-    memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
-    offset += 10+recs[i].rdlength;
-    ret += 10+recs[i].rdlength;
-  }
-
-  return(ret);
-}
-
-/*******************************************************************
-  put a compressed name pointer record into a packet
-  ******************************************************************/
-static int put_compressed_name_ptr(uint8_t *buf,int offset,struct res_rec *rec,int ptr_offset)
-{  
-  int ret=0;
-  buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
-  buf[offset+1] = (ptr_offset & 0xFF);
-  offset += 2;
-  ret += 2;
-  RSSVAL(buf,offset,rec->rr_type);
-  RSSVAL(buf,offset+2,rec->rr_class);
-  RSIVAL(buf,offset+4,rec->ttl);
-  RSSVAL(buf,offset+8,rec->rdlength);
-  memcpy(buf+offset+10,rec->rdata,rec->rdlength);
-  offset += 10+rec->rdlength;
-  ret += 10+rec->rdlength;
-    
-  return(ret);
-}
-
-/*******************************************************************
-  parse a dgram packet. Return False if the packet can't be parsed 
-  or is invalid for some reason, True otherwise 
-
-  this is documented in section 4.4.1 of RFC1002
-  ******************************************************************/
-static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
-{
-  int offset;
-  int flags;
-
-  memset((char *)dgram,'\0',sizeof(*dgram));
-
-  if (length < 14) return(False);
-
-  dgram->header.msg_type = CVAL(inbuf,0);
-  flags = CVAL(inbuf,1);
-  dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
-  if (flags & 1) dgram->header.flags.more = True;
-  if (flags & 2) dgram->header.flags.first = True;
-  dgram->header.dgm_id = RSVAL(inbuf,2);
-  putip((char *)&dgram->header.source_ip,inbuf+4);
-  dgram->header.source_port = RSVAL(inbuf,8);
-  dgram->header.dgm_length = RSVAL(inbuf,10);
-  dgram->header.packet_offset = RSVAL(inbuf,12);
-
-  offset = 14;
-
-  if (dgram->header.msg_type == 0x10 ||
-      dgram->header.msg_type == 0x11 ||
-      dgram->header.msg_type == 0x12) {      
-    offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
-    offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
-  }
-
-  if (offset >= length || (length-offset > sizeof(dgram->data))) 
-    return(False);
-
-  dgram->datasize = length-offset;
-  memcpy(dgram->data,inbuf+offset,dgram->datasize);
-
-  return(True);
-}
-
-
-/*******************************************************************
-  parse a nmb packet. Return False if the packet can't be parsed 
-  or is invalid for some reason, True otherwise 
-  ******************************************************************/
-static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
-{
-  int nm_flags,offset;
-
-  memset((char *)nmb,'\0',sizeof(*nmb));
-
-  if (length < 12) return(False);
-
-  /* parse the header */
-  nmb->header.name_trn_id = RSVAL(inbuf,0);
-
-  DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
-
-  nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
-  nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
-  nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
-  nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
-  nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
-  nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
-  nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
-  nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;  
-  nmb->header.rcode = CVAL(inbuf,3) & 0xF;
-  nmb->header.qdcount = RSVAL(inbuf,4);
-  nmb->header.ancount = RSVAL(inbuf,6);
-  nmb->header.nscount = RSVAL(inbuf,8);
-  nmb->header.arcount = RSVAL(inbuf,10);
-  
-  if (nmb->header.qdcount) {
-    offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
-    if (!offset) return(False);
-
-    if (length - (12+offset) < 4) return(False);
-    nmb->question.question_type = RSVAL(inbuf,12+offset);
-    nmb->question.question_class = RSVAL(inbuf,12+offset+2);
-
-    offset += 12+4;
-  } else {
-    offset = 12;
-  }
-
-  /* and any resource records */
-  if (nmb->header.ancount && 
-      !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
-                          nmb->header.ancount))
-    return(False);
-
-  if (nmb->header.nscount && 
-      !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
-                          nmb->header.nscount))
-    return(False);
-  
-  if (nmb->header.arcount && 
-      !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
-                          nmb->header.arcount))
-    return(False);
-
-  return(True);
-}
-
-/*******************************************************************
-  'Copy constructor' for an nmb packet
-  ******************************************************************/
-static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
-{  
-  struct nmb_packet *nmb;
-  struct nmb_packet *copy_nmb;
-  struct packet_struct *pkt_copy;
-
-  if(( pkt_copy = malloc_p(struct packet_struct)) == NULL)
-  {
-    DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
-    return NULL;
-  }
-
-  /* Structure copy of entire thing. */
-
-  *pkt_copy = *packet;
-
-  /* Ensure this copy is not locked. */
-  pkt_copy->locked = False;
-
-  /* Ensure this copy has no resource records. */
-  nmb = &packet->packet.nmb;
-  copy_nmb = &pkt_copy->packet.nmb;
-
-  copy_nmb->answers = NULL;
-  copy_nmb->nsrecs = NULL;
-  copy_nmb->additional = NULL;
-
-  /* Now copy any resource records. */
-
-  if (nmb->answers)
-  {
-    if((copy_nmb->answers = malloc_array_p(struct res_rec, nmb->header.ancount)) == NULL)
-      goto free_and_exit;
-    memcpy((char *)copy_nmb->answers, (char *)nmb->answers, 
-           nmb->header.ancount * sizeof(struct res_rec));
-  }
-  if (nmb->nsrecs)
-  {
-    if((copy_nmb->nsrecs = malloc_array_p(struct res_rec, nmb->header.nscount)) == NULL)
-      goto free_and_exit;
-    memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, 
-           nmb->header.nscount * sizeof(struct res_rec));
-  }
-  if (nmb->additional)
-  {
-    if((copy_nmb->additional = malloc_array_p(struct res_rec, nmb->header.arcount)) == NULL)
-      goto free_and_exit;
-    memcpy((char *)copy_nmb->additional, (char *)nmb->additional, 
-           nmb->header.arcount * sizeof(struct res_rec));
-  }
-
-  return pkt_copy;
-
-free_and_exit:
-
-  SAFE_FREE(copy_nmb->answers);
-  SAFE_FREE(copy_nmb->nsrecs);
-  SAFE_FREE(copy_nmb->additional);
-  SAFE_FREE(pkt_copy);
-
-  DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
-  return NULL;
-}
-
-/*******************************************************************
-  'Copy constructor' for a dgram packet
-  ******************************************************************/
-static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
-{ 
-  struct packet_struct *pkt_copy;
-
-  if(( pkt_copy = malloc_p(struct packet_struct)) == NULL)
-  {
-    DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
-    return NULL;
-  }
-
-  /* Structure copy of entire thing. */
-
-  *pkt_copy = *packet;
-
-  /* Ensure this copy is not locked. */
-  pkt_copy->locked = False;
-
-  /* There are no additional pointers in a dgram packet,
-     we are finished. */
-  return pkt_copy;
-}
-
-/*******************************************************************
-  'Copy constructor' for a generic packet
-  ******************************************************************/
-struct packet_struct *copy_packet(struct packet_struct *packet)
-{  
-  if(packet->packet_type == NMB_PACKET)
-    return copy_nmb_packet(packet);
-  else if (packet->packet_type == DGRAM_PACKET)
-    return copy_dgram_packet(packet);
-  return NULL;
-}
-/*******************************************************************
-  free up any resources associated with an nmb packet
-  ******************************************************************/
-static void free_nmb_packet(struct nmb_packet *nmb)
-{  
-  SAFE_FREE(nmb->answers);
-  SAFE_FREE(nmb->nsrecs);
-  SAFE_FREE(nmb->additional);
-}
-
-/*******************************************************************
-  free up any resources associated with a dgram packet
-  ******************************************************************/
-static void free_dgram_packet(struct dgram_packet *nmb)
-{  
-  /* We have nothing to do for a dgram packet. */
-}
-
-/*******************************************************************
-  free up any resources associated with a packet
-  ******************************************************************/
-void free_packet(struct packet_struct *packet)
-{  
-       if (packet->locked) 
-               return;
-       if (packet->packet_type == NMB_PACKET)
-               free_nmb_packet(&packet->packet.nmb);
-       else if (packet->packet_type == DGRAM_PACKET)
-               free_dgram_packet(&packet->packet.dgram);
-       ZERO_STRUCTPN(packet);
-       SAFE_FREE(packet);
-}
-
-/*******************************************************************
-parse a packet buffer into a packet structure
-  ******************************************************************/
-struct packet_struct *parse_packet(char *buf,int length,
-                                  enum packet_type packet_type)
-{
-       struct packet_struct *p;
-       BOOL ok=False;
-
-       p = malloc_p(struct packet_struct);
-       if (!p) return(NULL);
-
-       p->next = NULL;
-       p->prev = NULL;
-       p->locked = False;
-       p->timestamp = time(NULL);
-       p->packet_type = packet_type;
-
-       switch (packet_type) {
-       case NMB_PACKET:
-               ok = parse_nmb(buf,length,&p->packet.nmb);
-               break;
-               
-       case DGRAM_PACKET:
-               ok = parse_dgram(buf,length,&p->packet.dgram);
-               break;
-       }
-
-       if (!ok) {
-               free_packet(p);
-               return NULL;
-       }
-
-       return p;
-}
-
-/*******************************************************************
-  read a packet from a socket and parse it, returning a packet ready
-  to be used or put on the queue. This assumes a UDP socket
-  ******************************************************************/
-struct packet_struct *read_packet(int fd,enum packet_type packet_type)
-{
-       struct packet_struct *packet;
-       char buf[MAX_DGRAM_SIZE];
-       int length;
-       struct ipv4_addr addr;
-       int port;
-       
-       length = read_udp_socket(fd, buf, sizeof(buf), &addr, &port);
-       if (length < MIN_DGRAM_SIZE) return(NULL);
-       
-       packet = parse_packet(buf, length, packet_type);
-       if (!packet) return NULL;
-
-       packet->fd = fd;
-       packet->ip = addr;
-       packet->port = port;
-       
-       DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
-                length, sys_inet_ntoa(packet->ip), packet->port));
-       
-       return packet;
-}
-                                        
-
-/*******************************************************************
-  send a udp packet on a already open socket
-  ******************************************************************/
-static BOOL send_udp(int fd,char *buf,int len,struct ipv4_addr ip,int port)
-{
-  BOOL ret = False;
-  int i;
-  struct sockaddr_in sock_out;
-
-  /* set the address and port */
-  memset((char *)&sock_out,'\0',sizeof(sock_out));
-  putip((char *)&sock_out.sin_addr,(char *)&ip);
-  sock_out.sin_port = htons( port );
-  sock_out.sin_family = AF_INET;
-  
-  DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
-             len, sys_inet_ntoa(ip), port ) );
-
-  /*
-   * Patch to fix asynch error notifications from Linux kernel.
-   */
-       
-  for (i = 0; i < 5; i++) {
-    ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0);
-    if (ret || errno != ECONNREFUSED)
-      break;
-  }
-
-  if (!ret)
-    DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
-            sys_inet_ntoa(ip),port,strerror(errno)));
-
-  return(ret);
-}
-
-/*******************************************************************
-  build a dgram packet ready for sending
-
-  XXXX This currently doesn't handle packets too big for one
-  datagram. It should split them and use the packet_offset, more and
-  first flags to handle the fragmentation. Yuck.
-
-    [...but it isn't clear that we would ever need to send a
-    a fragmented NBT Datagram.  The IP layer does its own
-    fragmentation to ensure that messages can fit into the path
-    MTU.  It *is* important to be able to receive and rebuild
-    fragmented NBT datagrams, just in case someone out there
-    really has implemented this 'feature'.  crh -)------ ]
-
-  ******************************************************************/
-static int build_dgram(char *buf,struct packet_struct *p)
-{
-  struct dgram_packet *dgram = &p->packet.dgram;
-  uint8_t *ubuf = (uint8_t *)buf;
-  int offset=0;
-
-  /* put in the header */
-  ubuf[0] = dgram->header.msg_type;
-  ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
-  if (dgram->header.flags.more) ubuf[1] |= 1;
-  if (dgram->header.flags.first) ubuf[1] |= 2;
-  RSSVAL(ubuf,2,dgram->header.dgm_id);
-  putip(ubuf+4,(char *)&dgram->header.source_ip);
-  RSSVAL(ubuf,8,dgram->header.source_port);
-  RSSVAL(ubuf,12,dgram->header.packet_offset);
-
-  offset = 14;
-
-  if (dgram->header.msg_type == 0x10 ||
-      dgram->header.msg_type == 0x11 ||
-      dgram->header.msg_type == 0x12) {      
-    offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
-    offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
-  }
-
-  memcpy(ubuf+offset,dgram->data,dgram->datasize);
-  offset += dgram->datasize;
-
-  /* automatically set the dgm_length
-   * NOTE: RFC1002 says the dgm_length does *not*
-   *       include the fourteen-byte header. crh
-   */
-  dgram->header.dgm_length = (offset - 14);
-  RSSVAL(ubuf,10,dgram->header.dgm_length); 
-
-  return(offset);
-}
-
-/*******************************************************************
- Build a nmb name
-*******************************************************************/
-
-void make_nmb_name( struct nmb_name *n, const char *name, int type)
-{
-       memset( (char *)n, '\0', sizeof(struct nmb_name) );
-       push_ascii(n->name, name, 16, STR_TERMINATE|STR_UPPER);
-       n->name_type = (uint_t)type & 0xFF;
-       StrnCpy( n->scope, lp_netbios_scope(), 63 );
-       strupper( n->scope );
-}
-
-/*******************************************************************
-  Compare two nmb names
-  ******************************************************************/
-
-BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
-{
-  return ((n1->name_type == n2->name_type) &&
-         strequal(n1->name ,n2->name ) &&
-         strequal(n1->scope,n2->scope));
-}
-
-/*******************************************************************
-  build a nmb packet ready for sending
-
-  XXXX this currently relies on not being passed something that expands
-  to a packet too big for the buffer. Eventually this should be
-  changed to set the trunc bit so the receiver can request the rest
-  via tcp (when that becomes supported)
-  ******************************************************************/
-static int build_nmb(char *buf,struct packet_struct *p)
-{
-  struct nmb_packet *nmb = &p->packet.nmb;
-  uint8_t *ubuf = (uint8_t *)buf;
-  int offset=0;
-
-  /* put in the header */
-  RSSVAL(ubuf,offset,nmb->header.name_trn_id);
-  ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
-  if (nmb->header.response) ubuf[offset+2] |= (1<<7);
-  if (nmb->header.nm_flags.authoritative && 
-      nmb->header.response) ubuf[offset+2] |= 0x4;
-  if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
-  if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
-  if (nmb->header.nm_flags.recursion_available &&
-      nmb->header.response) ubuf[offset+3] |= 0x80;
-  if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
-  ubuf[offset+3] |= (nmb->header.rcode & 0xF);
-
-  RSSVAL(ubuf,offset+4,nmb->header.qdcount);
-  RSSVAL(ubuf,offset+6,nmb->header.ancount);
-  RSSVAL(ubuf,offset+8,nmb->header.nscount);
-  RSSVAL(ubuf,offset+10,nmb->header.arcount);
-  
-  offset += 12;
-  if (nmb->header.qdcount) {
-    /* XXXX this doesn't handle a qdcount of > 1 */
-    offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
-    RSSVAL(ubuf,offset,nmb->question.question_type);
-    RSSVAL(ubuf,offset+2,nmb->question.question_class);
-    offset += 4;
-  }
-
-  if (nmb->header.ancount)
-    offset += put_res_rec((char *)ubuf,offset,nmb->answers,
-                         nmb->header.ancount);
-
-  if (nmb->header.nscount)
-    offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
-                         nmb->header.nscount);
-
-  /*
-   * The spec says we must put compressed name pointers
-   * in the following outgoing packets :
-   * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
-   * NAME_RELEASE_REQUEST.
-   */
-
-  if((nmb->header.response == False) &&
-     ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
-      (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
-      (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
-      (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
-      (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
-     (nmb->header.arcount == 1)) {
-
-    offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12);
-
-  } else if (nmb->header.arcount) {
-    offset += put_res_rec((char *)ubuf,offset,nmb->additional,
-                         nmb->header.arcount);  
-  }
-  return(offset);
-}
-
-
-/*******************************************************************
-linearise a packet
-  ******************************************************************/
-int build_packet(char *buf, struct packet_struct *p)
-{
-       int len = 0;
-
-       switch (p->packet_type) {
-       case NMB_PACKET:
-               len = build_nmb(buf,p);
-               break;
-
-       case DGRAM_PACKET:
-               len = build_dgram(buf,p);
-               break;
-       }
-
-       return len;
-}
-
-/*******************************************************************
-  send a packet_struct
-  ******************************************************************/
-BOOL send_packet(struct packet_struct *p)
-{
-  char buf[1024];
-  int len=0;
-
-  memset(buf,'\0',sizeof(buf));
-
-  len = build_packet(buf, p);
-
-  if (!len) return(False);
-
-  return(send_udp(p->fd,buf,len,p->ip,p->port));
-}
-
-/****************************************************************************
-  receive a packet with timeout on a open UDP filedescriptor
-  The timeout is in milliseconds
-  ***************************************************************************/
-struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
-{
-       fd_set fds;
-       struct timeval timeout;
-       int ret;
-
-       FD_ZERO(&fds);
-       FD_SET(fd,&fds);
-       timeout.tv_sec = t/1000;
-       timeout.tv_usec = 1000*(t%1000);
-
-       if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) {
-               /* errno should be EBADF or EINVAL. */
-               DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno));
-               return NULL;
-       }
-
-       if (ret == 0) /* timeout */
-               return NULL;
-
-       if (FD_ISSET(fd,&fds)) 
-               return(read_packet(fd,type));
-       
-       return(NULL);
-}
-
-
-/****************************************************************************
-  receive a UDP/137 packet either via UDP or from the unexpected packet
-  queue. The packet must be a reply packet and have the specified trn_id
-  The timeout is in milliseconds
-  ***************************************************************************/
-struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
-{
-       struct packet_struct *p;
-
-       p = receive_packet(fd, NMB_PACKET, t);
-
-       if (p && p->packet.nmb.header.response &&
-           p->packet.nmb.header.name_trn_id == trn_id) {
-               return p;
-       }
-       if (p) free_packet(p);
-
-       /* try the unexpected packet queue */
-       return receive_unexpected(NMB_PACKET, trn_id, NULL);
-}
-
-/****************************************************************************
-  receive a UDP/138 packet either via UDP or from the unexpected packet
-  queue. The packet must be a reply packet and have the specified mailslot name
-  The timeout is in milliseconds
-  ***************************************************************************/
-struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name)
-{
-       struct packet_struct *p;
-
-       p = receive_packet(fd, DGRAM_PACKET, t);
-
-       if (p && match_mailslot_name(p, mailslot_name)) {
-               return p;
-       }
-       if (p) free_packet(p);
-
-       /* try the unexpected packet queue */
-       return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);
-}
-
-
-/****************************************************************************
- see if a datagram has the right mailslot name
-***************************************************************************/
-BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
-{
-       struct dgram_packet *dgram = &p->packet.dgram;
-       char *buf;
-
-       buf = &dgram->data[0];
-       buf -= 4;
-
-       buf = smb_buf(buf);
-
-       if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
-               return True;
-       }
-
-       return False;
-}
-
-
-/****************************************************************************
-return the number of bits that match between two 4 character buffers
-  ***************************************************************************/
-int matching_quad_bits(uint8_t *p1, uint8_t *p2)
-{
-       int i, j, ret = 0;
-       for (i=0; i<4; i++) {
-               if (p1[i] != p2[i]) break;
-               ret += 8;
-       }
-
-       if (i==4) return ret;
-
-       for (j=0; j<8; j++) {
-               if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break;
-               ret++;
-       }       
-       
-       return ret;
-}
-
-
-static uint8_t sort_ip[4];
-
-/****************************************************************************
-compare two query reply records
-  ***************************************************************************/
-static int name_query_comp(uint8_t *p1, uint8_t *p2)
-{
-       return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip);
-}
-
-/****************************************************************************
-sort a set of 6 byte name query response records so that the IPs that
-have the most leading bits in common with the specified address come first
-  ***************************************************************************/
-void sort_query_replies(char *data, int n, struct ipv4_addr ip)
-{
-       if (n <= 1) return;
-
-       putip(sort_ip, (char *)&ip);
-
-       qsort(data, n, 6, QSORT_CAST name_query_comp);
-}
-
-
-#define TRUNCATE_NETBIOS_NAME 1
-
-/*******************************************************************
- convert, possibly using a stupid microsoft-ism which has destroyed
- the transport independence of netbios (for CIFS vendors that usually
- use the Win95-type methods, not for NT to NT communication, which uses
- DCE/RPC and therefore full-length unicode strings...) a dns name into
- a netbios name.
-
- the netbios name (NOT necessarily null-terminated) is truncated to 15
- characters.
-
- ******************************************************************/
-char *dns_to_netbios_name(char *dns_name)
-{
-       static char netbios_name[16];
-       int i;
-       StrnCpy(netbios_name, dns_name, 15);
-       netbios_name[15] = 0;
-       
-#ifdef TRUNCATE_NETBIOS_NAME
-       /* ok.  this is because of a stupid microsoft-ism.  if the called host
-          name contains a '.', microsoft clients expect you to truncate the
-          netbios name up to and including the '.'  this even applies, by
-          mistake, to workgroup (domain) names, which is _really_ daft.
-        */
-       for (i = 15; i >= 0; i--)
-       {
-               if (netbios_name[i] == '.')
-               {
-                       netbios_name[i] = 0;
-                       break;
-               }
-       }
-#endif /* TRUNCATE_NETBIOS_NAME */
-
-       return netbios_name;
-}
-
-
-/****************************************************************************
-interpret the weird netbios "name". Return the name type
-****************************************************************************/
-static int name_interpret(char *in,char *out)
-{
-  int ret;
-  int len = (*in++) / 2;
-
-  *out=0;
-
-  if (len > 30 || len<1) return(0);
-
-  while (len--)
-    {
-      if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
-       *out = 0;
-       return(0);
-      }
-      *out = ((in[0]-'A')<<4) + (in[1]-'A');
-      in += 2;
-      out++;
-    }
-  *out = 0;
-  ret = out[-1];
-
-#ifdef NETBIOS_SCOPE
-  /* Handle any scope names */
-  while(*in) 
-    {
-      *out++ = '.'; /* Scope names are separated by periods */
-      len = *(uint8_t *)in++;
-      StrnCpy(out, in, len);
-      out += len;
-      *out=0;
-      in += len;
-    }
-#endif
-  return(ret);
-}
-
-
-/****************************************************************************
-return the number of bytes that would be occupied by the result of
-name_mangle()
-****************************************************************************/
-uint_t nbt_mangled_name_len(void)
-{
-       const char *scope = lp_netbios_scope();
-       uint_t ret = 34;
-       if (scope && *scope) {
-               ret += strlen(scope) + 1;
-       }
-       return ret;
-}
-
-/****************************************************************************
-mangle a name into netbios format
-
-  Note:  <Out> must be nbt_mangled_name_len() in length
-****************************************************************************/
-int name_mangle(char *In, char *Out, char name_type)
-{
-       int   i;
-       int   c;
-       int   len;
-       char  buf[20];
-       char *p = Out;
-       const char *scope = lp_netbios_scope();
-
-       /* Safely copy the input string, In, into buf[]. */
-       memset( buf, 0, 20 );
-       if (strcmp(In,"*") == 0) {
-               buf[0] = '*';
-       } else {
-               slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type);
-       }
-
-       /* Place the length of the first field into the output buffer. */
-       p[0] = 32;
-       p++;
-
-       /* Now convert the name to the rfc1001/1002 format. */
-       for ( i = 0; i < 16; i++ ) {
-               c = toupper( buf[i] );
-               p[i*2]     = ( (c >> 4) & 0xF ) + 'A';
-               p[(i*2)+1] = (c & 0xF) + 'A';
-       }
-       p += 32;
-       p[0] = '\0';
-
-       if (!scope || !*scope) {
-               return name_len(Out);
-       }
-
-       /* Add the scope string. */
-       for (i = 0, len = 0; scope[i]; i++, len++) {
-               switch(scope[i]) {
-               case '.':
-                       p[0] = len;
-                       p   += (len + 1);
-                       len  = -1;
-                       break;
-               default:
-                       p[len+1] = scope[i];
-                       break;
-               }
-       }
-
-       p[0] = len;
-       if (len > 0) {  
-               p[len+1] = 0;
-       }
-
-       return name_len(Out);
-}
-
-/****************************************************************************
-find a pointer to a netbios name
-****************************************************************************/
-static char *name_ptr(char *buf,int ofs)
-{
-  uint8_t c = *(uint8_t *)(buf+ofs);
-
-  if ((c & 0xC0) == 0xC0)
-    {
-      uint16_t l = RSVAL(buf, ofs) & 0x3FFF;
-      DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
-      return(buf + l);
-    }
-  else
-    return(buf+ofs);
-}  
-
-/****************************************************************************
-extract a netbios name from a buf
-****************************************************************************/
-int name_extract(char *buf,int ofs,char *name)
-{
-       char *p = name_ptr(buf,ofs);
-       int d = PTR_DIFF(p,buf+ofs);
-       pstrcpy(name,"");
-       if (d < -50 || d > 50) return(0);
-       return(name_interpret(p,name));
-}
-  
-/****************************************************************************
-return the total storage length of a mangled name
-****************************************************************************/
-int name_len(char *s1)
-{
-       /* NOTE: this argument _must_ be unsigned */
-       uint8_t *s = (uint8_t *)s1;
-       int len;
-
-       /* If the two high bits of the byte are set, return 2. */
-       if (0xC0 == (*s & 0xC0))
-               return(2);
-
-       /* Add up the length bytes. */
-       for (len = 1; (*s); s += (*s) + 1) {
-               len += *s + 1;
-               SMB_ASSERT(len < 80);
-       }
-
-       return(len);
-} /* name_len */
-
-
-/*
-  choose a name to use when calling a server in a NBT session request.
-  we use heuristics to see if the name we have been given is a IP
-  address, or a too-long name. If it is then use *SMBSERVER, or a
-  truncated name
-*/
-void choose_called_name(struct nmb_name *n, const char *name, int type)
-{
-       if (is_ipaddress(name)) {
-               make_nmb_name(n, "*SMBSERVER", type);
-               return;
-       }
-       if (strlen(name) > 16) {
-               const char *p = strchr(name, '.');
-               char name2[17];
-               if (p - name > 16) {
-                       make_nmb_name(n, "*SMBSERVER", type);
-                       return;
-               }
-               strlcpy(name2, name, 1+(p-name));
-               make_nmb_name(n, name2, type);
-               return;
-       }
-
-       /* looks OK */
-       make_nmb_name(n, name, type);
-}
index 0edb95e1a135fcbd95308bcdbfad0f1505768d7c..e9810495355f46259c15b1bfecd26de50bea4aed 100644 (file)
@@ -326,10 +326,11 @@ resolve a hostname and connect
 ****************************************************************************/
 BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, int port)
 {
-       int name_type = 0x20;
-       struct ipv4_addr ip;
-       char *name, *p;
+       int name_type = NBT_NAME_SERVER;
+       const char *address;
        NTSTATUS status;
+       struct nbt_name nbt_name;
+       char *name, *p;
 
        name = talloc_strdup(sock, host);
 
@@ -339,13 +340,18 @@ BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, in
                *p = 0;
        }
 
-       if (!resolve_name(name, name, &ip, name_type)) {
+       nbt_name.name = name;
+       nbt_name.type = name_type;
+       nbt_name.scope = NULL;
+       
+       status = resolve_name(&nbt_name, sock, &address);
+       if (!NT_STATUS_IS_OK(status)) {
                return False;
        }
 
        sock->hostname = name;
 
-       status = smbcli_sock_connect(sock, sys_inet_ntoa(ip), port);
+       status = smbcli_sock_connect(sock, address, port);
 
        return NT_STATUS_IS_OK(status);
 }
index e6d40639c62715295fafe5091efd4b33e5d3f1b9..918f18fa4069de2b467d62a46e8330ef6a55260e 100644 (file)
@@ -145,41 +145,52 @@ static void smbcli_transport_write_disable(struct smbcli_transport *transport)
   send a session request
 */
 struct smbcli_request *smbcli_transport_connect_send(struct smbcli_transport *transport,
-                                                    struct nmb_name *calling, 
-                                                    struct nmb_name *called)
+                                                    struct nbt_name *calling, 
+                                                    struct nbt_name *called)
 {
        uint8_t *p;
-       int len = NBT_HDR_SIZE;
        struct smbcli_request *req;
+       DATA_BLOB calling_blob, called_blob;
+       TALLOC_CTX *tmp_ctx = talloc_new(transport);
+       NTSTATUS status;
 
-       if (called) {
-               transport->called = *called;
-       }
+       status = nbt_name_dup(transport, called, &transport->called);
+       if (!NT_STATUS_IS_OK(status)) goto failed;
+       
+       status = nbt_name_to_blob(tmp_ctx, &calling_blob, calling);
+       if (!NT_STATUS_IS_OK(status)) goto failed;
+
+       status = nbt_name_to_blob(tmp_ctx, &called_blob, called);
+       if (!NT_STATUS_IS_OK(status)) goto failed;
 
        /* allocate output buffer */
        req = smbcli_request_setup_nonsmb(transport, 
-                                         NBT_HDR_SIZE + 2*nbt_mangled_name_len());
-       if (req == NULL) return NULL;
+                                         NBT_HDR_SIZE + 
+                                         calling_blob.length + called_blob.length);
+       if (req == NULL) goto failed;
 
        /* put in the destination name */
        p = req->out.buffer + NBT_HDR_SIZE;
-       name_mangle(called->name, (char *)p, called->name_type);
-       len += name_len((char *)p);
+       memcpy(p, called_blob.data, called_blob.length);
+       p += called_blob.length;
 
-       /* and my name */
-       p = req->out.buffer+len;
-       name_mangle(calling->name, (char *)p, calling->name_type);
-       len += name_len((char *)p);
+       memcpy(p, calling_blob.data, calling_blob.length);
+       p += calling_blob.length;
 
-       _smb_setlen(req->out.buffer,len-4);
+       _smb_setlen(req->out.buffer, PTR_DIFF(p, req->out.buffer)-4);
        SCVAL(req->out.buffer,0,0x81);
 
        if (!smbcli_request_send(req)) {
                smbcli_request_destroy(req);
-               return NULL;
+               goto failed;
        }
 
+       talloc_free(tmp_ctx);
        return req;
+
+failed:
+       talloc_free(tmp_ctx);
+       return NULL;
 }
 
 /*
@@ -237,8 +248,8 @@ NTSTATUS smbcli_transport_connect_recv(struct smbcli_request *req)
   send a session request (if needed)
 */
 BOOL smbcli_transport_connect(struct smbcli_transport *transport,
-                             struct nmb_name *calling, 
-                             struct nmb_name *called)
+                             struct nbt_name *calling, 
+                             struct nbt_name *called)
 {
        struct smbcli_request *req;
        NTSTATUS status;
index 4047a5d36957ffdffb369968af9c111185f5d809..d7414a237ec13ae309430e2e0cc8b28cb50f4682 100644 (file)
@@ -21,6 +21,7 @@
 */
 
 #include "request.h"
+#include "librpc/gen_ndr/ndr_nbt.h"
 
 struct smbcli_tree;  /* forward declare */
 struct smbcli_request;  /* forward declare */
@@ -151,7 +152,7 @@ struct smbcli_transport {
 
        /* remember the called name - some sub-protocols require us to
           know the server name */
-       struct nmb_name called;
+       struct nbt_name called;
 
        /* a buffer for partially received SMB packets. */
        struct {
diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c
new file mode 100644 (file)
index 0000000..b2d37fb
--- /dev/null
@@ -0,0 +1,163 @@
+/* 
+   Unix SMB/CIFS implementation.
+
+   broadcast name resolution module
+
+   Copyright (C) Andrew Tridgell 2005
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "system/network.h"
+#include "libcli/raw/libcliraw.h"
+#include "libcli/nbt/libnbt.h"
+#include "libcli/composite/composite.h"
+
+struct bcast_state {
+       struct nbt_name name;
+       struct nbt_name_socket *nbtsock;
+       int num_queries;
+       struct nbt_name_request **queries;
+       struct nbt_name_query *io_queries;
+       const char *reply_addr;
+};
+
+/*
+  handle events during broadcast name resolution
+*/
+static void bcast_handler(struct nbt_name_request *req)
+{
+       struct smbcli_composite *c = talloc_get_type(req->async.private, 
+                                                    struct smbcli_composite);
+       struct bcast_state *state = talloc_get_type(c->private, struct bcast_state);
+       int i;
+
+       for (i=0;i<state->num_queries;i++) {
+               if (req == state->queries[i]) break;
+       }
+       if (i == state->num_queries) {
+               /* not for us?! */
+               c->status = NT_STATUS_INTERNAL_ERROR;
+               c->state = SMBCLI_REQUEST_ERROR;                
+               goto done;
+       } 
+
+       c->status = nbt_name_query_recv(req, state, &state->io_queries[i]);
+       if (!NT_STATUS_IS_OK(c->status)) {
+               c->state = SMBCLI_REQUEST_ERROR;
+       } else {
+               c->state = SMBCLI_REQUEST_DONE;
+               state->reply_addr = talloc_steal(state, state->io_queries[i].out.reply_addr);
+       }
+
+done:
+       talloc_free(state->nbtsock);
+       if (c->async.fn) {
+               c->async.fn(c);
+       }
+}
+
+/*
+  broadcast name resolution method - async send
+ */
+struct smbcli_composite *resolve_name_bcast_send(struct nbt_name *name, 
+                                                struct event_context *event_ctx)
+{
+       struct smbcli_composite *c;
+       struct bcast_state *state;
+       int i;
+       NTSTATUS status;
+
+       c = talloc_zero(NULL, struct smbcli_composite);
+       if (c == NULL) goto failed;
+
+       state = talloc(c, struct bcast_state);
+       if (state == NULL) goto failed;
+
+       status = nbt_name_dup(state, name, &state->name);
+       if (!NT_STATUS_IS_OK(status)) goto failed;
+
+       state->nbtsock = nbt_name_socket_init(state, event_ctx);
+       if (state->nbtsock == NULL) goto failed;
+
+       state->num_queries = iface_count();
+
+       state->io_queries = talloc_array(state, struct nbt_name_query, state->num_queries);
+       if (!state->io_queries) goto failed;
+
+       state->queries = talloc_array(state, struct nbt_name_request *, state->num_queries);
+       if (!state->queries) goto failed;
+
+       for (i=0;i<state->num_queries;i++) {
+               struct ipv4_addr *ip = iface_n_bcast(i);
+               const char *addr = sys_inet_ntoa(*ip);
+               if (!addr) goto failed;
+
+               state->io_queries[i].in.name = state->name;
+               state->io_queries[i].in.dest_addr = talloc_strdup(state->io_queries, addr);
+               if (!state->io_queries[i].in.dest_addr) goto failed;
+               state->io_queries[i].in.broadcast = True;
+               state->io_queries[i].in.wins_lookup = False;
+               state->io_queries[i].in.timeout = lp_parm_int(-1, "nbt", "bcastTimeout", 5);
+
+               state->queries[i] = nbt_name_query_send(state->nbtsock, &state->io_queries[i]);
+               if (!state->queries[i]) goto failed;
+
+               state->queries[i]->async.fn = bcast_handler;
+               state->queries[i]->async.private = c;
+       }
+
+       c->state = SMBCLI_REQUEST_SEND;
+       c->private = state;
+       c->event_ctx = state->nbtsock->event_ctx;
+
+       return c;
+
+failed:
+       talloc_free(c);
+       return NULL;
+}
+
+/*
+  broadcast name resolution method - recv side
+ */
+NTSTATUS resolve_name_bcast_recv(struct smbcli_composite *c, 
+                                TALLOC_CTX *mem_ctx, const char **reply_addr)
+{
+       NTSTATUS status;
+
+       status = smb_composite_wait(c);
+
+       if (NT_STATUS_IS_OK(status)) {
+               struct bcast_state *state = talloc_get_type(c->private, struct bcast_state);
+               *reply_addr = talloc_steal(mem_ctx, state->reply_addr);
+       }
+
+       talloc_free(c);
+       return status;
+}
+
+/*
+  broadcast name resolution method - sync call
+ */
+NTSTATUS resolve_name_bcast(struct nbt_name *name, 
+                           TALLOC_CTX *mem_ctx,
+                           const char **reply_addr)
+{
+       struct smbcli_composite *c = resolve_name_bcast_send(name, NULL);
+       return resolve_name_bcast_recv(c, mem_ctx, reply_addr);
+}
+
diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c
new file mode 100644 (file)
index 0000000..e83b11c
--- /dev/null
@@ -0,0 +1,51 @@
+/* 
+   Unix SMB/CIFS implementation.
+
+   general name resolution interface
+
+   Copyright (C) Andrew Tridgell 2005
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "libcli/raw/libcliraw.h"
+#include "libcli/composite/composite.h"
+
+/*
+  general name resolution - async send
+ */
+struct smbcli_composite *resolve_name_send(struct nbt_name *name, struct event_context *event_ctx)
+{
+       return resolve_name_bcast_send(name, event_ctx);
+}
+
+/*
+  general name resolution method - recv side
+ */
+NTSTATUS resolve_name_recv(struct smbcli_composite *c, 
+                          TALLOC_CTX *mem_ctx, const char **reply_addr)
+{
+       return resolve_name_bcast_recv(c, mem_ctx, reply_addr);
+}
+
+/*
+  general name resolution - sync call
+ */
+NTSTATUS resolve_name(struct nbt_name *name, TALLOC_CTX *mem_ctx, const char **reply_addr)
+{
+       struct smbcli_composite *c = resolve_name_send(name, NULL);
+       return resolve_name_recv(c, mem_ctx, reply_addr);
+}
diff --git a/source4/libcli/unexpected.c b/source4/libcli/unexpected.c
deleted file mode 100644 (file)
index 264b9d7..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/* 
-   Unix SMB/CIFS implementation.
-   handle unexpected packets
-   Copyright (C) Andrew Tridgell 2000
-   
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-   
-*/
-
-#include "includes.h"
-
-static struct tdb_wrap *tdbd = NULL;
-
-/* the key type used in the unexpeceted packet database */
-struct unexpected_key {
-       enum packet_type packet_type;
-       time_t timestamp;
-       int count;
-};
-
-
-
-/****************************************************************************
- all unexpected packets are passed in here, to be stored in a unexpected
- packet database. This allows nmblookup and other tools to receive packets
- erroneoously sent to the wrong port by broken MS systems
-  **************************************************************************/
-void unexpected_packet(struct packet_struct *p)
-{
-       static int count;
-       TDB_DATA kbuf, dbuf;
-       struct unexpected_key key;
-       char buf[1024];
-       int len=0;
-
-       if (!tdbd) {
-               char *path = smbd_tmp_path(NULL, "unexpected.tdb");
-               tdbd = tdb_wrap_open(NULL, path, 0, 
-                                    TDB_DEFAULT,
-                                    O_RDWR | O_CREAT, 0644);
-               talloc_free(path);
-               if (!tdbd) {
-                       return;
-               }
-       }
-
-       memset(buf,'\0',sizeof(buf));
-       
-       len = build_packet(buf, p);
-
-       key.packet_type = p->packet_type;
-       key.timestamp = p->timestamp;
-       key.count = count++;
-
-       kbuf.dptr = (char *)&key;
-       kbuf.dsize = sizeof(key);
-       dbuf.dptr = buf;
-       dbuf.dsize = len;
-
-       tdb_store(tdbd->tdb, kbuf, dbuf, TDB_REPLACE);
-}
-
-
-static time_t lastt;
-
-/****************************************************************************
-delete the record if it is too old
-  **************************************************************************/
-static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
-{
-       struct unexpected_key key;
-
-       memcpy(&key, kbuf.dptr, sizeof(key));
-
-       if (lastt - key.timestamp > NMBD_UNEXPECTED_TIMEOUT) {
-               tdb_delete(ttdb, kbuf);
-       }
-
-       return 0;
-}
-
-
-/****************************************************************************
-delete all old unexpected packets
-  **************************************************************************/
-void clear_unexpected(time_t t)
-{
-       if (!tdbd) return;
-
-       if ((lastt != 0) && (t < lastt + NMBD_UNEXPECTED_TIMEOUT))
-               return;
-
-       lastt = t;
-
-       tdb_traverse(tdbd->tdb, traverse_fn, NULL);
-}
-
-
-static struct packet_struct *matched_packet;
-static int match_id;
-static enum packet_type match_type;
-static const char *match_name;
-
-/****************************************************************************
-tdb traversal fn to find a matching 137 packet
-  **************************************************************************/
-static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
-{
-       struct unexpected_key key;
-       struct packet_struct *p;
-
-       memcpy(&key, kbuf.dptr, sizeof(key));
-
-       if (key.packet_type != match_type) return 0;
-
-       p = parse_packet(dbuf.dptr, dbuf.dsize, match_type);
-
-       if ((match_type == NMB_PACKET && 
-            p->packet.nmb.header.name_trn_id == match_id) ||
-           (match_type == DGRAM_PACKET && 
-            match_mailslot_name(p, match_name))) {
-               matched_packet = p;
-               return -1;
-       }
-
-       free_packet(p);
-
-       return 0;
-}
-
-
-/****************************************************************************
-check for a particular packet in the unexpected packet queue
-  **************************************************************************/
-struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, 
-                                        const char *mailslot_name)
-{
-       struct tdb_wrap *tdb2;
-       char *path;
-
-       path = smbd_tmp_path(NULL, "unexpected.tdb");
-       tdb2 = tdb_wrap_open(NULL, path, 0, 0, O_RDONLY, 0);
-       talloc_free(path);
-       if (!tdb2) {
-               return NULL;
-       }
-
-       matched_packet = NULL;
-       match_id = id;
-       match_type = packet_type;
-       match_name = mailslot_name;
-
-       tdb_traverse(tdb2->tdb, traverse_match, NULL);
-
-       talloc_free(tdb2);
-
-       return matched_packet;
-}
index b4b33bf4c0b93efa18ae7cbee349b26928e54cb9..1f546d89a4a03d169d1e991ddb62cb99a55cdc01 100644 (file)
 */
 
 #include "includes.h"
+#include "libcli/nbt/libnbt.h"
 #include "libnet/libnet.h"
 
 /* find a domain pdc generic */
-static NTSTATUS libnet_find_pdc_generic(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_find_pdc *r)
+static NTSTATUS libnet_find_pdc_generic(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, 
+                                       union libnet_find_pdc *r)
 {
-       BOOL ret;
-       struct ipv4_addr ip;
+       const char *address;
+       NTSTATUS status;
+       struct nbt_name name;
 
        if (is_ipaddress(r->generic.in.domain_name)) {
                r->generic.out.pdc_name = r->generic.in.domain_name;
                return NT_STATUS_OK;
        }
 
-       ret = get_pdc_ip(mem_ctx, r->generic.in.domain_name, &ip);
-       if (!ret) {
-               /* fallback to a workstation name */
-               ret = resolve_name(mem_ctx, r->generic.in.domain_name, &ip, 0x20);
-               if (!ret) {
-                       return NT_STATUS_NO_LOGON_SERVERS;
-               }
+       name.name = r->generic.in.domain_name;
+       name.type = NBT_NAME_PDC;
+       name.scope = NULL;
+
+       status = resolve_name(&name, mem_ctx, &address);
+       if (!NT_STATUS_IS_OK(status)) {
+               name.type = NBT_NAME_SERVER;
+               status = resolve_name(&name, mem_ctx, &address);
        }
+       NT_STATUS_NOT_OK_RETURN(status);
 
-       r->generic.out.pdc_name = talloc_strdup(mem_ctx, sys_inet_ntoa(ip));
+       r->generic.out.pdc_name = talloc_strdup(mem_ctx, address);
 
        return NT_STATUS_OK;
 }
index 6dcd456fdb4445240bc05e465793f22c6fe44d05..8acf3c4eb7c24061b1640ae8470c48b0ad3d17af 100644 (file)
@@ -62,12 +62,15 @@ static NTSTATUS after_negprot(struct smbcli_transport **dst_transport,
        talloc_set_destructor(transport, destroy_transport);
 
        {
-               struct nmb_name calling;
-               struct nmb_name called;
+               struct nbt_name calling;
+               struct nbt_name called;
 
                /* send a NBT session request, if applicable */
-               make_nmb_name(&calling, my_name, 0x0);
-               choose_called_name(&called, dest_host, 0x20);
+               calling.name = my_name;
+               calling.type = NBT_NAME_CLIENT;
+               calling.scope = NULL;
+
+               nbt_choose_called_name(transport, &called, dest_host, NBT_NAME_SERVER);
 
                if (!smbcli_transport_connect(transport, &calling, &called)) {
                        talloc_free(transport);
index b2219c617c42aced3d3ae9b0de898d2a66ad923d..63793b41dab1ae3d64370911e368390a0f3b4232 100644 (file)
@@ -44,12 +44,15 @@ BOOL torture_showall = False;
 
 static struct smbcli_state *open_nbt_connection(void)
 {
-       struct nmb_name called, calling;
+       struct nbt_name called, calling;
        struct smbcli_state *cli;
        const char *host = lp_parm_string(-1, "torture", "host");
 
-       make_nmb_name(&calling, lp_netbios_name(), 0x0);
-       choose_called_name(&called, host, 0x20);
+       calling.name = lp_netbios_name();
+       calling.type = NBT_NAME_CLIENT;
+       calling.scope = NULL;
+
+       nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
 
        cli = smbcli_state_init(NULL);
        if (!cli) {
@@ -63,23 +66,9 @@ static struct smbcli_state *open_nbt_connection(void)
        }
 
        if (!smbcli_transport_establish(cli, &calling, &called)) {
-               /*
-                * Well, that failed, try *SMBSERVER ... 
-                * However, we must reconnect as well ...
-                */
-               if (!smbcli_socket_connect(cli, host)) {
-                       printf("Failed to connect with %s\n", host);
-                       return False;
-               }
-
-               make_nmb_name(&called, "*SMBSERVER", 0x20);
-               if (!smbcli_transport_establish(cli, &calling, &called)) {
-                       printf("%s rejected the session\n",host);
-                       printf("We tried with a called name of %s & %s\n",
-                               host, "*SMBSERVER");
-                       smbcli_shutdown(cli);
-                       return NULL;
-               }
+               printf("%s rejected the session\n",host);
+               smbcli_shutdown(cli);
+               return NULL;
        }
 
        return cli;