Search code examples
c#permissionsregistry

Can I read registry permissions? If so, how?


I am experimenting with registry functions because I don't understand them yet. I am attempting to create two registry keys, one with read-only permission, and one with read-write permission. I have successfully created them, but I want to check that they have the proper permissions before I move forward. I know I could simply test them by attempting to manipulate them, but I'm thinking that there must be a way to just read a registry key's permissions.

Does anyone know how to do that?

I am using VisualStudio and writing in C#. I've been trying to search "Read registry key permissions", "get key permissions" and such things, but I just get a lot of information on WHAT read-only permission is and things like that. Useful, but not helpful to this specific task.

The code for creating those keys is as follows:

//Create ROKey - "ReadOnlyKey"
RegistryKey rKey = Registry.CurrentUser.CreateSubKey("ROKey", RegistryKeyPermissionCheck.ReadSubTree);
//Create WRKey - "ReadWriteKey"
RegistryKey wKey = Registry.CurrentUser.CreateSubKey("WRKey", RegistryKeyPermissionCheck.ReadWriteSubTree);

Edit:

At the suggestion of @itsme86, I have included the following code:

var security = rKey.GetAccessControl();
var rules = security.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
foreach (var rule in rules.Cast<AuthorizationRule>())
{
    Console.WriteLine(rule.IdentityReference.ToString());
}

security = wKey.GetAccessControl();
rules = security.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
foreach (var rule in rules.Cast<AuthorizationRule>()){
    Console.WriteLine(rule.IdentityReference.ToString());
}

Unfortunately, I am now getting the following error:

Error 1 'System.Security.AccessControl.AuthorizationRuleCollection' does not contain a definition for 'Cast' and no extension method 'Cast' accepting a first argument of type 'System.Security.AccessControl.AuthorizationRuleCollection' could be found (are you missing a using directive or an assembly reference?) C:\Users\DoD_Admin\Documents\Visual Studio 2013\Projects\RegistryManipulationTest\RegistryManipulationTest\rKeyTestClass.cs 249 40 RegistryManipulationTest

I'm using the "System" and "Microsoft.Win32" namespaces. Is there another namespace I should be using?

Edit 2:

I've added "Using Linq;" to the program, and now it recognizes "Cast". The downside is, it doesn't recognize the AuthorizationRule type. I tried "using System.Web.Configuration;", the namespace for the AuthorizationRule class, but now I'm told "The type or namespace name 'Configuration' does not exist in the namespace 'System.Web'".


Solution

  • What you want is RegistryKey.GetAccessControl(). It will return a RegistrySecurity object which you can call GetAccessRules() on. There's also a corresponding SetAccessControl() method if you want to change the permissions.

    You'll obviously need to be running your application with elevated permissions.

    Here's an example of how to use it:

    using (RegistryKey key = Registry.LocalMachine.OpenSubKey("software"))
    {
        var security = key.GetAccessControl();
        var rules = security.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
    
        foreach (var rule in rules.Cast<AuthorizationRule>())
        {
            Console.WriteLine(rule.IdentityReference.ToString());
        }
    }