diff options
author | Andrew Tridgell <tridge@samba.org> | 1996-08-21 08:30:29 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 1996-08-21 08:30:29 +0000 |
commit | 04353a9479c01322e34b2f59330fd74a759f6869 (patch) | |
tree | 8430087a40a564c0867bea562654bb0670ddba63 /source/nameservreply.c | |
parent | 07b0cf29d345d2f880a45d8bcbfec8355f1f83ef (diff) | |
download | samba-04353a9479c01322e34b2f59330fd74a759f6869.tar.gz |
- 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.
Diffstat (limited to 'source/nameservreply.c')
-rw-r--r-- | source/nameservreply.c | 65 |
1 files changed, 51 insertions, 14 deletions
diff --git a/source/nameservreply.c b/source/nameservreply.c index b77f9958b81..b01c2c25b4c 100644 --- a/source/nameservreply.c +++ b/source/nameservreply.c @@ -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) |