diff options
-rw-r--r-- | source3/include/nameserv.h | 23 | ||||
-rw-r--r-- | source3/nameannounce.c | 40 | ||||
-rw-r--r-- | source3/namebrowse.c | 215 | ||||
-rw-r--r-- | source3/namedb.c | 169 | ||||
-rw-r--r-- | source3/nameelect.c | 14 | ||||
-rw-r--r-- | source3/namelogon.c | 119 | ||||
-rw-r--r-- | source3/nameresp.c | 20 | ||||
-rw-r--r-- | source3/nameserv.c | 51 | ||||
-rw-r--r-- | source3/namework.c | 516 |
9 files changed, 646 insertions, 521 deletions
diff --git a/source3/include/nameserv.h b/source3/include/nameserv.h index 03bb521558..9e4145213b 100644 --- a/source3/include/nameserv.h +++ b/source3/include/nameserv.h @@ -24,7 +24,7 @@ #define MAINTAIN_LIST 2 #define ELECTION_VERSION 1 -#define MAX_DGRAM_SIZE (80*18+64) +#define MAX_DGRAM_SIZE (576) /* tcp/ip datagram limit is 576 bytes */ #define MIN_DGRAM_SIZE 12 #define NMB_QUERY 0x20 @@ -36,6 +36,7 @@ #define NMB_WAIT_ACK 0x07 /* see rfc1002.txt 4.2.17 */ /* XXXX what about all the other types?? 0x1, 0x2, 0x3, 0x4, 0x8? */ +/* NetBIOS flags */ #define NB_GROUP 0x80 #define NB_PERM 0x02 #define NB_ACTIVE 0x04 @@ -51,6 +52,7 @@ #define NAME_POLL_REFRESH_TIME (5*60) #define NAME_POLL_INTERVAL 15 +/* NetBIOS flag identifier */ #define NAME_PERMANENT(p) ((p) & NB_PERM) #define NAME_ACTIVE(p) ((p) & NB_ACTIVE) #define NAME_CONFLICT(p) ((p) & NB_CONFL) @@ -62,12 +64,22 @@ #define NAME_MFLAG(p) (((p) & NB_FLGMSK) == NB_MFLAG) #define NAME__FLAG(p) (((p) & NB_FLGMSK) == NB__FLAG) +/* server type identifiers */ +#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER) +#define AM_BACKUP(work) (work->ServerType & SV_TYPE_BACKUP_BROWSER) +#define AM_DOMCTL(work) (work->ServerType & SV_TYPE_DOMAIN_CTRL) + +/* microsoft browser NetBIOS name */ #define MSBROWSE "\001\002__MSBROWSE__\002" +/* mail slots */ +#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE" +#define NET_LOGON_MAILSLOT "\\MAILSLOT\\NET\\NETLOGON" + enum name_source {STATUS_QUERY, LMHOSTS, REGISTER, SELF, DNS, DNSFAIL}; enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3}; enum packet_type {NMB_PACKET, DGRAM_PACKET}; -enum cmd_type +enum state_type { NAME_STATUS_MASTER_CHECK, NAME_STATUS_CHECK, @@ -161,7 +173,7 @@ struct response_record struct response_record *prev; uint16 response_id; - enum cmd_type cmd_type; + enum state_type state; int fd; int quest_type; @@ -301,11 +313,6 @@ struct packet_struct }; -#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER) -#define AM_BACKUP(work) (work->ServerType & SV_TYPE_BACKUP_BROWSER) -#define AM_DOMCTL(work) (work->ServerType & SV_TYPE_DOMAIN_CTRL) - - /* ids for netbios packet types */ #define ANN_HostAnnouncement 1 #define ANN_AnnouncementRequest 2 diff --git a/source3/nameannounce.c b/source3/nameannounce.c index 5163c4aea9..0fad2fe7ec 100644 --- a/source3/nameannounce.c +++ b/source3/nameannounce.c @@ -50,8 +50,6 @@ extern int workgroup_count; /* what server type are we currently */ -#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE" - /**************************************************************************** send a announce request to the local net **************************************************************************/ @@ -109,6 +107,26 @@ void do_announce_request(char *info, char *to_name, int announce_type, myname,to_name,from,to,dest_ip,*iface_ip(dest_ip)); } + +/**************************************************************************** + find a server responsible for a workgroup, and sync browse lists + control ends up back here via response_name_query. + **************************************************************************/ +void sync_server(enum state_type state, char *serv_name, char *work_name, + int name_type, + struct in_addr ip) +{ + add_browser_entry(serv_name, name_type, work_name, 0, ip); + + if (state == NAME_QUERY_MST_SRV_CHK) + { + /* announce ourselves as a master browser to serv_name */ + do_announce_request(myname, serv_name, ANN_MasterAnnouncement, + 0x20, 0, ip); + } +} + + /**************************************************************************** construct a host announcement unicast **************************************************************************/ @@ -294,8 +312,8 @@ void announce_host(void) if (work->needannounce) { /* drop back to a max 3 minute announce - this is to prevent a single lost packet from stuffing things up for too long */ - work->announce_interval = MIN(work->announce_interval, - CHECK_TIME_MIN_HOST_ANNCE*60); + work->announce_interval = MIN(work->announce_interval, + CHECK_TIME_MIN_HOST_ANNCE*60); work->lastannounce_time = t - (work->announce_interval+1); } @@ -323,18 +341,18 @@ void announce_host(void) } if (announce) - { + { announce_server(d,work,my_name,comment,work->announce_interval,stype); - } + } if (work->needannounce) - { + { work->needannounce = False; break; /* sorry: can't do too many announces. do some more later */ - } + } } - } + } } @@ -356,8 +374,8 @@ void announce_master(void) time_t t = time(NULL); BOOL am_master = False; /* are we a master of some sort? :-) */ - if (last && (t-last < CHECK_TIME_MST_ANNOUNCE * 60)) - return; + if (last && (t-last < CHECK_TIME_MST_ANNOUNCE * 60)) + return; last = t; diff --git a/source3/namebrowse.c b/source3/namebrowse.c new file mode 100644 index 0000000000..31ee9347ec --- /dev/null +++ b/source3/namebrowse.c @@ -0,0 +1,215 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + NBT netbios routines and daemon - version 2 + Copyright (C) Andrew Tridgell 1994-1995 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Revision History: + + 14 jan 96: lkcl@pires.co.uk + added multiple workgroup domain master support + +*/ + +#include "includes.h" +#include "smb.h" + +extern int ClientNMB; + +extern int DEBUGLEVEL; + +/* this is our browse master/backup cache database */ +static struct browse_cache_record *browserlist = NULL; + + +/*************************************************************************** + add a browser into the list + **************************************************************************/ +static void add_browse_cache(struct browse_cache_record *b) +{ + struct browse_cache_record *b2; + + if (!browserlist) + { + browserlist = b; + b->prev = NULL; + b->next = NULL; + return; + } + + for (b2 = browserlist; b2->next; b2 = b2->next) ; + + b2->next = b; + b->next = NULL; + b->prev = b2; +} + + +/******************************************************************* + remove old browse entries + ******************************************************************/ +void expire_browse_cache(time_t t) +{ + struct browse_cache_record *b; + struct browse_cache_record *nextb; + + /* expire old entries in the serverlist */ + for (b = browserlist; b; b = nextb) + { + if (b->synced && b->sync_time < t) + { + DEBUG(3,("Removing dead cached browser %s\n",b->name)); + nextb = b->next; + + if (b->prev) b->prev->next = b->next; + if (b->next) b->next->prev = b->prev; + + if (browserlist == b) browserlist = b->next; + + free(b); + } + else + { + nextb = b->next; + } + } +} + + +/**************************************************************************** + add a browser entry + ****************************************************************************/ +struct browse_cache_record *add_browser_entry(char *name, int type, char *wg, + time_t ttl, struct in_addr ip) +{ + BOOL newentry=False; + + struct browse_cache_record *b; + + /* search for the entry: if it's already in the cache, update that entry */ + for (b = browserlist; b; b = b->next) + { + if (ip_equal(ip,b->ip) && strequal(b->group, wg)) break; + } + + if (b && b->synced) + { + /* entries get left in the cache for a while. this stops sync'ing too + often if the network is large */ + DEBUG(4, ("browser %s %s %s already sync'd at time %d\n", + b->name, b->group, inet_ntoa(b->ip), b->sync_time)); + return NULL; + } + + if (!b) + { + newentry = True; + b = (struct browse_cache_record *)malloc(sizeof(*b)); + + if (!b) return(NULL); + + bzero((char *)b,sizeof(*b)); + } + + /* update the entry */ + ttl = time(NULL)+ttl; + + StrnCpy(b->name ,name,sizeof(b->name )-1); + StrnCpy(b->group,wg ,sizeof(b->group)-1); + strupper(b->name); + strupper(b->group); + + b->ip = ip; + b->type = type; + + if (newentry || ttl < b->sync_time) + b->sync_time = ttl; + + if (newentry) + { + b->synced = False; + add_browse_cache(b); + + DEBUG(3,("Added cache entry %s %s(%2x) %s ttl %d\n", + wg, name, type, inet_ntoa(ip),ttl)); + } + else + { + DEBUG(3,("Updated cache entry %s %s(%2x) %s ttl %d\n", + wg, name, type, inet_ntoa(ip),ttl)); + } + + return(b); +} + + +/**************************************************************************** +find a server responsible for a workgroup, and sync browse lists +**************************************************************************/ +static void start_sync_browse_entry(struct browse_cache_record *b) +{ + struct subnet_record *d; + struct work_record *work; + + if (!(d = find_subnet(b->ip))) return; + + /* only sync if we are the master */ + if (AM_MASTER(work)) { + + /* first check whether the group we intend to sync with exists. if it + doesn't, the server must have died. o dear. */ + + /* see response_netbios_packet() or expire_netbios_response_entries() */ + queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_SYNC, + b->group,0x20,0,0, + False,False,b->ip); + } + + b->synced = True; +} + + +/**************************************************************************** + search through browser list for an entry to sync with + **************************************************************************/ +void do_browser_lists(void) +{ + struct browse_cache_record *b; + static time_t last = 0; + time_t t = time(NULL); + + if (t-last < 20) return; /* don't do too many of these at once! */ + /* XXXX equally this period should not be too long + the server may die in the intervening gap */ + + last = t; + + /* pick any entry in the list, preferably one whose time is up */ + for (b = browserlist; b && b->next; b = b->next) + { + if (b->sync_time < t && b->synced == False) break; + } + + if (b && !b->synced) + { + /* sync with the selected entry then remove some dead entries */ + start_sync_browse_entry(b); + expire_browse_cache(t - 60); + } + +} + diff --git a/source3/namedb.c b/source3/namedb.c index a1442c0f03..1855103c99 100644 --- a/source3/namedb.c +++ b/source3/namedb.c @@ -40,9 +40,6 @@ extern pstring scope; extern struct in_addr ipgrp; extern struct in_addr ipzero; -/* this is our browse master/backup cache database */ -struct browse_cache_record *browserlist = NULL; - /* local interfaces structure */ extern struct interface *local_interfaces; @@ -230,29 +227,6 @@ static void add_subnet(struct subnet_record *d) } /*************************************************************************** - add a browser into the list - **************************************************************************/ -static void add_browse_cache(struct browse_cache_record *b) -{ - struct browse_cache_record *b2; - - if (!browserlist) - { - browserlist = b; - b->prev = NULL; - b->next = NULL; - return; - } - - for (b2 = browserlist; b2->next; b2 = b2->next) ; - - b2->next = b; - b->next = NULL; - b->prev = b2; -} - - -/*************************************************************************** add a server into the list **************************************************************************/ static void add_server(struct work_record *work,struct server_record *s) @@ -274,37 +248,6 @@ static void add_server(struct work_record *work,struct server_record *s) } -/******************************************************************* - remove old browse entries - ******************************************************************/ -void expire_browse_cache(time_t t) -{ - struct browse_cache_record *b; - struct browse_cache_record *nextb; - - /* expire old entries in the serverlist */ - for (b = browserlist; b; b = nextb) - { - if (b->synced && b->sync_time < t) - { - DEBUG(3,("Removing dead cached browser %s\n",b->name)); - nextb = b->next; - - if (b->prev) b->prev->next = b->next; - if (b->next) b->next->prev = b->prev; - - if (browserlist == b) browserlist = b->next; - - free(b); - } - else - { - nextb = b->next; - } - } -} - - /**************************************************************************** find a workgroup in the workgrouplist only create it if the domain allows it, or the parameter 'add' insists @@ -387,8 +330,8 @@ struct subnet_record *find_subnet(struct in_addr bcast_ip) } else if (same_net(bcast_ip, d->bcast_ip, d->mask_ip)) { - return(d); - } + return(d); + } } return (NULL); @@ -447,7 +390,7 @@ static struct subnet_record *make_subnet(struct in_addr bcast_ip, struct in_addr d->mask_ip = mask_ip; d->workgrouplist = NULL; d->my_interface = False; /* True iff the interface is on the samba host */ - + add_subnet(d); return d; @@ -506,7 +449,7 @@ struct subnet_record *add_subnet_entry(struct in_addr bcast_ip, char *name, BOOL add, BOOL lmhosts) { struct subnet_record *d; - + /* XXXX andrew: struct in_addr ip appears not to be referenced at all except in the DEBUG comment. i assume that the DEBUG comment below actually intends to refer to bcast_ip? i don't know. @@ -514,7 +457,7 @@ struct subnet_record *add_subnet_entry(struct in_addr bcast_ip, struct in_addr ip = ipgrp; */ - + if (zero_ip(bcast_ip)) bcast_ip = *iface_bcast(bcast_ip); @@ -536,9 +479,9 @@ struct subnet_record *add_subnet_entry(struct in_addr bcast_ip, } /* add samba server name to workgroup list */ if ((strequal(lp_workgroup(), name) && d->my_interface) || lmhosts) - { - add_server_entry(d,w,myname,w->ServerType,0,ServerComment,True); - } + { + add_server_entry(d,w,myname,w->ServerType,0,ServerComment,True); + } DEBUG(3,("Added domain name entry %s at %s\n", name,inet_ntoa(bcast_ip))); return d; @@ -547,73 +490,6 @@ struct subnet_record *add_subnet_entry(struct in_addr bcast_ip, } /**************************************************************************** - add a browser entry - ****************************************************************************/ -struct browse_cache_record *add_browser_entry(char *name, int type, char *wg, - time_t ttl, struct in_addr ip) -{ - BOOL newentry=False; - - struct browse_cache_record *b; - - /* search for the entry: if it's already in the cache, update that entry */ - for (b = browserlist; b; b = b->next) - { - if (ip_equal(ip,b->ip) && strequal(b->group, wg)) break; - } - - if (b && b->synced) - { - /* entries get left in the cache for a while. this stops sync'ing too - often if the network is large */ - DEBUG(4, ("browser %s %s %s already sync'd at time %d\n", - b->name, b->group, inet_ntoa(b->ip), b->sync_time)); - return NULL; - } - - if (!b) - { - newentry = True; - b = (struct browse_cache_record *)malloc(sizeof(*b)); - - if (!b) return(NULL); - - bzero((char *)b,sizeof(*b)); - } - - /* update the entry */ - ttl = time(NULL)+ttl; - - StrnCpy(b->name ,name,sizeof(b->name )-1); - StrnCpy(b->group,wg ,sizeof(b->group)-1); - strupper(b->name); - strupper(b->group); - - b->ip = ip; - b->type = type; - - if (newentry || ttl < b->sync_time) - b->sync_time = ttl; - - if (newentry) - { - b->synced = False; - add_browse_cache(b); - - DEBUG(3,("Added cache entry %s %s(%2x) %s ttl %d\n", - wg, name, type, inet_ntoa(ip),ttl)); - } - else - { - DEBUG(3,("Updated cache entry %s %s(%2x) %s ttl %d\n", - wg, name, type, inet_ntoa(ip),ttl)); - } - - return(b); -} - - -/**************************************************************************** remove all samba's server entries ****************************************************************************/ void remove_my_servers(void) @@ -664,8 +540,8 @@ struct server_record *add_server_entry(struct subnet_record *d, } if (!s || s->serv.type != servertype || !strequal(s->serv.comment, comment)) - updatedlists=True; - + updatedlists=True; + if (!s) { newentry = True; @@ -679,8 +555,8 @@ struct server_record *add_server_entry(struct subnet_record *d, if (d->my_interface && strequal(lp_workgroup(),work->work_group)) { - if (servertype) - servertype |= SV_TYPE_LOCAL_LIST_ONLY; + if (servertype) + servertype |= SV_TYPE_LOCAL_LIST_ONLY; } else { @@ -717,6 +593,27 @@ struct server_record *add_server_entry(struct subnet_record *d, } +/**************************************************************************** + add the default workgroup into my domain + **************************************************************************/ +void add_my_subnets(char *group) +{ + struct interface *i; + + /* add or find domain on our local subnet, in the default workgroup */ + + if (*group == '*') return; + + /* the coding choice is up to you, andrew: i can see why you don't want + global access to the local_interfaces structure: so it can't get + messed up! */ + for (i = local_interfaces; i; i = i->next) + { + add_subnet_entry(i->bcast,i->nmask,group, True, False); + } +} + + /******************************************************************* write out browse.dat ******************************************************************/ diff --git a/source3/nameelect.c b/source3/nameelect.c index c841d9b7a6..855ea26348 100644 --- a/source3/nameelect.c +++ b/source3/nameelect.c @@ -42,8 +42,6 @@ extern pstring ServerComment; extern time_t StartupTime; -#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE" - extern struct subnet_record *subnetlist; @@ -57,7 +55,7 @@ void check_master_browser(void) struct subnet_record *d; if (!lastrun) lastrun = t; - if (t < lastrun + CHECK_TIME_MST_BROWSE * 60) + if (t < lastrun + CHECK_TIME_MST_BROWSE * 60) return; lastrun = t; @@ -215,7 +213,7 @@ void become_nonmaster(struct subnet_record *d, struct work_record *work, /* unbecome a master browser; unbecome a domain master, too :-( */ if (remove_type & SV_TYPE_MASTER_BROWSER) remove_type |= SV_TYPE_DOMAIN_MASTER; - + new_server_type &= ~remove_type; if (!(new_server_type & (SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER))) @@ -223,8 +221,8 @@ void become_nonmaster(struct subnet_record *d, struct work_record *work, /* no longer a master browser of any sort */ work->ServerType |= SV_TYPE_POTENTIAL_BROWSER; - work->ElectionCriterion &= ~0x4; - + work->ElectionCriterion &= ~0x4; + /* announce ourselves as no longer active as a master browser. */ announce_server(d, work, work->work_group, myname, 0, 0); remove_name_entry(d,MSBROWSE ,0x01); @@ -356,10 +354,10 @@ void process_election(struct packet_struct *p,char *buf) /* if we are the master then remove our masterly names */ if (AM_MASTER(work)) - { + { become_nonmaster(d, work, SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER); - } + } } } } diff --git a/source3/namelogon.c b/source3/namelogon.c new file mode 100644 index 0000000000..8a7fe87965 --- /dev/null +++ b/source3/namelogon.c @@ -0,0 +1,119 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + NBT netbios routines and daemon - version 2 + Copyright (C) Andrew Tridgell 1994-1995 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Revision History: + + 14 jan 96: lkcl@pires.co.uk + added multiple workgroup domain master support + +*/ + +#include "includes.h" + +extern int ClientDGRAM; + +#define TEST_CODE /* want to debug unknown browse packets */ + +extern int DEBUGLEVEL; + +extern pstring myname; + + +/**************************************************************************** + process a domain logon packet + **************************************************************************/ +void process_logon_packet(struct packet_struct *p,char *buf,int len) +{ + struct dgram_packet *dgram = &p->packet.dgram; + struct in_addr ip = dgram->header.source_ip; + struct subnet_record *d = find_subnet(ip); + char *logname,*q; + char *reply_name; + BOOL add_slashes = False; + pstring outbuf; + int code,reply_code; + struct work_record *work; + + if (!d) return; + + if (!(work = find_workgroupstruct(d,dgram->dest_name.name, False))) + return; + + if (!lp_domain_logons()) { + DEBUG(3,("No domain logons\n")); + return; + } + if (!listening_name(work, &dgram->dest_name)) + { + DEBUG(4,("Not listening to that domain\n")); + return; + } + + code = SVAL(buf,0); + switch (code) { + case 0: + { + char *machine = buf+2; + char *user = skip_string(machine,1); + logname = skip_string(user,1); + reply_code = 6; + reply_name = myname; + add_slashes = True; + DEBUG(3,("Domain login request from %s(%s) user=%s\n", + machine,inet_ntoa(p->ip),user)); + } + break; + case 7: + { + char *machine = buf+2; + logname = skip_string(machine,1); + reply_code = 7; + reply_name = lp_domain_controller(); + if (!*reply_name) { + DEBUG(3,("No domain controller configured\n")); + return; + } + DEBUG(3,("GETDC request from %s(%s)\n", + machine,inet_ntoa(p->ip))); + } + break; + default: + DEBUG(3,("Unknown domain request %d\n",code)); + return; + } + + bzero(outbuf,sizeof(outbuf)); + q = outbuf; + SSVAL(q,0,reply_code); + q += 2; + if (add_slashes) { + strcpy(q,"\\\\"); + q += 2; + } + StrnCpy(q,reply_name,16); + strupper(q); + q = skip_string(q,1); + SSVAL(q,0,0xFFFF); + q += 2; + + send_mailslot_reply(logname,ClientDGRAM,outbuf,PTR_DIFF(q,outbuf), + myname,&dgram->source_name.name[0],0x20,0,p->ip, + *iface_ip(p->ip)); +} diff --git a/source3/nameresp.c b/source3/nameresp.c index 14b9956186..8484cb4fd1 100644 --- a/source3/nameresp.c +++ b/source3/nameresp.c @@ -86,7 +86,7 @@ static void dead_netbios_entry(struct subnet_record *d, DEBUG(3,("Removing dead netbios entry for %s %s (num_msgs=%d)\n", inet_ntoa(n->to_ip), namestr(&n->name), n->num_msgs)); - switch (n->cmd_type) + switch (n->state) { case NAME_QUERY_CONFIRM: { @@ -384,10 +384,16 @@ void reply_netbios_packet(struct packet_struct *p1,int trn_id, WINS server specified, the packet will NOT be sent. ****************************************************************************/ void queue_netbios_pkt_wins(struct subnet_record *d, - int fd,int quest_type,enum cmd_type cmd, + int fd,int quest_type,enum state_type state, char *name,int name_type,int nb_flags, time_t ttl, BOOL bcast,BOOL recurse,struct in_addr to_ip) { + /* XXXX note: please see rfc1001.txt section 10 for details on this + function: it is currently inappropriate to use this - it will do + for now - once there is a clarification of B, M and P nodes and + which one samba is supposed to be + */ + if ((!lp_wins_support()) && (*lp_wins_server())) { /* samba is not a WINS server, and we are using a WINS server */ @@ -409,7 +415,7 @@ void queue_netbios_pkt_wins(struct subnet_record *d, if (zero_ip(to_ip)) return; - queue_netbios_packet(d,fd, quest_type, cmd, + queue_netbios_packet(d,fd, quest_type, state, name, name_type, nb_flags, ttl, bcast, recurse, to_ip); } @@ -418,7 +424,7 @@ void queue_netbios_pkt_wins(struct subnet_record *d, create a name query response record **************************************************************************/ static struct response_record * -make_response_queue_record(enum cmd_type cmd,int id,int fd, +make_response_queue_record(enum state_type state,int id,int fd, int quest_type, char *name,int type, int nb_flags, time_t ttl, BOOL bcast,BOOL recurse, struct in_addr ip) { @@ -430,7 +436,7 @@ make_response_queue_record(enum cmd_type cmd,int id,int fd, return(NULL); n->response_id = id; - n->cmd_type = cmd; + n->state = state; n->fd = fd; n->quest_type = quest_type; make_nmb_name(&n->name, name, type, scope); @@ -459,7 +465,7 @@ make_response_queue_record(enum cmd_type cmd,int id,int fd, complete lists across a wide area network ****************************************************************************/ void queue_netbios_packet(struct subnet_record *d, - int fd,int quest_type,enum cmd_type cmd,char *name, + int fd,int quest_type,enum state_type state,char *name, int name_type,int nb_flags, time_t ttl, BOOL bcast,BOOL recurse, struct in_addr to_ip) { @@ -475,7 +481,7 @@ void queue_netbios_packet(struct subnet_record *d, if (id == 0xffff) return; - if ((n = make_response_queue_record(cmd,id,fd, + if ((n = make_response_queue_record(state,id,fd, quest_type,name,name_type,nb_flags,ttl, bcast,recurse,to_ip))) { diff --git a/source3/nameserv.c b/source3/nameserv.c index 557bad73c3..9025b66429 100644 --- a/source3/nameserv.c +++ b/source3/nameserv.c @@ -64,6 +64,7 @@ static struct subnet_record *find_req_subnet(struct in_addr ip, BOOL bcast) return find_subnet(ipgrp); } + /**************************************************************************** true if two netbios names are equal ****************************************************************************/ @@ -74,6 +75,7 @@ static BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2) return(strequal(n1->name,n2->name) && strequal(n1->scope,n2->scope)); } + /**************************************************************************** add a netbios name into the namelist **************************************************************************/ @@ -98,6 +100,7 @@ static void add_name(struct subnet_record *d, struct name_record *n) n->prev = n2; } + /**************************************************************************** remove a name from the namelist. The pointer must be an element just retrieved @@ -1360,15 +1363,15 @@ void reply_name_query(struct packet_struct *p) /**************************************************************************** - response from a name query server check. commands of type NAME_QUERY_MST_SRV_CHK, + response from a name query server check. states of type NAME_QUERY_MST_SRV_CHK, NAME_QUERY_SRV_CHK, and NAME_QUERY_FIND_MST dealt with here. ****************************************************************************/ static void response_server_check(struct nmb_name *ans_name, struct response_record *n, struct subnet_record *d) { - /* issue another command: this time to do a name status check */ + /* issue another state: this time to do a name status check */ - enum cmd_type cmd = (n->cmd_type == NAME_QUERY_MST_SRV_CHK) ? + enum state_type cmd = (n->state == NAME_QUERY_MST_SRV_CHK) ? NAME_STATUS_MASTER_CHECK : NAME_STATUS_CHECK; /* initiate a name status check on the server that replied */ @@ -1379,7 +1382,7 @@ static void response_server_check(struct nmb_name *ans_name, } /**************************************************************************** - response from a name status check. commands of type NAME_STATUS_MASTER_CHECK + response from a name status check. states of type NAME_STATUS_MASTER_CHECK and NAME_STATUS_CHECK dealt with here. ****************************************************************************/ static void response_name_status_check(struct in_addr ip, @@ -1397,7 +1400,7 @@ static void response_name_status_check(struct in_addr ip, { if (*serv_name) { - sync_server(n->cmd_type,serv_name, + sync_server(n->state,serv_name, name.name,name.name_type, n->to_ip); } } @@ -1410,7 +1413,7 @@ static void response_name_status_check(struct in_addr ip, /**************************************************************************** response from a name query to sync browse lists or to update our netbios - entry. commands of type NAME_QUERY_SYNC and NAME_QUERY_CONFIRM + entry. states of type NAME_QUERY_SYNC and NAME_QUERY_CONFIRM ****************************************************************************/ static void response_name_query_sync(struct nmb_packet *nmb, struct nmb_name *ans_name, BOOL bcast, @@ -1419,7 +1422,7 @@ static void response_name_query_sync(struct nmb_packet *nmb, DEBUG(4, ("Name query at %s ip %s - ", namestr(&n->name), inet_ntoa(n->to_ip))); - if (!name_equal(n->name, ans_name)) + if (!name_equal(&n->name, ans_name)) { /* someone gave us the wrong name as a reply. oops. */ DEBUG(4,("unexpected name received: %s\n", namestr(ans_name))); @@ -1433,17 +1436,17 @@ static void response_name_query_sync(struct nmb_packet *nmb, putip((char*)&found_ip,&nmb->answers->rdata[2]); - if (!ip_equal(n->ip, found_ip)) + if (!ip_equal(n->to_ip, found_ip)) { /* someone gave us the wrong ip as a reply. oops. */ - DEBUG(4,("expected ip: %s\n", inet_ntoa(n->ip))); + DEBUG(4,("expected ip: %s\n", inet_ntoa(n->to_ip))); DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip))); return; } DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip))); - if (n->cmd_type == NAME_QUERY_SYNC) + if (n->state == NAME_QUERY_SYNC) { struct work_record *work = NULL; if ((work = find_workgroupstruct(d, ans_name->name, False))) @@ -1465,7 +1468,7 @@ static void response_name_query_sync(struct nmb_packet *nmb, { DEBUG(4, (" NEGATIVE RESPONSE!\n")); - if (n->cmd_type == NAME_QUERY_CONFIRM) + if (n->state == NAME_QUERY_CONFIRM) { /* XXXX remove_netbios_entry()? */ /* lots of things we ought to do, here. if we get here, @@ -1473,7 +1476,7 @@ static void response_name_query_sync(struct nmb_packet *nmb, reality. sort it out */ remove_netbios_name(d,n->name.name, n->name.name_type, - REGISTER,n->ip); + REGISTER,n->to_ip); } } } @@ -1494,12 +1497,12 @@ static void debug_rr_type(int rr_type) } /**************************************************************************** - report the response record nmbd command type + report the response record nmbd state ****************************************************************************/ -static void debug_cmd_type(int cmd_type) +static void debug_state_type(int state) { - /* report the command type to help debugging */ - switch (cmd_type) + /* report the state type to help debugging */ + switch (state) { case NAME_QUERY_MST_SRV_CHK : DEBUG(4,("MASTER_SVR_CHECK\n")); break; case NAME_QUERY_SRV_CHK : DEBUG(4,("NAME_QUERY_SRV_CHK\n")); break; @@ -1566,7 +1569,7 @@ static BOOL response_problem_check(struct response_record *n, /* this may cause problems for some early versions of nmbd */ - switch (n->cmd_type) + switch (n->state) { case NAME_QUERY_MST_SRV_CHK: case NAME_QUERY_SRV_CHK: @@ -1609,7 +1612,7 @@ static BOOL response_problem_check(struct response_record *n, static BOOL response_compatible(struct response_record *n, struct nmb_packet *nmb) { - switch (n->cmd_type) + switch (n->state) { case NAME_RELEASE: { @@ -1659,7 +1662,7 @@ static BOOL response_compatible(struct response_record *n, default: { - DEBUG(0,("unknown command received in response_netbios_packet\n")); + DEBUG(0,("unknown state type received in response_netbios_packet\n")); break; } } @@ -1674,7 +1677,7 @@ static void response_process(struct subnet_record *d, struct packet_struct *p, struct response_record *n, struct nmb_packet *nmb, BOOL bcast, struct nmb_name *ans_name) { - switch (n->cmd_type) + switch (n->state) { case NAME_RELEASE: { @@ -1721,7 +1724,7 @@ static void response_process(struct subnet_record *d, struct packet_struct *p, default: { - DEBUG(0,("unknown command received in response_netbios_packet\n")); + DEBUG(0,("unknown state type received in response_netbios_packet\n")); break; } } @@ -1776,17 +1779,17 @@ static void response_netbios_packet(struct packet_struct *p) n->num_msgs++; /* count number of responses received */ n->repeat_count = 0; /* don't resend: see expire_netbios_packets() */ - debug_cmd_type(n->cmd_type); + debug_state_type(n->state); /* problem checking: multiple responses etc */ if (response_problem_check(n, nmb, qname)) return; - /* now check whether the command has received the correct type of response*/ + /* now check whether the state has received the correct type of response */ if (!response_compatible(n, nmb)) return; - /* now deal with the command */ + /* now deal with the current state */ response_process(d, p, n, nmb, bcast, ans_name); } diff --git a/source3/namework.c b/source3/namework.c index f0fca0071e..7307ddce04 100644 --- a/source3/namework.c +++ b/source3/namework.c @@ -45,12 +45,6 @@ extern struct in_addr ipzero; extern int workgroup_count; /* total number of workgroups we know about */ -/* this is our browse cache database */ -extern struct browse_cache_record *browserlist; - -/* this is our domain/workgroup/server database */ -extern struct interface *local_interfaces; - /* this is our domain/workgroup/server database */ extern struct subnet_record *subnetlist; @@ -70,8 +64,6 @@ extern int updatecount; extern time_t StartupTime; -#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE" - #define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl()) @@ -106,6 +98,11 @@ tell a server to become a backup browser **************************************************************************/ void tell_become_backup(void) { + /* XXXX note: this function is currently unsuitable for use, as it + does not properly check that a server is in a fit state to become + a backup browser before asking it to be one. + */ + struct subnet_record *d; for (d = subnetlist; d; d = d->next) { @@ -155,234 +152,6 @@ void tell_become_backup(void) } } -/**************************************************************************** -find a server responsible for a workgroup, and sync browse lists -**************************************************************************/ -static void start_sync_browse_entry(struct browse_cache_record *b) -{ - struct subnet_record *d; - struct work_record *work; - - if (!(d = find_subnet(b->ip))) return; - - /* only sync if we are the master */ - if (AM_MASTER(work)) { - - /* first check whether the group we intend to sync with exists. if it - doesn't, the server must have died. o dear. */ - - /* see response_netbios_packet() or expire_netbios_response_entries() */ - queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_SYNC, - b->group,0x20,0,0, - False,False,b->ip); - } - - b->synced = True; -} - - -/**************************************************************************** -search through browser list for an entry to sync with -**************************************************************************/ -void do_browser_lists(void) -{ - struct browse_cache_record *b; - static time_t last = 0; - time_t t = time(NULL); - - if (t-last < 20) return; /* don't do too many of these at once! */ - /* XXXX equally this period should not be too long - the server may die in the intervening gap */ - - last = t; - - /* pick any entry in the list, preferably one whose time is up */ - for (b = browserlist; b && b->next; b = b->next) - { - if (b->sync_time < t && b->synced == False) break; - } - - if (b && !b->synced) - { - /* sync with the selected entry then remove some dead entries */ - start_sync_browse_entry(b); - expire_browse_cache(t - 60); - } - -} - - -/**************************************************************************** -find a server responsible for a workgroup, and sync browse lists -control ends up back here via response_name_query. -**************************************************************************/ -void sync_server(enum cmd_type cmd, char *serv_name, char *work_name, - int name_type, - struct in_addr ip) -{ - add_browser_entry(serv_name, name_type, work_name, 0, ip); - - if (cmd == NAME_QUERY_MST_SRV_CHK) - { - /* announce ourselves as a master browser to serv_name */ - do_announce_request(myname, serv_name, ANN_MasterAnnouncement, - 0x20, 0, ip); - } -} - - -/**************************************************************************** - add the default workgroup into my domain - **************************************************************************/ -void add_my_subnets(char *group) -{ - struct interface *i; - - /* add or find domain on our local subnet, in the default workgroup */ - - if (*group == '*') return; - - /* the coding choice is up to you, andrew: i can see why you don't want - global access to the local_interfaces structure: so it can't get - messed up! */ - for (i = local_interfaces; i; i = i->next) - { - add_subnet_entry(i->bcast,i->nmask,group, True, False); - } -} - - -/**************************************************************************** - send a backup list response. - **************************************************************************/ -static void send_backup_list(char *work_name, struct nmb_name *src_name, - int info_count, int token, int info, - int name_type, struct in_addr ip) -{ - struct subnet_record *d; - char outbuf[1024]; - char *p, *countptr, *nameptr; - int count = 0; - int i, j; - char *theirname = src_name->name; - - DEBUG(3,("sending backup list of %s to %s: %s(%x) %s(%x)\n", - work_name, inet_ntoa(ip), - myname,0x20,theirname,0x0)); - - if (name_type == 0x1d) - { - DEBUG(4,("master browsers: ")); - } - else if (name_type == 0x1b) - { - DEBUG(4,("domain controllers: ")); - } - else - { - DEBUG(0,("backup request for unknown type %0x\n", name_type)); - return; - } - - bzero(outbuf,sizeof(outbuf)); - p = outbuf; - - CVAL(p,0) = 10; /* backup list response */ - p++; - - countptr = p; /* count pointer */ - - SSVAL(p,1,token); /* sender's workgroup index representation */ - SSVAL(p,3,info); /* XXXX clueless: info, usually zero */ - p += 5; - - nameptr = p; - - for (d = subnetlist; d; d = d->next) - { - struct work_record *work; - - 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); - } - } - } - } - - if (count == 0) - { - DEBUG(4, ("none\n")); - return; - } - else - { - DEBUG(4, (" - count %d\n", count)); - } - - CVAL(countptr,0) = count; /* total number of backup browsers found */ - - { - int len = PTR_DIFF(p, outbuf); - - for (i = 0; i < len; i+= 16) - { - DEBUG(4, ("%3x char ", i)); - - for (j = 0; j < 16; j++) - { - unsigned char x = outbuf[i+j]; - if (x < 32 || x > 127) x = '.'; - - if (i+j >= len) break; - DEBUG(4, ("%c", x)); - } - - DEBUG(4, (" hex ", i)); - - for (j = 0; j < 16; j++) - { - if (i+j >= len) break; - DEBUG(4, (" %02x", outbuf[i+j])); - } - - DEBUG(4, ("\n")); - } - - } - send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf), - myname,theirname,0x20,0,ip,*iface_ip(ip)); -} - /******************************************************************* same context: scope. should check name_type as well, and makes sure @@ -471,7 +240,16 @@ static void process_announce(struct packet_struct *p,int command,char *buf) if (same_context(dgram)) return; - if (command == ANN_DomainAnnouncement) { + if (command == ANN_DomainAnnouncement) { + /* XXXX if we are a master browser for the workgroup work_name, + then there is a local subnet configuration problem. only + we should be sending out such domain announcements, because + as the master browser, that is our job. + + stop being a master browser, and force an election. this will + sort out the network problem. hopefully. + */ + work_name = name; } else { work_name = dgram->dest_name.name; @@ -501,6 +279,14 @@ static void process_announce(struct packet_struct *p,int command,char *buf) tell_become_backup(); #endif + /* XXXX over-kill: i don't think we should really be doing this, + but it doesn't do much harm other than to add extra network + traffic. to be more precise, we should (possibly) only + sync browse lists with a host that sends an + ANN_LocalMasterAnnouncement or an ANN_DomainAnnouncement. + possibly. + */ + /* get their browse list from them and add it to ours. */ add_browser_entry(serv_name,dgram->dest_name.name_type, work->work_group,30,ip); @@ -543,6 +329,12 @@ static void process_master_announce(struct packet_struct *p,char *buf) we receive a list of servers, and we attempt to locate them all on our local subnet, and sync browse lists with them on the workgroup they are said to be in. + + XXXX NOTE: this function is in overdrive. it should not really do + half of what it actually does (it should pick _one_ name from the + list received and sync with it at regular intervals, rather than + sync with them all only once!) + ******************************************************************/ static void process_rcv_backup_list(struct packet_struct *p,char *buf) { @@ -570,7 +362,7 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf) 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 */ + approach is to use reply_name_query functionality to find the name */ back_ip = *interpret_addr2(buf1); if (zero_ip(back_ip)) @@ -602,10 +394,143 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf) } } + +/**************************************************************************** + send a backup list response. + **************************************************************************/ +static void send_backup_list(char *work_name, struct nmb_name *src_name, + int info_count, int token, int info, + int name_type, struct in_addr ip) +{ + struct subnet_record *d; + char outbuf[1024]; + char *p, *countptr, *nameptr; + int count = 0; + int i, j; + char *theirname = src_name->name; + + DEBUG(3,("sending backup list of %s to %s: %s(%x) %s(%x)\n", + work_name, inet_ntoa(ip), + myname,0x20,theirname,0x0)); + + if (name_type == 0x1d) + { + DEBUG(4,("master browsers: ")); + } + else if (name_type == 0x1b) + { + DEBUG(4,("domain controllers: ")); + } + else + { + DEBUG(0,("backup request for unknown type %0x\n", name_type)); + return; + } + + bzero(outbuf,sizeof(outbuf)); + p = outbuf; + + CVAL(p,0) = ANN_GetBackupListResp; /* backup list response */ + p++; + + countptr = p; /* count pointer */ + + SSVAL(p,1,token); /* sender's workgroup index representation */ + SSVAL(p,3,info); /* XXXX clueless: info, usually zero */ + p += 5; + + nameptr = p; + + for (d = subnetlist; d; d = d->next) + { + struct work_record *work; + + 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); + } + } + } + } + + if (count == 0) + { + DEBUG(4, ("none\n")); + return; + } + else + { + DEBUG(4, (" - count %d\n", count)); + } + + CVAL(countptr,0) = count; /* total number of backup browsers found */ + + { + int len = PTR_DIFF(p, outbuf); + + for (i = 0; i < len; i+= 16) + { + DEBUG(4, ("%3x char ", i)); + + for (j = 0; j < 16; j++) + { + unsigned char x = outbuf[i+j]; + if (x < 32 || x > 127) x = '.'; + + if (i+j >= len) break; + DEBUG(4, ("%c", x)); + } + + DEBUG(4, (" hex ", i)); + + for (j = 0; j < 16; j++) + { + if (i+j >= len) break; + DEBUG(4, (" %02x", outbuf[i+j])); + } + + DEBUG(4, ("\n")); + } + + } + send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf), + myname,theirname,0x20,0x0,ip,*iface_ip(ip)); +} + + /******************************************************************* process a send backup list request - A client send a backup list request to ask for a list of servers on + A client sends a backup list request to ask for a list of servers on the net that maintain server lists for a domain. A server is then chosen from this list to send NetServerEnum commands to to list available servers. @@ -618,7 +543,7 @@ static void process_send_backup_list(struct packet_struct *p,char *buf) { struct dgram_packet *dgram = &p->packet.dgram; struct in_addr ip = dgram->header.source_ip; - struct subnet_record *d; + struct subnet_record *d; struct work_record *work; int count = CVAL(buf,0); @@ -658,7 +583,7 @@ static void process_send_backup_list(struct packet_struct *p,char *buf) process a reset browser state diagnostic packet: - 0x1 - stop being a master browser + 0x1 - stop being a master browser and become a backup browser. 0x2 - discard browse lists, stop being a master browser, try again. 0x4 - stop being a master browser forever. no way. ain't gonna. @@ -688,6 +613,10 @@ static void process_reset_browser(struct packet_struct *p,char *buf) } } + /* XXXX documentation inconsistency: the above description does not + exactly tally with what is implemented for state & 0x2 + */ + /* totally delete all servers and start afresh */ if (state & 0x2) { @@ -730,12 +659,23 @@ static void process_announce_request(struct packet_struct *p,char *buf) 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. + + if (strequal(dgram->dest_name, lp_workgroup()) return; ??? + */ + if (!d) return; if (!d->my_interface) return; for (work = d->workgrouplist; work; work = work->next) { + /* 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; @@ -745,89 +685,6 @@ static void process_announce_request(struct packet_struct *p,char *buf) /**************************************************************************** - process a domain logon packet - **************************************************************************/ -void process_logon_packet(struct packet_struct *p,char *buf,int len) -{ - struct dgram_packet *dgram = &p->packet.dgram; - struct in_addr ip = dgram->header.source_ip; - struct subnet_record *d = find_subnet(ip); - char *logname,*q; - char *reply_name; - BOOL add_slashes = False; - pstring outbuf; - int code,reply_code; - struct work_record *work; - - if (!d) return; - - if (!(work = find_workgroupstruct(d,dgram->dest_name.name, False))) - return; - - if (!lp_domain_logons()) { - DEBUG(3,("No domain logons\n")); - return; - } - if (!listening_name(work, &dgram->dest_name)) - { - DEBUG(4,("Not listening to that domain\n")); - return; - } - - code = SVAL(buf,0); - switch (code) { - case 0: - { - char *machine = buf+2; - char *user = skip_string(machine,1); - logname = skip_string(user,1); - reply_code = 6; - reply_name = myname; - add_slashes = True; - DEBUG(3,("Domain login request from %s(%s) user=%s\n", - machine,inet_ntoa(p->ip),user)); - } - break; - case 7: - { - char *machine = buf+2; - logname = skip_string(machine,1); - reply_code = 7; - reply_name = lp_domain_controller(); - if (!*reply_name) { - DEBUG(3,("No domain controller configured\n")); - return; - } - DEBUG(3,("GETDC request from %s(%s)\n", - machine,inet_ntoa(p->ip))); - } - break; - default: - DEBUG(3,("Unknown domain request %d\n",code)); - return; - } - - bzero(outbuf,sizeof(outbuf)); - q = outbuf; - SSVAL(q,0,reply_code); - q += 2; - if (add_slashes) { - strcpy(q,"\\\\"); - q += 2; - } - StrnCpy(q,reply_name,16); - strupper(q); - q = skip_string(q,1); - SSVAL(q,0,0xFFFF); - q += 2; - - send_mailslot_reply(logname,ClientDGRAM,outbuf,PTR_DIFF(q,outbuf), - myname,&dgram->source_name.name[0],0x20,0,p->ip, - *iface_ip(p->ip)); -} - - -/**************************************************************************** depending on what announce has been made, we are only going to accept certain types of name announce. XXXX untested code @@ -988,11 +845,16 @@ void process_dgram(struct packet_struct *p) if (len <= 0) return; - if (strequal(smb_buf(buf),"\\MAILSLOT\\BROWSE")) - { + /* datagram packet received for the browser mailslot */ + if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) { process_browse_packet(p,buf2,len); - } else if (strequal(smb_buf(buf),"\\MAILSLOT\\NET\\NETLOGON")) { + return; + } + + /* datagram packet received for the domain log on mailslot */ + if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) { process_logon_packet(p,buf2,len); + return; } } |