From ec6fde99ab739ff2c410e5459bba06b06d18b5dc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 20 Apr 1998 20:32:50 +0000 Subject: Fixed bug that John found in WINS server code. When nmbd as a WINS server is sending out a name_query after a WACK, it needs to send a packet with recursion_desired = 0 (yes Luke, you were right all along :-). If it doesn't then if it's talking to itself then the query packet ends up back in the WINS server instead of in the client side code. Makefile: Changed proto generation to stop including NMBDOBJ twice. nmbd_namequery.c nmbd_packets.c nmbd_winsserver.c: Added extra query_name_from_wins_server() code. Jeremy. (This used to be commit c5ca05c29546053a771f4ea3ef850efb3be970ea) --- source3/include/proto.h | 12 ++++++++ source3/nmbd/nmbd_namequery.c | 29 +++++++++++++++++++ source3/nmbd/nmbd_packets.c | 64 ++++++++++++++++++++++++++++++++++++++++++ source3/nmbd/nmbd_winsserver.c | 15 ++++------ 4 files changed, 111 insertions(+), 9 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 3afc150649..539ddc2ae5 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1276,6 +1276,11 @@ BOOL query_name(struct subnet_record *subrec, char *name, int type, query_name_success_function success_fn, query_name_fail_function fail_fn, struct userdata_struct *userdata); +BOOL query_name_from_wins_server(struct in_addr ip_to, + char *name, int type, + query_name_success_function success_fn, + query_name_fail_function fail_fn, + struct userdata_struct *userdata); /*The following definitions come from nmbd_nameregister.c */ @@ -1347,6 +1352,13 @@ struct response_record *queue_query_name( struct subnet_record *subrec, query_name_fail_function fail_fn, struct userdata_struct *userdata, struct nmb_name *nmbname); +struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip, + response_function resp_fn, + timeout_response_function timeout_fn, + query_name_success_function success_fn, + query_name_fail_function fail_fn, + struct userdata_struct *userdata, + struct nmb_name *nmbname); struct response_record *queue_node_status( struct subnet_record *subrec, response_function resp_fn, timeout_response_function timeout_fn, diff --git a/source3/nmbd/nmbd_namequery.c b/source3/nmbd/nmbd_namequery.c index 51f18edd05..1794efe890 100644 --- a/source3/nmbd/nmbd_namequery.c +++ b/source3/nmbd/nmbd_namequery.c @@ -232,3 +232,32 @@ BOOL query_name(struct subnet_record *subrec, char *name, int type, } return False; } + +/**************************************************************************** + Try and query for a name from nmbd acting as a WINS server. +****************************************************************************/ + +BOOL query_name_from_wins_server(struct in_addr ip_to, + char *name, int type, + query_name_success_function success_fn, + query_name_fail_function fail_fn, + struct userdata_struct *userdata) +{ + struct nmb_name nmbname; + + make_nmb_name(&nmbname, name, type, scope); + + if(queue_query_name_from_wins_server( ip_to, + query_name_response, + query_name_timeout_response, + success_fn, + fail_fn, + userdata, + &nmbname) == NULL) + { + DEBUG(0,("query_name_from_wins_server: Failed to send packet trying to query name %s\n", + namestr(&nmbname))); + return True; + } + return False; +} diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c index 19c61a877a..54f4f3a2cb 100644 --- a/source3/nmbd/nmbd_packets.c +++ b/source3/nmbd/nmbd_packets.c @@ -281,6 +281,28 @@ static BOOL initiate_name_query_packet( struct packet_struct *packet) return send_netbios_packet( packet ); } +/*************************************************************************** + Sends out a name query - from a WINS server. +**************************************************************************/ + +static BOOL initiate_name_query_packet_from_wins_server( struct packet_struct *packet) +{ + struct nmb_packet *nmb = NULL; + + nmb = &packet->packet.nmb; + + nmb->header.opcode = NMB_NAME_QUERY_OPCODE; + nmb->header.arcount = 0; + + nmb->header.nm_flags.recursion_desired = False; + + DEBUG(4,("initiate_name_query_packet_from_wins_server: sending query for name %s (bcast=%s) to IP %s\n", + namestr(&nmb->question.question_name), + BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip))); + + return send_netbios_packet( packet ); +} + /*************************************************************************** Sends out a name register. **************************************************************************/ @@ -679,6 +701,48 @@ struct response_record *queue_query_name( struct subnet_record *subrec, return rrec; } +/**************************************************************************** + Queue a query name packet to a given address from the WINS subnet. +****************************************************************************/ + +struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip, + response_function resp_fn, + timeout_response_function timeout_fn, + query_name_success_function success_fn, + query_name_fail_function fail_fn, + struct userdata_struct *userdata, + struct nmb_name *nmbname) +{ + struct packet_struct *p; + struct response_record *rrec; + BOOL bcast = False; + + if(( p = create_and_init_netbios_packet(nmbname, bcast, to_ip)) == NULL) + return NULL; + + if(initiate_name_query_packet_from_wins_server( p ) == False) + { + p->locked = False; + free_packet(p); + return NULL; + } + + if((rrec = make_response_record(wins_server_subnet, /* subnet record. */ + p, /* packet we sent. */ + resp_fn, /* function to call on response. */ + timeout_fn, /* function to call on timeout. */ + (success_function)success_fn, /* function to call on operation success. */ + (fail_function)fail_fn, /* function to call on operation fail. */ + userdata)) == NULL) + { + p->locked = False; + free_packet(p); + return NULL; + } + + return rrec; +} + /**************************************************************************** Queue a node status packet to a given name and address. ****************************************************************************/ diff --git a/source3/nmbd/nmbd_winsserver.c b/source3/nmbd/nmbd_winsserver.c index afc8741366..d089686917 100644 --- a/source3/nmbd/nmbd_winsserver.c +++ b/source3/nmbd/nmbd_winsserver.c @@ -808,20 +808,17 @@ is one of our (WINS server) names. Denying registration.\n", namestr(question) ) memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) ); /* - * As query_name uses the subnet broadcast address as the destination - * of the packet we temporarily change the subnet broadcast address to - * be the first IP address of the name owner and send the packet. This - * is a *horrible* hack but the alternative is to add the destination - * address parameter to all query_name() calls. I hate this code :-). + * Use the new call to send a query directly to an IP address. + * This sends the query directly to the IP address, and ensures + * the recursion desired flag is not set (you were right Luke :-). + * This function should *only* be called from the WINS server + * code. JRA. */ - subrec->bcast_ip = *namerec->ip; - - query_name( subrec, question->name, question->name_type, + query_name_from_wins_server( *namerec->ip, question->name, question->name_type, wins_register_query_success, wins_register_query_fail, userdata); - subrec->bcast_ip = ipzero; return; } -- cgit