summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2003-08-27 01:25:01 +0000
committerJeremy Allison <jra@samba.org>2003-08-27 01:25:01 +0000
commit9fdc1363bec6ae9a0a0f9a37130b98a92ebe8ce2 (patch)
treea3f5b31cb23487dab3c01bb3eeb1a65c5a675afe /source3
parent7e27147422e78125c2bb5b8115bd9084a657e084 (diff)
downloadsamba-9fdc1363bec6ae9a0a0f9a37130b98a92ebe8ce2.tar.gz
samba-9fdc1363bec6ae9a0a0f9a37130b98a92ebe8ce2.tar.bz2
samba-9fdc1363bec6ae9a0a0f9a37130b98a92ebe8ce2.zip
Fix the character set handling properly in nmbd. Also fix bug where
iconv wasn't re-initialised on reading of "charset" parameters. This caused workgroup name to be set incorrectly if it contained an extended character. Jeremy. (This used to be commit 84ae44678a6c59c999bc1023fdd9b7ad87f4ec18)
Diffstat (limited to 'source3')
-rw-r--r--source3/libsmb/nmblib.c3
-rw-r--r--source3/nmbd/asyncdns.c73
-rw-r--r--source3/nmbd/nmbd.c3
-rw-r--r--source3/nmbd/nmbd_elections.c1
-rw-r--r--source3/nmbd/nmbd_incomingrequests.c606
-rw-r--r--source3/nmbd/nmbd_lmhosts.c91
-rw-r--r--source3/nmbd/nmbd_logonnames.c195
-rw-r--r--source3/nmbd/nmbd_mynames.c184
-rw-r--r--source3/nmbd/nmbd_namelistdb.c800
-rw-r--r--source3/nmbd/nmbd_namequery.c410
-rw-r--r--source3/nmbd/nmbd_nameregister.c28
-rw-r--r--source3/nmbd/nmbd_nodestatus.c68
-rw-r--r--source3/nmbd/nmbd_packets.c2499
-rw-r--r--source3/nmbd/nmbd_processlogon.c813
-rw-r--r--source3/nmbd/nmbd_responserecordsdb.c318
-rw-r--r--source3/nmbd/nmbd_sendannounce.c765
-rw-r--r--source3/nmbd/nmbd_serverlistdb.c520
-rw-r--r--source3/nmbd/nmbd_subnetdb.c395
-rw-r--r--source3/nmbd/nmbd_synclists.c29
-rw-r--r--source3/nmbd/nmbd_winsproxy.c260
-rw-r--r--source3/nmbd/nmbd_winsserver.c2649
-rw-r--r--source3/nmbd/nmbd_workgroupdb.c357
-rw-r--r--source3/param/loadparm.c15
23 files changed, 5337 insertions, 5745 deletions
diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c
index 23eac9ad7c..ff38245435 100644
--- a/source3/libsmb/nmblib.c
+++ b/source3/libsmb/nmblib.c
@@ -825,8 +825,7 @@ void make_nmb_name( struct nmb_name *n, const char *name, int type)
memset( (char *)n, '\0', sizeof(struct nmb_name) );
push_ascii(n->name, name, sizeof(n->name), STR_TERMINATE|STR_UPPER);
n->name_type = (unsigned int)type & 0xFF;
- StrnCpy( n->scope, global_scope(), 63 );
- strupper_m( n->scope );
+ push_ascii(n->scope, global_scope(), 64, STR_TERMINATE);
}
/*******************************************************************
diff --git a/source3/nmbd/asyncdns.c b/source3/nmbd/asyncdns.c
index c86ee69a09..6d5d487b11 100644
--- a/source3/nmbd/asyncdns.c
+++ b/source3/nmbd/asyncdns.c
@@ -26,26 +26,25 @@
static struct name_record *add_dns_result(struct nmb_name *question, struct in_addr addr)
{
- int name_type = question->name_type;
- char *qname = question->name;
-
+ int name_type = question->name_type;
+ nstring qname;
+
+ pull_ascii_nstring(qname, question->name);
- if (!addr.s_addr) {
- /* add the fail to WINS cache of names. give it 1 hour in the cache */
- DEBUG(3,("add_dns_result: Negative DNS answer for %s\n", qname));
- (void)add_name_to_subnet( wins_server_subnet, qname, name_type,
- NB_ACTIVE, 60*60, DNSFAIL_NAME, 1, &addr );
- return( NULL );
- }
-
- /* add it to our WINS cache of names. give it 2 hours in the cache */
- DEBUG(3,("add_dns_result: DNS gave answer for %s of %s\n", qname, inet_ntoa(addr)));
-
- return( add_name_to_subnet( wins_server_subnet, qname, name_type,
- NB_ACTIVE, 2*60*60, DNS_NAME, 1, &addr ) );
-}
+ if (!addr.s_addr) {
+ /* add the fail to WINS cache of names. give it 1 hour in the cache */
+ DEBUG(3,("add_dns_result: Negative DNS answer for %s\n", qname));
+ (void)add_name_to_subnet( wins_server_subnet, qname, name_type,
+ NB_ACTIVE, 60*60, DNSFAIL_NAME, 1, &addr );
+ return( NULL );
+ }
+ /* add it to our WINS cache of names. give it 2 hours in the cache */
+ DEBUG(3,("add_dns_result: DNS gave answer for %s of %s\n", qname, inet_ntoa(addr)));
+ return( add_name_to_subnet( wins_server_subnet, qname, name_type,
+ NB_ACTIVE, 2*60*60, DNS_NAME, 1, &addr ) );
+}
#ifndef SYNC_DNS
@@ -70,6 +69,7 @@ static struct packet_struct *dns_current;
return the fd used to gather async dns replies. This is added to the select
loop
****************************************************************************/
+
int asyncdns_fd(void)
{
return fd_in;
@@ -110,7 +110,7 @@ static void asyncdns_process(void)
static void sig_term(int sig)
{
- _exit(0);
+ _exit(0);
}
/***************************************************************************
@@ -224,10 +224,10 @@ void run_dns_queue(void)
if (query_current(&r)) {
DEBUG(3,("DNS calling send_wins_name_query_response\n"));
in_dns = 1;
- if(namerec == NULL)
- send_wins_name_query_response(NAM_ERR, dns_current, NULL);
- else
- send_wins_name_query_response(0,dns_current,namerec);
+ if(namerec == NULL)
+ send_wins_name_query_response(NAM_ERR, dns_current, NULL);
+ else
+ send_wins_name_query_response(0,dns_current,namerec);
in_dns = 0;
}
@@ -245,10 +245,10 @@ void run_dns_queue(void)
if (nmb_name_equal(question, &r.name)) {
DEBUG(3,("DNS calling send_wins_name_query_response\n"));
in_dns = 1;
- if(namerec == NULL)
- send_wins_name_query_response(NAM_ERR, p, NULL);
- else
- send_wins_name_query_response(0,p,namerec);
+ if(namerec == NULL)
+ send_wins_name_query_response(NAM_ERR, p, NULL);
+ else
+ send_wins_name_query_response(0,p,namerec);
in_dns = 0;
p->locked = False;
@@ -269,7 +269,8 @@ void run_dns_queue(void)
if (dns_queue) {
dns_current = dns_queue;
dns_queue = dns_queue->next;
- if (dns_queue) dns_queue->prev = NULL;
+ if (dns_queue)
+ dns_queue->prev = NULL;
dns_current->next = NULL;
if (!write_child(dns_current)) {
@@ -277,12 +278,12 @@ void run_dns_queue(void)
return;
}
}
-
}
/***************************************************************************
queue a DNS query
****************************************************************************/
+
BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
struct name_record **n)
{
@@ -315,11 +316,14 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
/***************************************************************************
we use this when we can't do async DNS lookups
****************************************************************************/
+
BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
struct name_record **n)
{
- char *qname = question->name;
struct in_addr dns_ip;
+ nstring qname;
+
+ pull_ascii_nstring(qname, question->name);
DEBUG(3,("DNS search for %s - ", nmb_namestr(question)));
@@ -332,18 +336,19 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
BlockSignals(True, SIGTERM);
*n = add_dns_result(question, dns_ip);
- if(*n == NULL)
- send_wins_name_query_response(NAM_ERR, p, NULL);
- else
- send_wins_name_query_response(0, p, *n);
+ if(*n == NULL)
+ send_wins_name_query_response(NAM_ERR, p, NULL);
+ else
+ send_wins_name_query_response(0, p, *n);
return False;
}
/***************************************************************************
With sync dns there is no child to kill on SIGTERM.
****************************************************************************/
+
void kill_async_dns_child(void)
{
- return;
+ return;
}
#endif
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index c33011a417..25ba07c8a7 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -231,7 +231,8 @@ static BOOL reload_interfaces(time_t t)
DEBUG(2,("Found new interface %s\n",
inet_ntoa(iface->ip)));
subrec = make_normal_subnet(iface);
- if (subrec) register_my_workgroup_one_subnet(subrec);
+ if (subrec)
+ register_my_workgroup_one_subnet(subrec);
}
}
diff --git a/source3/nmbd/nmbd_elections.c b/source3/nmbd/nmbd_elections.c
index 09ab9ee783..d4d6da081a 100644
--- a/source3/nmbd/nmbd_elections.c
+++ b/source3/nmbd/nmbd_elections.c
@@ -51,6 +51,7 @@ static void send_election_dgram(struct subnet_record *subrec, const char *workgr
p += 13;
fstrcpy(srv_name, server_name);
strupper_m(srv_name);
+ /* The following call does UNIX -> DOS charset conversion. */
pstrcpy_base(p, srv_name, outbuf);
p = skip_string(p,1);
diff --git a/source3/nmbd/nmbd_incomingrequests.c b/source3/nmbd/nmbd_incomingrequests.c
index a3faf5e104..dd999fbdf7 100644
--- a/source3/nmbd/nmbd_incomingrequests.c
+++ b/source3/nmbd/nmbd_incomingrequests.c
@@ -3,7 +3,7 @@
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Jeremy Allison 1994-2003
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
@@ -33,18 +33,18 @@ Send a name release response.
static void send_name_release_response(int rcode, struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- char rdata[6];
+ struct nmb_packet *nmb = &p->packet.nmb;
+ char rdata[6];
- memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
+ memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
- reply_netbios_packet(p, /* Packet to reply to. */
- rcode, /* Result code. */
- NMB_REL, /* nmbd type code. */
- NMB_NAME_RELEASE_OPCODE, /* opcode. */
- 0, /* ttl. */
- rdata, /* data to send. */
- 6); /* data length. */
+ reply_netbios_packet(p, /* Packet to reply to. */
+ rcode, /* Result code. */
+ NMB_REL, /* nmbd type code. */
+ NMB_NAME_RELEASE_OPCODE, /* opcode. */
+ 0, /* ttl. */
+ rdata, /* data to send. */
+ 6); /* data length. */
}
/****************************************************************************
@@ -55,76 +55,74 @@ Ignore it if it's not one of our names.
void process_name_release_request(struct subnet_record *subrec,
struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct in_addr owner_ip;
- struct nmb_name *question = &nmb->question.question_name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
- BOOL group = (nb_flags & NB_GROUP) ? True : False;
- struct name_record *namerec;
- int rcode = 0;
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct in_addr owner_ip;
+ struct nmb_name *question = &nmb->question.question_name;
+ nstring qname;
+ BOOL bcast = nmb->header.nm_flags.bcast;
+ uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
+ BOOL group = (nb_flags & NB_GROUP) ? True : False;
+ struct name_record *namerec;
+ int rcode = 0;
- putip((char *)&owner_ip,&nmb->additional->rdata[2]);
+ putip((char *)&owner_ip,&nmb->additional->rdata[2]);
- if(!bcast)
- {
- /* We should only get broadcast name release packets here.
- Anyone trying to release unicast should be going to a WINS
- server. If the code gets here, then either we are not a wins
- server and they sent it anyway, or we are a WINS server and
- the request was malformed. Either way, log an error here.
- and send an error reply back.
- */
- DEBUG(0,("process_name_release_request: unicast name release request \
+ if(!bcast) {
+ /* We should only get broadcast name release packets here.
+ Anyone trying to release unicast should be going to a WINS
+ server. If the code gets here, then either we are not a wins
+ server and they sent it anyway, or we are a WINS server and
+ the request was malformed. Either way, log an error here.
+ and send an error reply back.
+ */
+ DEBUG(0,("process_name_release_request: unicast name release request \
received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n",
- nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name));
+ nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name));
- send_name_release_response(FMT_ERR, p);
- return;
- }
+ send_name_release_response(FMT_ERR, p);
+ return;
+ }
- DEBUG(3,("process_name_release_request: Name release on name %s, \
+ DEBUG(3,("process_name_release_request: Name release on name %s, \
subnet %s from owner IP %s\n",
- nmb_namestr(&nmb->question.question_name),
- subrec->subnet_name, inet_ntoa(owner_ip)));
+ nmb_namestr(&nmb->question.question_name),
+ subrec->subnet_name, inet_ntoa(owner_ip)));
- /* If someone is releasing a broadcast group name, just ignore it. */
- if( group && !ismyip(owner_ip) )
- return;
-
- /*
- * Code to work around a bug in FTP OnNet software NBT implementation.
- * They do a broadcast name release for WORKGROUP<0> and WORKGROUP<1e>
- * names and *don't set the group bit* !!!!!
- */
-
- if( !group && !ismyip(owner_ip) && strequal(question->name, lp_workgroup()) &&
- ((question->name_type == 0x0) || (question->name_type == 0x1e)))
- {
- DEBUG(6,("process_name_release_request: FTP OnNet bug workaround. Ignoring \
+ /* If someone is releasing a broadcast group name, just ignore it. */
+ if( group && !ismyip(owner_ip) )
+ return;
+
+ /*
+ * Code to work around a bug in FTP OnNet software NBT implementation.
+ * They do a broadcast name release for WORKGROUP<0> and WORKGROUP<1e>
+ * names and *don't set the group bit* !!!!!
+ */
+
+ pull_ascii_nstring(qname, question->name);
+ if( !group && !ismyip(owner_ip) && strequal(qname, lp_workgroup()) &&
+ ((question->name_type == 0x0) || (question->name_type == 0x1e))) {
+ DEBUG(6,("process_name_release_request: FTP OnNet bug workaround. Ignoring \
group release name %s from IP %s on subnet %s with no group bit set.\n",
- nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name ));
- return;
- }
-
- namerec = find_name_on_subnet(subrec, &nmb->question.question_name, FIND_ANY_NAME);
-
- /* We only care about someone trying to release one of our names. */
- if( namerec
- && ( (namerec->data.source == SELF_NAME)
- || (namerec->data.source == PERMANENT_NAME) ) )
- {
- rcode = ACT_ERR;
- DEBUG(0, ("process_name_release_request: Attempt to release name %s from IP %s \
+ nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name ));
+ return;
+ }
+
+ namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
+
+ /* We only care about someone trying to release one of our names. */
+ if( namerec && ( (namerec->data.source == SELF_NAME)
+ || (namerec->data.source == PERMANENT_NAME) ) ) {
+ rcode = ACT_ERR;
+ DEBUG(0, ("process_name_release_request: Attempt to release name %s from IP %s \
on subnet %s being rejected as it is one of our names.\n",
- nmb_namestr(&nmb->question.question_name), inet_ntoa(owner_ip), subrec->subnet_name));
- }
+ nmb_namestr(&nmb->question.question_name), inet_ntoa(owner_ip), subrec->subnet_name));
+ }
- if(rcode == 0)
- return;
+ if(rcode == 0)
+ return;
- /* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
- send_name_release_response(rcode, p);
+ /* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
+ send_name_release_response(rcode, p);
}
/****************************************************************************
@@ -133,18 +131,18 @@ Send a name registration response.
static void send_name_registration_response(int rcode, int ttl, struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- char rdata[6];
+ struct nmb_packet *nmb = &p->packet.nmb;
+ char rdata[6];
- memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
+ memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
- reply_netbios_packet(p, /* Packet to reply to. */
- rcode, /* Result code. */
- NMB_REG, /* nmbd type code. */
- NMB_NAME_REG_OPCODE, /* opcode. */
- ttl, /* ttl. */
- rdata, /* data to send. */
- 6); /* data length. */
+ reply_netbios_packet(p, /* Packet to reply to. */
+ rcode, /* Result code. */
+ NMB_REG, /* nmbd type code. */
+ NMB_NAME_REG_OPCODE, /* opcode. */
+ ttl, /* ttl. */
+ rdata, /* data to send. */
+ 6); /* data length. */
}
/****************************************************************************
@@ -154,38 +152,34 @@ Process a name refresh request on a broadcast subnet.
void process_name_refresh_request(struct subnet_record *subrec,
struct packet_struct *p)
{
-
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- struct in_addr from_ip;
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct nmb_name *question = &nmb->question.question_name;
+ BOOL bcast = nmb->header.nm_flags.bcast;
+ struct in_addr from_ip;
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
-
- if(!bcast)
- {
- /* We should only get broadcast name refresh packets here.
- Anyone trying to refresh unicast should be going to a WINS
- server. If the code gets here, then either we are not a wins
- server and they sent it anyway, or we are a WINS server and
- the request was malformed. Either way, log an error here.
- and send an error reply back.
- */
- DEBUG(0,("process_name_refresh_request: unicast name registration request \
+ putip((char *)&from_ip,&nmb->additional->rdata[2]);
+
+ if(!bcast) {
+ /* We should only get broadcast name refresh packets here.
+ Anyone trying to refresh unicast should be going to a WINS
+ server. If the code gets here, then either we are not a wins
+ server and they sent it anyway, or we are a WINS server and
+ the request was malformed. Either way, log an error here.
+ and send an error reply back.
+ */
+ DEBUG(0,("process_name_refresh_request: unicast name registration request \
received for name %s from IP %s on subnet %s.\n",
- nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- DEBUG(0,("Error - should be sent to WINS server\n"));
+ nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
+ DEBUG(0,("Error - should be sent to WINS server\n"));
- send_name_registration_response(FMT_ERR, 0, p);
- return;
- }
+ send_name_registration_response(FMT_ERR, 0, p);
+ return;
+ }
- /* Just log a message. We really don't care about broadcast name
- refreshes. */
+ /* Just log a message. We really don't care about broadcast name refreshes. */
- DEBUG(3,("process_name_refresh_request: Name refresh for name %s \
+ DEBUG(3,("process_name_refresh_request: Name refresh for name %s \
IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
-
}
/****************************************************************************
@@ -195,92 +189,83 @@ Process a name registration request on a broadcast subnet.
void process_name_registration_request(struct subnet_record *subrec,
struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
- BOOL group = (nb_flags & NB_GROUP) ? True : False;
- struct name_record *namerec = NULL;
- int ttl = nmb->additional->ttl;
- struct in_addr from_ip;
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct nmb_name *question = &nmb->question.question_name;
+ BOOL bcast = nmb->header.nm_flags.bcast;
+ uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
+ BOOL group = (nb_flags & NB_GROUP) ? True : False;
+ struct name_record *namerec = NULL;
+ int ttl = nmb->additional->ttl;
+ struct in_addr from_ip;
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
+ putip((char *)&from_ip,&nmb->additional->rdata[2]);
- if(!bcast)
- {
- /* We should only get broadcast name registration packets here.
- Anyone trying to register unicast should be going to a WINS
- server. If the code gets here, then either we are not a wins
- server and they sent it anyway, or we are a WINS server and
- the request was malformed. Either way, log an error here.
- and send an error reply back.
- */
- DEBUG(0,("process_name_registration_request: unicast name registration request \
+ if(!bcast) {
+ /* We should only get broadcast name registration packets here.
+ Anyone trying to register unicast should be going to a WINS
+ server. If the code gets here, then either we are not a wins
+ server and they sent it anyway, or we are a WINS server and
+ the request was malformed. Either way, log an error here.
+ and send an error reply back.
+ */
+ DEBUG(0,("process_name_registration_request: unicast name registration request \
received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n",
- nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
+ nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- send_name_registration_response(FMT_ERR, 0, p);
- return;
- }
+ send_name_registration_response(FMT_ERR, 0, p);
+ return;
+ }
- DEBUG(3,("process_name_registration_request: Name registration for name %s \
+ DEBUG(3,("process_name_registration_request: Name registration for name %s \
IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- /* See if the name already exists. */
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
+ /* See if the name already exists. */
+ namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
- /*
- * If the name being registered exists and is a WINS_PROXY_NAME
- * then delete the WINS proxy name entry so we don't reply erroneously
- * later to queries.
- */
-
- if((namerec != NULL) && (namerec->data.source == WINS_PROXY_NAME))
- {
- remove_name_from_namelist( subrec, namerec );
- namerec = NULL;
- }
-
- if (!group)
- {
- /* Unique name. */
-
- if( (namerec != NULL)
- && ( (namerec->data.source == SELF_NAME)
- || (namerec->data.source == PERMANENT_NAME)
- || NAME_GROUP(namerec) ) )
- {
- /* No-one can register one of Samba's names, nor can they
- register a name that's a group name as a unique name */
-
- send_name_registration_response(ACT_ERR, 0, p);
- return;
- }
- else if(namerec != NULL)
- {
- /* Update the namelist record with the new information. */
- namerec->data.ip[0] = from_ip;
- update_name_ttl(namerec, ttl);
-
- DEBUG(3,("process_name_registration_request: Updated name record %s \
+ /*
+ * If the name being registered exists and is a WINS_PROXY_NAME
+ * then delete the WINS proxy name entry so we don't reply erroneously
+ * later to queries.
+ */
+
+ if((namerec != NULL) && (namerec->data.source == WINS_PROXY_NAME)) {
+ remove_name_from_namelist( subrec, namerec );
+ namerec = NULL;
+ }
+
+ if (!group) {
+ /* Unique name. */
+
+ if( (namerec != NULL)
+ && ( (namerec->data.source == SELF_NAME)
+ || (namerec->data.source == PERMANENT_NAME)
+ || NAME_GROUP(namerec) ) ) {
+ /* No-one can register one of Samba's names, nor can they
+ register a name that's a group name as a unique name */
+
+ send_name_registration_response(ACT_ERR, 0, p);
+ return;
+ } else if(namerec != NULL) {
+ /* Update the namelist record with the new information. */
+ namerec->data.ip[0] = from_ip;
+ update_name_ttl(namerec, ttl);
+
+ DEBUG(3,("process_name_registration_request: Updated name record %s \
with IP %s on subnet %s\n",nmb_namestr(&namerec->name),inet_ntoa(from_ip), subrec->subnet_name));
- return;
- }
- }
- else
- {
- /* Group name. */
-
- if( (namerec != NULL)
- && !NAME_GROUP(namerec)
- && ( (namerec->data.source == SELF_NAME)
- || (namerec->data.source == PERMANENT_NAME) ) )
- {
- /* Disallow group names when we have a unique name. */
- send_name_registration_response(ACT_ERR, 0, p);
- return;
- }
- }
+ return;
+ }
+ } else {
+ /* Group name. */
+
+ if( (namerec != NULL)
+ && !NAME_GROUP(namerec)
+ && ( (namerec->data.source == SELF_NAME)
+ || (namerec->data.source == PERMANENT_NAME) ) ) {
+ /* Disallow group names when we have a unique name. */
+ send_name_registration_response(ACT_ERR, 0, p);
+ return;
+ }
+ }
}
/****************************************************************************
@@ -290,147 +275,150 @@ We put our own names first, then in alphabetical order.
static int status_compare(char *n1,char *n2)
{
- int l1,l2,l3;
-
- /* It's 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(global_myname());
-
- if ((l1==l3) && strncmp(n1,global_myname(),l3) == 0 &&
- (l2!=l3 || strncmp(n2,global_myname(),l3) != 0))
- return -1;
-
- if ((l2==l3) && strncmp(n2,global_myname(),l3) == 0 &&
- (l1!=l3 || strncmp(n1,global_myname(),l3) != 0))
- return 1;
-
- return memcmp(n1,n2,18);
+ nstring name1, name2;
+ int l1,l2,l3;
+
+ pull_ascii_nstring(name1, n1);
+ pull_ascii_nstring(name2, n2);
+ n1 = name1;
+ n2 = name2;
+
+ /* It's 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(global_myname());
+
+ if ((l1==l3) && strncmp(n1,global_myname(),l3) == 0 &&
+ (l2!=l3 || strncmp(n2,global_myname(),l3) != 0))
+ return -1;
+
+ if ((l2==l3) && strncmp(n2,global_myname(),l3) == 0 &&
+ (l1!=l3 || strncmp(n1,global_myname(),l3) != 0))
+ return 1;
+
+ return memcmp(n1,n2,sizeof(nstring));
}
-
/****************************************************************************
Process a node status query
****************************************************************************/
void process_node_status_request(struct subnet_record *subrec, struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- 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, *buf0;
- int names_added,i;
- struct name_record *namerec;
-
- DEBUG(3,("process_node_status_request: status request for name %s from IP %s on \
-subnet %s.\n", nmb_namestr(&nmb->question.question_name), inet_ntoa(p->ip),
- subrec->subnet_name));
-
- if((namerec = find_name_on_subnet(subrec, &nmb->question.question_name,
- FIND_SELF_NAME)) == 0)
- {
- DEBUG(1,("process_node_status_request: status request for name %s from IP %s on \
+ struct nmb_packet *nmb = &p->packet.nmb;
+ nstring qname;
+ int ques_type = nmb->question.question_name.name_type;
+ char rdata[MAX_DGRAM_SIZE];
+ char *countptr, *buf, *bufend, *buf0;
+ int names_added,i;
+ struct name_record *namerec;
+
+ pull_ascii_nstring(qname, nmb->question.question_name.name);
+
+ DEBUG(3,("process_node_status_request: status request for name %s from IP %s on \
+subnet %s.\n", nmb_namestr(&nmb->question.question_name), inet_ntoa(p->ip), subrec->subnet_name));
+
+ if((namerec = find_name_on_subnet(subrec, &nmb->question.question_name, FIND_SELF_NAME)) == 0) {
+ DEBUG(1,("process_node_status_request: status request for name %s from IP %s on \
subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name),
- inet_ntoa(p->ip), subrec->subnet_name));
+ inet_ntoa(p->ip), subrec->subnet_name));
- return;
- }
+ return;
+ }
- /* this is not an exact calculation. the 46 is for the stats buffer
- and the 60 is to leave room for the header etc */
- bufend = &rdata[MAX_DGRAM_SIZE] - (18 + 46 + 60);
- countptr = buf = rdata;
- buf += 1;
- buf0 = buf;
-
- names_added = 0;
-
- namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
-
- while (buf < bufend)
- {
- if( (namerec->data.source == SELF_NAME)
- || (namerec->data.source == PERMANENT_NAME) )
- {
- int name_type = namerec->name.name_type;
-
- if (!strequal(namerec->name.name,"*") &&
- !strequal(namerec->name.name,"__SAMBA__") &&
- (name_type < 0x1b || name_type >= 0x20 ||
- ques_type < 0x1b || ques_type >= 0x20 ||
- strequal(qname, namerec->name.name)))
- {
- /* Start with the name. */
- memset(buf,'\0',18);
- slprintf(buf, 17, "%-15.15s",namerec->name.name);
- strupper_m(buf);
-
- /* Put the name type and netbios flags in the buffer. */
- buf[15] = name_type;
- set_nb_flags( &buf[16],namerec->data.nb_flags );
- buf[16] |= NB_ACTIVE; /* all our names are active */
-
- buf += 18;
-
- names_added++;
- }
- }
-
- /* Remove duplicate names. */
- if (names_added > 1) {
- 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;
-
- namerec = (struct name_record *)ubi_trNext( namerec );
-
- if (!namerec)
- {
- /* End of the subnet specific name list. Now
- add the names on the unicast subnet . */
- struct subnet_record *uni_subrec = unicast_subnet;
-
- if (uni_subrec != subrec)
- {
- subrec = uni_subrec;
- namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
- }
- }
- if (!namerec)
- break;
-
- }
+ /* this is not an exact calculation. the 46 is for the stats buffer
+ and the 60 is to leave room for the header etc */
+ bufend = &rdata[MAX_DGRAM_SIZE] - (18 + 46 + 60);
+ countptr = buf = rdata;
+ buf += 1;
+ buf0 = buf;
+
+ names_added = 0;
+
+ namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
+
+ while (buf < bufend) {
+ if( (namerec->data.source == SELF_NAME) || (namerec->data.source == PERMANENT_NAME) ) {
+ int name_type = namerec->name.name_type;
+ nstring name;
+
+ pull_ascii_nstring(name, namerec->name.name);
+ strupper_m(name);
+ if (!strequal(name,"*") &&
+ !strequal(name,"__SAMBA__") &&
+ (name_type < 0x1b || name_type >= 0x20 ||
+ ques_type < 0x1b || ques_type >= 0x20 ||
+ strequal(qname, name))) {
+ /* Start with the name. */
+ nstring tmp_name;
+ memset(tmp_name,'\0',sizeof(tmp_name));
+ snprintf(tmp_name, sizeof(tmp_name), "%-15.15s",name);
+ push_ascii_nstring(buf, tmp_name);
+
+ /* Put the name type and netbios flags in the buffer. */
+
+ buf[15] = name_type;
+ set_nb_flags( &buf[16],namerec->data.nb_flags );
+ buf[16] |= NB_ACTIVE; /* all our names are active */
+
+ buf += 18;
+
+ names_added++;
+ }
+ }
+
+ /* Remove duplicate names. */
+ if (names_added > 1) {
+ 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;
+
+ namerec = (struct name_record *)ubi_trNext( namerec );
+
+ if (!namerec) {
+ /* End of the subnet specific name list. Now
+ add the names on the unicast subnet . */
+ struct subnet_record *uni_subrec = unicast_subnet;
+
+ if (uni_subrec != subrec) {
+ subrec = uni_subrec;
+ namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
+ }
+ }
+ if (!namerec)
+ break;
+
+ }
- SCVAL(countptr,0,names_added);
+ SCVAL(countptr,0,names_added);
- /* We don't send any stats as they could be used to attack
- the protocol. */
- memset(buf,'\0',46);
+ /* We don't send any stats as they could be used to attack
+ the protocol. */
+ memset(buf,'\0',46);
- buf += 46;
+ buf += 46;
- /* Send a NODE STATUS RESPONSE */
- reply_netbios_packet(p, /* Packet to reply to. */
- 0, /* Result code. */
- NMB_STATUS, /* nmbd type code. */
- NMB_NAME_QUERY_OPCODE, /* opcode. */
- 0, /* ttl. */
- rdata, /* data to send. */
- PTR_DIFF(buf,rdata)); /* data length. */
+ /* Send a NODE STATUS RESPONSE */
+ reply_netbios_packet(p, /* Packet to reply to. */
+ 0, /* Result code. */
+ NMB_STATUS, /* nmbd type code. */
+ NMB_NAME_QUERY_OPCODE, /* opcode. */
+ 0, /* ttl. */
+ rdata, /* data to send. */
+ PTR_DIFF(buf,rdata)); /* data length. */
}
diff --git a/source3/nmbd/nmbd_lmhosts.c b/source3/nmbd/nmbd_lmhosts.c
index 3c067d8ed4..b14e13f3a4 100644
--- a/source3/nmbd/nmbd_lmhosts.c
+++ b/source3/nmbd/nmbd_lmhosts.c
@@ -28,50 +28,46 @@
/****************************************************************************
Load a lmhosts file.
****************************************************************************/
+
void load_lmhosts_file(char *fname)
{
- pstring name;
- int name_type;
- struct in_addr ipaddr;
- XFILE *fp = startlmhosts( fname );
-
- if (!fp) {
- DEBUG(2,("load_lmhosts_file: Can't open lmhosts file %s. Error was %s\n",
- fname, strerror(errno)));
- return;
- }
+ pstring name;
+ int name_type;
+ struct in_addr ipaddr;
+ XFILE *fp = startlmhosts( fname );
+
+ if (!fp) {
+ DEBUG(2,("load_lmhosts_file: Can't open lmhosts file %s. Error was %s\n",
+ fname, strerror(errno)));
+ return;
+ }
- while (getlmhostsent(fp, name, &name_type, &ipaddr) )
- {
- struct subnet_record *subrec = NULL;
- enum name_source source = LMHOSTS_NAME;
-
- /* We find a relevent subnet to put this entry on, then add it. */
- /* Go through all the broadcast subnets and see if the mask matches. */
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- if(same_net(ipaddr, subrec->bcast_ip, subrec->mask_ip))
- break;
- }
+ while (getlmhostsent(fp, name, &name_type, &ipaddr) ) {
+ struct subnet_record *subrec = NULL;
+ enum name_source source = LMHOSTS_NAME;
+
+ /* We find a relevent subnet to put this entry on, then add it. */
+ /* Go through all the broadcast subnets and see if the mask matches. */
+ for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
+ if(same_net(ipaddr, subrec->bcast_ip, subrec->mask_ip))
+ break;
+ }
- /* If none match add the name to the remote_broadcast_subnet. */
- if(subrec == NULL)
- subrec = remote_broadcast_subnet;
-
- if(name_type == -1)
- {
- /* Add the (0) and (0x20) names directly into the namelist for this subnet. */
- (void)add_name_to_subnet(subrec,name,0x00,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
- (void)add_name_to_subnet(subrec,name,0x20,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
- }
- else
- {
- /* Add the given name type to the subnet namelist. */
- (void)add_name_to_subnet(subrec,name,name_type,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
- }
- }
+ /* If none match add the name to the remote_broadcast_subnet. */
+ if(subrec == NULL)
+ subrec = remote_broadcast_subnet;
+
+ if(name_type == -1) {
+ /* Add the (0) and (0x20) names directly into the namelist for this subnet. */
+ (void)add_name_to_subnet(subrec,name,0x00,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
+ (void)add_name_to_subnet(subrec,name,0x20,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
+ } else {
+ /* Add the given name type to the subnet namelist. */
+ (void)add_name_to_subnet(subrec,name,name_type,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
+ }
+ }
- endlmhosts(fp);
+ endlmhosts(fp);
}
/****************************************************************************
@@ -82,17 +78,16 @@ void load_lmhosts_file(char *fname)
BOOL find_name_in_lmhosts(struct nmb_name *nmbname, struct name_record **namerecp)
{
- struct name_record *namerec;
+ struct name_record *namerec;
- *namerecp = NULL;
+ *namerecp = NULL;
- if((namerec = find_name_on_subnet(remote_broadcast_subnet, nmbname,
- FIND_ANY_NAME))==NULL)
- return False;
+ if((namerec = find_name_on_subnet(remote_broadcast_subnet, nmbname, FIND_ANY_NAME))==NULL)
+ return False;
- if(!NAME_IS_ACTIVE(namerec) || (namerec->data.source != LMHOSTS_NAME))
- return False;
+ if(!NAME_IS_ACTIVE(namerec) || (namerec->data.source != LMHOSTS_NAME))
+ return False;
- *namerecp = namerec;
- return True;
+ *namerecp = namerec;
+ return True;
}
diff --git a/source3/nmbd/nmbd_logonnames.c b/source3/nmbd/nmbd_logonnames.c
index b73586aa45..f79fc56f7b 100644
--- a/source3/nmbd/nmbd_logonnames.c
+++ b/source3/nmbd/nmbd_logonnames.c
@@ -3,7 +3,7 @@
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Jeremy Allison 1994-2003
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
@@ -29,38 +29,40 @@ extern uint16 samba_nb_type; /* Samba's NetBIOS type. */
/****************************************************************************
Fail to become a Logon server on a subnet.
- ****************************************************************************/
+****************************************************************************/
+
static void become_logon_server_fail(struct subnet_record *subrec,
struct response_record *rrec,
struct nmb_name *fail_name)
{
- struct work_record *work = find_workgroup_on_subnet(subrec, fail_name->name);
- struct server_record *servrec;
-
- if(!work)
- {
- DEBUG(0,("become_logon_server_fail: Error - cannot find \
-workgroup %s on subnet %s\n", fail_name->name, subrec->subnet_name));
- return;
- }
-
- if((servrec = find_server_in_workgroup( work, global_myname())) == NULL)
- {
- DEBUG(0,("become_logon_server_fail: Error - cannot find server %s \
+ nstring failname;
+ struct work_record *work;
+ struct server_record *servrec;
+
+ pull_ascii_nstring(failname, fail_name->name);
+ work = find_workgroup_on_subnet(subrec, failname);
+ if(!work) {
+ DEBUG(0,("become_logon_server_fail: Error - cannot find \
+workgroup %s on subnet %s\n", failname, subrec->subnet_name));
+ return;
+ }
+
+ if((servrec = find_server_in_workgroup( work, global_myname())) == NULL) {
+ DEBUG(0,("become_logon_server_fail: Error - cannot find server %s \
in workgroup %s on subnet %s\n",
- global_myname(), fail_name->name, subrec->subnet_name));
- work->log_state = LOGON_NONE;
- return;
- }
+ global_myname(), failname, subrec->subnet_name));
+ work->log_state = LOGON_NONE;
+ return;
+ }
- /* Set the state back to LOGON_NONE. */
- work->log_state = LOGON_NONE;
+ /* Set the state back to LOGON_NONE. */
+ work->log_state = LOGON_NONE;
- servrec->serv.type &= ~SV_TYPE_DOMAIN_CTRL;
+ servrec->serv.type &= ~SV_TYPE_DOMAIN_CTRL;
- DEBUG(0,("become_logon_server_fail: Failed to become a domain master for \
+ DEBUG(0,("become_logon_server_fail: Failed to become a domain master for \
workgroup %s on subnet %s. Couldn't register name %s.\n",
- work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));
+ work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));
}
@@ -74,49 +76,51 @@ static void become_logon_server_success(struct subnet_record *subrec,
uint16 nb_flags,
int ttl, struct in_addr registered_ip)
{
- struct work_record *work = find_workgroup_on_subnet( subrec, registered_name->name);
- struct server_record *servrec;
-
- if(!work)
- {
- DEBUG(0,("become_logon_server_success: Error - cannot find \
-workgroup %s on subnet %s\n", registered_name->name, subrec->subnet_name));
- return;
- }
-
- if((servrec = find_server_in_workgroup( work, global_myname())) == NULL)
- {
- DEBUG(0,("become_logon_server_success: Error - cannot find server %s \
+ nstring reg_name;
+ struct work_record *work;
+ struct server_record *servrec;
+
+ pull_ascii_nstring(reg_name, registered_name->name);
+ work = find_workgroup_on_subnet( subrec, reg_name);
+ if(!work) {
+ DEBUG(0,("become_logon_server_success: Error - cannot find \
+workgroup %s on subnet %s\n", reg_name, subrec->subnet_name));
+ return;
+ }
+
+ if((servrec = find_server_in_workgroup( work, global_myname())) == NULL) {
+ DEBUG(0,("become_logon_server_success: Error - cannot find server %s \
in workgroup %s on subnet %s\n",
- global_myname(), registered_name->name, subrec->subnet_name));
- work->log_state = LOGON_NONE;
- return;
- }
-
- /* Set the state in the workgroup structure. */
- work->log_state = LOGON_SRV; /* Become domain master. */
-
- /* Update our server status. */
- servrec->serv.type |= (SV_TYPE_NT|SV_TYPE_DOMAIN_MEMBER);
- /* To allow Win95 policies to load we need to set type domain
- controller.
- */
- servrec->serv.type |= SV_TYPE_DOMAIN_CTRL;
-
- /* Tell the namelist writer to write out a change. */
- subrec->work_changed = True;
-
- /*
- * Add the WORKGROUP<1C> name to the UNICAST subnet with the IP address
- * for this subnet so we will respond to queries on this name.
- */
- {
- struct nmb_name nmbname;
- make_nmb_name(&nmbname,lp_workgroup(),0x1c);
- insert_permanent_name_into_unicast(subrec, &nmbname, 0x1c);
- }
-
- DEBUG(0,("become_logon_server_success: Samba is now a logon server \
+ global_myname(), reg_name, subrec->subnet_name));
+ work->log_state = LOGON_NONE;
+ return;
+ }
+
+ /* Set the state in the workgroup structure. */
+ work->log_state = LOGON_SRV; /* Become domain master. */
+
+ /* Update our server status. */
+ servrec->serv.type |= (SV_TYPE_NT|SV_TYPE_DOMAIN_MEMBER);
+ /* To allow Win95 policies to load we need to set type domain
+ controller.
+ */
+ servrec->serv.type |= SV_TYPE_DOMAIN_CTRL;
+
+ /* Tell the namelist writer to write out a change. */
+ subrec->work_changed = True;
+
+ /*
+ * Add the WORKGROUP<1C> name to the UNICAST subnet with the IP address
+ * for this subnet so we will respond to queries on this name.
+ */
+
+ {
+ struct nmb_name nmbname;
+ make_nmb_name(&nmbname,lp_workgroup(),0x1c);
+ insert_permanent_name_into_unicast(subrec, &nmbname, 0x1c);
+ }
+
+ DEBUG(0,("become_logon_server_success: Samba is now a logon server \
for workgroup %s on subnet %s\n", work->work_group, subrec->subnet_name));
}
@@ -128,45 +132,42 @@ for workgroup %s on subnet %s\n", work->work_group, subrec->subnet_name));
static void become_logon_server(struct subnet_record *subrec,
struct work_record *work)
{
- DEBUG(2,("become_logon_server: Atempting to become logon server for workgroup %s \
+ DEBUG(2,("become_logon_server: Atempting to become logon server for workgroup %s \
on subnet %s\n", work->work_group,subrec->subnet_name));
- DEBUG(3,("become_logon_server: go to first stage: register %s<1c> name\n",
- work->work_group));
- work->log_state = LOGON_WAIT;
+ DEBUG(3,("become_logon_server: go to first stage: register %s<1c> name\n",
+ work->work_group));
+ work->log_state = LOGON_WAIT;
- register_name(subrec, work->work_group,0x1c,samba_nb_type|NB_GROUP,
- become_logon_server_success,
- become_logon_server_fail, NULL);
+ register_name(subrec, work->work_group,0x1c,samba_nb_type|NB_GROUP,
+ become_logon_server_success,
+ become_logon_server_fail, NULL);
}
/*****************************************************************************
Add the internet group <1c> logon names by unicast and broadcast.
****************************************************************************/
+
void add_logon_names(void)
{
- struct subnet_record *subrec;
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
- {
- struct work_record *work = find_workgroup_on_subnet(subrec, lp_workgroup());
-
- if (work && (work->log_state == LOGON_NONE))
- {
- struct nmb_name nmbname;
- make_nmb_name(&nmbname,lp_workgroup(),0x1c);
-
- if (find_name_on_subnet(subrec, &nmbname, FIND_SELF_NAME) == NULL)
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "add_domain_logon_names:\n" );
- dbgtext( "Attempting to become logon server " );
- dbgtext( "for workgroup %s ", lp_workgroup() );
- dbgtext( "on subnet %s\n", subrec->subnet_name );
- }
- become_logon_server(subrec, work);
- }
- }
- }
+ struct subnet_record *subrec;
+
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) {
+ struct work_record *work = find_workgroup_on_subnet(subrec, lp_workgroup());
+
+ if (work && (work->log_state == LOGON_NONE)) {
+ struct nmb_name nmbname;
+ make_nmb_name(&nmbname,lp_workgroup(),0x1c);
+
+ if (find_name_on_subnet(subrec, &nmbname, FIND_SELF_NAME) == NULL) {
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "add_domain_logon_names:\n" );
+ dbgtext( "Attempting to become logon server " );
+ dbgtext( "for workgroup %s ", lp_workgroup() );
+ dbgtext( "on subnet %s\n", subrec->subnet_name );
+ }
+ become_logon_server(subrec, work);
+ }
+ }
+ }
}
diff --git a/source3/nmbd/nmbd_mynames.c b/source3/nmbd/nmbd_mynames.c
index dd66821839..f02fbe1640 100644
--- a/source3/nmbd/nmbd_mynames.c
+++ b/source3/nmbd/nmbd_mynames.c
@@ -3,7 +3,7 @@
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Jeremy Allison 1994-2003
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
@@ -27,20 +27,21 @@ extern uint16 samba_nb_type; /* Samba's NetBIOS type. */
/****************************************************************************
Fail funtion when registering my netbios names.
- **************************************************************************/
+**************************************************************************/
static void my_name_register_failed(struct subnet_record *subrec,
struct response_record *rrec, struct nmb_name *nmbname)
{
- DEBUG(0,("my_name_register_failed: Failed to register my name %s on subnet %s.\n",
- nmb_namestr(nmbname), subrec->subnet_name));
+ DEBUG(0,("my_name_register_failed: Failed to register my name %s on subnet %s.\n",
+ nmb_namestr(nmbname), subrec->subnet_name));
}
/****************************************************************************
Add my workgroup and my given names to one subnet
Also add the magic Samba names.
- **************************************************************************/
+**************************************************************************/
+
void register_my_workgroup_one_subnet(struct subnet_record *subrec)
{
int i;
@@ -84,111 +85,104 @@ Exiting.\n", lp_workgroup(), subrec->subnet_name));
static void insert_refresh_name_into_unicast( struct subnet_record *subrec,
struct nmb_name *nmbname, uint16 nb_type )
{
- struct name_record *namerec;
-
- if (!we_are_a_wins_client()) {
- insert_permanent_name_into_unicast(subrec, nmbname, nb_type);
- return;
- }
-
- if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL)
- {
- /* The name needs to be created on the unicast subnet. */
- (void)add_name_to_subnet( unicast_subnet, nmbname->name,
- nmbname->name_type, nb_type,
- MIN(lp_max_ttl(), MAX_REFRESH_TIME), SELF_NAME, 1, &subrec->myip);
- }
- else
- {
- /* The name already exists on the unicast subnet. Add our local
- IP for the given broadcast subnet to the name. */
- add_ip_to_name_record( namerec, subrec->myip);
- }
+ struct name_record *namerec;
+
+ if (!we_are_a_wins_client()) {
+ insert_permanent_name_into_unicast(subrec, nmbname, nb_type);
+ return;
+ }
+
+ if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL) {
+ nstring name;
+ pull_ascii_nstring(name, nmbname->name);
+ /* The name needs to be created on the unicast subnet. */
+ (void)add_name_to_subnet( unicast_subnet, name,
+ nmbname->name_type, nb_type,
+ MIN(lp_max_ttl(), MAX_REFRESH_TIME), SELF_NAME, 1, &subrec->myip);
+ } else {
+ /* The name already exists on the unicast subnet. Add our local
+ IP for the given broadcast subnet to the name. */
+ add_ip_to_name_record( namerec, subrec->myip);
+ }
}
/****************************************************************************
Add my workgroup and my given names to the subnet lists.
Also add the magic Samba names.
- **************************************************************************/
+**************************************************************************/
BOOL register_my_workgroup_and_names(void)
{
- struct subnet_record *subrec;
- int i;
-
- for(subrec = FIRST_SUBNET;
- subrec;
- subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
- {
- register_my_workgroup_one_subnet(subrec);
- }
-
- /* We still need to add the magic Samba
- names and the netbios names to the unicast subnet directly. This is
- to allow unicast node status requests and queries to still work
- in a broadcast only environment. */
-
- add_samba_names_to_subnet(unicast_subnet);
-
- for (i=0; my_netbios_names(i); i++)
- {
- for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- /*
- * Ensure all the IP addresses are added if we are multihomed.
- */
- struct nmb_name nmbname;
-
- make_nmb_name(&nmbname, my_netbios_names(i),0x20);
- insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
-
- make_nmb_name(&nmbname, my_netbios_names(i),0x3);
- insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
-
- make_nmb_name(&nmbname, my_netbios_names(i),0x0);
- insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
- }
- }
-
- /*
- * Add the WORKGROUP<0> and WORKGROUP<1e> group names to the unicast subnet
- * also for the same reasons.
- */
-
- for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- /*
- * Ensure all the IP addresses are added if we are multihomed.
- */
- struct nmb_name nmbname;
-
- make_nmb_name(&nmbname, lp_workgroup(), 0x0);
- insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP);
-
- make_nmb_name(&nmbname, lp_workgroup(), 0x1e);
- insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP);
- }
-
- /*
- * We need to add the Samba names to the remote broadcast subnet,
- * as NT 4.x does directed broadcast requests to the *<0x0> name.
- */
- add_samba_names_to_subnet(remote_broadcast_subnet);
-
- return True;
+ struct subnet_record *subrec;
+ int i;
+
+ for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) {
+ register_my_workgroup_one_subnet(subrec);
+ }
+
+ /* We still need to add the magic Samba
+ names and the netbios names to the unicast subnet directly. This is
+ to allow unicast node status requests and queries to still work
+ in a broadcast only environment. */
+
+ add_samba_names_to_subnet(unicast_subnet);
+
+ for (i=0; my_netbios_names(i); i++) {
+ for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
+ /*
+ * Ensure all the IP addresses are added if we are multihomed.
+ */
+ struct nmb_name nmbname;
+
+ make_nmb_name(&nmbname, my_netbios_names(i),0x20);
+ insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
+
+ make_nmb_name(&nmbname, my_netbios_names(i),0x3);
+ insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
+
+ make_nmb_name(&nmbname, my_netbios_names(i),0x0);
+ insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type);
+ }
+ }
+
+ /*
+ * Add the WORKGROUP<0> and WORKGROUP<1e> group names to the unicast subnet
+ * also for the same reasons.
+ */
+
+ for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
+ /*
+ * Ensure all the IP addresses are added if we are multihomed.
+ */
+ struct nmb_name nmbname;
+
+ make_nmb_name(&nmbname, lp_workgroup(), 0x0);
+ insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP);
+
+ make_nmb_name(&nmbname, lp_workgroup(), 0x1e);
+ insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP);
+ }
+
+ /*
+ * We need to add the Samba names to the remote broadcast subnet,
+ * as NT 4.x does directed broadcast requests to the *<0x0> name.
+ */
+
+ add_samba_names_to_subnet(remote_broadcast_subnet);
+
+ return True;
}
/****************************************************************************
Remove all the names we registered.
**************************************************************************/
+
void release_wins_names(void)
{
struct subnet_record *subrec = unicast_subnet;
struct name_record *namerec, *nextnamerec;
- for (namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
- namerec;
- namerec = nextnamerec) {
+ for (namerec = (struct name_record *)ubi_trFirst( subrec->namelist ); namerec; namerec = nextnamerec) {
nextnamerec = (struct name_record *)ubi_trNext( namerec );
if( (namerec->data.source == SELF_NAME)
&& !NAME_IS_DEREGISTERING(namerec) )
@@ -199,12 +193,14 @@ void release_wins_names(void)
/*******************************************************************
Refresh our registered names with WINS
- ******************************************************************/
+******************************************************************/
+
void refresh_my_names(time_t t)
{
struct name_record *namerec;
- if (wins_srv_count() < 1) return;
+ if (wins_srv_count() < 1)
+ return;
for (namerec = (struct name_record *)ubi_trFirst(unicast_subnet->namelist);
namerec;
diff --git a/source3/nmbd/nmbd_namelistdb.c b/source3/nmbd/nmbd_namelistdb.c
index 3f6d2f3b64..d1c9afd608 100644
--- a/source3/nmbd/nmbd_namelistdb.c
+++ b/source3/nmbd/nmbd_namelistdb.c
@@ -3,7 +3,7 @@
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Jeremy Allison 1994-2003
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
@@ -26,152 +26,149 @@
uint16 samba_nb_type = 0; /* samba's NetBIOS name type */
-/* ************************************************************************** **
- * Set Samba's NetBIOS name type.
- * ************************************************************************** **
- */
+/**************************************************************************
+ Set Samba's NetBIOS name type.
+***************************************************************************/
+
void set_samba_nb_type(void)
- {
- if( lp_wins_support() || wins_srv_count() )
- samba_nb_type = NB_HFLAG; /* samba is a 'hybrid' node type. */
- else
- samba_nb_type = NB_BFLAG; /* samba is broadcast-only node type. */
- } /* set_samba_nb_type */
-
-/* ************************************************************************** **
- * Convert a NetBIOS name to upper case.
- * ************************************************************************** **
- */
+{
+ if( lp_wins_support() || wins_srv_count() )
+ samba_nb_type = NB_HFLAG; /* samba is a 'hybrid' node type. */
+ else
+ samba_nb_type = NB_BFLAG; /* samba is broadcast-only node type. */
+}
+
+/***************************************************************************
+ Convert a NetBIOS name to upper case.
+***************************************************************************/
+
static void upcase_name( struct nmb_name *target, struct nmb_name *source )
- {
- int i;
-
- if( NULL != source )
- (void)memcpy( target, source, sizeof( struct nmb_name ) );
-
- strupper_m( target->name );
- strupper_m( target->scope );
-
- /* fudge... We're using a byte-by-byte compare, so we must be sure that
- * unused space doesn't have garbage in it.
- */
- for( i = strlen( target->name ); i < sizeof( target->name ); i++ )
- target->name[i] = '\0';
- for( i = strlen( target->scope ); i < sizeof( target->scope ); i++ )
- target->scope[i] = '\0';
- } /* upcase_name */
-
-/* ************************************************************************** **
- * Add a new or overwrite an existing namelist entry.
- * ************************************************************************** **
- */
+{
+ int i;
+ nstring targ;
+ fstring scope;
+
+ if( NULL != source )
+ memcpy( target, source, sizeof( struct nmb_name ) );
+
+ pull_ascii_nstring(targ, target->name);
+ strupper_m( targ );
+ push_ascii_nstring( target->name, targ);
+
+ pull_ascii(scope, target->scope, 64, -1, STR_TERMINATE);
+ strupper_m( scope );
+ push_ascii(target->scope, scope, 64, STR_TERMINATE);
+
+ /* fudge... We're using a byte-by-byte compare, so we must be sure that
+ * unused space doesn't have garbage in it.
+ */
+
+ for( i = strlen( target->name ); i < sizeof( target->name ); i++ )
+ target->name[i] = '\0';
+ for( i = strlen( target->scope ); i < sizeof( target->scope ); i++ )
+ target->scope[i] = '\0';
+}
+
+/**************************************************************************
+ Add a new or overwrite an existing namelist entry.
+***************************************************************************/
+
static void update_name_in_namelist( struct subnet_record *subrec,
struct name_record *namerec )
- {
- struct name_record *oldrec = NULL;
-
- (void)ubi_trInsert( subrec->namelist, namerec, &(namerec->name), &oldrec );
- if( oldrec )
- {
- SAFE_FREE( oldrec->data.ip );
- SAFE_FREE( oldrec );
- }
- } /* update_name_in_namelist */
-
-/* ************************************************************************** **
- * Remove a name from the namelist.
- * ************************************************************************** **
- */
-void remove_name_from_namelist( struct subnet_record *subrec,
- struct name_record *namerec )
- {
- (void)ubi_trRemove( subrec->namelist, namerec );
+{
+ struct name_record *oldrec = NULL;
- SAFE_FREE(namerec->data.ip);
+ ubi_trInsert( subrec->namelist, namerec, &(namerec->name), &oldrec );
+ if( oldrec ) {
+ SAFE_FREE( oldrec->data.ip );
+ SAFE_FREE( oldrec );
+ }
+}
- ZERO_STRUCTP(namerec);
- SAFE_FREE(namerec);
+/**************************************************************************
+ Remove a name from the namelist.
+***************************************************************************/
+
+void remove_name_from_namelist( struct subnet_record *subrec,
+ struct name_record *namerec )
+{
+ ubi_trRemove( subrec->namelist, namerec );
+ SAFE_FREE(namerec->data.ip);
+ ZERO_STRUCTP(namerec);
+ SAFE_FREE(namerec);
+ subrec->namelist_changed = True;
+}
- subrec->namelist_changed = True;
- } /* remove_name_from_namelist */
+/**************************************************************************
+ Find a name in a subnet.
+**************************************************************************/
-/* ************************************************************************** **
- * Find a name in a subnet.
- * ************************************************************************** **
- */
struct name_record *find_name_on_subnet( struct subnet_record *subrec,
struct nmb_name *nmbname,
BOOL self_only )
- {
- struct nmb_name uc_name[1];
- struct name_record *name_ret;
-
- upcase_name( uc_name, nmbname );
- name_ret = (struct name_record *)ubi_trFind( subrec->namelist, uc_name );
- if( name_ret )
- {
- /* Self names only - these include permanent names. */
- if( self_only
- && (name_ret->data.source != SELF_NAME)
- && (name_ret->data.source != PERMANENT_NAME) )
- {
- DEBUG( 9,
- ( "find_name_on_subnet: on subnet %s - self name %s NOT FOUND\n",
- subrec->subnet_name, nmb_namestr(nmbname) ) );
- return( NULL );
- }
- DEBUG( 9, ("find_name_on_subnet: on subnet %s - found name %s source=%d\n",
- subrec->subnet_name, nmb_namestr(nmbname), name_ret->data.source) );
- return( name_ret );
- }
- DEBUG( 9,
- ( "find_name_on_subnet: on subnet %s - name %s NOT FOUND\n",
- subrec->subnet_name, nmb_namestr(nmbname) ) );
- return( NULL );
- } /* find_name_on_subnet */
-
-/* ************************************************************************** **
- * Find a name over all known broadcast subnets.
- * ************************************************************************** **
- */
+{
+ struct nmb_name uc_name[1];
+ struct name_record *name_ret;
+
+ upcase_name( uc_name, nmbname );
+ name_ret = (struct name_record *)ubi_trFind( subrec->namelist, uc_name );
+ if( name_ret ) {
+ /* Self names only - these include permanent names. */
+ if( self_only && (name_ret->data.source != SELF_NAME) && (name_ret->data.source != PERMANENT_NAME) ) {
+ DEBUG( 9, ( "find_name_on_subnet: on subnet %s - self name %s NOT FOUND\n",
+ subrec->subnet_name, nmb_namestr(nmbname) ) );
+ return( NULL );
+ }
+
+ DEBUG( 9, ("find_name_on_subnet: on subnet %s - found name %s source=%d\n",
+ subrec->subnet_name, nmb_namestr(nmbname), name_ret->data.source) );
+ return( name_ret );
+ }
+
+ DEBUG( 9, ( "find_name_on_subnet: on subnet %s - name %s NOT FOUND\n",
+ subrec->subnet_name, nmb_namestr(nmbname) ) );
+ return( NULL );
+}
+
+/**************************************************************************
+ Find a name over all known broadcast subnets.
+************************************************************************/
+
struct name_record *find_name_for_remote_broadcast_subnet(
struct nmb_name *nmbname,
BOOL self_only )
- {
- struct subnet_record *subrec;
- struct name_record *namerec = NULL;
-
- for( subrec = FIRST_SUBNET;
- subrec;
- subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) )
- {
- if( NULL != (namerec = find_name_on_subnet(subrec, nmbname, self_only)) )
- break;
- }
-
- return( namerec );
- } /* find_name_for_remote_broadcast_subnet */
+{
+ struct subnet_record *subrec;
+ struct name_record *namerec = NULL;
+
+ for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) ) {
+ if( NULL != (namerec = find_name_on_subnet(subrec, nmbname, self_only)) )
+ break;
+ }
+
+ return( namerec );
+}
-/* ************************************************************************** **
- * Update the ttl of an entry in a subnet name list.
- * ************************************************************************** **
- */
+/**************************************************************************
+ Update the ttl of an entry in a subnet name list.
+***************************************************************************/
+
void update_name_ttl( struct name_record *namerec, int ttl )
{
- time_t time_now = time(NULL);
+ time_t time_now = time(NULL);
- if( namerec->data.death_time != PERMANENT_TTL )
- namerec->data.death_time = time_now + ttl;
+ if( namerec->data.death_time != PERMANENT_TTL )
+ namerec->data.death_time = time_now + ttl;
- namerec->data.refresh_time = time_now + MIN((ttl/2), MAX_REFRESH_TIME);
+ namerec->data.refresh_time = time_now + MIN((ttl/2), MAX_REFRESH_TIME);
+
+ namerec->subnet->namelist_changed = True;
+}
- namerec->subnet->namelist_changed = True;
-} /* update_name_ttl */
+/**************************************************************************
+ Add an entry to a subnet name list.
+***********************************************************************/
-/* ************************************************************************** **
- * Add an entry to a subnet name list.
- * ************************************************************************** **
- */
struct name_record *add_name_to_subnet( struct subnet_record *subrec,
const char *name,
int type,
@@ -181,70 +178,66 @@ struct name_record *add_name_to_subnet( struct subnet_record *subrec,
int num_ips,
struct in_addr *iplist)
{
- struct name_record *namerec;
- time_t time_now = time(NULL);
+ struct name_record *namerec;
+ time_t time_now = time(NULL);
- namerec = (struct name_record *)malloc( sizeof(*namerec) );
- if( NULL == namerec )
- {
- DEBUG( 0, ( "add_name_to_subnet: malloc fail.\n" ) );
- return( NULL );
- }
+ namerec = (struct name_record *)malloc( sizeof(*namerec) );
+ if( NULL == namerec ) {
+ DEBUG( 0, ( "add_name_to_subnet: malloc fail.\n" ) );
+ return( NULL );
+ }
- memset( (char *)namerec, '\0', sizeof(*namerec) );
- namerec->data.ip = (struct in_addr *)malloc( sizeof(struct in_addr)
- * num_ips );
- if( NULL == namerec->data.ip )
- {
- DEBUG( 0, ( "add_name_to_subnet: malloc fail when creating ip_flgs.\n" ) );
+ memset( (char *)namerec, '\0', sizeof(*namerec) );
+ namerec->data.ip = (struct in_addr *)malloc( sizeof(struct in_addr) * num_ips );
+ if( NULL == namerec->data.ip ) {
+ DEBUG( 0, ( "add_name_to_subnet: malloc fail when creating ip_flgs.\n" ) );
+ ZERO_STRUCTP(namerec);
+ SAFE_FREE(namerec);
+ return NULL;
+ }
- ZERO_STRUCTP(namerec);
- SAFE_FREE(namerec);
- return NULL;
- }
+ namerec->subnet = subrec;
- namerec->subnet = subrec;
+ make_nmb_name(&namerec->name, name, type);
+ upcase_name(&namerec->name, NULL );
- make_nmb_name(&namerec->name, name, type);
- upcase_name(&namerec->name, NULL );
+ /* Enter the name as active. */
+ namerec->data.nb_flags = nb_flags | NB_ACTIVE;
+ namerec->data.wins_flags = WINS_ACTIVE;
- /* Enter the name as active. */
- namerec->data.nb_flags = nb_flags | NB_ACTIVE;
- namerec->data.wins_flags = WINS_ACTIVE;
+ /* If it's our primary name, flag it as so. */
+ if( strequal( my_netbios_names(0), name ) )
+ namerec->data.nb_flags |= NB_PERM;
- /* If it's our primary name, flag it as so. */
- if( strequal( my_netbios_names(0), name ) )
- namerec->data.nb_flags |= NB_PERM;
+ /* Copy the IPs. */
+ namerec->data.num_ips = num_ips;
+ memcpy( (namerec->data.ip), iplist, num_ips * sizeof(struct in_addr) );
- /* Copy the IPs. */
- namerec->data.num_ips = num_ips;
- memcpy( (namerec->data.ip), iplist, num_ips * sizeof(struct in_addr) );
+ /* Data source. */
+ namerec->data.source = source;
- /* Data source. */
- namerec->data.source = source;
+ /* Setup the death_time and refresh_time. */
+ if( ttl == PERMANENT_TTL )
+ namerec->data.death_time = PERMANENT_TTL;
+ else
+ namerec->data.death_time = time_now + ttl;
- /* Setup the death_time and refresh_time. */
- if( ttl == PERMANENT_TTL )
- namerec->data.death_time = PERMANENT_TTL;
- else
- namerec->data.death_time = time_now + ttl;
+ namerec->data.refresh_time = time_now + MIN((ttl/2), MAX_REFRESH_TIME);
- namerec->data.refresh_time = time_now + MIN((ttl/2), MAX_REFRESH_TIME);
+ /* Now add the record to the name list. */
+ update_name_in_namelist( subrec, namerec );
- /* Now add the record to the name list. */
- update_name_in_namelist( subrec, namerec );
-
- DEBUG( 3, ( "add_name_to_subnet: Added netbios name %s with first IP %s \
+ DEBUG( 3, ( "add_name_to_subnet: Added netbios name %s with first IP %s \
ttl=%d nb_flags=%2x to subnet %s\n",
- nmb_namestr( &namerec->name ),
- inet_ntoa( *iplist ),
- ttl,
- (unsigned int)nb_flags,
- subrec->subnet_name ) );
+ nmb_namestr( &namerec->name ),
+ inet_ntoa( *iplist ),
+ ttl,
+ (unsigned int)nb_flags,
+ subrec->subnet_name ) );
- subrec->namelist_changed = True;
+ subrec->namelist_changed = True;
- return(namerec);
+ return(namerec);
}
/*******************************************************************
@@ -258,14 +251,17 @@ void standard_success_register(struct subnet_record *subrec,
struct nmb_name *nmbname, uint16 nb_flags, int ttl,
struct in_addr registered_ip)
{
- struct name_record *namerec;
-
- namerec = find_name_on_subnet( subrec, nmbname, FIND_SELF_NAME );
- if( NULL == namerec )
- (void)add_name_to_subnet( subrec, nmbname->name, nmbname->name_type,
- nb_flags, ttl, SELF_NAME, 1, &registered_ip );
- else
- update_name_ttl( namerec, ttl );
+ struct name_record *namerec;
+
+ namerec = find_name_on_subnet( subrec, nmbname, FIND_SELF_NAME );
+ if( NULL == namerec ) {
+ nstring name;
+ pull_ascii_nstring(name, nmbname->name);
+ add_name_to_subnet( subrec, name, nmbname->name_type,
+ nb_flags, ttl, SELF_NAME, 1, &registered_ip );
+ } else {
+ update_name_ttl( namerec, ttl );
+ }
}
/*******************************************************************
@@ -279,17 +275,16 @@ void standard_fail_register( struct subnet_record *subrec,
struct response_record *rrec,
struct nmb_name *nmbname )
{
- struct name_record *namerec;
+ struct name_record *namerec;
- namerec = find_name_on_subnet( subrec, nmbname, FIND_SELF_NAME );
+ namerec = find_name_on_subnet( subrec, nmbname, FIND_SELF_NAME );
- DEBUG( 0, ( "standard_fail_register: Failed to register/refresh name %s \
-on subnet %s\n",
- nmb_namestr(nmbname), subrec->subnet_name) );
+ DEBUG( 0, ( "standard_fail_register: Failed to register/refresh name %s \
+on subnet %s\n", nmb_namestr(nmbname), subrec->subnet_name) );
- /* Remove the name from the subnet. */
- if( namerec )
- remove_name_from_namelist(subrec, namerec);
+ /* Remove the name from the subnet. */
+ if( namerec )
+ remove_name_from_namelist(subrec, namerec);
}
/*******************************************************************
@@ -298,13 +293,13 @@ on subnet %s\n",
static void remove_nth_ip_in_record( struct name_record *namerec, int ind)
{
- if( ind != namerec->data.num_ips )
- memmove( (char *)(&namerec->data.ip[ind]),
- (char *)(&namerec->data.ip[ind+1]),
- ( namerec->data.num_ips - ind - 1) * sizeof(struct in_addr) );
+ if( ind != namerec->data.num_ips )
+ memmove( (char *)(&namerec->data.ip[ind]),
+ (char *)(&namerec->data.ip[ind+1]),
+ ( namerec->data.num_ips - ind - 1) * sizeof(struct in_addr) );
- namerec->data.num_ips--;
- namerec->subnet->namelist_changed = True;
+ namerec->data.num_ips--;
+ namerec->subnet->namelist_changed = True;
}
/*******************************************************************
@@ -313,13 +308,13 @@ static void remove_nth_ip_in_record( struct name_record *namerec, int ind)
BOOL find_ip_in_name_record( struct name_record *namerec, struct in_addr ip )
{
- int i;
+ int i;
- for(i = 0; i < namerec->data.num_ips; i++)
- if(ip_equal( namerec->data.ip[i], ip))
- return True;
+ for(i = 0; i < namerec->data.num_ips; i++)
+ if(ip_equal( namerec->data.ip[i], ip))
+ return True;
- return False;
+ return False;
}
/*******************************************************************
@@ -328,30 +323,26 @@ BOOL find_ip_in_name_record( struct name_record *namerec, struct in_addr ip )
void add_ip_to_name_record( struct name_record *namerec, struct in_addr new_ip )
{
- struct in_addr *new_list;
+ struct in_addr *new_list;
- /* Don't add one we already have. */
- if( find_ip_in_name_record( namerec, new_ip ) )
- return;
+ /* Don't add one we already have. */
+ if( find_ip_in_name_record( namerec, new_ip ) )
+ return;
- new_list = (struct in_addr *)malloc( (namerec->data.num_ips + 1)
- * sizeof(struct in_addr) );
- if( NULL == new_list )
- {
- DEBUG(0,("add_ip_to_name_record: Malloc fail !\n"));
- return;
- }
-
- memcpy( (char *)new_list,
- (char *)namerec->data.ip,
- namerec->data.num_ips * sizeof(struct in_addr) );
- new_list[namerec->data.num_ips] = new_ip;
-
- SAFE_FREE(namerec->data.ip);
- namerec->data.ip = new_list;
- namerec->data.num_ips += 1;
-
- namerec->subnet->namelist_changed = True;
+ new_list = (struct in_addr *)malloc( (namerec->data.num_ips + 1) * sizeof(struct in_addr) );
+ if( NULL == new_list ) {
+ DEBUG(0,("add_ip_to_name_record: Malloc fail !\n"));
+ return;
+ }
+
+ memcpy( (char *)new_list, (char *)namerec->data.ip, namerec->data.num_ips * sizeof(struct in_addr) );
+ new_list[namerec->data.num_ips] = new_ip;
+
+ SAFE_FREE(namerec->data.ip);
+ namerec->data.ip = new_list;
+ namerec->data.num_ips += 1;
+
+ namerec->subnet->namelist_changed = True;
}
/*******************************************************************
@@ -361,16 +352,16 @@ void add_ip_to_name_record( struct name_record *namerec, struct in_addr new_ip )
void remove_ip_from_name_record( struct name_record *namerec,
struct in_addr remove_ip )
{
- /* Try and find the requested ip address - remove it. */
- int i;
- int orig_num = namerec->data.num_ips;
-
- for(i = 0; i < orig_num; i++)
- if( ip_equal( remove_ip, namerec->data.ip[i]) )
- {
- remove_nth_ip_in_record( namerec, i);
- break;
- }
+ /* Try and find the requested ip address - remove it. */
+ int i;
+ int orig_num = namerec->data.num_ips;
+
+ for(i = 0; i < orig_num; i++) {
+ if( ip_equal( remove_ip, namerec->data.ip[i]) ) {
+ remove_nth_ip_in_record( namerec, i);
+ break;
+ }
+ }
}
/*******************************************************************
@@ -384,85 +375,67 @@ void standard_success_release( struct subnet_record *subrec,
struct nmb_name *nmbname,
struct in_addr released_ip )
{
- struct name_record *namerec;
-
- namerec = find_name_on_subnet( subrec, nmbname, FIND_ANY_NAME );
-
- if( namerec == NULL )
- {
- DEBUG( 0, ( "standard_success_release: Name release for name %s IP %s \
-on subnet %s. Name was not found on subnet.\n",
- nmb_namestr(nmbname),
- inet_ntoa(released_ip),
- subrec->subnet_name) );
- return;
- }
- else
- {
- int orig_num = namerec->data.num_ips;
-
- remove_ip_from_name_record( namerec, released_ip );
-
- if( namerec->data.num_ips == orig_num )
- DEBUG( 0, ( "standard_success_release: Name release for name %s IP %s \
-on subnet %s. This ip is not known for this name.\n",
- nmb_namestr(nmbname),
- inet_ntoa(released_ip),
- subrec->subnet_name ) );
- }
-
- if( namerec->data.num_ips == 0 )
- remove_name_from_namelist( subrec, namerec );
+ struct name_record *namerec;
+
+ namerec = find_name_on_subnet( subrec, nmbname, FIND_ANY_NAME );
+ if( namerec == NULL ) {
+ DEBUG( 0, ( "standard_success_release: Name release for name %s IP %s \
+on subnet %s. Name was not found on subnet.\n", nmb_namestr(nmbname), inet_ntoa(released_ip),
+ subrec->subnet_name) );
+ return;
+ } else {
+ int orig_num = namerec->data.num_ips;
+
+ remove_ip_from_name_record( namerec, released_ip );
+
+ if( namerec->data.num_ips == orig_num )
+ DEBUG( 0, ( "standard_success_release: Name release for name %s IP %s \
+on subnet %s. This ip is not known for this name.\n", nmb_namestr(nmbname), inet_ntoa(released_ip), subrec->subnet_name ) );
+ }
+
+ if( namerec->data.num_ips == 0 )
+ remove_name_from_namelist( subrec, namerec );
}
/*******************************************************************
Expires old names in a subnet namelist.
- ******************************************************************/
+******************************************************************/
void expire_names_on_subnet(struct subnet_record *subrec, time_t t)
{
- struct name_record *namerec;
- struct name_record *next_namerec;
-
- for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
- namerec;
- namerec = next_namerec )
- {
- next_namerec = (struct name_record *)ubi_trNext( namerec );
- if( (namerec->data.death_time != PERMANENT_TTL)
- && (namerec->data.death_time < t) )
- {
- if( namerec->data.source == SELF_NAME )
- {
- DEBUG( 3, ( "expire_names_on_subnet: Subnet %s not expiring SELF \
-name %s\n",
- subrec->subnet_name, nmb_namestr(&namerec->name) ) );
- namerec->data.death_time += 300;
- namerec->subnet->namelist_changed = True;
- continue;
- }
- DEBUG(3,("expire_names_on_subnet: Subnet %s - removing expired name %s\n",
- subrec->subnet_name, nmb_namestr(&namerec->name)));
+ struct name_record *namerec;
+ struct name_record *next_namerec;
+
+ for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist ); namerec; namerec = next_namerec ) {
+ next_namerec = (struct name_record *)ubi_trNext( namerec );
+ if( (namerec->data.death_time != PERMANENT_TTL) && (namerec->data.death_time < t) ) {
+ if( namerec->data.source == SELF_NAME ) {
+ DEBUG( 3, ( "expire_names_on_subnet: Subnet %s not expiring SELF \
+name %s\n", subrec->subnet_name, nmb_namestr(&namerec->name) ) );
+ namerec->data.death_time += 300;
+ namerec->subnet->namelist_changed = True;
+ continue;
+ }
+
+ DEBUG(3,("expire_names_on_subnet: Subnet %s - removing expired name %s\n",
+ subrec->subnet_name, nmb_namestr(&namerec->name)));
- remove_name_from_namelist( subrec, namerec );
- }
- }
+ remove_name_from_namelist( subrec, namerec );
+ }
+ }
}
/*******************************************************************
Expires old names in all subnet namelists.
- ******************************************************************/
+******************************************************************/
void expire_names(time_t t)
{
- struct subnet_record *subrec;
-
- for( subrec = FIRST_SUBNET;
- subrec;
- subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec) )
- {
- expire_names_on_subnet( subrec, t );
- }
+ struct subnet_record *subrec;
+
+ for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec) ) {
+ expire_names_on_subnet( subrec, t );
+ }
}
/****************************************************************************
@@ -475,46 +448,39 @@ void expire_names(time_t t)
void add_samba_names_to_subnet( struct subnet_record *subrec )
{
- struct in_addr *iplist = &subrec->myip;
- int num_ips = 1;
-
- /* These names are added permanently (ttl of zero) and will NOT be
- refreshed. */
-
- if( (subrec == unicast_subnet)
- || (subrec == wins_server_subnet)
- || (subrec == remote_broadcast_subnet) )
- {
- struct subnet_record *bcast_subrecs;
- int i;
- /* Create an IP list containing all our known subnets. */
-
- num_ips = iface_count();
- iplist = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr) );
- if( NULL == iplist )
- {
- DEBUG(0,("add_samba_names_to_subnet: Malloc fail !\n"));
- return;
- }
-
- for( bcast_subrecs = FIRST_SUBNET, i = 0;
- bcast_subrecs;
- bcast_subrecs = NEXT_SUBNET_EXCLUDING_UNICAST(bcast_subrecs), i++ )
- iplist[i] = bcast_subrecs->myip;
-
- }
-
- (void)add_name_to_subnet(subrec,"*",0x0,samba_nb_type, PERMANENT_TTL,
- PERMANENT_NAME, num_ips, iplist);
- (void)add_name_to_subnet(subrec,"*",0x20,samba_nb_type,PERMANENT_TTL,
- PERMANENT_NAME, num_ips, iplist);
- (void)add_name_to_subnet(subrec,"__SAMBA__",0x20,samba_nb_type,PERMANENT_TTL,
- PERMANENT_NAME, num_ips, iplist);
- (void)add_name_to_subnet(subrec,"__SAMBA__",0x00,samba_nb_type,PERMANENT_TTL,
- PERMANENT_NAME, num_ips, iplist);
-
- if(iplist != &subrec->myip)
- SAFE_FREE(iplist);
+ struct in_addr *iplist = &subrec->myip;
+ int num_ips = 1;
+
+ /* These names are added permanently (ttl of zero) and will NOT be refreshed. */
+
+ if( (subrec == unicast_subnet) || (subrec == wins_server_subnet) || (subrec == remote_broadcast_subnet) ) {
+ struct subnet_record *bcast_subrecs;
+ int i;
+
+ /* Create an IP list containing all our known subnets. */
+
+ num_ips = iface_count();
+ iplist = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr) );
+ if( NULL == iplist ) {
+ DEBUG(0,("add_samba_names_to_subnet: Malloc fail !\n"));
+ return;
+ }
+
+ for( bcast_subrecs = FIRST_SUBNET, i = 0; bcast_subrecs; bcast_subrecs = NEXT_SUBNET_EXCLUDING_UNICAST(bcast_subrecs), i++ )
+ iplist[i] = bcast_subrecs->myip;
+ }
+
+ add_name_to_subnet(subrec,"*",0x0,samba_nb_type, PERMANENT_TTL,
+ PERMANENT_NAME, num_ips, iplist);
+ add_name_to_subnet(subrec,"*",0x20,samba_nb_type,PERMANENT_TTL,
+ PERMANENT_NAME, num_ips, iplist);
+ add_name_to_subnet(subrec,"__SAMBA__",0x20,samba_nb_type,PERMANENT_TTL,
+ PERMANENT_NAME, num_ips, iplist);
+ add_name_to_subnet(subrec,"__SAMBA__",0x00,samba_nb_type,PERMANENT_TTL,
+ PERMANENT_NAME, num_ips, iplist);
+
+ if(iplist != &subrec->myip)
+ SAFE_FREE(iplist);
}
/****************************************************************************
@@ -524,68 +490,65 @@ void add_samba_names_to_subnet( struct subnet_record *subrec )
static void dump_subnet_namelist( struct subnet_record *subrec, XFILE *fp)
{
- struct name_record *namerec;
- const char *src_type;
- struct tm *tm;
- int i;
-
- x_fprintf(fp, "Subnet %s\n----------------------\n", subrec->subnet_name);
- for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
- namerec;
- namerec = (struct name_record *)ubi_trNext( namerec ) )
- {
- x_fprintf(fp,"\tName = %s\t", nmb_namestr(&namerec->name));
- switch(namerec->data.source)
- {
- case LMHOSTS_NAME:
- src_type = "LMHOSTS_NAME";
- break;
- case WINS_PROXY_NAME:
- src_type = "WINS_PROXY_NAME";
- break;
- case REGISTER_NAME:
- src_type = "REGISTER_NAME";
- break;
- case SELF_NAME:
- src_type = "SELF_NAME";
- break;
- case DNS_NAME:
- src_type = "DNS_NAME";
- break;
- case DNSFAIL_NAME:
- src_type = "DNSFAIL_NAME";
- break;
- case PERMANENT_NAME:
- src_type = "PERMANENT_NAME";
- break;
- default:
- src_type = "unknown!";
- break;
- }
- x_fprintf(fp,"Source = %s\nb_flags = %x\t", src_type, namerec->data.nb_flags);
-
- if(namerec->data.death_time != PERMANENT_TTL)
- {
- tm = LocalTime(&namerec->data.death_time);
- x_fprintf(fp, "death_time = %s\t", asctime(tm));
- }
- else
- x_fprintf(fp, "death_time = PERMANENT\t");
-
- if(namerec->data.refresh_time != PERMANENT_TTL)
- {
- tm = LocalTime(&namerec->data.refresh_time);
- x_fprintf(fp, "refresh_time = %s\n", asctime(tm));
- }
- else
- x_fprintf(fp, "refresh_time = PERMANENT\n");
-
- x_fprintf(fp, "\t\tnumber of IPS = %d", namerec->data.num_ips);
- for(i = 0; i < namerec->data.num_ips; i++)
- x_fprintf(fp, "\t%s", inet_ntoa(namerec->data.ip[i]));
-
- x_fprintf(fp, "\n\n");
- }
+ struct name_record *namerec;
+ const char *src_type;
+ struct tm *tm;
+ int i;
+
+ x_fprintf(fp, "Subnet %s\n----------------------\n", subrec->subnet_name);
+ for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist ); namerec;
+ namerec = (struct name_record *)ubi_trNext( namerec ) ) {
+
+ x_fprintf(fp,"\tName = %s\t", nmb_namestr(&namerec->name));
+ switch(namerec->data.source) {
+ case LMHOSTS_NAME:
+ src_type = "LMHOSTS_NAME";
+ break;
+ case WINS_PROXY_NAME:
+ src_type = "WINS_PROXY_NAME";
+ break;
+ case REGISTER_NAME:
+ src_type = "REGISTER_NAME";
+ break;
+ case SELF_NAME:
+ src_type = "SELF_NAME";
+ break;
+ case DNS_NAME:
+ src_type = "DNS_NAME";
+ break;
+ case DNSFAIL_NAME:
+ src_type = "DNSFAIL_NAME";
+ break;
+ case PERMANENT_NAME:
+ src_type = "PERMANENT_NAME";
+ break;
+ default:
+ src_type = "unknown!";
+ break;
+ }
+
+ x_fprintf(fp,"Source = %s\nb_flags = %x\t", src_type, namerec->data.nb_flags);
+
+ if(namerec->data.death_time != PERMANENT_TTL) {
+ tm = LocalTime(&namerec->data.death_time);
+ x_fprintf(fp, "death_time = %s\t", asctime(tm));
+ } else {
+ x_fprintf(fp, "death_time = PERMANENT\t");
+ }
+
+ if(namerec->data.refresh_time != PERMANENT_TTL) {
+ tm = LocalTime(&namerec->data.refresh_time);
+ x_fprintf(fp, "refresh_time = %s\n", asctime(tm));
+ } else {
+ x_fprintf(fp, "refresh_time = PERMANENT\n");
+ }
+
+ x_fprintf(fp, "\t\tnumber of IPS = %d", namerec->data.num_ips);
+ for(i = 0; i < namerec->data.num_ips; i++)
+ x_fprintf(fp, "\t%s", inet_ntoa(namerec->data.ip[i]));
+
+ x_fprintf(fp, "\n\n");
+ }
}
/****************************************************************************
@@ -595,30 +558,27 @@ static void dump_subnet_namelist( struct subnet_record *subrec, XFILE *fp)
void dump_all_namelists(void)
{
- XFILE *fp;
- struct subnet_record *subrec;
+ XFILE *fp;
+ struct subnet_record *subrec;
- fp = x_fopen(lock_path("namelist.debug"),O_WRONLY|O_CREAT|O_TRUNC, 0644);
+ fp = x_fopen(lock_path("namelist.debug"),O_WRONLY|O_CREAT|O_TRUNC, 0644);
- if (!fp)
- {
- DEBUG(0,("dump_all_namelists: Can't open file %s. Error was %s\n",
- "namelist.debug",strerror(errno)));
- return;
- }
+ if (!fp) {
+ DEBUG(0,("dump_all_namelists: Can't open file %s. Error was %s\n",
+ "namelist.debug",strerror(errno)));
+ return;
+ }
- for( subrec = FIRST_SUBNET;
- subrec;
- subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec) )
- dump_subnet_namelist( subrec, fp );
+ for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec) )
+ dump_subnet_namelist( subrec, fp );
- if( !we_are_a_wins_client() )
- dump_subnet_namelist( unicast_subnet, fp );
+ if( !we_are_a_wins_client() )
+ dump_subnet_namelist( unicast_subnet, fp );
- if( remote_broadcast_subnet->namelist != NULL )
- dump_subnet_namelist( remote_broadcast_subnet, fp );
+ if( remote_broadcast_subnet->namelist != NULL )
+ dump_subnet_namelist( remote_broadcast_subnet, fp );
- if( wins_server_subnet != NULL )
- dump_subnet_namelist( wins_server_subnet, fp );
- x_fclose( fp );
+ if( wins_server_subnet != NULL )
+ dump_subnet_namelist( wins_server_subnet, fp );
+ x_fclose( fp );
}
diff --git a/source3/nmbd/nmbd_namequery.c b/source3/nmbd/nmbd_namequery.c
index 2a200713b9..1b07852f11 100644
--- a/source3/nmbd/nmbd_namequery.c
+++ b/source3/nmbd/nmbd_namequery.c
@@ -3,7 +3,7 @@
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Jeremy Allison 1994-2003
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
@@ -31,106 +31,95 @@ static void query_name_response( struct subnet_record *subrec,
struct response_record *rrec,
struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- BOOL success = False;
- struct nmb_name *question_name =
- &rrec->packet->packet.nmb.question.question_name;
- struct in_addr answer_ip;
-
- zero_ip(&answer_ip);
-
- /* Ensure we don't retry the query but leave the response record cleanup
- to the timeout code. We may get more answer responses in which case
- we should mark the name in conflict.. */
- rrec->repeat_count = 0;
-
- if(rrec->num_msgs == 1)
- {
- /* This is the first response. */
-
- if(nmb->header.opcode == NMB_WACK_OPCODE)
- {
- /* WINS server is telling us to wait. Pretend we didn't get
- the response but don't send out any more query requests. */
-
- if( DEBUGLVL( 5 ) )
- {
- dbgtext( "query_name_response: " );
- dbgtext( "WACK from WINS server %s ", inet_ntoa(p->ip) );
- dbgtext( "in querying name %s ", nmb_namestr(question_name) );
- dbgtext( "on subnet %s.\n", subrec->subnet_name );
- }
+ struct nmb_packet *nmb = &p->packet.nmb;
+ BOOL success = False;
+ struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;
+ struct in_addr answer_ip;
+
+ zero_ip(&answer_ip);
+
+ /* Ensure we don't retry the query but leave the response record cleanup
+ to the timeout code. We may get more answer responses in which case
+ we should mark the name in conflict.. */
+ rrec->repeat_count = 0;
+
+ if(rrec->num_msgs == 1) {
+ /* This is the first response. */
+
+ if(nmb->header.opcode == NMB_WACK_OPCODE) {
+ /* WINS server is telling us to wait. Pretend we didn't get
+ the response but don't send out any more query requests. */
+
+ if( DEBUGLVL( 5 ) ) {
+ dbgtext( "query_name_response: " );
+ dbgtext( "WACK from WINS server %s ", inet_ntoa(p->ip) );
+ dbgtext( "in querying name %s ", nmb_namestr(question_name) );
+ dbgtext( "on subnet %s.\n", subrec->subnet_name );
+ }
- rrec->repeat_count = 0;
- /* How long we should wait for. */
- rrec->repeat_time = p->timestamp + nmb->answers->ttl;
- rrec->num_msgs--;
- return;
- }
- else if(nmb->header.rcode != 0)
- {
- success = False;
-
- if( DEBUGLVL( 5 ) )
- {
- dbgtext( "query_name_response: On subnet %s ", subrec->subnet_name );
- dbgtext( "- negative response from IP %s ", inet_ntoa(p->ip) );
- dbgtext( "for name %s. ", nmb_namestr(question_name) );
- dbgtext( "Error code was %d.\n", nmb->header.rcode );
- }
- }
- else
- {
- if (!nmb->answers)
- {
- dbgtext( "query_name_response: On subnet %s ", subrec->subnet_name );
- dbgtext( "IP %s ", inet_ntoa(p->ip) );
- dbgtext( "returned a success response with no answer\n" );
- return;
- }
-
- success = True;
-
- putip((char *)&answer_ip,&nmb->answers->rdata[2]);
- if( DEBUGLVL( 5 ) )
- {
- dbgtext( "query_name_response: On subnet %s ", subrec->subnet_name );
- dbgtext( "- positive response from IP %s ", inet_ntoa(p->ip) );
- dbgtext( "for name %s. ", nmb_namestr(question_name) );
- dbgtext( "IP of that name is %s\n", inet_ntoa(answer_ip) );
- }
-
- /* Interestingly, we could add these names to our namelists, and
- change nmbd to a model that checked its own name cache first,
- before sending out a query. This is a task for another day, though.
- */
- }
- }
- else if( rrec->num_msgs > 1)
- {
- if( DEBUGLVL( 0 ) )
- {
- if (nmb->answers)
- putip( (char *)&answer_ip, &nmb->answers->rdata[2] );
- dbgtext( "query_name_response: " );
- dbgtext( "Multiple (%d) responses ", rrec->num_msgs );
- dbgtext( "received for a query on subnet %s ", subrec->subnet_name );
- dbgtext( "for name %s.\nThis response ", nmb_namestr(question_name) );
- dbgtext( "was from IP %s, reporting ", inet_ntoa(p->ip) );
- dbgtext( "an IP address of %s.\n", inet_ntoa(answer_ip) );
- }
-
- /* We have already called the success or fail function, so we
- don't call again here. Leave the response record around in
- case we get more responses. */
-
- return;
- }
+ rrec->repeat_count = 0;
+ /* How long we should wait for. */
+ rrec->repeat_time = p->timestamp + nmb->answers->ttl;
+ rrec->num_msgs--;
+ return;
+ } else if(nmb->header.rcode != 0) {
+
+ success = False;
+
+ if( DEBUGLVL( 5 ) ) {
+ dbgtext( "query_name_response: On subnet %s ", subrec->subnet_name );
+ dbgtext( "- negative response from IP %s ", inet_ntoa(p->ip) );
+ dbgtext( "for name %s. ", nmb_namestr(question_name) );
+ dbgtext( "Error code was %d.\n", nmb->header.rcode );
+ }
+ } else {
+ if (!nmb->answers) {
+ dbgtext( "query_name_response: On subnet %s ", subrec->subnet_name );
+ dbgtext( "IP %s ", inet_ntoa(p->ip) );
+ dbgtext( "returned a success response with no answer\n" );
+ return;
+ }
+
+ success = True;
+
+ putip((char *)&answer_ip,&nmb->answers->rdata[2]);
+
+ if( DEBUGLVL( 5 ) ) {
+ dbgtext( "query_name_response: On subnet %s ", subrec->subnet_name );
+ dbgtext( "- positive response from IP %s ", inet_ntoa(p->ip) );
+ dbgtext( "for name %s. ", nmb_namestr(question_name) );
+ dbgtext( "IP of that name is %s\n", inet_ntoa(answer_ip) );
+ }
+
+ /* Interestingly, we could add these names to our namelists, and
+ change nmbd to a model that checked its own name cache first,
+ before sending out a query. This is a task for another day, though.
+ */
+ }
+ } else if( rrec->num_msgs > 1) {
+
+ if( DEBUGLVL( 0 ) ) {
+ if (nmb->answers)
+ putip( (char *)&answer_ip, &nmb->answers->rdata[2] );
+ dbgtext( "query_name_response: " );
+ dbgtext( "Multiple (%d) responses ", rrec->num_msgs );
+ dbgtext( "received for a query on subnet %s ", subrec->subnet_name );
+ dbgtext( "for name %s.\nThis response ", nmb_namestr(question_name) );
+ dbgtext( "was from IP %s, reporting ", inet_ntoa(p->ip) );
+ dbgtext( "an IP address of %s.\n", inet_ntoa(answer_ip) );
+ }
+
+ /* We have already called the success or fail function, so we
+ don't call again here. Leave the response record around in
+ case we get more responses. */
+
+ return;
+ }
- if(success && rrec->success_fn)
- (*(query_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, answer_ip, nmb->answers);
- else if( rrec->fail_fn)
- (*(query_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name, nmb->header.rcode);
+ if(success && rrec->success_fn)
+ (*(query_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, answer_ip, nmb->answers);
+ else if( rrec->fail_fn)
+ (*(query_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name, nmb->header.rcode);
}
@@ -141,32 +130,30 @@ static void query_name_response( struct subnet_record *subrec,
static void query_name_timeout_response(struct subnet_record *subrec,
struct response_record *rrec)
{
- struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
- /* We can only fail here, never succeed. */
- BOOL failed = True;
- struct nmb_name *question_name = &sent_nmb->question.question_name;
-
- if(rrec->num_msgs != 0)
- {
- /* We got at least one response, and have called the success/fail
- function already. */
-
- failed = False;
- }
-
- if(failed)
- {
- if( DEBUGLVL( 5 ) )
- {
- dbgtext( "query_name_timeout_response: No response to " );
- dbgtext( "query for name %s ", nmb_namestr(question_name) );
- dbgtext( "on subnet %s.\n", subrec->subnet_name );
- }
- if(rrec->fail_fn)
- (*(query_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name, 0);
- }
-
- remove_response_record(subrec, rrec);
+ struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
+ /* We can only fail here, never succeed. */
+ BOOL failed = True;
+ struct nmb_name *question_name = &sent_nmb->question.question_name;
+
+ if(rrec->num_msgs != 0) {
+ /* We got at least one response, and have called the success/fail
+ function already. */
+
+ failed = False;
+ }
+
+ if(failed) {
+ if( DEBUGLVL( 5 ) ) {
+ dbgtext( "query_name_timeout_response: No response to " );
+ dbgtext( "query for name %s ", nmb_namestr(question_name) );
+ dbgtext( "on subnet %s.\n", subrec->subnet_name );
+ }
+
+ if(rrec->fail_fn)
+ (*(query_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name, 0);
+ }
+
+ remove_response_record(subrec, rrec);
}
/****************************************************************************
@@ -177,24 +164,21 @@ static void query_name_timeout_response(struct subnet_record *subrec,
static BOOL query_local_namelists(struct subnet_record *subrec, struct nmb_name *nmbname,
struct name_record **namerecp)
{
- struct name_record *namerec;
+ struct name_record *namerec;
- *namerecp = NULL;
+ *namerecp = NULL;
- if(find_name_in_lmhosts(nmbname, namerecp))
- return True;
+ if(find_name_in_lmhosts(nmbname, namerecp))
+ return True;
- if((namerec = find_name_on_subnet(subrec, nmbname, FIND_ANY_NAME))==NULL)
- return False;
-
- if( NAME_IS_ACTIVE(namerec)
- && ( (namerec->data.source == SELF_NAME)
- || (namerec->data.source == LMHOSTS_NAME) ) )
- {
- *namerecp = namerec;
- return True;
- }
- return False;
+ if((namerec = find_name_on_subnet(subrec, nmbname, FIND_ANY_NAME))==NULL)
+ return False;
+
+ if( NAME_IS_ACTIVE(namerec) && ( (namerec->data.source == SELF_NAME) || (namerec->data.source == LMHOSTS_NAME) ) ) {
+ *namerecp = namerec;
+ return True;
+ }
+ return False;
}
/****************************************************************************
@@ -206,69 +190,57 @@ BOOL query_name(struct subnet_record *subrec, const char *name, int type,
query_name_fail_function fail_fn,
struct userdata_struct *userdata)
{
- struct nmb_name nmbname;
- struct name_record *namerec;
-
- make_nmb_name(&nmbname, name, type);
-
- /*
- * We need to check our local namelists first.
- * It may be an magic name, lmhosts name or just
- * a name we have registered.
- */
-
- if(query_local_namelists(subrec, &nmbname, &namerec) == True)
- {
- struct res_rec rrec;
- int i;
-
- memset((char *)&rrec, '\0', sizeof(struct res_rec));
-
- /* Fake up the needed res_rec just in case it's used. */
- rrec.rr_name = nmbname;
- rrec.rr_type = RR_TYPE_NB;
- rrec.rr_class = RR_CLASS_IN;
- rrec.ttl = PERMANENT_TTL;
- rrec.rdlength = namerec->data.num_ips * 6;
- if(rrec.rdlength > MAX_DGRAM_SIZE)
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "query_name: nmbd internal error - " );
- dbgtext( "there are %d ip addresses ", namerec->data.num_ips );
- dbgtext( "for name %s.\n", nmb_namestr(&nmbname) );
- }
- return False;
- }
-
- for( i = 0; i < namerec->data.num_ips; i++)
- {
- set_nb_flags( &rrec.rdata[i*6], namerec->data.nb_flags );
- putip( &rrec.rdata[(i*6) + 2], (char *)&namerec->data.ip[i]);
- }
-
- /* Call the success function directly. */
- if(success_fn)
- (*(query_name_success_function)success_fn)(subrec, userdata, &nmbname, namerec->data.ip[0], &rrec);
- return False;
- }
-
- if(queue_query_name( subrec,
- query_name_response,
- query_name_timeout_response,
- success_fn,
- fail_fn,
- userdata,
- &nmbname) == NULL)
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "query_name: Failed to send packet " );
- dbgtext( "trying to query name %s\n", nmb_namestr(&nmbname) );
- }
- return True;
- }
- return False;
+ struct nmb_name nmbname;
+ struct name_record *namerec;
+
+ make_nmb_name(&nmbname, name, type);
+
+ /*
+ * We need to check our local namelists first.
+ * It may be an magic name, lmhosts name or just
+ * a name we have registered.
+ */
+
+ if(query_local_namelists(subrec, &nmbname, &namerec) == True) {
+ struct res_rec rrec;
+ int i;
+
+ memset((char *)&rrec, '\0', sizeof(struct res_rec));
+
+ /* Fake up the needed res_rec just in case it's used. */
+ rrec.rr_name = nmbname;
+ rrec.rr_type = RR_TYPE_NB;
+ rrec.rr_class = RR_CLASS_IN;
+ rrec.ttl = PERMANENT_TTL;
+ rrec.rdlength = namerec->data.num_ips * 6;
+ if(rrec.rdlength > MAX_DGRAM_SIZE) {
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "query_name: nmbd internal error - " );
+ dbgtext( "there are %d ip addresses ", namerec->data.num_ips );
+ dbgtext( "for name %s.\n", nmb_namestr(&nmbname) );
+ }
+ return False;
+ }
+
+ for( i = 0; i < namerec->data.num_ips; i++) {
+ set_nb_flags( &rrec.rdata[i*6], namerec->data.nb_flags );
+ putip( &rrec.rdata[(i*6) + 2], (char *)&namerec->data.ip[i]);
+ }
+
+ /* Call the success function directly. */
+ if(success_fn)
+ (*(query_name_success_function)success_fn)(subrec, userdata, &nmbname, namerec->data.ip[0], &rrec);
+ return False;
+ }
+
+ if(queue_query_name( subrec, query_name_response, query_name_timeout_response, success_fn, fail_fn, userdata, &nmbname) == NULL) {
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "query_name: Failed to send packet " );
+ dbgtext( "trying to query name %s\n", nmb_namestr(&nmbname) );
+ }
+ return True;
+ }
+ return False;
}
/****************************************************************************
@@ -281,24 +253,16 @@ BOOL query_name_from_wins_server(struct in_addr ip_to,
query_name_fail_function fail_fn,
struct userdata_struct *userdata)
{
- struct nmb_name nmbname;
-
- make_nmb_name(&nmbname, name, type);
-
- if(queue_query_name_from_wins_server( ip_to,
- query_name_response,
- query_name_timeout_response,
- success_fn,
- fail_fn,
- userdata,
- &nmbname) == NULL)
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "query_name_from_wins_server: Failed to send packet " );
- dbgtext( "trying to query name %s\n", nmb_namestr(&nmbname) );
- }
- return True;
- }
- return False;
+ struct nmb_name nmbname;
+
+ make_nmb_name(&nmbname, name, type);
+
+ if(queue_query_name_from_wins_server( ip_to, query_name_response, query_name_timeout_response, success_fn, fail_fn, userdata, &nmbname) == NULL) {
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "query_name_from_wins_server: Failed to send packet " );
+ dbgtext( "trying to query name %s\n", nmb_namestr(&nmbname) );
+ }
+ return True;
+ }
+ return False;
}
diff --git a/source3/nmbd/nmbd_nameregister.c b/source3/nmbd/nmbd_nameregister.c
index 7bf2584053..5c9deeb4db 100644
--- a/source3/nmbd/nmbd_nameregister.c
+++ b/source3/nmbd/nmbd_nameregister.c
@@ -3,7 +3,7 @@
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Jeremy Allison 1994-2003
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
@@ -85,7 +85,9 @@ static void register_name_response(struct subnet_record *subrec,
*/
#if 1 /* OLD_SAMBA_SERVER_HACK */
- if((nmb->header.rcode == ACT_ERR) && strequal(lp_workgroup(), answer_name->name) &&
+ nstring ans_name;
+ pull_ascii_nstring(ans_name, answer_name->name);
+ if((nmb->header.rcode == ACT_ERR) && strequal(lp_workgroup(), ans_name) &&
(answer_name->name_type == 0x1b)) {
/* Pretend we did not get this. */
rrec->num_msgs--;
@@ -161,10 +163,10 @@ static void register_name_response(struct subnet_record *subrec,
remove_response_record(subrec, rrec);
}
-
/****************************************************************************
Deal with a timeout of a WINS registration request
****************************************************************************/
+
static void wins_registration_timeout(struct subnet_record *subrec,
struct response_record *rrec)
{
@@ -233,7 +235,6 @@ static void wins_registration_timeout(struct subnet_record *subrec,
us trying to register with each of our failover wins servers */
}
-
/****************************************************************************
Deal with a timeout when registering one of our names.
****************************************************************************/
@@ -290,10 +291,10 @@ static void register_name_timeout_response(struct subnet_record *subrec,
remove_response_record(subrec, rrec);
}
-
/****************************************************************************
-initiate one multi-homed name registration packet
+ Initiate one multi-homed name registration packet.
****************************************************************************/
+
static void multihomed_register_one(struct nmb_name *nmbname,
uint16 nb_flags,
register_name_success_function success_fn,
@@ -336,11 +337,11 @@ static void multihomed_register_one(struct nmb_name *nmbname,
free(userdata);
}
-
/****************************************************************************
-we have finished the registration of one IP and need to see if we have
-any more IPs left to register with this group of wins server for this name
+ We have finished the registration of one IP and need to see if we have
+ any more IPs left to register with this group of wins server for this name.
****************************************************************************/
+
static void wins_next_registration(struct response_record *rrec)
{
struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
@@ -388,6 +389,7 @@ static void wins_next_registration(struct response_record *rrec)
/****************************************************************************
Try and register one of our names on the unicast subnet - multihomed.
****************************************************************************/
+
static void multihomed_register_name(struct nmb_name *nmbname, uint16 nb_flags,
register_name_success_function success_fn,
register_name_fail_function fail_fn)
@@ -416,6 +418,7 @@ static void multihomed_register_name(struct nmb_name *nmbname, uint16 nb_flags,
struct subnet_record *subrec;
char **wins_tags;
struct in_addr *ip_list;
+ nstring name;
for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) )
num_ips++;
@@ -431,7 +434,8 @@ static void multihomed_register_name(struct nmb_name *nmbname, uint16 nb_flags,
ip_list[i] = subrec->myip;
}
- add_name_to_subnet(unicast_subnet, nmbname->name, nmbname->name_type,
+ pull_ascii_nstring(name, nmbname->name);
+ add_name_to_subnet(unicast_subnet, name, nmbname->name_type,
nb_flags, lp_max_ttl(), SELF_NAME,
num_ips, ip_list);
@@ -456,10 +460,10 @@ static void multihomed_register_name(struct nmb_name *nmbname, uint16 nb_flags,
SAFE_FREE(ip_list);
}
-
/****************************************************************************
Try and register one of our names.
****************************************************************************/
+
void register_name(struct subnet_record *subrec,
const char *name, int type, uint16 nb_flags,
register_name_success_function success_fn,
@@ -498,10 +502,10 @@ void register_name(struct subnet_record *subrec,
}
}
-
/****************************************************************************
Try and refresh one of our names. This is *only* called for WINS refresh
****************************************************************************/
+
void wins_refresh_name(struct name_record *namerec)
{
int t;
diff --git a/source3/nmbd/nmbd_nodestatus.c b/source3/nmbd/nmbd_nodestatus.c
index 993e4d9d17..0ea5d6a818 100644
--- a/source3/nmbd/nmbd_nodestatus.c
+++ b/source3/nmbd/nmbd_nodestatus.c
@@ -3,7 +3,7 @@
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Jeremy Allison 1994-2003
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
@@ -26,52 +26,52 @@
/****************************************************************************
Deal with a successful node status response.
****************************************************************************/
+
static void node_status_response(struct subnet_record *subrec,
struct response_record *rrec, struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;
- struct nmb_name *answer_name = &nmb->answers->rr_name;
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;
+ struct nmb_name *answer_name = &nmb->answers->rr_name;
- /* Sanity check. Ensure that the answer name in the incoming packet is the
- same as the requested name in the outgoing packet. */
+ /* Sanity check. Ensure that the answer name in the incoming packet is the
+ same as the requested name in the outgoing packet. */
- if(!nmb_name_equal(question_name, answer_name))
- {
- DEBUG(0,("node_status_response: Answer name %s differs from question \
+ if(!nmb_name_equal(question_name, answer_name)) {
+ DEBUG(0,("node_status_response: Answer name %s differs from question \
name %s.\n", nmb_namestr(answer_name), nmb_namestr(question_name)));
- return;
- }
+ return;
+ }
- DEBUG(5,("node_status_response: response from name %s on subnet %s.\n",
- nmb_namestr(answer_name), subrec->subnet_name));
+ DEBUG(5,("node_status_response: response from name %s on subnet %s.\n",
+ nmb_namestr(answer_name), subrec->subnet_name));
- /* Just send the whole answer resource record for the success function
- to parse. */
- if(rrec->success_fn)
- (*(node_status_success_function)rrec->success_fn)(subrec, rrec->userdata, nmb->answers, p->ip);
+ /* Just send the whole answer resource record for the success function to parse. */
+ if(rrec->success_fn)
+ (*(node_status_success_function)rrec->success_fn)(subrec, rrec->userdata, nmb->answers, p->ip);
- /* Ensure we don't retry. */
- remove_response_record(subrec, rrec);
+ /* Ensure we don't retry. */
+ remove_response_record(subrec, rrec);
}
/****************************************************************************
Deal with a timeout when requesting a node status.
****************************************************************************/
+
static void node_status_timeout_response(struct subnet_record *subrec,
struct response_record *rrec)
{
- struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
- struct nmb_name *question_name = &sent_nmb->question.question_name;
+ struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
+ struct nmb_name *question_name = &sent_nmb->question.question_name;
- DEBUG(5,("node_status_timeout_response: failed to get node status from name %s on subnet %s\n",
- nmb_namestr(question_name), subrec->subnet_name));
+ DEBUG(5,("node_status_timeout_response: failed to get node status from name %s on subnet %s\n",
+ nmb_namestr(question_name), subrec->subnet_name));
- if( rrec->fail_fn)
- (*rrec->fail_fn)(subrec, rrec);
+ if( rrec->fail_fn)
+ (*rrec->fail_fn)(subrec, rrec);
- /* Ensure we don't retry. */
- remove_response_record(subrec, rrec);
+ /* Ensure we don't retry. */
+ remove_response_record(subrec, rrec);
}
/****************************************************************************
@@ -82,13 +82,11 @@ BOOL node_status(struct subnet_record *subrec, struct nmb_name *nmbname,
struct in_addr send_ip, node_status_success_function success_fn,
node_status_fail_function fail_fn, struct userdata_struct *userdata)
{
- if(queue_node_status( subrec,
- node_status_response, node_status_timeout_response,
- success_fn, fail_fn, userdata, nmbname, send_ip)==NULL)
- {
- DEBUG(0,("node_status: Failed to send packet trying to get node status for \
+ if(queue_node_status( subrec, node_status_response, node_status_timeout_response,
+ success_fn, fail_fn, userdata, nmbname, send_ip)==NULL) {
+ DEBUG(0,("node_status: Failed to send packet trying to get node status for \
name %s, IP address %s\n", nmb_namestr(nmbname), inet_ntoa(send_ip)));
- return True;
- }
- return False;
+ return True;
+ }
+ return False;
}
diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c
index 6c3446d6c8..72eb1b5019 100644
--- a/source3/nmbd/nmbd_packets.c
+++ b/source3/nmbd/nmbd_packets.c
@@ -3,7 +3,7 @@
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Jeremy Allison 1994-2003
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
@@ -50,13 +50,13 @@ Utility function to find the specific fd to send a packet out on.
static int find_subnet_fd_for_address( struct in_addr local_ip )
{
- struct subnet_record *subrec;
+ struct subnet_record *subrec;
- for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- if(ip_equal(local_ip, subrec->myip))
- return subrec->nmb_sock;
+ for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ if(ip_equal(local_ip, subrec->myip))
+ return subrec->nmb_sock;
- return ClientNMB;
+ return ClientNMB;
}
/***************************************************************************
@@ -65,13 +65,13 @@ Utility function to find the specific fd to send a mailslot packet out on.
static int find_subnet_mailslot_fd_for_address( struct in_addr local_ip )
{
- struct subnet_record *subrec;
+ struct subnet_record *subrec;
- for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- if(ip_equal(local_ip, subrec->myip))
- return subrec->dgram_sock;
+ for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ if(ip_equal(local_ip, subrec->myip))
+ return subrec->dgram_sock;
- return ClientDGRAM;
+ return ClientDGRAM;
}
/***************************************************************************
@@ -80,13 +80,13 @@ Get/Set problematic nb_flags as network byte order 16 bit int.
uint16 get_nb_flags(char *buf)
{
- return ((((uint16)*buf)&0xFFFF) & NB_FLGMSK);
+ return ((((uint16)*buf)&0xFFFF) & NB_FLGMSK);
}
void set_nb_flags(char *buf, uint16 nb_flags)
{
- *buf++ = ((nb_flags & NB_FLGMSK) & 0xFF);
- *buf = '\0';
+ *buf++ = ((nb_flags & NB_FLGMSK) & 0xFF);
+ *buf = '\0';
}
/***************************************************************************
@@ -95,37 +95,34 @@ Dumps out the browse packet data.
static void debug_browse_data(char *outbuf, int len)
{
- int i,j;
-
- DEBUG( 4, ( "debug_browse_data():\n" ) );
- for (i = 0; i < len; i+= 16)
- {
- DEBUGADD( 4, ( "%3x char ", i ) );
-
- for (j = 0; j < 16; j++)
- {
- unsigned char x;
- if (i+j >= len)
- break;
-
- x = outbuf[i+j];
- if (x < 32 || x > 127)
- x = '.';
+ int i,j;
+
+ DEBUG( 4, ( "debug_browse_data():\n" ) );
+ for (i = 0; i < len; i+= 16) {
+ DEBUGADD( 4, ( "%3x char ", i ) );
+
+ for (j = 0; j < 16; j++) {
+ unsigned char x;
+ if (i+j >= len)
+ break;
+
+ x = outbuf[i+j];
+ if (x < 32 || x > 127)
+ x = '.';
- DEBUGADD( 4, ( "%c", x ) );
- }
+ DEBUGADD( 4, ( "%c", x ) );
+ }
- DEBUGADD( 4, ( "%*s hex", 16-j, "" ) );
+ DEBUGADD( 4, ( "%*s hex", 16-j, "" ) );
- for (j = 0; j < 16; j++)
- {
- if (i+j >= len)
- break;
- DEBUGADD( 4, ( " %02x", (unsigned char)outbuf[i+j] ) );
- }
+ for (j = 0; j < 16; j++) {
+ if (i+j >= len)
+ break;
+ DEBUGADD( 4, ( " %02x", (unsigned char)outbuf[i+j] ) );
+ }
- DEBUGADD( 4, ("\n") );
- }
+ DEBUGADD( 4, ("\n") );
+ }
}
/***************************************************************************
@@ -136,13 +133,11 @@ static uint16 name_trn_id=0;
static uint16 generate_name_trn_id(void)
{
-
- if (!name_trn_id)
- {
- name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100);
- }
- name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
- return name_trn_id;
+ if (!name_trn_id) {
+ name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100);
+ }
+ name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
+ return name_trn_id;
}
/***************************************************************************
@@ -151,28 +146,25 @@ static uint16 generate_name_trn_id(void)
static BOOL send_netbios_packet(struct packet_struct *p)
{
- BOOL loopback_this_packet = False;
-
- /* Check if we are sending to or from ourselves as a WINS server. */
- if(ismyip(p->ip) && (p->port == global_nmb_port))
- loopback_this_packet = True;
-
- if(loopback_this_packet)
- {
- struct packet_struct *lo_packet = NULL;
- DEBUG(5,("send_netbios_packet: sending packet to ourselves.\n"));
- if((lo_packet = copy_packet(p)) == NULL)
- return False;
- queue_packet(lo_packet);
- }
- else if (!send_packet(p))
- {
- DEBUG(0,("send_netbios_packet: send_packet() to IP %s port %d failed\n",
- inet_ntoa(p->ip),p->port));
- return False;
- }
+ BOOL loopback_this_packet = False;
+
+ /* Check if we are sending to or from ourselves as a WINS server. */
+ if(ismyip(p->ip) && (p->port == global_nmb_port))
+ loopback_this_packet = True;
+
+ if(loopback_this_packet) {
+ struct packet_struct *lo_packet = NULL;
+ DEBUG(5,("send_netbios_packet: sending packet to ourselves.\n"));
+ if((lo_packet = copy_packet(p)) == NULL)
+ return False;
+ queue_packet(lo_packet);
+ } else if (!send_packet(p)) {
+ DEBUG(0,("send_netbios_packet: send_packet() to IP %s port %d failed\n",
+ inet_ntoa(p->ip),p->port));
+ return False;
+ }
- return True;
+ return True;
}
/***************************************************************************
@@ -188,45 +180,44 @@ static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmb
BOOL bcast, BOOL rec_des,
struct in_addr to_ip)
{
- struct packet_struct *packet = NULL;
- struct nmb_packet *nmb = NULL;
-
- /* Allocate the packet_struct we will return. */
- if((packet = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
- {
- DEBUG(0,("create_and_init_netbios_packet: malloc fail (1) for packet struct.\n"));
- return NULL;
- }
+ struct packet_struct *packet = NULL;
+ struct nmb_packet *nmb = NULL;
+
+ /* Allocate the packet_struct we will return. */
+ if((packet = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) {
+ DEBUG(0,("create_and_init_netbios_packet: malloc fail (1) for packet struct.\n"));
+ return NULL;
+ }
- memset((char *)packet,'\0',sizeof(*packet));
+ memset((char *)packet,'\0',sizeof(*packet));
- nmb = &packet->packet.nmb;
+ nmb = &packet->packet.nmb;
- nmb->header.name_trn_id = generate_name_trn_id();
- nmb->header.response = False;
- nmb->header.nm_flags.recursion_desired = rec_des;
- nmb->header.nm_flags.recursion_available = False;
- nmb->header.nm_flags.trunc = False;
- nmb->header.nm_flags.authoritative = False;
- nmb->header.nm_flags.bcast = bcast;
+ nmb->header.name_trn_id = generate_name_trn_id();
+ nmb->header.response = False;
+ nmb->header.nm_flags.recursion_desired = rec_des;
+ nmb->header.nm_flags.recursion_available = False;
+ nmb->header.nm_flags.trunc = False;
+ nmb->header.nm_flags.authoritative = False;
+ nmb->header.nm_flags.bcast = bcast;
- nmb->header.rcode = 0;
- nmb->header.qdcount = 1;
- nmb->header.ancount = 0;
- nmb->header.nscount = 0;
-
- nmb->question.question_name = *nmbname;
- nmb->question.question_type = QUESTION_TYPE_NB_QUERY;
- nmb->question.question_class = QUESTION_CLASS_IN;
-
- packet->ip = to_ip;
- packet->port = NMB_PORT;
- packet->fd = ClientNMB;
- packet->timestamp = time(NULL);
- packet->packet_type = NMB_PACKET;
- packet->locked = False;
+ nmb->header.rcode = 0;
+ nmb->header.qdcount = 1;
+ nmb->header.ancount = 0;
+ nmb->header.nscount = 0;
+
+ nmb->question.question_name = *nmbname;
+ nmb->question.question_type = QUESTION_TYPE_NB_QUERY;
+ nmb->question.question_class = QUESTION_CLASS_IN;
+
+ packet->ip = to_ip;
+ packet->port = NMB_PORT;
+ packet->fd = ClientNMB;
+ packet->timestamp = time(NULL);
+ packet->packet_type = NMB_PACKET;
+ packet->locked = False;
- return packet; /* Caller must free. */
+ return packet; /* Caller must free. */
}
/***************************************************************************
@@ -283,20 +274,20 @@ static BOOL create_and_init_additional_record(struct packet_struct *packet,
static BOOL initiate_name_query_packet( struct packet_struct *packet)
{
- struct nmb_packet *nmb = NULL;
+ struct nmb_packet *nmb = NULL;
- nmb = &packet->packet.nmb;
+ nmb = &packet->packet.nmb;
- nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
- nmb->header.arcount = 0;
+ nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
+ nmb->header.arcount = 0;
- nmb->header.nm_flags.recursion_desired = True;
+ nmb->header.nm_flags.recursion_desired = True;
- DEBUG(4,("initiate_name_query_packet: sending query for name %s (bcast=%s) to IP %s\n",
- nmb_namestr(&nmb->question.question_name),
- BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
+ DEBUG(4,("initiate_name_query_packet: sending query for name %s (bcast=%s) to IP %s\n",
+ nmb_namestr(&nmb->question.question_name),
+ BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
- return send_netbios_packet( packet );
+ return send_netbios_packet( packet );
}
/***************************************************************************
@@ -305,20 +296,20 @@ static BOOL initiate_name_query_packet( struct packet_struct *packet)
static BOOL initiate_name_query_packet_from_wins_server( struct packet_struct *packet)
{
- struct nmb_packet *nmb = NULL;
+ struct nmb_packet *nmb = NULL;
- nmb = &packet->packet.nmb;
+ nmb = &packet->packet.nmb;
- nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
- nmb->header.arcount = 0;
+ nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
+ nmb->header.arcount = 0;
- nmb->header.nm_flags.recursion_desired = False;
+ nmb->header.nm_flags.recursion_desired = False;
- DEBUG(4,("initiate_name_query_packet_from_wins_server: sending query for name %s (bcast=%s) to IP %s\n",
- nmb_namestr(&nmb->question.question_name),
- BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
+ DEBUG(4,("initiate_name_query_packet_from_wins_server: sending query for name %s (bcast=%s) to IP %s\n",
+ nmb_namestr(&nmb->question.question_name),
+ BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
- return send_netbios_packet( packet );
+ return send_netbios_packet( packet );
}
/***************************************************************************
@@ -328,21 +319,21 @@ static BOOL initiate_name_query_packet_from_wins_server( struct packet_struct *p
static BOOL initiate_name_register_packet( struct packet_struct *packet,
uint16 nb_flags, struct in_addr *register_ip)
{
- struct nmb_packet *nmb = &packet->packet.nmb;
+ struct nmb_packet *nmb = &packet->packet.nmb;
- nmb->header.opcode = NMB_NAME_REG_OPCODE;
- nmb->header.arcount = 1;
+ nmb->header.opcode = NMB_NAME_REG_OPCODE;
+ nmb->header.arcount = 1;
- nmb->header.nm_flags.recursion_desired = True;
+ nmb->header.nm_flags.recursion_desired = True;
- if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
- return False;
+ if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
+ return False;
- DEBUG(4,("initiate_name_register_packet: sending registration for name %s (bcast=%s) to IP %s\n",
- nmb_namestr(&nmb->additional->rr_name),
- BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
+ DEBUG(4,("initiate_name_register_packet: sending registration for name %s (bcast=%s) to IP %s\n",
+ nmb_namestr(&nmb->additional->rr_name),
+ BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
- return send_netbios_packet( packet );
+ return send_netbios_packet( packet );
}
/***************************************************************************
@@ -380,21 +371,21 @@ for name %s IP %s (bcast=%s) to IP %s\n",
static BOOL initiate_name_refresh_packet( struct packet_struct *packet,
uint16 nb_flags, struct in_addr *refresh_ip)
{
- struct nmb_packet *nmb = &packet->packet.nmb;
+ struct nmb_packet *nmb = &packet->packet.nmb;
- nmb->header.opcode = NMB_NAME_REFRESH_OPCODE_8;
- nmb->header.arcount = 1;
+ nmb->header.opcode = NMB_NAME_REFRESH_OPCODE_8;
+ nmb->header.arcount = 1;
- nmb->header.nm_flags.recursion_desired = False;
+ nmb->header.nm_flags.recursion_desired = False;
- if(create_and_init_additional_record(packet, nb_flags, refresh_ip) == False)
- return False;
+ if(create_and_init_additional_record(packet, nb_flags, refresh_ip) == False)
+ return False;
- DEBUG(4,("initiate_name_refresh_packet: sending refresh for name %s (bcast=%s) to IP %s\n",
- nmb_namestr(&nmb->additional->rr_name),
- BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
+ DEBUG(4,("initiate_name_refresh_packet: sending refresh for name %s (bcast=%s) to IP %s\n",
+ nmb_namestr(&nmb->additional->rr_name),
+ BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
- return send_netbios_packet( packet );
+ return send_netbios_packet( packet );
}
/***************************************************************************
@@ -404,21 +395,21 @@ static BOOL initiate_name_refresh_packet( struct packet_struct *packet,
static BOOL initiate_name_release_packet( struct packet_struct *packet,
uint16 nb_flags, struct in_addr *release_ip)
{
- struct nmb_packet *nmb = &packet->packet.nmb;
+ struct nmb_packet *nmb = &packet->packet.nmb;
- nmb->header.opcode = NMB_NAME_RELEASE_OPCODE;
- nmb->header.arcount = 1;
+ nmb->header.opcode = NMB_NAME_RELEASE_OPCODE;
+ nmb->header.arcount = 1;
- nmb->header.nm_flags.recursion_desired = False;
+ nmb->header.nm_flags.recursion_desired = False;
- if(create_and_init_additional_record(packet, nb_flags, release_ip) == False)
- return False;
+ if(create_and_init_additional_record(packet, nb_flags, release_ip) == False)
+ return False;
- DEBUG(4,("initiate_name_release_packet: sending release for name %s (bcast=%s) to IP %s\n",
- nmb_namestr(&nmb->additional->rr_name),
- BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
+ DEBUG(4,("initiate_name_release_packet: sending release for name %s (bcast=%s) to IP %s\n",
+ nmb_namestr(&nmb->additional->rr_name),
+ BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
- return send_netbios_packet( packet );
+ return send_netbios_packet( packet );
}
/***************************************************************************
@@ -427,20 +418,20 @@ static BOOL initiate_name_release_packet( struct packet_struct *packet,
static BOOL initiate_node_status_packet( struct packet_struct *packet )
{
- struct nmb_packet *nmb = &packet->packet.nmb;
+ struct nmb_packet *nmb = &packet->packet.nmb;
- nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
- nmb->header.arcount = 0;
+ nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
+ nmb->header.arcount = 0;
- nmb->header.nm_flags.recursion_desired = False;
+ nmb->header.nm_flags.recursion_desired = False;
- nmb->question.question_type = QUESTION_TYPE_NB_STATUS;
+ nmb->question.question_type = QUESTION_TYPE_NB_STATUS;
- DEBUG(4,("initiate_node_status_packet: sending node status request for name %s to IP %s\n",
- nmb_namestr(&nmb->question.question_name),
- inet_ntoa(packet->ip)));
+ DEBUG(4,("initiate_node_status_packet: sending node status request for name %s to IP %s\n",
+ nmb_namestr(&nmb->question.question_name),
+ inet_ntoa(packet->ip)));
- return send_netbios_packet( packet );
+ return send_netbios_packet( packet );
}
/****************************************************************************
@@ -456,13 +447,12 @@ static BOOL initiate_node_status_packet( struct packet_struct *packet )
static BOOL assert_check_subnet(struct subnet_record *subrec)
{
- if( subrec == remote_broadcast_subnet)
- {
- DEBUG(0,("assert_check_subnet: Attempt to send packet on remote broadcast subnet. \
+ if( subrec == remote_broadcast_subnet) {
+ DEBUG(0,("assert_check_subnet: Attempt to send packet on remote broadcast subnet. \
This is a bug.\n"));
- return True;
- }
- return False;
+ return True;
+ }
+ return False;
}
/****************************************************************************
@@ -478,46 +468,42 @@ struct response_record *queue_register_name( struct subnet_record *subrec,
struct nmb_name *nmbname,
uint16 nb_flags)
{
- struct packet_struct *p;
- struct response_record *rrec;
-
- if(assert_check_subnet(subrec))
- return NULL;
-
- /* note that all name registration requests have RD set (rfc1002 -
- section 4.2.2 */
- if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), True,
- subrec->bcast_ip)) == NULL)
- return NULL;
-
- if(initiate_name_register_packet( p, nb_flags,
- iface_ip(subrec->bcast_ip)) == False)
- {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- if((rrec = make_response_record(subrec, /* subnet record. */
- p, /* packet we sent. */
- resp_fn, /* function to call on response. */
- timeout_fn, /* function to call on timeout. */
- (success_function)success_fn, /* function to call on operation success. */
- (fail_function)fail_fn, /* function to call on operation fail. */
- userdata)) == NULL)
- {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- return rrec;
-}
+ struct packet_struct *p;
+ struct response_record *rrec;
+
+ if(assert_check_subnet(subrec))
+ return NULL;
+
+ /* note that all name registration requests have RD set (rfc1002 - section 4.2.2 */
+ if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), True,
+ subrec->bcast_ip)) == NULL)
+ return NULL;
+
+ if(initiate_name_register_packet( p, nb_flags, iface_ip(subrec->bcast_ip)) == False) {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ if((rrec = make_response_record(subrec, /* subnet record. */
+ p, /* packet we sent. */
+ resp_fn, /* function to call on response. */
+ timeout_fn, /* function to call on timeout. */
+ (success_function)success_fn, /* function to call on operation success. */
+ (fail_function)fail_fn, /* function to call on operation fail. */
+ userdata)) == NULL) {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+ return rrec;
+}
/****************************************************************************
Queue a refresh name packet to the broadcast address of a subnet.
****************************************************************************/
+
void queue_wins_refresh(struct nmb_name *nmbname,
response_function resp_fn,
timeout_response_function timeout_fn,
@@ -648,47 +634,44 @@ struct response_record *queue_release_name( struct subnet_record *subrec,
struct in_addr release_ip,
struct in_addr dest_ip)
{
- struct packet_struct *p;
- struct response_record *rrec;
-
- if(assert_check_subnet(subrec))
- return NULL;
-
- if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), False,
- dest_ip)) == NULL)
- return NULL;
-
- if(initiate_name_release_packet( p, nb_flags, &release_ip) == False)
- {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- if((rrec = make_response_record(subrec, /* subnet record. */
- p, /* packet we sent. */
- resp_fn, /* function to call on response. */
- timeout_fn, /* function to call on timeout. */
- (success_function)success_fn, /* function to call on operation success. */
- (fail_function)fail_fn, /* function to call on operation fail. */
- userdata)) == NULL)
- {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- /*
- * For a broadcast release packet, only send once.
- * This will cause us to remove the name asap. JRA.
- */
-
- if (subrec != unicast_subnet) {
- rrec->repeat_count = 0;
- rrec->repeat_time = 0;
- }
-
- return rrec;
+ struct packet_struct *p;
+ struct response_record *rrec;
+
+ if(assert_check_subnet(subrec))
+ return NULL;
+
+ if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), False, dest_ip)) == NULL)
+ return NULL;
+
+ if(initiate_name_release_packet( p, nb_flags, &release_ip) == False) {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ if((rrec = make_response_record(subrec, /* subnet record. */
+ p, /* packet we sent. */
+ resp_fn, /* function to call on response. */
+ timeout_fn, /* function to call on timeout. */
+ (success_function)success_fn, /* function to call on operation success. */
+ (fail_function)fail_fn, /* function to call on operation fail. */
+ userdata)) == NULL) {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ /*
+ * For a broadcast release packet, only send once.
+ * This will cause us to remove the name asap. JRA.
+ */
+
+ if (subrec != unicast_subnet) {
+ rrec->repeat_count = 0;
+ rrec->repeat_time = 0;
+ }
+
+ return rrec;
}
/****************************************************************************
@@ -703,80 +686,80 @@ struct response_record *queue_query_name( struct subnet_record *subrec,
struct userdata_struct *userdata,
struct nmb_name *nmbname)
{
- struct packet_struct *p;
- struct response_record *rrec;
- struct in_addr to_ip;
+ struct packet_struct *p;
+ struct response_record *rrec;
+ struct in_addr to_ip;
- if(assert_check_subnet(subrec))
- return NULL;
+ if(assert_check_subnet(subrec))
+ return NULL;
- to_ip = subrec->bcast_ip;
+ to_ip = subrec->bcast_ip;
- /* queries to the WINS server turn up here as queries to IP 0.0.0.0
- These need to be handled a bit differently */
- if (subrec->type == UNICAST_SUBNET && is_zero_ip(to_ip)) {
- /* what we really need to do is loop over each of our wins
- * servers and wins server tags here, but that just doesn't
- * fit our architecture at the moment (userdata may already
- * be used when we get here). For now we just query the first
- * active wins server on the first tag. */
- char **tags = wins_srv_tags();
- if (!tags) {
- return NULL;
- }
- to_ip = wins_srv_ip_tag(tags[0], to_ip);
- wins_srv_tags_free(tags);
- }
-
- if(( p = create_and_init_netbios_packet(nmbname,
- (subrec != unicast_subnet),
- (subrec == unicast_subnet),
- to_ip)) == NULL)
- return NULL;
-
- if(lp_bind_interfaces_only()) {
- int i;
-
- DEBUG(10,("queue_query_name: bind_interfaces_only is set, looking for suitable source IP\n"));
- for(i = 0; i < iface_count(); i++) {
- struct in_addr *ifip = iface_n_ip(i);
-
- if(ifip == NULL) {
- DEBUG(0,("queue_query_name: interface %d has NULL IP address !\n", i));
- continue;
- }
-
- if (ip_equal(*ifip,loopback_ip)) {
- DEBUG(5,("queue_query_name: ignoring loopback interface (%d)\n", i));
- continue;
- }
-
- DEBUG(10,("queue_query_name: using source IP %s\n",inet_ntoa(*ifip)));
- p->fd = find_subnet_fd_for_address( *ifip );
- break;
- }
- }
-
- if(initiate_name_query_packet( p ) == False) {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- if((rrec = make_response_record(subrec, /* subnet record. */
- p, /* packet we sent. */
- resp_fn, /* function to call on response. */
- timeout_fn, /* function to call on timeout. */
- (success_function)success_fn, /* function to call on operation success. */
- (fail_function)fail_fn, /* function to call on operation fail. */
- userdata)) == NULL)
- {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- return rrec;
+ /* queries to the WINS server turn up here as queries to IP 0.0.0.0
+ These need to be handled a bit differently */
+ if (subrec->type == UNICAST_SUBNET && is_zero_ip(to_ip)) {
+ /* What we really need to do is loop over each of our wins
+ * servers and wins server tags here, but that just doesn't
+ * fit our architecture at the moment (userdata may already
+ * be used when we get here). For now we just query the first
+ * active wins server on the first tag.
+ */
+ char **tags = wins_srv_tags();
+ if (!tags) {
+ return NULL;
+ }
+ to_ip = wins_srv_ip_tag(tags[0], to_ip);
+ wins_srv_tags_free(tags);
+ }
+
+ if(( p = create_and_init_netbios_packet(nmbname,
+ (subrec != unicast_subnet),
+ (subrec == unicast_subnet),
+ to_ip)) == NULL)
+ return NULL;
+
+ if(lp_bind_interfaces_only()) {
+ int i;
+
+ DEBUG(10,("queue_query_name: bind_interfaces_only is set, looking for suitable source IP\n"));
+ for(i = 0; i < iface_count(); i++) {
+ struct in_addr *ifip = iface_n_ip(i);
+
+ if(ifip == NULL) {
+ DEBUG(0,("queue_query_name: interface %d has NULL IP address !\n", i));
+ continue;
+ }
+
+ if (ip_equal(*ifip,loopback_ip)) {
+ DEBUG(5,("queue_query_name: ignoring loopback interface (%d)\n", i));
+ continue;
+ }
+
+ DEBUG(10,("queue_query_name: using source IP %s\n",inet_ntoa(*ifip)));
+ p->fd = find_subnet_fd_for_address( *ifip );
+ break;
+ }
+ }
+
+ if(initiate_name_query_packet( p ) == False) {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ if((rrec = make_response_record(subrec, /* subnet record. */
+ p, /* packet we sent. */
+ resp_fn, /* function to call on response. */
+ timeout_fn, /* function to call on timeout. */
+ (success_function)success_fn, /* function to call on operation success. */
+ (fail_function)fail_fn, /* function to call on operation fail. */
+ userdata)) == NULL) {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ return rrec;
}
/****************************************************************************
@@ -791,33 +774,31 @@ struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip,
struct userdata_struct *userdata,
struct nmb_name *nmbname)
{
- struct packet_struct *p;
- struct response_record *rrec;
-
- if ((p = create_and_init_netbios_packet(nmbname, False, False, to_ip)) == NULL)
- return NULL;
-
- if(initiate_name_query_packet_from_wins_server( p ) == False)
- {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- if((rrec = make_response_record(wins_server_subnet, /* subnet record. */
- p, /* packet we sent. */
- resp_fn, /* function to call on response. */
- timeout_fn, /* function to call on timeout. */
- (success_function)success_fn, /* function to call on operation success. */
- (fail_function)fail_fn, /* function to call on operation fail. */
- userdata)) == NULL)
- {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- return rrec;
+ struct packet_struct *p;
+ struct response_record *rrec;
+
+ if ((p = create_and_init_netbios_packet(nmbname, False, False, to_ip)) == NULL)
+ return NULL;
+
+ if(initiate_name_query_packet_from_wins_server( p ) == False) {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ if((rrec = make_response_record(wins_server_subnet, /* subnet record. */
+ p, /* packet we sent. */
+ resp_fn, /* function to call on response. */
+ timeout_fn, /* function to call on timeout. */
+ (success_function)success_fn, /* function to call on operation success. */
+ (fail_function)fail_fn, /* function to call on operation fail. */
+ userdata)) == NULL) {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ return rrec;
}
/****************************************************************************
@@ -833,45 +814,41 @@ struct response_record *queue_node_status( struct subnet_record *subrec,
struct nmb_name *nmbname,
struct in_addr send_ip)
{
- struct packet_struct *p;
- struct response_record *rrec;
+ struct packet_struct *p;
+ struct response_record *rrec;
- /* Sanity check. */
- if(subrec != unicast_subnet)
- {
- DEBUG(0,("queue_register_multihomed_name: should only be done on \
+ /* Sanity check. */
+ if(subrec != unicast_subnet) {
+ DEBUG(0,("queue_register_multihomed_name: should only be done on \
unicast subnet. subnet is %s\n.", subrec->subnet_name ));
- return NULL;
- }
-
- if(assert_check_subnet(subrec))
- return NULL;
-
- if(( p = create_and_init_netbios_packet(nmbname, False, False,
- send_ip)) == NULL)
- return NULL;
-
- if(initiate_node_status_packet(p) == False)
- {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- if((rrec = make_response_record(subrec, /* subnet record. */
- p, /* packet we sent. */
- resp_fn, /* function to call on response. */
- timeout_fn, /* function to call on timeout. */
- (success_function)success_fn, /* function to call on operation success. */
- (fail_function)fail_fn, /* function to call on operation fail. */
- userdata)) == NULL)
- {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
-
- return rrec;
+ return NULL;
+ }
+
+ if(assert_check_subnet(subrec))
+ return NULL;
+
+ if(( p = create_and_init_netbios_packet(nmbname, False, False, send_ip)) == NULL)
+ return NULL;
+
+ if(initiate_node_status_packet(p) == False) {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ if((rrec = make_response_record(subrec, /* subnet record. */
+ p, /* packet we sent. */
+ resp_fn, /* function to call on response. */
+ timeout_fn, /* function to call on timeout. */
+ (success_function)success_fn, /* function to call on operation success. */
+ (fail_function)fail_fn, /* function to call on operation fail. */
+ userdata)) == NULL) {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ return rrec;
}
/****************************************************************************
@@ -882,169 +859,145 @@ void reply_netbios_packet(struct packet_struct *orig_packet,
int rcode, enum netbios_reply_type_code rcv_code, int opcode,
int ttl, char *data,int len)
{
- struct packet_struct packet;
- struct nmb_packet *nmb = NULL;
- struct res_rec answers;
- struct nmb_packet *orig_nmb = &orig_packet->packet.nmb;
- BOOL loopback_this_packet = False;
- const char *packet_type = "unknown";
+ struct packet_struct packet;
+ struct nmb_packet *nmb = NULL;
+ struct res_rec answers;
+ struct nmb_packet *orig_nmb = &orig_packet->packet.nmb;
+ BOOL loopback_this_packet = False;
+ const char *packet_type = "unknown";
- /* Check if we are sending to or from ourselves. */
- if(ismyip(orig_packet->ip) && (orig_packet->port == global_nmb_port))
- loopback_this_packet = True;
+ /* Check if we are sending to or from ourselves. */
+ if(ismyip(orig_packet->ip) && (orig_packet->port == global_nmb_port))
+ loopback_this_packet = True;
- nmb = &packet.packet.nmb;
-
- /* Do a partial copy of the packet. We clear the locked flag and
- the resource record pointers. */
- packet = *orig_packet; /* Full structure copy. */
- packet.locked = False;
- nmb->answers = NULL;
- nmb->nsrecs = NULL;
- nmb->additional = NULL;
-
- switch (rcv_code)
- {
- case NMB_STATUS:
- {
- packet_type = "nmb_status";
- nmb->header.nm_flags.recursion_desired = False;
- nmb->header.nm_flags.recursion_available = False;
- break;
- }
- case NMB_QUERY:
- {
- packet_type = "nmb_query";
- nmb->header.nm_flags.recursion_desired = True;
- nmb->header.nm_flags.recursion_available = True;
- break;
- }
- case NMB_REG:
- case NMB_REG_REFRESH:
- {
- packet_type = "nmb_reg";
- nmb->header.nm_flags.recursion_desired = True;
- nmb->header.nm_flags.recursion_available = True;
- break;
- }
- case NMB_REL:
- {
- packet_type = "nmb_rel";
- nmb->header.nm_flags.recursion_desired = False;
- nmb->header.nm_flags.recursion_available = False;
- break;
- }
- case NMB_WAIT_ACK:
- {
- packet_type = "nmb_wack";
- nmb->header.nm_flags.recursion_desired = False;
- nmb->header.nm_flags.recursion_available = False;
- break;
- }
- case WINS_REG:
- {
- packet_type = "wins_reg";
- nmb->header.nm_flags.recursion_desired = True;
- nmb->header.nm_flags.recursion_available = True;
- break;
- }
- case WINS_QUERY:
- {
- packet_type = "wins_query";
- nmb->header.nm_flags.recursion_desired = True;
- nmb->header.nm_flags.recursion_available = True;
- break;
- }
-
- default:
- {
- DEBUG(0,("reply_netbios_packet: Unknown packet type: %s %s to ip %s\n",
- packet_type, nmb_namestr(&orig_nmb->question.question_name),
- inet_ntoa(packet.ip)));
-
- return;
- }
- }
-
- DEBUG(4,("reply_netbios_packet: sending a reply of packet type: %s %s to ip %s \
-for id %hu\n",
- packet_type, nmb_namestr(&orig_nmb->question.question_name),
- inet_ntoa(packet.ip), orig_nmb->header.name_trn_id));
-
- nmb->header.name_trn_id = orig_nmb->header.name_trn_id;
- nmb->header.opcode = opcode;
- nmb->header.response = True;
- nmb->header.nm_flags.bcast = False;
- nmb->header.nm_flags.trunc = False;
- nmb->header.nm_flags.authoritative = True;
+ nmb = &packet.packet.nmb;
+
+ /* Do a partial copy of the packet. We clear the locked flag and
+ the resource record pointers. */
+ packet = *orig_packet; /* Full structure copy. */
+ packet.locked = False;
+ nmb->answers = NULL;
+ nmb->nsrecs = NULL;
+ nmb->additional = NULL;
+
+ switch (rcv_code) {
+ case NMB_STATUS:
+ packet_type = "nmb_status";
+ nmb->header.nm_flags.recursion_desired = False;
+ nmb->header.nm_flags.recursion_available = False;
+ break;
+ case NMB_QUERY:
+ packet_type = "nmb_query";
+ nmb->header.nm_flags.recursion_desired = True;
+ nmb->header.nm_flags.recursion_available = True;
+ break;
+ case NMB_REG:
+ case NMB_REG_REFRESH:
+ packet_type = "nmb_reg";
+ nmb->header.nm_flags.recursion_desired = True;
+ nmb->header.nm_flags.recursion_available = True;
+ break;
+ case NMB_REL:
+ packet_type = "nmb_rel";
+ nmb->header.nm_flags.recursion_desired = False;
+ nmb->header.nm_flags.recursion_available = False;
+ break;
+ case NMB_WAIT_ACK:
+ packet_type = "nmb_wack";
+ nmb->header.nm_flags.recursion_desired = False;
+ nmb->header.nm_flags.recursion_available = False;
+ break;
+ case WINS_REG:
+ packet_type = "wins_reg";
+ nmb->header.nm_flags.recursion_desired = True;
+ nmb->header.nm_flags.recursion_available = True;
+ break;
+ case WINS_QUERY:
+ packet_type = "wins_query";
+ nmb->header.nm_flags.recursion_desired = True;
+ nmb->header.nm_flags.recursion_available = True;
+ break;
+ default:
+ DEBUG(0,("reply_netbios_packet: Unknown packet type: %s %s to ip %s\n",
+ packet_type, nmb_namestr(&orig_nmb->question.question_name),
+ inet_ntoa(packet.ip)));
+ return;
+ }
+
+ DEBUG(4,("reply_netbios_packet: sending a reply of packet type: %s %s to ip %s \
+for id %hu\n", packet_type, nmb_namestr(&orig_nmb->question.question_name),
+ inet_ntoa(packet.ip), orig_nmb->header.name_trn_id));
+
+ nmb->header.name_trn_id = orig_nmb->header.name_trn_id;
+ nmb->header.opcode = opcode;
+ nmb->header.response = True;
+ nmb->header.nm_flags.bcast = False;
+ nmb->header.nm_flags.trunc = False;
+ nmb->header.nm_flags.authoritative = True;
- nmb->header.rcode = rcode;
- nmb->header.qdcount = 0;
- nmb->header.ancount = 1;
- nmb->header.nscount = 0;
- nmb->header.arcount = 0;
+ nmb->header.rcode = rcode;
+ nmb->header.qdcount = 0;
+ nmb->header.ancount = 1;
+ nmb->header.nscount = 0;
+ nmb->header.arcount = 0;
- memset((char*)&nmb->question,'\0',sizeof(nmb->question));
+ memset((char*)&nmb->question,'\0',sizeof(nmb->question));
- nmb->answers = &answers;
- memset((char*)nmb->answers,'\0',sizeof(*nmb->answers));
+ nmb->answers = &answers;
+ memset((char*)nmb->answers,'\0',sizeof(*nmb->answers));
- nmb->answers->rr_name = orig_nmb->question.question_name;
- nmb->answers->rr_type = orig_nmb->question.question_type;
- nmb->answers->rr_class = orig_nmb->question.question_class;
- nmb->answers->ttl = ttl;
+ nmb->answers->rr_name = orig_nmb->question.question_name;
+ nmb->answers->rr_type = orig_nmb->question.question_type;
+ nmb->answers->rr_class = orig_nmb->question.question_class;
+ nmb->answers->ttl = ttl;
- if (data && len)
- {
- nmb->answers->rdlength = len;
- memcpy(nmb->answers->rdata, data, len);
- }
+ if (data && len) {
+ nmb->answers->rdlength = len;
+ memcpy(nmb->answers->rdata, data, len);
+ }
- packet.packet_type = NMB_PACKET;
- /* Ensure we send out on the same fd that the original
- packet came in on to give the correct source IP address. */
- packet.fd = orig_packet->fd;
- packet.timestamp = time(NULL);
+ packet.packet_type = NMB_PACKET;
+ /* Ensure we send out on the same fd that the original
+ packet came in on to give the correct source IP address. */
+ packet.fd = orig_packet->fd;
+ packet.timestamp = time(NULL);
- debug_nmb_packet(&packet);
+ debug_nmb_packet(&packet);
- if(loopback_this_packet)
- {
- struct packet_struct *lo_packet;
- DEBUG(5,("reply_netbios_packet: sending packet to ourselves.\n"));
- if((lo_packet = copy_packet(&packet)) == NULL)
- return;
- queue_packet(lo_packet);
- }
- else if (!send_packet(&packet))
- {
- DEBUG(0,("reply_netbios_packet: send_packet to IP %s port %d failed\n",
- inet_ntoa(packet.ip),packet.port));
- }
+ if(loopback_this_packet) {
+ struct packet_struct *lo_packet;
+ DEBUG(5,("reply_netbios_packet: sending packet to ourselves.\n"));
+ if((lo_packet = copy_packet(&packet)) == NULL)
+ return;
+ queue_packet(lo_packet);
+ } else if (!send_packet(&packet)) {
+ DEBUG(0,("reply_netbios_packet: send_packet to IP %s port %d failed\n",
+ inet_ntoa(packet.ip),packet.port));
+ }
}
/*******************************************************************
Queue a packet into a packet queue
******************************************************************/
+
static void queue_packet(struct packet_struct *packet)
{
- struct packet_struct *p;
-
- if (!packet_queue)
- {
- packet->prev = NULL;
- packet->next = NULL;
- packet_queue = packet;
- return;
- }
+ struct packet_struct *p;
+
+ if (!packet_queue) {
+ packet->prev = NULL;
+ packet->next = NULL;
+ packet_queue = packet;
+ return;
+ }
- /* find the bottom */
- for (p=packet_queue;p->next;p=p->next)
- ;
+ /* find the bottom */
+ for (p=packet_queue;p->next;p=p->next)
+ ;
- p->next = packet;
- packet->next = NULL;
- packet->prev = p;
+ p->next = packet;
+ packet->next = NULL;
+ packet->prev = p;
}
/****************************************************************************
@@ -1053,184 +1006,153 @@ static void queue_packet(struct packet_struct *packet)
static struct subnet_record *find_subnet_for_dgram_browse_packet(struct packet_struct *p)
{
- struct subnet_record *subrec;
-
- /* Go through all the broadcast subnets and see if the mask matches. */
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
- return subrec;
- }
-
- /* If the subnet record is the remote announce broadcast subnet,
- hack it here to be the first subnet. This is really gross and
- is needed due to people turning on port 137/138 broadcast
- forwarding on their routers. May fire and brimstone rain
- down upon them...
- */
-
- return FIRST_SUBNET;
+ struct subnet_record *subrec;
+
+ /* Go through all the broadcast subnets and see if the mask matches. */
+ for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
+ if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
+ return subrec;
+ }
+
+ /* If the subnet record is the remote announce broadcast subnet,
+ hack it here to be the first subnet. This is really gross and
+ is needed due to people turning on port 137/138 broadcast
+ forwarding on their routers. May fire and brimstone rain
+ down upon them...
+ */
+
+ return FIRST_SUBNET;
}
/****************************************************************************
Dispatch a browse frame from port 138 to the correct processing function.
****************************************************************************/
+
static void process_browse_packet(struct packet_struct *p, char *buf,int len)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- int command = CVAL(buf,0);
- struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
-
- /* Drop the packet if it's a different NetBIOS scope, or
- the source is from one of our names. */
-
- if (!strequal(dgram->dest_name.scope, global_scope()))
- {
- DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Scope (%s) \
-mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, global_scope()));
- return;
- }
-
- if (is_myname(dgram->source_name.name))
- {
- DEBUG(0,("process_browse_packet: Discarding datagram from IP %s. Source name \
+ struct dgram_packet *dgram = &p->packet.dgram;
+ int command = CVAL(buf,0);
+ struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
+ char scope[64];
+ nstring src_name;
+
+ /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
+ pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
+ if (!strequal(scope, global_scope())) {
+ DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Scope (%s) \
+mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
+ return;
+ }
+
+ pull_ascii_nstring(src_name, dgram->source_name.name);
+ if (is_myname(src_name)) {
+ DEBUG(0,("process_browse_packet: Discarding datagram from IP %s. Source name \
%s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
- return;
- }
-
- switch (command)
- {
- case ANN_HostAnnouncement:
- {
- debug_browse_data(buf, len);
- process_host_announce(subrec, p, buf+1);
- break;
- }
- case ANN_DomainAnnouncement:
- {
- debug_browse_data(buf, len);
- process_workgroup_announce(subrec, p, buf+1);
- break;
- }
- case ANN_LocalMasterAnnouncement:
- {
- debug_browse_data(buf, len);
- process_local_master_announce(subrec, p, buf+1);
- break;
- }
- case ANN_AnnouncementRequest:
- {
- debug_browse_data(buf, len);
- process_announce_request(subrec, p, buf+1);
- break;
- }
- case ANN_Election:
- {
- debug_browse_data(buf, len);
- process_election(subrec, p, buf+1);
- break;
- }
- case ANN_GetBackupListReq:
- {
- debug_browse_data(buf, len);
- process_get_backup_list_request(subrec, p, buf+1);
- break;
- }
- case ANN_GetBackupListResp:
- {
- debug_browse_data(buf, len);
- /* We never send ANN_GetBackupListReq so we
- should never get these. */
- DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
+ return;
+ }
+
+ switch (command) {
+ case ANN_HostAnnouncement:
+ debug_browse_data(buf, len);
+ process_host_announce(subrec, p, buf+1);
+ break;
+ case ANN_DomainAnnouncement:
+ debug_browse_data(buf, len);
+ process_workgroup_announce(subrec, p, buf+1);
+ break;
+ case ANN_LocalMasterAnnouncement:
+ debug_browse_data(buf, len);
+ process_local_master_announce(subrec, p, buf+1);
+ break;
+ case ANN_AnnouncementRequest:
+ debug_browse_data(buf, len);
+ process_announce_request(subrec, p, buf+1);
+ break;
+ case ANN_Election:
+ debug_browse_data(buf, len);
+ process_election(subrec, p, buf+1);
+ break;
+ case ANN_GetBackupListReq:
+ debug_browse_data(buf, len);
+ process_get_backup_list_request(subrec, p, buf+1);
+ break;
+ case ANN_GetBackupListResp:
+ debug_browse_data(buf, len);
+ /* We never send ANN_GetBackupListReq so we should never get these. */
+ DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
- break;
- }
- case ANN_ResetBrowserState:
- {
- debug_browse_data(buf, len);
- process_reset_browser(subrec, p, buf+1);
- break;
- }
- case ANN_MasterAnnouncement:
- {
- /* Master browser datagrams must be processed
- on the unicast subnet. */
- subrec = unicast_subnet;
-
- debug_browse_data(buf, len);
- process_master_browser_announce(subrec, p, buf+1);
- break;
- }
- case ANN_BecomeBackup:
- {
- /*
- * We don't currently implement this. Log it just in case.
- */
- debug_browse_data(buf, len);
- DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
-command ANN_BecomeBackup from %s IP %s to %s\n",
- subrec->subnet_name, nmb_namestr(&dgram->source_name),
- inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
- break;
- }
- default:
- {
- debug_browse_data(buf, len);
- DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
-command code %d from %s IP %s to %s\n",
- subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
- inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
- }
- }
+ break;
+ case ANN_ResetBrowserState:
+ debug_browse_data(buf, len);
+ process_reset_browser(subrec, p, buf+1);
+ break;
+ case ANN_MasterAnnouncement:
+ /* Master browser datagrams must be processed on the unicast subnet. */
+ subrec = unicast_subnet;
+
+ debug_browse_data(buf, len);
+ process_master_browser_announce(subrec, p, buf+1);
+ break;
+ case ANN_BecomeBackup:
+ /*
+ * We don't currently implement this. Log it just in case.
+ */
+ debug_browse_data(buf, len);
+ DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
+command ANN_BecomeBackup from %s IP %s to %s\n", subrec->subnet_name, nmb_namestr(&dgram->source_name),
+ inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
+ break;
+ default:
+ debug_browse_data(buf, len);
+ DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
+command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
+ inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
+ break;
+ }
}
/****************************************************************************
Dispatch a LanMan browse frame from port 138 to the correct processing function.
****************************************************************************/
+
static void process_lanman_packet(struct packet_struct *p, char *buf,int len)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- int command = SVAL(buf,0);
- struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
-
- /* Drop the packet if it's a different NetBIOS scope, or
- the source is from one of our names. */
-
- if (!strequal(dgram->dest_name.scope, global_scope()))
- {
- DEBUG(7,("process_lanman_packet: Discarding datagram from IP %s. Scope (%s) \
-mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, global_scope()));
- return;
- }
-
- if (is_myname(dgram->source_name.name))
- {
- DEBUG(0,("process_lanman_packet: Discarding datagram from IP %s. Source name \
+ struct dgram_packet *dgram = &p->packet.dgram;
+ int command = SVAL(buf,0);
+ struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
+ char scope[64];
+ nstring src_name;
+
+ /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */
+
+ pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
+ if (!strequal(scope, global_scope())) {
+ DEBUG(7,("process_lanman_packet: Discarding datagram from IP %s. Scope (%s) \
+mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
+ return;
+ }
+
+ pull_ascii_nstring(src_name, dgram->source_name.name);
+ if (is_myname(src_name)) {
+ DEBUG(0,("process_lanman_packet: Discarding datagram from IP %s. Source name \
%s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
- return;
- }
-
- switch (command)
- {
- case ANN_HostAnnouncement:
- {
- debug_browse_data(buf, len);
- process_lm_host_announce(subrec, p, buf+1);
- break;
- }
- case ANN_AnnouncementRequest:
- {
- process_lm_announce_request(subrec, p, buf+1);
- break;
- }
- default:
- {
- DEBUG(0,("process_lanman_packet: On subnet %s ignoring browse packet \
-command code %d from %s IP %s to %s\n",
- subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
- inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
- }
- }
+ return;
+ }
+
+ switch (command) {
+ case ANN_HostAnnouncement:
+ debug_browse_data(buf, len);
+ process_lm_host_announce(subrec, p, buf+1);
+ break;
+ case ANN_AnnouncementRequest:
+ process_lm_announce_request(subrec, p, buf+1);
+ break;
+ default:
+ DEBUG(0,("process_lanman_packet: On subnet %s ignoring browse packet \
+command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
+ inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
+ break;
+ }
}
/****************************************************************************
@@ -1241,104 +1163,94 @@ command code %d from %s IP %s to %s\n",
static BOOL listening(struct packet_struct *p,struct nmb_name *nbname)
{
- struct subnet_record *subrec = NULL;
+ struct subnet_record *subrec = NULL;
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
- break;
- }
+ for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
+ if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
+ break;
+ }
- if(subrec == NULL)
- subrec = unicast_subnet;
+ if(subrec == NULL)
+ subrec = unicast_subnet;
- return (find_name_on_subnet(subrec, nbname, FIND_SELF_NAME) != NULL);
+ return (find_name_on_subnet(subrec, nbname, FIND_SELF_NAME) != NULL);
}
/****************************************************************************
Process udp 138 datagrams
****************************************************************************/
+
static void process_dgram(struct packet_struct *p)
{
- char *buf;
- char *buf2;
- int len;
- struct dgram_packet *dgram = &p->packet.dgram;
-
- /* If we aren't listening to the destination name then ignore the packet */
- if (!listening(p,&dgram->dest_name))
- {
- unexpected_packet(p);
- DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
- nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
- return;
- }
-
- if (dgram->header.msg_type != 0x10 &&
- dgram->header.msg_type != 0x11 &&
- dgram->header.msg_type != 0x12)
- {
- unexpected_packet(p);
- /* Don't process error packets etc yet */
- DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
-an error packet of type %x\n",
- nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
- return;
- }
-
- buf = &dgram->data[0];
- buf -= 4; /* XXXX for the pseudo tcp length -
- someday I need to get rid of this */
-
- if (CVAL(buf,smb_com) != SMBtrans)
- return;
-
- len = SVAL(buf,smb_vwv11);
- buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
-
- if (len <= 0)
- return;
-
- if (buf2 + len > buf + sizeof(dgram->data)) {
- DEBUG(2,("process_dgram: datagram from %s to %s IP %s for %s len=%d too long.\n",
+ char *buf;
+ char *buf2;
+ int len;
+ struct dgram_packet *dgram = &p->packet.dgram;
+
+ /* If we aren't listening to the destination name then ignore the packet */
+ if (!listening(p,&dgram->dest_name)) {
+ unexpected_packet(p);
+ DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
+ nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
+ return;
+ }
+
+ if (dgram->header.msg_type != 0x10 && dgram->header.msg_type != 0x11 && dgram->header.msg_type != 0x12) {
+ unexpected_packet(p);
+ /* Don't process error packets etc yet */
+ DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
+an error packet of type %x\n", nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
+ return;
+ }
+
+ buf = &dgram->data[0];
+ buf -= 4; /* XXXX for the pseudo tcp length - someday I need to get rid of this */
+
+ if (CVAL(buf,smb_com) != SMBtrans)
+ return;
+
+ len = SVAL(buf,smb_vwv11);
+ buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
+
+ if (len <= 0)
+ return;
+
+ if (buf2 + len > buf + sizeof(dgram->data)) {
+ DEBUG(2,("process_dgram: datagram from %s to %s IP %s for %s len=%d too long.\n",
+ nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
+ inet_ntoa(p->ip), smb_buf(buf),len));
+ len = (buf + sizeof(dgram->data)) - buf;
+ }
+
+ DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n",
nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
- inet_ntoa(p->ip), smb_buf(buf),len));
- len = (buf + sizeof(dgram->data)) - buf;
- }
+ inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
- DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n",
- nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
- inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
+ /* Datagram packet received for the browser mailslot */
+ if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
+ process_browse_packet(p,buf2,len);
+ return;
+ }
-
- /* Datagram packet received for the browser mailslot */
- if (strequal(smb_buf(buf),BROWSE_MAILSLOT))
- {
- process_browse_packet(p,buf2,len);
- return;
- }
-
- /* Datagram packet received for the LAN Manager mailslot */
- if (strequal(smb_buf(buf),LANMAN_MAILSLOT)) {
- process_lanman_packet(p,buf2,len);
- return;
- }
-
- /* Datagram packet received for the domain logon mailslot */
- if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT))
- {
- process_logon_packet(p,buf2,len,NET_LOGON_MAILSLOT);
- return;
- }
-
- /* Datagram packet received for the NT domain logon mailslot */
- if (strequal(smb_buf(buf),NT_LOGON_MAILSLOT))
- {
- process_logon_packet(p,buf2,len,NT_LOGON_MAILSLOT);
- return;
- }
-
- unexpected_packet(p);
+ /* Datagram packet received for the LAN Manager mailslot */
+ if (strequal(smb_buf(buf),LANMAN_MAILSLOT)) {
+ process_lanman_packet(p,buf2,len);
+ return;
+ }
+
+ /* Datagram packet received for the domain logon mailslot */
+ if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
+ process_logon_packet(p,buf2,len,NET_LOGON_MAILSLOT);
+ return;
+ }
+
+ /* Datagram packet received for the NT domain logon mailslot */
+ if (strequal(smb_buf(buf),NT_LOGON_MAILSLOT)) {
+ process_logon_packet(p,buf2,len,NT_LOGON_MAILSLOT);
+ return;
+ }
+
+ unexpected_packet(p);
}
/****************************************************************************
@@ -1347,52 +1259,49 @@ an error packet of type %x\n",
static BOOL validate_nmb_response_packet( struct nmb_packet *nmb )
{
- BOOL ignore = False;
-
- switch (nmb->header.opcode)
- {
- case NMB_NAME_REG_OPCODE:
- case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
- case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
- if (nmb->header.ancount == 0)
- {
- DEBUG(0,("validate_nmb_response_packet: Bad REG/REFRESH Packet. "));
- ignore = True;
- }
- break;
-
- case NMB_NAME_QUERY_OPCODE:
- if ((nmb->header.ancount != 0) && (nmb->header.ancount != 1))
- {
- DEBUG(0,("validate_nmb_response_packet: Bad QUERY Packet. "));
- ignore = True;
- }
- break;
- case NMB_NAME_RELEASE_OPCODE:
- if (nmb->header.ancount == 0)
- {
- DEBUG(0,("validate_nmb_response_packet: Bad RELEASE Packet. "));
- ignore = True;
- }
- break;
- case NMB_WACK_OPCODE:
- /* Check WACK response here. */
- if (nmb->header.ancount != 1)
- {
- DEBUG(0,("validate_nmb_response_packet: Bad WACK Packet. "));
- ignore = True;
- }
- break;
- default:
- DEBUG(0,("validate_nmb_response_packet: Ignoring packet with unknown opcode %d.\n",
- nmb->header.opcode));
- return True;
- }
-
- if(ignore)
- DEBUG(0,("Ignoring response packet with opcode %d.\n", nmb->header.opcode));
-
- return ignore;
+ BOOL ignore = False;
+
+ switch (nmb->header.opcode) {
+ case NMB_NAME_REG_OPCODE:
+ case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
+ case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
+ if (nmb->header.ancount == 0) {
+ DEBUG(0,("validate_nmb_response_packet: Bad REG/REFRESH Packet. "));
+ ignore = True;
+ }
+ break;
+
+ case NMB_NAME_QUERY_OPCODE:
+ if ((nmb->header.ancount != 0) && (nmb->header.ancount != 1)) {
+ DEBUG(0,("validate_nmb_response_packet: Bad QUERY Packet. "));
+ ignore = True;
+ }
+ break;
+
+ case NMB_NAME_RELEASE_OPCODE:
+ if (nmb->header.ancount == 0) {
+ DEBUG(0,("validate_nmb_response_packet: Bad RELEASE Packet. "));
+ ignore = True;
+ }
+ break;
+
+ case NMB_WACK_OPCODE:
+ /* Check WACK response here. */
+ if (nmb->header.ancount != 1) {
+ DEBUG(0,("validate_nmb_response_packet: Bad WACK Packet. "));
+ ignore = True;
+ }
+ break;
+ default:
+ DEBUG(0,("validate_nmb_response_packet: Ignoring packet with unknown opcode %d.\n",
+ nmb->header.opcode));
+ return True;
+ }
+
+ if(ignore)
+ DEBUG(0,("Ignoring response packet with opcode %d.\n", nmb->header.opcode));
+
+ return ignore;
}
/****************************************************************************
@@ -1401,48 +1310,43 @@ static BOOL validate_nmb_response_packet( struct nmb_packet *nmb )
static BOOL validate_nmb_packet( struct nmb_packet *nmb )
{
- BOOL ignore = False;
-
- switch (nmb->header.opcode)
- {
- case NMB_NAME_REG_OPCODE:
- case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
- case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
- case NMB_NAME_MULTIHOMED_REG_OPCODE:
- if (nmb->header.qdcount==0 || nmb->header.arcount==0)
- {
- DEBUG(0,("validate_nmb_packet: Bad REG/REFRESH Packet. "));
- ignore = True;
- }
- break;
-
- case NMB_NAME_QUERY_OPCODE:
- if ((nmb->header.qdcount == 0) ||
- ((nmb->question.question_type != QUESTION_TYPE_NB_QUERY) &&
- (nmb->question.question_type != QUESTION_TYPE_NB_STATUS)))
- {
- DEBUG(0,("validate_nmb_packet: Bad QUERY Packet. "));
- ignore = True;
- }
- break;
-
- case NMB_NAME_RELEASE_OPCODE:
- if (nmb->header.qdcount==0 || nmb->header.arcount==0)
- {
- DEBUG(0,("validate_nmb_packet: Bad RELEASE Packet. "));
- ignore = True;
- }
- break;
- default:
- DEBUG(0,("validate_nmb_packet: Ignoring packet with unknown opcode %d.\n",
- nmb->header.opcode));
- return True;
- }
-
- if(ignore)
- DEBUG(0,("validate_nmb_packet: Ignoring request packet with opcode %d.\n", nmb->header.opcode));
-
- return ignore;
+ BOOL ignore = False;
+
+ switch (nmb->header.opcode) {
+ case NMB_NAME_REG_OPCODE:
+ case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
+ case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
+ case NMB_NAME_MULTIHOMED_REG_OPCODE:
+ if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
+ DEBUG(0,("validate_nmb_packet: Bad REG/REFRESH Packet. "));
+ ignore = True;
+ }
+ break;
+
+ case NMB_NAME_QUERY_OPCODE:
+ if ((nmb->header.qdcount == 0) || ((nmb->question.question_type != QUESTION_TYPE_NB_QUERY) &&
+ (nmb->question.question_type != QUESTION_TYPE_NB_STATUS))) {
+ DEBUG(0,("validate_nmb_packet: Bad QUERY Packet. "));
+ ignore = True;
+ }
+ break;
+
+ case NMB_NAME_RELEASE_OPCODE:
+ if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
+ DEBUG(0,("validate_nmb_packet: Bad RELEASE Packet. "));
+ ignore = True;
+ }
+ break;
+ default:
+ DEBUG(0,("validate_nmb_packet: Ignoring packet with unknown opcode %d.\n",
+ nmb->header.opcode));
+ return True;
+ }
+
+ if(ignore)
+ DEBUG(0,("validate_nmb_packet: Ignoring request packet with opcode %d.\n", nmb->header.opcode));
+
+ return ignore;
}
/****************************************************************************
@@ -1452,58 +1356,53 @@ static BOOL validate_nmb_packet( struct nmb_packet *nmb )
static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p,
struct response_record **pprrec)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct response_record *rrec = NULL;
- struct subnet_record *subrec = NULL;
-
- if(pprrec != NULL)
- *pprrec = NULL;
-
- if(nmb->header.response)
- {
- /* It's a response packet. Find a record for it or it's an error. */
-
- rrec = find_response_record( &subrec, nmb->header.name_trn_id);
- if(rrec == NULL)
- {
- DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
- nmb->header.name_trn_id));
- unexpected_packet(p);
- return NULL;
- }
-
- if(subrec == NULL)
- {
- DEBUG(0,("find_subnet_for_nmb_packet: subnet record not found for response id %hu\n",
- nmb->header.name_trn_id));
- return NULL;
- }
-
- if(pprrec != NULL)
- *pprrec = rrec;
- return subrec;
- }
-
- /* Try and see what subnet this packet belongs to. */
-
- /* WINS server ? */
- if(packet_is_for_wins_server(p))
- return wins_server_subnet;
-
- /* If it wasn't a broadcast packet then send to the UNICAST subnet. */
- if(nmb->header.nm_flags.bcast == False)
- return unicast_subnet;
-
- /* Go through all the broadcast subnets and see if the mask matches. */
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
- return subrec;
- }
-
- /* If none match it must have been a directed broadcast - assign
- the remote_broadcast_subnet. */
- return remote_broadcast_subnet;
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct response_record *rrec = NULL;
+ struct subnet_record *subrec = NULL;
+
+ if(pprrec != NULL)
+ *pprrec = NULL;
+
+ if(nmb->header.response) {
+ /* It's a response packet. Find a record for it or it's an error. */
+
+ rrec = find_response_record( &subrec, nmb->header.name_trn_id);
+ if(rrec == NULL) {
+ DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
+ nmb->header.name_trn_id));
+ unexpected_packet(p);
+ return NULL;
+ }
+
+ if(subrec == NULL) {
+ DEBUG(0,("find_subnet_for_nmb_packet: subnet record not found for response id %hu\n",
+ nmb->header.name_trn_id));
+ return NULL;
+ }
+
+ if(pprrec != NULL)
+ *pprrec = rrec;
+ return subrec;
+ }
+
+ /* Try and see what subnet this packet belongs to. */
+
+ /* WINS server ? */
+ if(packet_is_for_wins_server(p))
+ return wins_server_subnet;
+
+ /* If it wasn't a broadcast packet then send to the UNICAST subnet. */
+ if(nmb->header.nm_flags.bcast == False)
+ return unicast_subnet;
+
+ /* Go through all the broadcast subnets and see if the mask matches. */
+ for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
+ if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
+ return subrec;
+ }
+
+ /* If none match it must have been a directed broadcast - assign the remote_broadcast_subnet. */
+ return remote_broadcast_subnet;
}
/****************************************************************************
@@ -1512,79 +1411,71 @@ static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p
static void process_nmb_request(struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct subnet_record *subrec = NULL;
-
- debug_nmb_packet(p);
-
- /* Ensure we have a good packet. */
- if(validate_nmb_packet(nmb))
- return;
-
- /* Allocate a subnet to this packet - if we cannot - fail. */
- if((subrec = find_subnet_for_nmb_packet(p, NULL))==NULL)
- return;
-
- switch (nmb->header.opcode)
- {
- case NMB_NAME_REG_OPCODE:
- if(subrec == wins_server_subnet)
- wins_process_name_registration_request(subrec, p);
- else
- process_name_registration_request(subrec, p);
- break;
-
- case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
- case NMB_NAME_REFRESH_OPCODE_9:
- if(subrec == wins_server_subnet)
- wins_process_name_refresh_request(subrec, p);
- else
- process_name_refresh_request(subrec, p);
- break;
-
- case NMB_NAME_MULTIHOMED_REG_OPCODE:
- if(subrec == wins_server_subnet)
- wins_process_multihomed_name_registration_request(subrec, p);
- else
- {
- DEBUG(0,("process_nmb_request: Multihomed registration request must be \
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct subnet_record *subrec = NULL;
+
+ debug_nmb_packet(p);
+
+ /* Ensure we have a good packet. */
+ if(validate_nmb_packet(nmb))
+ return;
+
+ /* Allocate a subnet to this packet - if we cannot - fail. */
+ if((subrec = find_subnet_for_nmb_packet(p, NULL))==NULL)
+ return;
+
+ switch (nmb->header.opcode) {
+ case NMB_NAME_REG_OPCODE:
+ if(subrec == wins_server_subnet)
+ wins_process_name_registration_request(subrec, p);
+ else
+ process_name_registration_request(subrec, p);
+ break;
+
+ case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
+ case NMB_NAME_REFRESH_OPCODE_9:
+ if(subrec == wins_server_subnet)
+ wins_process_name_refresh_request(subrec, p);
+ else
+ process_name_refresh_request(subrec, p);
+ break;
+
+ case NMB_NAME_MULTIHOMED_REG_OPCODE:
+ if(subrec == wins_server_subnet) {
+ wins_process_multihomed_name_registration_request(subrec, p);
+ } else {
+ DEBUG(0,("process_nmb_request: Multihomed registration request must be \
directed at a WINS server.\n"));
- }
- break;
-
- case NMB_NAME_QUERY_OPCODE:
- switch (nmb->question.question_type)
- {
- case QUESTION_TYPE_NB_QUERY:
- {
- if(subrec == wins_server_subnet)
- wins_process_name_query_request(subrec, p);
- else
- process_name_query_request(subrec, p);
- break;
- }
- case QUESTION_TYPE_NB_STATUS:
- {
- if(subrec == wins_server_subnet)
- {
- DEBUG(0,("process_nmb_request: NB_STATUS request directed at WINS server is \
+ }
+ break;
+
+ case NMB_NAME_QUERY_OPCODE:
+ switch (nmb->question.question_type) {
+ case QUESTION_TYPE_NB_QUERY:
+ if(subrec == wins_server_subnet)
+ wins_process_name_query_request(subrec, p);
+ else
+ process_name_query_request(subrec, p);
+ break;
+ case QUESTION_TYPE_NB_STATUS:
+ if(subrec == wins_server_subnet) {
+ DEBUG(0,("process_nmb_request: NB_STATUS request directed at WINS server is \
not allowed.\n"));
- break;
- }
- else
- process_node_status_request(subrec, p);
- break;
- }
- }
- break;
+ break;
+ } else {
+ process_node_status_request(subrec, p);
+ }
+ break;
+ }
+ break;
- case NMB_NAME_RELEASE_OPCODE:
- if(subrec == wins_server_subnet)
- wins_process_name_release_request(subrec, p);
- else
- process_name_release_request(subrec, p);
- break;
- }
+ case NMB_NAME_RELEASE_OPCODE:
+ if(subrec == wins_server_subnet)
+ wins_process_name_release_request(subrec, p);
+ else
+ process_name_release_request(subrec, p);
+ break;
+ }
}
/****************************************************************************
@@ -1594,65 +1485,61 @@ not allowed.\n"));
static void process_nmb_response(struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct subnet_record *subrec = NULL;
- struct response_record *rrec = NULL;
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct subnet_record *subrec = NULL;
+ struct response_record *rrec = NULL;
- debug_nmb_packet(p);
+ debug_nmb_packet(p);
- if(validate_nmb_response_packet(nmb))
- return;
+ if(validate_nmb_response_packet(nmb))
+ return;
- if((subrec = find_subnet_for_nmb_packet(p, &rrec))==NULL)
- return;
+ if((subrec = find_subnet_for_nmb_packet(p, &rrec))==NULL)
+ return;
- if(rrec == NULL)
- {
- DEBUG(0,("process_nmb_response: response packet received but no response record \
+ if(rrec == NULL) {
+ DEBUG(0,("process_nmb_response: response packet received but no response record \
found for id = %hu. Ignoring packet.\n", nmb->header.name_trn_id));
- return;
- }
+ return;
+ }
- /* Increment the number of responses received for this record. */
- rrec->num_msgs++;
- /* Ensure we don't re-send the request. */
- rrec->repeat_count = 0;
+ /* Increment the number of responses received for this record. */
+ rrec->num_msgs++;
+ /* Ensure we don't re-send the request. */
+ rrec->repeat_count = 0;
- /* Call the response received function for this packet. */
- (*rrec->resp_fn)(subrec, rrec, p);
+ /* Call the response received function for this packet. */
+ (*rrec->resp_fn)(subrec, rrec, p);
}
-
/*******************************************************************
Run elements off the packet queue till its empty
******************************************************************/
void run_packet_queue(void)
{
- struct packet_struct *p;
-
- while ((p = packet_queue))
- {
- packet_queue = p->next;
- if (packet_queue)
- packet_queue->prev = NULL;
- p->next = p->prev = NULL;
-
- switch (p->packet_type)
- {
- case NMB_PACKET:
- if(p->packet.nmb.header.response)
- process_nmb_response(p);
- else
- process_nmb_request(p);
- break;
-
- case DGRAM_PACKET:
- process_dgram(p);
- break;
- }
- free_packet(p);
- }
+ struct packet_struct *p;
+
+ while ((p = packet_queue)) {
+ packet_queue = p->next;
+ if (packet_queue)
+ packet_queue->prev = NULL;
+ p->next = p->prev = NULL;
+
+ switch (p->packet_type) {
+ case NMB_PACKET:
+ if(p->packet.nmb.header.response)
+ process_nmb_response(p);
+ else
+ process_nmb_request(p);
+ break;
+
+ case DGRAM_PACKET:
+ process_dgram(p);
+ break;
+ }
+ free_packet(p);
+ }
}
/*******************************************************************
@@ -1665,66 +1552,54 @@ void run_packet_queue(void)
void retransmit_or_expire_response_records(time_t t)
{
- struct subnet_record *subrec;
+ struct subnet_record *subrec;
- for (subrec = FIRST_SUBNET; subrec;
- subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec))
- {
- struct response_record *rrec, *nextrrec;
+ for (subrec = FIRST_SUBNET; subrec; subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec)) {
+ struct response_record *rrec, *nextrrec;
- for (rrec = subrec->responselist; rrec; rrec = nextrrec)
- {
- nextrrec = rrec->next;
+ for (rrec = subrec->responselist; rrec; rrec = nextrrec) {
+ nextrrec = rrec->next;
- if (rrec->repeat_time <= t)
- {
- if (rrec->repeat_count > 0)
- {
- /* Resend while we have a non-zero repeat_count. */
- if(!send_packet(rrec->packet))
- {
- DEBUG(0,("retransmit_or_expire_response_records: Failed to resend packet id %hu \
-to IP %s on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip),
- subrec->subnet_name));
- }
- rrec->repeat_time = t + rrec->repeat_interval;
- rrec->repeat_count--;
- }
- else
- {
- DEBUG(4,("retransmit_or_expire_response_records: timeout for packet id %hu to IP %s \
-on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip),
- subrec->subnet_name));
-
- /*
- * Check the flag in this record to prevent recursion if we end
- * up in this function again via the timeout function call.
- */
-
- if(!rrec->in_expiration_processing)
- {
-
- /*
- * Set the recursion protection flag in this record.
- */
-
- rrec->in_expiration_processing = True;
-
- /* Call the timeout function. This will deal with removing the
- timed out packet. */
- if(rrec->timeout_fn)
- (*rrec->timeout_fn)(subrec, rrec);
- else
- {
- /* We must remove the record ourself if there is
- no timeout function. */
- remove_response_record(subrec, rrec);
- }
- } /* !rrec->in_expitation_processing */
- } /* rrec->repeat_count > 0 */
- } /* rrec->repeat_time <= t */
- } /* end for rrec */
- } /* end for subnet */
+ if (rrec->repeat_time <= t) {
+ if (rrec->repeat_count > 0) {
+ /* Resend while we have a non-zero repeat_count. */
+ if(!send_packet(rrec->packet)) {
+ DEBUG(0,("retransmit_or_expire_response_records: Failed to resend packet id %hu \
+to IP %s on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
+ }
+ rrec->repeat_time = t + rrec->repeat_interval;
+ rrec->repeat_count--;
+ } else {
+ DEBUG(4,("retransmit_or_expire_response_records: timeout for packet id %hu to IP %s \
+on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
+
+ /*
+ * Check the flag in this record to prevent recursion if we end
+ * up in this function again via the timeout function call.
+ */
+
+ if(!rrec->in_expiration_processing) {
+
+ /*
+ * Set the recursion protection flag in this record.
+ */
+
+ rrec->in_expiration_processing = True;
+
+ /* Call the timeout function. This will deal with removing the
+ timed out packet. */
+ if(rrec->timeout_fn) {
+ (*rrec->timeout_fn)(subrec, rrec);
+ } else {
+ /* We must remove the record ourself if there is
+ no timeout function. */
+ remove_response_record(subrec, rrec);
+ }
+ } /* !rrec->in_expitation_processing */
+ } /* rrec->repeat_count > 0 */
+ } /* rrec->repeat_time <= t */
+ } /* end for rrec */
+ } /* end for subnet */
}
/****************************************************************************
@@ -1734,68 +1609,63 @@ on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip),
static BOOL create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number)
{
- int *sock_array = NULL;
- struct subnet_record *subrec = NULL;
- int count = 0;
- int num = 0;
- fd_set *pset = (fd_set *)malloc(sizeof(fd_set));
-
- if(pset == NULL)
- {
- DEBUG(0,("create_listen_fdset: malloc fail !\n"));
- return True;
- }
-
- /* Check that we can add all the fd's we need. */
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- count++;
-
- if((count*2) + 2 > FD_SETSIZE)
- {
- DEBUG(0,("create_listen_fdset: Too many file descriptors needed (%d). We can \
+ int *sock_array = NULL;
+ struct subnet_record *subrec = NULL;
+ int count = 0;
+ int num = 0;
+ fd_set *pset = (fd_set *)malloc(sizeof(fd_set));
+
+ if(pset == NULL) {
+ DEBUG(0,("create_listen_fdset: malloc fail !\n"));
+ return True;
+ }
+
+ /* Check that we can add all the fd's we need. */
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ count++;
+
+ if((count*2) + 2 > FD_SETSIZE) {
+ DEBUG(0,("create_listen_fdset: Too many file descriptors needed (%d). We can \
only use %d.\n", (count*2) + 2, FD_SETSIZE));
- return True;
- }
-
- if((sock_array = (int *)malloc(((count*2) + 2)*sizeof(int))) == NULL)
- {
- DEBUG(0,("create_listen_fdset: malloc fail for socket array.\n"));
- return True;
- }
-
- FD_ZERO(pset);
-
- /* Add in the broadcast socket on 137. */
- FD_SET(ClientNMB,pset);
- sock_array[num++] = ClientNMB;
-
- /* Add in the 137 sockets on all the interfaces. */
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- FD_SET(subrec->nmb_sock,pset);
- sock_array[num++] = subrec->nmb_sock;
- }
-
- /* Add in the broadcast socket on 138. */
- FD_SET(ClientDGRAM,pset);
- sock_array[num++] = ClientDGRAM;
-
- /* Add in the 138 sockets on all the interfaces. */
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- FD_SET(subrec->dgram_sock,pset);
- sock_array[num++] = subrec->dgram_sock;
- }
-
- *listen_number = (count*2) + 2;
-
- SAFE_FREE(*ppset);
- SAFE_FREE(*psock_array);
-
- *ppset = pset;
- *psock_array = sock_array;
+ return True;
+ }
+
+ if((sock_array = (int *)malloc(((count*2) + 2)*sizeof(int))) == NULL) {
+ DEBUG(0,("create_listen_fdset: malloc fail for socket array.\n"));
+ return True;
+ }
+
+ FD_ZERO(pset);
+
+ /* Add in the broadcast socket on 137. */
+ FD_SET(ClientNMB,pset);
+ sock_array[num++] = ClientNMB;
+
+ /* Add in the 137 sockets on all the interfaces. */
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
+ FD_SET(subrec->nmb_sock,pset);
+ sock_array[num++] = subrec->nmb_sock;
+ }
+
+ /* Add in the broadcast socket on 138. */
+ FD_SET(ClientDGRAM,pset);
+ sock_array[num++] = ClientDGRAM;
+
+ /* Add in the 138 sockets on all the interfaces. */
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
+ FD_SET(subrec->dgram_sock,pset);
+ sock_array[num++] = subrec->dgram_sock;
+ }
+
+ *listen_number = (count*2) + 2;
+
+ SAFE_FREE(*ppset);
+ SAFE_FREE(*psock_array);
+
+ *ppset = pset;
+ *psock_array = sock_array;
- return False;
+ return False;
}
/****************************************************************************
@@ -1805,214 +1675,211 @@ only use %d.\n", (count*2) + 2, FD_SETSIZE));
BOOL listen_for_packets(BOOL run_election)
{
- static fd_set *listen_set = NULL;
- static int listen_number = 0;
- static int *sock_array = NULL;
- int i;
-
- fd_set fds;
- int selrtn;
- struct timeval timeout;
+ static fd_set *listen_set = NULL;
+ static int listen_number = 0;
+ static int *sock_array = NULL;
+ int i;
+
+ fd_set fds;
+ int selrtn;
+ struct timeval timeout;
#ifndef SYNC_DNS
- int dns_fd;
+ int dns_fd;
#endif
- if(listen_set == NULL || rescan_listen_set)
- {
- if(create_listen_fdset(&listen_set, &sock_array, &listen_number))
- {
- DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
- return True;
- }
- rescan_listen_set = False;
- }
+ if(listen_set == NULL || rescan_listen_set) {
+ if(create_listen_fdset(&listen_set, &sock_array, &listen_number)) {
+ DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
+ return True;
+ }
+ rescan_listen_set = False;
+ }
- memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set));
+ memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set));
#ifndef SYNC_DNS
- dns_fd = asyncdns_fd();
- if (dns_fd != -1) {
- FD_SET(dns_fd, &fds);
- }
+ dns_fd = asyncdns_fd();
+ if (dns_fd != -1) {
+ FD_SET(dns_fd, &fds);
+ }
#endif
+ /*
+ * During elections and when expecting a netbios response packet we
+ * need to send election packets at tighter intervals.
+ * Ideally it needs to be the interval (in ms) between time now and
+ * the time we are expecting the next netbios packet.
+ */
- /*
- * During elections and when expecting a netbios response packet we
- * need to send election packets at tighter intervals.
- * Ideally it needs to be the interval (in ms) between time now and
- * the time we are expecting the next netbios packet.
- */
-
- timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
- timeout.tv_usec = 0;
+ timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
+ timeout.tv_usec = 0;
- /* Prepare for the select - allow certain signals. */
+ /* Prepare for the select - allow certain signals. */
- BlockSignals(False, SIGTERM);
+ BlockSignals(False, SIGTERM);
- selrtn = sys_select(FD_SETSIZE,&fds,NULL,NULL,&timeout);
+ selrtn = sys_select(FD_SETSIZE,&fds,NULL,NULL,&timeout);
- /* We can only take signals when we are in the select - block them again here. */
+ /* We can only take signals when we are in the select - block them again here. */
- BlockSignals(True, SIGTERM);
+ BlockSignals(True, SIGTERM);
- if(selrtn == -1) {
- return False;
- }
+ if(selrtn == -1) {
+ return False;
+ }
#ifndef SYNC_DNS
- if (dns_fd != -1 && FD_ISSET(dns_fd,&fds)) {
- run_dns_queue();
- }
+ if (dns_fd != -1 && FD_ISSET(dns_fd,&fds)) {
+ run_dns_queue();
+ }
#endif
- for(i = 0; i < listen_number; i++) {
- if (i < (listen_number/2)) {
- /* Processing a 137 socket. */
- if (FD_ISSET(sock_array[i],&fds)) {
- struct packet_struct *packet = read_packet(sock_array[i], NMB_PACKET);
- if (packet) {
- /*
- * If we got a packet on the broadcast socket and interfaces
- * only is set then check it came from one of our local nets.
- */
- if(lp_bind_interfaces_only() && (sock_array[i] == ClientNMB) &&
- (!is_local_net(packet->ip))) {
- DEBUG(7,("discarding nmb packet sent to broadcast socket from %s:%d\n",
- inet_ntoa(packet->ip),packet->port));
- free_packet(packet);
- } else if ((ip_equal(loopback_ip, packet->ip) ||
- ismyip(packet->ip)) && packet->port == global_nmb_port &&
- packet->packet.nmb.header.nm_flags.bcast) {
- DEBUG(7,("discarding own bcast packet from %s:%d\n",
- inet_ntoa(packet->ip),packet->port));
- free_packet(packet);
- } else {
- /* Save the file descriptor this packet came in on. */
- packet->fd = sock_array[i];
- queue_packet(packet);
- }
- }
- }
- } else {
- /* Processing a 138 socket. */
- if (FD_ISSET(sock_array[i],&fds)) {
- struct packet_struct *packet = read_packet(sock_array[i], DGRAM_PACKET);
- if (packet) {
- /*
- * If we got a packet on the broadcast socket and interfaces
- * only is set then check it came from one of our local nets.
- */
- if(lp_bind_interfaces_only() && (sock_array[i] == ClientDGRAM) &&
- (!is_local_net(packet->ip))) {
- DEBUG(7,("discarding dgram packet sent to broadcast socket from %s:%d\n",
- inet_ntoa(packet->ip),packet->port));
- free_packet(packet);
- } else if ((ip_equal(loopback_ip, packet->ip) ||
- ismyip(packet->ip)) && packet->port == DGRAM_PORT) {
- DEBUG(7,("discarding own dgram packet from %s:%d\n",
- inet_ntoa(packet->ip),packet->port));
- free_packet(packet);
- } else {
- /* Save the file descriptor this packet came in on. */
- packet->fd = sock_array[i];
- queue_packet(packet);
- }
- }
- }
- } /* end processing 138 socket. */
- } /* end for */
- return False;
+ for(i = 0; i < listen_number; i++) {
+ if (i < (listen_number/2)) {
+ /* Processing a 137 socket. */
+ if (FD_ISSET(sock_array[i],&fds)) {
+ struct packet_struct *packet = read_packet(sock_array[i], NMB_PACKET);
+ if (packet) {
+ /*
+ * If we got a packet on the broadcast socket and interfaces
+ * only is set then check it came from one of our local nets.
+ */
+ if(lp_bind_interfaces_only() && (sock_array[i] == ClientNMB) &&
+ (!is_local_net(packet->ip))) {
+ DEBUG(7,("discarding nmb packet sent to broadcast socket from %s:%d\n",
+ inet_ntoa(packet->ip),packet->port));
+ free_packet(packet);
+ } else if ((ip_equal(loopback_ip, packet->ip) ||
+ ismyip(packet->ip)) && packet->port == global_nmb_port &&
+ packet->packet.nmb.header.nm_flags.bcast) {
+ DEBUG(7,("discarding own bcast packet from %s:%d\n",
+ inet_ntoa(packet->ip),packet->port));
+ free_packet(packet);
+ } else {
+ /* Save the file descriptor this packet came in on. */
+ packet->fd = sock_array[i];
+ queue_packet(packet);
+ }
+ }
+ }
+ } else {
+ /* Processing a 138 socket. */
+ if (FD_ISSET(sock_array[i],&fds)) {
+ struct packet_struct *packet = read_packet(sock_array[i], DGRAM_PACKET);
+ if (packet) {
+ /*
+ * If we got a packet on the broadcast socket and interfaces
+ * only is set then check it came from one of our local nets.
+ */
+ if(lp_bind_interfaces_only() && (sock_array[i] == ClientDGRAM) &&
+ (!is_local_net(packet->ip))) {
+ DEBUG(7,("discarding dgram packet sent to broadcast socket from %s:%d\n",
+ inet_ntoa(packet->ip),packet->port));
+ free_packet(packet);
+ } else if ((ip_equal(loopback_ip, packet->ip) ||
+ ismyip(packet->ip)) && packet->port == DGRAM_PORT) {
+ DEBUG(7,("discarding own dgram packet from %s:%d\n",
+ inet_ntoa(packet->ip),packet->port));
+ free_packet(packet);
+ } else {
+ /* Save the file descriptor this packet came in on. */
+ packet->fd = sock_array[i];
+ queue_packet(packet);
+ }
+ }
+ }
+ } /* end processing 138 socket. */
+ } /* end for */
+ return False;
}
/****************************************************************************
Construct and send a netbios DGRAM.
**************************************************************************/
+
BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf, size_t len,
const char *srcname, int src_type,
const char *dstname, int dest_type,
struct in_addr dest_ip,struct in_addr src_ip,
int dest_port)
{
- BOOL loopback_this_packet = False;
- struct packet_struct p;
- struct dgram_packet *dgram = &p.packet.dgram;
- char *ptr,*p2;
- char tmp[4];
-
- memset((char *)&p,'\0',sizeof(p));
-
- if(ismyip(dest_ip) && (dest_port == DGRAM_PORT)) /* Only if to DGRAM_PORT */
- loopback_this_packet = True;
-
- /* generate_name_trn_id(); */ /* Not used, so gone, RJS */
-
- /* DIRECT GROUP or UNIQUE datagram. */
- dgram->header.msg_type = unique ? 0x10 : 0x11;
- dgram->header.flags.node_type = M_NODE;
- dgram->header.flags.first = True;
- dgram->header.flags.more = False;
- dgram->header.dgm_id = generate_name_trn_id();
- dgram->header.source_ip = src_ip;
- dgram->header.source_port = DGRAM_PORT;
- dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
- dgram->header.packet_offset = 0;
+ BOOL loopback_this_packet = False;
+ struct packet_struct p;
+ struct dgram_packet *dgram = &p.packet.dgram;
+ char *ptr,*p2;
+ char tmp[4];
+
+ memset((char *)&p,'\0',sizeof(p));
+
+ if(ismyip(dest_ip) && (dest_port == DGRAM_PORT)) /* Only if to DGRAM_PORT */
+ loopback_this_packet = True;
+
+ /* generate_name_trn_id(); */ /* Not used, so gone, RJS */
+
+ /* DIRECT GROUP or UNIQUE datagram. */
+ dgram->header.msg_type = unique ? 0x10 : 0x11;
+ dgram->header.flags.node_type = M_NODE;
+ dgram->header.flags.first = True;
+ dgram->header.flags.more = False;
+ dgram->header.dgm_id = generate_name_trn_id();
+ dgram->header.source_ip = src_ip;
+ dgram->header.source_port = DGRAM_PORT;
+ dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
+ dgram->header.packet_offset = 0;
- make_nmb_name(&dgram->source_name,srcname,src_type);
- make_nmb_name(&dgram->dest_name,dstname,dest_type);
-
- ptr = &dgram->data[0];
-
- /* Setup the smb part. */
- ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
- memcpy(tmp,ptr,4);
- set_message(ptr,17,23 + len,True);
- memcpy(ptr,tmp,4);
-
- SCVAL(ptr,smb_com,SMBtrans);
- SSVAL(ptr,smb_vwv1,len);
- SSVAL(ptr,smb_vwv11,len);
- SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
- SSVAL(ptr,smb_vwv13,3);
- SSVAL(ptr,smb_vwv14,1);
- SSVAL(ptr,smb_vwv15,1);
- SSVAL(ptr,smb_vwv16,2);
- p2 = smb_buf(ptr);
- safe_strcpy_base(p2, mailslot, dgram->data, sizeof(dgram->data));
- p2 = skip_string(p2,1);
+ make_nmb_name(&dgram->source_name,srcname,src_type);
+ make_nmb_name(&dgram->dest_name,dstname,dest_type);
+
+ ptr = &dgram->data[0];
+
+ /* Setup the smb part. */
+ ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
+ memcpy(tmp,ptr,4);
+ set_message(ptr,17,23 + len,True);
+ memcpy(ptr,tmp,4);
+
+ SCVAL(ptr,smb_com,SMBtrans);
+ SSVAL(ptr,smb_vwv1,len);
+ SSVAL(ptr,smb_vwv11,len);
+ SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
+ SSVAL(ptr,smb_vwv13,3);
+ SSVAL(ptr,smb_vwv14,1);
+ SSVAL(ptr,smb_vwv15,1);
+ SSVAL(ptr,smb_vwv16,2);
+ p2 = smb_buf(ptr);
+ safe_strcpy_base(p2, mailslot, dgram->data, sizeof(dgram->data));
+ p2 = skip_string(p2,1);
- if (((p2+len) > dgram->data+sizeof(dgram->data)) || ((p2+len) < p2)) {
- DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
- return False;
- } else {
- memcpy(p2,buf,len);
- p2 += len;
- }
-
- dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
-
- p.ip = dest_ip;
- p.port = dest_port;
- p.fd = find_subnet_mailslot_fd_for_address( src_ip );
- p.timestamp = time(NULL);
- p.packet_type = DGRAM_PACKET;
-
- DEBUG(4,("send_mailslot: Sending to mailslot %s from %s IP %s ", mailslot,
- nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
- DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
-
- debug_browse_data(buf, len);
-
- if(loopback_this_packet)
- {
- struct packet_struct *lo_packet = NULL;
- DEBUG(5,("send_mailslot: sending packet to ourselves.\n"));
- if((lo_packet = copy_packet(&p)) == NULL)
- return False;
- queue_packet(lo_packet);
- return True;
- }
- else
- return(send_packet(&p));
+ if (((p2+len) > dgram->data+sizeof(dgram->data)) || ((p2+len) < p2)) {
+ DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
+ return False;
+ } else {
+ memcpy(p2,buf,len);
+ p2 += len;
+ }
+
+ dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
+
+ p.ip = dest_ip;
+ p.port = dest_port;
+ p.fd = find_subnet_mailslot_fd_for_address( src_ip );
+ p.timestamp = time(NULL);
+ p.packet_type = DGRAM_PACKET;
+
+ DEBUG(4,("send_mailslot: Sending to mailslot %s from %s IP %s ", mailslot,
+ nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
+ DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
+
+ debug_browse_data(buf, len);
+
+ if(loopback_this_packet) {
+ struct packet_struct *lo_packet = NULL;
+ DEBUG(5,("send_mailslot: sending packet to ourselves.\n"));
+ if((lo_packet = copy_packet(&p)) == NULL)
+ return False;
+ queue_packet(lo_packet);
+ return True;
+ } else {
+ return(send_packet(&p));
+ }
}
diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c
index bc3540af70..2a6a6b66d1 100644
--- a/source3/nmbd/nmbd_processlogon.c
+++ b/source3/nmbd/nmbd_processlogon.c
@@ -3,7 +3,7 @@
NBT netbios routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
- Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Jeremy Allison 1994-2003
Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
This program is free software; you can redistribute it and/or modify
@@ -35,6 +35,7 @@ struct sam_database_info {
/****************************************************************************
Send a message to smbd to do a sam delta sync
**************************************************************************/
+
static void send_repl_message(uint32 low_serial)
{
TDB_CONTEXT *tdb;
@@ -64,432 +65,452 @@ Process a domain logon packet
void process_logon_packet(struct packet_struct *p, char *buf,int len,
const char *mailslot)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- pstring my_name;
- fstring reply_name;
- pstring outbuf;
- int code;
- uint16 token = 0;
- uint32 ntversion = 0;
- uint16 lmnttoken = 0;
- uint16 lm20token = 0;
- uint32 domainsidsize;
- BOOL short_request = False;
- char *getdc;
- char *uniuser; /* Unicode user name. */
- pstring ascuser;
- char *unicomp; /* Unicode computer name. */
-
- memset(outbuf, 0, sizeof(outbuf));
-
- if (!lp_domain_logons())
- {
- DEBUG(3,("process_logon_packet: Logon packet received from IP %s and domain \
+ struct dgram_packet *dgram = &p->packet.dgram;
+ pstring my_name;
+ fstring reply_name;
+ pstring outbuf;
+ int code;
+ uint16 token = 0;
+ uint32 ntversion = 0;
+ uint16 lmnttoken = 0;
+ uint16 lm20token = 0;
+ uint32 domainsidsize;
+ BOOL short_request = False;
+ char *getdc;
+ char *uniuser; /* Unicode user name. */
+ pstring ascuser;
+ char *unicomp; /* Unicode computer name. */
+
+ memset(outbuf, 0, sizeof(outbuf));
+
+ if (!lp_domain_logons()) {
+ DEBUG(3,("process_logon_packet: Logon packet received from IP %s and domain \
logons are not enabled.\n", inet_ntoa(p->ip) ));
- return;
- }
-
- pstrcpy(my_name, global_myname());
-
- code = SVAL(buf,0);
- DEBUG(1,("process_logon_packet: Logon from %s: code = 0x%x\n", inet_ntoa(p->ip), code));
-
- switch (code)
- {
- case 0:
- {
- char *q = buf + 2;
- char *machine = q;
- char *user = skip_string(machine,1);
-
- getdc = skip_string(user,1);
- q = skip_string(getdc,1);
- token = SVAL(q,3);
-
- fstrcpy(reply_name,my_name);
-
- DEBUG(3,("process_logon_packet: Domain login request from %s at IP %s user=%s token=%x\n",
- machine,inet_ntoa(p->ip),user,token));
-
- q = outbuf;
- SSVAL(q, 0, 6);
- q += 2;
-
- fstrcpy(reply_name, "\\\\");
- fstrcat(reply_name, my_name);
- fstrcpy(q, reply_name); q = skip_string(q, 1); /* PDC name */
-
- SSVAL(q, 0, token);
- q += 2;
-
- dump_data(4, outbuf, PTR_DIFF(q, outbuf));
-
- send_mailslot(True, getdc,
- outbuf,PTR_DIFF(q,outbuf),
- global_myname(), 0x0,
- machine,
- dgram->source_name.name_type,
- p->ip, *iface_ip(p->ip), p->port);
- break;
- }
-
- case QUERYFORPDC:
- {
- char *q = buf + 2;
- char *machine = q;
-
- if (!lp_domain_master())
- {
- /* We're not Primary Domain Controller -- ignore this */
- return;
- }
-
- getdc = skip_string(machine,1);
- q = skip_string(getdc,1);
- q = ALIGN2(q, buf);
-
- /* at this point we can work out if this is a W9X or NT style
- request. Experiments show that the difference is wether the
- packet ends here. For a W9X request we now end with a pair of
- bytes (usually 0xFE 0xFF) whereas with NT we have two further
- strings - the following is a simple way of detecting this */
- if (len - PTR_DIFF(q, buf) <= 3) {
- short_request = True;
- } else {
- unicomp = q;
-
- /* A full length (NT style) request */
- q = skip_unibuf(unicomp, PTR_DIFF(buf + len, unicomp));
-
- if (len - PTR_DIFF(q, buf) > 8) {
+ return;
+ }
+
+ pstrcpy(my_name, global_myname());
+
+ code = SVAL(buf,0);
+ DEBUG(1,("process_logon_packet: Logon from %s: code = 0x%x\n", inet_ntoa(p->ip), code));
+
+ switch (code) {
+ case 0:
+ {
+ fstring mach_str, user_str, getdc_str;
+ char *q = buf + 2;
+ char *machine = q;
+ char *user = skip_string(machine,1);
+
+ getdc = skip_string(user,1);
+ q = skip_string(getdc,1);
+ token = SVAL(q,3);
+
+ fstrcpy(reply_name,my_name);
+
+ pull_ascii_fstring(mach_str, machine);
+ pull_ascii_fstring(user_str, user);
+ pull_ascii_fstring(getdc_str, getdc);
+
+ DEBUG(3,("process_logon_packet: Domain login request from %s at IP %s user=%s token=%x\n",
+ mach_str,inet_ntoa(p->ip),user_str,token));
+
+ q = outbuf;
+ SSVAL(q, 0, 6);
+ q += 2;
+
+ fstrcpy(reply_name, "\\\\");
+ fstrcat(reply_name, my_name);
+ push_ascii_fstring(q, reply_name);
+ q = skip_string(q, 1); /* PDC name */
+
+ SSVAL(q, 0, token);
+ q += 2;
+
+ dump_data(4, outbuf, PTR_DIFF(q, outbuf));
+
+ send_mailslot(True, getdc_str,
+ outbuf,PTR_DIFF(q,outbuf),
+ global_myname(), 0x0,
+ mach_str,
+ dgram->source_name.name_type,
+ p->ip, *iface_ip(p->ip), p->port);
+ break;
+ }
+
+ case QUERYFORPDC:
+ {
+ fstring mach_str, getdc_str;
+ nstring source_name;
+ char *q = buf + 2;
+ char *machine = q;
+
+ if (!lp_domain_master()) {
+ /* We're not Primary Domain Controller -- ignore this */
+ return;
+ }
+
+ getdc = skip_string(machine,1);
+ q = skip_string(getdc,1);
+ q = ALIGN2(q, buf);
+
+ /* At this point we can work out if this is a W9X or NT style
+ request. Experiments show that the difference is wether the
+ packet ends here. For a W9X request we now end with a pair of
+ bytes (usually 0xFE 0xFF) whereas with NT we have two further
+ strings - the following is a simple way of detecting this */
+
+ if (len - PTR_DIFF(q, buf) <= 3) {
+ short_request = True;
+ } else {
+ unicomp = q;
+
+ /* A full length (NT style) request */
+ q = skip_unibuf(unicomp, PTR_DIFF(buf + len, unicomp));
+
+ if (len - PTR_DIFF(q, buf) > 8) {
+ /* with NT5 clients we can sometimes
+ get additional data - a length specificed string
+ containing the domain name, then 16 bytes of
+ data (no idea what it is) */
+ int dom_len = CVAL(q, 0);
+ q++;
+ if (dom_len != 0) {
+ q += dom_len + 1;
+ }
+ q += 16;
+ }
+ ntversion = IVAL(q, 0);
+ lmnttoken = SVAL(q, 4);
+ lm20token = SVAL(q, 6);
+ }
+
+ /* Construct reply. */
+ q = outbuf;
+ SSVAL(q, 0, QUERYFORPDC_R);
+ q += 2;
+
+ fstrcpy(reply_name,my_name);
+ push_ascii_fstring(q, reply_name);
+ q = skip_string(q, 1); /* PDC name */
+
+ /* PDC and domain name */
+ if (!short_request) {
+ /* Make a full reply */
+ q = ALIGN2(q, outbuf);
+
+ q += dos_PutUniCode(q, my_name, sizeof(pstring), True); /* PDC name */
+ q += dos_PutUniCode(q, lp_workgroup(),sizeof(pstring), True); /* Domain name*/
+ SIVAL(q, 0, 1); /* our nt version */
+ SSVAL(q, 4, 0xffff); /* our lmnttoken */
+ SSVAL(q, 6, 0xffff); /* our lm20token */
+ q += 8;
+ }
+
+ /* RJS, 21-Feb-2000, we send a short reply if the request was short */
+
+ pull_ascii_fstring(mach_str, machine);
+
+ DEBUG(3,("process_logon_packet: GETDC request from %s at IP %s, \
+reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
+ mach_str,inet_ntoa(p->ip), reply_name, lp_workgroup(),
+ QUERYFORPDC_R, (uint32)ntversion, (uint32)lmnttoken,
+ (uint32)lm20token ));
+
+ dump_data(4, outbuf, PTR_DIFF(q, outbuf));
+
+ pull_ascii_fstring(getdc_str, getdc);
+ pull_ascii_nstring(source_name, dgram->source_name.name);
+
+ send_mailslot(True, getdc_str,
+ outbuf,PTR_DIFF(q,outbuf),
+ global_myname(), 0x0,
+ source_name,
+ dgram->source_name.name_type,
+ p->ip, *iface_ip(p->ip), p->port);
+ return;
+ }
+
+ case SAMLOGON:
+
+ {
+ fstring getdc_str;
+ nstring source_name;
+ char *q = buf + 2;
+ fstring asccomp;
+
+ q += 2;
+ unicomp = q;
+ uniuser = skip_unibuf(unicomp, PTR_DIFF(buf+len, unicomp));
+ getdc = skip_unibuf(uniuser,PTR_DIFF(buf+len, uniuser));
+ q = skip_string(getdc,1);
+ q += 4; /* Account Control Bits - indicating username type */
+ domainsidsize = IVAL(q, 0);
+ q += 4;
+
+ DEBUG(3,("process_logon_packet: SAMLOGON sidsize %d, len = %d\n", domainsidsize, len));
+
+ if (domainsidsize < (len - PTR_DIFF(q, buf)) && (domainsidsize != 0)) {
+ q += domainsidsize;
+ q = ALIGN4(q, buf);
+ }
+
+ DEBUG(3,("process_logon_packet: len = %d PTR_DIFF(q, buf) = %d\n", len, PTR_DIFF(q, buf) ));
+
+ if (len - PTR_DIFF(q, buf) > 8) {
/* with NT5 clients we can sometimes
- get additional data - a length specificed string
- containing the domain name, then 16 bytes of
- data (no idea what it is) */
+ get additional data - a length specificed string
+ containing the domain name, then 16 bytes of
+ data (no idea what it is) */
int dom_len = CVAL(q, 0);
q++;
- if (dom_len != 0) {
+ if (dom_len < (len - PTR_DIFF(q, buf)) && (dom_len != 0)) {
q += dom_len + 1;
}
q += 16;
- }
- ntversion = IVAL(q, 0);
- lmnttoken = SVAL(q, 4);
- lm20token = SVAL(q, 6);
- }
-
- /* Construct reply. */
- q = outbuf;
- SSVAL(q, 0, QUERYFORPDC_R);
- q += 2;
-
- fstrcpy(reply_name,my_name);
- fstrcpy(q, reply_name);
- q = skip_string(q, 1); /* PDC name */
-
- /* PDC and domain name */
- if (!short_request) /* Make a full reply */
- {
- q = ALIGN2(q, outbuf);
-
- q += dos_PutUniCode(q, my_name, sizeof(pstring), True); /* PDC name */
- q += dos_PutUniCode(q, lp_workgroup(),sizeof(pstring), True); /* Domain name*/
- SIVAL(q, 0, 1); /* our nt version */
- SSVAL(q, 4, 0xffff); /* our lmnttoken */
- SSVAL(q, 6, 0xffff); /* our lm20token */
- q += 8;
- }
-
- /* RJS, 21-Feb-2000, we send a short reply if the request was short */
-
- DEBUG(3,("process_logon_packet: GETDC request from %s at IP %s, \
-reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
- machine,inet_ntoa(p->ip), reply_name, lp_workgroup(),
- QUERYFORPDC_R, (uint32)ntversion, (uint32)lmnttoken,
- (uint32)lm20token ));
-
- dump_data(4, outbuf, PTR_DIFF(q, outbuf));
-
- send_mailslot(True, getdc,
- outbuf,PTR_DIFF(q,outbuf),
- global_myname(), 0x0,
- dgram->source_name.name,
- dgram->source_name.name_type,
- p->ip, *iface_ip(p->ip), p->port);
- return;
- }
-
- case SAMLOGON:
- {
- char *q = buf + 2;
- fstring asccomp;
-
- q += 2;
- unicomp = q;
- uniuser = skip_unibuf(unicomp, PTR_DIFF(buf+len, unicomp));
- getdc = skip_unibuf(uniuser,PTR_DIFF(buf+len, uniuser));
- q = skip_string(getdc,1);
- q += 4; /* Account Control Bits - indicating username type */
- domainsidsize = IVAL(q, 0);
- q += 4;
-
- DEBUG(3,("process_logon_packet: SAMLOGON sidsize %d, len = %d\n", domainsidsize, len));
-
- if (domainsidsize < (len - PTR_DIFF(q, buf)) && (domainsidsize != 0)) {
- q += domainsidsize;
- q = ALIGN4(q, buf);
- }
-
- DEBUG(3,("process_logon_packet: len = %d PTR_DIFF(q, buf) = %d\n", len, PTR_DIFF(q, buf) ));
-
- if (len - PTR_DIFF(q, buf) > 8) {
- /* with NT5 clients we can sometimes
- get additional data - a length specificed string
- containing the domain name, then 16 bytes of
- data (no idea what it is) */
- int dom_len = CVAL(q, 0);
- q++;
- if (dom_len < (len - PTR_DIFF(q, buf)) && (dom_len != 0)) {
- q += dom_len + 1;
- }
- q += 16;
- }
-
- ntversion = IVAL(q, 0);
- lmnttoken = SVAL(q, 4);
- lm20token = SVAL(q, 6);
- q += 8;
-
- DEBUG(3,("process_logon_packet: SAMLOGON sidsize %d ntv %d\n", domainsidsize, ntversion));
-
- /*
- * we respond regadless of whether the machine is in our password
- * database. If it isn't then we let smbd send an appropriate error.
- * Let's ignore the SID.
- */
- pull_ucs2_pstring(ascuser, uniuser);
- pull_ucs2_fstring(asccomp, unicomp);
- DEBUG(3,("process_logon_packet: SAMLOGON user %s\n", ascuser));
-
- fstrcpy(reply_name, "\\\\"); /* Here it wants \\LOGONSERVER. */
- fstrcat(reply_name, my_name);
-
- DEBUG(3,("process_logon_packet: SAMLOGON request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n",
- asccomp,inet_ntoa(p->ip), ascuser, reply_name, lp_workgroup(),
- SAMLOGON_R ,lmnttoken));
-
- /* Construct reply. */
-
- q = outbuf;
- /* we want the simple version unless we are an ADS PDC..which means */
- /* never, at least for now */
- if ((ntversion < 11) || (SEC_ADS != lp_security()) || (ROLE_DOMAIN_PDC != lp_server_role())) {
- if (SVAL(uniuser, 0) == 0) {
- SSVAL(q, 0, SAMLOGON_UNK_R); /* user unknown */
- } else {
- SSVAL(q, 0, SAMLOGON_R);
- }
+ }
+
+ ntversion = IVAL(q, 0);
+ lmnttoken = SVAL(q, 4);
+ lm20token = SVAL(q, 6);
+ q += 8;
+
+ DEBUG(3,("process_logon_packet: SAMLOGON sidsize %d ntv %d\n", domainsidsize, ntversion));
+
+ /*
+ * we respond regadless of whether the machine is in our password
+ * database. If it isn't then we let smbd send an appropriate error.
+ * Let's ignore the SID.
+ */
+ pull_ucs2_pstring(ascuser, uniuser);
+ pull_ucs2_fstring(asccomp, unicomp);
+ DEBUG(3,("process_logon_packet: SAMLOGON user %s\n", ascuser));
+
+ fstrcpy(reply_name, "\\\\"); /* Here it wants \\LOGONSERVER. */
+ fstrcat(reply_name, my_name);
+
+ DEBUG(3,("process_logon_packet: SAMLOGON request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n",
+ asccomp,inet_ntoa(p->ip), ascuser, reply_name, lp_workgroup(),
+ SAMLOGON_R ,lmnttoken));
+
+ /* Construct reply. */
+
+ q = outbuf;
+ /* we want the simple version unless we are an ADS PDC..which means */
+ /* never, at least for now */
+ if ((ntversion < 11) || (SEC_ADS != lp_security()) || (ROLE_DOMAIN_PDC != lp_server_role())) {
+ if (SVAL(uniuser, 0) == 0) {
+ SSVAL(q, 0, SAMLOGON_UNK_R); /* user unknown */
+ } else {
+ SSVAL(q, 0, SAMLOGON_R);
+ }
- q += 2;
+ q += 2;
- q += dos_PutUniCode(q, reply_name,sizeof(pstring), True);
- q += dos_PutUniCode(q, ascuser, sizeof(pstring), True);
- q += dos_PutUniCode(q, lp_workgroup(),sizeof(pstring), True);
- }
+ q += dos_PutUniCode(q, reply_name,sizeof(pstring), True);
+ q += dos_PutUniCode(q, ascuser, sizeof(pstring), True);
+ q += dos_PutUniCode(q, lp_workgroup(),sizeof(pstring), True);
+ }
#ifdef HAVE_ADS
- else {
- GUID domain_guid;
- pstring domain;
- pstring hostname;
- char *component, *dc, *q1;
- uint8 size;
- char *q_orig = q;
- int str_offset;
-
- get_mydomname(domain);
- get_myname(hostname);
+ else {
+ GUID domain_guid;
+ pstring domain;
+ pstring hostname;
+ char *component, *dc, *q1;
+ uint8 size;
+ char *q_orig = q;
+ int str_offset;
+
+ get_mydomname(domain);
+ get_myname(hostname);
- if (SVAL(uniuser, 0) == 0) {
- SIVAL(q, 0, SAMLOGON_AD_UNK_R); /* user unknown */
- } else {
- SIVAL(q, 0, SAMLOGON_AD_R);
- }
- q += 4;
+ if (SVAL(uniuser, 0) == 0) {
+ SIVAL(q, 0, SAMLOGON_AD_UNK_R); /* user unknown */
+ } else {
+ SIVAL(q, 0, SAMLOGON_AD_R);
+ }
+ q += 4;
- SIVAL(q, 0, ADS_PDC|ADS_GC|ADS_LDAP|ADS_DS|
- ADS_KDC|ADS_TIMESERV|ADS_CLOSEST|ADS_WRITABLE);
- q += 4;
+ SIVAL(q, 0, ADS_PDC|ADS_GC|ADS_LDAP|ADS_DS|
+ ADS_KDC|ADS_TIMESERV|ADS_CLOSEST|ADS_WRITABLE);
+ q += 4;
- /* Push Domain GUID */
- if (False == secrets_fetch_domain_guid(domain, &domain_guid)) {
- DEBUG(2, ("Could not fetch DomainGUID for %s\n", domain));
- return;
- }
- memcpy(q, &domain_guid, sizeof(domain_guid));
- q += sizeof(domain_guid);
-
- /* Forest */
- str_offset = q - q_orig;
- dc = domain;
- q1 = q;
- while ((component = strtok(dc, "."))) {
- dc = NULL;
- size = push_ascii(&q[1], component, -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
- }
+ /* Push Domain GUID */
+ if (False == secrets_fetch_domain_guid(domain, &domain_guid)) {
+ DEBUG(2, ("Could not fetch DomainGUID for %s\n", domain));
+ return;
+ }
+ memcpy(q, &domain_guid, sizeof(domain_guid));
+ q += sizeof(domain_guid);
+
+ /* Forest */
+ str_offset = q - q_orig;
+ dc = domain;
+ q1 = q;
+ while ((component = strtok(dc, "."))) {
+ dc = NULL;
+ size = push_ascii(&q[1], component, -1, 0);
+ SCVAL(q, 0, size);
+ q += (size + 1);
+ }
- /* Unk0 */
- SCVAL(q, 0, 0); q++;
-
- /* Domain */
- SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F));
- SCVAL(q, 1, str_offset & 0xFF);
- q += 2;
-
- /* Hostname */
- size = push_ascii(&q[1], hostname, -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
- SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F));
- SCVAL(q, 1, str_offset & 0xFF);
- q += 2;
-
- /* NETBIOS of domain */
- size = push_ascii(&q[1], lp_workgroup(), -1, STR_UPPER);
- SCVAL(q, 0, size);
- q += (size + 1);
-
- /* Unk1 */
- SCVAL(q, 0, 0); q++;
-
- /* NETBIOS of hostname */
- size = push_ascii(&q[1], my_name, -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
-
- /* Unk2 */
- SCVAL(q, 0, 0); q++;
-
- /* User name */
- if (SVAL(uniuser, 0) != 0) {
- size = push_ascii(&q[1], ascuser, -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
- }
+ /* Unk0 */
+ SCVAL(q, 0, 0);
+ q++;
- q_orig = q;
- /* Site name */
- size = push_ascii(&q[1], "Default-First-Site-Name", -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
-
- /* Site name (2) */
- str_offset = q - q_orig;
- SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F));
- SCVAL(q, 1, str_offset & 0xFF);
- q += 2;
-
- SCVAL(q, 0, PTR_DIFF(q,q1));
- SCVAL(q, 1, 0x10); /* unknown */
-
- SIVAL(q, 0, 0x00000002); q += 4; /* unknown */
- SIVAL(q, 0, (iface_ip(p->ip))->s_addr); q += 4;
- SIVAL(q, 0, 0x00000000); q += 4; /* unknown */
- SIVAL(q, 0, 0x00000000); q += 4; /* unknown */
- }
+ /* Domain */
+ SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F));
+ SCVAL(q, 1, str_offset & 0xFF);
+ q += 2;
+
+ /* Hostname */
+ size = push_ascii(&q[1], hostname, -1, 0);
+ SCVAL(q, 0, size);
+ q += (size + 1);
+ SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F));
+ SCVAL(q, 1, str_offset & 0xFF);
+ q += 2;
+
+ /* NETBIOS of domain */
+ size = push_ascii(&q[1], lp_workgroup(), -1, STR_UPPER);
+ SCVAL(q, 0, size);
+ q += (size + 1);
+
+ /* Unk1 */
+ SCVAL(q, 0, 0);
+ q++;
+
+ /* NETBIOS of hostname */
+ size = push_ascii(&q[1], my_name, -1, 0);
+ SCVAL(q, 0, size);
+ q += (size + 1);
+
+ /* Unk2 */
+ SCVAL(q, 0, 0);
+ q++;
+
+ /* User name */
+ if (SVAL(uniuser, 0) != 0) {
+ size = push_ascii(&q[1], ascuser, -1, 0);
+ SCVAL(q, 0, size);
+ q += (size + 1);
+ }
+
+ q_orig = q;
+ /* Site name */
+ size = push_ascii(&q[1], "Default-First-Site-Name", -1, 0);
+ SCVAL(q, 0, size);
+ q += (size + 1);
+
+ /* Site name (2) */
+ str_offset = q - q_orig;
+ SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F));
+ SCVAL(q, 1, str_offset & 0xFF);
+ q += 2;
+
+ SCVAL(q, 0, PTR_DIFF(q,q1));
+ SCVAL(q, 1, 0x10); /* unknown */
+
+ SIVAL(q, 0, 0x00000002);
+ q += 4; /* unknown */
+ SIVAL(q, 0, (iface_ip(p->ip))->s_addr);
+ q += 4;
+ SIVAL(q, 0, 0x00000000);
+ q += 4; /* unknown */
+ SIVAL(q, 0, 0x00000000);
+ q += 4; /* unknown */
+ }
#endif
- /* tell the client what version we are */
- SIVAL(q, 0, ((ntversion < 11) || (SEC_ADS != lp_security())) ? 1 : 13);
- /* our ntversion */
- SSVAL(q, 4, 0xffff); /* our lmnttoken */
- SSVAL(q, 6, 0xffff); /* our lm20token */
- q += 8;
-
- dump_data(4, outbuf, PTR_DIFF(q, outbuf));
-
- send_mailslot(True, getdc,
- outbuf,PTR_DIFF(q,outbuf),
- global_myname(), 0x0,
- dgram->source_name.name,
- dgram->source_name.name_type,
- p->ip, *iface_ip(p->ip), p->port);
- break;
- }
-
- /* Announce change to UAS or SAM. Send by the domain controller when a
- replication event is required. */
-
- case SAM_UAS_CHANGE: {
- struct sam_database_info *db_info;
- char *q = buf + 2;
- int i, db_count;
- uint32 low_serial;
+ /* tell the client what version we are */
+ SIVAL(q, 0, ((ntversion < 11) || (SEC_ADS != lp_security())) ? 1 : 13);
+ /* our ntversion */
+ SSVAL(q, 4, 0xffff); /* our lmnttoken */
+ SSVAL(q, 6, 0xffff); /* our lm20token */
+ q += 8;
+
+ dump_data(4, outbuf, PTR_DIFF(q, outbuf));
+
+ pull_ascii_fstring(getdc_str, getdc);
+ pull_ascii_nstring(source_name, dgram->source_name.name);
+
+ send_mailslot(True, getdc,
+ outbuf,PTR_DIFF(q,outbuf),
+ global_myname(), 0x0,
+ dgram->source_name.name,
+ dgram->source_name.name_type,
+ p->ip, *iface_ip(p->ip), p->port);
+ break;
+ }
+
+ /* Announce change to UAS or SAM. Send by the domain controller when a
+ replication event is required. */
+
+ case SAM_UAS_CHANGE:
+ {
+ struct sam_database_info *db_info;
+ char *q = buf + 2;
+ int i, db_count;
+ uint32 low_serial;
- /* Header */
+ /* Header */
- low_serial = IVAL(q, 0); q += 4; /* Low serial number */
+ low_serial = IVAL(q, 0); q += 4; /* Low serial number */
- q += 4; /* Date/time */
- q += 4; /* Pulse */
- q += 4; /* Random */
+ q += 4; /* Date/time */
+ q += 4; /* Pulse */
+ q += 4; /* Random */
- /* Domain info */
+ /* Domain info */
- q = skip_string(q, 1); /* PDC name */
- q = skip_string(q, 1); /* Domain name */
- q = skip_unibuf(q, PTR_DIFF(buf + len, q)); /* Unicode PDC name */
- q = skip_unibuf(q, PTR_DIFF(buf + len, q)); /* Unicode domain name */
+ q = skip_string(q, 1); /* PDC name */
+ q = skip_string(q, 1); /* Domain name */
+ q = skip_unibuf(q, PTR_DIFF(buf + len, q)); /* Unicode PDC name */
+ q = skip_unibuf(q, PTR_DIFF(buf + len, q)); /* Unicode domain name */
- /* Database info */
+ /* Database info */
- db_count = SVAL(q, 0); q += 2;
+ db_count = SVAL(q, 0); q += 2;
- db_info = (struct sam_database_info *)
- malloc(sizeof(struct sam_database_info) * db_count);
-
- if (db_info == NULL) {
- DEBUG(3, ("out of memory allocating info for %d databases\n",
- db_count));
- return;
- }
+ db_info = (struct sam_database_info *)
+ malloc(sizeof(struct sam_database_info) * db_count);
+
+ if (db_info == NULL) {
+ DEBUG(3, ("out of memory allocating info for %d databases\n", db_count));
+ return;
+ }
- for (i = 0; i < db_count; i++) {
- db_info[i].index = IVAL(q, 0);
- db_info[i].serial_lo = IVAL(q, 4);
- db_info[i].serial_hi = IVAL(q, 8);
- db_info[i].date_lo = IVAL(q, 12);
- db_info[i].date_hi = IVAL(q, 16);
- q += 20;
- }
-
- /* Domain SID */
-
- q += IVAL(q, 0) + 4; /* 4 byte length plus data */
+ for (i = 0; i < db_count; i++) {
+ db_info[i].index = IVAL(q, 0);
+ db_info[i].serial_lo = IVAL(q, 4);
+ db_info[i].serial_hi = IVAL(q, 8);
+ db_info[i].date_lo = IVAL(q, 12);
+ db_info[i].date_hi = IVAL(q, 16);
+ q += 20;
+ }
+
+ /* Domain SID */
+
+ q += IVAL(q, 0) + 4; /* 4 byte length plus data */
- q += 2; /* Alignment? */
-
- /* Misc other info */
+ q += 2; /* Alignment? */
- q += 4; /* NT version (0x1) */
- q += 2; /* LMNT token (0xff) */
- q += 2; /* LM20 token (0xff) */
+ /* Misc other info */
- SAFE_FREE(db_info); /* Not sure whether we need to do anything
- useful with these */
+ q += 4; /* NT version (0x1) */
+ q += 2; /* LMNT token (0xff) */
+ q += 2; /* LM20 token (0xff) */
- /* Send message to smbd */
+ SAFE_FREE(db_info); /* Not sure whether we need to do anything useful with these */
- send_repl_message(low_serial);
+ /* Send message to smbd */
- break;
- }
+ send_repl_message(low_serial);
+ break;
+ }
- default:
- {
- DEBUG(3,("process_logon_packet: Unknown domain request %d\n",code));
- return;
- }
- }
+ default:
+ DEBUG(3,("process_logon_packet: Unknown domain request %d\n",code));
+ return;
+ }
}
diff --git a/source3/nmbd/nmbd_responserecordsdb.c b/source3/nmbd/nmbd_responserecordsdb.c
index 7e8c8025ae..30c0c12950 100644
--- a/source3/nmbd/nmbd_responserecordsdb.c
+++ b/source3/nmbd/nmbd_responserecordsdb.c
@@ -34,27 +34,26 @@ int num_response_packets = 0;
static void add_response_record(struct subnet_record *subrec,
struct response_record *rrec)
{
- struct response_record *rrec2;
+ struct response_record *rrec2;
- num_response_packets++; /* count of total number of packets still around */
+ num_response_packets++; /* count of total number of packets still around */
- DEBUG(4,("add_response_record: adding response record id:%hu to subnet %s. num_records:%d\n",
- rrec->response_id, subrec->subnet_name, num_response_packets));
+ DEBUG(4,("add_response_record: adding response record id:%hu to subnet %s. num_records:%d\n",
+ rrec->response_id, subrec->subnet_name, num_response_packets));
- if (!subrec->responselist)
- {
- subrec->responselist = rrec;
- rrec->prev = NULL;
- rrec->next = NULL;
- return;
- }
+ if (!subrec->responselist) {
+ subrec->responselist = rrec;
+ rrec->prev = NULL;
+ rrec->next = NULL;
+ return;
+ }
- for (rrec2 = subrec->responselist; rrec2->next; rrec2 = rrec2->next)
- ;
+ for (rrec2 = subrec->responselist; rrec2->next; rrec2 = rrec2->next)
+ ;
- rrec2->next = rrec;
- rrec->next = NULL;
- rrec->prev = rrec2;
+ rrec2->next = rrec;
+ rrec->next = NULL;
+ rrec->prev = rrec2;
}
/***************************************************************************
@@ -64,32 +63,31 @@ static void add_response_record(struct subnet_record *subrec,
void remove_response_record(struct subnet_record *subrec,
struct response_record *rrec)
{
- if (rrec->prev)
- rrec->prev->next = rrec->next;
- if (rrec->next)
- rrec->next->prev = rrec->prev;
-
- if (subrec->responselist == rrec)
- subrec->responselist = rrec->next;
-
- if(rrec->userdata)
- {
- if(rrec->userdata->free_fn) {
- (*rrec->userdata->free_fn)(rrec->userdata);
- } else {
- ZERO_STRUCTP(rrec->userdata);
- SAFE_FREE(rrec->userdata);
- }
- }
-
- /* Ensure we can delete. */
- rrec->packet->locked = False;
- free_packet(rrec->packet);
-
- ZERO_STRUCTP(rrec);
- SAFE_FREE(rrec);
-
- num_response_packets--; /* count of total number of packets still around */
+ if (rrec->prev)
+ rrec->prev->next = rrec->next;
+ if (rrec->next)
+ rrec->next->prev = rrec->prev;
+
+ if (subrec->responselist == rrec)
+ subrec->responselist = rrec->next;
+
+ if(rrec->userdata) {
+ if(rrec->userdata->free_fn) {
+ (*rrec->userdata->free_fn)(rrec->userdata);
+ } else {
+ ZERO_STRUCTP(rrec->userdata);
+ SAFE_FREE(rrec->userdata);
+ }
+ }
+
+ /* Ensure we can delete. */
+ rrec->packet->locked = False;
+ free_packet(rrec->packet);
+
+ ZERO_STRUCTP(rrec);
+ SAFE_FREE(rrec);
+
+ num_response_packets--; /* count of total number of packets still around */
}
/****************************************************************************
@@ -104,77 +102,70 @@ struct response_record *make_response_record( struct subnet_record *subrec,
fail_function fail_fn,
struct userdata_struct *userdata)
{
- struct response_record *rrec;
- struct nmb_packet *nmb = &p->packet.nmb;
-
- if (!(rrec = (struct response_record *)malloc(sizeof(*rrec))))
- {
- DEBUG(0,("make_response_queue_record: malloc fail for response_record.\n"));
- return NULL;
- }
-
- memset((char *)rrec, '\0', sizeof(*rrec));
-
- rrec->response_id = nmb->header.name_trn_id;
-
- rrec->resp_fn = resp_fn;
- rrec->timeout_fn = timeout_fn;
- rrec->success_fn = success_fn;
- rrec->fail_fn = fail_fn;
-
- rrec->packet = p;
-
- if(userdata)
- {
- /* Intelligent userdata. */
- if(userdata->copy_fn)
- {
- if((rrec->userdata = (*userdata->copy_fn)(userdata)) == NULL)
- {
- DEBUG(0,("make_response_queue_record: copy fail for userdata.\n"));
- ZERO_STRUCTP(rrec);
- SAFE_FREE(rrec);
- return NULL;
- }
- }
- else
- {
- /* Primitive userdata, do a memcpy. */
- if((rrec->userdata = (struct userdata_struct *)
- malloc(sizeof(struct userdata_struct)+userdata->userdata_len)) == NULL)
- {
- DEBUG(0,("make_response_queue_record: malloc fail for userdata.\n"));
- ZERO_STRUCTP(rrec);
- SAFE_FREE(rrec);
- return NULL;
- }
- rrec->userdata->copy_fn = userdata->copy_fn;
- rrec->userdata->free_fn = userdata->free_fn;
- rrec->userdata->userdata_len = userdata->userdata_len;
- memcpy(rrec->userdata->data, userdata->data, userdata->userdata_len);
- }
- }
- else
- rrec->userdata = NULL;
-
- rrec->num_msgs = 0;
-
- if(!nmb->header.nm_flags.bcast)
- rrec->repeat_interval = 5; /* 5 seconds for unicast packets. */
- else
- rrec->repeat_interval = 1; /* XXXX should be in ms */
- rrec->repeat_count = 3; /* 3 retries */
- rrec->repeat_time = time(NULL) + rrec->repeat_interval; /* initial retry time */
-
- /* This packet is not being processed. */
- rrec->in_expiration_processing = False;
-
- /* Lock the packet so we won't lose it while it's on the list. */
- p->locked = True;
-
- add_response_record(subrec, rrec);
-
- return rrec;
+ struct response_record *rrec;
+ struct nmb_packet *nmb = &p->packet.nmb;
+
+ if (!(rrec = (struct response_record *)malloc(sizeof(*rrec)))) {
+ DEBUG(0,("make_response_queue_record: malloc fail for response_record.\n"));
+ return NULL;
+ }
+
+ memset((char *)rrec, '\0', sizeof(*rrec));
+
+ rrec->response_id = nmb->header.name_trn_id;
+
+ rrec->resp_fn = resp_fn;
+ rrec->timeout_fn = timeout_fn;
+ rrec->success_fn = success_fn;
+ rrec->fail_fn = fail_fn;
+
+ rrec->packet = p;
+
+ if(userdata) {
+ /* Intelligent userdata. */
+ if(userdata->copy_fn) {
+ if((rrec->userdata = (*userdata->copy_fn)(userdata)) == NULL) {
+ DEBUG(0,("make_response_queue_record: copy fail for userdata.\n"));
+ ZERO_STRUCTP(rrec);
+ SAFE_FREE(rrec);
+ return NULL;
+ }
+ } else {
+ /* Primitive userdata, do a memcpy. */
+ if((rrec->userdata = (struct userdata_struct *)
+ malloc(sizeof(struct userdata_struct)+userdata->userdata_len)) == NULL) {
+ DEBUG(0,("make_response_queue_record: malloc fail for userdata.\n"));
+ ZERO_STRUCTP(rrec);
+ SAFE_FREE(rrec);
+ return NULL;
+ }
+ rrec->userdata->copy_fn = userdata->copy_fn;
+ rrec->userdata->free_fn = userdata->free_fn;
+ rrec->userdata->userdata_len = userdata->userdata_len;
+ memcpy(rrec->userdata->data, userdata->data, userdata->userdata_len);
+ }
+ } else {
+ rrec->userdata = NULL;
+ }
+
+ rrec->num_msgs = 0;
+
+ if(!nmb->header.nm_flags.bcast)
+ rrec->repeat_interval = 5; /* 5 seconds for unicast packets. */
+ else
+ rrec->repeat_interval = 1; /* XXXX should be in ms */
+ rrec->repeat_count = 3; /* 3 retries */
+ rrec->repeat_time = time(NULL) + rrec->repeat_interval; /* initial retry time */
+
+ /* This packet is not being processed. */
+ rrec->in_expiration_processing = False;
+
+ /* Lock the packet so we won't lose it while it's on the list. */
+ p->locked = True;
+
+ add_response_record(subrec, rrec);
+
+ return rrec;
}
/****************************************************************************
@@ -184,18 +175,16 @@ struct response_record *make_response_record( struct subnet_record *subrec,
static struct response_record *find_response_record_on_subnet(
struct subnet_record *subrec, uint16 id)
{
- struct response_record *rrec = NULL;
-
- for (rrec = subrec->responselist; rrec; rrec = rrec->next)
- {
- if (rrec->response_id == id)
- {
- DEBUG(4, ("find_response_record: found response record id = %hu on subnet %s\n",
- id, subrec->subnet_name));
- break;
- }
- }
- return rrec;
+ struct response_record *rrec = NULL;
+
+ for (rrec = subrec->responselist; rrec; rrec = rrec->next) {
+ if (rrec->response_id == id) {
+ DEBUG(4, ("find_response_record: found response record id = %hu on subnet %s\n",
+ id, subrec->subnet_name));
+ break;
+ }
+ }
+ return rrec;
}
/****************************************************************************
@@ -205,37 +194,34 @@ static struct response_record *find_response_record_on_subnet(
struct response_record *find_response_record(struct subnet_record **ppsubrec,
uint16 id)
{
- struct response_record *rrec = NULL;
-
- for ((*ppsubrec) = FIRST_SUBNET; (*ppsubrec);
- (*ppsubrec) = NEXT_SUBNET_INCLUDING_UNICAST(*ppsubrec))
- {
- if((rrec = find_response_record_on_subnet(*ppsubrec, id)) != NULL)
- return rrec;
- }
-
- /* There should never be response records on the remote_broadcast subnet.
- Sanity check to ensure this is so. */
- if(remote_broadcast_subnet->responselist != NULL)
- {
- DEBUG(0,("find_response_record: response record found on subnet %s. This should \
+ struct response_record *rrec = NULL;
+
+ for ((*ppsubrec) = FIRST_SUBNET; (*ppsubrec);
+ (*ppsubrec) = NEXT_SUBNET_INCLUDING_UNICAST(*ppsubrec)) {
+ if((rrec = find_response_record_on_subnet(*ppsubrec, id)) != NULL)
+ return rrec;
+ }
+
+ /* There should never be response records on the remote_broadcast subnet.
+ Sanity check to ensure this is so. */
+ if(remote_broadcast_subnet->responselist != NULL) {
+ DEBUG(0,("find_response_record: response record found on subnet %s. This should \
never happen !\n", remote_broadcast_subnet->subnet_name));
- }
+ }
- /* Now check the WINS server subnet if it exists. */
- if(wins_server_subnet != NULL)
- {
- *ppsubrec = wins_server_subnet;
- if((rrec = find_response_record_on_subnet(*ppsubrec, id))!= NULL)
- return rrec;
- }
+ /* Now check the WINS server subnet if it exists. */
+ if(wins_server_subnet != NULL) {
+ *ppsubrec = wins_server_subnet;
+ if((rrec = find_response_record_on_subnet(*ppsubrec, id))!= NULL)
+ return rrec;
+ }
- DEBUG(0,("find_response_record: response packet id %hu received with no \
+ DEBUG(0,("find_response_record: response packet id %hu received with no \
matching record.\n", id));
- *ppsubrec = NULL;
+ *ppsubrec = NULL;
- return NULL;
+ return NULL;
}
/****************************************************************************
@@ -244,21 +230,19 @@ matching record.\n", id));
BOOL is_refresh_already_queued(struct subnet_record *subrec, struct name_record *namerec)
{
- struct response_record *rrec = NULL;
+ struct response_record *rrec = NULL;
- for (rrec = subrec->responselist; rrec; rrec = rrec->next)
- {
- struct packet_struct *p = rrec->packet;
- struct nmb_packet *nmb = &p->packet.nmb;
-
- if((nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
- (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9))
- {
- /* Yes it's a queued refresh - check if the name is correct. */
- if(nmb_name_equal(&nmb->question.question_name, &namerec->name))
- return True;
- }
- }
-
- return False;
-}
+ for (rrec = subrec->responselist; rrec; rrec = rrec->next) {
+ struct packet_struct *p = rrec->packet;
+ struct nmb_packet *nmb = &p->packet.nmb;
+
+ if((nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
+ (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9)) {
+ /* Yes it's a queued refresh - check if the name is correct. */
+ if(nmb_name_equal(&nmb->question.question_name, &namerec->name))
+ return True;
+ }
+ }
+
+ return False;
+}
diff --git a/source3/nmbd/nmbd_sendannounce.c b/source3/nmbd/nmbd_sendannounce.c
index 353717ee62..87908e352c 100644
--- a/source3/nmbd/nmbd_sendannounce.c
+++ b/source3/nmbd/nmbd_sendannounce.c
@@ -35,21 +35,21 @@ extern BOOL found_lm_clients;
void send_browser_reset(int reset_type, const char *to_name, int to_type, struct in_addr to_ip)
{
- pstring outbuf;
- char *p;
+ pstring outbuf;
+ char *p;
- DEBUG(3,("send_browser_reset: sending reset request type %d to %s<%02x> IP %s.\n",
- reset_type, to_name, to_type, inet_ntoa(to_ip) ));
+ DEBUG(3,("send_browser_reset: sending reset request type %d to %s<%02x> IP %s.\n",
+ reset_type, to_name, to_type, inet_ntoa(to_ip) ));
- memset(outbuf,'\0',sizeof(outbuf));
- p = outbuf;
- SCVAL(p,0,ANN_ResetBrowserState);
- p++;
- SCVAL(p,0,reset_type);
- p++;
+ memset(outbuf,'\0',sizeof(outbuf));
+ p = outbuf;
+ SCVAL(p,0,ANN_ResetBrowserState);
+ p++;
+ SCVAL(p,0,reset_type);
+ p++;
- send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
- global_myname(), 0x0, to_name, to_type, to_ip,
+ send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
+ global_myname(), 0x0, to_name, to_type, to_ip,
FIRST_SUBNET->myip, DGRAM_PORT);
}
@@ -60,25 +60,25 @@ void send_browser_reset(int reset_type, const char *to_name, int to_type, struct
void broadcast_announce_request(struct subnet_record *subrec, struct work_record *work)
{
- pstring outbuf;
- char *p;
+ pstring outbuf;
+ char *p;
- work->needannounce = True;
+ work->needannounce = True;
- DEBUG(3,("broadcast_announce_request: sending announce request for workgroup %s \
+ DEBUG(3,("broadcast_announce_request: sending announce request for workgroup %s \
to subnet %s\n", work->work_group, subrec->subnet_name));
- memset(outbuf,'\0',sizeof(outbuf));
- p = outbuf;
- SCVAL(p,0,ANN_AnnouncementRequest);
- p++;
+ memset(outbuf,'\0',sizeof(outbuf));
+ p = outbuf;
+ SCVAL(p,0,ANN_AnnouncementRequest);
+ p++;
- SCVAL(p,0,work->token); /* (local) Unique workgroup token id. */
- p++;
- p += push_string(NULL, p+1, global_myname(), 15, STR_ASCII|STR_UPPER|STR_TERMINATE);
+ SCVAL(p,0,work->token); /* (local) Unique workgroup token id. */
+ p++;
+ p += push_string(NULL, p+1, global_myname(), 15, STR_ASCII|STR_UPPER|STR_TERMINATE);
- send_mailslot(False, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
- global_myname(), 0x0, work->work_group,0x1e, subrec->bcast_ip,
+ send_mailslot(False, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
+ global_myname(), 0x0, work->work_group,0x1e, subrec->bcast_ip,
subrec->myip, DGRAM_PORT);
}
@@ -91,33 +91,33 @@ static void send_announcement(struct subnet_record *subrec, int announce_type,
time_t announce_interval,
const char *server_name, int server_type, const char *server_comment)
{
- pstring outbuf;
- char *p;
+ pstring outbuf;
+ char *p;
- memset(outbuf,'\0',sizeof(outbuf));
- p = outbuf+1;
+ memset(outbuf,'\0',sizeof(outbuf));
+ p = outbuf+1;
- SCVAL(outbuf,0,announce_type);
+ SCVAL(outbuf,0,announce_type);
- /* Announcement parameters. */
- SCVAL(p,0,updatecount);
- SIVAL(p,1,announce_interval*1000); /* Milliseconds - despite the spec. */
+ /* Announcement parameters. */
+ SCVAL(p,0,updatecount);
+ SIVAL(p,1,announce_interval*1000); /* Milliseconds - despite the spec. */
- push_string(NULL, p+5, server_name, 15, STR_ASCII|STR_UPPER|STR_TERMINATE);
+ push_string(NULL, p+5, server_name, 15, STR_ASCII|STR_UPPER|STR_TERMINATE);
- SCVAL(p,21,lp_major_announce_version()); /* Major version. */
- SCVAL(p,22,lp_minor_announce_version()); /* Minor version. */
+ SCVAL(p,21,lp_major_announce_version()); /* Major version. */
+ SCVAL(p,22,lp_minor_announce_version()); /* Minor version. */
- SIVAL(p,23,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
- /* Browse version: got from NT/AS 4.00 - Value defined in smb.h (JHT). */
- SSVAL(p,27,BROWSER_ELECTION_VERSION);
- SSVAL(p,29,BROWSER_CONSTANT); /* Browse signature. */
+ SIVAL(p,23,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
+ /* Browse version: got from NT/AS 4.00 - Value defined in smb.h (JHT). */
+ SSVAL(p,27,BROWSER_ELECTION_VERSION);
+ SSVAL(p,29,BROWSER_CONSTANT); /* Browse signature. */
- p += 31 + push_string(NULL, p+31, server_comment, -1, STR_ASCII|STR_TERMINATE);
+ p += 31 + push_string(NULL, p+31, server_comment, -1, STR_ASCII|STR_TERMINATE);
- send_mailslot(False,BROWSE_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
- from_name, 0x0, to_name, to_type, to_ip, subrec->myip,
- DGRAM_PORT);
+ send_mailslot(False,BROWSE_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
+ from_name, 0x0, to_name, to_type, to_ip, subrec->myip,
+ DGRAM_PORT);
}
/****************************************************************************
@@ -129,28 +129,23 @@ static void send_lm_announcement(struct subnet_record *subrec, int announce_type
time_t announce_interval,
char *server_name, int server_type, char *server_comment)
{
- pstring outbuf;
- char *p=outbuf;
-
- memset(outbuf,'\0',sizeof(outbuf));
-
- SSVAL(p,0,announce_type);
- SIVAL(p,2,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
- SCVAL(p,6,lp_major_announce_version()); /* Major version. */
- SCVAL(p,7,lp_minor_announce_version()); /* Minor version. */
- SSVAL(p,8,announce_interval); /* In seconds - according to spec. */
-
- p += 10;
- /*StrnCpy(p,server_name,15);
- strupper_m(p);
- p = skip_string(p,1);
- pstrcpy(p,server_comment);
- p = skip_string(p,1);*/
- p += push_string(NULL, p, server_name, 15, STR_ASCII|STR_UPPER|STR_TERMINATE);
- p += push_string(NULL, p, server_comment, sizeof(pstring)-15, STR_ASCII|STR_UPPER|STR_TERMINATE);
-
- send_mailslot(False,LANMAN_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
- from_name, 0x0, to_name, to_type, to_ip, subrec->myip,
+ pstring outbuf;
+ char *p=outbuf;
+
+ memset(outbuf,'\0',sizeof(outbuf));
+
+ SSVAL(p,0,announce_type);
+ SIVAL(p,2,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
+ SCVAL(p,6,lp_major_announce_version()); /* Major version. */
+ SCVAL(p,7,lp_minor_announce_version()); /* Minor version. */
+ SSVAL(p,8,announce_interval); /* In seconds - according to spec. */
+
+ p += 10;
+ p += push_string(NULL, p, server_name, 15, STR_ASCII|STR_UPPER|STR_TERMINATE);
+ p += push_string(NULL, p, server_comment, sizeof(pstring)-15, STR_ASCII|STR_UPPER|STR_TERMINATE);
+
+ send_mailslot(False,LANMAN_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
+ from_name, 0x0, to_name, to_type, to_ip, subrec->myip,
DGRAM_PORT);
}
@@ -161,20 +156,20 @@ static void send_lm_announcement(struct subnet_record *subrec, int announce_type
static void send_local_master_announcement(struct subnet_record *subrec, struct work_record *work,
struct server_record *servrec)
{
- /* Ensure we don't have the prohibited bit set. */
- uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
-
- DEBUG(3,("send_local_master_announcement: type %x for name %s on subnet %s for workgroup %s\n",
- type, global_myname(), subrec->subnet_name, work->work_group));
-
- send_announcement(subrec, ANN_LocalMasterAnnouncement,
- global_myname(), /* From nbt name. */
- work->work_group, 0x1e, /* To nbt name. */
- subrec->bcast_ip, /* To ip. */
- work->announce_interval, /* Time until next announce. */
- global_myname(), /* Name to announce. */
- type, /* Type field. */
- servrec->serv.comment);
+ /* Ensure we don't have the prohibited bit set. */
+ uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
+
+ DEBUG(3,("send_local_master_announcement: type %x for name %s on subnet %s for workgroup %s\n",
+ type, global_myname(), subrec->subnet_name, work->work_group));
+
+ send_announcement(subrec, ANN_LocalMasterAnnouncement,
+ global_myname(), /* From nbt name. */
+ work->work_group, 0x1e, /* To nbt name. */
+ subrec->bcast_ip, /* To ip. */
+ work->announce_interval, /* Time until next announce. */
+ global_myname(), /* Name to announce. */
+ type, /* Type field. */
+ servrec->serv.comment);
}
/****************************************************************************
@@ -183,17 +178,17 @@ static void send_local_master_announcement(struct subnet_record *subrec, struct
static void send_workgroup_announcement(struct subnet_record *subrec, struct work_record *work)
{
- DEBUG(3,("send_workgroup_announcement: on subnet %s for workgroup %s\n",
- subrec->subnet_name, work->work_group));
-
- send_announcement(subrec, ANN_DomainAnnouncement,
- global_myname(), /* From nbt name. */
- MSBROWSE, 0x1, /* To nbt name. */
- subrec->bcast_ip, /* To ip. */
- work->announce_interval, /* Time until next announce. */
- work->work_group, /* Name to announce. */
- SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT, /* workgroup announce flags. */
- global_myname()); /* From name as comment. */
+ DEBUG(3,("send_workgroup_announcement: on subnet %s for workgroup %s\n",
+ subrec->subnet_name, work->work_group));
+
+ send_announcement(subrec, ANN_DomainAnnouncement,
+ global_myname(), /* From nbt name. */
+ MSBROWSE, 0x1, /* To nbt name. */
+ subrec->bcast_ip, /* To ip. */
+ work->announce_interval, /* Time until next announce. */
+ work->work_group, /* Name to announce. */
+ SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT, /* workgroup announce flags. */
+ global_myname()); /* From name as comment. */
}
/****************************************************************************
@@ -203,20 +198,20 @@ static void send_workgroup_announcement(struct subnet_record *subrec, struct wor
static void send_host_announcement(struct subnet_record *subrec, struct work_record *work,
struct server_record *servrec)
{
- /* Ensure we don't have the prohibited bits set. */
- uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
-
- DEBUG(3,("send_host_announcement: type %x for host %s on subnet %s for workgroup %s\n",
- type, servrec->serv.name, subrec->subnet_name, work->work_group));
-
- send_announcement(subrec, ANN_HostAnnouncement,
- servrec->serv.name, /* From nbt name. */
- work->work_group, 0x1d, /* To nbt name. */
- subrec->bcast_ip, /* To ip. */
- work->announce_interval, /* Time until next announce. */
- servrec->serv.name, /* Name to announce. */
- type, /* Type field. */
- servrec->serv.comment);
+ /* Ensure we don't have the prohibited bits set. */
+ uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
+
+ DEBUG(3,("send_host_announcement: type %x for host %s on subnet %s for workgroup %s\n",
+ type, servrec->serv.name, subrec->subnet_name, work->work_group));
+
+ send_announcement(subrec, ANN_HostAnnouncement,
+ servrec->serv.name, /* From nbt name. */
+ work->work_group, 0x1d, /* To nbt name. */
+ subrec->bcast_ip, /* To ip. */
+ work->announce_interval, /* Time until next announce. */
+ servrec->serv.name, /* Name to announce. */
+ type, /* Type field. */
+ servrec->serv.comment);
}
/****************************************************************************
@@ -226,20 +221,20 @@ static void send_host_announcement(struct subnet_record *subrec, struct work_rec
static void send_lm_host_announcement(struct subnet_record *subrec, struct work_record *work,
struct server_record *servrec, int lm_interval)
{
- /* Ensure we don't have the prohibited bits set. */
- uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
-
- DEBUG(3,("send_lm_host_announcement: type %x for host %s on subnet %s for workgroup %s, ttl: %d\n",
- type, servrec->serv.name, subrec->subnet_name, work->work_group, lm_interval));
-
- send_lm_announcement(subrec, ANN_HostAnnouncement,
- servrec->serv.name, /* From nbt name. */
- work->work_group, 0x00, /* To nbt name. */
- subrec->bcast_ip, /* To ip. */
- lm_interval, /* Time until next announce. */
- servrec->serv.name, /* Name to announce. */
- type, /* Type field. */
- servrec->serv.comment);
+ /* Ensure we don't have the prohibited bits set. */
+ uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
+
+ DEBUG(3,("send_lm_host_announcement: type %x for host %s on subnet %s for workgroup %s, ttl: %d\n",
+ type, servrec->serv.name, subrec->subnet_name, work->work_group, lm_interval));
+
+ send_lm_announcement(subrec, ANN_HostAnnouncement,
+ servrec->serv.name, /* From nbt name. */
+ work->work_group, 0x00, /* To nbt name. */
+ subrec->bcast_ip, /* To ip. */
+ lm_interval, /* Time until next announce. */
+ servrec->serv.name, /* Name to announce (fstring not netbios name struct). */
+ type, /* Type field. */
+ servrec->serv.comment);
}
/****************************************************************************
@@ -249,18 +244,15 @@ static void send_lm_host_announcement(struct subnet_record *subrec, struct work_
static void announce_server(struct subnet_record *subrec, struct work_record *work,
struct server_record *servrec)
{
- /* Only do domain announcements if we are a master and it's
- our primary name we're being asked to announce. */
-
- if (AM_LOCAL_MASTER_BROWSER(work) && strequal(global_myname(),servrec->serv.name))
- {
- send_local_master_announcement(subrec, work, servrec);
- send_workgroup_announcement(subrec, work);
- }
- else
- {
- send_host_announcement(subrec, work, servrec);
- }
+ /* Only do domain announcements if we are a master and it's
+ our primary name we're being asked to announce. */
+
+ if (AM_LOCAL_MASTER_BROWSER(work) && strequal(global_myname(),servrec->serv.name)) {
+ send_local_master_announcement(subrec, work, servrec);
+ send_workgroup_announcement(subrec, work);
+ } else {
+ send_host_announcement(subrec, work, servrec);
+ }
}
/****************************************************************************
@@ -270,43 +262,39 @@ static void announce_server(struct subnet_record *subrec, struct work_record *wo
void announce_my_server_names(time_t t)
{
- struct subnet_record *subrec;
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- struct work_record *work = find_workgroup_on_subnet(subrec, lp_workgroup());
-
- if(work)
- {
- struct server_record *servrec;
-
- if (work->needannounce)
- {
- /* Drop back to a max 3 minute announce. This is to prevent a
- single lost packet from breaking things for too long. */
-
- work->announce_interval = MIN(work->announce_interval,
- CHECK_TIME_MIN_HOST_ANNCE*60);
- work->lastannounce_time = t - (work->announce_interval+1);
- work->needannounce = False;
- }
-
- /* Announce every minute at first then progress to every 12 mins */
- if ((t - work->lastannounce_time) < work->announce_interval)
- continue;
-
- if (work->announce_interval < (CHECK_TIME_MAX_HOST_ANNCE * 60))
- work->announce_interval += 60;
-
- work->lastannounce_time = t;
-
- for (servrec = work->serverlist; servrec; servrec = servrec->next)
- {
- if (is_myname(servrec->serv.name))
- announce_server(subrec, work, servrec);
- }
- } /* if work */
- } /* for subrec */
+ struct subnet_record *subrec;
+
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
+ struct work_record *work = find_workgroup_on_subnet(subrec, lp_workgroup());
+
+ if(work) {
+ struct server_record *servrec;
+
+ if (work->needannounce) {
+ /* Drop back to a max 3 minute announce. This is to prevent a
+ single lost packet from breaking things for too long. */
+
+ work->announce_interval = MIN(work->announce_interval,
+ CHECK_TIME_MIN_HOST_ANNCE*60);
+ work->lastannounce_time = t - (work->announce_interval+1);
+ work->needannounce = False;
+ }
+
+ /* Announce every minute at first then progress to every 12 mins */
+ if ((t - work->lastannounce_time) < work->announce_interval)
+ continue;
+
+ if (work->announce_interval < (CHECK_TIME_MAX_HOST_ANNCE * 60))
+ work->announce_interval += 60;
+
+ work->lastannounce_time = t;
+
+ for (servrec = work->serverlist; servrec; servrec = servrec->next) {
+ if (is_myname(servrec->serv.name))
+ announce_server(subrec, work, servrec);
+ }
+ } /* if work */
+ } /* for subrec */
}
/****************************************************************************
@@ -316,47 +304,42 @@ void announce_my_server_names(time_t t)
void announce_my_lm_server_names(time_t t)
{
- struct subnet_record *subrec;
- static time_t last_lm_announce_time=0;
- int announce_interval = lp_lm_interval();
- int lm_announce = lp_lm_announce();
-
- if ((announce_interval <= 0) || (lm_announce <= 0))
- {
- /* user absolutely does not want LM announcements to be sent. */
- return;
- }
-
- if ((lm_announce >= 2) && (!found_lm_clients))
- {
- /* has been set to 2 (Auto) but no LM clients detected (yet). */
- return;
- }
-
- /* Otherwise: must have been set to 1 (Yes), or LM clients *have*
- been detected. */
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- struct work_record *work = find_workgroup_on_subnet(subrec, lp_workgroup());
-
- if(work)
- {
- struct server_record *servrec;
-
- if (last_lm_announce_time && ((t - last_lm_announce_time) < announce_interval ))
- continue;
-
- last_lm_announce_time = t;
-
- for (servrec = work->serverlist; servrec; servrec = servrec->next)
- {
- if (is_myname(servrec->serv.name))
- /* skipping equivalent of announce_server() */
- send_lm_host_announcement(subrec, work, servrec, announce_interval);
- }
- } /* if work */
- } /* for subrec */
+ struct subnet_record *subrec;
+ static time_t last_lm_announce_time=0;
+ int announce_interval = lp_lm_interval();
+ int lm_announce = lp_lm_announce();
+
+ if ((announce_interval <= 0) || (lm_announce <= 0)) {
+ /* user absolutely does not want LM announcements to be sent. */
+ return;
+ }
+
+ if ((lm_announce >= 2) && (!found_lm_clients)) {
+ /* has been set to 2 (Auto) but no LM clients detected (yet). */
+ return;
+ }
+
+ /* Otherwise: must have been set to 1 (Yes), or LM clients *have*
+ been detected. */
+
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
+ struct work_record *work = find_workgroup_on_subnet(subrec, lp_workgroup());
+
+ if(work) {
+ struct server_record *servrec;
+
+ if (last_lm_announce_time && ((t - last_lm_announce_time) < announce_interval ))
+ continue;
+
+ last_lm_announce_time = t;
+
+ for (servrec = work->serverlist; servrec; servrec = servrec->next) {
+ if (is_myname(servrec->serv.name))
+ /* skipping equivalent of announce_server() */
+ send_lm_host_announcement(subrec, work, servrec, announce_interval);
+ }
+ } /* if work */
+ } /* for subrec */
}
/* Announce timer. Moved into global static so it can be reset
@@ -370,7 +353,7 @@ static time_t announce_timer_last=0;
void reset_announce_timer(void)
{
- announce_timer_last = time(NULL) - (CHECK_TIME_MST_ANNOUNCE * 60);
+ announce_timer_last = time(NULL) - (CHECK_TIME_MST_ANNOUNCE * 60);
}
/****************************************************************************
@@ -379,45 +362,40 @@ void reset_announce_timer(void)
void announce_myself_to_domain_master_browser(time_t t)
{
- struct subnet_record *subrec;
- struct work_record *work;
-
- if(!we_are_a_wins_client())
- {
- DEBUG(10,("announce_myself_to_domain_master_browser: no unicast subnet, ignoring.\n"));
- return;
- }
-
- if (!announce_timer_last)
- announce_timer_last = t;
-
- if ((t-announce_timer_last) < (CHECK_TIME_MST_ANNOUNCE * 60))
- {
- DEBUG(10,("announce_myself_to_domain_master_browser: t (%d) - last(%d) < %d\n",
- (int)t, (int)announce_timer_last,
- CHECK_TIME_MST_ANNOUNCE * 60 ));
- return;
- }
-
- announce_timer_last = t;
-
- /* Look over all our broadcast subnets to see if any of them
- has the state set as local master browser. */
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- for (work = subrec->workgrouplist; work; work = work->next)
- {
- if (AM_LOCAL_MASTER_BROWSER(work))
- {
- DEBUG(4,( "announce_myself_to_domain_master_browser: I am a local master browser for \
+ struct subnet_record *subrec;
+ struct work_record *work;
+
+ if(!we_are_a_wins_client()) {
+ DEBUG(10,("announce_myself_to_domain_master_browser: no unicast subnet, ignoring.\n"));
+ return;
+ }
+
+ if (!announce_timer_last)
+ announce_timer_last = t;
+
+ if ((t-announce_timer_last) < (CHECK_TIME_MST_ANNOUNCE * 60)) {
+ DEBUG(10,("announce_myself_to_domain_master_browser: t (%d) - last(%d) < %d\n",
+ (int)t, (int)announce_timer_last,
+ CHECK_TIME_MST_ANNOUNCE * 60 ));
+ return;
+ }
+
+ announce_timer_last = t;
+
+ /* Look over all our broadcast subnets to see if any of them
+ has the state set as local master browser. */
+
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
+ for (work = subrec->workgrouplist; work; work = work->next) {
+ if (AM_LOCAL_MASTER_BROWSER(work)) {
+ DEBUG(4,( "announce_myself_to_domain_master_browser: I am a local master browser for \
workgroup %s on subnet %s\n", work->work_group, subrec->subnet_name));
- /* Look in nmbd_browsersync.c for the rest of this code. */
- announce_and_sync_with_domain_master_browser(subrec, work);
- }
- }
- }
+ /* Look in nmbd_browsersync.c for the rest of this code. */
+ announce_and_sync_with_domain_master_browser(subrec, work);
+ }
+ }
+ }
}
/****************************************************************************
@@ -427,49 +405,43 @@ This must *only* be called on shutdown.
void announce_my_servers_removed(void)
{
- int announce_interval = lp_lm_interval();
- int lm_announce = lp_lm_announce();
- struct subnet_record *subrec;
-
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- struct work_record *work;
- for (work = subrec->workgrouplist; work; work = work->next)
- {
- struct server_record *servrec;
-
- work->announce_interval = 0;
- for (servrec = work->serverlist; servrec; servrec = servrec->next)
- {
- if (!is_myname(servrec->serv.name))
- continue;
- servrec->serv.type = 0;
- if(AM_LOCAL_MASTER_BROWSER(work))
- send_local_master_announcement(subrec, work, servrec);
- send_host_announcement(subrec, work, servrec);
-
-
- if ((announce_interval <= 0) || (lm_announce <= 0))
- {
- /* user absolutely does not want LM announcements to be sent. */
- continue;
- }
-
- if ((lm_announce >= 2) && (!found_lm_clients))
- {
- /* has been set to 2 (Auto) but no LM clients detected (yet). */
- continue;
- }
-
- /*
- * lm announce was set or we have seen lm announcements, so do
- * a lm announcement of host removed.
- */
-
- send_lm_host_announcement(subrec, work, servrec, 0);
- }
- }
- }
+ int announce_interval = lp_lm_interval();
+ int lm_announce = lp_lm_announce();
+ struct subnet_record *subrec;
+
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
+ struct work_record *work;
+ for (work = subrec->workgrouplist; work; work = work->next) {
+ struct server_record *servrec;
+
+ work->announce_interval = 0;
+ for (servrec = work->serverlist; servrec; servrec = servrec->next) {
+ if (!is_myname(servrec->serv.name))
+ continue;
+ servrec->serv.type = 0;
+ if(AM_LOCAL_MASTER_BROWSER(work))
+ send_local_master_announcement(subrec, work, servrec);
+ send_host_announcement(subrec, work, servrec);
+
+ if ((announce_interval <= 0) || (lm_announce <= 0)) {
+ /* user absolutely does not want LM announcements to be sent. */
+ continue;
+ }
+
+ if ((lm_announce >= 2) && (!found_lm_clients)) {
+ /* has been set to 2 (Auto) but no LM clients detected (yet). */
+ continue;
+ }
+
+ /*
+ * lm announce was set or we have seen lm announcements, so do
+ * a lm announcement of host removed.
+ */
+
+ send_lm_host_announcement(subrec, work, servrec, 0);
+ }
+ }
+ }
}
/****************************************************************************
@@ -480,132 +452,127 @@ void announce_my_servers_removed(void)
void announce_remote(time_t t)
{
- char *s;
- const char *ptr;
- static time_t last_time = 0;
- pstring s2;
- struct in_addr addr;
- char *comment;
- int stype = lp_default_server_announce();
-
- if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL)))
- return;
-
- last_time = t;
-
- s = lp_remote_announce();
- if (!*s)
- return;
-
- comment = string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH);
-
- for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); )
- {
- /* The entries are of the form a.b.c.d/WORKGROUP with
- WORKGROUP being optional */
- const char *wgroup;
- char *pwgroup;
- int i;
-
- pwgroup = strchr_m(s2,'/');
- if (pwgroup)
- *pwgroup++ = 0;
- if (!pwgroup || !*pwgroup)
- wgroup = lp_workgroup();
- else
- wgroup = pwgroup;
-
- addr = *interpret_addr2(s2);
+ char *s;
+ const char *ptr;
+ static time_t last_time = 0;
+ pstring s2;
+ struct in_addr addr;
+ char *comment;
+ int stype = lp_default_server_announce();
+
+ if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL)))
+ return;
+
+ last_time = t;
+
+ s = lp_remote_announce();
+ if (!*s)
+ return;
+
+ comment = string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH);
+
+ for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); ) {
+ /* The entries are of the form a.b.c.d/WORKGROUP with
+ WORKGROUP being optional */
+ const char *wgroup;
+ char *pwgroup;
+ int i;
+
+ pwgroup = strchr_m(s2,'/');
+ if (pwgroup)
+ *pwgroup++ = 0;
+ if (!pwgroup || !*pwgroup)
+ wgroup = lp_workgroup();
+ else
+ wgroup = pwgroup;
+
+ addr = *interpret_addr2(s2);
- /* Announce all our names including aliases */
- /* Give the ip address as the address of our first
- broadcast subnet. */
-
- for(i=0; my_netbios_names(i); i++)
- {
- const char *name = my_netbios_names(i);
-
- DEBUG(5,("announce_remote: Doing remote announce for server %s to IP %s.\n",
- name, inet_ntoa(addr) ));
-
- send_announcement(FIRST_SUBNET, ANN_HostAnnouncement,
- name, /* From nbt name. */
- wgroup, 0x1d, /* To nbt name. */
- addr, /* To ip. */
- REMOTE_ANNOUNCE_INTERVAL, /* Time until next announce. */
- name, /* Name to announce. */
- stype, /* Type field. */
- comment);
- }
- }
+ /* Announce all our names including aliases */
+ /* Give the ip address as the address of our first
+ broadcast subnet. */
+
+ for(i=0; my_netbios_names(i); i++) {
+ const char *name = my_netbios_names(i);
+
+ DEBUG(5,("announce_remote: Doing remote announce for server %s to IP %s.\n",
+ name, inet_ntoa(addr) ));
+
+ send_announcement(FIRST_SUBNET, ANN_HostAnnouncement,
+ name, /* From nbt name. */
+ wgroup, 0x1d, /* To nbt name. */
+ addr, /* To ip. */
+ REMOTE_ANNOUNCE_INTERVAL, /* Time until next announce. */
+ name, /* Name to announce. */
+ stype, /* Type field. */
+ comment);
+ }
+ }
}
/****************************************************************************
Implement the 'remote browse sync' feature Andrew added.
These are used to put our browse lists into remote browse lists.
- **************************************************************************/
+**************************************************************************/
void browse_sync_remote(time_t t)
{
- char *s;
- const char *ptr;
- static time_t last_time = 0;
- pstring s2;
- struct in_addr addr;
- struct work_record *work;
- pstring outbuf;
- char *p;
- fstring myname;
+ char *s;
+ const char *ptr;
+ static time_t last_time = 0;
+ pstring s2;
+ struct in_addr addr;
+ struct work_record *work;
+ pstring outbuf;
+ char *p;
+ fstring myname;
- if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL)))
- return;
+ if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL)))
+ return;
- last_time = t;
-
- s = lp_remote_browse_sync();
- if (!*s)
- return;
-
- /*
- * We only do this if we are the local master browser
- * for our workgroup on the firsst subnet.
- */
-
- if((work = find_workgroup_on_subnet(FIRST_SUBNET, lp_workgroup())) == NULL)
- {
- DEBUG(0,("browse_sync_remote: Cannot find workgroup %s on subnet %s\n",
- lp_workgroup(), FIRST_SUBNET->subnet_name ));
- return;
- }
+ last_time = t;
+
+ s = lp_remote_browse_sync();
+ if (!*s)
+ return;
+
+ /*
+ * We only do this if we are the local master browser
+ * for our workgroup on the firsst subnet.
+ */
+
+ if((work = find_workgroup_on_subnet(FIRST_SUBNET, lp_workgroup())) == NULL) {
+ DEBUG(0,("browse_sync_remote: Cannot find workgroup %s on subnet %s\n",
+ lp_workgroup(), FIRST_SUBNET->subnet_name ));
+ return;
+ }
- if(!AM_LOCAL_MASTER_BROWSER(work))
- {
- DEBUG(5,("browse_sync_remote: We can only do this if we are a local master browser \
+ if(!AM_LOCAL_MASTER_BROWSER(work)) {
+ DEBUG(5,("browse_sync_remote: We can only do this if we are a local master browser \
for workgroup %s on subnet %s.\n", lp_workgroup(), FIRST_SUBNET->subnet_name ));
- return;
- }
+ return;
+ }
- memset(outbuf,'\0',sizeof(outbuf));
- p = outbuf;
- SCVAL(p,0,ANN_MasterAnnouncement);
- p++;
+ memset(outbuf,'\0',sizeof(outbuf));
+ p = outbuf;
+ SCVAL(p,0,ANN_MasterAnnouncement);
+ p++;
- fstrcpy(myname, global_myname());
- strupper_m(myname);
- myname[15]='\0';
- push_pstring_base(p, myname, outbuf);
+ fstrcpy(myname, global_myname());
+ strupper_m(myname);
+ myname[15]='\0';
+ push_pstring_base(p, myname, outbuf);
- p = skip_string(p,1);
+ p = skip_string(p,1);
- for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); )
- {
- /* The entries are of the form a.b.c.d */
- addr = *interpret_addr2(s2);
+ for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); ) {
+ /* The entries are of the form a.b.c.d */
+ addr = *interpret_addr2(s2);
- DEBUG(5,("announce_remote: Doing remote browse sync announce for server %s to IP %s.\n",
- global_myname(), inet_ntoa(addr) ));
+ DEBUG(5,("announce_remote: Doing remote browse sync announce for server %s to IP %s.\n",
+ global_myname(), inet_ntoa(addr) ));
- send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
- global_myname(), 0x0, "*", 0x0, addr, FIRST_SUBNET->myip, DGRAM_PORT);
- }
+ send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
+ global_myname(), 0x0, "*", 0x0, addr, FIRST_SUBNET->myip, DGRAM_PORT);
+ }
}
diff --git a/source3/nmbd/nmbd_serverlistdb.c b/source3/nmbd/nmbd_serverlistdb.c
index 2484a7f830..b4c6e2902d 100644
--- a/source3/nmbd/nmbd_serverlistdb.c
+++ b/source3/nmbd/nmbd_serverlistdb.c
@@ -33,28 +33,26 @@ int updatecount = 0;
void remove_all_servers(struct work_record *work)
{
- struct server_record *servrec;
- struct server_record *nexts;
+ struct server_record *servrec;
+ struct server_record *nexts;
- for (servrec = work->serverlist; servrec; servrec = nexts)
- {
- DEBUG(7,("remove_all_servers: Removing server %s\n",servrec->serv.name));
- nexts = servrec->next;
+ for (servrec = work->serverlist; servrec; servrec = nexts) {
+ DEBUG(7,("remove_all_servers: Removing server %s\n",servrec->serv.name));
+ nexts = servrec->next;
- if (servrec->prev)
- servrec->prev->next = servrec->next;
- if (servrec->next)
- servrec->next->prev = servrec->prev;
+ if (servrec->prev)
+ servrec->prev->next = servrec->next;
+ if (servrec->next)
+ servrec->next->prev = servrec->prev;
- if (work->serverlist == servrec)
- work->serverlist = servrec->next;
+ if (work->serverlist == servrec)
+ work->serverlist = servrec->next;
- ZERO_STRUCTP(servrec);
- SAFE_FREE(servrec);
+ ZERO_STRUCTP(servrec);
+ SAFE_FREE(servrec);
+ }
- }
-
- work->subnet->work_changed = True;
+ work->subnet->work_changed = True;
}
/***************************************************************************
@@ -64,23 +62,22 @@ void remove_all_servers(struct work_record *work)
static void add_server_to_workgroup(struct work_record *work,
struct server_record *servrec)
{
- struct server_record *servrec2;
-
- if (!work->serverlist)
- {
- work->serverlist = servrec;
- servrec->prev = NULL;
- servrec->next = NULL;
- return;
- }
-
- for (servrec2 = work->serverlist; servrec2->next; servrec2 = servrec2->next)
- ;
-
- servrec2->next = servrec;
- servrec->next = NULL;
- servrec->prev = servrec2;
- work->subnet->work_changed = True;
+ struct server_record *servrec2;
+
+ if (!work->serverlist) {
+ work->serverlist = servrec;
+ servrec->prev = NULL;
+ servrec->next = NULL;
+ return;
+ }
+
+ for (servrec2 = work->serverlist; servrec2->next; servrec2 = servrec2->next)
+ ;
+
+ servrec2->next = servrec;
+ servrec->next = NULL;
+ servrec->prev = servrec2;
+ work->subnet->work_changed = True;
}
/****************************************************************************
@@ -89,14 +86,13 @@ static void add_server_to_workgroup(struct work_record *work,
struct server_record *find_server_in_workgroup(struct work_record *work, const char *name)
{
- struct server_record *ret;
+ struct server_record *ret;
- for (ret = work->serverlist; ret; ret = ret->next)
- {
- if (strequal(ret->serv.name,name))
- return ret;
- }
- return NULL;
+ for (ret = work->serverlist; ret; ret = ret->next) {
+ if (strequal(ret->serv.name,name))
+ return ret;
+ }
+ return NULL;
}
@@ -106,17 +102,17 @@ struct server_record *find_server_in_workgroup(struct work_record *work, const c
void remove_server_from_workgroup(struct work_record *work, struct server_record *servrec)
{
- if (servrec->prev)
- servrec->prev->next = servrec->next;
- if (servrec->next)
- servrec->next->prev = servrec->prev;
+ if (servrec->prev)
+ servrec->prev->next = servrec->next;
+ if (servrec->next)
+ servrec->next->prev = servrec->prev;
- if (work->serverlist == servrec)
- work->serverlist = servrec->next;
+ if (work->serverlist == servrec)
+ work->serverlist = servrec->next;
- ZERO_STRUCTP(servrec);
- SAFE_FREE(servrec);
- work->subnet->work_changed = True;
+ ZERO_STRUCTP(servrec);
+ SAFE_FREE(servrec);
+ work->subnet->work_changed = True;
}
/****************************************************************************
@@ -127,47 +123,44 @@ struct server_record *create_server_on_workgroup(struct work_record *work,
const char *name,int servertype,
int ttl, const char *comment)
{
- struct server_record *servrec;
+ struct server_record *servrec;
- if (name[0] == '*')
- {
- DEBUG(7,("create_server_on_workgroup: not adding name starting with '*' (%s)\n",
- name));
- return (NULL);
- }
+ if (name[0] == '*') {
+ DEBUG(7,("create_server_on_workgroup: not adding name starting with '*' (%s)\n",
+ name));
+ return (NULL);
+ }
- if((servrec = find_server_in_workgroup(work, name)) != NULL)
- {
- DEBUG(0,("create_server_on_workgroup: Server %s already exists on \
+ if((servrec = find_server_in_workgroup(work, name)) != NULL) {
+ DEBUG(0,("create_server_on_workgroup: Server %s already exists on \
workgroup %s. This is a bug.\n", name, work->work_group));
- return NULL;
- }
+ return NULL;
+ }
- if((servrec = (struct server_record *)malloc(sizeof(*servrec))) == NULL)
- {
- DEBUG(0,("create_server_entry_on_workgroup: malloc fail !\n"));
- return NULL;
- }
+ if((servrec = (struct server_record *)malloc(sizeof(*servrec))) == NULL) {
+ DEBUG(0,("create_server_entry_on_workgroup: malloc fail !\n"));
+ return NULL;
+ }
- memset((char *)servrec,'\0',sizeof(*servrec));
+ memset((char *)servrec,'\0',sizeof(*servrec));
- servrec->subnet = work->subnet;
+ servrec->subnet = work->subnet;
- fstrcpy(servrec->serv.name,name);
- fstrcpy(servrec->serv.comment,comment);
- strupper_m(servrec->serv.name);
- servrec->serv.type = servertype;
+ fstrcpy(servrec->serv.name,name);
+ fstrcpy(servrec->serv.comment,comment);
+ strupper_m(servrec->serv.name);
+ servrec->serv.type = servertype;
- update_server_ttl(servrec, ttl);
+ update_server_ttl(servrec, ttl);
- add_server_to_workgroup(work, servrec);
+ add_server_to_workgroup(work, servrec);
- DEBUG(3,("create_server_on_workgroup: Created server entry %s of type %x (%s) on \
+ DEBUG(3,("create_server_on_workgroup: Created server entry %s of type %x (%s) on \
workgroup %s.\n", name,servertype,comment, work->work_group));
- work->subnet->work_changed = True;
+ work->subnet->work_changed = True;
- return(servrec);
+ return(servrec);
}
/*******************************************************************
@@ -176,15 +169,15 @@ workgroup %s.\n", name,servertype,comment, work->work_group));
void update_server_ttl(struct server_record *servrec, int ttl)
{
- if(ttl > lp_max_ttl())
- ttl = lp_max_ttl();
+ if(ttl > lp_max_ttl())
+ ttl = lp_max_ttl();
- if(is_myname(servrec->serv.name))
- servrec->death_time = PERMANENT_TTL;
- else
- servrec->death_time = (ttl != PERMANENT_TTL) ? time(NULL)+(ttl*3) : PERMANENT_TTL;
+ if(is_myname(servrec->serv.name))
+ servrec->death_time = PERMANENT_TTL;
+ else
+ servrec->death_time = (ttl != PERMANENT_TTL) ? time(NULL)+(ttl*3) : PERMANENT_TTL;
- servrec->subnet->work_changed = True;
+ servrec->subnet->work_changed = True;
}
/*******************************************************************
@@ -195,20 +188,18 @@ void update_server_ttl(struct server_record *servrec, int ttl)
void expire_servers(struct work_record *work, time_t t)
{
- struct server_record *servrec;
- struct server_record *nexts;
+ struct server_record *servrec;
+ struct server_record *nexts;
- for (servrec = work->serverlist; servrec; servrec = nexts)
- {
- nexts = servrec->next;
-
- if ((servrec->death_time != PERMANENT_TTL) && ((t == -1) || (servrec->death_time < t)))
- {
- DEBUG(3,("expire_old_servers: Removing timed out server %s\n",servrec->serv.name));
- remove_server_from_workgroup(work, servrec);
- work->subnet->work_changed = True;
- }
- }
+ for (servrec = work->serverlist; servrec; servrec = nexts) {
+ nexts = servrec->next;
+
+ if ((servrec->death_time != PERMANENT_TTL) && ((t == -1) || (servrec->death_time < t))) {
+ DEBUG(3,("expire_old_servers: Removing timed out server %s\n",servrec->serv.name));
+ remove_server_from_workgroup(work, servrec);
+ work->subnet->work_changed = True;
+ }
+ }
}
/*******************************************************************
@@ -221,33 +212,30 @@ static uint32 write_this_server_name( struct subnet_record *subrec,
struct work_record *work,
struct server_record *servrec)
{
- struct subnet_record *ssub;
- struct work_record *iwork;
-
- /* Go through all the subnets we have already seen. */
- for (ssub = FIRST_SUBNET; ssub != subrec; ssub = NEXT_SUBNET_INCLUDING_UNICAST(ssub))
- {
- for(iwork = ssub->workgrouplist; iwork; iwork = iwork->next)
- {
- if(find_server_in_workgroup( iwork, servrec->serv.name) != NULL)
- {
- /*
- * We have already written out this server record, don't
- * do it again. This gives precedence to servers we have seen
- * on the broadcast subnets over servers that may have been
- * added via a sync on the unicast_subet.
- *
- * The correct way to do this is to have a serverlist file
- * per subnet - this means changes to smbd as well. I may
- * add this at a later date (JRA).
- */
-
- return 0;
- }
- }
- }
-
- return servrec->serv.type;
+ struct subnet_record *ssub;
+ struct work_record *iwork;
+
+ /* Go through all the subnets we have already seen. */
+ for (ssub = FIRST_SUBNET; ssub != subrec; ssub = NEXT_SUBNET_INCLUDING_UNICAST(ssub)) {
+ for(iwork = ssub->workgrouplist; iwork; iwork = iwork->next) {
+ if(find_server_in_workgroup( iwork, servrec->serv.name) != NULL) {
+ /*
+ * We have already written out this server record, don't
+ * do it again. This gives precedence to servers we have seen
+ * on the broadcast subnets over servers that may have been
+ * added via a sync on the unicast_subet.
+ *
+ * The correct way to do this is to have a serverlist file
+ * per subnet - this means changes to smbd as well. I may
+ * add this at a later date (JRA).
+ */
+
+ return 0;
+ }
+ }
+ }
+
+ return servrec->serv.type;
}
/*******************************************************************
@@ -261,30 +249,29 @@ static uint32 write_this_server_name( struct subnet_record *subrec,
static uint32 write_this_workgroup_name( struct subnet_record *subrec,
struct work_record *work)
{
- struct subnet_record *ssub;
+ struct subnet_record *ssub;
- if(strequal(lp_workgroup(), work->work_group))
- return 0;
+ if(strequal(lp_workgroup(), work->work_group))
+ return 0;
- /* This is a workgroup we have seen on a broadcast subnet. All
- these have the same type. */
+ /* This is a workgroup we have seen on a broadcast subnet. All
+ these have the same type. */
- if(subrec != unicast_subnet)
- return (SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT|SV_TYPE_LOCAL_LIST_ONLY);
+ if(subrec != unicast_subnet)
+ return (SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT|SV_TYPE_LOCAL_LIST_ONLY);
- for(ssub = FIRST_SUBNET; ssub; ssub = NEXT_SUBNET_EXCLUDING_UNICAST(ssub))
- {
- /* This is the unicast subnet so check if we've already written out
- this subnet when we passed over the broadcast subnets. */
+ for(ssub = FIRST_SUBNET; ssub; ssub = NEXT_SUBNET_EXCLUDING_UNICAST(ssub)) {
+ /* This is the unicast subnet so check if we've already written out
+ this subnet when we passed over the broadcast subnets. */
- if(find_workgroup_on_subnet( ssub, work->work_group) != NULL)
- return 0;
- }
+ if(find_workgroup_on_subnet( ssub, work->work_group) != NULL)
+ return 0;
+ }
- /* All workgroups on the unicast subnet (except our own, which we
- have already written out) cannot be local. */
+ /* All workgroups on the unicast subnet (except our own, which we
+ have already written out) cannot be local. */
- return (SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT);
+ return (SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT);
}
/*******************************************************************
@@ -306,143 +293,130 @@ void write_browse_list_entry(XFILE *fp, const char *name, uint32 rec_type,
void write_browse_list(time_t t, BOOL force_write)
{
- struct subnet_record *subrec;
- struct work_record *work;
- struct server_record *servrec;
- pstring fname,fnamenew;
- uint32 stype;
- int i;
- XFILE *fp;
- BOOL list_changed = force_write;
- static time_t lasttime = 0;
+ struct subnet_record *subrec;
+ struct work_record *work;
+ struct server_record *servrec;
+ pstring fname,fnamenew;
+ uint32 stype;
+ int i;
+ XFILE *fp;
+ BOOL list_changed = force_write;
+ static time_t lasttime = 0;
- /* Always dump if we're being told to by a signal. */
- if(force_write == False)
- {
- if (!lasttime)
- lasttime = t;
- if (t - lasttime < 5)
- return;
- }
-
- lasttime = t;
-
- dump_workgroups(force_write);
+ /* Always dump if we're being told to by a signal. */
+ if(force_write == False) {
+ if (!lasttime)
+ lasttime = t;
+ if (t - lasttime < 5)
+ return;
+ }
+
+ lasttime = t;
+
+ dump_workgroups(force_write);
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
- {
- if(subrec->work_changed)
- {
- list_changed = True;
- break;
- }
- }
-
- if(!list_changed)
- return;
-
- updatecount++;
+ for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) {
+ if(subrec->work_changed) {
+ list_changed = True;
+ break;
+ }
+ }
+
+ if(!list_changed)
+ return;
+
+ updatecount++;
- pstrcpy(fname,lp_lockdir());
- trim_string(fname,NULL,"/");
- pstrcat(fname,"/");
- pstrcat(fname,SERVER_LIST);
- pstrcpy(fnamenew,fname);
- pstrcat(fnamenew,".");
+ pstrcpy(fname,lp_lockdir());
+ trim_string(fname,NULL,"/");
+ pstrcat(fname,"/");
+ pstrcat(fname,SERVER_LIST);
+ pstrcpy(fnamenew,fname);
+ pstrcat(fnamenew,".");
- fp = x_fopen(fnamenew,O_WRONLY|O_CREAT|O_TRUNC, 0644);
+ fp = x_fopen(fnamenew,O_WRONLY|O_CREAT|O_TRUNC, 0644);
- if (!fp)
- {
- DEBUG(0,("write_browse_list: Can't open file %s. Error was %s\n",
- fnamenew,strerror(errno)));
- return;
- }
+ if (!fp) {
+ DEBUG(0,("write_browse_list: Can't open file %s. Error was %s\n",
+ fnamenew,strerror(errno)));
+ return;
+ }
- /*
- * Write out a record for our workgroup. Use the record from the first
- * subnet.
- */
-
- if((work = find_workgroup_on_subnet(FIRST_SUBNET, lp_workgroup())) == NULL)
- {
- DEBUG(0,("write_browse_list: Fatal error - cannot find my workgroup %s\n",
- lp_workgroup()));
- x_fclose(fp);
- return;
- }
-
- write_browse_list_entry(fp, work->work_group,
- SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT|SV_TYPE_LOCAL_LIST_ONLY,
- work->local_master_browser_name, work->work_group);
-
- /*
- * We need to do something special for our own names.
- * This is due to the fact that we may be a local master browser on
- * one of our broadcast subnets, and a domain master on the unicast
- * subnet. We iterate over the subnets and only write out the name
- * once.
- */
-
- for (i=0; my_netbios_names(i); i++)
- {
- stype = 0;
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
- {
- if((work = find_workgroup_on_subnet( subrec, lp_workgroup() )) == NULL)
- continue;
- if((servrec = find_server_in_workgroup( work, my_netbios_names(i))) == NULL)
- continue;
-
- stype |= servrec->serv.type;
- }
-
- /* Output server details, plus what workgroup they're in. */
- write_browse_list_entry(fp, my_netbios_names(i), stype,
- string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH), lp_workgroup());
- }
+ /*
+ * Write out a record for our workgroup. Use the record from the first
+ * subnet.
+ */
+
+ if((work = find_workgroup_on_subnet(FIRST_SUBNET, lp_workgroup())) == NULL) {
+ DEBUG(0,("write_browse_list: Fatal error - cannot find my workgroup %s\n",
+ lp_workgroup()));
+ x_fclose(fp);
+ return;
+ }
+
+ write_browse_list_entry(fp, work->work_group,
+ SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT|SV_TYPE_LOCAL_LIST_ONLY,
+ work->local_master_browser_name, work->work_group);
+
+ /*
+ * We need to do something special for our own names.
+ * This is due to the fact that we may be a local master browser on
+ * one of our broadcast subnets, and a domain master on the unicast
+ * subnet. We iterate over the subnets and only write out the name
+ * once.
+ */
+
+ for (i=0; my_netbios_names(i); i++) {
+ stype = 0;
+ for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) {
+ if((work = find_workgroup_on_subnet( subrec, lp_workgroup() )) == NULL)
+ continue;
+ if((servrec = find_server_in_workgroup( work, my_netbios_names(i))) == NULL)
+ continue;
+
+ stype |= servrec->serv.type;
+ }
+
+ /* Output server details, plus what workgroup they're in. */
+ write_browse_list_entry(fp, my_netbios_names(i), stype,
+ string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH), lp_workgroup());
+ }
- for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
- {
- subrec->work_changed = False;
-
- for (work = subrec->workgrouplist; work ; work = work->next)
- {
- /* Write out a workgroup record for a workgroup. */
- uint32 wg_type = write_this_workgroup_name( subrec, work);
-
- if(wg_type)
- {
- write_browse_list_entry(fp, work->work_group, wg_type,
- work->local_master_browser_name,
- work->work_group);
- }
-
- /* Now write out any server records a workgroup may have. */
-
- for (servrec = work->serverlist; servrec ; servrec = servrec->next)
- {
- uint32 serv_type;
-
- /* We have already written our names here. */
- if(is_myname(servrec->serv.name))
- continue;
-
- serv_type = write_this_server_name(subrec, work, servrec);
-
- if(serv_type)
- {
- /* Output server details, plus what workgroup they're in. */
- write_browse_list_entry(fp, servrec->serv.name, serv_type,
- servrec->serv.comment, work->work_group);
- }
- }
- }
- }
+ for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) {
+ subrec->work_changed = False;
+
+ for (work = subrec->workgrouplist; work ; work = work->next) {
+ /* Write out a workgroup record for a workgroup. */
+ uint32 wg_type = write_this_workgroup_name( subrec, work);
+
+ if(wg_type) {
+ write_browse_list_entry(fp, work->work_group, wg_type,
+ work->local_master_browser_name,
+ work->work_group);
+ }
+
+ /* Now write out any server records a workgroup may have. */
+
+ for (servrec = work->serverlist; servrec ; servrec = servrec->next) {
+ uint32 serv_type;
+
+ /* We have already written our names here. */
+ if(is_myname(servrec->serv.name))
+ continue;
+
+ serv_type = write_this_server_name(subrec, work, servrec);
+ if(serv_type) {
+ /* Output server details, plus what workgroup they're in. */
+ write_browse_list_entry(fp, servrec->serv.name, serv_type,
+ servrec->serv.comment, work->work_group);
+ }
+ }
+ }
+ }
- x_fclose(fp);
- unlink(fname);
- chmod(fnamenew,0644);
- rename(fnamenew,fname);
- DEBUG(3,("write_browse_list: Wrote browse list into file %s\n",fname));
+ x_fclose(fp);
+ unlink(fname);
+ chmod(fnamenew,0644);
+ rename(fnamenew,fname);
+ DEBUG(3,("write_browse_list: Wrote browse list into file %s\n",fname));
}
diff --git a/source3/nmbd/nmbd_subnetdb.c b/source3/nmbd/nmbd_subnetdb.c
index 6296826425..02a91f2760 100644
--- a/source3/nmbd/nmbd_subnetdb.c
+++ b/source3/nmbd/nmbd_subnetdb.c
@@ -63,28 +63,27 @@ static void add_subnet(struct subnet_record *subrec)
* ************************************************************************** **
*/
static int namelist_entry_compare( ubi_trItemPtr Item, ubi_trNodePtr Node )
- {
- struct name_record *NR = (struct name_record *)Node;
-
- if( DEBUGLVL( 10 ) )
- {
- struct nmb_name *Iname = (struct nmb_name *)Item;
+{
+ struct name_record *NR = (struct name_record *)Node;
- Debug1( "nmbd_subnetdb:namelist_entry_compare()\n" );
- Debug1( "%d == memcmp( \"%s\", \"%s\", %d )\n",
- memcmp( Item, &(NR->name), sizeof(struct nmb_name) ),
- nmb_namestr(Iname), nmb_namestr(&NR->name), (int)sizeof(struct nmb_name) );
- }
+ if( DEBUGLVL( 10 ) ) {
+ struct nmb_name *Iname = (struct nmb_name *)Item;
- return( memcmp( Item, &(NR->name), sizeof(struct nmb_name) ) );
- } /* namelist_entry_compare */
+ Debug1( "nmbd_subnetdb:namelist_entry_compare()\n" );
+ Debug1( "%d == memcmp( \"%s\", \"%s\", %d )\n",
+ memcmp( Item, &(NR->name), sizeof(struct nmb_name) ),
+ nmb_namestr(Iname), nmb_namestr(&NR->name), (int)sizeof(struct nmb_name) );
+ }
+ return( memcmp( Item, &(NR->name), sizeof(struct nmb_name) ) );
+}
/****************************************************************************
stop listening on a subnet
we don't free the record as we don't have proper reference counting for it
yet and it may be in use by a response record
****************************************************************************/
+
void close_subnet(struct subnet_record *subrec)
{
DLIST_REMOVE(subnetlist, subrec);
@@ -99,8 +98,6 @@ void close_subnet(struct subnet_record *subrec)
}
}
-
-
/****************************************************************************
Create a subnet entry.
****************************************************************************/
@@ -109,102 +106,90 @@ static struct subnet_record *make_subnet(const char *name, enum subnet_type type
struct in_addr myip, struct in_addr bcast_ip,
struct in_addr mask_ip)
{
- struct subnet_record *subrec = NULL;
- int nmb_sock, dgram_sock;
-
- /* Check if we are creating a non broadcast subnet - if so don't create
- sockets.
- */
-
- if(type != NORMAL_SUBNET)
- {
- nmb_sock = -1;
- dgram_sock = -1;
- }
- else
- {
- /*
- * Attempt to open the sockets on port 137/138 for this interface
- * and bind them.
- * Fail the subnet creation if this fails.
- */
-
- if((nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,0, myip.s_addr,True)) == -1)
- {
- if( DEBUGLVL( 0 ) )
- {
- Debug1( "nmbd_subnetdb:make_subnet()\n" );
- Debug1( " Failed to open nmb socket on interface %s ", inet_ntoa(myip) );
- Debug1( "for port %d. ", global_nmb_port );
- Debug1( "Error was %s\n", strerror(errno) );
- }
- return NULL;
- }
-
- if((dgram_sock = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3, myip.s_addr,True)) == -1)
- {
- if( DEBUGLVL( 0 ) )
- {
- Debug1( "nmbd_subnetdb:make_subnet()\n" );
- Debug1( " Failed to open dgram socket on interface %s ", inet_ntoa(myip) );
- Debug1( "for port %d. ", DGRAM_PORT );
- Debug1( "Error was %s\n", strerror(errno) );
- }
- return NULL;
- }
-
- /* Make sure we can broadcast from these sockets. */
- set_socket_options(nmb_sock,"SO_BROADCAST");
- set_socket_options(dgram_sock,"SO_BROADCAST");
-
- }
-
- subrec = (struct subnet_record *)malloc(sizeof(*subrec));
-
- if (!subrec)
- {
- DEBUG(0,("make_subnet: malloc fail !\n"));
- close(nmb_sock);
- close(dgram_sock);
- return(NULL);
- }
+ struct subnet_record *subrec = NULL;
+ int nmb_sock, dgram_sock;
+
+ /* Check if we are creating a non broadcast subnet - if so don't create
+ sockets. */
+
+ if(type != NORMAL_SUBNET) {
+ nmb_sock = -1;
+ dgram_sock = -1;
+ } else {
+ /*
+ * Attempt to open the sockets on port 137/138 for this interface
+ * and bind them.
+ * Fail the subnet creation if this fails.
+ */
+
+ if((nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,0, myip.s_addr,True)) == -1) {
+ if( DEBUGLVL( 0 ) ) {
+ Debug1( "nmbd_subnetdb:make_subnet()\n" );
+ Debug1( " Failed to open nmb socket on interface %s ", inet_ntoa(myip) );
+ Debug1( "for port %d. ", global_nmb_port );
+ Debug1( "Error was %s\n", strerror(errno) );
+ }
+ return NULL;
+ }
+
+ if((dgram_sock = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3, myip.s_addr,True)) == -1) {
+ if( DEBUGLVL( 0 ) ) {
+ Debug1( "nmbd_subnetdb:make_subnet()\n" );
+ Debug1( " Failed to open dgram socket on interface %s ", inet_ntoa(myip) );
+ Debug1( "for port %d. ", DGRAM_PORT );
+ Debug1( "Error was %s\n", strerror(errno) );
+ }
+ return NULL;
+ }
+
+ /* Make sure we can broadcast from these sockets. */
+ set_socket_options(nmb_sock,"SO_BROADCAST");
+ set_socket_options(dgram_sock,"SO_BROADCAST");
+ }
+
+ subrec = (struct subnet_record *)malloc(sizeof(*subrec));
+ if (!subrec) {
+ DEBUG(0,("make_subnet: malloc fail !\n"));
+ close(nmb_sock);
+ close(dgram_sock);
+ return(NULL);
+ }
- memset( (char *)subrec, '\0', sizeof(*subrec) );
- (void)ubi_trInitTree( subrec->namelist,
- namelist_entry_compare,
- ubi_trOVERWRITE );
-
- if((subrec->subnet_name = strdup(name)) == NULL)
- {
- DEBUG(0,("make_subnet: malloc fail for subnet name !\n"));
- close(nmb_sock);
- close(dgram_sock);
- ZERO_STRUCTP(subrec);
- SAFE_FREE(subrec);
- return(NULL);
- }
-
- DEBUG(2, ("making subnet name:%s ", name ));
- DEBUG(2, ("Broadcast address:%s ", inet_ntoa(bcast_ip)));
- DEBUG(2, ("Subnet mask:%s\n", inet_ntoa(mask_ip)));
+ memset( (char *)subrec, '\0', sizeof(*subrec) );
+ (void)ubi_trInitTree( subrec->namelist,
+ namelist_entry_compare,
+ ubi_trOVERWRITE );
+
+ if((subrec->subnet_name = strdup(name)) == NULL) {
+ DEBUG(0,("make_subnet: malloc fail for subnet name !\n"));
+ close(nmb_sock);
+ close(dgram_sock);
+ ZERO_STRUCTP(subrec);
+ SAFE_FREE(subrec);
+ return(NULL);
+ }
+
+ DEBUG(2, ("making subnet name:%s ", name ));
+ DEBUG(2, ("Broadcast address:%s ", inet_ntoa(bcast_ip)));
+ DEBUG(2, ("Subnet mask:%s\n", inet_ntoa(mask_ip)));
- subrec->namelist_changed = False;
- subrec->work_changed = False;
+ subrec->namelist_changed = False;
+ subrec->work_changed = False;
- subrec->bcast_ip = bcast_ip;
- subrec->mask_ip = mask_ip;
- subrec->myip = myip;
- subrec->type = type;
- subrec->nmb_sock = nmb_sock;
- subrec->dgram_sock = dgram_sock;
+ subrec->bcast_ip = bcast_ip;
+ subrec->mask_ip = mask_ip;
+ subrec->myip = myip;
+ subrec->type = type;
+ subrec->nmb_sock = nmb_sock;
+ subrec->dgram_sock = dgram_sock;
- return subrec;
+ return subrec;
}
-
/****************************************************************************
Create a normal subnet
**************************************************************************/
+
struct subnet_record *make_normal_subnet(struct interface *iface)
{
struct subnet_record *subrec;
@@ -217,100 +202,99 @@ struct subnet_record *make_normal_subnet(struct interface *iface)
return subrec;
}
-
/****************************************************************************
Create subnet entries.
**************************************************************************/
BOOL create_subnets(void)
{
- int num_interfaces = iface_count();
- int i;
- struct in_addr unicast_ip, ipzero;
- extern struct in_addr loopback_ip;
-
- if(num_interfaces == 0) {
- DEBUG(0,("create_subnets: No local interfaces !\n"));
- DEBUG(0,("create_subnets: Waiting for an interface to appear ...\n"));
- while (iface_count() == 0) {
- sleep(5);
- load_interfaces();
- }
- }
-
- num_interfaces = iface_count();
-
- /*
- * Create subnets from all the local interfaces and thread them onto
- * the linked list.
- */
-
- for (i = 0 ; i < num_interfaces; i++)
- {
- struct interface *iface = get_interface(i);
-
- /*
- * We don't want to add a loopback interface, in case
- * someone has added 127.0.0.1 for smbd, nmbd needs to
- * ignore it here. JRA.
- */
-
- if (ip_equal(iface->ip, loopback_ip)) {
- DEBUG(2,("create_subnets: Ignoring loopback interface.\n" ));
- continue;
- }
-
- if (!make_normal_subnet(iface)) return False;
- }
-
- if (lp_we_are_a_wins_server()) {
- /* Pick the first interface ip address as the WINS server ip. */
- unicast_ip = *iface_n_ip(0);
- } else {
- /* note that we do not set the wins server IP here. We just
- set it at zero and let the wins registration code cope
- with getting the IPs right for each packet */
- zero_ip(&unicast_ip);
- }
-
- /*
- * Create the unicast and remote broadcast subnets.
- * Don't put these onto the linked list.
- * The ip address of the unicast subnet is set to be
- * the WINS server address, if it exists, or ipzero if not.
- */
-
- unicast_subnet = make_subnet( "UNICAST_SUBNET", UNICAST_SUBNET,
- unicast_ip, unicast_ip, unicast_ip);
-
- zero_ip(&ipzero);
-
- remote_broadcast_subnet = make_subnet( "REMOTE_BROADCAST_SUBNET",
- REMOTE_BROADCAST_SUBNET,
- ipzero, ipzero, ipzero);
-
- if((unicast_subnet == NULL) || (remote_broadcast_subnet == NULL))
- return False;
-
- /*
- * If we are WINS server, create the WINS_SERVER_SUBNET - don't put on
- * the linked list.
- */
-
- if (lp_we_are_a_wins_server())
- {
- if( (wins_server_subnet = make_subnet( "WINS_SERVER_SUBNET",
- WINS_SERVER_SUBNET,
- ipzero, ipzero, ipzero )) == NULL )
- return False;
- }
-
- return True;
+ int num_interfaces = iface_count();
+ int i;
+ struct in_addr unicast_ip, ipzero;
+ extern struct in_addr loopback_ip;
+
+ if(num_interfaces == 0) {
+ DEBUG(0,("create_subnets: No local interfaces !\n"));
+ DEBUG(0,("create_subnets: Waiting for an interface to appear ...\n"));
+ while (iface_count() == 0) {
+ sleep(5);
+ load_interfaces();
+ }
+ }
+
+ num_interfaces = iface_count();
+
+ /*
+ * Create subnets from all the local interfaces and thread them onto
+ * the linked list.
+ */
+
+ for (i = 0 ; i < num_interfaces; i++) {
+ struct interface *iface = get_interface(i);
+
+ /*
+ * We don't want to add a loopback interface, in case
+ * someone has added 127.0.0.1 for smbd, nmbd needs to
+ * ignore it here. JRA.
+ */
+
+ if (ip_equal(iface->ip, loopback_ip)) {
+ DEBUG(2,("create_subnets: Ignoring loopback interface.\n" ));
+ continue;
+ }
+
+ if (!make_normal_subnet(iface))
+ return False;
+ }
+
+ if (lp_we_are_a_wins_server()) {
+ /* Pick the first interface ip address as the WINS server ip. */
+ unicast_ip = *iface_n_ip(0);
+ } else {
+ /* note that we do not set the wins server IP here. We just
+ set it at zero and let the wins registration code cope
+ with getting the IPs right for each packet */
+ zero_ip(&unicast_ip);
+ }
+
+ /*
+ * Create the unicast and remote broadcast subnets.
+ * Don't put these onto the linked list.
+ * The ip address of the unicast subnet is set to be
+ * the WINS server address, if it exists, or ipzero if not.
+ */
+
+ unicast_subnet = make_subnet( "UNICAST_SUBNET", UNICAST_SUBNET,
+ unicast_ip, unicast_ip, unicast_ip);
+
+ zero_ip(&ipzero);
+
+ remote_broadcast_subnet = make_subnet( "REMOTE_BROADCAST_SUBNET",
+ REMOTE_BROADCAST_SUBNET,
+ ipzero, ipzero, ipzero);
+
+ if((unicast_subnet == NULL) || (remote_broadcast_subnet == NULL))
+ return False;
+
+ /*
+ * If we are WINS server, create the WINS_SERVER_SUBNET - don't put on
+ * the linked list.
+ */
+
+ if (lp_we_are_a_wins_server()) {
+ if( (wins_server_subnet = make_subnet( "WINS_SERVER_SUBNET",
+ WINS_SERVER_SUBNET,
+ ipzero, ipzero, ipzero )) == NULL )
+ return False;
+ }
+
+ return True;
}
/*******************************************************************
Function to tell us if we can use the unicast subnet.
******************************************************************/
+
BOOL we_are_a_wins_client(void)
{
if (wins_srv_count() > 0) {
@@ -326,12 +310,12 @@ Access function used by NEXT_SUBNET_INCLUDING_UNICAST
struct subnet_record *get_next_subnet_maybe_unicast(struct subnet_record *subrec)
{
- if(subrec == unicast_subnet)
- return NULL;
- else if((subrec->next == NULL) && we_are_a_wins_client())
- return unicast_subnet;
- else
- return subrec->next;
+ if(subrec == unicast_subnet)
+ return NULL;
+ else if((subrec->next == NULL) && we_are_a_wins_client())
+ return unicast_subnet;
+ else
+ return subrec->next;
}
/*******************************************************************
@@ -343,19 +327,18 @@ struct subnet_record *get_next_subnet_maybe_unicast(struct subnet_record *subrec
struct subnet_record *get_next_subnet_maybe_unicast_or_wins_server(struct subnet_record *subrec)
{
- if(subrec == unicast_subnet)
- {
- if(wins_server_subnet)
- return wins_server_subnet;
- else
- return NULL;
- }
-
- if(wins_server_subnet && subrec == wins_server_subnet)
- return NULL;
-
- if((subrec->next == NULL) && we_are_a_wins_client())
- return unicast_subnet;
- else
- return subrec->next;
+ if(subrec == unicast_subnet) {
+ if(wins_server_subnet)
+ return wins_server_subnet;
+ else
+ return NULL;
+ }
+
+ if(wins_server_subnet && subrec == wins_server_subnet)
+ return NULL;
+
+ if((subrec->next == NULL) && we_are_a_wins_client())
+ return unicast_subnet;
+ else
+ return subrec->next;
}
diff --git a/source3/nmbd/nmbd_synclists.c b/source3/nmbd/nmbd_synclists.c
index b9952fb446..337c2f9468 100644
--- a/source3/nmbd/nmbd_synclists.c
+++ b/source3/nmbd/nmbd_synclists.c
@@ -47,6 +47,7 @@ static XFILE *fp;
This is the NetServerEnum callback.
Note sname and comment are in UNIX codepage format.
******************************************************************/
+
static void callback(const char *sname, uint32 stype,
const char *comment, void *state)
{
@@ -58,6 +59,7 @@ static void callback(const char *sname, uint32 stype,
Log in on the remote server's SMB port to their IPC$ service,
do a NetServerEnum and record the results in fname
******************************************************************/
+
static void sync_child(char *name, int nm_type,
char *workgroup,
struct in_addr ip, BOOL local, BOOL servers,
@@ -78,10 +80,9 @@ static void sync_child(char *name, int nm_type,
}
make_nmb_name(&calling, local_machine, 0x0);
- make_nmb_name(&called , name , nm_type);
+ make_nmb_name(&called , name, nm_type);
- if (!cli_session_request(&cli, &calling, &called))
- {
+ if (!cli_session_request(&cli, &calling, &called)) {
cli_shutdown(&cli);
return;
}
@@ -120,12 +121,12 @@ static void sync_child(char *name, int nm_type,
cli_shutdown(&cli);
}
-
/*******************************************************************
initialise a browse sync with another browse server. Log in on the
remote server's SMB port to their IPC$ service, do a NetServerEnum
and record the results
******************************************************************/
+
void sync_browse_lists(struct work_record *work,
char *name, int nm_type,
struct in_addr ip, BOOL local, BOOL servers)
@@ -182,8 +183,9 @@ done:
}
/**********************************************************************
-handle one line from a completed sync file
+ Handle one line from a completed sync file.
**********************************************************************/
+
static void complete_one(struct sync_record *s,
char *sname, uint32 stype, char *comment)
{
@@ -235,10 +237,10 @@ static void complete_one(struct sync_record *s,
create_server_on_workgroup(work, sname,stype, lp_max_ttl(), comment);
}
-
/**********************************************************************
-read the completed sync info
- **********************************************************************/
+ Read the completed sync info.
+**********************************************************************/
+
static void complete_sync(struct sync_record *s)
{
XFILE *f;
@@ -251,11 +253,13 @@ static void complete_sync(struct sync_record *s)
f = x_fopen(s->fname,O_RDONLY, 0);
- if (!f) return;
+ if (!f)
+ return;
while (!x_feof(f)) {
- if (!fgets_slash(line,sizeof(pstring),f)) continue;
+ if (!fgets_slash(line,sizeof(pstring),f))
+ continue;
ptr = line;
@@ -281,8 +285,9 @@ static void complete_sync(struct sync_record *s)
}
/**********************************************************************
-check for completion of any of the child processes
- **********************************************************************/
+ Check for completion of any of the child processes.
+**********************************************************************/
+
void sync_check_completion(void)
{
struct sync_record *s, *next;
diff --git a/source3/nmbd/nmbd_winsproxy.c b/source3/nmbd/nmbd_winsproxy.c
index 2e65ebb612..bace112752 100644
--- a/source3/nmbd/nmbd_winsproxy.c
+++ b/source3/nmbd/nmbd_winsproxy.c
@@ -30,92 +30,85 @@ static void wins_proxy_name_query_request_success( struct subnet_record *subrec,
struct userdata_struct *userdata,
struct nmb_name *nmbname, struct in_addr ip, struct res_rec *rrec)
{
- struct packet_struct *original_packet;
- struct subnet_record *orig_broadcast_subnet;
- struct name_record *namerec;
- uint16 nb_flags;
- int num_ips;
- int i;
- int ttl = 3600; /* By default one hour in the cache. */
- struct in_addr *iplist;
-
- /* Extract the original packet and the original broadcast subnet from
- the userdata. */
-
- memcpy( (char *)&orig_broadcast_subnet, userdata->data, sizeof(struct subnet_record *) );
- memcpy( (char *)&original_packet, &userdata->data[sizeof(struct subnet_record *)],
- sizeof(struct packet_struct *) );
-
- nb_flags = get_nb_flags( rrec->rdata );
-
- num_ips = rrec->rdlength / 6;
- if(num_ips == 0)
- {
- DEBUG(0,("wins_proxy_name_query_request_success: Invalid number of IP records (0) \
+ nstring name;
+ struct packet_struct *original_packet;
+ struct subnet_record *orig_broadcast_subnet;
+ struct name_record *namerec;
+ uint16 nb_flags;
+ int num_ips;
+ int i;
+ int ttl = 3600; /* By default one hour in the cache. */
+ struct in_addr *iplist;
+
+ /* Extract the original packet and the original broadcast subnet from
+ the userdata. */
+
+ memcpy( (char *)&orig_broadcast_subnet, userdata->data, sizeof(struct subnet_record *) );
+ memcpy( (char *)&original_packet, &userdata->data[sizeof(struct subnet_record *)],
+ sizeof(struct packet_struct *) );
+
+ nb_flags = get_nb_flags( rrec->rdata );
+
+ num_ips = rrec->rdlength / 6;
+ if(num_ips == 0) {
+ DEBUG(0,("wins_proxy_name_query_request_success: Invalid number of IP records (0) \
returned for name %s.\n", nmb_namestr(nmbname) ));
- return;
- }
-
- if(num_ips == 1)
- iplist = &ip;
- else
- {
- if((iplist = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr) )) == NULL)
- {
- DEBUG(0,("wins_proxy_name_query_request_success: malloc fail !\n"));
- return;
- }
-
- for(i = 0; i < num_ips; i++)
- putip( (char *)&iplist[i], (char *)&rrec->rdata[ (i*6) + 2]);
- }
-
- /* Add the queried name to the original subnet as a WINS_PROXY_NAME. */
-
- if(rrec == PERMANENT_TTL)
- ttl = lp_max_ttl();
-
- namerec = add_name_to_subnet( orig_broadcast_subnet, nmbname->name,
- nmbname->name_type, nb_flags, ttl,
- WINS_PROXY_NAME, num_ips, iplist );
-
- if(iplist != &ip)
- SAFE_FREE(iplist);
-
- /*
- * Check that none of the IP addresses we are returning is on the
- * same broadcast subnet as the original requesting packet. If it
- * is then don't reply (although we still need to add the name
- * to the cache) as the actual machine will be replying also
- * and we don't want two replies to a broadcast query.
- */
-
- if(namerec && original_packet->packet.nmb.header.nm_flags.bcast)
- {
- for( i = 0; i < namerec->data.num_ips; i++)
- {
- if( same_net( namerec->data.ip[i],
- orig_broadcast_subnet->myip,
- orig_broadcast_subnet->mask_ip ) )
- {
- DEBUG( 5, ( "wins_proxy_name_query_request_success: name %s is a WINS \
+ return;
+ }
+
+ if(num_ips == 1) {
+ iplist = &ip;
+ } else {
+ if((iplist = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr) )) == NULL) {
+ DEBUG(0,("wins_proxy_name_query_request_success: malloc fail !\n"));
+ return;
+ }
+
+ for(i = 0; i < num_ips; i++)
+ putip( (char *)&iplist[i], (char *)&rrec->rdata[ (i*6) + 2]);
+ }
+
+ /* Add the queried name to the original subnet as a WINS_PROXY_NAME. */
+
+ if(rrec == PERMANENT_TTL)
+ ttl = lp_max_ttl();
+
+ pull_ascii_nstring(name, nmbname->name);
+ namerec = add_name_to_subnet( orig_broadcast_subnet, name,
+ nmbname->name_type, nb_flags, ttl,
+ WINS_PROXY_NAME, num_ips, iplist );
+
+ if(iplist != &ip)
+ SAFE_FREE(iplist);
+
+ /*
+ * Check that none of the IP addresses we are returning is on the
+ * same broadcast subnet as the original requesting packet. If it
+ * is then don't reply (although we still need to add the name
+ * to the cache) as the actual machine will be replying also
+ * and we don't want two replies to a broadcast query.
+ */
+
+ if(namerec && original_packet->packet.nmb.header.nm_flags.bcast) {
+ for( i = 0; i < namerec->data.num_ips; i++) {
+ if( same_net( namerec->data.ip[i], orig_broadcast_subnet->myip,
+ orig_broadcast_subnet->mask_ip ) ) {
+ DEBUG( 5, ( "wins_proxy_name_query_request_success: name %s is a WINS \
proxy name and is also on the same subnet (%s) as the requestor. \
-Not replying.\n",
- nmb_namestr(&namerec->name),
- orig_broadcast_subnet->subnet_name ) );
- return;
- }
- }
- }
-
- /* Finally reply to the original name query. */
- reply_netbios_packet(original_packet, /* Packet to reply to. */
- 0, /* Result code. */
- NMB_QUERY, /* nmbd type code. */
- NMB_NAME_QUERY_OPCODE, /* opcode. */
- ttl, /* ttl. */
- rrec->rdata, /* data to send. */
- rrec->rdlength); /* data length. */
+Not replying.\n", nmb_namestr(&namerec->name), orig_broadcast_subnet->subnet_name ) );
+ return;
+ }
+ }
+ }
+
+ /* Finally reply to the original name query. */
+ reply_netbios_packet(original_packet, /* Packet to reply to. */
+ 0, /* Result code. */
+ NMB_QUERY, /* nmbd type code. */
+ NMB_NAME_QUERY_OPCODE, /* opcode. */
+ ttl, /* ttl. */
+ rrec->rdata, /* data to send. */
+ rrec->rdlength); /* data length. */
}
/****************************************************************************
@@ -126,7 +119,7 @@ static void wins_proxy_name_query_request_fail(struct subnet_record *subrec,
struct response_record *rrec,
struct nmb_name *question_name, int fail_code)
{
- DEBUG(4,("wins_proxy_name_query_request_fail: WINS server returned error code %d for lookup \
+ DEBUG(4,("wins_proxy_name_query_request_fail: WINS server returned error code %d for lookup \
of name %s.\n", fail_code, nmb_namestr(question_name) ));
}
@@ -137,38 +130,35 @@ proxy query returns.
static struct userdata_struct *wins_proxy_userdata_copy_fn(struct userdata_struct *userdata)
{
- struct packet_struct *p, *copy_of_p;
- struct userdata_struct *new_userdata =
- (struct userdata_struct *)malloc( userdata->userdata_len );
+ struct packet_struct *p, *copy_of_p;
+ struct userdata_struct *new_userdata = (struct userdata_struct *)malloc( userdata->userdata_len );
- if(new_userdata == NULL)
- return NULL;
+ if(new_userdata == NULL)
+ return NULL;
- new_userdata->copy_fn = userdata->copy_fn;
- new_userdata->free_fn = userdata->free_fn;
- new_userdata->userdata_len = userdata->userdata_len;
+ new_userdata->copy_fn = userdata->copy_fn;
+ new_userdata->free_fn = userdata->free_fn;
+ new_userdata->userdata_len = userdata->userdata_len;
- /* Copy the subnet_record pointer. */
- memcpy( new_userdata->data, userdata->data, sizeof(struct subnet_record *) );
+ /* Copy the subnet_record pointer. */
+ memcpy( new_userdata->data, userdata->data, sizeof(struct subnet_record *) );
- /* Extract the pointer to the packet struct */
- memcpy((char *)&p, &userdata->data[sizeof(struct subnet_record *)],
- sizeof(struct packet_struct *) );
+ /* Extract the pointer to the packet struct */
+ memcpy((char *)&p, &userdata->data[sizeof(struct subnet_record *)], sizeof(struct packet_struct *) );
- /* Do a deep copy of the packet. */
- if((copy_of_p = copy_packet(p)) == NULL)
- {
- SAFE_FREE(new_userdata);
- return NULL;
- }
+ /* Do a deep copy of the packet. */
+ if((copy_of_p = copy_packet(p)) == NULL) {
+ SAFE_FREE(new_userdata);
+ return NULL;
+ }
- /* Lock the copy. */
- copy_of_p->locked = True;
+ /* Lock the copy. */
+ copy_of_p->locked = True;
- memcpy( &new_userdata->data[sizeof(struct subnet_record *)], (char *)&copy_of_p,
- sizeof(struct packet_struct *) );
+ memcpy( &new_userdata->data[sizeof(struct subnet_record *)], (char *)&copy_of_p,
+ sizeof(struct packet_struct *) );
- return new_userdata;
+ return new_userdata;
}
/****************************************************************************
@@ -178,18 +168,18 @@ proxy query returned.
static void wins_proxy_userdata_free_fn(struct userdata_struct *userdata)
{
- struct packet_struct *p;
+ struct packet_struct *p;
- /* Extract the pointer to the packet struct */
- memcpy((char *)&p, &userdata->data[sizeof(struct subnet_record *)],
- sizeof(struct packet_struct *));
+ /* Extract the pointer to the packet struct */
+ memcpy((char *)&p, &userdata->data[sizeof(struct subnet_record *)],
+ sizeof(struct packet_struct *));
- /* Unlock the packet. */
- p->locked = False;
+ /* Unlock the packet. */
+ p->locked = False;
- free_packet(p);
- ZERO_STRUCTP(userdata);
- SAFE_FREE(userdata);
+ free_packet(p);
+ ZERO_STRUCTP(userdata);
+ SAFE_FREE(userdata);
}
/****************************************************************************
@@ -200,22 +190,24 @@ void make_wins_proxy_name_query_request( struct subnet_record *subrec,
struct packet_struct *incoming_packet,
struct nmb_name *question_name)
{
- long *ud[(sizeof(struct userdata_struct) + sizeof(struct subrec *) +
- sizeof(struct packet_struct *))/sizeof(long *) + 1];
- struct userdata_struct *userdata = (struct userdata_struct *)ud;
+ long *ud[(sizeof(struct userdata_struct) + sizeof(struct subrec *) +
+ sizeof(struct packet_struct *))/sizeof(long *) + 1];
+ struct userdata_struct *userdata = (struct userdata_struct *)ud;
+ nstring qname;
- memset(ud, '\0', sizeof(ud));
+ memset(ud, '\0', sizeof(ud));
- userdata->copy_fn = wins_proxy_userdata_copy_fn;
- userdata->free_fn = wins_proxy_userdata_free_fn;
- userdata->userdata_len = sizeof(ud);
- memcpy( userdata->data, (char *)&subrec, sizeof(struct subnet_record *));
- memcpy( &userdata->data[sizeof(struct subnet_record *)], (char *)&incoming_packet,
- sizeof(struct packet_struct *));
-
- /* Now use the unicast subnet to query the name with the WINS server. */
- query_name( unicast_subnet, question_name->name, question_name->name_type,
- wins_proxy_name_query_request_success,
- wins_proxy_name_query_request_fail,
- userdata);
+ userdata->copy_fn = wins_proxy_userdata_copy_fn;
+ userdata->free_fn = wins_proxy_userdata_free_fn;
+ userdata->userdata_len = sizeof(ud);
+ memcpy( userdata->data, (char *)&subrec, sizeof(struct subnet_record *));
+ memcpy( &userdata->data[sizeof(struct subnet_record *)], (char *)&incoming_packet,
+ sizeof(struct packet_struct *));
+
+ /* Now use the unicast subnet to query the name with the WINS server. */
+ pull_ascii_nstring(qname, question_name->name);
+ query_name( unicast_subnet, qname, question_name->name_type,
+ wins_proxy_name_query_request_success,
+ wins_proxy_name_query_request_fail,
+ userdata);
}
diff --git a/source3/nmbd/nmbd_winsserver.c b/source3/nmbd/nmbd_winsserver.c
index 784c909c81..1abff5d5e2 100644
--- a/source3/nmbd/nmbd_winsserver.c
+++ b/source3/nmbd/nmbd_winsserver.c
@@ -2,7 +2,7 @@
Unix SMB/CIFS implementation.
NBT netbios routines and daemon - version 2
- Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Jeremy Allison 1994-2003
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
@@ -26,8 +26,9 @@
#define WINS_VERSION 1
/****************************************************************************
-change the wins owner address in the record.
+ Change the wins owner address in the record.
*****************************************************************************/
+
static void update_wins_owner(struct name_record *namerec, struct in_addr wins_ip)
{
if (namerec==NULL)
@@ -36,8 +37,9 @@ static void update_wins_owner(struct name_record *namerec, struct in_addr wins_i
}
/****************************************************************************
-create the wins flags based on the nb flags and the input value.
+ Create the wins flags based on the nb flags and the input value.
*****************************************************************************/
+
static void update_wins_flag(struct name_record *namerec, int flags)
{
if (namerec==NULL)
@@ -74,12 +76,12 @@ static void update_wins_flag(struct name_record *namerec, int flags)
DEBUG(8,("update_wins_flag: nbflags: 0x%x, ttl: 0x%d, flags: 0x%x, winsflags: 0x%x\n",
namerec->data.nb_flags, (int)namerec->data.death_time, flags, namerec->data.wins_flags));
-
}
/****************************************************************************
-return the general ID value and increase it if requested
+ Return the general ID value and increase it if requested.
*****************************************************************************/
+
static void get_global_id_and_update(SMB_BIG_UINT *current_id, BOOL update)
{
/*
@@ -98,8 +100,9 @@ static void get_global_id_and_update(SMB_BIG_UINT *current_id, BOOL update)
}
/****************************************************************************
-possibly call the WINS hook external program when a WINS change is made
+ Possibly call the WINS hook external program when a WINS change is made.
*****************************************************************************/
+
static void wins_hook(const char *operation, struct name_record *namerec, int ttl)
{
pstring command;
@@ -139,63 +142,58 @@ Determine if this packet should be allocated to the WINS server.
BOOL packet_is_for_wins_server(struct packet_struct *packet)
{
- struct nmb_packet *nmb = &packet->packet.nmb;
-
- /* Only unicast packets go to a WINS server. */
- if((wins_server_subnet == NULL) || (nmb->header.nm_flags.bcast == True))
- {
- DEBUG(10, ("packet_is_for_wins_server: failing WINS test #1.\n"));
- return False;
- }
-
- /* Check for node status requests. */
- if (nmb->question.question_type != QUESTION_TYPE_NB_QUERY)
- return False;
-
- switch(nmb->header.opcode)
- {
- /*
- * A WINS server issues WACKS, not receives them.
- */
- case NMB_WACK_OPCODE:
- DEBUG(10, ("packet_is_for_wins_server: failing WINS test #2 (WACK).\n"));
- return False;
- /*
- * A WINS server only processes registration and
- * release requests, not responses.
- */
- case NMB_NAME_REG_OPCODE:
- case NMB_NAME_MULTIHOMED_REG_OPCODE:
- case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
- case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
- if(nmb->header.response)
- {
- DEBUG(10, ("packet_is_for_wins_server: failing WINS test #3 (response = 1).\n"));
- return False;
- }
- break;
-
- case NMB_NAME_RELEASE_OPCODE:
- if(nmb->header.response)
- {
- DEBUG(10, ("packet_is_for_wins_server: failing WINS test #4 (response = 1).\n"));
- return False;
- }
- break;
-
- /*
- * Only process unicast name queries with rd = 1.
- */
- case NMB_NAME_QUERY_OPCODE:
- if(!nmb->header.response && !nmb->header.nm_flags.recursion_desired)
- {
- DEBUG(10, ("packet_is_for_wins_server: failing WINS test #5 (response = 1).\n"));
- return False;
- }
- break;
- }
-
- return True;
+ struct nmb_packet *nmb = &packet->packet.nmb;
+
+ /* Only unicast packets go to a WINS server. */
+ if((wins_server_subnet == NULL) || (nmb->header.nm_flags.bcast == True)) {
+ DEBUG(10, ("packet_is_for_wins_server: failing WINS test #1.\n"));
+ return False;
+ }
+
+ /* Check for node status requests. */
+ if (nmb->question.question_type != QUESTION_TYPE_NB_QUERY)
+ return False;
+
+ switch(nmb->header.opcode) {
+ /*
+ * A WINS server issues WACKS, not receives them.
+ */
+ case NMB_WACK_OPCODE:
+ DEBUG(10, ("packet_is_for_wins_server: failing WINS test #2 (WACK).\n"));
+ return False;
+ /*
+ * A WINS server only processes registration and
+ * release requests, not responses.
+ */
+ case NMB_NAME_REG_OPCODE:
+ case NMB_NAME_MULTIHOMED_REG_OPCODE:
+ case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
+ case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
+ if(nmb->header.response) {
+ DEBUG(10, ("packet_is_for_wins_server: failing WINS test #3 (response = 1).\n"));
+ return False;
+ }
+ break;
+
+ case NMB_NAME_RELEASE_OPCODE:
+ if(nmb->header.response) {
+ DEBUG(10, ("packet_is_for_wins_server: failing WINS test #4 (response = 1).\n"));
+ return False;
+ }
+ break;
+
+ /*
+ * Only process unicast name queries with rd = 1.
+ */
+ case NMB_NAME_QUERY_OPCODE:
+ if(!nmb->header.response && !nmb->header.nm_flags.recursion_desired) {
+ DEBUG(10, ("packet_is_for_wins_server: failing WINS test #5 (response = 1).\n"));
+ return False;
+ }
+ break;
+ }
+
+ return True;
}
/****************************************************************************
@@ -204,15 +202,15 @@ Utility function to decide what ttl to give a register/refresh request.
static int get_ttl_from_packet(struct nmb_packet *nmb)
{
- int ttl = nmb->additional->ttl;
+ int ttl = nmb->additional->ttl;
- if(ttl < lp_min_wins_ttl() )
- ttl = lp_min_wins_ttl();
+ if(ttl < lp_min_wins_ttl() )
+ ttl = lp_min_wins_ttl();
- if(ttl > lp_max_wins_ttl() )
- ttl = lp_max_wins_ttl();
+ if(ttl > lp_max_wins_ttl() )
+ ttl = lp_max_wins_ttl();
- return ttl;
+ return ttl;
}
/****************************************************************************
@@ -221,177 +219,160 @@ Load or create the WINS database.
BOOL initialise_wins(void)
{
- time_t time_now = time(NULL);
- XFILE *fp;
- pstring line;
-
- if(!lp_we_are_a_wins_server())
- return True;
-
- add_samba_names_to_subnet(wins_server_subnet);
-
- if((fp = x_fopen(lock_path(WINS_LIST),O_RDONLY,0)) == NULL)
- {
- DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n",
- WINS_LIST, strerror(errno) ));
- return True;
- }
-
- while (!x_feof(fp))
- {
- pstring name_str, ip_str, ttl_str, nb_flags_str;
- unsigned int num_ips;
- pstring name;
- struct in_addr *ip_list;
- int type = 0;
- int nb_flags;
- int ttl;
- const char *ptr;
- char *p;
- BOOL got_token;
- BOOL was_ip;
- int i;
- unsigned hash;
- int version;
-
- /* Read a line from the wins.dat file. Strips whitespace
- from the beginning and end of the line.
- */
- if (!fgets_slash(line,sizeof(pstring),fp))
- continue;
+ time_t time_now = time(NULL);
+ XFILE *fp;
+ pstring line;
+
+ if(!lp_we_are_a_wins_server())
+ return True;
+
+ add_samba_names_to_subnet(wins_server_subnet);
+
+ if((fp = x_fopen(lock_path(WINS_LIST),O_RDONLY,0)) == NULL) {
+ DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n",
+ WINS_LIST, strerror(errno) ));
+ return True;
+ }
+
+ while (!x_feof(fp)) {
+ pstring name_str, ip_str, ttl_str, nb_flags_str;
+ unsigned int num_ips;
+ pstring name;
+ struct in_addr *ip_list;
+ int type = 0;
+ int nb_flags;
+ int ttl;
+ const char *ptr;
+ char *p;
+ BOOL got_token;
+ BOOL was_ip;
+ int i;
+ unsigned int hash;
+ int version;
+
+ /* Read a line from the wins.dat file. Strips whitespace
+ from the beginning and end of the line. */
+ if (!fgets_slash(line,sizeof(pstring),fp))
+ continue;
- if (*line == '#')
- continue;
-
- if (strncmp(line,"VERSION ", 8) == 0) {
- if (sscanf(line,"VERSION %d %u", &version, &hash) != 2 ||
- version != WINS_VERSION) {
- DEBUG(0,("Discarding invalid wins.dat file [%s]\n",line));
- x_fclose(fp);
- return True;
- }
- continue;
- }
-
- ptr = line;
-
- /*
- * Now we handle multiple IP addresses per name we need
- * to iterate over the line twice. The first time to
- * determine how many IP addresses there are, the second
- * time to actually parse them into the ip_list array.
- */
-
- if (!next_token(&ptr,name_str,NULL,sizeof(name_str)))
- {
- DEBUG(0,("initialise_wins: Failed to parse name when parsing line %s\n", line ));
- continue;
- }
-
- if (!next_token(&ptr,ttl_str,NULL,sizeof(ttl_str)))
- {
- DEBUG(0,("initialise_wins: Failed to parse time to live when parsing line %s\n", line ));
- continue;
- }
-
- /*
- * Determine the number of IP addresses per line.
- */
- num_ips = 0;
- do
- {
- got_token = next_token(&ptr,ip_str,NULL,sizeof(ip_str));
- was_ip = False;
-
- if(got_token && strchr(ip_str, '.'))
- {
- num_ips++;
- was_ip = True;
- }
- } while( got_token && was_ip);
-
- if(num_ips == 0)
- {
- DEBUG(0,("initialise_wins: Missing IP address when parsing line %s\n", line ));
- continue;
- }
-
- if(!got_token)
- {
- DEBUG(0,("initialise_wins: Missing nb_flags when parsing line %s\n", line ));
- continue;
- }
-
- /* Allocate the space for the ip_list. */
- if((ip_list = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr))) == NULL)
- {
- DEBUG(0,("initialise_wins: Malloc fail !\n"));
- return False;
- }
+ if (*line == '#')
+ continue;
+
+ if (strncmp(line,"VERSION ", 8) == 0) {
+ if (sscanf(line,"VERSION %d %u", &version, &hash) != 2 ||
+ version != WINS_VERSION) {
+ DEBUG(0,("Discarding invalid wins.dat file [%s]\n",line));
+ x_fclose(fp);
+ return True;
+ }
+ continue;
+ }
+
+ ptr = line;
+
+ /*
+ * Now we handle multiple IP addresses per name we need
+ * to iterate over the line twice. The first time to
+ * determine how many IP addresses there are, the second
+ * time to actually parse them into the ip_list array.
+ */
+
+ if (!next_token(&ptr,name_str,NULL,sizeof(name_str))) {
+ DEBUG(0,("initialise_wins: Failed to parse name when parsing line %s\n", line ));
+ continue;
+ }
+
+ if (!next_token(&ptr,ttl_str,NULL,sizeof(ttl_str))) {
+ DEBUG(0,("initialise_wins: Failed to parse time to live when parsing line %s\n", line ));
+ continue;
+ }
+
+ /*
+ * Determine the number of IP addresses per line.
+ */
+ num_ips = 0;
+ do {
+ got_token = next_token(&ptr,ip_str,NULL,sizeof(ip_str));
+ was_ip = False;
+
+ if(got_token && strchr(ip_str, '.')) {
+ num_ips++;
+ was_ip = True;
+ }
+ } while( got_token && was_ip);
+
+ if(num_ips == 0) {
+ DEBUG(0,("initialise_wins: Missing IP address when parsing line %s\n", line ));
+ continue;
+ }
+
+ if(!got_token) {
+ DEBUG(0,("initialise_wins: Missing nb_flags when parsing line %s\n", line ));
+ continue;
+ }
+
+ /* Allocate the space for the ip_list. */
+ if((ip_list = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr))) == NULL) {
+ DEBUG(0,("initialise_wins: Malloc fail !\n"));
+ return False;
+ }
- /* Reset and re-parse the line. */
- ptr = line;
- next_token(&ptr,name_str,NULL,sizeof(name_str));
- next_token(&ptr,ttl_str,NULL,sizeof(ttl_str));
- for(i = 0; i < num_ips; i++)
- {
- next_token(&ptr, ip_str, NULL, sizeof(ip_str));
- ip_list[i] = *interpret_addr2(ip_str);
- }
- next_token(&ptr,nb_flags_str,NULL, sizeof(nb_flags_str));
-
- /*
- * Deal with SELF or REGISTER name encoding. Default is REGISTER
- * for compatibility with old nmbds.
- */
-
- if(nb_flags_str[strlen(nb_flags_str)-1] == 'S')
- {
- DEBUG(5,("initialise_wins: Ignoring SELF name %s\n", line));
- SAFE_FREE(ip_list);
- continue;
- }
+ /* Reset and re-parse the line. */
+ ptr = line;
+ next_token(&ptr,name_str,NULL,sizeof(name_str));
+ next_token(&ptr,ttl_str,NULL,sizeof(ttl_str));
+ for(i = 0; i < num_ips; i++) {
+ next_token(&ptr, ip_str, NULL, sizeof(ip_str));
+ ip_list[i] = *interpret_addr2(ip_str);
+ }
+ next_token(&ptr,nb_flags_str,NULL, sizeof(nb_flags_str));
+
+ /*
+ * Deal with SELF or REGISTER name encoding. Default is REGISTER
+ * for compatibility with old nmbds.
+ */
+
+ if(nb_flags_str[strlen(nb_flags_str)-1] == 'S') {
+ DEBUG(5,("initialise_wins: Ignoring SELF name %s\n", line));
+ SAFE_FREE(ip_list);
+ continue;
+ }
- if(nb_flags_str[strlen(nb_flags_str)-1] == 'R')
- nb_flags_str[strlen(nb_flags_str)-1] = '\0';
+ if(nb_flags_str[strlen(nb_flags_str)-1] == 'R')
+ nb_flags_str[strlen(nb_flags_str)-1] = '\0';
- /* Netbios name. # divides the name from the type (hex): netbios#xx */
- pstrcpy(name,name_str);
+ /* Netbios name. # divides the name from the type (hex): netbios#xx */
+ pstrcpy(name,name_str);
- if((p = strchr(name,'#')) != NULL)
- {
- *p = 0;
- sscanf(p+1,"%x",&type);
- }
+ if((p = strchr(name,'#')) != NULL) {
+ *p = 0;
+ sscanf(p+1,"%x",&type);
+ }
- /* Decode the netbios flags (hex) and the time-to-live (in seconds). */
- sscanf(nb_flags_str,"%x",&nb_flags);
- sscanf(ttl_str,"%d",&ttl);
-
- /* add all entries that have 60 seconds or more to live */
- if ((ttl - 60) > time_now || ttl == PERMANENT_TTL)
- {
- if(ttl != PERMANENT_TTL)
- ttl -= time_now;
+ /* Decode the netbios flags (hex) and the time-to-live (in seconds). */
+ sscanf(nb_flags_str,"%x",&nb_flags);
+ sscanf(ttl_str,"%d",&ttl);
+
+ /* add all entries that have 60 seconds or more to live */
+ if ((ttl - 60) > time_now || ttl == PERMANENT_TTL) {
+ if(ttl != PERMANENT_TTL)
+ ttl -= time_now;
- DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
- name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
-
- (void)add_name_to_subnet( wins_server_subnet, name, type, nb_flags,
- ttl, REGISTER_NAME, num_ips, ip_list );
-
- }
- else
- {
- DEBUG(4, ("initialise_wins: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n",
- name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
- }
+ DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
+ name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
+
+ (void)add_name_to_subnet( wins_server_subnet, name, type, nb_flags,
+ ttl, REGISTER_NAME, num_ips, ip_list );
+ } else {
+ DEBUG(4, ("initialise_wins: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n",
+ name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
+ }
- SAFE_FREE(ip_list);
- }
+ SAFE_FREE(ip_list);
+ }
- x_fclose(fp);
- return True;
+ x_fclose(fp);
+ return True;
}
/****************************************************************************
@@ -400,30 +381,33 @@ Send a WINS WACK (Wait ACKnowledgement) response.
static void send_wins_wack_response(int ttl, struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- unsigned char rdata[2];
-
- rdata[0] = rdata[1] = 0;
-
- /* Taken from nmblib.c - we need to send back almost
- identical bytes from the requesting packet header. */
-
- rdata[0] = (nmb->header.opcode & 0xF) << 3;
- if (nmb->header.nm_flags.authoritative &&
- nmb->header.response) rdata[0] |= 0x4;
- if (nmb->header.nm_flags.trunc) rdata[0] |= 0x2;
- if (nmb->header.nm_flags.recursion_desired) rdata[0] |= 0x1;
- if (nmb->header.nm_flags.recursion_available &&
- nmb->header.response) rdata[1] |= 0x80;
- if (nmb->header.nm_flags.bcast) rdata[1] |= 0x10;
-
- reply_netbios_packet(p, /* Packet to reply to. */
- 0, /* Result code. */
- NMB_WAIT_ACK, /* nmbd type code. */
- NMB_WACK_OPCODE, /* opcode. */
- ttl, /* ttl. */
- (char *)rdata, /* data to send. */
- 2); /* data length. */
+ struct nmb_packet *nmb = &p->packet.nmb;
+ unsigned char rdata[2];
+
+ rdata[0] = rdata[1] = 0;
+
+ /* Taken from nmblib.c - we need to send back almost
+ identical bytes from the requesting packet header. */
+
+ rdata[0] = (nmb->header.opcode & 0xF) << 3;
+ if (nmb->header.nm_flags.authoritative && nmb->header.response)
+ rdata[0] |= 0x4;
+ if (nmb->header.nm_flags.trunc)
+ rdata[0] |= 0x2;
+ if (nmb->header.nm_flags.recursion_desired)
+ rdata[0] |= 0x1;
+ if (nmb->header.nm_flags.recursion_available && nmb->header.response)
+ rdata[1] |= 0x80;
+ if (nmb->header.nm_flags.bcast)
+ rdata[1] |= 0x10;
+
+ reply_netbios_packet(p, /* Packet to reply to. */
+ 0, /* Result code. */
+ NMB_WAIT_ACK, /* nmbd type code. */
+ NMB_WACK_OPCODE, /* opcode. */
+ ttl, /* ttl. */
+ (char *)rdata, /* data to send. */
+ 2); /* data length. */
}
/****************************************************************************
@@ -432,18 +416,18 @@ Send a WINS name registration response.
static void send_wins_name_registration_response(int rcode, int ttl, struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- char rdata[6];
-
- memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
-
- reply_netbios_packet(p, /* Packet to reply to. */
- rcode, /* Result code. */
- WINS_REG, /* nmbd type code. */
- NMB_NAME_REG_OPCODE, /* opcode. */
- ttl, /* ttl. */
- rdata, /* data to send. */
- 6); /* data length. */
+ struct nmb_packet *nmb = &p->packet.nmb;
+ char rdata[6];
+
+ memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
+
+ reply_netbios_packet(p, /* Packet to reply to. */
+ rcode, /* Result code. */
+ WINS_REG, /* nmbd type code. */
+ NMB_NAME_REG_OPCODE, /* opcode. */
+ ttl, /* ttl. */
+ rdata, /* data to send. */
+ 6); /* data length. */
}
/***********************************************************************
@@ -453,139 +437,128 @@ static void send_wins_name_registration_response(int rcode, int ttl, struct pack
void wins_process_name_refresh_request(struct subnet_record *subrec,
struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
- BOOL group = (nb_flags & NB_GROUP) ? True : False;
- struct name_record *namerec = NULL;
- int ttl = get_ttl_from_packet(nmb);
- struct in_addr from_ip;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
-
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
-
- if(bcast)
- {
- /*
- * We should only get unicast name refresh packets here.
- * Anyone trying to refresh broadcast should not be going to a WINS
- * server. Log an error here.
- */
-
- DEBUG(0,("wins_process_name_refresh_request: broadcast name refresh request \
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct nmb_name *question = &nmb->question.question_name;
+ BOOL bcast = nmb->header.nm_flags.bcast;
+ uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
+ BOOL group = (nb_flags & NB_GROUP) ? True : False;
+ struct name_record *namerec = NULL;
+ int ttl = get_ttl_from_packet(nmb);
+ struct in_addr from_ip;
+ struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
+
+ putip((char *)&from_ip,&nmb->additional->rdata[2]);
+
+ if(bcast) {
+ /*
+ * We should only get unicast name refresh packets here.
+ * Anyone trying to refresh broadcast should not be going to a WINS
+ * server. Log an error here.
+ */
+
+ DEBUG(0,("wins_process_name_refresh_request: broadcast name refresh request \
received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
- nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- return;
- }
+ nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
+ return;
+ }
- DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s \
+ DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s \
IP %s\n", nmb_namestr(question), inet_ntoa(from_ip) ));
- /*
- * See if the name already exists.
- */
+ /*
+ * See if the name already exists.
+ */
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
+ namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
- /*
- * If this is a refresh request and the name doesn't exist then
- * treat it like a registration request. This allows us to recover
- * from errors (tridge)
- */
+ /*
+ * If this is a refresh request and the name doesn't exist then
+ * treat it like a registration request. This allows us to recover
+ * from errors (tridge)
+ */
- if(namerec == NULL)
- {
- DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s and \
+ if(namerec == NULL) {
+ DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s and \
the name does not exist. Treating as registration.\n", nmb_namestr(question) ));
- wins_process_name_registration_request(subrec,p);
- return;
- }
-
- /*
- * if the name is present but not active,
- * simply remove it and treat the request
- * as a registration
- */
- if (namerec != NULL && !WINS_STATE_ACTIVE(namerec))
- {
- DEBUG(5,("wins_process_name_refresh_request: Name (%s) in WINS was \
+ wins_process_name_registration_request(subrec,p);
+ return;
+ }
+
+ /*
+ * if the name is present but not active,
+ * simply remove it and treat the request
+ * as a registration
+ */
+ if (namerec != NULL && !WINS_STATE_ACTIVE(namerec)) {
+ DEBUG(5,("wins_process_name_refresh_request: Name (%s) in WINS was \
not active - removing it.\n", nmb_namestr(question) ));
- remove_name_from_namelist( subrec, namerec );
- namerec = NULL;
- wins_process_name_registration_request(subrec,p);
- return;
- }
-
- /*
- * Check that the group bits for the refreshing name and the
- * name in our database match.
- */
-
- if((namerec != NULL) && ((group && !NAME_GROUP(namerec)) || (!group && NAME_GROUP(namerec))) )
- {
- DEBUG(3,("wins_process_name_refresh_request: Name %s group bit = %s \
+ remove_name_from_namelist( subrec, namerec );
+ namerec = NULL;
+ wins_process_name_registration_request(subrec,p);
+ return;
+ }
+
+ /*
+ * Check that the group bits for the refreshing name and the
+ * name in our database match.
+ */
+
+ if((namerec != NULL) && ((group && !NAME_GROUP(namerec)) || (!group && NAME_GROUP(namerec))) ) {
+ DEBUG(3,("wins_process_name_refresh_request: Name %s group bit = %s \
does not match group bit in WINS for this name.\n", nmb_namestr(question), group ? "True" : "False" ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
-
- /*
- * For a unique name check that the person refreshing the name is one of the registered IP
- * addresses. If not - fail the refresh. Do the same for group names with a type of 0x1c.
- * Just return success for unique 0x1d refreshes. For normal group names update the ttl
- * and return success.
- */
-
- if((!group || (group && (question->name_type == 0x1c))) && find_ip_in_name_record(namerec, from_ip ))
- {
- /*
- * Update the ttl.
- */
- update_name_ttl(namerec, ttl);
-
- /*
- * if the record is a replica:
- * we take ownership and update the version ID.
- */
- if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
- update_wins_owner(namerec, our_fake_ip);
- get_global_id_and_update(&namerec->data.id, True);
- }
-
- send_wins_name_registration_response(0, ttl, p);
- wins_hook("refresh", namerec, ttl);
- return;
- }
- else if(group)
- {
- /*
- * Normal groups are all registered with an IP address of 255.255.255.255
- * so we can't search for the IP address.
- */
- update_name_ttl(namerec, ttl);
- send_wins_name_registration_response(0, ttl, p);
- return;
- }
- else if(!group && (question->name_type == 0x1d))
- {
- /*
- * Special name type - just pretend the refresh succeeded.
- */
- send_wins_name_registration_response(0, ttl, p);
- return;
- }
- else
- {
- /*
- * Fail the refresh.
- */
-
- DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s with IP %s and \
+ send_wins_name_registration_response(RFS_ERR, 0, p);
+ return;
+ }
+
+ /*
+ * For a unique name check that the person refreshing the name is one of the registered IP
+ * addresses. If not - fail the refresh. Do the same for group names with a type of 0x1c.
+ * Just return success for unique 0x1d refreshes. For normal group names update the ttl
+ * and return success.
+ */
+
+ if((!group || (group && (question->name_type == 0x1c))) && find_ip_in_name_record(namerec, from_ip )) {
+ /*
+ * Update the ttl.
+ */
+ update_name_ttl(namerec, ttl);
+
+ /*
+ * if the record is a replica:
+ * we take ownership and update the version ID.
+ */
+ if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
+ update_wins_owner(namerec, our_fake_ip);
+ get_global_id_and_update(&namerec->data.id, True);
+ }
+
+ send_wins_name_registration_response(0, ttl, p);
+ wins_hook("refresh", namerec, ttl);
+ return;
+ } else if(group) {
+ /*
+ * Normal groups are all registered with an IP address of 255.255.255.255
+ * so we can't search for the IP address.
+ */
+ update_name_ttl(namerec, ttl);
+ send_wins_name_registration_response(0, ttl, p);
+ return;
+ } else if(!group && (question->name_type == 0x1d)) {
+ /*
+ * Special name type - just pretend the refresh succeeded.
+ */
+ send_wins_name_registration_response(0, ttl, p);
+ return;
+ } else {
+ /*
+ * Fail the refresh.
+ */
+
+ DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s with IP %s and \
is IP is not known to the name.\n", nmb_namestr(question), inet_ntoa(from_ip) ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
+ send_wins_name_registration_response(RFS_ERR, 0, p);
+ return;
+ }
}
/***********************************************************************
@@ -604,17 +577,17 @@ static void wins_register_query_success(struct subnet_record *subrec,
struct in_addr ip,
struct res_rec *answers)
{
- struct packet_struct *orig_reg_packet;
+ struct packet_struct *orig_reg_packet;
- memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
+ memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
- DEBUG(3,("wins_register_query_success: Original client at IP %s still wants the \
+ DEBUG(3,("wins_register_query_success: Original client at IP %s still wants the \
name %s. Rejecting registration request.\n", inet_ntoa(ip), nmb_namestr(question_name) ));
- send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
+ send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
- orig_reg_packet->locked = False;
- free_packet(orig_reg_packet);
+ orig_reg_packet->locked = False;
+ free_packet(orig_reg_packet);
}
/***********************************************************************
@@ -632,40 +605,37 @@ static void wins_register_query_fail(struct subnet_record *subrec,
struct nmb_name *question_name,
int rcode)
{
- struct userdata_struct *userdata = rrec->userdata;
- struct packet_struct *orig_reg_packet;
- struct name_record *namerec = NULL;
-
- memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
-
- /*
- * We want to just add the name, as we now know the original owner
- * didn't want it. But we can't just do that as an arbitary
- * amount of time may have taken place between the name query
- * request and this timeout/error response. So we check that
- * the name still exists and is in the same state - if so
- * we remove it and call wins_process_name_registration_request()
- * as we know it will do the right thing now.
- */
-
- namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
-
- if( (namerec != NULL)
- && (namerec->data.source == REGISTER_NAME)
- && ip_equal(rrec->packet->ip, *namerec->data.ip) )
- {
- remove_name_from_namelist( subrec, namerec);
- namerec = NULL;
- }
-
- if(namerec == NULL)
- wins_process_name_registration_request(subrec, orig_reg_packet);
- else
- DEBUG(2,("wins_register_query_fail: The state of the WINS database changed between \
+ struct userdata_struct *userdata = rrec->userdata;
+ struct packet_struct *orig_reg_packet;
+ struct name_record *namerec = NULL;
+
+ memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
+
+ /*
+ * We want to just add the name, as we now know the original owner
+ * didn't want it. But we can't just do that as an arbitary
+ * amount of time may have taken place between the name query
+ * request and this timeout/error response. So we check that
+ * the name still exists and is in the same state - if so
+ * we remove it and call wins_process_name_registration_request()
+ * as we know it will do the right thing now.
+ */
+
+ namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
+
+ if( (namerec != NULL) && (namerec->data.source == REGISTER_NAME) && ip_equal(rrec->packet->ip, *namerec->data.ip) ) {
+ remove_name_from_namelist( subrec, namerec);
+ namerec = NULL;
+ }
+
+ if(namerec == NULL)
+ wins_process_name_registration_request(subrec, orig_reg_packet);
+ else
+ DEBUG(2,("wins_register_query_fail: The state of the WINS database changed between \
querying for name %s in order to replace it and this reply.\n", nmb_namestr(question_name) ));
- orig_reg_packet->locked = False;
- free_packet(orig_reg_packet);
+ orig_reg_packet->locked = False;
+ free_packet(orig_reg_packet);
}
/***********************************************************************
@@ -728,279 +698,269 @@ querying for name %s in order to replace it and this reply.\n", nmb_namestr(ques
void wins_process_name_registration_request(struct subnet_record *subrec,
struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
- int ttl = get_ttl_from_packet(nmb);
- struct name_record *namerec = NULL;
- struct in_addr from_ip;
- BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
-
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
-
- if(bcast)
- {
- /*
- * We should only get unicast name registration packets here.
- * Anyone trying to register broadcast should not be going to a WINS
- * server. Log an error here.
- */
-
- DEBUG(0,("wins_process_name_registration_request: broadcast name registration request \
+ nstring name;
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct nmb_name *question = &nmb->question.question_name;
+ BOOL bcast = nmb->header.nm_flags.bcast;
+ uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
+ int ttl = get_ttl_from_packet(nmb);
+ struct name_record *namerec = NULL;
+ struct in_addr from_ip;
+ BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;
+ struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
+
+ putip((char *)&from_ip,&nmb->additional->rdata[2]);
+
+ if(bcast) {
+ /*
+ * We should only get unicast name registration packets here.
+ * Anyone trying to register broadcast should not be going to a WINS
+ * server. Log an error here.
+ */
+
+ DEBUG(0,("wins_process_name_registration_request: broadcast name registration request \
received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
- nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- return;
- }
+ nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
+ return;
+ }
- DEBUG(3,("wins_process_name_registration_request: %s name registration for name %s \
+ DEBUG(3,("wins_process_name_registration_request: %s name registration for name %s \
IP %s\n", registering_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
- /*
- * See if the name already exists.
- */
+ /*
+ * See if the name already exists.
+ */
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
+ namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
- /*
- * if the record exists but NOT in active state,
- * consider it dead.
- */
- if ( (namerec != NULL) && !WINS_STATE_ACTIVE(namerec))
- {
- DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
+ /*
+ * if the record exists but NOT in active state,
+ * consider it dead.
+ */
+ if ( (namerec != NULL) && !WINS_STATE_ACTIVE(namerec)) {
+ DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
not active - removing it.\n", nmb_namestr(question) ));
- remove_name_from_namelist( subrec, namerec );
- namerec = NULL;
- }
-
- /*
- * Deal with the case where the name found was a dns entry.
- * Remove it as we now have a NetBIOS client registering the
- * name.
- */
-
- if( (namerec != NULL)
- && ( (namerec->data.source == DNS_NAME)
- || (namerec->data.source == DNSFAIL_NAME) ) )
- {
- DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
+ remove_name_from_namelist( subrec, namerec );
+ namerec = NULL;
+ }
+
+ /*
+ * Deal with the case where the name found was a dns entry.
+ * Remove it as we now have a NetBIOS client registering the
+ * name.
+ */
+
+ if( (namerec != NULL) && ( (namerec->data.source == DNS_NAME) || (namerec->data.source == DNSFAIL_NAME) ) ) {
+ DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
a dns lookup - removing it.\n", nmb_namestr(question) ));
- remove_name_from_namelist( subrec, namerec );
- namerec = NULL;
- }
-
- /*
- * Reject if the name exists and is not a REGISTER_NAME.
- * (ie. Don't allow any static names to be overwritten.
- */
-
- if((namerec != NULL) && (namerec->data.source != REGISTER_NAME))
- {
- DEBUG( 3, ( "wins_process_name_registration_request: Attempt \
+ remove_name_from_namelist( subrec, namerec );
+ namerec = NULL;
+ }
+
+ /*
+ * Reject if the name exists and is not a REGISTER_NAME.
+ * (ie. Don't allow any static names to be overwritten.
+ */
+
+ if((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) {
+ DEBUG( 3, ( "wins_process_name_registration_request: Attempt \
to register name %s. Name already exists in WINS with source type %d.\n",
- nmb_namestr(question), namerec->data.source ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
-
- /*
- * Special policy decisions based on MS documentation.
- * 1). All group names (except names ending in 0x1c) are added as 255.255.255.255.
- * 2). All unique names ending in 0x1d are ignored, although a positive response is sent.
- */
-
- /*
- * A group name is always added as the local broadcast address, except
- * for group names ending in 0x1c.
- * Group names with type 0x1c are registered with individual IP addresses.
- */
-
- if(registering_group_name && (question->name_type != 0x1c))
- from_ip = *interpret_addr2("255.255.255.255");
-
- /*
- * Ignore all attempts to register a unique 0x1d name, although return success.
- */
-
- if(!registering_group_name && (question->name_type == 0x1d))
- {
- DEBUG(3,("wins_process_name_registration_request: Ignoring request \
+ nmb_namestr(question), namerec->data.source ));
+ send_wins_name_registration_response(RFS_ERR, 0, p);
+ return;
+ }
+
+ /*
+ * Special policy decisions based on MS documentation.
+ * 1). All group names (except names ending in 0x1c) are added as 255.255.255.255.
+ * 2). All unique names ending in 0x1d are ignored, although a positive response is sent.
+ */
+
+ /*
+ * A group name is always added as the local broadcast address, except
+ * for group names ending in 0x1c.
+ * Group names with type 0x1c are registered with individual IP addresses.
+ */
+
+ if(registering_group_name && (question->name_type != 0x1c))
+ from_ip = *interpret_addr2("255.255.255.255");
+
+ /*
+ * Ignore all attempts to register a unique 0x1d name, although return success.
+ */
+
+ if(!registering_group_name && (question->name_type == 0x1d)) {
+ DEBUG(3,("wins_process_name_registration_request: Ignoring request \
to register name %s from IP %s.\n", nmb_namestr(question), inet_ntoa(p->ip) ));
- send_wins_name_registration_response(0, ttl, p);
- return;
- }
-
- /*
- * Next two cases are the 'if statement' mentioned above.
- */
-
- if((namerec != NULL) && NAME_GROUP(namerec))
- {
- if(registering_group_name)
- {
- /*
- * If we are adding a group name, the name exists and is also a group entry just add this
- * IP address to it and update the ttl.
- */
-
- DEBUG(3,("wins_process_name_registration_request: Adding IP %s to group name %s.\n",
- inet_ntoa(from_ip), nmb_namestr(question) ));
- /*
- * Check the ip address is not already in the group.
- */
- if(!find_ip_in_name_record(namerec, from_ip)) {
- add_ip_to_name_record(namerec, from_ip);
- /* we need to update the record for replication */
- get_global_id_and_update(&namerec->data.id, True);
+ send_wins_name_registration_response(0, ttl, p);
+ return;
+ }
/*
- * if the record is a replica, we must change
- * the wins owner to us to make the replication updates
- * it on the other wins servers.
- * And when the partner will receive this record,
- * it will update its own record.
+ * Next two cases are the 'if statement' mentioned above.
*/
- update_wins_owner(namerec, our_fake_ip);
+ if((namerec != NULL) && NAME_GROUP(namerec)) {
+ if(registering_group_name) {
+ /*
+ * If we are adding a group name, the name exists and is also a group entry just add this
+ * IP address to it and update the ttl.
+ */
+
+ DEBUG(3,("wins_process_name_registration_request: Adding IP %s to group name %s.\n",
+ inet_ntoa(from_ip), nmb_namestr(question) ));
+
+ /*
+ * Check the ip address is not already in the group.
+ */
+
+ if(!find_ip_in_name_record(namerec, from_ip)) {
+ add_ip_to_name_record(namerec, from_ip);
+ /* we need to update the record for replication */
+ get_global_id_and_update(&namerec->data.id, True);
+
+ /*
+ * if the record is a replica, we must change
+ * the wins owner to us to make the replication updates
+ * it on the other wins servers.
+ * And when the partner will receive this record,
+ * it will update its own record.
+ */
+
+ update_wins_owner(namerec, our_fake_ip);
+ }
+ update_name_ttl(namerec, ttl);
+ send_wins_name_registration_response(0, ttl, p);
+ return;
+ } else {
- }
- update_name_ttl(namerec, ttl);
- send_wins_name_registration_response(0, ttl, p);
- return;
- }
- else
- {
- /*
- * If we are adding a unique name, the name exists in the WINS db
- * and is a group name then reject the registration.
- *
- * explanation: groups have a higher priority than unique names.
- */
-
- DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
+ /*
+ * If we are adding a unique name, the name exists in the WINS db
+ * and is a group name then reject the registration.
+ *
+ * explanation: groups have a higher priority than unique names.
+ */
+
+ DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
- }
-
- /*
- * From here on down we know that if the name exists in the WINS db it is
- * a unique name, not a group name.
- */
-
- /*
- * If the name exists and is one of our names then check the
- * registering IP address. If it's not one of ours then automatically
- * reject without doing the query - we know we will reject it.
- */
-
- if((namerec != NULL) && (is_myname(namerec->name.name)) )
- {
- if(!ismyip(from_ip))
- {
- DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
+ send_wins_name_registration_response(RFS_ERR, 0, p);
+ return;
+ }
+ }
+
+ /*
+ * From here on down we know that if the name exists in the WINS db it is
+ * a unique name, not a group name.
+ */
+
+ /*
+ * If the name exists and is one of our names then check the
+ * registering IP address. If it's not one of ours then automatically
+ * reject without doing the query - we know we will reject it.
+ */
+
+ pull_ascii_nstring(name, namerec->name.name);
+ if((namerec != NULL) && (is_myname(name)) ) {
+ if(!ismyip(from_ip)) {
+ DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
- else
- {
- /*
- * It's one of our names and one of our IP's - update the ttl.
- */
- update_name_ttl(namerec, ttl);
- send_wins_name_registration_response(0, ttl, p);
- wins_hook("refresh", namerec, ttl);
- return;
- }
- }
-
- /*
- * If the name exists and it is a unique registration and the registering IP
- * is the same as the (single) already registered IP then just update the ttl.
- *
- * But not if the record is an active replica. IF it's a replica, it means it can be
- * the same client which has moved and not yet expired. So we don't update
- * the ttl in this case and go beyond to do a WACK and query the old client
- */
-
- if( !registering_group_name
- && (namerec != NULL)
- && (namerec->data.num_ips == 1)
- && ip_equal( namerec->data.ip[0], from_ip )
- && ip_equal(namerec->data.wins_ip, our_fake_ip) )
- {
- update_name_ttl( namerec, ttl );
- send_wins_name_registration_response( 0, ttl, p );
- wins_hook("refresh", namerec, ttl);
- return;
- }
-
- /*
- * Finally if the name exists do a query to the registering machine
- * to see if they still claim to have the name.
- */
-
- if( namerec != NULL )
- {
- long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
- struct userdata_struct *userdata = (struct userdata_struct *)ud;
-
- /*
- * First send a WACK to the registering machine.
- */
-
- send_wins_wack_response(60, p);
-
- /*
- * When the reply comes back we need the original packet.
- * Lock this so it won't be freed and then put it into
- * the userdata structure.
- */
-
- p->locked = True;
-
- userdata = (struct userdata_struct *)ud;
-
- userdata->copy_fn = NULL;
- userdata->free_fn = NULL;
- userdata->userdata_len = sizeof(struct packet_struct *);
- memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
-
- /*
- * Use the new call to send a query directly to an IP address.
- * This sends the query directly to the IP address, and ensures
- * the recursion desired flag is not set (you were right Luke :-).
- * This function should *only* be called from the WINS server
- * code. JRA.
- */
-
- query_name_from_wins_server( *namerec->data.ip,
- question->name,
- question->name_type,
- wins_register_query_success,
- wins_register_query_fail,
- userdata );
- return;
- }
-
- /*
- * Name did not exist - add it.
- */
-
- (void)add_name_to_subnet( subrec, question->name, question->name_type,
- nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
- if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
- get_global_id_and_update(&namerec->data.id, True);
- update_wins_owner(namerec, our_fake_ip);
- update_wins_flag(namerec, WINS_ACTIVE);
- wins_hook("add", namerec, ttl);
- }
+ send_wins_name_registration_response(RFS_ERR, 0, p);
+ return;
+ } else {
+ /*
+ * It's one of our names and one of our IP's - update the ttl.
+ */
+ update_name_ttl(namerec, ttl);
+ send_wins_name_registration_response(0, ttl, p);
+ wins_hook("refresh", namerec, ttl);
+ return;
+ }
+ }
- send_wins_name_registration_response(0, ttl, p);
+ /*
+ * If the name exists and it is a unique registration and the registering IP
+ * is the same as the (single) already registered IP then just update the ttl.
+ *
+ * But not if the record is an active replica. IF it's a replica, it means it can be
+ * the same client which has moved and not yet expired. So we don't update
+ * the ttl in this case and go beyond to do a WACK and query the old client
+ */
+
+ if( !registering_group_name
+ && (namerec != NULL)
+ && (namerec->data.num_ips == 1)
+ && ip_equal( namerec->data.ip[0], from_ip )
+ && ip_equal(namerec->data.wins_ip, our_fake_ip) ) {
+ update_name_ttl( namerec, ttl );
+ send_wins_name_registration_response( 0, ttl, p );
+ wins_hook("refresh", namerec, ttl);
+ return;
+ }
+
+ /*
+ * Finally if the name exists do a query to the registering machine
+ * to see if they still claim to have the name.
+ */
+
+ if( namerec != NULL ) {
+ long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
+ struct userdata_struct *userdata = (struct userdata_struct *)ud;
+
+ /*
+ * First send a WACK to the registering machine.
+ */
+
+ send_wins_wack_response(60, p);
+
+ /*
+ * When the reply comes back we need the original packet.
+ * Lock this so it won't be freed and then put it into
+ * the userdata structure.
+ */
+
+ p->locked = True;
+
+ userdata = (struct userdata_struct *)ud;
+
+ userdata->copy_fn = NULL;
+ userdata->free_fn = NULL;
+ userdata->userdata_len = sizeof(struct packet_struct *);
+ memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
+
+ /*
+ * Use the new call to send a query directly to an IP address.
+ * This sends the query directly to the IP address, and ensures
+ * the recursion desired flag is not set (you were right Luke :-).
+ * This function should *only* be called from the WINS server
+ * code. JRA.
+ */
+
+ pull_ascii_nstring(name, question->name);
+ query_name_from_wins_server( *namerec->data.ip,
+ name,
+ question->name_type,
+ wins_register_query_success,
+ wins_register_query_fail,
+ userdata );
+ return;
+ }
+
+ /*
+ * Name did not exist - add it.
+ */
+
+ pull_ascii_nstring(name, question->name);
+ add_name_to_subnet( subrec, name, question->name_type,
+ nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
+
+ if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
+ get_global_id_and_update(&namerec->data.id, True);
+ update_wins_owner(namerec, our_fake_ip);
+ update_wins_flag(namerec, WINS_ACTIVE);
+ wins_hook("add", namerec, ttl);
+ }
+
+ send_wins_name_registration_response(0, ttl, p);
}
/***********************************************************************
@@ -1017,55 +977,54 @@ static void wins_multihomed_register_query_success(struct subnet_record *subrec,
struct in_addr ip,
struct res_rec *answers)
{
- struct packet_struct *orig_reg_packet;
- struct nmb_packet *nmb;
- struct name_record *namerec = NULL;
- struct in_addr from_ip;
- int ttl;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
-
- memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
-
- nmb = &orig_reg_packet->packet.nmb;
-
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
- ttl = get_ttl_from_packet(nmb);
-
- /*
- * We want to just add the new IP, as we now know the requesting
- * machine claims to own it. But we can't just do that as an arbitary
- * amount of time may have taken place between the name query
- * request and this response. So we check that
- * the name still exists and is in the same state - if so
- * we just add the extra IP and update the ttl.
- */
-
- namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
-
- if( (namerec == NULL) || (namerec->data.source != REGISTER_NAME) || !WINS_STATE_ACTIVE(namerec) )
- {
- DEBUG(3,("wins_multihomed_register_query_success: name %s is not in the correct state to add \
+ struct packet_struct *orig_reg_packet;
+ struct nmb_packet *nmb;
+ struct name_record *namerec = NULL;
+ struct in_addr from_ip;
+ int ttl;
+ struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
+
+ memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
+
+ nmb = &orig_reg_packet->packet.nmb;
+
+ putip((char *)&from_ip,&nmb->additional->rdata[2]);
+ ttl = get_ttl_from_packet(nmb);
+
+ /*
+ * We want to just add the new IP, as we now know the requesting
+ * machine claims to own it. But we can't just do that as an arbitary
+ * amount of time may have taken place between the name query
+ * request and this response. So we check that
+ * the name still exists and is in the same state - if so
+ * we just add the extra IP and update the ttl.
+ */
+
+ namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
+
+ if( (namerec == NULL) || (namerec->data.source != REGISTER_NAME) || !WINS_STATE_ACTIVE(namerec) ) {
+ DEBUG(3,("wins_multihomed_register_query_success: name %s is not in the correct state to add \
a subsequent IP address.\n", nmb_namestr(question_name) ));
- send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
+ send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
- orig_reg_packet->locked = False;
- free_packet(orig_reg_packet);
+ orig_reg_packet->locked = False;
+ free_packet(orig_reg_packet);
- return;
- }
+ return;
+ }
- if(!find_ip_in_name_record(namerec, from_ip))
- add_ip_to_name_record(namerec, from_ip);
+ if(!find_ip_in_name_record(namerec, from_ip))
+ add_ip_to_name_record(namerec, from_ip);
- get_global_id_and_update(&namerec->data.id, True);
- update_wins_owner(namerec, our_fake_ip);
- update_wins_flag(namerec, WINS_ACTIVE);
- update_name_ttl(namerec, ttl);
- send_wins_name_registration_response(0, ttl, orig_reg_packet);
- wins_hook("add", namerec, ttl);
+ get_global_id_and_update(&namerec->data.id, True);
+ update_wins_owner(namerec, our_fake_ip);
+ update_wins_flag(namerec, WINS_ACTIVE);
+ update_name_ttl(namerec, ttl);
+ send_wins_name_registration_response(0, ttl, orig_reg_packet);
+ wins_hook("add", namerec, ttl);
- orig_reg_packet->locked = False;
- free_packet(orig_reg_packet);
+ orig_reg_packet->locked = False;
+ free_packet(orig_reg_packet);
}
/***********************************************************************
@@ -1081,18 +1040,18 @@ static void wins_multihomed_register_query_fail(struct subnet_record *subrec,
struct nmb_name *question_name,
int rcode)
{
- struct userdata_struct *userdata = rrec->userdata;
- struct packet_struct *orig_reg_packet;
+ struct userdata_struct *userdata = rrec->userdata;
+ struct packet_struct *orig_reg_packet;
- memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
+ memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
- DEBUG(3,("wins_multihomed_register_query_fail: Registering machine at IP %s failed to answer \
+ DEBUG(3,("wins_multihomed_register_query_fail: Registering machine at IP %s failed to answer \
query successfully for name %s.\n", inet_ntoa(orig_reg_packet->ip), nmb_namestr(question_name) ));
- send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
+ send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
- orig_reg_packet->locked = False;
- free_packet(orig_reg_packet);
- return;
+ orig_reg_packet->locked = False;
+ free_packet(orig_reg_packet);
+ return;
}
/***********************************************************************
@@ -1103,250 +1062,241 @@ query successfully for name %s.\n", inet_ntoa(orig_reg_packet->ip), nmb_namestr(
void wins_process_multihomed_name_registration_request( struct subnet_record *subrec,
struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
- int ttl = get_ttl_from_packet(nmb);
- struct name_record *namerec = NULL;
- struct in_addr from_ip;
- BOOL group = (nb_flags & NB_GROUP) ? True : False;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
-
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
-
- if(bcast)
- {
- /*
- * We should only get unicast name registration packets here.
- * Anyone trying to register broadcast should not be going to a WINS
- * server. Log an error here.
- */
-
- DEBUG(0,("wins_process_multihomed_name_registration_request: broadcast name registration request \
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct nmb_name *question = &nmb->question.question_name;
+ BOOL bcast = nmb->header.nm_flags.bcast;
+ uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
+ int ttl = get_ttl_from_packet(nmb);
+ struct name_record *namerec = NULL;
+ struct in_addr from_ip;
+ BOOL group = (nb_flags & NB_GROUP) ? True : False;
+ struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
+ nstring qname;
+
+ putip((char *)&from_ip,&nmb->additional->rdata[2]);
+
+ if(bcast) {
+ /*
+ * We should only get unicast name registration packets here.
+ * Anyone trying to register broadcast should not be going to a WINS
+ * server. Log an error here.
+ */
+
+ DEBUG(0,("wins_process_multihomed_name_registration_request: broadcast name registration request \
received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
- nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- return;
- }
+ nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
+ return;
+ }
- /*
- * Only unique names should be registered multihomed.
- */
+ /*
+ * Only unique names should be registered multihomed.
+ */
- if(group)
- {
- DEBUG(0,("wins_process_multihomed_name_registration_request: group name registration request \
+ if(group) {
+ DEBUG(0,("wins_process_multihomed_name_registration_request: group name registration request \
received for name %s from IP %s on subnet %s. Errror - group names should not be multihomed.\n",
- nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- return;
- }
+ nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
+ return;
+ }
- DEBUG(3,("wins_process_multihomed_name_registration_request: name registration for name %s \
+ DEBUG(3,("wins_process_multihomed_name_registration_request: name registration for name %s \
IP %s\n", nmb_namestr(question), inet_ntoa(from_ip) ));
- /*
- * Deal with policy regarding 0x1d names.
- */
+ /*
+ * Deal with policy regarding 0x1d names.
+ */
- if(question->name_type == 0x1d)
- {
- DEBUG(3,("wins_process_multihomed_name_registration_request: Ignoring request \
+ if(question->name_type == 0x1d) {
+ DEBUG(3,("wins_process_multihomed_name_registration_request: Ignoring request \
to register name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
- send_wins_name_registration_response(0, ttl, p);
- return;
- }
-
- /*
- * See if the name already exists.
- */
-
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
-
- /*
- * if the record exists but NOT in active state,
- * consider it dead.
- */
- if ((namerec != NULL) && !WINS_STATE_ACTIVE(namerec)) {
- DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was not active - removing it.\n", nmb_namestr(question)));
- remove_name_from_namelist(subrec, namerec);
- namerec = NULL;
- }
+ send_wins_name_registration_response(0, ttl, p);
+ return;
+ }
+
+ /*
+ * See if the name already exists.
+ */
+
+ namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
+
+ /*
+ * if the record exists but NOT in active state,
+ * consider it dead.
+ */
+
+ if ((namerec != NULL) && !WINS_STATE_ACTIVE(namerec)) {
+ DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was not active - removing it.\n", nmb_namestr(question)));
+ remove_name_from_namelist(subrec, namerec);
+ namerec = NULL;
+ }
- /*
- * Deal with the case where the name found was a dns entry.
- * Remove it as we now have a NetBIOS client registering the
- * name.
- */
-
- if( (namerec != NULL)
- && ( (namerec->data.source == DNS_NAME)
- || (namerec->data.source == DNSFAIL_NAME) ) )
- {
- DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was a dns lookup \
+ /*
+ * Deal with the case where the name found was a dns entry.
+ * Remove it as we now have a NetBIOS client registering the
+ * name.
+ */
+
+ if( (namerec != NULL) && ( (namerec->data.source == DNS_NAME) || (namerec->data.source == DNSFAIL_NAME) ) ) {
+ DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was a dns lookup \
- removing it.\n", nmb_namestr(question) ));
- remove_name_from_namelist( subrec, namerec);
- namerec = NULL;
- }
-
- /*
- * Reject if the name exists and is not a REGISTER_NAME.
- * (ie. Don't allow any static names to be overwritten.
- */
-
- if( (namerec != NULL) && (namerec->data.source != REGISTER_NAME) )
- {
- DEBUG( 3, ( "wins_process_multihomed_name_registration_request: Attempt \
+ remove_name_from_namelist( subrec, namerec);
+ namerec = NULL;
+ }
+
+ /*
+ * Reject if the name exists and is not a REGISTER_NAME.
+ * (ie. Don't allow any static names to be overwritten.
+ */
+
+ if( (namerec != NULL) && (namerec->data.source != REGISTER_NAME) ) {
+ DEBUG( 3, ( "wins_process_multihomed_name_registration_request: Attempt \
to register name %s. Name already exists in WINS with source type %d.\n",
- nmb_namestr(question), namerec->data.source ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
-
- /*
- * Reject if the name exists and is a GROUP name and is active.
- */
-
- if((namerec != NULL) && NAME_GROUP(namerec) && WINS_STATE_ACTIVE(namerec))
- {
- DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
+ nmb_namestr(question), namerec->data.source ));
+ send_wins_name_registration_response(RFS_ERR, 0, p);
+ return;
+ }
+
+ /*
+ * Reject if the name exists and is a GROUP name and is active.
+ */
+
+ if((namerec != NULL) && NAME_GROUP(namerec) && WINS_STATE_ACTIVE(namerec)) {
+ DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
-
- /*
- * From here on down we know that if the name exists in the WINS db it is
- * a unique name, not a group name.
- */
-
- /*
- * If the name exists and is one of our names then check the
- * registering IP address. If it's not one of ours then automatically
- * reject without doing the query - we know we will reject it.
- */
-
- if((namerec != NULL) && (is_myname(namerec->name.name)) )
- {
- if(!ismyip(from_ip))
- {
- DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
+ send_wins_name_registration_response(RFS_ERR, 0, p);
+ return;
+ }
+
+ /*
+ * From here on down we know that if the name exists in the WINS db it is
+ * a unique name, not a group name.
+ */
+
+ /*
+ * If the name exists and is one of our names then check the
+ * registering IP address. If it's not one of ours then automatically
+ * reject without doing the query - we know we will reject it.
+ */
+
+ if((namerec != NULL) && (is_myname(namerec->name.name)) ) {
+ if(!ismyip(from_ip)) {
+ DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
- send_wins_name_registration_response(RFS_ERR, 0, p);
- return;
- }
- else
- {
- /*
- * It's one of our names and one of our IP's. Ensure the IP is in the record and
- * update the ttl. Update the version ID to force replication.
- */
- if(!find_ip_in_name_record(namerec, from_ip)) {
- get_global_id_and_update(&namerec->data.id, True);
- update_wins_owner(namerec, our_fake_ip);
- update_wins_flag(namerec, WINS_ACTIVE);
-
- add_ip_to_name_record(namerec, from_ip);
- wins_hook("add", namerec, ttl);
- } else {
- wins_hook("refresh", namerec, ttl);
- }
-
- update_name_ttl(namerec, ttl);
- send_wins_name_registration_response(0, ttl, p);
- return;
- }
- }
-
- /*
- * If the name exists and is active, check if the IP address is already registered
- * to that name. If so then update the ttl and reply success.
- */
-
- if((namerec != NULL) && find_ip_in_name_record(namerec, from_ip) && WINS_STATE_ACTIVE(namerec))
- {
- update_name_ttl(namerec, ttl);
- /*
- * If it's a replica, we need to become the wins owner
- * to force the replication
- */
- if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
- get_global_id_and_update(&namerec->data.id, True);
- update_wins_owner(namerec, our_fake_ip);
- update_wins_flag(namerec, WINS_ACTIVE);
- }
+ send_wins_name_registration_response(RFS_ERR, 0, p);
+ return;
+ } else {
+ /*
+ * It's one of our names and one of our IP's. Ensure the IP is in the record and
+ * update the ttl. Update the version ID to force replication.
+ */
+ if(!find_ip_in_name_record(namerec, from_ip)) {
+ get_global_id_and_update(&namerec->data.id, True);
+ update_wins_owner(namerec, our_fake_ip);
+ update_wins_flag(namerec, WINS_ACTIVE);
+
+ add_ip_to_name_record(namerec, from_ip);
+ wins_hook("add", namerec, ttl);
+ } else {
+ wins_hook("refresh", namerec, ttl);
+ }
+
+ update_name_ttl(namerec, ttl);
+ send_wins_name_registration_response(0, ttl, p);
+ return;
+ }
+ }
+
+ /*
+ * If the name exists and is active, check if the IP address is already registered
+ * to that name. If so then update the ttl and reply success.
+ */
+
+ if((namerec != NULL) && find_ip_in_name_record(namerec, from_ip) && WINS_STATE_ACTIVE(namerec)) {
+ update_name_ttl(namerec, ttl);
+
+ /*
+ * If it's a replica, we need to become the wins owner
+ * to force the replication
+ */
+ if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
+ get_global_id_and_update(&namerec->data.id, True);
+ update_wins_owner(namerec, our_fake_ip);
+ update_wins_flag(namerec, WINS_ACTIVE);
+ }
- send_wins_name_registration_response(0, ttl, p);
- wins_hook("refresh", namerec, ttl);
- return;
- }
-
- /*
- * If the name exists do a query to the owner
- * to see if they still want the name.
- */
-
- if(namerec != NULL)
- {
- long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
- struct userdata_struct *userdata = (struct userdata_struct *)ud;
-
- /*
- * First send a WACK to the registering machine.
- */
-
- send_wins_wack_response(60, p);
-
- /*
- * When the reply comes back we need the original packet.
- * Lock this so it won't be freed and then put it into
- * the userdata structure.
- */
-
- p->locked = True;
-
- userdata = (struct userdata_struct *)ud;
-
- userdata->copy_fn = NULL;
- userdata->free_fn = NULL;
- userdata->userdata_len = sizeof(struct packet_struct *);
- memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
-
- /*
- * Use the new call to send a query directly to an IP address.
- * This sends the query directly to the IP address, and ensures
- * the recursion desired flag is not set (you were right Luke :-).
- * This function should *only* be called from the WINS server
- * code. JRA.
- *
- * Note that this packet is sent to the current owner of the name,
- * not the person who sent the packet
- */
-
- query_name_from_wins_server( namerec->data.ip[0],
- question->name,
- question->name_type,
- wins_multihomed_register_query_success,
- wins_multihomed_register_query_fail,
- userdata );
-
- return;
- }
-
- /*
- * Name did not exist - add it.
- */
-
- (void)add_name_to_subnet( subrec, question->name, question->name_type,
- nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
-
- if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
- get_global_id_and_update(&namerec->data.id, True);
- update_wins_owner(namerec, our_fake_ip);
- update_wins_flag(namerec, WINS_ACTIVE);
- wins_hook("add", namerec, ttl);
- }
-
- send_wins_name_registration_response(0, ttl, p);
+ send_wins_name_registration_response(0, ttl, p);
+ wins_hook("refresh", namerec, ttl);
+ return;
+ }
+
+ /*
+ * If the name exists do a query to the owner
+ * to see if they still want the name.
+ */
+
+ if(namerec != NULL) {
+ long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
+ struct userdata_struct *userdata = (struct userdata_struct *)ud;
+
+ /*
+ * First send a WACK to the registering machine.
+ */
+
+ send_wins_wack_response(60, p);
+
+ /*
+ * When the reply comes back we need the original packet.
+ * Lock this so it won't be freed and then put it into
+ * the userdata structure.
+ */
+
+ p->locked = True;
+
+ userdata = (struct userdata_struct *)ud;
+
+ userdata->copy_fn = NULL;
+ userdata->free_fn = NULL;
+ userdata->userdata_len = sizeof(struct packet_struct *);
+ memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
+
+ /*
+ * Use the new call to send a query directly to an IP address.
+ * This sends the query directly to the IP address, and ensures
+ * the recursion desired flag is not set (you were right Luke :-).
+ * This function should *only* be called from the WINS server
+ * code. JRA.
+ *
+ * Note that this packet is sent to the current owner of the name,
+ * not the person who sent the packet
+ */
+
+ pull_ascii_nstring( qname, question->name);
+ query_name_from_wins_server( namerec->data.ip[0],
+ qname,
+ question->name_type,
+ wins_multihomed_register_query_success,
+ wins_multihomed_register_query_fail,
+ userdata );
+
+ return;
+ }
+
+ /*
+ * Name did not exist - add it.
+ */
+
+ pull_ascii_nstring( qname, question->name);
+ add_name_to_subnet( subrec, qname, question->name_type,
+ nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
+
+ if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
+ get_global_id_and_update(&namerec->data.id, True);
+ update_wins_owner(namerec, our_fake_ip);
+ update_wins_flag(namerec, WINS_ACTIVE);
+ wins_hook("add", namerec, ttl);
+ }
+
+ send_wins_name_registration_response(0, ttl, p);
}
/***********************************************************************
@@ -1356,76 +1306,68 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
static void process_wins_dmb_query_request(struct subnet_record *subrec,
struct packet_struct *p)
{
- struct name_record *namerec = NULL;
- char *prdata;
- int num_ips;
-
- /*
- * Go through all the ACTIVE names in the WINS db looking for those
- * ending in <1b>. Use this to calculate the number of IP
- * addresses we need to return.
- */
-
- num_ips = 0;
- for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
- namerec;
- namerec = (struct name_record *)ubi_trNext( namerec ) )
- {
- if(WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b )
- num_ips += namerec->data.num_ips;
- }
-
- if(num_ips == 0)
- {
- /*
- * There are no 0x1b names registered. Return name query fail.
- */
- send_wins_name_query_response(NAM_ERR, p, NULL);
- return;
- }
-
- if((prdata = (char *)malloc( num_ips * 6 )) == NULL)
- {
- DEBUG(0,("process_wins_dmb_query_request: Malloc fail !.\n"));
- return;
- }
-
- /*
- * Go through all the names again in the WINS db looking for those
- * ending in <1b>. Add their IP addresses into the list we will
- * return.
- */
-
- num_ips = 0;
- for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
- namerec;
- namerec = (struct name_record *)ubi_trNext( namerec ) )
- {
- if(WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b)
- {
- int i;
- for(i = 0; i < namerec->data.num_ips; i++)
- {
- set_nb_flags(&prdata[num_ips * 6],namerec->data.nb_flags);
- putip((char *)&prdata[(num_ips * 6) + 2], &namerec->data.ip[i]);
- num_ips++;
- }
- }
- }
-
- /*
- * Send back the reply containing the IP list.
- */
-
- reply_netbios_packet(p, /* Packet to reply to. */
- 0, /* Result code. */
- WINS_QUERY, /* nmbd type code. */
- NMB_NAME_QUERY_OPCODE, /* opcode. */
- lp_min_wins_ttl(), /* ttl. */
- prdata, /* data to send. */
- num_ips*6); /* data length. */
-
- SAFE_FREE(prdata);
+ struct name_record *namerec = NULL;
+ char *prdata;
+ int num_ips;
+
+ /*
+ * Go through all the ACTIVE names in the WINS db looking for those
+ * ending in <1b>. Use this to calculate the number of IP
+ * addresses we need to return.
+ */
+
+ num_ips = 0;
+ for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
+ namerec; namerec = (struct name_record *)ubi_trNext( namerec ) ) {
+ if(WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b )
+ num_ips += namerec->data.num_ips;
+ }
+
+ if(num_ips == 0) {
+ /*
+ * There are no 0x1b names registered. Return name query fail.
+ */
+ send_wins_name_query_response(NAM_ERR, p, NULL);
+ return;
+ }
+
+ if((prdata = (char *)malloc( num_ips * 6 )) == NULL) {
+ DEBUG(0,("process_wins_dmb_query_request: Malloc fail !.\n"));
+ return;
+ }
+
+ /*
+ * Go through all the names again in the WINS db looking for those
+ * ending in <1b>. Add their IP addresses into the list we will
+ * return.
+ */
+
+ num_ips = 0;
+ for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
+ namerec; namerec = (struct name_record *)ubi_trNext( namerec ) ) {
+ if(WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b) {
+ int i;
+ for(i = 0; i < namerec->data.num_ips; i++) {
+ set_nb_flags(&prdata[num_ips * 6],namerec->data.nb_flags);
+ putip((char *)&prdata[(num_ips * 6) + 2], &namerec->data.ip[i]);
+ num_ips++;
+ }
+ }
+ }
+
+ /*
+ * Send back the reply containing the IP list.
+ */
+
+ reply_netbios_packet(p, /* Packet to reply to. */
+ 0, /* Result code. */
+ WINS_QUERY, /* nmbd type code. */
+ NMB_NAME_QUERY_OPCODE, /* opcode. */
+ lp_min_wins_ttl(), /* ttl. */
+ prdata, /* data to send. */
+ num_ips*6); /* data length. */
+
+ SAFE_FREE(prdata);
}
/****************************************************************************
@@ -1435,55 +1377,48 @@ Send a WINS name query response.
void send_wins_name_query_response(int rcode, struct packet_struct *p,
struct name_record *namerec)
{
- char rdata[6];
- char *prdata = rdata;
- int reply_data_len = 0;
- int ttl = 0;
- int i;
-
- memset(rdata,'\0',6);
-
- if(rcode == 0)
- {
- ttl = (namerec->data.death_time != PERMANENT_TTL) ?
- namerec->data.death_time - p->timestamp : lp_max_wins_ttl();
-
- /* Copy all known ip addresses into the return data. */
- /* Optimise for the common case of one IP address so
- we don't need a malloc. */
-
- if( namerec->data.num_ips == 1 )
- prdata = rdata;
- else
- {
- if((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL)
- {
- DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
- return;
- }
- }
-
- for(i = 0; i < namerec->data.num_ips; i++)
- {
- set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
- putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
- }
-
- sort_query_replies(prdata, i, p->ip);
-
- reply_data_len = namerec->data.num_ips * 6;
- }
-
- reply_netbios_packet(p, /* Packet to reply to. */
- rcode, /* Result code. */
- WINS_QUERY, /* nmbd type code. */
- NMB_NAME_QUERY_OPCODE, /* opcode. */
- ttl, /* ttl. */
- prdata, /* data to send. */
- reply_data_len); /* data length. */
-
- if(prdata != rdata)
- SAFE_FREE(prdata);
+ char rdata[6];
+ char *prdata = rdata;
+ int reply_data_len = 0;
+ int ttl = 0;
+ int i;
+
+ memset(rdata,'\0',6);
+
+ if(rcode == 0) {
+ ttl = (namerec->data.death_time != PERMANENT_TTL) ? namerec->data.death_time - p->timestamp : lp_max_wins_ttl();
+
+ /* Copy all known ip addresses into the return data. */
+ /* Optimise for the common case of one IP address so we don't need a malloc. */
+
+ if( namerec->data.num_ips == 1 ) {
+ prdata = rdata;
+ } else {
+ if((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL) {
+ DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
+ return;
+ }
+ }
+
+ for(i = 0; i < namerec->data.num_ips; i++) {
+ set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
+ putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
+ }
+
+ sort_query_replies(prdata, i, p->ip);
+ reply_data_len = namerec->data.num_ips * 6;
+ }
+
+ reply_netbios_packet(p, /* Packet to reply to. */
+ rcode, /* Result code. */
+ WINS_QUERY, /* nmbd type code. */
+ NMB_NAME_QUERY_OPCODE, /* opcode. */
+ ttl, /* ttl. */
+ prdata, /* data to send. */
+ reply_data_len); /* data length. */
+
+ if(prdata != rdata)
+ SAFE_FREE(prdata);
}
/***********************************************************************
@@ -1493,93 +1428,87 @@ void send_wins_name_query_response(int rcode, struct packet_struct *p,
void wins_process_name_query_request(struct subnet_record *subrec,
struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- struct name_record *namerec = NULL;
-
- DEBUG(3,("wins_process_name_query: name query for name %s from IP %s\n",
- nmb_namestr(question), inet_ntoa(p->ip) ));
-
- /*
- * Special name code. If the queried name is *<1b> then search
- * the entire WINS database and return a list of all the IP addresses
- * registered to any <1b> name. This is to allow domain master browsers
- * to discover other domains that may not have a presence on their subnet.
- */
-
- if(strequal( question->name, "*") && (question->name_type == 0x1b))
- {
- process_wins_dmb_query_request( subrec, p);
- return;
- }
-
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
-
- if(namerec != NULL)
- {
- /*
- * If the name is not anymore in active state then reply not found.
- * it's fair even if we keep it in the cache for days.
- */
- if (!WINS_STATE_ACTIVE(namerec))
- {
- DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
- nmb_namestr(question) ));
- send_wins_name_query_response(NAM_ERR, p, namerec);
- return;
- }
- /*
- * If it's a DNSFAIL_NAME then reply name not found.
- */
-
- if( namerec->data.source == DNSFAIL_NAME )
- {
- DEBUG(3,("wins_process_name_query: name query for name %s returning DNS fail.\n",
- nmb_namestr(question) ));
- send_wins_name_query_response(NAM_ERR, p, namerec);
- return;
- }
-
- /*
- * If the name has expired then reply name not found.
- */
-
- if( (namerec->data.death_time != PERMANENT_TTL)
- && (namerec->data.death_time < p->timestamp) )
- {
- DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
- nmb_namestr(question) ));
- send_wins_name_query_response(NAM_ERR, p, namerec);
- return;
- }
-
- DEBUG(3,("wins_process_name_query: name query for name %s returning first IP %s.\n",
- nmb_namestr(question), inet_ntoa(namerec->data.ip[0]) ));
-
- send_wins_name_query_response(0, p, namerec);
- return;
- }
-
- /*
- * Name not found in WINS - try a dns query if it's a 0x20 name.
- */
-
- if(lp_dns_proxy() &&
- ((question->name_type == 0x20) || question->name_type == 0))
- {
-
- DEBUG(3,("wins_process_name_query: name query for name %s not found - doing dns lookup.\n",
- nmb_namestr(question) ));
-
- queue_dns_query(p, question, &namerec);
- return;
- }
-
- /*
- * Name not found - return error.
- */
-
- send_wins_name_query_response(NAM_ERR, p, NULL);
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct nmb_name *question = &nmb->question.question_name;
+ struct name_record *namerec = NULL;
+ nstring qname;
+
+ DEBUG(3,("wins_process_name_query: name query for name %s from IP %s\n",
+ nmb_namestr(question), inet_ntoa(p->ip) ));
+
+ /*
+ * Special name code. If the queried name is *<1b> then search
+ * the entire WINS database and return a list of all the IP addresses
+ * registered to any <1b> name. This is to allow domain master browsers
+ * to discover other domains that may not have a presence on their subnet.
+ */
+
+ pull_ascii_nstring(qname, question->name);
+ if(strequal( qname, "*") && (question->name_type == 0x1b)) {
+ process_wins_dmb_query_request( subrec, p);
+ return;
+ }
+
+ namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
+
+ if(namerec != NULL) {
+ /*
+ * If the name is not anymore in active state then reply not found.
+ * it's fair even if we keep it in the cache for days.
+ */
+ if (!WINS_STATE_ACTIVE(namerec)) {
+ DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
+ nmb_namestr(question) ));
+ send_wins_name_query_response(NAM_ERR, p, namerec);
+ return;
+ }
+
+ /*
+ * If it's a DNSFAIL_NAME then reply name not found.
+ */
+
+ if( namerec->data.source == DNSFAIL_NAME ) {
+ DEBUG(3,("wins_process_name_query: name query for name %s returning DNS fail.\n",
+ nmb_namestr(question) ));
+ send_wins_name_query_response(NAM_ERR, p, namerec);
+ return;
+ }
+
+ /*
+ * If the name has expired then reply name not found.
+ */
+
+ if( (namerec->data.death_time != PERMANENT_TTL) && (namerec->data.death_time < p->timestamp) ) {
+ DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
+ nmb_namestr(question) ));
+ send_wins_name_query_response(NAM_ERR, p, namerec);
+ return;
+ }
+
+ DEBUG(3,("wins_process_name_query: name query for name %s returning first IP %s.\n",
+ nmb_namestr(question), inet_ntoa(namerec->data.ip[0]) ));
+
+ send_wins_name_query_response(0, p, namerec);
+ return;
+ }
+
+ /*
+ * Name not found in WINS - try a dns query if it's a 0x20 name.
+ */
+
+ if(lp_dns_proxy() && ((question->name_type == 0x20) || question->name_type == 0)) {
+ DEBUG(3,("wins_process_name_query: name query for name %s not found - doing dns lookup.\n",
+ nmb_namestr(question) ));
+
+ queue_dns_query(p, question, &namerec);
+ return;
+ }
+
+ /*
+ * Name not found - return error.
+ */
+
+ send_wins_name_query_response(NAM_ERR, p, NULL);
}
/****************************************************************************
@@ -1588,18 +1517,18 @@ Send a WINS name release response.
static void send_wins_name_release_response(int rcode, struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- char rdata[6];
-
- memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
-
- reply_netbios_packet(p, /* Packet to reply to. */
- rcode, /* Result code. */
- NMB_REL, /* nmbd type code. */
- NMB_NAME_RELEASE_OPCODE, /* opcode. */
- 0, /* ttl. */
- rdata, /* data to send. */
- 6); /* data length. */
+ struct nmb_packet *nmb = &p->packet.nmb;
+ char rdata[6];
+
+ memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
+
+ reply_netbios_packet(p, /* Packet to reply to. */
+ rcode, /* Result code. */
+ NMB_REL, /* nmbd type code. */
+ NMB_NAME_RELEASE_OPCODE, /* opcode. */
+ 0, /* ttl. */
+ rdata, /* data to send. */
+ 6); /* data length. */
}
/***********************************************************************
@@ -1609,123 +1538,115 @@ static void send_wins_name_release_response(int rcode, struct packet_struct *p)
void wins_process_name_release_request(struct subnet_record *subrec,
struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
- struct name_record *namerec = NULL;
- struct in_addr from_ip;
- BOOL releasing_group_name = (nb_flags & NB_GROUP) ? True : False;;
-
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
-
- if(bcast)
- {
- /*
- * We should only get unicast name registration packets here.
- * Anyone trying to register broadcast should not be going to a WINS
- * server. Log an error here.
- */
-
- DEBUG(0,("wins_process_name_release_request: broadcast name registration request \
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct nmb_name *question = &nmb->question.question_name;
+ BOOL bcast = nmb->header.nm_flags.bcast;
+ uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
+ struct name_record *namerec = NULL;
+ struct in_addr from_ip;
+ BOOL releasing_group_name = (nb_flags & NB_GROUP) ? True : False;;
+
+ putip((char *)&from_ip,&nmb->additional->rdata[2]);
+
+ if(bcast) {
+ /*
+ * We should only get unicast name registration packets here.
+ * Anyone trying to register broadcast should not be going to a WINS
+ * server. Log an error here.
+ */
+
+ DEBUG(0,("wins_process_name_release_request: broadcast name registration request \
received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
- nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- return;
- }
+ nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
+ return;
+ }
- DEBUG(3,("wins_process_name_release_request: %s name release for name %s \
+ DEBUG(3,("wins_process_name_release_request: %s name release for name %s \
IP %s\n", releasing_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
- /*
- * Deal with policy regarding 0x1d names.
- */
+ /*
+ * Deal with policy regarding 0x1d names.
+ */
- if(!releasing_group_name && (question->name_type == 0x1d))
- {
- DEBUG(3,("wins_process_name_release_request: Ignoring request \
+ if(!releasing_group_name && (question->name_type == 0x1d)) {
+ DEBUG(3,("wins_process_name_release_request: Ignoring request \
to release name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
- send_wins_name_release_response(0, p);
- return;
- }
+ send_wins_name_release_response(0, p);
+ return;
+ }
- /*
- * See if the name already exists.
- */
+ /*
+ * See if the name already exists.
+ */
- namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
-
- if( (namerec == NULL)
- || ((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) )
- {
- send_wins_name_release_response(NAM_ERR, p);
- return;
- }
-
- /*
- * Check that the sending machine has permission to release this name.
- * If it's a group name not ending in 0x1c then just say yes and let
- * the group time out.
- */
-
- if(releasing_group_name && (question->name_type != 0x1c))
- {
- send_wins_name_release_response(0, p);
- return;
- }
-
- /*
- * Check that the releasing node is on the list of IP addresses
- * for this name. Disallow the release if not.
- */
-
- if(!find_ip_in_name_record(namerec, from_ip))
- {
- DEBUG(3,("wins_process_name_release_request: Refusing request to \
+ namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
+
+ if( (namerec == NULL) || ((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) ) {
+ send_wins_name_release_response(NAM_ERR, p);
+ return;
+ }
+
+ /*
+ * Check that the sending machine has permission to release this name.
+ * If it's a group name not ending in 0x1c then just say yes and let
+ * the group time out.
+ */
+
+ if(releasing_group_name && (question->name_type != 0x1c)) {
+ send_wins_name_release_response(0, p);
+ return;
+ }
+
+ /*
+ * Check that the releasing node is on the list of IP addresses
+ * for this name. Disallow the release if not.
+ */
+
+ if(!find_ip_in_name_record(namerec, from_ip)) {
+ DEBUG(3,("wins_process_name_release_request: Refusing request to \
release name %s as IP %s is not one of the known IP's for this name.\n",
- nmb_namestr(question), inet_ntoa(from_ip) ));
- send_wins_name_release_response(NAM_ERR, p);
- return;
- }
-
- /*
- * Check if the record is active. IF it's already released
- * or tombstoned, refuse the release.
- */
- if (!WINS_STATE_ACTIVE(namerec)) {
- DEBUG(3,("wins_process_name_release_request: Refusing request to \
-release name %s as this record is not anymore active.\n",
- nmb_namestr(question) ));
- send_wins_name_release_response(NAM_ERR, p);
- return;
- }
-
- /*
- * Check if the record is a 0x1c group
- * and has more then one ip
- * remove only this address.
- */
-
- if(releasing_group_name &&
- (question->name_type == 0x1c) &&
- (namerec->data.num_ips > 1)) {
- remove_ip_from_name_record(namerec, from_ip);
- DEBUG(3,("wins_process_name_release_request: Remove IP %s from NAME: %s\n",
- inet_ntoa(from_ip),nmb_namestr(question)));
- send_wins_name_release_response(0, p);
- return;
- }
+ nmb_namestr(question), inet_ntoa(from_ip) ));
+ send_wins_name_release_response(NAM_ERR, p);
+ return;
+ }
+
+ /*
+ * Check if the record is active. IF it's already released
+ * or tombstoned, refuse the release.
+ */
+
+ if (!WINS_STATE_ACTIVE(namerec)) {
+ DEBUG(3,("wins_process_name_release_request: Refusing request to \
+release name %s as this record is not active anymore.\n", nmb_namestr(question) ));
+ send_wins_name_release_response(NAM_ERR, p);
+ return;
+ }
+
+ /*
+ * Check if the record is a 0x1c group
+ * and has more then one ip
+ * remove only this address.
+ */
+
+ if(releasing_group_name && (question->name_type == 0x1c) && (namerec->data.num_ips > 1)) {
+ remove_ip_from_name_record(namerec, from_ip);
+ DEBUG(3,("wins_process_name_release_request: Remove IP %s from NAME: %s\n",
+ inet_ntoa(from_ip),nmb_namestr(question)));
+ send_wins_name_release_response(0, p);
+ return;
+ }
- /*
- * Send a release response.
- * Flag the name as released and update the ttl
- */
+ /*
+ * Send a release response.
+ * Flag the name as released and update the ttl
+ */
- send_wins_name_release_response(0, p);
+ send_wins_name_release_response(0, p);
- namerec->data.wins_flags |= WINS_RELEASED;
- update_name_ttl(namerec, EXTINCTION_INTERVAL);
+ namerec->data.wins_flags |= WINS_RELEASED;
+ update_name_ttl(namerec, EXTINCTION_INTERVAL);
- wins_hook("delete", namerec, 0);
+ wins_hook("delete", namerec, 0);
}
/*******************************************************************
@@ -1817,94 +1738,89 @@ we are not the wins owner !\n", nmb_namestr(&namerec->name)));
/*******************************************************************
Write out the current WINS database.
******************************************************************/
+
void wins_write_database(BOOL background)
{
- struct name_record *namerec;
- pstring fname, fnamenew;
+ struct name_record *namerec;
+ pstring fname, fnamenew;
- XFILE *fp;
+ XFILE *fp;
- if(!lp_we_are_a_wins_server())
- return;
-
- /* we will do the writing in a child process to ensure that the parent
- doesn't block while this is done */
- if (background) {
- CatchChild();
- if (sys_fork()) {
- return;
- }
- }
-
- slprintf(fname,sizeof(fname)-1,"%s/%s", lp_lockdir(), WINS_LIST);
- all_string_sub(fname,"//", "/", 0);
- slprintf(fnamenew,sizeof(fnamenew)-1,"%s.%u", fname, (unsigned int)sys_getpid());
-
- if((fp = x_fopen(fnamenew,O_WRONLY|O_CREAT,0644)) == NULL)
- {
- DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
- if (background) {
- _exit(0);
- }
- return;
- }
-
- DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
-
- x_fprintf(fp,"VERSION %d %u\n", WINS_VERSION, 0);
+ if(!lp_we_are_a_wins_server())
+ return;
+
+ /* We will do the writing in a child process to ensure that the parent doesn't block while this is done */
+ if (background) {
+ CatchChild();
+ if (sys_fork()) {
+ return;
+ }
+ }
+
+ slprintf(fname,sizeof(fname)-1,"%s/%s", lp_lockdir(), WINS_LIST);
+ all_string_sub(fname,"//", "/", 0);
+ slprintf(fnamenew,sizeof(fnamenew)-1,"%s.%u", fname, (unsigned int)sys_getpid());
+
+ if((fp = x_fopen(fnamenew,O_WRONLY|O_CREAT,0644)) == NULL) {
+ DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
+ if (background) {
+ _exit(0);
+ }
+ return;
+ }
+
+ DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
+
+ x_fprintf(fp,"VERSION %d %u\n", WINS_VERSION, 0);
- for( namerec
- = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist );
- namerec;
- namerec = (struct name_record *)ubi_trNext( namerec ) )
- {
- int i;
- struct tm *tm;
-
- DEBUGADD(4,("%-19s ", nmb_namestr(&namerec->name) ));
-
- if( namerec->data.death_time != PERMANENT_TTL )
- {
- char *ts, *nl;
-
- tm = LocalTime(&namerec->data.death_time);
- ts = asctime(tm);
- nl = strrchr( ts, '\n' );
- if( NULL != nl )
- *nl = '\0';
- DEBUGADD(4,("TTL = %s ", ts ));
- }
- else
- DEBUGADD(4,("TTL = PERMANENT "));
-
- for (i = 0; i < namerec->data.num_ips; i++)
- DEBUGADD(4,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
- DEBUGADD(4,("%2x\n", namerec->data.nb_flags ));
-
- if( namerec->data.source == REGISTER_NAME )
- {
- x_fprintf(fp, "\"%s#%02x\" %d ",
- namerec->name.name,namerec->name.name_type, /* Ignore scope. */
- (int)namerec->data.death_time);
-
- for (i = 0; i < namerec->data.num_ips; i++)
- x_fprintf( fp, "%s ", inet_ntoa( namerec->data.ip[i] ) );
- x_fprintf( fp, "%2xR\n", namerec->data.nb_flags );
- }
- }
+ for( namerec = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist ); namerec; namerec = (struct name_record *)ubi_trNext( namerec ) ) {
+ int i;
+ struct tm *tm;
+
+ DEBUGADD(4,("%-19s ", nmb_namestr(&namerec->name) ));
+
+ if( namerec->data.death_time != PERMANENT_TTL ) {
+ char *ts, *nl;
+
+ tm = LocalTime(&namerec->data.death_time);
+ ts = asctime(tm);
+ nl = strrchr( ts, '\n' );
+ if( NULL != nl )
+ *nl = '\0';
+ DEBUGADD(4,("TTL = %s ", ts ));
+ } else {
+ DEBUGADD(4,("TTL = PERMANENT "));
+ }
+
+ for (i = 0; i < namerec->data.num_ips; i++)
+ DEBUGADD(4,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
+ DEBUGADD(4,("%2x\n", namerec->data.nb_flags ));
+
+ if( namerec->data.source == REGISTER_NAME ) {
+ nstring name;
+ pull_ascii_nstring(name, namerec->name.name);
+ x_fprintf(fp, "\"%s#%02x\" %d ", name,namerec->name.name_type, /* Ignore scope. */
+ (int)namerec->data.death_time);
+
+ for (i = 0; i < namerec->data.num_ips; i++)
+ x_fprintf( fp, "%s ", inet_ntoa( namerec->data.ip[i] ) );
+ x_fprintf( fp, "%2xR\n", namerec->data.nb_flags );
+ }
+ }
- x_fclose(fp);
- chmod(fnamenew,0644);
- unlink(fname);
- rename(fnamenew,fname);
- if (background) {
- _exit(0);
- }
+ x_fclose(fp);
+ chmod(fnamenew,0644);
+ unlink(fname);
+ rename(fnamenew,fname);
+ if (background) {
+ _exit(0);
+ }
}
/****************************************************************************
-process a internal Samba message receiving a wins record
+ Process a internal Samba message receiving a wins record.
***************************************************************************/
+
void nmbd_wins_new_entry(int msg_type, pid_t src, void *buf, size_t len)
{
WINS_RECORD *record;
@@ -1918,11 +1834,10 @@ void nmbd_wins_new_entry(int msg_type, pid_t src, void *buf, size_t len)
if (buf==NULL)
return;
+ /* Record should use UNIX codepage. Ensure this is so in the wrepld code. JRA. */
record=(WINS_RECORD *)buf;
- ZERO_STRUCT(question);
- memcpy(question.name, record->name, 16);
- question.name_type=record->type;
+ make_nmb_name(&question, record->name, record->type);
namerec = find_name_on_subnet(wins_server_subnet, &question, FIND_ANY_NAME);
@@ -1994,9 +1909,9 @@ void nmbd_wins_new_entry(int msg_type, pid_t src, void *buf, size_t len)
for (i=0; i<record->num_ips; i++)
if(!find_ip_in_name_record(namerec, record->ip[i]))
add_ip_to_name_record(namerec, record->ip[i]);
- }
- else
+ } else {
overwrite=True;
+ }
}
/* the replica is a multihomed host */
diff --git a/source3/nmbd/nmbd_workgroupdb.c b/source3/nmbd/nmbd_workgroupdb.c
index 2357fd637b..08d6fb2c62 100644
--- a/source3/nmbd/nmbd_workgroupdb.c
+++ b/source3/nmbd/nmbd_workgroupdb.c
@@ -31,7 +31,7 @@ int workgroup_count = 0; /* unique index key: one for each workgroup */
/****************************************************************************
Add a workgroup into the list.
- **************************************************************************/
+**************************************************************************/
static void add_workgroup(struct subnet_record *subrec, struct work_record *work)
{
@@ -42,164 +42,153 @@ static void add_workgroup(struct subnet_record *subrec, struct work_record *work
/****************************************************************************
Create an empty workgroup.
- **************************************************************************/
+**************************************************************************/
static struct work_record *create_workgroup(const char *name, int ttl)
{
- struct work_record *work;
- struct subnet_record *subrec;
- int t = -1;
+ struct work_record *work;
+ struct subnet_record *subrec;
+ int t = -1;
- if((work = (struct work_record *)malloc(sizeof(*work))) == NULL)
- {
- DEBUG(0,("create_workgroup: malloc fail !\n"));
- return NULL;
- }
- memset((char *)work, '\0', sizeof(*work));
+ if((work = (struct work_record *)malloc(sizeof(*work))) == NULL) {
+ DEBUG(0,("create_workgroup: malloc fail !\n"));
+ return NULL;
+ }
+ memset((char *)work, '\0', sizeof(*work));
- fstrcpy(work->work_group,name);
- work->serverlist = NULL;
+ fstrcpy(work->work_group,name);
+ work->serverlist = NULL;
- work->RunningElection = False;
- work->ElectionCount = 0;
- work->announce_interval = 0;
- work->needelection = False;
- work->needannounce = True;
- work->lastannounce_time = time(NULL);
- work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
- work->dom_state = DOMAIN_NONE;
- work->log_state = LOGON_NONE;
+ work->RunningElection = False;
+ work->ElectionCount = 0;
+ work->announce_interval = 0;
+ work->needelection = False;
+ work->needannounce = True;
+ work->lastannounce_time = time(NULL);
+ work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
+ work->dom_state = DOMAIN_NONE;
+ work->log_state = LOGON_NONE;
- work->death_time = (ttl != PERMANENT_TTL) ? time(NULL)+(ttl*3) : PERMANENT_TTL;
+ work->death_time = (ttl != PERMANENT_TTL) ? time(NULL)+(ttl*3) : PERMANENT_TTL;
- /* Make sure all token representations of workgroups are unique. */
+ /* Make sure all token representations of workgroups are unique. */
- for (subrec = FIRST_SUBNET; subrec && (t == -1);
- subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
- {
- struct work_record *w;
- for (w = subrec->workgrouplist; w && t == -1; w = w->next)
- {
- if (strequal(w->work_group, work->work_group))
- t = w->token;
- }
- }
+ for (subrec = FIRST_SUBNET; subrec && (t == -1); subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) {
+ struct work_record *w;
+ for (w = subrec->workgrouplist; w && t == -1; w = w->next) {
+ if (strequal(w->work_group, work->work_group))
+ t = w->token;
+ }
+ }
- if (t == -1)
- work->token = ++workgroup_count;
- else
- work->token = t;
+ if (t == -1)
+ work->token = ++workgroup_count;
+ else
+ work->token = t;
- /* No known local master browser as yet. */
- *work->local_master_browser_name = '\0';
-
- /* No known domain master browser as yet. */
- *work->dmb_name.name = '\0';
- zero_ip(&work->dmb_addr);
-
- /* WfWg uses 01040b01 */
- /* Win95 uses 01041501 */
- /* NTAS uses ???????? */
- work->ElectionCriterion = (MAINTAIN_LIST)|(BROWSER_ELECTION_VERSION<<8);
- work->ElectionCriterion |= (lp_os_level() << 24);
- if (lp_domain_master())
- work->ElectionCriterion |= 0x80;
+ /* No known local master browser as yet. */
+ *work->local_master_browser_name = '\0';
+
+ /* No known domain master browser as yet. */
+ *work->dmb_name.name = '\0';
+ zero_ip(&work->dmb_addr);
+
+ /* WfWg uses 01040b01 */
+ /* Win95 uses 01041501 */
+ /* NTAS uses ???????? */
+ work->ElectionCriterion = (MAINTAIN_LIST)|(BROWSER_ELECTION_VERSION<<8);
+ work->ElectionCriterion |= (lp_os_level() << 24);
+ if (lp_domain_master())
+ work->ElectionCriterion |= 0x80;
- return work;
+ return work;
}
/*******************************************************************
Remove a workgroup.
- ******************************************************************/
+******************************************************************/
static struct work_record *remove_workgroup_from_subnet(struct subnet_record *subrec,
struct work_record *work)
{
- struct work_record *ret_work = NULL;
+ struct work_record *ret_work = NULL;
- DEBUG(3,("remove_workgroup: Removing workgroup %s\n", work->work_group));
+ DEBUG(3,("remove_workgroup: Removing workgroup %s\n", work->work_group));
- ret_work = work->next;
+ ret_work = work->next;
- remove_all_servers(work);
+ remove_all_servers(work);
- if (!work->serverlist)
- {
- if (work->prev)
- work->prev->next = work->next;
- if (work->next)
- work->next->prev = work->prev;
+ if (!work->serverlist) {
+ if (work->prev)
+ work->prev->next = work->next;
+ if (work->next)
+ work->next->prev = work->prev;
- if (subrec->workgrouplist == work)
- subrec->workgrouplist = work->next;
+ if (subrec->workgrouplist == work)
+ subrec->workgrouplist = work->next;
- ZERO_STRUCTP(work);
- SAFE_FREE(work);
- }
+ ZERO_STRUCTP(work);
+ SAFE_FREE(work);
+ }
- subrec->work_changed = True;
+ subrec->work_changed = True;
- return ret_work;
+ return ret_work;
}
-
/****************************************************************************
Find a workgroup in the workgroup list of a subnet.
- **************************************************************************/
+**************************************************************************/
struct work_record *find_workgroup_on_subnet(struct subnet_record *subrec,
const char *name)
{
- struct work_record *ret;
+ struct work_record *ret;
- DEBUG(4, ("find_workgroup_on_subnet: workgroup search for %s on subnet %s: ",
- name, subrec->subnet_name));
+ DEBUG(4, ("find_workgroup_on_subnet: workgroup search for %s on subnet %s: ",
+ name, subrec->subnet_name));
- for (ret = subrec->workgrouplist; ret; ret = ret->next)
- {
- if (!strcmp(ret->work_group,name))
- {
- DEBUGADD(4, ("found.\n"));
- return(ret);
- }
- }
- DEBUGADD(4, ("not found.\n"));
- return NULL;
+ for (ret = subrec->workgrouplist; ret; ret = ret->next) {
+ if (strequal(ret->work_group,name)) {
+ DEBUGADD(4, ("found.\n"));
+ return(ret);
+ }
+ }
+ DEBUGADD(4, ("not found.\n"));
+ return NULL;
}
/****************************************************************************
Create a workgroup in the workgroup list of the subnet.
- **************************************************************************/
+**************************************************************************/
struct work_record *create_workgroup_on_subnet(struct subnet_record *subrec,
const char *name, int ttl)
{
- struct work_record *work = NULL;
+ struct work_record *work = NULL;
- DEBUG(4,("create_workgroup_on_subnet: creating group %s on subnet %s\n",
- name, subrec->subnet_name));
+ DEBUG(4,("create_workgroup_on_subnet: creating group %s on subnet %s\n",
+ name, subrec->subnet_name));
- if ((work = create_workgroup(name, ttl)))
- {
- add_workgroup(subrec, work);
-
- subrec->work_changed = True;
+ if ((work = create_workgroup(name, ttl))) {
+ add_workgroup(subrec, work);
+ subrec->work_changed = True;
+ return(work);
+ }
- return(work);
- }
-
- return NULL;
+ return NULL;
}
/****************************************************************************
Update a workgroup ttl.
- **************************************************************************/
+**************************************************************************/
void update_workgroup_ttl(struct work_record *work, int ttl)
{
- if(work->death_time != PERMANENT_TTL)
- work->death_time = time(NULL)+(ttl*3);
- work->subnet->work_changed = True;
+ if(work->death_time != PERMANENT_TTL)
+ work->death_time = time(NULL)+(ttl*3);
+ work->subnet->work_changed = True;
}
/****************************************************************************
@@ -210,8 +199,8 @@ void update_workgroup_ttl(struct work_record *work, int ttl)
static void fail_register(struct subnet_record *subrec, struct response_record *rrec,
struct nmb_name *nmbname)
{
- DEBUG(0,("fail_register: Failed to register name %s on subnet %s.\n",
- nmb_namestr(nmbname), subrec->subnet_name));
+ DEBUG(0,("fail_register: Failed to register name %s on subnet %s.\n",
+ nmb_namestr(nmbname), subrec->subnet_name));
}
/****************************************************************************
@@ -220,50 +209,38 @@ static void fail_register(struct subnet_record *subrec, struct response_record *
void initiate_myworkgroup_startup(struct subnet_record *subrec, struct work_record *work)
{
- int i;
+ int i;
- if(!strequal(lp_workgroup(), work->work_group))
- return;
+ if(!strequal(lp_workgroup(), work->work_group))
+ return;
- /* If this is a broadcast subnet then start elections on it
- if we are so configured. */
+ /* If this is a broadcast subnet then start elections on it if we are so configured. */
- if ((subrec != unicast_subnet) && (subrec != remote_broadcast_subnet) &&
- (subrec != wins_server_subnet) && lp_preferred_master() &&
- lp_local_master())
- {
- DEBUG(3, ("initiate_myworkgroup_startup: preferred master startup for \
+ if ((subrec != unicast_subnet) && (subrec != remote_broadcast_subnet) &&
+ (subrec != wins_server_subnet) && lp_preferred_master() && lp_local_master()) {
+ DEBUG(3, ("initiate_myworkgroup_startup: preferred master startup for \
workgroup %s on subnet %s\n", work->work_group, subrec->subnet_name));
- work->needelection = True;
- work->ElectionCriterion |= (1<<3);
- }
+ work->needelection = True;
+ work->ElectionCriterion |= (1<<3);
+ }
- /* Register the WORKGROUP<0> and WORKGROUP<1e> names on the network. */
+ /* Register the WORKGROUP<0> and WORKGROUP<1e> names on the network. */
- register_name(subrec,lp_workgroup(),0x0,samba_nb_type|NB_GROUP,
- NULL,
- fail_register,NULL);
-
- register_name(subrec,lp_workgroup(),0x1e,samba_nb_type|NB_GROUP,
- NULL,
- fail_register,NULL);
-
- for( i = 0; my_netbios_names(i); i++)
- {
- const char *name = my_netbios_names(i);
- int stype = lp_default_server_announce() | (lp_local_master() ?
- SV_TYPE_POTENTIAL_BROWSER : 0 );
+ register_name(subrec,lp_workgroup(),0x0,samba_nb_type|NB_GROUP, NULL, fail_register,NULL);
+ register_name(subrec,lp_workgroup(),0x1e,samba_nb_type|NB_GROUP, NULL, fail_register,NULL);
+
+ for( i = 0; my_netbios_names(i); i++) {
+ const char *name = my_netbios_names(i);
+ int stype = lp_default_server_announce() | (lp_local_master() ? SV_TYPE_POTENTIAL_BROWSER : 0 );
- if(!strequal(global_myname(), name))
- stype &= ~(SV_TYPE_MASTER_BROWSER|SV_TYPE_POTENTIAL_BROWSER|
- SV_TYPE_DOMAIN_MASTER|SV_TYPE_DOMAIN_MEMBER);
+ if(!strequal(global_myname(), name))
+ stype &= ~(SV_TYPE_MASTER_BROWSER|SV_TYPE_POTENTIAL_BROWSER|SV_TYPE_DOMAIN_MASTER|SV_TYPE_DOMAIN_MEMBER);
- create_server_on_workgroup(work,name,stype|SV_TYPE_LOCAL_LIST_ONLY,
- PERMANENT_TTL,
- string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
- DEBUG(3,("initiate_myworkgroup_startup: Added server name entry %s \
+ create_server_on_workgroup(work,name,stype|SV_TYPE_LOCAL_LIST_ONLY, PERMANENT_TTL,
+ string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
+ DEBUG(3,("initiate_myworkgroup_startup: Added server name entry %s \
on subnet %s\n", name, subrec->subnet_name));
- }
+ }
}
/****************************************************************************
@@ -272,43 +249,34 @@ on subnet %s\n", name, subrec->subnet_name));
void dump_workgroups(BOOL force_write)
{
- struct subnet_record *subrec;
- int debuglevel = force_write ? 0 : 4;
+ struct subnet_record *subrec;
+ int debuglevel = force_write ? 0 : 4;
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
- {
- if (subrec->workgrouplist)
- {
- struct work_record *work;
-
- if( DEBUGLVL( debuglevel ) )
- {
- dbgtext( "dump_workgroups()\n " );
- dbgtext( "dump workgroup on subnet %15s: ", subrec->subnet_name );
- dbgtext( "netmask=%15s:\n", inet_ntoa(subrec->mask_ip) );
- }
-
- for (work = subrec->workgrouplist; work; work = work->next)
- {
- DEBUGADD( debuglevel, ( "\t%s(%d) current master browser = %s\n",
- work->work_group,
- work->token,
- *work->local_master_browser_name
- ? work->local_master_browser_name : "UNKNOWN" ) );
- if (work->serverlist)
- {
- struct server_record *servrec;
- for (servrec = work->serverlist; servrec; servrec = servrec->next)
- {
- DEBUGADD( debuglevel, ( "\t\t%s %8x (%s)\n",
- servrec->serv.name,
- servrec->serv.type,
- servrec->serv.comment ) );
- }
- }
- }
- }
- }
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) {
+ if (subrec->workgrouplist) {
+ struct work_record *work;
+
+ if( DEBUGLVL( debuglevel ) ) {
+ dbgtext( "dump_workgroups()\n " );
+ dbgtext( "dump workgroup on subnet %15s: ", subrec->subnet_name );
+ dbgtext( "netmask=%15s:\n", inet_ntoa(subrec->mask_ip) );
+ }
+
+ for (work = subrec->workgrouplist; work; work = work->next) {
+ DEBUGADD( debuglevel, ( "\t%s(%d) current master browser = %s\n", work->work_group,
+ work->token, *work->local_master_browser_name ? work->local_master_browser_name : "UNKNOWN" ) );
+ if (work->serverlist) {
+ struct server_record *servrec;
+ for (servrec = work->serverlist; servrec; servrec = servrec->next) {
+ DEBUGADD( debuglevel, ( "\t\t%s %8x (%s)\n",
+ servrec->serv.name,
+ servrec->serv.type,
+ servrec->serv.comment ) );
+ }
+ }
+ }
+ }
+ }
}
/****************************************************************************
@@ -318,25 +286,22 @@ void dump_workgroups(BOOL force_write)
void expire_workgroups_and_servers(time_t t)
{
- struct subnet_record *subrec;
+ struct subnet_record *subrec;
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
- {
- struct work_record *work;
- struct work_record *nextwork;
-
- for (work = subrec->workgrouplist; work; work = nextwork)
- {
- nextwork = work->next;
- expire_servers(work, t);
-
- if ((work->serverlist == NULL) && (work->death_time != PERMANENT_TTL) &&
- ((t == -1) || (work->death_time < t)))
- {
- DEBUG(3,("expire_workgroups_and_servers: Removing timed out workgroup %s\n",
- work->work_group));
- remove_workgroup_from_subnet(subrec, work);
- }
- }
- }
+ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) {
+ struct work_record *work;
+ struct work_record *nextwork;
+
+ for (work = subrec->workgrouplist; work; work = nextwork) {
+ nextwork = work->next;
+ expire_servers(work, t);
+
+ if ((work->serverlist == NULL) && (work->death_time != PERMANENT_TTL) &&
+ ((t == -1) || (work->death_time < t))) {
+ DEBUG(3,("expire_workgroups_and_servers: Removing timed out workgroup %s\n",
+ work->work_group));
+ remove_workgroup_from_subnet(subrec, work);
+ }
+ }
+ }
}
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index c0d0e501f3..5d67ae9169 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -563,6 +563,7 @@ static BOOL handle_debug_list( const char *pszParmValue, char **ptr );
static BOOL handle_workgroup( const char *pszParmValue, char **ptr );
static BOOL handle_netbios_aliases( const char *pszParmValue, char **ptr );
static BOOL handle_netbios_scope( const char *pszParmValue, char **ptr );
+static BOOL handle_charset( const char *pszParmValue, char **ptr );
static BOOL handle_ldap_suffix ( const char *pszParmValue, char **ptr );
static BOOL handle_ldap_sub_suffix ( const char *pszParmValue, char **ptr );
@@ -753,9 +754,9 @@ static const struct enum_list enum_map_to_guest[] = {
static struct parm_struct parm_table[] = {
{"Base Options", P_SEP, P_SEPARATOR},
- {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED},
- {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED},
- {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED},
+ {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, handle_charset, NULL, FLAG_ADVANCED},
+ {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, handle_charset, NULL, FLAG_ADVANCED},
+ {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, handle_charset, NULL, FLAG_ADVANCED},
{"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
{"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
{"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
@@ -2701,7 +2702,6 @@ static BOOL handle_netbios_name(const char *pszParmValue, char **ptr)
standard_sub_basic(current_user_info.smb_name, netbios_name,sizeof(netbios_name));
-
ret = set_global_myname(netbios_name);
string_set(&Globals.szNetbiosName,global_myname());
@@ -2711,6 +2711,13 @@ static BOOL handle_netbios_name(const char *pszParmValue, char **ptr)
return ret;
}
+static BOOL handle_charset(const char *pszParmValue, char **ptr)
+{
+ string_set(ptr, pszParmValue);
+ init_iconv();
+ return True;
+}
+
static BOOL handle_workgroup(const char *pszParmValue, char **ptr)
{
BOOL ret;