mirror of
https://github.com/samba-team/samba.git
synced 2025-12-20 16:23:51 +03:00
Wed May 7 1997: Update for 1.9.17alpha1 release - 'browsefix release' designed to make browsing across subnets work. byteorder.h: Updated copyright to 1997. charcnv.c: Updated copyright to 1997. charset.c Updated copyright to 1997. charset.h Updated copyright to 1997. client.c Updated copyright to 1997. clientutil.c Updated copyright to 1997. dir.c Updated copyright to 1997. fault.c Updated copyright to 1997. includes.h Updated copyright to 1997. interface.c Updated copyright to 1997. ipc.c Updated copyright to 1997. kanji.c Updated copyright to 1997. kanji.h Updated copyright to 1997. loadparm.c Updated copyright to 1997. locking.c Updated copyright to 1997. mangle.c Updated copyright to 1997. message.c Updated copyright to 1997. nameannounce.c Made use of WINS subnet explicit. Added reset_announce_timer() so announcement can be made immediately when we become a master. Expanded code to do sync with dmb. namebrowse.c Removed redundent checks for AM_MASTER in sync code. Made use of WINS subnet explicit. namedbname.c Made use of WINS subnet explicit. namedbresp.c Made use of WINS subnet explicit. namedbserver.c Made use of WINS subnet explicit. namedbsubnet.c Explicitly add workgroup to WINS subnet when we become a dmb. Made use of WINS subnet explicit. namedbwork.c Made use of WINS subnet explicit. Removed redundent check_work_servertype() function. nameelect.c Explicitly add workgroup to WINS subnet when we become a master browser. Made use of WINS subnet explicit. namelogon.c Updated copyright to 1997. namepacket.c Updated copyright to 1997. namequery.c Updated copyright to 1997. nameresp.c Made use of WINS subnet explicit. Made nmbd fail if configured as master browser and one exists already. nameserv.c Made use of WINS subnet explicit. Remove redundent logon server and domain master code. nameserv.h Add emumerate subnet macros. nameservreply.c Made use of WINS subnet explicit. nameservresp.c Updated copyright to 1997. namework.c Made use of WINS subnet explicit. Updated code to add sync browser entries to add subnet parameter. nmbd.c Added sanity check for misconfigured nmbd. nmblib.c Updated copyright to 1997. nmblookup.c Updated copyright to 1997. nmbsync.c Removed redundent AM_ANY_MASTER check. params.c Updated copyright to 1997. password.c Updated copyright to 1997. pipes.c Updated copyright to 1997. predict.c Updated copyright to 1997. printing.c Updated copyright to 1997. proto.h Changed protos for new nmbd code. quotas.c Updated copyright to 1997. replace.c Updated copyright to 1997. reply.c Updated copyright to 1997. server.c Updated copyright to 1997. shmem.c Updated copyright to 1997. smb.h Updated copyright to 1997. smbencrypt.c Updated copyright to 1997. smbpasswd.c Updated copyright to 1997. smbrun.c Updated copyright to 1997. status.c Updated copyright to 1997. system.c Updated copyright to 1997. testparm.c Updated copyright to 1997. testprns.c Updated copyright to 1997. time.c Updated copyright to 1997. trans2.c Updated copyright to 1997. trans2.h Updated copyright to 1997. uid.c Updated copyright to 1997. username.c Updated copyright to 1997. util.c Updated copyright to 1997. version.h Changed to 1.9.17alpha1.
-
296 lines
7.8 KiB
C
296 lines
7.8 KiB
C
/*
|
|
Unix SMB/Netbios implementation.
|
|
Version 1.9.
|
|
name query routines
|
|
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
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
|
|
|
#include "includes.h"
|
|
|
|
extern pstring scope;
|
|
extern int DEBUGLEVEL;
|
|
|
|
|
|
/****************************************************************************
|
|
interpret a node status response
|
|
****************************************************************************/
|
|
static void _interpret_node_status(char *p, char *master,char *rname)
|
|
{
|
|
int numnames = CVAL(p,0);
|
|
DEBUG(1,("received %d names\n",numnames));
|
|
|
|
if (rname) *rname = 0;
|
|
if (master) *master = 0;
|
|
|
|
p += 1;
|
|
while (numnames--)
|
|
{
|
|
char qname[17];
|
|
int type;
|
|
fstring flags;
|
|
int i;
|
|
*flags = 0;
|
|
StrnCpy(qname,p,15);
|
|
type = CVAL(p,15);
|
|
p += 16;
|
|
|
|
strcat(flags, (p[0] & 0x80) ? "<GROUP> " : " ");
|
|
if ((p[0] & 0x60) == 0x00) strcat(flags,"B ");
|
|
if ((p[0] & 0x60) == 0x20) strcat(flags,"P ");
|
|
if ((p[0] & 0x60) == 0x40) strcat(flags,"M ");
|
|
if ((p[0] & 0x60) == 0x60) strcat(flags,"H ");
|
|
if (p[0] & 0x10) strcat(flags,"<DEREGISTERING> ");
|
|
if (p[0] & 0x08) strcat(flags,"<CONFLICT> ");
|
|
if (p[0] & 0x04) strcat(flags,"<ACTIVE> ");
|
|
if (p[0] & 0x02) strcat(flags,"<PERMANENT> ");
|
|
|
|
if (master && !*master && type == 0x1d) {
|
|
StrnCpy(master,qname,15);
|
|
trim_string(master,NULL," ");
|
|
}
|
|
|
|
if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) {
|
|
StrnCpy(rname,qname,15);
|
|
trim_string(rname,NULL," ");
|
|
}
|
|
|
|
for (i = strlen( qname) ; --i >= 0 ; ) {
|
|
if (!isprint(qname[i])) qname[i] = '.';
|
|
}
|
|
DEBUG(1,("\t%-15s <%02x> - %s\n",qname,type,flags));
|
|
p+=2;
|
|
}
|
|
DEBUG(1,("num_good_sends=%d num_good_receives=%d\n",
|
|
IVAL(p,20),IVAL(p,24)));
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
do a netbios name status query on a host
|
|
|
|
the "master" parameter is a hack used for finding workgroups.
|
|
**************************************************************************/
|
|
BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
|
|
struct in_addr to_ip,char *master,char *rname,
|
|
void (*fn)())
|
|
{
|
|
BOOL found=False;
|
|
int retries = 2;
|
|
int retry_time = 5000;
|
|
struct timeval tval;
|
|
struct packet_struct p;
|
|
struct packet_struct *p2;
|
|
struct nmb_packet *nmb = &p.packet.nmb;
|
|
static int name_trn_id = 0;
|
|
|
|
bzero((char *)&p,sizeof(p));
|
|
|
|
if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) +
|
|
(getpid()%(unsigned)100);
|
|
name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
|
|
|
|
nmb->header.name_trn_id = name_trn_id;
|
|
nmb->header.opcode = 0;
|
|
nmb->header.response = False;
|
|
nmb->header.nm_flags.bcast = False;
|
|
nmb->header.nm_flags.recursion_available = False;
|
|
nmb->header.nm_flags.recursion_desired = False;
|
|
nmb->header.nm_flags.trunc = False;
|
|
nmb->header.nm_flags.authoritative = False;
|
|
nmb->header.rcode = 0;
|
|
nmb->header.qdcount = 1;
|
|
nmb->header.ancount = 0;
|
|
nmb->header.nscount = 0;
|
|
nmb->header.arcount = 0;
|
|
|
|
make_nmb_name(&nmb->question.question_name,name,name_type,scope);
|
|
|
|
nmb->question.question_type = 0x21;
|
|
nmb->question.question_class = 0x1;
|
|
|
|
p.ip = to_ip;
|
|
p.port = NMB_PORT;
|
|
p.fd = fd;
|
|
p.timestamp = time(NULL);
|
|
p.packet_type = NMB_PACKET;
|
|
|
|
GetTimeOfDay(&tval);
|
|
|
|
if (!send_packet(&p))
|
|
return(False);
|
|
|
|
retries--;
|
|
|
|
while (1)
|
|
{
|
|
struct timeval tval2;
|
|
GetTimeOfDay(&tval2);
|
|
if (TvalDiff(&tval,&tval2) > retry_time) {
|
|
if (!retries) break;
|
|
if (!found && !send_packet(&p))
|
|
return False;
|
|
GetTimeOfDay(&tval);
|
|
retries--;
|
|
}
|
|
|
|
if ((p2=receive_packet(fd,NMB_PACKET,90)))
|
|
{
|
|
struct nmb_packet *nmb2 = &p2->packet.nmb;
|
|
debug_nmb_packet(p2);
|
|
|
|
if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
|
|
!nmb2->header.response) {
|
|
/* its not for us - maybe deal with it later */
|
|
if (fn)
|
|
fn(p2);
|
|
else
|
|
free_packet(p2);
|
|
continue;
|
|
}
|
|
|
|
if (nmb2->header.opcode != 0 ||
|
|
nmb2->header.nm_flags.bcast ||
|
|
nmb2->header.rcode ||
|
|
!nmb2->header.ancount ||
|
|
nmb2->answers->rr_type != 0x21) {
|
|
/* XXXX what do we do with this? could be a redirect, but
|
|
we'll discard it for the moment */
|
|
free_packet(p2);
|
|
continue;
|
|
}
|
|
|
|
_interpret_node_status(&nmb2->answers->rdata[0], master,rname);
|
|
free_packet(p2);
|
|
return(True);
|
|
}
|
|
}
|
|
|
|
|
|
DEBUG(0,("No status response (this is not unusual)\n"));
|
|
|
|
return(False);
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
do a netbios name query to find someones IP
|
|
****************************************************************************/
|
|
BOOL name_query(int fd,char *name,int name_type,
|
|
BOOL bcast,BOOL recurse,
|
|
struct in_addr to_ip, struct in_addr *ip,void (*fn)())
|
|
{
|
|
BOOL found=False;
|
|
int retries = 3;
|
|
int retry_time = bcast?250:2000;
|
|
struct timeval tval;
|
|
struct packet_struct p;
|
|
struct packet_struct *p2;
|
|
struct nmb_packet *nmb = &p.packet.nmb;
|
|
static int name_trn_id = 0;
|
|
|
|
bzero((char *)&p,sizeof(p));
|
|
|
|
if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) +
|
|
(getpid()%(unsigned)100);
|
|
name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
|
|
|
|
nmb->header.name_trn_id = name_trn_id;
|
|
nmb->header.opcode = 0;
|
|
nmb->header.response = False;
|
|
nmb->header.nm_flags.bcast = bcast;
|
|
nmb->header.nm_flags.recursion_available = False;
|
|
nmb->header.nm_flags.recursion_desired = True;
|
|
nmb->header.nm_flags.trunc = False;
|
|
nmb->header.nm_flags.authoritative = False;
|
|
nmb->header.rcode = 0;
|
|
nmb->header.qdcount = 1;
|
|
nmb->header.ancount = 0;
|
|
nmb->header.nscount = 0;
|
|
nmb->header.arcount = 0;
|
|
|
|
make_nmb_name(&nmb->question.question_name,name,name_type,scope);
|
|
|
|
nmb->question.question_type = 0x20;
|
|
nmb->question.question_class = 0x1;
|
|
|
|
p.ip = to_ip;
|
|
p.port = NMB_PORT;
|
|
p.fd = fd;
|
|
p.timestamp = time(NULL);
|
|
p.packet_type = NMB_PACKET;
|
|
|
|
GetTimeOfDay(&tval);
|
|
|
|
if (!send_packet(&p))
|
|
return(False);
|
|
|
|
retries--;
|
|
|
|
while (1)
|
|
{
|
|
struct timeval tval2;
|
|
GetTimeOfDay(&tval2);
|
|
if (TvalDiff(&tval,&tval2) > retry_time) {
|
|
if (!retries) break;
|
|
if (!found && !send_packet(&p))
|
|
return False;
|
|
GetTimeOfDay(&tval);
|
|
retries--;
|
|
}
|
|
|
|
if ((p2=receive_packet(fd,NMB_PACKET,90)))
|
|
{
|
|
struct nmb_packet *nmb2 = &p2->packet.nmb;
|
|
debug_nmb_packet(p2);
|
|
|
|
if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
|
|
!nmb2->header.response) {
|
|
/* its not for us - maybe deal with it later
|
|
(put it on the queue?) */
|
|
if (fn)
|
|
fn(p2);
|
|
else
|
|
free_packet(p2);
|
|
continue;
|
|
}
|
|
|
|
if (nmb2->header.opcode != 0 ||
|
|
nmb2->header.nm_flags.bcast ||
|
|
nmb2->header.rcode ||
|
|
!nmb2->header.ancount) {
|
|
/* XXXX what do we do with this? could be a redirect, but
|
|
we'll discard it for the moment */
|
|
free_packet(p2);
|
|
continue;
|
|
}
|
|
|
|
if (ip) {
|
|
putip((char *)ip,&nmb2->answers->rdata[2]);
|
|
DEBUG(fn?3:2,("Got a positive name query response from %s",
|
|
inet_ntoa(p2->ip)));
|
|
DEBUG(fn?3:2,(" (%s)\n",inet_ntoa(*ip)));
|
|
}
|
|
found=True; retries=0;
|
|
free_packet(p2);
|
|
if (fn) break;
|
|
}
|
|
}
|
|
|
|
return(found);
|
|
}
|