summaryrefslogtreecommitdiff
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
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)
-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;