Larry Osterman's WebLog

Confessions of an Old Fogey
Blog - Title

What is this thing called, SID?

What is this thing called, SID?

Rate This
  • Comments 24

One of the core data structures in the NT security infrastructure is the security identifier, or SID.

NT uses two data types to represent the SID, a PSID, which is just an alias for VOID *, and a SID, which is a more complicated structure (declared in winnt.h).

The contents of a SID can actually be rather fascinating.  Here’s the basic SID structure:

typedef struct _SID {
   BYTE  Revision;
   BYTE  SubAuthorityCount;
   SID_IDENTIFIER_AUTHORITY IdentifierAuthority;

Not a lot there, but some fascinating stuff none the less.  First let’s consider the Revision.  That’s always set to 1, for existing versions of NT.  There may be a future version of NT that defines other values, but not yet.

The next interesting field in a version 1 SID is the IdentifierAuthority.  The IdentifierAuthority is an array of 6 bytes, which describes which system “owns” the SID.  Essentially the IdentifierAuthority defines the meaning of the fields in the SubAuthority array, which is an array of DWORDs that is SubAuthorityCount in length (SubAuthorityCount can be any number between 1 and SID_MAX_SUB_AUTHORITIES (15 currently).  NT’s access check logic and SID validation logic treats the sub authority array as an opaque data structure, which can allow a resource manager to define their own semantics for the contents of the SubAuthority (this is strongly NOT recommended btw).

The “good stuff” in the SID (the stuff that makes a SID unique) lives in the SubAuthority array in the SID.  Each entry in the SubAuthority array is known as a RID (for Relative ID), more on this later. 

NT defines a string representation of the SID by constructing a string S-<Revision>-<IdentifierAuthority>-<SubAuthority0>-<SubAuthority1>-…-<SubAuthority<SubAuthorityCount>>.  For the purposes of constructing a string sid, the IdentifierAuthority is treated as a 48bit number.  You can convert between a binary SID and back by using the ConvertSidToStringSid and ConvertStringSidToSid APIs.

NT defines 6 IdentifierAuthorities, they are:

#define SECURITY_NULL_SID_AUTHORITY         {0,0,0,0,0,0}
#define SECURITY_WORLD_SID_AUTHORITY        {0,0,0,0,0,1}
#define SECURITY_LOCAL_SID_AUTHORITY        {0,0,0,0,0,2}
#define SECURITY_CREATOR_SID_AUTHORITY      {0,0,0,0,0,3}
#define SECURITY_NON_UNIQUE_AUTHORITY       {0,0,0,0,0,4}
#define SECURITY_NT_AUTHORITY               {0,0,0,0,0,5}

Taken in turn, they are:

·         SECURITY_NULL_SID_AUTHORITY: The “NULL” Sid authority is used to hold the “null” account SID, or S-1-0-0. 

·         SECURITY_WORLD_SID_AUTHORITY: The “World” Sid authority is used for the “Everyone” group, there’s only one SID in that group, S-1-1-0.

·         SECURITY_LOCAL_SID_AUTHORITY: The “Local” Sid authority is used for the “Local” group, again, there’s only one SID in that group, S-1-2-0.

·         SECURITY_CREATOR_SID_AUTHORITY: This Sid authority is responsible for the CREATOR_OWNER, CREATOR_GROUP, CREATOR_OWNER_SERVER and CREATOR_GROUP_SERVER well known SIDs, S-1-3-0, S-1-3-1, S-1-3-2 and S-1-3-3.
The SIDs under the CREATOR_SID_AUTHORITY are sort-of “meta-SIDs”.  Basically, when ACL inheritance is run, any ACEs that are owned by the SECURITY_CREATOR_SID_AUTHORITY are replaced (duplicated if the ACEs are inheritable) by ACEs that reflect the relevant principal that is performing the inheritance.  So a CREATOR_OWNER ACE will be replaced by the owner SID from the token of the user that’s performing the inheritance.


·         SECURITY_RESOURCE_MANAGER_AUTHORITY:  The “resource manager” authority is a catch-all that’s used for 3rd party resource managers. 

·         SECURITY_NT_AUTHORITY: The big kahuna.  This describes accounts that are managed by the NT security subsystem.

There are literally dozens of well known SIDs under the SECURITY_NT_AUTHORITY sub authority.  They range from NETWORK (S-1-5-2), a group added to the token of all users connected to the machine via a network, to S-1-5-5-X-Y, which is the SID for all authenticated NT users (X and Y will be replaced by values specific to your per-machine logon instance).

Each domain controller allocates RIDs for that domain, each principal created gets its own RID.  In general, for NT principals, the SID for each user in a domain will be identical, except for the last RID (that’s why it’s a “relative” ID – the value in SubAuthority[n] is relative to SubAuthority[n-1]).  In Windows NT (before Win2000), RID allocation was trivial – user accounts could only be created at the primary domain controller (there was only one  PDC, with multiple backup domain controllers) so the PDC could manage the list of RIDs that was allocated easily.  For Windows 2000 and later, user accounts can be created on any domain controller, so the RID allocation algorithm is somewhat more complicated.

Clearly a great deal of effort is made to ensure uniqueness of SIDs, if SIDs did not uniquely identify a user, then “bad things” would happen.

If you look in WINNT.H, you can find definitions for many of the RIDs for the builtin NT accounts, to form a SID for one of those accounts, you’d initialize a SID with the SECURITY_NT_AUTHORITY, and set the first SubAuthority to the RID of the desired account.  The good news is that because this is an extremely tedious process, the NT security guys defined an API (in Windows XP and later) named CreateWellKnownSid which can be used to create any of the “standard” SIDs.

Tomorrow: Some fun things you can do with a SID.


  • What about some, any, documentation on the restricted account. There is one MS article that mentions it, in relation to the RunAs dialog, that says it prevents registry writing. In a MS list of well known SIDS it is listed but that is all.

    One cannot get effective permissions on files or registry keys for this Restricted user/group. XP's dialogs has not heard of Restricted so ...

    Also Restricted in not recognised by User Rights either.
  • Do you mean the RestrictedCode user? Well, if you search MSDN for SECURITY_RESTRICTED_CODE_RID, you'll find:

    Which has a pointer to:

    To me, this implies that the restricted code group (S-1-5-C) is added to the token that is created by the CreateRestrictedToken API.

    This allows you to put an ACE in an ACL that would deny access to all restricted tokens.
  • Lovely gobblygook that. It still seems that noone actually knows what this new prominent feature does exactly.

    I ran a program with restricted and it errored. I can't think of a way to debug it while restricted (I'm not going to even attempt to start the VB IDE while restricted).

    But this raises another point. How many types of error dialogs are there in XP. Because I've just seen a new one - it's very polite but has no details at all and Alt + D doesn't work (and I'm sure I've seen Alt + D style dialogs). It's an XP two tone dialog. Error Reporting for programs is enabled. And when one closes it one gets a second error message, similar to the first, but one I've seen often before, also without error reporting or details. It looks like a conventional message box.

    There seems to be a lot of different types of error dialogs.
  • talk about gobbledygook, David. I actually understood Larry's, but yours are truly special.

    How do XP dialog control characters relate to the drilldown on security identifiers? If there's a connection, please enlighten us, because I think this is bound to be a good topic.
  • In the RunAs graphical command in XP a feature was added called "Protect My Computer ...".

    There is one reference to this in the MSDN library and one reference in the web. MSDN says, in an article in passing, that it prevents registry writes. The web reference says it uses the Restricted SID, which is mentioned in the PSDK but that all.

    However it prevents more than registry writes. I just wrote a program with file writes only in it and got Path/File Access Error (RunTime Error 75).

    However I tried to avooid writing anything so earlier used an old program that I had written, this written in same language/same version. This generated an error, but not from the Runtime library but from XP. Surprisingly it is a type of error dialog I've not seen before.

    There are many types of dialogs in XP. EG in Add Fonts it is a Win 3.1 dialog. I use classic scheme so what I see others mightn't. But there are two tone error dialogs (similar in style, but smaller to the Help - About dialogs) without error reporting or details. There are Win2000/ME error dialogs (have to press Alt + D to see details), there are standard XP error dialogs with error reporting, there are explorer.exe error dialogs that look like a message box but don't log as an error in event viewer (plus sometimes a second dialog saying the shell stopped or started), not to mention app error dialogs. PS MS Word still includes all the Win 2 or 1 dialogs - the ugly white ones without titlebars.

    I hate XP as it's not tested or designed. If you look at something like Win CE or Palm you find an integrated design philosophy. This is totally missing from XP and has been since 95 to a lesser extent and IE4 to a greater extent.

    So. I want to know what ticking "Protect My Computer ..", a in your face new undocumented feature, does. It's SID is S-1–5–12 and it's only description is Restricted (which I had sort of worked out from it's mnomic SECURITY_RESTRICTED_CODE_RID). The only MS reference to the feature states that it prevents registry writes - this it may do but it also appears to prevent file system writes as well. I can't use something if I don't know exactly what it does.


    1. What exactly does the protect my computer protect against. The docs larry gave are aimed at people wanting to create their own restricted users not what Windows does.

    2. It brings up the second point why is there so many different types of error dialogs. There should be 1. Why do they have different features and appearance.

    3 Why aren't both of the above documented. In the MS language I knew best many things were illegal because someone added code to make it not work because they thought it was illogical for it to work at the conceptual level - none of this was ever documented so I've spent years of my life writing programs to run experiments so I can write the program I'm trying to write. An pseudo example would be not allowed to enter a page number if the view was outline because someone thought it's illogical to do that and so we'll write code to error if it is tried and keep silent about it in the docs.

  • The VB6 IDE doesn't work at all unless you're an administrator, I've found, or at least for ActiveX components since it's continually monkeying with HKEY_CLASSES_ROOT.

    Aaron Margosis' PrivBar can show you what's in a restricted token. When you create one, basically every SID in your token - apart from your own - gets added again as a restricting SID. A restricting SID in a token tells AccessCheck and its kernel brethren to only consider this SID for Deny entries in ACLs; Allow entries (which might override inherited Deny entries) are not considered. If a restricting SID isn't explicitly Denied, you might end up being Allowed.

    This feature allows a user who would normally have high privileges to drop them temporarily. It's probably safer to work the other way around, though.

    You can't allow access specifically to restricted tokens, because the Restricted SID is added to the token as a restricting (deny-only) SID.

    S-1-5-5-X-Y is your logon SID. Each logon session gets its own logon SID. When you log on, WinLogon replaces the ACL on Winsta0, the interactive window station (a window station handles human-interface input and contains desktops, which contain windows) so that only the logon SID which it's just created can manipulate this window station. When you log in through Terminal Services, the window station created for your login also has an ACL applied so that that session is the only one which can manipulate the window station.

    This is a slight simplification: the Administrators group also has some read-only access, LocalSystem has unlimited access, and the logged-in user's principal has very limited additional rights.

    More on SIDs, logons, tokens, window stations and desktops in Keith Brown's excellent book "Programming Windows Security".
  • In general, for NT principals, the SID for each user in a domain will be identical, except for the last RID (that&#8217;s why it&#8217;s a &#8220;relative&#8221; ID &#8211; the value in SubAuthority[n] is relative to SubAuthority[n-1]). In Windows NT (before Win2000), RID allocation was trivial &#8211; user accounts could only be created at the primary domain controller (there was only one PDC, with multiple backup domain controllers) so the PDC could manage the list of RIDs that was allocated easily.
  • I have PrivBar installed (don't know why - I'm always admin). It doesn't seem to work if IE is started as Restricted. One can tick or untick the menu but no bar appears.

    Of course one needs explorer running to select restricted and I can't see a way to do it - maybe as a bat file - nope.

    Perhaps you saw on the privbar article my post on how the rules are not as simple as stated in that article re explorer seperate processes.

    I read the disallow part in the msdn. Presumbably I have no deny (and a check confirms) on the file that I tried to write (c:\test.txt).
  • Why does HKEY_LOCAL_MACHINE in w2k has an Allow Read ACE for the RESTRICTED SID, if this SID is meant only for denying purpose?
  • PrivBar works under a restricted setting. Its just mostlike the privbar is hanging off the screen. Since PrevBar cant keep its position.

    As for what "Protect My Computer .." does:

    Restricted SIDs:
    <Computer name>\None | mandatory enabled default
    Everyone | mandatory enabled default
    BUILTIN\Remote Desktop Users | mandatory enabled default
    BUILTIN\Users | mandatory enabled default
    NT AUTHORITY\INTERACTIVE | mandatory enabled default
    NT AUTHORITY\Authenticated Users | mandatory enabled default
    <login ID> | mandatory enabled default
    LOCAL | mandatory enabled default
    NT AUTHORITY\RESTRICTED | mandatory enabled default

    As for what the hell this is denying is another question.
  • I have to say that when checking permissions I go straight to the effective permissions tab. There is no Restricted there. But there is on all the dialogs on the way to effective permissions. Caught by not reading dialogs again.

    XP is the same as 2000 in it's Allow Permissions.

    I'm fairly certain it disallows all file and registry writes. But what else? Particulary for non file/registry objects and Priveledges (like Shutdown System).
  • You need to use regsvr32 on PrivBar as an administrator so that the registration information ends up in the "all users" part of HKEY_CLASSES_ROOT, I think. Also, you need to ensure that Everyone has read access to PrivBar.dll. Otherwise, IE simply gets an error from CoCreateInstance.

    ACLs can have two basic types of Access Control Entries (ACEs) - Allowed and Denied. An Allowed ACE matching a non-restricted SID in the token causes the matching bits to be permitted in the resulting access mask; once all bits are set, the request succeeds.

    A Denied ACE matching any SID in the token with any bits matching the requested access causes the access check to abort at that point. A restricting SID (one marked SE_GROUP_USE_FOR_DENY_ONLY) can never permit access, only deny.

    Your own SID is never restricted. This means that a restricted token created from your logon token can do whatever you can, unless a group you belong to is explicitly denied in the ACL. Windows XP's default for new objects created by an administrator is to set the object's owner to the creating account, unlike older versions and Server 2003, which set BUILTIN\Administrators. Since the default DACL includes CREATOR OWNER with Full Control, it actually means that you still have access to a lot of things you might not have if you'd installed software using a different account. This explains why I get errors from some programs at work that I don't get at home - most of my software at work was installed before we set up our domain, and the files and registry keys are therefore owned by a different principal from the one I now use to log on.

    Windows security is very flexible - far more so than Unix's standard owner/group/all read/write/execute bitmasks - but can also be very confusing.

    I should probably lock down %ProgramFiles% so it's owned by BUILTIN\Administrators and my principal isn't listed in the ACLs at all.
  • > A restricting SID (one marked
    > SE_GROUP_USE_FOR_DENY_ONLY) can never
    > permit access, only deny

    Actually, restricting SIDs and deny-only SIDs are two separate things. CreateRestrictedToken allows you to specify both.

    The best way to see what exactly "protect my computer" option does is to try it. Run cmd.exe with protection turned on, then run pview.exe from Platform SDK and look at the process token for cmd.exe. You will see both deny-only (disabled) SIDs and restricted SIDs (under Other...).

    > This allows you to put an ACE in an ACL
    > that would deny access to all restricted
    > tokens.

    Note that SECURITY_RESTRICTED_CODE_RID is added only to the list of restricting SIDs. So if you grant access to RESTRICTED, it doesn't mean arbitrary restricted code will be allowed access (access is only granted if both lists allow it - read the docs for CreateRestrictedToken for details).

    Essentially, RESTRICTED is used to give you back some of the rights that you lost by running a program as restricted code. For example, if you turn on "protect my computer" then you can't access your profile folder, but you can read from HCKU. This is because HCKU grants read access to RESTRICTED and %USERPROFILE% does not.

  • Only the NT4 version of Pview has a button for token and that is greyed out. All the other pview/pviewer (Pview now was pviewer in NT4)are of a different style (XP support tools/MSDN 7.1(whatever that is)/VS6) and only show memory stats.

    I'll have to find a CD with the sdk on it (I only have filed CDs I got 5 years ago - I gave up filing then - so I know exactly where 1998 sdk cd is but not any more recent). But that makes some sense what you are saying.

    This page will end up as the definitive documentation on this feature. But I can't believe MS built in a prominent GUI feature without any reference mention of it anywhere and a wrong article about how good it is.

    Larry will end up being known as the "Protect My Computer" king.
Page 1 of 2 (24 items) 12