Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I check whether a user is allowed to read / write a particular registry key?

Does anybody know how I can programmatically check (using C#) whether my program will be able to read / write a particular registry key (specifically: "SOFTWARE\Microsoft\Windows\CurrentVersion\Run")?

I am asking because my program has the option to enable or disable the 'run at startup' behaviour. I want to disable this option if the current user is not allowed to make changes to the registry. Is this key always allowed to be written by the current user, or is there the possibility that it has been locked down? If the latter, how do I check this?

I have seen several conflicting ways of checking registry permissions - but basically I can't find a way to check a specific key before I try to read it. I would rather perform the check before accessing the key than trying to access it and receive an exception.

Any help is much appreciated.

Tom

like image 444
HalliHax Avatar asked Jul 27 '09 15:07

HalliHax


People also ask

How do I check permissions on my registry?

To view or edit permissions on registry directories: Open the Registry Editor by entering regedit in Windows Run, and then clicking OK. In Registry Editor, navigate to the directory where you want to view or edit permissions. Right-click the directory, and then click Permissions....

How do I take full permissions control to edit protected registry keys?

Get Full Control Permissions to a Registry keyOn the Permission Entry dialog box, click the Select a principal link. Then, type your user name in the Enter the object name to select box and click Check Names, like you did earlier. Then, click OK. Check the Full Control box under Basic permissions and click OK.


2 Answers

The RegistryPermission class governs the security permissions around reg keys. To check if you may have write access to a permission you use it in the following manner:

RegistryPermission perm1 = new RegistryPermission(RegistryPermissionAccess.Write, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run");

You would then use the "Demand" method in a try/catch and return on failure (the raising of a security exception). On success you'd carry on and perform your update. Although this isn't quite what you want, a check on permissions before access, it is the accepted way of ensuring you have the permissions you need before you operate on the keys. In a fully structured manner this would equate to:

try
{
    RegistryPermission perm1 = new RegistryPermission(RegistryPermissionAccess.Write, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run");
    perm1.Demand();
}
catch (System.Security.SecurityException ex)
{
    return;
}

//Do your reg updates here

EDIT: Thinking on what I mentioned in the comment, here are extension methods to the RegistryPermission class for permission checks:

using System.Security.Permissions;
using System.Security;

public static class RegistryExtensions
{
    public static bool HavePermissionsOnKey(this RegistryPermission reg, RegistryPermissionAccess accessLevel, string key)
    {
        try
        {
            RegistryPermission r = new RegistryPermission(accessLevel, key);
            r.Demand();
            return true;
        }
        catch (SecurityException)
        {
            return false;
        }
    }

    public static bool CanWriteKey(this RegistryPermission reg, string key)
    {
        try
        {
            RegistryPermission r = new RegistryPermission(RegistryPermissionAccess.Write, key);
            r.Demand();
            return true;
        }
        catch (SecurityException)
        {
            return false;
        }
    }

    public static bool CanReadKey(this RegistryPermission reg, string key)
    {
        try
        {
            RegistryPermission r = new RegistryPermission(RegistryPermissionAccess.Read, key);
            r.Demand();
            return true;
        }
        catch (SecurityException)
        {
            return false;
        }
    }
}
like image 144
Wolfwyrd Avatar answered Sep 24 '22 17:09

Wolfwyrd


One thing you should know about permissions is that they are volatile. That means you could do your security check on the registry key, attempt to add your value only if the check passes, and then still fail with an insufficient access exception because the permissions changed in between when you made the check and when you acted on the results. This is possible even if they are consecutive statements in your program.

Granted security permissions tend to be relatively stable, but the chance still exists. This means that you must have code to handle the security exception, and if you have to do that anyway there's not really any point in making the check in the first place. Instead, put your time into making your exception handler a little bit better.

That said, "boo" to any app that wants to run something at start-up. YAGNI.

like image 28
Joel Coehoorn Avatar answered Sep 23 '22 17:09

Joel Coehoorn