class Ucert::AdTracker

Class to handle the ative directory local data cache repository. Note this class depends on the 3rd party program 'openldap' @ www.openldap.org

Attributes

acct_cntl_code[R]
ad_computer_records[R]
ad_delta[RW]
ad_delta_map[RW]
ad_person_records[R]
known_hosts[R]
ldap_base[RW]
ldap_connector[RW]
ldap_connector_id[RW]
ldap_connector_pass[RW]
ldap_host[RW]
ldap_port[RW]
ldapsearch_argv_1[RW]
ldapsearch_argv_2[RW]
ldapsearch_cache_computer[R]
ldapsearch_cache_person[R]
program_ldapsearch[R]
refresh_dns_records[RW]
verbose[RW]

Public Class Methods

new(params ={}) click to toggle source

Instance default variables

# File lib/ucert/ad_tracker.rb, line 21
def initialize (params ={})
              # Specify the dependency 3rd party application 'ldapsearch' installation path
              @verbose=params.fetch(:verbose, false)
              @refresh_dns_records=params.fetch(:refresh_dns_records, false)                # params to turn on/off DNS records refreshment. Use with caution as it's time intensive task.
              @program_ldapsearch = "/usr/bin/ldapsearch"
              # Specify default ldap connector and connecting credential; currently we support: 1) 'openldap'
              @ldap_connector = "openldap"
              @ldap_connector_id=params.fetch(:ldap_connector_id,"")
              @ldap_connector_pass=params.fetch(:ldap_connector_pass,"")
              @ldap_host = params.fetch(:ldap_host, "CMBNY-OADC2.ny.cmbchina.com")
              @ldap_port = params.fetch(:ldap_port, "389")
              @ldap_base = params.fetch(:ldap_base, "DC=ny,DC=cmbchina,DC=com")
              # Specify the dependency 3rd party application 'ldapsearh' command argument options
              #@ldapsearch_argv_1 = " -b \"DC=ny,DC=cmbchina,DC=com\" -h CMBNY-OADC2.ny.cmbchina.com -p 389 -D "
              @ldapsearch_argv_1 = " -b " + @ldap_base + " -h " + @ldap_host + " -p " + @ldap_port + " -D "
              @ldapsearch_argv_2 = " -s sub \"objectcategory="
              # Specify the cache file location for 'ldapsearch'
              @ldapsearch_cache_person = File.dirname(__FILE__) + "/../../data/ad/ldap_person.txt"
              @ldapsearch_cache_computer = File.dirname(__FILE__) + "/../../data/ad/ldap_computer.txt"
              # Specify the local hosts cache file for fast DNS resolving
              @hosts_cache = File.dirname(__FILE__) + "/../../data/ad/hosts"
              @known_hosts=load_known_hosts(@hosts_cache)
              # AD Delta detection
              @ad_delta_map = File.dirname(__FILE__) + "/../../data/ad/ad_delta.txt"
              @ad_delta = load_known_user_map_from_file (@ad_delta_map)
              # class instance variables to keep track of the AD record changes
              @ad_person_records = Hash.new
  @ad_computer_records = Hash.new
              # Refer to microsoft KB 'How to use the UserAccountControl flags' - https://support.microsoft.com/en-us/kb/305144
              @acct_cntl_code={"SCRIPT"=>1, "ACCOUNTDISABLE"=>2, "HOMEDIR_REQUIRED"=>4, "LOCKOUT"=>5, "PASSWD_NOTREQD"=>6, \
                      "PASSWD_CANT_CHANGE"=>7, "ENCRYPTED_TEXT_PWD_ALLOWED"=>8, "TEMP_DUPLICATE_ACCOUNT"=>9, "NORMAL_ACCOUNT"=>10, \
                      "'INTERDOMAIN_TRUST_ACCOUNT'"=>12, "WORKSTATION_TRUST_ACCOUNT"=>13, "SERVER_TRUST_ACCOUNT"=>14, \
                      "DONT_EXPIRE_PASSWORD"=>17, "MNS_LOGON_ACCOUNT"=>18, "SMARTCARD_REQUIRED"=>19, \
                      "TRUSTED_FOR_DELEGATION"=>20, "NOT_DELEGATED"=>21, "USE_DES_KEY_ONLY"=>22, "DONT_REQ_PREAUTH"=>23, \
                      "PASSWORD_EXPIRED"=>24, "TRUSTED_TO_AUTH_FOR_DELEGATION"=>25, "PARTIAL_SECRETS_ACCOUNT"=>27}
              # loading the instance variables
              load_ad(@ldap_connector)
      end

Public Instance Methods

ad_search_by_text(keyword,opt="person") click to toggle source

generic text string search of ad local cache for matched record, return the record primary key, i.e. DN

# File lib/ucert/ad_tracker.rb, line 210
def ad_search_by_text (keyword,opt="person")
  begin
    puts "Begin search on the cache for: #{keyword}" if @verbose
                return nil if keyword.nil?
                keywords=keyword.downcase.split(/(\,|\s|\;|\&|\!|\@|\#|\$|\%|\^|\*|\(|\)|\-|\=|\+|\=|\{|\}|\[|\]|\:|\~)/) \
                        - [" ", "", nil, ",", ";", "&", "!", "@", "#", "$", "%", "^", "*", "(", ")", "-", "+", "=", "{", "}", "[", "]", ":" "~"]
    #txt.downcase!
    case opt
    when "computer"
      @ad_computer_records.each do |key, val|
        puts "Searching computer cache data." if @verbose
        val.map do |entry|
                                        every=entry.to_s.downcase
                                        success=keywords.inject(true) {|found,word| break unless found; every.include?(word) && found; }
          if success
            return key
          end
        end
      end
    when "person"
      @ad_person_records.each do |key, val|
        puts "Searching person cache data." if @verbose
                                word_1=keywords.join(" ")
                                word_2=keywords.reverse.join(" ")
                                val.map do |entry|
          puts "First order searching: #{entry} for #{word_1} or #{word_2}" if @verbose
               every=entry.to_s.downcase
                if every.include?(" " + word_1) or every.include?(" " + word_2)
            puts "Best match found: #{entry}" if @verboseirb
            return key
          elsif every.include?(word_1) or every.include?(word_2)
            puts "Best match found: #{entry}" if @verbose
            return key
          end
        end
                        end
                        @ad_person_records.each do |key, val|
                                val.map do |entry|
          puts "Secondary order searching: #{entry}" if @verbose
               every=entry.to_s.downcase
                                        success2=keywords.inject(true) {|found,word| break unless found; every.include?(word) && found; }
                                        if success2
            puts "Close match found: #{entry}" if @verbose
            return key
          end
        end
      end
    else
      raise "Unknow cache: #{opt}"
    end
    return nil
  rescue => ee
    puts "Exception on method #{__method__}: #{ee}"
  end
end
Also aliased as: search
ad_searches_by_text(keyword,opt="person",max=10) click to toggle source

generic text string search of ad local cache for matched records. Input is a keyword string, return the record primary keys, i.e. multiple DNs in an array.

# File lib/ucert/ad_tracker.rb, line 269
  def ad_searches_by_text (keyword,opt="person",max=10)
    begin
      puts "Begin searches on the cache for: #{keyword}" if @verbose
                  return nil if keyword.nil?
keywords=keyword.downcase.split(/(\,|\s|\;|\&|\!|\@|\#|\$|\%|\^|\*|\(|\)|\-|\=|\+|\=|\{|\}|\[|\]|\:|\~)/) \
                          - [" ", "", nil, ",", ";", "&", "!", "@", "#", "$", "%", "^", "*", "(", ")", "-", "+", "=", "{", "}", "[", "]", ":" "~"]
                  search_result=Array.new
                  case opt
      when "computer"
                          cnt=0
        @ad_computer_records.each do |key, val|
          puts "Searching computer cache data on: #{key}" if @verbose
          val.map do |entry|
                                          break if cnt >= max  # limit returned records to max
                                          every = entry.to_s.downcase
                                          success=keywords.inject(true) {|found,word| break unless found; every.include?(word) && found; }
                                          if success
              puts "Match found: #{entry}" if @verbose
              search_result.push(key)
                                                  cnt+=1
                                                  break
            end
          end
        end
      when "person"
                          cnt=0
                          # Perform 1st order search of CN portion of DN only for the best match
                          @ad_person_records.keys.map do |x|
                                  puts "Searching person DN entry for #{key}" if @verbose
                                  word_1=keywords.join(" ").downcase
                                  word_2=keywords.reverse.join(" ").downcase
                                  y=get_cn(x).downcase
                                  if y.include?(word_1) or y.include?(word_2)
                                          puts "Match found: #{x}" if @verbose
                                          search_result.push(x)
                                          cnt+=1
                                  end
                          end
                          # Perform 2nd order search of complete keyword string on person record attributes
        @ad_person_records.each do |key, val|
          puts "Searching person cache data on: #{key}" if @verbose
    word_1=keywords.join(" ")
                                  word_2=keywords.reverse.join(" ")
    val.map do |entry|
                                          break if cnt >= max  # limit returned records to max
                                          every = entry.to_s.downcase
                                          if every.include?(word_1) or every.include?(word_2)
              puts "Match found: #{entry}" if @verbose
              search_result.push(key)
                                                  cnt+=1
                                                  break
            end
          end
        end
                          # Perform 3rd order search of partial keyword string on the person record attributes
                          @ad_person_records.each do |key, val|
          puts "Searching person cache data on: #{key}" if @verbose
          val.map do |entry|
                                          break if cnt >= max  # limit returned records to max
                                          every = entry.to_s.downcase
                                          success=keywords.inject(true) {|found,word| break unless found; every.include?(word) && found; }
            #entry_clean=entry.chomp
                                          #if entry_clean.downcase.include?(txt)
                                          if success
              puts "Match found: #{entry}" if @verbose
              search_result.push(key)
                                                  cnt+=1
                                                  break
            end
          end
        end
                          #
      else
        raise "Unknow cache: #{opt}"
      end
      return search_result.uniq
    rescue => ee
      puts "Exception on method #{__method__}: #{ee}"
                  return search_result
    end
  end
Also aliased as: searches
cntl_code_2_property_flag(code) click to toggle source

Convertion of MS UserAccountControl code in decimal value back to 'Property flag'

# File lib/ucert/ad_tracker.rb, line 504
def cntl_code_2_property_flag (code)
        begin
                puts "Perform user account status lookup for user account control code: #{code}" if @verbose
                code_2_status = Hash.new
                @acct_cntl_code.each { |k,v| code_2_status[v]=k }
                account_status = Array.new
                b_code = code.to_i.to_s(2)
                a_code = b_code.split('').reverse
                (0...a_code.count).each do |x|
                        if a_code[x] === "1"
                                status = code_2_status[x+1]
                                account_status.push(status)
                        end
                end
                return account_status.join(' + ')
        rescue => ee
                puts "Exception on method #{__method__}: #{ee}" if @verbose
                return "Unknown"
        end
end
Also aliased as: code_2_flag
code_2_flag(code)
dump(opt)
Alias for: print
extract_first_cn(dn) click to toggle source

String manipulation to extract the first CN from the DN

# File lib/ucert/ad_tracker.rb, line 453
def extract_first_cn (dn)
        begin
                return nil if dn.nil? or dn.empty?
                dn.split(',').map do |x|
                        return x if x=~ /^cn=/i
                end
        rescue => ee
                puts "Exception on method #{__method__}: #{ee}"
        end
end
get_ad_record(dn) click to toggle source

Retrieve the specific dn object

# File lib/ucert/ad_tracker.rb, line 353
def get_ad_record (dn)
  begin
      return @ad_person_records[dn] if @ad_person_records.key?(dn)
      return @ad_computer_records[dn] if @ad_computer_records.key?(dn)
                        return "Unfound"
  rescue => ee
      puts "Exception on method #{__method__}: #{ee}"
                        return "Unfound"
  end
end
get_cn(dn) click to toggle source

Retrieve the first CN “Full Name” for the DN

# File lib/ucert/ad_tracker.rb, line 435
def get_cn (dn)
        begin
                attrs=@ad_person_records[dn] if @ad_person_records.key?(dn)
                attrs=@ad_computer_records[dn] if @ad_computer_records.key?(dn)
                attrs.map do |line|
                        (key,val)=line.chomp.split(':')
                        if key=="cn"
                                return val.strip
                        end
                end
                return "Unfound"
        rescue => ee
                puts "Exception on method #{__method__}: #{ee}"
                return "Unfound"
        end
end
get_cns(dns) click to toggle source

Retrieve a list of CNs i.e. “Full Name” for the dns

# File lib/ucert/ad_tracker.rb, line 465
def get_cns (dns)
        begin
                result=Array.new
                dns.map do |dn|
                        cn=get_cn(dn)
                        result.push(cn)
                end
                return result
        rescue => ee
                puts "Exception on method #{__method__}: #{ee}"
                return result
        end
end
get_dn_attribute(opt="person",dn,attr_name) click to toggle source

Retrieve the specific attribute from the dn's attribute collection

# File lib/ucert/ad_tracker.rb, line 365
def get_dn_attribute (opt="person",dn,attr_name)
  begin
                case opt
                when "person"
                        attrs=@ad_person_records[dn] if @ad_person_records.key?(dn)
                when "computer"
       attrs=@ad_computer_records[dn] if @ad_computer_records.key?(dn)
                else
                        raise "Error - unknown objectcategory: #{opt}"
                end
    #puts attrs
    attrs.map do |line|
      (key,val)=line.chomp.split(':')
      if key==attr_name
        return val.strip
      end
    end
                return nil
  rescue => ee
    puts "Exception on method #{__method__}: #{ee}"
                return nil
  end
end
get_dn_attributes(opt,dn,attr_name) click to toggle source

Retrieve the attributes from the dn's attribute collection; the output is the matchs inside an array

# File lib/ucert/ad_tracker.rb, line 390
def get_dn_attributes (opt,dn,attr_name)
  begin
                founds = Array.new
                case opt
                when "person"
                        attrs=@ad_person_records[dn] if @ad_person_records.key?(dn)
                when "computer"
       attrs=@ad_computer_records[dn] if @ad_computer_records.key?(dn)
                else
                        raise "Error - unknown objectcategory: #{opt}"
                end
    #puts attrs
    attrs.map do |line|
      (key,val)=line.chomp.split(':')
      if key==attr_name
        founds.push(val.strip)
      end
    end
                return founds
  rescue => ee
    puts "Exception on method #{__method__}: #{ee}"
                return nil
  end
end
get_os(dn)
Alias for: get_os_info
get_os_info(dn) click to toggle source
# File lib/ucert/ad_tracker.rb, line 479
def get_os_info (dn)
        begin
                puts "Retrieve Operation System information for: #{dn}" if @verbose
                os_info = String.new
                attrs=@ad_computer_records[dn] if @ad_computer_records.key?(dn)
                attrs.map do |line|
                        (key,val)=line.chomp.split(':')
                        case key
                        when "operatingSystem"
                                os_info += val.strip
                        when "operatingSystemVersion"
                                os_info += val
                        when "operatingSystemServicePack"
                                os_info += val
                        end
                end
                return os_info
        rescue => ee
                puts "Exception on method #{__method__}: #{ee}" if @verbose
                return "Unfound"
        end
end
Also aliased as: get_os
is_ldap_bind?() click to toggle source

wrapper to Net::LDAP ldap.bind method

# File lib/ucert/ad_tracker.rb, line 78
def is_ldap_bind?
        begin
                ldap = Net::LDAP.new
                ldap.host = @ldap_host
                ldap.port = @ldap_port
                ldap.auth @ldap_connector_id, @ldap_connector_pass
                if ldap.bind
                        puts "LDAP bind to #{@ldap_host} successfully!"
                        return true
                else
                        puts "LDAP bind to #{@ldap_host} fail!"
                        return false
                end
        rescue => ee
    puts "Exception on method #{__method__}: #{ee}"
  end
end
load_ad(connector) click to toggle source

Load AD tracker instance variables from the cache files; re-create the cache files if non-existing.

# File lib/ucert/ad_tracker.rb, line 61
def load_ad (connector)
        begin
                case connector
                when "openldap"
                        update_openldap_cache("person") unless File.exist?(@ldapsearch_cache_person)
                        parse_openldap_cache("person")
                        update_openldap_cache("computer") unless File.exist?(@ldapsearch_cache_computer)
                        parse_openldap_cache("computer")
                else
                        #do nothing
                end
        rescue => ee
    puts "Exception on method #{__method__}: #{ee}"
  end
end
load_known_hosts(f_hosts=@file_hosts) click to toggle source

Load the hosts cache file for fast DNS resolving

# File lib/ucert/ad_tracker.rb, line 632
def load_known_hosts (f_hosts=@file_hosts)
        puts "Loading local hosts from file: #{f_hosts} ..." if @verbose
        begin
                known_hosts=Hash.new
                f=File.open(f_hosts, 'r')
                f.each do |line|
                        next unless line =~ /\d+\.\d+\.\d+\.\d+/
                        entry=line.chomp.split(%r{\t+|\s+|\,})
                        key=entry[0].downcase
                        value=entry[1]
                        puts "Loading value pair: #{key} - #{value}" if @verbose
                        known_hosts[key] = Hash.new unless known_hosts.key?(key)
                        known_hosts[key]= value
                end
                f.close
                return known_hosts
        rescue => ee
                puts "Exception on method #{__method__}: #{ee}"
                return Hash.new
        end
end
local_ip_2_host(ip) click to toggle source

Local DNS reverse lookup

# File lib/ucert/ad_tracker.rb, line 655
def local_ip_2_host (ip)
        puts "Perform local IP to hostname lookup on IP: #{ip}" if @verbose
        begin
                ip.chomp!
                raise "Invalid IP address format: #{ip}" unless ip =~ /\d+\.\d+\.\d+\.\d+/
                @known_hosts.to_a.reverse.to_h.each do |key,val|
                        return key.to_s if val == ip
                end
                return nil
        rescue => ee
                puts "Exception on method #{__method__}: #{ee}"
                return nil
        end
end
parse_openldap_cache(opt) click to toggle source

method to parse the openldap cache file, save the record into a hash data structure

# File lib/ucert/ad_tracker.rb, line 131
def parse_openldap_cache (opt)
  begin
    case opt
    when "person"
      file = @ldapsearch_cache_person
    when "computer"
      file = @ldapsearch_cache_computer
    else
      raise "Unkown log file type: #{opt}"
    end
    puts "Start working on openldap log file: #{file}" if @verbose
    raise "File not found. Please check your path again: #{file}" unless File.exist?(file)
    f_cache = File.open(file, 'r:ISO-8859-1:UTF-8')
    # recording bit to flag start / end of new ad record
    recording=false
    ad_objs=Hash.new
    dn_key=String.new
                # flag to check next line in file where the dn string may be split over to
                dn_key_nextline_check=false
    f_cache.each do |line|
      line.chomp!
      if dn_key_nextline_check
                                puts "Perform DN Key next line check for its completeness: #{dn_key}" if @verbose
                                if line =~ /^\s/
                                        puts "Incomplete DN Key found: #{dn_key}" if @verbose
                                        dn_key=dn_key+line.sub(/^\s/,'')
                                        ad_objs[dn_key]=Array.new
                                        dn_key_nextline_check=false
                                        recording=true
                                        next
                                else
                                        puts "DN Key found completed: #{dn_key}" if @verbose
                                        dn_key_nextline_check=false
                                        ad_objs[dn_key]=Array.new
                                        dn_key_nextline_check=false
                                        recording=true
                                end
                        end
      if line =~ /^dn\:/
                                puts "DN Key found in line: #{line}" if @verbose
        dn_key=line.split(':')[1].sub(/^\s/,'')
                                puts "DN found: #{dn_key}" if @verbose
                                dn_key_nextline_check=true
        next
      end
      if line.nil? or line.empty?
        puts "Done processing one record." if @verbose
        #sleep(2)
        recording=false
        next
      end
      if recording
                                puts "Start recording for record: #{dn_key}" if @verbose
                                if line=~ /^\s/
                                        puts "Modify last attribute for its incompleteness: #{ad_objs[dn_key].last} - #{line} " if @verbose
                                        ad_objs[dn_key][-1] = ad_objs[dn_key].last + line.sub(/^\s/,'')
                                else
                                        puts "Adding new record attribute: #{line}" if @verbose
                                        ad_objs[dn_key].push(line)
                                end
      end
    end
    f_cache.close
    case opt
    when "person"
      @ad_person_records=ad_objs
    when "computer"
      @ad_computer_records=ad_objs
                        save_hosts  # refresh the hosts file
    else
      raise "Unkown log file type: #{opt}"
    end
    puts "Done processing the cache file: #{file}" if @verbose
  rescue => ee
    puts "Exception on method #{__method__}: #{ee}"
  end
end
print(opt) click to toggle source

Print out Adstore cache record in tab-delimited file format

Also aliased as: dump
refresh_hosts() click to toggle source

refresh @known_hosts instance based on the lastest ad_computer_records

# File lib/ucert/ad_tracker.rb, line 571
def refresh_hosts
        begin
                @ad_computer_records.keys.map do |my_dn|
                        my_sam_id=get_dn_attribute("computer",my_dn,"sAMAccountName")
                        my_os=get_os_info(my_dn)
                        my_host=get_dn_attribute("computer",my_dn,"dNSHostName")
                        my_membership=get_dn_attributes("computer",my_dn,"memberOf")
                        if @known_hosts.key?(my_host)
                                my_ip=@known_hosts[my_host]
                        else
                                my_ip=nslookup(my_host)
                                @known_hosts[my_host]=my_ip
                        end
                end
        rescue => ee
                puts "Exception on method #{__method__}: #{ee}"
        end
end
sam_2_dn(id) click to toggle source

SAM ID to DN reverse lookup

# File lib/ucert/ad_tracker.rb, line 671
def sam_2_dn (id)
  puts "Perform SAM ID to DN lookup for: #{id}" if @verbose
              begin
    id.strip!
                      @ad_person_records.keys.map do |my_dn|
      sam_id=get_dn_attribute("person",my_dn,"sAMAccountName")
      if sam_id == id
        return my_dn
      end
    end
    @ad_computer_records.keys.map do |my_dn|
      sam_id=get_dn_attribute("computer",my_dn,"sAMAccountName")
      if sam_id == id
        return my_dn
      end
    end
                      return nil
              rescue => ee
                      puts "Exception on method #{__method__}: #{ee}"
                      return nil
              end
end
save_delta(f_delta=@ad_delta_map) click to toggle source

Save the AD change back into cache file

# File lib/ucert/ad_tracker.rb, line 613
def save_delta (f_delta=@ad_delta_map)
        begin
                puts "Save the AD Delta table from memory to file: #{f_delta} ..." if @verbose
                timestamp=Time.now
                f=File.open(f_delta, 'w')
                f.write "# AD Delta created by the #{self.class} class #{__method__} method at: #{timestamp}"
                @ad_delta.each do |key, value|
                        unless key =~ /\d+\.\d+\.\d+\.\d+/ or key.nil?
                                f.write "\n#{key}|#{value}"
                        end
                end
                f.close
                puts "AD delta records are successfully saved to: #{f_hosts}" if @verbose
        rescue => ee
                puts "Exception on method #{__method__}: #{ee}"
        end
end
save_hosts(f_hosts=@hosts_cache) click to toggle source

Save the known hosts table into cache file

# File lib/ucert/ad_tracker.rb, line 591
def save_hosts(f_hosts=@hosts_cache)
        begin
                puts "Save the hosts table from memory to file: #{f_hosts} ..." if @verbose
                # update the @known_hosts instance
                refresh_hosts if @refresh_dns_records
                # Write the @known_hosts instance back to hosts file
                timestamp=Time.now
                f=File.open(f_hosts, 'w')
                f.write "# local hosts file created by the #{self.class} class #{__method__} method at: #{timestamp}"
                (@known_hosts.keys-[nil]).sort.map do |key|
                        unless key =~ /\d+\.\d+\.\d+\.\d+/
                                f.write "\n#{key}\t#{@known_hosts[key]}"
                        end
                end
                f.close
                puts "local host repository is successfully saved to: #{f_hosts}" if @verbose
        rescue => ee
                puts "Exception on method #{__method__}: #{ee}"
        end
end
searches(keyword,opt="person",max=10)
Alias for: ad_searches_by_text
sid_2_dn(sid) click to toggle source

Lookup DN by sAMAccountName attribute

# File lib/ucert/ad_tracker.rb, line 416
def sid_2_dn (sid)
        begin
                @ad_person_records.keys.map do |dn|
                        attrs=@ad_person_records[dn]
                        attrs.map do |line|
                                (key,val)=line.chomp.split(':')
                                if val.strip.upcase==sid.strip.upcase
                                        return dn
                                end
                        end
                end
                return nil
        rescue => ee
    puts "Exception on method #{__method__}: #{ee}"
                return "Unfound"
  end
end
update(opt)
Alias for: update_ad_cache
update_ad_cache(opt) click to toggle source

method to update the active directory local cache file

# File lib/ucert/ad_tracker.rb, line 97
        def update_ad_cache (opt)
          begin
                        puts "Start AD cache file update process for objectcategory: #{opt}"
                        case @ldap_connector
                        when "openldap"
                                my_dn=sid_2_dn(@ldap_connector_id)
                                abort "Error. Unknown user ID: #{@ldap_connector_id}" if my_dn.nil?
                                case opt
                                when "person"
#                                       cmd = @program_ldapsearch + @ldapsearch_argv_1 + "\"" + my_dn + "\" -w " + @ldap_connector_pass + @ldapsearch_argv_2 + opt + "\" > " + @ldapsearch_cache_person
                                        cmd = @program_ldapsearch + @ldapsearch_argv_1 + "\"" + @ldap_connector_id + "\" -w " + @ldap_connector_pass + @ldapsearch_argv_2 + opt + "\" > " + @ldapsearch_cache_person
                                when "computer"
#                                       cmd = @program_ldapsearch + @ldapsearch_argv_1 + "\"" + my_dn + "\" -w " + @ldap_connector_pass + @ldapsearch_argv_2 + opt + "\" > " + @ldapsearch_cache_computer
                                        cmd = @program_ldapsearch + @ldapsearch_argv_1 + "\"" + @ldap_connector_id  + "\" -w " + @ldap_connector_pass + @ldapsearch_argv_2 + opt + "\" > " + @ldapsearch_cache_computer
                                else
                                        raise "Error - unknown objectcategory: #{opt}"
                                end
                        else
                                raise "Error - unknown LDAP connector: #{@ldap_connector}"
                        end
                        # Test connection before the update
            if is_ldap_bind?
                                puts "Execute shell command: #{cmd}" if @verbose
               system(cmd)
               puts "Done!"
                        end
            sleep (2)
          rescue => ee
            puts "Exception on method #{__method__}: #{ee}"
          end
        end
Also aliased as: update