1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-26 21:57:41 +03:00

- bit a bit manipulation bug in find_name_search()

- add the * and __SAMBA__ names to all subnets

- sort the name status reply list and remove duplicate entries.
(This used to be commit 04353a9479c01322e34b2f59330fd74a759f6869)
This commit is contained in:
Andrew Tridgell 1996-08-21 08:30:29 +00:00
parent ac1f8b11dc
commit 044b403a9a
3 changed files with 81 additions and 47 deletions

View File

@ -173,27 +173,25 @@ struct name_record *find_name_search(struct subnet_record **d,
{
if (d == NULL) return NULL; /* bad error! */
if ((search & FIND_LOCAL) == FIND_LOCAL)
{
if (*d != NULL)
{
struct name_record *n = find_name((*d)->namelist, name, search);
DEBUG(4,("find_name on local: %s %s search %x\n",
namestr(name),inet_ntoa(ip), search));
if (n) return n;
}
}
if (search & FIND_LOCAL) {
if (*d != NULL) {
struct name_record *n = find_name((*d)->namelist, name, search);
DEBUG(4,("find_name on local: %s %s search %x\n",
namestr(name),inet_ntoa(ip), search));
if (n) return n;
}
}
if ((search & FIND_WINS) != FIND_WINS) return NULL;
if (!(search & FIND_WINS)) return NULL;
/* find WINS subnet record. */
*d = find_subnet(ipgrp);
if (*d == NULL) return NULL;
DEBUG(4,("find_name on WINS: %s %s search %x\n",
namestr(name),inet_ntoa(ip), search));
return find_name((*d)->namelist, name, search);
/* find WINS subnet record. */
*d = find_subnet(ipgrp);
if (*d == NULL) return NULL;
DEBUG(4,("find_name on WINS: %s %s search %x\n",
namestr(name),inet_ntoa(ip), search));
return find_name((*d)->namelist, name, search);
}

View File

@ -160,11 +160,7 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
**************************************************************************/
void add_my_names(void)
{
BOOL wins = lp_wins_support();
struct subnet_record *d;
struct in_addr ip = ipzero;
/* each subnet entry, including WINS pseudo-subnet, has SELF names */
/* XXXX if there was a transport layer added to samba (ipx/spx etc) then
@ -173,20 +169,23 @@ void add_my_names(void)
for (d = subnetlist; d; d = d->next)
{
add_my_name_entry(d, myname,0x20,nb_type|NB_ACTIVE);
add_my_name_entry(d, myname,0x03,nb_type|NB_ACTIVE);
add_my_name_entry(d, myname,0x00,nb_type|NB_ACTIVE);
add_my_name_entry(d, myname,0x1f,nb_type|NB_ACTIVE);
BOOL wins = lp_wins_support() && ip_equal(d->bcast_ip,ipgrp);
add_my_name_entry(d, myname,0x20,nb_type|NB_ACTIVE);
add_my_name_entry(d, myname,0x03,nb_type|NB_ACTIVE);
add_my_name_entry(d, myname,0x00,nb_type|NB_ACTIVE);
add_my_name_entry(d, myname,0x1f,nb_type|NB_ACTIVE);
/* these names are added permanently (ttl of zero) and will NOT be
refreshed with the WINS server */
add_netbios_entry(d,"*",0x0,nb_type|NB_ACTIVE,0,SELF,ip,False,wins);
add_netbios_entry(d,"__SAMBA__",0x20,nb_type|NB_ACTIVE,0,SELF,ip,False,wins);
add_netbios_entry(d,"__SAMBA__",0x00,nb_type|NB_ACTIVE,0,SELF,ip,False,wins);
add_netbios_entry(d,"*",0x0,nb_type|NB_ACTIVE,0,SELF,d->myip,False,wins);
add_netbios_entry(d,"*",0x20,nb_type|NB_ACTIVE,0,SELF,d->myip,False,wins);
add_netbios_entry(d,"__SAMBA__",0x20,nb_type|NB_ACTIVE,0,SELF,d->myip,False,wins);
add_netbios_entry(d,"__SAMBA__",0x00,nb_type|NB_ACTIVE,0,SELF,d->myip,False,wins);
if (lp_domain_logons()) {
/* XXXX the 0x1c is apparently something to do with domain logons */
add_my_name_entry(d, lp_workgroup(),0x1c,nb_type|NB_ACTIVE|NB_GROUP);
/* XXXX the 0x1c is apparently something to do with domain logons */
add_my_name_entry(d, lp_workgroup(),0x1c,nb_type|NB_ACTIVE|NB_GROUP);
}
}
if (lp_domain_master() && (d = find_subnet(ipgrp)))

View File

@ -310,6 +310,29 @@ void reply_name_reg(struct packet_struct *p)
}
}
/* this is used to sort names for a name status into a sensible order
we put our own names first, then in alphabetical order */
static int status_compare(char *n1,char *n2)
{
extern pstring myname;
int l1,l2,l3;
/* its a bit tricky because the names are space padded */
for (l1=0;l1<15 && n1[l1] && n1[l1] != ' ';l1++) ;
for (l2=0;l2<15 && n2[l2] && n2[l2] != ' ';l2++) ;
l3 = strlen(myname);
if ((l1==l3) && strncmp(n1,myname,l3) == 0 &&
(l2!=l3 || strncmp(n2,myname,l3) != 0))
return -1;
if ((l2==l3) && strncmp(n2,myname,l3) == 0 &&
(l1!=l3 || strncmp(n1,myname,l3) != 0))
return 1;
return memcmp(n1,n2,18);
}
/****************************************************************************
reply to a name status query
@ -323,15 +346,14 @@ void reply_name_status(struct packet_struct *p)
char *qname = nmb->question.question_name.name;
int ques_type = nmb->question.question_name.name_type;
char rdata[MAX_DGRAM_SIZE];
char *countptr, *buf, *bufend;
int names_added;
char *countptr, *buf, *bufend, *buf0;
int names_added,i;
struct name_record *n;
struct subnet_record *d = NULL;
int search = FIND_SELF | FIND_WINS;
int search = FIND_SELF | FIND_WINS | FIND_LOCAL;
BOOL bcast = nmb->header.nm_flags.bcast;
if (!(d = find_req_subnet(p->ip, bcast)))
/* NOTE: we always treat a name status lookup as a bcast */
if (!(d = find_req_subnet(p->ip, True)))
{
DEBUG(3,("Name status req: bcast %s not known\n",
inet_ntoa(p->ip)));
@ -339,10 +361,8 @@ void reply_name_status(struct packet_struct *p)
}
DEBUG(3,("Name status for name %s %s\n",
namestr(&nmb->question.question_name), inet_ntoa(p->ip)));
if (bcast)
search |= FIND_LOCAL;
namestr(&nmb->question.question_name),
inet_ntoa(p->ip)));
n = find_name_search(&d, &nmb->question.question_name,
search, p->ip);
@ -353,7 +373,8 @@ void reply_name_status(struct packet_struct *p)
bufend = &rdata[MAX_DGRAM_SIZE] - 18;
countptr = buf = rdata;
buf += 1;
buf0 = buf;
names_added = 0;
n = d->namelist;
@ -368,9 +389,11 @@ void reply_name_status(struct packet_struct *p)
from the response. if we don't exclude them, windows clients
get confused and will respond with an error for NET VIEW */
if (name_type < 0x1b || name_type > 0x20 ||
ques_type < 0x1b || ques_type > 0x20 ||
strequal(qname, n->name.name))
if (!strequal(n->name.name,"*") &&
!strequal(n->name.name,"__SAMBA__") &&
(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 */
bzero(buf,18);
@ -387,6 +410,20 @@ void reply_name_status(struct packet_struct *p)
}
}
/* remove duplicate names */
qsort(buf0,names_added,18,QSORT_CAST status_compare);
for (i=1;i<names_added;i++) {
if (memcmp(buf0 + 18*i,buf0 + 18*(i-1),16) == 0) {
names_added--;
if (names_added == i) break;
memmove(buf0 + 18*i,buf0 + 18*(i+1),18*(names_added-i));
i--;
}
}
buf = buf0 + 18*names_added;
n = n->next;
if (!n)