summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/nameserv.h3
-rw-r--r--source3/nameresp.c28
-rw-r--r--source3/nameserv.c44
3 files changed, 68 insertions, 7 deletions
diff --git a/source3/include/nameserv.h b/source3/include/nameserv.h
index 75461ce5e6..027931f9e6 100644
--- a/source3/include/nameserv.h
+++ b/source3/include/nameserv.h
@@ -123,7 +123,8 @@ enum state_type
NAME_QUERY_DOM_SRV_CHK,
NAME_QUERY_SRV_CHK,
NAME_QUERY_FIND_MST,
- NAME_QUERY_MST_CHK
+ NAME_QUERY_MST_CHK,
+ NAME_QUERY_DOMAIN,
};
/* a netbios name structure */
diff --git a/source3/nameresp.c b/source3/nameresp.c
index 949bb366bb..77addc2985 100644
--- a/source3/nameresp.c
+++ b/source3/nameresp.c
@@ -160,6 +160,34 @@ static void dead_netbios_entry(struct subnet_record *d,
break;
}
+ case NAME_QUERY_DOMAIN:
+ {
+ /* if no response received, there is no domain controller on
+ this local subnet. it's ok for us to register
+ */
+
+ if (!n->bcast)
+ {
+ DEBUG(0,("NAME_QUERY_DOMAIN incorrectly used - contact samba-bugs!\n"));
+ /* XXXX whoops. someone's using this to unicast a packet. this state
+ should only be used for broadcast checks
+ */
+ break;
+ }
+ if (n->num_msgs == 0)
+ {
+ if (ismyip(n->send_ip))
+ {
+ struct work_record *work = find_workgroupstruct(d,n->name.name,False);
+ if (work && d)
+ {
+ become_domain_master(d,work);
+ }
+ }
+ }
+ break;
+ }
+
default:
{
/* nothing to do but delete the dead expected-response structure */
diff --git a/source3/nameserv.c b/source3/nameserv.c
index 7f1c0fadee..77c3906242 100644
--- a/source3/nameserv.c
+++ b/source3/nameserv.c
@@ -80,14 +80,18 @@ void remove_name_entry(struct subnet_record *d, char *name,int type)
don't really own */
remove_netbios_name(d,name,type,SELF,n2->ip_flgs[0].ip);
- if (ip_equal(d->bcast_ip, ipgrp)) {
- if (!lp_wins_support()) {
+ if (ip_equal(d->bcast_ip, ipgrp))
+ {
+ if (!lp_wins_support())
+ {
/* not a WINS server: we have to release them on the network */
queue_netbios_pkt_wins(d,ClientNMB,NMB_REL,NAME_RELEASE,
name, type, 0, 0,0,NULL,NULL,
False, True, ipzero, ipzero);
}
- } else {
+ }
+ else
+ {
/* local interface: release them on the network */
queue_netbios_packet(d,ClientNMB,NMB_REL,NAME_RELEASE,
name, type, 0, 0,0,NULL,NULL,
@@ -181,19 +185,47 @@ void add_domain_names(time_t t)
make_nmb_name(&n,lp_workgroup(),0x1c,scope);
if (!find_name(d->namelist, &n, FIND_SELF))
{
+ /* logon servers are group names - we don't expect this to fail. */
DEBUG(0,("%s attempting to become logon server for %s %s\n",
timestring(), lp_workgroup(), inet_ntoa(d->bcast_ip)));
become_logon_server(d, work);
}
}
+
if (lp_domain_master() && work && work->dom_state == DOMAIN_NONE)
{
make_nmb_name(&n,lp_workgroup(),0x1b,scope);
if (!find_name(d->namelist, &n, FIND_SELF))
{
- DEBUG(1,("%s attempting to become logon server for %s %s\n",
- timestring(), lp_workgroup(), inet_ntoa(d->bcast_ip)));
- become_domain_master(d, work);
+ if (ip_equal(d->bcast_ip,ipgrp))
+ {
+ if (lp_wins_support())
+ {
+ /* use the wins server's capabilities (indirectly). if
+ someone has already register 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 logon server for %s %s\n",
+ timestring(), lp_workgroup(), inet_ntoa(d->bcast_ip)));
+ become_domain_master(d, work);
+ }
+ }
+ else
+ {
+ /* send out a query to establish whether there's a
+ domain controller on the local subnet. if not,
+ we can become a domain controller on that subnet.
+ it's only polite that we check, before claiming the
+ NetBIOS name 0x1b.
+ */
+
+ queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_DOMAIN,
+ lp_workgroup(), 0x1b,
+ 0, 0,0,NULL,NULL,
+ True, True, d->bcast_ip, d->bcast_ip);
+ }
}
}
}