summaryrefslogtreecommitdiff
path: root/source3/nmbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nmbd')
-rw-r--r--source3/nmbd/nmbd.c98
-rw-r--r--source3/nmbd/nmbd_become_lmb.c3
-rw-r--r--source3/nmbd/nmbd_browserdb.c139
-rw-r--r--source3/nmbd/nmbd_browsesync.c8
-rw-r--r--source3/nmbd/nmbd_elections.c2
-rw-r--r--source3/nmbd/nmbd_incomingdgrams.c16
-rw-r--r--source3/nmbd/nmbd_incomingrequests.c2
-rw-r--r--source3/nmbd/nmbd_namelistdb.c4
-rw-r--r--source3/nmbd/nmbd_processlogon.c67
-rw-r--r--source3/nmbd/nmbd_sendannounce.c10
-rw-r--r--source3/nmbd/nmbd_serverlistdb.c6
-rw-r--r--source3/nmbd/nmbd_winsserver.c416
-rw-r--r--source3/nmbd/nmbd_workgroupdb.c2
13 files changed, 423 insertions, 350 deletions
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index ad5ab4d734..2801e54551 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -299,12 +299,35 @@ static BOOL reload_nmbd_services(BOOL test)
}
/**************************************************************************** **
+ * React on 'smbcontrol nmbd reload-config' in the same way as to SIGHUP
+ * We use buf here to return BOOL result to process() when reload_interfaces()
+ * detects that there are no subnets.
+ **************************************************************************** */
+static void msg_reload_nmbd_services(int msg_type, pid_t src, void *buf, size_t len)
+{
+ write_browse_list( 0, True );
+ dump_all_namelists();
+ reload_nmbd_services( True );
+ reopen_logs();
+
+ if(buf) {
+ /* We were called from process() */
+ /* If reload_interfaces() returned True */
+ /* we need to shutdown if there are no subnets... */
+ /* pass this info back to process() */
+ *((BOOL*)buf) = reload_interfaces(0);
+ }
+}
+
+
+/**************************************************************************** **
The main select loop.
**************************************************************************** */
static void process(void)
{
BOOL run_election;
+ BOOL no_subnets;
while( True ) {
time_t t = time(NULL);
@@ -513,11 +536,8 @@ static void process(void)
if(reload_after_sighup) {
DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
- write_browse_list( 0, True );
- dump_all_namelists();
- reload_nmbd_services( True );
- reopen_logs();
- if(reload_interfaces(0))
+ msg_reload_nmbd_services(MSG_SMB_CONF_UPDATED, (pid_t) 0, (void*) &no_subnets, 0);
+ if(no_subnets)
return;
reload_after_sighup = 0;
}
@@ -573,8 +593,10 @@ static BOOL open_sockets(BOOL isdaemon, int port)
**************************************************************************** */
int main(int argc, const char *argv[])
{
- static BOOL opt_interactive = False;
+ pstring logfile;
+ static BOOL opt_interactive;
poptContext pc;
+ int opt;
struct poptOption long_options[] = {
POPT_AUTOHELP
{"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon(default)" },
@@ -586,46 +608,47 @@ static BOOL open_sockets(BOOL isdaemon, int port)
POPT_COMMON_SAMBA
{ NULL }
};
- pstring logfile;
-
- global_nmb_port = NMB_PORT;
- global_in_nmbd = True;
-
- StartupTime = time(NULL);
-
- sys_srandom(time(NULL) ^ sys_getpid());
- slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", dyn_LOGFILEBASE);
- lp_set_logfile(logfile);
+ global_nmb_port = NMB_PORT;
- fault_setup((void (*)(void *))fault_continue );
-
- /* POSIX demands that signals are inherited. If the invoking process has
- * these signals masked, we will have problems, as we won't receive them. */
- BlockSignals(False, SIGHUP);
- BlockSignals(False, SIGUSR1);
- BlockSignals(False, SIGTERM);
-
- CatchSignal( SIGHUP, SIGNAL_CAST sig_hup );
- CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
+ pc = poptGetContext("nmbd", argc, argv, long_options, 0);
+ while ((opt = poptGetNextOpt(pc)) != -1) ;
+ poptFreeContext(pc);
+ global_in_nmbd = True;
+
+ StartupTime = time(NULL);
+
+ sys_srandom(time(NULL) ^ sys_getpid());
+
+ slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", dyn_LOGFILEBASE);
+ lp_set_logfile(logfile);
+
+ fault_setup((void (*)(void *))fault_continue );
+
+ /* POSIX demands that signals are inherited. If the invoking process has
+ * these signals masked, we will have problems, as we won't receive them. */
+ BlockSignals(False, SIGHUP);
+ BlockSignals(False, SIGUSR1);
+ BlockSignals(False, SIGTERM);
+
+ CatchSignal( SIGHUP, SIGNAL_CAST sig_hup );
+ CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
+
#if defined(SIGFPE)
- /* we are never interested in SIGFPE */
- BlockSignals(True,SIGFPE);
+ /* we are never interested in SIGFPE */
+ BlockSignals(True,SIGFPE);
#endif
- /* We no longer use USR2... */
+ /* We no longer use USR2... */
#if defined(SIGUSR2)
- BlockSignals(True, SIGUSR2);
+ BlockSignals(True, SIGUSR2);
#endif
- pc = poptGetContext("nmbd", argc, argv, long_options, 0);
-
- poptFreeContext(pc);
- if ( opt_interactive ) {
- Fork = False;
- log_stdout = True;
- }
+ if ( opt_interactive ) {
+ Fork = False;
+ log_stdout = True;
+ }
if ( log_stdout && Fork ) {
DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
@@ -693,6 +716,7 @@ static BOOL open_sockets(BOOL isdaemon, int port)
message_register(MSG_FORCE_ELECTION, nmbd_message_election);
message_register(MSG_WINS_NEW_ENTRY, nmbd_wins_new_entry);
message_register(MSG_SHUTDOWN, nmbd_terminate);
+ message_register(MSG_SMB_CONF_UPDATED, msg_reload_nmbd_services);
DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
diff --git a/source3/nmbd/nmbd_become_lmb.c b/source3/nmbd/nmbd_become_lmb.c
index 6f8e7efb1a..d390bf72e9 100644
--- a/source3/nmbd/nmbd_become_lmb.c
+++ b/source3/nmbd/nmbd_become_lmb.c
@@ -600,6 +600,5 @@ local_master_browser_name for workgroup %s to workgroup name.\n",
}
#endif
- StrnCpy(work->local_master_browser_name, newname,
- sizeof(work->local_master_browser_name)-1);
+ fstrcpy(work->local_master_browser_name, newname);
}
diff --git a/source3/nmbd/nmbd_browserdb.c b/source3/nmbd/nmbd_browserdb.c
index a4ef98e265..4a302ddfd4 100644
--- a/source3/nmbd/nmbd_browserdb.c
+++ b/source3/nmbd/nmbd_browserdb.c
@@ -37,7 +37,6 @@
ubi_dlNewList( lmb_browserlist );
-
/* -------------------------------------------------------------------------- **
* Functions...
*/
@@ -52,9 +51,9 @@ ubi_dlNewList( lmb_browserlist );
* ************************************************************************** **
*/
static void remove_lmb_browser_entry( struct browse_cache_record *browc )
- {
- safe_free( ubi_dlRemThis( lmb_browserlist, browc ) );
- } /* remove_lmb_browser_entry */
+{
+ safe_free( ubi_dlRemThis( lmb_browserlist, browc ) );
+}
/* ************************************************************************** **
* Update a browser death time.
@@ -65,10 +64,10 @@ static void remove_lmb_browser_entry( struct browse_cache_record *browc )
* ************************************************************************** **
*/
void update_browser_death_time( struct browse_cache_record *browc )
- {
- /* Allow the new lmb to miss an announce period before we remove it. */
- browc->death_time = time(NULL) + ( (CHECK_TIME_MST_ANNOUNCE + 2) * 60 );
- } /* update_browser_death_time */
+{
+ /* Allow the new lmb to miss an announce period before we remove it. */
+ browc->death_time = time(NULL) + ( (CHECK_TIME_MST_ANNOUNCE + 2) * 60 );
+}
/* ************************************************************************** **
* Create a browser entry and add it to the local master browser list.
@@ -84,48 +83,47 @@ void update_browser_death_time( struct browse_cache_record *browc )
struct browse_cache_record *create_browser_in_lmb_cache( char *work_name,
char *browser_name,
struct in_addr ip )
- {
- struct browse_cache_record *browc;
- time_t now = time( NULL );
+{
+ struct browse_cache_record *browc;
+ time_t now = time( NULL );
- browc = (struct browse_cache_record *)malloc( sizeof( *browc ) );
+ browc = (struct browse_cache_record *)malloc( sizeof( *browc ) );
- if( NULL == browc )
- {
- DEBUG( 0, ("create_browser_in_lmb_cache: malloc fail !\n") );
- return( NULL );
- }
+ if( NULL == browc ) {
+ DEBUG( 0, ("create_browser_in_lmb_cache: malloc fail !\n") );
+ return( NULL );
+ }
- memset( (char *)browc, '\0', sizeof( *browc ) );
+ memset( (char *)browc, '\0', sizeof( *browc ) );
- /* For a new lmb entry we want to sync with it after one minute. This
- will allow it time to send out a local announce and build its
- browse list.
- */
- browc->sync_time = now + 60;
-
- /* Allow the new lmb to miss an announce period before we remove it. */
- browc->death_time = now + ( (CHECK_TIME_MST_ANNOUNCE + 2) * 60 );
-
- StrnCpy( browc->lmb_name, browser_name, sizeof(browc->lmb_name)-1 );
- StrnCpy( browc->work_group, work_name, sizeof(browc->work_group)-1 );
- strupper( browc->lmb_name );
- strupper( browc->work_group );
+ /* For a new lmb entry we want to sync with it after one minute. This
+ will allow it time to send out a local announce and build its
+ browse list.
+ */
+
+ browc->sync_time = now + 60;
+
+ /* Allow the new lmb to miss an announce period before we remove it. */
+ browc->death_time = now + ( (CHECK_TIME_MST_ANNOUNCE + 2) * 60 );
+
+ pstrcpy( browc->lmb_name, browser_name);
+ pstrcpy( browc->work_group, work_name);
+ strupper_m( browc->lmb_name );
+ strupper_m( browc->work_group );
- browc->ip = ip;
+ browc->ip = ip;
- (void)ubi_dlAddTail( lmb_browserlist, browc );
-
- if( DEBUGLVL( 3 ) )
- {
- Debug1( "nmbd_browserdb:create_browser_in_lmb_cache()\n" );
- Debug1( " Added lmb cache entry for workgroup %s ", browc->work_group );
- Debug1( "name %s IP %s ", browc->lmb_name, inet_ntoa(ip) );
- Debug1( "ttl %d\n", (int)browc->death_time );
- }
+ (void)ubi_dlAddTail( lmb_browserlist, browc );
+
+ if( DEBUGLVL( 3 ) ) {
+ Debug1( "nmbd_browserdb:create_browser_in_lmb_cache()\n" );
+ Debug1( " Added lmb cache entry for workgroup %s ", browc->work_group );
+ Debug1( "name %s IP %s ", browc->lmb_name, inet_ntoa(ip) );
+ Debug1( "ttl %d\n", (int)browc->death_time );
+ }
- return( browc );
- } /* create_browser_in_lmb_cache */
+ return( browc );
+}
/* ************************************************************************** **
* Find a browser entry in the local master browser list.
@@ -137,17 +135,16 @@ struct browse_cache_record *create_browser_in_lmb_cache( char *work_name,
* ************************************************************************** **
*/
struct browse_cache_record *find_browser_in_lmb_cache( char *browser_name )
- {
- struct browse_cache_record *browc;
+{
+ struct browse_cache_record *browc;
- for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist );
- browc;
- browc = (struct browse_cache_record *)ubi_dlNext( browc ) )
- if( strequal( browser_name, browc->lmb_name ) )
- break;
+ for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist );
+ browc; browc = (struct browse_cache_record *)ubi_dlNext( browc ) )
+ if( strequal( browser_name, browc->lmb_name ) )
+ break;
- return( browc );
- } /* find_browser_in_lmb_cache */
+ return( browc );
+}
/* ************************************************************************** **
* Expire timed out browsers in the browserlist.
@@ -159,24 +156,20 @@ struct browse_cache_record *find_browser_in_lmb_cache( char *browser_name )
* ************************************************************************** **
*/
void expire_lmb_browsers( time_t t )
- {
- struct browse_cache_record *browc;
- struct browse_cache_record *nextbrowc;
-
- for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist );
- browc;
- browc = nextbrowc )
- {
- nextbrowc = (struct browse_cache_record *)ubi_dlNext( browc );
-
- if( browc->death_time < t )
- {
- if( DEBUGLVL( 3 ) )
- {
- Debug1( "nmbd_browserdb:expire_lmb_browsers()\n" );
- Debug1( " Removing timed out lmb entry %s\n", browc->lmb_name );
- }
- remove_lmb_browser_entry( browc );
- }
- }
- } /* expire_lmb_browsers */
+{
+ struct browse_cache_record *browc;
+ struct browse_cache_record *nextbrowc;
+
+ for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist );
+ browc; browc = nextbrowc ) {
+ nextbrowc = (struct browse_cache_record *)ubi_dlNext( browc );
+
+ if( browc->death_time < t ) {
+ if( DEBUGLVL( 3 ) ) {
+ Debug1( "nmbd_browserdb:expire_lmb_browsers()\n" );
+ Debug1( " Removing timed out lmb entry %s\n", browc->lmb_name );
+ }
+ remove_lmb_browser_entry( browc );
+ }
+ }
+}
diff --git a/source3/nmbd/nmbd_browsesync.c b/source3/nmbd/nmbd_browsesync.c
index adfefc9f27..26d4735744 100644
--- a/source3/nmbd/nmbd_browsesync.c
+++ b/source3/nmbd/nmbd_browsesync.c
@@ -106,6 +106,7 @@ As a local master browser, send an announce packet to the domain master browser.
static void announce_local_master_browser_to_domain_master_browser( struct work_record *work)
{
pstring outbuf;
+ fstring myname;
char *p;
if(ismyip(work->dmb_addr))
@@ -125,8 +126,11 @@ static void announce_local_master_browser_to_domain_master_browser( struct work_
SCVAL(p,0,ANN_MasterAnnouncement);
p++;
- StrnCpy(p,global_myname(),15);
- strupper(p);
+ fstrcpy(myname, global_myname());
+ strupper_m(myname);
+ myname[15]='\0';
+ push_pstring_base(p, myname, outbuf);
+
p = skip_string(p,1);
if( DEBUGLVL( 4 ) )
diff --git a/source3/nmbd/nmbd_elections.c b/source3/nmbd/nmbd_elections.c
index 339a27d207..b948eb9d04 100644
--- a/source3/nmbd/nmbd_elections.c
+++ b/source3/nmbd/nmbd_elections.c
@@ -48,7 +48,7 @@ static void send_election_dgram(struct subnet_record *subrec, const char *workgr
SIVAL(p,5,timeup*1000); /* ms - Despite what the spec says. */
p += 13;
pstrcpy_base(p, server_name, outbuf);
- strupper(p);
+ strupper_m(p);
p = skip_string(p,1);
send_mailslot(False, BROWSE_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
diff --git a/source3/nmbd/nmbd_incomingdgrams.c b/source3/nmbd/nmbd_incomingdgrams.c
index cd6954fc62..80465ada0d 100644
--- a/source3/nmbd/nmbd_incomingdgrams.c
+++ b/source3/nmbd/nmbd_incomingdgrams.c
@@ -172,7 +172,7 @@ void process_host_announce(struct subnet_record *subrec, struct packet_struct *p
/* Update the record. */
servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
update_server_ttl( servrec, ttl);
- StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1);
+ fstrcpy(servrec->serv.comment,comment);
}
}
else
@@ -343,7 +343,7 @@ a local master browser for workgroup %s and we think we are master. Forcing elec
/* Update the record. */
servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
update_server_ttl(servrec, ttl);
- StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1);
+ fstrcpy(servrec->serv.comment,comment);
}
set_workgroup_local_master_browser_name( work, server_name );
@@ -520,7 +520,7 @@ originate from OS/2 Warp client. Ignoring packet.\n"));
/* Update the record. */
servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
update_server_ttl( servrec, ttl);
- StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1);
+ fstrcpy(servrec->serv.comment,comment);
}
}
else
@@ -559,6 +559,7 @@ static void send_backup_list_response(struct subnet_record *subrec,
#if 0
struct server_record *servrec;
#endif
+ fstring myname;
memset(outbuf,'\0',sizeof(outbuf));
@@ -578,8 +579,11 @@ static void send_backup_list_response(struct subnet_record *subrec,
/* We always return at least one name - our own. */
count = 1;
- StrnCpy(p,global_myname(),15);
- strupper(p);
+ fstrcpy(myname, global_myname());
+ strupper_m(myname);
+ myname[15]='\0';
+ push_pstring_base(p, myname, outbuf);
+
p = skip_string(p,1);
/* Look for backup browsers in this workgroup. */
@@ -610,7 +614,7 @@ static void send_backup_list_response(struct subnet_record *subrec,
continue;
StrnCpy(p, servrec->serv.name, 15);
- strupper(p);
+ strupper_m(p);
count++;
DEBUG(5,("send_backup_list_response: Adding server %s number %d\n",
diff --git a/source3/nmbd/nmbd_incomingrequests.c b/source3/nmbd/nmbd_incomingrequests.c
index a8168566f1..a3faf5e104 100644
--- a/source3/nmbd/nmbd_incomingrequests.c
+++ b/source3/nmbd/nmbd_incomingrequests.c
@@ -364,7 +364,7 @@ subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name),
/* Start with the name. */
memset(buf,'\0',18);
slprintf(buf, 17, "%-15.15s",namerec->name.name);
- strupper(buf);
+ strupper_m(buf);
/* Put the name type and netbios flags in the buffer. */
buf[15] = name_type;
diff --git a/source3/nmbd/nmbd_namelistdb.c b/source3/nmbd/nmbd_namelistdb.c
index 932d926a91..3f6d2f3b64 100644
--- a/source3/nmbd/nmbd_namelistdb.c
+++ b/source3/nmbd/nmbd_namelistdb.c
@@ -49,8 +49,8 @@ static void upcase_name( struct nmb_name *target, struct nmb_name *source )
if( NULL != source )
(void)memcpy( target, source, sizeof( struct nmb_name ) );
- strupper( target->name );
- strupper( target->scope );
+ 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.
diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c
index a702fc3015..42edcc871f 100644
--- a/source3/nmbd/nmbd_processlogon.c
+++ b/source3/nmbd/nmbd_processlogon.c
@@ -304,19 +304,19 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
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) {
- SSVAL(q, 0, SAMLOGON_AD_UNK_R); /* user unknown */
+ SIVAL(q, 0, SAMLOGON_AD_UNK_R); /* user unknown */
} else {
- SSVAL(q, 0, SAMLOGON_AD_R);
+ SIVAL(q, 0, SAMLOGON_AD_R);
}
- q += 2;
+ q += 4;
- SSVAL(q, 0, 0);
- q += 2;
SIVAL(q, 0, ADS_PDC|ADS_GC|ADS_LDAP|ADS_DS|
ADS_KDC|ADS_TIMESERV|ADS_CLOSEST|ADS_WRITABLE);
q += 4;
@@ -329,7 +329,8 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
memcpy(q, &domain_guid, sizeof(domain_guid));
q += sizeof(domain_guid);
- /* Push domain components */
+ /* Forest */
+ str_offset = q - q_orig;
dc = domain;
q1 = q;
while ((component = strtok(dc, "."))) {
@@ -338,44 +339,60 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
SCVAL(q, 0, size);
q += (size + 1);
}
+
+ /* Unk0 */
SCVAL(q, 0, 0); q++;
- SSVAL(q, 0, 0x18c0); /* not sure what this is for, but */
- q += 2; /* it must follow the domain name. */
- /* Push dns host name */
+ /* 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);
- SSVAL(q, 0, 0x18c0); /* not sure what this is for, but */
- q += 2; /* it must follow the domain name. */
+ SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F));
+ SCVAL(q, 1, str_offset & 0xFF);
+ q += 2;
- /* Push NETBIOS of domain */
+ /* NETBIOS of domain */
size = push_ascii(&q[1], lp_workgroup(), -1, STR_UPPER);
SCVAL(q, 0, size);
q += (size + 1);
- SCVAL(q, 0, 0); q++; /* is this a null terminator or empty field */
- /* null terminator would not be needed because size is included */
- /* Push NETBIOS of hostname */
+ /* 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);
- SCVAL(q, 0, 0); q++; /* null terminator or empty field? */
- /* Push user account */
- size = push_ascii(&q[1], ascuser, -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);
+ }
- /* Push 'Default-First-Site-Name' */
+ q_orig = q;
+ /* Site name */
size = push_ascii(&q[1], "Default-First-Site-Name", -1, 0);
SCVAL(q, 0, size);
q += (size + 1);
- SSVAL(q, 0, 0xc000); /* unknown */
- SCVAL(q, 2, PTR_DIFF(q,q1));
- SCVAL(q, 3, 0x10); /* unknown */
- q += 4;
+ /* 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;
diff --git a/source3/nmbd/nmbd_sendannounce.c b/source3/nmbd/nmbd_sendannounce.c
index 40d07aae16..353717ee62 100644
--- a/source3/nmbd/nmbd_sendannounce.c
+++ b/source3/nmbd/nmbd_sendannounce.c
@@ -142,7 +142,7 @@ static void send_lm_announcement(struct subnet_record *subrec, int announce_type
p += 10;
/*StrnCpy(p,server_name,15);
- strupper(p);
+ strupper_m(p);
p = skip_string(p,1);
pstrcpy(p,server_comment);
p = skip_string(p,1);*/
@@ -555,6 +555,7 @@ void browse_sync_remote(time_t t)
struct work_record *work;
pstring outbuf;
char *p;
+ fstring myname;
if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL)))
return;
@@ -589,8 +590,11 @@ for workgroup %s on subnet %s.\n", lp_workgroup(), FIRST_SUBNET->subnet_name ));
SCVAL(p,0,ANN_MasterAnnouncement);
p++;
- StrnCpy(p,global_myname(),15);
- strupper(p);
+ fstrcpy(myname, global_myname());
+ strupper_m(myname);
+ myname[15]='\0';
+ push_pstring_base(p, myname, outbuf);
+
p = skip_string(p,1);
for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); )
diff --git a/source3/nmbd/nmbd_serverlistdb.c b/source3/nmbd/nmbd_serverlistdb.c
index ee0c021d5d..2484a7f830 100644
--- a/source3/nmbd/nmbd_serverlistdb.c
+++ b/source3/nmbd/nmbd_serverlistdb.c
@@ -153,9 +153,9 @@ workgroup %s. This is a bug.\n", name, work->work_group));
servrec->subnet = work->subnet;
- StrnCpy(servrec->serv.name,name,sizeof(servrec->serv.name)-1);
- StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1);
- strupper(servrec->serv.name);
+ fstrcpy(servrec->serv.name,name);
+ fstrcpy(servrec->serv.comment,comment);
+ strupper_m(servrec->serv.name);
servrec->serv.type = servertype;
update_server_ttl(servrec, ttl);
diff --git a/source3/nmbd/nmbd_winsserver.c b/source3/nmbd/nmbd_winsserver.c
index 47ce8119f3..eafff03b76 100644
--- a/source3/nmbd/nmbd_winsserver.c
+++ b/source3/nmbd/nmbd_winsserver.c
@@ -22,7 +22,7 @@
#include "includes.h"
-#define WINS_LIST "wins.tdb"
+#define WINS_LIST "wins.dat"
#define WINS_VERSION 1
/****************************************************************************
@@ -221,123 +221,177 @@ Load or create the WINS database.
BOOL initialise_wins(void)
{
- time_t time_now = time(NULL);
- TDB_CONTEXT *tdb;
- TDB_DATA kbuf, dbuf, newkey;
- struct name_record *namerec = NULL;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
+ time_t time_now = time(NULL);
+ XFILE *fp;
+ pstring line;
- DEBUG(2,("initialise_wins: started\n"));
+ if(!lp_we_are_a_wins_server())
+ return True;
- if(!lp_we_are_a_wins_server())
- return True;
+ add_samba_names_to_subnet(wins_server_subnet);
- 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;
+ }
- tdb = tdb_open_log(lock_path(WINS_LIST), 0, TDB_DEFAULT, O_RDONLY, 0600);
- if (!tdb) {
- 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;
+
+ 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;
+ }
- if (tdb_fetch_int32(tdb, INFO_VERSION) != WINS_VERSION) {
- DEBUG(0,("Discarding invalid wins.tdb file\n"));
- tdb_close(tdb);
- return True;
- }
+ ptr = line;
- for (kbuf = tdb_firstkey(tdb);
- kbuf.dptr;
- newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
-
- fstring name_type;
- pstring name, ip_str;
- char *p;
- int type = 0;
- int nb_flags;
- int ttl;
- unsigned int num_ips;
- int high, low;
- struct in_addr wins_ip;
- struct in_addr *ip_list;
- int wins_flags;
- int len,i;
-
- if (strncmp(kbuf.dptr, ENTRY_PREFIX, strlen(ENTRY_PREFIX)) != 0)
- continue;
-
- dbuf = tdb_fetch(tdb, kbuf);
- if (!dbuf.dptr)
- continue;
+ /*
+ * 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.
+ */
- fstrcpy(name_type, kbuf.dptr+strlen(ENTRY_PREFIX));
+ 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;
+ }
- pstrcpy(name, name_type);
+ 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;
+ }
- if((p = strchr(name,'#')) != NULL) {
- *p = 0;
- sscanf(p+1,"%x",&type);
- }
+ /*
+ * 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;
- len = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddfddd",
- &nb_flags, &high, &low,
- ip_str, &ttl, &num_ips, &wins_flags);
+ if(got_token && strchr(ip_str, '.'))
+ {
+ num_ips++;
+ was_ip = True;
+ }
+ } while( got_token && was_ip);
- wins_ip=*interpret_addr2(ip_str);
+ if(num_ips == 0)
+ {
+ DEBUG(0,("initialise_wins: Missing IP address when parsing line %s\n", line ));
+ continue;
+ }
- /* Don't reload replica records */
- if (!ip_equal(wins_ip, our_fake_ip)) {
- SAFE_FREE(dbuf.dptr);
- continue;
- }
+ if(!got_token)
+ {
+ DEBUG(0,("initialise_wins: Missing nb_flags when parsing line %s\n", line ));
+ continue;
+ }
- /* Don't reload released or tombstoned records */
- if ((wins_flags&WINS_STATE_MASK) != WINS_ACTIVE) {
- SAFE_FREE(dbuf.dptr);
- 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));
- /* Allocate the space for the ip_list. */
- if((ip_list = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr))) == NULL) {
- SAFE_FREE(dbuf.dptr);
- DEBUG(0,("initialise_wins: Malloc fail !\n"));
- return False;
- }
+ /*
+ * Deal with SELF or REGISTER name encoding. Default is REGISTER
+ * for compatibility with old nmbds.
+ */
- for (i = 0; i < num_ips; i++) {
- len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f", ip_str);
- ip_list[i] = *interpret_addr2(ip_str);
- }
+ 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';
+
+ /* 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);
+ }
+
+ /* 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;
+ /* 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));
-
- namerec=add_name_to_subnet( wins_server_subnet, name, type, nb_flags,
- ttl, REGISTER_NAME, num_ips, ip_list);
- if (namerec!=NULL) {
- update_wins_owner(namerec, wins_ip);
- update_wins_flag(namerec, wins_flags);
- /* we don't reload the ID, on startup we restart at 1 */
- get_global_id_and_update(&namerec->data.id, True);
- }
+ 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));
- } 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));
- }
+ (void)add_name_to_subnet( wins_server_subnet, name, type, nb_flags,
+ ttl, REGISTER_NAME, num_ips, ip_list );
- SAFE_FREE(dbuf.dptr);
- SAFE_FREE(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);
+ }
- tdb_close(tdb);
- DEBUG(2,("initialise_wins: done\n"));
- return True;
+ x_fclose(fp);
+ return True;
}
/****************************************************************************
@@ -1765,113 +1819,87 @@ we are not the wins owner !\n", nmb_namestr(&namerec->name)));
******************************************************************/
void wins_write_database(BOOL background)
{
- struct name_record *namerec;
- pstring fname, fnamenew;
- TDB_CONTEXT *tdb;
- TDB_DATA kbuf, dbuf;
- pstring key, buf;
- int len;
- int num_record=0;
- SMB_BIG_UINT id;
-
- 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());
-
- tdb = tdb_open_log(fnamenew, 0, TDB_DEFAULT, O_RDWR|O_CREAT|O_TRUNC, 0644);
- if (!tdb) {
- DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
- if (background)
- _exit(0);
- return;
- }
-
- DEBUG(3,("wins_write_database: Dump of WINS name list.\n"));
-
- tdb_store_int32(tdb, INFO_VERSION, WINS_VERSION);
-
- 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(3,("%-19s ", nmb_namestr(&namerec->name) ));
+ struct name_record *namerec;
+ pstring fname, fnamenew;
- if( namerec->data.death_time != PERMANENT_TTL ) {
- char *ts, *nl;
-
- tm = LocalTime(&namerec->data.death_time);
- ts = asctime(tm);
- nl = strrchr_m( ts, '\n' );
- if( NULL != nl )
- *nl = '\0';
+ XFILE *fp;
+
+ if(!lp_we_are_a_wins_server())
+ return;
- DEBUGADD(3,("TTL = %s ", ts ));
- } else
- DEBUGADD(3,("TTL = PERMANENT "));
+ /* 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;
+ }
+ }
- for (i = 0; i < namerec->data.num_ips; i++)
- DEBUGADD(0,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
+ 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());
- DEBUGADD(3,("0x%2x 0x%2x %15s\n", namerec->data.nb_flags, namerec->data.wins_flags, inet_ntoa(namerec->data.wins_ip)));
+ 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;
+ }
- if( namerec->data.source == REGISTER_NAME ) {
-
- /* store the type in the key to make the name unique */
- slprintf(key, sizeof(key), "%s%s#%02x", ENTRY_PREFIX, namerec->name.name, namerec->name.name_type);
-
- len = tdb_pack(buf, sizeof(buf), "dddfddd",
- (int)namerec->data.nb_flags,
- (int)(namerec->data.id>>32),
- (int)(namerec->data.id&0xffffffff),
- inet_ntoa(namerec->data.wins_ip),
- (int)namerec->data.death_time,
- namerec->data.num_ips,
- namerec->data.wins_flags);
-
- for (i = 0; i < namerec->data.num_ips; i++)
- len += tdb_pack(buf+len, sizeof(buf)-len, "f", inet_ntoa(namerec->data.ip[i]));
-
- kbuf.dsize = strlen(key)+1;
- kbuf.dptr = key;
- dbuf.dsize = len;
- dbuf.dptr = buf;
- if (tdb_store(tdb, kbuf, dbuf, TDB_INSERT) != 0) return;
+ DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
- num_record++;
- }
- }
+ 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;
- /* store the number of records */
- tdb_store_int32(tdb, INFO_COUNT, num_record);
+ DEBUGADD(4,("%-19s ", nmb_namestr(&namerec->name) ));
- /* get and store the last used ID */
- get_global_id_and_update(&id, False);
- tdb_store_int32(tdb, INFO_ID_HIGH, id>>32);
- tdb_store_int32(tdb, INFO_ID_LOW, id&0xffffffff);
+ 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 "));
- tdb_close(tdb);
+ 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 ));
- chmod(fnamenew,0644);
- unlink(fname);
- rename(fnamenew,fname);
+ 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);
- if (background)
- _exit(0);
+ 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);
+ }
}
/****************************************************************************
diff --git a/source3/nmbd/nmbd_workgroupdb.c b/source3/nmbd/nmbd_workgroupdb.c
index b8ea60dec0..2357fd637b 100644
--- a/source3/nmbd/nmbd_workgroupdb.c
+++ b/source3/nmbd/nmbd_workgroupdb.c
@@ -57,7 +57,7 @@ static struct work_record *create_workgroup(const char *name, int ttl)
}
memset((char *)work, '\0', sizeof(*work));
- StrnCpy(work->work_group,name,sizeof(work->work_group)-1);
+ fstrcpy(work->work_group,name);
work->serverlist = NULL;
work->RunningElection = False;