LCOV - code coverage report
Current view: top level - source3/nmbd - nmbd_become_lmb.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 61 184 33.2 %
Date: 2021-09-23 10:06:22 Functions: 5 15 33.3 %

          Line data    Source code
       1             : /* 
       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-2003
       7             :    
       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 3 of the License, or
      11             :    (at your option) any later version.
      12             :    
      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.
      17             :    
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             :    
      21             : */
      22             : 
      23             : #include "includes.h"
      24             : #include "nmbd/nmbd.h"
      25             : #include "../librpc/gen_ndr/svcctl.h"
      26             : #include "lib/util/string_wrappers.h"
      27             : 
      28             : extern uint16_t samba_nb_type; /* Samba's NetBIOS name type. */
      29             : 
      30             : /*******************************************************************
      31             :  Utility function to add a name to the unicast subnet, or add in
      32             :  our IP address if it already exists.
      33             : ******************************************************************/
      34             : 
      35         230 : void insert_permanent_name_into_unicast( struct subnet_record *subrec, 
      36             :                                                 struct nmb_name *nmbname, uint16_t nb_type )
      37             : {
      38             :         unstring name;
      39             :         struct name_record *namerec;
      40             : 
      41         230 :         if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL) {
      42         230 :                 pull_ascii_nstring(name, sizeof(name), nmbname->name);
      43             :                 /* The name needs to be created on the unicast subnet. */
      44         421 :                 (void)add_name_to_subnet( unicast_subnet, name,
      45         230 :                                 nmbname->name_type, nb_type,
      46             :                                 PERMANENT_TTL, PERMANENT_NAME, 1, &subrec->myip);
      47             :         } else {
      48             :                 /* The name already exists on the unicast subnet. Add our local
      49             :                 IP for the given broadcast subnet to the name. */
      50           0 :                 add_ip_to_name_record( namerec, subrec->myip);
      51             :         }
      52         230 : }
      53             : 
      54             : /*******************************************************************
      55             :  Utility function to remove a name from the unicast subnet.
      56             : ******************************************************************/
      57             : 
      58           0 : static void remove_permanent_name_from_unicast( struct subnet_record *subrec,
      59             :                                                 struct nmb_name *nmbname )
      60             : {
      61             :         struct name_record *namerec;
      62             : 
      63           0 :         if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) != NULL) {
      64             :                 /* Remove this broadcast subnet IP address from the name. */
      65           0 :                 remove_ip_from_name_record( namerec, subrec->myip);
      66           0 :                 if(namerec->data.num_ips == 0)
      67           0 :                         remove_name_from_namelist( unicast_subnet, namerec);
      68             :         }
      69           0 : }
      70             : 
      71             : /*******************************************************************
      72             :  Utility function always called to set our workgroup and server
      73             :  state back to potential browser, or none.
      74             : ******************************************************************/
      75             : 
      76           0 : static void reset_workgroup_state( struct subnet_record *subrec, const char *workgroup_name,
      77             :                                    bool force_new_election )
      78             : {
      79             :         struct work_record *work;
      80             :         struct server_record *servrec;
      81             :         struct nmb_name nmbname;
      82             : 
      83           0 :         if((work = find_workgroup_on_subnet( subrec, workgroup_name)) == NULL) {
      84           0 :                 DEBUG(0,("reset_workgroup_state: Error - cannot find workgroup %s on \
      85             : subnet %s.\n", workgroup_name, subrec->subnet_name ));
      86           0 :                 return;
      87             :         }
      88             : 
      89           0 :         if((servrec = find_server_in_workgroup( work, lp_netbios_name())) == NULL) {
      90           0 :                 DEBUG(0,("reset_workgroup_state: Error - cannot find server %s \
      91             : in workgroup %s on subnet %s\n",
      92             :                         lp_netbios_name(), work->work_group, subrec->subnet_name));
      93           0 :                 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
      94           0 :                 return;
      95             :         }
      96             : 
      97             :         /* Update our server status - remove any master flag and replace
      98             :                 it with the potential browser flag. */
      99           0 :         servrec->serv.type &= ~SV_TYPE_MASTER_BROWSER;
     100           0 :         servrec->serv.type |= (lp_local_master() ? SV_TYPE_POTENTIAL_BROWSER : 0);
     101             : 
     102             :         /* Tell the namelist writer to write out a change. */
     103           0 :         subrec->work_changed = True;
     104             : 
     105             :         /* Reset our election flags. */
     106           0 :         work->ElectionCriterion &= ~0x4;
     107             : 
     108           0 :         work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
     109             : 
     110             :         /* Forget who the local master browser was for
     111             :                 this workgroup. */
     112             : 
     113           0 :         set_workgroup_local_master_browser_name( work, "");
     114             : 
     115             :         /*
     116             :          * Ensure the IP address of this subnet is not registered as one
     117             :          * of the IP addresses of the WORKGROUP<1d> name on the unicast
     118             :          * subnet. This undoes what we did below when we became a local
     119             :          * master browser.
     120             :          */
     121             : 
     122           0 :         make_nmb_name(&nmbname, work->work_group, 0x1d);
     123             : 
     124           0 :         remove_permanent_name_from_unicast( subrec, &nmbname);
     125             : 
     126           0 :         if(force_new_election)
     127           0 :                 work->needelection = True;
     128             : }
     129             : 
     130             : /*******************************************************************
     131             :   Unbecome the local master browser name release success function.
     132             : ******************************************************************/
     133             : 
     134           0 : static void unbecome_local_master_success(struct subnet_record *subrec,
     135             :                              struct userdata_struct *userdata,
     136             :                              struct nmb_name *released_name,
     137             :                              struct in_addr released_ip)
     138             : { 
     139           0 :         bool force_new_election = False;
     140             :         unstring relname;
     141             : 
     142           0 :         memcpy((char *)&force_new_election, userdata->data, sizeof(bool));
     143             : 
     144           0 :         DEBUG(3,("unbecome_local_master_success: released name %s.\n",
     145             :                 nmb_namestr(released_name)));
     146             : 
     147             :         /* Now reset the workgroup and server state. */
     148           0 :         pull_ascii_nstring(relname, sizeof(relname), released_name->name);
     149           0 :         reset_workgroup_state( subrec, relname, force_new_election );
     150             : 
     151           0 :         if( DEBUGLVL( 0 ) ) {
     152           0 :                 dbgtext( "*****\n\n" );
     153           0 :                 dbgtext( "Samba name server %s ", lp_netbios_name() );
     154           0 :                 dbgtext( "has stopped being a local master browser " );
     155           0 :                 dbgtext( "for workgroup %s ", relname );
     156           0 :                 dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
     157             :         }
     158             : 
     159           0 : }
     160             : 
     161             : /*******************************************************************
     162             :   Unbecome the local master browser name release fail function.
     163             : ******************************************************************/
     164             : 
     165           0 : static void unbecome_local_master_fail(struct subnet_record *subrec, struct response_record *rrec,
     166             :                        struct nmb_name *fail_name)
     167             : {
     168             :         struct name_record *namerec;
     169           0 :         struct userdata_struct *userdata = rrec->userdata;
     170           0 :         bool force_new_election = False;
     171             :         unstring failname;
     172             : 
     173           0 :         memcpy((char *)&force_new_election, userdata->data, sizeof(bool));
     174             : 
     175           0 :         DEBUG(0,("unbecome_local_master_fail: failed to release name %s. \
     176             : Removing from namelist anyway.\n", nmb_namestr(fail_name)));
     177             : 
     178             :         /* Do it anyway. */
     179           0 :         namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
     180           0 :         if(namerec)
     181           0 :                 remove_name_from_namelist(subrec, namerec);
     182             : 
     183             :         /* Now reset the workgroup and server state. */
     184           0 :         pull_ascii_nstring(failname, sizeof(failname), fail_name->name);
     185           0 :         reset_workgroup_state( subrec, failname, force_new_election );
     186             : 
     187           0 :         if( DEBUGLVL( 0 ) ) {
     188           0 :                 dbgtext( "*****\n\n" );
     189           0 :                 dbgtext( "Samba name server %s ", lp_netbios_name() );
     190           0 :                 dbgtext( "has stopped being a local master browser " );
     191           0 :                 dbgtext( "for workgroup %s ", failname );
     192           0 :                 dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
     193             :         }
     194           0 : }
     195             : 
     196             : /*******************************************************************
     197             :  Utility function to remove the WORKGROUP<1d> name.
     198             : ******************************************************************/
     199             : 
     200           0 : static void release_1d_name( struct subnet_record *subrec, const char *workgroup_name,
     201             :                              bool force_new_election)
     202             : {
     203             :         struct nmb_name nmbname;
     204             :         struct name_record *namerec;
     205             : 
     206           0 :         make_nmb_name(&nmbname, workgroup_name, 0x1d);
     207           0 :         if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL) {
     208             :                 struct userdata_struct *userdata;
     209           0 :                 size_t size = sizeof(struct userdata_struct) + sizeof(bool);
     210             : 
     211           0 :                 if((userdata = (struct userdata_struct *)SMB_MALLOC(size)) == NULL) {
     212           0 :                         DEBUG(0,("release_1d_name: malloc fail.\n"));
     213           0 :                         return;
     214             :                 }
     215             : 
     216           0 :                 userdata->copy_fn = NULL;
     217           0 :                 userdata->free_fn = NULL;
     218           0 :                 userdata->userdata_len = sizeof(bool);
     219           0 :                 memcpy((char *)userdata->data, &force_new_election, sizeof(bool));
     220             : 
     221           0 :                 release_name(subrec, namerec,
     222             :                         unbecome_local_master_success,
     223             :                         unbecome_local_master_fail,
     224             :                         userdata);
     225             : 
     226           0 :                 zero_free(userdata, size);
     227             :         }
     228             : }
     229             : 
     230             : /*******************************************************************
     231             :  Unbecome the local master browser MSBROWSE name release success function.
     232             : ******************************************************************/
     233             : 
     234           0 : static void release_msbrowse_name_success(struct subnet_record *subrec,
     235             :                       struct userdata_struct *userdata,
     236             :                       struct nmb_name *released_name,
     237             :                       struct in_addr released_ip)
     238             : {
     239           0 :         DEBUG(4,("release_msbrowse_name_success: Released name %s on subnet %s\n.",
     240             :                 nmb_namestr(released_name), subrec->subnet_name ));
     241             : 
     242             :         /* Remove the permanent MSBROWSE name added into the unicast subnet. */
     243           0 :         remove_permanent_name_from_unicast( subrec, released_name);
     244           0 : }
     245             : 
     246             : /*******************************************************************
     247             :  Unbecome the local master browser MSBROWSE name release fail function.
     248             : ******************************************************************/
     249             : 
     250           0 : static void release_msbrowse_name_fail( struct subnet_record *subrec, 
     251             :                        struct response_record *rrec,
     252             :                        struct nmb_name *fail_name)
     253             : {
     254             :         struct name_record *namerec;
     255             : 
     256           0 :         DEBUG(4,("release_msbrowse_name_fail: Failed to release name %s on subnet %s\n.",
     257             :                 nmb_namestr(fail_name), subrec->subnet_name ));
     258             : 
     259             :         /* Release the name anyway. */
     260           0 :         namerec = find_name_on_subnet(subrec, fail_name, FIND_SELF_NAME);
     261           0 :         if(namerec)
     262           0 :                 remove_name_from_namelist(subrec, namerec);
     263             : 
     264             :         /* Remove the permanent MSBROWSE name added into the unicast subnet. */
     265           0 :         remove_permanent_name_from_unicast( subrec, fail_name);
     266           0 : }
     267             : 
     268             : /*******************************************************************
     269             :   Unbecome the local master browser. If force_new_election is true, restart
     270             :   the election process after we've unbecome the local master.
     271             : ******************************************************************/
     272             : 
     273           0 : void unbecome_local_master_browser(struct subnet_record *subrec, struct work_record *work,
     274             :                                    bool force_new_election)
     275             : {
     276             :         struct name_record *namerec;
     277             :         struct nmb_name nmbname;
     278             : 
     279             :   /* Sanity check. */
     280             : 
     281           0 :         DEBUG(2,("unbecome_local_master_browser: unbecoming local master for workgroup %s \
     282             : on subnet %s\n",work->work_group, subrec->subnet_name));
     283             :   
     284           0 :         if(find_server_in_workgroup( work, lp_netbios_name()) == NULL) {
     285           0 :                 DEBUG(0,("unbecome_local_master_browser: Error - cannot find server %s \
     286             : in workgroup %s on subnet %s\n",
     287             :                         lp_netbios_name(), work->work_group, subrec->subnet_name));
     288           0 :                         work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
     289           0 :                 return;
     290             :         }
     291             :   
     292             :         /* Set the state to unbecoming. */
     293           0 :         work->mst_state = MST_UNBECOMING_MASTER;
     294             : 
     295             :         /*
     296             :          * Release the WORKGROUP<1d> name asap to allow another machine to
     297             :          * claim it.
     298             :          */
     299             : 
     300           0 :         release_1d_name( subrec, work->work_group, force_new_election);
     301             : 
     302             :         /* Deregister any browser names we may have. */
     303           0 :         make_nmb_name(&nmbname, MSBROWSE, 0x1);
     304           0 :         if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL) {
     305           0 :                 release_name(subrec, namerec,
     306             :                         release_msbrowse_name_success,
     307             :                         release_msbrowse_name_fail,
     308             :                         NULL);
     309             :         }
     310             : 
     311             :         /*
     312             :          * Ensure we have sent and processed these release packets
     313             :          * before returning - we don't want to process any election
     314             :          * packets before dealing with the 1d release.
     315             :          */
     316             : 
     317           0 :         retransmit_or_expire_response_records(time(NULL));
     318             : }
     319             : 
     320             : /****************************************************************************
     321             :   Success in registering the WORKGROUP<1d> name.
     322             :   We are now *really* a local master browser.
     323             :   ****************************************************************************/
     324             : 
     325          19 : static void become_local_master_stage2(struct subnet_record *subrec,
     326             :                                         struct userdata_struct *userdata,
     327             :                                         struct nmb_name *registered_name,
     328             :                                         uint16_t nb_flags,
     329             :                                         int ttl, struct in_addr registered_ip)
     330             : {
     331          19 :         int i = 0;
     332             :         struct server_record *sl;
     333             :         struct work_record *work;
     334             :         struct server_record *servrec;
     335             :         unstring regname;
     336             : 
     337          19 :         pull_ascii_nstring(regname, sizeof(regname), registered_name->name);
     338          19 :         work = find_workgroup_on_subnet( subrec, regname);
     339             : 
     340          19 :         if(!work) {
     341           0 :                 DEBUG(0,("become_local_master_stage2: Error - cannot find \
     342             : workgroup %s on subnet %s\n", regname, subrec->subnet_name));
     343           0 :                 return;
     344             :         }
     345             : 
     346          19 :         if((servrec = find_server_in_workgroup( work, lp_netbios_name())) == NULL) {
     347           0 :                 DEBUG(0,("become_local_master_stage2: Error - cannot find server %s \
     348             : in workgroup %s on subnet %s\n",
     349             :                         lp_netbios_name(), regname, subrec->subnet_name));
     350           0 :                         work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE;
     351           0 :                 return;
     352             :         }
     353             :   
     354          19 :         DEBUG(3,("become_local_master_stage2: registered as master browser for workgroup %s \
     355             : on subnet %s\n", work->work_group, subrec->subnet_name));
     356             : 
     357          19 :         work->mst_state = MST_BROWSER; /* registering WORKGROUP(1d) succeeded */
     358             : 
     359             :         /* update our server status */
     360          19 :         servrec->serv.type |= SV_TYPE_MASTER_BROWSER;
     361          19 :         servrec->serv.type &= ~SV_TYPE_POTENTIAL_BROWSER;
     362             : 
     363             :         /* Tell the namelist writer to write out a change. */
     364          19 :         subrec->work_changed = True;
     365             : 
     366             :         /* Add this name to the workgroup as local master browser. */
     367          19 :         set_workgroup_local_master_browser_name( work, lp_netbios_name());
     368             : 
     369             :         /* Count the number of servers we have on our list. If it's
     370             :                 less than 10 (just a heuristic) request the servers
     371             :                 to announce themselves.
     372             :         */
     373          42 :         for( sl = work->serverlist; sl != NULL; sl = sl->next)
     374          23 :                 i++;
     375             : 
     376          19 :         if (i < 10) {
     377             :                 /* Ask all servers on our local net to announce to us. */
     378          19 :                 broadcast_announce_request(subrec, work);
     379             :         }
     380             : 
     381             :         /*
     382             :          * Now we are a local master on a broadcast subnet, we need to add
     383             :          * the WORKGROUP<1d> name to the unicast subnet so that we can answer
     384             :          * unicast requests sent to this name. We can create this name directly on
     385             :          * the unicast subnet as a WINS server always returns true when registering
     386             :          * this name, and discards the registration. We use the number of IP
     387             :          * addresses registered to this name as a reference count, as we
     388             :          * remove this broadcast subnet IP address from it when we stop becoming a local
     389             :          * master browser for this broadcast subnet.
     390             :          */
     391             : 
     392          19 :         insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
     393             : 
     394             :         /* Reset the announce master browser timer so that we try and tell a domain
     395             :                 master browser as soon as possible that we are a local master browser. */
     396          19 :         reset_announce_timer();
     397             : 
     398          19 :         if( DEBUGLVL( 0 ) ) {
     399          19 :                 dbgtext( "*****\n\n" );
     400          19 :                 dbgtext( "Samba name server %s ", lp_netbios_name() );
     401          19 :                 dbgtext( "is now a local master browser " );
     402          19 :                 dbgtext( "for workgroup %s ", work->work_group );
     403          19 :                 dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name );
     404             :         }
     405             : }
     406             : 
     407             : /****************************************************************************
     408             :   Failed to register the WORKGROUP<1d> name.
     409             :   ****************************************************************************/
     410             : 
     411           0 : static void become_local_master_fail2(struct subnet_record *subrec,
     412             :                                       struct response_record *rrec,
     413             :                                       struct nmb_name *fail_name)
     414             : {
     415             :         unstring failname;
     416             :         struct work_record *work;
     417             : 
     418           0 :         DEBUG(0,("become_local_master_fail2: failed to register name %s on subnet %s. \
     419             : Failed to become a local master browser.\n", nmb_namestr(fail_name), subrec->subnet_name));
     420             : 
     421           0 :         pull_ascii_nstring(failname, sizeof(failname), fail_name->name);
     422           0 :         work = find_workgroup_on_subnet( subrec, failname);
     423             : 
     424           0 :         if(!work) {
     425           0 :                 DEBUG(0,("become_local_master_fail2: Error - cannot find \
     426             : workgroup %s on subnet %s\n", failname, subrec->subnet_name));
     427           0 :                 return;
     428             :         }
     429             : 
     430             :         /* Roll back all the way by calling unbecome_local_master_browser(). */
     431           0 :         unbecome_local_master_browser(subrec, work, False);
     432             : }
     433             : 
     434             : /****************************************************************************
     435             :   Success in registering the MSBROWSE name.
     436             :   ****************************************************************************/
     437             : 
     438          20 : static void become_local_master_stage1(struct subnet_record *subrec,
     439             :                                         struct userdata_struct *userdata,
     440             :                                         struct nmb_name *registered_name,
     441             :                                         uint16_t nb_flags,
     442             :                                         int ttl, struct in_addr registered_ip)
     443             : {
     444          20 :         char *work_name = userdata->data;
     445          20 :         struct work_record *work = find_workgroup_on_subnet( subrec, work_name);
     446             : 
     447          20 :         if(!work) {
     448           0 :                 DEBUG(0,("become_local_master_stage1: Error - cannot find \
     449             :                         %s on subnet %s\n", work_name, subrec->subnet_name));
     450           0 :                 return;
     451             :         }
     452             : 
     453          20 :         DEBUG(3,("become_local_master_stage1: go to stage 2: register the %s<1d> name.\n",
     454             :                 work->work_group));
     455             : 
     456          20 :         work->mst_state = MST_MSB; /* Registering MSBROWSE was successful. */
     457             : 
     458             :         /*
     459             :          * We registered the MSBROWSE name on a broadcast subnet, now need to add
     460             :          * the MSBROWSE name to the unicast subnet so that we can answer
     461             :          * unicast requests sent to this name. We create this name directly on
     462             :          * the unicast subnet.
     463             :          */
     464             : 
     465          20 :         insert_permanent_name_into_unicast( subrec, registered_name, nb_flags);
     466             : 
     467             :         /* Attempt to register the WORKGROUP<1d> name. */
     468          20 :         register_name(subrec, work->work_group,0x1d,samba_nb_type,
     469             :                 become_local_master_stage2,
     470             :                 become_local_master_fail2,
     471             :                 NULL);
     472             : }
     473             : 
     474             : /****************************************************************************
     475             :   Failed to register the MSBROWSE name.
     476             :   ****************************************************************************/
     477             : 
     478           0 : static void become_local_master_fail1(struct subnet_record *subrec,
     479             :                                       struct response_record *rrec,
     480             :                                       struct nmb_name *fail_name)
     481             : {
     482           0 :         char *work_name = rrec->userdata->data;
     483           0 :         struct work_record *work = find_workgroup_on_subnet(subrec, work_name);
     484             : 
     485           0 :         if(!work) {
     486           0 :                 DEBUG(0,("become_local_master_fail1: Error - cannot find \
     487             : workgroup %s on subnet %s\n", work_name, subrec->subnet_name));
     488           0 :                 return;
     489             :         }
     490             : 
     491           0 :         if(find_server_in_workgroup(work, lp_netbios_name()) == NULL) {
     492           0 :                 DEBUG(0,("become_local_master_fail1: Error - cannot find server %s \
     493             : in workgroup %s on subnet %s\n",
     494             :                         lp_netbios_name(), work->work_group, subrec->subnet_name));
     495           0 :                 return;
     496             :         }
     497             : 
     498           0 :         reset_workgroup_state( subrec, work->work_group, False );
     499             : 
     500           0 :         DEBUG(0,("become_local_master_fail1: Failed to become a local master browser for \
     501             : workgroup %s on subnet %s. Couldn't register name %s.\n",
     502             :                 work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));
     503             : }
     504             : 
     505             : /******************************************************************
     506             :   Become the local master browser on a subnet.
     507             :   This gets called if we win an election on this subnet.
     508             : 
     509             :   Stage 1: mst_state was MST_POTENTIAL - go to MST_BACK register ^1^2__MSBROWSE__^2^1.
     510             :   Stage 2: mst_state was MST_BACKUP  - go to MST_MSB  and register WORKGROUP<1d>.
     511             :   Stage 3: mst_state was MST_MSB  - go to MST_BROWSER.
     512             : ******************************************************************/
     513             : 
     514          24 : void become_local_master_browser(struct subnet_record *subrec, struct work_record *work)
     515             : {
     516             :         struct userdata_struct *userdata;
     517          24 :         size_t size = sizeof(struct userdata_struct) + sizeof(fstring) + 1;
     518             : 
     519             :         /* Sanity check. */
     520          24 :         if (!lp_local_master()) { 
     521           0 :                 DEBUG(0,("become_local_master_browser: Samba not configured as a local master browser.\n"));
     522           0 :                 return;
     523             :         }
     524             : 
     525          24 :         if(!AM_POTENTIAL_MASTER_BROWSER(work)) {
     526           4 :                 DEBUG(2,("become_local_master_browser: Awaiting potential browser state. Current state is %d\n",
     527             :                         work->mst_state ));
     528           4 :                 return;
     529             :         }
     530             : 
     531          20 :         if(find_server_in_workgroup( work, lp_netbios_name()) == NULL) {
     532           0 :                 DEBUG(0,("become_local_master_browser: Error - cannot find server %s \
     533             : in workgroup %s on subnet %s\n",
     534             :                         lp_netbios_name(), work->work_group, subrec->subnet_name));
     535           0 :                 return;
     536             :         }
     537             : 
     538          20 :         DEBUG(2,("become_local_master_browser: Starting to become a master browser for workgroup \
     539             : %s on subnet %s\n", work->work_group, subrec->subnet_name));
     540             :   
     541          20 :         DEBUG(3,("become_local_master_browser: first stage - attempt to register ^1^2__MSBROWSE__^2^1\n"));
     542          20 :         work->mst_state = MST_BACKUP; /* an election win was successful */
     543             : 
     544          20 :         work->ElectionCriterion |= 0x5;
     545             : 
     546             :         /* Tell the namelist writer to write out a change. */
     547          20 :         subrec->work_changed = True;
     548             : 
     549             :         /* Setup the userdata_struct. */
     550          20 :         if((userdata = (struct userdata_struct *)SMB_MALLOC(size)) == NULL) {
     551           0 :                 DEBUG(0,("become_local_master_browser: malloc fail.\n"));
     552           0 :                 return;
     553             :         }
     554             : 
     555          20 :         userdata->copy_fn = NULL;
     556          20 :         userdata->free_fn = NULL;
     557          20 :         userdata->userdata_len = strlen(work->work_group)+1;
     558          20 :         strlcpy(userdata->data, work->work_group, size - sizeof(*userdata));
     559             : 
     560             :         /* Register the special browser group name. */
     561          20 :         register_name(subrec, MSBROWSE, 0x01, samba_nb_type|NB_GROUP,
     562             :                 become_local_master_stage1,
     563             :                 become_local_master_fail1,
     564             :                 userdata);
     565             : 
     566          20 :         zero_free(userdata, size);
     567             : }
     568             : 
     569             : /***************************************************************
     570             :  Utility function to set the local master browser name. Does
     571             :  some sanity checking as old versions of Samba seem to sometimes
     572             :  say that the master browser name for a workgroup is the same
     573             :  as the workgroup name.
     574             : ****************************************************************/
     575             : 
     576          55 : void set_workgroup_local_master_browser_name( struct work_record *work, const char *newname)
     577             : {
     578          55 :         DEBUG(5,("set_workgroup_local_master_browser_name: setting local master name to '%s' \
     579             : for workgroup %s.\n", newname, work->work_group ));
     580             : 
     581             : #if 0
     582             :   /*
     583             :    * Apparently some sites use the workgroup name as the local
     584             :    * master browser name. Arrrrggghhhhh ! (JRA).
     585             :    */
     586             :   if(strequal( work->work_group, newname))
     587             :   {
     588             :     DEBUG(5, ("set_workgroup_local_master_browser_name: Refusing to set \
     589             : local_master_browser_name for workgroup %s to workgroup name.\n",
     590             :          work->work_group ));
     591             :     return;
     592             :   }
     593             : #endif
     594             : 
     595          55 :         unstrcpy(work->local_master_browser_name, newname);
     596          55 : }

Generated by: LCOV version 1.13