This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
+#include "nmbd/nmbd.h"
/* This is our local master browser list database. */
-extern ubi_dlList lmb_browserlist[];
+extern struct browse_cache_record *lmb_browserlist;
/****************************************************************************
As a domain master browser, do a sync with a local master browser.
expire_lmb_browsers(t);
- for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist );
- browc;
- browc = (struct browse_cache_record *)ubi_dlNext( browc ) ) {
+ for( browc = lmb_browserlist; browc; browc = browc->next ) {
if (browc->sync_time < t)
sync_with_lmb(browc);
}
static void announce_local_master_browser_to_domain_master_browser( struct work_record *work)
{
- pstring outbuf;
- fstring myname;
+ char outbuf[1024];
+ unstring myname;
+ unstring dmb_name;
char *p;
- if(ismyip(work->dmb_addr)) {
+ if(ismyip_v4(work->dmb_addr)) {
if( DEBUGLVL( 2 ) ) {
dbgtext( "announce_local_master_browser_to_domain_master_browser:\n" );
dbgtext( "We are both a domain and a local master browser for " );
SCVAL(p,0,ANN_MasterAnnouncement);
p++;
- fstrcpy(myname, global_myname());
- strupper_m(myname);
+ unstrcpy(myname, lp_netbios_name());
+ if (!strupper_m(myname)) {
+ DEBUG(2,("strupper_m %s failed\n", myname));
+ return;
+ }
myname[15]='\0';
/* The call below does CH_UNIX -> CH_DOS conversion. JRA */
- push_pstring_base(p, myname, outbuf);
+ push_ascii(p, myname, sizeof(outbuf)-PTR_DIFF(p,outbuf)-1, STR_TERMINATE);
- p = skip_string(p,1);
+ p = skip_string(outbuf,sizeof(outbuf),p);
if( DEBUGLVL( 4 ) ) {
dbgtext( "announce_local_master_browser_to_domain_master_browser:\n" );
work->work_group );
}
+ /* Target name for send_mailslot must be in UNIX charset. */
+ pull_ascii_nstring(dmb_name, sizeof(dmb_name), work->dmb_name.name);
send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
- global_myname(), 0x0, work->dmb_name.name, 0x0,
+ lp_netbios_name(), 0x0, dmb_name, 0x0,
work->dmb_addr, FIRST_SUBNET->myip, DGRAM_PORT);
}
static void sync_with_dmb(struct work_record *work)
{
- nstring dmb_name;
+ unstring dmb_name;
if( DEBUGLVL( 2 ) ) {
dbgtext( "sync_with_dmb:\n" );
dbgtext( "for workgroup %s\n", work->work_group );
}
- pull_ascii_nstring(dmb_name, work->dmb_name.name);
+ pull_ascii_nstring(dmb_name, sizeof(dmb_name), work->dmb_name.name);
sync_browse_lists(work, dmb_name, work->dmb_name.name_type,
work->dmb_addr, False, True);
}
/* Go through the list of names found at answers->rdata and look for
the first SERVER<0x20> name. */
- if(answers->rdata != NULL) {
+ if (answers->rdlength > 0) {
char *p = answers->rdata;
int numnames = CVAL(p, 0);
p += 1;
while (numnames--) {
- nstring qname;
- uint16 nb_flags;
+ unstring qname;
+ uint16_t nb_flags;
int name_type;
- pull_ascii_nstring(qname, p);
+ pull_ascii_nstring(qname, sizeof(qname), p);
name_type = CVAL(p,15);
nb_flags = get_nb_flags(&p[16]);
trim_char(qname,'\0',' ');
struct nmb_name nmbname;
struct userdata_struct *userdata;
size_t size = sizeof(struct userdata_struct) + sizeof(fstring)+1;
- nstring qname;
+ unstring qname;
- pull_ascii_nstring(qname, q_name->name);
+ pull_ascii_nstring(qname, sizeof(qname), q_name->name);
if( !(work = find_workgroup_on_subnet(subrec, qname)) ) {
if( DEBUGLVL( 0 ) ) {
dbgtext( "find_domain_master_name_query_success:\n" );
/* First check if we already have a dmb for this workgroup. */
- if(!is_zero_ip(work->dmb_addr) && ip_equal(work->dmb_addr, answer_ip)) {
+ if(!is_zero_ip_v4(work->dmb_addr) && ip_equal_v4(work->dmb_addr, answer_ip)) {
/* Do the local master browser announcement to the domain
master browser name and IP. */
announce_local_master_browser_to_domain_master_browser( work );
sync_with_dmb(work);
return;
} else {
- zero_ip(&work->dmb_addr);
+ zero_ip_v4(&work->dmb_addr);
}
/* Now initiate the node status request. */
/* Setup the userdata_struct - this is copied so we can use
a stack variable for this. */
- if((userdata = (struct userdata_struct *)malloc(size)) == NULL) {
+ if((userdata = (struct userdata_struct *)SMB_MALLOC(size)) == NULL) {
DEBUG(0, ("find_domain_master_name_query_success: malloc fail.\n"));
return;
}
userdata->copy_fn = NULL;
userdata->free_fn = NULL;
userdata->userdata_len = strlen(work->work_group)+1;
- overmalloc_safe_strcpy(userdata->data, work->work_group, size - sizeof(*userdata) - 1);
+ strlcpy(userdata->data, work->work_group, size - sizeof(*userdata));
node_status( subrec, &nmbname, answer_ip,
domain_master_node_status_success,
struct res_rec *answers,
struct in_addr from_ip)
{
- struct work_record *work;
- fstring server_name;
+ unstring server_name;
server_name[0] = 0;
* the first WORKGROUP<0x1b> name.
*/
- if(answers->rdata != NULL) {
+ if (answers->rdlength > 0) {
char *p = answers->rdata;
int numnames = CVAL(p, 0);
p += 1;
while (numnames--) {
- nstring qname;
- uint16 nb_flags;
+ unstring qname;
+ uint16_t nb_flags;
int name_type;
- pull_ascii_nstring(qname, p);
+ pull_ascii_nstring(qname, sizeof(qname), p);
name_type = CVAL(p,15);
nb_flags = get_nb_flags(&p[16]);
trim_char(qname,'\0',' ');
if(!(nb_flags & NB_GROUP) && (name_type == 0x00) &&
server_name[0] == 0) {
/* this is almost certainly the server netbios name */
- fstrcpy(server_name, qname);
+ strlcpy(server_name, qname, sizeof(server_name));
continue;
}
if(!(nb_flags & NB_GROUP) && (name_type == 0x1b)) {
+ struct work_record *work;
+
if( DEBUGLVL( 5 ) ) {
dbgtext( "get_domain_master_name_node_status_success:\n" );
dbgtext( "%s(%s) ", server_name, inet_ntoa(from_ip) );
* to the workgroup list on the unicast_subnet.
*/
- if((work = find_workgroup_on_subnet( subrec, qname)) == NULL) {
+ work = find_workgroup_on_subnet( subrec, qname);
+ if (work == NULL) {
struct nmb_name nmbname;
/*
* Add it - with an hour in the cache.
*/
- if(!(work= create_workgroup_on_subnet(subrec, qname, 60*60)))
+ work = create_workgroup_on_subnet(subrec, qname, 60*60);
+ if (work == NULL) {
return;
+ }
/* remember who the master is */
- nstrcpy(work->local_master_browser_name, server_name);
+ strlcpy(work->local_master_browser_name,
+ server_name,
+ sizeof(work->local_master_browser_name));
make_nmb_name(&nmbname, server_name, 0x20);
work->dmb_name = nmbname;
work->dmb_addr = from_ip;
break;
}
}
- } else if( DEBUGLVL( 0 ) ) {
+ } else if( DEBUGLVL( 1 ) ) {
dbgtext( "get_domain_master_name_node_status_success:\n" );
dbgtext( "Failed to find a WORKGROUP<0x1b> name in reply from IP " );
dbgtext( "%s.\n", inet_ntoa(from_ip) );
static void get_domain_master_name_node_status_fail(struct subnet_record *subrec,
struct response_record *rrec)
{
- if( DEBUGLVL( 0 ) ) {
+ if( DEBUGLVL( 2 ) ) {
dbgtext( "get_domain_master_name_node_status_fail:\n" );
dbgtext( "Doing a node status request to the domain master browser " );
dbgtext( "at IP %s failed.\n", inet_ntoa(rrec->packet->ip) );
* Don't send node status requests to ourself.
*/
- if(ismyip( send_ip )) {
+ if(ismyip_v4( send_ip )) {
if( DEBUGLVL( 5 ) ) {
dbgtext( "find_all_domain_master_names_query_succes:\n" );
dbgtext( "Not sending node status to our own IP " );
/* count how many syncs we might need to do */
for (work=unicast_subnet->workgrouplist; work; work = work->next) {
- if (strncmp(lp_workgroup(), work->work_group, sizeof(nstring))) {
+ if (strcmp(lp_workgroup(), work->work_group)) {
count++;
}
}
+ /* leave if we don't have to do any syncs */
+ if (count == 0) {
+ return;
+ }
+
/* sync with a probability of 1/count */
for (work=unicast_subnet->workgrouplist; work; work = work->next) {
- if (strncmp(lp_workgroup(), work->work_group, sizeof(nstring))) {
- nstring dmb_name;
+ if (strcmp(lp_workgroup(), work->work_group)) {
+ unstring dmb_name;
if (((unsigned)sys_random()) % count != 0)
continue;
0x20);
}
- pull_ascii_nstring(dmb_name, work->dmb_name.name);
+ pull_ascii_nstring(dmb_name, sizeof(dmb_name), work->dmb_name.name);
DEBUG(3,("Initiating DMB<->DMB sync with %s(%s)\n",
dmb_name, inet_ntoa(work->dmb_addr)));