From 3ffb30e8be5bcddca9d0489e1993085a4995c3af Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Thu, 1 Aug 1996 17:49:40 +0000 Subject: local_only NetServerEnum syncs can now be issued. bug spotted in nameservresp.c - arguments to test subnet the response is received on (same_net()) were the wrong way round (ccm@shentel.net) samba was adding WORKGROUP(1e) as a unique not a group name: fixed this bug in reply_name_status() and reply_name_query(): WINS entries weren't being looked up. name status reply adds local SELF entries to WINS SELF entries: some SELF entries are only added locally, while others are only added via WINS. name status needs to have both, combined. a sync will only occur when an ANN_LocalMasterAnnouncement is received, NOT an ANN_HostAnnouncement or an ANN_DomainAnnouncement. when samba is a member of a workgroup, it looks for (using a wins server) and announces to its domain master. NAME_QUERY_ANNOUNCE_HOST - yet another 'state' - has been created to do this: do the name query on the wins server and send the announce host to the answer to this query. jeremy @ vantive wrote the original code to do this, which used the name_query() function. i'm trying to avoid name_query: it times out and generally messes things up, but using queue_netbios_packet() and queue_netbios_pkt_wins() is... not intuitive? lkcl with help from jra (This used to be commit 6e932e4bae8b46e7ff4a55a75484bad78308336a) --- source3/include/nameserv.h | 25 ++++++--- source3/include/proto.h | 20 +++++-- source3/libsmb/namequery.c | 14 ++--- source3/nameannounce.c | 137 +++++++++++++++++++++++++++++---------------- source3/namebrowse.c | 8 ++- source3/namedbname.c | 23 +++++++- source3/namedbresp.c | 4 ++ source3/namedbsubnet.c | 7 ++- source3/namedbwork.c | 2 +- source3/nameelect.c | 11 ++-- source3/nameresp.c | 8 ++- source3/nameserv.c | 27 ++++----- source3/nameservreply.c | 103 ++++++++++++++++++++-------------- source3/nameservresp.c | 133 ++++++++++++++++++++++++++++++++++--------- source3/namework.c | 28 ++++----- source3/nmbd/nmbd.c | 5 +- source3/nmbsync.c | 9 ++- source3/utils/nmblookup.c | 18 +++--- 18 files changed, 387 insertions(+), 195 deletions(-) (limited to 'source3') diff --git a/source3/include/nameserv.h b/source3/include/nameserv.h index 7a97097e78..582378e183 100644 --- a/source3/include/nameserv.h +++ b/source3/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/source3/include/proto.h b/source3/include/proto.h index 60b8eed59a..10f2bc3325 100644 --- a/source3/include/proto.h +++ b/source3/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/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 5480913001..21d3bd1e50 100644 --- a/source3/libsmb/namequery.c +++ b/source3/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," "); if (p[0] & 0x08) strcat(flags," "); if (p[0] & 0x04) strcat(flags," "); @@ -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/source3/nameannounce.c b/source3/nameannounce.c index 4801f9e0bd..c76dffda00 100644 --- a/source3/nameannounce.c +++ b/source3/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/source3/namebrowse.c b/source3/namebrowse.c index e62aa1ec6d..b426bc7a15 100644 --- a/source3/namebrowse.c +++ b/source3/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/source3/namedbname.c b/source3/namedbname.c index 37a9fe9c31..177c36fc07 100644 --- a/source3/namedbname.c +++ b/source3/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/source3/namedbresp.c b/source3/namedbresp.c index c453d9bbec..d89bfe8ae8 100644 --- a/source3/namedbresp.c +++ b/source3/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/source3/namedbsubnet.c b/source3/namedbsubnet.c index a259f25393..5c683e5e49 100644 --- a/source3/namedbsubnet.c +++ b/source3/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/source3/namedbwork.c b/source3/namedbwork.c index 13dde54b22..200132304b 100644 --- a/source3/namedbwork.c +++ b/source3/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/source3/nameelect.c b/source3/nameelect.c index 1095f8a7fa..8c93de03a8 100644 --- a/source3/nameelect.c +++ b/source3/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/source3/nameresp.c b/source3/nameresp.c index 0f76323df0..7fcb41e79f 100644 --- a/source3/nameresp.c +++ b/source3/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/source3/nameserv.c b/source3/nameserv.c index 93cc597415..da1480961f 100644 --- a/source3/nameserv.c +++ b/source3/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/source3/nameservreply.c b/source3/nameservreply.c index 84b9277d60..5b45e88c5e 100644 --- a/source3/nameservreply.c +++ b/source3/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/source3/nameservresp.c b/source3/nameservresp.c index 46acc2b992..a4cda7cdfb 100644 --- a/source3/nameservresp.c +++ b/source3/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," "); } if (NAME_CONFLICT (nb_flags)) { strcat(flags," "); add=True;} if (NAME_ACTIVE (nb_flags)) { strcat(flags," "); 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/source3/namework.c b/source3/namework.c index 1a7a48aa9a..74c567fa74 100644 --- a/source3/namework.c +++ b/source3/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/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index 10b356d9b5..e2a4bdeb67 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/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/source3/nmbsync.c b/source3/nmbsync.c index de3d9e8733..2efb364bca 100644 --- a/source3/nmbsync.c +++ b/source3/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/source3/utils/nmblookup.c b/source3/utils/nmblookup.c index a543b90762..292b526df9 100644 --- a/source3/utils/nmblookup.c +++ b/source3/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