2 Unix SMB/Netbios implementation.
4 NBT netbios routines and daemon - version 2
5 Copyright (C) Andrew Tridgell 1994-1997
6 Copyright (C) Luke Kenneth Casson Leighton 1994-1997
7 Copyright (C) Jeremy Allison 1994-1997
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 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 static 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 add_name_to_subnet( unicast_subnet, nmbname->name, nmbname->name_type,
47 nb_type, PERMANENT_TTL, PERMANENT_NAME, 1, &subrec->myip);
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->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 )
82 struct work_record *work;
83 struct server_record *servrec;
84 struct nmb_name nmbname;
86 if((work = find_workgroup_on_subnet( subrec, workgroup_name)) == NULL)
88 DEBUG(0,("reset_workgroup_state: Error - cannot find workgroup %s on \
89 subnet %s.\n", workgroup_name, subrec->subnet_name ));
93 if((servrec = find_server_in_workgroup( work, myname)) == NULL)
95 DEBUG(0,("reset_workgroup_state: Error - cannot find server %s \
96 in workgroup %s on subnet %s\n",
97 myname, work->work_group, subrec->subnet_name));
98 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
102 /* Update our server status - remove any master flag and replace
103 it with the potential browser flag. */
104 servrec->serv.type &= ~SV_TYPE_MASTER_BROWSER;
105 servrec->serv.type |= (lp_local_master() ? SV_TYPE_POTENTIAL_BROWSER : 0);
107 /* Tell the namelist writer to write out a change. */
108 subrec->work_changed = True;
110 /* Reset our election flags. */
111 work->ElectionCriterion &= ~0x4;
113 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
115 /* Forget who the local master browser was for
118 set_workgroup_local_master_browser_name( work, "");
121 * Ensure the IP address of this subnet is not registered as one
122 * of the IP addresses of the WORKGROUP<1d> name on the unicast
123 * subnet. This undoes what we did below when we became a local
127 make_nmb_name(&nmbname, work->work_group, 0x1d, scope);
129 remove_permanent_name_from_unicast( subrec, &nmbname);
133 /*******************************************************************
134 Unbecome the local master browser name release success function.
135 ******************************************************************/
137 void unbecome_local_master_success(struct subnet_record *subrec,
138 struct userdata_struct *userdata,
139 struct nmb_name *released_name,
140 struct in_addr released_ip)
142 DEBUG(3,("unbecome_local_master_success: released name %s.\n",
143 namestr(released_name)));
145 /* Now reset the workgroup and server state. */
146 reset_workgroup_state( subrec, released_name->name );
148 DEBUG(0,("\n***** Samba name server %s has stopped being a local master browser for workgroup %s \
149 on subnet %s *****\n\n", myname, released_name->name, subrec->subnet_name));
153 /*******************************************************************
154 Unbecome the local master browser name release fail function.
155 ******************************************************************/
157 void unbecome_local_master_fail(struct subnet_record *subrec, struct response_record *rrec,
158 struct nmb_name *fail_name)
160 struct name_record *namerec;
162 DEBUG(0,("unbecome_local_master_fail: failed to release name %s. \
163 Removing from namelist anyway.\n", namestr(fail_name)));
166 namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
168 remove_name_from_namelist(subrec, namerec);
170 /* Now reset the workgroup and server state. */
171 reset_workgroup_state( subrec, fail_name->name );
173 DEBUG(0,("\n***** Samba name server %s has stopped being a local master browser for workgroup %s \
174 on subnet %s *****\n\n", myname, fail_name->name, subrec->subnet_name));
178 /*******************************************************************
179 Utility function to remove the WORKGROUP<1d> name called by both
180 success and fail of releasing the MSBROWSE name.
181 ******************************************************************/
183 void release_1d_name( struct subnet_record *subrec, char *workgroup_name)
185 struct nmb_name nmbname;
186 struct name_record *namerec;
188 make_nmb_name(&nmbname, workgroup_name, 0x1d, scope);
189 if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL)
191 release_name(subrec, namerec,
192 unbecome_local_master_success,
193 unbecome_local_master_fail,
198 /*******************************************************************
199 Unbecome the local master browser MSBROWSE name release success function.
200 ******************************************************************/
202 static void release_msbrowse_name_success(struct subnet_record *subrec,
203 struct userdata_struct *userdata,
204 struct nmb_name *released_name,
205 struct in_addr released_ip)
207 DEBUG(4,("release_msbrowse_name_success: Released name %s on subnet %s\n.",
208 namestr(released_name), subrec->subnet_name ));
210 /* Remove the permanent MSBROWSE name added into the unicast subnet. */
211 remove_permanent_name_from_unicast( subrec, released_name);
213 release_1d_name( subrec, userdata->data );
216 /*******************************************************************
217 Unbecome the local master browser MSBROWSE name release fail function.
218 ******************************************************************/
220 static void release_msbrowse_name_fail( struct subnet_record *subrec,
221 struct response_record *rrec,
222 struct nmb_name *fail_name)
224 struct userdata_struct *userdata = rrec->userdata;
225 struct name_record *namerec;
227 DEBUG(4,("release_msbrowse_name_fail: Failed to release name %s on subnet %s\n.",
228 namestr(fail_name), subrec->subnet_name ));
230 /* Release the name anyway. */
231 namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
233 remove_name_from_namelist(subrec, namerec);
235 /* Remove the permanent MSBROWSE name added into the unicast subnet. */
236 remove_permanent_name_from_unicast( subrec, fail_name);
238 release_1d_name( subrec, userdata->data );
241 /*******************************************************************
242 Unbecome the local master browser.
243 ******************************************************************/
245 void unbecome_local_master_browser(struct subnet_record *subrec, struct work_record *work)
247 struct server_record *servrec;
248 struct name_record *namerec;
249 struct nmb_name nmbname;
250 struct userdata_struct *userdata;
251 char ud[sizeof(struct userdata_struct) + sizeof(fstring)+1];
255 DEBUG(2,("unbecome_local_master_browser: unbecoming local master for workgroup %s \
256 on subnet %s\n",work->work_group, subrec->subnet_name));
258 if((servrec = find_server_in_workgroup( work, myname)) == NULL)
260 DEBUG(0,("unbecome_local_master_browser: Error - cannot find server %s \
261 in workgroup %s on subnet %s\n",
262 myname, work->work_group, subrec->subnet_name));
263 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
267 /* Set the state to unbecoming. */
268 work->mst_state = MST_UNBECOMING_MASTER;
270 /* Setup the userdata for the MSBROWSE name release. */
271 /* Setup the userdata_struct - this is copied so we can use
272 a stack variable for this. */
273 userdata = (struct userdata_struct *)ud;
275 userdata->copy_fn = NULL;
276 userdata->free_fn = NULL;
277 userdata->userdata_len = strlen(work->work_group)+1;
278 strcpy(userdata->data, work->work_group);
280 /* Deregister any browser names we may have. */
281 make_nmb_name(&nmbname, MSBROWSE, 0x1, scope);
282 if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL)
284 release_name(subrec, namerec,
285 release_msbrowse_name_success,
286 release_msbrowse_name_fail,
291 /****************************************************************************
292 Success in registering the WORKGROUP<1d> name.
293 We are now *really* a local master browser.
294 ****************************************************************************/
296 static void become_local_master_stage2(struct subnet_record *subrec,
297 struct userdata_struct *userdata,
298 struct nmb_name *registered_name,
300 int ttl, struct in_addr registered_ip)
303 struct server_record *sl;
304 struct work_record *work = find_workgroup_on_subnet( subrec, registered_name->name);
305 struct server_record *servrec;
309 DEBUG(0,("become_local_master_stage2: Error - cannot find \
310 workgroup %s on subnet %s\n", registered_name->name, subrec->subnet_name));
314 if((servrec = find_server_in_workgroup( work, myname)) == NULL)
316 DEBUG(0,("become_local_master_stage2: Error - cannot find server %s \
317 in workgroup %s on subnet %s\n",
318 myname, registered_name->name, subrec->subnet_name));
319 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
323 DEBUG(3,("become_local_master_stage2: registered as master browser for workgroup %s \
324 on subnet %s\n", work->work_group, subrec->subnet_name));
326 work->mst_state = MST_BROWSER; /* registering WORKGROUP(1d) succeeded */
328 /* update our server status */
329 servrec->serv.type |= SV_TYPE_MASTER_BROWSER;
330 servrec->serv.type &= ~SV_TYPE_POTENTIAL_BROWSER;
332 /* Tell the namelist writer to write out a change. */
333 subrec->work_changed = True;
335 /* Add this name to the workgroup as local master browser. */
336 set_workgroup_local_master_browser_name( work, myname);
338 /* Count the number of servers we have on our list. If it's
339 less than 10 (just a heuristic) request the servers
340 to announce themselves.
342 for( sl = work->serverlist; sl != NULL; sl = sl->next)
347 /* Ask all servers on our local net to announce to us. */
348 broadcast_announce_request(subrec, work);
352 * Now we are a local master on a broadcast subnet, we need to add
353 * the WORKGROUP<1d> name to the unicast subnet so that we can answer
354 * unicast requests sent to this name. We can create this name directly on
355 * the unicast subnet as a WINS server always returns true when registering
356 * this name, and discards the registration. We use the number of IP
357 * addresses registered to this name as a reference count, as we
358 * remove this broadcast subnet IP address from it when we stop becoming a local
359 * master browser for this broadcast subnet.
362 insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
364 /* Reset the announce master browser timer so that we try and tell a domain
365 master browser as soon as possible that we are a local master browser. */
366 reset_announce_timer();
368 DEBUG(0,("\n***** Samba name server %s is now a local master browser for workgroup %s \
369 on subnet %s *****\n\n", myname, work->work_group, subrec->subnet_name));
373 /****************************************************************************
374 Failed to register the WORKGROUP<1d> name.
375 ****************************************************************************/
376 static void become_local_master_fail2(struct subnet_record *subrec,
377 struct response_record *rrec,
378 struct nmb_name *fail_name)
380 struct work_record *work = find_workgroup_on_subnet( subrec, fail_name->name);
382 DEBUG(0,("become_local_master_fail2: failed to register name %s on subnet %s. \
383 Failed to become a local master browser.\n", namestr(fail_name), subrec->subnet_name));
387 DEBUG(0,("become_local_master_fail2: Error - cannot find \
388 workgroup %s on subnet %s\n", fail_name->name, subrec->subnet_name));
392 /* Roll back all the way by calling unbecome_local_master_browser(). */
393 unbecome_local_master_browser(subrec, work);
396 /****************************************************************************
397 Success in registering the MSBROWSE name.
398 ****************************************************************************/
400 static void become_local_master_stage1(struct subnet_record *subrec,
401 struct userdata_struct *userdata,
402 struct nmb_name *registered_name,
404 int ttl, struct in_addr registered_ip)
406 char *work_name = userdata->data;
407 struct work_record *work = find_workgroup_on_subnet( subrec, work_name);
411 DEBUG(0,("become_local_master_stage1: Error - cannot find \
412 workgroup %s on subnet %s\n", work_name, subrec->subnet_name));
416 DEBUG(3,("become_local_master_stage1: go to stage 2: register the %s<1d> name.\n",
419 work->mst_state = MST_MSB; /* Registering MSBROWSE was successful. */
422 * We registered the MSBROWSE name on a broadcast subnet, now need to add
423 * the MSBROWSE name to the unicast subnet so that we can answer
424 * unicast requests sent to this name. We create this name directly on
425 * the unicast subnet.
428 insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
430 /* Attempt to register the WORKGROUP<1d> name. */
431 register_name(subrec, work->work_group,0x1d,samba_nb_type,
432 become_local_master_stage2,
433 become_local_master_fail2,
437 /****************************************************************************
438 Failed to register the MSBROWSE name.
439 ****************************************************************************/
441 static void become_local_master_fail1(struct subnet_record *subrec,
442 struct response_record *rrec,
443 struct nmb_name *fail_name)
445 char *work_name = rrec->userdata->data;
446 struct work_record *work = find_workgroup_on_subnet(subrec, work_name);
447 struct server_record *servrec;
451 DEBUG(0,("become_local_master_fail1: Error - cannot find \
452 workgroup %s on subnet %s\n", work_name, subrec->subnet_name));
456 if((servrec = find_server_in_workgroup(work, myname)) == NULL)
458 DEBUG(0,("become_local_master_fail1: Error - cannot find server %s \
459 in workgroup %s on subnet %s\n",
460 myname, work->work_group, subrec->subnet_name));
464 reset_workgroup_state( subrec, work->work_group );
466 DEBUG(0,("become_local_master_fail1: Failed to become a local master browser for \
467 workgroup %s on subnet %s. Couldn't register name %s.\n",
468 work->work_group, subrec->subnet_name, namestr(fail_name)));
471 /******************************************************************
472 Become the local master browser on a subnet.
473 This gets called if we win an election on this subnet.
475 Stage 1: mst_state was MST_POTENTIAL - go to MST_BACK register ^1^2__MSBROWSE__^2^1.
476 Stage 2: mst_state was MST_BACKUP - go to MST_MSB and register WORKGROUP<1d>.
477 Stage 3: mst_state was MST_MSB - go to MST_BROWSER.
478 ******************************************************************/
480 void become_local_master_browser(struct subnet_record *subrec, struct work_record *work)
482 struct server_record *servrec;
483 struct userdata_struct *userdata;
484 char ud[sizeof(struct userdata_struct) + sizeof(fstring)+1];
487 if (!lp_local_master())
489 DEBUG(0,("become_local_master_browser: Samba not configured as a local master browser.\n"));
493 if(!AM_POTENTIAL_MASTER_BROWSER(work))
495 DEBUG(2,("become_local_master_browser: Awaiting potential browser state. Current state is %d\n",
500 if((servrec = find_server_in_workgroup( work, myname)) == NULL)
502 DEBUG(0,("become_local_master_browser: Error - cannot find server %s \
503 in workgroup %s on subnet %s\n",
504 myname, work->work_group, subrec->subnet_name));
508 DEBUG(2,("become_local_master_browser: Starting to become a master browser for workgroup \
509 %s on subnet %s\n", work->work_group, subrec->subnet_name));
511 DEBUG(3,("become_local_master_browser: first stage - attempt to register ^1^2__MSBROWSE__^2^1\n"));
512 work->mst_state = MST_BACKUP; /* an election win was successful */
514 work->ElectionCriterion |= 0x5;
516 /* Tell the namelist writer to write out a change. */
517 subrec->work_changed = True;
519 /* Setup the userdata_struct - this is copied so we can use
520 a stack variable for this. */
521 userdata = (struct userdata_struct *)ud;
523 userdata->copy_fn = NULL;
524 userdata->free_fn = NULL;
525 userdata->userdata_len = strlen(work->work_group)+1;
526 strcpy(userdata->data, work->work_group);
528 /* Register the special browser group name. */
529 register_name(subrec, MSBROWSE, 0x01, samba_nb_type|NB_GROUP,
530 become_local_master_stage1,
531 become_local_master_fail1,
535 /***************************************************************
536 Utility function to set the local master browser name. Does
537 some sanity checking as old versions of Samba seem to sometimes
538 say that the master browser name for a workgroup is the same
539 as the workgroup name.
540 ****************************************************************/
542 void set_workgroup_local_master_browser_name( struct work_record *work, char *newname)
544 DEBUG(5,("set_workgroup_local_master_browser_name: setting local master name to '%s' \
545 for workgroup %s.\n", newname, work->work_group ));
547 if(strequal( work->work_group, newname))
549 DEBUG(5, ("set_workgroup_local_master_browser_name: Refusing to set \
550 local_master_browser_name for workgroup %s to workgroup name.\n",
555 StrnCpy(work->local_master_browser_name, newname,
556 sizeof(work->local_master_browser_name)-1);