@@ -18,30 +18,51 @@ class WindowsSecurityTester
1818 :current_user => Puppet ::Util ::Windows ::Security . name_to_sid ( Sys ::Admin . get_login ) ,
1919 :system => Win32 ::Security ::SID ::LocalSystem ,
2020 :admin => Puppet ::Util ::Windows ::Security . name_to_sid ( "Administrator" ) ,
21+ :administrators => Win32 ::Security ::SID ::BuiltinAdministrators ,
2122 :guest => Puppet ::Util ::Windows ::Security . name_to_sid ( "Guest" ) ,
2223 :users => Win32 ::Security ::SID ::BuiltinUsers ,
2324 :power_users => Win32 ::Security ::SID ::PowerUsers ,
25+ :none => Win32 ::Security ::SID ::Nobody ,
2426 }
2527 end
2628
2729 let ( :sids ) { @sids }
2830 let ( :winsec ) { WindowsSecurityTester . new }
2931
32+ def set_group_depending_on_current_user ( path )
33+ if sids [ :current_user ] == sids [ :system ]
34+ # if the current user is SYSTEM, by setting the group to
35+ # guest, SYSTEM is automagically given full control, so instead
36+ # override that behavior with SYSTEM as group and a specific mode
37+ winsec . set_group ( sids [ :system ] , path )
38+ mode = winsec . get_mode ( path )
39+ winsec . set_mode ( mode & ~WindowsSecurityTester ::S_IRWXG , path )
40+ else
41+ winsec . set_group ( sids [ :guest ] , path )
42+ end
43+ end
44+
3045 shared_examples_for "only child owner" do
3146 it "should allow child owner" do
3247 check_child_owner
3348 end
3449
3550 it "should deny parent owner" do
36- lambda { check_parent_owner } . should raise_error ( Errno ::EACCES )
51+ pending ( "when running as SYSTEM the absence of a SYSTEM group/owner causes full access to be added for SYSTEM" ,
52+ :if => sids [ :current_user ] == sids [ :system ] ) do
53+ lambda { check_parent_owner } . should raise_error ( Errno ::EACCES )
54+ end
3755 end
3856
3957 it "should deny group" do
4058 lambda { check_group } . should raise_error ( Errno ::EACCES )
4159 end
4260
4361 it "should deny other" do
44- lambda { check_other } . should raise_error ( Errno ::EACCES )
62+ pending ( "when running as SYSTEM the absence of a SYSTEM group/owner causes full access to be added for SYSTEM" ,
63+ :if => sids [ :current_user ] == sids [ :system ] ) do
64+ lambda { check_other } . should raise_error ( Errno ::EACCES )
65+ end
4566 end
4667 end
4768
@@ -127,10 +148,15 @@ class WindowsSecurityTester
127148 # new file has SYSTEM
128149 system_aces = winsec . get_aces_for_path_by_sid ( path , sids [ :system ] )
129150 system_aces . should_not be_empty
130- system_aces . each { |ace | ace [ :mask ] . should == WindowsSecurityTester ::FILE_ALL_ACCESS }
151+
152+ # when running under SYSTEM account, multiple ACEs come back
153+ # so we only care that we have at least one of these
154+ system_aces . any? do |ace |
155+ ace [ :mask ] == Windows ::File ::FILE_ALL_ACCESS
156+ end . should be_true
131157
132158 winsec . set_group ( sids [ :power_users ] , path )
133- winsec . set_owner ( sids [ :current_user ] , path )
159+ winsec . set_owner ( sids [ :administrators ] , path )
134160
135161 # and should still have a noninherited SYSTEM ACE granting full control
136162 system_aces = winsec . get_aces_for_path_by_sid ( path , sids [ :system ] )
@@ -175,8 +201,13 @@ class WindowsSecurityTester
175201 # new file has SYSTEM
176202 system_aces = winsec . get_aces_for_path_by_sid ( path , sids [ :system ] )
177203 system_aces . should_not be_empty
178- system_aces . each { |ace | ace [ :mask ] . should == WindowsSecurityTester ::FILE_ALL_ACCESS }
204+ # when running under SYSTEM account, multiple ACEs come back
205+ # so we only care that we have at least one of these
206+ system_aces . any? do |ace |
207+ ace [ :mask ] == WindowsSecurityTester ::FILE_ALL_ACCESS
208+ end . should be_true
179209
210+ winsec . set_group ( sids [ :none ] , path )
180211 winsec . set_mode ( 0600 , path )
181212
182213 # and should still have the same SYSTEM ACE(s)
@@ -204,6 +235,8 @@ class WindowsSecurityTester
204235
205236 describe "for read-only objects" do
206237 before :each do
238+ winsec . set_group ( sids [ :none ] , path )
239+ winsec . set_mode ( 0600 , path )
207240 winsec . add_attributes ( path , WindowsSecurityTester ::FILE_ATTRIBUTE_READONLY )
208241 ( winsec . get_attributes ( path ) & WindowsSecurityTester ::FILE_ATTRIBUTE_READONLY ) . should be_nonzero
209242 end
@@ -218,7 +251,12 @@ class WindowsSecurityTester
218251 ( winsec . get_attributes ( path ) & WindowsSecurityTester ::FILE_ATTRIBUTE_READONLY ) . should be_nonzero
219252
220253 system_aces = winsec . get_aces_for_path_by_sid ( path , sids [ :system ] )
221- system_aces . each { |ace | ace [ :mask ] . should == WindowsSecurityTester ::FILE_ALL_ACCESS }
254+
255+ # when running under SYSTEM account, and set_group / set_owner hasn't been called
256+ # SYSTEM full access will be restored
257+ system_aces . any? do |ace |
258+ ace [ :mask ] == Windows ::File ::FILE_ALL_ACCESS
259+ end . should be_true
222260 end
223261 end
224262
@@ -297,7 +335,7 @@ class WindowsSecurityTester
297335 describe "for an administrator" , :if => Puppet . features . root? do
298336 before :each do
299337 winsec . set_mode ( WindowsSecurityTester ::S_IRWXU | WindowsSecurityTester ::S_IRWXG , path )
300- winsec . set_group ( sids [ :guest ] , path )
338+ set_group_depending_on_current_user ( path )
301339 winsec . set_owner ( sids [ :guest ] , path )
302340 lambda { File . open ( path , 'r' ) } . should raise_error ( Errno ::EACCES )
303341 end
@@ -474,7 +512,10 @@ def check_other
474512 end
475513
476514 it "should deny other" do
477- lambda { check_other } . should raise_error ( Errno ::EACCES )
515+ pending ( "when running as SYSTEM the absence of a SYSTEM group/owner causes full access to be added for SYSTEM" ,
516+ :if => sids [ :current_user ] == sids [ :system ] ) do
517+ lambda { check_other } . should raise_error ( Errno ::EACCES )
518+ end
478519 end
479520 end
480521
0 commit comments