2 Unix SMB/Netbios implementation.
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
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.
37 extern int ClientDGRAM;
39 extern int DEBUGLEVEL;
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;
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(0,("%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);
93 /* if we are not the browse master of a workgroup,
94 and we can't find a browser on the subnet, do
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))
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;
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)
173 DEBUG(2,("Sending election to %s for workgroup %s\n",
174 inet_ntoa(d->bcast_ip),group));
176 bzero(outbuf,sizeof(outbuf));
178 CVAL(p,0) = ANN_Election; /* election */
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 */
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 /****************************************************************************
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)) ?
254 struct work_record *work = find_workgroupstruct(d,
257 add_netbios_entry(d,name,name_type,nb_flags,ttl,source,ip,True,!bcast);
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
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
323 uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT;
328 if (!lp_local_master())
330 DEBUG(0,("Samba not configured as a local master browser.\n"));
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,0,lp_serverstring(),True);
350 /* add special browser name */
351 add_my_name_entry(d,MSBROWSE,0x01,nb_type|NB_ACTIVE|NB_GROUP,False);
353 /* DON'T do anything else after calling add_my_name_entry() */
357 case MST_BACK: /* while nothing had happened except we won an election... */
359 DEBUG(3,("go to second stage: register as master browser\n"));
360 work->mst_state = MST_MSB; /* registering MSBROWSE was successful */
362 /* add server entry on successful registration of MSBROWSE */
363 add_server_entry(d,work,work->work_group,domain_type,0,myname,True);
365 /* add master name */
366 add_my_name_entry(d,work->work_group,0x1d,nb_type|NB_ACTIVE,False);
368 /* DON'T do anything else after calling add_my_name_entry() */
372 case MST_MSB: /* while we were still only registered MSBROWSE state... */
375 struct server_record *sl;
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 */
381 /* update our server status */
382 work->ServerType |= SV_TYPE_MASTER_BROWSER;
384 DEBUG(3,("become_local_master: updating our server %s to type %x\n",
385 myname, work->ServerType));
387 add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True);
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.
393 for( sl = work->serverlist; sl != NULL; sl = sl->next)
398 /* ask all servers on our local net to announce to us */
399 announce_request(work, d->bcast_ip);
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();
406 DEBUG(0,("Samba is now a local master browser for workgroup %s on subnet %s\n",
407 work->work_group, inet_ntoa(d->bcast_ip)));
414 /* don't have to do anything: just report success */
415 DEBUG(3,("3rd stage: become master browser!\n"));
422 /*******************************************************************
423 become the domain master browser.
425 this is done in stages. note that this could take a while,
426 particularly on a broadcast subnet, as we have to wait for
427 the implicit registration of each name to be accepted.
429 as each name is successfully registered, become_domain_master() is
430 called again, in order to initiate the next stage. see
431 dead_netbios_entry() - deals with implicit name registration
432 and response_name_reg() - deals with explicit registration
435 stage 1: was DOMAIN_NONE - go to DOMAIN_MST
437 XXXX note: this code still does not cope with the distinction
438 between different types of nodes, particularly between M and P
439 nodes. that comes later.
441 ******************************************************************/
442 void become_domain_master(struct subnet_record *d, struct work_record *work)
444 /* domain type must be limited to domain enum + server type. it must
445 not have SV_TYPE_SERVER or anything else with SERVER in it, else
446 clients get confused and start thinking this entry is a server
450 if (!work || !d) return;
452 if (!lp_domain_master())
454 DEBUG(0,("Samba not configured as a domain master browser.\n"));
458 DEBUG(2,("Becoming domain master for %s %s (currently at stage %d)\n",
459 work->work_group,inet_ntoa(d->bcast_ip),work->dom_state));
461 switch (work->dom_state)
463 case DOMAIN_NONE: /* while we were nothing but a server... */
465 DEBUG(3,("become_domain_master: go to first stage: register <1b> name\n"));
466 work->dom_state = DOMAIN_WAIT;
468 /* Registering the DOMAIN<1b> name is very tricky. We need to
469 do this on all our subnets, but don't want to bradcast it
470 on locally connected subnets (WinNT doesn't do this). Also,
471 previous versions of Samba screw up royally when we do this.
472 We need to register it immediatly on our local subnet, but
473 also actually check with the WINS server if it exists. If the name
474 has already been claimed by someone else in the WINS server
475 then we need to back out all our local registrations and
476 fail. Thus we only directly enter the name on local subnets,
477 on the WINS subnet we actually check...
479 /* XXXX the 0x1b is domain master browser name */
481 add_my_name_entry(d, work->work_group,0x1b,nb_type|NB_ACTIVE,False);
483 add_my_name_entry(d, work->work_group,0x1b,nb_type|NB_ACTIVE,True);
485 /* DON'T do anything else after calling add_my_name_entry() */
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,0,
497 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)));
507 /* don't have to do anything: just report success */
508 DEBUG(3,("domain second stage: there isn't one!\n"));
515 /*******************************************************************
516 become a logon server.
517 ******************************************************************/
518 void become_logon_server(struct subnet_record *d, struct work_record *work)
520 if (!work || !d) return;
522 if (lp_domain_logons())
524 DEBUG(0,("samba not configured as a logon master.\n"));
528 DEBUG(2,("Becoming logon server for %s %s (currently at stage %d)\n",
529 work->work_group,inet_ntoa(d->bcast_ip),work->log_state));
531 switch (work->log_state)
533 case LOGON_NONE: /* while we were nothing but a server... */
535 DEBUG(3,("go to first stage: register <1c> name\n"));
536 work->log_state = LOGON_WAIT;
538 /* XXXX the 0x1c is apparently something to do with domain logons */
539 add_my_name_entry(d, myworkgroup,0x1c,nb_type|NB_ACTIVE|NB_GROUP,False);
541 /* DON'T do anything else after calling add_my_name_entry() */
547 work->log_state = LOGON_SRV; /* ... become logon server */
548 DEBUG(3,("logon second stage: register \n"));
550 /* update our server status */
551 work->ServerType |= SV_TYPE_NT|SV_TYPE_DOMAIN_MEMBER;
552 add_server_entry(d,work,myname,work->ServerType,0,
553 lp_serverstring(),True);
555 /* DON'T do anything else after calling add_my_name_entry() */
561 DEBUG(3,("logon third stage: there isn't one!\n"));
568 /*******************************************************************
569 unbecome the local master browser. initates removal of necessary netbios
570 names, and tells the world that we are no longer a master browser.
572 XXXX this _should_ be used to demote to a backup master browser, without
573 going straight to non-master browser. another time.
575 ******************************************************************/
576 void unbecome_local_master(struct subnet_record *d, struct work_record *work,
579 int new_server_type = work->ServerType;
581 /* can only remove master types with this function */
582 remove_type &= SV_TYPE_MASTER_BROWSER;
584 new_server_type &= ~remove_type;
588 DEBUG(2,("Becoming local non-master for %s\n",work->work_group));
590 /* no longer a master browser of any sort */
592 work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
593 work->ElectionCriterion &= ~0x4;
594 work->mst_state = MST_POTENTIAL;
596 /* announce ourselves as no longer active as a master browser. */
597 announce_server(d, work, work->work_group, myname, 0, 0);
598 remove_name_entry(d,MSBROWSE ,0x01,False);
599 remove_name_entry(d,work->work_group,0x1d,False);
604 /*******************************************************************
605 unbecome the domain master browser. initates removal of necessary netbios
606 names, and tells the world that we are no longer a domain browser.
607 ******************************************************************/
608 void unbecome_domain_master(struct subnet_record *d, struct work_record *work,
611 int new_server_type = work->ServerType;
613 DEBUG(2,("Becoming domain non-master for %s\n",work->work_group));
615 /* can only remove master or domain types with this function */
616 remove_type &= SV_TYPE_DOMAIN_MASTER;
618 new_server_type &= ~remove_type;
622 /* no longer a domain master browser of any sort */
624 work->dom_state = DOMAIN_NONE;
626 /* announce ourselves as no longer active as a master browser on
627 all our local subnets. */
628 for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
630 work = find_workgroupstruct(d, myworkgroup, False);
632 announce_server(d, work, work->work_group, myname, 0, 0);
633 /* Remove the name entry without any NetBIOS traffic as that's
634 how it was registered. */
635 remove_name_entry(d,work->work_group,0x1b,True);
641 /*******************************************************************
642 unbecome the logon server. initates removal of necessary netbios
643 names, and tells the world that we are no longer a logon server.
644 ******************************************************************/
645 void unbecome_logon_server(struct subnet_record *d, struct work_record *work,
648 int new_server_type = work->ServerType;
650 DEBUG(2,("Becoming logon non-server for %s\n",work->work_group));
652 /* can only remove master or domain types with this function */
653 remove_type &= SV_TYPE_DOMAIN_MEMBER;
655 new_server_type &= ~remove_type;
659 /* no longer a master browser of any sort */
661 work->log_state = LOGON_NONE;
663 /* announce ourselves as no longer active as a master browser. */
664 announce_server(d, work, work->work_group, myname, 0, 0);
665 remove_name_entry(d,work->work_group,0x1c,False);
670 /*******************************************************************
672 ******************************************************************/
673 void run_elections(time_t t)
675 static time_t lastime = 0;
677 struct subnet_record *d;
679 /* send election packets once a second */
680 if (lastime && t-lastime <= 0) return;
684 for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
686 struct work_record *work;
688 for (work = d->workgrouplist; work; work = work->next)
690 if (work->RunningElection)
692 send_election(d,work->work_group, work->ElectionCriterion,
693 t-StartupTime,myname);
695 if (work->ElectionCount++ >= 4)
697 /* I won! now what :-) */
698 DEBUG(2,(">>> Won election on %s %s <<<\n",
699 work->work_group,inet_ntoa(d->bcast_ip)));
701 work->RunningElection = False;
702 work->mst_state = MST_POTENTIAL;
704 become_local_master(d, work);
712 /*******************************************************************
713 work out if I win an election
714 ******************************************************************/
715 static BOOL win_election(struct work_record *work,int version,uint32 criterion,
716 int timeup,char *name)
718 int mytimeup = time(NULL) - StartupTime;
719 uint32 mycriterion = work->ElectionCriterion;
721 /* If local master is false then never win
722 in election broadcasts. */
723 if(!lp_local_master())
725 DEBUG(3,("win_election: Losing election as local master == False\n"));
729 DEBUG(4,("election comparison: %x:%x %x:%x %d:%d %s:%s\n",
730 version,ELECTION_VERSION,
731 criterion,mycriterion,
735 if (version > ELECTION_VERSION) return(False);
736 if (version < ELECTION_VERSION) return(True);
738 if (criterion > mycriterion) return(False);
739 if (criterion < mycriterion) return(True);
741 if (timeup > mytimeup) return(False);
742 if (timeup < mytimeup) return(True);
744 if (strcasecmp(myname,name) > 0) return(False);
750 /*******************************************************************
751 process a election packet
753 An election dynamically decides who will be the master.
754 ******************************************************************/
755 void process_election(struct packet_struct *p,char *buf)
757 struct dgram_packet *dgram = &p->packet.dgram;
758 struct in_addr ip = dgram->header.source_ip;
759 struct subnet_record *d = find_subnet(ip);
760 int version = CVAL(buf,0);
761 uint32 criterion = IVAL(buf,1);
762 int timeup = IVAL(buf,5)/1000;
764 struct work_record *work;
768 if (ip_equal(d->bcast_ip,wins_ip))
770 DEBUG(3,("Unexpected election request from %s %s on WINS net\n",
771 name, inet_ntoa(p->ip)));
777 DEBUG(3,("Election request from %s %s vers=%d criterion=%08x timeup=%d\n",
778 name,inet_ntoa(p->ip),version,criterion,timeup));
780 if (same_context(dgram)) return;
782 for (work = d->workgrouplist; work; work = work->next)
784 if (!strequal(work->work_group, myworkgroup))
787 if (win_election(work, version,criterion,timeup,name))
789 if (!work->RunningElection)
791 work->needelection = True;
792 work->ElectionCount=0;
793 work->mst_state = MST_POTENTIAL;
798 work->needelection = False;
800 if (work->RunningElection || AM_MASTER(work))
802 work->RunningElection = False;
803 DEBUG(3,(">>> Lost election on %s %s <<<\n",
804 work->work_group,inet_ntoa(d->bcast_ip)));
807 unbecome_local_master(d, work, SV_TYPE_MASTER_BROWSER);
815 /****************************************************************************
816 checks whether a browser election is to be run on any workgroup
818 this function really ought to return the time between election
819 packets (which depends on whether samba intends to be a domain
820 master or a master browser) in milliseconds.
822 ***************************************************************************/
823 BOOL check_elections(void)
825 struct subnet_record *d;
826 BOOL run_any_election = False;
828 for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
830 struct work_record *work;
831 for (work = d->workgrouplist; work; work = work->next)
833 run_any_election |= work->RunningElection;
835 if (work->needelection && !work->RunningElection)
837 DEBUG(3,(">>> Starting election on %s %s <<<\n",
838 work->work_group,inet_ntoa(d->bcast_ip)));
839 work->ElectionCount = 0;
840 work->RunningElection = True;
841 work->needelection = False;
845 return run_any_election;