# From the book "Managing Enterprise Active Directory Services"
# ISBN: 0-672-32125-4
use strict;
use Net::DNS;
use Net::DNS::RR;
use Net::DNS::Packet;
use Win32::NetResource;
$|++;
# Need admin login privs on the DC
my $user = 'XYZ\administrator';
my $passwd = 'password';
my $domain = 'xyz.com';
# Location of netlogon.dns file using admin share ($) notation
my $rr_file = 'c$\winnt\system32\config\netlogon.dns';
# Step 1
my $res = Net::DNS::Resolver->new();
# Can point to an alternate DNS server
# to perform the RR lookups if needed
# $res->nameservers("dns-rtp.xyz.com");
print "Querying for Domain Controllers in $domain...\n";
my $dc_query = $res->search("_ldap._tcp.dc._msdcs.$domain", "SRV");
if ($dc_query) {
# Step 2
# Iterate through each DC
foreach my $rr ($dc_query->answer) {
my $dc = $rr->target;
print "\n $dc:\n";
# Create an IPC connection to the DC so we can access
# the netlogon.dns file
my %conn_info = (Type => RESOURCETYPE_ANY,
RemoteName => "\\\\$dc\\IPC\$");
my $ret = Win32::NetResource::AddConnection(\%conn_info,
$passwd,$user,0);
unless ($ret) {
print " Could not add IPC connection to $dc: $^E\n";
next;
}
# Step 3
my $found = 0;
my $not_found = 0;
unless ( open (RR, "\\\\$dc\\$rr_file") ) {
print " Could not open netlogon.dns file: $!\n";
next;
}
# Iterate through each line of the netlogon.dns file
while (my $rr_entry = <RR>) {
chomp $rr_entry;
next if $rr_entry =~ /^\s*$/; # skip blank lines
# Step 4
# Query DNS for the RR
my $rrObj = Net::DNS::RR->new($rr_entry);
my $query = $res->send($rrObj->name,$rrObj->type);
my $tmp_found;
my @rrs_found;
if ($query) {
# Step 5
foreach my $rrObj2($query->answer) {
next unless $r rObj2->type eq $rrObj->type;
push @rrs_found,$rrObj2;
# Next few steps are to check to see if RR is the
# same one from the file
next unless lc $rrObj2->name eq lc $rrObj->name;
if ($rrObj2->type eq 'SRV') {
next unless lc $rrObj2->target eq lc $rrObj->target;
}
if ($rrObj2->type eq 'CNAME') {
next unless lc $rrObj2->cname eq lc $rrObj->cname;
}
if ($rrObj2->type eq 'A') {
next unless lc $rrObj2->address eq lc $rrObj->address;
}
$tmp_found++;
last;
}
}
# Step 6
if ($tmp_found) {
$found++;
}
else {
$not_found++;
print " Record not found:\n $rr_entry\n";
print " Other records found:\n";
print " ",$_->string,"\n" foreach @rrs_found;
}
}
print " Found: $found\n Not Found: $not_found\n";
# Step 7
close RR;
# Close IPC connection
Win32::NetResource::CancelConnection("\\\\$dc", 0, 0)
or print " Could not cancel IPC connection: $^E\n";
}
}
else {
die "DC query failed: ", $res->errorstring, "\n";
}
exit;
|