summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/client/client.c2
-rw-r--r--source3/include/proto.h4
-rw-r--r--source3/include/version.h2
-rw-r--r--source3/lib/charcnv.c4
-rw-r--r--source3/libsmb/nmblib.c5
-rw-r--r--source3/namedbname.c11
-rw-r--r--source3/namedbsubnet.c11
-rw-r--r--source3/nameelect.c183
-rw-r--r--source3/namepacket.c16
-rw-r--r--source3/nameserv.c124
-rw-r--r--source3/nameservreply.c2
-rw-r--r--source3/nameservresp.c86
-rw-r--r--source3/nmbd/nmbd.c2
-rw-r--r--source3/smbd/server.c2
-rw-r--r--source3/smbd/trans2.c1
-rw-r--r--source3/smbd/uid.c3
16 files changed, 305 insertions, 153 deletions
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 "<ERROR>";
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;
}
-
-