Managing Infrastructure with RapidIdentity Part 4: Checking the Status of RapidIdentity Password Filter Installations on DC’s

     

blog-managing-infrastructure-with-rapididentity-4.jpg


Today, I want to look at one of the ways that RapidIdentity allows administrators to automate tedious and cumbersome tasks. I’ll demonstrate a way to analyze Windows domain controllers for the presence of a specific software installation and also provide the entire RapidConnect action at the end of the post, so that you can modify it to fit your needs.

In order to synchronize Active Directory credentials, RapidIdentity deployments use a “password filter” on all writable (not read only) domain controllers in a customer environment. The password filter’s function is to intercept user password change events on a domain controller and then encrypt and store the new passwords within the user’s attributes in the domain.

Subsequently, the new passwords may be retrieved by RapidConnect and synchronized out to disparate systems. If a password change occurs on a domain controller that is missing a password filter installation, that password cannot be synchronized. Therefore, it is imperative to ensure that each writable domain controller is running the password filter.

Scenario

A large school district has implemented RapidIdentity to synchronize user credentials among multiple cloud and internal services. Until recently, all of their users have successfully authenticated to their assigned resources and the synchronization has been flawless. However, over the past few days, the district help desk has received multiple new support tickets indicating that users’ newly-changed passwords are not working beyond their Active Directory environment and RapidIdentity appliances.

After discussion with Identity Automation’s support team, there is reason to believe that the district has added one or more new domain controllers to the environment, but has not yet installed the password filter on them. Now, support has been asked to help them identify any domain controllers that are missing the filter.

Solution

In order to provide a solution that allows the customer to regularly query and report on the installation and status of the password filters on their domain controllers, I’ve created a RapidConnect action, “CheckPWFilterStatus." While the entire action set will be provided at the end of this post, we’ll examine each section, below to understand how it functions.

(Note - this action doesn’t differentiate between Read Only and writeable domain controllers, so in the final log report, administrators will have to validate that only Read Only domain controllers are listed in the “DC's without the password filter running:” section of the log.)

Let’s get started!

First, the action reads in the Global variables and opens a connection to Active Directory.

Globals()
# Open PDC AD Connection and CLI
sessionPDC = openADConnection(Global.adServer, 636, true, Global.adUser,)


Next, arrays are created to allow the domain controllers to be sorted based on the status of the password filter installations.

# Create arrays for servers with and without pwfilter running
withFilter = createArray()
withoutFilter = createArray()
installedButNotRunning = createArray()
couldntConnect = createArray()


Using the Active Directory adapter, Active Directory is queried, and a list of domain controllers is built. The blue highlighted userAccountControl portion of the LDAP filter below is what differentiates DCs from other computer objects. 

# Query for DCs to check for pwfilter
adDCs = getADRecords(sessionPDC, Global.adBaseDN, "sub", "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))", "@dn,name,dNSHostName")


Once the list is gathered, the action iterates through the list, uses the CLI adapter to open a remote CLI connection to each domain controller, and runs a powershell command to check if the password filter is already running on the domain controller.

If the password filter is running, it appends the domain controller to the ‘withFilter’ array. If the password filter is not running, an additional powershell command is sent to check whether or not the idautopwfilter.dll is registered with the lsass process. This step to check with the lsass process can indicate whether the password filter is installed but not running (after installation, the domain controller requires a reboot, so that the filter will function).

As the validations proceed, each domain controller is added to the proper array, based on it’s status (withFilter, withoutFilter, installedButNotRunning, or couldntConnect), and the action closes the established remote CLI session to that server.

# Iterate and check status of idautopwconduit process
forEach(adDC, adDCs) {
    pdcCLI = openRemoteWindowsCLI(Global.adHost, "Administrator", Global.adDNSDomain,)
    if(pdcCLI) {
        # Check for running idautopwfilter.dll
        filterStatusReturn = runRemoteCLICommand(pdcCLI, "powershell \"$($(get-process lsass -ErrorAction SilentlyContinue).modules | where {$_.ModuleName -match 'idautopwfilter.dll'}).ModuleName\"")
        if(filterStatusReturn['exitStatus'] == 0) {
            pwfilterRunning = stringContains(filterStatusReturn['output'], "idautopwfilter.DLL")
            if(pwfilterRunning) {
                appendArrayItem(withFilter, adDC['@dn'])
            } else {
                # Check for registered, but not running idautopwfilter.dll
                dllRegistered = runRemoteCLICommand(pdcCLI, "powershell \"$(Get-ItemProperty 'HKLM:SYSTEM\\CurrentControlSet\\Control\\Lsa' 'Notification Packages' -ErrorAction SilentlyContinue).'Notification Packages'\"")
                if(dllRegistered['exitStatus'] == 0) {
                    foundDLL = stringContains(dllRegistered['output'], "idautopwfilter", true)
                    if(foundDLL) {
                        appendArrayItem(installedButNotRunning, adDC['@dn'])
                    } else {
                        appendArrayItem(withoutFilter, adDC['@dn'])
                    }
                } else {
                    log("There was an error running the powershell command to check for an installed / registered idautopwfilter.dll on server " + adDC['dnsHostName'], "red")
                }
            }
        } else {
            log("There was an error running the powershell command to check the running idautopwfilter.dll on server " + adDC['dnsHostName'], "red")
        }
        close(pdcCLI)
    } else {
        appendArrayItem(couldntConnect, adDC['@dn'])
    }
}


The action logs each category and the domain controllers from that category, such that any without a running status can be checked and validated by the customers’ staff, and they can install the password filter if necessary. Finally, the action ends by closing the LDAP connection to Active Directory.

# Log DC's with and without password filter running
withFilter:  {
    log("DC's with the password filter running:", "green")
    log("----------------------------------------------------------------------------------------", "black")
    forEach(item, withFilter) {
        log(item, "black")
    }
}
log("", "black")
log("", "black")
installedButNotRunning:  {
    log("DC's with the password filter installed, but not running:", "red")
    log("----------------------------------------------------------------------------------------", "black")
    forEach(item, installedButNotRunning) {
        log(item, "black")
    }
}
log("", "black")
log("", "black")
withoutFilter:  {
    log("DC's without the password filter running:", "red")
    log("----------------------------------------------------------------------------------------", "black")
    forEach(item, withoutFilter) {
        log(item, "black")
    }
}
log("", "black")
log("", "black")
couldntConnect:  {
    log("DC's we couldn't CLI connect to:", "red")
    log("----------------------------------------------------------------------------------------", "black")
    forEach(item, couldntConnect) {
        log(item, "black")
    }
}
# Close PDC AD Connection
close(sessionPDC)

To review, in this blog post we’ve utilized a RapidConnect action to validate the installation status of specific software. Using the Active Directory adapter, we queried LDAP and retrieved a list of Domain Controllers. We iterated through that list and used the CLI adapter to run powershell commands on each server to query for status of the RapidIdentity password filter and log the status for each server.

Files

CheckPWFilterStatus (No Input Properties)


globals()
# Open PDC AD Connection and CLI
sessionPDC = openADConnection(Global.adHost, 636, true, Global.adUser,)
# Create arrays for servers with and without pwfilter running
withFilter = createArray()
withoutFilter = createArray()
installedButNotRunning = createArray()
couldntConnect = createArray()
# Query for DCs to check for pwfilter
adDCs = getADRecords(sessionPDC, Global.adBaseDN, "sub", "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))", "@dn,name,dNSHostName")
# Iterate and check status of idautopwconduit process
forEach(adDC, adDCs) {
    pdcCLI = openRemoteWindowsCLI(Global.adHost, "Administrator", Global.adDNSDomain,)
    if(pdcCLI) {
        # Check for running idautopwfilter.dll
        filterStatusReturn = runRemoteCLICommand(pdcCLI, "powershell \"$($(get-process lsass -ErrorAction SilentlyContinue).modules | where {$_.ModuleName -match 'idautopwfilter.dll'}).ModuleName\"")
        if(filterStatusReturn['exitStatus'] == 0) {
            pwfilterRunning = stringContains(filterStatusReturn['output'], "idautopwfilter.DLL")
            if(pwfilterRunning) {
                appendArrayItem(withFilter, adDC['@dn'])
            } else {
                # Check for registered, but not running idautopwfilter.dll
                dllRegistered = runRemoteCLICommand(pdcCLI, "powershell \"$(Get-ItemProperty 'HKLM:SYSTEM\\CurrentControlSet\\Control\\Lsa' 'Notification Packages' -ErrorAction SilentlyContinue).'Notification Packages'\"")
                if(dllRegistered['exitStatus'] == 0) {
                    foundDLL = stringContains(dllRegistered['output'], "idautopwfilter", true)
                    if(foundDLL) {
                        appendArrayItem(installedButNotRunning, adDC['@dn'])
                    } else {
                        appendArrayItem(withoutFilter, adDC['@dn'])
                    }
                } else {
                    log("There was an error running the powershell command to check for an installed / registered idautopwfilter.dll on server " + adDC['dnsHostName'], "red")
                }
            }
        } else {
            log("There was an error running the powershell command to check the running idautopwfilter.dll on server " + adDC['dnsHostName'], "red")
        }
        close(pdcCLI)
    } else {
        appendArrayItem(couldntConnect, adDC['@dn'])
    }
}
# Log DC's with and without password filter running
withFilter:  {
    log("DC's with the password filter running:", "green")
    log("----------------------------------------------------------------------------------------", "black")
    forEach(item, withFilter) {
        log(item, "black")
    }
}
log("", "black")
log("", "black")
installedButNotRunning:  {
    log("DC's with the password filter installed, but not running:", "red")
    log("----------------------------------------------------------------------------------------", "black")
    forEach(item, installedButNotRunning) {
        log(item, "black")
    }
}
log("", "black")
log("", "black")
withoutFilter:  {
    log("DC's without the password filter running:", "red")
    log("----------------------------------------------------------------------------------------", "black")
    forEach(item, withoutFilter) {
        log(item, "black")
    }
}
log("", "black")
log("", "black")
couldntConnect:  {
    log("DC's we couldn't CLI connect to:", "red")
    log("----------------------------------------------------------------------------------------", "black")
    forEach(item, couldntConnect) {
        log(item, "black")
    }
}
# Close PDC AD Connection
close(sessionPDC)

 

 

is-your-legacy-iam-system-doing-more-harm-than-good

Comments

Subscribe Here!