[Samba] Hostname DNS update (using nsupdate-gss) to Active Directory DNS using Sites

Dag Wieers dag at wieers.com
Wed Aug 1 14:23:49 GMT 2007


Hi,

We were unable to use nsupdate-gss to a Windows 2003 Active Directory. I 
modified the nsupdate-gss script to use the local Domain Controller to do 
the DNS update and then it works (albeit giving a TKEY integrity error).

The patch attached adds a 5th argument to the command line to specify the 
local Domain Controller to send the DNS update to.

	Usage: nsupdate-gss.pl HOST DOMAIN IP TTL [NS]

Here is the example output when it fails:

----
	[root at rhun root]# nsupdate-gss rhun REALM.DOM 1.2.3.4 3600
	Found 93 nameserver(s)
	Using DNS server name somedc.REALM.DOM
	creds acquired
	init done
	calling RR new
	init_sec_context step 2: Unspecified GSS failure.  Minor code may provide more information
	Message stream modified

	Failed to negotiate a TKEY
----

And this is shown when it works (using the extra argument):

----
	[root at rhun redhat]# nsupdate-gss rhun REALM.DOM 1.2.3.4 3600 localdc.REALM.DOM
	Found 1 nameserver(s)
	Using DNS server name localdc.REALM.DOM
	creds acquired
	init done
	calling RR new
	verifying
	calling sig_data
	Use of uninitialized value in pack at /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/Net/DNS/RR/TKEY.pm line 104.
	sig_data_done
	Failed to verify TKEY reply: A token had an invalid Message Integrity Check (MIC)
	No error

	verifying done
	Negotiated TKEY 9019541380429
	Update gave rcode NOERROR
 ----

(Beware IANAADE: I Am Not an Active Directory Expert)

Apparently with Active Directory and Sites and Services enabled you can 
not just update using any Domain Controller but instead you need to use 
the local one. Apparently there is a mapping between routes and "Sites" 
that contain local DCs and only these allow to updates the DNS.

As a result the normal nsupdate-gss fails. I've tested with Samba 3.0.25b 
as well and that fails too, most likely because it tries one out of the 93 
Domain Controllers we have.

I've tried to look into finding who my local DCs are from DNS information, 
but as far as I can see there is no query to link the local route with a 
"Site".

I was wondering of someone knows exactly how this is supposed to work ? 

How can we register the hostname with Active Directory DNS ? And how can 
we make this information persistent ? (ie. if DHCP provides a new IP, 
update the DNS accordingly)

I also fail to see how the Kerberos credentials can be persistent for this 
functionality to work without someone providing a user password. Even an 
ADS join requires a password every time again.

Is there anyone with a clue ? Or is there any documentation I failed to 
Google for ?

Thanks in advance :)

--   dag wieers,  dag at wieers.com,  http://dag.wieers.com/   --
[Any errors in spelling, tact or fact are transmission errors]
-------------- next part --------------
--- /usr/src/redhat/SOURCES/nsupdate-gss	2006-01-23 06:35:10.000000000 +0100
+++ /usr/bin/nsupdate-gss	2007-08-01 13:28:39.000000000 +0200
@@ -5,6 +5,9 @@
 # jmruiz at animatika.net
 # updated, 2004-Enero
 
+# dag at wieers.com
+# updated, 2007-EMC
+
 
 # See draft-ietf-dnsext-gss-tsig-02, RFC2845 and RFC2930
 
@@ -20,9 +23,9 @@
 
 # Integrity of the arguments
 
-if ($#ARGV != 3) {
+if ($#ARGV < 3) {
     print "
-Usage: nsupdate-gss.pl HOST DOMAIN IP TTL
+Usage: nsupdate-gss.pl HOST DOMAIN IP TTL [NS]
 ";
     exit 1;
 }
@@ -35,6 +38,7 @@
 my $ip = $ARGV[2];
 my $ttl = $ARGV[3];
 my $alg = "gss.microsoft.com";
+my $ns = $ARGV[4] if ($#ARGV >= 4);
 
 
 
@@ -229,7 +233,11 @@
 # find the nameservers
 my $nameserver = find_nameservers("$domain.");
 
-print "Found nameserver $nameserver\n";
+$nameserver->nameservers("$ns") if (defined($ns));
+#print $nameserver->print;
+
+#print "Found nameserver $nameserver\n";
+print "Found ".$nameserver->nameservers." nameserver(s)\n";
 
 if (!defined($nameserver) || $nameserver->{'errorstring'} ne 'NOERROR') {
     print "Failed to find a nameserver for domain $domain\n";
@@ -238,6 +246,8 @@
 
 # find the name of the DNS server
 my $server_name = find_server_name($domain);
+$server_name = $ns if (defined($ns));
+
 if (!defined($server_name)) {
     print "Failed to find a DNS server name for $domain\n";
     exit 1;


More information about the samba mailing list