Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Access registry of another user

I'm having a problem with the windows service I work on currently. Basically, I store some values in HKCU registry (from a GUI tool run as administrator) and from within that GUI I am starting a service. The service uses SYSTEM account to run, and I believe that's my problem - I can't access registry keys stored with my GUI tool inside the service, as it points to a different HKCU!

How can I "redirect" the service to use the HKCU of the user it was stored with? (Actually I can pass a user name to the service or SID if someone will point me how to retrieve it in my GUI, but I don't know what should I use to "change" the user to point to the correct one)

EDIT 1:

I use a static class to access registry, it is used by both GUI and Service and the function to retrieve the base key is (rootKey is string variable holding the subkey name):

private static RegistryKey GetBaseKey(bool writable = false)
{
    try
    {
        RegistryKey reg = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64);
        RegistryKey rk = reg?.OpenSubKey("SOFTWARE", writable)?.OpenSubKey(rootKey, writable);

        return rk;
    }
    catch (Exception ex)
    {
        // handle exceptions later
    }

    return null;
}

I have found WindowsIdentity class which can provide a handle (AccessToken) for current user, should I pass it as an argument to my service and use this handle to impersonate inside the service?

EDIT 2:

I have done some stuff but it doesn't work. What I tried:

CurrentUserToken = WindowsIdentity.GetCurrent().Token; // to get current identity token

then with ServiceController.Start I added CurrentUserToken.ToString() as an argument. Within my service I initialized RegistryUserToken (IntPtr) with the passed value and I'm stuck at:

WindowsIdentity RegUser = new WindowsIdentity(RegistryUserToken)

throwing exception:

Invalid token for impersonation - it cannot be duplicated

I tried the same with AccessToken of current instance of WindowsIdentity - same exception is thrown.

Can I at all go that way? Or should I try something different?

like image 791
pzaj Avatar asked Oct 24 '25 02:10

pzaj


1 Answers

I can give you two options: impersonate that user if you have their credentials or use idea that HKCU is a symbolic link for one of the keys under HKEY_USERS. For impersonating you can see this link. If you know the SID of that user, then you can find it in there. You can get the SID as so:

var account = new NTAccount("usernameThatYouNeed");
var identifier = (SecurityIdentifier)account.Translate(typeof(SecurityIdentifier));
var sid = identifier.Value;

I prefer impersonate. The second option is for case if you don't know that user's credentials. I dislike second option because it requires administrative rights to write in someone else's account.

like image 145
Yuriy Zaletskyy Avatar answered Oct 26 '25 17:10

Yuriy Zaletskyy