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:
parent
c290c229f9
commit
45d3b26447
@ -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();
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -1 +1 @@
|
|||||||
#define VERSION "1.9.16alpha10"
|
#define VERSION "1.9.16a10"
|
||||||
|
@ -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 ||
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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))
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
|
@ -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:
|
||||||
{
|
{
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user