Blog - Title

October, 2011

  • Friday Mail Sack: They Pull Me Back in Edition

    Hiya world, Ned is back with your best questions and comments. I’ve been off to teach this fall’s MCM, done Win8 stuff, and generally been slacking keeping busy; sorry for the delay in posting. That means a hefty backlog - get ready to slurp.

    Today we talk:

    I know it was you, Fredo.

    Question

    If I run netdom query dc only writable DCs are returned. If I instead run nltest /dclist:contoso.com, both writable and RODCs are returned. Is it by design that netdom can't find RODC?

    Answer

    It’s by design, but not by any specific intentions. Netdom was written for NT 4.0 and uses a very old function when you invoke QUERY DC, which means that if a domain controller is not of type SV_TYPE_DOMAIN_CTRL or SV_TYPE_DOMAIN_BAKCTRL, they are not shown in the list. Effectively, it queries for all the DCs just like Nltest, but it doesn’t know what RODCs are, so it won’t show them to you.

    Nltest is old too, but its owners have updated it more consistently. When it returns all the DCs (using what amounts to the same lookup functions), it knows modern information. For instance, when it became a Win2008 tool, its owners updated it to use the DS_DOMAIN_CONTROLLER_INFO_3 structure, which is why it can tell you the FQDN, which servers are RODCs, who the PDCE is, and what sites map to each server.

    image

    When all this new RODC stuff came about, the developers either forgot about Netdom or more likely, didn’t feel it necessary to update both with redundant capabilities – so they updated Nltest only. Remember that these were formerly out-of-band support tools that were not owned by the Windows team until Vista/2008 – in many cases, the original developers had been gone for more than a decade.

    Now that we’ve decided to make PowerShell the first class citizen, I wouldn’t expect any further improvements in these legacy utilities.

    Question

    We’re trying to use DSRevoke on Win2008 R2 to enumerate access control entries. We are finding it spits out: “Error occurred in finding ACEs.” This seems to have gone belly up in Server 2008. Is this tool in fact deprecated, and if so do you know of a replacement?

    Answer

    According to the download page, it only works on Win2003 (Win2000 being its original platform, and being dead). It’s not an officially supported tool in any case – just made by some random internal folks. You might say it was deprecated the day it released. :)

    I also find that it fails as you said on Win2008 R2, so you are not going crazy. As for why it’s failing on 2008 and 2008 R2, I have not the foggiest idea, and I cannot find any info on who created this tool or if it even still has source code (it is not in the Windows source tree, I checked). I thought at first it might be an artifact of User Account Control, but even on a Win2008 R2 Core server, it is still a spaz.

    I don’t know of any purpose-built replacements, although if I want to enumerate access on OUs (or anything), I’d use AD PowerShell and Get-ACL. For example, a human-readable output:

    import-module activedirectory

    cd ad:

    get-acl(get-adobject someDNinquotes) | format-list

    image

    Or to get all the OUs:

    get-acl(get-adorganizationalunit –filter *) | fl

    image

    Or fancy spreadsheets using select-object and export-csv (note – massaged in Excel, it won’t come out this purty):

    image

    image

    Or whatever. The world is your oyster at that point.

    You can also use Dsacls.exe, but it’s not as easy to control the output. And there are the fancy/free Quest AD PowerShell tools, but I can’t speak to them (Get-QADPermission is the cmdlet for this).

    Question

    We are thinking about removing evil WINS name resolution from our environment. We hear that this has been done successfully in several organizations. Is there anything we need to watch out for in regards to Active Directory infrastructure? Are there any gotchas you've seen with environments in general? Also, it seems that the days of WINS may be numbered. Can you offer any insight into this?

    Answer

    Nothing “current” in Windows has any reliance on WINS resolution – even the classic components like DFS Namespaces have long ago offered DNS alternatives - but legacy products may still need it. I’m not aware of any list of Microsoft products with all dependencies, but we know Exchange 2003 and 2007 require it, for instance (and 2010 does not). Anything here that requires port 137 Netbios name resolution may fail if it doesn’t also use DNS. Active Directory technologies do not need it; they are all from the DNS era.

    A primary limitation of WINS and NetBT is that they do not support IPv6, so anything written for Server 2008 and up wouldn’t have been tested without DNS-only resolution. If you have legacy applications with WINS dependency for specific static records, and they are running at least Server 2008 for DNS, you can replace the single-label resolution functionality provided by WINS with the DNS GlobalNames zone. See http://technet.microsoft.com/en-us/library/cc731744.aspx. Do not disable the TCP/IP NetBIOS Helper service on any computers, even if you get rid of WINS. All heck will break loose.

    Rest assured that WINS is still included in the Windows 8 Server Developer Preview, and Microsoft itself still runs many WINS servers; odds are good that you have at least 12 more years of WINS in your future. Yay!

    I expect to hear horror stories in the Comments…

    Question

    What is the expected behavior with respect to any files created in DFSR-replicated folders if they're made prior to initial sync completion? I.e. data in the replicated folder is added or modified on the non-authoritative server during the initial sync?

    Answer

    1. If it’s a brand new file created by the user on the downstream, or if the file has already “replicated” from the upstream (meaning that its hash and File ID are now recorded by the downstream server, not that the file actually replicates) and is later changed by the user before initial replication is fully complete, nothing “bad” happens. Once initial sync completes, their original changes and edits will replicate back outbound without issues.
    2. If the user has bad timing and starts modifying existing pre-seeded files that have not yet had their file ID and hashes replicated (which would probably take a really big dataset combined with a really poor network), their files will get conflicted and changes wiped out, in favor of the upstream server.

    Question

    During initial DFSR replication of a lot of data, I often see debug log messages like:

    20111028 17:06:30.308 9092 CRED   105 CreditManager::GetCredits [CREDIT] No update credits available. Suspending Task:00000000010D3850 listSize:1 this:00000000010D3898

     

    20111028 17:06:30.308 9092 IINC   281 IInConnectionCreditManager::GetCredits [CREDIT] No connection credits available, queuing request.totalConnectionCreditsGranted:98 totalGlobalCreditsGranted:98 csId:{6A576AEE-561E-8F93-8C99-048D2348D524} csName:GooconnId:{B34747C-4142-478F-96AF-D2121E732B16} sessionTaskPtr:000000000B4D5040

    And just what are DFSR “Credits?” Does this amount just control how many files can be replicated to a partner before another request has to be made?  Is it a set amount for a specific amount of time per server?

    Answer

    Not how many files, per se - how many updates. A credit maps to a "change" - create, modify, delete.  All the Credit Manager code does is allow an upstream server to ration out how many updates each downstream server can request in a batch. Once that pool is used up, the downstream can ask again. It ensures that one server doesn't get to replicate all the time and other servers never replicate - except in Win2003/2008, this still happened. Because we suck. In Win2008 R2, the credit manager now correctly puts you to the back of the queue if you just showed up asking for more credits, and gives other servers a chance. As an update replicates, a credit is "given back" until your list is exhausted. It has nothing to do with time, just work.

    "No update credits available" is normal and expected if you are replicating a bung-load of updates. And in initial sync, you are.

    Question

    The registry changes I made after reading your DFSR tuning article made a world of difference. I do have a question though: is the max number of replicating server only 64?

    Answer

    Not the overall max, just the max simultaneously. I.e. 64 servers replicating a file at this exact instance in time. We have some customers with more than a thousand replicating servers (thankfully, using pretty static data).

    Question

    Can members of the Event Log Readers group automatically access all event logs?

    Answer

    Almost all. To see the security on any particular event log, you can use wevtutil gl . For example:

    wevtutil gl security

    image

    Note the S-1-5-32-573 SID there on the end – that is the Event Log Readers well-known built-in SID. If you wanted to see the security on all your event logs, you could use this in a batch file (wraps):

    @echo off

    if exist %temp%\eventlistmsft.txt del %temp%\eventlistmsft.txt

    if exist %temp%\eventlistmsft2.txt del %temp%\eventlistmsft2.txt

    Wevtutil el > %temp%\eventlistmsft.txt

    For /f "delims=;" %%i in (%temp%\eventlistmsft.txt) do wevtutil gl "%%i" >> %temp%\eventlistmsft2.txt

    notepad %temp%\eventlistmsft2.txt

    My own quick look showed that a few do not ACL with that group – Internet Explorer, Microsoft-Windows-CAPI2, Microsoft-Windows-Crypto-RNG, Group Policy, Microsoft-Windows-Firewall with advanced security. IE seems like an accident, but the others were likely just considered sensitive by their developers.

    Other stuff

    Happy Birthday to Bill Gates and to Windows XP. You’re equally responsible for nearly every reader or writer of this blog having a job. And in my case, one not digging ditches. So thanks, you crazy kids.

    The ten best Jeremy Clarkson Top Gear lines… in the world!

    Halloween Part 1: Awesome jack-o-lantern templates, courtesy of ThinkGeek. Yes, they have NOTLD!

    Halloween Part 2: Dogs in costume, courtesy of Bing. The AskDS favorite, of course, is:

    image

     

    Thanks to Japan, you can now send your boss the most awesome emoticon ever, when you fix an issue but couldn’t get root cause:

    ¯\_(ツ)_/¯

    Pluto returning to planet status? It better be; that do-over was lame…

    Finally – my new favorite place to get Sci-Fi and Fantasy pics is Cgsociety. Check out some of 3D and 2D samples from the Showcase Gallery:

     

    clip_image002 clip_image004
    clip_image006 clip_image008
    clip_image010 clip_image012
    clip_image014
    That last one makes a great lock screen

    Have a great weekend, folks.

    - Ned “They hit him with five shots and he's still alive!” Pyle

  • AD FS 2.0 Claims Rule Language Primer

    Hi guys, Joji Oshima here again. On the Directory Services team, we get questions regarding the Claims Rule Language in AD FS 2.0 so I would like to go through some of the basics. I’ve written this article for those who have a solid understanding of Claims-based authentication. If you would like to read up on the fundamentals first, here are some good resources.

    An Introduction to Claims
    http://msdn.microsoft.com/en-us/library/ff359101.aspx

    Security Briefs: Exploring Claims-Based Identity
    http://msdn.microsoft.com/en-us/magazine/cc163366.aspx

    AD FS 2.0 Content Map
    http://social.technet.microsoft.com/wiki/contents/articles/2735.aspx

    Claims Rules follow a basic pipeline. The rules define which claims are accepted, processed, and eventually sent to the relying party. You define claims rules as a property of the Claims Provider Trust (incoming) and the Relying Party Trust (outgoing).

    image
    Basic flowchart for the Claims Pipeline taken from TechNet.

    There is also an authorization stage checks if the requestor has access to receive a token for the relying party. You can choose to allow all incoming claims through by setting the Authorization Rules to Permit All. Alternately, you could permit or deny certain users based on their incoming claim set. You can read more about authorization claim rules here and here.

    You can create the majority of claims issuance and claims transformations using a Claim Rule Template in AD FS 2.0 Management console, but there are some situations where a custom rule is the only way to get the results you need. For example, if you want to combine values from multiple claims into a single claim, you will need to write a custom rule to accomplish that. To get started, I would recommend creating several rules through the Claim Rule Templates and view the rule language generated. Once you save the template, you can click the View Rule Language button from the Edit Rule window to see how the language works.

    image

    image

    In the screenshot above, the rule translates as follows:

    If (there is an incoming claim that matches the type "http://contoso.com/department")

    Then (issue a claim with the type "http://adatum.com/department", using the Issuer, Original Issuer, Value, and ValueType of the incoming claim)

    The claims "http://contoso.com/department" and "http://adatum.com/department" are URIs. These claims can be in the URN or HTTP format. The HTTP format is NOT a URL and does not have to specifically link to actual content on the Internet or intranet.

    Claims Rule Language Syntax:

    Typically, the claims rule language is structured similarly to an “if statement” in many programming languages.

    If (condition is true)

    Then (issue a claim with this value)

    What this says is “if a condition is true, issue this claim”. A special operator “=>” separates the condition from the issuance statement and a semicolon ends the statement.

    Condition statement => issuance statement;

    Review some of the claims you created and look at the structure. See if you can pick out each part. Here is the one we looked at in the first section. Let’s break it down in to the basic parts.

    image

    The “if statement” condition:

    c:[Type == http://contoso.com/department]

    The special operator:

    =>

    The issuance statement:

    issue(Type = "http://adatum.com/department", Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, Value = c.Value, ValueType = c.ValueType);

    For each rule defined, AD FS checks the input claims, evaluates them against the condition, and issues the claim if the condition is true. You probably notice the variable “C” in the syntax. Think of “C” as an incoming claim that you can check conditions against, and use values from it to add to an outgoing claim. In this example, we are checking if there is an incoming claim that has a type that is “http://contoso.com/department”. We also use the values in this claim to assign the value of Issuer, OriginalIssuer, Value, and ValueType to the outgoing claim.

    There are exceptions to this that are discussed later (using ADD instead of ISSUE and issuing a claim without a condition statement).

    Issue a claim to everyone:

    In the Claims Rule Language, the condition part is optional. Therefore, you can choose to issue or add a claim regardless of what claims are incoming. To do this, start with the special operator “=>”.

    Syntax:

    => issue(type = "http://contoso.com/partner", value = "Adatum");

    This syntax will issue a claim type “http://contoso.com/partner” with a value of “Adatum”

    You could set similar rules for each Claims Provider Trust so that the Relying Party (or application) can know where the user came from.

    Using a Single Condition:

    In this example, we will look at a single condition statement. A basic claim rule checks to see if there is an incoming claim with a certain type and if so, issue a claim.

    c:[Type == "http://contoso.com/role"]
     => issue(claim = c);

    This syntax will check to see if there is an incoming claim with the type “http://contoso.com/role” and, if so, issue the exact same claim going out.

    You can create this claim rule using the GUI. Choose the template named “Pass Through or Filter an Incoming Claim” and choose the appropriate incoming claim type.

    image
    Screenshot: Entries for a simple pass through claim.

    You may also check for multiple values within your condition statement. For example, you can check and see if there is an incoming claim with a specific value. In the following example, we will check for an incoming claim with the type “http://contoso.com/role” that has the value of “Editors” and, if so, issue the exact same claim.

    c:[Type == "http://contoso.com/role", Value=="Editors"]
     => issue(claim = c);

    You can create this claim rule using the GUI as well. Choose “Pass Through or Filter an Incoming Claim”, choose the appropriate incoming claim type, select “Pass though only a specific claim value”, then enter the appropriate value.

    image
    Screenshot: Entries to pass through the Role claim if the value is “Editors”

    Using Multiple Conditions:

    Say you want to issue a claim only if the user has an Editor and has an Email claim and, if so, issue the Editor Role claim. To have multiple conditions, we will use multiple “C” variables. We will join the two condition statements with the special operator “&&”.

    c1:[Type == "http://contoso.com/role", Value=="Editors"] &&
    c2:[Type == "http://contoso.com/email"]
     => issue(claim = c1);

    The first condition (c1) checks to see if you have an incoming role claim with the value of Editors. The second condition (c2) checks to see if there is an incoming email claim. If both conditions are met, it will issue an outgoing claim identical to the incoming c1 claim.

    Combining Claim Values:

    Say you want to join information together from multiple incoming claims to form a single outgoing claim. The following example will check for an incoming claim type of "http://contoso.com/location" and “http://contoso.com/role”. If it has both, it will issue a new claim, “http://contoso.com/targeted”, combining the two values.

    c1:[Type == "http://contoso.com/location"] &&
    c2:[Type == "http://contoso.com/role"]
     => issue(Type="http://contoso.com/targeted", Value=c1.value+" "+c2.value);

    The resulting value is the value of the first claim (c1), plus a space, plus the value of the second claim (c2). You can combine static strings with the values of the claims using the special operator “+”. The example below shows a sample set of incoming claims, and the resulting output claim.

    Example Incoming Claims:
    "http://contoso.com/location" is "Seattle"
    "http://contoso.com/role" is "Editor"

    Example Outgoing Claim:
    "http://contoso.com/targeted" is "Seattle Editor"

    Using ADD instead of ISSUE:

    As mentioned in an earlier section, you can ADD a claim instead of ISSUE a claim. You may be wondering what the difference between these two statements are. Using the ADD command instead of the ISSUE command will add a claim to the incoming claim set. This will not add the claim to the outgoing token. Use this for adding placeholder data to use in subsequent claims rules.

    image

    This illustration was taken from a TechNet article. Here you can see that the first rule adds a role claim with the value of Editor. It then uses this newly added claim to create a greeting claim. Assuming these are the only two rules, the outgoing token will only have a greeting claim, not a role claim.

    I’ve outlined another example below.

    Sample Rule 1:

    c:[Type == "http://contoso.com/location", Value=="NYC"]
     => add(Type = "http://contoso.com/region", Value = "East");

    Sample Rule 2:

    c:[Type == "http://contoso.com/location", Value=="LAX"]
     => add(Type = "http://contoso.com/region", Value = "West");

    Sample Rule 3:

    c1:[Type == "http://contoso.com/location"] &&
    c2:[Type == "http://contoso.com/region"]
     => issue(Type="http://contoso.com/area", Value=c1.value+" "+c2.value);

    In this example, we have two rules that ADD claims to the incoming claim set, and one that issues a claim to the outgoing claim set. This will add a region claim to the incoming claim set and use that to create combine the values to create an area claim. The ADD functionality is very useful with the next section for aggregate functions.

    Using aggregate functions (EXISTS and NOT EXISTS):

    Using aggregate functions, you can issue or add a single output claim instead of getting an output claim for each match. The aggregate functions in the Claims Rule Language are EXISTS and NOT EXISTS.

    Say we want to use the location claim, but not all users have it. Using NOT EXISTS, we can add a universal location claim if the user does not have one.

    In Sample Rule 1, we will add a location claim with the value of “Unknown” if the user does not have a location claim. In Sample Rule 2, we will use that value to generate the “http://contoso.com/targeted” claim.

    Sample Rule 1:

    NOT EXISTS([Type == "http://contoso.com/location"])
     => add(Type = "http://contoso.com/location", Value = "Unknown");

    Sample Rule 2:

    c1:[Type == "http://contoso.com/location"] &&
    c2:[Type == "http://contoso.com/role"]
     => issue(Type="http://contoso.com/targeted", Value=c1.value+" "+c2.value);

    This way, users without the "http://contoso.com/location" claim can still get the "http://contoso.com/targeted" claim.

    Claims Rule Language, beyond this post:

    There is more you can do with the Claims Rule Language that goes beyond the scope of this blog post. If you would like to dig deeper by using Custom Attribute Stores and using Regular Expressions in the language, I’ve put up a TechNet Wiki article that contains these advanced topics and other sample syntax. In addition, some other articles may help with these topics.

    Understanding Claim Rule Language in AD FS 2.0:
    http://social.technet.microsoft.com/wiki/contents/articles/4792.aspx

    When to Use a Custom Claim Rule:
    http://technet.microsoft.com/en-us/library/ee913558(WS.10).aspx

    The Role of the Claim Rule Language:
    http://technet.microsoft.com/en-us/library/dd807118(WS.10).aspx

    The Role of the Claims Engine:
    http://technet.microsoft.com/en-us/library/ee913582(WS.10).aspx

    The Role of the Claims Pipeline:
    http://technet.microsoft.com/en-us/library/ee913585(WS.10).aspx

    Conclusion:

    Creating custom rules with the Claims Rule Language gives you more flexibility over the standard templates. Syntax familiarization takes a while, but with some practice, you should be able to write custom rules in no time. Start by writing custom rules instead of using the templates in your lab environment and build on those.

    - Joji “small claims court” Oshima

  • Oh man, I seriously overslept

    Hi folks, Ned here again. We haven’t posted anything in weeks here, and I apologize for that; a perfect storm (of busy) happened. I’ll have a mail sack tomorrow and in the meantime, here’s our old pal Mark with a DFSN article that shares a really slick technique. Enjoy.

    - Ned “excuses excuses” Pyle

  • DFS Override Referral Ordering, Messing with the Natural Order

    Hi everyone. This is your friendly (debatable) PFE, Mark Renoden again. Today I’m talking about DFS Override Referral Ordering – a seldom-used feature with an interesting benefit. For the purpose of this discussion, I’ll refer to the following Active Directory Site Diagram:

    image

    For the entire discussion, let’s suppose our client is in the site Spoke-A and is accessing a DFS Folder target

    Referral Configuration

    DFS Namespaces allow three options for the ordering of referrals. These are available in the Properties page of the namespace (and optionally overridden using the properties page of individual DFS folders)

    image

    Note the highlighted text. DFS referrals list DFS targets in the same site as the client, first. As an administrator, you have the option to return DFS targets outside the client’s site in random order, by lowest cost or not at all. The last option – Exclude targets outside of the client’s site – is also known as INSITE.

    To see an explanation of Active Directory Site Topology impact on DFS referrals, look here.

    I’m going to ignore “Random order” in this discussion. It’s self-explanatory – your DFS referral list for targets outside the client site is random (huh, I just explained it).

    Referrals Returned by Lowest Cost

    Assume I’ve configured my namespace to return referrals by lowest cost. For my client residing in site Spoke-A, the DFS referral process will offer the ordered list:

    DFS Target A
    DFS Target Hub
    <random ordering of DFS Target B and DFS Target C>
    <random ordering of DFS Target D and DFS Target E>

    Site Hub has a total cost of 100 from site Spoke-A and is listed first in the out-of-site order.

    Sites Spoke-B and Spoke-C have a total cost of 200 from site Spoke-A and are randomly listed next.

    Sites Spoke-D and Spoke-E have a total cost of 250 from site Spoke-A and are randomly listed last.

    DFS Override Referral Ordering

    Now let’s look at the setting we’ve all come to see. DFS Override Referral Ordering is a property set on a DFS target. This could be a DFS Namespace server or a DFS Folder target.

    image

    I’ll walk through the effects of each option shown here when set on DFS Target B.

    First Among All Targets

    The DFS referral process will offer the ordered list:

    DFS Target B
    DFS Target A
    DFS Target Hub
    DFS Target C
    <random ordering of DFS Target D and DFS Target E>

    Last Among All Targets

    The DFS referral process will offer the ordered list:

    DFS Target A
    DFS Target Hub
    DFS Target C
    <random ordering of DFS Target D and DFS Target E>
    DFS Target B

    First Among Targets of Equal Cost

    The DFS referral process will offer the ordered list:

    DFS Target A
    DFS Target Hub
    DFS Target B
    DFS Target C
    <random ordering of DFS Target D and DFS Target E>

    Last Among Targets of Equal Cost

    The DFS referral process will offer the ordered list:

    DFS Target A
    DFS Target Hub
    DFS Target C
    DFS Target B
    <random ordering of DFS Target D and DFS Target E>

    As you can see, these options give predictable results. Now for the cool bit …

    INSITE + DFS Override Referral Ordering

    As I mentioned earlier, INSITE (or Exclude targets outside of the client’s site) will cause the DFS referral process to offer only:

    DFS Target A

    If we combine this with DFS Override Referral Ordering set to Last Among all Targets on DFS Target Hub, the DFS referral process will offer:

    DFS Target A
    DFS Target Hub

    In other words, our local target first and the hub target second with no other out of site referrals. This would be desirable in environments where the network is not fully routable with client connectivity limited to the local site and the hub site.

    If more than one target has DFS Override Referral Ordering set to the same value, those targets will be returned in random order at the appropriate point in the referral list (i.e. site costing is ignored for those targets with override settings). For example, if DFS Target Hub and DFS Target B were configured with DFS Override Referral Ordering set to Last Among all Targets in combination with INSITE, the DFS referral process will offer:

    DFS Target A
    <random ordering of DFS Target Hub and DFS Target B>

    Lastly, First/Last Among Targets of Equal Cost have no effect when INSITE is set.

    Conclusion

    DFS Override Referral Ordering has some interesting applications and allows you to steer clients to targets in environments where site-costed referrals are not ideal.

    - Mark “Be Glad I’m not a Geneticist” Renoden