13

In Windows Operating System, user SIDs are represented with a string such as :

S-5-1-76-1812374880-3438888550-261701130-6117

Is there any way that I can identify that such a string is a valid User SID?

Thanks.

Chibueze Opata
  • 9,856
  • 7
  • 42
  • 65
  • 8
    Are you looking for validation or verification? For verification simply try to get an account from the SID. ([How can I convert from a SID to an account name in C#](http://stackoverflow.com/q/499053/1386111)) – Alvin Wong Apr 19 '13 at 08:01
  • No, I'm looking for verification. Thanks – Chibueze Opata Apr 19 '13 at 08:06
  • @ChibuezeOpata He suggested a solution for verification - `For verification simply try to get an account from the SID.` – DGibbs Apr 19 '13 at 08:08

5 Answers5

30

According to Security Identifiers description, SID has following form (it has one to fourteen subauthority values):

S-1-<identifier authority>-<sub1>-<sub2>-…-<subn>-<rid>

You can use regular expression to check if string matches this pattern:

string input = "S-5-1-76-1812374880-3438888550-261701130-6117";
string sidPattern = @"^S-\d-\d+-(\d+-){1,14}\d+$";
bool isValidFormat = Regex.IsMatch(input, sidPattern);

That will ensure that input string has valid format, but that will not prove that SID is valid. As suggested in comments, you should try get account if you need to check if you have valid SID.

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
11

I found this slight variation helpful which allows for some well known security identifiers. For example, the well known sid Everyone S-1-1-0

^S-\d-(\d+-){1,14}\d+$
Phillip Fleischer
  • 1,023
  • 12
  • 14
5

It's not a good idea to rely on a regex to check if a SID is valid. For one, the only valid SID version is 1 so this regex will think S-9-(\d+-){1,14}\d+ is valid when 9 is not a valid version. However fixing the regex to only allow version 1 would fail should there ever by a new SID version or even a completely new SID format. The better way to do this is let the system decide if the SID is valid. Just do this:

string notSureIfSID = "S-9-5-76-1812374880-3438888550-261701130-6117";
bool sidIsValid = false;
bool sidIsAccount = false;
try {
    SecurityIdentifier sid = new SecurityIdentifier(notSureIfSID);
    sidIsValid = true;
    sidIsAccount = sid.IsAccountSid();
}
catch (ArgumentException) {
    // Handle invalid SID
}

If the SID format is invalid (if, for instance the version is not 1 or the number of sub-authorities is over 15 or less than 1) the constructor will throw an ArgumentException. If you want to check if the SID is an actual existing account, just call IsAccountSid on the SecurityIdentifier.

Joels Elf
  • 714
  • 6
  • 10
  • `IsAccountSid()` just checks if sid matches `S-1-5-21-D-D-D-X` wheres `S-1-5-21` is default for all windows computers (domain or not), `D` is `Domain SID` and it is always same for all domain SIDsm and X is `RID` which increments almost for each new object in domain. This means that AD Group, Local account and Computer account will pass `IsAccountSID` as True. And you can loose functionality by ignoring Non-Account SIDs like `S-1-1-0 Everyone` – filimonic Oct 17 '21 at 22:22
1

The regex shoud be "S-\d-\d-\d+-\d+-\d+-\d+-\w+"

1

If you need to check SID is SID, use SecurityIdentifier constructor inside try\catch.

This will not validate that this sid belongs to anyone\anything in the whole world.


SIDs are

  • Always start with S
  • For current, always continue with -1- (this is SID version, and there is only one)
  • Continues with single SID_IDENTIFIER_AUTHORITY which is not more than 6 bytes, means this value is not more than 281474976710656 (15 characters)
  • Continues with [1..14] - separated SID_IDENTIFIER_SUBAUTHORITY which are not more than 4 bytes wide (10 characters max)
  • Optionally ends with RID - separated which is not more than 4 bytes wide (10 characters max)

More detailed refer to MS-AZOD, chapter 1.1.1.2

filimonic
  • 3,988
  • 2
  • 19
  • 26