AD Recycle Bin and a Eulogy for the Infrastructure Master

Ruminate with me a while, won't you?

Ah, the Infrastructure Master.  Probably the least-appreciated FSMO role of all.  In discussions such as technical job interviews, most people can list the five FSMOs for me... maybe even tell me which are per-forest and which are per-domain... but if you then start asking for specifics about what each one of them actually does, the interviewee usually gets a bit more wobbly.  And I think the Infrastructure Master in particular is probably the most difficult of all to grasp.  I know it was certainly the last one for me to really "get."

I won't spill it all out here on what exactly the IM does - there's plenty of documentation out there if you're really interested. I would also direct you to this ServerFault post wherein I give a real-world example of what the IM does and what might happen if the IM is on the wrong domain controller.

This brings me to the Active Directory Recylce Bin.  The AD Recycle Bin was introduced in 2008 R2, and was a long time coming.  Before, restoring AD objects was a lot more arcane and cumbersome than it is with a good ole' Recycle Bin.  Considering the AD Recycle Bin is going on 5 years old now, even though it's an optional feature, there's less and less of an excuse as time goes on for you to not have it enabled in your AD domain.

(You don't, do you?)

So here's the interesting bit that you might not have known: (sorry for wasting your time if you did know) once you've enabled the AD Recycle Bin, your Infrastructure Master no longer has anything to do.  Nothing.  Not even in an environment where some domain controllers are not also global catalogs.

From Technet:

When the Recycle Bin optional feature is enabled, every DC is responsible for updating its cross-domain object references in the event that the referenced object is moved, renamed, or deleted. In this case, there are no tasks associated with the Infrastructure FSMO role, and it is not important which domain controller owns the Infrastructure Master role.

So as the AD Recycle Bin becomes more and more commonplace in Active Directory environments, it seems that the Infrastructure Master may slowly dwindle away until only the old guard even remembers what it was, and budding young IT pros will only have 4 FSMOs to remember.

ShareDiscreetlyWebServer v1.0.1.2

Several improvements over the last release the past few days:

  • Some code optimizations. Pages are rendering about an order of magnitude faster now.
  • Just about all the HTML and Javascript has been exported to editable files so that an administrator can change up the code, color schemes, branding, etc., without needing to recompile the code.
  • The server can now send an S/MIME, digitally signed email to the person you want to send the URL to. Unfortunately some email clients (such as the Gmail web client) don't natively understand S/MIME, but Outlook handles it just fine. You can also get various plugins and programs to read S/MIME emails if your email client doesn't understand it. I'd rather lean toward more security-related bells and whistles than max compatibility for this project.

You can access the secret server at https://myotherpcisacloud.com.

ShareDiscreetlyWebServer v1.0.0.3

I wrote a web service.  I call it "ShareDiscreetly".  Creative name, huh?

I wrote the server in C# .NET 4.0.  It runs as a Windows service.

ShareDiscreetlyWebServer serves a single purpose: to allow two people to share little bits of information - secrets - such as passwords, etc., in a secure, discreet manner.  The secrets are protected both in transit and at rest, using the FIPS-approved AES-256 algorithm with asymmetric keys supplied by an X.509 certificate.

Oh, and I made sure that it's thoroughly compatible with Powershell so that the server can be used in a scriptable/automatable way.

You can read a more thorough description of the server as you try it out here.

Please let me know if you find any bugs, exploits, or if you have any feature requests!

DNS over HTTP

I was discussing with some fellow IT admins, the topic of blocking certain websites so that employees or students couldn't access them from the work or school network.  This is a pretty common topic for IT in most workplaces.  However, I personally don't want to be involved in it.  I realize that at some places, like schools for instance, filtering of some websites may be a legal or policy requirement.  But at the workplace, if an employee wants to waste company time on espn.com, that is an issue for HR and management to take up with that employee.  And again in my opinion, it's not about how much time an employee spends on ESPN or Reddit either, but simply whether that employee delivers satisfactory results.  I don't want to handle a people problem with a technical solution.  I don't want to be the IT guy that derives secret pleasure from blocking everyone from looking up their fantasy football scores.  (Or whatever it is people do on espn.com.)  I could spend my entire career until I retire working on a web proxy, blocking each and every new porn site that pops up.  If there's one thing the internet has taught me, it's that there will always be an infinite number of new porn sites.

On the other extreme of black listing, someone then suggested white listing.  Specifically, implementing "DNS white listing" in their environment for the purpose of restricting what internet sites users were allowed to access to only a handful of internet sites.  Well that is a terrible idea.  The only proper way of doing this in my opinion is to use a real web proxy, such as ISA or TMG or Squid.  But I could not help but imagine how I might implement such a system, and then how I might go about circumventing it from the perspective of a user.

OK, well for my first half-baked idea, I can imagine standing up a DNS server, disabling recursion/forwarders on that DNS server, and putting my "white list" of records on that DNS server.  Then, by way of firewall, block all port 53 access to any other IP except my special DNS server.  Congratulations, you just made your users miserable, and have done almost nothing to actually improve the security of your network or prevent people from accessing other sites.  Now the users just have to find another way of acquiring IP addresses for sites that aren't on your white list.

Well how do I get name resolution back if I can't use my DNS server?  I have an idea... DNS over HTTP!

The guys at StatDNS have already thought about this.  And what's awesome, is that they've created a web API for resolving names to IPs over HTTP.  Here's what I did in 5 minutes of Powershell:

PS C:\> Function Get-ARecordOverHTTP([string]$Query) { $($($(Invoke-WebRequest http://api.statdns.com/$Query/a).Content | ConvertFrom-Json).Answer).rdata }

PS C:\> Get-ARecordOverHTTP google.com
173.194.70.101
173.194.70.100
173.194.70.138
173.194.70.102
173.194.70.139
173.194.70.113

PS C:\> Get-ARecordOverHTTP myotherpcisacloud.com
168.61.52.184

Simple as that. How cool is Powershell, seriously?  One line to create a function that accepts a name and returns a list of IPs by interacting with an internet web service.  Pretty awesome if you ask me.

As long as you have port 80 open to StatDNS, you have internet name resolution.  Now, to wrap this into a .NET-based Windows service...

Why Does It Say <Unknown Contact> When Viewing Network Share Permissions?

I only get to work with Active Directory trusts every so often. I think multi-domain forests seem to be falling out of fashion. At least for those of us who've heard of federation. Regardless, here's an interesting issue I ran into the other day:

So I have this domain, contoso.com.  In contoso.com, there is a one-way forest trust established with fabrikam.com, such that contoso.com trusts fabrikam.com.  This way, users in fabrikam.com can access resources in contoso.com.

On pc1.contoso.com, I create a network file share. I add permissions for my own user account, contoso\ryan, to it.  Then, I add permissions for fabrikam\steve to access the file share also.  The operation was successful and the file share appears to be set correctly.  However, when I go back and view the permissions for the file share again, it takes a very long time, as if it were waiting on something to time out, and then eventually, this is what I see:

File Share Permissions

So why is fabrikam\steve showing up as <Unknown Contact> when viewed from the contoso.com domain?  What we have here, is a SID translation failure.  But why?  First, a little background.  Here is what Microsoft says about users in your forest who are members of another forest:

"When a trust is established between a domain in a forest and a domain outside of that forest, security principals from the external domain can access resources in the internal domain. Active Directory creates a foreign security principal object in the internal domain to represent each security principal from the trusted external domain. These foreign security principals can become members of domain local groups in the internal domain. Directory objects for foreign security principals are created by Active Directory and should not be manually modified. You can view foreign security principal objects from Active Directory Users and Computers by enabling advanced features." [ Source ]

So if you go look in the ForeignSecurityPrincipals container in contoso.com, you'll see an object that represents the user account of fabrikam\steve, but his friendly name or samAccountName is not part of that record. It's just a SID.  When we pull up a permissions file dialog box like the one above, Windows attempts a SID to name translation... but it fails.  There's a little bit of technical documentation on how SID translation occurs:

"LSA on the computer that the call is sent to (using the LSA RPC interface) will resolve the SIDs it can map and send on the remaining unresolved SIDs to a domain controller in the primary domain. The domain controller will resolve additional SIDs to account names from the local database, including SIDs found in SidHistory on a global catalog.

If SIDs cannot be resolved there, the domain controller will send remaining SIDs to domain controllers in a trusted domain where the domain part of the SID matches the trust information." [ Source ]

There are many functions regarding SID lookups, and I don't know exactly which ones are used at each location, but the general concept is the same and you can see how this procedure could take a while to time out. And when it fails, you see <Unknown Contact>.  Or maybe just the unresolved SID of security principal.  Depends on which version of Windows you're using and exactly which dialog box you're looking at.

The reason it happens in our scenario is because of the one-way trust. Contoso.com cannot call upon fabrikam to translate SIDs from its forest, because fabrikam does not trust contoso.

To fix it, we could allow anonymous SID translation in fabrikam... but for many that is an unacceptable security risk.  Or we could make the trust two-way.  Or, if you're unable to do either of those things, you could at least create a security group in contoso, add the individuals from fabrikam to that group, and just assign the group to the network share ACL.  The functionality would be the same but at least you wouldn't have to look at "<Unknown Contact>" every time you opened that dialog box.

Mystery solved.

For more information on this, see the ServerFault question that I answered here, as well as the much better Ask the Directory Services team blog post here.