nameserv.c: split add_domain_names() into three functions:
[Samba.git] / source / nameelect.c
blob295fcd73335f9d200133b7ab29a866d241628a73
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 NBT netbios routines and daemon - version 2
5 Copyright (C) Andrew Tridgell 1994-1997
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 Module name: nameelect.c
23 Revision History:
25 14 jan 96: lkcl@pires.co.uk
26 added multiple workgroup domain master support
28 04 jul 96: lkcl@pires.co.uk
29 added system to become a master browser by stages.
34 #include "includes.h"
36 extern int ClientNMB;
37 extern int ClientDGRAM;
39 extern int DEBUGLEVEL;
40 extern pstring scope;
42 extern pstring myname;
43 extern fstring myworkgroup;
44 extern struct in_addr ipzero;
45 extern struct in_addr wins_ip;
47 /* here are my election parameters */
49 extern time_t StartupTime;
51 extern struct subnet_record *subnetlist;
53 extern uint16 nb_type; /* samba's NetBIOS name type */
56 /*******************************************************************
57 occasionally check to see if the master browser is around
58 ******************************************************************/
59 void check_master_browser(time_t t)
61 static time_t lastrun=0;
62 struct subnet_record *d;
64 if (!lastrun) lastrun = t;
65 if (t < lastrun + CHECK_TIME_MST_BROWSE * 60) return;
67 lastrun = t;
69 dump_workgroups();
71 for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
73 struct work_record *work;
75 for (work = d->workgrouplist; work; work = work->next)
77 if (strequal(work->work_group, myworkgroup) && !AM_MASTER(work))
79 if (lp_local_master())
81 /* potential master browser - not a master browser. force
82 becoming a master browser, hence the log message.
85 DEBUG(2,("%s potential master for %s %s - force election\n",
86 timestring(), work->work_group,
87 inet_ntoa(d->bcast_ip)));
89 browser_gone(work->work_group, d->bcast_ip);
91 else
93 /* if we are not the browse master of a workgroup,
94 and we can't find a browser on the subnet, do
95 something about it.
98 queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_MST_CHK,
99 work->work_group,0x1d,0,0,0,NULL,NULL,
100 True,False,d->bcast_ip,d->bcast_ip);
108 /*******************************************************************
109 what to do if a master browser DOESN't exist.
111 option 1: force an election, and participate in it
112 option 2: force an election, and let everyone else participate.
114 ******************************************************************/
115 void browser_gone(char *work_name, struct in_addr ip)
117 struct subnet_record *d = find_subnet(ip);
118 struct work_record *work = find_workgroupstruct(d, work_name, False);
120 /* i don't know about this workgroup, therefore i don't care */
121 if (!work || !d) return;
123 /* don't do election stuff on the WINS subnet */
124 if (ip_equal(d->bcast_ip,wins_ip))
125 return;
127 if (strequal(work->work_group, myworkgroup))
130 if (lp_local_master())
132 /* we have discovered that there is no local master
133 browser, and we are configured to initiate
134 an election under exactly such circumstances.
136 DEBUG(2,("Forcing election on %s %s\n",
137 work->work_group,inet_ntoa(d->bcast_ip)));
139 /* we can attempt to become master browser */
140 work->needelection = True;
142 else
144 /* we need to force an election, because we are configured
145 not to _become_ the local master, but we still _need_ one,
146 having detected that one doesn't exist.
149 /* local interfaces: force an election */
150 send_election(d, work->work_group, 0, 0, myname);
152 /* only removes workgroup completely on a local interface
153 persistent lmhosts entries on a local interface _will_ be removed).
155 remove_workgroup(d, work,True);
156 add_workgroup_to_subnet(d, work->work_group);
162 /****************************************************************************
163 send an election packet
164 **************************************************************************/
165 void send_election(struct subnet_record *d, char *group,uint32 criterion,
166 int timeup,char *name)
168 pstring outbuf;
169 char *p;
171 if (!d) return;
173 DEBUG(2,("Sending election to %s for workgroup %s\n",
174 inet_ntoa(d->bcast_ip),group));
176 bzero(outbuf,sizeof(outbuf));
177 p = outbuf;
178 CVAL(p,0) = ANN_Election; /* election */
179 p++;
181 CVAL(p,0) = (criterion == 0 && timeup == 0) ? 0 : ELECTION_VERSION;
182 SIVAL(p,1,criterion);
183 SIVAL(p,5,timeup*1000); /* ms - despite the spec */
184 p += 13;
185 strcpy(p,name);
186 strupper(p);
187 p = skip_string(p,1);
189 send_mailslot_reply(False,BROWSE_MAILSLOT,ClientDGRAM,
190 outbuf,PTR_DIFF(p,outbuf),
191 name,group,0,0x1e,d->bcast_ip,*iface_ip(d->bcast_ip));
195 /****************************************************************************
196 un-register a SELF name that got rejected.
198 if this name happens to be rejected when samba is in the process
199 of becoming a master browser (registering __MSBROWSE__, WORKGROUP(1d)
200 or WORKGROUP(1b)) then we must stop being a master browser. sad.
202 **************************************************************************/
203 void name_unregister_work(struct subnet_record *d, char *name, int name_type)
205 struct work_record *work;
206 int remove_type_local = 0;
207 int remove_type_domain = 0;
208 int remove_type_logon = 0;
210 remove_netbios_name(d,name,name_type,SELF,ipzero);
212 if (!(work = find_workgroupstruct(d, name, False))) return;
214 /* work out what to unbecome, from the name type being removed */
216 if (ms_browser_name(name, name_type))
218 remove_type_local |= SV_TYPE_MASTER_BROWSER;
220 if (AM_MASTER(work) && strequal(name, myworkgroup) && name_type == 0x1d)
222 remove_type_local |= SV_TYPE_MASTER_BROWSER;
224 if (AM_DOMMST(work) && strequal(name, myworkgroup) && name_type == 0x1b)
226 remove_type_domain |= SV_TYPE_DOMAIN_MASTER;
228 if (AM_DOMMEM(work) && strequal(name, myworkgroup) && name_type == 0x1c)
230 remove_type_logon|= SV_TYPE_DOMAIN_MEMBER;
233 if (remove_type_local ) unbecome_local_master (d, work, remove_type_local );
234 if (remove_type_domain) unbecome_domain_master(d, work, remove_type_domain);
235 if (remove_type_logon ) unbecome_logon_server (d, work, remove_type_logon );
239 /****************************************************************************
240 registers a name.
242 if the name being added is a SELF name, we must additionally check
243 whether to proceed to the next stage in samba becoming a master browser.
245 **************************************************************************/
246 void name_register_work(struct subnet_record *d, char *name, int name_type,
247 int nb_flags, time_t ttl, struct in_addr ip, BOOL bcast)
249 enum name_source source = (ismyip(ip) || ip_equal(ip, ipzero)) ?
250 SELF : REGISTER;
252 if (source == SELF)
254 struct work_record *work = find_workgroupstruct(d,
255 myworkgroup, False);
257 add_netbios_entry(d,name,name_type,nb_flags,ttl,source,ip,True,!bcast);
259 if (work)
261 int add_type_local = False;
262 int add_type_domain = False;
263 int add_type_logon = False;
265 DEBUG(4,("checking next stage: name_register_work %s\n", name));
267 /* work out what to become, from the name type being added */
269 if (ms_browser_name(name, name_type))
271 add_type_local = True;
273 if (strequal(name, myworkgroup) && name_type == 0x1d)
275 add_type_local = True;
277 if (strequal(name, myworkgroup) && name_type == 0x1b)
279 add_type_domain = True;
281 if (strequal(name, myworkgroup) && name_type == 0x1c)
283 add_type_logon = True;
286 if (add_type_local ) become_local_master (d, work);
287 if (add_type_domain) become_domain_master(d, work);
288 if (add_type_logon ) become_logon_server (d, work);
294 /*******************************************************************
295 become the local master browser.
297 this is done in stages. note that this could take a while,
298 particularly on a broadcast subnet, as we have to wait for
299 the implicit registration of each name to be accepted.
301 as each name is successfully registered, become_local_master() is
302 called again, in order to initiate the next stage. see
303 dead_netbios_entry() - deals with implicit name registration
304 and response_name_reg() - deals with explicit registration
305 with a WINS server.
307 stage 1: was MST_POTENTIAL - go to MST_POTENTIAL and register ^1^2__MSBROWSE__^2^1.
308 stage 2: was MST_BACK - go to MST_MSB and register WORKGROUP(0x1d)
309 stage 3: was MST_MSB - go to MST_BROWSER and stay there
311 XXXX note: this code still does not cope with the distinction
312 between different types of nodes, particularly between M and P
313 nodes. that comes later.
315 ******************************************************************/
316 void become_local_master(struct subnet_record *d, struct work_record *work)
318 /* domain type must be limited to domain enum + server type. it must
319 not have SV_TYPE_SERVER or anything else with SERVER in it, else
320 clients get confused and start thinking this entry is a server
321 not a workgroup
323 uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT;
325 if (!work || !d)
326 return;
328 if (!lp_local_master())
330 DEBUG(0,("Samba not configured as a local master browser.\n"));
331 return;
334 DEBUG(2,("Becoming master for %s %s (currently at stage %d)\n",
335 work->work_group,inet_ntoa(d->bcast_ip),work->mst_state));
337 switch (work->mst_state)
339 case MST_POTENTIAL: /* while we were nothing but a server... */
341 DEBUG(3,("go to first stage: register ^1^2__MSBROWSE__^2^1\n"));
342 work->mst_state = MST_BACK; /* an election win was successful */
344 work->ElectionCriterion |= 0x5;
346 /* update our server status */
347 work->ServerType &= ~SV_TYPE_POTENTIAL_BROWSER;
348 add_server_entry(d,work,myname,work->ServerType|SV_TYPE_LOCAL_LIST_ONLY,
349 0,lp_serverstring(),True);
351 /* add special browser name */
352 add_my_name_entry(d,MSBROWSE,0x01,nb_type|NB_ACTIVE|NB_GROUP);
354 /* DON'T do anything else after calling add_my_name_entry() */
355 break;
358 case MST_BACK: /* while nothing had happened except we won an election... */
360 DEBUG(3,("go to second stage: register as master browser\n"));
361 work->mst_state = MST_MSB; /* registering MSBROWSE was successful */
363 /* add server entry on successful registration of MSBROWSE */
364 add_server_entry(d,work,work->work_group,domain_type|SV_TYPE_LOCAL_LIST_ONLY,
365 0,myname,True);
367 /* add master name */
368 add_my_name_entry(d,work->work_group,0x1d,nb_type|NB_ACTIVE);
370 /* DON'T do anything else after calling add_my_name_entry() */
371 break;
374 case MST_MSB: /* while we were still only registered MSBROWSE state... */
376 int i = 0;
377 struct server_record *sl;
379 DEBUG(3,("2nd stage complete: registered as master browser for workgroup %s \
380 on subnet %s\n", work->work_group, inet_ntoa(d->bcast_ip)));
381 work->mst_state = MST_BROWSER; /* registering WORKGROUP(1d) succeeded */
383 /* update our server status */
384 work->ServerType |= SV_TYPE_MASTER_BROWSER;
386 DEBUG(3,("become_local_master: updating our server %s to type %x\n",
387 myname, work->ServerType));
389 add_server_entry(d,work,myname,work->ServerType|SV_TYPE_LOCAL_LIST_ONLY,
390 0,lp_serverstring(),True);
392 /* Count the number of servers we have on our list. If it's
393 less than 10 (just a heuristic) request the servers
394 to announce themselves.
396 for( sl = work->serverlist; sl != NULL; sl = sl->next)
397 i++;
399 if (i < 10)
401 /* ask all servers on our local net to announce to us */
402 announce_request(work, d->bcast_ip);
405 /* Reset the announce master timer so that we do an announce as soon as possible
406 now we are a master. */
407 reset_announce_timer();
409 DEBUG(0,("Samba is now a local master browser for workgroup %s on subnet %s\n",
410 work->work_group, inet_ntoa(d->bcast_ip)));
412 break;
415 case MST_BROWSER:
417 /* don't have to do anything: just report success */
418 DEBUG(3,("3rd stage: become master browser!\n"));
419 break;
425 /*******************************************************************
426 become the domain master browser.
428 this is done in stages. note that this could take a while,
429 particularly on a broadcast subnet, as we have to wait for
430 the implicit registration of each name to be accepted.
432 as each name is successfully registered, become_domain_master() is
433 called again, in order to initiate the next stage. see
434 dead_netbios_entry() - deals with implicit name registration
435 and response_name_reg() - deals with explicit registration
436 with a WINS server.
438 stage 1: was DOMAIN_NONE - go to DOMAIN_MST
440 XXXX note: this code still does not cope with the distinction
441 between different types of nodes, particularly between M and P
442 nodes. that comes later.
444 ******************************************************************/
445 void become_domain_master(struct subnet_record *d, struct work_record *work)
447 /* domain type must be limited to domain enum + server type. it must
448 not have SV_TYPE_SERVER or anything else with SERVER in it, else
449 clients get confused and start thinking this entry is a server
450 not a workgroup
453 if (!work || !d) return;
455 if (!lp_domain_master())
457 DEBUG(0,("Samba not configured as a domain master browser.\n"));
458 return;
461 DEBUG(2,("Becoming domain master for %s %s (currently at stage %d)\n",
462 work->work_group,inet_ntoa(d->bcast_ip),work->dom_state));
464 switch (work->dom_state)
466 case DOMAIN_NONE: /* while we were nothing but a server... */
468 DEBUG(3,("become_domain_master: go to first stage: register <1b> name\n"));
469 work->dom_state = DOMAIN_WAIT;
471 /* Registering the DOMAIN<1b> name is very tricky. We need to
472 do this on all our subnets, but don't want to bradcast it
473 on locally connected subnets (WinNT doesn't do this). Also,
474 previous versions of Samba screw up royally when we do this.
475 We need to register it immediatly on our local subnet, but
476 also actually check with the WINS server if it exists. If the name
477 has already been claimed by someone else in the WINS server
478 then we need to back out all our local registrations and
479 fail. Thus we only directly enter the name on local subnets,
480 on the WINS subnet we actually check...
482 /* XXXX the 0x1b is domain master browser name */
483 add_my_name_entry(d, work->work_group,0x1b,nb_type|NB_ACTIVE);
485 /* DON'T do anything else after calling add_my_name_entry() */
486 break;
489 case DOMAIN_WAIT:
491 work->dom_state = DOMAIN_MST; /* ... become domain master */
492 DEBUG(3,("become_domain_master: first stage - register as domain member\n"));
494 /* update our server status */
495 work->ServerType |= SV_TYPE_NT|SV_TYPE_DOMAIN_MASTER;
496 add_server_entry(d,work,myname,work->ServerType|SV_TYPE_LOCAL_LIST_ONLY,
497 0, lp_serverstring(),True);
499 DEBUG(0,("Samba is now a domain master browser for workgroup %s on subnet %s\n",
500 work->work_group, inet_ntoa(d->bcast_ip)));
502 if (d == wins_subnet)
504 /* ok! we successfully registered by unicast with the
505 WINS server. we now expect to become the domain
506 master on the local subnets. if this fails, it's
507 probably a 1.9.16p2 to 1.9.16p11 server's fault
509 add_domain_master_bcast();
511 break;
514 case DOMAIN_MST:
516 /* don't have to do anything: just report success */
517 DEBUG(3,("domain second stage: there isn't one!\n"));
518 break;
524 /*******************************************************************
525 become a logon server.
526 ******************************************************************/
527 void become_logon_server(struct subnet_record *d, struct work_record *work)
529 if (!work || !d) return;
531 if (!lp_domain_logons())
533 DEBUG(0,("samba not configured as a logon master.\n"));
534 return;
537 DEBUG(2,("Becoming logon server for %s %s (currently at stage %d)\n",
538 work->work_group,inet_ntoa(d->bcast_ip),work->log_state));
540 switch (work->log_state)
542 case LOGON_NONE: /* while we were nothing but a server... */
544 DEBUG(3,("go to first stage: register <1c> name\n"));
545 work->log_state = LOGON_WAIT;
547 /* XXXX the 0x1c is apparently something to do with domain logons */
548 add_my_name_entry(d, myworkgroup,0x1c,nb_type|NB_ACTIVE|NB_GROUP);
550 /* DON'T do anything else after calling add_my_name_entry() */
551 break;
554 case LOGON_WAIT:
556 work->log_state = LOGON_SRV; /* ... become logon server */
557 DEBUG(3,("logon second stage: register \n"));
559 /* update our server status */
560 work->ServerType |= SV_TYPE_NT|SV_TYPE_DOMAIN_MEMBER;
561 add_server_entry(d,work,myname,work->ServerType|SV_TYPE_LOCAL_LIST_ONLY
562 ,0, lp_serverstring(),True);
564 /* DON'T do anything else after calling add_my_name_entry() */
565 break;
568 case LOGON_SRV:
570 DEBUG(3,("logon third stage: there isn't one!\n"));
571 break;
577 /*******************************************************************
578 unbecome the local master browser. initates removal of necessary netbios
579 names, and tells the world that we are no longer a master browser.
581 XXXX this _should_ be used to demote to a backup master browser, without
582 going straight to non-master browser. another time.
584 ******************************************************************/
585 void unbecome_local_master(struct subnet_record *d, struct work_record *work,
586 int remove_type)
588 int new_server_type = work->ServerType;
590 /* can only remove master types with this function */
591 remove_type &= SV_TYPE_MASTER_BROWSER;
593 new_server_type &= ~remove_type;
595 if (remove_type)
597 DEBUG(2,("Becoming local non-master for %s\n",work->work_group));
599 /* no longer a master browser of any sort */
601 work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
602 work->ElectionCriterion &= ~0x4;
603 work->mst_state = MST_POTENTIAL;
605 /* announce ourselves as no longer active as a master browser. */
606 announce_server(d, work, work->work_group, myname, 0, 0);
607 remove_name_entry(d,MSBROWSE ,0x01);
608 remove_name_entry(d,work->work_group,0x1d);
613 /*******************************************************************
614 unbecome the domain master browser. initates removal of necessary netbios
615 names, and tells the world that we are no longer a domain browser.
616 ******************************************************************/
617 void unbecome_domain_master(struct subnet_record *d, struct work_record *work,
618 int remove_type)
620 int new_server_type = work->ServerType;
622 DEBUG(2,("Becoming domain non-master for %s\n",work->work_group));
624 /* can only remove master or domain types with this function */
625 remove_type &= SV_TYPE_DOMAIN_MASTER;
627 new_server_type &= ~remove_type;
629 if (remove_type)
631 /* no longer a domain master browser of any sort */
633 work->dom_state = DOMAIN_NONE;
635 /* announce ourselves as no longer active as a master browser on
636 all our local subnets. */
637 for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
639 work = find_workgroupstruct(d, myworkgroup, False);
641 announce_server(d, work, work->work_group, myname, 0, 0);
642 /* Remove the name entry without any NetBIOS traffic as that's
643 how it was registered. */
644 remove_name_entry(d,work->work_group,0x1b);
650 /*******************************************************************
651 unbecome the logon server. initates removal of necessary netbios
652 names, and tells the world that we are no longer a logon server.
653 ******************************************************************/
654 void unbecome_logon_server(struct subnet_record *d, struct work_record *work,
655 int remove_type)
657 int new_server_type = work->ServerType;
659 DEBUG(2,("Becoming logon non-server for %s\n",work->work_group));
661 /* can only remove master or domain types with this function */
662 remove_type &= SV_TYPE_DOMAIN_MEMBER;
664 new_server_type &= ~remove_type;
666 if (remove_type)
668 /* no longer a master browser of any sort */
670 work->log_state = LOGON_NONE;
672 /* announce ourselves as no longer active as a master browser. */
673 announce_server(d, work, work->work_group, myname, 0, 0);
674 remove_name_entry(d,work->work_group,0x1c);
679 /*******************************************************************
680 run the election
681 ******************************************************************/
682 void run_elections(time_t t)
684 static time_t lastime = 0;
686 struct subnet_record *d;
688 /* send election packets once a second */
689 if (lastime && t-lastime <= 0) return;
691 lastime = t;
693 for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
695 struct work_record *work;
697 for (work = d->workgrouplist; work; work = work->next)
699 if (work->RunningElection)
701 send_election(d,work->work_group, work->ElectionCriterion,
702 t-StartupTime,myname);
704 if (work->ElectionCount++ >= 4)
706 /* I won! now what :-) */
707 DEBUG(2,(">>> Won election on %s %s <<<\n",
708 work->work_group,inet_ntoa(d->bcast_ip)));
710 work->RunningElection = False;
711 work->mst_state = MST_POTENTIAL;
713 become_local_master(d, work);
721 /*******************************************************************
722 work out if I win an election
723 ******************************************************************/
724 static BOOL win_election(struct work_record *work,int version,uint32 criterion,
725 int timeup,char *name)
727 int mytimeup = time(NULL) - StartupTime;
728 uint32 mycriterion = work->ElectionCriterion;
730 /* If local master is false then never win
731 in election broadcasts. */
732 if(!lp_local_master())
734 DEBUG(3,("win_election: Losing election as local master == False\n"));
735 return False;
738 DEBUG(4,("election comparison: %x:%x %x:%x %d:%d %s:%s\n",
739 version,ELECTION_VERSION,
740 criterion,mycriterion,
741 timeup,mytimeup,
742 name,myname));
744 if (version > ELECTION_VERSION) return(False);
745 if (version < ELECTION_VERSION) return(True);
747 if (criterion > mycriterion) return(False);
748 if (criterion < mycriterion) return(True);
750 if (timeup > mytimeup) return(False);
751 if (timeup < mytimeup) return(True);
753 if (strcasecmp(myname,name) > 0) return(False);
755 return(True);
759 /*******************************************************************
760 process a election packet
762 An election dynamically decides who will be the master.
763 ******************************************************************/
764 void process_election(struct packet_struct *p,char *buf)
766 struct dgram_packet *dgram = &p->packet.dgram;
767 struct in_addr ip = dgram->header.source_ip;
768 struct subnet_record *d = find_subnet(ip);
769 int version = CVAL(buf,0);
770 uint32 criterion = IVAL(buf,1);
771 int timeup = IVAL(buf,5)/1000;
772 char *name = buf+13;
773 struct work_record *work;
775 if (!d) return;
777 if (ip_equal(d->bcast_ip,wins_ip))
779 DEBUG(3,("Unexpected election request from %s %s on WINS net\n",
780 name, inet_ntoa(p->ip)));
781 return;
784 name[15] = 0;
786 DEBUG(3,("Election request from %s %s vers=%d criterion=%08x timeup=%d\n",
787 name,inet_ntoa(p->ip),version,criterion,timeup));
789 if (same_context(dgram)) return;
791 for (work = d->workgrouplist; work; work = work->next)
793 if (!strequal(work->work_group, myworkgroup))
794 continue;
796 if (win_election(work, version,criterion,timeup,name))
798 if (!work->RunningElection)
800 work->needelection = True;
801 work->ElectionCount=0;
802 work->mst_state = MST_POTENTIAL;
805 else
807 work->needelection = False;
809 if (work->RunningElection || AM_MASTER(work))
811 work->RunningElection = False;
812 DEBUG(3,(">>> Lost election on %s %s <<<\n",
813 work->work_group,inet_ntoa(d->bcast_ip)));
814 if (AM_MASTER(work))
816 unbecome_local_master(d, work, SV_TYPE_MASTER_BROWSER);
824 /****************************************************************************
825 checks whether a browser election is to be run on any workgroup
827 this function really ought to return the time between election
828 packets (which depends on whether samba intends to be a domain
829 master or a master browser) in milliseconds.
831 ***************************************************************************/
832 BOOL check_elections(void)
834 struct subnet_record *d;
835 BOOL run_any_election = False;
837 for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
839 struct work_record *work;
840 for (work = d->workgrouplist; work; work = work->next)
842 run_any_election |= work->RunningElection;
844 if (work->needelection && !work->RunningElection)
846 DEBUG(3,(">>> Starting election on %s %s <<<\n",
847 work->work_group,inet_ntoa(d->bcast_ip)));
848 work->ElectionCount = 0;
849 work->RunningElection = True;
850 work->needelection = False;
854 return run_any_election;