diff options
author | Andrew Tridgell <tridge@samba.org> | 1996-10-02 15:41:30 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 1996-10-02 15:41:30 +0000 |
commit | 45e66a69d320024877c8b13f12b21bf895e04410 (patch) | |
tree | bdf4244d8e22f17764b424dd378350c842c942de /source/namework.c | |
parent | 20b6203dac4bbb43e4e7bea0b214496d76d679d9 (diff) | |
download | samba-45e66a69d320024877c8b13f12b21bf895e04410.tar.gz samba-45e66a69d320024877c8b13f12b21bf895e04410.tar.xz samba-45e66a69d320024877c8b13f12b21bf895e04410.zip |
backout all the changes to nmbd.
The 1.9.16 tree is now back to 1.9.16p2 as far as nmbd is concerned
apart from a small change that fixes the announce type in two places.
Diffstat (limited to 'source/namework.c')
-rw-r--r-- | source/namework.c | 465 |
1 files changed, 231 insertions, 234 deletions
diff --git a/source/namework.c b/source/namework.c index 630f3dea12a..0380c1460af 100644 --- a/source/namework.c +++ b/source/namework.c @@ -23,9 +23,6 @@ 14 jan 96: lkcl@pires.co.uk added multiple workgroup domain master support - 30 July 96: David.Chappell@mail.trincoll.edu - Expanded multiple workgroup domain master browser support. - */ #include "includes.h" @@ -33,34 +30,41 @@ extern int ClientNMB; extern int ClientDGRAM; +#define TEST_CODE /* want to debug unknown browse packets */ + extern int DEBUGLEVEL; extern pstring scope; extern BOOL CanRecurse; +extern pstring myname; + extern int ClientNMB; extern int ClientDGRAM; extern struct in_addr ipzero; +extern int workgroup_count; /* total number of workgroups we know about */ + /* this is our domain/workgroup/server database */ extern struct subnet_record *subnetlist; extern int updatecount; +/* backup request types: which servers are to be included */ +#define MASTER_TYPE (SV_TYPE_MASTER_BROWSER) +#define DOMCTL_TYPE (SV_TYPE_DOMAIN_CTRL ) + extern time_t StartupTime; extern BOOL updatedlists; -extern pstring myname; - - /**************************************************************************** tell a server to become a backup browser state - 0x01 become backup instead of master - 0x02 remove all entries in browse list and become non-master - 0x04 stop master browser service altogether. NT ignores this **************************************************************************/ -void reset_server(struct work_record *work, char *name, int state, struct in_addr ip) +void reset_server(char *name, int state, struct in_addr ip) { char outbuf[20]; char *p; @@ -73,10 +77,10 @@ void reset_server(struct work_record *work, char *name, int state, struct in_add p += 2; DEBUG(2,("sending reset to %s %s of state %d\n", - name,inet_ntoa(ip),state)); + name,inet_ntoa(ip),state)); send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf), - conf_browsing_alias(work->token),name,0x20,0x1d,ip,*iface_ip(ip)); + myname,name,0x20,0x1d,ip,*iface_ip(ip)); } @@ -95,47 +99,47 @@ void tell_become_backup(void) { struct work_record *work; for (work = d->workgrouplist; work; work = work->next) - { - struct server_record *s; - int num_servers = 0; - int num_backups = 0; - - for (s = work->serverlist; s; s = s->next) - { - if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue; - - num_servers++; - - if (strequal(conf_browsing_alias(work->token), s->serv.name)) continue; - - if (s->serv.type & SV_TYPE_BACKUP_BROWSER) { - num_backups++; - continue; - } - - if (s->serv.type & SV_TYPE_MASTER_BROWSER) continue; - - if (!(s->serv.type & SV_TYPE_POTENTIAL_BROWSER)) continue; - - DEBUG(3,("num servers: %d num backups: %d\n", - num_servers, num_backups)); - - /* make first server a backup server. thereafter make every - tenth server a backup server */ - if (num_backups != 0 && (num_servers+9) / num_backups > 10) - { - continue; - } - - DEBUG(2,("sending become backup to %s %s for %s\n", - s->serv.name, inet_ntoa(d->bcast_ip), - work->work_group)); - - /* type 11 request from conf_browsing_alias(work->token)(20) to WG(1e) for SERVER */ - do_announce_request(s->serv.name, s->serv.name, work->work_group, - ANN_BecomeBackup, 0x20, 0x1e, d->bcast_ip); - } - } + { + struct server_record *s; + int num_servers = 0; + int num_backups = 0; + + for (s = work->serverlist; s; s = s->next) + { + if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue; + + num_servers++; + + if (strequal(myname, s->serv.name)) continue; + + if (s->serv.type & SV_TYPE_BACKUP_BROWSER) { + num_backups++; + continue; + } + + if (s->serv.type & SV_TYPE_MASTER_BROWSER) continue; + + if (!(s->serv.type & SV_TYPE_POTENTIAL_BROWSER)) continue; + + DEBUG(3,("num servers: %d num backups: %d\n", + num_servers, num_backups)); + + /* make first server a backup server. thereafter make every + tenth server a backup server */ + if (num_backups != 0 && (num_servers+9) / num_backups > 10) + { + continue; + } + + DEBUG(2,("sending become backup to %s %s for %s\n", + s->serv.name, inet_ntoa(d->bcast_ip), + work->work_group)); + + /* type 11 request from MYNAME(20) to WG(1e) for SERVER */ + do_announce_request(s->serv.name, work->work_group, + ANN_BecomeBackup, 0x20, 0x1e, d->bcast_ip); + } + } } } @@ -146,23 +150,8 @@ void tell_become_backup(void) ******************************************************************/ BOOL same_context(struct dgram_packet *dgram) { - if (!strequal(dgram->dest_name .scope,scope )) return True; - - return False; -} - - -/******************************************************************* - am I listening on a name. XXXX check the type of name as well. - ******************************************************************/ -BOOL listening_name(struct work_record *work, struct nmb_name *n) -{ - if (strequal(n->name,conf_browsing_alias(work->token)) || - strequal(n->name,work->work_group) || - strequal(n->name,MSBROWSE)) - { - return(True); - } + if (!strequal(dgram->dest_name .scope,scope )) return(True); + if ( strequal(dgram->source_name.name ,myname)) return(True); return(False); } @@ -208,8 +197,8 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf) DEBUG(4,("Announce(%d) %s(%x)",command,name,name[15])); DEBUG(4,("%s count=%d ttl=%d OS=(%d,%d) type=%08x sig=%4x %4x comment=%s\n", - namestr(&dgram->dest_name),update_count,ttl,osmajor,osminor, - servertype,browse_type,browse_sig,comment)); + namestr(&dgram->dest_name),update_count,ttl,osmajor,osminor, + servertype,browse_type,browse_sig,comment)); name[15] = 0; @@ -224,7 +213,7 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf) dgram->dest_name.name_type != 0x1)) { DEBUG(0,("Announce(%d) from %s should be __MSBROWSE__(1) not %s\n", - command, inet_ntoa(ip), namestr(&dgram->dest_name))); + command, inet_ntoa(ip), namestr(&dgram->dest_name))); return; } @@ -276,7 +265,7 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf) if (command == ANN_LocalMasterAnnouncement) { add_browser_entry(serv_name,dgram->dest_name.name_type, - work->work_group,30,ip,True); + work->work_group,30,ip,True); } } @@ -289,40 +278,26 @@ static void process_master_announce(struct packet_struct *p,char *buf) struct in_addr ip = dgram->header.source_ip; struct subnet_record *d = find_subnet(ip); struct subnet_record *mydomain = find_subnet(*iface_bcast(ip)); - char *to_name = dgram->dest_name.name; /* our primary name or an alias */ - char *name = buf; - char *work_name; - int token; + struct work_record *work; name[15] = 0; - DEBUG(3,("Master Announce from %s (%s)\n", name, inet_ntoa(ip))); + DEBUG(3,("Master Announce from %s (%s)\n",name,inet_ntoa(ip))); if (same_context(dgram)) return; if (!d || !mydomain) return; - token = conf_alias_to_token(to_name); - - if (token == -1) + if (!lp_domain_master()) return; + + for (work = mydomain->workgrouplist; work; work = work->next) { - DEBUG(4, ("alias %s not known\n", to_name)); - return; + if (AM_MASTER(work)) + { + /* merge browse lists with them */ + add_browser_entry(name,0x1b, work->work_group,30,ip,True); + } } - - /* carry on only if we are a domain master under the server alias */ - if (!conf_should_domain_master(token)) return; - - /* Convert the server name by which the master browser - called this server to the workgroup name. */ - if ((work_name = conf_workgroup_name(token)) == (char*)NULL) - { - DEBUG(4, ("process_master_announce(): no alias for \"%s\"\n", to_name)); - return; - } - - /* merge browse lists with them */ - add_browser_entry(name, 0x1b, work_name,30,ip,True); } /******************************************************************* @@ -343,44 +318,62 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf) struct dgram_packet *dgram = &p->packet.dgram; struct in_addr ip = dgram->header.source_ip; int count = CVAL(buf,0); - unsigned int pick; uint32 info = IVAL(buf,1); /* XXXX caller's incremental info */ char *buf1; DEBUG(3,("Receive Backup ack for %s from %s total=%d info=%d\n", - namestr(&dgram->dest_name), inet_ntoa(ip), - count, info)); + namestr(&dgram->dest_name), inet_ntoa(ip), + count, info)); if (same_context(dgram)) return; if (count <= 0) return; - pick = sys_random(count); - /* go through the list of servers attempting to sync browse lists */ for (buf1 = buf+5; *buf1 && count; buf1 = skip_string(buf1, 1), --count) { + struct in_addr back_ip; struct subnet_record *d; - if (count != pick) continue; + DEBUG(4,("Searching for backup browser %s at %s...\n", + buf1, inet_ntoa(ip))); + + /* XXXX assume name is a DNS name NOT a netbios name. a more complete + approach is to use reply_name_query functionality to find the name */ - DEBUG(4,("Searching for backup browser %s...\n", buf1)); + back_ip = *interpret_addr2(buf1); - if ((d = find_subnet(ip)) != NULL) - { - struct work_record *work; - for (work = d->workgrouplist; work; work = work->next) - { - if (work->token == 0 /* token */) - { - queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_SRV_CHK, - work->token,work->work_group,0x1d, - 0,0,0,0,NULL,NULL, - False,False,ipzero,ipzero); - return; - } - } - } + if (zero_ip(back_ip)) + { + DEBUG(4,("Failed to find backup browser server using DNS\n")); + continue; + } + + DEBUG(4,("Found browser server at %s\n", inet_ntoa(back_ip))); + DEBUG(4,("END THIS LOOP: CODE NEEDS UPDATING\n")); + + /* XXXX function needs work */ + continue; + + if ((d = find_subnet(back_ip))) + { + struct subnet_record *d1; + for (d1 = subnetlist; d1; d1 = d1->next) + { + struct work_record *work; + for (work = d1->workgrouplist; work; work = work->next) + { + if (work->token == 0 /* token */) + { + queue_netbios_packet(d1,ClientNMB,NMB_QUERY,NAME_QUERY_SRV_CHK, + work->work_group,0x1d, + 0,0,0,NULL,NULL, + False,False,back_ip,back_ip); + return; + } + } + } + } } } @@ -388,9 +381,9 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf) /**************************************************************************** send a backup list response. **************************************************************************/ -static void send_backup_list(struct work_record *work, struct nmb_name *src_name, - int token, uint32 info, - int name_type, struct in_addr ip) +static void send_backup_list(char *work_name, struct nmb_name *src_name, + int token, uint32 info, + int name_type, struct in_addr ip) { char outbuf[1024]; char *p, *countptr, *nameptr; @@ -398,8 +391,8 @@ static void send_backup_list(struct work_record *work, struct nmb_name *src_name char *theirname = src_name->name; DEBUG(3,("sending backup list of %s to %s: %s(%x) %s(%x)\n", - work->work_group, inet_ntoa(ip), - conf_browsing_alias(work->token),0x0,theirname,0x0)); + work_name, inet_ntoa(ip), + myname,0x0,theirname,0x0)); if (name_type == 0x1d) { @@ -431,51 +424,62 @@ static void send_backup_list(struct work_record *work, struct nmb_name *src_name #if 0 - struct server_record *s; + for (d = subnetlist; d; d = d->next) + { + struct work_record *work; - for (s = work->serverlist; s; s = s->next) - { - BOOL found = False; - char *n; - - if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue; - - for (n = nameptr; n < p; n = skip_string(n, 1)) - { - if (strequal(n, s->serv.name)) found = True; - } - - if (found) continue; /* exclude names already added */ - - /* workgroup request: include all backup browsers in the list */ - /* domain request: include all domain members in the list */ - - if ((name_type == 0x1d && (s->serv.type & SV_TYPE_MASTER_BROWSER)) || - (name_type == 0x1b && (s->serv.type & SV_TYPE_DOMAIN_BROWSER))) - { - DEBUG(4, ("%s ", s->serv.name)); - - count++; - strcpy(p,s->serv.name); - strupper(p); - p = skip_string(p,1); - } + for (work = d->workgrouplist; work; work = work->next) + { + struct server_record *s; + + if (!strequal(work->work_group, work_name)) continue; + + for (s = work->serverlist; s; s = s->next) + { + BOOL found = False; + char *n; + + if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue; + + for (n = nameptr; n < p; n = skip_string(n, 1)) + { + if (strequal(n, s->serv.name)) found = True; + } + + if (found) continue; /* exclude names already added */ + + /* workgroup request: include all backup browsers in the list */ + /* domain request: include all domain members in the list */ + + if ((name_type == 0x1d && (s->serv.type & MASTER_TYPE)) || + (name_type == 0x1b && (s->serv.type & DOMCTL_TYPE))) + { + DEBUG(4, ("%s ", s->serv.name)); + + count++; + strcpy(p,s->serv.name); + strupper(p); + p = skip_string(p,1); + } + } + } } + #endif - count++; - strcpy(p,conf_browsing_alias(work->token)); - strupper(p); - p = skip_string(p,1); + count++; + strcpy(p,myname); + strupper(p); + p = skip_string(p,1); if (count == 0) - { + { DEBUG(4, ("none\n")); - } + } else - { + { DEBUG(4, (" - count %d\n", count)); - } + } CVAL(countptr, 0) = count; @@ -484,7 +488,7 @@ static void send_backup_list(struct work_record *work, struct nmb_name *src_name debug_browse_data(outbuf, len); } send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf), - conf_browsing_alias(work->token),theirname,0x0,0x0,ip,*iface_ip(ip)); + myname,theirname,0x0,0x0,ip,*iface_ip(ip)); } @@ -515,24 +519,24 @@ static void process_send_backup_list(struct packet_struct *p,char *buf) if (name_type != 0x1b && name_type != 0x1d) { DEBUG(0,("backup request to wrong type %d from %s\n", - name_type,inet_ntoa(ip))); + name_type,inet_ntoa(ip))); return; } for (d = subnetlist; d; d = d->next) { for (work = d->workgrouplist; work; work = work->next) - { - if (strequal(work->work_group, dgram->dest_name.name)) - { - DEBUG(2,("sending backup list to %s %s id=%x\n", - namestr(&dgram->dest_name),inet_ntoa(ip),info)); - - send_backup_list(work,&dgram->source_name, - token,info,name_type,ip); - return; - } - } + { + if (strequal(work->work_group, dgram->dest_name.name)) + { + DEBUG(2,("sending backup list to %s %s id=%x\n", + namestr(&dgram->dest_name),inet_ntoa(ip),info)); + + send_backup_list(work->work_group,&dgram->source_name, + token,info,name_type,ip); + return; + } + } } } @@ -552,23 +556,23 @@ static void process_reset_browser(struct packet_struct *p,char *buf) int state = CVAL(buf,0); DEBUG(1,("received diagnostic browser reset request to %s state=0x%X\n", - namestr(&dgram->dest_name), state)); + namestr(&dgram->dest_name), state)); /* stop being a master but still deal with being a backup browser */ if (state & 0x1) { struct subnet_record *d; for (d = subnetlist; d; d = d->next) - { - struct work_record *work; - for (work = d->workgrouplist; work; work = work->next) - { - if (AM_MASTER(work)) - { - become_nonmaster(d,work,SV_TYPE_DOMAIN_MASTER|SV_TYPE_MASTER_BROWSER); - } - } - } + { + struct work_record *work; + for (work = d->workgrouplist; work; work = work->next) + { + if (AM_MASTER(work)) + { + become_nonmaster(d,work,SV_TYPE_DOMAIN_MASTER|SV_TYPE_MASTER_BROWSER); + } + } + } } /* XXXX documentation inconsistency: the above description does not @@ -577,24 +581,21 @@ static void process_reset_browser(struct packet_struct *p,char *buf) /* totally delete all servers and start afresh */ if (state & 0x2) - { - /* remove all workgroups (and their servers) from database */ - struct subnet_record *d; - for (d = subnetlist; d; d = d->next) { - struct work_record *work; - for (work=d->workgrouplist;work;work=remove_workgroup(d,work,True)); + struct subnet_record *d; + for (d = subnetlist; d; d = d->next) + { + struct work_record *work; + for (work=d->workgrouplist;work;work=remove_workgroup(d,work,True)); + } + add_my_subnets(lp_workgroup()); } - - /* add all known workgroups back into database */ - add_workgroups_to_subnets(); - } /* stop browsing altogether. i don't think this is a good idea! */ if (state & 0x4) - { + { DEBUG(1,("ignoring request to stop being a browser. sorry!\n")); - } + } } /******************************************************************* @@ -610,43 +611,39 @@ static void process_announce_request(struct packet_struct *p,char *buf) struct in_addr ip = dgram->header.source_ip; struct subnet_record *d = find_subnet(ip); int token = CVAL(buf,0); - int wg_token = 0; char *name = buf+1; - char *samba_alias; - + name[15] = 0; DEBUG(3,("Announce request from %s to %s token=0x%X\n", - name,namestr(&dgram->dest_name), token)); + name,namestr(&dgram->dest_name), token)); - /* look up the index for this workgroup */ - wg_token = conf_workgroup_name_to_token(dgram->dest_name.name,myname); - if (wg_token == -1) return; - - /* check that samba is participating in this workgroup */ - if (!conf_should_workgroup_member(wg_token)) return; + if (strequal(dgram->source_name.name,myname)) return; + + /* XXXX BUG or FEATURE?: need to ensure that we are a member of + this workgroup before announcing, particularly as we only + respond on local interfaces anyway. - /* find samba's NetBIOS alias it operates under in this workgroup */ - if ((samba_alias = conf_browsing_alias(wg_token)) == (char*)NULL) return; + if (strequal(dgram->dest_name, lp_workgroup()) return; ??? + */ - /* ignore announce requests from samba under its own alias. - this should no longer happen because code has been added to - discard packets from ourself. */ - if (strequal(dgram->source_name.name,samba_alias)) return; - if (!d) return; - /* XXXX BUG: the destination name type should also be checked, - not just the name. e.g if the name is WORKGROUP(0x1d) then - we should only respond if we own that name */ - for (work = d->workgrouplist; work; work = work->next) - { - if (wg_token == work->token) work->needannounce = True; - } + { + /* XXXX BUG: the destination name type should also be checked, + not just the name. e.g if the name is WORKGROUP(0x1d) then + we should only respond if we own that name */ + + if (strequal(dgram->dest_name.name,work->work_group)) + { + work->needannounce = True; + } + } } + /**************************************************************************** process a browse frame ****************************************************************************/ @@ -660,27 +657,27 @@ void process_browse_packet(struct packet_struct *p,char *buf,int len) case ANN_LocalMasterAnnouncement: { debug_browse_data(buf, len); - process_announce(p,command,buf+1); - break; + process_announce(p,command,buf+1); + break; } case ANN_AnnouncementRequest: { - process_announce_request(p,buf+1); - break; + process_announce_request(p,buf+1); + break; } case ANN_Election: { - process_election(p,buf+1); - break; + process_election(p,buf+1); + break; } case ANN_GetBackupListReq: { debug_browse_data(buf, len); - process_send_backup_list(p,buf+1); - break; + process_send_backup_list(p,buf+1); + break; } case ANN_GetBackupListResp: @@ -692,22 +689,22 @@ void process_browse_packet(struct packet_struct *p,char *buf,int len) case ANN_ResetBrowserState: { - process_reset_browser(p, buf+1); - break; + process_reset_browser(p, buf+1); + break; } case ANN_MasterAnnouncement: { - process_master_announce(p,buf+1); - break; + process_master_announce(p,buf+1); + break; } default: { - struct dgram_packet *dgram = &p->packet.dgram; - DEBUG(4,("ignoring browse packet %d from %s %s to %s\n", - command, namestr(&dgram->source_name), - inet_ntoa(p->ip), namestr(&dgram->dest_name))); + struct dgram_packet *dgram = &p->packet.dgram; + DEBUG(4,("ignoring browse packet %d from %s %s to %s\n", + command, namestr(&dgram->source_name), + inet_ntoa(p->ip), namestr(&dgram->dest_name))); } } } |