2 Unix SMB/CIFS implementation.
3 NBT netbios routines and daemon - version 2
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Luke Kenneth Casson Leighton 1994-1998
6 Copyright (C) Jeremy Allison 1994-1998
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 extern pstring global_myname;
28 extern uint16 samba_nb_type; /* Samba's NetBIOS name type. */
30 /*******************************************************************
31 Utility function to add a name to the unicast subnet, or add in
32 our IP address if it already exists.
33 ******************************************************************/
35 void insert_permanent_name_into_unicast( struct subnet_record *subrec,
36 struct nmb_name *nmbname, uint16 nb_type )
38 struct name_record *namerec;
40 if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL)
42 /* The name needs to be created on the unicast subnet. */
43 (void)add_name_to_subnet( unicast_subnet, nmbname->name,
44 nmbname->name_type, nb_type,
45 PERMANENT_TTL, PERMANENT_NAME, 1, &subrec->myip);
49 /* The name already exists on the unicast subnet. Add our local
50 IP for the given broadcast subnet to the name. */
51 add_ip_to_name_record( namerec, subrec->myip);
55 /*******************************************************************
56 Utility function to remove a name from the unicast subnet.
57 ******************************************************************/
59 static void remove_permanent_name_from_unicast( struct subnet_record *subrec,
60 struct nmb_name *nmbname )
62 struct name_record *namerec;
64 if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) != NULL)
66 /* Remove this broadcast subnet IP address from the name. */
67 remove_ip_from_name_record( namerec, subrec->myip);
68 if(namerec->data.num_ips == 0)
69 remove_name_from_namelist( unicast_subnet, namerec);
73 /*******************************************************************
74 Utility function always called to set our workgroup and server
75 state back to potential browser, or none.
76 ******************************************************************/
78 static void reset_workgroup_state( struct subnet_record *subrec, char *workgroup_name,
79 BOOL force_new_election )
81 struct work_record *work;
82 struct server_record *servrec;
83 struct nmb_name nmbname;
85 if((work = find_workgroup_on_subnet( subrec, workgroup_name)) == NULL)
87 DEBUG(0,("reset_workgroup_state: Error - cannot find workgroup %s on \
88 subnet %s.\n", workgroup_name, subrec->subnet_name ));
92 if((servrec = find_server_in_workgroup( work, global_myname)) == NULL)
94 DEBUG(0,("reset_workgroup_state: Error - cannot find server %s \
95 in workgroup %s on subnet %s\n",
96 global_myname, work->work_group, subrec->subnet_name));
97 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
101 /* Update our server status - remove any master flag and replace
102 it with the potential browser flag. */
103 servrec->serv.type &= ~SV_TYPE_MASTER_BROWSER;
104 servrec->serv.type |= (lp_local_master() ? SV_TYPE_POTENTIAL_BROWSER : 0);
106 /* Tell the namelist writer to write out a change. */
107 subrec->work_changed = True;
109 /* Reset our election flags. */
110 work->ElectionCriterion &= ~0x4;
112 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
114 /* Forget who the local master browser was for
117 set_workgroup_local_master_browser_name( work, "");
120 * Ensure the IP address of this subnet is not registered as one
121 * of the IP addresses of the WORKGROUP<1d> name on the unicast
122 * subnet. This undoes what we did below when we became a local
126 make_nmb_name(&nmbname, work->work_group, 0x1d);
128 remove_permanent_name_from_unicast( subrec, &nmbname);
130 if(force_new_election)
131 work->needelection = True;
134 /*******************************************************************
135 Unbecome the local master browser name release success function.
136 ******************************************************************/
138 static void unbecome_local_master_success(struct subnet_record *subrec,
139 struct userdata_struct *userdata,
140 struct nmb_name *released_name,
141 struct in_addr released_ip)
143 BOOL force_new_election = False;
145 memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL));
147 DEBUG(3,("unbecome_local_master_success: released name %s.\n",
148 nmb_namestr(released_name)));
150 /* Now reset the workgroup and server state. */
151 reset_workgroup_state( subrec, released_name->name, force_new_election );
155 dbgtext( "*****\n\n" );
156 dbgtext( "Samba name server %s ", global_myname );
157 dbgtext( "has stopped being a local master browser " );
158 dbgtext( "for workgroup %s ", released_name->name );
159 dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
164 /*******************************************************************
165 Unbecome the local master browser name release fail function.
166 ******************************************************************/
168 static void unbecome_local_master_fail(struct subnet_record *subrec, struct response_record *rrec,
169 struct nmb_name *fail_name)
171 struct name_record *namerec;
172 struct userdata_struct *userdata = rrec->userdata;
173 BOOL force_new_election = False;
175 memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL));
177 DEBUG(0,("unbecome_local_master_fail: failed to release name %s. \
178 Removing from namelist anyway.\n", nmb_namestr(fail_name)));
181 namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
183 remove_name_from_namelist(subrec, namerec);
185 /* Now reset the workgroup and server state. */
186 reset_workgroup_state( subrec, fail_name->name, force_new_election );
190 dbgtext( "*****\n\n" );
191 dbgtext( "Samba name server %s ", global_myname );
192 dbgtext( "has stopped being a local master browser " );
193 dbgtext( "for workgroup %s ", fail_name->name );
194 dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
198 /*******************************************************************
199 Utility function to remove the WORKGROUP<1d> name.
200 ******************************************************************/
202 static void release_1d_name( struct subnet_record *subrec, char *workgroup_name,
203 BOOL force_new_election)
205 struct nmb_name nmbname;
206 struct name_record *namerec;
208 make_nmb_name(&nmbname, workgroup_name, 0x1d);
209 if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL)
211 struct userdata_struct *userdata;
212 int size = sizeof(struct userdata_struct) + sizeof(BOOL);
214 if((userdata = (struct userdata_struct *)malloc(size)) == NULL)
216 DEBUG(0,("release_1d_name: malloc fail.\n"));
220 userdata->copy_fn = NULL;
221 userdata->free_fn = NULL;
222 userdata->userdata_len = sizeof(BOOL);
223 memcpy((char *)userdata->data, &force_new_election, sizeof(BOOL));
225 release_name(subrec, namerec,
226 unbecome_local_master_success,
227 unbecome_local_master_fail,
230 zero_free(userdata, size);
234 /*******************************************************************
235 Unbecome the local master browser MSBROWSE name release success function.
236 ******************************************************************/
238 static void release_msbrowse_name_success(struct subnet_record *subrec,
239 struct userdata_struct *userdata,
240 struct nmb_name *released_name,
241 struct in_addr released_ip)
243 DEBUG(4,("release_msbrowse_name_success: Released name %s on subnet %s\n.",
244 nmb_namestr(released_name), subrec->subnet_name ));
246 /* Remove the permanent MSBROWSE name added into the unicast subnet. */
247 remove_permanent_name_from_unicast( subrec, released_name);
250 /*******************************************************************
251 Unbecome the local master browser MSBROWSE name release fail function.
252 ******************************************************************/
254 static void release_msbrowse_name_fail( struct subnet_record *subrec,
255 struct response_record *rrec,
256 struct nmb_name *fail_name)
258 struct name_record *namerec;
260 DEBUG(4,("release_msbrowse_name_fail: Failed to release name %s on subnet %s\n.",
261 nmb_namestr(fail_name), subrec->subnet_name ));
263 /* Release the name anyway. */
264 namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
266 remove_name_from_namelist(subrec, namerec);
268 /* Remove the permanent MSBROWSE name added into the unicast subnet. */
269 remove_permanent_name_from_unicast( subrec, fail_name);
272 /*******************************************************************
273 Unbecome the local master browser. If force_new_election is true, restart
274 the election process after we've unbecome the local master.
275 ******************************************************************/
277 void unbecome_local_master_browser(struct subnet_record *subrec, struct work_record *work,
278 BOOL force_new_election)
280 struct name_record *namerec;
281 struct nmb_name nmbname;
285 DEBUG(2,("unbecome_local_master_browser: unbecoming local master for workgroup %s \
286 on subnet %s\n",work->work_group, subrec->subnet_name));
288 if(find_server_in_workgroup( work, global_myname) == NULL)
290 DEBUG(0,("unbecome_local_master_browser: Error - cannot find server %s \
291 in workgroup %s on subnet %s\n",
292 global_myname, work->work_group, subrec->subnet_name));
293 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
297 /* Set the state to unbecoming. */
298 work->mst_state = MST_UNBECOMING_MASTER;
301 * Release the WORKGROUP<1d> name asap to allow another machine to
305 release_1d_name( subrec, work->work_group, force_new_election);
307 /* Deregister any browser names we may have. */
308 make_nmb_name(&nmbname, MSBROWSE, 0x1);
309 if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL)
311 release_name(subrec, namerec,
312 release_msbrowse_name_success,
313 release_msbrowse_name_fail,
318 * Ensure we have sent and processed these release packets
319 * before returning - we don't want to process any election
320 * packets before dealing with the 1d release.
323 retransmit_or_expire_response_records(time(NULL));
326 /****************************************************************************
327 Success in registering the WORKGROUP<1d> name.
328 We are now *really* a local master browser.
329 ****************************************************************************/
331 static void become_local_master_stage2(struct subnet_record *subrec,
332 struct userdata_struct *userdata,
333 struct nmb_name *registered_name,
335 int ttl, struct in_addr registered_ip)
338 struct server_record *sl;
339 struct work_record *work = find_workgroup_on_subnet( subrec, registered_name->name);
340 struct server_record *servrec;
344 DEBUG(0,("become_local_master_stage2: Error - cannot find \
345 workgroup %s on subnet %s\n", registered_name->name, subrec->subnet_name));
349 if((servrec = find_server_in_workgroup( work, global_myname)) == NULL)
351 DEBUG(0,("become_local_master_stage2: Error - cannot find server %s \
352 in workgroup %s on subnet %s\n",
353 global_myname, registered_name->name, subrec->subnet_name));
354 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
358 DEBUG(3,("become_local_master_stage2: registered as master browser for workgroup %s \
359 on subnet %s\n", work->work_group, subrec->subnet_name));
361 work->mst_state = MST_BROWSER; /* registering WORKGROUP(1d) succeeded */
363 /* update our server status */
364 servrec->serv.type |= SV_TYPE_MASTER_BROWSER;
365 servrec->serv.type &= ~SV_TYPE_POTENTIAL_BROWSER;
367 /* Tell the namelist writer to write out a change. */
368 subrec->work_changed = True;
370 /* Add this name to the workgroup as local master browser. */
371 set_workgroup_local_master_browser_name( work, global_myname);
373 /* Count the number of servers we have on our list. If it's
374 less than 10 (just a heuristic) request the servers
375 to announce themselves.
377 for( sl = work->serverlist; sl != NULL; sl = sl->next)
382 /* Ask all servers on our local net to announce to us. */
383 broadcast_announce_request(subrec, work);
387 * Now we are a local master on a broadcast subnet, we need to add
388 * the WORKGROUP<1d> name to the unicast subnet so that we can answer
389 * unicast requests sent to this name. We can create this name directly on
390 * the unicast subnet as a WINS server always returns true when registering
391 * this name, and discards the registration. We use the number of IP
392 * addresses registered to this name as a reference count, as we
393 * remove this broadcast subnet IP address from it when we stop becoming a local
394 * master browser for this broadcast subnet.
397 insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
399 /* Reset the announce master browser timer so that we try and tell a domain
400 master browser as soon as possible that we are a local master browser. */
401 reset_announce_timer();
405 dbgtext( "*****\n\n" );
406 dbgtext( "Samba name server %s ", global_myname );
407 dbgtext( "is now a local master browser " );
408 dbgtext( "for workgroup %s ", work->work_group );
409 dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
414 /****************************************************************************
415 Failed to register the WORKGROUP<1d> name.
416 ****************************************************************************/
417 static void become_local_master_fail2(struct subnet_record *subrec,
418 struct response_record *rrec,
419 struct nmb_name *fail_name)
421 struct work_record *work = find_workgroup_on_subnet( subrec, fail_name->name);
423 DEBUG(0,("become_local_master_fail2: failed to register name %s on subnet %s. \
424 Failed to become a local master browser.\n", nmb_namestr(fail_name), subrec->subnet_name));
428 DEBUG(0,("become_local_master_fail2: Error - cannot find \
429 workgroup %s on subnet %s\n", fail_name->name, subrec->subnet_name));
433 /* Roll back all the way by calling unbecome_local_master_browser(). */
434 unbecome_local_master_browser(subrec, work, False);
437 /****************************************************************************
438 Success in registering the MSBROWSE name.
439 ****************************************************************************/
441 static void become_local_master_stage1(struct subnet_record *subrec,
442 struct userdata_struct *userdata,
443 struct nmb_name *registered_name,
445 int ttl, struct in_addr registered_ip)
447 char *work_name = userdata->data;
448 struct work_record *work = find_workgroup_on_subnet( subrec, work_name);
452 DEBUG(0,("become_local_master_stage1: Error - cannot find \
453 workgroup %s on subnet %s\n", work_name, subrec->subnet_name));
457 DEBUG(3,("become_local_master_stage1: go to stage 2: register the %s<1d> name.\n",
460 work->mst_state = MST_MSB; /* Registering MSBROWSE was successful. */
463 * We registered the MSBROWSE name on a broadcast subnet, now need to add
464 * the MSBROWSE name to the unicast subnet so that we can answer
465 * unicast requests sent to this name. We create this name directly on
466 * the unicast subnet.
469 insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
471 /* Attempt to register the WORKGROUP<1d> name. */
472 register_name(subrec, work->work_group,0x1d,samba_nb_type,
473 become_local_master_stage2,
474 become_local_master_fail2,
478 /****************************************************************************
479 Failed to register the MSBROWSE name.
480 ****************************************************************************/
482 static void become_local_master_fail1(struct subnet_record *subrec,
483 struct response_record *rrec,
484 struct nmb_name *fail_name)
486 char *work_name = rrec->userdata->data;
487 struct work_record *work = find_workgroup_on_subnet(subrec, work_name);
491 DEBUG(0,("become_local_master_fail1: Error - cannot find \
492 workgroup %s on subnet %s\n", work_name, subrec->subnet_name));
496 if(find_server_in_workgroup(work, global_myname) == NULL)
498 DEBUG(0,("become_local_master_fail1: Error - cannot find server %s \
499 in workgroup %s on subnet %s\n",
500 global_myname, work->work_group, subrec->subnet_name));
504 reset_workgroup_state( subrec, work->work_group, False );
506 DEBUG(0,("become_local_master_fail1: Failed to become a local master browser for \
507 workgroup %s on subnet %s. Couldn't register name %s.\n",
508 work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));
511 /******************************************************************
512 Become the local master browser on a subnet.
513 This gets called if we win an election on this subnet.
515 Stage 1: mst_state was MST_POTENTIAL - go to MST_BACK register ^1^2__MSBROWSE__^2^1.
516 Stage 2: mst_state was MST_BACKUP - go to MST_MSB and register WORKGROUP<1d>.
517 Stage 3: mst_state was MST_MSB - go to MST_BROWSER.
518 ******************************************************************/
520 void become_local_master_browser(struct subnet_record *subrec, struct work_record *work)
522 struct userdata_struct *userdata;
523 int size = sizeof(struct userdata_struct) + sizeof(fstring) + 1;
526 if (!lp_local_master())
528 DEBUG(0,("become_local_master_browser: Samba not configured as a local master browser.\n"));
532 if(!AM_POTENTIAL_MASTER_BROWSER(work))
534 DEBUG(2,("become_local_master_browser: Awaiting potential browser state. Current state is %d\n",
539 if(find_server_in_workgroup( work, global_myname) == NULL)
541 DEBUG(0,("become_local_master_browser: Error - cannot find server %s \
542 in workgroup %s on subnet %s\n",
543 global_myname, work->work_group, subrec->subnet_name));
547 DEBUG(2,("become_local_master_browser: Starting to become a master browser for workgroup \
548 %s on subnet %s\n", work->work_group, subrec->subnet_name));
550 DEBUG(3,("become_local_master_browser: first stage - attempt to register ^1^2__MSBROWSE__^2^1\n"));
551 work->mst_state = MST_BACKUP; /* an election win was successful */
553 work->ElectionCriterion |= 0x5;
555 /* Tell the namelist writer to write out a change. */
556 subrec->work_changed = True;
558 /* Setup the userdata_struct. */
559 if((userdata = (struct userdata_struct *)malloc(size)) == NULL)
561 DEBUG(0,("become_local_master_browser: malloc fail.\n"));
565 userdata->copy_fn = NULL;
566 userdata->free_fn = NULL;
567 userdata->userdata_len = strlen(work->work_group)+1;
568 pstrcpy(userdata->data, work->work_group);
570 /* Register the special browser group name. */
571 register_name(subrec, MSBROWSE, 0x01, samba_nb_type|NB_GROUP,
572 become_local_master_stage1,
573 become_local_master_fail1,
576 zero_free(userdata, size);
579 /***************************************************************
580 Utility function to set the local master browser name. Does
581 some sanity checking as old versions of Samba seem to sometimes
582 say that the master browser name for a workgroup is the same
583 as the workgroup name.
584 ****************************************************************/
586 void set_workgroup_local_master_browser_name( struct work_record *work, char *newname)
588 DEBUG(5,("set_workgroup_local_master_browser_name: setting local master name to '%s' \
589 for workgroup %s.\n", newname, work->work_group ));
593 * Apparently some sites use the workgroup name as the local
594 * master browser name. Arrrrggghhhhh ! (JRA).
596 if(strequal( work->work_group, newname))
598 DEBUG(5, ("set_workgroup_local_master_browser_name: Refusing to set \
599 local_master_browser_name for workgroup %s to workgroup name.\n",
605 StrnCpy(work->local_master_browser_name, newname,
606 sizeof(work->local_master_browser_name)-1);