Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

Creating Python Service to Query AD Attributes

I'm integrating our AD with web services running Python on linux using Python-LDAP over SASL(DIGEST-MD5) to query AD 2012 user attributes (division, department, phone extension, email, etc). After working out the kinks specific to my service against an AD 2003 I started to run into an SPN error against our new AD 2012, that the digest-uri didn't match any SPNs on the server. I've cross referenced the SPN list for both servers and they contain identical analogues of each other.

The Error: The digest-uri does not match any LDAP SPN's registered for this server

The Fix?

This was fixed by running:

setspn -A ldap/<Domain_Name> <Computer_Name>

Note that creating a service account did not fix my SPN error even when the following command was run:

setspn -A ldap/<Domain_Name> <Domain_Name>/<Service_Account_Name>

simple_bind_s() doesn't need SPN, sasl_interactive_bind_s() needs SPN

Only adding the SPN to the local machine SPN list worked for my Python-LDAP service using sasl_interactive_bind_s(). I should also note that the SPN step can be skipped if I use simple_bind_s() but this method sends credentials in cleartext which is unacceptable.

However I noticed that the record only stays on the SPN list for about a minute before disappearing? There are no errors when I run the setspn command, the event logs are completely empty, there are no duplicates anywhere, checked with the -F forest-wide search on the base dn and nothing. I've added and tried to re-add and removed and moved the SPN from object to object to verify that it's not hiding anywhere, but the second I add the object anywhere and then attempt to re-add it notifies me of a duplicate. So I'm very confident that there isn't a duplicate hidden somewhere.

The Hack

For now I've got a scheduled task re-running the command to keep the record on the list so my service will work aptly named "SPN Hack"

cmd.exe /C "setspn -A ldap/<Domain_Name> <Computer_Name>"

until I can find out why the SPN is being cleaned off the list.

I'm not the primary administrator for this particular AD, could the admin have a service running that syncing the SPN from another service on the AD and not be aware of it? My title is Web Developer, not as an excuse but to explain my ignorance for matters Active Directory. I've been told to make the AD the master user DB and I've been reading a lot but I can't find anywhere where people are having an issue with the SPN being 'overwritten' or 'cleaned' periodically and none of the admins are very familiar with SPN outside SQLServer entries.

Why do I need the hack?

So far my hack doesn't appear to have caused any issues for any users or services and hasn't generated any errors, so the admin says he'll just let it run and I'll keep looking. But then I find myself in the precarious situation of writing a service whose implementation is built on, essentially a cron hack /shiver... So, any help would be appreciated.


Update

After a conversation with the sysadmin he's agreed that building a service on top of a hack isn't a solution, therefore he's given me permission to spin up a local service with endpoint encryption that I can use for my purposes, the result is the same. I'll keep an eye out for what is causing the SPN to clear out. Local binds aren't a problem using Python-LDAP and the local service is already up and running after only an hour or so. It's unfortunate that I'm essentially wrapping functionality built into LDAP but we do what we have to do.

share|improve this question
    
Well that's a mystery. SPNs don't usually just disappear on their own. I'm betting that an application is deleting it. Does Python-Ldap automatically register its own SPNs? If so, is it doing it correctly? Beyond that you may need to configure object access auditing on the domain controller to try and catch who is responsible for deleting the SPN every couple minutes. –  Ryan Ries Nov 19 '13 at 15:22
1  
Python-LDAP doesn't register it's own SPN. I've wiresharked the heck out of my testing services and network wise it just looks like a standard login flow, now as to whether or not the initial request would register that on the AD side that seems like it would defeat the purpose of the SPN in the first place? I do know that the cleartext bind works without the spn, it's only the sasl request that fails without the SPN record on the AD... I've started looking for services that might be managing the SPN outside, almost feels like a wipe and replace script is running somewhere... –  Melignus Nov 19 '13 at 16:24
    
Hey did you find why your SPN was disappearing ? We seem to have the same behavior after a few hours... –  David Dec 6 '13 at 13:52
add comment

1 Answer 1

This is a truly interesting (and annoying) phenomenon and I insist that we find out what's going on here.

Fortunately, Windows Server has some fine grained auditing policies since 2008, and we can use auditing to track down who did this. To do so, we'll need to:

  1. Find out where the SPN modification occurs
  2. Enable AD DS object change auditing
  3. Set an audit ACE on the object
  4. Reproduce the error
  5. Inspect the security log on the offending DC

Find out where the SPN modification occurs:

Open an elevated command prompt on a domain controller and issue this command:

repadmin /showobjmeta . "CN=computerAccount,DC=domain,DC=local"|findstr servicePricipalName

The output will contain the name of the Domain Controller who originally wrote the current version of the servicePrincipalName attributes value: repadmin iz boss

Enable AD DS object change auditing:

If a global audit policy is not already defined, you can make this change to the local security policy on the Domain Controller identified in the previous step

Open the Group Policy Management Console (gpmc.msc) and locate the Default Domain Controllers Policy and edit it.

  1. Go to Computer Configuration -> Windows Settings -> Security Settings
  2. Select and Expand Local Policies -> Security Options
  3. Make sure that Audit: Force audit policy subcategory settings... is set to Enabled Force audit subcategories where classic categories are a already being applied
  4. Select and Expand Advanced Audit Policy -> Audit Policies -> DS Access
  5. Make sure that Audit Directory Service Changes is set to at least Success Audit Directory Service Changes

Set an audit ACE on the object:

Open Active Directory Users and Computers (dsa.msc) and Check the "Advanced Features" setting in the "View" menu.
Navigate to the computer account object, right-click it and select Properties. Choose the Security tab, and hit the "Advanced" button.

In the prompt, select the Auditing tab and ensure that "Write all properties" is being audited for Everyone. If not, or if you're in doubt, Add a new entry:

  1. Press Add.
  2. Input "Everyone" as the target principal
  3. Select "Success" as the type
  4. Scroll down under properties and check "Write servicePrincipalName"
  5. Press OK to add the entry and exit ADUC

(If you're lazy you can just select "Write all properties")

Reproduce the error

From your question it seems that the SPN get's deleted every minute or so, so this is probably the easiest step. Take a 1 minute music lesson in the mean time.

Inspect the security log on the offending DC

Now that a minute has passed, let's inspect the security log on the Domain Controller identified as the originator in step 1. This can be a pain in large domains, but filtering can help with this:

  1. Open Event Viewer and navigate to Windows Logs -> Security
  2. In the right pane, select Filter Current Log
  3. In the input field that says "<All Event IDs>", input 5136 (this is the event id for directory object modification)

You should now be able to find an event entry for each change to the servicePrincipalName attribute on the computer account.

Identify the "Subject" responsible for the change and see where it came from. Kill that process/machine/account with fire!

If the subject is identified as SYSTEM, ANONYMOUS LOGON or a similarly generic description, we're dealing with internal processing on the domain controller itself, and we'll need to break out some NTDS Diagnostic Logging to find out what's going on. Please update the question if this is the case

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.