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

Generated by: LCOV version 1.14