namedbname.c: Fixed problem with remove_name code that could cause core dump.
[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-1997
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 fstring myworkgroup;
44 extern struct in_addr ipzero;
45 extern struct in_addr wins_ip;
46
47 /* here are my election parameters */
48
49 extern time_t StartupTime;
50
51 extern struct subnet_record *subnetlist;
52
53 extern uint16 nb_type; /* samba's NetBIOS name type */
54
55
56 /*******************************************************************
57   occasionally check to see if the master browser is around
58   ******************************************************************/
59 void check_master_browser(time_t t)
60 {
61   static time_t lastrun=0;
62   struct subnet_record *d;
63
64   if (!lastrun) lastrun = t;
65   if (t < lastrun + CHECK_TIME_MST_BROWSE * 60) return;
66
67   lastrun = t;
68
69   dump_workgroups();
70
71   for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
72   {
73     struct work_record *work;
74
75     for (work = d->workgrouplist; work; work = work->next)
76     {
77       if (strequal(work->work_group, myworkgroup) && !AM_MASTER(work))
78       {
79         if (lp_local_master())
80         {
81           /* potential master browser - not a master browser.  force
82              becoming a master browser, hence the log message.
83            */
84
85           DEBUG(0,("%s potential master for %s %s - force election\n",
86                    timestring(), work->work_group,
87                    inet_ntoa(d->bcast_ip)));
88
89           browser_gone(work->work_group, d->bcast_ip);
90         }
91         else
92         {
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.
96            */
97
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);
101         }
102       }
103     }
104   }
105 }
106
107
108 /*******************************************************************
109   what to do if a master browser DOESN't exist.
110
111   option 1: force an election, and participate in it
112   option 2: force an election, and let everyone else participate.
113
114   ******************************************************************/
115 void browser_gone(char *work_name, struct in_addr ip)
116 {
117   struct subnet_record *d = find_subnet(ip);
118   struct work_record *work = find_workgroupstruct(d, work_name, False);
119
120   /* i don't know about this workgroup, therefore i don't care */
121   if (!work || !d) return;
122
123   /* don't do election stuff on the WINS subnet */
124   if (ip_equal(d->bcast_ip,wins_ip)) 
125     return;
126
127   if (strequal(work->work_group, myworkgroup))
128   {
129
130     if (lp_local_master())
131     {
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.
135        */
136       DEBUG(2,("Forcing election on %s %s\n",
137                work->work_group,inet_ntoa(d->bcast_ip)));
138
139       /* we can attempt to become master browser */
140       work->needelection = True;
141     }
142     else
143     {
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.
147        */
148
149       /* local interfaces: force an election */
150       send_election(d, work->work_group, 0, 0, myname);
151
152       /* only removes workgroup completely on a local interface 
153          persistent lmhosts entries on a local interface _will_ be removed).
154        */
155       remove_workgroup(d, work,True);
156       add_workgroup_to_subnet(d, work->work_group);
157     }
158   }
159 }
160
161
162 /****************************************************************************
163   send an election packet
164   **************************************************************************/
165 void send_election(struct subnet_record *d, char *group,uint32 criterion,
166                    int timeup,char *name)
167 {
168   pstring outbuf;
169   char *p;
170
171   if (!d) return;
172   
173   DEBUG(2,("Sending election to %s for workgroup %s\n",
174            inet_ntoa(d->bcast_ip),group));         
175
176   bzero(outbuf,sizeof(outbuf));
177   p = outbuf;
178   CVAL(p,0) = ANN_Election; /* election */
179   p++;
180
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);
188   
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));
192 }
193
194
195 /****************************************************************************
196   un-register a SELF name that got rejected.
197
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.
201
202   **************************************************************************/
203 void name_unregister_work(struct subnet_record *d, char *name, int name_type)
204 {
205     struct work_record *work;
206     int remove_type_local  = 0;
207     int remove_type_domain = 0;
208     int remove_type_logon  = 0;
209
210     remove_netbios_name(d,name,name_type,SELF,ipzero);
211
212     if (!(work = find_workgroupstruct(d, name, False))) return;
213
214     /* work out what to unbecome, from the name type being removed */
215
216     if (ms_browser_name(name, name_type))
217     {
218       remove_type_local |= SV_TYPE_MASTER_BROWSER;
219     }
220     if (AM_MASTER(work) && strequal(name, myworkgroup) && name_type == 0x1d)
221     {
222       remove_type_local |= SV_TYPE_MASTER_BROWSER;
223     }
224     if (AM_DOMMST(work) && strequal(name, myworkgroup) && name_type == 0x1b)
225     {
226       remove_type_domain |= SV_TYPE_DOMAIN_MASTER;
227     }
228     if (AM_DOMMEM(work) && strequal(name, myworkgroup) && name_type == 0x1c)
229     {
230       remove_type_logon|= SV_TYPE_DOMAIN_MEMBER;
231     }
232
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 );
236 }
237
238
239 /****************************************************************************
240   registers a name.
241
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.
244
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)
248 {
249   enum name_source source = (ismyip(ip) || ip_equal(ip, ipzero)) ?
250                                   SELF : REGISTER;
251
252   if (source == SELF)
253     {
254       struct work_record *work = find_workgroupstruct(d, 
255                                   myworkgroup, False);
256
257       add_netbios_entry(d,name,name_type,nb_flags,ttl,source,ip,True,!bcast);
258
259       if (work)
260       {
261         int add_type_local  = False;
262         int add_type_domain = False;
263         int add_type_logon  = False;
264
265         DEBUG(4,("checking next stage: name_register_work %s\n", name));
266
267         /* work out what to become, from the name type being added */
268
269         if (ms_browser_name(name, name_type))
270         {
271           add_type_local = True;
272         }
273         if (strequal(name, myworkgroup) && name_type == 0x1d)
274         {
275           add_type_local = True;
276         }
277         if (strequal(name, myworkgroup) && name_type == 0x1b)
278         {
279           add_type_domain = True;
280         }
281         if (strequal(name, myworkgroup) && name_type == 0x1c)
282         {
283           add_type_logon = True;
284         }
285
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);
289       }
290     }
291 }
292
293
294 /*******************************************************************
295   become the local master browser.
296
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.
300
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.
306
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 
310
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.
314
315   ******************************************************************/
316 void become_local_master(struct subnet_record *d, struct work_record *work)
317 {
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
322    */
323   uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT;
324
325   if (!work || !d) 
326     return;
327   
328   if (!lp_local_master())
329   { 
330     DEBUG(0,("Samba not configured as a local master browser.\n"));
331     return;
332   }
333
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));
336   
337   switch (work->mst_state)
338   {
339     case MST_POTENTIAL: /* while we were nothing but a server... */
340     {
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 */
343
344       work->ElectionCriterion |= 0x5;
345
346       /* update our server status */
347       work->ServerType &= ~SV_TYPE_POTENTIAL_BROWSER;
348       add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True);
349
350       /* add special browser name */
351       add_my_name_entry(d,MSBROWSE,0x01,nb_type|NB_ACTIVE|NB_GROUP,False);
352
353       /* DON'T do anything else after calling add_my_name_entry() */
354       break;
355     }
356
357     case MST_BACK: /* while nothing had happened except we won an election... */
358     {
359       DEBUG(3,("go to second stage: register as master browser\n"));
360       work->mst_state = MST_MSB; /* registering MSBROWSE was successful */
361
362       /* add server entry on successful registration of MSBROWSE */
363       add_server_entry(d,work,work->work_group,domain_type,0,myname,True);
364
365       /* add master name */
366       add_my_name_entry(d,work->work_group,0x1d,nb_type|NB_ACTIVE,False);
367   
368       /* DON'T do anything else after calling add_my_name_entry() */
369       break;
370     }
371
372     case MST_MSB: /* while we were still only registered MSBROWSE state... */
373     {
374       int i = 0;
375       struct server_record *sl;
376
377       DEBUG(3,("2nd stage complete: registered as master browser for workgroup %s \
378 on subnet %s\n", work->work_group, inet_ntoa(d->bcast_ip)));
379       work->mst_state = MST_BROWSER; /* registering WORKGROUP(1d) succeeded */
380
381       /* update our server status */
382       work->ServerType |= SV_TYPE_MASTER_BROWSER;
383
384       DEBUG(3,("become_local_master: updating our server %s to type %x\n", 
385                 myname, work->ServerType));
386
387       add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True);
388
389       /* Count the number of servers we have on our list. If it's
390          less than 10 (just a heuristic) request the servers
391          to announce themselves.
392        */
393       for( sl = work->serverlist; sl != NULL; sl = sl->next)
394         i++;
395
396       if (i < 10)
397       {
398         /* ask all servers on our local net to announce to us */
399         announce_request(work, d->bcast_ip);
400       }
401
402       /* Reset the announce master timer so that we do an announce as soon as possible
403          now we are a master. */
404       reset_announce_timer();
405       break;
406     }
407
408     case MST_BROWSER:
409     {
410       /* don't have to do anything: just report success */
411       DEBUG(3,("3rd stage: become master browser!\n"));
412       break;
413     }
414   }
415 }
416
417
418 /*******************************************************************
419   become the domain master browser.
420
421   this is done in stages. note that this could take a while, 
422   particularly on a broadcast subnet, as we have to wait for
423   the implicit registration of each name to be accepted.
424
425   as each name is successfully registered, become_domain_master() is
426   called again, in order to initiate the next stage. see
427   dead_netbios_entry() - deals with implicit name registration
428   and response_name_reg() - deals with explicit registration
429   with a WINS server.
430
431   stage 1: was DOMAIN_NONE - go to DOMAIN_MST 
432
433   XXXX note: this code still does not cope with the distinction
434   between different types of nodes, particularly between M and P
435   nodes. that comes later.
436
437   ******************************************************************/
438 void become_domain_master(struct subnet_record *d, struct work_record *work)
439 {
440   /* domain type must be limited to domain enum + server type. it must
441      not have SV_TYPE_SERVER or anything else with SERVER in it, else
442      clients get confused and start thinking this entry is a server
443      not a workgroup
444    */
445
446   if (!work || !d) return;
447  
448   if (!lp_domain_master())
449   { 
450     DEBUG(0,("Samba not configured as a domain master browser.\n"));
451     return;
452   }
453
454   DEBUG(2,("Becoming domain master for %s %s (currently at stage %d)\n",
455         work->work_group,inet_ntoa(d->bcast_ip),work->dom_state));
456   
457   switch (work->dom_state)
458   {
459     case DOMAIN_NONE: /* while we were nothing but a server... */
460     {
461       DEBUG(3,("become_domain_master: go to first stage: register <1b> name\n"));
462       work->dom_state = DOMAIN_WAIT;
463
464       /* Registering the DOMAIN<1b> name is very tricky. We need to
465          do this on all our subnets, but don't want to bradcast it
466          on locally connected subnets (WinNT doesn't do this). Also,
467          previous versions of Samba screw up royally when we do this.
468          We need to register it immediatly on our local subnet, but
469          also actually check with the WINS server if it exists. If the name
470          has already been claimed by someone else in the WINS server
471          then we need to back out all our local registrations and
472          fail. Thus we only directly enter the name on local subnets,
473          on the WINS subnet we actually check...
474       */
475       /* XXXX the 0x1b is domain master browser name */
476       if(d == wins_subnet)
477         add_my_name_entry(d, work->work_group,0x1b,nb_type|NB_ACTIVE,False);
478       else
479         add_my_name_entry(d, work->work_group,0x1b,nb_type|NB_ACTIVE,True);
480
481       /* DON'T do anything else after calling add_my_name_entry() */
482       break;
483     }
484
485     case DOMAIN_WAIT:
486     {
487       work->dom_state = DOMAIN_MST; /* ... become domain master */
488       DEBUG(3,("become_domain_master: first stage - register as domain member\n"));
489  
490       /* update our server status */
491       work->ServerType |= SV_TYPE_NT|SV_TYPE_DOMAIN_MASTER;
492       add_server_entry(d,work,myname,work->ServerType,0,
493                         lp_serverstring(),True);
494
495       DEBUG(4,("Samba is now a domain master browser for workgroup %s on subnet %s\n", 
496                 work->work_group, inet_ntoa(d->bcast_ip)));
497
498       break;
499     }
500
501     case DOMAIN_MST:
502     {
503       /* don't have to do anything: just report success */
504       DEBUG(3,("domain second stage: there isn't one!\n"));
505       break;
506     }
507   }
508 }
509
510
511 /*******************************************************************
512   become a logon server.
513   ******************************************************************/
514 void become_logon_server(struct subnet_record *d, struct work_record *work)
515 {
516   if (!work || !d) return;
517   
518   if (lp_domain_logons())
519   {
520     DEBUG(0,("samba not configured as a logon master.\n"));
521     return;
522   }
523
524   DEBUG(2,("Becoming logon server for %s %s (currently at stage %d)\n",
525         work->work_group,inet_ntoa(d->bcast_ip),work->log_state));
526   
527   switch (work->log_state)
528   {
529     case LOGON_NONE: /* while we were nothing but a server... */
530     {
531       DEBUG(3,("go to first stage: register <1c> name\n"));
532             work->log_state = LOGON_WAIT;
533
534      /* XXXX the 0x1c is apparently something to do with domain logons */
535      add_my_name_entry(d, myworkgroup,0x1c,nb_type|NB_ACTIVE|NB_GROUP,False);
536
537       /* DON'T do anything else after calling add_my_name_entry() */
538       break;
539     }
540
541     case LOGON_WAIT:
542     {
543       work->log_state = LOGON_SRV; /* ... become logon server */
544       DEBUG(3,("logon second stage: register \n"));
545  
546       /* update our server status */
547       work->ServerType |= SV_TYPE_NT|SV_TYPE_DOMAIN_MEMBER;
548       add_server_entry(d,work,myname,work->ServerType,0,
549                       lp_serverstring(),True);
550
551       /* DON'T do anything else after calling add_my_name_entry() */
552       break;
553     }
554
555     case LOGON_SRV:
556     {
557       DEBUG(3,("logon third stage: there isn't one!\n"));
558       break;
559     }
560   }
561 }
562
563
564 /*******************************************************************
565   unbecome the local master browser. initates removal of necessary netbios 
566   names, and tells the world that we are no longer a master browser.
567
568   XXXX this _should_ be used to demote to a backup master browser, without
569   going straight to non-master browser.  another time.
570
571   ******************************************************************/
572 void unbecome_local_master(struct subnet_record *d, struct work_record *work,
573                                 int remove_type)
574 {
575   int new_server_type = work->ServerType;
576
577   /* can only remove master types with this function */
578   remove_type &= SV_TYPE_MASTER_BROWSER;
579
580   new_server_type &= ~remove_type;
581
582   if (remove_type)
583   {
584     DEBUG(2,("Becoming local non-master for %s\n",work->work_group));
585   
586     /* no longer a master browser of any sort */
587
588     work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
589     work->ElectionCriterion &= ~0x4;
590     work->mst_state = MST_POTENTIAL;
591
592         /* announce ourselves as no longer active as a master browser. */
593     announce_server(d, work, work->work_group, myname, 0, 0);
594     remove_name_entry(d,MSBROWSE        ,0x01,False);
595     remove_name_entry(d,work->work_group,0x1d,False);
596   }
597 }
598
599
600 /*******************************************************************
601   unbecome the domain master browser. initates removal of necessary netbios 
602   names, and tells the world that we are no longer a domain browser.
603   ******************************************************************/
604 void unbecome_domain_master(struct subnet_record *d, struct work_record *work,
605                                 int remove_type)
606 {
607   int new_server_type = work->ServerType;
608
609   DEBUG(2,("Becoming domain non-master for %s\n",work->work_group));
610   
611   /* can only remove master or domain types with this function */
612   remove_type &= SV_TYPE_DOMAIN_MASTER;
613
614   new_server_type &= ~remove_type;
615
616   if (remove_type)
617   {
618     /* no longer a domain master browser of any sort */
619
620     work->dom_state = DOMAIN_NONE;
621
622     /* announce ourselves as no longer active as a master browser on
623        all our local subnets. */
624     for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
625     {
626       work = find_workgroupstruct(d, myworkgroup, False);
627
628       announce_server(d, work, work->work_group, myname, 0, 0);
629       /* Remove the name entry without any NetBIOS traffic as that's
630          how it was registered. */
631       remove_name_entry(d,work->work_group,0x1b,True);    
632     }
633   }
634 }
635
636
637 /*******************************************************************
638   unbecome the logon server. initates removal of necessary netbios 
639   names, and tells the world that we are no longer a logon server.
640   ******************************************************************/
641 void unbecome_logon_server(struct subnet_record *d, struct work_record *work,
642                                 int remove_type)
643 {
644   int new_server_type = work->ServerType;
645
646   DEBUG(2,("Becoming logon non-server for %s\n",work->work_group));
647   
648   /* can only remove master or domain types with this function */
649   remove_type &= SV_TYPE_DOMAIN_MEMBER;
650
651   new_server_type &= ~remove_type;
652
653   if (remove_type)
654   {
655     /* no longer a master browser of any sort */
656
657     work->log_state = LOGON_NONE;
658
659         /* announce ourselves as no longer active as a master browser. */
660     announce_server(d, work, work->work_group, myname, 0, 0);
661     remove_name_entry(d,work->work_group,0x1c,False);    
662   }
663 }
664
665
666 /*******************************************************************
667   run the election
668   ******************************************************************/
669 void run_elections(time_t t)
670 {
671   static time_t lastime = 0;
672   
673   struct subnet_record *d;
674   
675   /* send election packets once a second */
676   if (lastime && t-lastime <= 0) return;
677   
678   lastime = t;
679   
680   for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
681   {
682     struct work_record *work;
683
684     for (work = d->workgrouplist; work; work = work->next)
685         {
686           if (work->RunningElection)
687           {
688             send_election(d,work->work_group, work->ElectionCriterion,
689                             t-StartupTime,myname);
690               
691             if (work->ElectionCount++ >= 4)
692                 {
693                   /* I won! now what :-) */
694                   DEBUG(2,(">>> Won election on %s %s <<<\n",
695                            work->work_group,inet_ntoa(d->bcast_ip)));
696                   
697                   work->RunningElection = False;
698                   work->mst_state = MST_POTENTIAL;
699
700                   become_local_master(d, work);
701                 }
702           }
703         }
704   }
705 }
706
707
708 /*******************************************************************
709   work out if I win an election
710   ******************************************************************/
711 static BOOL win_election(struct work_record *work,int version,uint32 criterion,
712                          int timeup,char *name)
713 {  
714   int mytimeup = time(NULL) - StartupTime;
715   uint32 mycriterion = work->ElectionCriterion;
716
717   /* If local master is false then never win
718      in election broadcasts. */
719   if(!lp_local_master())
720   {
721     DEBUG(3,("win_election: Losing election as local master == False\n"));
722     return False;
723   }
724  
725   DEBUG(4,("election comparison: %x:%x %x:%x %d:%d %s:%s\n",
726            version,ELECTION_VERSION,
727            criterion,mycriterion,
728            timeup,mytimeup,
729            name,myname));
730
731   if (version > ELECTION_VERSION) return(False);
732   if (version < ELECTION_VERSION) return(True);
733   
734   if (criterion > mycriterion) return(False);
735   if (criterion < mycriterion) return(True);
736
737   if (timeup > mytimeup) return(False);
738   if (timeup < mytimeup) return(True);
739
740   if (strcasecmp(myname,name) > 0) return(False);
741   
742   return(True);
743 }
744
745
746 /*******************************************************************
747   process a election packet
748
749   An election dynamically decides who will be the master. 
750   ******************************************************************/
751 void process_election(struct packet_struct *p,char *buf)
752 {
753         struct dgram_packet *dgram = &p->packet.dgram;
754         struct in_addr ip = dgram->header.source_ip;
755         struct subnet_record *d = find_subnet(ip);
756         int version = CVAL(buf,0);
757         uint32 criterion = IVAL(buf,1);
758         int timeup = IVAL(buf,5)/1000;
759         char *name = buf+13;
760         struct work_record *work;
761
762         if (!d) return;
763
764         if (ip_equal(d->bcast_ip,wins_ip))
765         {
766                 DEBUG(3,("Unexpected election request from %s %s on WINS net\n",
767                           name, inet_ntoa(p->ip)));
768                 return;
769         }
770
771         name[15] = 0;  
772
773         DEBUG(3,("Election request from %s %s vers=%d criterion=%08x timeup=%d\n",
774                   name,inet_ntoa(p->ip),version,criterion,timeup));
775
776         if (same_context(dgram)) return;
777
778         for (work = d->workgrouplist; work; work = work->next)
779         {
780                 if (!strequal(work->work_group, myworkgroup))
781                 continue;
782
783                 if (win_election(work, version,criterion,timeup,name))
784                 {
785                         if (!work->RunningElection)
786                         {
787                                 work->needelection = True;
788                                 work->ElectionCount=0;
789                                 work->mst_state = MST_POTENTIAL;
790                         }
791                 }
792                 else
793                 {
794                         work->needelection = False;
795
796                         if (work->RunningElection || AM_MASTER(work))
797                         {
798                                 work->RunningElection = False;
799                                 DEBUG(3,(">>> Lost election on %s %s <<<\n",
800                                                   work->work_group,inet_ntoa(d->bcast_ip)));
801                                 if (AM_MASTER(work))
802                                 {
803                                         unbecome_local_master(d, work, SV_TYPE_MASTER_BROWSER);
804                                 }
805                         }
806                 }
807         }
808 }
809
810
811 /****************************************************************************
812   checks whether a browser election is to be run on any workgroup
813
814   this function really ought to return the time between election
815   packets (which depends on whether samba intends to be a domain
816   master or a master browser) in milliseconds.
817
818   ***************************************************************************/
819 BOOL check_elections(void)
820 {
821   struct subnet_record *d;
822   BOOL run_any_election = False;
823
824   for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
825     {
826       struct work_record *work;
827       for (work = d->workgrouplist; work; work = work->next)
828         {
829           run_any_election |= work->RunningElection;
830           
831           if (work->needelection && !work->RunningElection)
832             {
833               DEBUG(3,(">>> Starting election on %s %s <<<\n",
834                        work->work_group,inet_ntoa(d->bcast_ip)));
835               work->ElectionCount = 0;
836               work->RunningElection = True;
837               work->needelection = False;
838             }
839         }
840     }
841   return run_any_election;
842 }
843