renamed macro WITH_TDBSAM to work with new configure script.
[Samba.git] / source / nmbd / nmbd_become_lmb.c
blob31c67ae7f3f46d87289cc8eaf582a6a245157176
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 NBT netbios routines and daemon - version 2
5 Copyright (C) Andrew Tridgell 1994-1998
6 Copyright (C) Luke Kenneth Casson Leighton 1994-1998
7 Copyright (C) Jeremy Allison 1994-1998
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "includes.h"
27 extern int DEBUGLEVEL;
28 extern pstring global_myname;
30 extern uint16 samba_nb_type; /* Samba's NetBIOS name type. */
32 /*******************************************************************
33 Utility function to add a name to the unicast subnet, or add in
34 our IP address if it already exists.
35 ******************************************************************/
37 void insert_permanent_name_into_unicast( struct subnet_record *subrec,
38 struct nmb_name *nmbname, uint16 nb_type )
40 struct name_record *namerec;
42 if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL)
44 /* The name needs to be created on the unicast subnet. */
45 (void)add_name_to_subnet( unicast_subnet, nmbname->name,
46 nmbname->name_type, nb_type,
47 PERMANENT_TTL, PERMANENT_NAME, 1, &subrec->myip);
49 else
51 /* The name already exists on the unicast subnet. Add our local
52 IP for the given broadcast subnet to the name. */
53 add_ip_to_name_record( namerec, subrec->myip);
57 /*******************************************************************
58 Utility function to remove a name from the unicast subnet.
59 ******************************************************************/
61 static void remove_permanent_name_from_unicast( struct subnet_record *subrec,
62 struct nmb_name *nmbname )
64 struct name_record *namerec;
66 if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) != NULL)
68 /* Remove this broadcast subnet IP address from the name. */
69 remove_ip_from_name_record( namerec, subrec->myip);
70 if(namerec->data.num_ips == 0)
71 remove_name_from_namelist( unicast_subnet, namerec);
75 /*******************************************************************
76 Utility function always called to set our workgroup and server
77 state back to potential browser, or none.
78 ******************************************************************/
80 static void reset_workgroup_state( struct subnet_record *subrec, char *workgroup_name,
81 BOOL force_new_election )
83 struct work_record *work;
84 struct server_record *servrec;
85 struct nmb_name nmbname;
87 if((work = find_workgroup_on_subnet( subrec, workgroup_name)) == NULL)
89 DEBUG(0,("reset_workgroup_state: Error - cannot find workgroup %s on \
90 subnet %s.\n", workgroup_name, subrec->subnet_name ));
91 return;
94 if((servrec = find_server_in_workgroup( work, global_myname)) == NULL)
96 DEBUG(0,("reset_workgroup_state: Error - cannot find server %s \
97 in workgroup %s on subnet %s\n",
98 global_myname, work->work_group, subrec->subnet_name));
99 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
100 return;
103 /* Update our server status - remove any master flag and replace
104 it with the potential browser flag. */
105 servrec->serv.type &= ~SV_TYPE_MASTER_BROWSER;
106 servrec->serv.type |= (lp_local_master() ? SV_TYPE_POTENTIAL_BROWSER : 0);
108 /* Tell the namelist writer to write out a change. */
109 subrec->work_changed = True;
111 /* Reset our election flags. */
112 work->ElectionCriterion &= ~0x4;
114 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
116 /* Forget who the local master browser was for
117 this workgroup. */
119 set_workgroup_local_master_browser_name( work, "");
122 * Ensure the IP address of this subnet is not registered as one
123 * of the IP addresses of the WORKGROUP<1d> name on the unicast
124 * subnet. This undoes what we did below when we became a local
125 * master browser.
128 make_nmb_name(&nmbname, work->work_group, 0x1d);
130 remove_permanent_name_from_unicast( subrec, &nmbname);
132 if(force_new_election)
133 work->needelection = True;
136 /*******************************************************************
137 Unbecome the local master browser name release success function.
138 ******************************************************************/
140 static void unbecome_local_master_success(struct subnet_record *subrec,
141 struct userdata_struct *userdata,
142 struct nmb_name *released_name,
143 struct in_addr released_ip)
145 BOOL force_new_election = False;
147 memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL));
149 DEBUG(3,("unbecome_local_master_success: released name %s.\n",
150 nmb_namestr(released_name)));
152 /* Now reset the workgroup and server state. */
153 reset_workgroup_state( subrec, released_name->name, force_new_election );
155 if( DEBUGLVL( 0 ) )
157 dbgtext( "*****\n\n" );
158 dbgtext( "Samba name server %s ", global_myname );
159 dbgtext( "has stopped being a local master browser " );
160 dbgtext( "for workgroup %s ", released_name->name );
161 dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
166 /*******************************************************************
167 Unbecome the local master browser name release fail function.
168 ******************************************************************/
170 static void unbecome_local_master_fail(struct subnet_record *subrec, struct response_record *rrec,
171 struct nmb_name *fail_name)
173 struct name_record *namerec;
174 struct userdata_struct *userdata = rrec->userdata;
175 BOOL force_new_election = False;
177 memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL));
179 DEBUG(0,("unbecome_local_master_fail: failed to release name %s. \
180 Removing from namelist anyway.\n", nmb_namestr(fail_name)));
182 /* Do it anyway. */
183 namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
184 if(namerec)
185 remove_name_from_namelist(subrec, namerec);
187 /* Now reset the workgroup and server state. */
188 reset_workgroup_state( subrec, fail_name->name, force_new_election );
190 if( DEBUGLVL( 0 ) )
192 dbgtext( "*****\n\n" );
193 dbgtext( "Samba name server %s ", global_myname );
194 dbgtext( "has stopped being a local master browser " );
195 dbgtext( "for workgroup %s ", fail_name->name );
196 dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
200 /*******************************************************************
201 Utility function to remove the WORKGROUP<1d> name.
202 ******************************************************************/
204 static void release_1d_name( struct subnet_record *subrec, char *workgroup_name,
205 BOOL force_new_election)
207 struct nmb_name nmbname;
208 struct name_record *namerec;
210 make_nmb_name(&nmbname, workgroup_name, 0x1d);
211 if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL)
213 struct userdata_struct *userdata;
214 int size = sizeof(struct userdata_struct) + sizeof(BOOL);
216 if((userdata = (struct userdata_struct *)malloc(size)) == NULL)
218 DEBUG(0,("release_1d_name: malloc fail.\n"));
219 return;
222 userdata->copy_fn = NULL;
223 userdata->free_fn = NULL;
224 userdata->userdata_len = sizeof(BOOL);
225 memcpy((char *)userdata->data, &force_new_election, sizeof(BOOL));
227 release_name(subrec, namerec,
228 unbecome_local_master_success,
229 unbecome_local_master_fail,
230 userdata);
232 zero_free(userdata, size);
236 /*******************************************************************
237 Unbecome the local master browser MSBROWSE name release success function.
238 ******************************************************************/
240 static void release_msbrowse_name_success(struct subnet_record *subrec,
241 struct userdata_struct *userdata,
242 struct nmb_name *released_name,
243 struct in_addr released_ip)
245 DEBUG(4,("release_msbrowse_name_success: Released name %s on subnet %s\n.",
246 nmb_namestr(released_name), subrec->subnet_name ));
248 /* Remove the permanent MSBROWSE name added into the unicast subnet. */
249 remove_permanent_name_from_unicast( subrec, released_name);
252 /*******************************************************************
253 Unbecome the local master browser MSBROWSE name release fail function.
254 ******************************************************************/
256 static void release_msbrowse_name_fail( struct subnet_record *subrec,
257 struct response_record *rrec,
258 struct nmb_name *fail_name)
260 struct name_record *namerec;
262 DEBUG(4,("release_msbrowse_name_fail: Failed to release name %s on subnet %s\n.",
263 nmb_namestr(fail_name), subrec->subnet_name ));
265 /* Release the name anyway. */
266 namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
267 if(namerec)
268 remove_name_from_namelist(subrec, namerec);
270 /* Remove the permanent MSBROWSE name added into the unicast subnet. */
271 remove_permanent_name_from_unicast( subrec, fail_name);
274 /*******************************************************************
275 Unbecome the local master browser. If force_new_election is true, restart
276 the election process after we've unbecome the local master.
277 ******************************************************************/
279 void unbecome_local_master_browser(struct subnet_record *subrec, struct work_record *work,
280 BOOL force_new_election)
282 struct name_record *namerec;
283 struct nmb_name nmbname;
285 /* Sanity check. */
287 DEBUG(2,("unbecome_local_master_browser: unbecoming local master for workgroup %s \
288 on subnet %s\n",work->work_group, subrec->subnet_name));
290 if(find_server_in_workgroup( work, global_myname) == NULL)
292 DEBUG(0,("unbecome_local_master_browser: Error - cannot find server %s \
293 in workgroup %s on subnet %s\n",
294 global_myname, work->work_group, subrec->subnet_name));
295 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
296 return;
299 /* Set the state to unbecoming. */
300 work->mst_state = MST_UNBECOMING_MASTER;
303 * Release the WORKGROUP<1d> name asap to allow another machine to
304 * claim it.
307 release_1d_name( subrec, work->work_group, force_new_election);
309 /* Deregister any browser names we may have. */
310 make_nmb_name(&nmbname, MSBROWSE, 0x1);
311 if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL)
313 release_name(subrec, namerec,
314 release_msbrowse_name_success,
315 release_msbrowse_name_fail,
316 NULL);
320 * Ensure we have sent and processed these release packets
321 * before returning - we don't want to process any election
322 * packets before dealing with the 1d release.
325 retransmit_or_expire_response_records(time(NULL));
328 /****************************************************************************
329 Success in registering the WORKGROUP<1d> name.
330 We are now *really* a local master browser.
331 ****************************************************************************/
333 static void become_local_master_stage2(struct subnet_record *subrec,
334 struct userdata_struct *userdata,
335 struct nmb_name *registered_name,
336 uint16 nb_flags,
337 int ttl, struct in_addr registered_ip)
339 int i = 0;
340 struct server_record *sl;
341 struct work_record *work = find_workgroup_on_subnet( subrec, registered_name->name);
342 struct server_record *servrec;
344 if(!work)
346 DEBUG(0,("become_local_master_stage2: Error - cannot find \
347 workgroup %s on subnet %s\n", registered_name->name, subrec->subnet_name));
348 return;
351 if((servrec = find_server_in_workgroup( work, global_myname)) == NULL)
353 DEBUG(0,("become_local_master_stage2: Error - cannot find server %s \
354 in workgroup %s on subnet %s\n",
355 global_myname, registered_name->name, subrec->subnet_name));
356 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
357 return;
360 DEBUG(3,("become_local_master_stage2: registered as master browser for workgroup %s \
361 on subnet %s\n", work->work_group, subrec->subnet_name));
363 work->mst_state = MST_BROWSER; /* registering WORKGROUP(1d) succeeded */
365 /* update our server status */
366 servrec->serv.type |= SV_TYPE_MASTER_BROWSER;
367 servrec->serv.type &= ~SV_TYPE_POTENTIAL_BROWSER;
369 /* Tell the namelist writer to write out a change. */
370 subrec->work_changed = True;
372 /* Add this name to the workgroup as local master browser. */
373 set_workgroup_local_master_browser_name( work, global_myname);
375 /* Count the number of servers we have on our list. If it's
376 less than 10 (just a heuristic) request the servers
377 to announce themselves.
379 for( sl = work->serverlist; sl != NULL; sl = sl->next)
380 i++;
382 if (i < 10)
384 /* Ask all servers on our local net to announce to us. */
385 broadcast_announce_request(subrec, work);
389 * Now we are a local master on a broadcast subnet, we need to add
390 * the WORKGROUP<1d> name to the unicast subnet so that we can answer
391 * unicast requests sent to this name. We can create this name directly on
392 * the unicast subnet as a WINS server always returns true when registering
393 * this name, and discards the registration. We use the number of IP
394 * addresses registered to this name as a reference count, as we
395 * remove this broadcast subnet IP address from it when we stop becoming a local
396 * master browser for this broadcast subnet.
399 insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
401 /* Reset the announce master browser timer so that we try and tell a domain
402 master browser as soon as possible that we are a local master browser. */
403 reset_announce_timer();
405 if( DEBUGLVL( 0 ) )
407 dbgtext( "*****\n\n" );
408 dbgtext( "Samba name server %s ", global_myname );
409 dbgtext( "is now a local master browser " );
410 dbgtext( "for workgroup %s ", work->work_group );
411 dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
416 /****************************************************************************
417 Failed to register the WORKGROUP<1d> name.
418 ****************************************************************************/
419 static void become_local_master_fail2(struct subnet_record *subrec,
420 struct response_record *rrec,
421 struct nmb_name *fail_name)
423 struct work_record *work = find_workgroup_on_subnet( subrec, fail_name->name);
425 DEBUG(0,("become_local_master_fail2: failed to register name %s on subnet %s. \
426 Failed to become a local master browser.\n", nmb_namestr(fail_name), subrec->subnet_name));
428 if(!work)
430 DEBUG(0,("become_local_master_fail2: Error - cannot find \
431 workgroup %s on subnet %s\n", fail_name->name, subrec->subnet_name));
432 return;
435 /* Roll back all the way by calling unbecome_local_master_browser(). */
436 unbecome_local_master_browser(subrec, work, False);
439 /****************************************************************************
440 Success in registering the MSBROWSE name.
441 ****************************************************************************/
443 static void become_local_master_stage1(struct subnet_record *subrec,
444 struct userdata_struct *userdata,
445 struct nmb_name *registered_name,
446 uint16 nb_flags,
447 int ttl, struct in_addr registered_ip)
449 char *work_name = userdata->data;
450 struct work_record *work = find_workgroup_on_subnet( subrec, work_name);
452 if(!work)
454 DEBUG(0,("become_local_master_stage1: Error - cannot find \
455 workgroup %s on subnet %s\n", work_name, subrec->subnet_name));
456 return;
459 DEBUG(3,("become_local_master_stage1: go to stage 2: register the %s<1d> name.\n",
460 work->work_group));
462 work->mst_state = MST_MSB; /* Registering MSBROWSE was successful. */
465 * We registered the MSBROWSE name on a broadcast subnet, now need to add
466 * the MSBROWSE name to the unicast subnet so that we can answer
467 * unicast requests sent to this name. We create this name directly on
468 * the unicast subnet.
471 insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
473 /* Attempt to register the WORKGROUP<1d> name. */
474 register_name(subrec, work->work_group,0x1d,samba_nb_type,
475 become_local_master_stage2,
476 become_local_master_fail2,
477 NULL);
480 /****************************************************************************
481 Failed to register the MSBROWSE name.
482 ****************************************************************************/
484 static void become_local_master_fail1(struct subnet_record *subrec,
485 struct response_record *rrec,
486 struct nmb_name *fail_name)
488 char *work_name = rrec->userdata->data;
489 struct work_record *work = find_workgroup_on_subnet(subrec, work_name);
491 if(!work)
493 DEBUG(0,("become_local_master_fail1: Error - cannot find \
494 workgroup %s on subnet %s\n", work_name, subrec->subnet_name));
495 return;
498 if(find_server_in_workgroup(work, global_myname) == NULL)
500 DEBUG(0,("become_local_master_fail1: Error - cannot find server %s \
501 in workgroup %s on subnet %s\n",
502 global_myname, work->work_group, subrec->subnet_name));
503 return;
506 reset_workgroup_state( subrec, work->work_group, False );
508 DEBUG(0,("become_local_master_fail1: Failed to become a local master browser for \
509 workgroup %s on subnet %s. Couldn't register name %s.\n",
510 work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));
513 /******************************************************************
514 Become the local master browser on a subnet.
515 This gets called if we win an election on this subnet.
517 Stage 1: mst_state was MST_POTENTIAL - go to MST_BACK register ^1^2__MSBROWSE__^2^1.
518 Stage 2: mst_state was MST_BACKUP - go to MST_MSB and register WORKGROUP<1d>.
519 Stage 3: mst_state was MST_MSB - go to MST_BROWSER.
520 ******************************************************************/
522 void become_local_master_browser(struct subnet_record *subrec, struct work_record *work)
524 struct userdata_struct *userdata;
525 int size = sizeof(struct userdata_struct) + sizeof(fstring) + 1;
527 /* Sanity check. */
528 if (!lp_local_master())
530 DEBUG(0,("become_local_master_browser: Samba not configured as a local master browser.\n"));
531 return;
534 if(!AM_POTENTIAL_MASTER_BROWSER(work))
536 DEBUG(2,("become_local_master_browser: Awaiting potential browser state. Current state is %d\n",
537 work->mst_state ));
538 return;
541 if(find_server_in_workgroup( work, global_myname) == NULL)
543 DEBUG(0,("become_local_master_browser: Error - cannot find server %s \
544 in workgroup %s on subnet %s\n",
545 global_myname, work->work_group, subrec->subnet_name));
546 return;
549 DEBUG(2,("become_local_master_browser: Starting to become a master browser for workgroup \
550 %s on subnet %s\n", work->work_group, subrec->subnet_name));
552 DEBUG(3,("become_local_master_browser: first stage - attempt to register ^1^2__MSBROWSE__^2^1\n"));
553 work->mst_state = MST_BACKUP; /* an election win was successful */
555 work->ElectionCriterion |= 0x5;
557 /* Tell the namelist writer to write out a change. */
558 subrec->work_changed = True;
560 /* Setup the userdata_struct. */
561 if((userdata = (struct userdata_struct *)malloc(size)) == NULL)
563 DEBUG(0,("become_local_master_browser: malloc fail.\n"));
564 return;
567 userdata->copy_fn = NULL;
568 userdata->free_fn = NULL;
569 userdata->userdata_len = strlen(work->work_group)+1;
570 pstrcpy(userdata->data, work->work_group);
572 /* Register the special browser group name. */
573 register_name(subrec, MSBROWSE, 0x01, samba_nb_type|NB_GROUP,
574 become_local_master_stage1,
575 become_local_master_fail1,
576 userdata);
578 zero_free(userdata, size);
581 /***************************************************************
582 Utility function to set the local master browser name. Does
583 some sanity checking as old versions of Samba seem to sometimes
584 say that the master browser name for a workgroup is the same
585 as the workgroup name.
586 ****************************************************************/
588 void set_workgroup_local_master_browser_name( struct work_record *work, char *newname)
590 DEBUG(5,("set_workgroup_local_master_browser_name: setting local master name to '%s' \
591 for workgroup %s.\n", newname, work->work_group ));
593 #if 0
595 * Apparently some sites use the workgroup name as the local
596 * master browser name. Arrrrggghhhhh ! (JRA).
598 if(strequal( work->work_group, newname))
600 DEBUG(5, ("set_workgroup_local_master_browser_name: Refusing to set \
601 local_master_browser_name for workgroup %s to workgroup name.\n",
602 work->work_group ));
603 return;
605 #endif
607 StrnCpy(work->local_master_browser_name, newname,
608 sizeof(work->local_master_browser_name)-1);