1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

Did more integration of Lukes code ready for the first release.

I've now got WINS registration working, and refresh working. Its
looking pretty good so far, but needs lots of testing.
This commit is contained in:
Andrew Tridgell 0001-01-01 00:00:00 +00:00
parent bc4a299437
commit 045014aa57
15 changed files with 2158 additions and 2119 deletions

View File

@ -1962,14 +1962,6 @@ merits of each are discussed in the README file.
.B Example:
protocol = LANMAN1
.SS proxy name resolution (G)
This is a boolean that controls if nmbd will respond to broadcast name
queries on behalf of other hosts. You may need to set this to no for
some older clients.
.B Default:
proxy name resolution = yes
.SS public (S)
A synonym for this parameter is 'guest ok'.
@ -2548,6 +2540,33 @@ only to areas that are outside the directory tree being exported.
.B Example:
wide links = no
.SS wins proxy (G)
This is a boolean that controls if nmbd will respond to broadcast name
queries on behalf of other hosts. You may need to set this to no for
some older clients.
.B Default:
wins proxy = no
.SS wins support (G)
This boolean controls if Samba will act as a WINS server. You should
normally set this to true unless you already have another WINS server
on the network.
.B Default:
wins support = yes
.SS wins server (G)
This specifies the DNS name of the WINS server that Samba should
register with. If you have a WINS server on your network then you
should set this to the WINS servers name.
This option only takes effect if Samba is not acting as a WINS server
itself.
.B Default:
wins server =
.SS workgroup (G)
This controls what workgroup your server will appear to be in when

View File

@ -3599,6 +3599,7 @@ static BOOL list_servers()
pstring param;
int uLevel = 1;
int count = 0;
BOOL ok = False;
/* now send a SMBtrans command with api ServerEnum? */
p = param;
@ -3645,7 +3646,8 @@ static BOOL list_servers()
printf("\t%-16.16s %s\n",
sname,
comment_offset?rdata+comment_offset-converter:"");
ok=True;
p2 += 26;
}
}
@ -3683,6 +3685,7 @@ static BOOL list_servers()
sname,
comment_offset?rdata+comment_offset-converter:"");
ok=True;
p2 += 26;
}
}
@ -3691,7 +3694,7 @@ static BOOL list_servers()
if (rparam) free(rparam);
if (rdata) free(rdata);
return(count>0);
return(ok);
}

View File

@ -20,6 +20,10 @@
*/
/* NTAS uses 2, NT uses 1, WfWg uses 0 */
#define MAINTAIN_LIST 2
#define ELECTION_VERSION 2
#define MAX_DGRAM_SIZE (80*18+64)
#define MIN_DGRAM_SIZE 12
@ -39,6 +43,8 @@
#define NB__FLAG 0x60
#define NB_FLGMSK 0x60
#define REFRESH_TIME (15*60)
#define NAME_PERMANENT(p) ((p) & NB_PERM)
#define NAME_ACTIVE(p) ((p) & NB_ACTIVE)
#define NAME_CONFLICT(p) ((p) & NB_CONFL)

View File

@ -1820,11 +1820,10 @@ int read_udp_socket(int fd,char *buf,int len)
bzero((char *)&sock,socklen);
bzero((char *)&lastip,sizeof(lastip));
ret = recvfrom(fd,buf,len,0,&sock,&socklen);
if (ret <= 0)
{
DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
return(0);
}
if (ret <= 0) {
DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
return(0);
}
lastip = *(struct in_addr *) &sock.sa_data[2];
lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);

View File

@ -472,7 +472,7 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type)
length = read_udp_socket(fd,buf,sizeof(buf));
if (length < MIN_DGRAM_SIZE) return(NULL);
packet = (struct packet_struct *)malloc(sizeof(*packet));
if (!packet) return(NULL);

View File

@ -68,6 +68,7 @@ extern int lp_maxxmit(void);
extern int lp_maxmux(void);
extern int lp_mangledstack(void);
extern BOOL lp_wins_support(void);
extern BOOL lp_wins_proxy(void);
extern BOOL lp_preferred_master(void);
extern BOOL lp_domain_master(void);
extern BOOL lp_domain_logons(void);
@ -82,7 +83,6 @@ extern BOOL lp_strip_dot(void);
extern BOOL lp_encrypted_passwords(void);
extern BOOL lp_syslog_only(void);
extern BOOL lp_browse_list(void);
extern BOOL lp_proxy_name_resolution(void);
extern int lp_numservices(void);
extern int lp_keepalive(void);
extern int lp_passwordlevel(void);

View File

@ -98,23 +98,23 @@ void announce_request(struct work_record *work, struct in_addr ip)
void do_announce_request(char *info, char *to_name, int announce_type, int from,
int to, struct in_addr dest_ip)
{
pstring outbuf;
char *p;
bzero(outbuf,sizeof(outbuf));
p = outbuf;
CVAL(p,0) = announce_type; /* announce request */
p++;
DEBUG(2,("Sending announce type %d: info %s to %s - server %s(%x)\n",
announce_type, info, inet_ntoa(dest_ip),to_name,to));
StrnCpy(p,info,16);
strupper(p);
p = skip_string(p,1);
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
myname,to_name,from,to,dest_ip,myip);
pstring outbuf;
char *p;
bzero(outbuf,sizeof(outbuf));
p = outbuf;
CVAL(p,0) = announce_type; /* announce request */
p++;
DEBUG(2,("Sending announce type %d: info %s to %s - server %s(%x)\n",
announce_type, info, inet_ntoa(dest_ip),to_name,to));
StrnCpy(p,info,16);
strupper(p);
p = skip_string(p,1);
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
myname,to_name,from,to,dest_ip,myip);
}
/****************************************************************************
@ -192,135 +192,133 @@ void announce_backup(void)
**************************************************************************/
void announce_host(void)
{
time_t t = time(NULL);
pstring outbuf;
char *p;
char *namep;
char *stypep;
char *commentp;
pstring comment;
char *my_name;
struct domain_record *d;
time_t t = time(NULL);
pstring outbuf;
char *p;
char *namep;
char *stypep;
char *commentp;
pstring comment;
char *my_name;
struct domain_record *d;
StrnCpy(comment, *ServerComment ? ServerComment : "NoComment", 43);
StrnCpy(comment, *ServerComment ? ServerComment : "NoComment", 43);
my_name = *myname ? myname : "NoName";
my_name = *myname ? myname : "NoName";
for (d = domainlist; d; d = d->next)
for (d = domainlist; d; d = d->next)
{
struct work_record *work;
if (!ip_equal(bcast_ip,d->bcast_ip))
continue;
for (work = d->workgrouplist; work; work = work->next)
{
struct work_record *work;
uint32 stype = work->ServerType;
struct server_record *s;
BOOL announce = False;
if (work->needannounce) {
/* drop back to a max 3 minute announce - this is to prevent a
single lost packet from stuffing things up for too long */
work->announce_interval = MIN(work->announce_interval,3*60);
work->lastannounce_time = t - (work->announce_interval+1);
}
/* announce every minute at first then progress to every 12 mins */
if (work->lastannounce_time &&
(t - work->lastannounce_time) < work->announce_interval)
continue;
if (work->announce_interval < 12*60)
work->announce_interval += 60;
work->lastannounce_time = t;
if (!ip_equal(bcast_ip,d->bcast_ip))
DEBUG(2,("Sending announcement to subnet %s for workgroup %s\n",
inet_ntoa(d->bcast_ip),work->work_group));
if (!ip_equal(bcast_ip,d->bcast_ip)) {
stype &= ~(SV_TYPE_POTENTIAL_BROWSER | SV_TYPE_MASTER_BROWSER |
SV_TYPE_DOMAIN_MASTER | SV_TYPE_BACKUP_BROWSER |
SV_TYPE_DOMAIN_CTRL | SV_TYPE_DOMAIN_MEMBER);
}
for (s = work->serverlist; s; s = s->next) {
if (strequal(myname, s->serv.name)) {
announce = True;
break;
}
}
if (announce)
{
bzero(outbuf,sizeof(outbuf));
p = outbuf+1;
CVAL(p,0) = updatecount;
SIVAL(p,1,work->announce_interval*1000); /* ms - despite the spec */
namep = p+5;
StrnCpy(namep,my_name,16);
strupper(namep);
CVAL(p,21) = 2; /* major version */
CVAL(p,22) = 2; /* minor version */
stypep = p+23;
SIVAL(p,23,stype);
SSVAL(p,27,0xaa55); /* browse signature */
SSVAL(p,29,1); /* browse version */
commentp = p+31;
strcpy(commentp,comment);
p = p+31;
p = skip_string(p,1);
if (ip_equal(bcast_ip,d->bcast_ip))
{
continue;
}
for (work = d->workgrouplist; work; work = work->next)
{
uint32 stype = work->ServerType;
struct server_record *s;
BOOL announce = False;
if (work->needannounce)
{
/* drop back to a max 3 minute announce - this is to prevent a
single lost packet from stuffing things up for too long */
work->announce_interval = MIN(work->announce_interval,3*60);
work->lastannounce_time = t - (work->announce_interval+1);
}
/* announce every minute at first then progress to every 12 mins */
if (work->lastannounce_time &&
(t - work->lastannounce_time) < work->announce_interval)
{
continue;
}
if (work->announce_interval < 12*60) work->announce_interval += 60;
work->lastannounce_time = t;
DEBUG(2,("Sending announcement to subnet %s for workgroup %s\n",
inet_ntoa(d->bcast_ip),work->work_group));
if (!ip_equal(bcast_ip,d->bcast_ip))
{
stype &= ~(SV_TYPE_POTENTIAL_BROWSER | SV_TYPE_MASTER_BROWSER |
SV_TYPE_DOMAIN_MASTER | SV_TYPE_BACKUP_BROWSER |
SV_TYPE_DOMAIN_CTRL | SV_TYPE_DOMAIN_MEMBER);
}
for (s = work->serverlist; s; s = s->next)
{
if (strequal(myname, s->serv.name)) { announce = True; break; }
}
if (announce)
{
bzero(outbuf,sizeof(outbuf));
p = outbuf+1;
CVAL(p,0) = updatecount;
SIVAL(p,1,work->announce_interval*1000); /* ms - despite the spec */
namep = p+5;
StrnCpy(namep,my_name,16);
strupper(namep);
CVAL(p,21) = 2; /* major version */
CVAL(p,22) = 2; /* minor version */
stypep = p+23;
SIVAL(p,23,stype);
SSVAL(p,27,0xaa55); /* browse signature */
SSVAL(p,29,1); /* browse version */
commentp = p+31;
strcpy(commentp,comment);
p = p+31;
p = skip_string(p,1);
if (ip_equal(bcast_ip,d->bcast_ip))
{
if (AM_MASTER(work))
{
SIVAL(stypep,0,work->ServerType);
CVAL(outbuf,0) = 15; /* local member announce */
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
PTR_DIFF(p,outbuf),
my_name,work->work_group,0,0x1e,d->bcast_ip,myip);
CVAL(outbuf,0) = 12; /* domain announce */
StrnCpy(namep,work->work_group,15);
strupper(namep);
StrnCpy(commentp,myname,15);
strupper(commentp);
SIVAL(stypep,0,(unsigned)0x80000000);
p = commentp + strlen(commentp) + 1;
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
PTR_DIFF(p,outbuf),
my_name,MSBROWSE,0,0x01,d->bcast_ip,myip);
}
else
{
CVAL(outbuf,0) = 1; /* host announce */
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
PTR_DIFF(p,outbuf),
my_name,work->work_group,0,0x1d,d->bcast_ip,myip);
}
}
}
if (work->needannounce)
{
work->needannounce = False;
break;
/* sorry: can't do too many announces. do some more later */
}
if (AM_MASTER(work))
{
SIVAL(stypep,0,work->ServerType);
CVAL(outbuf,0) = 15; /* local member announce */
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
PTR_DIFF(p,outbuf),
my_name,work->work_group,0,
0x1e,d->bcast_ip,myip);
CVAL(outbuf,0) = 12; /* domain announce */
StrnCpy(namep,work->work_group,15);
strupper(namep);
StrnCpy(commentp,myname,15);
strupper(commentp);
SIVAL(stypep,0,(unsigned)0x80000000);
p = commentp + strlen(commentp) + 1;
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
PTR_DIFF(p,outbuf),
my_name,MSBROWSE,0,0x01,d->bcast_ip,myip);
}
else
{
CVAL(outbuf,0) = 1; /* host announce */
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
PTR_DIFF(p,outbuf),
my_name,work->work_group,0,0x1d,d->bcast_ip,myip);
}
}
}
if (work->needannounce)
{
work->needannounce = False;
break;
/* sorry: can't do too many announces. do some more later */
}
}
}
}
@ -337,108 +335,108 @@ void announce_host(void)
**************************************************************************/
void announce_master(void)
{
struct domain_record *d;
static time_t last=0;
time_t t = time(NULL);
BOOL am_master = False; /* are we a master of some sort? :-) */
struct domain_record *d;
static time_t last=0;
time_t t = time(NULL);
BOOL am_master = False; /* are we a master of some sort? :-) */
#ifdef TEST_CODE
if (last && (t-last < 2*60)) return;
if (last && (t-last < 2*60)) return;
#else
if (last && (t-last < 15*60)) return;
if (last && (t-last < 15*60)) return;
#endif
last = t;
last = t;
for (d = domainlist; d; d = d->next)
for (d = domainlist; d; d = d->next)
{
struct work_record *work;
for (work = d->workgrouplist; work; work = work->next)
{
struct work_record *work;
for (work = d->workgrouplist; work; work = work->next)
{
if (AM_MASTER(work))
{
am_master = True;
}
}
if (AM_MASTER(work))
{
am_master = True;
}
}
if (!am_master) return; /* only proceed if we are a master browser */
for (d = domainlist; d; d = d->next)
}
if (!am_master) return; /* only proceed if we are a master browser */
for (d = domainlist; d; d = d->next)
{
struct work_record *work;
for (work = d->workgrouplist; work; work = work->next)
{
struct work_record *work;
for (work = d->workgrouplist; work; work = work->next)
struct server_record *s;
for (s = work->serverlist; s; s = s->next)
{
if (strequal(s->serv.name, myname)) continue;
/* all PDCs (which should also be master browsers) */
if (s->serv.type & SV_TYPE_DOMAIN_CTRL)
{
struct server_record *s;
for (s = work->serverlist; s; s = s->next)
/* check the existence of a pdc for this workgroup, and if
one exists at the specified ip, sync with it and announce
ourselves as a master browser to it */
if (!*lp_domain_controller() ||
!strequal(lp_domain_controller(), s->serv.name))
{
if (!lp_wins_support() && *lp_wins_server())
{
if (strequal(s->serv.name, myname)) continue;
/* all PDCs (which should also be master browsers) */
if (s->serv.type & SV_TYPE_DOMAIN_CTRL)
{
/* check the existence of a pdc for this workgroup, and if
one exists at the specified ip, sync with it and announce
ourselves as a master browser to it */
if (!*lp_domain_controller() ||
!strequal(lp_domain_controller(), s->serv.name))
{
if (!lp_wins_support() && *lp_wins_server())
{
struct in_addr ip;
ip = ipzero;
queue_netbios_pkt_wins(ClientNMB,NMB_QUERY,
MASTER_SERVER_CHECK,
work->work_group,0x1b,0,
False, False, ip);
}
else
{
struct domain_record *d2;
for (d2 = domainlist; d2; d2 = d2->next)
{
queue_netbios_packet(ClientNMB,NMB_QUERY,
MASTER_SERVER_CHECK,
work->work_group,0x1b,0,
True, False, d2->bcast_ip);
}
}
}
}
struct in_addr ip;
ip = ipzero;
queue_netbios_pkt_wins(ClientNMB,NMB_QUERY,
MASTER_SERVER_CHECK,
work->work_group,0x1b,0,
False, False, ip);
}
/* now do primary domain controller - the one that's not
necessarily in our browse lists, although it ought to be
this pdc is the one that we get TOLD about through smb.conf.
basically, if it's on a subnet that we know about, it may end
up in our browse lists (which is why it's explicitly excluded
in the code above) */
if (*lp_domain_controller())
else
{
struct in_addr ip;
BOOL bcast = False;
ip = *interpret_addr2(lp_domain_controller());
if (zero_ip(ip))
{
ip = bcast_ip;
bcast = True;
}
DEBUG(2, ("Searching for PDC %s at %s\n",
lp_domain_controller(), inet_ntoa(ip)));
/* check the existence of a pdc for this workgroup, and if
one exists at the specified ip, sync with it and announce
ourselves as a master browser to it */
queue_netbios_pkt_wins(ClientNMB, NMB_QUERY,MASTER_SERVER_CHECK,
work->work_group,0x1b, 0,
bcast, False, ip);
struct domain_record *d2;
for (d2 = domainlist; d2; d2 = d2->next)
{
queue_netbios_packet(ClientNMB,NMB_QUERY,
MASTER_SERVER_CHECK,
work->work_group,0x1b,0,
True, False, d2->bcast_ip);
}
}
}
}
}
/* now do primary domain controller - the one that's not
necessarily in our browse lists, although it ought to be
this pdc is the one that we get TOLD about through smb.conf.
basically, if it's on a subnet that we know about, it may end
up in our browse lists (which is why it's explicitly excluded
in the code above) */
if (*lp_domain_controller())
{
struct in_addr ip;
BOOL bcast = False;
ip = *interpret_addr2(lp_domain_controller());
if (zero_ip(ip))
{
ip = bcast_ip;
bcast = True;
}
DEBUG(2, ("Searching for PDC %s at %s\n",
lp_domain_controller(), inet_ntoa(ip)));
/* check the existence of a pdc for this workgroup, and if
one exists at the specified ip, sync with it and announce
ourselves as a master browser to it */
queue_netbios_pkt_wins(ClientNMB, NMB_QUERY,MASTER_SERVER_CHECK,
work->work_group,0x1b, 0,
bcast, False, ip);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -39,10 +39,6 @@ extern pstring ServerComment;
/* here are my election parameters */
/* NTAS uses 2, NT uses 1, WfWg uses 0 */
#define MAINTAIN_LIST 2
#define ELECTION_VERSION 2
extern time_t StartupTime;
#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
@ -124,29 +120,29 @@ void browser_gone(char *work_name, struct in_addr ip)
void send_election(struct domain_record *d, char *group,uint32 criterion,
int timeup,char *name)
{
pstring outbuf;
char *p;
pstring outbuf;
char *p;
if (!d) return;
DEBUG(2,("Sending election to %s for workgroup %s\n",
if (!d) return;
DEBUG(2,("Sending election to %s for workgroup %s\n",
inet_ntoa(d->bcast_ip),group));
bzero(outbuf,sizeof(outbuf));
p = outbuf;
CVAL(p,0) = 8; /* election */
p++;
bzero(outbuf,sizeof(outbuf));
p = outbuf;
CVAL(p,0) = 8; /* election */
p++;
CVAL(p,0) = (criterion == 0 && timeup == 0) ? 0 : ELECTION_VERSION;
SIVAL(p,1,criterion);
SIVAL(p,5,timeup*1000); /* ms - despite the spec */
p += 13;
strcpy(p,name);
strupper(p);
p = skip_string(p,1);
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
name,group,0,0x1e,d->bcast_ip,myip);
CVAL(p,0) = (criterion == 0 && timeup == 0) ? 0 : ELECTION_VERSION;
SIVAL(p,1,criterion);
SIVAL(p,5,timeup*1000); /* ms - despite the spec */
p += 13;
strcpy(p,name);
strupper(p);
p = skip_string(p,1);
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
name,group,0,0x1e,d->bcast_ip,myip);
}
@ -155,46 +151,46 @@ void send_election(struct domain_record *d, char *group,uint32 criterion,
******************************************************************/
static void become_master(struct domain_record *d, struct work_record *work)
{
uint32 domain_type = SV_TYPE_DOMAIN_ENUM | SV_TYPE_SERVER_UNIX | 0x00400000;
uint32 domain_type = SV_TYPE_DOMAIN_ENUM | SV_TYPE_SERVER_UNIX | 0x00400000;
if (!work) return;
DEBUG(2,("Becoming master for %s\n",work->work_group));
work->ServerType |= SV_TYPE_MASTER_BROWSER;
work->ServerType &= ~SV_TYPE_POTENTIAL_BROWSER;
work->ElectionCriterion |= 0x5;
/* add browse, master and general names to database or register with WINS */
add_name_entry(MSBROWSE ,0x01,NB_ACTIVE|NB_GROUP);
add_name_entry(work->work_group,0x1d,NB_ACTIVE );
if (lp_domain_master())
if (!work) return;
DEBUG(2,("Becoming master for %s\n",work->work_group));
work->ServerType |= SV_TYPE_MASTER_BROWSER;
work->ServerType &= ~SV_TYPE_POTENTIAL_BROWSER;
work->ElectionCriterion |= 0x5;
/* add browse, master and general names to database or register with WINS */
add_name_entry(MSBROWSE ,0x01,NB_ACTIVE|NB_GROUP);
add_name_entry(work->work_group,0x1d,NB_ACTIVE );
if (lp_domain_master())
{
DEBUG(4,("Domain master: adding names...\n"));
/* add domain master and domain member names or register with WINS */
add_name_entry(work->work_group,0x1b,NB_ACTIVE );
add_name_entry(work->work_group,0x1c,NB_ACTIVE|NB_GROUP);
work->ServerType |= SV_TYPE_DOMAIN_MASTER;
if (lp_domain_logons())
{
DEBUG(4,("Domain master: adding names...\n"));
/* add domain master and domain member names or register with WINS */
add_name_entry(work->work_group,0x1b,NB_ACTIVE );
add_name_entry(work->work_group,0x1c,NB_ACTIVE|NB_GROUP);
work->ServerType |= SV_TYPE_DOMAIN_MASTER;
if (lp_domain_logons())
{
work->ServerType |= SV_TYPE_DOMAIN_CTRL;
work->ServerType |= SV_TYPE_DOMAIN_MEMBER;
}
}
/* update our server status */
add_server_entry(d,work,work->work_group,domain_type,0,myname,True);
add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
if (ip_equal(bcast_ip, d->bcast_ip))
{
/* ask all servers on our local net to announce to us */
announce_request(work, d->bcast_ip);
work->ServerType |= SV_TYPE_DOMAIN_CTRL;
work->ServerType |= SV_TYPE_DOMAIN_MEMBER;
}
}
/* update our server status */
add_server_entry(d,work,work->work_group,domain_type,0,myname,True);
add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
if (ip_equal(bcast_ip, d->bcast_ip))
{
/* ask all servers on our local net to announce to us */
announce_request(work, d->bcast_ip);
}
}
@ -203,18 +199,18 @@ static void become_master(struct domain_record *d, struct work_record *work)
******************************************************************/
void become_nonmaster(struct domain_record *d, struct work_record *work)
{
DEBUG(2,("Becoming non-master for %s\n",work->work_group));
work->ServerType &= ~SV_TYPE_MASTER_BROWSER;
work->ServerType &= ~SV_TYPE_DOMAIN_MASTER;
work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
work->ElectionCriterion &= ~0x4;
remove_name_entry(work->work_group,0x1b);
remove_name_entry(work->work_group,0x1c);
remove_name_entry(work->work_group,0x1d);
remove_name_entry(MSBROWSE ,0x01);
DEBUG(2,("Becoming non-master for %s\n",work->work_group));
work->ServerType &= ~SV_TYPE_MASTER_BROWSER;
work->ServerType &= ~SV_TYPE_DOMAIN_MASTER;
work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
work->ElectionCriterion &= ~0x4;
remove_name_entry(work->work_group,0x1b);
remove_name_entry(work->work_group,0x1c);
remove_name_entry(work->work_group,0x1d);
remove_name_entry(MSBROWSE ,0x01);
}
@ -223,37 +219,37 @@ void become_nonmaster(struct domain_record *d, struct work_record *work)
******************************************************************/
void run_elections(void)
{
time_t t = time(NULL);
static time_t lastime = 0;
struct domain_record *d;
/* send election packets once a second */
if (lastime && t-lastime <= 0) return;
lastime = t;
for (d = domainlist; d; d = d->next)
time_t t = time(NULL);
static time_t lastime = 0;
struct domain_record *d;
/* send election packets once a second */
if (lastime && t-lastime <= 0) return;
lastime = t;
for (d = domainlist; d; d = d->next)
{
struct work_record *work;
for (work = d->workgrouplist; work; work = work->next)
{
struct work_record *work;
for (work = d->workgrouplist; work; work = work->next)
if (work->RunningElection)
{
send_election(d,work->work_group, work->ElectionCriterion,
t-StartupTime,myname);
if (work->ElectionCount++ >= 4)
{
if (work->RunningElection)
{
send_election(d,work->work_group, work->ElectionCriterion,
t-StartupTime,myname);
if (work->ElectionCount++ >= 4)
{
/* I won! now what :-) */
DEBUG(2,(">>> Won election on %s <<<\n",work->work_group));
work->RunningElection = False;
become_master(d, work);
}
}
/* I won! now what :-) */
DEBUG(2,(">>> Won election on %s <<<\n",work->work_group));
work->RunningElection = False;
become_master(d, work);
}
}
}
}
}
@ -289,56 +285,56 @@ static BOOL win_election(struct work_record *work,int version,uint32 criterion,
******************************************************************/
void process_election(struct packet_struct *p,char *buf)
{
struct dgram_packet *dgram = &p->packet.dgram;
struct in_addr ip = dgram->header.source_ip;
struct domain_record *d = find_domain(ip);
int version = CVAL(buf,0);
uint32 criterion = IVAL(buf,1);
int timeup = IVAL(buf,5)/1000;
char *name = buf+13;
struct work_record *work;
struct dgram_packet *dgram = &p->packet.dgram;
struct in_addr ip = dgram->header.source_ip;
struct domain_record *d = find_domain(ip);
int version = CVAL(buf,0);
uint32 criterion = IVAL(buf,1);
int timeup = IVAL(buf,5)/1000;
char *name = buf+13;
struct work_record *work;
if (!d) return;
if (!d) return;
name[15] = 0;
name[15] = 0;
DEBUG(3,("Election request from %s vers=%d criterion=%08x timeup=%d\n",
name,version,criterion,timeup));
if (same_context(dgram)) return;
for (work = d->workgrouplist; work; work = work->next)
DEBUG(3,("Election request from %s vers=%d criterion=%08x timeup=%d\n",
name,version,criterion,timeup));
if (same_context(dgram)) return;
for (work = d->workgrouplist; work; work = work->next)
{
if (listening_name(work, &dgram->dest_name) &&
strequal(work->work_group, lp_workgroup()) &&
ip_equal(d->bcast_ip, bcast_ip))
{
if (listening_name(work, &dgram->dest_name) &&
strequal(work->work_group, lp_workgroup()) &&
ip_equal(d->bcast_ip, bcast_ip))
if (win_election(work, version,criterion,timeup,name))
{
if (!work->RunningElection)
{
if (win_election(work, version,criterion,timeup,name))
{
if (!work->RunningElection)
{
work->needelection = True;
work->ElectionCount=0;
}
}
else
{
work->needelection = False;
if (work->RunningElection)
{
work->RunningElection = False;
DEBUG(3,(">>> Lost election on %s <<<\n",work->work_group));
/* if we are the master then remove our masterly names */
if (AM_MASTER(work))
{
become_nonmaster(d, work);
}
}
}
work->needelection = True;
work->ElectionCount=0;
}
}
else
{
work->needelection = False;
if (work->RunningElection)
{
work->RunningElection = False;
DEBUG(3,(">>> Lost election on %s <<<\n",work->work_group));
/* if we are the master then remove our masterly names */
if (AM_MASTER(work))
{
become_nonmaster(d, work);
}
}
}
}
}
}

View File

@ -245,29 +245,6 @@ uint16 initiate_netbios_packet(int fd,int quest_type,char *name,int name_type,
}
void send_name_reg(void)
{
struct packet_struct p;
struct nmb_packet *nmb = &p.packet.nmb;
int rcode = 0;
nmb->header.opcode = 5;
nmb->header.response = True;
nmb->header.nm_flags.bcast = False;
nmb->header.nm_flags.recursion_available = CanRecurse;
nmb->header.nm_flags.recursion_desired = CanRecurse;
nmb->header.nm_flags.trunc = False;
nmb->header.nm_flags.authoritative = True;
nmb->header.qdcount = 0;
nmb->header.ancount = 1;
nmb->header.nscount = 0;
nmb->header.arcount = 0;
nmb->header.rcode = rcode;
send_packet(&p);
}
/****************************************************************************
wrapper function to override a broadcast message and send it to the WINS
name server instead, if it exists. if wins is false, and there has been no
@ -349,7 +326,8 @@ void queue_netbios_packet(int fd,int quest_type,enum cmd_type cmd,char *name,
if (id == 0) return;
if ((n = make_name_query_record(cmd,id,fd,name,name_type,bcast,recurse,to_ip)))
if ((n =
make_name_query_record(cmd,id,fd,name,name_type,bcast,recurse,to_ip)))
{
add_response_record(n);
}
@ -453,13 +431,41 @@ void listen_for_packets(BOOL run_election)
if (FD_ISSET(ClientNMB,&fds))
{
struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
if (packet) queue_packet(packet);
if (packet) {
#if 0
if (ip_equal(packet->ip,myip) &&
(packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
DEBUG(3,("discarding packet from %s:%d\n",
inet_ntoa(packet->ip),packet->port));
DEBUG(3,("myip=%s eq=%d\n",
inet_ntoa(myip),ip_equal(packet->ip,myip)));
free_packet(packet);
} else
#endif
{
queue_packet(packet);
}
}
}
if (FD_ISSET(ClientDGRAM,&fds))
{
struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
if (packet) queue_packet(packet);
if (packet) {
#if 0
if (ip_equal(packet->ip,myip) &&
(packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
DEBUG(3,("discarding packet from %s:%d\n",
inet_ntoa(packet->ip),packet->port));
DEBUG(3,("myip=%s eq=%d\n",
inet_ntoa(myip),ip_equal(packet->ip,myip)));
free_packet(packet);
} else
#endif
{
queue_packet(packet);
}
}
}
}
@ -615,7 +621,7 @@ BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
p.ip = dest_ip;
p.port = DGRAM_PORT;
p.fd = fd;
p.fd = ClientDGRAM;
p.timestamp = time(NULL);
p.packet_type = DGRAM_PACKET;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -144,15 +144,15 @@ static void fault_continue(void)
******************************************************************/
static void expire_names_and_servers(void)
{
static time_t lastrun = 0;
time_t t = time(NULL);
if (!lastrun) lastrun = t;
if (t < lastrun + 5) return;
lastrun = t;
expire_names(t);
expire_servers(t);
static time_t lastrun = 0;
time_t t = time(NULL);
if (!lastrun) lastrun = t;
if (t < lastrun + 5) return;
lastrun = t;
expire_names(t);
expire_servers(t);
}
/*****************************************************************************
@ -285,6 +285,7 @@ static void process(void)
while (True)
{
time_t t = time(NULL);
run_election = check_elections();
listen_for_packets(run_election);
@ -296,7 +297,8 @@ static void process(void)
announce_master();
expire_names_and_servers();
expire_netbios_response_entries(time(NULL)-10);
expire_netbios_response_entries(t-10);
refresh_my_names(t);
write_browse_list();
do_browser_lists();

View File

@ -58,78 +58,78 @@ adds information retrieved from a NetServerEnum call
****************************************************************************/
static BOOL add_info(struct domain_record *d, struct work_record *work, int servertype)
{
char *rparam = NULL;
char *rdata = NULL;
int rdrcnt,rprcnt;
char *p;
pstring param;
int uLevel = 1;
int count = -1;
/* now send a SMBtrans command with api ServerEnum? */
p = param;
SSVAL(p,0,0x68); /* api number */
p += 2;
strcpy(p,"WrLehDz");
p = skip_string(p,1);
strcpy(p,"B16BBDz");
p = skip_string(p,1);
SSVAL(p,0,uLevel);
SSVAL(p,2,0x2000); /* buf length */
p += 4;
SIVAL(p,0,servertype);
p += 4;
strcpy(p, work->work_group);
p = skip_string(p,1);
if (cli_call_api(PTR_DIFF(p,param),0, 8,10000,
&rprcnt,&rdrcnt, param,NULL,
&rparam,&rdata))
char *rparam = NULL;
char *rdata = NULL;
int rdrcnt,rprcnt;
char *p;
pstring param;
int uLevel = 1;
int count = -1;
/* now send a SMBtrans command with api ServerEnum? */
p = param;
SSVAL(p,0,0x68); /* api number */
p += 2;
strcpy(p,"WrLehDz");
p = skip_string(p,1);
strcpy(p,"B16BBDz");
p = skip_string(p,1);
SSVAL(p,0,uLevel);
SSVAL(p,2,0x2000); /* buf length */
p += 4;
SIVAL(p,0,servertype);
p += 4;
strcpy(p, work->work_group);
p = skip_string(p,1);
if (cli_call_api(PTR_DIFF(p,param),0, 8,10000,
&rprcnt,&rdrcnt, param,NULL,
&rparam,&rdata))
{
int res = SVAL(rparam,0);
int converter=SVAL(rparam,2);
int i;
if (res == 0)
{
int res = SVAL(rparam,0);
int converter=SVAL(rparam,2);
int i;
if (res == 0)
count=SVAL(rparam,4);
p = rdata;
for (i = 0;i < count;i++, p += 26)
{
char *sname = p;
uint32 stype = IVAL(p,18);
int comment_offset = IVAL(p,22) & 0xFFFF;
char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
struct work_record *w = work;
DEBUG(4, ("\t%-16.16s %08x %s\n", sname, stype, cmnt));
if (stype & SV_TYPE_DOMAIN_ENUM)
{
count=SVAL(rparam,4);
p = rdata;
for (i = 0;i < count;i++, p += 26)
/* creates workgroup on remote subnet */
if ((w = find_workgroupstruct(d,sname, False)))
{
if (ip_equal(bcast_ip, d->bcast_ip))
{
char *sname = p;
uint32 stype = IVAL(p,18);
int comment_offset = IVAL(p,22) & 0xFFFF;
char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
struct work_record *w = work;
DEBUG(4, ("\t%-16.16s %08x %s\n", sname, stype, cmnt));
if (stype & SV_TYPE_DOMAIN_ENUM)
{
/* creates workgroup on remote subnet */
if ((w = find_workgroupstruct(d,sname, False)))
{
if (ip_equal(bcast_ip, d->bcast_ip))
{
announce_request(w, d->bcast_ip);
}
}
}
add_server_entry(d,w,sname,stype,lp_max_ttl(),cmnt,False);
announce_request(w, d->bcast_ip);
}
}
}
add_server_entry(d,w,sname,stype,lp_max_ttl(),cmnt,False);
}
}
if (rparam) free(rparam);
if (rdata) free(rdata);
return(True);
}
if (rparam) free(rparam);
if (rdata) free(rdata);
return(True);
}

View File

@ -149,6 +149,7 @@ typedef struct
int os_level;
int max_ttl;
BOOL bWINSsupport;
BOOL bWINSproxy;
BOOL bPreferredMaster;
BOOL bDomainMaster;
BOOL bDomainLogons;
@ -163,7 +164,6 @@ typedef struct
BOOL bReadbmpx;
BOOL bSyslogOnly;
BOOL bBrowseList;
BOOL bProxyNameResolution;
} global;
static global Globals;
@ -414,13 +414,13 @@ struct parm_struct
{"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL},
{"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL},
{"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL},
{"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL},
{"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL},
{"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
{"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
{"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL},
{"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL},
{"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL},
{"proxy name resolution",P_BOOL,P_GLOBAL,&Globals.bProxyNameResolution,NULL},
{"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL},
{"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL},
@ -578,8 +578,8 @@ static void init_globals(void)
Globals.bDomainMaster = False;
Globals.bDomainLogons = False;
Globals.bBrowseList = True;
Globals.bProxyNameResolution = True;
Globals.bWINSsupport = True;
Globals.bWINSproxy = False;
#ifdef KANJI
coding_system = interpret_coding_system (KANJI, SJIS_CODE);
@ -706,6 +706,7 @@ FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
@ -721,7 +722,6 @@ FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
FN_GLOBAL_BOOL(lp_proxy_name_resolution,&Globals.bProxyNameResolution)
FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)