Unix SMB/Netbios implementation.
Version 1.9.
NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1995
+ Copyright (C) Andrew Tridgell 1994-1996
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
*/
#include "includes.h"
-#include "loadparm.h"
-#include "localnet.h"
+
+extern int ClientNMB;
+extern int ClientDGRAM;
#define TEST_CODE /* want to debug unknown browse packets */
extern pstring scope;
extern BOOL CanRecurse;
-extern struct in_addr myip;
-extern struct in_addr bcast_ip;
-extern struct in_addr Netmask;
-
extern pstring myname;
extern int ClientNMB;
extern int ClientDGRAM;
-extern int workgroup_count; /* total number of workgroups we know about */
+extern struct in_addr ipzero;
-/* this is our browse cache database */
-extern struct browse_cache_record *browserlist;
+extern int workgroup_count; /* total number of workgroups we know about */
/* this is our domain/workgroup/server database */
-extern struct domain_record *domainlist;
+extern struct subnet_record *subnetlist;
/* machine comment for host announcements */
extern pstring ServerComment;
extern time_t StartupTime;
-#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
-#define AM_BACKUP(work) (work->ServerType & SV_TYPE_BACKUP_BROWSER)
-
-#define MSBROWSE "\001\002__MSBROWSE__\002"
-#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE"
-
-#define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
-
+extern BOOL updatedlists;
/****************************************************************************
tell a server to become a backup browser
name,inet_ntoa(ip),state));
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
- myname,name,0x20,0x1d,ip,myip);
+ myname,name,0x20,0x1d,ip,*iface_ip(ip));
}
**************************************************************************/
void tell_become_backup(void)
{
- struct domain_record *d;
- for (d = domainlist; d; d = d->next)
+ /* 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)
{
struct work_record *work;
for (work = d->workgrouplist; work; work = work->next)
}
}
-/****************************************************************************
-find a server responsible for a workgroup, and sync browse lists
-**************************************************************************/
-static BOOL sync_browse_entry(struct browse_cache_record *b)
-{
- struct domain_record *d;
- struct work_record *work;
- /*
- if (!strequal(serv_name, b->name))
- {
- DEBUG(0, ("browser's netbios name (%s) does not match %s (%s)",
- b->name, inet_ntoa(b->ip), serv_name));
- }
- */
- if (!(d = find_domain(b->ip))) return False;
- if (!(work = find_workgroupstruct(d, b->group, False))) return False;
-
- if (AM_MASTER(work)) {
- /* only try to sync browse lists if we are the master, otherwise
- the net could get a little bit too busy */
- sync_browse_lists(work,b->name,0x20,b->ip);
- }
- b->synced = True;
-
- return 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 < 4) return; /* don't do too many of these at once! */
-
- 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_browse_entry(b))
- {
- /* leave entries (even ones already sync'd) for up to a minute.
- this stops them getting re-sync'd too often */
- 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 == MASTER_SERVER_CHECK)
- {
- /* announce ourselves as a master browser to serv_name */
- do_announce_request(myname, serv_name, ANN_MasterAnnouncement,
- 0x20, 0, ip);
- }
-}
-
-
-/****************************************************************************
-update workgroup database from a name registration
-**************************************************************************/
-void update_from_reg(char *name, int type, struct in_addr ip)
-{
- /* default server type: minimum guess at requirement XXXX */
-
- DEBUG(3,("update from registration: host %s ip %s type %0x\n",
- name, inet_ntoa(ip), type));
-
- /* workgroup types, but not a chat type */
- if (type >= 0x1b && type <= 0x1e)
- {
- struct work_record *work;
- struct domain_record *d;
-
- if (!(d = find_domain(ip))) return;
- if (!(work = find_workgroupstruct(d, name, False))) return;
-
- /* request the server to announce if on our subnet */
- if (ip_equal(bcast_ip, d->bcast_ip)) announce_request(work, ip);
-
- /* domain master type or master browser type */
- if (type == 0x1b || type == 0x1d)
- {
- struct hostent *hp = gethostbyaddr((char*)&ip, sizeof(ip), AF_INET);
- if (hp) {
- /* gethostbyaddr name may not match netbios name but who cares */
- add_browser_entry(hp->h_name, type, work->work_group, 120, ip);
- }
- }
- }
-}
-
-
-/****************************************************************************
- add the default workgroup into my domain
- **************************************************************************/
-void add_my_domains(void)
-{
- /* add or find domain on our local subnet, in the default workgroup */
-
- if (*lp_workgroup() != '*')
- {
- add_domain_entry(bcast_ip,Netmask,lp_workgroup(), True);
- }
-}
-
-
-/****************************************************************************
- 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 domain_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 = domainlist; 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,myip);
-}
-
/*******************************************************************
same context: scope. should check name_type as well, and makes sure
resources. We just have to pass it to smbd (via browser.dat) and let
the client choose using bit masks.
******************************************************************/
-static void process_announce(struct packet_struct *p,int command,char *buf)
+static void process_announce(struct packet_struct *p,uint16 command,char *buf)
{
struct dgram_packet *dgram = &p->packet.dgram;
struct in_addr ip = dgram->header.source_ip;
- struct domain_record *d = find_domain(ip);
-
+ struct subnet_record *d = find_subnet(ip);
int update_count = CVAL(buf,0);
+
int ttl = IVAL(buf,1)/1000;
char *name = buf+5;
int osmajor=CVAL(buf,21);
int osminor=CVAL(buf,22);
uint32 servertype = IVAL(buf,23);
+ uint32 browse_type= CVAL(buf,27);
+ uint32 browse_sig = CVAL(buf,29);
char *comment = buf+31;
+
struct work_record *work;
char *work_name;
char *serv_name = dgram->source_name.name;
-
+ BOOL add = False;
+
comment[43] = 0;
DEBUG(4,("Announce(%d) %s(%x)",command,name,name[15]));
- DEBUG(4,("%s count=%d ttl=%d OS=(%d,%d) type=%08x comment=%s\n",
+ 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,comment));
+ servertype,browse_type,browse_sig,comment));
name[15] = 0;
return;
}
- if (same_context(dgram)) return;
+ if (!strequal(dgram->dest_name.scope,scope )) 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;
+ add = True;
} else {
work_name = dgram->dest_name.name;
}
+
+ /* we need some way of finding out about new workgroups
+ that appear to be sending packets to us. The name_type checks make
+ sure we don't add host names as workgroups */
+ if (command == ANN_HostAnnouncement &&
+ (dgram->dest_name.name_type == 0x1d ||
+ dgram->dest_name.name_type == 0x1e))
+ add = True;
- if (!(work = find_workgroupstruct(d, work_name, False))) return;
+ if (!(work = find_workgroupstruct(d, work_name,add)))
+ return;
DEBUG(4, ("workgroup %s on %s\n", work->work_group, serv_name));
ttl = GET_TTL(ttl);
- /* add them to our browse list */
+ /* add them to our browse list, and update the browse.dat file */
add_server_entry(d,work,name,servertype,ttl,comment,True);
-
+ updatedlists = True;
+
#if 0
/* the tell become backup code is broken, no great harm is done by
disabling it */
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);
{
struct dgram_packet *dgram = &p->packet.dgram;
struct in_addr ip = dgram->header.source_ip;
- struct domain_record *d = find_domain(ip);
- struct domain_record *mydomain = find_domain(bcast_ip);
+ struct subnet_record *d = find_subnet(ip);
+ struct subnet_record *mydomain = find_subnet(*iface_bcast(ip));
char *name = buf;
struct work_record *work;
name[15] = 0;
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)
{
struct dgram_packet *dgram = &p->packet.dgram;
struct in_addr ip = dgram->header.source_ip;
int count = CVAL(buf,0);
- int Index = IVAL(buf,1); /* caller's index representing workgroup */
+ uint32 info = IVAL(buf,1); /* XXXX caller's incremental info */
char *buf1;
- DEBUG(3,("Receive Backup ack for %s from %s total=%d index=%d\n",
+ DEBUG(3,("Receive Backup ack for %s from %s total=%d info=%d\n",
namestr(&dgram->dest_name), inet_ntoa(ip),
- count, Index));
+ count, info));
if (same_context(dgram)) return;
/* 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 domain_record *d;
+ {
+ struct in_addr back_ip;
+ struct subnet_record *d;
- DEBUG(4,("Searching for backup browser %s at %s...\n",
+ 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 */
- back_ip = *interpret_addr2(buf1);
+ /* 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 */
+
+ back_ip = *interpret_addr2(buf1);
- if (zero_ip(back_ip))
+ 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"));
- if ((d = find_domain(back_ip)))
+ /* XXXX function needs work */
+ continue;
+
+ if ((d = find_subnet(back_ip)))
{
- struct domain_record *d1;
- for (d1 = domainlist; d1; d1 = d1->next)
- {
+ 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 == Index)
- {
- queue_netbios_packet(ClientNMB,NMB_QUERY,SERVER_CHECK,
- work->work_group,0x1d,0,
- False,False,back_ip);
+ if (work->token == 0 /* token */)
+ {
+ queue_netbios_packet(d1,ClientNMB,NMB_QUERY,NAME_QUERY_SRV_CHK,
+ work->work_group,0x1d,0,0,
+ False,False,back_ip,back_ip);
return;
- }
+ }
}
- }
+ }
+ }
+ }
+}
+
+
+/****************************************************************************
+ send a backup list response.
+ **************************************************************************/
+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;
+ int count = 0;
+ 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,0x0,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;
+
+ SIVAL(p,1,info); /* the sender's unique info */
+
+ p += 5;
+
+ nameptr = p;
+
+#if 0
+
+ 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);
+ }
+ }
}
+ }
+
+#endif
+
+ 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;
+
+ {
+ int len = PTR_DIFF(p, outbuf);
+ debug_browse_data(outbuf, len);
+ }
+ send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
+ myname,theirname,0x0,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.
{
struct dgram_packet *dgram = &p->packet.dgram;
struct in_addr ip = dgram->header.source_ip;
- struct domain_record *d; /* = find_domain(ip); */
+ struct subnet_record *d;
struct work_record *work;
- int count = CVAL(buf,0);
- int token = SVAL(buf,1); /* sender's key index for the workgroup? */
- int info = SVAL(buf,3); /* XXXX don't know: some sort of info */
+ int token = CVAL(buf,0); /* sender's key index for the workgroup */
+ uint32 info = IVAL(buf,1); /* XXXX don't know: some sort of info */
int name_type = dgram->dest_name.name_type;
if (same_context(dgram)) return;
- if (count <= 0) return;
-
if (name_type != 0x1b && name_type != 0x1d) {
DEBUG(0,("backup request to wrong type %d from %s\n",
name_type,inet_ntoa(ip)));
return;
}
- for (d = domainlist; d; d = d->next)
+ 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 count=%d\n",
- namestr(&dgram->dest_name),inet_ntoa(ip),count));
+ 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,
- count,token,info,name_type,ip);
+ token,info,name_type,ip);
return;
}
}
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.
/* stop being a master but still deal with being a backup browser */
if (state & 0x1)
{
- struct domain_record *d;
- for (d = domainlist; d; d = d->next)
+ 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);
+ become_nonmaster(d,work,SV_TYPE_DOMAIN_MASTER|SV_TYPE_MASTER_BROWSER);
}
}
}
}
+ /* 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)
{
- struct domain_record *d;
- for (d = domainlist; d; d = d->next)
+ 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));
+ for (work=d->workgrouplist;work;work=remove_workgroup(d,work,True));
}
- add_my_domains();
+ add_my_subnets(lp_workgroup());
}
/* stop browsing altogether. i don't think this is a good idea! */
}
}
-
/*******************************************************************
process a announcement request
struct dgram_packet *dgram = &p->packet.dgram;
struct work_record *work;
struct in_addr ip = dgram->header.source_ip;
- struct domain_record *d = find_domain(ip);
+ struct subnet_record *d = find_subnet(ip);
int token = CVAL(buf,0);
char *name = buf+1;
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 (!ip_equal(bcast_ip, d->bcast_ip)) 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;
}
-/****************************************************************************
- 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 domain_record *d = find_domain(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,myip);
- }
-
-
/****************************************************************************
depending on what announce has been made, we are only going to
accept certain types of name announce. XXXX untested code
case ANN_DomainAnnouncement:
case ANN_LocalMasterAnnouncement:
{
+ debug_browse_data(buf, len);
process_announce(p,command,buf+1);
break;
}
case ANN_GetBackupListReq:
{
+ debug_browse_data(buf, len);
process_send_backup_list(p,buf+1);
break;
}
case ANN_GetBackupListResp:
- {
- process_rcv_backup_list(p, buf+1);
- break;
- }
+ {
+ debug_browse_data(buf, len);
+ process_rcv_backup_list(p, buf+1);
+ break;
+ }
case ANN_ResetBrowserState:
{
}
-/****************************************************************************
-process udp 138 datagrams
-****************************************************************************/
-void process_dgram(struct packet_struct *p)
-{
- char *buf;
- char *buf2;
- int len;
- struct dgram_packet *dgram = &p->packet.dgram;
-
- if (dgram->header.msg_type != 0x10 &&
- dgram->header.msg_type != 0x11 &&
- dgram->header.msg_type != 0x12) {
- /* don't process error packets etc yet */
- return;
- }
-
- buf = &dgram->data[0];
- buf -= 4; /* XXXX for the pseudo tcp length -
- someday I need to get rid of this */
-
- if (CVAL(buf,smb_com) != SMBtrans) return;
-
- len = SVAL(buf,smb_vwv11);
- buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
-
- DEBUG(4,("datagram from %s to %s for %s of type %d len=%d\n",
- namestr(&dgram->source_name),namestr(&dgram->dest_name),
- smb_buf(buf),CVAL(buf2,0),len));
-
-
- if (len <= 0) return;
-
- if (strequal(smb_buf(buf),"\\MAILSLOT\\BROWSE"))
- {
- process_browse_packet(p,buf2,len);
- } else if (strequal(smb_buf(buf),"\\MAILSLOT\\NET\\NETLOGON")) {
- process_logon_packet(p,buf2,len);
- }
-}
-