diff options
Diffstat (limited to 'source3/nameelect.c')
-rw-r--r-- | source3/nameelect.c | 248 |
1 files changed, 126 insertions, 122 deletions
diff --git a/source3/nameelect.c b/source3/nameelect.c index 02fda9f817..82cebd3e6c 100644 --- a/source3/nameelect.c +++ b/source3/nameelect.c @@ -40,6 +40,7 @@ extern int DEBUGLEVEL; extern pstring scope; extern pstring myname; +extern fstring myworkgroup; extern struct in_addr ipzero; extern struct in_addr wins_ip; @@ -57,55 +58,59 @@ extern uint16 nb_type; /* samba's NetBIOS name type */ ******************************************************************/ void check_master_browser(time_t t) { - static time_t lastrun=0; - struct subnet_record *d; + static time_t lastrun=0; + struct subnet_record *d; - if (!lastrun) lastrun = t; - if (t < lastrun + CHECK_TIME_MST_BROWSE * 60) return; + if (!lastrun) lastrun = t; + if (t < lastrun + CHECK_TIME_MST_BROWSE * 60) return; - lastrun = t; + lastrun = t; - dump_workgroups(); + dump_workgroups(); - for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d)) - { - struct work_record *work; + for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d)) + { + struct work_record *work; - for (work = d->workgrouplist; work; work = work->next) - { - if (strequal(work->work_group, lp_workgroup()) && !AM_MASTER(work)) - { - if (lp_preferred_master()) - { - /* preferred master - not a master browser. force - becoming a master browser, hence the log message. - */ - - DEBUG(0,("%s preferred master for %s %s - force election\n", - timestring(), work->work_group, - inet_ntoa(d->bcast_ip))); - - browser_gone(work->work_group, d->bcast_ip); - } - else - { - /* if we are not the browse master of a workgroup, - and we can't find a browser on the subnet, do - something about it. - */ - - queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_MST_CHK, - work->work_group,0x1d,0,0,0,NULL,NULL, - True,False,d->bcast_ip,d->bcast_ip); - } - } - } - } + for (work = d->workgrouplist; work; work = work->next) + { + if (strequal(work->work_group, myworkgroup) && !AM_MASTER(work)) + { + if (lp_local_master()) + { + /* potential master browser - not a master browser. force + becoming a master browser, hence the log message. + */ + + DEBUG(0,("%s potential master for %s %s - force election\n", + timestring(), work->work_group, + inet_ntoa(d->bcast_ip))); + + browser_gone(work->work_group, d->bcast_ip); + } + else + { + /* if we are not the browse master of a workgroup, + and we can't find a browser on the subnet, do + something about it. + */ + + queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_MST_CHK, + work->work_group,0x1d,0,0,0,NULL,NULL, + True,False,d->bcast_ip,d->bcast_ip); + } + } + } + } } /******************************************************************* - what to do if a master browser DOESN't exist + what to do if a master browser DOESN't exist. + + option 1: force an election, and participate in it + option 2: force an election, and let everyone else participate. + ******************************************************************/ void browser_gone(char *work_name, struct in_addr ip) { @@ -119,24 +124,37 @@ void browser_gone(char *work_name, struct in_addr ip) if (ip_equal(d->bcast_ip,wins_ip)) return; - if (strequal(work->work_group, lp_workgroup())) + if (strequal(work->work_group, myworkgroup)) { + if (lp_local_master()) + { + /* we have discovered that there is no local master + browser, and we are configured to initiate + an election under exactly such circumstances. + */ DEBUG(2,("Forcing election on %s %s\n", work->work_group,inet_ntoa(d->bcast_ip))); /* we can attempt to become master browser */ work->needelection = True; - } - else - { - /* local interfaces: force an election */ - send_election(d, work->work_group, 0, 0, myname); - - /* only removes workgroup completely on a local interface - persistent lmhosts entries on a local interface _will_ be removed). - */ - remove_workgroup(d, work,True); + } + else + { + /* we need to force an election, because we are configured + not to _become_ the local master, but we still _need_ one, + having detected that one doesn't exist. + */ + + /* local interfaces: force an election */ + send_election(d, work->work_group, 0, 0, myname); + + /* only removes workgroup completely on a local interface + persistent lmhosts entries on a local interface _will_ be removed). + */ + remove_workgroup(d, work,True); + add_workgroup_to_subnet(d, work->work_group); + } } } @@ -199,15 +217,15 @@ void name_unregister_work(struct subnet_record *d, char *name, int name_type) { remove_type_local |= SV_TYPE_MASTER_BROWSER; } - if (AM_MASTER(work) && strequal(name, lp_workgroup()) && name_type == 0x1d) + if (AM_MASTER(work) && strequal(name, myworkgroup) && name_type == 0x1d) { remove_type_local |= SV_TYPE_MASTER_BROWSER; } - if (AM_DOMMST(work) && strequal(name, lp_workgroup()) && name_type == 0x1b) + if (AM_DOMMST(work) && strequal(name, myworkgroup) && name_type == 0x1b) { remove_type_domain |= SV_TYPE_DOMAIN_MASTER; } - if (AM_DOMMEM(work) && strequal(name, lp_workgroup()) && name_type == 0x1c) + if (AM_DOMMEM(work) && strequal(name, myworkgroup) && name_type == 0x1c) { remove_type_logon|= SV_TYPE_DOMAIN_MEMBER; } @@ -228,47 +246,48 @@ void name_unregister_work(struct subnet_record *d, char *name, int name_type) void name_register_work(struct subnet_record *d, char *name, int name_type, int nb_flags, time_t ttl, struct in_addr ip, BOOL bcast) { - enum name_source source = (ismyip(ip) || ip_equal(ip, ipzero)) ? + enum name_source source = (ismyip(ip) || ip_equal(ip, ipzero)) ? SELF : REGISTER; - if (source == SELF) - { - struct work_record *work = find_workgroupstruct(d, lp_workgroup(), False); + if (source == SELF) + { + struct work_record *work = find_workgroupstruct(d, + myworkgroup, False); - add_netbios_entry(d,name,name_type,nb_flags,ttl,source,ip,True,!bcast); + add_netbios_entry(d,name,name_type,nb_flags,ttl,source,ip,True,!bcast); - if (work) - { - int add_type_local = False; - int add_type_domain = False; - int add_type_logon = False; - - DEBUG(4,("checking next stage: name_register_work %s\n", name)); - - /* work out what to become, from the name type being added */ - - if (ms_browser_name(name, name_type)) - { - add_type_local = True; - } - if (strequal(name, lp_workgroup()) && name_type == 0x1d) - { - add_type_local = True; - } - if (strequal(name, lp_workgroup()) && name_type == 0x1b) - { - add_type_domain = True; - } - if (strequal(name, lp_workgroup()) && name_type == 0x1c) - { - add_type_logon = True; - } - - if (add_type_local ) become_local_master (d, work); - if (add_type_domain) become_domain_master(d, work); - if (add_type_logon ) become_logon_server (d, work); - } - } + if (work) + { + int add_type_local = False; + int add_type_domain = False; + int add_type_logon = False; + + DEBUG(4,("checking next stage: name_register_work %s\n", name)); + + /* work out what to become, from the name type being added */ + + if (ms_browser_name(name, name_type)) + { + add_type_local = True; + } + if (strequal(name, myworkgroup) && name_type == 0x1d) + { + add_type_local = True; + } + if (strequal(name, myworkgroup) && name_type == 0x1b) + { + add_type_domain = True; + } + if (strequal(name, myworkgroup) && name_type == 0x1c) + { + add_type_logon = True; + } + + if (add_type_local ) become_local_master (d, work); + if (add_type_domain) become_domain_master(d, work); + if (add_type_logon ) become_logon_server (d, work); + } + } } @@ -303,17 +322,18 @@ void become_local_master(struct subnet_record *d, struct work_record *work) */ uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT; - if (!work || !d) return; + if (!work || !d) + return; DEBUG(2,("Becoming master for %s %s (currently at stage %d)\n", - work->work_group,inet_ntoa(d->bcast_ip),work->mst_state)); + work->work_group,inet_ntoa(d->bcast_ip),work->mst_state)); switch (work->mst_state) { case MST_POTENTIAL: /* while we were nothing but a server... */ { DEBUG(3,("go to first stage: register ^1^2__MSBROWSE__^2^1\n")); - work->mst_state = MST_BACK; /* ... an election win was successful */ + work->mst_state = MST_BACK; /* an election win was successful */ work->ElectionCriterion |= 0x5; @@ -322,7 +342,7 @@ void become_local_master(struct subnet_record *d, struct work_record *work) add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True); /* add special browser name */ - add_my_name_entry(d,MSBROWSE ,0x01,nb_type|NB_ACTIVE|NB_GROUP); + add_my_name_entry(d,MSBROWSE,0x01,nb_type|NB_ACTIVE|NB_GROUP); /* DON'T do anything else after calling add_my_name_entry() */ break; @@ -331,7 +351,7 @@ void become_local_master(struct subnet_record *d, struct work_record *work) case MST_BACK: /* while nothing had happened except we won an election... */ { DEBUG(3,("go to second stage: register as master browser\n")); - work->mst_state = MST_MSB; /* ... registering MSBROWSE was successful */ + work->mst_state = MST_MSB; /* registering MSBROWSE was successful */ /* add server entry on successful registration of MSBROWSE */ add_server_entry(d,work,work->work_group,domain_type,0,myname,True); @@ -346,49 +366,33 @@ void become_local_master(struct subnet_record *d, struct work_record *work) case MST_MSB: /* while we were still only registered MSBROWSE state... */ { DEBUG(3,("2nd stage complete: registered as master browser\n")); - work->mst_state = MST_BROWSER; /* ... registering WORKGROUP(1d) succeeded */ + work->mst_state = MST_BROWSER; /* registering WORKGROUP(1d) succeeded */ /* update our server status */ work->ServerType |= SV_TYPE_MASTER_BROWSER; - DEBUG(3,("become_local_master: updating our server %s to type %x\n", myname, work->ServerType)); + DEBUG(3,("become_local_master: updating our server %s to type %x\n", + myname, work->ServerType)); add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True); if (work->serverlist == NULL) /* no servers! */ { /* ask all servers on our local net to announce to us */ - /* XXXX OOPS! add_server_entry will always add one entry - our own. */ + /* XXXX OOPS! add_server_entry always adds one entry - ours. */ announce_request(work, d->bcast_ip); } - /* If we have WINS support or are a WINS server we must add - the workgroup we just became master browser for to the - WINS subnet. This is needed so we have somewhere to save - server lists when we do browser synchronization. */ - if(wins_subnet != 0) - { - if(find_workgroupstruct(wins_subnet, work->work_group, True) == 0) - DEBUG(0, ("become_local_master: \ -Failed to add workgroup %s to WINS subnet.\n", - work->work_group)); - else - DEBUG(3, ("become_local_master: Added workgroup %s to WINS subnet.\n", - work->work_group)); - - /* Reset the announce master timer so that we do an announce as soon as possible - now we are a master. */ - reset_announce_timer(); - } + /* Reset the announce master timer so that we do an announce as soon as possible + now we are a master. */ + reset_announce_timer(); break; - } case MST_BROWSER: { /* don't have to do anything: just report success */ DEBUG(3,("3rd stage: become master browser!\n")); - break; } } @@ -438,7 +442,7 @@ void become_domain_master(struct subnet_record *d, struct work_record *work) work->dom_state = DOMAIN_WAIT; /* XXXX the 0x1b is domain master browser name */ - add_my_name_entry(d, lp_workgroup(),0x1b,nb_type|NB_ACTIVE|NB_GROUP); + add_my_name_entry(d, myworkgroup,0x1b,nb_type|NB_ACTIVE|NB_GROUP); /* DON'T do anything else after calling add_my_name_entry() */ break; @@ -505,7 +509,7 @@ void become_logon_server(struct subnet_record *d, struct work_record *work) work->log_state = LOGON_WAIT; /* XXXX the 0x1c is apparently something to do with domain logons */ - add_my_name_entry(d, lp_workgroup(),0x1c,nb_type|NB_ACTIVE|NB_GROUP); + add_my_name_entry(d, myworkgroup,0x1c,nb_type|NB_ACTIVE|NB_GROUP); /* DON'T do anything else after calling add_my_name_entry() */ break; @@ -749,7 +753,7 @@ void process_election(struct packet_struct *p,char *buf) for (work = d->workgrouplist; work; work = work->next) { - if (!strequal(work->work_group, lp_workgroup())) + if (!strequal(work->work_group, myworkgroup)) continue; if (win_election(work, version,criterion,timeup,name)) { |