registrychef-infrachef-windows

Access the registry of another user with Chef


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.


Solution

  • 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.