From 3ab97ebe6db1a5a4a0573c7c8482c94876bbce9a Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Fri, 30 May 1997 20:40:48 +0000 Subject: charcnv.c: Fixed silly bugs detected on IRIX. client.c: Fixed silly bugs detected on IRIX. namedbname.c: Stopped 1d names from being registered in WINS db. namedbsubnet.c: Only register 1e names on broadcast subnet. nameelect.c: Changed add_my_name entries. Forced host announces if we have less than 10 servers listed. Fixed registering 1b domain name issues. namepacket.c: Added error message when dgram discarded. nameserv.c: Added notion of 'direct' names that are not registered on the network. Needed to get around bugs in earlier nmbd handling of DOMAIN(1b) names. nameservreply.c:Tidied up debug message. nameservresp.c: Added response_name_query_domain() code. Deals with re-registering DOMAIN(1b) name. nmbd.c: Fixed silly bugs detected on IRIX. nmblib.c: Added paranoia debugs. proto.h: Updated remove_name_entry(), add_my_name_entry(). server.c: Fixed silly bugs detected on IRIX. trans2.c: Fixed silly bugs detected on IRIX. uid.c: Fixed silly bugs detected on IRIX. version.h: Updated to alpha3. Jeremy (jallison@whistle.com). (This used to be commit f08222bd8b86a061c52d22015f946a4737eb47fd) --- source3/client/client.c | 2 +- source3/include/proto.h | 4 +- source3/include/version.h | 2 +- source3/lib/charcnv.c | 4 +- source3/libsmb/nmblib.c | 5 ++ source3/namedbname.c | 11 ++- source3/namedbsubnet.c | 11 ++- source3/nameelect.c | 183 +++++++++++++++++++++++++--------------------- source3/namepacket.c | 16 +++- source3/nameserv.c | 124 +++++++++++++++++++------------ source3/nameservreply.c | 2 +- source3/nameservresp.c | 86 +++++++++++++++++++++- source3/nmbd/nmbd.c | 2 + source3/smbd/server.c | 2 +- source3/smbd/trans2.c | 1 - source3/smbd/uid.c | 3 +- 16 files changed, 305 insertions(+), 153 deletions(-) (limited to 'source3') diff --git a/source3/client/client.c b/source3/client/client.c index e023530cb5..32bbbae8cd 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -843,7 +843,7 @@ else { unsigned int offset = datap - converter; - if( offset < 0 || offset >= rdrcnt ) + if( offset >= rdrcnt ) { DEBUG(1,("bad char ptr: datap=%u, converter=%u, rdata=%u, rdrcnt=%d>", datap, converter, (unsigned)rdata, rdrcnt)); return ""; diff --git a/source3/include/proto.h b/source3/include/proto.h index 04202dd88c..e6d39c3a3f 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -481,8 +481,8 @@ struct response_record *queue_netbios_packet(struct subnet_record *d, /*The following definitions come from nameserv.c */ -void remove_name_entry(struct subnet_record *d, char *name,int type); -void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags); +void remove_name_entry(struct subnet_record *d, char *name,int type, BOOL direct); +void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags, BOOL direct); void add_domain_names(time_t t); void add_my_names(void); void remove_my_names(); diff --git a/source3/include/version.h b/source3/include/version.h index 2f7596f41d..37e26dd65e 100644 --- a/source3/include/version.h +++ b/source3/include/version.h @@ -1 +1 @@ -#define VERSION "1.9.17alpha2" +#define VERSION "1.9.17alpha3" diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index b6debbec4a..6be455c47b 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -25,7 +25,7 @@ extern int DEBUGLEVEL; static char cvtbuf[1024]; -static mapsinited = 0; +static BOOL mapsinited = 0; static char unix2dos[256]; static char dos2unix[256]; @@ -36,7 +36,7 @@ static void initmaps() { for (k = 0; k < 256; k++) unix2dos[k] = k; for (k = 0; k < 256; k++) dos2unix[k] = k; - mapsinited = 1; + mapsinited = True; } static void update_map(char * str) { diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 89a5cf9534..bc967bdacb 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -418,6 +418,9 @@ static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) /* parse the header */ nmb->header.name_trn_id = RSVAL(inbuf,0); + + DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id)); + nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF; nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False; nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4); @@ -521,6 +524,8 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) break; } if (!ok) { + DEBUG(10,("parse_nmb: discarding packet id = %d\n", + packet->packet.nmb.header.name_trn_id)); free(packet); return(NULL); } diff --git a/source3/namedbname.c b/source3/namedbname.c index aa41726450..5eb03bc637 100644 --- a/source3/namedbname.c +++ b/source3/namedbname.c @@ -419,7 +419,7 @@ struct name_record *add_netbios_entry(struct subnet_record *d, struct name_record *n2=NULL; struct subnet_record *found_subnet = 0; int search = 0; - BOOL self = source == SELF; + BOOL self = (source == SELF); /* add the name to the WINS list if the name comes from a directed query */ search |= wins ? FIND_WINS : FIND_LOCAL; @@ -434,12 +434,19 @@ struct name_record *add_netbios_entry(struct subnet_record *d, if (!self) { - if (!wins && type != 0x1b) + if (!wins && (type != 0x1b)) { /* the only broadcast (non-WINS) names we are adding are ours (SELF) and Domain Master type names */ return NULL; } + if(wins && (type == 0x1d)) + { + /* Do not allow any 0x1d names to be registered in a WINS, + database although we return success for them. + */ + return NULL; + } } n = (struct name_record *)malloc(sizeof(*n)); diff --git a/source3/namedbsubnet.c b/source3/namedbsubnet.c index 393db363d8..ab1f133dd4 100644 --- a/source3/namedbsubnet.c +++ b/source3/namedbsubnet.c @@ -209,13 +209,16 @@ void add_workgroup_to_subnet( struct subnet_record *d, char *group) return; } - /* add WORKGROUP(1e) and WORKGROUP(00) entries into name database - or register with WINS server, if it's our workgroup + /* add WORKGROUP(00) entries into name database + or register with WINS server, if it's our workgroup. + Don't register WORKGROUP(0x1e) on the WINS subnet - this is a broadcast + only name. */ if (strequal(myworkgroup, group)) { - add_my_name_entry(d,group,0x1e,nb_type|NB_ACTIVE|NB_GROUP); - add_my_name_entry(d,group,0x0 ,nb_type|NB_ACTIVE|NB_GROUP); + add_my_name_entry(d,group,0x0 ,nb_type|NB_ACTIVE|NB_GROUP,False); + if((d != wins_subnet)) + add_my_name_entry(d,group,0x1e,nb_type|NB_ACTIVE|NB_GROUP,False); /* add samba server name to workgroup list. */ add_server_entry(d,w,myname,w->ServerType,0,lp_serverstring(),True); DEBUG(3,("add_workgroup_to_subnet: Added server name entry %s to subnet %s\n", diff --git a/source3/nameelect.c b/source3/nameelect.c index b3251d8da6..752e27fb07 100644 --- a/source3/nameelect.c +++ b/source3/nameelect.c @@ -325,6 +325,12 @@ void become_local_master(struct subnet_record *d, struct work_record *work) if (!work || !d) return; + if (!lp_local_master()) + { + DEBUG(0,("Samba not configured as a local master browser.\n")); + return; + } + DEBUG(2,("Becoming master for %s %s (currently at stage %d)\n", work->work_group,inet_ntoa(d->bcast_ip),work->mst_state)); @@ -342,7 +348,7 @@ void become_local_master(struct subnet_record *d, struct work_record *work) add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True); /* add special browser name */ - add_my_name_entry(d,MSBROWSE,0x01,nb_type|NB_ACTIVE|NB_GROUP); + add_my_name_entry(d,MSBROWSE,0x01,nb_type|NB_ACTIVE|NB_GROUP,False); /* DON'T do anything else after calling add_my_name_entry() */ break; @@ -357,7 +363,7 @@ void become_local_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_type|NB_ACTIVE); + add_my_name_entry(d,work->work_group,0x1d,nb_type|NB_ACTIVE,False); /* DON'T do anything else after calling add_my_name_entry() */ break; @@ -365,7 +371,11 @@ void become_local_master(struct subnet_record *d, struct work_record *work) case MST_MSB: /* while we were still only registered MSBROWSE state... */ { - DEBUG(3,("2nd stage complete: registered as master browser\n")); + int i = 0; + struct server_record *sl; + + DEBUG(3,("2nd stage complete: registered as master browser for workgroup %s \ +on subnet %s\n", work->work_group, inet_ntoa(d->bcast_ip))); work->mst_state = MST_BROWSER; /* registering WORKGROUP(1d) succeeded */ /* update our server status */ @@ -376,10 +386,16 @@ void become_local_master(struct subnet_record *d, struct work_record *work) add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True); - if (work->serverlist == NULL) /* no servers! */ + /* Count the number of servers we have on our list. If it's + less than 10 (just a heuristic) request the servers + to announce themselves. + */ + for( sl = work->serverlist; sl != NULL; sl = sl->next) + i++; + + if (i < 10) { /* ask all servers on our local net to announce to us */ - /* XXXX OOPS! add_server_entry always adds one entry - ours. */ announce_request(work, d->bcast_ip); } @@ -428,56 +444,59 @@ void become_domain_master(struct subnet_record *d, struct work_record *work) */ if (!work || !d) return; - + + if (!lp_domain_master()) + { + DEBUG(0,("Samba not configured as a domain master browser.\n")); + return; + } + DEBUG(2,("Becoming domain master for %s %s (currently at stage %d)\n", - work->work_group,inet_ntoa(d->bcast_ip),work->dom_state)); + work->work_group,inet_ntoa(d->bcast_ip),work->dom_state)); switch (work->dom_state) { case DOMAIN_NONE: /* while we were nothing but a server... */ { - if (lp_domain_master()) - { - DEBUG(3,("go to first stage: register <1b> name\n")); - work->dom_state = DOMAIN_WAIT; - - /* XXXX the 0x1b is domain master browser name */ - add_my_name_entry(d, work->work_group,0x1b,nb_type|NB_ACTIVE|NB_GROUP); - - /* DON'T do anything else after calling add_my_name_entry() */ - break; - } + DEBUG(3,("become_domain_master: go to first stage: register <1b> name\n")); + work->dom_state = DOMAIN_WAIT; + + /* Registering the DOMAIN<1b> name is very tricky. We need to + do this on all our subnets, but don't want to bradcast it + on locally connected subnets (WinNT doesn't do this). Also, + previous versions of Samba screw up royally when we do this. + We need to register it immediatly on our local subnet, but + also actually check with the WINS server if it exists. If the name + has already been claimed by someone else in the WINS server + then we need to back out all our local registrations and + fail. Thus we only directly enter the name on local subnets, + on the WINS subnet we actually check... + */ + /* XXXX the 0x1b is domain master browser name */ + if(d == wins_subnet) + add_my_name_entry(d, work->work_group,0x1b,nb_type|NB_ACTIVE,False); else - { - DEBUG(4,("samba not configured as a domain master.\n")); - } - + add_my_name_entry(d, work->work_group,0x1b,nb_type|NB_ACTIVE,True); + + /* DON'T do anything else after calling add_my_name_entry() */ break; } - case DOMAIN_WAIT: - { - if (lp_domain_master()) - { - work->dom_state = DOMAIN_MST; /* ... become domain master */ - DEBUG(3,("domain first stage: register as domain member\n")); + case DOMAIN_WAIT: + { + work->dom_state = DOMAIN_MST; /* ... become domain master */ + DEBUG(3,("become_domain_master: first stage - register as domain member\n")); - /* update our server status */ - work->ServerType |= SV_TYPE_NT|SV_TYPE_DOMAIN_MASTER; - add_server_entry(d,work,myname,work->ServerType,0, - lp_serverstring(),True); + /* update our server status */ + work->ServerType |= SV_TYPE_NT|SV_TYPE_DOMAIN_MASTER; + add_server_entry(d,work,myname,work->ServerType,0, + lp_serverstring(),True); - DEBUG(4,("samba is now a domain master\n")); + DEBUG(4,("Samba is now a domain master browser for workgroup %s on subnet %s\n", + work->work_group, inet_ntoa(d->bcast_ip))); - break; - } - else - { - DEBUG(4,("samba not configured as a domain master.\n")); - } - break; - } + } case DOMAIN_MST: { @@ -496,60 +515,48 @@ void become_logon_server(struct subnet_record *d, struct work_record *work) { if (!work || !d) return; + if (lp_domain_logons()) + { + DEBUG(0,("samba not configured as a logon master.\n")); + return; + } + DEBUG(2,("Becoming logon server for %s %s (currently at stage %d)\n", - work->work_group,inet_ntoa(d->bcast_ip),work->log_state)); + work->work_group,inet_ntoa(d->bcast_ip),work->log_state)); switch (work->log_state) { case LOGON_NONE: /* while we were nothing but a server... */ { - if (lp_domain_logons()) - { - DEBUG(3,("go to first stage: register <1c> name\n")); - work->log_state = LOGON_WAIT; + DEBUG(3,("go to first stage: register <1c> name\n")); + work->log_state = LOGON_WAIT; - /* XXXX the 0x1c is apparently something to do with domain logons */ - add_my_name_entry(d, myworkgroup,0x1c,nb_type|NB_ACTIVE|NB_GROUP); + /* XXXX the 0x1c is apparently something to do with domain logons */ + add_my_name_entry(d, myworkgroup,0x1c,nb_type|NB_ACTIVE|NB_GROUP,False); - /* DON'T do anything else after calling add_my_name_entry() */ - break; - } - { - DEBUG(4,("samba not configured as a logon master.\n")); - } - + /* DON'T do anything else after calling add_my_name_entry() */ break; } - case LOGON_WAIT: - { - if (lp_domain_logons()) - { - work->log_state = LOGON_SRV; /* ... become logon server */ - DEBUG(3,("logon second stage: register \n")); + case LOGON_WAIT: + { + work->log_state = LOGON_SRV; /* ... become logon server */ + DEBUG(3,("logon second stage: register \n")); - /* update our server status */ - work->ServerType |= SV_TYPE_NT|SV_TYPE_DOMAIN_MEMBER; - add_server_entry(d,work,myname,work->ServerType,0, - lp_serverstring(),True); + /* update our server status */ + work->ServerType |= SV_TYPE_NT|SV_TYPE_DOMAIN_MEMBER; + add_server_entry(d,work,myname,work->ServerType,0, + lp_serverstring(),True); - /* DON'T do anything else after calling add_my_name_entry() */ - break; - } - else - { - DEBUG(4,("samba not configured as a logon server.\n")); - } - + /* DON'T do anything else after calling add_my_name_entry() */ break; - } + } - case LOGON_SRV: - { + case LOGON_SRV: + { DEBUG(3,("logon third stage: there isn't one!\n")); break; - } - + } } } @@ -584,8 +591,8 @@ void unbecome_local_master(struct subnet_record *d, struct work_record *work, /* announce ourselves as no longer active as a master browser. */ announce_server(d, work, work->work_group, myname, 0, 0); - remove_name_entry(d,MSBROWSE ,0x01); - remove_name_entry(d,work->work_group,0x1d); + remove_name_entry(d,MSBROWSE ,0x01,False); + remove_name_entry(d,work->work_group,0x1d,False); } } @@ -612,9 +619,17 @@ void unbecome_domain_master(struct subnet_record *d, struct work_record *work, work->dom_state = DOMAIN_NONE; - /* announce ourselves as no longer active as a master browser. */ - announce_server(d, work, work->work_group, myname, 0, 0); - remove_name_entry(d,work->work_group,0x1b); + /* announce ourselves as no longer active as a master browser on + all our local subnets. */ + for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d)) + { + work = find_workgroupstruct(d, myworkgroup, False); + + announce_server(d, work, work->work_group, myname, 0, 0); + /* Remove the name entry without any NetBIOS traffic as that's + how it was registered. */ + remove_name_entry(d,work->work_group,0x1b,True); + } } } @@ -643,7 +658,7 @@ void unbecome_logon_server(struct subnet_record *d, struct work_record *work, /* announce ourselves as no longer active as a master browser. */ announce_server(d, work, work->work_group, myname, 0, 0); - remove_name_entry(d,work->work_group,0x1c); + remove_name_entry(d,work->work_group,0x1c,False); } } diff --git a/source3/namepacket.c b/source3/namepacket.c index c9db43dcc5..31cad92791 100644 --- a/source3/namepacket.c +++ b/source3/namepacket.c @@ -324,7 +324,7 @@ static BOOL listening(struct packet_struct *p,struct nmb_name *n) struct name_record *n1; /* We explicitly don't search WINS here - this will be done - in find_name_search is it was a packet from a non-local subnet. */ + in find_name_search if it was a packet from a non-local subnet. */ d = find_subnet(p->ip); n1 = find_name_search(&d,n,FIND_LOCAL|FIND_WINS|FIND_SELF,p->ip); @@ -345,13 +345,21 @@ static void process_dgram(struct packet_struct *p) /* if we aren't listening to the destination name then ignore the packet */ if (!listening(p,&dgram->dest_name)) + { + DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s(%x) from %s\n", + dgram->dest_name.name, dgram->dest_name.name_type, inet_ntoa(p->ip))); return; - + } if (dgram->header.msg_type != 0x10 && dgram->header.msg_type != 0x11 && - dgram->header.msg_type != 0x12) { + dgram->header.msg_type != 0x12) + { /* don't process error packets etc yet */ + DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s(%d) from %s as it is \ + an error packet of type %x\n", + dgram->dest_name.name, dgram->dest_name.name_type, + inet_ntoa(p->ip), dgram->header.msg_type)); return; } @@ -364,7 +372,7 @@ static void process_dgram(struct packet_struct *p) len = SVAL(buf,smb_vwv11); buf2 = smb_base(buf) + SVAL(buf,smb_vwv12); - DEBUG(4,("datagram from %s to %s for %s of type %d len=%d\n", + DEBUG(4,("process_dgram: datagram from %s to %s for %s of type %d len=%d\n", namestr(&dgram->source_name),namestr(&dgram->dest_name), smb_buf(buf),CVAL(buf2,0),len)); diff --git a/source3/nameserv.c b/source3/nameserv.c index 9163642896..93111eb268 100644 --- a/source3/nameserv.c +++ b/source3/nameserv.c @@ -51,8 +51,12 @@ extern uint16 nb_type; /* samba's NetBIOS type */ note: the name will _always_ be removed XXXX at present, the name is removed _even_ if a WINS server says keep it. + If direct is True then the name being removed must have been a direct name + add. This is done for special names such as DOMAIN<1b>. Just delete it + without any network release traffic. + ****************************************************************************/ -void remove_name_entry(struct subnet_record *d, char *name,int type) +void remove_name_entry(struct subnet_record *d, char *name,int type, BOOL direct) { /* XXXX BUG: if samba is offering WINS support, it should still broadcast a de-registration packet to the local subnet before removing the @@ -83,7 +87,7 @@ void remove_name_entry(struct subnet_record *d, char *name,int type) if (ip_equal(d->bcast_ip, wins_ip)) { - if (!lp_wins_support()) + if (!lp_wins_support() && !direct) { /* not a WINS server: we have to release them on the network */ queue_netbios_pkt_wins(ClientNMB,NMB_REL,NAME_RELEASE, @@ -93,8 +97,9 @@ void remove_name_entry(struct subnet_record *d, char *name,int type) } else { - /* local interface: release them on the network */ - queue_netbios_packet(d,ClientNMB,NMB_REL,NAME_RELEASE, + if(!direct) + /* local interface: release them on the network */ + queue_netbios_packet(d,ClientNMB,NMB_REL,NAME_RELEASE, name, type, 0, 0,0,NULL,NULL, True, True, d->bcast_ip, d->bcast_ip); } @@ -103,12 +108,16 @@ void remove_name_entry(struct subnet_record *d, char *name,int type) /**************************************************************************** add an entry to the name list - + If the direct BOOL is set then no network traffic is done for the add - it + is just blasted into the subnet entry with a zero TTL - it will not + expire and has not been legitimately claimed. This is *only* done if + we are a WINS server or for a special name such as DOMAIN<1b>. + big note: our name will _always_ be added (if there are no objections). it's just a matter of when this will be done (e.g after a time-out). ****************************************************************************/ -void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags) +void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags, BOOL direct) { BOOL re_reg = False; struct nmb_name n; @@ -128,15 +137,14 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags) if (ip_equal(d->bcast_ip, wins_ip)) { - if (lp_wins_support()) + if (lp_wins_support() || direct) { /* we are a WINS server. */ - /* XXXX assume that if we are a WINS server that we are therefore - not pointing to another WINS server as well. this may later NOT - actually be true - */ - - DEBUG(4,("samba as WINS server adding: ")); + if(lp_wins_support()) + DEBUG(4,("add_my_name_entry: samba as WINS server adding: ")); + else + DEBUG(4,("add_my_name_entry: direct name entry : adding: ")); + /* this will call add_netbios_entry() */ name_register_work(d, name, type, nb_flags,0, ipzero, False); } @@ -154,11 +162,23 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags) } else { - /* broadcast the packet, but it comes from ipzero */ - queue_netbios_packet(d,ClientNMB, - re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER, - name, type, nb_flags, GET_TTL(0),0,NULL,NULL, - True, True, d->bcast_ip, ipzero); + if(direct) + { + /* Just enter the name to be the ip address of the subnet + via name_register_work to ensure all side effects are done. + */ + DEBUG(4,("add_my_name_entry: direct name entry : adding: ")); + /* this will call add_netbios_entry() */ + name_register_work(d, name, type, nb_flags,0, d->myip, False); + } + else + { + /* broadcast the packet, but it comes from ipzero */ + queue_netbios_packet(d,ClientNMB, + re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER, + name, type, nb_flags, GET_TTL(0),0,NULL,NULL, + True, True, d->bcast_ip, ipzero); + } } } @@ -210,34 +230,47 @@ void add_domain_names(time_t t) browser on workgroup %s %s\n", timestring(), myworkgroup, inet_ntoa(d->bcast_ip))); - if (lp_wins_support()) + if(d == wins_subnet) { - /* use the wins server's capabilities (indirectly). if - someone has already registered the domain<1b> name with - the WINS server, then the WINS server's job is to _check_ - that the owner still wants it, before giving it away. - */ + if (lp_wins_support()) + { + /* use the wins server's capabilities (indirectly). if + someone has already registered the domain<1b> name with + the WINS server, then the WINS server's job is to _check_ + that the owner still wants it, before giving it away. + */ - DEBUG(1,("%s initiating becoming domain master for %s\n", + DEBUG(1,("%s initiating becoming domain master for %s\n", timestring(), myworkgroup)); - become_domain_master(d, work); - } - else - { - /* send out a query to establish whether there's a - domain controller on the WINS subnet. if not, - we can become a domain controller. - it's only polite that we check, before claiming the - NetBIOS name 0x1b. - */ - - DEBUG(0,("add_domain_names:querying WINS for domain master \ + become_domain_master(d, work); + } + else + { + /* send out a query to establish whether there's a + domain controller on the WINS subnet. if not, + we can become a domain controller. + it's only polite that we check, before claiming the + NetBIOS name 0x1b. + */ + + DEBUG(0,("add_domain_names:querying WINS for domain master \ on workgroup %s\n", myworkgroup)); - queue_netbios_pkt_wins(ClientNMB,NMB_QUERY,NAME_QUERY_DOMAIN, - myworkgroup, 0x1b, + queue_netbios_pkt_wins(ClientNMB,NMB_QUERY,NAME_QUERY_DOMAIN, + myworkgroup, 0x1b, 0, 0,0,NULL,NULL, False, False, ipzero, ipzero); + } + } + else + { + DEBUG(0,("add_domain_names:querying subnet %s for domain master \ +on workgroup %s\n", inet_ntoa(d->bcast_ip), myworkgroup)); + queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_DOMAIN, + myworkgroup, 0x1b, + 0, 0,0,NULL,NULL, + True, False, + d->bcast_ip, d->bcast_ip); } } } @@ -261,10 +294,9 @@ void add_my_names(void) { BOOL wins = (lp_wins_support() && (d == wins_subnet)); - 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); + add_my_name_entry(d, myname,0x20,nb_type|NB_ACTIVE,False); + add_my_name_entry(d, myname,0x03,nb_type|NB_ACTIVE,False); + add_my_name_entry(d, myname,0x00,nb_type|NB_ACTIVE,False); /* these names are added permanently (ttl of zero) and will NOT be refreshed with the WINS server */ @@ -295,7 +327,7 @@ void remove_my_names() /* get all SELF names removed from the WINS server's database */ /* XXXX note: problem occurs if this removes the wrong one! */ - remove_name_entry(d,n->name.name, n->name.name_type); + remove_name_entry(d,n->name.name, n->name.name_type,False); } } } @@ -313,14 +345,14 @@ void refresh_my_names(time_t t) { struct name_record *n; - for (n = d->namelist; n; n = n->next) + for (n = d->namelist; n; n = n->next) { /* each SELF name has an individual time to be refreshed */ if (n->source == SELF && n->refresh_time < t && n->death_time != 0) { add_my_name_entry(d,n->name.name,n->name.name_type, - n->ip_flgs[0].nb_flags); + n->ip_flgs[0].nb_flags,False); /* they get a new lease on life :-) */ n->death_time += GET_TTL(0); n->refresh_time += GET_TTL(0); diff --git a/source3/nameservreply.c b/source3/nameservreply.c index 00e940df67..a4888b04d4 100644 --- a/source3/nameservreply.c +++ b/source3/nameservreply.c @@ -195,7 +195,7 @@ void reply_name_reg(struct packet_struct *p) if (!(d = find_req_subnet(p->ip, bcast))) { - DEBUG(3,("response packet: bcast %s not known\n", + DEBUG(3,("reply_name_reg: subnet %s not known\n", inet_ntoa(p->ip))); return; } diff --git a/source3/nameservresp.c b/source3/nameservresp.c index 27356d95e6..226a997c5f 100644 --- a/source3/nameservresp.c +++ b/source3/nameservresp.c @@ -37,7 +37,11 @@ extern int ClientNMB; extern int DEBUGLEVEL; extern pstring scope; +extern fstring myworkgroup; extern struct in_addr ipzero; +extern struct in_addr wins_ip; +extern struct in_addr ipzero; + #define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl()) @@ -99,7 +103,20 @@ static void response_name_reg(struct nmb_name *ans_name, DEBUG(4,("response name registration received!\n")); +#if 1 + /* This code is neccesitated due to bugs in earlier versions of + Samba (up to 1.9.16p11). They respond to a broadcast + name registration of WORKGROUP<1b> when they should + not. Hence, until these versions are gone, we should + treat such errors as success for this particular + case only. jallison@whistle.com. + */ + if ( ((d != wins_subnet) && (nmb->header.rcode == 6) && strequal(myworkgroup, name) && + (type == 0x1b)) || + (nmb->header.rcode == 0 && nmb->answers->rdata)) +#else if (nmb->header.rcode == 0 && nmb->answers->rdata) +#endif { /* IMPORTANT: see expire_netbios_response_entries() */ @@ -489,6 +506,55 @@ static void response_name_query_sync(struct nmb_packet *nmb, } } +/**************************************************************************** + response from a name query for DOMAIN<1b> + NAME_QUERY_DOMAIN is dealt with here - we are trying to become a domain + master browser and WINS replied - check it's our address. + ****************************************************************************/ +static void response_name_query_domain(struct nmb_name *ans_name, + struct nmb_packet *nmb, + struct response_record *n, struct subnet_record *d) +{ + DEBUG(4, ("response_name_query_domain: Got %s response from %s for query \ +for %s\n", nmb->header.rcode == 0 ? "success" : "failure", + inet_ntoa(n->send_ip), namestr(ans_name))); + + /* Check the name is correct and ip address returned is our own. If it is then we + just remove the response record. + */ + if (name_equal(&n->name, ans_name) && (nmb->header.rcode == 0) && (nmb->answers->rdata)) + { + struct in_addr found_ip; + + putip((char*)&found_ip,&nmb->answers->rdata[2]); + /* Samba 1.9.16p11 servers seem to return the broadcast address for this + query. */ + if (ismyip(found_ip) || ip_equal(wins_ip, found_ip) || ip_equal(ipzero, found_ip)) + { + DEBUG(4, ("response_name_query_domain: WINS server returned our ip \ +address. Pretending we never received response.\n")); + n->num_msgs = 0; + n->repeat_count = 0; + n->repeat_time = 0; + } + else + { + DEBUG(0,("response_name_query_domain: WINS server already has a \ +domain master browser registered %s at address %s\n", + namestr(ans_name), inet_ntoa(found_ip))); + } + } + else + { + /* Negative/incorrect response. No domain master + browser was registered - pretend we didn't get this response. + */ + n->num_msgs = 0; + n->repeat_count = 0; + n->repeat_time = 0; + } + +} /**************************************************************************** report the response record type @@ -521,6 +587,7 @@ void debug_state_type(int state) 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_QUERY_DOMAIN : DEBUG(4,("NAME_QUERY_DOMAIN\n")); break; case NAME_REGISTER : DEBUG(4,("NAME_REGISTER\n")); break; case NAME_REGISTER_CHALLENGE : DEBUG(4,("NAME_REGISTER_CHALLENGE\n"));break; @@ -593,7 +660,7 @@ static BOOL response_problem_check(struct response_record *n, { case NAME_QUERY_FIND_MST: { - /* query for ^1^2__MSBROWSE__^2^1 expect + /* query for ^1^2__MSBROWSE__^2^1 expect lots of responses */ return False; } @@ -768,7 +835,22 @@ static void response_process(struct subnet_record *d, struct packet_struct *p, namestr(&n->name), inet_ntoa(n->send_ip))); break; } - + + case NAME_QUERY_DOMAIN: + { + /* We were asking to be a domain master browser, and someone + replied. If it was the WINS server and the IP it is + returning is our own - then remove the record and pretend + we didn't get a response. Else we do nothing and let + dead_netbios_entry deal with it. + We can only become domain master browser + when no broadcast responses are received and WINS + either contains no entry for the DOMAIN<1b> name or + contains our IP address. + */ + response_name_query_domain(ans_name, nmb, n, d); + break; + } default: { DEBUG(1,("unknown state type received in response_netbios_packet\n")); diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index 11f005b785..99d65d551a 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -73,6 +73,8 @@ static int sig_term() /* XXXX other things: if we are a master browser, force an election? */ exit(0); + /* Keep compiler happy.. */ + return 0; } diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 4ae139fc58..51710b7b77 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -1358,7 +1358,7 @@ BOOL check_file_sharing(int cnum,char *fname) if (old_shares[i].share_mode != DENY_DOS) goto free_and_exit; - if(old_shares[i].pid != pid); + if(old_shares[i].pid != pid) goto free_and_exit; } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 1d9977c66e..1f727c4ecd 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -941,7 +941,6 @@ static int call_trans2qfsinfo(char *inbuf, char *outbuf, int length, int bufsize DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n", strlen(vname), vname)); break; - break; case SMB_QUERY_FS_SIZE_INFO: { int dfree,dsize,bsize; diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index e2c5f590b7..7a903e0551 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -466,6 +466,5 @@ int smbrun(char *cmd,char *outfile,BOOL shared) /* not reached */ exit(82); #endif + return 1; } - - -- cgit