summaryrefslogtreecommitdiff
path: root/source3/nameservresp.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nameservresp.c')
-rw-r--r--source3/nameservresp.c86
1 files changed, 84 insertions, 2 deletions
diff --git a/source3/nameservresp.c b/source3/nameservresp.c
index 27356d95e6..226a997c5f 100644
--- a/source3/nameservresp.c
+++ b/source3/nameservresp.c
@@ -37,7 +37,11 @@ extern int ClientNMB;
extern int DEBUGLEVEL;
extern pstring scope;
+extern fstring myworkgroup;
extern struct in_addr ipzero;
+extern struct in_addr wins_ip;
+extern struct in_addr ipzero;
+
#define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
@@ -99,7 +103,20 @@ static void response_name_reg(struct nmb_name *ans_name,
DEBUG(4,("response name registration received!\n"));
+#if 1
+ /* This code is neccesitated due to bugs in earlier versions of
+ Samba (up to 1.9.16p11). They respond to a broadcast
+ name registration of WORKGROUP<1b> when they should
+ not. Hence, until these versions are gone, we should
+ treat such errors as success for this particular
+ case only. jallison@whistle.com.
+ */
+ if ( ((d != wins_subnet) && (nmb->header.rcode == 6) && strequal(myworkgroup, name) &&
+ (type == 0x1b)) ||
+ (nmb->header.rcode == 0 && nmb->answers->rdata))
+#else
if (nmb->header.rcode == 0 && nmb->answers->rdata)
+#endif
{
/* IMPORTANT: see expire_netbios_response_entries() */
@@ -489,6 +506,55 @@ static void response_name_query_sync(struct nmb_packet *nmb,
}
}
+/****************************************************************************
+ response from a name query for DOMAIN<1b>
+ NAME_QUERY_DOMAIN is dealt with here - we are trying to become a domain
+ master browser and WINS replied - check it's our address.
+ ****************************************************************************/
+static void response_name_query_domain(struct nmb_name *ans_name,
+ struct nmb_packet *nmb,
+ struct response_record *n, struct subnet_record *d)
+{
+ DEBUG(4, ("response_name_query_domain: Got %s response from %s for query \
+for %s\n", nmb->header.rcode == 0 ? "success" : "failure",
+ inet_ntoa(n->send_ip), namestr(ans_name)));
+
+ /* Check the name is correct and ip address returned is our own. If it is then we
+ just remove the response record.
+ */
+ if (name_equal(&n->name, ans_name) && (nmb->header.rcode == 0) && (nmb->answers->rdata))
+ {
+ struct in_addr found_ip;
+
+ putip((char*)&found_ip,&nmb->answers->rdata[2]);
+ /* Samba 1.9.16p11 servers seem to return the broadcast address for this
+ query. */
+ if (ismyip(found_ip) || ip_equal(wins_ip, found_ip) || ip_equal(ipzero, found_ip))
+ {
+ DEBUG(4, ("response_name_query_domain: WINS server returned our ip \
+address. Pretending we never received response.\n"));
+ n->num_msgs = 0;
+ n->repeat_count = 0;
+ n->repeat_time = 0;
+ }
+ else
+ {
+ DEBUG(0,("response_name_query_domain: WINS server already has a \
+domain master browser registered %s at address %s\n",
+ namestr(ans_name), inet_ntoa(found_ip)));
+ }
+ }
+ else
+ {
+ /* Negative/incorrect response. No domain master
+ browser was registered - pretend we didn't get this response.
+ */
+ n->num_msgs = 0;
+ n->repeat_count = 0;
+ n->repeat_time = 0;
+ }
+
+}
/****************************************************************************
report the response record type
@@ -521,6 +587,7 @@ void debug_state_type(int state)
case NAME_QUERY_SYNC_LOCAL : DEBUG(4,("NAME_QUERY_SYNC_LOCAL\n")); break;
case NAME_QUERY_SYNC_REMOTE : DEBUG(4,("NAME_QUERY_SYNC_REMOTE\n")); break;
case NAME_QUERY_ANNOUNCE_HOST: DEBUG(4,("NAME_QUERY_ANNCE_HOST\n"));break;
+ case NAME_QUERY_DOMAIN : DEBUG(4,("NAME_QUERY_DOMAIN\n")); break;
case NAME_REGISTER : DEBUG(4,("NAME_REGISTER\n")); break;
case NAME_REGISTER_CHALLENGE : DEBUG(4,("NAME_REGISTER_CHALLENGE\n"));break;
@@ -593,7 +660,7 @@ static BOOL response_problem_check(struct response_record *n,
{
case NAME_QUERY_FIND_MST:
{
- /* query for ^1^2__MSBROWSE__^2^1 expect
+ /* query for ^1^2__MSBROWSE__^2^1 expect
lots of responses */
return False;
}
@@ -768,7 +835,22 @@ static void response_process(struct subnet_record *d, struct packet_struct *p,
namestr(&n->name), inet_ntoa(n->send_ip)));
break;
}
-
+
+ case NAME_QUERY_DOMAIN:
+ {
+ /* We were asking to be a domain master browser, and someone
+ replied. If it was the WINS server and the IP it is
+ returning is our own - then remove the record and pretend
+ we didn't get a response. Else we do nothing and let
+ dead_netbios_entry deal with it.
+ We can only become domain master browser
+ when no broadcast responses are received and WINS
+ either contains no entry for the DOMAIN<1b> name or
+ contains our IP address.
+ */
+ response_name_query_domain(ans_name, nmb, n, d);
+ break;
+ }
default:
{
DEBUG(1,("unknown state type received in response_netbios_packet\n"));