Listing11_DC_RR_Validation (Perl)

This code can be found in Chapter 8 of Managing Enterprise Active Directory Services

Purchase XP Cookbook or Networking Recipes for only $25 plus shipping! While supplies last.

Find out how to download all of the Perl code from this site.

# 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;

This code has been viewed 886 times.

New from the creators of TechTasks.com: StatSheet.com