nmbd_become_lmb.c
来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 595 行 · 第 1/2 页
C
595 行
/* Deregister any browser names we may have. */ make_nmb_name(&nmbname, MSBROWSE, 0x1); if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL) { release_name(subrec, namerec, release_msbrowse_name_success, release_msbrowse_name_fail, NULL); } /* * Ensure we have sent and processed these release packets * before returning - we don't want to process any election * packets before dealing with the 1d release. */ retransmit_or_expire_response_records(time(NULL));}/**************************************************************************** Success in registering the WORKGROUP<1d> name. We are now *really* a local master browser. ****************************************************************************/static void become_local_master_stage2(struct subnet_record *subrec, struct userdata_struct *userdata, struct nmb_name *registered_name, uint16 nb_flags, int ttl, struct in_addr registered_ip){ int i = 0; struct server_record *sl; struct work_record *work; struct server_record *servrec; unstring regname; pull_ascii_nstring(regname, sizeof(regname), registered_name->name); work = find_workgroup_on_subnet( subrec, regname); if(!work) { DEBUG(0,("become_local_master_stage2: Error - cannot find \workgroup %s on subnet %s\n", regname, subrec->subnet_name)); return; } if((servrec = find_server_in_workgroup( work, global_myname())) == NULL) { DEBUG(0,("become_local_master_stage2: Error - cannot find server %s \in workgroup %s on subnet %s\n", global_myname(), regname, subrec->subnet_name)); work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE; return; } DEBUG(3,("become_local_master_stage2: registered as master browser for workgroup %s \on subnet %s\n", work->work_group, subrec->subnet_name)); work->mst_state = MST_BROWSER; /* registering WORKGROUP(1d) succeeded */ /* update our server status */ servrec->serv.type |= SV_TYPE_MASTER_BROWSER; servrec->serv.type &= ~SV_TYPE_POTENTIAL_BROWSER; /* Tell the namelist writer to write out a change. */ subrec->work_changed = True; /* Add this name to the workgroup as local master browser. */ set_workgroup_local_master_browser_name( work, global_myname()); /* Count the number of servers we have on our list. If it's less than 10 (just a heuristic) request the servers to announce themselves. */ for( sl = work->serverlist; sl != NULL; sl = sl->next) i++; if (i < 10) { /* Ask all servers on our local net to announce to us. */ broadcast_announce_request(subrec, work); } /* * Now we are a local master on a broadcast subnet, we need to add * the WORKGROUP<1d> name to the unicast subnet so that we can answer * unicast requests sent to this name. We can create this name directly on * the unicast subnet as a WINS server always returns true when registering * this name, and discards the registration. We use the number of IP * addresses registered to this name as a reference count, as we * remove this broadcast subnet IP address from it when we stop becoming a local * master browser for this broadcast subnet. */ insert_permanent_name_into_unicast( subrec, registered_name, nb_flags); /* Reset the announce master browser timer so that we try and tell a domain master browser as soon as possible that we are a local master browser. */ reset_announce_timer(); if( DEBUGLVL( 0 ) ) { dbgtext( "*****\n\n" ); dbgtext( "Samba name server %s ", global_myname() ); dbgtext( "is now a local master browser " ); dbgtext( "for workgroup %s ", work->work_group ); dbgtext( "on subnet %s\n\n*****\n", subrec->subnet_name ); }}/**************************************************************************** Failed to register the WORKGROUP<1d> name. ****************************************************************************/static void become_local_master_fail2(struct subnet_record *subrec, struct response_record *rrec, struct nmb_name *fail_name){ unstring failname; struct work_record *work; DEBUG(0,("become_local_master_fail2: failed to register name %s on subnet %s. \Failed to become a local master browser.\n", nmb_namestr(fail_name), subrec->subnet_name)); pull_ascii_nstring(failname, sizeof(failname), fail_name->name); work = find_workgroup_on_subnet( subrec, failname); if(!work) { DEBUG(0,("become_local_master_fail2: Error - cannot find \workgroup %s on subnet %s\n", failname, subrec->subnet_name)); return; } /* Roll back all the way by calling unbecome_local_master_browser(). */ unbecome_local_master_browser(subrec, work, False);}/**************************************************************************** Success in registering the MSBROWSE name. ****************************************************************************/static void become_local_master_stage1(struct subnet_record *subrec, struct userdata_struct *userdata, struct nmb_name *registered_name, uint16 nb_flags, int ttl, struct in_addr registered_ip){ char *work_name = userdata->data; struct work_record *work = find_workgroup_on_subnet( subrec, work_name); if(!work) { DEBUG(0,("become_local_master_stage1: Error - cannot find \ %s on subnet %s\n", work_name, subrec->subnet_name)); return; } DEBUG(3,("become_local_master_stage1: go to stage 2: register the %s<1d> name.\n", work->work_group)); work->mst_state = MST_MSB; /* Registering MSBROWSE was successful. */ /* * We registered the MSBROWSE name on a broadcast subnet, now need to add * the MSBROWSE name to the unicast subnet so that we can answer * unicast requests sent to this name. We create this name directly on * the unicast subnet. */ insert_permanent_name_into_unicast( subrec, registered_name, nb_flags); /* Attempt to register the WORKGROUP<1d> name. */ register_name(subrec, work->work_group,0x1d,samba_nb_type, become_local_master_stage2, become_local_master_fail2, NULL);}/**************************************************************************** Failed to register the MSBROWSE name. ****************************************************************************/static void become_local_master_fail1(struct subnet_record *subrec, struct response_record *rrec, struct nmb_name *fail_name){ char *work_name = rrec->userdata->data; struct work_record *work = find_workgroup_on_subnet(subrec, work_name); if(!work) { DEBUG(0,("become_local_master_fail1: Error - cannot find \workgroup %s on subnet %s\n", work_name, subrec->subnet_name)); return; } if(find_server_in_workgroup(work, global_myname()) == NULL) { DEBUG(0,("become_local_master_fail1: Error - cannot find server %s \in workgroup %s on subnet %s\n", global_myname(), work->work_group, subrec->subnet_name)); return; } reset_workgroup_state( subrec, work->work_group, False ); DEBUG(0,("become_local_master_fail1: Failed to become a local master browser for \workgroup %s on subnet %s. Couldn't register name %s.\n", work->work_group, subrec->subnet_name, nmb_namestr(fail_name)));}/****************************************************************** Become the local master browser on a subnet. This gets called if we win an election on this subnet. Stage 1: mst_state was MST_POTENTIAL - go to MST_BACK register ^1^2__MSBROWSE__^2^1. Stage 2: mst_state was MST_BACKUP - go to MST_MSB and register WORKGROUP<1d>. Stage 3: mst_state was MST_MSB - go to MST_BROWSER.******************************************************************/void become_local_master_browser(struct subnet_record *subrec, struct work_record *work){ struct userdata_struct *userdata; size_t size = sizeof(struct userdata_struct) + sizeof(fstring) + 1; /* Sanity check. */ if (!lp_local_master()) { DEBUG(0,("become_local_master_browser: Samba not configured as a local master browser.\n")); return; } if(!AM_POTENTIAL_MASTER_BROWSER(work)) { DEBUG(2,("become_local_master_browser: Awaiting potential browser state. Current state is %d\n", work->mst_state )); return; } if(find_server_in_workgroup( work, global_myname()) == NULL) { DEBUG(0,("become_local_master_browser: Error - cannot find server %s \in workgroup %s on subnet %s\n", global_myname(), work->work_group, subrec->subnet_name)); return; } DEBUG(2,("become_local_master_browser: Starting to become a master browser for workgroup \%s on subnet %s\n", work->work_group, subrec->subnet_name)); DEBUG(3,("become_local_master_browser: first stage - attempt to register ^1^2__MSBROWSE__^2^1\n")); work->mst_state = MST_BACKUP; /* an election win was successful */ work->ElectionCriterion |= 0x5; /* Tell the namelist writer to write out a change. */ subrec->work_changed = True; /* Setup the userdata_struct. */ if((userdata = (struct userdata_struct *)SMB_MALLOC(size)) == NULL) { DEBUG(0,("become_local_master_browser: malloc fail.\n")); return; } userdata->copy_fn = NULL; userdata->free_fn = NULL; userdata->userdata_len = strlen(work->work_group)+1; overmalloc_safe_strcpy(userdata->data, work->work_group, size - sizeof(*userdata) - 1); /* Register the special browser group name. */ register_name(subrec, MSBROWSE, 0x01, samba_nb_type|NB_GROUP, become_local_master_stage1, become_local_master_fail1, userdata); zero_free(userdata, size);}/*************************************************************** Utility function to set the local master browser name. Does some sanity checking as old versions of Samba seem to sometimes say that the master browser name for a workgroup is the same as the workgroup name.****************************************************************/void set_workgroup_local_master_browser_name( struct work_record *work, const char *newname){ DEBUG(5,("set_workgroup_local_master_browser_name: setting local master name to '%s' \for workgroup %s.\n", newname, work->work_group ));#if 0 /* * Apparently some sites use the workgroup name as the local * master browser name. Arrrrggghhhhh ! (JRA). */ if(strequal( work->work_group, newname)) { DEBUG(5, ("set_workgroup_local_master_browser_name: Refusing to set \local_master_browser_name for workgroup %s to workgroup name.\n", work->work_group )); return; }#endif unstrcpy(work->local_master_browser_name, newname);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?