summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/include/nameserv.h25
-rw-r--r--source/include/proto.h20
-rw-r--r--source/libsmb/namequery.c14
-rw-r--r--source/nameannounce.c137
-rw-r--r--source/namebrowse.c8
-rw-r--r--source/namedbname.c23
-rw-r--r--source/namedbresp.c4
-rw-r--r--source/namedbsubnet.c7
-rw-r--r--source/namedbwork.c2
-rw-r--r--source/nameelect.c11
-rw-r--r--source/nameresp.c8
-rw-r--r--source/nameserv.c27
-rw-r--r--source/nameservreply.c103
-rw-r--r--source/nameservresp.c133
-rw-r--r--source/namework.c28
-rw-r--r--source/nmbd/nmbd.c5
-rw-r--r--source/nmbsync.c9
-rw-r--r--source/utils/nmblookup.c18
18 files changed, 387 insertions, 195 deletions
diff --git a/source/include/nameserv.h b/source/include/nameserv.h
index 7a97097e78e..582378e1839 100644
--- a/source/include/nameserv.h
+++ b/source/include/nameserv.h
@@ -48,10 +48,10 @@
#define NB_ACTIVE 0x04
#define NB_CONFL 0x08
#define NB_DEREG 0x10
-#define NB_BFLAG 0x00
-#define NB_PFLAG 0x20
-#define NB_MFLAG 0x40
-#define NB__FLAG 0x60
+#define NB_BFLAG 0x00 /* broadcast node type */
+#define NB_PFLAG 0x20 /* point-to-point node type */
+#define NB_MFLAG 0x40 /* mixed bcast & p-p node type */
+#define NB_HFLAG 0x60 /* microsoft 'hybrid' node type */
#define NB_FLGMSK 0x60
#define REFRESH_TIME (15*60)
@@ -68,7 +68,7 @@
#define NAME_BFLAG(p) (((p) & NB_FLGMSK) == NB_BFLAG)
#define NAME_PFLAG(p) (((p) & NB_FLGMSK) == NB_PFLAG)
#define NAME_MFLAG(p) (((p) & NB_FLGMSK) == NB_MFLAG)
-#define NAME__FLAG(p) (((p) & NB_FLGMSK) == NB__FLAG)
+#define NAME_HFLAG(p) (((p) & NB_FLGMSK) == NB_HFLAG)
/* server type identifiers */
#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
@@ -99,14 +99,16 @@ enum master_state
enum state_type
{
- NAME_STATUS_PDC_SRV_CHK,
+ NAME_STATUS_DOM_SRV_CHK,
NAME_STATUS_SRV_CHK,
NAME_REGISTER_CHALLENGE,
NAME_REGISTER,
NAME_RELEASE,
NAME_QUERY_CONFIRM,
- NAME_QUERY_SYNC,
- NAME_QUERY_PDC_SRV_CHK,
+ NAME_QUERY_ANNOUNCE_HOST,
+ NAME_QUERY_SYNC_LOCAL,
+ NAME_QUERY_SYNC_REMOTE,
+ NAME_QUERY_DOM_SRV_CHK,
NAME_QUERY_SRV_CHK,
NAME_QUERY_FIND_MST,
NAME_QUERY_MST_CHK
@@ -147,6 +149,7 @@ struct browse_cache_record
struct in_addr ip;
time_t sync_time;
BOOL synced;
+ BOOL local;
};
/* this is used to hold the list of servers in my domain, and is */
@@ -190,6 +193,8 @@ struct work_record
};
/* initiated name queries recorded in this list to track any responses... */
+/* sadly, we need to group everything together. i suppose that if this
+ gets unwieldy, then a union ought to be considered. oh for c++... */
struct response_record
{
struct response_record *next;
@@ -204,6 +209,10 @@ struct response_record
int nb_flags;
time_t ttl;
+ int server_type;
+ fstring my_name;
+ fstring my_comment;
+
BOOL bcast;
BOOL recurse;
struct in_addr send_ip;
diff --git a/source/include/proto.h b/source/include/proto.h
index 60b8eed59a5..10f2bc33257 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -295,6 +295,11 @@ void sync_server(enum state_type state, char *serv_name, char *work_name,
int name_type,
struct in_addr ip);
void announce_backup(void);
+void do_announce_host(int command,
+ char *from_name, int from_type, struct in_addr from_ip,
+ char *to_name , int to_type , struct in_addr to_ip,
+ time_t announce_interval,
+ char *server_name, int server_type, char *server_comment);
void remove_my_servers(void);
void announce_server(struct subnet_record *d, struct work_record *work,
char *name, char *comment, time_t ttl, int server_type);
@@ -305,11 +310,15 @@ void announce_master(void);
void expire_browse_cache(time_t t);
struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
- time_t ttl, struct in_addr ip);
+ time_t ttl, struct in_addr ip, BOOL local);
void do_browser_lists(void);
+/*The following definitions come from namedb.c */
+
+
/*The following definitions come from namedbname.c */
+void set_samba_nb_type(void);
BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2);
BOOL ms_browser_name(char *name, int type);
void remove_name(struct subnet_record *d, struct name_record *n);
@@ -342,6 +351,7 @@ void remove_response_record(struct subnet_record *d,
struct response_record *make_response_queue_record(enum state_type state,
int id,uint16 fd,
int quest_type, char *name,int type, int nb_flags, time_t ttl,
+ int server_type, char *my_name, char *my_comment,
BOOL bcast,BOOL recurse,
struct in_addr send_ip, struct in_addr reply_to_ip);
struct response_record *find_response_record(struct subnet_record **d,
@@ -432,13 +442,15 @@ void expire_netbios_response_entries();
struct response_record *queue_netbios_pkt_wins(struct subnet_record *d,
int fd,int quest_type,enum state_type state,
char *name,int name_type,int nb_flags, time_t ttl,
+ int server_type, char *my_name, char *my_comment,
BOOL bcast,BOOL recurse,
struct in_addr send_ip, struct in_addr reply_to_ip);
struct response_record *queue_netbios_packet(struct subnet_record *d,
int fd,int quest_type,enum state_type state,char *name,
int name_type,int nb_flags, time_t ttl,
- BOOL bcast,BOOL recurse,
- struct in_addr send_ip, struct in_addr reply_to_ip);
+ int server_type, char *my_name, char *my_comment,
+ BOOL bcast,BOOL recurse,
+ struct in_addr send_ip, struct in_addr reply_to_ip);
/*The following definitions come from nameserv.c */
@@ -502,7 +514,7 @@ int main(int argc,char *argv[]);
char *getsmbpass(char *pass);
void sync_browse_lists(struct subnet_record *d, struct work_record *work,
- char *name, int nm_type, struct in_addr ip);
+ char *name, int nm_type, struct in_addr ip, BOOL local);
/*The following definitions come from params.c */
diff --git a/source/libsmb/namequery.c b/source/libsmb/namequery.c
index 54809130017..21d3bd1e501 100644
--- a/source/libsmb/namequery.c
+++ b/source/libsmb/namequery.c
@@ -54,7 +54,7 @@ static void _interpret_node_status(char *p, char *master,char *rname)
if ((p[0] & 0x60) == 0x00) strcat(flags,"B ");
if ((p[0] & 0x60) == 0x20) strcat(flags,"P ");
if ((p[0] & 0x60) == 0x40) strcat(flags,"M ");
- if ((p[0] & 0x60) == 0x60) strcat(flags,"_ ");
+ if ((p[0] & 0x60) == 0x60) strcat(flags,"H ");
if (p[0] & 0x10) strcat(flags,"<DEREGISTERING> ");
if (p[0] & 0x08) strcat(flags,"<CONFLICT> ");
if (p[0] & 0x04) strcat(flags,"<ACTIVE> ");
@@ -109,8 +109,8 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
nmb->header.opcode = 0;
nmb->header.response = False;
nmb->header.nm_flags.bcast = False;
- nmb->header.nm_flags.recursion_available = 0;
- nmb->header.nm_flags.recursion_desired = 1;
+ nmb->header.nm_flags.recursion_available = False;
+ nmb->header.nm_flags.recursion_desired = False;
nmb->header.nm_flags.trunc = False;
nmb->header.nm_flags.authoritative = False;
nmb->header.rcode = 0;
@@ -152,6 +152,8 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
if ((p2=receive_packet(fd,NMB_PACKET,90)))
{
struct nmb_packet *nmb2 = &p2->packet.nmb;
+ debug_nmb_packet(p2);
+
if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
!nmb2->header.response) {
/* its not for us - maybe deal with it later */
@@ -173,8 +175,6 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
continue;
}
- debug_nmb_packet(p2);
-
_interpret_node_status(&nmb2->answers->rdata[0], master,rname);
free_packet(p2);
return(True);
@@ -257,6 +257,8 @@ BOOL name_query(int fd,char *name,int name_type,
if ((p2=receive_packet(fd,NMB_PACKET,90)))
{
struct nmb_packet *nmb2 = &p2->packet.nmb;
+ debug_nmb_packet(p2);
+
if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
!nmb2->header.response) {
/* its not for us - maybe deal with it later
@@ -268,8 +270,6 @@ BOOL name_query(int fd,char *name,int name_type,
continue;
}
- debug_nmb_packet(p2);
-
if (nmb2->header.opcode != 0 ||
nmb2->header.nm_flags.bcast ||
nmb2->header.rcode ||
diff --git a/source/nameannounce.c b/source/nameannounce.c
index 4801f9e0bd2..c76dffda00a 100644
--- a/source/nameannounce.c
+++ b/source/nameannounce.c
@@ -120,9 +120,12 @@ void sync_server(enum state_type state, char *serv_name, char *work_name,
int name_type,
struct in_addr ip)
{
- add_browser_entry(serv_name, name_type, work_name, 0, ip);
+ /* with a domain master we can get the whole list (not local only list) */
+ BOOL local_only = state != NAME_STATUS_DOM_SRV_CHK;
- if (state == NAME_STATUS_PDC_SRV_CHK)
+ add_browser_entry(serv_name, name_type, work_name, 0, ip, local_only);
+
+ if (state == NAME_STATUS_DOM_SRV_CHK)
{
/* announce ourselves as a master browser to serv_name */
do_announce_request(myname, serv_name, ANN_MasterAnnouncement,
@@ -230,7 +233,7 @@ void announce_backup(void)
/****************************************************************************
send a host announcement packet
**************************************************************************/
-static void do_announce_host(int command,
+void do_announce_host(int command,
char *from_name, int from_type, struct in_addr from_ip,
char *to_name , int to_type , struct in_addr to_ip,
time_t announce_interval,
@@ -303,45 +306,86 @@ void announce_server(struct subnet_record *d, struct work_record *work,
char *name, char *comment, time_t ttl, int server_type)
{
uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_SERVER_UNIX;
-
- if (AM_MASTER(work))
+ BOOL wins_iface = ip_equal(d->bcast_ip, ipgrp);
+
+ if (wins_iface && server_type != 0)
{
- DEBUG(3,("sending local master announce to %s for %s(1e)\n",
- inet_ntoa(d->bcast_ip),work->work_group));
-
- do_announce_host(ANN_LocalMasterAnnouncement,
- name , 0x00, d->myip,
- work->work_group, 0x1e, d->bcast_ip,
- ttl*1000,
- name, server_type, comment);
-
- DEBUG(3,("sending domain announce to %s for %s\n",
- inet_ntoa(d->bcast_ip),work->work_group));
-
- /* XXXX should we do a domain-announce-kill? */
- if (server_type != 0)
+ /* wins pseudo-ip interface */
+ if (!AM_MASTER(work))
{
- if (AM_DOMCTL(work)) {
- domain_type |= SV_TYPE_DOMAIN_CTRL;
+ /* non-master announce by unicast to the domain master */
+ if (!lp_wins_support() && *lp_wins_server())
+ {
+ /* look up the domain master with the WINS server */
+ queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,
+ NAME_QUERY_ANNOUNCE_HOST,
+ work->work_group,0x1b,0,ttl*1000,
+ server_type,name,comment,
+ False, False, ipzero, d->bcast_ip);
}
- do_announce_host(ANN_DomainAnnouncement,
- name , 0x00, d->myip,
- MSBROWSE, 0x01, d->bcast_ip,
- ttl*1000,
- work->work_group, server_type ? domain_type : 0,
- comment);
+ else
+ {
+ /* we are the WINS server, but not the domain master.
+ what's going on??? and we're not going to deal with
+ this case, right now
+ */
+ }
+ }
+
+ if (AM_DOMCTL(work))
+ {
+ /* XXXX announce to backup domain masters? */
}
+
+ /* XXXX any other kinds of announcements we need to consider here?
+ e.g local master browsers... no. local master browsers do
+ local master announcements to their domain master. they even
+ use WINS lookup of the domain master if another wins server
+ is being used!
+ */
}
else
{
- DEBUG(3,("sending host announce to %s for %s(1d)\n",
- inet_ntoa(d->bcast_ip),work->work_group));
-
- do_announce_host(ANN_HostAnnouncement,
- name , 0x00, d->myip,
- work->work_group, 0x1d, d->bcast_ip,
- ttl*1000,
- name, server_type, comment);
+ if (AM_MASTER(work))
+ {
+ DEBUG(3,("sending local master announce to %s for %s(1e)\n",
+ inet_ntoa(d->bcast_ip),work->work_group));
+
+ do_announce_host(ANN_LocalMasterAnnouncement,
+ name , 0x00, d->myip,
+ work->work_group, 0x1e, d->bcast_ip,
+ ttl*1000,
+ name, server_type, comment);
+
+ DEBUG(3,("sending domain announce to %s for %s\n",
+ inet_ntoa(d->bcast_ip),work->work_group));
+
+ /* XXXX should we do a domain-announce-kill? */
+ if (server_type != 0)
+ {
+ if (AM_DOMCTL(work))
+ {
+ domain_type |= SV_TYPE_DOMAIN_CTRL;
+ }
+ do_announce_host(ANN_DomainAnnouncement,
+ name , 0x00, d->myip,
+ MSBROWSE, 0x01, d->bcast_ip,
+ ttl*1000,
+ work->work_group, server_type ? domain_type : 0,
+ comment);
+ }
+ }
+ else
+ {
+ DEBUG(3,("sending host announce to %s for %s(1d)\n",
+ inet_ntoa(d->bcast_ip),work->work_group));
+
+ do_announce_host(ANN_HostAnnouncement,
+ name , 0x00, d->myip,
+ work->work_group, 0x1d, d->bcast_ip,
+ ttl*1000,
+ name, server_type, comment);
+ }
}
}
@@ -433,7 +477,7 @@ void announce_host(void)
least 15 minutes.
this actually gets done in search_and_sync_workgroups() via the
- NAME_QUERY_PDC_SRV_CHK command, if there is a response from the
+ NAME_QUERY_DOM_SRV_CHK command, if there is a response from the
name query initiated here. see response_name_query()
**************************************************************************/
void announce_master(void)
@@ -473,7 +517,7 @@ void announce_master(void)
{
if (strequal(s->serv.name, myname)) continue;
- /* all PDCs (which should also be master browsers) */
+ /* all DOMs (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
@@ -485,13 +529,10 @@ void announce_master(void)
{
if (!lp_wins_support() && *lp_wins_server())
{
- struct in_addr ip;
- ip = ipzero;
-
queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,
- NAME_QUERY_PDC_SRV_CHK,
- work->work_group,0x1b,0,0,
- False, False, ip, ip);
+ NAME_QUERY_DOM_SRV_CHK,
+ work->work_group,0x1b,0,0,0,NULL,NULL,
+ False, False, ipzero, ipzero);
}
else
{
@@ -499,8 +540,8 @@ void announce_master(void)
for (d2 = subnetlist; d2; d2 = d2->next)
{
queue_netbios_packet(d,ClientNMB,NMB_QUERY,
- NAME_QUERY_PDC_SRV_CHK,
- work->work_group,0x1b,0,0,
+ NAME_QUERY_DOM_SRV_CHK,
+ work->work_group,0x1b,0,0,0,NULL,NULL,
True, False, d2->bcast_ip, d2->bcast_ip);
}
}
@@ -527,14 +568,14 @@ void announce_master(void)
bcast = True;
}
- DEBUG(2, ("Searching for PDC %s at %s\n",
+ DEBUG(2, ("Searching for DOM %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(d,ClientNMB, NMB_QUERY,NAME_QUERY_PDC_SRV_CHK,
- work->work_group,0x1b, 0, 0,
+ queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,NAME_QUERY_DOM_SRV_CHK,
+ work->work_group,0x1b,0,0,0,NULL,NULL,
bcast, False, ip, ip);
}
}
diff --git a/source/namebrowse.c b/source/namebrowse.c
index e62aa1ec6db..b426bc7a150 100644
--- a/source/namebrowse.c
+++ b/source/namebrowse.c
@@ -94,7 +94,7 @@ void expire_browse_cache(time_t t)
add a browser entry
****************************************************************************/
struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
- time_t ttl, struct in_addr ip)
+ time_t ttl, struct in_addr ip, BOOL local)
{
BOOL newentry=False;
@@ -135,6 +135,7 @@ struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
b->ip = ip;
b->type = type;
+ b->local = local; /* local server list sync or complete sync required */
if (newentry || ttl < b->sync_time)
b->sync_time = ttl;
@@ -176,8 +177,9 @@ static void start_sync_browse_entry(struct browse_cache_record *b)
doesn't, the server must have died. o dear. */
/* see response_netbios_packet() or expire_netbios_response_entries() */
- queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_SYNC,
- b->group,0x20,0,0,
+ queue_netbios_packet(d,ClientNMB,NMB_QUERY,
+ b->local?NAME_QUERY_SYNC_LOCAL:NAME_QUERY_SYNC_REMOTE,
+ b->group,0x20,0,0,0,NULL,NULL,
False,False,b->ip,b->ip);
}
diff --git a/source/namedbname.c b/source/namedbname.c
index 37a9fe9c31e..177c36fc07e 100644
--- a/source/namedbname.c
+++ b/source/namedbname.c
@@ -41,6 +41,27 @@ extern struct subnet_record *subnetlist;
#define WINS_LIST "wins.dat"
+uint16 nb_type = 0; /* samba's NetBIOS name type */
+
+
+/****************************************************************************
+ samba's NetBIOS name type
+
+ XXXX maybe functionality could be set: B, M, P or H name registration
+ and resolution could be set through nb_type. just a thought.
+ ****************************************************************************/
+void set_samba_nb_type(void)
+{
+ if (lp_wins_support() || (*lp_wins_server()))
+ {
+ nb_type = NB_MFLAG; /* samba is a 'hybrid' node type */
+ }
+ else
+ {
+ nb_type = NB_BFLAG; /* samba is broadcast-only node type */
+ }
+}
+
/****************************************************************************
true if two netbios names are equal
@@ -390,7 +411,7 @@ struct name_record *add_netbios_entry(struct subnet_record *d,
if (!wins && type != 0x1b)
{
/* the only broadcast (non-WINS) names we are adding are ours
- (SELF) and PDC type names */
+ (SELF) and Domain Master type names */
return NULL;
}
}
diff --git a/source/namedbresp.c b/source/namedbresp.c
index c453d9bbec2..d89bfe8ae84 100644
--- a/source/namedbresp.c
+++ b/source/namedbresp.c
@@ -94,6 +94,7 @@ void remove_response_record(struct subnet_record *d,
struct response_record *make_response_queue_record(enum state_type state,
int id,uint16 fd,
int quest_type, char *name,int type, int nb_flags, time_t ttl,
+ int server_type, char *my_name, char *my_comment,
BOOL bcast,BOOL recurse,
struct in_addr send_ip, struct in_addr reply_to_ip)
{
@@ -111,10 +112,13 @@ struct response_record *make_response_queue_record(enum state_type state,
make_nmb_name(&n->name, name, type, scope);
n->nb_flags = nb_flags;
n->ttl = ttl;
+ n->server_type = server_type;
n->bcast = bcast;
n->recurse = recurse;
n->send_ip = send_ip;
n->reply_to_ip = reply_to_ip;
+ StrnCpy(my_name , n->my_name , sizeof(n->my_name )-1);
+ StrnCpy(my_comment, n->my_comment, sizeof(n->my_comment)-1);
n->repeat_interval = 1; /* XXXX should be in ms */
n->repeat_count = 3; /* 3 retries */
diff --git a/source/namedbsubnet.c b/source/namedbsubnet.c
index a259f25393a..5c683e5e49b 100644
--- a/source/namedbsubnet.c
+++ b/source/namedbsubnet.c
@@ -50,6 +50,7 @@ extern struct interface *local_interfaces;
/* this is our domain/workgroup/server database */
struct subnet_record *subnetlist = NULL;
+extern uint16 nb_type; /* samba's NetBIOS name type */
/****************************************************************************
add a domain into the list
@@ -166,7 +167,7 @@ void add_subnet_interfaces(void)
}
/* add the pseudo-ip interface for WINS: 255.255.255.255 */
- if (lp_wins_support())
+ if (lp_wins_support() || (*lp_wins_server()))
{
struct in_addr wins_bcast = ipgrp;
struct in_addr wins_nmask = ipzero;
@@ -231,8 +232,8 @@ struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
or register with WINS server, if it's our workgroup */
if (strequal(lp_workgroup(), name))
{
- add_my_name_entry(d,name,0x1e,NB_ACTIVE|NB_GROUP);
- add_my_name_entry(d,name,0x0 ,NB_ACTIVE|NB_GROUP);
+ add_my_name_entry(d,name,0x1e,nb_type|NB_ACTIVE|NB_GROUP);
+ add_my_name_entry(d,name,0x0 ,nb_type|NB_ACTIVE|NB_GROUP);
}
/* add samba server name to workgroup list. don't add
lmhosts server entries to local interfaces */
diff --git a/source/namedbwork.c b/source/namedbwork.c
index 13dde54b227..200132304b0 100644
--- a/source/namedbwork.c
+++ b/source/namedbwork.c
@@ -181,7 +181,7 @@ struct work_record *find_workgroupstruct(struct subnet_record *d,
DEBUG(2,("add any workgroups: initiating browser search on %s\n",
inet_ntoa(d->bcast_ip)));
queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY, NAME_QUERY_FIND_MST,
- MSBROWSE,0x1,0,0,
+ MSBROWSE,0x1,0,0,0,NULL,NULL,
True,False, d->bcast_ip, d->bcast_ip);
return NULL;
}
diff --git a/source/nameelect.c b/source/nameelect.c
index 1095f8a7fad..8c93de03a85 100644
--- a/source/nameelect.c
+++ b/source/nameelect.c
@@ -52,6 +52,7 @@ extern time_t StartupTime;
extern struct subnet_record *subnetlist;
+extern uint16 nb_type; /* samba's NetBIOS name type */
/*******************************************************************
occasionally check to see if the master browser is around
@@ -81,7 +82,7 @@ void check_master_browser(void)
if (!AM_MASTER(work))
{
queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_MST_CHK,
- work->work_group,0x1d,0,0,
+ work->work_group,0x1d,0,0,0,NULL,NULL,
True,False,d->bcast_ip,d->bcast_ip);
}
}
@@ -268,7 +269,7 @@ void become_master(struct subnet_record *d, struct work_record *work)
add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
/* add special browser name */
- add_my_name_entry(d,MSBROWSE ,0x01,NB_ACTIVE|NB_GROUP);
+ add_my_name_entry(d,MSBROWSE ,0x01,nb_type|NB_ACTIVE|NB_GROUP);
/* DON'T do anything else after calling add_my_name_entry() */
return;
@@ -282,7 +283,7 @@ void become_master(struct subnet_record *d, struct work_record *work)
add_server_entry(d,work,work->work_group,domain_type,0,myname,True);
/* add master name */
- add_my_name_entry(d,work->work_group,0x1d,NB_ACTIVE );
+ add_my_name_entry(d,work->work_group,0x1d,nb_type|NB_ACTIVE);
/* DON'T do anything else after calling add_my_name_entry() */
return;
@@ -320,7 +321,7 @@ void become_master(struct subnet_record *d, struct work_record *work)
DEBUG(3,("domain first stage: register as domain member\n"));
/* add domain member name */
- add_my_name_entry(d,work->work_group,0x1e,NB_ACTIVE );
+ add_my_name_entry(d,work->work_group,0x1e,nb_type|NB_ACTIVE|NB_GROUP);
/* DON'T do anything else after calling add_my_name_entry() */
return;
@@ -347,7 +348,7 @@ void become_master(struct subnet_record *d, struct work_record *work)
}
/* add domain master name */
- add_my_name_entry(d,work->work_group,0x1b,NB_ACTIVE );
+ add_my_name_entry(d,work->work_group,0x1b,nb_type|NB_ACTIVE );
/* DON'T do anything else after calling add_my_name_entry() */
return;
diff --git a/source/nameresp.c b/source/nameresp.c
index 0f76323df0b..7fcb41e79f0 100644
--- a/source/nameresp.c
+++ b/source/nameresp.c
@@ -224,6 +224,7 @@ void expire_netbios_response_entries()
struct response_record *queue_netbios_pkt_wins(struct subnet_record *d,
int fd,int quest_type,enum state_type state,
char *name,int name_type,int nb_flags, time_t ttl,
+ int server_type, char *my_name, char *my_comment,
BOOL bcast,BOOL recurse,
struct in_addr send_ip, struct in_addr reply_to_ip)
{
@@ -256,6 +257,7 @@ struct response_record *queue_netbios_pkt_wins(struct subnet_record *d,
return queue_netbios_packet(d,fd, quest_type, state,
name, name_type, nb_flags, ttl,
+ server_type,my_name,my_comment,
bcast, recurse, send_ip, reply_to_ip);
}
@@ -269,8 +271,9 @@ struct response_record *queue_netbios_pkt_wins(struct subnet_record *d,
struct response_record *queue_netbios_packet(struct subnet_record *d,
int fd,int quest_type,enum state_type state,char *name,
int name_type,int nb_flags, time_t ttl,
- BOOL bcast,BOOL recurse,
- struct in_addr send_ip, struct in_addr reply_to_ip)
+ int server_type, char *my_name, char *my_comment,
+ BOOL bcast,BOOL recurse,
+ struct in_addr send_ip, struct in_addr reply_to_ip)
{
struct in_addr wins_ip = ipgrp;
struct response_record *n;
@@ -289,6 +292,7 @@ struct response_record *queue_netbios_packet(struct subnet_record *d,
if ((n = make_response_queue_record(state,id,fd,
quest_type,name,name_type,nb_flags,ttl,
+ server_type,my_name, my_comment,
bcast,recurse,send_ip,reply_to_ip)))
{
add_response_record(d,n);
diff --git a/source/nameserv.c b/source/nameserv.c
index 93cc5974153..da1480961f1 100644
--- a/source/nameserv.c
+++ b/source/nameserv.c
@@ -43,6 +43,7 @@ extern struct in_addr ipgrp;
extern struct subnet_record *subnetlist;
+extern uint16 nb_type; /* samba's NetBIOS type */
/****************************************************************************
remove an entry from the name list
@@ -90,7 +91,7 @@ void remove_name_entry(struct subnet_record *d, char *name,int type)
server, or if no reply is received, then we can remove the name */
queue_netbios_pkt_wins(d,ClientNMB,NMB_REL,NAME_RELEASE,
- name, type, 0, 0,
+ name, type, 0, 0,0,NULL,NULL,
False, True, ipzero, ipzero);
}
}
@@ -101,7 +102,7 @@ void remove_name_entry(struct subnet_record *d, char *name,int type)
then we can remove the name. */
queue_netbios_packet(d,ClientNMB,NMB_REL,NAME_RELEASE,
- name, type, 0, 0,
+ name, type, 0, 0,0,NULL,NULL,
True, True, d->bcast_ip, d->bcast_ip);
}
}
@@ -151,7 +152,7 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
/* a time-to-live allows us to refresh this name with the WINS server. */
queue_netbios_pkt_wins(d,ClientNMB,
re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
- name, type, nb_flags, GET_TTL(0),
+ name, type, nb_flags, GET_TTL(0),0,NULL,NULL,
False, True, ipzero, ipzero);
}
}
@@ -160,7 +161,7 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
/* broadcast the packet, but it comes from ipzero */
queue_netbios_packet(d,ClientNMB,
re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
- name, type, nb_flags, GET_TTL(0),
+ name, type, nb_flags, GET_TTL(0),0,NULL,NULL,
True, True, d->bcast_ip, ipzero);
}
}
@@ -186,20 +187,20 @@ void add_my_names(void)
{
BOOL wins_iface = ip_equal(d->bcast_ip, ipgrp);
- add_my_name_entry(d, myname,0x20,NB_ACTIVE);
- add_my_name_entry(d, myname,0x03,NB_ACTIVE);
- add_my_name_entry(d, myname,0x00,NB_ACTIVE);
- add_my_name_entry(d, myname,0x1f,NB_ACTIVE);
+ add_my_name_entry(d, myname,0x20,nb_type|NB_ACTIVE);
+ add_my_name_entry(d, myname,0x03,nb_type|NB_ACTIVE);
+ add_my_name_entry(d, myname,0x00,nb_type|NB_ACTIVE);
+ add_my_name_entry(d, myname,0x1f,nb_type|NB_ACTIVE);
/* these names are added permanently (ttl of zero) and will NOT be
refreshed with the WINS server */
- add_netbios_entry(d,"*",0x0,NB_ACTIVE,0,SELF,ip,False,wins);
- add_netbios_entry(d,"__SAMBA__",0x20,NB_ACTIVE,0,SELF,ip,False,wins);
- add_netbios_entry(d,"__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip,False,wins);
+ add_netbios_entry(d,"*",0x0,nb_type|NB_ACTIVE,0,SELF,ip,False,wins);
+ add_netbios_entry(d,"__SAMBA__",0x20,nb_type|NB_ACTIVE,0,SELF,ip,False,wins);
+ add_netbios_entry(d,"__SAMBA__",0x00,nb_type|NB_ACTIVE,0,SELF,ip,False,wins);
if (!wins_iface && lp_domain_logons() && lp_domain_master()) {
/* XXXX the 0x1c is apparently something to do with domain logons */
- add_my_name_entry(d, my_workgroup(),0x1c,NB_ACTIVE|NB_GROUP);
+ add_my_name_entry(d, my_workgroup(),0x1c,nb_type|NB_ACTIVE|NB_GROUP);
}
}
if (lp_domain_master() && (d = find_subnet(ipgrp)))
@@ -310,7 +311,7 @@ void query_refresh_names(void)
queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_CONFIRM,
n->name.name, n->name.name_type,
- 0,0,
+ 0,0,0,NULL,NULL,
False,False,n->ip,n->ip);
count++;
}
diff --git a/source/nameservreply.c b/source/nameservreply.c
index 84b9277d603..5b45e88c5e7 100644
--- a/source/nameservreply.c
+++ b/source/nameservreply.c
@@ -294,7 +294,8 @@ void reply_name_reg(struct packet_struct *p)
/* initiate some enquiries to the current owner. */
queue_netbios_packet(d,ClientNMB,NMB_QUERY,
NAME_REGISTER_CHALLENGE,
- reply_name->name,reply_name->name_type,nb_flags,0,
+ reply_name->name,reply_name->name_type,
+ nb_flags,0,0,NULL,NULL,
False, False, n->ip, p->ip);
}
else
@@ -311,8 +312,11 @@ void reply_name_reg(struct packet_struct *p)
/****************************************************************************
-reply to a name status query
-****************************************************************************/
+ reply to a name status query
+
+ combine the list of the local interface on which the query was made with
+ the names registered via wins.
+ ****************************************************************************/
void reply_name_status(struct packet_struct *p)
{
struct nmb_packet *nmb = &p->packet.nmb;
@@ -323,7 +327,7 @@ void reply_name_status(struct packet_struct *p)
int names_added;
struct name_record *n;
struct subnet_record *d = NULL;
- int search = FIND_SELF;
+ int search = FIND_SELF | FIND_WINS;
BOOL bcast = nmb->header.nm_flags.bcast;
@@ -338,8 +342,6 @@ void reply_name_status(struct packet_struct *p)
namestr(&nmb->question.question_name), inet_ntoa(p->ip)));
if (bcast)
- search |= FIND_WINS;
- else
search |= FIND_LOCAL;
n = find_name_search(&d, &nmb->question.question_name,
@@ -353,38 +355,55 @@ void reply_name_status(struct packet_struct *p)
buf += 1;
names_added = 0;
-
- for (n = d->namelist ; n && buf < bufend; n = n->next)
+
+ n = d->namelist;
+
+ while (buf < bufend)
+ {
+ if (n->source == SELF)
{
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);
- sprintf(buf,"%-15.15s",n->name.name);
- 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 */
+ /* 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 */
- buf[15] = name_type;
- buf[16] = n->nb_flags;
+ if (name_type < 0x1b || name_type > 0x20 ||
+ ques_type < 0x1b || ques_type > 0x20 ||
+ strequal(qname, n->name.name))
+ {
+ /* start with first bit of putting info in buffer: the name */
+ bzero(buf,18);
+ sprintf(buf,"%-15.15s",n->name.name);
+ strupper(buf);
+
+ /* put name type and netbios flags in buffer */
+ buf[15] = name_type;
+ buf[16] = n->nb_flags;
+
+ buf += 18;
- buf += 18;
-
- names_added++;
+ names_added++;
+ }
}
+
+ n = n->next;
+
+ if (!n)
+ {
+ /* end of this name list: add wins names too? */
+ struct subnet_record *w_d;
+
+ if (!(w_d = find_subnet(ipgrp))) break;
+
+ if (w_d != d)
+ {
+ d = w_d;
+ n = d->namelist; /* start on the wins name list */
+ }
+ }
+ if (!n) break;
+ }
SCVAL(countptr,0,names_added);
@@ -396,9 +415,7 @@ void reply_name_status(struct packet_struct *p)
SIVAL(buf,24,num_good_receives);
}
- SIVAL(buf,46,0xFFB8E5); /* undocumented - used by NT */
-
- buf += 64;
+ buf += 46;
/* Send a POSITIVE NAME STATUS RESPONSE */
reply_netbios_packet(p,nmb->header.name_trn_id,
@@ -451,14 +468,13 @@ void reply_name_query(struct packet_struct *p)
struct name_record *n;
/* directed queries are for WINS server: broadcasts are local SELF queries.
- the exception is PDC names. */
+ the exception is Domain Master names. */
int search = bcast ? FIND_LOCAL | FIND_SELF : FIND_WINS;
- if (name_type == 0x1b)
+ if (name_type == 0x1b || name_type == 0x0 || name_type == 0x20)
{
- /* even if it's a broadcast, we don't ignore queries for PDC names */
- search = FIND_WINS;
+ search |= FIND_WINS;
}
if (search | FIND_LOCAL)
@@ -500,10 +516,11 @@ void reply_name_query(struct packet_struct *p)
}
}
- /* name is directed query, or it's self, or it's a PDC type name, or
- we're replying on behalf of a caller because they are on a different
- subnet and cannot hear the broadcast. XXXX lp_wins_proxy should be
- switched off in environments where broadcasts are forwarded */
+ /* name is directed query, or it's self, or it's a Domain Master type
+ name, or we're replying on behalf of a caller because they are on a
+ different subnet and cannot hear the broadcast. XXXX lp_wins_proxy
+ should be switched off in environments where broadcasts are forwarded
+ */
/* XXXX note: for proxy servers, we should forward the query on to
another WINS server if the name is not in our database, or we are
diff --git a/source/nameservresp.c b/source/nameservresp.c
index 46acc2b9927..a4cda7cdfb5 100644
--- a/source/nameservresp.c
+++ b/source/nameservresp.c
@@ -124,7 +124,66 @@ static void response_name_reg(struct subnet_record *d, struct packet_struct *p)
/****************************************************************************
- response from a name query server check. states of type NAME_QUERY_PDC_SRV_CHK,
+ response from a name query announce host
+ NAME_QUERY_ANNOUNCE_HOST is dealt with here
+ ****************************************************************************/
+static void response_announce_host(struct nmb_name *ans_name,
+ struct nmb_packet *nmb,
+ struct response_record *n, struct subnet_record *d)
+{
+ DEBUG(4, ("Name query at %s ip %s - ",
+ namestr(&n->name), inet_ntoa(n->send_ip)));
+
+ if (!name_equal(&n->name, ans_name))
+ {
+ /* someone gave us the wrong name as a reply. oops. */
+ /* XXXX should say to them 'oi! release that name!' */
+
+ DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
+ return;
+ }
+
+ if (nmb->header.rcode == 0 && nmb->answers->rdata)
+ {
+ /* we had sent out a name query to the current owner
+ of a name because someone else wanted it. now they
+ have responded saying that they still want the name,
+ so the other host can't have it.
+ */
+
+ /* first check all the details are correct */
+
+ int nb_flags = nmb->answers->rdata[0];
+ struct in_addr found_ip;
+
+ putip((char*)&found_ip,&nmb->answers->rdata[2]);
+
+ if (nb_flags != n->nb_flags)
+ {
+ /* someone gave us the wrong nb_flags as a reply. oops. */
+ /* XXXX should say to them 'oi! release that name!' */
+
+ DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
+ DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
+ return;
+ }
+
+ /* do an announce host */
+ do_announce_host(ANN_HostAnnouncement,
+ n->my_name , 0x00, d->myip,
+ n->name.name, 0x1d, found_ip,
+ n->ttl,
+ n->my_name, n->server_type, n->my_comment);
+ }
+ else
+ {
+ /* XXXX negative name query response. no master exists. oops */
+ }
+}
+
+
+/****************************************************************************
+ response from a name query server check. states of type NAME_QUERY_DOM_SRV_CHK,
NAME_QUERY_SRV_CHK, and NAME_QUERY_FIND_MST dealt with here.
****************************************************************************/
static void response_server_check(struct nmb_name *ans_name,
@@ -132,13 +191,13 @@ static void response_server_check(struct nmb_name *ans_name,
{
/* issue another state: this time to do a name status check */
- enum state_type cmd = (n->state == NAME_QUERY_PDC_SRV_CHK) ?
- NAME_STATUS_PDC_SRV_CHK : NAME_STATUS_SRV_CHK;
+ enum state_type cmd = (n->state == NAME_QUERY_DOM_SRV_CHK) ?
+ NAME_STATUS_DOM_SRV_CHK : NAME_STATUS_SRV_CHK;
/* initiate a name status check on the server that replied */
queue_netbios_packet(d,ClientNMB,NMB_STATUS, cmd,
ans_name->name, ans_name->name_type,
- 0,0,
+ 0,0,0,NULL,NULL,
False,False,n->send_ip,n->reply_to_ip);
}
@@ -185,7 +244,7 @@ static BOOL interpret_node_status(struct subnet_record *d,
if (NAME_BFLAG (nb_flags)) { strcat(flags,"B "); }
if (NAME_PFLAG (nb_flags)) { strcat(flags,"P "); }
if (NAME_MFLAG (nb_flags)) { strcat(flags,"M "); }
- if (NAME__FLAG (nb_flags)) { strcat(flags,"_ "); }
+ if (NAME_HFLAG (nb_flags)) { strcat(flags,"H "); }
if (NAME_DEREG (nb_flags)) { strcat(flags,"<DEREGISTERING> "); }
if (NAME_CONFLICT (nb_flags)) { strcat(flags,"<CONFLICT> "); add=True;}
if (NAME_ACTIVE (nb_flags)) { strcat(flags,"<ACTIVE> "); add=True; }
@@ -236,7 +295,7 @@ static BOOL interpret_node_status(struct subnet_record *d,
/****************************************************************************
- response from a name status check. states of type NAME_STATUS_PDC_SRV_CHK
+ response from a name status check. states of type NAME_STATUS_DOM_SRV_CHK
and NAME_STATUS_SRV_CHK dealt with here.
****************************************************************************/
static void response_name_status_check(struct in_addr ip,
@@ -380,14 +439,17 @@ static void response_name_query_sync(struct nmb_packet *nmb,
DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
- if (n->state == NAME_QUERY_SYNC)
+ if (n->state == NAME_QUERY_SYNC_LOCAL ||
+ n->state == NAME_QUERY_SYNC_REMOTE)
{
struct work_record *work = NULL;
if ((work = find_workgroupstruct(d, ans_name->name, False)))
{
+ BOOL local_list_only = n->state == NAME_QUERY_SYNC_LOCAL;
+
/* the server is there: sync quick before it (possibly) dies! */
sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
- found_ip);
+ found_ip, local_list_only);
}
}
else
@@ -439,17 +501,23 @@ void debug_state_type(int state)
/* report the state type to help debugging */
switch (state)
{
- case NAME_QUERY_PDC_SRV_CHK : DEBUG(4,("MASTER_SVR_CHECK\n")); break;
- case NAME_QUERY_SRV_CHK : DEBUG(4,("NAME_QUERY_SRV_CHK\n")); break;
- case NAME_QUERY_FIND_MST : DEBUG(4,("NAME_QUERY_FIND_MST\n")); break;
- case NAME_STATUS_PDC_SRV_CHK: DEBUG(4,("NAME_STAT_MST_CHK\n")); break;
- case NAME_STATUS_SRV_CHK : DEBUG(4,("NAME_STATUS_SRV_CHK\n")); break;
- case NAME_QUERY_MST_CHK : DEBUG(4,("NAME_QUERY_MST_CHK\n")); break;
- case NAME_REGISTER : DEBUG(4,("NAME_REGISTER\n")); break;
- case NAME_REGISTER_CHALLENGE: DEBUG(4,("NAME_REGISTER_CHALLENGE\n")); break;
- case NAME_RELEASE : DEBUG(4,("NAME_RELEASE\n")); break;
- case NAME_QUERY_CONFIRM : DEBUG(4,("NAME_QUERY_CONFIRM\n")); break;
- case NAME_QUERY_SYNC : DEBUG(4,("NAME_QUERY_SYNC\n")); break;
+ case NAME_QUERY_DOM_SRV_CHK : DEBUG(4,("MASTER_SVR_CHECK\n")); break;
+ case NAME_QUERY_SRV_CHK : DEBUG(4,("NAME_QUERY_SRV_CHK\n")); break;
+ case NAME_QUERY_FIND_MST : DEBUG(4,("NAME_QUERY_FIND_MST\n")); break;
+ case NAME_QUERY_MST_CHK : DEBUG(4,("NAME_QUERY_MST_CHK\n")); break;
+ case NAME_QUERY_CONFIRM : DEBUG(4,("NAME_QUERY_CONFIRM\n")); break;
+ case NAME_QUERY_SYNC_LOCAL : DEBUG(4,("NAME_QUERY_SYNC_LOCAL\n")); break;
+ case NAME_QUERY_SYNC_REMOTE : DEBUG(4,("NAME_QUERY_SYNC_REMOTE\n")); break;
+ case NAME_QUERY_ANNOUNCE_HOST: DEBUG(4,("NAME_QUERY_ANNCE_HOST\n"));break;
+
+ case NAME_REGISTER : DEBUG(4,("NAME_REGISTER\n")); break;
+ case NAME_REGISTER_CHALLENGE : DEBUG(4,("NAME_REGISTER_CHALLENGE\n"));break;
+
+ case NAME_RELEASE : DEBUG(4,("NAME_RELEASE\n")); break;
+
+ case NAME_STATUS_DOM_SRV_CHK : DEBUG(4,("NAME_STAT_MST_CHK\n")); break;
+ case NAME_STATUS_SRV_CHK : DEBUG(4,("NAME_STATUS_SRV_CHK\n")); break;
+
default: break;
}
}
@@ -512,7 +580,8 @@ static BOOL response_problem_check(struct response_record *n,
/* query for ^1^2__MSBROWSE__^2^1 expect lots of responses */
return False;
}
- case NAME_QUERY_PDC_SRV_CHK:
+ case NAME_QUERY_ANNOUNCE_HOST:
+ case NAME_QUERY_DOM_SRV_CHK:
case NAME_QUERY_SRV_CHK:
case NAME_QUERY_MST_CHK:
{
@@ -576,8 +645,10 @@ static BOOL response_compatible(struct response_record *n,
case NAME_REGISTER_CHALLENGE: /* this is a query: we then do a register */
case NAME_QUERY_CONFIRM:
- case NAME_QUERY_SYNC:
- case NAME_QUERY_PDC_SRV_CHK:
+ case NAME_QUERY_ANNOUNCE_HOST:
+ case NAME_QUERY_SYNC_LOCAL:
+ case NAME_QUERY_SYNC_REMOTE:
+ case NAME_QUERY_DOM_SRV_CHK:
case NAME_QUERY_SRV_CHK:
case NAME_QUERY_FIND_MST:
case NAME_QUERY_MST_CHK:
@@ -590,7 +661,7 @@ static BOOL response_compatible(struct response_record *n,
break;
}
- case NAME_STATUS_PDC_SRV_CHK:
+ case NAME_STATUS_DOM_SRV_CHK:
case NAME_STATUS_SRV_CHK:
{
if (nmb->answers->rr_type != NMB_STATUS)
@@ -638,7 +709,7 @@ static void response_process(struct subnet_record *d, struct packet_struct *p,
break;
}
- case NAME_QUERY_PDC_SRV_CHK:
+ case NAME_QUERY_DOM_SRV_CHK:
case NAME_QUERY_SRV_CHK:
case NAME_QUERY_FIND_MST:
{
@@ -646,15 +717,22 @@ static void response_process(struct subnet_record *d, struct packet_struct *p,
break;
}
- case NAME_STATUS_PDC_SRV_CHK:
+ case NAME_STATUS_DOM_SRV_CHK:
case NAME_STATUS_SRV_CHK:
{
response_name_status_check(p->ip, nmb, bcast, n, d);
break;
}
+ case NAME_QUERY_ANNOUNCE_HOST:
+ {
+ response_announce_host(ans_name, nmb, n, d);
+ break;
+ }
+
case NAME_QUERY_CONFIRM:
- case NAME_QUERY_SYNC:
+ case NAME_QUERY_SYNC_LOCAL:
+ case NAME_QUERY_SYNC_REMOTE:
{
response_name_query_sync(nmb, ans_name, bcast, n, d);
break;
@@ -702,7 +780,8 @@ void response_netbios_packet(struct packet_struct *p)
return;
}
- if (!same_net(d->bcast_ip, d->mask_ip, p->ip)) /* copes with WINS 'subnet' */
+ /* args wrong way round: spotted by ccm@shentel.net */
+ if (!same_net(d->bcast_ip, p->ip, d->mask_ip)) /* copes with WINS 'subnet' */
{
DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
DEBUG(2,("expected on subnet %s. hmm.\n", inet_ntoa(d->bcast_ip)));
diff --git a/source/namework.c b/source/namework.c
index 1a7a48aa9a7..74c567fa748 100644
--- a/source/namework.c
+++ b/source/namework.c
@@ -284,17 +284,12 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf)
tell_become_backup();
#endif
- /* XXXX over-kill: i don't think we should really be doing this,
- but it doesn't do much harm other than to add extra network
- traffic. to be more precise, we should (possibly) only
- sync browse lists with a host that sends an
- ANN_LocalMasterAnnouncement or an ANN_DomainAnnouncement.
- possibly.
- */
-
- /* 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);
+ /* get the local_only browse list from the local master and add it to ours. */
+ if (command == ANN_LocalMasterAnnouncement)
+ {
+ add_browser_entry(serv_name,dgram->dest_name.name_type,
+ work->work_group,30,ip,True);
+ }
}
/*******************************************************************
@@ -319,13 +314,13 @@ static void process_master_announce(struct packet_struct *p,char *buf)
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);
- }
+ add_browser_entry(name,0x1b, work->work_group,30,ip,True);
}
+ }
}
/*******************************************************************
@@ -394,7 +389,8 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf)
if (work->token == 0 /* token */)
{
queue_netbios_packet(d1,ClientNMB,NMB_QUERY,NAME_QUERY_SRV_CHK,
- work->work_group,0x1d,0,0,
+ work->work_group,0x1d,
+ 0,0,0,NULL,NULL,
False,False,back_ip,back_ip);
return;
}
diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c
index 10b356d9b50..e2a4bdeb67f 100644
--- a/source/nmbd/nmbd.c
+++ b/source/nmbd/nmbd.c
@@ -53,7 +53,6 @@ time_t StartupTime =0;
extern struct in_addr ipzero;
-
/****************************************************************************
catch a sigterm
****************************************************************************/
@@ -90,6 +89,8 @@ static int sig_hup(void)
dump_names();
reload_services(True);
+ set_samba_nb_type();
+
BlockSignals(False);
#ifndef DONT_REINSTALL_SIG
signal(SIGHUP,SIGNAL_CAST sig_hup);
@@ -524,6 +525,8 @@ static void usage(char *pname)
if (!reload_services(False))
return(-1);
+ set_samba_nb_type();
+
if (*group)
add_my_subnets(group);
diff --git a/source/nmbsync.c b/source/nmbsync.c
index de3d9e87331..2efb364bcae 100644
--- a/source/nmbsync.c
+++ b/source/nmbsync.c
@@ -136,8 +136,10 @@ static BOOL add_info(struct subnet_record *d, struct work_record *work, int serv
do a NetServerEnum and update our server and workgroup databases.
******************************************************************/
void sync_browse_lists(struct subnet_record *d, struct work_record *work,
- char *name, int nm_type, struct in_addr ip)
+ char *name, int nm_type, struct in_addr ip, BOOL local)
{
+ uint32 local_type = local ? SV_TYPE_LOCAL_LIST_ONLY : 0;
+
if (!d || !work || !AM_MASTER(work)) return;
pid = getpid();
@@ -169,8 +171,9 @@ void sync_browse_lists(struct subnet_record *d, struct work_record *work,
{
if (cli_send_login(NULL,NULL,True,True))
{
- add_info(d, work, SV_TYPE_DOMAIN_ENUM);
- add_info(d, work, SV_TYPE_ALL&~SV_TYPE_DOMAIN_ENUM);
+ add_info(d, work, local_type|SV_TYPE_DOMAIN_ENUM);
+ add_info(d, work, local_type|(SV_TYPE_ALL&
+ ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY)));
}
close_sockets();
diff --git a/source/utils/nmblookup.c b/source/utils/nmblookup.c
index a543b90762f..292b526df93 100644
--- a/source/utils/nmblookup.c
+++ b/source/utils/nmblookup.c
@@ -49,7 +49,7 @@ static BOOL open_sockets(void)
return False;
}
- ServerFD = open_socket_in(SOCK_DGRAM, NMB_PORT,3);
+ ServerFD = open_socket_in(SOCK_DGRAM, 0,3);
if (ServerFD == -1)
return(False);
@@ -151,7 +151,7 @@ int main(int argc,char *argv[])
for (i=optind;i<argc;i++)
- {
+ {
BOOL bcast = True;
int retries = 2;
char *p;
@@ -177,20 +177,18 @@ int main(int argc,char *argv[])
retries = 1;
}
- if (name_query(ServerFD,lookup,lookup_type,bcast,True,
+ if (name_query(ServerFD,lookup,lookup_type,bcast,True,
*iface_bcast(ipzero),&ip,NULL))
{
printf("%s %s\n",inet_ntoa(ip),lookup);
- if (find_status)
- {
+ }
+ if (find_status)
+ {
printf("Looking up status of %s\n",inet_ntoa(ip));
name_status(ServerFD,lookup,lookup_type,True,ip,NULL,NULL,NULL);
printf("\n");
- }
- } else {
- printf("couldn't find name %s\n",lookup);
- }
- }
+ }
+ }
return(0);
}