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();
410 /* don't have to do anything: just report success */
411 DEBUG(3,("3rd stage: become master browser!\n"));
418 /*******************************************************************
419 become the domain master browser.
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.
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
431 stage 1: was DOMAIN_NONE - go to DOMAIN_MST
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.
437 ******************************************************************/
438 void become_domain_master(struct subnet_record *d, struct work_record *work)
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
446 if (!work || !d) return;
448 if (!lp_domain_master())
450 DEBUG(0,("Samba not configured as a domain master browser.\n"));
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));
457 switch (work->dom_state)
459 case DOMAIN_NONE: /* while we were nothing but a server... */
461 DEBUG(3,("become_domain_master: go to first stage: register <1b> name\n"));
462 work->dom_state = DOMAIN_WAIT;
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...
475 /* XXXX the 0x1b is domain master browser name */
477 add_my_name_entry(d, work->work_group,0x1b,nb_type|NB_ACTIVE,False);
479 add_my_name_entry(d, work->work_group,0x1b,nb_type|NB_ACTIVE,True);
481 /* DON'T do anything else after calling add_my_name_entry() */
487 work->dom_state = DOMAIN_MST; /* ... become domain master */
488 DEBUG(3,("become_domain_master: first stage - register as domain member\n"));
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);
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)));
503 /* don't have to do anything: just report success */
504 DEBUG(3,("domain second stage: there isn't one!\n"));
511 /*******************************************************************
512 become a logon server.
513 ******************************************************************/
514 void become_logon_server(struct subnet_record *d, struct work_record *work)
516 if (!work || !d) return;
518 if (lp_domain_logons())
520 DEBUG(0,("samba not configured as a logon master.\n"));
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));
527 switch (work->log_state)
529 case LOGON_NONE: /* while we were nothing but a server... */
531 DEBUG(3,("go to first stage: register <1c> name\n"));
532 work->log_state = LOGON_WAIT;
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);
537 /* DON'T do anything else after calling add_my_name_entry() */
543 work->log_state = LOGON_SRV; /* ... become logon server */
544 DEBUG(3,("logon second stage: register \n"));
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);
551 /* DON'T do anything else after calling add_my_name_entry() */
557 DEBUG(3,("logon third stage: there isn't one!\n"));
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.
568 XXXX this _should_ be used to demote to a backup master browser, without
569 going straight to non-master browser. another time.
571 ******************************************************************/
572 void unbecome_local_master(struct subnet_record *d, struct work_record *work,
575 int new_server_type = work->ServerType;
577 /* can only remove master types with this function */
578 remove_type &= SV_TYPE_MASTER_BROWSER;
580 new_server_type &= ~remove_type;
584 DEBUG(2,("Becoming local non-master for %s\n",work->work_group));
586 /* no longer a master browser of any sort */
588 work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
589 work->ElectionCriterion &= ~0x4;
590 work->mst_state = MST_POTENTIAL;
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);
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,
607 int new_server_type = work->ServerType;
609 DEBUG(2,("Becoming domain non-master for %s\n",work->work_group));
611 /* can only remove master or domain types with this function */
612 remove_type &= SV_TYPE_DOMAIN_MASTER;
614 new_server_type &= ~remove_type;
618 /* no longer a domain master browser of any sort */
620 work->dom_state = DOMAIN_NONE;
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))
626 work = find_workgroupstruct(d, myworkgroup, False);
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);
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,
644 int new_server_type = work->ServerType;
646 DEBUG(2,("Becoming logon non-server for %s\n",work->work_group));
648 /* can only remove master or domain types with this function */
649 remove_type &= SV_TYPE_DOMAIN_MEMBER;
651 new_server_type &= ~remove_type;
655 /* no longer a master browser of any sort */
657 work->log_state = LOGON_NONE;
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);
666 /*******************************************************************
668 ******************************************************************/
669 void run_elections(time_t t)
671 static time_t lastime = 0;
673 struct subnet_record *d;
675 /* send election packets once a second */
676 if (lastime && t-lastime <= 0) return;
680 for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
682 struct work_record *work;
684 for (work = d->workgrouplist; work; work = work->next)
686 if (work->RunningElection)
688 send_election(d,work->work_group, work->ElectionCriterion,
689 t-StartupTime,myname);
691 if (work->ElectionCount++ >= 4)
693 /* I won! now what :-) */
694 DEBUG(2,(">>> Won election on %s %s <<<\n",
695 work->work_group,inet_ntoa(d->bcast_ip)));
697 work->RunningElection = False;
698 work->mst_state = MST_POTENTIAL;
700 become_local_master(d, work);
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)
714 int mytimeup = time(NULL) - StartupTime;
715 uint32 mycriterion = work->ElectionCriterion;
717 /* If local master is false then never win
718 in election broadcasts. */
719 if(!lp_local_master())
721 DEBUG(3,("win_election: Losing election as local master == False\n"));
725 DEBUG(4,("election comparison: %x:%x %x:%x %d:%d %s:%s\n",
726 version,ELECTION_VERSION,
727 criterion,mycriterion,
731 if (version > ELECTION_VERSION) return(False);
732 if (version < ELECTION_VERSION) return(True);
734 if (criterion > mycriterion) return(False);
735 if (criterion < mycriterion) return(True);
737 if (timeup > mytimeup) return(False);
738 if (timeup < mytimeup) return(True);
740 if (strcasecmp(myname,name) > 0) return(False);
746 /*******************************************************************
747 process a election packet
749 An election dynamically decides who will be the master.
750 ******************************************************************/
751 void process_election(struct packet_struct *p,char *buf)
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;
760 struct work_record *work;
764 if (ip_equal(d->bcast_ip,wins_ip))
766 DEBUG(3,("Unexpected election request from %s %s on WINS net\n",
767 name, inet_ntoa(p->ip)));
773 DEBUG(3,("Election request from %s %s vers=%d criterion=%08x timeup=%d\n",
774 name,inet_ntoa(p->ip),version,criterion,timeup));
776 if (same_context(dgram)) return;
778 for (work = d->workgrouplist; work; work = work->next)
780 if (!strequal(work->work_group, myworkgroup))
783 if (win_election(work, version,criterion,timeup,name))
785 if (!work->RunningElection)
787 work->needelection = True;
788 work->ElectionCount=0;
789 work->mst_state = MST_POTENTIAL;
794 work->needelection = False;
796 if (work->RunningElection || AM_MASTER(work))
798 work->RunningElection = False;
799 DEBUG(3,(">>> Lost election on %s %s <<<\n",
800 work->work_group,inet_ntoa(d->bcast_ip)));
803 unbecome_local_master(d, work, SV_TYPE_MASTER_BROWSER);
811 /****************************************************************************
812 checks whether a browser election is to be run on any workgroup
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.
818 ***************************************************************************/
819 BOOL check_elections(void)
821 struct subnet_record *d;
822 BOOL run_any_election = False;
824 for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
826 struct work_record *work;
827 for (work = d->workgrouplist; work; work = work->next)
829 run_any_election |= work->RunningElection;
831 if (work->needelection && !work->RunningElection)
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;
841 return run_any_election;