Chibueze Opata
Chibueze Opata

Reputation: 10034

How to determine if a string is a User SID?

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.

Upvotes: 13

Views: 10490

Answers (5)

Joels Elf
Joels Elf

Reputation: 784

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.

Edit: Prompted by @filimonic reply below I did some testing and looked into SIDs more and found this explanation for the string representation. Basically a SID is S-R-X-Y1-Y2-Yn-1-Yn, where:

Comment Description
S Indicates that the string is a SID
R Indicates the revision level
X Indicates the identifier authority value
Y Represents a series of subauthority values, where n is the number of values

There must be at least 1 Y value and X can be multiple digits.

Testing shows that IsAccountSID returns true only for "Windows account SID"s and so returns false for other valid SIDs. However new SecurityIdentifier([some string]) will throw an exception for bad SIDs, so you can still use it to check for generally valid SIDs use a try-catch as above.

Upvotes: 5

filimonic
filimonic

Reputation: 4644

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

Upvotes: 1

user2862372
user2862372

Reputation: 19

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

Upvotes: 1

Phillip Fleischer
Phillip Fleischer

Reputation: 1103

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+$

Upvotes: 11

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236268

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.

Upvotes: 30

Related Questions