Search code examples
c#windowscredential-providerswinlogon

How can I get the SID of a user having from his/her username when the AD is not available?


I'm trying to get a user SID by using the following function:

return new NTAccount(username).Translate(typeof(SecurityIdentifier)).ToString();

Although this function works almost in all cases, when the machine in which this function runs is isolated from the Active Directory this usually gives me a system exception with the following associated message:

The trust relationship between this workstation and the primary domain failed. 

Is there a way to bypass this and permit the NTAccount function to work only by looking inside the locally available users?

Doing some testing, when launching a command with the User associated with the input of the NTAccount, and after having launched the command successfully, the Translate command starts working without it being dependent on the AD.

I am trying to use that function in a custom credential provider in order to enable a custom 2FA and I need the SID (an unique identifier) to be used for user identification in my backend service.


Solution

  • Have a look at registry path HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList.

    There are SIDs of users (including system Accounts too).

    Then look at HKEY_USERS\<SID>\Volatile Environment path.
    Values USERDOMAIN and USERNAME wait for you.

    Found here - Getting the Username from the HKEY_USERS values

    UPDATE

    Another approach - you are developing a CredentialProvider.
    So you can implement ICredentialProviderSetUserArray interface.

    Then you ca enumerate through users list and ask them for:

    • SID - ICredentialProviderUser::GetSid
    • Text SID - ICredentialProviderUser::GetStringValue(PKEY_Identity_PrimarySid)
    • Qualifed name - ICredentialProviderUser::GetStringValue(PKEY_Identity_QualifiedUserName)
    • User Name - ICredentialProviderUser::GetStringValue(PKEY_Identity_UserName)

    See MS Docs