2 Unix SMB/Netbios implementation.
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.
27 extern int DEBUGLEVEL;
29 extern pstring global_myname;
31 extern uint16 samba_nb_type; /* Samba's NetBIOS name type. */
33 /*******************************************************************
34 Utility function to add a name to the unicast subnet, or add in
35 our IP address if it already exists.
36 ******************************************************************/
38 void insert_permanent_name_into_unicast( struct subnet_record *subrec,
39 struct nmb_name *nmbname, uint16 nb_type )
41 struct name_record *namerec;
43 if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL)
45 /* The name needs to be created on the unicast subnet. */
46 (void)add_name_to_subnet( unicast_subnet, nmbname->name,
47 nmbname->name_type, nb_type,
48 PERMANENT_TTL, PERMANENT_NAME, 1, &subrec->myip);
52 /* The name already exists on the unicast subnet. Add our local
53 IP for the given broadcast subnet to the name. */
54 add_ip_to_name_record( namerec, subrec->myip);
58 /*******************************************************************
59 Utility function to remove a name from the unicast subnet.
60 ******************************************************************/
62 static void remove_permanent_name_from_unicast( struct subnet_record *subrec,
63 struct nmb_name *nmbname )
65 struct name_record *namerec;
67 if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) != NULL)
69 /* Remove this broadcast subnet IP address from the name. */
70 remove_ip_from_name_record( namerec, subrec->myip);
71 if(namerec->data.num_ips == 0)
72 remove_name_from_namelist( unicast_subnet, namerec);
76 /*******************************************************************
77 Utility function always called to set our workgroup and server
78 state back to potential browser, or none.
79 ******************************************************************/
81 static void reset_workgroup_state( struct subnet_record *subrec, char *workgroup_name,
82 BOOL force_new_election )
84 struct work_record *work;
85 struct server_record *servrec;
86 struct nmb_name nmbname;
88 if((work = find_workgroup_on_subnet( subrec, workgroup_name)) == NULL)
90 DEBUG(0,("reset_workgroup_state: Error - cannot find workgroup %s on \
91 subnet %s.\n", workgroup_name, subrec->subnet_name ));
95 if((servrec = find_server_in_workgroup( work, global_myname)) == NULL)
97 DEBUG(0,("reset_workgroup_state: Error - cannot find server %s \
98 in workgroup %s on subnet %s\n",
99 global_myname, work->work_group, subrec->subnet_name));
100 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
104 /* Update our server status - remove any master flag and replace
105 it with the potential browser flag. */
106 servrec->serv.type &= ~SV_TYPE_MASTER_BROWSER;
107 servrec->serv.type |= (lp_local_master() ? SV_TYPE_POTENTIAL_BROWSER : 0);
109 /* Tell the namelist writer to write out a change. */
110 subrec->work_changed = True;
112 /* Reset our election flags. */
113 work->ElectionCriterion &= ~0x4;
115 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
117 /* Forget who the local master browser was for
120 set_workgroup_local_master_browser_name( work, "");
123 * Ensure the IP address of this subnet is not registered as one
124 * of the IP addresses of the WORKGROUP<1d> name on the unicast
125 * subnet. This undoes what we did below when we became a local
129 make_nmb_name(&nmbname, work->work_group, 0x1d, scope);
131 remove_permanent_name_from_unicast( subrec, &nmbname);
133 if(force_new_election)
134 work->needelection = True;
137 /*******************************************************************
138 Unbecome the local master browser name release success function.
139 ******************************************************************/
141 void unbecome_local_master_success(struct subnet_record *subrec,
142 struct userdata_struct *userdata,
143 struct nmb_name *released_name,
144 struct in_addr released_ip)
146 BOOL force_new_election = False;
148 memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL));
150 DEBUG(3,("unbecome_local_master_success: released name %s.\n",
151 namestr(released_name)));
153 /* Now reset the workgroup and server state. */
154 reset_workgroup_state( subrec, released_name->name, force_new_election );
156 DEBUG(0,("\n%s ***** Samba name server %s has stopped being a local master browser for workgroup %s \
157 on subnet %s *****\n\n", timestring(), global_myname, released_name->name, subrec->subnet_name));
161 /*******************************************************************
162 Unbecome the local master browser name release fail function.
163 ******************************************************************/
165 void unbecome_local_master_fail(struct subnet_record *subrec, struct response_record *rrec,
166 struct nmb_name *fail_name)
168 struct name_record *namerec;
169 struct userdata_struct *userdata = rrec->userdata;
170 BOOL force_new_election = False;
172 memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL));
174 DEBUG(0,("unbecome_local_master_fail: failed to release name %s. \
175 Removing from namelist anyway.\n", namestr(fail_name)));
178 namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
180 remove_name_from_namelist(subrec, namerec);
182 /* Now reset the workgroup and server state. */
183 reset_workgroup_state( subrec, fail_name->name, force_new_election );
185 DEBUG(0,("\n%s ***** Samba name server %s has stopped being a local master browser for workgroup %s \
186 on subnet %s *****\n\n", timestring(), global_myname, fail_name->name, subrec->subnet_name));
189 /*******************************************************************
190 Utility function to remove the WORKGROUP<1d> name.
191 ******************************************************************/
193 static void release_1d_name( struct subnet_record *subrec, char *workgroup_name,
194 BOOL force_new_election)
196 struct nmb_name nmbname;
197 struct name_record *namerec;
199 make_nmb_name(&nmbname, workgroup_name, 0x1d, scope);
200 if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL)
202 struct userdata_struct *userdata;
204 if((userdata = (struct userdata_struct *)malloc(
205 sizeof(struct userdata_struct) + sizeof(BOOL))) == NULL)
207 DEBUG(0,("release_1d_name: malloc fail.\n"));
211 userdata->copy_fn = NULL;
212 userdata->free_fn = NULL;
213 userdata->userdata_len = sizeof(BOOL);
214 memcpy((char *)userdata->data, &force_new_election, sizeof(BOOL));
216 release_name(subrec, namerec,
217 unbecome_local_master_success,
218 unbecome_local_master_fail,
221 free((char *)userdata);
225 /*******************************************************************
226 Unbecome the local master browser MSBROWSE name release success function.
227 ******************************************************************/
229 static void release_msbrowse_name_success(struct subnet_record *subrec,
230 struct userdata_struct *userdata,
231 struct nmb_name *released_name,
232 struct in_addr released_ip)
234 DEBUG(4,("release_msbrowse_name_success: Released name %s on subnet %s\n.",
235 namestr(released_name), subrec->subnet_name ));
237 /* Remove the permanent MSBROWSE name added into the unicast subnet. */
238 remove_permanent_name_from_unicast( subrec, released_name);
241 /*******************************************************************
242 Unbecome the local master browser MSBROWSE name release fail function.
243 ******************************************************************/
245 static void release_msbrowse_name_fail( struct subnet_record *subrec,
246 struct response_record *rrec,
247 struct nmb_name *fail_name)
249 struct name_record *namerec;
251 DEBUG(4,("release_msbrowse_name_fail: Failed to release name %s on subnet %s\n.",
252 namestr(fail_name), subrec->subnet_name ));
254 /* Release the name anyway. */
255 namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
257 remove_name_from_namelist(subrec, namerec);
259 /* Remove the permanent MSBROWSE name added into the unicast subnet. */
260 remove_permanent_name_from_unicast( subrec, fail_name);
263 /*******************************************************************
264 Unbecome the local master browser. If force_new_election is true, restart
265 the election process after we've unbecome the local master.
266 ******************************************************************/
268 void unbecome_local_master_browser(struct subnet_record *subrec, struct work_record *work,
269 BOOL force_new_election)
271 struct server_record *servrec;
272 struct name_record *namerec;
273 struct nmb_name nmbname;
277 DEBUG(2,("unbecome_local_master_browser: unbecoming local master for workgroup %s \
278 on subnet %s\n",work->work_group, subrec->subnet_name));
280 if((servrec = find_server_in_workgroup( work, global_myname)) == NULL)
282 DEBUG(0,("unbecome_local_master_browser: Error - cannot find server %s \
283 in workgroup %s on subnet %s\n",
284 global_myname, work->work_group, subrec->subnet_name));
285 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
289 /* Set the state to unbecoming. */
290 work->mst_state = MST_UNBECOMING_MASTER;
293 * Release the WORKGROUP<1d> name asap to allow another machine to
297 release_1d_name( subrec, work->work_group, force_new_election);
299 /* Deregister any browser names we may have. */
300 make_nmb_name(&nmbname, MSBROWSE, 0x1, scope);
301 if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL)
303 release_name(subrec, namerec,
304 release_msbrowse_name_success,
305 release_msbrowse_name_fail,
310 * Ensure we have sent and processed these release packets
311 * before returning - we don't want to process any election
312 * packets before dealing with the 1d release.
315 retransmit_or_expire_response_records(time(NULL));
318 /****************************************************************************
319 Success in registering the WORKGROUP<1d> name.
320 We are now *really* a local master browser.
321 ****************************************************************************/
323 static void become_local_master_stage2(struct subnet_record *subrec,
324 struct userdata_struct *userdata,
325 struct nmb_name *registered_name,
327 int ttl, struct in_addr registered_ip)
330 struct server_record *sl;
331 struct work_record *work = find_workgroup_on_subnet( subrec, registered_name->name);
332 struct server_record *servrec;
336 DEBUG(0,("become_local_master_stage2: Error - cannot find \
337 workgroup %s on subnet %s\n", registered_name->name, subrec->subnet_name));
341 if((servrec = find_server_in_workgroup( work, global_myname)) == NULL)
343 DEBUG(0,("become_local_master_stage2: Error - cannot find server %s \
344 in workgroup %s on subnet %s\n",
345 global_myname, registered_name->name, subrec->subnet_name));
346 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
350 DEBUG(3,("become_local_master_stage2: registered as master browser for workgroup %s \
351 on subnet %s\n", work->work_group, subrec->subnet_name));
353 work->mst_state = MST_BROWSER; /* registering WORKGROUP(1d) succeeded */
355 /* update our server status */
356 servrec->serv.type |= SV_TYPE_MASTER_BROWSER;
357 servrec->serv.type &= ~SV_TYPE_POTENTIAL_BROWSER;
359 /* Tell the namelist writer to write out a change. */
360 subrec->work_changed = True;
362 /* Add this name to the workgroup as local master browser. */
363 set_workgroup_local_master_browser_name( work, global_myname);
365 /* Count the number of servers we have on our list. If it's
366 less than 10 (just a heuristic) request the servers
367 to announce themselves.
369 for( sl = work->serverlist; sl != NULL; sl = sl->next)
374 /* Ask all servers on our local net to announce to us. */
375 broadcast_announce_request(subrec, work);
379 * Now we are a local master on a broadcast subnet, we need to add
380 * the WORKGROUP<1d> name to the unicast subnet so that we can answer
381 * unicast requests sent to this name. We can create this name directly on
382 * the unicast subnet as a WINS server always returns true when registering
383 * this name, and discards the registration. We use the number of IP
384 * addresses registered to this name as a reference count, as we
385 * remove this broadcast subnet IP address from it when we stop becoming a local
386 * master browser for this broadcast subnet.
389 insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
391 /* Reset the announce master browser timer so that we try and tell a domain
392 master browser as soon as possible that we are a local master browser. */
393 reset_announce_timer();
395 DEBUG(0,("\n%s ***** Samba name server %s is now a local master browser for workgroup %s \
396 on subnet %s *****\n\n", timestring(), global_myname, work->work_group, subrec->subnet_name));
400 /****************************************************************************
401 Failed to register the WORKGROUP<1d> name.
402 ****************************************************************************/
403 static void become_local_master_fail2(struct subnet_record *subrec,
404 struct response_record *rrec,
405 struct nmb_name *fail_name)
407 struct work_record *work = find_workgroup_on_subnet( subrec, fail_name->name);
409 DEBUG(0,("become_local_master_fail2: failed to register name %s on subnet %s. \
410 Failed to become a local master browser.\n", namestr(fail_name), subrec->subnet_name));
414 DEBUG(0,("become_local_master_fail2: Error - cannot find \
415 workgroup %s on subnet %s\n", fail_name->name, subrec->subnet_name));
419 /* Roll back all the way by calling unbecome_local_master_browser(). */
420 unbecome_local_master_browser(subrec, work, False);
423 /****************************************************************************
424 Success in registering the MSBROWSE name.
425 ****************************************************************************/
427 static void become_local_master_stage1(struct subnet_record *subrec,
428 struct userdata_struct *userdata,
429 struct nmb_name *registered_name,
431 int ttl, struct in_addr registered_ip)
433 char *work_name = userdata->data;
434 struct work_record *work = find_workgroup_on_subnet( subrec, work_name);
438 DEBUG(0,("become_local_master_stage1: Error - cannot find \
439 workgroup %s on subnet %s\n", work_name, subrec->subnet_name));
443 DEBUG(3,("become_local_master_stage1: go to stage 2: register the %s<1d> name.\n",
446 work->mst_state = MST_MSB; /* Registering MSBROWSE was successful. */
449 * We registered the MSBROWSE name on a broadcast subnet, now need to add
450 * the MSBROWSE name to the unicast subnet so that we can answer
451 * unicast requests sent to this name. We create this name directly on
452 * the unicast subnet.
455 insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
457 /* Attempt to register the WORKGROUP<1d> name. */
458 register_name(subrec, work->work_group,0x1d,samba_nb_type,
459 become_local_master_stage2,
460 become_local_master_fail2,
464 /****************************************************************************
465 Failed to register the MSBROWSE name.
466 ****************************************************************************/
468 static void become_local_master_fail1(struct subnet_record *subrec,
469 struct response_record *rrec,
470 struct nmb_name *fail_name)
472 char *work_name = rrec->userdata->data;
473 struct work_record *work = find_workgroup_on_subnet(subrec, work_name);
474 struct server_record *servrec;
478 DEBUG(0,("become_local_master_fail1: Error - cannot find \
479 workgroup %s on subnet %s\n", work_name, subrec->subnet_name));
483 if((servrec = find_server_in_workgroup(work, global_myname)) == NULL)
485 DEBUG(0,("become_local_master_fail1: Error - cannot find server %s \
486 in workgroup %s on subnet %s\n",
487 global_myname, work->work_group, subrec->subnet_name));
491 reset_workgroup_state( subrec, work->work_group, False );
493 DEBUG(0,("become_local_master_fail1: Failed to become a local master browser for \
494 workgroup %s on subnet %s. Couldn't register name %s.\n",
495 work->work_group, subrec->subnet_name, namestr(fail_name)));
498 /******************************************************************
499 Become the local master browser on a subnet.
500 This gets called if we win an election on this subnet.
502 Stage 1: mst_state was MST_POTENTIAL - go to MST_BACK register ^1^2__MSBROWSE__^2^1.
503 Stage 2: mst_state was MST_BACKUP - go to MST_MSB and register WORKGROUP<1d>.
504 Stage 3: mst_state was MST_MSB - go to MST_BROWSER.
505 ******************************************************************/
507 void become_local_master_browser(struct subnet_record *subrec, struct work_record *work)
509 struct server_record *servrec;
510 struct userdata_struct *userdata;
513 if (!lp_local_master())
515 DEBUG(0,("become_local_master_browser: Samba not configured as a local master browser.\n"));
519 if(!AM_POTENTIAL_MASTER_BROWSER(work))
521 DEBUG(2,("become_local_master_browser: Awaiting potential browser state. Current state is %d\n",
526 if((servrec = find_server_in_workgroup( work, global_myname)) == NULL)
528 DEBUG(0,("become_local_master_browser: Error - cannot find server %s \
529 in workgroup %s on subnet %s\n",
530 global_myname, work->work_group, subrec->subnet_name));
534 DEBUG(2,("become_local_master_browser: Starting to become a master browser for workgroup \
535 %s on subnet %s\n", work->work_group, subrec->subnet_name));
537 DEBUG(3,("become_local_master_browser: first stage - attempt to register ^1^2__MSBROWSE__^2^1\n"));
538 work->mst_state = MST_BACKUP; /* an election win was successful */
540 work->ElectionCriterion |= 0x5;
542 /* Tell the namelist writer to write out a change. */
543 subrec->work_changed = True;
545 /* Setup the userdata_struct. */
546 if((userdata = (struct userdata_struct *)malloc(sizeof(struct userdata_struct) + sizeof(fstring)+1)) == NULL)
548 DEBUG(0,("become_local_master_browser: malloc fail.\n"));
552 userdata->copy_fn = NULL;
553 userdata->free_fn = NULL;
554 userdata->userdata_len = strlen(work->work_group)+1;
555 pstrcpy(userdata->data, work->work_group);
557 /* Register the special browser group name. */
558 register_name(subrec, MSBROWSE, 0x01, samba_nb_type|NB_GROUP,
559 become_local_master_stage1,
560 become_local_master_fail1,
563 free((char *)userdata);
566 /***************************************************************
567 Utility function to set the local master browser name. Does
568 some sanity checking as old versions of Samba seem to sometimes
569 say that the master browser name for a workgroup is the same
570 as the workgroup name.
571 ****************************************************************/
573 void set_workgroup_local_master_browser_name( struct work_record *work, char *newname)
575 DEBUG(5,("set_workgroup_local_master_browser_name: setting local master name to '%s' \
576 for workgroup %s.\n", newname, work->work_group ));
580 * Apparently some sites use the workgroup name as the local
581 * master browser name. Arrrrggghhhhh ! (JRA).
583 if(strequal( work->work_group, newname))
585 DEBUG(5, ("set_workgroup_local_master_browser_name: Refusing to set \
586 local_master_browser_name for workgroup %s to workgroup name.\n",
592 StrnCpy(work->local_master_browser_name, newname,
593 sizeof(work->local_master_browser_name)-1);