From a95390d935fc720e4c20ccf7ed909d87224c445b Mon Sep 17 00:00:00 2001 From: rico89 Date: Thu, 26 Oct 2017 09:51:26 +0200 Subject: [PATCH 01/14] add support for deleting hash tables --- lib/puppet/provider/gpo/lgpo.rb | 16 ++++++++ spec/unit/puppet/provider/gpo/lgpo_spec.rb | 48 ++++++++++++++++------ 2 files changed, 52 insertions(+), 12 deletions(-) diff --git a/lib/puppet/provider/gpo/lgpo.rb b/lib/puppet/provider/gpo/lgpo.rb index c111d84..24de363 100644 --- a/lib/puppet/provider/gpo/lgpo.rb +++ b/lib/puppet/provider/gpo/lgpo.rb @@ -125,6 +125,8 @@ def set_value(val) out_file.write(out) end + remove_key(path['setting_key'], scope) if real_val == 'DELETEALLVALUES' + # Convert lgpo_import.txt to lgpo_import.pol with lgpo.exe lgpo_args = ['/r', out_file_path, '/w', out_polfile_path] lgpo(*lgpo_args) @@ -138,4 +140,18 @@ def set_value(val) lgpo(*lgpo_args) File.delete(out_polfile_path) end + + def remove_key(key, scope) + pol_file = "C:\\Windows\\System32\\GroupPolicy\\#{scope.capitalize}\\Registry.pol" + out_file_path = File.join(Puppet[:vardir], 'lgpo_import.txt') + gpos = lgpo('/parse', '/q', "/#{scope[0]}", pol_file) + gpos.split("\n\n").reject { |l| l.start_with? ';' }.each do |g| + split_g = g.split("\n") + unless split_g[1] == key + File.open(out_file_path, 'a') do |out_file| + out_file.write(split_g) + end + end + end + end end diff --git a/spec/unit/puppet/provider/gpo/lgpo_spec.rb b/spec/unit/puppet/provider/gpo/lgpo_spec.rb index b708070..1ef4bda 100644 --- a/spec/unit/puppet/provider/gpo/lgpo_spec.rb +++ b/spec/unit/puppet/provider/gpo/lgpo_spec.rb @@ -60,6 +60,25 @@ def stub_create(scope, content, cse) provider.class.expects(:lgpo).once.with(*args).returns(nil) expect(File).to receive(:delete).once.with(out_polfile).and_return(nil) end + def hash_delete(scope, content, cse) + file = StringIO.new + allow(File).to receive(:open).once.with(out_file, 'w').and_yield(file) + allow(file).to receive(:write).with(content) + + stub_lgpo_pol(scope, true) + allow(file).to receive(:open).at_least(:once).with(out_file, 'a').and_yield(file) + allow(file).to receive(:write).at_least(:once) + + args = ["/r", out_file] + args << '/w' << out_polfile + provider.class.expects(:lgpo).once.with(*args).returns(nil) + expect(File).to receive(:delete).once.with(out_file).and_return(nil) + + args = ["/#{scope[0]}", out_polfile] + args << '/e' << cse unless cse.nil? + provider.class.expects(:lgpo).once.with(*args).returns(nil) + expect(File).to receive(:delete).once.with(out_polfile).and_return(nil) + end context 'when listing instances' do context 'when the gpo file exists' do @@ -211,32 +230,37 @@ def stub_create(scope, content, cse) end end - context 'when we need to delete a HASHTABLE instance' do + context 'when there is a cse' do let(:params) do { - :title => 'machine::windowsdefender::exclusions_processes::exclusions_processeslist', - :ensure => :deleted, + :title => 'admpwd::pol_admpwd_enabled::admpwdenabled', + :value => '1', :provider => 'lgpo', } end - it 'should create a resource without /e' do - stub_create('machine', "computer\nSoftware\\Policies\\Microsoft\\Windows Defender\\Exclusions\\Processes\n*\nDELETEALLVALUES", nil) + + it 'should create a resource with /e' do + stub_create('machine', "computer\nSoftware\\Policies\\Microsoft Services\\AdmPwd\nAdmPwdEnabled\nDELETE", '{D76B9641-3288-4f75-942D-087DE603E3EA}') provider.delete end end - - context 'when there is a cse' do + end + context 'when deleting a hash resource' do + before :each do + expect(Puppet).to receive(:[]).exactly(3).times.with(:vardir).and_return('C:\ProgramData\PuppetLabs\Puppet\var') + end + + context 'when we need to delete a HASHTABLE instance' do let(:params) do { - :title => 'admpwd::pol_admpwd_enabled::admpwdenabled', - :value => '1', + :title => 'machine::windowsdefender::exclusions_processes::exclusions_processeslist', + :ensure => :deleted, :provider => 'lgpo', } end - - it 'should create a resource with /e' do - stub_create('machine', "computer\nSoftware\\Policies\\Microsoft Services\\AdmPwd\nAdmPwdEnabled\nDELETE", '{D76B9641-3288-4f75-942D-087DE603E3EA}') + it 'should create a resource without /e' do + hash_delete('machine', "computer\nSoftware\\Policies\\Microsoft\\Windows Defender\\Exclusions\\Processes\n*\nDELETEALLVALUES", nil) provider.delete end From 5561f99283bac332fae7165bd494a6222e783fb7 Mon Sep 17 00:00:00 2001 From: rico89 Date: Fri, 27 Oct 2017 18:45:03 +0200 Subject: [PATCH 02/14] fixing errors in spec for the deletion of hashtad instances --- lib/puppet/provider/gpo/lgpo.rb | 14 ++++++--- spec/unit/puppet/provider/gpo/lgpo_spec.rb | 35 +++++++++++++++++----- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/lib/puppet/provider/gpo/lgpo.rb b/lib/puppet/provider/gpo/lgpo.rb index 24de363..bd7b790 100644 --- a/lib/puppet/provider/gpo/lgpo.rb +++ b/lib/puppet/provider/gpo/lgpo.rb @@ -132,6 +132,11 @@ def set_value(val) lgpo(*lgpo_args) File.delete(out_file_path) + if real_val == 'DELETEALLVALUES' + pol_file = "C:\\Windows\\System32\\GroupPolicy\\#{scope.capitalize}\\Registry.pol" + File.delete(pol_file) + end + # import lgpo_import.pol with lgpo.exe lgpo_args = ["/#{scope[0]}", out_polfile_path] if guid = path['policy_cse'] @@ -143,12 +148,13 @@ def set_value(val) def remove_key(key, scope) pol_file = "C:\\Windows\\System32\\GroupPolicy\\#{scope.capitalize}\\Registry.pol" + return [] unless File.file?(pol_file) out_file_path = File.join(Puppet[:vardir], 'lgpo_import.txt') gpos = lgpo('/parse', '/q', "/#{scope[0]}", pol_file) - gpos.split("\n\n").reject { |l| l.start_with? ';' }.each do |g| - split_g = g.split("\n") - unless split_g[1] == key - File.open(out_file_path, 'a') do |out_file| + out_file = File.open(out_file_path, 'a') do |out_file| + gpos.split("\n\n").reject { |l| l.start_with? ';' }.each do |g| + split_g = g.split("\n") + unless split_g[1] == key out_file.write(split_g) end end diff --git a/spec/unit/puppet/provider/gpo/lgpo_spec.rb b/spec/unit/puppet/provider/gpo/lgpo_spec.rb index 1ef4bda..8a02546 100644 --- a/spec/unit/puppet/provider/gpo/lgpo_spec.rb +++ b/spec/unit/puppet/provider/gpo/lgpo_spec.rb @@ -60,20 +60,39 @@ def stub_create(scope, content, cse) provider.class.expects(:lgpo).once.with(*args).returns(nil) expect(File).to receive(:delete).once.with(out_polfile).and_return(nil) end - def hash_delete(scope, content, cse) - file = StringIO.new - allow(File).to receive(:open).once.with(out_file, 'w').and_yield(file) - allow(file).to receive(:write).with(content) - stub_lgpo_pol(scope, true) - allow(file).to receive(:open).at_least(:once).with(out_file, 'a').and_yield(file) - allow(file).to receive(:write).at_least(:once) + def stub_hash_delete(scope, content, cse) + # This is the initial write to the gpo_import_file which writes the deleteallvalues statement for a hashed instance + lgpo_import_file = StringIO.new + expect(File).to receive(:open).once.with(out_file, 'w').and_yield(lgpo_import_file) + expect(lgpo_import_file).to receive(:write).with(content) + + # pol file should get read one time initiated by the lgpo.exe call + pol_file = "C:\\Windows\\System32\\GroupPolicy\\#{scope.capitalize}\\Registry.pol" + allow(File).to receive(:file?) # Catch all calls + expect(File).to receive(:file?).once.with(pol_file).and_return(true) + + # the stub for the pol lgpo call needs to be added here in order to simulate output + if true + provider.class.expects(:lgpo).once.with('/parse', '/q', "/#{scope[0]}", pol_file) + .returns(File.read(File.join( + File.dirname(__FILE__), + "../../../../fixtures/unit/puppet/provider/gpo/lgpo/#{scope}/full.out"))) + else + provider.class.expects(:lgpo).never + end + + # This is the subsequent writes to the lgpo file with the filtered content from the parsing + expect(File).to receive(:open).once.with(out_file, 'a').and_yield(lgpo_import_file) + expect(lgpo_import_file).to receive(:write).at_least(:once) args = ["/r", out_file] args << '/w' << out_polfile provider.class.expects(:lgpo).once.with(*args).returns(nil) expect(File).to receive(:delete).once.with(out_file).and_return(nil) + expect(File).to receive(:delete).once.with(pol_file).and_return(nil) + args = ["/#{scope[0]}", out_polfile] args << '/e' << cse unless cse.nil? provider.class.expects(:lgpo).once.with(*args).returns(nil) @@ -260,7 +279,7 @@ def hash_delete(scope, content, cse) } end it 'should create a resource without /e' do - hash_delete('machine', "computer\nSoftware\\Policies\\Microsoft\\Windows Defender\\Exclusions\\Processes\n*\nDELETEALLVALUES", nil) + stub_hash_delete('machine', "computer\nSoftware\\Policies\\Microsoft\\Windows Defender\\Exclusions\\Processes\n*\nDELETEALLVALUES", nil) provider.delete end From 4109c27e4b3d790f0032b96ed1213f26083601da Mon Sep 17 00:00:00 2001 From: rico89 Date: Fri, 27 Oct 2017 22:15:57 +0200 Subject: [PATCH 03/14] supporting the setting of hash values and added test for that --- lib/puppet/provider/gpo/lgpo.rb | 24 ++++++++++++------- spec/unit/puppet/provider/gpo/lgpo_spec.rb | 27 ++++++++++++++++++---- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/lib/puppet/provider/gpo/lgpo.rb b/lib/puppet/provider/gpo/lgpo.rb index bd7b790..ad638cc 100644 --- a/lib/puppet/provider/gpo/lgpo.rb +++ b/lib/puppet/provider/gpo/lgpo.rb @@ -5,7 +5,7 @@ commands :lgpo => 'lgpo.exe' def exists? - @property_hash[:ensure] == :present + @property_hash[:ensure] == :present || @property_hash[:ensure] == :deleted end def create @@ -110,19 +110,27 @@ def set_value(val) raise Puppet::Error, "Wrong path: '#{path}'" end - out_scope = scope == 'machine' ? 'computer' : scope + out_scope = (scope == 'machine' ? 'computer' : scope).capitalize delete_value = setting_valuetype == '[HASHTABLE]' ? 'DELETEALLVALUES' : 'DELETE' + + out = Array.new + if setting_valuetype == '[HASHTABLE]' and val != 'DELETE' + val.each do |k, v| + out << "#{out_scope}\n#{path['setting_key']}\n#{k}\nSZ:#{v}" + end + else + real_val = val == 'DELETE' ? delete_value : "#{path['setting_valuetype'].gsub('REG_', '')}:#{val}" + setting_valuename = real_val == 'DELETEALLVALUES' ? '*' : path['setting_valuename'] - real_val = val == 'DELETE' ? delete_value : "#{path['setting_valuetype'].gsub('REG_', '')}:#{val}" - setting_valuename = real_val == 'DELETEALLVALUES' ? '*' : path['setting_valuename'] + out << "#{out_scope}\n#{path['setting_key']}\n#{setting_valuename}\n#{real_val}" - out = "#{out_scope}\n#{path['setting_key']}\n#{setting_valuename}\n#{real_val}" + end out_file_path = File.join(Puppet[:vardir], 'lgpo_import.txt') out_polfile_path = File.join(Puppet[:vardir], 'lgpo_import.pol') File.open(out_file_path, 'w') do |out_file| - out_file.write(out) + out_file.write(out.join("\n\n")) end remove_key(path['setting_key'], scope) if real_val == 'DELETEALLVALUES' @@ -155,9 +163,9 @@ def remove_key(key, scope) gpos.split("\n\n").reject { |l| l.start_with? ';' }.each do |g| split_g = g.split("\n") unless split_g[1] == key - out_file.write(split_g) + out_file.write("\n\n#{g}") end end end end -end +end \ No newline at end of file diff --git a/spec/unit/puppet/provider/gpo/lgpo_spec.rb b/spec/unit/puppet/provider/gpo/lgpo_spec.rb index 8a02546..0beb1fb 100644 --- a/spec/unit/puppet/provider/gpo/lgpo_spec.rb +++ b/spec/unit/puppet/provider/gpo/lgpo_spec.rb @@ -91,6 +91,7 @@ def stub_hash_delete(scope, content, cse) provider.class.expects(:lgpo).once.with(*args).returns(nil) expect(File).to receive(:delete).once.with(out_file).and_return(nil) + # Polfile needs to be deleted so a fresh import can be done from the filtered lgpo file expect(File).to receive(:delete).once.with(pol_file).and_return(nil) args = ["/#{scope[0]}", out_polfile] @@ -213,7 +214,7 @@ def stub_hash_delete(scope, content, cse) context 'when there is no cse' do it 'should create a resource without /e' do - stub_create('machine', "computer\nSoftware\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU\nAllowMUUpdateService\nDWORD:1", nil) + stub_create('machine', "Computer\nSoftware\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU\nAllowMUUpdateService\nDWORD:1", nil) provider.create end @@ -229,7 +230,23 @@ def stub_hash_delete(scope, content, cse) end it 'should create a resource with /e' do - stub_create('machine', "computer\nSoftware\\Policies\\Microsoft Services\\AdmPwd\nAdmPwdEnabled\nDWORD:1", '{D76B9641-3288-4f75-942D-087DE603E3EA}') + stub_create('machine', "Computer\nSoftware\\Policies\\Microsoft Services\\AdmPwd\nAdmPwdEnabled\nDWORD:1", '{D76B9641-3288-4f75-942D-087DE603E3EA}') + + provider.create + end + end + + context 'when resource contain a hash value' do + let(:params) do + { + :title => 'windowsdefender::exclusions_processes::exclusions_processeslist', + :value => {'c:\windows\process0.exe' => '0', 'c:\windows\process1.exe' => '0',}, + :provider => 'lgpo', + } + end + + it 'should create two entries in LGPO import file' do + stub_create('machine', "Computer\nSoftware\\Policies\\Microsoft\\Windows Defender\\Exclusions\\Processes\nc:\\windows\\process0.exe\nSZ:0\n\nComputer\nSoftware\\Policies\\Microsoft\\Windows Defender\\Exclusions\\Processes\nc:\\windows\\process1.exe\nSZ:0", nil) provider.create end @@ -243,7 +260,7 @@ def stub_hash_delete(scope, content, cse) context 'when there is no cse' do it 'should create a resource without /e' do - stub_create('machine', "computer\nSoftware\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU\nAllowMUUpdateService\nDELETE", nil) + stub_create('machine', "Computer\nSoftware\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU\nAllowMUUpdateService\nDELETE", nil) provider.delete end @@ -259,7 +276,7 @@ def stub_hash_delete(scope, content, cse) end it 'should create a resource with /e' do - stub_create('machine', "computer\nSoftware\\Policies\\Microsoft Services\\AdmPwd\nAdmPwdEnabled\nDELETE", '{D76B9641-3288-4f75-942D-087DE603E3EA}') + stub_create('machine', "Computer\nSoftware\\Policies\\Microsoft Services\\AdmPwd\nAdmPwdEnabled\nDELETE", '{D76B9641-3288-4f75-942D-087DE603E3EA}') provider.delete end @@ -279,7 +296,7 @@ def stub_hash_delete(scope, content, cse) } end it 'should create a resource without /e' do - stub_hash_delete('machine', "computer\nSoftware\\Policies\\Microsoft\\Windows Defender\\Exclusions\\Processes\n*\nDELETEALLVALUES", nil) + stub_hash_delete('machine', "Computer\nSoftware\\Policies\\Microsoft\\Windows Defender\\Exclusions\\Processes\n*\nDELETEALLVALUES", nil) provider.delete end From 1a1c93e139f89ebd859fe980771d14464b8efbcc Mon Sep 17 00:00:00 2001 From: rico89 Date: Fri, 27 Oct 2017 22:56:53 +0200 Subject: [PATCH 04/14] fix issue with creating hash resources and modified test accordingly --- lib/puppet/provider/gpo/lgpo.rb | 4 ++-- spec/unit/puppet/provider/gpo/lgpo_spec.rb | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/puppet/provider/gpo/lgpo.rb b/lib/puppet/provider/gpo/lgpo.rb index ad638cc..388fb08 100644 --- a/lib/puppet/provider/gpo/lgpo.rb +++ b/lib/puppet/provider/gpo/lgpo.rb @@ -133,14 +133,14 @@ def set_value(val) out_file.write(out.join("\n\n")) end - remove_key(path['setting_key'], scope) if real_val == 'DELETEALLVALUES' + remove_key(path['setting_key'], scope) if setting_valuetype == '[HASHTABLE]' # Convert lgpo_import.txt to lgpo_import.pol with lgpo.exe lgpo_args = ['/r', out_file_path, '/w', out_polfile_path] lgpo(*lgpo_args) File.delete(out_file_path) - if real_val == 'DELETEALLVALUES' + if setting_valuetype == '[HASHTABLE]' pol_file = "C:\\Windows\\System32\\GroupPolicy\\#{scope.capitalize}\\Registry.pol" File.delete(pol_file) end diff --git a/spec/unit/puppet/provider/gpo/lgpo_spec.rb b/spec/unit/puppet/provider/gpo/lgpo_spec.rb index 0beb1fb..ae6896a 100644 --- a/spec/unit/puppet/provider/gpo/lgpo_spec.rb +++ b/spec/unit/puppet/provider/gpo/lgpo_spec.rb @@ -247,7 +247,8 @@ def stub_hash_delete(scope, content, cse) it 'should create two entries in LGPO import file' do stub_create('machine', "Computer\nSoftware\\Policies\\Microsoft\\Windows Defender\\Exclusions\\Processes\nc:\\windows\\process0.exe\nSZ:0\n\nComputer\nSoftware\\Policies\\Microsoft\\Windows Defender\\Exclusions\\Processes\nc:\\windows\\process1.exe\nSZ:0", nil) - + pol_file = "C:\\Windows\\System32\\GroupPolicy\\Machine\\Registry.pol" + expect(File).to receive(:delete).once.with(pol_file).and_return(nil) provider.create end end From 331f72379dd295edd6ebdfaf23df4e6e4d7e5086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Fri, 4 May 2018 10:32:29 +0200 Subject: [PATCH 05/14] Properly manage :deleted with insync? --- lib/puppet/provider/gpo/lgpo.rb | 6 +++++- lib/puppet/type/gpo.rb | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/puppet/provider/gpo/lgpo.rb b/lib/puppet/provider/gpo/lgpo.rb index 388fb08..7840b7e 100644 --- a/lib/puppet/provider/gpo/lgpo.rb +++ b/lib/puppet/provider/gpo/lgpo.rb @@ -5,7 +5,11 @@ commands :lgpo => 'lgpo.exe' def exists? - @property_hash[:ensure] == :present || @property_hash[:ensure] == :deleted + @property_hash[:ensure] == :present + end + + def deleted? + @property_hash[:ensure] == :deleted end def create diff --git a/lib/puppet/type/gpo.rb b/lib/puppet/type/gpo.rb index 253674f..bd99802 100644 --- a/lib/puppet/type/gpo.rb +++ b/lib/puppet/type/gpo.rb @@ -12,6 +12,11 @@ newvalue(:deleted) do provider.delete end + + def insync?(is) + return true if should == :deleted and provider.deleted? + super + end end newparam(:name, :namevar => true) do From ac7020d7ee1c986eb4d9635f89a484ef64c56a9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Fri, 4 May 2018 10:32:42 +0200 Subject: [PATCH 06/14] Fix spaces --- lib/puppet/provider/gpo/lgpo.rb | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/puppet/provider/gpo/lgpo.rb b/lib/puppet/provider/gpo/lgpo.rb index 7840b7e..182501c 100644 --- a/lib/puppet/provider/gpo/lgpo.rb +++ b/lib/puppet/provider/gpo/lgpo.rb @@ -55,7 +55,7 @@ def self.instances ['machine', 'user'].map do |scope| pol_file = "C:\\Windows\\System32\\GroupPolicy\\#{scope.capitalize}\\Registry.pol" next [] unless File.file?(pol_file) - + resources = Hash.new gpos = lgpo('/parse', '/q', "/#{scope[0]}", pol_file) @@ -96,10 +96,10 @@ def self.instances :value => value, } end - + end resources.map{|k, v| new(v)} - end.flatten + end.flatten end def set_value(val) @@ -115,15 +115,14 @@ def set_value(val) end out_scope = (scope == 'machine' ? 'computer' : scope).capitalize - delete_value = setting_valuetype == '[HASHTABLE]' ? 'DELETEALLVALUES' : 'DELETE' - + out = Array.new if setting_valuetype == '[HASHTABLE]' and val != 'DELETE' val.each do |k, v| out << "#{out_scope}\n#{path['setting_key']}\n#{k}\nSZ:#{v}" end - else + else real_val = val == 'DELETE' ? delete_value : "#{path['setting_valuetype'].gsub('REG_', '')}:#{val}" setting_valuename = real_val == 'DELETEALLVALUES' ? '*' : path['setting_valuename'] @@ -172,4 +171,4 @@ def remove_key(key, scope) end end end -end \ No newline at end of file +end From 7ade80b13f946d400532861a752379c410d3ea4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Fri, 4 May 2018 10:32:57 +0200 Subject: [PATCH 07/14] Remove out_file as it is never used --- lib/puppet/provider/gpo/lgpo.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/puppet/provider/gpo/lgpo.rb b/lib/puppet/provider/gpo/lgpo.rb index 182501c..bd2ab17 100644 --- a/lib/puppet/provider/gpo/lgpo.rb +++ b/lib/puppet/provider/gpo/lgpo.rb @@ -162,7 +162,7 @@ def remove_key(key, scope) return [] unless File.file?(pol_file) out_file_path = File.join(Puppet[:vardir], 'lgpo_import.txt') gpos = lgpo('/parse', '/q', "/#{scope[0]}", pol_file) - out_file = File.open(out_file_path, 'a') do |out_file| + File.open(out_file_path, 'a') do |out_file| gpos.split("\n\n").reject { |l| l.start_with? ';' }.each do |g| split_g = g.split("\n") unless split_g[1] == key From ff90106b7e16be9b1a0e6b2faa542bc2d04b82c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Fri, 4 May 2018 10:48:37 +0200 Subject: [PATCH 08/14] Simplify logic in set_value() --- lib/puppet/provider/gpo/lgpo.rb | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/puppet/provider/gpo/lgpo.rb b/lib/puppet/provider/gpo/lgpo.rb index bd2ab17..37b127b 100644 --- a/lib/puppet/provider/gpo/lgpo.rb +++ b/lib/puppet/provider/gpo/lgpo.rb @@ -102,6 +102,10 @@ def self.instances end.flatten end + def out_line(scope, key, value_name, value) + "#{scope}\n#{key}\n#{value_name}\n#{value}" + end + def set_value(val) scope = resource[:scope].to_s admx_file = resource[:admx_file] @@ -115,19 +119,19 @@ def set_value(val) end out_scope = (scope == 'machine' ? 'computer' : scope).capitalize - delete_value = setting_valuetype == '[HASHTABLE]' ? 'DELETEALLVALUES' : 'DELETE' out = Array.new - if setting_valuetype == '[HASHTABLE]' and val != 'DELETE' - val.each do |k, v| - out << "#{out_scope}\n#{path['setting_key']}\n#{k}\nSZ:#{v}" - end + if setting_valuetype == '[HASHTABLE]' + if val == 'DELETE' + out << out_line(out_scope, path['setting_key'], '*', 'DELETEALLVALUES') + else + val.each do |k, v| + out << out_line(out_scope, path['setting_key'], k, "SZ: #{v}") + end + end else - real_val = val == 'DELETE' ? delete_value : "#{path['setting_valuetype'].gsub('REG_', '')}:#{val}" - setting_valuename = real_val == 'DELETEALLVALUES' ? '*' : path['setting_valuename'] - - out << "#{out_scope}\n#{path['setting_key']}\n#{setting_valuename}\n#{real_val}" - + val = "#{path['setting_valuetype'].gsub('REG_', '')}:#{val}" unless val == 'DELETE' + out << out_line(out_scope, path['setting_key'], path['setting_valuename'], val) end out_file_path = File.join(Puppet[:vardir], 'lgpo_import.txt') From 316a98b50f4051048bb0c1c1b424ba979f23d637 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Fri, 4 May 2018 11:02:31 +0200 Subject: [PATCH 09/14] Convert to pol and import when removing key --- lib/puppet/provider/gpo/lgpo.rb | 37 ++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/lib/puppet/provider/gpo/lgpo.rb b/lib/puppet/provider/gpo/lgpo.rb index 37b127b..6b14df1 100644 --- a/lib/puppet/provider/gpo/lgpo.rb +++ b/lib/puppet/provider/gpo/lgpo.rb @@ -106,6 +106,25 @@ def out_line(scope, key, value_name, value) "#{scope}\n#{key}\n#{value_name}\n#{value}" end + # Convert lgpo_import.txt to lgpo_import.pol with lgpo.exe + def convert_to_pol(file) + pol_file = File.basename(file, '.txt') + '.pol' + lgpo_args = ['/r', file, '/w', pol_file] + lgpo(*lgpo_args) + File.delete(file) + pol_file + end + + # import lgpo_import.pol with lgpo.exe + def import_pol(file) + lgpo_args = ["/#{scope[0]}", file] + if guid = path['policy_cse'] + lgpo_args << '/e' << guid + end + lgpo(*lgpo_args) + File.delete(file) + end + def set_value(val) scope = resource[:scope].to_s admx_file = resource[:admx_file] @@ -135,30 +154,20 @@ def set_value(val) end out_file_path = File.join(Puppet[:vardir], 'lgpo_import.txt') - out_polfile_path = File.join(Puppet[:vardir], 'lgpo_import.pol') File.open(out_file_path, 'w') do |out_file| out_file.write(out.join("\n\n")) end remove_key(path['setting_key'], scope) if setting_valuetype == '[HASHTABLE]' - # Convert lgpo_import.txt to lgpo_import.pol with lgpo.exe - lgpo_args = ['/r', out_file_path, '/w', out_polfile_path] - lgpo(*lgpo_args) - File.delete(out_file_path) + out_polfile_path = convert_to_pol(out_file_path) if setting_valuetype == '[HASHTABLE]' pol_file = "C:\\Windows\\System32\\GroupPolicy\\#{scope.capitalize}\\Registry.pol" File.delete(pol_file) end - # import lgpo_import.pol with lgpo.exe - lgpo_args = ["/#{scope[0]}", out_polfile_path] - if guid = path['policy_cse'] - lgpo_args << '/e' << guid - end - lgpo(*lgpo_args) - File.delete(out_polfile_path) + import_pol(out_polfile_path) end def remove_key(key, scope) @@ -166,6 +175,7 @@ def remove_key(key, scope) return [] unless File.file?(pol_file) out_file_path = File.join(Puppet[:vardir], 'lgpo_import.txt') gpos = lgpo('/parse', '/q', "/#{scope[0]}", pol_file) + # Parse file and remove key File.open(out_file_path, 'a') do |out_file| gpos.split("\n\n").reject { |l| l.start_with? ';' }.each do |g| split_g = g.split("\n") @@ -174,5 +184,8 @@ def remove_key(key, scope) end end end + + pol_file = convert_to_pol(out_file) + import_pol(pol_file) end end From e69e9cd68104a429923e528bccc0ea40ace49754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Fri, 4 May 2018 11:12:13 +0200 Subject: [PATCH 10/14] Simplify filtering in remove_key --- lib/puppet/provider/gpo/lgpo.rb | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/lib/puppet/provider/gpo/lgpo.rb b/lib/puppet/provider/gpo/lgpo.rb index 6b14df1..dd67a60 100644 --- a/lib/puppet/provider/gpo/lgpo.rb +++ b/lib/puppet/provider/gpo/lgpo.rb @@ -176,14 +176,9 @@ def remove_key(key, scope) out_file_path = File.join(Puppet[:vardir], 'lgpo_import.txt') gpos = lgpo('/parse', '/q', "/#{scope[0]}", pol_file) # Parse file and remove key - File.open(out_file_path, 'a') do |out_file| - gpos.split("\n\n").reject { |l| l.start_with? ';' }.each do |g| - split_g = g.split("\n") - unless split_g[1] == key - out_file.write("\n\n#{g}") - end - end - end + new_gpos = gpos.split("\n\n").reject { |l| l.start_with? ';' } + .reject{ |l| l.split("\n")[1] == key } + File.write(out_file_path, new_gpos.join("\n\n")) pol_file = convert_to_pol(out_file) import_pol(pol_file) From 7e5656ecf1fd0a4e44795b2096ff4d6a7c76f7c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Fri, 4 May 2018 11:13:09 +0200 Subject: [PATCH 11/14] Fix out_file variable --- lib/puppet/provider/gpo/lgpo.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/puppet/provider/gpo/lgpo.rb b/lib/puppet/provider/gpo/lgpo.rb index dd67a60..63683e0 100644 --- a/lib/puppet/provider/gpo/lgpo.rb +++ b/lib/puppet/provider/gpo/lgpo.rb @@ -172,13 +172,14 @@ def set_value(val) def remove_key(key, scope) pol_file = "C:\\Windows\\System32\\GroupPolicy\\#{scope.capitalize}\\Registry.pol" - return [] unless File.file?(pol_file) - out_file_path = File.join(Puppet[:vardir], 'lgpo_import.txt') + return unless File.file?(pol_file) + + out_file = File.join(Puppet[:vardir], 'lgpo_import.txt') gpos = lgpo('/parse', '/q', "/#{scope[0]}", pol_file) # Parse file and remove key new_gpos = gpos.split("\n\n").reject { |l| l.start_with? ';' } .reject{ |l| l.split("\n")[1] == key } - File.write(out_file_path, new_gpos.join("\n\n")) + File.write(out_file, new_gpos.join("\n\n")) pol_file = convert_to_pol(out_file) import_pol(pol_file) From 532014e9208b25942416d0b35a08c15b89cb7789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Fri, 4 May 2018 13:13:38 +0200 Subject: [PATCH 12/14] Warn only when resource cannot be mapped --- lib/puppet/provider/gpo/lgpo.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/puppet/provider/gpo/lgpo.rb b/lib/puppet/provider/gpo/lgpo.rb index 63683e0..4fc8202 100644 --- a/lib/puppet/provider/gpo/lgpo.rb +++ b/lib/puppet/provider/gpo/lgpo.rb @@ -63,6 +63,11 @@ def self.instances split_g = g.split("\n") path = paths.get_by_key(scope, split_g[1].downcase, split_g[2].downcase) + if path.nil? + warn "Unkown path for gpo resource: '#{split_g[1]}/#{split_g[2]}'" + next + end + admx_file = path['admx_file'].downcase policy_id = path['policy_id'].downcase setting_valuename = path['setting_valuename'].downcase From e8653644cbf9f71e7612e916236932ee911a5f5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Fri, 4 May 2018 13:13:59 +0200 Subject: [PATCH 13/14] Pass guid to import_pol --- lib/puppet/provider/gpo/lgpo.rb | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/puppet/provider/gpo/lgpo.rb b/lib/puppet/provider/gpo/lgpo.rb index 4fc8202..70f3523 100644 --- a/lib/puppet/provider/gpo/lgpo.rb +++ b/lib/puppet/provider/gpo/lgpo.rb @@ -121,11 +121,9 @@ def convert_to_pol(file) end # import lgpo_import.pol with lgpo.exe - def import_pol(file) + def import_pol(file, scope, guid) lgpo_args = ["/#{scope[0]}", file] - if guid = path['policy_cse'] - lgpo_args << '/e' << guid - end + lgpo_args << '/e' << guid if guid lgpo(*lgpo_args) File.delete(file) end @@ -163,7 +161,8 @@ def set_value(val) out_file.write(out.join("\n\n")) end - remove_key(path['setting_key'], scope) if setting_valuetype == '[HASHTABLE]' + guid = path['policy_cse'] + remove_key(path['setting_key'], scope, guid) if setting_valuetype == '[HASHTABLE]' out_polfile_path = convert_to_pol(out_file_path) @@ -172,10 +171,10 @@ def set_value(val) File.delete(pol_file) end - import_pol(out_polfile_path) + import_pol(out_polfile_path, scope, guid) end - def remove_key(key, scope) + def remove_key(key, scope, guid) pol_file = "C:\\Windows\\System32\\GroupPolicy\\#{scope.capitalize}\\Registry.pol" return unless File.file?(pol_file) @@ -187,6 +186,6 @@ def remove_key(key, scope) File.write(out_file, new_gpos.join("\n\n")) pol_file = convert_to_pol(out_file) - import_pol(pol_file) + import_pol(pol_file, scope, guid) end end From dade06043effad0b69e10609ff3ddcee5233ad2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Fri, 4 May 2018 13:26:37 +0200 Subject: [PATCH 14/14] Remove pol_file if it exists --- lib/puppet/provider/gpo/lgpo.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/puppet/provider/gpo/lgpo.rb b/lib/puppet/provider/gpo/lgpo.rb index 70f3523..0b01c17 100644 --- a/lib/puppet/provider/gpo/lgpo.rb +++ b/lib/puppet/provider/gpo/lgpo.rb @@ -168,7 +168,7 @@ def set_value(val) if setting_valuetype == '[HASHTABLE]' pol_file = "C:\\Windows\\System32\\GroupPolicy\\#{scope.capitalize}\\Registry.pol" - File.delete(pol_file) + File.delete(pol_file) if File.file?(pol_file) end import_pol(out_polfile_path, scope, guid)