client.c: New print queue query code from Jeff C. Foster " <jfoste@wgc.woodward...
[Samba/gbeck.git] / source / nameelect.c
blob2b4ebf091cc0398085f03302b4bf45d2bb5ffdca
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,False);
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,False);
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 if(d == wins_subnet)
484 add_my_name_entry(d, work->work_group,0x1b,nb_type|NB_ACTIVE,False);
485 else
486 add_my_name_entry(d, work->work_group,0x1b,nb_type|NB_ACTIVE,True);
488 /* DON'T do anything else after calling add_my_name_entry() */
489 break;
492 case DOMAIN_WAIT:
494 work->dom_state = DOMAIN_MST; /* ... become domain master */
495 DEBUG(3,("become_domain_master: first stage - register as domain member\n"));
497 /* update our server status */
498 work->ServerType |= SV_TYPE_NT|SV_TYPE_DOMAIN_MASTER;
499 add_server_entry(d,work,myname,work->ServerType|SV_TYPE_LOCAL_LIST_ONLY,
500 0, lp_serverstring(),True);
502 DEBUG(0,("Samba is now a domain master browser for workgroup %s on subnet %s\n",
503 work->work_group, inet_ntoa(d->bcast_ip)));
505 break;
508 case DOMAIN_MST:
510 /* don't have to do anything: just report success */
511 DEBUG(3,("domain second stage: there isn't one!\n"));
512 break;
518 /*******************************************************************
519 become a logon server.
520 ******************************************************************/
521 void become_logon_server(struct subnet_record *d, struct work_record *work)
523 if (!work || !d) return;
525 if (!lp_domain_logons())
527 DEBUG(0,("samba not configured as a logon master.\n"));
528 return;
531 DEBUG(2,("Becoming logon server for %s %s (currently at stage %d)\n",
532 work->work_group,inet_ntoa(d->bcast_ip),work->log_state));
534 switch (work->log_state)
536 case LOGON_NONE: /* while we were nothing but a server... */
538 DEBUG(3,("go to first stage: register <1c> name\n"));
539 work->log_state = LOGON_WAIT;
541 /* XXXX the 0x1c is apparently something to do with domain logons */
542 add_my_name_entry(d, myworkgroup,0x1c,nb_type|NB_ACTIVE|NB_GROUP,False);
544 /* DON'T do anything else after calling add_my_name_entry() */
545 break;
548 case LOGON_WAIT:
550 work->log_state = LOGON_SRV; /* ... become logon server */
551 DEBUG(3,("logon second stage: register \n"));
553 /* update our server status */
554 work->ServerType |= SV_TYPE_NT|SV_TYPE_DOMAIN_MEMBER;
555 add_server_entry(d,work,myname,work->ServerType|SV_TYPE_LOCAL_LIST_ONLY
556 ,0, lp_serverstring(),True);
558 /* DON'T do anything else after calling add_my_name_entry() */
559 break;
562 case LOGON_SRV:
564 DEBUG(3,("logon third stage: there isn't one!\n"));
565 break;
571 /*******************************************************************
572 unbecome the local master browser. initates removal of necessary netbios
573 names, and tells the world that we are no longer a master browser.
575 XXXX this _should_ be used to demote to a backup master browser, without
576 going straight to non-master browser. another time.
578 ******************************************************************/
579 void unbecome_local_master(struct subnet_record *d, struct work_record *work,
580 int remove_type)
582 int new_server_type = work->ServerType;
584 /* can only remove master types with this function */
585 remove_type &= SV_TYPE_MASTER_BROWSER;
587 new_server_type &= ~remove_type;
589 if (remove_type)
591 DEBUG(2,("Becoming local non-master for %s\n",work->work_group));
593 /* no longer a master browser of any sort */
595 work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
596 work->ElectionCriterion &= ~0x4;
597 work->mst_state = MST_POTENTIAL;
599 /* announce ourselves as no longer active as a master browser. */
600 announce_server(d, work, work->work_group, myname, 0, 0);
601 remove_name_entry(d,MSBROWSE ,0x01,False);
602 remove_name_entry(d,work->work_group,0x1d,False);
607 /*******************************************************************
608 unbecome the domain master browser. initates removal of necessary netbios
609 names, and tells the world that we are no longer a domain browser.
610 ******************************************************************/
611 void unbecome_domain_master(struct subnet_record *d, struct work_record *work,
612 int remove_type)
614 int new_server_type = work->ServerType;
616 DEBUG(2,("Becoming domain non-master for %s\n",work->work_group));
618 /* can only remove master or domain types with this function */
619 remove_type &= SV_TYPE_DOMAIN_MASTER;
621 new_server_type &= ~remove_type;
623 if (remove_type)
625 /* no longer a domain master browser of any sort */
627 work->dom_state = DOMAIN_NONE;
629 /* announce ourselves as no longer active as a master browser on
630 all our local subnets. */
631 for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
633 work = find_workgroupstruct(d, myworkgroup, False);
635 announce_server(d, work, work->work_group, myname, 0, 0);
636 /* Remove the name entry without any NetBIOS traffic as that's
637 how it was registered. */
638 remove_name_entry(d,work->work_group,0x1b,True);
644 /*******************************************************************
645 unbecome the logon server. initates removal of necessary netbios
646 names, and tells the world that we are no longer a logon server.
647 ******************************************************************/
648 void unbecome_logon_server(struct subnet_record *d, struct work_record *work,
649 int remove_type)
651 int new_server_type = work->ServerType;
653 DEBUG(2,("Becoming logon non-server for %s\n",work->work_group));
655 /* can only remove master or domain types with this function */
656 remove_type &= SV_TYPE_DOMAIN_MEMBER;
658 new_server_type &= ~remove_type;
660 if (remove_type)
662 /* no longer a master browser of any sort */
664 work->log_state = LOGON_NONE;
666 /* announce ourselves as no longer active as a master browser. */
667 announce_server(d, work, work->work_group, myname, 0, 0);
668 remove_name_entry(d,work->work_group,0x1c,False);
673 /*******************************************************************
674 run the election
675 ******************************************************************/
676 void run_elections(time_t t)
678 static time_t lastime = 0;
680 struct subnet_record *d;
682 /* send election packets once a second */
683 if (lastime && t-lastime <= 0) return;
685 lastime = t;
687 for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
689 struct work_record *work;
691 for (work = d->workgrouplist; work; work = work->next)
693 if (work->RunningElection)
695 send_election(d,work->work_group, work->ElectionCriterion,
696 t-StartupTime,myname);
698 if (work->ElectionCount++ >= 4)
700 /* I won! now what :-) */
701 DEBUG(2,(">>> Won election on %s %s <<<\n",
702 work->work_group,inet_ntoa(d->bcast_ip)));
704 work->RunningElection = False;
705 work->mst_state = MST_POTENTIAL;
707 become_local_master(d, work);
715 /*******************************************************************
716 work out if I win an election
717 ******************************************************************/
718 static BOOL win_election(struct work_record *work,int version,uint32 criterion,
719 int timeup,char *name)
721 int mytimeup = time(NULL) - StartupTime;
722 uint32 mycriterion = work->ElectionCriterion;
724 /* If local master is false then never win
725 in election broadcasts. */
726 if(!lp_local_master())
728 DEBUG(3,("win_election: Losing election as local master == False\n"));
729 return False;
732 DEBUG(4,("election comparison: %x:%x %x:%x %d:%d %s:%s\n",
733 version,ELECTION_VERSION,
734 criterion,mycriterion,
735 timeup,mytimeup,
736 name,myname));
738 if (version > ELECTION_VERSION) return(False);
739 if (version < ELECTION_VERSION) return(True);
741 if (criterion > mycriterion) return(False);
742 if (criterion < mycriterion) return(True);
744 if (timeup > mytimeup) return(False);
745 if (timeup < mytimeup) return(True);
747 if (strcasecmp(myname,name) > 0) return(False);
749 return(True);
753 /*******************************************************************
754 process a election packet
756 An election dynamically decides who will be the master.
757 ******************************************************************/
758 void process_election(struct packet_struct *p,char *buf)
760 struct dgram_packet *dgram = &p->packet.dgram;
761 struct in_addr ip = dgram->header.source_ip;
762 struct subnet_record *d = find_subnet(ip);
763 int version = CVAL(buf,0);
764 uint32 criterion = IVAL(buf,1);
765 int timeup = IVAL(buf,5)/1000;
766 char *name = buf+13;
767 struct work_record *work;
769 if (!d) return;
771 if (ip_equal(d->bcast_ip,wins_ip))
773 DEBUG(3,("Unexpected election request from %s %s on WINS net\n",
774 name, inet_ntoa(p->ip)));
775 return;
778 name[15] = 0;
780 DEBUG(3,("Election request from %s %s vers=%d criterion=%08x timeup=%d\n",
781 name,inet_ntoa(p->ip),version,criterion,timeup));
783 if (same_context(dgram)) return;
785 for (work = d->workgrouplist; work; work = work->next)
787 if (!strequal(work->work_group, myworkgroup))
788 continue;
790 if (win_election(work, version,criterion,timeup,name))
792 if (!work->RunningElection)
794 work->needelection = True;
795 work->ElectionCount=0;
796 work->mst_state = MST_POTENTIAL;
799 else
801 work->needelection = False;
803 if (work->RunningElection || AM_MASTER(work))
805 work->RunningElection = False;
806 DEBUG(3,(">>> Lost election on %s %s <<<\n",
807 work->work_group,inet_ntoa(d->bcast_ip)));
808 if (AM_MASTER(work))
810 unbecome_local_master(d, work, SV_TYPE_MASTER_BROWSER);
818 /****************************************************************************
819 checks whether a browser election is to be run on any workgroup
821 this function really ought to return the time between election
822 packets (which depends on whether samba intends to be a domain
823 master or a master browser) in milliseconds.
825 ***************************************************************************/
826 BOOL check_elections(void)
828 struct subnet_record *d;
829 BOOL run_any_election = False;
831 for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
833 struct work_record *work;
834 for (work = d->workgrouplist; work; work = work->next)
836 run_any_election |= work->RunningElection;
838 if (work->needelection && !work->RunningElection)
840 DEBUG(3,(">>> Starting election on %s %s <<<\n",
841 work->work_group,inet_ntoa(d->bcast_ip)));
842 work->ElectionCount = 0;
843 work->RunningElection = True;
844 work->needelection = False;
848 return run_any_election;