3

Is it possible to access the registry of another user with Chef? I have the chef-client running as System and I want to modify the registry of User1? Is there a way to do this?

The registry_key resource provides a way to access HKEY_Users but I see no way to map the username to the SID.

TwistedTech
  • 275
  • 4
  • 13
  • I found a file [registry_helper.rb](https://github.com/discourse/discourse/blob/master/chef/cookbooks/windows/libraries/registry_helper.rb) in [the public repo](https://github.com/discourse/discourse) for [Discourse](http://www.discourse.org/), but the file itself seems to be part of [the official Chef windows cookbook](https://github.com/opscode-cookbooks/windows) and it contains a function `resolve_user_to_sid(username)` which probably helps to do what you (and I) are trying to do. – Kenny Evitt Jan 28 '15 at 21:07

1 Answers1

4

This ended up being mildly convoluted and looking at it makes me cringe. But it seems to work!

I wanted to modify another user's environment variables via the registry, as described in this Server Fault answer, but I also wanted to create the user with Chef. The problem then is that Windows doesn't create the registry hive for a user until they login.

If the relevant user definitely exists you can skip to Modifying a User's Registry Keys.

Forcing Windows to Create the User Registry Hive

The Chef builtin execute and batch resources don't seem to support supplying a password, so it doesn't seem like the user attribute for either can be used on Windows. But the official Chef Windows cookbook includes a windows_task resource that does include an attribute for specifying a user's password.

The problem now is granting the relevant user the Local Security Policy right to 'log on as a batch job'. To accomplish that, we can use SecEdit.

Make sure your cookbook depends on the official Chef windows cookbook; in your cookbook's metadata.rb file add:

depends "windows"

Here's the Chef recipe code:

group "BatchJobUsers" do
  append true
  members ["AnotherUser"]
  action :create
end

cookbook_file "BatchJobUsers-AddBatchLogonRight.inf" do
  path "#{ENV['TEMP']}\\BatchJobUsers-AddBatchLogonRight.inf"
  action :create_if_missing
end

execute "secedit" do
  cwd "#{ENV['TEMP']}"
  command "secedit /configure /db secedit.sdb /cfg BatchJobUsers-AddBatchLogonRight.inf"
end

windows_task "force-creation-of-AnotherUser-user-registry-hive" do
  command "echo Force creation of AnotherUser user registry hive"
  user "AnotherUser"
  password "password-for-another-user"
  action [:create, :run]
end

windows_task "force-creation-of-AnotherUser-user-registry-hive" do
  action :delete
end

You'll need to add a file to the COOKBOOK/files/default directory named BatchJobUsers-AddBatchLogonRight.inf; it should contain the following:

[Unicode]
Unicode=yes
[Version]
signature="$CHICAGO$"
Revision=1
[Privilege Rights]
SeBatchLogonRight = "BatchJobUsers"

Modifying a User's Registry Keys

Make sure your cookbook depends on the official Chef windows cookbook; in your cookbook's metadata.rb file add:

depends "windows"

In your recipe, add the following line:

::Chef::Recipe.send(:include, Windows::RegistryHelper)

Then you can use the function resolve_user_to_sid in your recipe like this:

get_user_sid = lambda { resolve_user_to_sid("USER_NAME") }

registry_key "Create environment variable registry keys" do
  key lazy { "HKEY_USERS\\#{ get_user_sid.call }\\Environment"
  values [{
      :name => "Variable",
      :type => :string,
      :data => "variable_data"
          }]
  recursive true
  action :create
end

The key attribute has to be lazily evaluated (i.e. evaluated during the converge phase of Chef running the recipe) to handle the user not existing.

Community
  • 1
  • 1
Kenny Evitt
  • 9,291
  • 5
  • 65
  • 93
  • 1
    That is very similar to what I ended up doing. Except I didn't know about the `resolve_user_to_sid` helper. I wrote an ohai plugin to gather the sids. Have you tested the code with `recursive true` and the user's hive not mounted? From what I have found the call will fail since `HKU\\` only allows hives to be mounted to it. – TwistedTech Jan 29 '15 at 21:42
  • @TwistedTech you're right that it's not working; I'll update it when it is. – Kenny Evitt Jan 29 '15 at 22:45
  • @TwistedTech I figured out a way to force Windows to create the user's registry hive. – Kenny Evitt Feb 03 '15 at 21:59
  • That's an ingenious way to create the hive. I haven't tried your code but does it keep it mounted after the task ends? I am not sure of all the circumstances that cause windows to (un)mount hives under HKU. Would the task have to be run before any HKU operations or just right after the user is created? – TwistedTech Feb 07 '15 at 21:13
  • @TwistedTech it seems to keep it mounted. I've been able to examine it in *regedit.exe* long after the recipe finishes. I haven't run the recipe with this code in several days and I just checked and the registry for the user is still accessible. – Kenny Evitt Feb 09 '15 at 00:13
  • @KennyEvitt I don't think the hive stays mounted anymore (at least, not in Server 2012 R2). While the chef client is running; if I keep refreshing regedit.exe, I can see the individual hives for each user appear and disappear very quickly. By the end of the chef run, only my current user's hive is still mounted. Which version of Windows Server did you run this on? – NullPointer Sep 29 '16 at 02:09
  • @NullPointer That's too bad if true. I'm guessing I was running this on Windows Server 2008 (R2) but maybe it was 2012 (or both). – Kenny Evitt Sep 29 '16 at 11:18