I am trying to convert a SID to a string and back again using ConvertSidToStringSid and ConvertStringSidToSid, but the conversion back is failing with error code 1337.
A test SID I created failed to make the round trip -- it caused ConvertStringSidToSid to fail with code 1337 (ERROR_INVALID_SID
). It looks like Windows represents identifier authorities with too many bytes using hex instead of decimal in the string representation, and ConvertStringSidToSid chokes. The documentation for ConvertStringSidToSid linked above says "You can use this function to retrieve a SID that the ConvertSidToStringSid function converted to string format," which suggests that what I am trying to do should be supported. Is there a better way to convert SIDs back and forth to their string representation?
Here is a minimal example that demonstrates the problem:
#include "pch.h"
#include <iostream>
#include <windows.h>
#include <sddl.h>
int main()
{
SID_IDENTIFIER_AUTHORITY sid_id_auth = { 1,2,3,4,5,6 };
PSID sid;
PSID new_sid;
LPWSTR string_sid;
// Create a new SID with the given ID authority and no sub-authorities
if (!AllocateAndInitializeSid(&sid_id_auth, 0, 0, 0, 0, 0, 0, 0, 0, 0, &sid)) {
std::cout << "Failed to allocate SID: error code " << GetLastError() << std::endl;
return 1;
}
// Stringify and print
if (!ConvertSidToStringSidW(sid, &string_sid)) {
std::cout << "Failed to convert to string: error code " << GetLastError() << std::endl;
FreeSid(sid);
return 2;
}
std::wcout << string_sid << std::endl;
// Destringify and print
if (ConvertStringSidToSidW(string_sid, &new_sid)) {
std::cout << "Success" << std::endl;
}
else {
std::cout << "Failed: error code " << GetLastError() << std::endl;
}
// Clean up
LocalFree(string_sid);
LocalFree(new_sid);
FreeSid(sid);
}
On my machine (Windows 10.0.16299, Visual Studio 15.9.7), this prints:
S-1-0x10203040506
Failed: error code 1337
You're passing an invalid value for nSubAuthorityCount
to AllocateAndInitializeSid
.
The documentation states:
Specifies the number of subauthorities to place in the SID. This parameter also identifies how many of the subauthority parameters have meaningful values. This parameter must contain a value from 1 to 8.
and
In this notation, the literal character "S" identifies the series of digits as a SID, R is the revision level, I is the identifier-authority value, and S… is one or more subauthority values.
Passing 0
is therefore wrong even though AllocateAndInitializeSid
returns TRUE
which might have been an oversight.
ConvertSidToStringSidW
doesn't seem to check for that requirement either which is why the conversion succeeds.
ConvertStringSidToSidW
fails because it expects a string in the format S-R-I-S….