Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EnsureRegistryValueOperation cannot write or delete registry values #96

Open
jimbobmcgee opened this issue Jan 17, 2025 · 0 comments
Open

Comments

@jimbobmcgee
Copy link

jimbobmcgee commented Jan 17, 2025

Both RegistryKey.OpenSubkey and RegistryKey.CreateSubkey methods have overloads which control whether subsequent code can write to the returned keys.

public Microsoft.Win32.RegistryKey? OpenSubKey (string name);
public Microsoft.Win32.RegistryKey? OpenSubKey (string name, bool writable);

public Microsoft.Win32.RegistryKey CreateSubKey (string subkey);
public Microsoft.Win32.RegistryKey CreateSubKey (string subkey, bool writable);    // since .NET4.6...

EnsureRegistryValueOperation only uses the single-parameter overload, which means that .NET only allows for read operations on the subkey. As such, using Ensure-RegistryValue in an OtterScript throws...

Unhandled exception: System.UnauthorizedAccessException: Cannot write to the registry key.
   at Microsoft.Win32.RegistryKey.EnsureWriteable()
   at Inedo.Extensions.Windows.Operations.Registry.EnsureRegistryValueOperation.RemoteConfigureAsync(IRemoteOperationExecutionContext context) in C:\Users\builds\AppData\Local\Temp\InedoAgent\BuildMaster\192.168.44.60\Temp\_E495994\Src\Windows\InedoExtension\Operations\Registry\EnsureRegistryValueOperation.cs:line 114
   at Inedo.Extensibility.Operations.RemoteEnsureOperation.RemoteConfigureJob.ExecuteAsync(IRemoteOperationExecutionContext context)
   at Inedo.Extensibility.Operations.RemoteOperationJob.ExecuteAsync(CancellationToken cancellationToken)
Unhandled exception: Inedo.ExecutionEngine.Executer.ExecutionFailureException: Exception of type 'Inedo.ExecutionEngine.Executer.ExecutionFailureException' was thrown.
   at Inedo.Extensibility.Operations.RemoteOperationJob.ExecuteAsync(CancellationToken cancellationToken)
   at Inedo.Agents.AgentCommand`1.Inedo.Agents.IAgentCommandWithResponse.ExecuteAsync(Stream responseStream)
   at Inedo.Agents.AgentCommandDispatcher.ExecuteCommandAsync(AgentCommand command, IClientConnection connection)

(OS-level permissions on the target registry key have been checked, and would permit writing.)

The fix would be to only open for read if you are checking for existence, and re-open for write if you are trying to change or delete the value -- that way, if the OS account does not have the permissions to write a key, this can be deferred until it knows it actually has to. It may be sufficient to open with false for the collect phase, and true for the remediation.

The quick-fix is to pass true to the two-parameter overload. This would likely cover 90% of the use-case.


Have just checked, and the same is true of EnsureRegistryKeyOperation too. You probably also want to add the logic which only creates the subkey if Exists = true, which you have in EnsureRegistryValueOperation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant