finally! doing a strequal() == 0 instead of just strequal(). too used to
[kai/samba.git] / source3 / nameelect.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NBT netbios routines and daemon - version 2
5    Copyright (C) Andrew Tridgell 1994-1996
6    
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.
11    
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.
16    
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.
20    
21    Module name: nameelect.c
22
23    Revision History:
24
25    14 jan 96: lkcl@pires.co.uk
26    added multiple workgroup domain master support
27
28    04 jul 96: lkcl@pires.co.uk
29    added system to become a master browser by stages.
30
31
32 */
33
34 #include "includes.h"
35
36 extern int ClientNMB;
37 extern int ClientDGRAM;
38
39 extern int DEBUGLEVEL;
40 extern pstring scope;
41
42 extern pstring myname;
43 extern struct in_addr ipzero;
44 extern struct in_addr ipgrp;
45
46 /* here are my election parameters */
47
48 extern time_t StartupTime;
49
50 extern struct subnet_record *subnetlist;
51
52 extern uint16 nb_type; /* samba's NetBIOS name type */
53
54
55 /*******************************************************************
56   occasionally check to see if the master browser is around
57   ******************************************************************/
58 void check_master_browser(time_t t)
59 {
60         static time_t lastrun=0;
61         struct subnet_record *d;
62
63         if (!lastrun) lastrun = t;
64         if (t < lastrun + CHECK_TIME_MST_BROWSE * 60) return;
65
66         lastrun = t;
67
68         dump_workgroups();
69
70         for (d = subnetlist; d; d = d->next)
71         {
72                 struct work_record *work;
73
74                 for (work = d->workgrouplist; work; work = work->next)
75                 {
76                         if (!AM_MASTER(work))
77                         {
78                                 if (lp_preferred_master())
79                                 {
80                                         /* preferred master - not a master browser.  force
81                                            becoming a master browser, hence the log message.
82                                          */
83
84                                         DEBUG(0,("%s preferred master for %s %s - force election\n",
85                                                   timestring(), work->work_group,
86                                                   inet_ntoa(d->bcast_ip)));
87
88                                         browser_gone(work->work_group, d->bcast_ip);
89                                 }
90                                 else
91                                 {
92                                         /* if we are not the browse master of a workgroup,
93                                            and we can't find a browser on the subnet, do
94                                            something about it.
95                                          */
96
97                                         queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_MST_CHK,
98                                                      work->work_group,0x1d,0,0,0,NULL,NULL,
99                                                      True,False,d->bcast_ip,d->bcast_ip);
100                                 }
101                         }
102                 }
103         }
104 }
105
106
107 /*******************************************************************
108   what to do if a master browser DOESN't exist
109   ******************************************************************/
110 void browser_gone(char *work_name, struct in_addr ip)
111 {
112   struct subnet_record *d = find_subnet(ip);
113   struct work_record *work = find_workgroupstruct(d, work_name, False);
114
115   /* i don't know about this workgroup, therefore i don't care */
116   if (!work || !d) return;
117
118   /* don't do election stuff on the WINS subnet */
119   if (ip_equal(d->bcast_ip,ipgrp)) 
120     return;
121
122   if (strequal(work->work_group, lp_workgroup()))
123   {
124
125       DEBUG(2,("Forcing election on %s %s\n",
126                work->work_group,inet_ntoa(d->bcast_ip)));
127
128       /* we can attempt to become master browser */
129       work->needelection = True;
130   }
131   else
132   {
133      /* local interfaces: force an election */
134     send_election(d, work->work_group, 0, 0, myname);
135
136      /* only removes workgroup completely on a local interface 
137         persistent lmhosts entries on a local interface _will_ be removed).
138       */
139      remove_workgroup(d, work,True);
140   }
141 }
142
143
144 /****************************************************************************
145   send an election packet
146   **************************************************************************/
147 void send_election(struct subnet_record *d, char *group,uint32 criterion,
148                    int timeup,char *name)
149 {
150   pstring outbuf;
151   char *p;
152
153   if (!d) return;
154   
155   DEBUG(2,("Sending election to %s for workgroup %s\n",
156            inet_ntoa(d->bcast_ip),group));         
157
158   bzero(outbuf,sizeof(outbuf));
159   p = outbuf;
160   CVAL(p,0) = ANN_Election; /* election */
161   p++;
162
163   CVAL(p,0) = (criterion == 0 && timeup == 0) ? 0 : ELECTION_VERSION;
164   SIVAL(p,1,criterion);
165   SIVAL(p,5,timeup*1000); /* ms - despite the spec */
166   p += 13;
167   strcpy(p,name);
168   strupper(p);
169   p = skip_string(p,1);
170   
171   send_mailslot_reply(False,BROWSE_MAILSLOT,ClientDGRAM,
172               outbuf,PTR_DIFF(p,outbuf),
173                       name,group,0,0x1e,d->bcast_ip,*iface_ip(d->bcast_ip));
174 }
175
176
177 /****************************************************************************
178   un-register a SELF name that got rejected.
179
180   if this name happens to be rejected when samba is in the process
181   of becoming a master browser (registering __MSBROWSE__, WORKGROUP(1d)
182   or WORKGROUP(1b)) then we must stop being a master browser. sad.
183
184   **************************************************************************/
185 void name_unregister_work(struct subnet_record *d, char *name, int name_type)
186 {
187     struct work_record *work;
188     int remove_type_local  = 0;
189     int remove_type_domain = 0;
190     int remove_type_logon  = 0;
191
192     remove_netbios_name(d,name,name_type,SELF,ipzero);
193
194     if (!(work = find_workgroupstruct(d, name, False))) return;
195
196     /* work out what to unbecome, from the name type being removed */
197
198     if (ms_browser_name(name, name_type))
199     {
200       remove_type_local |= SV_TYPE_MASTER_BROWSER;
201     }
202     if (AM_MASTER(work) && strequal(name, lp_workgroup()) && name_type == 0x1d)
203     {
204       remove_type_local |= SV_TYPE_MASTER_BROWSER;
205     }
206     if (AM_DOMMST(work) && strequal(name, lp_workgroup()) && name_type == 0x1b)
207     {
208       remove_type_domain |= SV_TYPE_DOMAIN_MASTER;
209     }
210     if (AM_DOMMEM(work) && strequal(name, lp_workgroup()) && name_type == 0x1c)
211     {
212       remove_type_logon|= SV_TYPE_DOMAIN_MEMBER;
213     }
214
215     if (remove_type_local ) unbecome_local_master (d, work, remove_type_local );
216     if (remove_type_domain) unbecome_domain_master(d, work, remove_type_domain);
217     if (remove_type_logon ) unbecome_logon_server (d, work, remove_type_logon );
218 }
219
220
221 /****************************************************************************
222   registers a name.
223
224   if the name being added is a SELF name, we must additionally check
225   whether to proceed to the next stage in samba becoming a master browser.
226
227   **************************************************************************/
228 void name_register_work(struct subnet_record *d, char *name, int name_type,
229                                 int nb_flags, time_t ttl, struct in_addr ip, BOOL bcast)
230 {
231         enum name_source source = (ismyip(ip) || ip_equal(ip, ipzero)) ?
232                                   SELF : REGISTER;
233
234         if (source == SELF)
235         {
236                 struct work_record *work = find_workgroupstruct(d, lp_workgroup(), False);
237
238                 add_netbios_entry(d,name,name_type,nb_flags,ttl,source,ip,True,!bcast);
239
240                 if (work)
241                 {
242                         int add_type_local  = False;
243                         int add_type_domain = False;
244                         int add_type_logon  = False;
245
246                         DEBUG(4,("checking next stage: name_register_work %s\n", name));
247
248                         /* work out what to become, from the name type being added */
249
250                         if (ms_browser_name(name, name_type))
251                         {
252                                 add_type_local = True;
253                         }
254                         if (strequal(name, lp_workgroup()) && name_type == 0x1d)
255                         {
256                                 add_type_local = True;
257                         }
258                         if (strequal(name, lp_workgroup()) && name_type == 0x1b)
259                         {
260                                 add_type_domain = True;
261                         }
262                         if (strequal(name, lp_workgroup()) && name_type == 0x1c)
263                         {
264                                 add_type_logon = True;
265                         }
266
267                         if (add_type_local ) become_local_master (d, work);
268                         if (add_type_domain) become_domain_master(d, work);
269                         if (add_type_logon ) become_logon_server (d, work);
270                 }
271         }
272 }
273
274
275 /*******************************************************************
276   become the local master browser.
277
278   this is done in stages. note that this could take a while, 
279   particularly on a broadcast subnet, as we have to wait for
280   the implicit registration of each name to be accepted.
281
282   as each name is successfully registered, become_local_master() is
283   called again, in order to initiate the next stage. see
284   dead_netbios_entry() - deals with implicit name registration
285   and response_name_reg() - deals with explicit registration
286   with a WINS server.
287
288   stage 1: was MST_POTENTIAL - go to MST_POTENTIAL and register ^1^2__MSBROWSE__^2^1.
289   stage 2: was MST_BACK  - go to MST_MSB  and register WORKGROUP(0x1d)
290   stage 3: was MST_MSB  - go to MST_BROWSER and stay there 
291
292   XXXX note: this code still does not cope with the distinction
293   between different types of nodes, particularly between M and P
294   nodes. that comes later.
295
296   ******************************************************************/
297 void become_local_master(struct subnet_record *d, struct work_record *work)
298 {
299   /* domain type must be limited to domain enum + server type. it must
300      not have SV_TYPE_SERVER or anything else with SERVER in it, else
301      clients get confused and start thinking this entry is a server
302      not a workgroup
303    */
304   uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT;
305
306   if (!work || !d) return;
307   
308   DEBUG(2,("Becoming master for %s %s (currently at stage %d)\n",
309                                         work->work_group,inet_ntoa(d->bcast_ip),work->mst_state));
310   
311   switch (work->mst_state)
312   {
313     case MST_POTENTIAL: /* while we were nothing but a server... */
314     {
315       DEBUG(3,("go to first stage: register ^1^2__MSBROWSE__^2^1\n"));
316       work->mst_state = MST_BACK; /* ... an election win was successful */
317
318       work->ElectionCriterion |= 0x5;
319
320       /* update our server status */
321       work->ServerType &= ~SV_TYPE_POTENTIAL_BROWSER;
322       add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True);
323
324       /* add special browser name */
325       add_my_name_entry(d,MSBROWSE        ,0x01,nb_type|NB_ACTIVE|NB_GROUP);
326
327       /* DON'T do anything else after calling add_my_name_entry() */
328       break;
329     }
330
331     case MST_BACK: /* while nothing had happened except we won an election... */
332     {
333       DEBUG(3,("go to second stage: register as master browser\n"));
334       work->mst_state = MST_MSB; /* ... registering MSBROWSE was successful */
335
336       /* add server entry on successful registration of MSBROWSE */
337       add_server_entry(d,work,work->work_group,domain_type,0,myname,True);
338
339       /* add master name */
340       add_my_name_entry(d,work->work_group,0x1d,nb_type|NB_ACTIVE);
341   
342       /* DON'T do anything else after calling add_my_name_entry() */
343       break;
344     }
345
346     case MST_MSB: /* while we were still only registered MSBROWSE state... */
347     {
348       DEBUG(3,("2nd stage complete: registered as master browser\n"));
349       work->mst_state = MST_BROWSER; /* ... registering WORKGROUP(1d) succeeded */
350
351       /* update our server status */
352       work->ServerType |= SV_TYPE_MASTER_BROWSER;
353       add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True);
354
355       if (work->serverlist == NULL) /* no servers! */
356       {
357         /* ask all servers on our local net to announce to us */
358         /* XXXX OOPS! add_server_entry will always add one entry - our own. */
359         announce_request(work, d->bcast_ip);
360       }
361       break;
362     }
363
364     case MST_BROWSER:
365     {
366       /* don't have to do anything: just report success */
367       DEBUG(3,("3rd stage: become master browser!\n"));
368
369       break;
370     }
371   }
372 }
373
374
375 /*******************************************************************
376   become the domain master browser.
377
378   this is done in stages. note that this could take a while, 
379   particularly on a broadcast subnet, as we have to wait for
380   the implicit registration of each name to be accepted.
381
382   as each name is successfully registered, become_domain_master() is
383   called again, in order to initiate the next stage. see
384   dead_netbios_entry() - deals with implicit name registration
385   and response_name_reg() - deals with explicit registration
386   with a WINS server.
387
388   stage 1: was DOMAIN_NONE - go to DOMAIN_MST 
389
390   XXXX note: this code still does not cope with the distinction
391   between different types of nodes, particularly between M and P
392   nodes. that comes later.
393
394   ******************************************************************/
395 void become_domain_master(struct subnet_record *d, struct work_record *work)
396 {
397   /* domain type must be limited to domain enum + server type. it must
398      not have SV_TYPE_SERVER or anything else with SERVER in it, else
399      clients get confused and start thinking this entry is a server
400      not a workgroup
401    */
402
403   if ((!work) || (!d)) return;
404   
405   DEBUG(2,("Becoming domain master for %s %s (currently at stage %d)\n",
406                                         work->work_group,inet_ntoa(d->bcast_ip),work->dom_state));
407   
408   switch (work->dom_state)
409   {
410     case DOMAIN_NONE: /* while we were nothing but a server... */
411     {
412       if (lp_domain_master())
413       {
414                   DEBUG(3,("go to first stage: register <1b> name\n"));
415                   work->dom_state = DOMAIN_WAIT;
416
417                   /* XXXX the 0x1b is domain master browser name */
418                   add_my_name_entry(d, lp_workgroup(),0x1b,nb_type|NB_ACTIVE|NB_GROUP);
419
420                   /* DON'T do anything else after calling add_my_name_entry() */
421                   break;
422       }
423       else
424       {
425         DEBUG(4,("samba not configured as a domain master.\n"));
426       }
427   
428       break;
429     }
430
431    case DOMAIN_WAIT:
432    {
433       if (lp_domain_master())
434       {
435         work->dom_state = DOMAIN_MST; /* ... become domain master */
436         DEBUG(3,("domain first stage: register as domain member\n"));
437  
438         /* update our server status */
439         work->ServerType |= SV_TYPE_NT|SV_TYPE_DOMAIN_MASTER;
440         add_server_entry(d,work,myname,work->ServerType,0,
441                          lp_serverstring(),True);
442
443         DEBUG(4,("samba is now a domain master\n"));
444
445         break;
446       }
447       else
448       {
449         DEBUG(4,("samba not configured as a domain master.\n"));
450       }
451   
452       break;
453    }
454
455     case DOMAIN_MST:
456     {
457       /* don't have to do anything: just report success */
458       DEBUG(3,("domain second stage: there isn't one!\n"));
459       break;
460     }
461   }
462 }
463
464
465 /*******************************************************************
466   become a logon server.
467   ******************************************************************/
468 void become_logon_server(struct subnet_record *d, struct work_record *work)
469 {
470   if (!work || !d) return;
471   
472   DEBUG(2,("Becoming logon server for %s %s (currently at stage %d)\n",
473                                         work->work_group,inet_ntoa(d->bcast_ip),work->log_state));
474   
475   switch (work->log_state)
476   {
477     case LOGON_NONE: /* while we were nothing but a server... */
478     {
479       if (lp_domain_logons())
480       {
481                   DEBUG(3,("go to first stage: register <1c> name\n"));
482                   work->log_state = LOGON_WAIT;
483
484           /* XXXX the 0x1c is apparently something to do with domain logons */
485           add_my_name_entry(d, lp_workgroup(),0x1c,nb_type|NB_ACTIVE|NB_GROUP);
486
487                   /* DON'T do anything else after calling add_my_name_entry() */
488                   break;
489       }
490       {
491         DEBUG(4,("samba not configured as a logon master.\n"));
492       }
493   
494       break;
495     }
496
497    case LOGON_WAIT:
498    {
499       if (lp_domain_logons())
500       {
501         work->log_state = LOGON_SRV; /* ... become logon server */
502         DEBUG(3,("logon second stage: register \n"));
503  
504         /* update our server status */
505         work->ServerType |= SV_TYPE_NT|SV_TYPE_DOMAIN_MEMBER;
506         add_server_entry(d,work,myname,work->ServerType,0,
507                          lp_serverstring(),True);
508
509         /* DON'T do anything else after calling add_my_name_entry() */
510         break;
511       }
512       else
513       {
514         DEBUG(4,("samba not configured as a logon server.\n"));
515       }
516   
517       break;
518    }
519
520    case LOGON_SRV:
521    {
522       DEBUG(3,("logon third stage: there isn't one!\n"));
523       break;
524    }
525
526   }
527 }
528
529
530 /*******************************************************************
531   unbecome the local master browser. initates removal of necessary netbios 
532   names, and tells the world that we are no longer a master browser.
533
534   XXXX this _should_ be used to demote to a backup master browser, without
535   going straight to non-master browser.  another time.
536
537   ******************************************************************/
538 void unbecome_local_master(struct subnet_record *d, struct work_record *work,
539                                 int remove_type)
540 {
541   int new_server_type = work->ServerType;
542
543   /* can only remove master types with this function */
544   remove_type &= SV_TYPE_MASTER_BROWSER;
545
546   new_server_type &= ~remove_type;
547
548   if (remove_type)
549   {
550     DEBUG(2,("Becoming local non-master for %s\n",work->work_group));
551   
552     /* no longer a master browser of any sort */
553
554     work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
555     work->ElectionCriterion &= ~0x4;
556     work->mst_state = MST_POTENTIAL;
557
558         /* announce ourselves as no longer active as a master browser. */
559     announce_server(d, work, work->work_group, myname, 0, 0);
560     remove_name_entry(d,MSBROWSE        ,0x01);
561     remove_name_entry(d,work->work_group,0x1d);
562   }
563 }
564
565
566 /*******************************************************************
567   unbecome the domain master browser. initates removal of necessary netbios 
568   names, and tells the world that we are no longer a domain browser.
569   ******************************************************************/
570 void unbecome_domain_master(struct subnet_record *d, struct work_record *work,
571                                 int remove_type)
572 {
573   int new_server_type = work->ServerType;
574
575   DEBUG(2,("Becoming domain non-master for %s\n",work->work_group));
576   
577   /* can only remove master or domain types with this function */
578   remove_type &= SV_TYPE_DOMAIN_MASTER;
579
580   new_server_type &= ~remove_type;
581
582   if (remove_type)
583   {
584     /* no longer a domain master browser of any sort */
585
586     work->dom_state = DOMAIN_NONE;
587
588         /* announce ourselves as no longer active as a master browser. */
589     announce_server(d, work, work->work_group, myname, 0, 0);
590     remove_name_entry(d,work->work_group,0x1b);    
591   }
592 }
593
594
595 /*******************************************************************
596   unbecome the logon server. initates removal of necessary netbios 
597   names, and tells the world that we are no longer a logon server.
598   ******************************************************************/
599 void unbecome_logon_server(struct subnet_record *d, struct work_record *work,
600                                 int remove_type)
601 {
602   int new_server_type = work->ServerType;
603
604   DEBUG(2,("Becoming logon non-server for %s\n",work->work_group));
605   
606   /* can only remove master or domain types with this function */
607   remove_type &= SV_TYPE_DOMAIN_MEMBER;
608
609   new_server_type &= ~remove_type;
610
611   if (remove_type)
612   {
613     /* no longer a master browser of any sort */
614
615     work->log_state = LOGON_NONE;
616
617         /* announce ourselves as no longer active as a master browser. */
618     announce_server(d, work, work->work_group, myname, 0, 0);
619     remove_name_entry(d,work->work_group,0x1c);    
620   }
621 }
622
623
624 /*******************************************************************
625   run the election
626   ******************************************************************/
627 void run_elections(time_t t)
628 {
629   static time_t lastime = 0;
630   
631   struct subnet_record *d;
632   
633   /* send election packets once a second */
634   if (lastime && t-lastime <= 0) return;
635   
636   lastime = t;
637   
638   for (d = subnetlist; d; d = d->next)
639   {
640     struct work_record *work;
641     for (work = d->workgrouplist; work; work = work->next)
642         {
643           if (work->RunningElection)
644           {
645             send_election(d,work->work_group, work->ElectionCriterion,
646                             t-StartupTime,myname);
647               
648             if (work->ElectionCount++ >= 4)
649                 {
650                   /* I won! now what :-) */
651                   DEBUG(2,(">>> Won election on %s %s <<<\n",
652                            work->work_group,inet_ntoa(d->bcast_ip)));
653                   
654                   work->RunningElection = False;
655                   work->mst_state = MST_POTENTIAL;
656
657                   become_local_master(d, work);
658                 }
659           }
660         }
661   }
662 }
663
664
665 /*******************************************************************
666   work out if I win an election
667   ******************************************************************/
668 static BOOL win_election(struct work_record *work,int version,uint32 criterion,
669                          int timeup,char *name)
670 {  
671   int mytimeup = time(NULL) - StartupTime;
672   uint32 mycriterion = work->ElectionCriterion;
673
674   DEBUG(4,("election comparison: %x:%x %x:%x %d:%d %s:%s\n",
675            version,ELECTION_VERSION,
676            criterion,mycriterion,
677            timeup,mytimeup,
678            name,myname));
679
680   if (version > ELECTION_VERSION) return(False);
681   if (version < ELECTION_VERSION) return(True);
682   
683   if (criterion > mycriterion) return(False);
684   if (criterion < mycriterion) return(True);
685
686   if (timeup > mytimeup) return(False);
687   if (timeup < mytimeup) return(True);
688
689   if (strcasecmp(myname,name) > 0) return(False);
690   
691   return(True);
692 }
693
694
695 /*******************************************************************
696   process a election packet
697
698   An election dynamically decides who will be the master. 
699   ******************************************************************/
700 void process_election(struct packet_struct *p,char *buf)
701 {
702   struct dgram_packet *dgram = &p->packet.dgram;
703   struct in_addr ip = dgram->header.source_ip;
704   struct subnet_record *d = find_subnet(ip);
705   int version = CVAL(buf,0);
706   uint32 criterion = IVAL(buf,1);
707   int timeup = IVAL(buf,5)/1000;
708   char *name = buf+13;
709   struct work_record *work;
710
711   if (!d) return;
712
713   if (ip_equal(d->bcast_ip,ipgrp)) {
714     DEBUG(3,("Unexpected election request from %s %s on WINS net\n",
715              name, inet_ntoa(p->ip)));
716     return;
717   }
718   
719   name[15] = 0;  
720
721   DEBUG(3,("Election request from %s %s vers=%d criterion=%08x timeup=%d\n",
722            name,inet_ntoa(p->ip),version,criterion,timeup));
723   
724   if (same_context(dgram)) return;
725   
726   for (work = d->workgrouplist; work; work = work->next)
727     {
728       if (!strequal(work->work_group, lp_workgroup()))
729         continue;
730
731       if (win_election(work, version,criterion,timeup,name)) {
732         if (!work->RunningElection) {
733           work->needelection = True;
734           work->ElectionCount=0;
735           work->mst_state = MST_POTENTIAL;
736         }
737       } else {
738         work->needelection = False;
739           
740         if (work->RunningElection || AM_MASTER(work)) {
741           work->RunningElection = False;
742           DEBUG(3,(">>> Lost election on %s %s <<<\n",
743                    work->work_group,inet_ntoa(d->bcast_ip)));
744           if (AM_MASTER(work))
745             unbecome_local_master(d, work, SV_TYPE_MASTER_BROWSER);
746         }
747       }
748     }
749 }
750
751
752 /****************************************************************************
753   checks whether a browser election is to be run on any workgroup
754
755   this function really ought to return the time between election
756   packets (which depends on whether samba intends to be a domain
757   master or a master browser) in milliseconds.
758
759   ***************************************************************************/
760 BOOL check_elections(void)
761 {
762   struct subnet_record *d;
763   BOOL run_any_election = False;
764
765   for (d = subnetlist; d; d = d->next)
766     {
767       struct work_record *work;
768       for (work = d->workgrouplist; work; work = work->next)
769         {
770           run_any_election |= work->RunningElection;
771           
772           if (work->needelection && !work->RunningElection)
773             {
774               DEBUG(3,(">>> Starting election on %s %s <<<\n",
775                        work->work_group,inet_ntoa(d->bcast_ip)));
776               work->ElectionCount = 0;
777               work->RunningElection = True;
778               work->needelection = False;
779             }
780         }
781     }
782   return run_any_election;
783 }
784