puppet 2.7.5 → 2.7.6

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (140) hide show
  1. data/CHANGELOG +121 -0
  2. data/conf/redhat/puppet.spec +16 -7
  3. data/lib/puppet.rb +1 -1
  4. data/lib/puppet/application/cert.rb +17 -3
  5. data/lib/puppet/application/device.rb +1 -0
  6. data/lib/puppet/application/kick.rb +0 -2
  7. data/lib/puppet/application/resource.rb +73 -66
  8. data/lib/puppet/configurer/plugin_handler.rb +6 -2
  9. data/lib/puppet/defaults.rb +60 -5
  10. data/lib/puppet/face/ca.rb +11 -2
  11. data/lib/puppet/face/certificate.rb +33 -4
  12. data/lib/puppet/file_serving/fileset.rb +1 -1
  13. data/lib/puppet/file_serving/indirection_hooks.rb +2 -2
  14. data/lib/puppet/file_serving/metadata.rb +43 -4
  15. data/lib/puppet/indirector.rb +0 -1
  16. data/lib/puppet/indirector/request.rb +3 -4
  17. data/lib/puppet/indirector/resource/active_record.rb +3 -10
  18. data/lib/puppet/indirector/resource/ral.rb +2 -2
  19. data/lib/puppet/indirector/rest.rb +1 -1
  20. data/lib/puppet/network/handler/ca.rb +16 -106
  21. data/lib/puppet/network/handler/master.rb +0 -3
  22. data/lib/puppet/network/handler/runner.rb +1 -0
  23. data/lib/puppet/parser/scope.rb +10 -0
  24. data/lib/puppet/provider/file/posix.rb +72 -34
  25. data/lib/puppet/provider/file/windows.rb +100 -0
  26. data/lib/puppet/provider/group/windows_adsi.rb +2 -2
  27. data/lib/puppet/provider/user/windows_adsi.rb +19 -4
  28. data/lib/puppet/resource.rb +16 -0
  29. data/lib/puppet/resource/catalog.rb +1 -1
  30. data/lib/puppet/ssl/certificate.rb +2 -2
  31. data/lib/puppet/ssl/certificate_authority.rb +86 -10
  32. data/lib/puppet/ssl/certificate_authority/interface.rb +64 -19
  33. data/lib/puppet/ssl/certificate_factory.rb +112 -91
  34. data/lib/puppet/ssl/certificate_request.rb +88 -1
  35. data/lib/puppet/ssl/host.rb +20 -3
  36. data/lib/puppet/type/file.rb +15 -34
  37. data/lib/puppet/type/file/group.rb +11 -91
  38. data/lib/puppet/type/file/mode.rb +11 -41
  39. data/lib/puppet/type/file/owner.rb +18 -34
  40. data/lib/puppet/type/file/source.rb +22 -7
  41. data/lib/puppet/type/group.rb +4 -3
  42. data/lib/puppet/type/user.rb +4 -1
  43. data/lib/puppet/util.rb +59 -6
  44. data/lib/puppet/util/adsi.rb +11 -0
  45. data/lib/puppet/util/log.rb +4 -0
  46. data/lib/puppet/util/log/destinations.rb +7 -1
  47. data/lib/puppet/util/monkey_patches.rb +19 -0
  48. data/lib/puppet/util/network_device/config.rb +4 -5
  49. data/lib/puppet/util/settings.rb +5 -0
  50. data/lib/puppet/util/suidmanager.rb +0 -1
  51. data/lib/puppet/util/windows.rb +4 -0
  52. data/lib/puppet/util/windows/error.rb +16 -0
  53. data/lib/puppet/util/windows/security.rb +593 -0
  54. data/spec/integration/defaults_spec.rb +27 -0
  55. data/spec/integration/network/handler_spec.rb +1 -1
  56. data/spec/integration/type/file_spec.rb +382 -145
  57. data/spec/integration/util/windows/security_spec.rb +468 -0
  58. data/spec/shared_behaviours/file_serving.rb +4 -3
  59. data/spec/unit/application/agent_spec.rb +1 -0
  60. data/spec/unit/application/device_spec.rb +5 -0
  61. data/spec/unit/application/resource_spec.rb +62 -101
  62. data/spec/unit/configurer/downloader_spec.rb +2 -2
  63. data/spec/unit/configurer/plugin_handler_spec.rb +15 -8
  64. data/spec/unit/configurer_spec.rb +2 -2
  65. data/spec/unit/face/ca_spec.rb +34 -0
  66. data/spec/unit/face/certificate_spec.rb +168 -1
  67. data/spec/unit/file_serving/fileset_spec.rb +1 -1
  68. data/spec/unit/file_serving/indirection_hooks_spec.rb +1 -1
  69. data/spec/unit/file_serving/metadata_spec.rb +151 -107
  70. data/spec/unit/indirector/certificate_request/ca_spec.rb +0 -3
  71. data/spec/unit/indirector/direct_file_server_spec.rb +10 -9
  72. data/spec/unit/indirector/file_metadata/file_spec.rb +6 -4
  73. data/spec/unit/indirector/request_spec.rb +13 -3
  74. data/spec/unit/indirector/resource/active_record_spec.rb +4 -10
  75. data/spec/unit/indirector/resource/ral_spec.rb +6 -4
  76. data/spec/unit/indirector/rest_spec.rb +5 -6
  77. data/spec/unit/network/handler/ca_spec.rb +86 -0
  78. data/spec/unit/parser/collector_spec.rb +7 -7
  79. data/spec/unit/parser/scope_spec.rb +20 -0
  80. data/spec/unit/provider/file/posix_spec.rb +226 -0
  81. data/spec/unit/provider/file/windows_spec.rb +136 -0
  82. data/spec/unit/provider/group/windows_adsi_spec.rb +7 -2
  83. data/spec/unit/provider/user/windows_adsi_spec.rb +36 -3
  84. data/spec/unit/resource/catalog_spec.rb +20 -10
  85. data/spec/unit/resource_spec.rb +55 -8
  86. data/spec/unit/ssl/certificate_authority/interface_spec.rb +97 -54
  87. data/spec/unit/ssl/certificate_authority_spec.rb +133 -23
  88. data/spec/unit/ssl/certificate_factory_spec.rb +90 -70
  89. data/spec/unit/ssl/certificate_request_spec.rb +62 -1
  90. data/spec/unit/ssl/certificate_spec.rb +20 -14
  91. data/spec/unit/ssl/host_spec.rb +52 -6
  92. data/spec/unit/type/file/content_spec.rb +4 -4
  93. data/spec/unit/type/file/group_spec.rb +34 -96
  94. data/spec/unit/type/file/mode_spec.rb +88 -0
  95. data/spec/unit/type/file/owner_spec.rb +32 -123
  96. data/spec/unit/type/file/source_spec.rb +120 -41
  97. data/spec/unit/type/file_spec.rb +1033 -753
  98. data/spec/unit/type_spec.rb +19 -1
  99. data/spec/unit/util/adsi_spec.rb +19 -0
  100. data/spec/unit/util/log/destinations_spec.rb +75 -0
  101. data/spec/unit/util/log_spec.rb +15 -0
  102. data/spec/unit/util/network_device/config_spec.rb +7 -0
  103. data/spec/unit/util/settings_spec.rb +10 -0
  104. data/spec/unit/util_spec.rb +126 -13
  105. data/test/language/functions.rb +0 -1
  106. data/test/language/snippets.rb +0 -9
  107. data/test/lib/puppettest/exetest.rb +1 -1
  108. data/test/lib/puppettest/servertest.rb +0 -1
  109. data/test/rails/rails.rb +0 -1
  110. data/test/ral/type/filesources.rb +0 -60
  111. metadata +13 -33
  112. data/lib/puppet/network/client.rb +0 -174
  113. data/lib/puppet/network/client/ca.rb +0 -56
  114. data/lib/puppet/network/client/file.rb +0 -6
  115. data/lib/puppet/network/client/proxy.rb +0 -27
  116. data/lib/puppet/network/client/report.rb +0 -26
  117. data/lib/puppet/network/client/runner.rb +0 -10
  118. data/lib/puppet/network/client/status.rb +0 -4
  119. data/lib/puppet/network/http_server.rb +0 -3
  120. data/lib/puppet/network/http_server/mongrel.rb +0 -130
  121. data/lib/puppet/network/http_server/webrick.rb +0 -155
  122. data/lib/puppet/network/xmlrpc/client.rb +0 -211
  123. data/lib/puppet/provider/file/win32.rb +0 -72
  124. data/lib/puppet/sslcertificates.rb +0 -146
  125. data/lib/puppet/sslcertificates/ca.rb +0 -375
  126. data/lib/puppet/sslcertificates/certificate.rb +0 -255
  127. data/lib/puppet/sslcertificates/inventory.rb +0 -38
  128. data/lib/puppet/sslcertificates/support.rb +0 -146
  129. data/spec/integration/network/client_spec.rb +0 -18
  130. data/spec/unit/network/xmlrpc/client_spec.rb +0 -172
  131. data/spec/unit/sslcertificates/ca_spec.rb +0 -106
  132. data/test/certmgr/certmgr.rb +0 -308
  133. data/test/certmgr/inventory.rb +0 -69
  134. data/test/certmgr/support.rb +0 -105
  135. data/test/network/client/ca.rb +0 -69
  136. data/test/network/client/dipper.rb +0 -34
  137. data/test/network/handler/ca.rb +0 -273
  138. data/test/network/server/mongrel_test.rb +0 -99
  139. data/test/network/server/webrick.rb +0 -111
  140. data/test/network/xmlrpc/client.rb +0 -45
@@ -0,0 +1,468 @@
1
+ #!/usr/bin/env ruby
2
+ require 'spec_helper'
3
+
4
+ require 'puppet/util/adsi'
5
+
6
+ if Puppet.features.microsoft_windows?
7
+ class WindowsSecurityTester
8
+ require 'puppet/util/windows/security'
9
+ include Puppet::Util::Windows::Security
10
+ end
11
+ end
12
+
13
+ describe "Puppet::Util::Windows::Security", :if => Puppet.features.microsoft_windows? do
14
+ include PuppetSpec::Files
15
+
16
+ before :all do
17
+ @sids = {
18
+ :current_user => Puppet::Util::ADSI.sid_for_account(Sys::Admin.get_login),
19
+ :admin => Puppet::Util::ADSI.sid_for_account("Administrator"),
20
+ :guest => Puppet::Util::ADSI.sid_for_account("Guest"),
21
+ :users => Win32::Security::SID::BuiltinUsers,
22
+ :power_users => Win32::Security::SID::PowerUsers,
23
+ }
24
+ end
25
+
26
+ let (:sids) { @sids }
27
+ let (:winsec) { WindowsSecurityTester.new }
28
+
29
+ shared_examples_for "a securable object" do
30
+ describe "for a normal user" do
31
+ before :each do
32
+ Puppet.features.stubs(:root?).returns(false)
33
+ end
34
+
35
+ after :each do
36
+ winsec.set_mode(WindowsSecurityTester::S_IRWXU, path)
37
+ end
38
+
39
+ describe "#owner=" do
40
+ it "should allow setting to the current user" do
41
+ winsec.set_owner(sids[:current_user], path)
42
+ end
43
+
44
+ it "should raise an exception when setting to a different user" do
45
+ lambda { winsec.set_owner(sids[:guest], path) }.should raise_error(Puppet::Error, /This security ID may not be assigned as the owner of this object./)
46
+ end
47
+ end
48
+
49
+ describe "#owner" do
50
+ it "it should not be empty" do
51
+ winsec.get_owner(path).should_not be_empty
52
+ end
53
+
54
+ it "should raise an exception if an invalid path is provided" do
55
+ lambda { winsec.get_owner("c:\\doesnotexist.txt") }.should raise_error(Puppet::Error, /The system cannot find the file specified./)
56
+ end
57
+ end
58
+
59
+ describe "#group=" do
60
+ it "should allow setting to a group the current owner is a member of" do
61
+ winsec.set_group(sids[:users], path)
62
+ end
63
+
64
+ # Unlike unix, if the user has permission to WRITE_OWNER, which the file owner has by default,
65
+ # then they can set the primary group to a group that the user does not belong to.
66
+ it "should allow setting to a group the current owner is not a member of" do
67
+ winsec.set_group(sids[:power_users], path)
68
+ end
69
+ end
70
+
71
+ describe "#group" do
72
+ it "should not be empty" do
73
+ winsec.get_group(path).should_not be_empty
74
+ end
75
+
76
+ it "should raise an exception if an invalid path is provided" do
77
+ lambda { winsec.get_group("c:\\doesnotexist.txt") }.should raise_error(Puppet::Error, /The system cannot find the file specified./)
78
+ end
79
+ end
80
+
81
+ describe "#mode=" do
82
+ [0000, 0100, 0200, 0300, 0400, 0500, 0600, 0700].each do |mode|
83
+ it "should enforce mode #{mode.to_s(8)}" do
84
+ winsec.set_mode(mode, path)
85
+
86
+ check_access(mode, path)
87
+ end
88
+ end
89
+
90
+ it "should round-trip all 64 modes that do not require deny ACEs" do
91
+ 0.upto(7).each do |u|
92
+ 0.upto(u).each do |g|
93
+ 0.upto(g).each do |o|
94
+ # if user is superset of group, and group superset of other, then
95
+ # no deny ace is required, and mode can be converted to win32
96
+ # access mask, and back to mode without loss of information
97
+ # (provided the owner and group are not the same)
98
+ next if ((u & g) != g) or ((g & o) != o)
99
+
100
+ mode = (u << 6 | g << 3 | o << 0)
101
+ winsec.set_mode(mode, path)
102
+ winsec.get_mode(path).to_s(8).should == mode.to_s(8)
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ describe "for modes that require deny aces" do
109
+ it "should map everyone to group and owner" do
110
+ winsec.set_mode(0426, path)
111
+ winsec.get_mode(path).to_s(8).should == "666"
112
+ end
113
+
114
+ it "should combine user and group modes when owner and group sids are equal" do
115
+ winsec.set_group(winsec.get_owner(path), path)
116
+
117
+ winsec.set_mode(0410, path)
118
+ winsec.get_mode(path).to_s(8).should == "550"
119
+ end
120
+ end
121
+
122
+ describe "for read-only objects" do
123
+ before :each do
124
+ winsec.add_attributes(path, WindowsSecurityTester::FILE_ATTRIBUTE_READONLY)
125
+ (winsec.get_attributes(path) & WindowsSecurityTester::FILE_ATTRIBUTE_READONLY).should be_nonzero
126
+ end
127
+
128
+ it "should make them writable if any sid has write permission" do
129
+ winsec.set_mode(WindowsSecurityTester::S_IWUSR, path)
130
+ (winsec.get_attributes(path) & WindowsSecurityTester::FILE_ATTRIBUTE_READONLY).should == 0
131
+ end
132
+
133
+ it "should leave them read-only if no sid has write permission" do
134
+ winsec.set_mode(WindowsSecurityTester::S_IRUSR | WindowsSecurityTester::S_IXGRP, path)
135
+ (winsec.get_attributes(path) & WindowsSecurityTester::FILE_ATTRIBUTE_READONLY).should be_nonzero
136
+ end
137
+ end
138
+
139
+ it "should raise an exception if an invalid path is provided" do
140
+ lambda { winsec.set_mode(sids[:guest], "c:\\doesnotexist.txt") }.should raise_error(Puppet::Error, /The system cannot find the file specified./)
141
+ end
142
+ end
143
+
144
+ describe "#mode" do
145
+ it "should report when extra aces are encounted" do
146
+ winsec.set_acl(path, true) do |acl|
147
+ [ 544, 545, 546, 547 ].each do |rid|
148
+ winsec.add_access_allowed_ace(acl, WindowsSecurityTester::STANDARD_RIGHTS_ALL, "S-1-5-32-#{rid}")
149
+ end
150
+ end
151
+ mode = winsec.get_mode(path)
152
+ (mode & WindowsSecurityTester::S_IEXTRA).should_not == 0
153
+ end
154
+
155
+ it "should warn if a deny ace is encountered" do
156
+ winsec.set_acl(path) do |acl|
157
+ winsec.add_access_denied_ace(acl, WindowsSecurityTester::FILE_GENERIC_WRITE, sids[:guest])
158
+ winsec.add_access_allowed_ace(acl, WindowsSecurityTester::STANDARD_RIGHTS_ALL | WindowsSecurityTester::SPECIFIC_RIGHTS_ALL, sids[:current_user])
159
+ end
160
+
161
+ Puppet.expects(:warning).with("Unsupported access control entry type: 0x1")
162
+
163
+ winsec.get_mode(path)
164
+ end
165
+
166
+ it "should skip inherit-only ace" do
167
+ winsec.set_acl(path) do |acl|
168
+ winsec.add_access_allowed_ace(acl, WindowsSecurityTester::STANDARD_RIGHTS_ALL | WindowsSecurityTester::SPECIFIC_RIGHTS_ALL, sids[:current_user])
169
+ winsec.add_access_allowed_ace(acl, WindowsSecurityTester::FILE_GENERIC_READ, Win32::Security::SID::Everyone, WindowsSecurityTester::INHERIT_ONLY_ACE | WindowsSecurityTester::OBJECT_INHERIT_ACE)
170
+ end
171
+
172
+ (winsec.get_mode(path) & WindowsSecurityTester::S_IRWXO).should == 0
173
+ end
174
+
175
+ it "should raise an exception if an invalid path is provided" do
176
+ lambda { winsec.get_mode("c:\\doesnotexist.txt") }.should raise_error(Puppet::Error, /The system cannot find the file specified./)
177
+ end
178
+ end
179
+
180
+ describe "inherited access control entries" do
181
+ it "should be absent when the access control list is protected" do
182
+ winsec.set_mode(WindowsSecurityTester::S_IRWXU, path)
183
+ (winsec.get_mode(path) & WindowsSecurityTester::S_IEXTRA).should == 0
184
+ end
185
+
186
+ it "should be present when the access control list is unprotected" do
187
+ dir = tmpdir('win_sec_parent')
188
+
189
+ # add a bunch of aces, make sure we can add to the directory
190
+ allow = WindowsSecurityTester::STANDARD_RIGHTS_ALL | WindowsSecurityTester::SPECIFIC_RIGHTS_ALL
191
+ inherit = WindowsSecurityTester::OBJECT_INHERIT_ACE | WindowsSecurityTester::CONTAINER_INHERIT_ACE
192
+
193
+ winsec.set_acl(dir, true) do |acl|
194
+ winsec.add_access_allowed_ace(acl, allow, "S-1-1-0", inherit) # everyone
195
+
196
+ [ 544, 545, 546, 547 ].each do |rid|
197
+ winsec.add_access_allowed_ace(acl, WindowsSecurityTester::STANDARD_RIGHTS_ALL, "S-1-5-32-#{rid}", inherit)
198
+ end
199
+ end
200
+
201
+ # add a file
202
+ child = File.join(dir, "child")
203
+ File.new(child, "w").close
204
+
205
+ # unprotect child, it should inherit from parent
206
+ winsec.set_mode(WindowsSecurityTester::S_IRWXU, child, false)
207
+ (winsec.get_mode(child) & WindowsSecurityTester::S_IEXTRA).should == WindowsSecurityTester::S_IEXTRA
208
+ end
209
+ end
210
+ end
211
+
212
+ describe "for an administrator", :if => Puppet.features.root? do
213
+ before :each do
214
+ winsec.set_owner(sids[:guest], path)
215
+ winsec.set_group(sids[:guest], path)
216
+ winsec.set_mode(WindowsSecurityTester::S_IRWXU | WindowsSecurityTester::S_IRWXG, path)
217
+ lambda { File.open(path, 'r') }.should raise_error(Errno::EACCES)
218
+ end
219
+
220
+ after :each do
221
+ winsec.set_owner(sids[:current_user], path)
222
+ winsec.set_mode(WindowsSecurityTester::S_IRWXU, path)
223
+ end
224
+
225
+ describe "#owner=" do
226
+ it "should accept a user sid" do
227
+ winsec.set_owner(sids[:admin], path)
228
+ winsec.get_owner(path).should == sids[:admin]
229
+ end
230
+
231
+ it "should accept a group sid" do
232
+ winsec.set_owner(sids[:power_users], path)
233
+ winsec.get_owner(path).should == sids[:power_users]
234
+ end
235
+
236
+ it "should raise an exception if an invalid sid is provided" do
237
+ lambda { winsec.set_owner("foobar", path) }.should raise_error(Puppet::Error, /Failed to convert string SID/)
238
+ end
239
+
240
+ it "should raise an exception if an invalid path is provided" do
241
+ lambda { winsec.set_owner(sids[:guest], "c:\\doesnotexist.txt") }.should raise_error(Puppet::Error, /The system cannot find the file specified./)
242
+ end
243
+ end
244
+
245
+ describe "#group=" do
246
+ it "should accept a group sid" do
247
+ winsec.set_group(sids[:power_users], path)
248
+ winsec.get_group(path).should == sids[:power_users]
249
+ end
250
+
251
+ it "should accept a user sid" do
252
+ winsec.set_group(sids[:admin], path)
253
+ winsec.get_group(path).should == sids[:admin]
254
+ end
255
+
256
+ it "should allow owner and group to be the same sid" do
257
+ winsec.set_owner(sids[:power_users], path)
258
+ winsec.set_group(sids[:power_users], path)
259
+ winsec.set_mode(0610, path)
260
+
261
+ winsec.get_owner(path).should == sids[:power_users]
262
+ winsec.get_group(path).should == sids[:power_users]
263
+ # note group execute permission added to user ace, and then group rwx value
264
+ # reflected to match
265
+ winsec.get_mode(path).to_s(8).should == "770"
266
+ end
267
+
268
+ it "should raise an exception if an invalid sid is provided" do
269
+ lambda { winsec.set_group("foobar", path) }.should raise_error(Puppet::Error, /Failed to convert string SID/)
270
+ end
271
+
272
+ it "should raise an exception if an invalid path is provided" do
273
+ lambda { winsec.set_group(sids[:guest], "c:\\doesnotexist.txt") }.should raise_error(Puppet::Error, /The system cannot find the file specified./)
274
+ end
275
+ end
276
+
277
+ describe "when the sid is NULL" do
278
+ it "should retrieve an empty owner sid"
279
+ it "should retrieve an empty group sid"
280
+ end
281
+
282
+ describe "when the sid refers to a deleted trustee" do
283
+ it "should retrieve the user sid" do
284
+ sid = nil
285
+ user = Puppet::Util::ADSI::User.create("delete_me_user")
286
+ user.commit
287
+ begin
288
+ sid = Sys::Admin::get_user(user.name).sid
289
+ winsec.set_owner(sid, path)
290
+ winsec.set_mode(WindowsSecurityTester::S_IRWXU, path)
291
+ ensure
292
+ Puppet::Util::ADSI::User.delete(user.name)
293
+ end
294
+
295
+ winsec.get_owner(path).should == sid
296
+ winsec.get_mode(path).should == WindowsSecurityTester::S_IRWXU
297
+ end
298
+
299
+ it "should retrieve the group sid" do
300
+ sid = nil
301
+ group = Puppet::Util::ADSI::Group.create("delete_me_group")
302
+ group.commit
303
+ begin
304
+ sid = Sys::Admin::get_group(group.name).sid
305
+ winsec.set_group(sid, path)
306
+ winsec.set_mode(WindowsSecurityTester::S_IRWXG, path)
307
+ ensure
308
+ Puppet::Util::ADSI::Group.delete(group.name)
309
+ end
310
+ winsec.get_group(path).should == sid
311
+ winsec.get_mode(path).should == WindowsSecurityTester::S_IRWXG
312
+ end
313
+ end
314
+
315
+ describe "#mode" do
316
+ it "should deny all access when the DACL is empty" do
317
+ winsec.set_acl(path, true) { |acl| }
318
+
319
+ winsec.get_mode(path).should == 0
320
+ end
321
+
322
+ # REMIND: ruby crashes when trying to set a NULL DACL
323
+ # it "should allow all when it is nil" do
324
+ # winsec.set_owner(sids[:current_user], path)
325
+ # winsec.open_file(path, WindowsSecurityTester::READ_CONTROL | WindowsSecurityTester::WRITE_DAC) do |handle|
326
+ # winsec.set_security_info(handle, WindowsSecurityTester::DACL_SECURITY_INFORMATION | WindowsSecurityTester::PROTECTED_DACL_SECURITY_INFORMATION, nil)
327
+ # end
328
+ # winsec.get_mode(path).to_s(8).should == "777"
329
+ # end
330
+ end
331
+
332
+ describe "#string_to_sid_ptr" do
333
+ it "should raise an error if an invalid SID is specified" do
334
+ expect do
335
+ winsec.string_to_sid_ptr('foobar')
336
+ end.to raise_error(Puppet::Util::Windows::Error) { |error| error.code.should == 1337 }
337
+ end
338
+
339
+ it "should yield if a block is given" do
340
+ yielded = nil
341
+ winsec.string_to_sid_ptr('S-1-1-0') do |sid|
342
+ yielded = sid
343
+ end
344
+ yielded.should_not be_nil
345
+ end
346
+
347
+ it "should allow no block to be specified" do
348
+ winsec.string_to_sid_ptr('S-1-1-0').should be_true
349
+ end
350
+ end
351
+ end
352
+ end
353
+
354
+ describe "file" do
355
+ let :path do
356
+ path = tmpfile('win_sec_test_file')
357
+ File.new(path, "w").close
358
+ path
359
+ end
360
+
361
+ it_behaves_like "a securable object" do
362
+ def check_access(mode, path)
363
+ if (mode & WindowsSecurityTester::S_IRUSR).nonzero?
364
+ check_read(path)
365
+ else
366
+ lambda { check_read(path) }.should raise_error(Errno::EACCES)
367
+ end
368
+
369
+ if (mode & WindowsSecurityTester::S_IWUSR).nonzero?
370
+ check_write(path)
371
+ else
372
+ lambda { check_write(path) }.should raise_error(Errno::EACCES)
373
+ end
374
+
375
+ if (mode & WindowsSecurityTester::S_IXUSR).nonzero?
376
+ lambda { check_execute(path) }.should raise_error(Errno::ENOEXEC)
377
+ else
378
+ lambda { check_execute(path) }.should raise_error(Errno::EACCES)
379
+ end
380
+ end
381
+
382
+ def check_read(path)
383
+ File.open(path, 'r').close
384
+ end
385
+
386
+ def check_write(path)
387
+ File.open(path, 'w').close
388
+ end
389
+
390
+ def check_execute(path)
391
+ Kernel.exec(path)
392
+ end
393
+ end
394
+
395
+ describe "locked files" do
396
+ let (:explorer) { File.join(Dir::WINDOWS, "explorer.exe") }
397
+
398
+ it "should get the owner" do
399
+ winsec.get_owner(explorer).should match /^S-1-5-/
400
+ end
401
+
402
+ it "should get the group" do
403
+ winsec.get_group(explorer).should match /^S-1-5-/
404
+ end
405
+
406
+ it "should get the mode" do
407
+ winsec.get_mode(explorer).should == (WindowsSecurityTester::S_IRWXU | WindowsSecurityTester::S_IRWXG | WindowsSecurityTester::S_IEXTRA)
408
+ end
409
+ end
410
+ end
411
+
412
+ describe "directory" do
413
+ let :path do
414
+ tmpdir('win_sec_test_dir')
415
+ end
416
+
417
+ it_behaves_like "a securable object" do
418
+ def check_access(mode, path)
419
+ if (mode & WindowsSecurityTester::S_IRUSR).nonzero?
420
+ check_read(path)
421
+ else
422
+ lambda { check_read(path) }.should raise_error(Errno::EACCES)
423
+ end
424
+
425
+ if (mode & WindowsSecurityTester::S_IWUSR).nonzero?
426
+ check_write(path)
427
+ else
428
+ lambda { check_write(path) }.should raise_error(Errno::EACCES)
429
+ end
430
+
431
+ if (mode & WindowsSecurityTester::S_IXUSR).nonzero?
432
+ check_execute(path)
433
+ else
434
+ lambda { check_execute(path) }.should raise_error(Errno::EACCES)
435
+ end
436
+ end
437
+
438
+ def check_read(path)
439
+ Dir.entries(path)
440
+ end
441
+
442
+ def check_write(path)
443
+ Dir.mkdir(File.join(path, "subdir"))
444
+ end
445
+
446
+ def check_execute(path)
447
+ Dir.chdir(path) {|dir| }
448
+ end
449
+ end
450
+
451
+ describe "inheritable aces" do
452
+ it "should be applied to child objects" do
453
+ mode640 = WindowsSecurityTester::S_IRUSR | WindowsSecurityTester::S_IWUSR | WindowsSecurityTester::S_IRGRP
454
+ winsec.set_mode(mode640, path)
455
+
456
+ newfile = File.join(path, "newfile.txt")
457
+ File.new(newfile, "w").close
458
+
459
+ newdir = File.join(path, "newdir")
460
+ Dir.mkdir(newdir)
461
+
462
+ [newfile, newdir].each do |p|
463
+ winsec.get_mode(p).to_s(8).should == mode640.to_s(8)
464
+ end
465
+ end
466
+ end
467
+ end
468
+ end