![]() |
Show Changes |
![]() |
|
![]() |
Recent Changes |
![]() |
Subscriptions |
![]() |
Lost and Found |
![]() |
Find References |
![]() |
Rename |
| Search |
History
| 3/10/2008 11:15:35 AM |
| PSWEB-keith |
![]() |
List all versions |
Most developers have a basic idea of what a security group in Windows is all about. It's a way to simplify administration by grouping users together. In a large system, a clearly defined group can allow an administrator to assign permissions for hundreds of files, registry keys, directory objects, and so on, without having to think about each individual user that will be in the group to which he’s granting permission. Similarly, when managing the group membership list, the administrator doesn't have to remember each and every resource to which the group has access. By clearly defining the semantics of the group, he can manage a more complex system than would otherwise be possible.
It would be nice if that were all there was to it, but in Windows there are four types of group and each has a different scope, overhead, and latency. Developers who care about security should know how they differ. Figure 20.1 summarizes the differences between them.

Figure 20.1 The four group types in Windows
The first three group types are housed in Active Directory and are always defined within a domain. The first two, universal and global, are pretty much equivalent as far as most developers are concerned. They are normally used by an administrator to categorize her enterprise. For example, she might create groups called SalesDept and EngineeringDept to track people based on their department. If this is a small business, it's likely that the entire sales force has accounts in a single domain, say DomA. In this case, she should create a single global group called DomA\SalesDept. Because global groups have forest scope, they can be used in any domain in the forest.1 This means that our administrator can now use a single group to grant access to the entire sales department, and she can do so on any resource in the entire forest. This is goodness!
Unfortunately global groups don't scale to a larger organization. You see, they have a very tight restriction on them. Take DomA\SalesDept. Only principals from DomA are allowed to be members of this group. If our administrator were working for a large company with many different offices, the sales department would be spread across many domains (domain boundaries are often decided based on geography to allow each region some autonomy of administration). To continue using global groups, she would need to create a SalesDept group in every domain that had salespeople. In a Windows NT 4 domain, this would be her only choice, and in order to grant access to the entire sales force, she would have to grant access to each of these groups. Imagine her agony each time a new domain was added or removed! Each resource that granted access to all of sales would have to be visited and its ACLs adjusted.
Windows 2000 solved this problem with the introduction of the universal group. Unlike global groups, universal groups make extensive use of the Global Catalog (GC) in Active Directory, allowing their entire membership list to be replicated among all domain controllers in the forest. A naïve system administrator might very well just create a single universal group to house all salespeople across all domains. This would work, but it wouldn't be very efficient, and the latency would be very high when adding or removing group members.2 A better approach would be to use a global group in each domain to gather together the individual salespeople and then use a single universal group to unify the global groups, as shown in Figure 20.2.
Groups defined in Active Directory can be nested. This method of "fanning out" group membership is more efficient because the universal group's membership list consists of only three SIDs: the three global groups. This reduces overhead in the GC and also reduces latency because adding a user to a global group can take effect immediately, assuming the user logs out and logs back in to get a new ticket (more on that later). For this reason global groups and universal groups are often used together by administrators to efficiently manage large groups of users, and because they have the same scope they can be regarded by application developers as largely the same.

Figure 20.2 Fanning out using universal and global groups
Let me skip ahead to the lowly local group. Local groups are a remnant from Windows NT 4, but they can be quite useful for developers, even on modern versions of Windows. You see, local groups are defined and scoped to a single machine; they aren't defined at the domain level. This means they can be easier to deploy for an application developer without much clout with the domain administrator, and they’re well suited to enabling role-based security in an application (WhatIsRoleBasedSecurity). Because they’re expanded last (more on this later), they’re nicely flexible: Although they can't be nested inside each other as domain groups can, they can hold principals and domain groups from any domain in the forest.
Finally we come to the domain local group, another idea introduced in Windows 2000. The domain local group is a lot like a local group in that it is expanded pretty late in the game and therefore can contain universal and global groups and principals from any domain. However, because it makes no use at all of the GC, its name and membership list are known only by the domain in which it is defined, making it a nice choice for implementing role-based security in a larger, distributed application such as a Web farm. It’s a lot easier to convince a domain administrator to create a few domain local groups for your application than to get her to create any global or universal groups, as the latter have a much broader impact on the forest. You can think of a domain local group as the big brother of the local group. A local group is scoped to a single machine whereas a domain local group is scoped to a single domain. A domain local group can be used to regulate access to resources throughout the domain where it's defined.
So far I've focused on the practical use of each group type. Now I want to focus on why groups work the way they do. Why do global groups have such onerous restrictions? What is this "scope" I keep referring to? Once I figured out the mechanics of how groups are expanded, a light turned on in my head and things really fell into place. I hope you'll have the same experience. Read on.

Figure 20.3 A scenario for exploring group expansion
Group membership is discovered during authentication (I need to talk about Kerberos a bit to explain this, so you may want to read WhatIsKerberos if you haven't already). Figure 20.3 shows a typical authentication scenario where a client (Alice) in one domain wants to access a resource on a machine (BobsMachine) in another domain. The way Kerberos works with cross domain authentication is as follows: Alice needs to transit the trust path from her domain to the resource domain,3 obtaining tickets along the way. Groups are communicated via tickets, so it's possible for each domain controller in the trust path to actually contribute groups. However, as of this writing only the client's domain (Denver) and the resource domain (NewZealand) will do so. The client's first stop is at her own domain controller (Denver). This is where global and universal groups are expanded, in that order. You see, global groups are designed to have low impact on the GC. Only the name of each global group is replicated in the GC for distribution throughout the forest, whereas the actual membership list is known only by the domain where the group is defined. This is why we must have Alice's domain authority (Denver) expand her global groups — it's the only domain that knows whether she's a member of these groups or not! And while Denver is at it, it may as well also expand all of Alice's universal groups, because the name and entire membership list for each universal group is replicated in the GC (thus the "high" impact I mentioned in Figure 20.1). Because all domain controllers have a replicated copy of the names and membership lists for all universal groups, Denver performs this expansion after expanding Alice's global groups. It then places the list of resulting groups (global and universal) in the ticket that it issues to Alice.
Alice sends this ticket to the next domain controller in the trust path, which copies the groups into the new ticket it issues for the next domain in the path. This continues until Alice reaches the resource domain (NewZealand). The resource domain is responsible for expanding any domain local groups because, just like Denver with its global groups, NewZealand is the only domain that knows the membership list of the domain local groups in use in the NewZealand domain. Heck, NewZealand is the only domain that knows anything about the domain local groups in it because domain local groups make no use at all of the GC. After expanding these groups, the entire group list is placed in the last ticket issued to Alice: This is the ticket that will authenticate her to the server process on BobsMachine.

Figure 20.4 Domain and local authorities expand groups during authentication.
So this final ticket has all of Alice's domain groups nicely flattened out in a list. When she sends this ticket to BobsMachine, the authentication plumbing in the server process hands it off to the local security authority on BobsMachine, which proceeds to expand local groups. Once all the groups are known, privileges (WhatIsAPrivilege) can be expanded. The user SID, group SIDs, and privilege identifiers are then tucked away into a token (WhatIsAToken), which references a brand new logon session (WhatIsALogonSession) for Alice.
At each step of this process, groups are expanded by looking at all previously expanded groups (and the user principal SID, of course), which leads us to the following rules that you'll find documented in the Windows help system.
The rule of thumb is that a group can have as a member any other type of group that has already been expanded. For example, the local group is the most flexible because it's expanded last. Pretty much anything can be a member of a local group because by the time the server's authority expands it, all the other group memberships are known. Global groups, on the other hand, because they’re expanded first, are heavily restricted. At the time they’re expanded, we know very little: The client's domain starts with the user's SID and begins expansion from there.
After seeing where the expansions occur, scoping becomes much more obvious. Why do global and universal groups "follow" you around the entire forest, no matter which server machine or domain is the target of your request? I hope Figure 20.4 helps answer this. No matter where the client looks for resources she always gets her initial ticket from her own domain, which expands global and universal groups. Global groups take advantage of this by not bothering to replicate their membership list in the GC. There's no need because the client must first request a ticket from her own domain before authenticating with any other principal. In other words, she'll always be talking to the one domain controller who knows the exact set of global groups in which she's a member. On the other hand, each server machine will define its own set of local groups and each domain will define its own set of domain local groups. If Alice decides to authenticate with a machine in the CentralAmerica domain, there's no need to talk to the NewZealand authority. The domain local groups come from CentralAmerica in this case.
In case some of you are wondering how all this works with NTLM, the older challenge-response protocol used in Windows NT 4 and still used today in some circumstances, we see a similar picture. The only difference is that the client doesn't transit the trust path. The client and server perform a three-leg challenge-response handshake; then the server takes the results and hands them up to its domain controller (the resource domain). This domain passes the request through to the client's domain, and group expansion occurs on the return trip in the same fashion: Global and universal groups are first expanded by the client's domain controller and sent back to the server's domain, where domain local groups are then expanded. The server's domain controller sends this entire list of domain groups back down to the server machine, which then expands local groups and privileges. Same deal, just a different mechanism.
One thing you may have noticed is that because groups are stored in Kerberos tickets (WhatIsKerberos), and those tickets are typically cached in the client's logon session (WhatIsALogonSession) for the entire workday, a server that receives a ticket from a client will necessarily get stale domain group membership information. This wasn't a problem with NTLM, where the server always contacted the domain controller with each client authentication. Kerberos tickets in Windows are thus a double-edged sword: The caching they provide improves scalability (domain controllers aren't as flooded with authentication requests), but it also increases latency for authorization attributes like group SIDs, which are communicated via cached tickets. By default, tickets must be renewed every ten hours, which allows the domain to inject fresh groups. However, you need to realize that a client who authenticated with a particular server earlier in the day will probably be using the same ticket to authenticate later in the day, and if her domain group membership has changed the change won't be reflected in her ticket unless she's purged her ticket cache and forced the operating system to retrieve a new ticket for her, which most naturally happens when she logs off the machine (destroying her logon session and all the tickets cached inside it) and logs back on before contacting that server.
Another thing you might consider is the potential for a client to modify her ticket and add privileged groups to it, like Domain Admins, which can directly affect her authorization level on just about any server with which she authenticates. Normal Kerberos tickets that clients use with server processes are encrypted using a key derived from the password for the server account. If the server account has a lousy password, the client won't have any trouble at all performing this attack. Well, my mother probably couldn't carry this out, but any respectable hacker certainly could, and it only takes one bored teenager to write up that exploit and publish it for anyone to use. So if you run your server under a custom daemon account (HowToChooseAnIdentityForADaemon), make absolutely sure your daemon account uses a very strong password. There's no reason you shouldn't use 20 characters or more, randomly generated, for every daemon account. No human needs to remember those passwords, and, as I discuss in WhatIsKerberos, poor server passwords in Kerberos can fall victim to brute force and dictionary attacks because an attacker can easily obtain ciphertext encrypted with the server's master key, which is derived from the server's password. Besides, you can get tools^5^ that help you manage passwords. Find one you trust and use it to manage your passwords.
1 Technically, groups I've labeled with "forest" scope can be used in any domain that trusts the domain in which the group is defined. You see, some external domains may be linked to the forest via manual trusts.
2 For example, if she makes the change to a universal group defined in Chicago, it may take quite a bit of time before the change is replicated to a domain in New Zealand.
3 I use the term resource domain to indicate the domain that hosts the server machine holding the resources (files, services, etc.) that a client wants to access. The distinction is purely temporal — any domain can play this role. We just need a way to identify the domain that hosts the server machine for a given request.
4 Note that in this list, when I say "from any domain" or "any domain user or group," I'm talking only about domains with which there is a trust relationship. This covers all domains in the forest and any domains that are linked to the forest via manual trusts.
5 Password Minder is a tool I wrote for this purpose, and I use it every day. You can download it from the book’s website. (See http://www.pluralsight.com/tools.aspx)
Keith's first book-in-a-wiki. If you would like to read the book online or order a physical copy to throw at annoying coworkers, surf to the HomePage. Please note that due to overwhelming wikispam, this particular wiki is no longer editable.
About FlexWiki.
Recent Topics