summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>1996-08-21 06:09:00 +0000
committerAndrew Tridgell <tridge@samba.org>1996-08-21 06:09:00 +0000
commitb5a64bb74056fad43afedcb05d29000618170ef4 (patch)
tree9373ad05fe68254b02678ebf5ea5e513c39d6226
parenta2fa290188911b1013a8950fe18489038c8fcb05 (diff)
downloadsamba-b5a64bb74056fad43afedcb05d29000618170ef4.tar.gz
samba-b5a64bb74056fad43afedcb05d29000618170ef4.tar.bz2
samba-b5a64bb74056fad43afedcb05d29000618170ef4.zip
- new handling of ST_TYPE bits, they are now consolidated much more in
DFLT_SERVER_TYPE in nameserv.h - got rid of a lot of spurious domain controller stuff. Samba is not a domain controller yet, but it can be a domain master. We were claiming to be a domain controller in some packets which may have caused problems - don't do preferred master startups on the WINS pseudo-net - don't do election requests on the WINS pseudo-net - fix a nasty bug in become_non_master() which wiped out the bits in remove_type before using them. The result was that samba didn't like losing its master status. - changed the logic in the election packet handling to enable us to become a non-master whenever we receive a winning election frame, even if we aren't expecting it - get another packet from the socket in nmbd when we reject one of our own packets, this stops us from going into the packet reading code too often and makes nmbd much snappier - always remove a name immediately when we try to release it, don't wait for the lack of response from the network, otherwise we will end up replying to name that we don't really own. We still send the dereg packets, we just don't wait for them to time out. (This used to be commit eb84f2f342375439d94481a0ccf47c9593544e32)
-rw-r--r--source3/include/nameserv.h6
-rw-r--r--source3/include/smb.h1
-rw-r--r--source3/lib/util.c2
-rw-r--r--source3/nameannounce.c14
-rw-r--r--source3/namedbwork.c12
-rw-r--r--source3/nameelect.c103
-rw-r--r--source3/namepacket.c4
-rw-r--r--source3/nameserv.c47
-rw-r--r--source3/namework.c5
-rw-r--r--source3/smbd/ipc.c3
10 files changed, 91 insertions, 106 deletions
diff --git a/source3/include/nameserv.h b/source3/include/nameserv.h
index 8dc737bdb0..e4876bac57 100644
--- a/source3/include/nameserv.h
+++ b/source3/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/source3/include/smb.h b/source3/include/smb.h
index 349d406b49..7e002122cc 100644
--- a/source3/include/smb.h
+++ b/source3/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/source3/lib/util.c b/source3/lib/util.c
index 2f3ac1bb15..2fedded329 100644
--- a/source3/lib/util.c
+++ b/source3/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/source3/nameannounce.c b/source3/nameannounce.c
index 5591c5ba19..ff2c89df85 100644
--- a/source3/nameannounce.c
+++ b/source3/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/source3/namedbwork.c b/source3/namedbwork.c
index 200132304b..04f2103254 100644
--- a/source3/namedbwork.c
+++ b/source3/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/source3/nameelect.c b/source3/nameelect.c
index 041e4a8cca..07429013e0 100644
--- a/source3/nameelect.c
+++ b/source3/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/source3/namepacket.c b/source3/namepacket.c
index 075096bc57..5bfa55d4f1 100644
--- a/source3/namepacket.c
+++ b/source3/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/source3/nameserv.c b/source3/nameserv.c
index 8831cb510f..26c2f330da 100644
--- a/source3/nameserv.c
+++ b/source3/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/source3/namework.c b/source3/namework.c
index be034488c4..0380c1460a 100644
--- a/source3/namework.c
+++ b/source3/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/source3/smbd/ipc.c b/source3/smbd/ipc.c
index 9da7c993dd..87df699e29 100644
--- a/source3/smbd/ipc.c
+++ b/source3/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());