Windows Account Tokens

In Windows NT user rights are defined by access permissions (defined in ACLs on file system and other objects) and privileges (defined for user accounts). Privileges override permissions.

Privileges for a a user account are defined in an account token. Specifically, they are one kind of TokenInformation which can be of different kinds. The different kinds of TokenInformation object are defined in the TOKEN_INFORMATION_CLASS enumeration and are gotten using the GetTokenInformation function for the token. The kind of TokenInformation needed here is TokenPrivileges (one of the values of TOKEN_INFORMATION_CLASS).

The TokenPrivileges come in structure TOKEN_PRIVILEGES. TokenPrivileges contain a number of privileges.

Each privilege is a LUID_AND_ATTRIBUTES structure consisting of, you will love this, a LUID and a 32 bit value Attributes. The LUID is a structure containing two 32 bit values representing lower and upper doublewords of a 64 bit value (a quadword). (Windows NT defines a "word" as a 16 bit value, even on 32 bit and 64 bit systems.)

The LUID encodes the privileges, apparently on a per-system basic (as the LUID is unique for each system). The Attributes define whether the privilege is enabled or used or whatever else might be encoded there because all the documentation I could find was another MSDN entry for LUID_AND_ATTRIBUTES in the MSDN hardwars section.

SE_PRIVILEGE_ENABLED

The privilege is enabled. 

SE_PRIVILEGE_ENABLED_BY_DEFAULT

The privilege is enabled by default. 

SE_PRIVILEGE_USED_FOR_ACCESS

The privilege was used to gain access to an object or service. This flag is used to identify the relevant privileges in a set passed by a client application that may contain unnecessary privileges. 

The LookupPrivilegeName function returns the (readable) names of a token's privileges encoded in the token's LUID.

I wrote a crude test program that displays the privileges of a user.

It can display privileges for the current local user or for any domain user.

Specifically, for my local user (who is an administrator), it displays this:

localpriv

When started without elevation, it looks like this:

notelev

(So this is what User Account Control does to honest people!)

It really doesn't work for other local users.

So I decided to try out my little program with a domain user.

storefront

My domain user isn't an administrator.

domainpriv

But I can see the privileges of other users:

hubertpriv1

User "hubert" has the same privileges as my user.

Running the program against the domain administrator account crashes the program because the domain administrator holds vastly more privileges than my 1000-item array can handle. (Yes, its size can be increased.) Running the program as domain administrator returns the same 23 privileges held by my local administrator account outside the domain.


Related links

 © Andrew Brehm 2016