summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/include/nameserv.h6
-rw-r--r--source/include/smb.h1
-rw-r--r--source/lib/util.c2
-rw-r--r--source/nameannounce.c14
-rw-r--r--source/namedbwork.c12
-rw-r--r--source/nameelect.c103
-rw-r--r--source/namepacket.c4
-rw-r--r--source/nameserv.c47
-rw-r--r--source/namework.c5
-rw-r--r--source/smbd/ipc.c3
10 files changed, 91 insertions, 106 deletions
diff --git a/source/include/nameserv.h b/source/include/nameserv.h
index 8dc737bdb06..e4876bac570 100644
--- a/source/include/nameserv.h
+++ b/source/include/nameserv.h
@@ -383,3 +383,9 @@ struct packet_struct
/* do all remote announcements this often */
#define REMOTE_ANNOUNCE_INTERVAL 180
+
+#define DFLT_SERVER_TYPE (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | \
+ SV_TYPE_TIME_SOURCE | SV_TYPE_SERVER_UNIX | \
+ SV_TYPE_PRINTQ_SERVER | SV_TYPE_SERVER_NT | \
+ SV_TYPE_NT)
+
diff --git a/source/include/smb.h b/source/include/smb.h
index 349d406b49f..7e002122cc7 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -785,6 +785,7 @@ char *Strstr(char *s, char *p);
#define SV_TYPE_DOMAIN_ENUM 0x80000000
#define SV_TYPE_ALL 0xFFFFFFFF
+/* what server type are we currently */
/* protocol types. It assumes that higher protocols include lower protocols
diff --git a/source/lib/util.c b/source/lib/util.c
index 2f3ac1bb150..2fedded3292 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -3148,7 +3148,7 @@ my own panic function - not suitable for general use
********************************************************************/
void ajt_panic(void)
{
- system("/usr/bin/X11/xedit -display :0 /tmp/ERROR_FAULT");
+ system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
}
#endif
diff --git a/source/nameannounce.c b/source/nameannounce.c
index 5591c5ba19a..ff2c89df852 100644
--- a/source/nameannounce.c
+++ b/source/nameannounce.c
@@ -208,7 +208,7 @@ void remove_my_servers(void)
void announce_server(struct subnet_record *d, struct work_record *work,
char *name, char *comment, time_t ttl, int server_type)
{
- uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_SERVER_UNIX;
+ uint32 domain_type = SV_TYPE_DOMAIN_ENUM|DFLT_SERVER_TYPE;
BOOL wins_iface = ip_equal(d->bcast_ip, ipgrp);
if (wins_iface && server_type != 0)
@@ -237,11 +237,6 @@ void announce_server(struct subnet_record *d, struct work_record *work,
}
}
- if (AM_DOMCTL(work))
- {
- /* XXXX announce to backup domain masters? */
- }
-
/* XXXX any other kinds of announcements we need to consider here?
e.g local master browsers... no. local master browsers do
local master announcements to their domain master. they even
@@ -268,10 +263,6 @@ void announce_server(struct subnet_record *d, struct work_record *work,
/* XXXX should we do a domain-announce-kill? */
if (server_type != 0)
{
- if (AM_DOMCTL(work))
- {
- domain_type |= SV_TYPE_DOMAIN_CTRL;
- }
do_announce_host(ANN_DomainAnnouncement,
name , 0x00, d->myip,
MSBROWSE, 0x01, d->bcast_ip,
@@ -490,8 +481,7 @@ void announce_remote(void)
pstring s2;
struct in_addr addr;
char *comment,*workgroup;
- int stype = SV_TYPE_WORKSTATION | SV_TYPE_SERVER | SV_TYPE_PRINTQ_SERVER |
- SV_TYPE_SERVER_UNIX;
+ int stype = DFLT_SERVER_TYPE;
if (last_time && t < last_time + REMOTE_ANNOUNCE_INTERVAL)
return;
diff --git a/source/namedbwork.c b/source/namedbwork.c
index 200132304b0..04f2103254b 100644
--- a/source/namedbwork.c
+++ b/source/namedbwork.c
@@ -38,13 +38,10 @@ extern int DEBUGLEVEL;
/* this is our domain/workgroup/server database */
extern struct subnet_record *subnetlist;
-int workgroup_count = 0; /* unique index key: one for each workgroup */
+extern struct in_addr ipgrp;
-/* what server type are we currently */
+int workgroup_count = 0; /* unique index key: one for each workgroup */
-#define DFLT_SERVER_TYPE (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | \
- SV_TYPE_TIME_SOURCE | SV_TYPE_SERVER_UNIX | \
- SV_TYPE_PRINTQ_SERVER | SV_TYPE_POTENTIAL_BROWSER)
/****************************************************************************
@@ -89,7 +86,7 @@ static struct work_record *make_workgroup(char *name)
StrnCpy(work->work_group,name,sizeof(work->work_group)-1);
work->serverlist = NULL;
- work->ServerType = DFLT_SERVER_TYPE;
+ work->ServerType = DFLT_SERVER_TYPE | SV_TYPE_POTENTIAL_BROWSER;
work->RunningElection = False;
work->ElectionCount = 0;
work->needelection = False;
@@ -202,7 +199,8 @@ struct work_record *find_workgroupstruct(struct subnet_record *d,
if ((work = make_workgroup(name)))
{
- if (lp_preferred_master() &&
+ if (!ip_equal(d->bcast_ip, ipgrp) &&
+ lp_preferred_master() &&
strequal(lp_workgroup(), name))
{
DEBUG(3, ("preferred master startup for %s\n", work->work_group));
diff --git a/source/nameelect.c b/source/nameelect.c
index 041e4a8cca9..07429013e0d 100644
--- a/source/nameelect.c
+++ b/source/nameelect.c
@@ -97,7 +97,11 @@ void browser_gone(char *work_name, struct in_addr ip)
/* i don't know about this workgroup, therefore i don't care */
if (!work || !d) return;
-
+
+ /* don't do election stuff on the WINS subnet */
+ if (ip_equal(d->bcast_ip,ipgrp))
+ return;
+
if (strequal(work->work_group, lp_workgroup()))
{
@@ -245,7 +249,8 @@ void name_register_work(struct subnet_record *d, char *name, int name_type,
******************************************************************/
void become_master(struct subnet_record *d, struct work_record *work)
{
- uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_SERVER_UNIX|0x00400000;
+ uint32 domain_type = SV_TYPE_DOMAIN_ENUM|DFLT_SERVER_TYPE|
+ SV_TYPE_POTENTIAL_BROWSER;
if (!work) return;
@@ -369,12 +374,8 @@ void become_master(struct subnet_record *d, struct work_record *work)
DEBUG(3,("domain third stage: samba is now a domain master.\n"));
work->state = MST_DOMAIN; /* ... registering WORKGROUP(1b) succeeded */
- update_type |= SV_TYPE_DOMAIN_MASTER;
-
- if (lp_domain_logons())
- {
- update_type |= SV_TYPE_DOMAIN_CTRL|SV_TYPE_SERVER_UNIX;
- }
+ update_type |= DFLT_SERVER_TYPE | SV_TYPE_DOMAIN_MASTER |
+ SV_TYPE_POTENTIAL_BROWSER;
work->ServerType |= update_type;
add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True);
@@ -427,7 +428,7 @@ void become_nonmaster(struct subnet_record *d, struct work_record *work,
DEBUG(2,("Becoming non-master for %s\n",work->work_group));
/* can only remove master or domain types with this function */
- remove_type &= ~(SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER);
+ remove_type &= SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER;
/* unbecome a master browser; unbecome a domain master, too :-( */
if (remove_type & SV_TYPE_MASTER_BROWSER)
@@ -439,7 +440,7 @@ void become_nonmaster(struct subnet_record *d, struct work_record *work,
{
/* no longer a master browser of any sort */
- work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
+ work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
work->ElectionCriterion &= ~0x4;
work->state = MST_NONE;
@@ -454,11 +455,10 @@ void become_nonmaster(struct subnet_record *d, struct work_record *work,
{
if (work->state == MST_DOMAIN)
work->state = MST_BROWSER;
- remove_name_entry(d,work->work_group,0x1b);
-
+ remove_name_entry(d,work->work_group,0x1b);
}
- if (!(work->ServerType & SV_TYPE_DOMAIN_MASTER))
+ if (!(work->ServerType & SV_TYPE_MASTER_BROWSER))
{
if (work->state >= MST_BROWSER)
work->state = MST_NONE;
@@ -515,18 +515,23 @@ void run_elections(void)
static BOOL win_election(struct work_record *work,int version,uint32 criterion,
int timeup,char *name)
{
- time_t t = time(NULL);
- uint32 mycriterion;
+ int mytimeup = time(NULL) - StartupTime;
+ uint32 mycriterion = work->ElectionCriterion;
+
+ DEBUG(4,("election comparison: %x:%x %x:%x %d:%d %s:%s\n",
+ version,ELECTION_VERSION,
+ criterion,mycriterion,
+ timeup,mytimeup,
+ name,myname));
+
if (version > ELECTION_VERSION) return(False);
if (version < ELECTION_VERSION) return(True);
- mycriterion = work->ElectionCriterion;
-
if (criterion > mycriterion) return(False);
if (criterion < mycriterion) return(True);
- if (timeup > (t - StartupTime)) return(False);
- if (timeup < (t - StartupTime)) return(True);
+ if (timeup > mytimeup) return(False);
+ if (timeup < mytimeup) return(True);
if (strcasecmp(myname,name) > 0) return(False);
@@ -551,46 +556,44 @@ void process_election(struct packet_struct *p,char *buf)
struct work_record *work;
if (!d) return;
+
+ if (ip_equal(d->bcast_ip,ipgrp)) {
+ DEBUG(3,("Unexpected election request from %s %s on WINS net\n",
+ name, inet_ntoa(p->ip)));
+ return;
+ }
name[15] = 0;
- DEBUG(3,("Election request from %s vers=%d criterion=%08x timeup=%d\n",
- name,version,criterion,timeup));
+ DEBUG(3,("Election request from %s %s vers=%d criterion=%08x timeup=%d\n",
+ name,inet_ntoa(p->ip),version,criterion,timeup));
if (same_context(dgram)) return;
for (work = d->workgrouplist; work; work = work->next)
{
- if (strequal(work->work_group, lp_workgroup()))
- {
- if (win_election(work, version,criterion,timeup,name))
- {
- if (!work->RunningElection)
- {
- work->needelection = True;
- work->ElectionCount=0;
- work->state = MST_NONE;
- }
- }
- else
- {
- work->needelection = False;
-
- if (work->RunningElection)
- {
- work->RunningElection = False;
- DEBUG(3,(">>> Lost election on %s %s <<<\n",
- work->work_group,inet_ntoa(d->bcast_ip)));
-
- /* if we are the master then remove our masterly names */
- if (AM_MASTER(work))
- {
- become_nonmaster(d, work,
- SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER);
- }
- }
- }
+ if (!strequal(work->work_group, lp_workgroup()))
+ continue;
+
+ if (win_election(work, version,criterion,timeup,name)) {
+ if (!work->RunningElection) {
+ work->needelection = True;
+ work->ElectionCount=0;
+ work->state = MST_NONE;
}
+ } else {
+ work->needelection = False;
+
+ if (work->RunningElection || AM_MASTER(work)) {
+ work->RunningElection = False;
+ DEBUG(3,(">>> Lost election on %s %s <<<\n",
+ work->work_group,inet_ntoa(d->bcast_ip)));
+ if (AM_MASTER(work))
+ become_nonmaster(d, work,
+ SV_TYPE_MASTER_BROWSER|
+ SV_TYPE_DOMAIN_MASTER);
+ }
+ }
}
}
diff --git a/source/namepacket.c b/source/namepacket.c
index 075096bc573..5bfa55d4f16 100644
--- a/source/namepacket.c
+++ b/source/namepacket.c
@@ -491,6 +491,8 @@ void listen_for_packets(BOOL run_election)
int selrtn;
struct timeval timeout;
+try_again:
+
FD_ZERO(&fds);
FD_SET(ClientNMB,&fds);
FD_SET(ClientDGRAM,&fds);
@@ -515,6 +517,7 @@ void listen_for_packets(BOOL run_election)
DEBUG(7,("discarding own packet from %s:%d\n",
inet_ntoa(packet->ip),packet->port));
free_packet(packet);
+ goto try_again;
} else {
queue_packet(packet);
}
@@ -530,6 +533,7 @@ void listen_for_packets(BOOL run_election)
DEBUG(7,("discarding own packet from %s:%d\n",
inet_ntoa(packet->ip),packet->port));
free_packet(packet);
+ goto try_again;
} else {
queue_packet(packet);
}
diff --git a/source/nameserv.c b/source/nameserv.c
index 8831cb510f1..26c2f330dac 100644
--- a/source/nameserv.c
+++ b/source/nameserv.c
@@ -47,7 +47,7 @@ extern uint16 nb_type; /* samba's NetBIOS type */
/****************************************************************************
remove an entry from the name list
- note: the name will _always_ be removed: it's just a matter of when.
+ note: the name will _always_ be removed
XXXX at present, the name is removed _even_ if a WINS server says keep it.
****************************************************************************/
@@ -72,37 +72,26 @@ void remove_name_entry(struct subnet_record *d, char *name,int type)
n2->ip_flgs[0].nb_flags &= NB_DEREG;
}
- if (ip_equal(d->bcast_ip, ipgrp))
- {
- if (lp_wins_support())
- {
- /* we are a WINS server. */
- /* XXXX assume that if we are a WINS server that we are therefore
- not pointing to another WINS server as well. this may later NOT
- actually be true
- */
- remove_netbios_name(d,name,type,SELF,ipzero);
- }
- else
- {
- /* not a WINS server: cannot just remove our own names: we have to
- release them on the network first. ask permission from the WINS
- server, or if no reply is received, then we can remove the name */
+ if (!n2) return;
- queue_netbios_pkt_wins(d,ClientNMB,NMB_REL,NAME_RELEASE,
- name, type, 0, 0,0,NULL,NULL,
- False, True, ipzero, ipzero);
- }
- }
- else
- {
- /* local interface: cannot just remove our own names: we have to
- release them on the network first. once no reply is received,
- then we can remove the name. */
+ /* remove the name immediately. even if the spec says we should
+ first try to release them, this is too dangerous with our current
+ name structures as otherwise we will end up replying to names we
+ don't really own */
+ remove_netbios_name(d,name,type,SELF,n2->ip_flgs[0].ip);
- queue_netbios_packet(d,ClientNMB,NMB_REL,NAME_RELEASE,
+ if (ip_equal(d->bcast_ip, ipgrp)) {
+ if (!lp_wins_support()) {
+ /* not a WINS server: we have to release them on the network */
+ queue_netbios_pkt_wins(d,ClientNMB,NMB_REL,NAME_RELEASE,
name, type, 0, 0,0,NULL,NULL,
- True, True, d->bcast_ip, d->bcast_ip);
+ False, True, ipzero, ipzero);
+ }
+ } else {
+ /* local interface: release them on the network */
+ queue_netbios_packet(d,ClientNMB,NMB_REL,NAME_RELEASE,
+ name, type, 0, 0,0,NULL,NULL,
+ True, True, d->bcast_ip, d->bcast_ip);
}
}
diff --git a/source/namework.c b/source/namework.c
index be034488c43..0380c1460af 100644
--- a/source/namework.c
+++ b/source/namework.c
@@ -50,11 +50,6 @@ extern struct subnet_record *subnetlist;
extern int updatecount;
-/* what server type are we currently */
-#define DFLT_SERVER_TYPE (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | \
- SV_TYPE_TIME_SOURCE | SV_TYPE_SERVER_UNIX |\
- SV_TYPE_PRINTQ_SERVER | SV_TYPE_POTENTIAL_BROWSER)
-
/* backup request types: which servers are to be included */
#define MASTER_TYPE (SV_TYPE_MASTER_BROWSER)
#define DOMCTL_TYPE (SV_TYPE_DOMAIN_CTRL )
diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c
index 9da7c993dd1..87df699e298 100644
--- a/source/smbd/ipc.c
+++ b/source/smbd/ipc.c
@@ -1666,8 +1666,7 @@ static BOOL api_RNetServerGetInfo(int cnum,int uid, char *param,char *data,
struct srv_info_struct *servers=NULL;
int i,count;
pstring comment;
- uint32 servertype=SV_TYPE_SERVER_UNIX|SV_TYPE_WORKSTATION|
- SV_TYPE_SERVER|SV_TYPE_TIME_SOURCE;
+ uint32 servertype=DFLT_SERVER_TYPE;
strcpy(comment,lp_serverstring());