1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34: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
****************************************************************************/
static BOOL list_servers()
static BOOL list_servers(char *wk_grp)
{
char *rparam = NULL;
char *rdata = NULL;
@ -3600,7 +3600,7 @@ static BOOL list_servers()
p = param;
SSVAL(p,0,0x68); /* api number */
p += 2;
strcpy(p,"WrLehDO");
strcpy(p,"WrLehDz");
p = skip_string(p,1);
strcpy(p,"B16BBDz");
@ -3615,6 +3615,11 @@ static BOOL list_servers()
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,
8,10000,
&rprcnt,&rdrcnt,
@ -3638,9 +3643,10 @@ static BOOL list_servers()
for (i=0;i<count;i++) {
char *sname = p2;
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,
comment_offset?rdata+comment_offset-converter:"");
comment_offset?rdata+comment_offset-converter:"", stype);
ok=True;
p2 += 26;
@ -3651,7 +3657,7 @@ static BOOL list_servers()
if (rparam) {free(rparam); rparam = 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,
8,10000,
@ -3676,9 +3682,10 @@ static BOOL list_servers()
for (i=0;i<count;i++) {
char *sname = p2;
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,
comment_offset?rdata+comment_offset-converter:"");
comment_offset?rdata+comment_offset-converter:"",stype);
ok=True;
p2 += 26;
@ -4391,9 +4398,9 @@ static void usage(char *pname)
sleep(1);
browse_host(True);
}
if (!list_servers()) {
if (!list_servers(workgroup)) {
sleep(1);
list_servers();
list_servers(workgroup);
}
send_logout();

View File

@ -85,7 +85,17 @@
enum name_source {STATUS_QUERY, LMHOSTS, REGISTER, SELF, DNS, DNSFAIL};
enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3};
enum packet_type {NMB_PACKET, DGRAM_PACKET};
enum 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
{

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);
struct name_record *find_name(struct name_record *n,
struct nmb_name *name,
int search, struct in_addr ip);
int search);
struct name_record *find_name_search(struct subnet_record **d,
struct nmb_name *name,
int search, struct in_addr ip);
@ -286,6 +286,7 @@ struct response_record *find_response_record(struct subnet_record **d,
uint16 id);
void remove_old_servers(struct work_record *work, time_t t,
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 work_record *work,
char *name,int servertype,
@ -320,12 +321,13 @@ void run_elections(void);
void process_election(struct packet_struct *p,char *buf);
BOOL check_elections(void);
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,
int fd,int quest_type,char *name,int name_type,
int nb_flags,BOOL bcast,BOOL recurse,
struct in_addr to_ip);
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,
char *data,int len);
void queue_packet(struct packet_struct *packet);
@ -357,11 +359,12 @@ void add_my_names(void);
void remove_my_names();
void refresh_my_names(time_t t);
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,
int nb_flags, int ttl, struct in_addr register_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,
struct nmb_name *reply_name, int nb_flags, int ttl,
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_status(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 reset_server(char *name, int state, struct in_addr ip);
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;
}
debug_nmb_packet(p2);
_interpret_node_status(&nmb2->answers->rdata[0], master,rname);
free_packet(p2);
return(True);
@ -266,6 +268,8 @@ BOOL name_query(int fd,char *name,int name_type,
continue;
}
debug_nmb_packet(p2);
if (nmb2->header.opcode != 0 ||
nmb2->header.nm_flags.bcast ||
nmb2->header.rcode ||

View File

@ -48,7 +48,7 @@ extern pstring ServerComment;
extern int updatecount;
extern int workgroup_count;
/* what server type are we currently */
extern struct in_addr ipgrp;
/****************************************************************************
send a announce request to the local net
@ -146,12 +146,19 @@ void announce_backup(void)
char *p;
struct subnet_record *d1;
int tok;
static uint32 id_count = 0;
if (!lastrun) lastrun = t;
#if 1
if (t < lastrun + 1 * 60)
#else
if (t < lastrun + CHECK_TIME_ANNOUNCE_BACKUP * 60)
#endif
return;
lastrun = t;
DEBUG(4,("checking backups...\n"));
for (tok = 0; tok <= workgroup_count; tok++)
{
for (d1 = subnetlist; d1; d1 = d1->next)
@ -178,13 +185,14 @@ void announce_backup(void)
bzero(outbuf,sizeof(outbuf));
p = outbuf;
CVAL(p,0) = ANN_GetBackupListReq;
p++;
CVAL(p,0) = 1; /* count? */
SIVAL(p,1,work->token); /* workgroup unique key index */
p += 5;
p++;
CVAL(p,0) = ANN_GetBackupListReq;
CVAL(p,1) = work->token; /* workgroup unique key index */
SIVAL(p,2,++id_count); /* unique count. not that we use it! */
p += 6;
debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
if (!AM_DOMCTL(work))
{
@ -199,6 +207,8 @@ void announce_backup(void)
*iface_ip(d->bcast_ip));
}
debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
if (!AM_MASTER(work))
{
/* only ask for a list of master browsers if we
@ -208,7 +218,7 @@ void announce_backup(void)
ClientDGRAM,outbuf,
PTR_DIFF(p,outbuf),
myname, work->work_group,
0x0,0x1b,d->bcast_ip,
0x0,0x1d,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 */
SIVAL(p,23,server_type);
SSVAL(p,27,0xaa55); /* browse signature */
SSVAL(p,29,0x001f); /* browse version: CIFS draft 1.0 indicates 0x001f */
SSVAL(p,27,0x010f); /* browse version: got from NT/AS 4.00 */
SSVAL(p,29,0xaa55); /* browse signature */
strcpy(p+31,server_comment);
p += 31;
p = skip_string(p,1);
debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
/* send the announcement */
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,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,
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))
{
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? */
if (server_type != 0)
{
if (AM_DOMCTL(work)) {
domain_type |= SV_TYPE_DOMAIN_CTRL;
}
do_announce_host(ANN_DomainAnnouncement,
work->work_group, 0x00, d->myip,
name , 0x00, d->myip,
MSBROWSE, 0x01, d->bcast_ip,
ttl*1000,
name, server_type ? SV_TYPE_DOMAIN_ENUM : 0, comment);
work->work_group, server_type ? domain_type : 0,
comment);
}
}
else
@ -345,6 +363,8 @@ void announce_host(void)
{
struct work_record *work;
if (ip_equal(d->bcast_ip, ipgrp)) continue;
for (work = d->workgrouplist; work; work = work->next)
{
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 nmb_name *name,
int search, struct in_addr ip)
int search)
{
struct name_record *ret;
@ -132,14 +132,9 @@ struct name_record *find_name(struct name_record *n,
if ((search&FIND_SELF) == FIND_SELF && ret->source != SELF)
continue;
/* zero ip is either samba's ip or a way of finding a
name without needing to know the ip address */
if (zero_ip(ip) || ip_equal(ip, ret->ip))
{
return ret;
}
}
}
return NULL;
}
@ -161,7 +156,9 @@ struct name_record *find_name_search(struct subnet_record **d,
{
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
{
@ -180,7 +177,9 @@ struct name_record *find_name_search(struct subnet_record **d,
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
****************************************************************************/
@ -119,10 +139,7 @@ struct server_record *add_server_entry(struct subnet_record *d,
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)
{

View File

@ -41,6 +41,7 @@ extern pstring scope;
extern pstring myname;
extern struct in_addr ipzero;
extern struct in_addr ipgrp;
/* machine comment for host announcements */
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,
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)
{
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)
{
if (work->state != MST_NONE)
{
/* samba is in the process of working towards master browser-ness.
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;
DEBUG(2,("Becoming master for %s (currently at stage %d)\n",
work->work_group,work->state));
DEBUG(2,("Becoming master for %s %s (currently at stage %d)\n",
work->work_group,inet_ntoa(d->bcast_ip),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 */
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())
{
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_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
{
DEBUG(3,("samba not configured as a domain master: no third stage.\n"));
DEBUG(4,("samba not configured as a domain master.\n"));
}
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 */
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->ServerType |= SV_TYPE_DOMAIN_MASTER;
update_type |= SV_TYPE_DOMAIN_MASTER;
if (lp_domain_logons())
{
work->ServerType |= SV_TYPE_DOMAIN_CTRL;
work->ServerType |= SV_TYPE_DOMAIN_MEMBER;
update_type |= SV_TYPE_DOMAIN_CTRL;
}
work->ServerType |= update_type;
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;
}
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"));
break;
}

View File

@ -40,6 +40,40 @@ extern struct in_addr ipgrp;
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
**************************************************************************/
@ -138,7 +172,7 @@ void initiate_netbios_packet(uint16 *id,
reply to a netbios name packet
****************************************************************************/
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,
char *data,int len)
{
@ -150,7 +184,7 @@ void reply_netbios_packet(struct packet_struct *p1,int trn_id,
p = *p1;
switch (rr_type)
switch (rcv_code)
{
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.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));
}

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",
inet_ntoa(n->send_ip), namestr(&n->name), n->num_msgs));
debug_state_type(n->state);
switch (n->state)
{
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
*/
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->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() */
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
{

View File

@ -131,18 +131,6 @@ samba should take this into account (see rfc1001.txt 10.3).
remove_name_entry() issues this samba 'state'
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
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 myname;
extern pstring ServerComment;
extern struct in_addr ipzero;
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 */
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;
/* 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
*/
DEBUG(4,("samba as WINS server adding: "));
/* this will call add_netbios_entry() */
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
{
/* broadcast the packet, but it comes from ipzero */
queue_netbios_packet(d,ClientNMB,
re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
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)
{
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,0x03,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__",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 */
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.
**************************************************************************/
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,
int nb_flags, int ttl, struct in_addr register_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);
/* 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,
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
**************************************************************************/
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,
struct nmb_name *reply_name, int nb_flags, int ttl,
struct in_addr ip)
@ -85,14 +86,14 @@ void send_name_response(int fd,
rdata[1] = 0;
putip(&rdata[2],(char *)&ip);
p.ip = ip;
p.ip = from_ip;
p.port = NMB_PORT;
p.fd = fd;
p.timestamp = time(NULL);
p.packet_type = NMB_PACKET;
reply_netbios_packet(&p,name_trn_id,
rcode,opcode,recurse,
rcode,opcode,opcode,recurse,
reply_name, 0x20, 0x1,
ttl,
rdata, 6);
@ -145,7 +146,7 @@ void reply_name_release(struct packet_struct *p)
if (bcast) return;
/* 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,
&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 */
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,
15*1000, /* 15 seconds long enough to wait? */
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
*/
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,
reply_name, nb_flags, ttl, ip);
}
@ -322,6 +323,7 @@ void reply_name_status(struct packet_struct *p)
int names_added;
struct name_record *n;
struct subnet_record *d = NULL;
int search = FIND_SELF;
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",
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,
FIND_SELF|FIND_LOCAL,
p->ip);
search, p->ip);
if (!n) return;
@ -396,7 +402,7 @@ void reply_name_status(struct packet_struct *p)
/* Send a POSITIVE NAME STATUS RESPONSE */
reply_netbios_packet(p,nmb->header.name_trn_id,
0,0,True,
0,NMB_STATUS,0,True,
&nmb->question.question_name,
nmb->question.question_type,
nmb->question.question_class,
@ -452,16 +458,27 @@ void reply_name_query(struct packet_struct *p)
if (name_type == 0x1b)
{
/* even if it's a broadcast, we don't ignore queries for PDC names */
search |= FIND_WINS;
search &= ~FIND_SELF;
search = FIND_WINS;
}
if (search | FIND_LOCAL)
{
if (!(d = find_req_subnet(p->ip, bcast)))
{
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 "));
@ -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
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;
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,
rcode,0,True,
rcode,NMB_QUERY,0,True,
&nmb->question.question_name,
nmb->question.question_type,
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 */
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,
new_owner, n->reply_to_ip);
}
@ -434,7 +434,7 @@ static void debug_rr_type(int rr_type)
/****************************************************************************
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 */
switch (state)

View File

@ -64,6 +64,7 @@ extern int updatecount;
extern time_t StartupTime;
extern BOOL updatedlists;
/****************************************************************************
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
the client choose using bit masks.
******************************************************************/
static void process_announce(struct packet_struct *p,int command,char *buf)
static void process_announce(struct packet_struct *p,uint16 command,char *buf)
{
struct dgram_packet *dgram = &p->packet.dgram;
struct in_addr ip = dgram->header.source_ip;
struct subnet_record *d = find_subnet(ip);
int update_count = CVAL(buf,0);
int ttl = IVAL(buf,1)/1000;
char *name = buf+5;
int osmajor=CVAL(buf,21);
int osminor=CVAL(buf,22);
uint32 servertype = IVAL(buf,23);
uint32 browse_type= CVAL(buf,27);
uint32 browse_sig = CVAL(buf,29);
char *comment = buf+31;
struct work_record *work;
char *work_name;
char *serv_name = dgram->source_name.name;
@ -215,9 +220,9 @@ static void process_announce(struct packet_struct *p,int command,char *buf)
comment[43] = 0;
DEBUG(4,("Announce(%d) %s(%x)",command,name,name[15]));
DEBUG(4,("%s count=%d ttl=%d OS=(%d,%d) type=%08x comment=%s\n",
DEBUG(4,("%s count=%d ttl=%d OS=(%d,%d) type=%08x sig=%4x %4x comment=%s\n",
namestr(&dgram->dest_name),update_count,ttl,osmajor,osminor,
servertype,comment));
servertype,browse_type,browse_sig,comment));
name[15] = 0;
@ -236,7 +241,7 @@ static void process_announce(struct packet_struct *p,int command,char *buf)
return;
}
if (same_context(dgram)) return;
if (!strequal(dgram->dest_name.scope,scope )) return;
if (command == ANN_DomainAnnouncement) {
/* 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;
add = True;
} else {
work_name = dgram->dest_name.name;
}
@ -268,8 +274,9 @@ static void process_announce(struct packet_struct *p,int command,char *buf)
ttl = GET_TTL(ttl);
/* add them to our browse list */
/* add them to our browse list, and update the browse.dat file */
add_server_entry(d,work,name,servertype,ttl,comment,True);
updatedlists = True;
#if 0
/* the tell become backup code is broken, no great harm is done by
@ -339,12 +346,12 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf)
struct dgram_packet *dgram = &p->packet.dgram;
struct in_addr ip = dgram->header.source_ip;
int count = CVAL(buf,0);
int Index = IVAL(buf,1); /* caller's index representing workgroup */
uint32 info = IVAL(buf,1); /* XXXX caller's incremental info */
char *buf1;
DEBUG(3,("Receive Backup ack for %s from %s total=%d index=%d\n",
DEBUG(3,("Receive Backup ack for %s from %s total=%d info=%d\n",
namestr(&dgram->dest_name), inet_ntoa(ip),
count, Index));
count, info));
if (same_context(dgram)) return;
@ -361,6 +368,7 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf)
/* XXXX assume name is a DNS name NOT a netbios name. a more complete
approach is to use reply_name_query functionality to find the name */
back_ip = *interpret_addr2(buf1);
if (zero_ip(back_ip))
@ -370,6 +378,10 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf)
}
DEBUG(4,("Found browser server at %s\n", inet_ntoa(back_ip)));
DEBUG(4,("END THIS LOOP: CODE NEEDS UPDATING\n"));
/* XXXX function needs work */
continue;
if ((d = find_subnet(back_ip)))
{
@ -379,7 +391,7 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf)
struct work_record *work;
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,
work->work_group,0x1d,0,0,
@ -397,19 +409,18 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf)
send a backup list response.
**************************************************************************/
static void send_backup_list(char *work_name, struct nmb_name *src_name,
int info_count, int token, int info,
int token, uint32 info,
int name_type, struct in_addr ip)
{
struct subnet_record *d;
char outbuf[1024];
char *p, *countptr, *nameptr;
int count = 0;
int i, j;
char *theirname = src_name->name;
DEBUG(3,("sending backup list of %s to %s: %s(%x) %s(%x)\n",
work_name, inet_ntoa(ip),
myname,0x20,theirname,0x0));
myname,0x0,theirname,0x0));
if (name_type == 0x1d)
{
@ -429,16 +440,18 @@ static void send_backup_list(char *work_name, struct nmb_name *src_name,
p = outbuf;
CVAL(p,0) = ANN_GetBackupListResp; /* backup list response */
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;
nameptr = p;
#if 0
for (d = subnetlist; d; d = d->next)
{
struct work_record *work;
@ -480,48 +493,30 @@ static void send_backup_list(char *work_name, struct nmb_name *src_name,
}
}
#endif
count++;
strcpy(p,myname);
strupper(p);
p = skip_string(p,1);
if (count == 0)
{
DEBUG(4, ("none\n"));
return;
}
else
{
DEBUG(4, (" - count %d\n", count));
}
CVAL(countptr,0) = count; /* total number of backup browsers found */
CVAL(countptr, 0) = count;
{
int len = PTR_DIFF(p, outbuf);
for (i = 0; i < len; i+= 16)
{
DEBUG(4, ("%3x char ", i));
for (j = 0; j < 16; j++)
{
unsigned char x = outbuf[i+j];
if (x < 32 || x > 127) x = '.';
if (i+j >= len) break;
DEBUG(4, ("%c", x));
}
DEBUG(4, (" hex ", i));
for (j = 0; j < 16; j++)
{
if (i+j >= len) break;
DEBUG(4, (" %02x", outbuf[i+j]));
}
DEBUG(4, ("\n"));
}
debug_browse_data(outbuf, len);
}
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 work_record *work;
int count = CVAL(buf,0);
int token = SVAL(buf,1); /* sender's key index for the workgroup? */
int info = SVAL(buf,3); /* XXXX don't know: some sort of info */
int token = CVAL(buf,0); /* sender's key index for the workgroup */
uint32 info = IVAL(buf,1); /* XXXX don't know: some sort of info */
int name_type = dgram->dest_name.name_type;
if (same_context(dgram)) return;
if (count <= 0) return;
if (name_type != 0x1b && name_type != 0x1d) {
DEBUG(0,("backup request to wrong type %d from %s\n",
name_type,inet_ntoa(ip)));
@ -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))
{
DEBUG(2,("sending backup list to %s %s count=%d\n",
namestr(&dgram->dest_name),inet_ntoa(ip),count));
DEBUG(2,("sending backup list to %s %s id=%x\n",
namestr(&dgram->dest_name),inet_ntoa(ip),info));
send_backup_list(work->work_group,&dgram->source_name,
count,token,info,name_type,ip);
token,info,name_type,ip);
return;
}
}
@ -634,7 +626,6 @@ static void process_reset_browser(struct packet_struct *p,char *buf)
}
}
/*******************************************************************
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_LocalMasterAnnouncement:
{
debug_browse_data(buf, len);
process_announce(p,command,buf+1);
break;
}
@ -777,12 +769,14 @@ void process_browse_packet(struct packet_struct *p,char *buf,int len)
case ANN_GetBackupListReq:
{
debug_browse_data(buf, len);
process_send_backup_list(p,buf+1);
break;
}
case ANN_GetBackupListResp:
{
debug_browse_data(buf, len);
process_rcv_backup_list(p, buf+1);
break;
}

View File

@ -323,7 +323,7 @@ static void process(void)
announce_host();
#if 0
#if 1
/* XXXX what was this stuff supposed to do? It sent
ANN_GetBackupListReq packets which I think should only be
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 i;
fstring domain;
BOOL domains = False;
BOOL domains;
BOOL domain_request;
BOOL local_request = servertype & SV_TYPE_LOCAL_LIST_ONLY;

View File

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