diff options
-rw-r--r-- | source3/include/nameserv.h | 6 | ||||
-rw-r--r-- | source3/include/smb.h | 1 | ||||
-rw-r--r-- | source3/lib/util.c | 2 | ||||
-rw-r--r-- | source3/nameannounce.c | 14 | ||||
-rw-r--r-- | source3/namedbwork.c | 12 | ||||
-rw-r--r-- | source3/nameelect.c | 103 | ||||
-rw-r--r-- | source3/namepacket.c | 4 | ||||
-rw-r--r-- | source3/nameserv.c | 47 | ||||
-rw-r--r-- | source3/namework.c | 5 | ||||
-rw-r--r-- | source3/smbd/ipc.c | 3 |
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()); |