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 static 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 );
158 dbgtext( "*****\n\n" );
159 dbgtext( "Samba name server %s ", global_myname );
160 dbgtext( "has stopped being a local master browser " );
161 dbgtext( "for workgroup %s ", released_name->name );
162 dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
167 /*******************************************************************
168 Unbecome the local master browser name release fail function.
169 ******************************************************************/
171 static void unbecome_local_master_fail(struct subnet_record *subrec, struct response_record *rrec,
172 struct nmb_name *fail_name)
174 struct name_record *namerec;
175 struct userdata_struct *userdata = rrec->userdata;
176 BOOL force_new_election = False;
178 memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL));
180 DEBUG(0,("unbecome_local_master_fail: failed to release name %s. \
181 Removing from namelist anyway.\n", namestr(fail_name)));
184 namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
186 remove_name_from_namelist(subrec, namerec);
188 /* Now reset the workgroup and server state. */
189 reset_workgroup_state( subrec, fail_name->name, force_new_election );
193 dbgtext( "*****\n\n" );
194 dbgtext( "Samba name server %s ", global_myname );
195 dbgtext( "has stopped being a local master browser " );
196 dbgtext( "for workgroup %s ", fail_name->name );
197 dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
201 /*******************************************************************
202 Utility function to remove the WORKGROUP<1d> name.
203 ******************************************************************/
205 static void release_1d_name( struct subnet_record *subrec, char *workgroup_name,
206 BOOL force_new_election)
208 struct nmb_name nmbname;
209 struct name_record *namerec;
211 make_nmb_name(&nmbname, workgroup_name, 0x1d, scope);
212 if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL)
214 struct userdata_struct *userdata;
215 int size = sizeof(struct userdata_struct) + sizeof(BOOL);
217 if((userdata = (struct userdata_struct *)malloc(size)) == NULL)
219 DEBUG(0,("release_1d_name: malloc fail.\n"));
223 userdata->copy_fn = NULL;
224 userdata->free_fn = NULL;
225 userdata->userdata_len = sizeof(BOOL);
226 memcpy((char *)userdata->data, &force_new_election, sizeof(BOOL));
228 release_name(subrec, namerec,
229 unbecome_local_master_success,
230 unbecome_local_master_fail,
233 zero_free(userdata, size);
237 /*******************************************************************
238 Unbecome the local master browser MSBROWSE name release success function.
239 ******************************************************************/
241 static void release_msbrowse_name_success(struct subnet_record *subrec,
242 struct userdata_struct *userdata,
243 struct nmb_name *released_name,
244 struct in_addr released_ip)
246 DEBUG(4,("release_msbrowse_name_success: Released name %s on subnet %s\n.",
247 namestr(released_name), subrec->subnet_name ));
249 /* Remove the permanent MSBROWSE name added into the unicast subnet. */
250 remove_permanent_name_from_unicast( subrec, released_name);
253 /*******************************************************************
254 Unbecome the local master browser MSBROWSE name release fail function.
255 ******************************************************************/
257 static void release_msbrowse_name_fail( struct subnet_record *subrec,
258 struct response_record *rrec,
259 struct nmb_name *fail_name)
261 struct name_record *namerec;
263 DEBUG(4,("release_msbrowse_name_fail: Failed to release name %s on subnet %s\n.",
264 namestr(fail_name), subrec->subnet_name ));
266 /* Release the name anyway. */
267 namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
269 remove_name_from_namelist(subrec, namerec);
271 /* Remove the permanent MSBROWSE name added into the unicast subnet. */
272 remove_permanent_name_from_unicast( subrec, fail_name);
275 /*******************************************************************
276 Unbecome the local master browser. If force_new_election is true, restart
277 the election process after we've unbecome the local master.
278 ******************************************************************/
280 void unbecome_local_master_browser(struct subnet_record *subrec, struct work_record *work,
281 BOOL force_new_election)
283 struct name_record *namerec;
284 struct nmb_name nmbname;
288 DEBUG(2,("unbecome_local_master_browser: unbecoming local master for workgroup %s \
289 on subnet %s\n",work->work_group, subrec->subnet_name));
291 if(find_server_in_workgroup( work, global_myname) == NULL)
293 DEBUG(0,("unbecome_local_master_browser: Error - cannot find server %s \
294 in workgroup %s on subnet %s\n",
295 global_myname, work->work_group, subrec->subnet_name));
296 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
300 /* Set the state to unbecoming. */
301 work->mst_state = MST_UNBECOMING_MASTER;
304 * Release the WORKGROUP<1d> name asap to allow another machine to
308 release_1d_name( subrec, work->work_group, force_new_election);
310 /* Deregister any browser names we may have. */
311 make_nmb_name(&nmbname, MSBROWSE, 0x1, scope);
312 if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL)
314 release_name(subrec, namerec,
315 release_msbrowse_name_success,
316 release_msbrowse_name_fail,
321 * Ensure we have sent and processed these release packets
322 * before returning - we don't want to process any election
323 * packets before dealing with the 1d release.
326 retransmit_or_expire_response_records(time(NULL));
329 /****************************************************************************
330 Success in registering the WORKGROUP<1d> name.
331 We are now *really* a local master browser.
332 ****************************************************************************/
334 static void become_local_master_stage2(struct subnet_record *subrec,
335 struct userdata_struct *userdata,
336 struct nmb_name *registered_name,
338 int ttl, struct in_addr registered_ip)
341 struct server_record *sl;
342 struct work_record *work = find_workgroup_on_subnet( subrec, registered_name->name);
343 struct server_record *servrec;
347 DEBUG(0,("become_local_master_stage2: Error - cannot find \
348 workgroup %s on subnet %s\n", registered_name->name, subrec->subnet_name));
352 if((servrec = find_server_in_workgroup( work, global_myname)) == NULL)
354 DEBUG(0,("become_local_master_stage2: Error - cannot find server %s \
355 in workgroup %s on subnet %s\n",
356 global_myname, registered_name->name, subrec->subnet_name));
357 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
361 DEBUG(3,("become_local_master_stage2: registered as master browser for workgroup %s \
362 on subnet %s\n", work->work_group, subrec->subnet_name));
364 work->mst_state = MST_BROWSER; /* registering WORKGROUP(1d) succeeded */
366 /* update our server status */
367 servrec->serv.type |= SV_TYPE_MASTER_BROWSER;
368 servrec->serv.type &= ~SV_TYPE_POTENTIAL_BROWSER;
370 /* Tell the namelist writer to write out a change. */
371 subrec->work_changed = True;
373 /* Add this name to the workgroup as local master browser. */
374 set_workgroup_local_master_browser_name( work, global_myname);
376 /* Count the number of servers we have on our list. If it's
377 less than 10 (just a heuristic) request the servers
378 to announce themselves.
380 for( sl = work->serverlist; sl != NULL; sl = sl->next)
385 /* Ask all servers on our local net to announce to us. */
386 broadcast_announce_request(subrec, work);
390 * Now we are a local master on a broadcast subnet, we need to add
391 * the WORKGROUP<1d> name to the unicast subnet so that we can answer
392 * unicast requests sent to this name. We can create this name directly on
393 * the unicast subnet as a WINS server always returns true when registering
394 * this name, and discards the registration. We use the number of IP
395 * addresses registered to this name as a reference count, as we
396 * remove this broadcast subnet IP address from it when we stop becoming a local
397 * master browser for this broadcast subnet.
400 insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
402 /* Reset the announce master browser timer so that we try and tell a domain
403 master browser as soon as possible that we are a local master browser. */
404 reset_announce_timer();
408 dbgtext( "*****\n\n" );
409 dbgtext( "Samba name server %s ", global_myname );
410 dbgtext( "is now a local master browser " );
411 dbgtext( "for workgroup %s ", work->work_group );
412 dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
417 /****************************************************************************
418 Failed to register the WORKGROUP<1d> name.
419 ****************************************************************************/
420 static void become_local_master_fail2(struct subnet_record *subrec,
421 struct response_record *rrec,
422 struct nmb_name *fail_name)
424 struct work_record *work = find_workgroup_on_subnet( subrec, fail_name->name);
426 DEBUG(0,("become_local_master_fail2: failed to register name %s on subnet %s. \
427 Failed to become a local master browser.\n", namestr(fail_name), subrec->subnet_name));
431 DEBUG(0,("become_local_master_fail2: Error - cannot find \
432 workgroup %s on subnet %s\n", fail_name->name, subrec->subnet_name));
436 /* Roll back all the way by calling unbecome_local_master_browser(). */
437 unbecome_local_master_browser(subrec, work, False);
440 /****************************************************************************
441 Success in registering the MSBROWSE name.
442 ****************************************************************************/
444 static void become_local_master_stage1(struct subnet_record *subrec,
445 struct userdata_struct *userdata,
446 struct nmb_name *registered_name,
448 int ttl, struct in_addr registered_ip)
450 char *work_name = userdata->data;
451 struct work_record *work = find_workgroup_on_subnet( subrec, work_name);
455 DEBUG(0,("become_local_master_stage1: Error - cannot find \
456 workgroup %s on subnet %s\n", work_name, subrec->subnet_name));
460 DEBUG(3,("become_local_master_stage1: go to stage 2: register the %s<1d> name.\n",
463 work->mst_state = MST_MSB; /* Registering MSBROWSE was successful. */
466 * We registered the MSBROWSE name on a broadcast subnet, now need to add
467 * the MSBROWSE name to the unicast subnet so that we can answer
468 * unicast requests sent to this name. We create this name directly on
469 * the unicast subnet.
472 insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
474 /* Attempt to register the WORKGROUP<1d> name. */
475 register_name(subrec, work->work_group,0x1d,samba_nb_type,
476 become_local_master_stage2,
477 become_local_master_fail2,
481 /****************************************************************************
482 Failed to register the MSBROWSE name.
483 ****************************************************************************/
485 static void become_local_master_fail1(struct subnet_record *subrec,
486 struct response_record *rrec,
487 struct nmb_name *fail_name)
489 char *work_name = rrec->userdata->data;
490 struct work_record *work = find_workgroup_on_subnet(subrec, work_name);
494 DEBUG(0,("become_local_master_fail1: Error - cannot find \
495 workgroup %s on subnet %s\n", work_name, subrec->subnet_name));
499 if(find_server_in_workgroup(work, global_myname) == NULL)
501 DEBUG(0,("become_local_master_fail1: Error - cannot find server %s \
502 in workgroup %s on subnet %s\n",
503 global_myname, work->work_group, subrec->subnet_name));
507 reset_workgroup_state( subrec, work->work_group, False );
509 DEBUG(0,("become_local_master_fail1: Failed to become a local master browser for \
510 workgroup %s on subnet %s. Couldn't register name %s.\n",
511 work->work_group, subrec->subnet_name, namestr(fail_name)));
514 /******************************************************************
515 Become the local master browser on a subnet.
516 This gets called if we win an election on this subnet.
518 Stage 1: mst_state was MST_POTENTIAL - go to MST_BACK register ^1^2__MSBROWSE__^2^1.
519 Stage 2: mst_state was MST_BACKUP - go to MST_MSB and register WORKGROUP<1d>.
520 Stage 3: mst_state was MST_MSB - go to MST_BROWSER.
521 ******************************************************************/
523 void become_local_master_browser(struct subnet_record *subrec, struct work_record *work)
525 struct userdata_struct *userdata;
526 int size = sizeof(struct userdata_struct) + sizeof(fstring) + 1;
529 if (!lp_local_master())
531 DEBUG(0,("become_local_master_browser: Samba not configured as a local master browser.\n"));
535 if(!AM_POTENTIAL_MASTER_BROWSER(work))
537 DEBUG(2,("become_local_master_browser: Awaiting potential browser state. Current state is %d\n",
542 if(find_server_in_workgroup( work, global_myname) == NULL)
544 DEBUG(0,("become_local_master_browser: Error - cannot find server %s \
545 in workgroup %s on subnet %s\n",
546 global_myname, work->work_group, subrec->subnet_name));
550 DEBUG(2,("become_local_master_browser: Starting to become a master browser for workgroup \
551 %s on subnet %s\n", work->work_group, subrec->subnet_name));
553 DEBUG(3,("become_local_master_browser: first stage - attempt to register ^1^2__MSBROWSE__^2^1\n"));
554 work->mst_state = MST_BACKUP; /* an election win was successful */
556 work->ElectionCriterion |= 0x5;
558 /* Tell the namelist writer to write out a change. */
559 subrec->work_changed = True;
561 /* Setup the userdata_struct. */
562 if((userdata = (struct userdata_struct *)malloc(size)) == NULL)
564 DEBUG(0,("become_local_master_browser: malloc fail.\n"));
568 userdata->copy_fn = NULL;
569 userdata->free_fn = NULL;
570 userdata->userdata_len = strlen(work->work_group)+1;
571 pstrcpy(userdata->data, work->work_group);
573 /* Register the special browser group name. */
574 register_name(subrec, MSBROWSE, 0x01, samba_nb_type|NB_GROUP,
575 become_local_master_stage1,
576 become_local_master_fail1,
579 zero_free(userdata, size);
582 /***************************************************************
583 Utility function to set the local master browser name. Does
584 some sanity checking as old versions of Samba seem to sometimes
585 say that the master browser name for a workgroup is the same
586 as the workgroup name.
587 ****************************************************************/
589 void set_workgroup_local_master_browser_name( struct work_record *work, char *newname)
591 DEBUG(5,("set_workgroup_local_master_browser_name: setting local master name to '%s' \
592 for workgroup %s.\n", newname, work->work_group ));
596 * Apparently some sites use the workgroup name as the local
597 * master browser name. Arrrrggghhhhh ! (JRA).
599 if(strequal( work->work_group, newname))
601 DEBUG(5, ("set_workgroup_local_master_browser_name: Refusing to set \
602 local_master_browser_name for workgroup %s to workgroup name.\n",
608 StrnCpy(work->local_master_browser_name, newname,
609 sizeof(work->local_master_browser_name)-1);