From 7950c5e87082f4292780b0b1571c5111b291e39e Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Thu, 24 Jul 1997 20:39:30 +0000 Subject: nameserv.c: split add_domain_names() into three functions: add_domain_logon_names() - adds <1c> names on WINS and broadcast. add_domain_master_wins() - adds <1b> name only with WINS server add_domain_master_bcast() - adds <1b> names only by bcast. : made add_domain_names() add <1c> names, unconditionally, and add <1b> name with the WINS server if using a WINS server, or add <1b> name by broadcast if _not_ using a WINS server, but _not_ both. : removed the direct parameter from remove_name_entry() and add_my_name_entry(). nameelect.c: made become_domain_master(), on successful registration of the <1b> name with the WINS server, go ahead and register the <1b> names by broadcast. if the <1b> name is _not_ successfully registered with the WINS server, the broadcast registration of <1b> names will _not_ proceed. namedbsubnet.c: sorted out calls to add_my_name_entry() and remove_my_name() which no longer has a direct parameter. this is all added because... in order to fix a compatibility bug with 1.9.16p2->p11, jeremy had added a feature that got the <1b> broadcast registered names _directly_ into the nmbd netbios lists, undefended. the aim was to get round the aggressive netbios registration of <1b> names of 1.9.16p2->p11. however, because 1.9.16p2->p11 don't properly _provide_ netlogon services, it is better that an error message appears in 1.9.17 logs, and that administrators are made aware of the problems with 1.9.16p2->p11, and replace 1.9.16p2->p11 servers, rather than attempt to run 1.9.16 alonside 1.9.17. (these warning messages will need to be added...) in _addition_, they shouldn't _be_ getting two samba servers to provide domain logon / domain master services for the same workgroup in the same WINS scope! lkcl (This used to be commit 5a668ff7ba83433b5eaa9f7d03a42573ee26caf9) --- source3/nameserv.c | 286 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 173 insertions(+), 113 deletions(-) (limited to 'source3/nameserv.c') diff --git a/source3/nameserv.c b/source3/nameserv.c index f1b34482c8..abad9b28c2 100644 --- a/source3/nameserv.c +++ b/source3/nameserv.c @@ -51,12 +51,8 @@ extern uint16 nb_type; /* samba's NetBIOS type */ note: the name will _always_ be removed XXXX at present, the name is removed _even_ if a WINS server says keep it. - If direct is True then the name being removed must have been a direct name - add. This is done for special names such as DOMAIN<1b>. Just delete it - without any network release traffic. - ****************************************************************************/ -void remove_name_entry(struct subnet_record *d, char *name,int type, BOOL direct) +void remove_name_entry(struct subnet_record *d, char *name,int type) { /* XXXX BUG: if samba is offering WINS support, it should still broadcast a de-registration packet to the local subnet before removing the @@ -101,7 +97,7 @@ void remove_name_entry(struct subnet_record *d, char *name,int type, BOOL direct if (ip_equal(d->bcast_ip, wins_ip)) { - if (!lp_wins_support() && !direct) + if (!lp_wins_support()) { /* not a WINS server: we have to release them on the network */ queue_netbios_pkt_wins(ClientNMB,NMB_REL,NAME_RELEASE, @@ -111,7 +107,6 @@ void remove_name_entry(struct subnet_record *d, char *name,int type, BOOL direct } else { - if(!direct) /* local interface: release them on the network */ queue_netbios_packet(d,ClientNMB,NMB_REL,NAME_RELEASE, name, type, 0, 0,0,NULL,NULL, @@ -122,16 +117,12 @@ void remove_name_entry(struct subnet_record *d, char *name,int type, BOOL direct /**************************************************************************** add an entry to the name list - If the direct BOOL is set then no network traffic is done for the add - it - is just blasted into the subnet entry with a zero TTL - it will not - expire and has not been legitimately claimed. This is *only* done if - we are a WINS server or for a special name such as DOMAIN<1b>. big note: our name will _always_ be added (if there are no objections). it's just a matter of when this will be done (e.g after a time-out). ****************************************************************************/ -void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags, BOOL direct) +void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags) { BOOL re_reg = False; struct nmb_name n; @@ -151,13 +142,13 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags, if (ip_equal(d->bcast_ip, wins_ip)) { - if (lp_wins_support() || direct) + if (lp_wins_support()) { /* we are a WINS server. */ if(lp_wins_support()) + { DEBUG(4,("add_my_name_entry: samba as WINS server adding: ")); - else - DEBUG(4,("add_my_name_entry: direct name entry : adding: ")); + } /* this will call add_netbios_entry() */ name_register_work(d, name, type, nb_flags,0, ipzero, False); @@ -176,27 +167,153 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags, } else { - if(direct) - { - /* Just enter the name to be the ip address of the subnet - via name_register_work to ensure all side effects are done. - */ - DEBUG(4,("add_my_name_entry: direct name entry : adding: ")); - /* this will call add_netbios_entry() */ - name_register_work(d, name, type, nb_flags,0, d->myip, False); - } - else - { - /* broadcast the packet, but it comes from ipzero */ - queue_netbios_packet(d,ClientNMB, + /* broadcast the packet, but it comes from ipzero */ + queue_netbios_packet(d,ClientNMB, re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER, name, type, nb_flags, GET_TTL(0),0,NULL,NULL, True, False, d->bcast_ip, ipzero); - } } } +/**************************************************************************** + add the internet group <1c> domain logon names by wins unicast and broadcast. + ****************************************************************************/ +void add_domain_logon_names(void) +{ + struct subnet_record *d; + + if (!lp_domain_logons()) return; + + for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d)) + { + struct work_record *work = find_workgroupstruct(d, myworkgroup, True); + + if (work && work->log_state == LOGON_NONE) + { + struct nmb_name n; + make_nmb_name(&n,myworkgroup,0x1c,scope); + + if (!find_name(d->namelist, &n, FIND_SELF)) + { + /* logon servers are group names. don't expect failure */ + + DEBUG(0,("%s attempting to become logon server for %s %s\n", + timestring(), myworkgroup, inet_ntoa(d->bcast_ip))); + + become_logon_server(d, work); + } + } + } +} + + +/**************************************************************************** + add the <1b> domain master names by broadcast. + ****************************************************************************/ +void add_domain_master_bcast(void) +{ + struct subnet_record *d; + + if (!lp_domain_master()) return; + + for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d)) + { + struct work_record *work = find_workgroupstruct(d, myworkgroup, True); + + if (work && work->dom_state == DOMAIN_NONE) + { + struct nmb_name n; + make_nmb_name(&n,myworkgroup,0x1b,scope); + + if (!find_name(d->namelist, &n, FIND_SELF)) + { + DEBUG(0,("%s add_domain_names: attempting to become domain \ +master browser on workgroup %s %s\n", + timestring(), myworkgroup, inet_ntoa(d->bcast_ip))); + + /* send out a query to establish whether there's a + domain controller on the local subnet. if not, + we can become a domain controller. it's only + polite that we check, before claiming the + NetBIOS name 0x1b. + */ + + DEBUG(0,("add_domain_names:querying subnet %s \ +for domain master on workgroup %s\n", + inet_ntoa(d->bcast_ip), myworkgroup)); + + queue_netbios_packet(d,ClientNMB,NMB_QUERY, + NAME_QUERY_DOMAIN, + myworkgroup, 0x1b, + 0, 0,0,NULL,NULL, + True, False, + d->bcast_ip, d->bcast_ip); + } + } + } +} + + +/**************************************************************************** + add the <1b> domain master name by wins unicast. + ****************************************************************************/ +void add_domain_master_wins(void) +{ + struct work_record *work; + + if (!lp_domain_master() || wins_subnet == NULL) return; + + work = find_workgroupstruct(wins_subnet, myworkgroup, True); + + if (work && work->dom_state == DOMAIN_NONE) + { + struct nmb_name n; + make_nmb_name(&n,myworkgroup,0x1b,scope); + + if (!find_name(wins_subnet->namelist, &n, FIND_SELF)) + { + DEBUG(0,("%s add_domain_names: attempting to become domain \ +master browser on workgroup %s %s\n", + timestring(), myworkgroup, inet_ntoa(wins_subnet->bcast_ip))); + + if (lp_wins_support()) + { + /* use the wins server's capabilities (indirectly). if + someone has already registered the domain<1b> + name with the WINS server, then the WINS + server's job is to _check_ that the owner still + wants it, before giving it away. + */ + + DEBUG(1,("%s initiate become domain master for %s\n", + timestring(), myworkgroup)); + + become_domain_master(wins_subnet, work); + } + else + { + /* send out a query to establish whether there's a + domain controller on the WINS subnet. if not, + we can become a domain controller. it's only + polite that we check, before claiming the + NetBIOS name 0x1b. + */ + + DEBUG(0,("add_domain_names:querying WINS \ +for domain master on workgroup %s\n", myworkgroup)); + + queue_netbios_pkt_wins(ClientNMB,NMB_QUERY, + NAME_QUERY_DOMAIN, + myworkgroup, 0x1b, + 0, 0,0,NULL,NULL, + False, True, ipzero, ipzero); + } + } + } +} + + /**************************************************************************** add the domain logon server and domain master browser names @@ -207,90 +324,33 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags, **************************************************************************/ void add_domain_names(time_t t) { - static time_t lastrun = 0; - struct subnet_record *d; - struct work_record *work; - struct nmb_name n; + static time_t lastrun = 0; - if (lastrun != 0 && t < lastrun + CHECK_TIME_ADD_DOM_NAMES * 60) return; - lastrun = t; + if (lastrun != 0 && t < lastrun + CHECK_TIME_ADD_DOM_NAMES * 60) return; + lastrun = t; - for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d)) - { - work = find_workgroupstruct(d, myworkgroup, False); - if (lp_domain_logons() && work && work->log_state == LOGON_NONE) - { - make_nmb_name(&n,myworkgroup,0x1c,scope); - if (!find_name(d->namelist, &n, FIND_SELF)) - { - /* logon servers are group names - we don't expect this to fail. */ - DEBUG(0,("%s attempting to become logon server for %s %s\n", - timestring(), myworkgroup, inet_ntoa(d->bcast_ip))); - become_logon_server(d, work); - } - } - } + /* do the "internet group" - <1c> names */ + add_domain_logon_names(); - for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d)) - { - work = find_workgroupstruct(d, myworkgroup, True); + /* do the domain master names */ + if (wins_subnet != NULL) + { + /* if the registration of the <1b> name is successful, then + add_domain_master_bcast() will be called. this will + result in domain logon services being gracefully provided, + as opposed to the aggressive nature of 1.9.16p2 to 1.9.16p11. - if (lp_domain_master() && work && work->dom_state == DOMAIN_NONE) - { - make_nmb_name(&n,myworkgroup,0x1b,scope); - if (!find_name(d->namelist, &n, FIND_SELF)) - { - DEBUG(0,("%s add_domain_names: attempting to become domain master \ -browser on workgroup %s %s\n", - timestring(), myworkgroup, inet_ntoa(d->bcast_ip))); - - if(d == wins_subnet) - { - if (lp_wins_support()) - { - /* use the wins server's capabilities (indirectly). if - someone has already registered the domain<1b> name with - the WINS server, then the WINS server's job is to _check_ - that the owner still wants it, before giving it away. - */ - - DEBUG(1,("%s initiating becoming domain master for %s\n", - timestring(), myworkgroup)); - become_domain_master(d, work); - } - else - { - /* send out a query to establish whether there's a - domain controller on the WINS subnet. if not, - we can become a domain controller. - it's only polite that we check, before claiming the - NetBIOS name 0x1b. - */ - - DEBUG(0,("add_domain_names:querying WINS for domain master \ -on workgroup %s\n", myworkgroup)); - - queue_netbios_pkt_wins(ClientNMB,NMB_QUERY,NAME_QUERY_DOMAIN, - myworkgroup, 0x1b, - 0, 0,0,NULL,NULL, - False, True, ipzero, ipzero); - } - } - else - { - DEBUG(0,("add_domain_names:querying subnet %s for domain master \ -on workgroup %s\n", inet_ntoa(d->bcast_ip), myworkgroup)); - queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_DOMAIN, - myworkgroup, 0x1b, - 0, 0,0,NULL,NULL, - True, False, - d->bcast_ip, d->bcast_ip); - } - } - } - } -} + which, due to a bug in namelogon.c from 1.9.16p2 to 1.9.16p11 + cannot _provide_ domain master / domain logon services!!! + */ + add_domain_master_wins(); + } + else + { + add_domain_master_bcast(); + } +} /**************************************************************************** add the magic samba names, useful for finding samba servers @@ -308,9 +368,9 @@ void add_my_names(void) { BOOL wins = (lp_wins_support() && (d == wins_subnet)); - add_my_name_entry(d, myname,0x20,nb_type|NB_ACTIVE,False); - add_my_name_entry(d, myname,0x03,nb_type|NB_ACTIVE,False); - add_my_name_entry(d, myname,0x00,nb_type|NB_ACTIVE,False); + add_my_name_entry(d, myname,0x20,nb_type|NB_ACTIVE); + add_my_name_entry(d, myname,0x03,nb_type|NB_ACTIVE); + add_my_name_entry(d, myname,0x00,nb_type|NB_ACTIVE); /* these names are added permanently (ttl of zero) and will NOT be refreshed with the WINS server */ @@ -341,7 +401,7 @@ void remove_my_names() /* get all SELF names removed from the WINS server's database */ /* XXXX note: problem occurs if this removes the wrong one! */ - remove_name_entry(d,n->name.name, n->name.name_type,False); + remove_name_entry(d,n->name.name, n->name.name_type); } } } @@ -366,7 +426,7 @@ void refresh_my_names(time_t t) n->death_time != 0) { add_my_name_entry(d,n->name.name,n->name.name_type, - n->ip_flgs[0].nb_flags,False); + n->ip_flgs[0].nb_flags); /* they get a new lease on life :-) */ n->death_time += GET_TTL(0); n->refresh_time += GET_TTL(0); -- cgit