Who knew, right?

Token bloat, also known as the MaxTokenSize problem, is a Windows security condition which happens when domain administrators put too many security groups or SIDHistory items into a users token. The problem happens when the token needs to be sent across the network. There’s only so much practical room in the token (specifically the PAC or privileged attribute certificate) and so some SIDs might get left out.

The result can lead to unexpected access denied errors for users when trying to access resources (files, folders, web apps, whatever) if the SID for the group which allows them access didn’t make it into the pack.

Picture a suitcase filled to overflowing. You managed to close it but some stuff had to get left out.

Over the years the Microsoft authentication team added some fixes to help reduce the likelihood of this happening or make it more easily detectable when it does. The most notable thing was to make the compression used in the PAC better. Basically allowing you to pack more into the suitcase.

More information on this condition and other methods to combat it can be found here and here.

To help detect these problems easily I wrote a PowerShell script. You can click this link to get it from the TechNet Script Center.

The problem is more likely to occur when users migrated from Active Directory domain to Active Directory domain and the SIDHistory (user’s Security ID or SID) is retained from the prior domain  to preserve seamless access to resources for the user.

It is also more likely to happen if users are added to many security groups, and made exponentially worse when those groups are nested into other group memberships.

There are some ways to detect that issue is happening if you have Windows Server 2012 domain controllers (see link mentioned above). If you do not have 2012 DCs then you can use this script to check the token size of the logged on user. This script can also be handy for ruling out sizing issues, gauging how large the current sizes are, and even understanding where the size is coming from: SIDHistory, or groups and if groups then what groups scopes.

This script will query for the items which make up the token and then calculate the token size based on that dynamic result using the formula in KB327825. It will also give you a total of how many SIDs are in the SIDHistory for the user, how many of each group scope the user has, and whether the account is trusted for delegation or not (if it is the token size may be much larger).

The script must be ran in the user context and can only be ran interactively. In other words, you can send it to a user who is calling you about intermittent authorization issues to have them run it and have them send the result message back to you.

Notes:

  • The script does detect nested and recursive groups. Group nesting (a group which is a member of a group) is a common cause of token sizing concerns since it invisibly expands the size of the users token-most group membership queries for users will not find them.
  • If the problem is detected the error message below will appear along with the token details:

Problem detected. The token was too large for consistent authorization. Alter the maximum size per KB http://support.microsoft.com/kb/327825 and consider reducing direct and transitive group memberships.

  • The script does not do impersonation.
  • The script does not query the token directly. Instead it queries Active Directory for the items in the token which effect the token size, tallies them up and then does the math to come up with the estimated size.
  • This script uses LDAP queries to obtain the userAccountControl and the SIDHistory attributes.
  • The script uses the Security.Principal.WindowsIdentity]::GetCurrent().Groups method to query the directory the users current group memberships.
  • The script does not work in PowerShell 1.0, only 2.0 and above. As a consequence I recommend trying to use it only on Windows Vista/Windows Server 2008 RTM with PowerShell 2.0 and above.
  • Special thanks to Microsoft PFE Marcus Lerch who had a method for consistently handling DirectorySearcherResults objects. These objects appear differently otherwise based on OS platform and PowerShell version. Great blog post and excellent code, sir.

Sample Result:

Checking the token of user 'tspring' in domain NORTHAMERICA.CONTOSO.COM for token sizing issues per Knowledge Base article http://support.microsoft.com/kb/327825.

The computer is Windows 8 and is a client.

There are 167 groups in the token.

16 are domain global scope security groups.

5 are domain local security groups.

42 are universal security groups inside of the users domain.

95 are universal security groups outside of the users domain.

There are 0 SIDs in the users SIDHistory.

The current userAccountControl value is 512.

Token size is 5664 and the user is not trusted for delegation.

******************************************

Problem not detected.

Hopefully this script helps rule in or rule out token sizing problems in your enterprise environment.