Unix SMB/Netbios implementation.
Version 1.9.
NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1996
+ Copyright (C) Andrew Tridgell 1994-1997
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
extern int DEBUGLEVEL;
-extern struct in_addr ipgrp;
+extern struct in_addr wins_ip;
/****************************************************************************
namestr(&nmb->question.question_name)));
if (!(d = find_req_subnet(p->ip, bcast)))
- {
- DEBUG(3,("response packet: bcast %s not known\n",
- inet_ntoa(p->ip)));
- return;
- }
+ {
+ DEBUG(3,("response packet: bcast %s not known\n",
+ inet_ntoa(p->ip)));
+ return;
+ }
if (bcast)
- search &= FIND_LOCAL;
+ search |= FIND_LOCAL;
else
- search &= FIND_WINS;
+ search |= FIND_WINS;
n = find_name_search(&d, &nmb->question.question_name,
- search, ip);
+ search, ip);
/* XXXX under what conditions should we reject the removal?? */
- if (n && n->ip_flgs[0].nb_flags == nb_flags)
- {
+ /* For now - remove if the names match and the group bit matches. */
+ if (n && (NAME_GROUP(n->ip_flgs[0].nb_flags) == NAME_GROUP(nb_flags)))
+ {
success = True;
+ DEBUG(5, ("reply_name_release: Removing name %s on subnet %s\n",
+ namestr(&nmb->question.question_name), inet_ntoa(d->bcast_ip)));
remove_name(d,n);
n = NULL;
- }
+ }
if (bcast) return;
/* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
send_name_response(p->fd,p->ip, nmb->header.name_trn_id, NMB_REL,
- success, False,
- &nmb->question.question_name, nb_flags, 0, ip);
+ success, False,
+ &nmb->question.question_name, nb_flags, 0, ip);
}
putip((char *)&from_ip,&nmb->additional->rdata[2]);
ip = from_ip;
- DEBUG(3,("Name registration for name %s at %s\n",
+ DEBUG(3,("Name registration for name %s at %s - ",
namestr(question),inet_ntoa(ip)));
if (group)
{
/* apparently we should return 255.255.255.255 for group queries
(email from MS) */
- ip = ipgrp;
+ ip = wins_ip;
}
if (!(d = find_req_subnet(p->ip, bcast)))
{
- DEBUG(3,("response packet: bcast %s not known\n",
+ DEBUG(3,("reply_name_reg: subnet %s not known\n",
inet_ntoa(p->ip)));
return;
}
if (bcast)
- search &= FIND_LOCAL;
+ search |= FIND_LOCAL;
else
- search &= FIND_WINS;
+ search |= FIND_WINS;
/* see if the name already exists */
n = find_name_search(&d, question, search, from_ip);
if (n)
{
+ DEBUG(3,("found\n"));
if (!group) /* unique names */
{
if (n->source == SELF || NAME_GROUP(n->ip_flgs[0].nb_flags))
}
else
{
+ DEBUG(3,("not found\n"));
/* add the name to our name/subnet, or WINS, database */
n = add_netbios_entry(d,qname,qname_type,nb_flags,ttl,REGISTER,ip,
True,!bcast);
/* initiate some enquiries to the current owner. */
queue_netbios_packet(d,ClientNMB,NMB_QUERY,
NAME_REGISTER_CHALLENGE,
- -1,reply_name->name,reply_name->name_type,
- n->source, nb_flags,0,0,NULL,NULL,
+ reply_name->name,reply_name->name_type,
+ nb_flags,0,0,NULL,NULL,
False, False, n->ip_flgs[0].ip, p->ip);
}
else
if (!strequal(n->name.name,"*") &&
!strequal(n->name.name,"__SAMBA__") &&
- (name_type < 0x1b || name_type > 0x20 ||
- ques_type < 0x1b || ques_type > 0x20 ||
+ (name_type < 0x1b || name_type >= 0x20 ||
+ ques_type < 0x1b || ques_type >= 0x20 ||
strequal(qname, n->name.name)))
{
/* start with first bit of putting info in buffer: the name */
/* end of this name list: add wins names too? */
struct subnet_record *w_d;
- if (!(w_d = find_subnet(ipgrp))) break;
+ if (!(w_d = wins_subnet)) break;
if (w_d != d)
{
reply_netbios_packet(p,nmb->header.name_trn_id,
0,NMB_STATUS,0,True,
&nmb->question.question_name,
- nmb->question.question_type,
- nmb->question.question_class,
- 0,
- rdata,PTR_DIFF(buf,rdata));
+ 0x21, 0x01,
+ 0, rdata,PTR_DIFF(buf,rdata));
}
char rdata[6];
struct subnet_record *d = NULL;
BOOL success = True;
- struct name_record *n;
+ struct name_record *n = NULL;
/* directed queries are for WINS server: broadcasts are local SELF queries.
the exception is Domain Master names. */
- int search = bcast ? FIND_LOCAL | FIND_SELF : FIND_WINS;
-
- if (name_type == 0x1b)
- {
- search |= FIND_WINS;
- }
+ int search = bcast ? FIND_LOCAL | FIND_WINS: FIND_WINS;
- if (search | FIND_LOCAL)
+ if (search & FIND_LOCAL)
{
if (!(d = find_req_subnet(p->ip, bcast)))
{
}
else
{
- if (!(d = find_subnet(ipgrp)))
+ if (!(d = wins_subnet))
{
DEBUG(3,("name query: wins search %s not known\n",
inet_ntoa(p->ip)));
}
}
- DEBUG(3,("Name query "));
+ DEBUG(3,("Name query from %s for name %s<0x%x>\n",
+ inet_ntoa(p->ip), question->name, question->name_type));
if (search == 0)
{
success = False;
}
- if (success && (n = search_for_name(&d,question,p->ip,p->timestamp, search)))
+ if (success)
{
- /* don't respond to broadcast queries unless the query is for
- a name we own or it is for a Primary Domain Controller name */
+ /* look up the name in the cache */
+ n = find_name_search(&d, question, search, p->ip);
- if (bcast && n->source != SELF && name_type != 0x1b) {
- if (!lp_wins_proxy() || same_net(p->ip,n->ip_flgs[0].ip,*iface_nmask(p->ip))) {
+ /* it is a name that already failed DNS lookup or it's expired */
+ if (n && (n->source == DNSFAIL ||
+ (n->death_time && n->death_time < p->timestamp)))
+ {
+ success = False;
+ }
+
+ /* do we want to do dns lookups? */
+ /* XXXX this DELAYS nmbd while it does a search. not a good idea
+ but there's no pleasant alternative. phil@hands.com suggested
+ making the name a full DNS name, which would succeed / fail
+ much quicker.
+ */
+ if (success && !n && (lp_wins_proxy() || !bcast))
+ {
+ n = dns_name_search(question, p->timestamp);
+ }
+ }
+
+ if (!n) success = False;
+
+ if (success)
+ {
+ if (bcast && n->source != SELF && name_type != 0x1b)
+ {
+ /* don't respond to broadcast queries unless the query is for
+ a name we own or it is for a Primary Domain Controller name */
+
+ if (!lp_wins_proxy() ||
+ same_net(p->ip,n->ip_flgs[0].ip,*iface_nmask(p->ip)))
+ {
/* never reply with a negative response to broadcast queries */
return;
}
retip = n->ip_flgs[0].ip;
nb_flags = n->ip_flgs[0].nb_flags;
}
- else
- {
- if (bcast) return; /* never reply negative response to bcasts */
- success = False;
- }
-
+
+ if (!success && bcast) return; /* never reply negative response to bcasts */
+
/* if the IP is 0 then substitute my IP */
if (zero_ip(retip)) retip = *iface_ip(p->ip);
reply_netbios_packet(p,nmb->header.name_trn_id,
rcode,NMB_QUERY,0,True,
&nmb->question.question_name,
- nmb->question.question_type,
- nmb->question.question_class,
+ 0x20, 0x01,
ttl,
rdata, success ? 6 : 0);
}
-
-