summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>1996-06-04 15:14:47 +0000
committerAndrew Tridgell <tridge@samba.org>1996-06-04 15:14:47 +0000
commita2641cfe00b7857056fd8fd1e020aae7ea817690 (patch)
tree39bcd37ec9240fb1a285a50fb12303cb2a865363
parent5607ff396c375976e440f9c955a313ddd58e3bbd (diff)
downloadsamba-a2641cfe00b7857056fd8fd1e020aae7ea817690.tar.gz
samba-a2641cfe00b7857056fd8fd1e020aae7ea817690.tar.bz2
samba-a2641cfe00b7857056fd8fd1e020aae7ea817690.zip
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 used to be commit 045014aa57721b9701ca379bcab055b908773184)
-rw-r--r--docs/manpages/smb.conf.535
-rw-r--r--source3/client/client.c7
-rw-r--r--source3/include/nameserv.h6
-rw-r--r--source3/lib/util.c9
-rw-r--r--source3/libsmb/nmblib.c2
-rw-r--r--source3/loadparm.h2
-rw-r--r--source3/nameannounce.c452
-rw-r--r--source3/namedb.c910
-rw-r--r--source3/nameelect.c286
-rw-r--r--source3/nameresp.c60
-rw-r--r--source3/nameserv.c1246
-rw-r--r--source3/namework.c1116
-rw-r--r--source3/nmbd/nmbd.c22
-rw-r--r--source3/nmbsync.c132
-rw-r--r--source3/param/loadparm.c8
15 files changed, 2166 insertions, 2127 deletions
diff --git a/docs/manpages/smb.conf.5 b/docs/manpages/smb.conf.5
index f29e7b6b02..7149be6a47 100644
--- a/docs/manpages/smb.conf.5
+++ b/docs/manpages/smb.conf.5
@@ -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
diff --git a/source3/client/client.c b/source3/client/client.c
index 3cefbc2284..5e464ea111 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -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);
}
diff --git a/source3/include/nameserv.h b/source3/include/nameserv.h
index 81079fabe0..51f5ec8479 100644
--- a/source3/include/nameserv.h
+++ b/source3/include/nameserv.h
@@ -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)
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 57f2e9240c..427d15cdcf 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -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);
diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c
index d8d6eb0ee4..87fe5fee78 100644
--- a/source3/libsmb/nmblib.c
+++ b/source3/libsmb/nmblib.c
@@ -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);
diff --git a/source3/loadparm.h b/source3/loadparm.h
index 5600d66922..92c8274767 100644
--- a/source3/loadparm.h
+++ b/source3/loadparm.h
@@ -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);
diff --git a/source3/nameannounce.c b/source3/nameannounce.c
index f0de4d0a27..083512990b 100644
--- a/source3/nameannounce.c
+++ b/source3/nameannounce.c
@@ -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;
-
- StrnCpy(comment, *ServerComment ? ServerComment : "NoComment", 43);
+ time_t t = time(NULL);
+ pstring outbuf;
+ char *p;
+ char *namep;
+ char *stypep;
+ char *commentp;
+ pstring comment;
+ char *my_name;
+ struct domain_record *d;
- my_name = *myname ? myname : "NoName";
+ StrnCpy(comment, *ServerComment ? ServerComment : "NoComment", 43);
- for (d = domainlist; d; d = d->next)
- {
- struct work_record *work;
+ my_name = *myname ? myname : "NoName";
- if (!ip_equal(bcast_ip,d->bcast_ip))
- {
- continue;
- }
+ 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)
+ 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))
{
- 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);
+ }
}
+ }
}
diff --git a/source3/namedb.c b/source3/namedb.c
index 9151789b9b..3e19f3fc8a 100644
--- a/source3/namedb.c
+++ b/source3/namedb.c
@@ -55,11 +55,6 @@ int workgroup_count = 0; /* unique index key: one for each workgroup */
SV_TYPE_PRINTQ_SERVER | SV_TYPE_POTENTIAL_BROWSER)
/* here are my election parameters */
-
-/* NTAS uses 2, NT uses 1, WfWg uses 0 */
-#define MAINTAIN_LIST 2
-#define ELECTION_VERSION 2
-
#define MSBROWSE "\001\002__MSBROWSE__\002"
@@ -68,23 +63,23 @@ int workgroup_count = 0; /* unique index key: one for each workgroup */
**************************************************************************/
static void add_workgroup(struct work_record *work, struct domain_record *d)
{
- struct work_record *w2;
-
- if (!work || !d) return;
-
- if (!d->workgrouplist)
- {
- d->workgrouplist = work;
- work->prev = NULL;
- work->next = NULL;
- return;
- }
-
- for (w2 = d->workgrouplist; w2->next; w2 = w2->next);
-
- w2->next = work;
- work->next = NULL;
- work->prev = w2;
+ struct work_record *w2;
+
+ if (!work || !d) return;
+
+ if (!d->workgrouplist)
+ {
+ d->workgrouplist = work;
+ work->prev = NULL;
+ work->next = NULL;
+ return;
+ }
+
+ for (w2 = d->workgrouplist; w2->next; w2 = w2->next);
+
+ w2->next = work;
+ work->next = NULL;
+ work->prev = w2;
}
@@ -93,56 +88,55 @@ static void add_workgroup(struct work_record *work, struct domain_record *d)
**************************************************************************/
static struct work_record *make_workgroup(char *name)
{
- struct work_record *work;
- struct domain_record *d;
- int t = -1;
-
- if (!name || !name[0]) return NULL;
-
- work = (struct work_record *)malloc(sizeof(*work));
- if (!work) return(NULL);
-
- StrnCpy(work->work_group,name,sizeof(work->work_group)-1);
- work->serverlist = NULL;
-
- work->ServerType = DFLT_SERVER_TYPE;
- work->RunningElection = False;
- work->ElectionCount = 0;
- work->needelection = False;
- work->needannounce = True;
-
- /* make sure all token representations of workgroups are unique */
-
- for (d = domainlist; d && t == -1; d = d->next)
- {
- struct work_record *w;
- for (w = d->workgrouplist; w && t == -1; w = w->next)
- {
- if (strequal(w->work_group, work->work_group)) t = w->token;
- }
- }
-
- if (t == -1)
- {
- work->token = ++workgroup_count;
- }
- else
- {
- work->token = t;
- }
-
-
- /* WfWg uses 01040b01 */
- /* Win95 uses 01041501 */
- /* NTAS uses ???????? */
- work->ElectionCriterion = (MAINTAIN_LIST<<1)|(ELECTION_VERSION<<8);
- work->ElectionCriterion |= (lp_os_level() << 24);
- if (lp_domain_master())
+ struct work_record *work;
+ struct domain_record *d;
+ int t = -1;
+
+ if (!name || !name[0]) return NULL;
+
+ work = (struct work_record *)malloc(sizeof(*work));
+ if (!work) return(NULL);
+
+ StrnCpy(work->work_group,name,sizeof(work->work_group)-1);
+ work->serverlist = NULL;
+
+ work->ServerType = DFLT_SERVER_TYPE;
+ work->RunningElection = False;
+ work->ElectionCount = 0;
+ work->needelection = False;
+ work->needannounce = True;
+
+ /* make sure all token representations of workgroups are unique */
+
+ for (d = domainlist; d && t == -1; d = d->next)
+ {
+ struct work_record *w;
+ for (w = d->workgrouplist; w && t == -1; w = w->next)
{
- work->ElectionCriterion |= 0x80;
+ if (strequal(w->work_group, work->work_group)) t = w->token;
}
-
- return work;
+ }
+
+ if (t == -1)
+ {
+ work->token = ++workgroup_count;
+ }
+ else
+ {
+ work->token = t;
+ }
+
+
+ /* WfWg uses 01040b01 */
+ /* Win95 uses 01041501 */
+ /* NTAS uses ???????? */
+ work->ElectionCriterion = (MAINTAIN_LIST<<1)|(ELECTION_VERSION<<8);
+ work->ElectionCriterion |= (lp_os_level() << 24);
+ if (lp_domain_master()) {
+ work->ElectionCriterion |= 0x80;
+ }
+
+ return work;
}
@@ -152,30 +146,31 @@ static struct work_record *make_workgroup(char *name)
******************************************************************/
static void remove_old_servers(struct work_record *work, time_t t)
{
- struct server_record *s;
- struct server_record *nexts;
-
- /* expire old entries in the serverlist */
- for (s = work->serverlist; s; s = nexts)
+ struct server_record *s;
+ struct server_record *nexts;
+
+ /* expire old entries in the serverlist */
+ for (s = work->serverlist; s; s = nexts)
+ {
+ if (t == -1 || (s->death_time && s->death_time < t))
{
- if (t == -1 || (s->death_time && s->death_time < t))
- {
- DEBUG(3,("Removing dead server %s\n",s->serv.name));
- updatedlists = True;
- nexts = s->next;
-
- if (s->prev) s->prev->next = s->next;
- if (s->next) s->next->prev = s->prev;
-
- if (work->serverlist == s) work->serverlist = s->next;
+ DEBUG(3,("Removing dead server %s\n",s->serv.name));
+ updatedlists = True;
+ nexts = s->next;
+
+ if (s->prev) s->prev->next = s->next;
+ if (s->next) s->next->prev = s->prev;
+
+ if (work->serverlist == s)
+ work->serverlist = s->next;
- free(s);
- }
- else
- {
- nexts = s->next;
- }
+ free(s);
}
+ else
+ {
+ nexts = s->next;
+ }
+ }
}
@@ -184,24 +179,24 @@ static void remove_old_servers(struct work_record *work, time_t t)
******************************************************************/
struct work_record *remove_workgroup(struct domain_record *d, struct work_record *work)
{
- struct work_record *ret_work = NULL;
-
- if (!d || !work) return NULL;
-
- DEBUG(3,("Removing old workgroup %s\n", work->work_group));
-
- remove_old_servers(work, -1);
-
- ret_work = work->next;
-
- if (work->prev) work->prev->next = work->next;
- if (work->next) work->next->prev = work->prev;
-
- if (d->workgrouplist == work) d->workgrouplist = work->next;
-
- free(work);
-
- return ret_work;
+ struct work_record *ret_work = NULL;
+
+ if (!d || !work) return NULL;
+
+ DEBUG(3,("Removing old workgroup %s\n", work->work_group));
+
+ remove_old_servers(work, -1);
+
+ ret_work = work->next;
+
+ if (work->prev) work->prev->next = work->next;
+ if (work->next) work->next->prev = work->prev;
+
+ if (d->workgrouplist == work) d->workgrouplist = work->next;
+
+ free(work);
+
+ return ret_work;
}
@@ -232,21 +227,21 @@ static void add_domain(struct domain_record *d)
**************************************************************************/
static void add_browse_cache(struct browse_cache_record *b)
{
-struct browse_cache_record *b2;
-
- if (!browserlist)
- {
- browserlist = b;
- b->prev = NULL;
- b->next = NULL;
- return;
- }
-
- for (b2 = browserlist; b2->next; b2 = b2->next) ;
-
- b2->next = b;
- b->next = NULL;
- b->prev = b2;
+ struct browse_cache_record *b2;
+
+ if (!browserlist)
+ {
+ browserlist = b;
+ b->prev = NULL;
+ b->next = NULL;
+ return;
+ }
+
+ for (b2 = browserlist; b2->next; b2 = b2->next) ;
+
+ b2->next = b;
+ b->next = NULL;
+ b->prev = b2;
}
@@ -277,29 +272,29 @@ static void add_server(struct work_record *work,struct server_record *s)
******************************************************************/
void expire_browse_cache(time_t t)
{
- struct browse_cache_record *b;
- struct browse_cache_record *nextb;
-
- /* expire old entries in the serverlist */
- for (b = browserlist; b; b = nextb)
+ struct browse_cache_record *b;
+ struct browse_cache_record *nextb;
+
+ /* expire old entries in the serverlist */
+ for (b = browserlist; b; b = nextb)
+ {
+ if (b->synced && b->sync_time < t)
{
- if (b->synced && b->sync_time < t)
- {
- DEBUG(3,("Removing dead cached browser %s\n",b->name));
- nextb = b->next;
-
- if (b->prev) b->prev->next = b->next;
- if (b->next) b->next->prev = b->prev;
-
- if (browserlist == b) browserlist = b->next;
-
- free(b);
- }
- else
- {
- nextb = b->next;
- }
+ DEBUG(3,("Removing dead cached browser %s\n",b->name));
+ nextb = b->next;
+
+ if (b->prev) b->prev->next = b->next;
+ if (b->next) b->next->prev = b->prev;
+
+ if (browserlist == b) browserlist = b->next;
+
+ free(b);
}
+ else
+ {
+ nextb = b->next;
+ }
+ }
}
@@ -311,51 +306,51 @@ void expire_browse_cache(time_t t)
**************************************************************************/
struct work_record *find_workgroupstruct(struct domain_record *d, fstring name, BOOL add)
{
- struct work_record *ret, *work;
-
- if (!d) return NULL;
-
- DEBUG(4, ("workgroup search for %s: ", name));
-
- if (strequal(name, "*"))
+ struct work_record *ret, *work;
+
+ if (!d) return NULL;
+
+ DEBUG(4, ("workgroup search for %s: ", name));
+
+ if (strequal(name, "*"))
+ {
+ DEBUG(2,("add any workgroups: initiating browser search on %s\n",
+ inet_ntoa(d->bcast_ip)));
+ queue_netbios_pkt_wins(ClientNMB,NMB_QUERY, FIND_MASTER,
+ MSBROWSE,0x1,0,
+ True,False, d->bcast_ip);
+ return NULL;
+ }
+
+ for (ret = d->workgrouplist; ret; ret = ret->next)
+ {
+ if (!strcmp(ret->work_group,name))
{
- DEBUG(2,("add any workgroups: initiating browser search on %s\n",
- inet_ntoa(d->bcast_ip)));
- queue_netbios_pkt_wins(ClientNMB,NMB_QUERY, FIND_MASTER,
- MSBROWSE,0x1,0,
- True,False, d->bcast_ip);
- return NULL;
+ DEBUG(4, ("found\n"));
+ return(ret);
}
-
- for (ret = d->workgrouplist; ret; ret = ret->next)
+ }
+
+ DEBUG(4, ("not found: creating\n"));
+
+ if ((work = make_workgroup(name)))
+ {
+ if (lp_preferred_master() &&
+ strequal(lp_workgroup(), name) &&
+ ip_equal(d->bcast_ip, bcast_ip))
{
- if (!strcmp(ret->work_group,name))
- {
- DEBUG(4, ("found\n"));
- return(ret);
- }
+ DEBUG(3, ("preferred master startup for %s\n", work->work_group));
+ work->needelection = True;
+ work->ElectionCriterion |= (1<<3);
}
-
- DEBUG(4, ("not found: creating\n"));
-
- if ((work = make_workgroup(name)))
+ if (!ip_equal(bcast_ip, d->bcast_ip))
{
- if (lp_preferred_master() &&
- strequal(lp_workgroup(), name) &&
- ip_equal(d->bcast_ip, bcast_ip))
- {
- DEBUG(3, ("preferred master startup for %s\n", work->work_group));
- work->needelection = True;
- work->ElectionCriterion |= (1<<3);
- }
- if (!ip_equal(bcast_ip, d->bcast_ip))
- {
- work->needelection = False;
- }
- add_workgroup(work, d);
- return(work);
+ work->needelection = False;
}
- return NULL;
+ add_workgroup(work, d);
+ return(work);
+ }
+ return NULL;
}
/****************************************************************************
@@ -363,20 +358,20 @@ struct work_record *find_workgroupstruct(struct domain_record *d, fstring name,
**************************************************************************/
struct domain_record *find_domain(struct in_addr source_ip)
{
- struct domain_record *d;
-
- /* search through domain list for broadcast/netmask that matches
- the source ip address */
-
- for (d = domainlist; d; d = d->next)
+ struct domain_record *d;
+
+ /* search through domain list for broadcast/netmask that matches
+ the source ip address */
+
+ for (d = domainlist; d; d = d->next)
+ {
+ if (same_net(source_ip, d->bcast_ip, d->mask_ip))
{
- if (same_net(source_ip, d->bcast_ip, d->mask_ip))
- {
- return(d);
- }
+ return(d);
}
-
- return (NULL);
+ }
+
+ return (NULL);
}
@@ -385,33 +380,33 @@ struct domain_record *find_domain(struct in_addr source_ip)
**************************************************************************/
static void dump_workgroups(void)
{
- struct domain_record *d;
-
- for (d = domainlist; d; d = d->next)
+ struct domain_record *d;
+
+ for (d = domainlist; d; d = d->next)
+ {
+ if (d->workgrouplist)
{
- if (d->workgrouplist)
+ struct work_record *work;
+
+ DEBUG(3,("dump domain %15s: ", inet_ntoa(d->bcast_ip)));
+ DEBUG(3,(" %15s:\n", inet_ntoa(d->bcast_ip)));
+
+ for (work = d->workgrouplist; work; work = work->next)
+ {
+ if (work->serverlist)
{
- struct work_record *work;
-
- DEBUG(3,("dump domain %15s: ", inet_ntoa(d->bcast_ip)));
- DEBUG(3,(" %15s:\n", inet_ntoa(d->bcast_ip)));
-
- for (work = d->workgrouplist; work; work = work->next)
- {
- if (work->serverlist)
- {
- struct server_record *s;
-
- DEBUG(3,("\t%s(%d)\n", work->work_group, work->token));
- for (s = work->serverlist; s; s = s->next)
- {
- DEBUG(3,("\t\t%s %8x (%s)\n",
- s->serv.name, s->serv.type, s->serv.comment));
- }
- }
- }
+ struct server_record *s;
+
+ DEBUG(3,("\t%s(%d)\n", work->work_group, work->token));
+ for (s = work->serverlist; s; s = s->next)
+ {
+ DEBUG(3,("\t\t%s %8x (%s)\n",
+ s->serv.name, s->serv.type, s->serv.comment));
+ }
}
+ }
}
+ }
}
/****************************************************************************
@@ -419,57 +414,60 @@ static void dump_workgroups(void)
****************************************************************************/
static struct domain_record *make_domain(struct in_addr ip, struct in_addr mask)
{
- struct domain_record *d;
- d = (struct domain_record *)malloc(sizeof(*d));
-
- if (!d) return(NULL);
-
- bzero((char *)d,sizeof(*d));
-
- DEBUG(4, ("making domain %s ", inet_ntoa(ip)));
- DEBUG(4, ("%s\n", inet_ntoa(mask)));
-
- d->bcast_ip = ip;
- d->mask_ip = mask;
- d->workgrouplist = NULL;
-
- add_domain(d);
-
- return d;
+ struct domain_record *d;
+ d = (struct domain_record *)malloc(sizeof(*d));
+
+ if (!d) return(NULL);
+
+ bzero((char *)d,sizeof(*d));
+
+ DEBUG(4, ("making domain %s ", inet_ntoa(ip)));
+ DEBUG(4, ("%s\n", inet_ntoa(mask)));
+
+ d->bcast_ip = ip;
+ d->mask_ip = mask;
+ d->workgrouplist = NULL;
+
+ add_domain(d);
+
+ return d;
}
/****************************************************************************
add a domain entry. creates a workgroup, if necessary, and adds the domain
to the named a workgroup.
****************************************************************************/
-struct domain_record *add_domain_entry(struct in_addr source_ip, struct in_addr source_mask,
+struct domain_record *add_domain_entry(struct in_addr source_ip,
+ struct in_addr source_mask,
char *name, BOOL add)
{
struct domain_record *d;
struct in_addr ip;
-
- ip = *interpret_addr2("255.255.255.255");
-
- if (zero_ip(source_ip)) source_ip = bcast_ip;
-
- /* add the domain into our domain database */
- if ((d = find_domain(source_ip)) ||
- (d = make_domain(source_ip, source_mask)))
+
+ ip = *interpret_addr2("255.255.255.255");
+
+ if (zero_ip(source_ip)) source_ip = bcast_ip;
+
+ /* add the domain into our domain database */
+ if ((d = find_domain(source_ip)) ||
+ (d = make_domain(source_ip, source_mask)))
+ {
+ struct work_record *w = find_workgroupstruct(d, name, add);
+
+ /* add WORKGROUP(1e) and WORKGROUP(00) entries into name database
+ or register with WINS server, if it's our workgroup */
+ if (strequal(lp_workgroup(), name))
{
- find_workgroupstruct(d, name, add);
-
- /* add WORKGROUP(1e) and WORKGROUP(00) entries into name database
- or register with WINS server, if it's our workgroup */
- if (strequal(lp_workgroup(), name))
- {
- add_name_entry(name,0x1e,NB_ACTIVE|NB_GROUP);
- add_name_entry(name,0x0 ,NB_ACTIVE|NB_GROUP);
- }
-
- DEBUG(3,("Added domain name entry %s at %s\n", name,inet_ntoa(ip)));
- return d;
+ extern pstring ServerComment;
+ add_name_entry(name,0x1e,NB_ACTIVE|NB_GROUP);
+ add_name_entry(name,0x0 ,NB_ACTIVE|NB_GROUP);
+ add_server_entry(d,w,myname,w->ServerType,0,ServerComment,True);
}
- return NULL;
+
+ DEBUG(3,("Added domain name entry %s at %s\n", name,inet_ntoa(ip)));
+ return d;
+ }
+ return NULL;
}
/****************************************************************************
@@ -478,141 +476,143 @@ struct domain_record *add_domain_entry(struct in_addr source_ip, struct in_addr
struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
time_t ttl, struct in_addr ip)
{
- BOOL newentry=False;
-
- struct browse_cache_record *b;
-
- /* search for the entry: if it's already in the cache, update that entry */
- for (b = browserlist; b; b = b->next)
- {
- if (ip_equal(ip,b->ip) && strequal(b->group, wg)) break;
- }
-
- if (b && b->synced)
- {
- /* entries get left in the cache for a while. this stops sync'ing too
- often if the network is large */
- DEBUG(4, ("browser %s %s %s already sync'd at time %d\n",
- b->name, b->group, inet_ntoa(b->ip), b->sync_time));
- return NULL;
- }
-
- if (!b)
- {
- newentry = True;
- b = (struct browse_cache_record *)malloc(sizeof(*b));
-
- if (!b) return(NULL);
-
- bzero((char *)b,sizeof(*b));
- }
-
- /* update the entry */
- ttl = time(NULL)+ttl;
-
- StrnCpy(b->name ,name,sizeof(b->name )-1);
- StrnCpy(b->group,wg ,sizeof(b->group)-1);
- strupper(b->name);
- strupper(b->group);
-
- b->ip = ip;
- b->type = type;
-
- if (newentry || ttl < b->sync_time) b->sync_time = ttl;
-
- if (newentry)
- {
- b->synced = False;
- add_browse_cache(b);
-
- DEBUG(3,("Added cache entry %s %s(%2x) %s ttl %d\n",
- wg, name, type, inet_ntoa(ip),ttl));
- }
- else
- {
- DEBUG(3,("Updated cache entry %s %s(%2x) %s ttl %d\n",
- wg, name, type, inet_ntoa(ip),ttl));
- }
-
- return(b);
+ BOOL newentry=False;
+
+ struct browse_cache_record *b;
+
+ /* search for the entry: if it's already in the cache, update that entry */
+ for (b = browserlist; b; b = b->next)
+ {
+ if (ip_equal(ip,b->ip) && strequal(b->group, wg)) break;
+ }
+
+ if (b && b->synced)
+ {
+ /* entries get left in the cache for a while. this stops sync'ing too
+ often if the network is large */
+ DEBUG(4, ("browser %s %s %s already sync'd at time %d\n",
+ b->name, b->group, inet_ntoa(b->ip), b->sync_time));
+ return NULL;
+ }
+
+ if (!b)
+ {
+ newentry = True;
+ b = (struct browse_cache_record *)malloc(sizeof(*b));
+
+ if (!b) return(NULL);
+
+ bzero((char *)b,sizeof(*b));
+ }
+
+ /* update the entry */
+ ttl = time(NULL)+ttl;
+
+ StrnCpy(b->name ,name,sizeof(b->name )-1);
+ StrnCpy(b->group,wg ,sizeof(b->group)-1);
+ strupper(b->name);
+ strupper(b->group);
+
+ b->ip = ip;
+ b->type = type;
+
+ if (newentry || ttl < b->sync_time) b->sync_time = ttl;
+
+ if (newentry)
+ {
+ b->synced = False;
+ add_browse_cache(b);
+
+ DEBUG(3,("Added cache entry %s %s(%2x) %s ttl %d\n",
+ wg, name, type, inet_ntoa(ip),ttl));
+ }
+ else
+ {
+ DEBUG(3,("Updated cache entry %s %s(%2x) %s ttl %d\n",
+ wg, name, type, inet_ntoa(ip),ttl));
+ }
+
+ return(b);
}
/****************************************************************************
add a server entry
****************************************************************************/
-struct server_record *add_server_entry(struct domain_record *d, struct work_record *work,
- char *name,int servertype, int ttl,char *comment,
+struct server_record *add_server_entry(struct domain_record *d,
+ struct work_record *work,
+ char *name,int servertype,
+ int ttl,char *comment,
BOOL replace)
{
- BOOL newentry=False;
- struct server_record *s;
-
- if (name[0] == '*')
- {
- return (NULL);
- }
-
- for (s = work->serverlist; s; s = s->next)
- {
- if (strequal(name,s->serv.name)) break;
- }
-
- if (s && !replace)
- {
- DEBUG(4,("Not replacing %s\n",name));
- return(s);
- }
-
- updatedlists=True;
-
- if (!s)
- {
- newentry = True;
- s = (struct server_record *)malloc(sizeof(*s));
-
- if (!s) return(NULL);
-
- bzero((char *)s,sizeof(*s));
- }
-
- if (ip_equal(bcast_ip, d->bcast_ip) &&
- strequal(lp_workgroup(),work->work_group))
- {
- servertype |= SV_TYPE_LOCAL_LIST_ONLY;
- }
- else
- {
- servertype &= ~SV_TYPE_LOCAL_LIST_ONLY;
- }
-
- /* update the entry */
- StrnCpy(s->serv.name,name,sizeof(s->serv.name)-1);
- StrnCpy(s->serv.comment,comment,sizeof(s->serv.comment)-1);
- strupper(s->serv.name);
- s->serv.type = servertype;
- s->death_time = ttl?time(NULL)+ttl*3:0;
-
- /* for a domain entry, the comment field refers to the server name */
-
- if (s->serv.type & SV_TYPE_DOMAIN_ENUM) strupper(s->serv.comment);
-
- if (newentry)
- {
- add_server(work, s);
-
- DEBUG(3,("Added "));
- }
- else
- {
- DEBUG(3,("Updated "));
- }
-
- DEBUG(3,("server entry %s of type %x (%s) to %s %s\n",
- name,servertype,comment,
- work->work_group,inet_ntoa(d->bcast_ip)));
-
- return(s);
+ BOOL newentry=False;
+ struct server_record *s;
+
+ if (name[0] == '*')
+ {
+ return (NULL);
+ }
+
+ for (s = work->serverlist; s; s = s->next)
+ {
+ if (strequal(name,s->serv.name)) break;
+ }
+
+ if (s && !replace)
+ {
+ DEBUG(4,("Not replacing %s\n",name));
+ return(s);
+ }
+
+ updatedlists=True;
+
+ if (!s)
+ {
+ newentry = True;
+ s = (struct server_record *)malloc(sizeof(*s));
+
+ if (!s) return(NULL);
+
+ bzero((char *)s,sizeof(*s));
+ }
+
+ if (ip_equal(bcast_ip, d->bcast_ip) &&
+ strequal(lp_workgroup(),work->work_group))
+ {
+ servertype |= SV_TYPE_LOCAL_LIST_ONLY;
+ }
+ else
+ {
+ servertype &= ~SV_TYPE_LOCAL_LIST_ONLY;
+ }
+
+ /* update the entry */
+ StrnCpy(s->serv.name,name,sizeof(s->serv.name)-1);
+ StrnCpy(s->serv.comment,comment,sizeof(s->serv.comment)-1);
+ strupper(s->serv.name);
+ s->serv.type = servertype;
+ s->death_time = ttl?time(NULL)+ttl*3:0;
+
+ /* for a domain entry, the comment field refers to the server name */
+
+ if (s->serv.type & SV_TYPE_DOMAIN_ENUM) strupper(s->serv.comment);
+
+ if (newentry)
+ {
+ add_server(work, s);
+
+ DEBUG(3,("Added "));
+ }
+ else
+ {
+ DEBUG(3,("Updated "));
+ }
+
+ DEBUG(3,("server entry %s of type %x (%s) to %s %s\n",
+ name,servertype,comment,
+ work->work_group,inet_ntoa(d->bcast_ip)));
+
+ return(s);
}
@@ -621,71 +621,71 @@ struct server_record *add_server_entry(struct domain_record *d, struct work_reco
******************************************************************/
void write_browse_list(void)
{
- struct domain_record *d;
-
- pstring fname,fnamenew;
- FILE *f;
-
- if (!updatedlists) return;
-
- dump_names();
- dump_workgroups();
-
- updatedlists = False;
- updatecount++;
-
- strcpy(fname,lp_lockdir());
- trim_string(fname,NULL,"/");
- strcat(fname,"/");
- strcat(fname,SERVER_LIST);
- strcpy(fnamenew,fname);
- strcat(fnamenew,".");
-
- f = fopen(fnamenew,"w");
-
- if (!f)
- {
- DEBUG(4,("Can't open %s - %s\n",fnamenew,strerror(errno)));
- return;
- }
-
- for (d = domainlist; d ; d = d->next)
+ struct domain_record *d;
+
+ pstring fname,fnamenew;
+ FILE *f;
+
+ if (!updatedlists) return;
+
+ dump_names();
+ dump_workgroups();
+
+ updatedlists = False;
+ updatecount++;
+
+ strcpy(fname,lp_lockdir());
+ trim_string(fname,NULL,"/");
+ strcat(fname,"/");
+ strcat(fname,SERVER_LIST);
+ strcpy(fnamenew,fname);
+ strcat(fnamenew,".");
+
+ f = fopen(fnamenew,"w");
+
+ if (!f)
+ {
+ DEBUG(4,("Can't open %s - %s\n",fnamenew,strerror(errno)));
+ return;
+ }
+
+ 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)
+ {
+ fstring tmp;
+
+ /* don't list domains I don't have a master for */
+ if ((s->serv.type & SV_TYPE_DOMAIN_ENUM) &&
+ !s->serv.comment[0])
{
- struct server_record *s;
- for (s = work->serverlist; s ; s = s->next)
- {
- fstring tmp;
-
- /* don't list domains I don't have a master for */
- if ((s->serv.type & SV_TYPE_DOMAIN_ENUM) &&
- !s->serv.comment[0])
- {
- continue;
- }
-
- /* output server details, plus what workgroup/domain
- they're in. without the domain information, the
- combined list of all servers in all workgroups gets
- sent to anyone asking about any workgroup! */
-
- sprintf(tmp, "\"%s\"", s->serv.name);
- fprintf(f, "%-25s ", tmp);
- fprintf(f, "%08x ", s->serv.type);
- sprintf(tmp, "\"%s\"", s->serv.comment);
- fprintf(f, "%-30s", tmp);
- fprintf(f, "\"%s\"\n", work->work_group);
- }
+ continue;
}
+
+ /* output server details, plus what workgroup/domain
+ they're in. without the domain information, the
+ combined list of all servers in all workgroups gets
+ sent to anyone asking about any workgroup! */
+
+ sprintf(tmp, "\"%s\"", s->serv.name);
+ fprintf(f, "%-25s ", tmp);
+ fprintf(f, "%08x ", s->serv.type);
+ sprintf(tmp, "\"%s\"", s->serv.comment);
+ fprintf(f, "%-30s", tmp);
+ fprintf(f, "\"%s\"\n", work->work_group);
+ }
}
-
- fclose(f);
- unlink(fname);
- chmod(fnamenew,0644);
- rename(fnamenew,fname);
- DEBUG(3,("Wrote browse list %s\n",fname));
+ }
+
+ fclose(f);
+ unlink(fname);
+ chmod(fnamenew,0644);
+ rename(fnamenew,fname);
+ DEBUG(3,("Wrote browse list %s\n",fname));
}
@@ -694,16 +694,16 @@ void write_browse_list(void)
******************************************************************/
void expire_servers(time_t t)
{
- struct domain_record *d;
-
- for (d = domainlist ; d ; d = d->next)
+ struct domain_record *d;
+
+ 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)
- {
- remove_old_servers(work, t);
- }
+ remove_old_servers(work, t);
}
+ }
}
diff --git a/source3/nameelect.c b/source3/nameelect.c
index 30c3c3795e..34455b27f9 100644
--- a/source3/nameelect.c
+++ b/source3/nameelect.c
@@ -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;
-
- if (!d) return;
+ pstring outbuf;
+ char *p;
- 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++;
-
- 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);
+ 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);
}
@@ -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;
-
- 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())
- {
- work->ServerType |= SV_TYPE_DOMAIN_CTRL;
- work->ServerType |= SV_TYPE_DOMAIN_MEMBER;
- }
- }
+ uint32 domain_type = SV_TYPE_DOMAIN_ENUM | SV_TYPE_SERVER_UNIX | 0x00400000;
- /* 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))
+ 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())
{
- /* 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;
-
- if (!d) return;
-
- 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;
+ 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;
+
+ name[15] = 0;
- 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);
+ }
}
+ }
}
+ }
}
diff --git a/source3/nameresp.c b/source3/nameresp.c
index a4a55c9f1b..8ed2ba92c4 100644
--- a/source3/nameresp.c
+++ b/source3/nameresp.c
@@ -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;
diff --git a/source3/nameserv.c b/source3/nameserv.c
index 4cd9b099f0..176d955853 100644
--- a/source3/nameserv.c
+++ b/source3/nameserv.c
@@ -206,20 +206,20 @@ struct name_record *add_netbios_entry(char *name, int type, int nb_flags, int tt
****************************************************************************/
void remove_name_entry(char *name,int type)
{
- if (lp_wins_support())
- {
- /* we are a WINS server. */
- remove_netbios_name(name,type,SELF,myip);
- }
- else
- {
- struct in_addr ip;
- ip = ipzero;
-
- queue_netbios_pkt_wins(ClientNMB,NMB_REL,NAME_RELEASE,
- name, type, 0,
- False, True, ip);
- }
+ if (lp_wins_support())
+ {
+ /* we are a WINS server. */
+ remove_netbios_name(name,type,SELF,myip);
+ }
+ else
+ {
+ struct in_addr ip;
+ ip = ipzero;
+
+ queue_netbios_pkt_wins(ClientNMB,NMB_REL,NAME_RELEASE,
+ name, type, 0,
+ False, True, ip);
+ }
}
@@ -228,20 +228,18 @@ void remove_name_entry(char *name,int type)
****************************************************************************/
void add_name_entry(char *name,int type,int nb_flags)
{
- if (lp_wins_support())
- {
- /* we are a WINS server. */
- add_netbios_entry(name,type,nb_flags,0,SELF,myip);
- }
- else
- {
- struct in_addr ip;
- ip = ipzero;
-
- queue_netbios_pkt_wins(ClientNMB,NMB_REG,NAME_REGISTER,
- name, type, nb_flags,
- False, True, ip);
- }
+ /* always add our own entries */
+ add_netbios_entry(name,type,nb_flags,0,SELF,myip);
+
+ if (!lp_wins_support())
+ {
+ struct in_addr ip;
+ ip = ipzero;
+
+ queue_netbios_pkt_wins(ClientNMB,NMB_REG,NAME_REGISTER,
+ name, type, nb_flags,
+ False, True, ip);
+ }
}
@@ -250,52 +248,67 @@ void add_name_entry(char *name,int type,int nb_flags)
**************************************************************************/
void add_my_names(void)
{
- struct in_addr ip;
+ struct in_addr ip;
- ip = ipzero;
-
- add_netbios_entry(myname,0x20,NB_ACTIVE,0,SELF,ip);
- add_netbios_entry(myname,0x03,NB_ACTIVE,0,SELF,ip);
- add_netbios_entry(myname,0x00,NB_ACTIVE,0,SELF,ip);
- add_netbios_entry(myname,0x1f,NB_ACTIVE,0,SELF,ip);
- add_netbios_entry("*",0x01,NB_ACTIVE,0,SELF,ip);
- add_netbios_entry("__SAMBA__",0x20,NB_ACTIVE,0,SELF,ip);
- add_netbios_entry("__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip);
-
- if (lp_wins_support()) {
- add_netbios_entry(inet_ntoa(myip),0x01,NB_ACTIVE,0,SELF,ip); /* nt as? */
- }
+ ip = ipzero;
+
+ add_name_entry(myname,0x20,NB_ACTIVE);
+ add_name_entry(myname,0x03,NB_ACTIVE);
+ add_name_entry(myname,0x00,NB_ACTIVE);
+ add_name_entry(myname,0x1f,NB_ACTIVE);
+
+ add_netbios_entry("*",0x0,NB_ACTIVE,0,SELF,ip);
+ add_netbios_entry("__SAMBA__",0x20,NB_ACTIVE,0,SELF,ip);
+ add_netbios_entry("__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip);
+
+ if (lp_wins_support()) {
+ add_netbios_entry(inet_ntoa(myip),0x01,NB_ACTIVE,0,SELF,ip); /* nt as? */
+ }
}
/*******************************************************************
- expires old names in the namelist
+ refresh my own names
******************************************************************/
-void expire_names(time_t t)
+void refresh_my_names(time_t t)
{
- struct name_record *n;
- struct name_record *next;
-
- /* expire old names */
- for (n = namelist; n; n = next)
- {
- if (n->death_time && n->death_time < t)
- {
- DEBUG(3,("Removing dead name %s\n", namestr(&n->name)));
-
- next = n->next;
+ static time_t lasttime = 0;
- if (n->prev) n->prev->next = n->next;
- if (n->next) n->next->prev = n->prev;
+ if (t - lasttime < REFRESH_TIME)
+ return;
+ lasttime = t;
- if (namelist == n) namelist = n->next;
+ add_my_names();
+}
- free(n);
- }
- else
- {
- next = n->next;
- }
+/*******************************************************************
+ expires old names in the namelist
+ ******************************************************************/
+void expire_names(time_t t)
+{
+ struct name_record *n;
+ struct name_record *next;
+
+ /* expire old names */
+ for (n = namelist; n; n = next)
+ {
+ if (n->death_time && n->death_time < t)
+ {
+ DEBUG(3,("Removing dead name %s\n", namestr(&n->name)));
+
+ next = n->next;
+
+ if (n->prev) n->prev->next = n->next;
+ if (n->next) n->next->prev = n->prev;
+
+ if (namelist == n) namelist = n->next;
+
+ free(n);
}
+ else
+ {
+ next = n->next;
+ }
+ }
}
@@ -304,27 +317,27 @@ response for a reg release received
**************************************************************************/
void response_name_release(struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- char *name = nmb->question.question_name.name;
- int type = nmb->question.question_name.name_type;
-
- DEBUG(4,("response name release received\n"));
-
- if (nmb->header.rcode == 0 && nmb->answers->rdata)
- {
- struct in_addr found_ip;
- putip((char*)&found_ip,&nmb->answers->rdata[2]);
-
- if (ip_equal(found_ip, myip))
- {
- remove_netbios_name(name,type,SELF,found_ip);
- }
- }
- else
+ struct nmb_packet *nmb = &p->packet.nmb;
+ char *name = nmb->question.question_name.name;
+ int type = nmb->question.question_name.name_type;
+
+ DEBUG(4,("response name release received\n"));
+
+ if (nmb->header.rcode == 0 && nmb->answers->rdata)
+ {
+ struct in_addr found_ip;
+ putip((char*)&found_ip,&nmb->answers->rdata[2]);
+
+ if (ip_equal(found_ip, myip))
{
- DEBUG(1,("name registration for %s rejected!\n",
- namestr(&nmb->question.question_name)));
+ remove_netbios_name(name,type,SELF,found_ip);
}
+ }
+ else
+ {
+ DEBUG(1,("name registration for %s rejected!\n",
+ namestr(&nmb->question.question_name)));
+ }
}
@@ -333,49 +346,49 @@ reply to a name release
****************************************************************************/
void reply_name_release(struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct in_addr ip;
- int rcode=0;
- int opcode = nmb->header.opcode;
- int nb_flags = nmb->additional->rdata[0];
- BOOL bcast = nmb->header.nm_flags.bcast;
- struct name_record *n;
- char rdata[6];
-
- putip((char *)&ip,&nmb->additional->rdata[2]);
-
- DEBUG(3,("Name release on name %s rcode=%d\n",
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct in_addr ip;
+ int rcode=0;
+ int opcode = nmb->header.opcode;
+ int nb_flags = nmb->additional->rdata[0];
+ BOOL bcast = nmb->header.nm_flags.bcast;
+ struct name_record *n;
+ char rdata[6];
+
+ putip((char *)&ip,&nmb->additional->rdata[2]);
+
+ DEBUG(3,("Name release on name %s rcode=%d\n",
namestr(&nmb->question.question_name),rcode));
-
- n = find_name_search(&nmb->question.question_name, FIND_GLOBAL, ip);
-
- /* XXXX under what conditions should we reject the removal?? */
- if (n && n->nb_flags == nb_flags && ip_equal(n->ip,ip))
- {
- /* success = True;
- rcode = 6; */
-
- remove_name(n);
- n = NULL;
- }
-
- if (bcast) return;
-
- /*if (success)*/
- {
- rdata[0] = nb_flags;
- rdata[1] = 0;
- putip(&rdata[2],(char *)&ip);
- }
-
- /* Send a NAME RELEASE RESPONSE */
- reply_netbios_packet(p,nmb->header.name_trn_id,rcode,opcode,
- &nmb->question.question_name,
- nmb->question.question_type,
- nmb->question.question_class,
- 0,
- rdata, 6 /*success ? 6 : 0*/);
- /* XXXX reject packet never tested: cannot tell what to do */
+
+ n = find_name_search(&nmb->question.question_name, FIND_GLOBAL, ip);
+
+ /* XXXX under what conditions should we reject the removal?? */
+ if (n && n->nb_flags == nb_flags && ip_equal(n->ip,ip))
+ {
+ /* success = True;
+ rcode = 6; */
+
+ remove_name(n);
+ n = NULL;
+ }
+
+ if (bcast) return;
+
+ /*if (success)*/
+ {
+ rdata[0] = nb_flags;
+ rdata[1] = 0;
+ putip(&rdata[2],(char *)&ip);
+ }
+
+ /* Send a NAME RELEASE RESPONSE */
+ reply_netbios_packet(p,nmb->header.name_trn_id,rcode,opcode,
+ &nmb->question.question_name,
+ nmb->question.question_type,
+ nmb->question.question_class,
+ 0,
+ rdata, 6 /*success ? 6 : 0*/);
+ /* XXXX reject packet never tested: cannot tell what to do */
}
@@ -384,30 +397,30 @@ response for a reg request received
**************************************************************************/
void response_name_reg(struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- char *name = nmb->question.question_name.name;
- int type = nmb->question.question_name.name_type;
-
- DEBUG(4,("response name registration received!\n"));
-
- if (nmb->header.rcode == 0 && nmb->answers->rdata)
- {
- int nb_flags = nmb->answers->rdata[0];
- struct in_addr found_ip;
- int ttl = nmb->answers->ttl;
- enum name_source source = REGISTER;
-
- putip((char*)&found_ip,&nmb->answers->rdata[2]);
-
- if (ip_equal(found_ip, myip)) source = SELF;
-
- add_netbios_entry(name,type,nb_flags,ttl,source,found_ip);
- }
- else
- {
- DEBUG(1,("name registration for %s rejected!\n",
- namestr(&nmb->question.question_name)));
- }
+ struct nmb_packet *nmb = &p->packet.nmb;
+ char *name = nmb->question.question_name.name;
+ int type = nmb->question.question_name.name_type;
+
+ DEBUG(4,("response name registration received!\n"));
+
+ if (nmb->header.rcode == 0 && nmb->answers->rdata)
+ {
+ int nb_flags = nmb->answers->rdata[0];
+ struct in_addr found_ip;
+ int ttl = nmb->answers->ttl;
+ enum name_source source = REGISTER;
+
+ putip((char*)&found_ip,&nmb->answers->rdata[2]);
+
+ if (ip_equal(found_ip, myip)) source = SELF;
+
+ add_netbios_entry(name,type,nb_flags,ttl,source,found_ip);
+ }
+ else
+ {
+ DEBUG(1,("name registration for %s rejected!\n",
+ namestr(&nmb->question.question_name)));
+ }
}
@@ -416,92 +429,92 @@ reply to a reg request
**************************************************************************/
void reply_name_reg(struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- char *qname = nmb->question.question_name.name;
- int name_type = nmb->question.question_name.name_type;
-
- BOOL bcast = nmb->header.nm_flags.bcast;
-
- int ttl = GET_TTL(nmb->additional->ttl);
- int nb_flags = nmb->additional->rdata[0];
- BOOL group = (nb_flags&0x80);
- int rcode = 0;
- int opcode = nmb->header.opcode;
- struct name_record *n = NULL;
- int success = True;
- char rdata[6];
- struct in_addr ip, from_ip;
-
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
- ip = from_ip;
-
- DEBUG(3,("Name registration for name %s at %s rcode=%d\n",
- namestr(question),inet_ntoa(ip),rcode));
-
- if (group)
- {
- /* apparently we should return 255.255.255.255 for group queries
- (email from MS) */
- ip = *interpret_addr2("255.255.255.255");
- }
-
- /* see if the name already exists */
- n = find_name_search(question, FIND_GLOBAL, from_ip);
-
- if (n)
- {
- if (!group && !ip_equal(ip,n->ip) && question->name_type != 0x3)
- {
- if (n->source == SELF)
- {
- rcode = 6;
- success = False;
- }
- else
- {
- n->ip = ip;
- n->death_time = ttl?p->timestamp+ttl*3:0;
- DEBUG(3,("%s changed owner to %s\n",
- namestr(&n->name),inet_ntoa(n->ip)));
- }
- }
- else
- {
- /* refresh the name */
- if (n->source != SELF)
- {
- n->death_time = ttl?p->timestamp + ttl*3:0;
- }
- }
- }
- else
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct nmb_name *question = &nmb->question.question_name;
+ char *qname = nmb->question.question_name.name;
+ int name_type = nmb->question.question_name.name_type;
+
+ BOOL bcast = nmb->header.nm_flags.bcast;
+
+ int ttl = GET_TTL(nmb->additional->ttl);
+ int nb_flags = nmb->additional->rdata[0];
+ BOOL group = (nb_flags&0x80);
+ int rcode = 0;
+ int opcode = nmb->header.opcode;
+ struct name_record *n = NULL;
+ int success = True;
+ char rdata[6];
+ struct in_addr ip, from_ip;
+
+ putip((char *)&from_ip,&nmb->additional->rdata[2]);
+ ip = from_ip;
+
+ DEBUG(3,("Name registration for name %s at %s rcode=%d\n",
+ namestr(question),inet_ntoa(ip),rcode));
+
+ if (group)
+ {
+ /* apparently we should return 255.255.255.255 for group queries
+ (email from MS) */
+ ip = *interpret_addr2("255.255.255.255");
+ }
+
+ /* see if the name already exists */
+ n = find_name_search(question, FIND_GLOBAL, from_ip);
+
+ if (n)
+ {
+ if (!group && !ip_equal(ip,n->ip) && question->name_type != 0x3)
{
- /* add the name to our subnet/name database */
- n = add_netbios_entry(qname,name_type,nb_flags,ttl,REGISTER,ip);
+ if (n->source == SELF)
+ {
+ rcode = 6;
+ success = False;
+ }
+ else
+ {
+ n->ip = ip;
+ n->death_time = ttl?p->timestamp+ttl*3:0;
+ DEBUG(3,("%s changed owner to %s\n",
+ namestr(&n->name),inet_ntoa(n->ip)));
+ }
}
-
- if (bcast) return;
-
- update_from_reg(nmb->question.question_name.name,
- nmb->question.question_name.name_type, from_ip);
-
- /* XXXX don't know how to reject a name register: stick info in anyway
- and guess that it doesn't matter if info is there! */
- /*if (success)*/
+ else
{
- rdata[0] = nb_flags;
- rdata[1] = 0;
- putip(&rdata[2],(char *)&ip);
+ /* refresh the name */
+ if (n->source != SELF)
+ {
+ n->death_time = ttl?p->timestamp + ttl*3:0;
+ }
}
-
- /* Send a NAME REGISTRATION RESPONSE */
- reply_netbios_packet(p,nmb->header.name_trn_id,rcode,opcode,
- &nmb->question.question_name,
- nmb->question.question_type,
- nmb->question.question_class,
- ttl,
- rdata, 6 /*success ? 6 : 0*/);
+ }
+ else
+ {
+ /* add the name to our subnet/name database */
+ n = add_netbios_entry(qname,name_type,nb_flags,ttl,REGISTER,ip);
+ }
+
+ if (bcast) return;
+
+ update_from_reg(nmb->question.question_name.name,
+ nmb->question.question_name.name_type, from_ip);
+
+ /* XXXX don't know how to reject a name register: stick info in anyway
+ and guess that it doesn't matter if info is there! */
+ /*if (success)*/
+ {
+ rdata[0] = nb_flags;
+ rdata[1] = 0;
+ putip(&rdata[2],(char *)&ip);
+ }
+
+ /* Send a NAME REGISTRATION RESPONSE */
+ reply_netbios_packet(p,nmb->header.name_trn_id,rcode,opcode,
+ &nmb->question.question_name,
+ nmb->question.question_type,
+ nmb->question.question_class,
+ ttl,
+ rdata, 6 /*success ? 6 : 0*/);
}
@@ -510,107 +523,107 @@ reply to a name status query
****************************************************************************/
void reply_name_status(struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- char *qname = nmb->question.question_name.name;
- int ques_type = nmb->question.question_name.name_type;
- BOOL wildcard = (qname[0] == '*');
- char rdata[MAX_DGRAM_SIZE];
- char *countptr, *buf;
- int count, names_added;
- struct name_record *n;
-
- DEBUG(3,("Name status for name %s %s\n",
+ struct nmb_packet *nmb = &p->packet.nmb;
+ char *qname = nmb->question.question_name.name;
+ int ques_type = nmb->question.question_name.name_type;
+ BOOL wildcard = (qname[0] == '*');
+ char rdata[MAX_DGRAM_SIZE];
+ char *countptr, *buf;
+ int count, names_added;
+ struct name_record *n;
+
+ DEBUG(3,("Name status for name %s %s\n",
namestr(&nmb->question.question_name), inet_ntoa(p->ip)));
-
- /* find a name: if it's a wildcard, search the entire database.
- if not, search for source SELF names only */
- n = find_name_search(&nmb->question.question_name,
- wildcard ? FIND_GLOBAL : FIND_SELF, p->ip);
-
- if (!wildcard && (!n || n->source != SELF)) return;
-
- for (count=0, n = namelist ; n; n = n->next)
- {
- int name_type = n->name.name_type;
-
- if (n->source != SELF) continue;
-
- if (name_type >= 0x1b && name_type <= 0x20 &&
- ques_type >= 0x1b && ques_type <= 0x20)
- {
- if (!strequal(qname, n->name.name)) continue;
- }
-
- count++;
- }
-
- /* XXXX hack, we should calculate exactly how many will fit */
- count = MIN(count,(sizeof(rdata) - 64) / 18);
-
- countptr = buf = rdata;
- buf += 1;
-
- names_added = 0;
-
- for (n = namelist ; n && count >= 0; n = n->next)
- {
- int name_type = n->name.name_type;
-
- if (n->source != SELF) continue;
-
- /* start with first bit of putting info in buffer: the name */
-
- bzero(buf,18);
- StrnCpy(buf,n->name.name,15);
- strupper(buf);
-
- /* now check if we want to exclude other workgroup names
- from the response. if we don't exclude them, windows clients
- get confused and will respond with an error for NET VIEW */
-
- if (name_type >= 0x1b && name_type <= 0x20 &&
- ques_type >= 0x1b && ques_type <= 0x20)
- {
- if (!strequal(qname, n->name.name)) continue;
- }
-
- /* carry on putting name info in buffer */
-
- buf[15] = name_type;
- buf[16] = n->nb_flags;
-
- buf += 18;
-
- count--;
- names_added++;
- }
-
- if (count < 0)
+
+ /* find a name: if it's a wildcard, search the entire database.
+ if not, search for source SELF names only */
+ n = find_name_search(&nmb->question.question_name,
+ wildcard ? FIND_GLOBAL : FIND_SELF, p->ip);
+
+ if (!wildcard && (!n || n->source != SELF)) return;
+
+ for (count=0, n = namelist ; n; n = n->next)
+ {
+ int name_type = n->name.name_type;
+
+ if (n->source != SELF) continue;
+
+ if (name_type >= 0x1b && name_type <= 0x20 &&
+ ques_type >= 0x1b && ques_type <= 0x20)
{
- DEBUG(3, (("too many names: missing a few!\n")));
+ if (!strequal(qname, n->name.name)) continue;
}
-
- SCVAL(countptr,0,names_added);
-
- /* XXXXXXX we should fill in more fields of the statistics structure */
- bzero(buf,64);
+
+ count++;
+ }
+
+ /* XXXX hack, we should calculate exactly how many will fit */
+ count = MIN(count,(sizeof(rdata) - 64) / 18);
+
+ countptr = buf = rdata;
+ buf += 1;
+
+ names_added = 0;
+
+ for (n = namelist ; n && count >= 0; n = n->next)
+ {
+ int name_type = n->name.name_type;
+
+ if (n->source != SELF) continue;
+
+ /* start with first bit of putting info in buffer: the name */
+
+ bzero(buf,18);
+ StrnCpy(buf,n->name.name,15);
+ strupper(buf);
+
+ /* now check if we want to exclude other workgroup names
+ from the response. if we don't exclude them, windows clients
+ get confused and will respond with an error for NET VIEW */
+
+ if (name_type >= 0x1b && name_type <= 0x20 &&
+ ques_type >= 0x1b && ques_type <= 0x20)
{
- extern int num_good_sends,num_good_receives;
- SIVAL(buf,20,num_good_sends);
- SIVAL(buf,24,num_good_receives);
+ if (!strequal(qname, n->name.name)) continue;
}
-
- SIVAL(buf,46,0xFFB8E5); /* undocumented - used by NT */
-
- buf += 64;
-
- /* Send a POSITIVE NAME STATUS RESPONSE */
- reply_netbios_packet(p,nmb->header.name_trn_id,0,0,
- &nmb->question.question_name,
- nmb->question.question_type,
- nmb->question.question_class,
- 0,
- rdata,PTR_DIFF(buf,rdata));
+
+ /* carry on putting name info in buffer */
+
+ buf[15] = name_type;
+ buf[16] = n->nb_flags;
+
+ buf += 18;
+
+ count--;
+ names_added++;
+ }
+
+ if (count < 0)
+ {
+ DEBUG(3, (("too many names: missing a few!\n")));
+ }
+
+ SCVAL(countptr,0,names_added);
+
+ /* XXXXXXX we should fill in more fields of the statistics structure */
+ bzero(buf,64);
+ {
+ extern int num_good_sends,num_good_receives;
+ SIVAL(buf,20,num_good_sends);
+ SIVAL(buf,24,num_good_receives);
+ }
+
+ SIVAL(buf,46,0xFFB8E5); /* undocumented - used by NT */
+
+ buf += 64;
+
+ /* Send a POSITIVE NAME STATUS RESPONSE */
+ reply_netbios_packet(p,nmb->header.name_trn_id,0,0,
+ &nmb->question.question_name,
+ nmb->question.question_type,
+ nmb->question.question_class,
+ 0,
+ rdata,PTR_DIFF(buf,rdata));
}
@@ -620,73 +633,73 @@ reply to a name query
struct name_record *search_for_name(struct nmb_name *question,
struct in_addr ip, int Time, int search)
{
- int name_type = question->name_type;
- char *qname = question->name;
- BOOL dns_type = name_type == 0x20 || name_type == 0;
-
- struct name_record *n;
-
- DEBUG(3,("Search for %s from %s - ", namestr(question), inet_ntoa(ip)));
-
- /* first look up name in cache */
- n = find_name_search(question,search,ip);
-
- /* now try DNS lookup. */
- if (!n)
- {
- struct in_addr dns_ip;
- unsigned long a;
-
- /* only do DNS lookups if the query is for type 0x20 or type 0x0 */
- if (!dns_type)
- {
- DEBUG(3,("types 0x20 0x1b 0x0 only: name not found\n"));
- return NULL;
- }
-
- /* look it up with DNS */
- a = interpret_addr(qname);
-
- putip((char *)&dns_ip,(char *)&a);
-
- if (!a)
- {
- /* no luck with DNS. We could possibly recurse here XXXX */
- /* if this isn't a bcast then we should send a negative reply XXXX */
- DEBUG(3,("no recursion\n"));
- add_netbios_entry(qname,name_type,NB_ACTIVE,60*60,DNSFAIL,dns_ip);
- return NULL;
- }
-
- /* add it to our cache of names. give it 2 hours in the cache */
- n = add_netbios_entry(qname,name_type,NB_ACTIVE,2*60*60,DNS,dns_ip);
-
- /* failed to add it? yikes! */
- if (!n) return NULL;
- }
-
- /* is our entry already dead? */
- if (n->death_time)
+ int name_type = question->name_type;
+ char *qname = question->name;
+ BOOL dns_type = name_type == 0x20 || name_type == 0;
+
+ struct name_record *n;
+
+ DEBUG(3,("Search for %s from %s - ", namestr(question), inet_ntoa(ip)));
+
+ /* first look up name in cache */
+ n = find_name_search(question,search,ip);
+
+ /* now try DNS lookup. */
+ if (!n)
+ {
+ struct in_addr dns_ip;
+ unsigned long a;
+
+ /* only do DNS lookups if the query is for type 0x20 or type 0x0 */
+ if (!dns_type)
{
- if (n->death_time < Time) return False;
+ DEBUG(3,("types 0x20 0x1b 0x0 only: name not found\n"));
+ return NULL;
}
-
- /* it may have been an earlier failure */
- if (n->source == DNSFAIL)
+
+ /* look it up with DNS */
+ a = interpret_addr(qname);
+
+ putip((char *)&dns_ip,(char *)&a);
+
+ if (!a)
{
- DEBUG(3,("DNSFAIL\n"));
- return NULL;
+ /* no luck with DNS. We could possibly recurse here XXXX */
+ /* if this isn't a bcast then we should send a negative reply XXXX */
+ DEBUG(3,("no recursion\n"));
+ add_netbios_entry(qname,name_type,NB_ACTIVE,60*60,DNSFAIL,dns_ip);
+ return NULL;
}
-
- DEBUG(3,("OK %s\n",inet_ntoa(n->ip)));
-
- return n;
+
+ /* add it to our cache of names. give it 2 hours in the cache */
+ n = add_netbios_entry(qname,name_type,NB_ACTIVE,2*60*60,DNS,dns_ip);
+
+ /* failed to add it? yikes! */
+ if (!n) return NULL;
+ }
+
+ /* is our entry already dead? */
+ if (n->death_time)
+ {
+ if (n->death_time < Time) return False;
+ }
+
+ /* it may have been an earlier failure */
+ if (n->source == DNSFAIL)
+ {
+ DEBUG(3,("DNSFAIL\n"));
+ return NULL;
+ }
+
+ DEBUG(3,("OK %s\n",inet_ntoa(n->ip)));
+
+ return n;
}
/* XXXX i think we should only do this if we are a WINS proxy
if (!n && bcast)
{
- // now try look up the name at the primary domain controller
+ // now try look up the name at the primary domain controller
if (*lp_domain_controller())
{
struct in_addr dom_ip;
@@ -729,78 +742,80 @@ with directed name queries:
****************************************************************************/
extern void reply_name_query(struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- int name_type = question->name_type;
- BOOL dns_type = name_type == 0x20 || name_type == 0;
- BOOL bcast = nmb->header.nm_flags.bcast;
- int ttl=0;
- int rcode = 0;
- int nb_flags = 0;
- struct in_addr retip;
- char rdata[6];
-
- struct in_addr gp_ip = *interpret_addr2("255.255.255.255");
- BOOL success = True;
-
- struct name_record *n;
- enum name_search search = dns_type || name_type == 0x1b ?
- FIND_GLOBAL : FIND_SELF;
-
- DEBUG(3,("Name query "));
-
- if ((n = search_for_name(question,p->ip,p->timestamp, search)))
- {
- /* don't respond to broadcast queries unless the query is for
- a name we own or it is for a Primary Domain Controller name */
- if (bcast && n->source != SELF && name_type != 0x1b)
- {
- /* never reply with a negative response to broadcast queries */
- return;
- }
-
- /* name is directed query, or it's self, or it's a PDC type name */
- ttl = n->death_time - p->timestamp;
- retip = n->ip;
- nb_flags = n->nb_flags;
- }
- else
- {
- if (bcast) return; /* never reply negative response to bcasts */
- success = False;
- }
-
- /* if asking for a group name (type 0x1e) return 255.255.255.255 */
- if (ip_equal(retip, gp_ip) && name_type == 0x1e) retip = gp_ip;
-
- /* if the IP is 0 then substitute my IP - we should see which one is on the
- right interface for the caller to do this right XXX */
- if (zero_ip(retip)) retip = myip;
-
- if (success)
- {
- rcode = 0;
- DEBUG(3,("OK %s\n",inet_ntoa(retip)));
- }
- else
- {
- rcode = 3;
- DEBUG(3,("UNKNOWN\n"));
- }
-
- if (success)
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct nmb_name *question = &nmb->question.question_name;
+ int name_type = question->name_type;
+ BOOL dns_type = name_type == 0x20 || name_type == 0;
+ BOOL bcast = nmb->header.nm_flags.bcast;
+ int ttl=0;
+ int rcode = 0;
+ int nb_flags = 0;
+ struct in_addr retip;
+ char rdata[6];
+
+ struct in_addr gp_ip = *interpret_addr2("255.255.255.255");
+ BOOL success = True;
+
+ struct name_record *n;
+ enum name_search search = dns_type || name_type == 0x1b ?
+ FIND_GLOBAL : FIND_SELF;
+
+ DEBUG(3,("Name query "));
+
+ if ((n = search_for_name(question,p->ip,p->timestamp, search)))
+ {
+ /* don't respond to broadcast queries unless the query is for
+ a name we own or it is for a Primary Domain Controller name */
+ if (bcast && n->source != SELF && name_type != 0x1b)
{
- rdata[0] = nb_flags;
- rdata[1] = 0;
- putip(&rdata[2],(char *)&retip);
+ if (!lp_wins_proxy() || same_net(p->ip,n->ip,Netmask)) {
+ /* never reply with a negative response to broadcast queries */
+ return;
+ }
}
-
- reply_netbios_packet(p,nmb->header.name_trn_id,rcode,0,
- &nmb->question.question_name,
- nmb->question.question_type,
- nmb->question.question_class,
- ttl,
- rdata, success ? 6 : 0);
+
+ /* we will reply */
+ ttl = n->death_time - p->timestamp;
+ retip = n->ip;
+ nb_flags = n->nb_flags;
+ }
+ else
+ {
+ if (bcast) return; /* never reply negative response to bcasts */
+ success = False;
+ }
+
+ /* if asking for a group name (type 0x1e) return 255.255.255.255 */
+ if (ip_equal(retip, gp_ip) && name_type == 0x1e) retip = gp_ip;
+
+ /* if the IP is 0 then substitute my IP - we should see which one is on the
+ right interface for the caller to do this right XXX */
+ if (zero_ip(retip)) retip = myip;
+
+ if (success)
+ {
+ rcode = 0;
+ DEBUG(3,("OK %s\n",inet_ntoa(retip)));
+ }
+ else
+ {
+ rcode = 3;
+ DEBUG(3,("UNKNOWN\n"));
+ }
+
+ if (success)
+ {
+ rdata[0] = nb_flags;
+ rdata[1] = 0;
+ putip(&rdata[2],(char *)&retip);
+ }
+
+ reply_netbios_packet(p,nmb->header.name_trn_id,rcode,0,
+ &nmb->question.question_name,
+ nmb->question.question_type,
+ nmb->question.question_class,
+ ttl,
+ rdata, success ? 6 : 0);
}
@@ -809,174 +824,169 @@ response from a name query
****************************************************************************/
static void response_netbios_packet(struct packet_struct *p)
{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- char *qname = question->name;
- BOOL bcast = nmb->header.nm_flags.bcast;
- struct name_response_record *n;
-
- if (nmb->answers == NULL)
- {
- DEBUG(3,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
- inet_ntoa(p->ip),
- BOOLSTR(bcast)));
- return;
- }
-
- if (nmb->answers->rr_type == NMB_STATUS)
- {
- DEBUG(3,("Name status "));
- }
-
- if (nmb->answers->rr_type == NMB_QUERY)
- {
- DEBUG(3,("Name query "));
- }
-
- if (nmb->answers->rr_type == NMB_REG)
- {
- DEBUG(3,("Name registration "));
- }
-
- if (nmb->answers->rr_type == NMB_REL)
- {
- DEBUG(3,("Name release "));
- }
-
- DEBUG(3,("response for %s from %s (bcast=%s)\n",
- namestr(&nmb->answers->rr_name),
- inet_ntoa(p->ip),
- BOOLSTR(bcast)));
-
- if (!(n = find_name_query(nmb->header.name_trn_id)))
- {
- DEBUG(3,("unknown response (received too late or from nmblookup?)\n"));
- return;
- }
-
- n->num_msgs++; /* count number of responses received */
-
- switch (n->cmd_type)
- {
- case MASTER_SERVER_CHECK : DEBUG(4,("MASTER_SVR_CHECK\n")); break;
- case SERVER_CHECK : DEBUG(4,("SERVER_CHECK\n")); break;
- case FIND_MASTER : DEBUG(4,("FIND_MASTER\n")); break;
- case NAME_STATUS_MASTER_CHECK: DEBUG(4,("NAME_STAT_MST_CHK\n")); break;
- case NAME_STATUS_CHECK : DEBUG(4,("NAME_STATUS_CHECK\n")); break;
- case CHECK_MASTER : DEBUG(4,("CHECK_MASTER\n")); break;
- case NAME_CONFIRM_QUERY : DEBUG(4,("NAME_CONFIRM_QUERY\n")); break;
- default: break;
- }
- switch (n->cmd_type)
- {
- case MASTER_SERVER_CHECK:
- case SERVER_CHECK:
- case FIND_MASTER:
- {
- if (nmb->answers->rr_type == NMB_QUERY)
- {
- enum cmd_type cmd = (n->cmd_type == MASTER_SERVER_CHECK) ?
- NAME_STATUS_MASTER_CHECK :
- NAME_STATUS_CHECK;
- if (n->num_msgs > 1 && !strequal(qname,n->name.name))
- {
- /* one subnet, one master browser per workgroup */
- /* XXXX force an election? */
- DEBUG(1,("more than one master browser replied!\n"));
- }
-
- /* initiate a name status check on the server that replied */
- queue_netbios_packet(ClientNMB,NMB_STATUS, cmd,
- nmb->answers->rr_name.name,
- nmb->answers->rr_name.name_type,0,
- False,False,n->to_ip);
- }
- else
- {
- DEBUG(1,("Name query reply has wrong answer rr_type\n"));
- }
- break;
- }
+ struct nmb_packet *nmb = &p->packet.nmb;
+ struct nmb_name *question = &nmb->question.question_name;
+ char *qname = question->name;
+ BOOL bcast = nmb->header.nm_flags.bcast;
+ struct name_response_record *n;
+
+ if (nmb->answers == NULL)
+ {
+ DEBUG(3,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
+ inet_ntoa(p->ip),
+ BOOLSTR(bcast)));
+ return;
+ }
+
+ if (nmb->answers->rr_type == NMB_STATUS) {
+ DEBUG(3,("Name status "));
+ }
- case NAME_STATUS_MASTER_CHECK:
- case NAME_STATUS_CHECK:
- {
- if (nmb->answers->rr_type == NMB_STATUS)
- {
- /* NMB_STATUS arrives: contains the workgroup name
- and server name we require */
- struct nmb_name name;
- fstring serv_name;
+ if (nmb->answers->rr_type == NMB_QUERY) {
+ DEBUG(3,("Name query "));
+ }
- if (interpret_node_status(nmb->answers->rdata,
- &name,0x1d,serv_name,n->to_ip))
- {
- if (*serv_name)
- {
- sync_server(n->cmd_type,serv_name,
- name.name,name.name_type,
- n->to_ip);
- }
- }
- else
- {
- DEBUG(1,("No 0x1d name type in interpret_node_status()\n"));
- }
- }
- else
- {
- DEBUG(1,("Name status reply has wrong answer rr_type\n"));
- }
- break;
- }
+ if (nmb->answers->rr_type == NMB_REG) {
+ DEBUG(3,("Name registration "));
+ }
- case CHECK_MASTER:
- {
- /* no action required here. it's when NO responses are received
- that we need to do something (see expire_name_query_entries) */
+ if (nmb->answers->rr_type == NMB_REL) {
+ DEBUG(3,("Name release "));
+ }
- DEBUG(4, ("Master browser exists for %s at %s\n",
- namestr(&n->name),
- inet_ntoa(n->to_ip)));
- if (n->num_msgs > 1)
- {
- DEBUG(1,("more than one master browser!\n"));
- }
- if (nmb->answers->rr_type != NMB_QUERY)
- {
- DEBUG(1,("Name query reply has wrong answer rr_type\n"));
- }
- break;
- }
- case NAME_CONFIRM_QUERY:
- {
- DEBUG(4, ("Name query at WINS server: %s at %s - ",
- namestr(&n->name),
- inet_ntoa(n->to_ip)));
- if (nmb->header.rcode == 0 && nmb->answers->rdata)
- {
- int nb_flags = nmb->answers->rdata[0];
- struct in_addr found_ip;
- putip((char*)&found_ip,&nmb->answers->rdata[2]);
-
- DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
- add_netbios_entry(nmb->answers->rr_name.name,
- nmb->answers->rr_name.name_type,
- nb_flags,GET_TTL(0),STATUS_QUERY,found_ip);
- }
- else
- {
- DEBUG(4, (" NEGATIVE RESPONSE\n"));
- }
+ DEBUG(3,("response for %s from %s (bcast=%s)\n",
+ namestr(&nmb->answers->rr_name),
+ inet_ntoa(p->ip),
+ BOOLSTR(bcast)));
+
+ if (!(n = find_name_query(nmb->header.name_trn_id))) {
+ DEBUG(3,("unknown response (received too late or from nmblookup?)\n"));
+ return;
+ }
- break;
- }
- default:
- {
- DEBUG(0,("unknown command received in response_netbios_packet\n"));
- break;
- }
- }
+ n->num_msgs++; /* count number of responses received */
+
+ switch (n->cmd_type)
+ {
+ case MASTER_SERVER_CHECK : DEBUG(4,("MASTER_SVR_CHECK\n")); break;
+ case SERVER_CHECK : DEBUG(4,("SERVER_CHECK\n")); break;
+ case FIND_MASTER : DEBUG(4,("FIND_MASTER\n")); break;
+ case NAME_STATUS_MASTER_CHECK: DEBUG(4,("NAME_STAT_MST_CHK\n")); break;
+ case NAME_STATUS_CHECK : DEBUG(4,("NAME_STATUS_CHECK\n")); break;
+ case CHECK_MASTER : DEBUG(4,("CHECK_MASTER\n")); break;
+ case NAME_CONFIRM_QUERY : DEBUG(4,("NAME_CONFIRM_QUERY\n")); break;
+ default: break;
+ }
+ switch (n->cmd_type)
+ {
+ case MASTER_SERVER_CHECK:
+ case SERVER_CHECK:
+ case FIND_MASTER:
+ {
+ if (nmb->answers->rr_type == NMB_QUERY)
+ {
+ enum cmd_type cmd = (n->cmd_type == MASTER_SERVER_CHECK) ?
+ NAME_STATUS_MASTER_CHECK :
+ NAME_STATUS_CHECK;
+ if (n->num_msgs > 1 && !strequal(qname,n->name.name))
+ {
+ /* one subnet, one master browser per workgroup */
+ /* XXXX force an election? */
+ DEBUG(1,("more than one master browser replied!\n"));
+ }
+
+ /* initiate a name status check on the server that replied */
+ queue_netbios_packet(ClientNMB,NMB_STATUS, cmd,
+ nmb->answers->rr_name.name,
+ nmb->answers->rr_name.name_type,0,
+ False,False,n->to_ip);
+ }
+ else
+ {
+ DEBUG(1,("Name query reply has wrong answer rr_type\n"));
+ }
+ break;
+ }
+
+ case NAME_STATUS_MASTER_CHECK:
+ case NAME_STATUS_CHECK:
+ {
+ if (nmb->answers->rr_type == NMB_STATUS)
+ {
+ /* NMB_STATUS arrives: contains the workgroup name
+ and server name we require */
+ struct nmb_name name;
+ fstring serv_name;
+
+ if (interpret_node_status(nmb->answers->rdata,
+ &name,0x1d,serv_name,n->to_ip))
+ {
+ if (*serv_name)
+ {
+ sync_server(n->cmd_type,serv_name,
+ name.name,name.name_type,
+ n->to_ip);
+ }
+ }
+ else
+ {
+ DEBUG(1,("No 0x1d name type in interpret_node_status()\n"));
+ }
+ }
+ else
+ {
+ DEBUG(1,("Name status reply has wrong answer rr_type\n"));
+ }
+ break;
+ }
+
+ case CHECK_MASTER:
+ {
+ /* no action required here. it's when NO responses are received
+ that we need to do something (see expire_name_query_entries) */
+
+ DEBUG(4, ("Master browser exists for %s at %s\n",
+ namestr(&n->name),
+ inet_ntoa(n->to_ip)));
+ if (n->num_msgs > 1)
+ {
+ DEBUG(1,("more than one master browser!\n"));
+ }
+ if (nmb->answers->rr_type != NMB_QUERY)
+ {
+ DEBUG(1,("Name query reply has wrong answer rr_type\n"));
+ }
+ break;
+ }
+ case NAME_CONFIRM_QUERY:
+ {
+ DEBUG(4, ("Name query at WINS server: %s at %s - ",
+ namestr(&n->name),
+ inet_ntoa(n->to_ip)));
+ if (nmb->header.rcode == 0 && nmb->answers->rdata)
+ {
+ int nb_flags = nmb->answers->rdata[0];
+ struct in_addr found_ip;
+ putip((char*)&found_ip,&nmb->answers->rdata[2]);
+
+ DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
+ add_netbios_entry(nmb->answers->rr_name.name,
+ nmb->answers->rr_name.name_type,
+ nb_flags,GET_TTL(0),STATUS_QUERY,found_ip);
+ }
+ else
+ {
+ DEBUG(4, (" NEGATIVE RESPONSE\n"));
+ }
+
+ break;
+ }
+ default:
+ {
+ DEBUG(0,("unknown command received in response_netbios_packet\n"));
+ break;
+ }
+ }
}
diff --git a/source3/namework.c b/source3/namework.c
index 91215ec45d..ee60e9115f 100644
--- a/source3/namework.c
+++ b/source3/namework.c
@@ -263,12 +263,12 @@ void update_from_reg(char *name, int type, struct in_addr ip)
**************************************************************************/
void add_my_domains(void)
{
- /* add or find domain on our local subnet, in the default workgroup */
-
- if (*lp_workgroup() != '*')
- {
- add_domain_entry(bcast_ip,Netmask,lp_workgroup(), True);
- }
+ /* add or find domain on our local subnet, in the default workgroup */
+
+ if (*lp_workgroup() != '*')
+ {
+ add_domain_entry(bcast_ip,Netmask,lp_workgroup(), True);
+ }
}
@@ -279,128 +279,128 @@ static void send_backup_list(char *work_name, struct nmb_name *src_name,
int info_count, int token, int info,
int name_type, struct in_addr ip)
{
- struct domain_record *d;
- char outbuf[1024];
- char *p, *countptr, *nameptr;
- int count = 0;
- int i, j;
- char *theirname = src_name->name;
-
- DEBUG(3,("Backup list of %s to %s: %s(%x) %s(%x)\n",
- work_name, inet_ntoa(ip),
- myname,0x20,theirname,0x0));
-
- if (name_type == 0x1d)
- {
- DEBUG(4,("master browsers: "));
- }
- else if (name_type == 0x1b)
- {
- DEBUG(4,("domain controllers: "));
- }
- else
- {
- DEBUG(0,("backup request for unknown type %0x\n", name_type));
- return;
- }
-
- bzero(outbuf,sizeof(outbuf));
- p = outbuf;
-
- CVAL(p,0) = 10; /* backup list response */
- p++;
-
- countptr = p; /* count pointer */
-
- SSVAL(p,1,token); /* sender's workgroup index representation */
- SSVAL(p,3,info); /* XXXX clueless: info, usually zero */
- p += 5;
-
- nameptr = p;
-
- for (d = domainlist; d; d = d->next)
+ struct domain_record *d;
+ char outbuf[1024];
+ char *p, *countptr, *nameptr;
+ int count = 0;
+ int i, j;
+ char *theirname = src_name->name;
+
+ DEBUG(3,("Backup list of %s to %s: %s(%x) %s(%x)\n",
+ work_name, inet_ntoa(ip),
+ myname,0x20,theirname,0x0));
+
+ if (name_type == 0x1d)
+ {
+ DEBUG(4,("master browsers: "));
+ }
+ else if (name_type == 0x1b)
+ {
+ DEBUG(4,("domain controllers: "));
+ }
+ else
+ {
+ DEBUG(0,("backup request for unknown type %0x\n", name_type));
+ return;
+ }
+
+ bzero(outbuf,sizeof(outbuf));
+ p = outbuf;
+
+ CVAL(p,0) = 10; /* backup list response */
+ p++;
+
+ countptr = p; /* count pointer */
+
+ SSVAL(p,1,token); /* sender's workgroup index representation */
+ SSVAL(p,3,info); /* XXXX clueless: info, usually zero */
+ p += 5;
+
+ nameptr = p;
+
+ for (d = domainlist; d; d = d->next)
+ {
+ struct work_record *work;
+
+ for (work = d->workgrouplist; work; work = work->next)
{
- struct work_record *work;
-
- for (work = d->workgrouplist; work; work = work->next)
+ struct server_record *s;
+
+ if (!strequal(work->work_group, work_name)) continue;
+
+ for (s = work->serverlist; s; s = s->next)
+ {
+ BOOL found = False;
+ char *n;
+
+ if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
+
+ for (n = nameptr; n < p; n = skip_string(n, 1))
{
- struct server_record *s;
-
- if (!strequal(work->work_group, work_name)) continue;
-
- for (s = work->serverlist; s; s = s->next)
- {
- BOOL found = False;
- char *n;
-
- if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
-
- for (n = nameptr; n < p; n = skip_string(n, 1))
- {
- if (strequal(n, s->serv.name)) found = True;
- }
-
- if (found) continue; /* exclude names already added */
-
- /* workgroup request: include all backup browsers in the list */
- /* domain request: include all domain members in the list */
-
- if ((name_type == 0x1d && (s->serv.type & MASTER_TYPE)) ||
- (name_type == 0x1b && (s->serv.type & DOMCTL_TYPE)))
- {
- DEBUG(4, ("%s ", s->serv.name));
-
- count++;
- strcpy(p,s->serv.name);
- strupper(p);
- p = skip_string(p,1);
- }
- }
+ if (strequal(n, s->serv.name)) found = True;
}
- }
-
- if (count == 0)
- {
- DEBUG(4, ("none\n"));
- return;
- }
- else
- {
- DEBUG(4, (" - count %d\n", count));
- }
-
- CVAL(countptr,0) = count; /* total number of backup browsers found */
-
- {
- int len = PTR_DIFF(p, outbuf);
-
- for (i = 0; i < len; i+= 16)
- {
- DEBUG(4, ("%3x char ", i));
-
- for (j = 0; j < 16; j++)
- {
- unsigned char x = outbuf[i+j];
- if (x < 32 || x > 127) x = '.';
-
- if (i+j >= len) break;
- DEBUG(4, ("%c", x));
- }
-
- DEBUG(4, (" hex ", i));
-
- for (j = 0; j < 16; j++)
- {
- if (i+j >= len) break;
- DEBUG(4, (" %02x", outbuf[i+j]));
- }
-
- DEBUG(4, ("\n"));
+
+ if (found) continue; /* exclude names already added */
+
+ /* workgroup request: include all backup browsers in the list */
+ /* domain request: include all domain members in the list */
+
+ if ((name_type == 0x1d && (s->serv.type & MASTER_TYPE)) ||
+ (name_type == 0x1b && (s->serv.type & DOMCTL_TYPE)))
+ {
+ DEBUG(4, ("%s ", s->serv.name));
+
+ count++;
+ strcpy(p,s->serv.name);
+ strupper(p);
+ p = skip_string(p,1);
}
-
+ }
}
- send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
- myname,theirname,0x20,0,ip,myip);
+ }
+
+ if (count == 0)
+ {
+ DEBUG(4, ("none\n"));
+ return;
+ }
+ else
+ {
+ DEBUG(4, (" - count %d\n", count));
+ }
+
+ CVAL(countptr,0) = count; /* total number of backup browsers found */
+
+ {
+ int len = PTR_DIFF(p, outbuf);
+
+ for (i = 0; i < len; i+= 16)
+ {
+ DEBUG(4, ("%3x char ", i));
+
+ for (j = 0; j < 16; j++)
+ {
+ unsigned char x = outbuf[i+j];
+ if (x < 32 || x > 127) x = '.';
+
+ if (i+j >= len) break;
+ DEBUG(4, ("%c", x));
+ }
+
+ DEBUG(4, (" hex ", i));
+
+ for (j = 0; j < 16; j++)
+ {
+ if (i+j >= len) break;
+ DEBUG(4, (" %02x", outbuf[i+j]));
+ }
+
+ DEBUG(4, ("\n"));
+ }
+
+ }
+ send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
+ myname,theirname,0x20,0,ip,myip);
}
@@ -410,10 +410,10 @@ static void send_backup_list(char *work_name, struct nmb_name *src_name,
******************************************************************/
BOOL same_context(struct dgram_packet *dgram)
{
- if (!strequal(dgram->dest_name .scope,scope )) return(True);
- if ( strequal(dgram->source_name.name ,myname)) return(True);
-
- return(False);
+ if (!strequal(dgram->dest_name .scope,scope )) return(True);
+ if ( strequal(dgram->source_name.name ,myname)) return(True);
+
+ return(False);
}
@@ -422,14 +422,14 @@ BOOL same_context(struct dgram_packet *dgram)
******************************************************************/
BOOL listening_name(struct work_record *work, struct nmb_name *n)
{
- if (strequal(n->name,myname) ||
- strequal(n->name,work->work_group) ||
- strequal(n->name,MSBROWSE))
- {
- return(True);
- }
-
- return(False);
+ if (strequal(n->name,myname) ||
+ strequal(n->name,work->work_group) ||
+ strequal(n->name,MSBROWSE))
+ {
+ return(True);
+ }
+
+ return(False);
}
@@ -450,69 +450,69 @@ BOOL listening_name(struct work_record *work, struct nmb_name *n)
******************************************************************/
static void process_announce(struct packet_struct *p,int command,char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- struct in_addr ip = dgram->header.source_ip;
- struct domain_record *d = find_domain(ip);
-
- 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);
- char *comment = buf+31;
- struct work_record *work;
- char *work_name;
- char *serv_name = dgram->source_name.name;
-
- comment[43] = 0;
-
- DEBUG(3,("Announce(%d) %s(%x)",command,name,name[15]));
- DEBUG(3,("%s count=%d ttl=%d OS=(%d,%d) type=%08x comment=%s\n",
+ struct dgram_packet *dgram = &p->packet.dgram;
+ struct in_addr ip = dgram->header.source_ip;
+ struct domain_record *d = find_domain(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);
+ char *comment = buf+31;
+ struct work_record *work;
+ char *work_name;
+ char *serv_name = dgram->source_name.name;
+
+ comment[43] = 0;
+
+ DEBUG(3,("Announce(%d) %s(%x)",command,name,name[15]));
+ DEBUG(3,("%s count=%d ttl=%d OS=(%d,%d) type=%08x comment=%s\n",
namestr(&dgram->dest_name),update_count,ttl,osmajor,osminor,
servertype,comment));
-
- name[15] = 0;
-
- if (dgram->dest_name.name_type == 0 && command == 1)
- {
- DEBUG(2,("Announce to nametype(0) not supported yet\n"));
- return;
- }
- if (command == 12 && ((!strequal(dgram->dest_name.name, MSBROWSE)) ||
- dgram->dest_name.name_type != 0x1))
- {
- DEBUG(0, ("Announce(%d) from %s should be __MSBROWSE__(1) not %s\n",
- command, inet_ntoa(ip), namestr(&dgram->dest_name)));
- return;
- }
-
- if (same_context(dgram)) return;
-
- if (command == 12)
- {
- work_name = name;
- }
- else
- {
- work_name = dgram->dest_name.name;
- }
-
- if (!(work = find_workgroupstruct(d, work_name, False))) return;
-
- DEBUG(4, ("workgroup %s on %s\n", work->work_group, serv_name));
-
- ttl = GET_TTL(ttl);
-
- /* add them to our browse list */
- add_server_entry(d,work,name,servertype,ttl,comment,True);
-
- /* make a selection of machines become backup browsers (1 in 10) */
- tell_become_backup();
-
- /* get their browse list from them and add it to ours. */
- add_browser_entry(serv_name,dgram->dest_name.name_type,
- work->work_group,30,ip);
+
+ name[15] = 0;
+
+ if (dgram->dest_name.name_type == 0 && command == 1)
+ {
+ DEBUG(2,("Announce to nametype(0) not supported yet\n"));
+ return;
+ }
+ if (command == 12 && ((!strequal(dgram->dest_name.name, MSBROWSE)) ||
+ dgram->dest_name.name_type != 0x1))
+ {
+ DEBUG(0, ("Announce(%d) from %s should be __MSBROWSE__(1) not %s\n",
+ command, inet_ntoa(ip), namestr(&dgram->dest_name)));
+ return;
+ }
+
+ if (same_context(dgram)) return;
+
+ if (command == 12)
+ {
+ work_name = name;
+ }
+ else
+ {
+ work_name = dgram->dest_name.name;
+ }
+
+ if (!(work = find_workgroupstruct(d, work_name, False))) return;
+
+ DEBUG(4, ("workgroup %s on %s\n", work->work_group, serv_name));
+
+ ttl = GET_TTL(ttl);
+
+ /* add them to our browse list */
+ add_server_entry(d,work,name,servertype,ttl,comment,True);
+
+ /* make a selection of machines become backup browsers (1 in 10) */
+ tell_become_backup();
+
+ /* get their browse list from them and add it to ours. */
+ add_browser_entry(serv_name,dgram->dest_name.name_type,
+ work->work_group,30,ip);
}
/*******************************************************************
@@ -520,30 +520,30 @@ static void process_announce(struct packet_struct *p,int command,char *buf)
******************************************************************/
static void process_master_announce(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);
- struct domain_record *mydomain = find_domain(bcast_ip);
- char *name = buf;
- struct work_record *work;
- name[15] = 0;
-
- DEBUG(3,("Master Announce from %s (%s)\n",name,inet_ntoa(ip)));
-
- if (same_context(dgram)) return;
-
- if (!d || !mydomain) return;
-
- if (!lp_domain_master()) return;
-
- for (work = mydomain->workgrouplist; work; work = work->next)
+ struct dgram_packet *dgram = &p->packet.dgram;
+ struct in_addr ip = dgram->header.source_ip;
+ struct domain_record *d = find_domain(ip);
+ struct domain_record *mydomain = find_domain(bcast_ip);
+ char *name = buf;
+ struct work_record *work;
+ name[15] = 0;
+
+ DEBUG(3,("Master Announce from %s (%s)\n",name,inet_ntoa(ip)));
+
+ if (same_context(dgram)) return;
+
+ if (!d || !mydomain) return;
+
+ if (!lp_domain_master()) return;
+
+ for (work = mydomain->workgrouplist; work; work = work->next)
+ {
+ if (AM_MASTER(work))
{
- if (AM_MASTER(work))
- {
- /* merge browse lists with them */
- add_browser_entry(name,0x1b, work->work_group,30,ip);
- }
+ /* merge browse lists with them */
+ add_browser_entry(name,0x1b, work->work_group,30,ip);
}
+ }
}
/*******************************************************************
@@ -555,60 +555,60 @@ static void process_master_announce(struct packet_struct *p,char *buf)
******************************************************************/
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 */
- char *buf1;
-
- DEBUG(3,("Receive Backup ack for %s from %s total=%d index=%d\n",
- namestr(&dgram->dest_name), inet_ntoa(ip),
- count, Index));
-
- if (same_context(dgram)) return;
-
- if (count <= 0) return;
-
- /* go through the list of servers attempting to sync browse lists */
- for (buf1 = buf+5; *buf1 && count; buf1 = skip_string(buf1, 1), --count)
+ struct 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 */
+ char *buf1;
+
+ DEBUG(3,("Receive Backup ack for %s from %s total=%d index=%d\n",
+ namestr(&dgram->dest_name), inet_ntoa(ip),
+ count, Index));
+
+ if (same_context(dgram)) return;
+
+ if (count <= 0) return;
+
+ /* go through the list of servers attempting to sync browse lists */
+ for (buf1 = buf+5; *buf1 && count; buf1 = skip_string(buf1, 1), --count)
+ {
+ struct in_addr back_ip;
+ struct domain_record *d;
+
+ DEBUG(4, ("Searching for backup browser %s at %s...\n",
+ buf1, inet_ntoa(ip)));
+
+ /* XXXX assume name is a DNS name NOT a netbios name. a more complete
+ approach is to use reply_name_query functionality to find the name */
+ back_ip = *interpret_addr2(buf1);
+
+ if (zero_ip(back_ip))
{
- struct in_addr back_ip;
- struct domain_record *d;
-
- DEBUG(4, ("Searching for backup browser %s at %s...\n",
- buf1, inet_ntoa(ip)));
-
- /* XXXX assume name is a DNS name NOT a netbios name. a more complete
- approach is to use reply_name_query functionality to find the name */
- back_ip = *interpret_addr2(buf1);
-
- if (zero_ip(back_ip))
- {
- DEBUG(4,("Failed to find backup browser server using DNS\n"));
- continue;
- }
-
- DEBUG(4,("Found browser server at %s\n", inet_ntoa(back_ip)));
-
- if ((d = find_domain(back_ip)))
+ DEBUG(4,("Failed to find backup browser server using DNS\n"));
+ continue;
+ }
+
+ DEBUG(4,("Found browser server at %s\n", inet_ntoa(back_ip)));
+
+ if ((d = find_domain(back_ip)))
+ {
+ struct domain_record *d1;
+ for (d1 = domainlist; d1; d1 = d1->next)
+ {
+ struct work_record *work;
+ for (work = d1->workgrouplist; work; work = work->next)
{
- struct domain_record *d1;
- for (d1 = domainlist; d1; d1 = d1->next)
- {
- struct work_record *work;
- for (work = d1->workgrouplist; work; work = work->next)
- {
- if (work->token == Index)
- {
- queue_netbios_packet(ClientNMB,NMB_QUERY,SERVER_CHECK,
- work->work_group,0x1d,0,
- False,False,back_ip);
- return;
- }
- }
- }
+ if (work->token == Index)
+ {
+ queue_netbios_packet(ClientNMB,NMB_QUERY,SERVER_CHECK,
+ work->work_group,0x1d,0,
+ False,False,back_ip);
+ return;
+ }
}
+ }
}
+ }
}
/*******************************************************************
@@ -676,46 +676,46 @@ static void process_send_backup_list(struct packet_struct *p,char *buf)
******************************************************************/
static void process_reset_browser(struct packet_struct *p,char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- int state = CVAL(buf,0);
+ struct dgram_packet *dgram = &p->packet.dgram;
+ int state = CVAL(buf,0);
- DEBUG(1,("Diagnostic browser reset request to %s state=0x%X\n",
- namestr(&dgram->dest_name), state));
+ DEBUG(1,("Diagnostic browser reset request to %s state=0x%X\n",
+ namestr(&dgram->dest_name), state));
- /* stop being a master but still deal with being a backup browser */
- if (state & 0x1)
- {
- struct domain_record *d;
- for (d = domainlist; d; d = d->next)
- {
- struct work_record *work;
- for (work = d->workgrouplist; work; work = work->next)
- {
- if (AM_MASTER(work))
- {
- become_nonmaster(d,work);
- }
- }
- }
- }
-
- /* totally delete all servers and start afresh */
- if (state & 0x2)
+ /* stop being a master but still deal with being a backup browser */
+ if (state & 0x1)
+ {
+ struct domain_record *d;
+ for (d = domainlist; d; d = d->next)
{
- struct domain_record *d;
- for (d = domainlist; d; d = d->next)
+ struct work_record *work;
+ for (work = d->workgrouplist; work; work = work->next)
+ {
+ if (AM_MASTER(work))
{
- struct work_record *work;
- for (work=d->workgrouplist;work;work=remove_workgroup(d,work));
+ become_nonmaster(d,work);
}
- add_my_domains();
+ }
}
-
- /* stop browsing altogether. i don't think this is a good idea! */
- if (state & 0x4)
+ }
+
+ /* totally delete all servers and start afresh */
+ if (state & 0x2)
+ {
+ struct domain_record *d;
+ for (d = domainlist; d; d = d->next)
{
- DEBUG(1, ("ignoring request to stop being a browser. sorry!\n"));
+ struct work_record *work;
+ for (work=d->workgrouplist;work;work=remove_workgroup(d,work));
}
+ add_my_domains();
+ }
+
+ /* stop browsing altogether. i don't think this is a good idea! */
+ if (state & 0x4)
+ {
+ DEBUG(1, ("ignoring request to stop being a browser. sorry!\n"));
+ }
}
@@ -727,31 +727,31 @@ static void process_reset_browser(struct packet_struct *p,char *buf)
******************************************************************/
static void process_announce_request(struct packet_struct *p,char *buf)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- struct work_record *work;
- struct in_addr ip = dgram->header.source_ip;
- struct domain_record *d = find_domain(ip);
- int token = CVAL(buf,0);
- char *name = buf+1;
-
- name[15] = 0;
-
- DEBUG(3,("Announce request from %s to %s token=0x%X\n",
- name,namestr(&dgram->dest_name), token));
-
- if (strequal(dgram->source_name.name,myname)) return;
-
- if (!d) return;
-
- if (!ip_equal(bcast_ip, d->bcast_ip)) return;
-
- for (work = d->workgrouplist; work; work = work->next)
+ struct dgram_packet *dgram = &p->packet.dgram;
+ struct work_record *work;
+ struct in_addr ip = dgram->header.source_ip;
+ struct domain_record *d = find_domain(ip);
+ int token = CVAL(buf,0);
+ char *name = buf+1;
+
+ name[15] = 0;
+
+ DEBUG(3,("Announce request from %s to %s token=0x%X\n",
+ name,namestr(&dgram->dest_name), token));
+
+ if (strequal(dgram->source_name.name,myname)) return;
+
+ if (!d) return;
+
+ if (!ip_equal(bcast_ip, d->bcast_ip)) return;
+
+ for (work = d->workgrouplist; work; work = work->next)
+ {
+ if (strequal(dgram->dest_name.name,work->work_group))
{
- if (strequal(dgram->dest_name.name,work->work_group))
- {
- work->needannounce = True;
- }
+ work->needannounce = True;
}
+ }
}
@@ -760,79 +760,79 @@ static void process_announce_request(struct packet_struct *p,char *buf)
**************************************************************************/
void process_logon_packet(struct packet_struct *p,char *buf,int len)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- struct in_addr ip = dgram->header.source_ip;
- struct domain_record *d = find_domain(ip);
- char *logname,*q;
- char *reply_name;
- BOOL add_slashes = False;
- pstring outbuf;
- int code,reply_code;
- struct work_record *work;
-
- if (!d) return;
-
- if (!(work = find_workgroupstruct(d,dgram->dest_name.name, False)))
- return;
-
- if (!lp_domain_logons()) {
- DEBUG(3,("No domain logons\n"));
- return;
- }
- if (!listening_name(work, &dgram->dest_name))
- {
- DEBUG(4,("Not listening to that domain\n"));
- return;
- }
-
- code = SVAL(buf,0);
- switch (code) {
- case 0:
- {
- char *machine = buf+2;
- char *user = skip_string(machine,1);
- logname = skip_string(user,1);
- reply_code = 6;
- reply_name = myname;
- add_slashes = True;
- DEBUG(3,("Domain login request from %s(%s) user=%s\n",
+ struct dgram_packet *dgram = &p->packet.dgram;
+ struct in_addr ip = dgram->header.source_ip;
+ struct domain_record *d = find_domain(ip);
+ char *logname,*q;
+ char *reply_name;
+ BOOL add_slashes = False;
+ pstring outbuf;
+ int code,reply_code;
+ struct work_record *work;
+
+ if (!d) return;
+
+ if (!(work = find_workgroupstruct(d,dgram->dest_name.name, False)))
+ return;
+
+ if (!lp_domain_logons()) {
+ DEBUG(3,("No domain logons\n"));
+ return;
+ }
+ if (!listening_name(work, &dgram->dest_name))
+ {
+ DEBUG(4,("Not listening to that domain\n"));
+ return;
+ }
+
+ code = SVAL(buf,0);
+ switch (code) {
+ case 0:
+ {
+ char *machine = buf+2;
+ char *user = skip_string(machine,1);
+ logname = skip_string(user,1);
+ reply_code = 6;
+ reply_name = myname;
+ add_slashes = True;
+ DEBUG(3,("Domain login request from %s(%s) user=%s\n",
machine,inet_ntoa(p->ip),user));
- }
- break;
- case 7:
- {
- char *machine = buf+2;
- logname = skip_string(machine,1);
- reply_code = 7;
- reply_name = lp_domain_controller();
- if (!*reply_name) {
+ }
+ break;
+ case 7:
+ {
+ char *machine = buf+2;
+ logname = skip_string(machine,1);
+ reply_code = 7;
+ reply_name = lp_domain_controller();
+ if (!*reply_name) {
DEBUG(3,("No domain controller configured\n"));
return;
- }
- DEBUG(3,("GETDC request from %s(%s)\n",
+ }
+ DEBUG(3,("GETDC request from %s(%s)\n",
machine,inet_ntoa(p->ip)));
- }
- break;
- default:
- DEBUG(3,("Unknown domain request %d\n",code));
- return;
- }
-
- bzero(outbuf,sizeof(outbuf));
- q = outbuf;
- SSVAL(q,0,reply_code);
- q += 2;
- if (add_slashes) {
- strcpy(q,"\\\\");
- q += 2;
- }
- StrnCpy(q,reply_name,16);
- strupper(q);
- q = skip_string(q,1);
- SSVAL(q,0,0xFFFF);
- q += 2;
-
- send_mailslot_reply(logname,ClientDGRAM,outbuf,PTR_DIFF(q,outbuf),
+ }
+ break;
+ default:
+ DEBUG(3,("Unknown domain request %d\n",code));
+ return;
+ }
+
+ bzero(outbuf,sizeof(outbuf));
+ q = outbuf;
+ SSVAL(q,0,reply_code);
+ q += 2;
+ if (add_slashes) {
+ strcpy(q,"\\\\");
+ q += 2;
+ }
+ StrnCpy(q,reply_name,16);
+ strupper(q);
+ q = skip_string(q,1);
+ SSVAL(q,0,0xFFFF);
+ q += 2;
+
+ send_mailslot_reply(logname,ClientDGRAM,outbuf,PTR_DIFF(q,outbuf),
myname,&dgram->source_name.name[0],0x20,0,p->ip,myip);
}
@@ -845,60 +845,60 @@ check listening name type
****************************************************************************/
BOOL listening_type(struct packet_struct *p, int command)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- int type = dgram->dest_name.name_type;
-
- switch (command)
- {
- case 1: /* host announce */
- {
- if (type != 0x0 || type != 0x20) return (False);
- break;
- }
-
- case 2: /* announce request */
- {
- return (True);
- break;
- }
-
- case 8: /* election */
- {
- return (True);
- break;
- }
-
- case 9: /* get backup list */
- {
- return (True);
- break;
- }
-
- case 10: /* receive backup list */
- {
- return (True);
- break;
- }
-
- case 12: /* domain announce */
- {
- if (type != 0x1b || type != 0x1c) return (False);
- break;
- }
-
- case 13: /* master announcement */
- {
- if (type != 0x1d) return (False);
- break;
- }
+ struct dgram_packet *dgram = &p->packet.dgram;
+ int type = dgram->dest_name.name_type;
- case 15: /* local master announce */
- {
- if (type != 0x1c || type != 0x1d) return (False);
- break;
- }
- }
- return (True); /* we're not dealing with unknown packet types */
+ switch (command)
+ {
+ case 1: /* host announce */
+ {
+ if (type != 0x0 || type != 0x20) return (False);
+ break;
+ }
+
+ case 2: /* announce request */
+ {
+ return (True);
+ break;
+ }
+
+ case 8: /* election */
+ {
+ return (True);
+ break;
+ }
+
+ case 9: /* get backup list */
+ {
+ return (True);
+ break;
+ }
+
+ case 10: /* receive backup list */
+ {
+ return (True);
+ break;
+ }
+
+ case 12: /* domain announce */
+ {
+ if (type != 0x1b || type != 0x1c) return (False);
+ break;
+ }
+
+ case 13: /* master announcement */
+ {
+ if (type != 0x1d) return (False);
+ break;
+ }
+
+ case 15: /* local master announce */
+ {
+ if (type != 0x1c || type != 0x1d) return (False);
+ break;
+ }
+ }
+ return (True); /* we're not dealing with unknown packet types */
}
@@ -907,123 +907,123 @@ process a browse frame
****************************************************************************/
void process_browse_packet(struct packet_struct *p,char *buf,int len)
{
- int command = CVAL(buf,0);
- switch (command)
- {
- case 1: /* host announce */
- case 12: /* domain announce */
- case 15: /* local master announce */
- {
- process_announce(p,command,buf+1);
- break;
- }
-
- case 2: /* announce request */
- {
- process_announce_request(p,buf+1);
- break;
- }
-
- case 8: /* election */
- {
- process_election(p,buf+1);
- break;
- }
-
- case 9: /* get backup list */
- {
- process_send_backup_list(p,buf+1);
- break;
- }
-
- case 10: /* receive backup list */
- {
+ int command = CVAL(buf,0);
+ switch (command)
+ {
+ case 1: /* host announce */
+ case 12: /* domain announce */
+ case 15: /* local master announce */
+ {
+ process_announce(p,command,buf+1);
+ break;
+ }
+
+ case 2: /* announce request */
+ {
+ process_announce_request(p,buf+1);
+ break;
+ }
+
+ case 8: /* election */
+ {
+ process_election(p,buf+1);
+ break;
+ }
+
+ case 9: /* get backup list */
+ {
+ process_send_backup_list(p,buf+1);
+ break;
+ }
+
+ case 10: /* receive backup list */
+ {
#ifdef TEST_CODE
- struct dgram_packet *dgram = &p->packet.dgram;
- int i, j;
-
- DEBUG(4, ("ignoring browse packet %d from %s %s to %s\n",
- command, namestr(&dgram->source_name),
- inet_ntoa(p->ip), namestr(&dgram->dest_name)));
-
- for (i = 0; i < len; i+= 16)
- {
- DEBUG(4, ("%3x char ", i));
-
- for (j = 0; j < 16; j++)
- {
- unsigned char x = buf[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", buf[i+j]));
- }
-
- DEBUG(4, ("\n"));
- }
-
+ struct dgram_packet *dgram = &p->packet.dgram;
+ int i, j;
+
+ DEBUG(4, ("ignoring browse packet %d from %s %s to %s\n",
+ command, namestr(&dgram->source_name),
+ inet_ntoa(p->ip), namestr(&dgram->dest_name)));
+
+ for (i = 0; i < len; i+= 16)
+ {
+ DEBUG(4, ("%3x char ", i));
+
+ for (j = 0; j < 16; j++)
+ {
+ unsigned char x = buf[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", buf[i+j]));
+ }
+
+ DEBUG(4, ("\n"));
+ }
+
#endif /* TEST_CODE */
- process_rcv_backup_list(p, buf+1);
- break;
- }
-
- case 11: /* reset browser state */
- {
- process_reset_browser(p, buf+1);
- break;
- }
-
- case 13: /* master announcement */
- {
- process_master_announce(p,buf+1);
- break;
- }
-
+ process_rcv_backup_list(p, buf+1);
+ break;
+ }
+
+ case 11: /* reset browser state */
+ {
+ process_reset_browser(p, buf+1);
+ break;
+ }
+
+ case 13: /* master announcement */
+ {
+ process_master_announce(p,buf+1);
+ break;
+ }
+
#ifdef TEST_CODE
- default:
- {
- struct dgram_packet *dgram = &p->packet.dgram;
- int i, j;
-
- DEBUG(4, ("ignoring browse packet %d from %s %s to %s\n",
- command, namestr(&dgram->source_name),
- inet_ntoa(p->ip), namestr(&dgram->dest_name)));
-
- for (i = 0; i < len; i+= 16)
- {
- DEBUG(4, ("%3x char ", i));
-
- for (j = 0; j < 16; j++)
- {
- unsigned char x = buf[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", buf[i+j]));
- }
-
- DEBUG(4, ("\n"));
- }
-
- }
+ default:
+ {
+ struct dgram_packet *dgram = &p->packet.dgram;
+ int i, j;
+
+ DEBUG(4, ("ignoring browse packet %d from %s %s to %s\n",
+ command, namestr(&dgram->source_name),
+ inet_ntoa(p->ip), namestr(&dgram->dest_name)));
+
+ for (i = 0; i < len; i+= 16)
+ {
+ DEBUG(4, ("%3x char ", i));
+
+ for (j = 0; j < 16; j++)
+ {
+ unsigned char x = buf[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", buf[i+j]));
+ }
+
+ DEBUG(4, ("\n"));
+ }
+
+ }
#endif /* TEST_CODE */
- }
+ }
}
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index 222ab3f921..b6ef717cc0 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -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();
diff --git a/source3/nmbsync.c b/source3/nmbsync.c
index 5a6c07086a..c3e3f43e51 100644
--- a/source3/nmbsync.c
+++ b/source3/nmbsync.c
@@ -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);
}
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 1e488ec90d..bbeb4801d5 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -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)