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 uint16 samba_nb_type; /* Samba's NetBIOS name type. */
28 /*******************************************************************
29 Utility function to add a name to the unicast subnet, or add in
30 our IP address if it already exists.
31 ******************************************************************/
33 void insert_permanent_name_into_unicast( struct subnet_record *subrec,
34 struct nmb_name *nmbname, uint16 nb_type )
36 struct name_record *namerec;
38 if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL)
40 /* The name needs to be created on the unicast subnet. */
41 (void)add_name_to_subnet( unicast_subnet, nmbname->name,
42 nmbname->name_type, nb_type,
43 PERMANENT_TTL, PERMANENT_NAME, 1, &subrec->myip);
47 /* The name already exists on the unicast subnet. Add our local
48 IP for the given broadcast subnet to the name. */
49 add_ip_to_name_record( namerec, subrec->myip);
53 /*******************************************************************
54 Utility function to remove a name from the unicast subnet.
55 ******************************************************************/
57 static void remove_permanent_name_from_unicast( struct subnet_record *subrec,
58 struct nmb_name *nmbname )
60 struct name_record *namerec;
62 if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) != NULL)
64 /* Remove this broadcast subnet IP address from the name. */
65 remove_ip_from_name_record( namerec, subrec->myip);
66 if(namerec->data.num_ips == 0)
67 remove_name_from_namelist( unicast_subnet, namerec);
71 /*******************************************************************
72 Utility function always called to set our workgroup and server
73 state back to potential browser, or none.
74 ******************************************************************/
76 static void reset_workgroup_state( struct subnet_record *subrec, char *workgroup_name,
77 BOOL force_new_election )
79 struct work_record *work;
80 struct server_record *servrec;
81 struct nmb_name nmbname;
83 if((work = find_workgroup_on_subnet( subrec, workgroup_name)) == NULL)
85 DEBUG(0,("reset_workgroup_state: Error - cannot find workgroup %s on \
86 subnet %s.\n", workgroup_name, subrec->subnet_name ));
90 if((servrec = find_server_in_workgroup( work, global_myname())) == NULL)
92 DEBUG(0,("reset_workgroup_state: Error - cannot find server %s \
93 in workgroup %s on subnet %s\n",
94 global_myname(), work->work_group, subrec->subnet_name));
95 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
99 /* Update our server status - remove any master flag and replace
100 it with the potential browser flag. */
101 servrec->serv.type &= ~SV_TYPE_MASTER_BROWSER;
102 servrec->serv.type |= (lp_local_master() ? SV_TYPE_POTENTIAL_BROWSER : 0);
104 /* Tell the namelist writer to write out a change. */
105 subrec->work_changed = True;
107 /* Reset our election flags. */
108 work->ElectionCriterion &= ~0x4;
110 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
112 /* Forget who the local master browser was for
115 set_workgroup_local_master_browser_name( work, "");
118 * Ensure the IP address of this subnet is not registered as one
119 * of the IP addresses of the WORKGROUP<1d> name on the unicast
120 * subnet. This undoes what we did below when we became a local
124 make_nmb_name(&nmbname, work->work_group, 0x1d);
126 remove_permanent_name_from_unicast( subrec, &nmbname);
128 if(force_new_election)
129 work->needelection = True;
132 /*******************************************************************
133 Unbecome the local master browser name release success function.
134 ******************************************************************/
136 static void unbecome_local_master_success(struct subnet_record *subrec,
137 struct userdata_struct *userdata,
138 struct nmb_name *released_name,
139 struct in_addr released_ip)
141 BOOL force_new_election = False;
143 memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL));
145 DEBUG(3,("unbecome_local_master_success: released name %s.\n",
146 nmb_namestr(released_name)));
148 /* Now reset the workgroup and server state. */
149 reset_workgroup_state( subrec, released_name->name, force_new_election );
153 dbgtext( "*****\n\n" );
154 dbgtext( "Samba name server %s ", global_myname() );
155 dbgtext( "has stopped being a local master browser " );
156 dbgtext( "for workgroup %s ", released_name->name );
157 dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
162 /*******************************************************************
163 Unbecome the local master browser name release fail function.
164 ******************************************************************/
166 static void unbecome_local_master_fail(struct subnet_record *subrec, struct response_record *rrec,
167 struct nmb_name *fail_name)
169 struct name_record *namerec;
170 struct userdata_struct *userdata = rrec->userdata;
171 BOOL force_new_election = False;
173 memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL));
175 DEBUG(0,("unbecome_local_master_fail: failed to release name %s. \
176 Removing from namelist anyway.\n", nmb_namestr(fail_name)));
179 namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
181 remove_name_from_namelist(subrec, namerec);
183 /* Now reset the workgroup and server state. */
184 reset_workgroup_state( subrec, fail_name->name, force_new_election );
188 dbgtext( "*****\n\n" );
189 dbgtext( "Samba name server %s ", global_myname() );
190 dbgtext( "has stopped being a local master browser " );
191 dbgtext( "for workgroup %s ", fail_name->name );
192 dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
196 /*******************************************************************
197 Utility function to remove the WORKGROUP<1d> name.
198 ******************************************************************/
200 static void release_1d_name( struct subnet_record *subrec, char *workgroup_name,
201 BOOL force_new_election)
203 struct nmb_name nmbname;
204 struct name_record *namerec;
206 make_nmb_name(&nmbname, workgroup_name, 0x1d);
207 if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL)
209 struct userdata_struct *userdata;
210 int size = sizeof(struct userdata_struct) + sizeof(BOOL);
212 if((userdata = (struct userdata_struct *)malloc(size)) == NULL)
214 DEBUG(0,("release_1d_name: malloc fail.\n"));
218 userdata->copy_fn = NULL;
219 userdata->free_fn = NULL;
220 userdata->userdata_len = sizeof(BOOL);
221 memcpy((char *)userdata->data, &force_new_election, sizeof(BOOL));
223 release_name(subrec, namerec,
224 unbecome_local_master_success,
225 unbecome_local_master_fail,
228 zero_free(userdata, size);
232 /*******************************************************************
233 Unbecome the local master browser MSBROWSE name release success function.
234 ******************************************************************/
236 static void release_msbrowse_name_success(struct subnet_record *subrec,
237 struct userdata_struct *userdata,
238 struct nmb_name *released_name,
239 struct in_addr released_ip)
241 DEBUG(4,("release_msbrowse_name_success: Released name %s on subnet %s\n.",
242 nmb_namestr(released_name), subrec->subnet_name ));
244 /* Remove the permanent MSBROWSE name added into the unicast subnet. */
245 remove_permanent_name_from_unicast( subrec, released_name);
248 /*******************************************************************
249 Unbecome the local master browser MSBROWSE name release fail function.
250 ******************************************************************/
252 static void release_msbrowse_name_fail( struct subnet_record *subrec,
253 struct response_record *rrec,
254 struct nmb_name *fail_name)
256 struct name_record *namerec;
258 DEBUG(4,("release_msbrowse_name_fail: Failed to release name %s on subnet %s\n.",
259 nmb_namestr(fail_name), subrec->subnet_name ));
261 /* Release the name anyway. */
262 namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
264 remove_name_from_namelist(subrec, namerec);
266 /* Remove the permanent MSBROWSE name added into the unicast subnet. */
267 remove_permanent_name_from_unicast( subrec, fail_name);
270 /*******************************************************************
271 Unbecome the local master browser. If force_new_election is true, restart
272 the election process after we've unbecome the local master.
273 ******************************************************************/
275 void unbecome_local_master_browser(struct subnet_record *subrec, struct work_record *work,
276 BOOL force_new_election)
278 struct name_record *namerec;
279 struct nmb_name nmbname;
283 DEBUG(2,("unbecome_local_master_browser: unbecoming local master for workgroup %s \
284 on subnet %s\n",work->work_group, subrec->subnet_name));
286 if(find_server_in_workgroup( work, global_myname()) == NULL)
288 DEBUG(0,("unbecome_local_master_browser: Error - cannot find server %s \
289 in workgroup %s on subnet %s\n",
290 global_myname(), work->work_group, subrec->subnet_name));
291 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
295 /* Set the state to unbecoming. */
296 work->mst_state = MST_UNBECOMING_MASTER;
299 * Release the WORKGROUP<1d> name asap to allow another machine to
303 release_1d_name( subrec, work->work_group, force_new_election);
305 /* Deregister any browser names we may have. */
306 make_nmb_name(&nmbname, MSBROWSE, 0x1);
307 if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL)
309 release_name(subrec, namerec,
310 release_msbrowse_name_success,
311 release_msbrowse_name_fail,
316 * Ensure we have sent and processed these release packets
317 * before returning - we don't want to process any election
318 * packets before dealing with the 1d release.
321 retransmit_or_expire_response_records(time(NULL));
324 /****************************************************************************
325 Success in registering the WORKGROUP<1d> name.
326 We are now *really* a local master browser.
327 ****************************************************************************/
329 static void become_local_master_stage2(struct subnet_record *subrec,
330 struct userdata_struct *userdata,
331 struct nmb_name *registered_name,
333 int ttl, struct in_addr registered_ip)
336 struct server_record *sl;
337 struct work_record *work = find_workgroup_on_subnet( subrec, registered_name->name);
338 struct server_record *servrec;
342 DEBUG(0,("become_local_master_stage2: Error - cannot find \
343 workgroup %s on subnet %s\n", registered_name->name, subrec->subnet_name));
347 if((servrec = find_server_in_workgroup( work, global_myname())) == NULL)
349 DEBUG(0,("become_local_master_stage2: Error - cannot find server %s \
350 in workgroup %s on subnet %s\n",
351 global_myname(), registered_name->name, subrec->subnet_name));
352 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
356 DEBUG(3,("become_local_master_stage2: registered as master browser for workgroup %s \
357 on subnet %s\n", work->work_group, subrec->subnet_name));
359 work->mst_state = MST_BROWSER; /* registering WORKGROUP(1d) succeeded */
361 /* update our server status */
362 servrec->serv.type |= SV_TYPE_MASTER_BROWSER;
363 servrec->serv.type &= ~SV_TYPE_POTENTIAL_BROWSER;
365 /* Tell the namelist writer to write out a change. */
366 subrec->work_changed = True;
368 /* Add this name to the workgroup as local master browser. */
369 set_workgroup_local_master_browser_name( work, global_myname());
371 /* Count the number of servers we have on our list. If it's
372 less than 10 (just a heuristic) request the servers
373 to announce themselves.
375 for( sl = work->serverlist; sl != NULL; sl = sl->next)
380 /* Ask all servers on our local net to announce to us. */
381 broadcast_announce_request(subrec, work);
385 * Now we are a local master on a broadcast subnet, we need to add
386 * the WORKGROUP<1d> name to the unicast subnet so that we can answer
387 * unicast requests sent to this name. We can create this name directly on
388 * the unicast subnet as a WINS server always returns true when registering
389 * this name, and discards the registration. We use the number of IP
390 * addresses registered to this name as a reference count, as we
391 * remove this broadcast subnet IP address from it when we stop becoming a local
392 * master browser for this broadcast subnet.
395 insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
397 /* Reset the announce master browser timer so that we try and tell a domain
398 master browser as soon as possible that we are a local master browser. */
399 reset_announce_timer();
403 dbgtext( "*****\n\n" );
404 dbgtext( "Samba name server %s ", global_myname() );
405 dbgtext( "is now a local master browser " );
406 dbgtext( "for workgroup %s ", work->work_group );
407 dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
412 /****************************************************************************
413 Failed to register the WORKGROUP<1d> name.
414 ****************************************************************************/
415 static void become_local_master_fail2(struct subnet_record *subrec,
416 struct response_record *rrec,
417 struct nmb_name *fail_name)
419 struct work_record *work = find_workgroup_on_subnet( subrec, fail_name->name);
421 DEBUG(0,("become_local_master_fail2: failed to register name %s on subnet %s. \
422 Failed to become a local master browser.\n", nmb_namestr(fail_name), subrec->subnet_name));
426 DEBUG(0,("become_local_master_fail2: Error - cannot find \
427 workgroup %s on subnet %s\n", fail_name->name, subrec->subnet_name));
431 /* Roll back all the way by calling unbecome_local_master_browser(). */
432 unbecome_local_master_browser(subrec, work, False);
435 /****************************************************************************
436 Success in registering the MSBROWSE name.
437 ****************************************************************************/
439 static void become_local_master_stage1(struct subnet_record *subrec,
440 struct userdata_struct *userdata,
441 struct nmb_name *registered_name,
443 int ttl, struct in_addr registered_ip)
445 char *work_name = userdata->data;
446 struct work_record *work = find_workgroup_on_subnet( subrec, work_name);
450 DEBUG(0,("become_local_master_stage1: Error - cannot find \
451 workgroup %s on subnet %s\n", work_name, subrec->subnet_name));
455 DEBUG(3,("become_local_master_stage1: go to stage 2: register the %s<1d> name.\n",
458 work->mst_state = MST_MSB; /* Registering MSBROWSE was successful. */
461 * We registered the MSBROWSE name on a broadcast subnet, now need to add
462 * the MSBROWSE name to the unicast subnet so that we can answer
463 * unicast requests sent to this name. We create this name directly on
464 * the unicast subnet.
467 insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
469 /* Attempt to register the WORKGROUP<1d> name. */
470 register_name(subrec, work->work_group,0x1d,samba_nb_type,
471 become_local_master_stage2,
472 become_local_master_fail2,
476 /****************************************************************************
477 Failed to register the MSBROWSE name.
478 ****************************************************************************/
480 static void become_local_master_fail1(struct subnet_record *subrec,
481 struct response_record *rrec,
482 struct nmb_name *fail_name)
484 char *work_name = rrec->userdata->data;
485 struct work_record *work = find_workgroup_on_subnet(subrec, work_name);
489 DEBUG(0,("become_local_master_fail1: Error - cannot find \
490 workgroup %s on subnet %s\n", work_name, subrec->subnet_name));
494 if(find_server_in_workgroup(work, global_myname()) == NULL)
496 DEBUG(0,("become_local_master_fail1: Error - cannot find server %s \
497 in workgroup %s on subnet %s\n",
498 global_myname(), work->work_group, subrec->subnet_name));
502 reset_workgroup_state( subrec, work->work_group, False );
504 DEBUG(0,("become_local_master_fail1: Failed to become a local master browser for \
505 workgroup %s on subnet %s. Couldn't register name %s.\n",
506 work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));
509 /******************************************************************
510 Become the local master browser on a subnet.
511 This gets called if we win an election on this subnet.
513 Stage 1: mst_state was MST_POTENTIAL - go to MST_BACK register ^1^2__MSBROWSE__^2^1.
514 Stage 2: mst_state was MST_BACKUP - go to MST_MSB and register WORKGROUP<1d>.
515 Stage 3: mst_state was MST_MSB - go to MST_BROWSER.
516 ******************************************************************/
518 void become_local_master_browser(struct subnet_record *subrec, struct work_record *work)
520 struct userdata_struct *userdata;
521 int size = sizeof(struct userdata_struct) + sizeof(fstring) + 1;
524 if (!lp_local_master())
526 DEBUG(0,("become_local_master_browser: Samba not configured as a local master browser.\n"));
530 if(!AM_POTENTIAL_MASTER_BROWSER(work))
532 DEBUG(2,("become_local_master_browser: Awaiting potential browser state. Current state is %d\n",
537 if(find_server_in_workgroup( work, global_myname()) == NULL)
539 DEBUG(0,("become_local_master_browser: Error - cannot find server %s \
540 in workgroup %s on subnet %s\n",
541 global_myname(), work->work_group, subrec->subnet_name));
545 DEBUG(2,("become_local_master_browser: Starting to become a master browser for workgroup \
546 %s on subnet %s\n", work->work_group, subrec->subnet_name));
548 DEBUG(3,("become_local_master_browser: first stage - attempt to register ^1^2__MSBROWSE__^2^1\n"));
549 work->mst_state = MST_BACKUP; /* an election win was successful */
551 work->ElectionCriterion |= 0x5;
553 /* Tell the namelist writer to write out a change. */
554 subrec->work_changed = True;
556 /* Setup the userdata_struct. */
557 if((userdata = (struct userdata_struct *)malloc(size)) == NULL)
559 DEBUG(0,("become_local_master_browser: malloc fail.\n"));
563 userdata->copy_fn = NULL;
564 userdata->free_fn = NULL;
565 userdata->userdata_len = strlen(work->work_group)+1;
566 fstrcpy(userdata->data, work->work_group);
568 /* Register the special browser group name. */
569 register_name(subrec, MSBROWSE, 0x01, samba_nb_type|NB_GROUP,
570 become_local_master_stage1,
571 become_local_master_fail1,
574 zero_free(userdata, size);
577 /***************************************************************
578 Utility function to set the local master browser name. Does
579 some sanity checking as old versions of Samba seem to sometimes
580 say that the master browser name for a workgroup is the same
581 as the workgroup name.
582 ****************************************************************/
584 void set_workgroup_local_master_browser_name( struct work_record *work, const char *newname)
586 DEBUG(5,("set_workgroup_local_master_browser_name: setting local master name to '%s' \
587 for workgroup %s.\n", newname, work->work_group ));
591 * Apparently some sites use the workgroup name as the local
592 * master browser name. Arrrrggghhhhh ! (JRA).
594 if(strequal( work->work_group, newname))
596 DEBUG(5, ("set_workgroup_local_master_browser_name: Refusing to set \
597 local_master_browser_name for workgroup %s to workgroup name.\n",
603 StrnCpy(work->local_master_browser_name, newname,
604 sizeof(work->local_master_browser_name)-1);