1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-10 01:18:15 +03:00

lots of changes to nmbd

lkcl
This commit is contained in:
Samba Release Account 0001-01-01 00:00:00 +00:00
parent c290c229f9
commit 45d3b26447
19 changed files with 394 additions and 206 deletions

View File

@ -3585,7 +3585,7 @@ static void server_info()
/**************************************************************************** /****************************************************************************
try and browse available connections on a host try and browse available connections on a host
****************************************************************************/ ****************************************************************************/
static BOOL list_servers() static BOOL list_servers(char *wk_grp)
{ {
char *rparam = NULL; char *rparam = NULL;
char *rdata = NULL; char *rdata = NULL;
@ -3600,7 +3600,7 @@ static BOOL list_servers()
p = param; p = param;
SSVAL(p,0,0x68); /* api number */ SSVAL(p,0,0x68); /* api number */
p += 2; p += 2;
strcpy(p,"WrLehDO"); strcpy(p,"WrLehDz");
p = skip_string(p,1); p = skip_string(p,1);
strcpy(p,"B16BBDz"); strcpy(p,"B16BBDz");
@ -3615,6 +3615,11 @@ static BOOL list_servers()
SIVAL(p,0,SV_TYPE_ALL); SIVAL(p,0,SV_TYPE_ALL);
p += 4;
strcpy(p, wk_grp);
p = skip_string(p,1);
if (call_api(PTR_DIFF(p+4,param),0, if (call_api(PTR_DIFF(p+4,param),0,
8,10000, 8,10000,
&rprcnt,&rdrcnt, &rprcnt,&rdrcnt,
@ -3638,9 +3643,10 @@ static BOOL list_servers()
for (i=0;i<count;i++) { for (i=0;i<count;i++) {
char *sname = p2; char *sname = p2;
int comment_offset = IVAL(p2,22) & 0xFFFF; int comment_offset = IVAL(p2,22) & 0xFFFF;
printf("\t%-16.16s %s\n", uint32 stype = IVAL(p2,18);
printf("\t%-16.16s %s %8x\n",
sname, sname,
comment_offset?rdata+comment_offset-converter:""); comment_offset?rdata+comment_offset-converter:"", stype);
ok=True; ok=True;
p2 += 26; p2 += 26;
@ -3651,7 +3657,7 @@ static BOOL list_servers()
if (rparam) {free(rparam); rparam = NULL;} if (rparam) {free(rparam); rparam = NULL;}
if (rdata) {free(rdata); rdata = NULL;} if (rdata) {free(rdata); rdata = NULL;}
SIVAL(p,0,SV_TYPE_DOMAIN_ENUM); SIVAL(p,0,0x7fffffff);
if (call_api(PTR_DIFF(p+4,param),0, if (call_api(PTR_DIFF(p+4,param),0,
8,10000, 8,10000,
@ -3676,9 +3682,10 @@ static BOOL list_servers()
for (i=0;i<count;i++) { for (i=0;i<count;i++) {
char *sname = p2; char *sname = p2;
int comment_offset = IVAL(p2,22) & 0xFFFF; int comment_offset = IVAL(p2,22) & 0xFFFF;
printf("\t%-16.16s %s\n", uint32 stype =IVAL(p2,18);
printf("\t%-16.16s %s %8x\n",
sname, sname,
comment_offset?rdata+comment_offset-converter:""); comment_offset?rdata+comment_offset-converter:"",stype);
ok=True; ok=True;
p2 += 26; p2 += 26;
@ -4391,9 +4398,9 @@ static void usage(char *pname)
sleep(1); sleep(1);
browse_host(True); browse_host(True);
} }
if (!list_servers()) { if (!list_servers(workgroup)) {
sleep(1); sleep(1);
list_servers(); list_servers(workgroup);
} }
send_logout(); send_logout();

View File

@ -85,7 +85,17 @@
enum name_source {STATUS_QUERY, LMHOSTS, REGISTER, SELF, DNS, DNSFAIL}; 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 node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3};
enum packet_type {NMB_PACKET, DGRAM_PACKET}; enum packet_type {NMB_PACKET, DGRAM_PACKET};
enum master_state { MST_NONE, MST_WON, MST_MSB, MST_BROWSER, MST_DOMAIN }; enum master_state
{
MST_NONE,
MST_WON,
MST_MSB,
MST_BROWSER,
MST_DOMAIN_NONE,
MST_DOMAIN_MEM,
MST_DOMAIN_TST,
MST_DOMAIN
};
enum state_type enum state_type
{ {

View File

@ -256,7 +256,7 @@ BOOL ms_browser_name(char *name, int type);
void remove_name(struct subnet_record *d, struct name_record *n); void remove_name(struct subnet_record *d, struct name_record *n);
struct name_record *find_name(struct name_record *n, struct name_record *find_name(struct name_record *n,
struct nmb_name *name, struct nmb_name *name,
int search, struct in_addr ip); int search);
struct name_record *find_name_search(struct subnet_record **d, struct name_record *find_name_search(struct subnet_record **d,
struct nmb_name *name, struct nmb_name *name,
int search, struct in_addr ip); int search, struct in_addr ip);
@ -286,6 +286,7 @@ struct response_record *find_response_record(struct subnet_record **d,
uint16 id); uint16 id);
void remove_old_servers(struct work_record *work, time_t t, void remove_old_servers(struct work_record *work, time_t t,
BOOL remove_all); BOOL remove_all);
struct server_record *find_server(struct work_record *work, char *name);
struct server_record *add_server_entry(struct subnet_record *d, struct server_record *add_server_entry(struct subnet_record *d,
struct work_record *work, struct work_record *work,
char *name,int servertype, char *name,int servertype,
@ -320,12 +321,13 @@ void run_elections(void);
void process_election(struct packet_struct *p,char *buf); void process_election(struct packet_struct *p,char *buf);
BOOL check_elections(void); BOOL check_elections(void);
void process_logon_packet(struct packet_struct *p,char *buf,int len); void process_logon_packet(struct packet_struct *p,char *buf,int len);
void debug_browse_data(char *outbuf, int len);
void initiate_netbios_packet(uint16 *id, void initiate_netbios_packet(uint16 *id,
int fd,int quest_type,char *name,int name_type, int fd,int quest_type,char *name,int name_type,
int nb_flags,BOOL bcast,BOOL recurse, int nb_flags,BOOL bcast,BOOL recurse,
struct in_addr to_ip); struct in_addr to_ip);
void reply_netbios_packet(struct packet_struct *p1,int trn_id, void reply_netbios_packet(struct packet_struct *p1,int trn_id,
int rcode,int opcode, BOOL recurse, int rcode, int rcv_code, int opcode, BOOL recurse,
struct nmb_name *rr_name,int rr_type,int rr_class,int ttl, struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
char *data,int len); char *data,int len);
void queue_packet(struct packet_struct *packet); void queue_packet(struct packet_struct *packet);
@ -357,11 +359,12 @@ void add_my_names(void);
void remove_my_names(); void remove_my_names();
void refresh_my_names(time_t t); void refresh_my_names(time_t t);
void query_refresh_names(void); void query_refresh_names(void);
void add_name_respond(struct subnet_record *d, int fd, uint16 response_id, void add_name_respond(struct subnet_record *d, int fd, struct in_addr from_ip,
uint16 response_id,
struct nmb_name *name, struct nmb_name *name,
int nb_flags, int ttl, struct in_addr register_ip, int nb_flags, int ttl, struct in_addr register_ip,
BOOL new_owner, struct in_addr reply_to_ip); BOOL new_owner, struct in_addr reply_to_ip);
void send_name_response(int fd, void send_name_response(int fd, struct in_addr from_ip,
int name_trn_id, int opcode, BOOL success, BOOL recurse, int name_trn_id, int opcode, BOOL success, BOOL recurse,
struct nmb_name *reply_name, int nb_flags, int ttl, struct nmb_name *reply_name, int nb_flags, int ttl,
struct in_addr ip); struct in_addr ip);
@ -369,6 +372,7 @@ void reply_name_release(struct packet_struct *p);
void reply_name_reg(struct packet_struct *p); void reply_name_reg(struct packet_struct *p);
void reply_name_status(struct packet_struct *p); void reply_name_status(struct packet_struct *p);
void reply_name_query(struct packet_struct *p); void reply_name_query(struct packet_struct *p);
void debug_state_type(int state);
void response_netbios_packet(struct packet_struct *p); void response_netbios_packet(struct packet_struct *p);
void reset_server(char *name, int state, struct in_addr ip); void reset_server(char *name, int state, struct in_addr ip);
void tell_become_backup(void); void tell_become_backup(void);

View File

@ -1 +1 @@
#define VERSION "1.9.16alpha10" #define VERSION "1.9.16a10"

View File

@ -173,6 +173,8 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
continue; continue;
} }
debug_nmb_packet(p2);
_interpret_node_status(&nmb2->answers->rdata[0], master,rname); _interpret_node_status(&nmb2->answers->rdata[0], master,rname);
free_packet(p2); free_packet(p2);
return(True); return(True);
@ -266,6 +268,8 @@ BOOL name_query(int fd,char *name,int name_type,
continue; continue;
} }
debug_nmb_packet(p2);
if (nmb2->header.opcode != 0 || if (nmb2->header.opcode != 0 ||
nmb2->header.nm_flags.bcast || nmb2->header.nm_flags.bcast ||
nmb2->header.rcode || nmb2->header.rcode ||

View File

@ -48,7 +48,7 @@ extern pstring ServerComment;
extern int updatecount; extern int updatecount;
extern int workgroup_count; extern int workgroup_count;
/* what server type are we currently */ extern struct in_addr ipgrp;
/**************************************************************************** /****************************************************************************
send a announce request to the local net send a announce request to the local net
@ -146,12 +146,19 @@ void announce_backup(void)
char *p; char *p;
struct subnet_record *d1; struct subnet_record *d1;
int tok; int tok;
static uint32 id_count = 0;
if (!lastrun) lastrun = t; if (!lastrun) lastrun = t;
#if 1
if (t < lastrun + 1 * 60)
#else
if (t < lastrun + CHECK_TIME_ANNOUNCE_BACKUP * 60) if (t < lastrun + CHECK_TIME_ANNOUNCE_BACKUP * 60)
#endif
return; return;
lastrun = t; lastrun = t;
DEBUG(4,("checking backups...\n"));
for (tok = 0; tok <= workgroup_count; tok++) for (tok = 0; tok <= workgroup_count; tok++)
{ {
for (d1 = subnetlist; d1; d1 = d1->next) for (d1 = subnetlist; d1; d1 = d1->next)
@ -178,14 +185,15 @@ void announce_backup(void)
bzero(outbuf,sizeof(outbuf)); bzero(outbuf,sizeof(outbuf));
p = outbuf; p = outbuf;
CVAL(p,0) = ANN_GetBackupListReq; CVAL(p,0) = ANN_GetBackupListReq;
p++; CVAL(p,1) = work->token; /* workgroup unique key index */
SIVAL(p,2,++id_count); /* unique count. not that we use it! */
CVAL(p,0) = 1; /* count? */
SIVAL(p,1,work->token); /* workgroup unique key index */ p += 6;
p += 5;
p++;
debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
if (!AM_DOMCTL(work)) if (!AM_DOMCTL(work))
{ {
/* only ask for a list of backup domain controllers /* only ask for a list of backup domain controllers
@ -199,6 +207,8 @@ void announce_backup(void)
*iface_ip(d->bcast_ip)); *iface_ip(d->bcast_ip));
} }
debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
if (!AM_MASTER(work)) if (!AM_MASTER(work))
{ {
/* only ask for a list of master browsers if we /* only ask for a list of master browsers if we
@ -208,7 +218,7 @@ void announce_backup(void)
ClientDGRAM,outbuf, ClientDGRAM,outbuf,
PTR_DIFF(p,outbuf), PTR_DIFF(p,outbuf),
myname, work->work_group, myname, work->work_group,
0x0,0x1b,d->bcast_ip, 0x0,0x1d,d->bcast_ip,
*iface_ip(d->bcast_ip)); *iface_ip(d->bcast_ip));
} }
} }
@ -246,13 +256,15 @@ static void do_announce_host(int command,
CVAL(p,22) = 0x02; /* minor version */ CVAL(p,22) = 0x02; /* minor version */
SIVAL(p,23,server_type); SIVAL(p,23,server_type);
SSVAL(p,27,0xaa55); /* browse signature */ SSVAL(p,27,0x010f); /* browse version: got from NT/AS 4.00 */
SSVAL(p,29,0x001f); /* browse version: CIFS draft 1.0 indicates 0x001f */ SSVAL(p,29,0xaa55); /* browse signature */
strcpy(p+31,server_comment); strcpy(p+31,server_comment);
p += 31; p += 31;
p = skip_string(p,1); p = skip_string(p,1);
debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
/* send the announcement */ /* send the announcement */
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf, send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
PTR_DIFF(p,outbuf), PTR_DIFF(p,outbuf),
@ -290,6 +302,8 @@ void remove_my_servers(void)
void announce_server(struct subnet_record *d, struct work_record *work, void announce_server(struct subnet_record *d, struct work_record *work,
char *name, char *comment, time_t ttl, int server_type) char *name, char *comment, time_t ttl, int server_type)
{ {
uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_SERVER_UNIX;
if (AM_MASTER(work)) if (AM_MASTER(work))
{ {
DEBUG(3,("sending local master announce to %s for %s(1e)\n", DEBUG(3,("sending local master announce to %s for %s(1e)\n",
@ -307,11 +321,15 @@ void announce_server(struct subnet_record *d, struct work_record *work,
/* XXXX should we do a domain-announce-kill? */ /* XXXX should we do a domain-announce-kill? */
if (server_type != 0) if (server_type != 0)
{ {
if (AM_DOMCTL(work)) {
domain_type |= SV_TYPE_DOMAIN_CTRL;
}
do_announce_host(ANN_DomainAnnouncement, do_announce_host(ANN_DomainAnnouncement,
work->work_group, 0x00, d->myip, name , 0x00, d->myip,
MSBROWSE , 0x01, d->bcast_ip, MSBROWSE, 0x01, d->bcast_ip,
ttl*1000, ttl*1000,
name, server_type ? SV_TYPE_DOMAIN_ENUM : 0, comment); work->work_group, server_type ? domain_type : 0,
comment);
} }
} }
else else
@ -345,6 +363,8 @@ void announce_host(void)
{ {
struct work_record *work; struct work_record *work;
if (ip_equal(d->bcast_ip, ipgrp)) continue;
for (work = d->workgrouplist; work; work = work->next) for (work = d->workgrouplist; work; work = work->next)
{ {
uint32 stype = work->ServerType; uint32 stype = work->ServerType;

View File

@ -120,7 +120,7 @@ void remove_name(struct subnet_record *d, struct name_record *n)
**************************************************************************/ **************************************************************************/
struct name_record *find_name(struct name_record *n, struct name_record *find_name(struct name_record *n,
struct nmb_name *name, struct nmb_name *name,
int search, struct in_addr ip) int search)
{ {
struct name_record *ret; struct name_record *ret;
@ -132,12 +132,7 @@ struct name_record *find_name(struct name_record *n,
if ((search&FIND_SELF) == FIND_SELF && ret->source != SELF) if ((search&FIND_SELF) == FIND_SELF && ret->source != SELF)
continue; continue;
/* zero ip is either samba's ip or a way of finding a return ret;
name without needing to know the ip address */
if (zero_ip(ip) || ip_equal(ip, ret->ip))
{
return ret;
}
} }
} }
return NULL; return NULL;
@ -161,7 +156,9 @@ struct name_record *find_name_search(struct subnet_record **d,
{ {
if (*d != NULL) if (*d != NULL)
{ {
return find_name((*d)->namelist, name, search, ip); DEBUG(4,("find_name on local: %s %s search %x\n",
namestr(name),inet_ntoa(ip), search));
return find_name((*d)->namelist, name, search);
} }
else else
{ {
@ -180,7 +177,9 @@ struct name_record *find_name_search(struct subnet_record **d,
if (*d == NULL) return NULL; if (*d == NULL) return NULL;
return find_name((*d)->namelist, name, search, ip); DEBUG(4,("find_name on WINS: %s %s search %x\n",
namestr(name),inet_ntoa(ip), search));
return find_name((*d)->namelist, name, search);
} }

View File

@ -102,6 +102,26 @@ static void add_server(struct work_record *work,struct server_record *s)
} }
/****************************************************************************
find a server in a server list.
**************************************************************************/
struct server_record *find_server(struct work_record *work, char *name)
{
struct server_record *ret;
if (!work) return NULL;
for (ret = work->serverlist; ret; ret = ret->next)
{
if (strequal(ret->serv.name,name))
{
return ret;
}
}
return NULL;
}
/**************************************************************************** /****************************************************************************
add a server entry add a server entry
****************************************************************************/ ****************************************************************************/
@ -115,33 +135,30 @@ struct server_record *add_server_entry(struct subnet_record *d,
struct server_record *s; struct server_record *s;
if (name[0] == '*') if (name[0] == '*')
{ {
return (NULL); return (NULL);
} }
for (s = work->serverlist; s; s = s->next)
{
if (strequal(name,s->serv.name)) break;
}
s = find_server(work, name);
if (s && !replace) if (s && !replace)
{ {
DEBUG(4,("Not replacing %s\n",name)); DEBUG(4,("Not replacing %s\n",name));
return(s); return(s);
} }
if (!s || s->serv.type != servertype || !strequal(s->serv.comment, comment)) if (!s || s->serv.type != servertype || !strequal(s->serv.comment, comment))
updatedlists=True; updatedlists=True;
if (!s) if (!s)
{ {
newentry = True; newentry = True;
s = (struct server_record *)malloc(sizeof(*s)); s = (struct server_record *)malloc(sizeof(*s));
if (!s) return(NULL); if (!s) return(NULL);
bzero((char *)s,sizeof(*s)); bzero((char *)s,sizeof(*s));
} }
if (d->my_interface && strequal(lp_workgroup(),work->work_group)) if (d->my_interface && strequal(lp_workgroup(),work->work_group))

View File

@ -41,6 +41,7 @@ extern pstring scope;
extern pstring myname; extern pstring myname;
extern struct in_addr ipzero; extern struct in_addr ipzero;
extern struct in_addr ipgrp;
/* machine comment for host announcements */ /* machine comment for host announcements */
extern pstring ServerComment; extern pstring ServerComment;
@ -201,21 +202,27 @@ void name_unregister_work(struct subnet_record *d, char *name, int name_type)
void name_register_work(struct subnet_record *d, char *name, int name_type, void name_register_work(struct subnet_record *d, char *name, int name_type,
int nb_flags, time_t ttl, struct in_addr ip, BOOL bcast) int nb_flags, time_t ttl, struct in_addr ip, BOOL bcast)
{ {
enum name_source source = ismyip(ip) ? SELF : REGISTER; enum name_source source = (ismyip(ip) || ip_equal(ip, ipzero)) ?
SELF : REGISTER;
if (source == SELF) if (source == SELF)
{ {
struct work_record *work = find_workgroupstruct(d, lp_workgroup(), False); struct work_record *work = find_workgroupstruct(d, lp_workgroup(), False);
if (work && work->state != MST_NONE) add_netbios_entry(d,name,name_type,nb_flags,ttl,source,ip,True,!bcast);
if (work)
{ {
/* samba is in the process of working towards master browser-ness. if (work->state != MST_NONE)
initiate the next stage. {
*/ /* samba is in the process of working towards master browser-ness.
become_master(d, work); initiate the next stage.
*/
become_master(d, work);
return;
}
} }
} }
add_netbios_entry(d,name,name_type,nb_flags,ttl,source,ip,True,!bcast);
} }
@ -248,8 +255,8 @@ void become_master(struct subnet_record *d, struct work_record *work)
if (!work) return; if (!work) return;
DEBUG(2,("Becoming master for %s (currently at stage %d)\n", DEBUG(2,("Becoming master for %s %s (currently at stage %d)\n",
work->work_group,work->state)); work->work_group,inet_ntoa(d->bcast_ip),work->state));
switch (work->state) switch (work->state)
{ {
@ -298,10 +305,50 @@ void become_master(struct subnet_record *d, struct work_record *work)
/* ask all servers on our local net to announce to us */ /* ask all servers on our local net to announce to us */
announce_request(work, d->bcast_ip); announce_request(work, d->bcast_ip);
} }
break;
}
case MST_BROWSER:
{
/* don't have to do anything: just report success */
DEBUG(3,("3rd stage: become master browser!\n"));
break;
}
case MST_DOMAIN_NONE:
{
if (lp_domain_master()) if (lp_domain_master())
{ {
DEBUG(3,("third stage: register as domain master\n")); work->state = MST_DOMAIN_MEM; /* ... become domain member */
DEBUG(3,("domain first stage: register as domain member\n"));
/* add domain member name */
add_my_name_entry(d,work->work_group,0x1e,NB_ACTIVE );
/* DON'T do anything else after calling add_my_name_entry() */
return;
}
else
{
DEBUG(4,("samba not configured as a domain master.\n"));
}
break;
}
case MST_DOMAIN_MEM:
{
if (lp_domain_master())
{
work->state = MST_DOMAIN_TST; /* ... possibly become domain master */
DEBUG(3,("domain second stage: register as domain master\n"));
if (lp_domain_logons())
{
work->ServerType |= SV_TYPE_DOMAIN_MEMBER;
add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
}
/* add domain master name */ /* add domain master name */
add_my_name_entry(d,work->work_group,0x1b,NB_ACTIVE ); add_my_name_entry(d,work->work_group,0x1b,NB_ACTIVE );
@ -311,34 +358,62 @@ void become_master(struct subnet_record *d, struct work_record *work)
} }
else else
{ {
DEBUG(3,("samba not configured as a domain master: no third stage.\n")); DEBUG(4,("samba not configured as a domain master.\n"));
} }
break; break;
} }
case MST_BROWSER: /* while we were still a master browser... */
case MST_DOMAIN_TST: /* while we were still a master browser... */
{ {
/* update our server status */ /* update our server status */
if (lp_domain_master()) if (lp_domain_master())
{ {
DEBUG(3,("fourth stage: samba is now a domain master.\n")); struct subnet_record *d1;
uint32 update_type = 0;
DEBUG(3,("domain third stage: samba is now a domain master.\n"));
work->state = MST_DOMAIN; /* ... registering WORKGROUP(1b) succeeded */ work->state = MST_DOMAIN; /* ... registering WORKGROUP(1b) succeeded */
work->ServerType |= SV_TYPE_DOMAIN_MASTER; update_type |= SV_TYPE_DOMAIN_MASTER;
if (lp_domain_logons()) if (lp_domain_logons())
{ {
work->ServerType |= SV_TYPE_DOMAIN_CTRL; update_type |= SV_TYPE_DOMAIN_CTRL;
work->ServerType |= SV_TYPE_DOMAIN_MEMBER;
} }
work->ServerType |= update_type;
add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True); add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
for (d1 = subnetlist; d1; d1 = d1->next)
{
struct work_record *w;
if (ip_equal(d1->bcast_ip, d->bcast_ip)) continue;
for (w = d1->workgrouplist; w; w = w->next)
{
struct server_record *s = find_server(w, myname);
if (strequal(w->work_group, work->work_group))
{
w->ServerType |= update_type;
}
if (s)
{
s->serv.type |= update_type;
DEBUG(4,("found server %s on %s: update to %8x\n",
s->serv.name, inet_ntoa(d1->bcast_ip),
s->serv.type));
}
}
}
} }
break; break;
} }
case MST_DOMAIN: case MST_DOMAIN:
{ {
/* nothing else to become, at the moment: we are top-dog. */ /* don't have to do anything: just report success */
DEBUG(3,("fifth stage: there isn't one yet!\n")); DEBUG(3,("fifth stage: there isn't one yet!\n"));
break; break;
} }
@ -414,16 +489,16 @@ void run_elections(void)
lastime = t; lastime = t;
for (d = subnetlist; d; d = d->next) for (d = subnetlist; d; d = d->next)
{ {
struct work_record *work; struct work_record *work;
for (work = d->workgrouplist; work; work = work->next) for (work = d->workgrouplist; work; work = work->next)
{ {
if (work->RunningElection) if (work->RunningElection)
{ {
send_election(d,work->work_group, work->ElectionCriterion, send_election(d,work->work_group, work->ElectionCriterion,
t-StartupTime,myname); t-StartupTime,myname);
if (work->ElectionCount++ >= 4) if (work->ElectionCount++ >= 4)
{ {
/* I won! now what :-) */ /* I won! now what :-) */
DEBUG(2,(">>> Won election on %s %s <<<\n", DEBUG(2,(">>> Won election on %s %s <<<\n",
@ -434,9 +509,9 @@ void run_elections(void)
become_master(d, work); become_master(d, work);
} }
} }
} }
} }
} }

View File

@ -40,6 +40,40 @@ extern struct in_addr ipgrp;
static uint16 name_trn_id=0; static uint16 name_trn_id=0;
/***************************************************************************
updates the unique transaction identifier
**************************************************************************/
void debug_browse_data(char *outbuf, int len)
{
int i,j;
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"));
}
}
/*************************************************************************** /***************************************************************************
updates the unique transaction identifier updates the unique transaction identifier
**************************************************************************/ **************************************************************************/
@ -138,7 +172,7 @@ void initiate_netbios_packet(uint16 *id,
reply to a netbios name packet reply to a netbios name packet
****************************************************************************/ ****************************************************************************/
void reply_netbios_packet(struct packet_struct *p1,int trn_id, void reply_netbios_packet(struct packet_struct *p1,int trn_id,
int rcode,int opcode, BOOL recurse, int rcode, int rcv_code, int opcode, BOOL recurse,
struct nmb_name *rr_name,int rr_type,int rr_class,int ttl, struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
char *data,int len) char *data,int len)
{ {
@ -150,7 +184,7 @@ void reply_netbios_packet(struct packet_struct *p1,int trn_id,
p = *p1; p = *p1;
switch (rr_type) switch (rcv_code)
{ {
case NMB_STATUS: case NMB_STATUS:
{ {
@ -539,5 +573,9 @@ BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
p.timestamp = time(NULL); p.timestamp = time(NULL);
p.packet_type = DGRAM_PACKET; p.packet_type = DGRAM_PACKET;
DEBUG(4,("send mailslot %s from %s %s", mailslot,
inet_ntoa(src_ip),namestr(&dgram->source_name)));
DEBUG(4,("to %s %s\n", inet_ntoa(dest_ip),namestr(&dgram->dest_name)));
return(send_packet(&p)); return(send_packet(&p));
} }

View File

@ -45,6 +45,8 @@ static void dead_netbios_entry(struct subnet_record *d,
DEBUG(3,("Removing dead netbios entry for %s %s (num_msgs=%d)\n", DEBUG(3,("Removing dead netbios entry for %s %s (num_msgs=%d)\n",
inet_ntoa(n->send_ip), namestr(&n->name), n->num_msgs)); inet_ntoa(n->send_ip), namestr(&n->name), n->num_msgs));
debug_state_type(n->state);
switch (n->state) switch (n->state)
{ {
case NAME_QUERY_CONFIRM: case NAME_QUERY_CONFIRM:
@ -113,7 +115,7 @@ static void dead_netbios_entry(struct subnet_record *d,
wanted the unique name and tell them that they can have it wanted the unique name and tell them that they can have it
*/ */
add_name_respond(d,n->fd, n->response_id ,&n->name, add_name_respond(d,n->fd,d->myip, n->response_id ,&n->name,
n->nb_flags, GET_TTL(0), n->nb_flags, GET_TTL(0),
n->reply_to_ip, False, n->reply_to_ip); n->reply_to_ip, False, n->reply_to_ip);
@ -140,7 +142,7 @@ static void dead_netbios_entry(struct subnet_record *d,
/* IMPORTANT: see response_name_reg() */ /* IMPORTANT: see response_name_reg() */
name_register_work(d,n->name.name,n->name.name_type, name_register_work(d,n->name.name,n->name.name_type,
n->nb_flags, n->ttl, n->send_ip, n->bcast); n->nb_flags, n->ttl, n->reply_to_ip, n->bcast);
} }
else else
{ {

View File

@ -131,18 +131,6 @@ samba should take this into account (see rfc1001.txt 10.3).
remove_name_entry() issues this samba 'state' remove_name_entry() issues this samba 'state'
response_name_rel() deals with responses to NAME_RELEASE. response_name_rel() deals with responses to NAME_RELEASE.
- NAME_REGISTER_CHALLENGE
when a samba 'state' of type NAME_REGISTER_CHALLENGE is sent, and a
response is not received, it is assumed that the server being queried
is either dead, deaf or unreachable. the host that wanted this
unique name is then informed that it can have it (the name query
challenge went unanswered) and that its registration of this name
did in fact succeed.
reply_name_reg() issues this samba 'state'
response_name_query_register() deals with responses.
- NAME_REGISTER - NAME_REGISTER
when a samba 'state' of type NAME_REGISTER is sent, and a response is when a samba 'state' of type NAME_REGISTER is sent, and a response is

View File

@ -37,6 +37,7 @@ extern int DEBUGLEVEL;
extern pstring scope; extern pstring scope;
extern pstring myname; extern pstring myname;
extern pstring ServerComment;
extern struct in_addr ipzero; extern struct in_addr ipzero;
extern struct in_addr ipgrp; extern struct in_addr ipgrp;
@ -124,7 +125,7 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
it must be re-registered, rather than just registered */ it must be re-registered, rather than just registered */
make_nmb_name(&n, name, type, scope); make_nmb_name(&n, name, type, scope);
if (find_name(d->namelist, &n, SELF, ipzero)) if (find_name(d->namelist, &n, SELF))
re_reg = True; re_reg = True;
/* XXXX BUG: if samba is offering WINS support, it should still add the /* XXXX BUG: if samba is offering WINS support, it should still add the
@ -141,6 +142,7 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
actually be true actually be true
*/ */
DEBUG(4,("samba as WINS server adding: "));
/* this will call add_netbios_entry() */ /* this will call add_netbios_entry() */
name_register_work(d, name, type, nb_flags,0, ipzero, False); name_register_work(d, name, type, nb_flags,0, ipzero, False);
} }
@ -155,10 +157,11 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
} }
else else
{ {
/* broadcast the packet, but it comes from ipzero */
queue_netbios_packet(d,ClientNMB, queue_netbios_packet(d,ClientNMB,
re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER, re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
name, type, nb_flags, GET_TTL(0), name, type, nb_flags, GET_TTL(0),
True, True, d->bcast_ip, d->bcast_ip); True, True, d->bcast_ip, ipzero);
} }
} }
@ -181,9 +184,10 @@ void add_my_names(void)
for (d = subnetlist; d; d = d->next) for (d = subnetlist; d; d = d->next)
{ {
if (!d->my_interface) continue; BOOL wins_iface = ip_equal(d->bcast_ip, ipgrp);
if (!d->my_interface && !wins_iface) continue;
/* these names need to be refreshed with the WINS server */
add_my_name_entry(d, myname,0x20,NB_ACTIVE); add_my_name_entry(d, myname,0x20,NB_ACTIVE);
add_my_name_entry(d, myname,0x03,NB_ACTIVE); add_my_name_entry(d, myname,0x03,NB_ACTIVE);
add_my_name_entry(d, myname,0x00,NB_ACTIVE); add_my_name_entry(d, myname,0x00,NB_ACTIVE);
@ -195,11 +199,20 @@ void add_my_names(void)
add_netbios_entry(d,"__SAMBA__",0x20,NB_ACTIVE,0,SELF,ip,False,wins); add_netbios_entry(d,"__SAMBA__",0x20,NB_ACTIVE,0,SELF,ip,False,wins);
add_netbios_entry(d,"__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip,False,wins); add_netbios_entry(d,"__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip,False,wins);
if (lp_domain_logons() && lp_domain_master()) { if (!wins_iface && lp_domain_logons() && lp_domain_master()) {
/* XXXX the 0x1c is apparently something to do with domain logons */ /* XXXX the 0x1c is apparently something to do with domain logons */
add_my_name_entry(d, my_workgroup(),0x1c,NB_ACTIVE|NB_GROUP); add_my_name_entry(d, my_workgroup(),0x1c,NB_ACTIVE|NB_GROUP);
} }
} }
if (lp_domain_master() && (d = find_subnet(ipgrp)))
{
struct work_record *work = find_workgroupstruct(d, lp_workgroup(), True);
if (work && work->state == MST_NONE)
{
work->state = MST_DOMAIN_NONE;
become_master(d, work);
}
}
} }

View File

@ -42,7 +42,8 @@ extern struct in_addr ipgrp;
/**************************************************************************** /****************************************************************************
add a netbios entry. respond to the (possibly new) owner. add a netbios entry. respond to the (possibly new) owner.
**************************************************************************/ **************************************************************************/
void add_name_respond(struct subnet_record *d, int fd, uint16 response_id, void add_name_respond(struct subnet_record *d, int fd, struct in_addr from_ip,
uint16 response_id,
struct nmb_name *name, struct nmb_name *name,
int nb_flags, int ttl, struct in_addr register_ip, int nb_flags, int ttl, struct in_addr register_ip,
BOOL new_owner, struct in_addr reply_to_ip) BOOL new_owner, struct in_addr reply_to_ip)
@ -52,7 +53,7 @@ void add_name_respond(struct subnet_record *d, int fd, uint16 response_id,
nb_flags,ttl,REGISTER,register_ip,False,True); nb_flags,ttl,REGISTER,register_ip,False,True);
/* reply yes or no to the host that requested the name */ /* reply yes or no to the host that requested the name */
send_name_response(fd, response_id, NMB_REG, send_name_response(fd,from_ip, response_id, NMB_REG,
new_owner, True, new_owner, True,
name, nb_flags, ttl, reply_to_ip); name, nb_flags, ttl, reply_to_ip);
} }
@ -60,7 +61,7 @@ void add_name_respond(struct subnet_record *d, int fd, uint16 response_id,
/**************************************************************************** /****************************************************************************
send a registration / release response: pos/neg send a registration / release response: pos/neg
**************************************************************************/ **************************************************************************/
void send_name_response(int fd, void send_name_response(int fd, struct in_addr from_ip,
int name_trn_id, int opcode, BOOL success, BOOL recurse, int name_trn_id, int opcode, BOOL success, BOOL recurse,
struct nmb_name *reply_name, int nb_flags, int ttl, struct nmb_name *reply_name, int nb_flags, int ttl,
struct in_addr ip) struct in_addr ip)
@ -85,14 +86,14 @@ void send_name_response(int fd,
rdata[1] = 0; rdata[1] = 0;
putip(&rdata[2],(char *)&ip); putip(&rdata[2],(char *)&ip);
p.ip = ip; p.ip = from_ip;
p.port = NMB_PORT; p.port = NMB_PORT;
p.fd = fd; p.fd = fd;
p.timestamp = time(NULL); p.timestamp = time(NULL);
p.packet_type = NMB_PACKET; p.packet_type = NMB_PACKET;
reply_netbios_packet(&p,name_trn_id, reply_netbios_packet(&p,name_trn_id,
rcode,opcode,recurse, rcode,opcode,opcode,recurse,
reply_name, 0x20, 0x1, reply_name, 0x20, 0x1,
ttl, ttl,
rdata, 6); rdata, 6);
@ -145,7 +146,7 @@ void reply_name_release(struct packet_struct *p)
if (bcast) return; if (bcast) return;
/* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */ /* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
send_name_response(p->fd, nmb->header.name_trn_id, NMB_REL, send_name_response(p->fd,p->ip, nmb->header.name_trn_id, NMB_REL,
success, False, success, False,
&nmb->question.question_name, nb_flags, 0, ip); &nmb->question.question_name, nb_flags, 0, ip);
} }
@ -285,7 +286,7 @@ void reply_name_reg(struct packet_struct *p)
/* send WAIT ACKNOWLEDGEMENT see rfc1002.txt 4.2.16 */ /* send WAIT ACKNOWLEDGEMENT see rfc1002.txt 4.2.16 */
reply_netbios_packet(p,nmb->header.name_trn_id, reply_netbios_packet(p,nmb->header.name_trn_id,
0,NMB_WAIT_ACK,False, 0,NMB_WAIT_ACK,NMB_WAIT_ACK,False,
reply_name, 0x0a, 0x01, reply_name, 0x0a, 0x01,
15*1000, /* 15 seconds long enough to wait? */ 15*1000, /* 15 seconds long enough to wait? */
rdata, 2); rdata, 2);
@ -302,7 +303,7 @@ void reply_name_reg(struct packet_struct *p)
or an END-NODE CHALLENGE REGISTRATION RESPONSE see rfc1002.txt 4.2.7 or an END-NODE CHALLENGE REGISTRATION RESPONSE see rfc1002.txt 4.2.7
*/ */
send_name_response(p->fd, nmb->header.name_trn_id, NMB_REG, send_name_response(p->fd,p->ip, nmb->header.name_trn_id, NMB_REG,
success, True, success, True,
reply_name, nb_flags, ttl, ip); reply_name, nb_flags, ttl, ip);
} }
@ -322,6 +323,7 @@ void reply_name_status(struct packet_struct *p)
int names_added; int names_added;
struct name_record *n; struct name_record *n;
struct subnet_record *d = NULL; struct subnet_record *d = NULL;
int search = FIND_SELF;
BOOL bcast = nmb->header.nm_flags.bcast; BOOL bcast = nmb->header.nm_flags.bcast;
@ -335,9 +337,13 @@ void reply_name_status(struct packet_struct *p)
DEBUG(3,("Name status for name %s %s\n", DEBUG(3,("Name status for name %s %s\n",
namestr(&nmb->question.question_name), inet_ntoa(p->ip))); namestr(&nmb->question.question_name), inet_ntoa(p->ip)));
if (bcast)
search |= FIND_WINS;
else
search |= FIND_LOCAL;
n = find_name_search(&d, &nmb->question.question_name, n = find_name_search(&d, &nmb->question.question_name,
FIND_SELF|FIND_LOCAL, search, p->ip);
p->ip);
if (!n) return; if (!n) return;
@ -396,7 +402,7 @@ void reply_name_status(struct packet_struct *p)
/* Send a POSITIVE NAME STATUS RESPONSE */ /* Send a POSITIVE NAME STATUS RESPONSE */
reply_netbios_packet(p,nmb->header.name_trn_id, reply_netbios_packet(p,nmb->header.name_trn_id,
0,0,True, 0,NMB_STATUS,0,True,
&nmb->question.question_name, &nmb->question.question_name,
nmb->question.question_type, nmb->question.question_type,
nmb->question.question_class, nmb->question.question_class,
@ -452,15 +458,26 @@ void reply_name_query(struct packet_struct *p)
if (name_type == 0x1b) if (name_type == 0x1b)
{ {
/* even if it's a broadcast, we don't ignore queries for PDC names */ /* even if it's a broadcast, we don't ignore queries for PDC names */
search |= FIND_WINS; search = FIND_WINS;
search &= ~FIND_SELF;
} }
if (!(d = find_req_subnet(p->ip, bcast))) if (search | FIND_LOCAL)
{ {
DEBUG(3,("name query: bcast %s not known\n", if (!(d = find_req_subnet(p->ip, bcast)))
inet_ntoa(p->ip))); {
success = False; DEBUG(3,("name query: bcast %s not known\n",
inet_ntoa(p->ip)));
success = False;
}
}
else
{
if (!(d = find_subnet(ipgrp)))
{
DEBUG(3,("name query: wins search %s not known\n",
inet_ntoa(p->ip)));
success = False;
}
} }
DEBUG(3,("Name query ")); DEBUG(3,("Name query "));
@ -492,7 +509,7 @@ void reply_name_query(struct packet_struct *p)
another WINS server if the name is not in our database, or we are another WINS server if the name is not in our database, or we are
not a WINS server ourselves not a WINS server ourselves
*/ */
ttl = n->death_time - p->timestamp; ttl = n->death_time ? n->death_time - p->timestamp : GET_TTL(0);
retip = n->ip; retip = n->ip;
nb_flags = n->nb_flags; nb_flags = n->nb_flags;
} }
@ -524,7 +541,7 @@ void reply_name_query(struct packet_struct *p)
} }
reply_netbios_packet(p,nmb->header.name_trn_id, reply_netbios_packet(p,nmb->header.name_trn_id,
rcode,0,True, rcode,NMB_QUERY,0,True,
&nmb->question.question_name, &nmb->question.question_name,
nmb->question.question_type, nmb->question.question_type,
nmb->question.question_class, nmb->question.question_class,

View File

@ -339,7 +339,7 @@ static void response_name_query_register(struct nmb_packet *nmb,
} }
/* register the old or the new owners' ip */ /* register the old or the new owners' ip */
add_name_respond(d, n->fd, n->response_id,&n->name,n->nb_flags, add_name_respond(d, n->fd, d->myip, n->response_id,&n->name,n->nb_flags,
GET_TTL(0), register_ip, GET_TTL(0), register_ip,
new_owner, n->reply_to_ip); new_owner, n->reply_to_ip);
} }
@ -434,7 +434,7 @@ static void debug_rr_type(int rr_type)
/**************************************************************************** /****************************************************************************
report the response record nmbd state report the response record nmbd state
****************************************************************************/ ****************************************************************************/
static void debug_state_type(int state) void debug_state_type(int state)
{ {
/* report the state type to help debugging */ /* report the state type to help debugging */
switch (state) switch (state)

View File

@ -64,6 +64,7 @@ extern int updatecount;
extern time_t StartupTime; extern time_t StartupTime;
extern BOOL updatedlists;
/**************************************************************************** /****************************************************************************
tell a server to become a backup browser tell a server to become a backup browser
@ -195,18 +196,22 @@ BOOL listening_name(struct work_record *work, struct nmb_name *n)
resources. We just have to pass it to smbd (via browser.dat) and let resources. We just have to pass it to smbd (via browser.dat) and let
the client choose using bit masks. 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 dgram_packet *dgram = &p->packet.dgram;
struct in_addr ip = dgram->header.source_ip; struct in_addr ip = dgram->header.source_ip;
struct subnet_record *d = find_subnet(ip); struct subnet_record *d = find_subnet(ip);
int update_count = CVAL(buf,0); int update_count = CVAL(buf,0);
int ttl = IVAL(buf,1)/1000; int ttl = IVAL(buf,1)/1000;
char *name = buf+5; char *name = buf+5;
int osmajor=CVAL(buf,21); int osmajor=CVAL(buf,21);
int osminor=CVAL(buf,22); int osminor=CVAL(buf,22);
uint32 servertype = IVAL(buf,23); uint32 servertype = IVAL(buf,23);
uint32 browse_type= CVAL(buf,27);
uint32 browse_sig = CVAL(buf,29);
char *comment = buf+31; char *comment = buf+31;
struct work_record *work; struct work_record *work;
char *work_name; char *work_name;
char *serv_name = dgram->source_name.name; char *serv_name = dgram->source_name.name;
@ -215,9 +220,9 @@ static void process_announce(struct packet_struct *p,int command,char *buf)
comment[43] = 0; comment[43] = 0;
DEBUG(4,("Announce(%d) %s(%x)",command,name,name[15])); 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, namestr(&dgram->dest_name),update_count,ttl,osmajor,osminor,
servertype,comment)); servertype,browse_type,browse_sig,comment));
name[15] = 0; name[15] = 0;
@ -236,7 +241,7 @@ static void process_announce(struct packet_struct *p,int command,char *buf)
return; 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, /* XXXX if we are a master browser for the workgroup work_name,
@ -249,6 +254,7 @@ static void process_announce(struct packet_struct *p,int command,char *buf)
*/ */
work_name = name; work_name = name;
add = True;
} else { } else {
work_name = dgram->dest_name.name; work_name = dgram->dest_name.name;
} }
@ -268,9 +274,10 @@ static void process_announce(struct packet_struct *p,int command,char *buf)
ttl = GET_TTL(ttl); 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); add_server_entry(d,work,name,servertype,ttl,comment,True);
updatedlists = True;
#if 0 #if 0
/* the tell become backup code is broken, no great harm is done by /* the tell become backup code is broken, no great harm is done by
disabling it */ disabling it */
@ -339,12 +346,12 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf)
struct dgram_packet *dgram = &p->packet.dgram; struct dgram_packet *dgram = &p->packet.dgram;
struct in_addr ip = dgram->header.source_ip; struct in_addr ip = dgram->header.source_ip;
int count = CVAL(buf,0); 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; 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), namestr(&dgram->dest_name), inet_ntoa(ip),
count, Index)); count, info));
if (same_context(dgram)) return; if (same_context(dgram)) return;
@ -352,44 +359,49 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf)
/* go through the list of servers attempting to sync browse lists */ /* go through the list of servers attempting to sync browse lists */
for (buf1 = buf+5; *buf1 && count; buf1 = skip_string(buf1, 1), --count) for (buf1 = buf+5; *buf1 && count; buf1 = skip_string(buf1, 1), --count)
{ {
struct in_addr back_ip; struct in_addr back_ip;
struct subnet_record *d; 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))); buf1, inet_ntoa(ip)));
/* XXXX assume name is a DNS name NOT a netbios name. a more complete /* 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);
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")); DEBUG(4,("Failed to find backup browser server using DNS\n"));
continue; continue;
} }
DEBUG(4,("Found browser server at %s\n", inet_ntoa(back_ip))); DEBUG(4,("Found browser server at %s\n", inet_ntoa(back_ip)));
DEBUG(4,("END THIS LOOP: CODE NEEDS UPDATING\n"));
if ((d = find_subnet(back_ip))) /* XXXX function needs work */
continue;
if ((d = find_subnet(back_ip)))
{ {
struct subnet_record *d1; struct subnet_record *d1;
for (d1 = subnetlist; d1; d1 = d1->next) for (d1 = subnetlist; d1; d1 = d1->next)
{ {
struct work_record *work; struct work_record *work;
for (work = d1->workgrouplist; work; work = work->next) for (work = d1->workgrouplist; work; work = work->next)
{ {
if (work->token == Index) if (work->token == 0 /* token */)
{ {
queue_netbios_packet(d1,ClientNMB,NMB_QUERY,NAME_QUERY_SRV_CHK, queue_netbios_packet(d1,ClientNMB,NMB_QUERY,NAME_QUERY_SRV_CHK,
work->work_group,0x1d,0,0, work->work_group,0x1d,0,0,
False,False,back_ip,back_ip); False,False,back_ip,back_ip);
return; return;
} }
} }
} }
} }
} }
} }
@ -397,19 +409,18 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf)
send a backup list response. send a backup list response.
**************************************************************************/ **************************************************************************/
static void send_backup_list(char *work_name, struct nmb_name *src_name, static void send_backup_list(char *work_name, struct nmb_name *src_name,
int info_count, int token, int info, int token, uint32 info,
int name_type, struct in_addr ip) int name_type, struct in_addr ip)
{ {
struct subnet_record *d; struct subnet_record *d;
char outbuf[1024]; char outbuf[1024];
char *p, *countptr, *nameptr; char *p, *countptr, *nameptr;
int count = 0; int count = 0;
int i, j;
char *theirname = src_name->name; char *theirname = src_name->name;
DEBUG(3,("sending backup list of %s to %s: %s(%x) %s(%x)\n", DEBUG(3,("sending backup list of %s to %s: %s(%x) %s(%x)\n",
work_name, inet_ntoa(ip), work_name, inet_ntoa(ip),
myname,0x20,theirname,0x0)); myname,0x0,theirname,0x0));
if (name_type == 0x1d) if (name_type == 0x1d)
{ {
@ -429,18 +440,20 @@ static void send_backup_list(char *work_name, struct nmb_name *src_name,
p = outbuf; p = outbuf;
CVAL(p,0) = ANN_GetBackupListResp; /* backup list response */ CVAL(p,0) = ANN_GetBackupListResp; /* backup list response */
p++; p++;
countptr = p;
countptr = p; /* count pointer */
SIVAL(p,1,info); /* the sender's unique info */
SSVAL(p,1,token); /* sender's workgroup index representation */
SSVAL(p,3,info); /* XXXX clueless: info, usually zero */
p += 5; p += 5;
nameptr = p; nameptr = p;
#if 0
for (d = subnetlist; d; d = d->next) for (d = subnetlist; d; d = d->next)
{ {
struct work_record *work; struct work_record *work;
for (work = d->workgrouplist; work; work = work->next) for (work = d->workgrouplist; work; work = work->next)
@ -465,9 +478,9 @@ static void send_backup_list(char *work_name, struct nmb_name *src_name,
/* workgroup request: include all backup browsers in the list */ /* workgroup request: include all backup browsers in the list */
/* domain request: include all domain members in the list */ /* domain request: include all domain members in the list */
if ((name_type == 0x1d && (s->serv.type & MASTER_TYPE)) || if ((name_type == 0x1d && (s->serv.type & MASTER_TYPE)) ||
(name_type == 0x1b && (s->serv.type & DOMCTL_TYPE))) (name_type == 0x1b && (s->serv.type & DOMCTL_TYPE)))
{ {
DEBUG(4, ("%s ", s->serv.name)); DEBUG(4, ("%s ", s->serv.name));
@ -476,52 +489,34 @@ static void send_backup_list(char *work_name, struct nmb_name *src_name,
strupper(p); strupper(p);
p = skip_string(p,1); p = skip_string(p,1);
} }
} }
} }
} }
#endif
count++;
strcpy(p,myname);
strupper(p);
p = skip_string(p,1);
if (count == 0) if (count == 0)
{ {
DEBUG(4, ("none\n")); DEBUG(4, ("none\n"));
return;
} }
else else
{ {
DEBUG(4, (" - count %d\n", count)); DEBUG(4, (" - count %d\n", count));
} }
CVAL(countptr,0) = count; /* total number of backup browsers found */ CVAL(countptr, 0) = count;
{ {
int len = PTR_DIFF(p, outbuf); int len = PTR_DIFF(p, outbuf);
debug_browse_data(outbuf, len);
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), send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
myname,theirname,0x20,0x0,ip,*iface_ip(ip)); myname,theirname,0x0,0x0,ip,*iface_ip(ip));
} }
@ -544,15 +539,12 @@ static void process_send_backup_list(struct packet_struct *p,char *buf)
struct subnet_record *d; struct subnet_record *d;
struct work_record *work; struct work_record *work;
int count = CVAL(buf,0); int token = CVAL(buf,0); /* sender's key index for the workgroup */
int token = SVAL(buf,1); /* sender's key index for the workgroup? */ uint32 info = IVAL(buf,1); /* XXXX don't know: some sort of info */
int info = SVAL(buf,3); /* XXXX don't know: some sort of info */
int name_type = dgram->dest_name.name_type; int name_type = dgram->dest_name.name_type;
if (same_context(dgram)) return; if (same_context(dgram)) return;
if (count <= 0) return;
if (name_type != 0x1b && name_type != 0x1d) { if (name_type != 0x1b && name_type != 0x1d) {
DEBUG(0,("backup request to wrong type %d from %s\n", DEBUG(0,("backup request to wrong type %d from %s\n",
name_type,inet_ntoa(ip))); name_type,inet_ntoa(ip)));
@ -565,11 +557,11 @@ static void process_send_backup_list(struct packet_struct *p,char *buf)
{ {
if (strequal(work->work_group, dgram->dest_name.name)) if (strequal(work->work_group, dgram->dest_name.name))
{ {
DEBUG(2,("sending backup list to %s %s count=%d\n", DEBUG(2,("sending backup list to %s %s id=%x\n",
namestr(&dgram->dest_name),inet_ntoa(ip),count)); namestr(&dgram->dest_name),inet_ntoa(ip),info));
send_backup_list(work->work_group,&dgram->source_name, send_backup_list(work->work_group,&dgram->source_name,
count,token,info,name_type,ip); token,info,name_type,ip);
return; return;
} }
} }
@ -634,7 +626,6 @@ static void process_reset_browser(struct packet_struct *p,char *buf)
} }
} }
/******************************************************************* /*******************************************************************
process a announcement request process a announcement request
@ -759,6 +750,7 @@ void process_browse_packet(struct packet_struct *p,char *buf,int len)
case ANN_DomainAnnouncement: case ANN_DomainAnnouncement:
case ANN_LocalMasterAnnouncement: case ANN_LocalMasterAnnouncement:
{ {
debug_browse_data(buf, len);
process_announce(p,command,buf+1); process_announce(p,command,buf+1);
break; break;
} }
@ -777,15 +769,17 @@ void process_browse_packet(struct packet_struct *p,char *buf,int len)
case ANN_GetBackupListReq: case ANN_GetBackupListReq:
{ {
debug_browse_data(buf, len);
process_send_backup_list(p,buf+1); process_send_backup_list(p,buf+1);
break; break;
} }
case ANN_GetBackupListResp: case ANN_GetBackupListResp:
{ {
process_rcv_backup_list(p, buf+1); debug_browse_data(buf, len);
break; process_rcv_backup_list(p, buf+1);
} break;
}
case ANN_ResetBrowserState: case ANN_ResetBrowserState:
{ {

View File

@ -323,7 +323,7 @@ static void process(void)
announce_host(); announce_host();
#if 0 #if 1
/* XXXX what was this stuff supposed to do? It sent /* XXXX what was this stuff supposed to do? It sent
ANN_GetBackupListReq packets which I think should only be ANN_GetBackupListReq packets which I think should only be
sent when trying to find out who to browse with */ sent when trying to find out who to browse with */

View File

@ -1013,7 +1013,7 @@ static BOOL api_RNetServerEnum(int cnum, int uid, char *param, char *data,
int counted=0,total=0; int counted=0,total=0;
int i; int i;
fstring domain; fstring domain;
BOOL domains = False; BOOL domains;
BOOL domain_request; BOOL domain_request;
BOOL local_request = servertype & SV_TYPE_LOCAL_LIST_ONLY; BOOL local_request = servertype & SV_TYPE_LOCAL_LIST_ONLY;

View File

@ -49,7 +49,7 @@ static BOOL open_sockets(void)
return False; return False;
} }
ServerFD = open_socket_in(SOCK_DGRAM, 0,3); ServerFD = open_socket_in(SOCK_DGRAM, NMB_PORT,3);
if (ServerFD == -1) if (ServerFD == -1)
return(False); return(False);
@ -164,7 +164,7 @@ int main(int argc,char *argv[])
strcpy(lookup,"\01\02__MSBROWSE__\02"); strcpy(lookup,"\01\02__MSBROWSE__\02");
lookup_type = 1; lookup_type = 1;
} else { } else {
lookup_type = 0x1d; lookup_type = 0x1b;
} }
} }