Detecting whether a SID is well-known SID

You might think that the Is­Well­Known­Sid function would tell you whether a SID is well-known, but it doesn't. Rather, it tells you whether a SID exactly matches the well-known SID you specified. For example, you can ask, "Is this the Authenticated Users SID?" or "Is this the Everyone SID?" But you can't ask, "Is this any type of well-known SID?"

I guess you could enumerate through all the well-known SIDs, and check if your SID matches any of them, but that's getting kind of ugly.

If what you're interested in is whether this is a machine-relative SID (or a domain-relative SID, which is the special case where the machine is the domain controller), as opposed to a universal SID, you can check whether the SID format is S-1-5-21-#-#-#-#. All machine-relative SIDs have that form.

#define SECURITY_NT_NON_UNIQUE          (0x00000015L) // decimal 21

If you want to exclude machine\Administrator and other predefined machine-relative SIDs, you can verify that the last number (the RID) is greater than or equal to 1000.

Comments (15)
  1. Henke37 says:

    There is also the fun possibility of there being a new well known SID created later and causing compatibility problems.

  2. dave says:

    Re: new SID

    If I didn't know about it, I don't consider it "well-known"


  3. Henke37 says:

    Too bad that the code wasn't asking you. :)

  4. Kirby FC says:

    "Too bad that the code wasn't asking you. :)"

    Yes, good thing.  I don't know anyone named Sid.

  5. Gechurch says:


    "There is also the fun possibility of there being a new well known SID created later and causing compatibility problems."

    Given that there are around 4 well-known SIDs on a client PC and user SIDs start at 1000, I'm pretty confident that's not going to be a problem any time soon.

  6. Can anyone suggest a case where it would be necessary to decide whether a particular SID was well-known or not?

  7. Anonymous Coward says:

    Why would anyone define SECURITY_OTHER_ORGANIZATION_RID in hex if its value is 1000?

  8. cheong00 says:

    @Anonymous Coward: It has no difference to the compiler whether you express it in decimal, binary or hexadecimal. Those are just literals.

    Btw, when is the last time you see a number that's not in hexadecimal in a Microsoft's header file?

  9. Erik F says:

    @cheong00: Any #define FOO 0 is technically octal :-P

  10. @cheong00: the Win32 error codes (the first half of WinError.h) are declared in decimal.  (The COM codes in the second half are declared in hex, of course.)

  11. cheong00 says:

    @Erik F: Okay. :)

    @Harry Johnston: Oops. I forgot about that. :P

  12. dave says:

    >Can anyone suggest a case where it would be necessary to decide whether a particular SID was well-known or not?

    Yes (and have actually implemented it).

    When moving objects from one protection domain to another and doing some semi-intelligent ACL conversion. Basically, ACEs with well-known SIDs can be moved verbatim, and the rest need to be subject to conversion heuristics.

    Though in practice I think I did it as suggested in Raymond's original post,by looking for the 'non-unique' SID prefix.

  13. Killer{R} says:

    A bit off-topic, but IMHO it would be more logical to have well-known SIDs to be binary-defined and either be exported by some system dll (advapi32.dll is good enough) either even be defined like GUID's in some SDK .lib – unlikely that binary representation of SID's will be changed in future without backward compatibility cuz SIDs are part of SDs that stored on disks and network shares that means they must be backward (and better – even forward) compatible. In this case instead of calling IsWellKnownSid(sid, WinWorldSid) it would be necessary to call EqualSid(sid, WellKnownWorldSid).

    [Oh, you mean Create­Well­Known­Sid? -Raymond]
  14. You might think that you can identify well-known SIDs using LookupAccountSid and seeing if SID_NAME_USE is SidTypeWellKnownGroup.  However, this doesn't include well-known SIDs in the builtin domain, such as Administrators.  You could check for the builtin domain separately, I suppose, but Raymond's approach probably makes more sense (and would certainly be faster).

    If you're being paranoid about forwards compatibility, you might want to conclude that SIDs starting with S-1-5-21 are definitely per-domain, that SIDs which begin S-1-5-32 or return SidTypeWellKnownGroup are definitely well-known, and that anything else is "we don't know, because SIDs of this sort didn't exist when the code was written".

Comments are closed.

Skip to main content