From 5d4345b66de2bbf9d60e78682d820adb30b52a79 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 16 Dec 1997 07:30:25 +0000 Subject: nmbd_incomingdgrams.c: Fix bug with Syntax 5.1 servers reported by SGI where they do host announcements to LOCAL_MASTER_BROWSER_NAME<00> rather than WORKGROUP<1d>. nmbd_incomingrequests.c: Deal with WINS_PROXY_NAME issues - don't reply with that name if it's the same broadcast net. nmbd_serverlistdb.c: Stopped writing "Unknown" for local master browsers we don't know. nmbd_winsproxy.c: Deal with WINS_PROXY_NAME issues - don't reply with that name if it's the same broadcast net. Jeremy. (This used to be commit 5adfff94c9020bd57f84ccbc8fba5b1d8d1615af) --- source3/nmbd/nmbd_incomingdgrams.c | 11 +++++++++++ source3/nmbd/nmbd_incomingrequests.c | 36 +++++++++++++++++++++++++++++++++++- source3/nmbd/nmbd_serverlistdb.c | 5 ++--- source3/nmbd/nmbd_winsproxy.c | 25 ++++++++++++++++++++++++- 4 files changed, 72 insertions(+), 5 deletions(-) (limited to 'source3') diff --git a/source3/nmbd/nmbd_incomingdgrams.c b/source3/nmbd/nmbd_incomingdgrams.c index 24b4f33838..d43b1369e6 100644 --- a/source3/nmbd/nmbd_incomingdgrams.c +++ b/source3/nmbd/nmbd_incomingdgrams.c @@ -134,6 +134,17 @@ void process_host_announce(struct subnet_record *subrec, struct packet_struct *p /* For a host announce the workgroup name is the destination name. */ work_name = dgram->dest_name.name; + /* + * Syntax servers version 5.1 send HostAnnounce packets to + * *THE WRONG NAME*. They send to LOCAL_MASTER_BROWSER_NAME<00> + * instead of WORKGROUP<1d> name. So to fix this we check if + * the workgroup name is our own name, and if so change it + * to be our primary workgroup name. + */ + + if(strequal(work_name, myname)) + work_name = myworkgroup; + /* * We are being very agressive here in adding a workgroup * name on the basis of a host announcing itself as being diff --git a/source3/nmbd/nmbd_incomingrequests.c b/source3/nmbd/nmbd_incomingrequests.c index ff4bb07a45..73abdf0050 100644 --- a/source3/nmbd/nmbd_incomingrequests.c +++ b/source3/nmbd/nmbd_incomingrequests.c @@ -213,7 +213,19 @@ IP %s on subnet %s\n", namestr(question), inet_ntoa(from_ip), subrec->subnet_nam /* See if the name already exists. */ namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME); - + + /* + * If the name being registered exists and is a WINS_PROXY_NAME + * then delete the WINS proxy name entry so we don't reply erroneously + * later to queries. + */ + + if((namerec != NULL) && (namerec->source == WINS_PROXY_NAME)) + { + remove_name_from_namelist( subrec, namerec ); + namerec = NULL; + } + if (!group) { /* Unique name. */ @@ -469,6 +481,28 @@ void process_name_query_request(struct subnet_record *subrec, struct packet_stru /* The requested name is a directed query, or it's SELF or PERMANENT or WINS_PROXY, or it's a Domain Master type. */ + /* + * If this is a WINS_PROXY_NAME, then ceck that none of the IP + * addresses we are returning is on the same broadcast subnet + * as the requesting packet. If it is then don't reply as the + * actual machine will be replying also and we don't want two + * replies to a broadcast query. + */ + + if(namerec->source == WINS_PROXY_NAME) + { + for( i = 0; i < namerec->num_ips; i++) + { + if(same_net( namerec->ip[i], subrec->myip, subrec->mask_ip )) + { + DEBUG(5,("process_name_query_request: name %s is a WINS proxy name and is also \ +on the same subnet (%s) as the requestor. Not replying.\n", + namestr(&namerec->name), subrec->subnet_name )); + return; + } + } + } + ttl = (namerec->death_time != PERMANENT_TTL) ? namerec->death_time - p->timestamp : lp_max_ttl(); diff --git a/source3/nmbd/nmbd_serverlistdb.c b/source3/nmbd/nmbd_serverlistdb.c index 1281fe2ee3..b3dca36c84 100644 --- a/source3/nmbd/nmbd_serverlistdb.c +++ b/source3/nmbd/nmbd_serverlistdb.c @@ -365,7 +365,7 @@ void write_browse_list(time_t t, BOOL force_write) sprintf(tmp, "\"%s\"", work->work_group); fprintf(fp, "%-25s ", tmp); fprintf(fp, "%08x ", SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT|SV_TYPE_LOCAL_LIST_ONLY); - sprintf(tmp, "\"%s\" ", *work->local_master_browser_name ? work->local_master_browser_name : "Unknown"); + sprintf(tmp, "\"%s\" ", work->local_master_browser_name); fprintf(fp, "%-30s", tmp); fprintf(fp, "\"%s\"\n", work->work_group); @@ -414,8 +414,7 @@ void write_browse_list(time_t t, BOOL force_write) fprintf(fp, "%-25s ", tmp); fprintf(fp, "%08x ", wg_type); - sprintf(tmp, "\"%s\" ", *work->local_master_browser_name ? - work->local_master_browser_name : "Unknown" ); + sprintf(tmp, "\"%s\" ", work->local_master_browser_name); fprintf(fp, "%-30s", tmp); fprintf(fp, "\"%s\"\n", work->work_group); } diff --git a/source3/nmbd/nmbd_winsproxy.c b/source3/nmbd/nmbd_winsproxy.c index ed8653b8bf..4f2326795d 100644 --- a/source3/nmbd/nmbd_winsproxy.c +++ b/source3/nmbd/nmbd_winsproxy.c @@ -35,6 +35,7 @@ static void wins_proxy_name_query_request_success( struct subnet_record *subrec, { struct packet_struct *original_packet; struct subnet_record *orig_broadcast_subnet; + struct name_record *namerec; uint16 nb_flags; int num_ips; int i; @@ -77,12 +78,34 @@ returned for name %s.\n", namestr(nmbname) )); if(rrec == PERMANENT_TTL) ttl = lp_max_ttl(); - add_name_to_subnet( orig_broadcast_subnet, nmbname->name, nmbname->name_type, + namerec = add_name_to_subnet( orig_broadcast_subnet, nmbname->name, nmbname->name_type, nb_flags, ttl, WINS_PROXY_NAME, num_ips, iplist); if(iplist != &ip) free((char *)iplist); + /* + * Check that none of the IP addresses we are returning is on the + * same broadcast subnet as the original requesting packet. If it + * is then don't reply (although we still need to add the name + * to the cache) as the actual machine will be replying also + * and we don't want two replies to a broadcast query. + */ + + if(namerec && original_packet->packet.nmb.header.nm_flags.bcast) + { + for( i = 0; i < namerec->num_ips; i++) + { + if(same_net( namerec->ip[i], orig_broadcast_subnet->myip, orig_broadcast_subnet->mask_ip )) + { + DEBUG(5,("wins_proxy_name_query_request_success: name %s is a WINS proxy name and is also \ +on the same subnet (%s) as the requestor. Not replying.\n", + namestr(&namerec->name), orig_broadcast_subnet->subnet_name )); + return; + } + } + } + /* Finally reply to the original name query. */ reply_netbios_packet(original_packet, /* Packet to reply to. */ 0, /* Result code. */ -- cgit