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:
parent
ac1f8b11dc
commit
044b403a9a
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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)))
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user