puppet 2.7.6 → 2.7.8
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.
- data/CHANGELOG +168 -0
- data/conf/auth.conf +5 -4
- data/conf/redhat/puppet.spec +16 -1
- data/conf/solaris/pkginfo +2 -2
- data/conf/suse/puppet.spec +9 -3
- data/ext/upload_facts.rb +120 -0
- data/install.rb +11 -16
- data/lib/puppet.rb +1 -1
- data/lib/puppet/application/agent.rb +0 -3
- data/lib/puppet/application/apply.rb +0 -3
- data/lib/puppet/application/queue.rb +21 -1
- data/lib/puppet/defaults.rb +6 -4
- data/lib/puppet/face/file/store.rb +1 -1
- data/lib/puppet/feature/base.rb +2 -1
- data/lib/puppet/file_bucket/dipper.rb +3 -2
- data/lib/puppet/file_serving/content.rb +1 -1
- data/lib/puppet/file_serving/metadata.rb +5 -2
- data/lib/puppet/indirector/facts/inventory_service.rb +20 -0
- data/lib/puppet/indirector/file_bucket_file/file.rb +3 -2
- data/lib/puppet/indirector/report/processor.rb +1 -1
- data/lib/puppet/network/handler/filebucket.rb +2 -0
- data/lib/puppet/network/handler/fileserver.rb +1 -1
- data/lib/puppet/network/handler/master.rb +1 -0
- data/lib/puppet/network/handler/report.rb +2 -0
- data/lib/puppet/network/handler/runner.rb +1 -0
- data/lib/puppet/network/handler/status.rb +2 -0
- data/lib/puppet/network/http/mongrel/rest.rb +8 -1
- data/lib/puppet/network/http_server.rb +3 -0
- data/lib/puppet/network/http_server/mongrel.rb +129 -0
- data/lib/puppet/network/rest_authconfig.rb +12 -4
- data/lib/puppet/parameter.rb +18 -0
- data/lib/puppet/parser/compiler.rb +1 -1
- data/lib/puppet/parser/grammar.ra +1 -1
- data/lib/puppet/parser/parser.rb +360 -350
- data/lib/puppet/property.rb +3 -3
- data/lib/puppet/provider/augeas/augeas.rb +1 -1
- data/lib/puppet/provider/exec/windows.rb +6 -7
- data/lib/puppet/provider/file/windows.rb +9 -2
- data/lib/puppet/provider/group/aix.rb +8 -8
- data/lib/puppet/provider/group/groupadd.rb +1 -3
- data/lib/puppet/provider/group/ldap.rb +8 -10
- data/lib/puppet/provider/group/windows_adsi.rb +8 -2
- data/lib/puppet/provider/package/aix.rb +1 -1
- data/lib/puppet/provider/package/macports.rb +3 -3
- data/lib/puppet/provider/package/msi.rb +12 -5
- data/lib/puppet/provider/package/nim.rb +1 -1
- data/lib/puppet/provider/package/pkgdmg.rb +3 -3
- data/lib/puppet/provider/package/ports.rb +1 -1
- data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +560 -0
- data/lib/puppet/provider/service/base.rb +2 -2
- data/lib/puppet/provider/service/bsd.rb +4 -3
- data/lib/puppet/provider/service/daemontools.rb +25 -25
- data/lib/puppet/provider/service/debian.rb +6 -4
- data/lib/puppet/provider/service/freebsd.rb +1 -1
- data/lib/puppet/provider/service/gentoo.rb +4 -3
- data/lib/puppet/provider/service/init.rb +3 -8
- data/lib/puppet/provider/service/launchd.rb +129 -96
- data/lib/puppet/provider/service/redhat.rb +2 -3
- data/lib/puppet/provider/service/runit.rb +20 -20
- data/lib/puppet/provider/service/smf.rb +8 -7
- data/lib/puppet/provider/service/src.rb +5 -6
- data/lib/puppet/provider/service/systemd.rb +1 -1
- data/lib/puppet/provider/service/upstart.rb +3 -5
- data/lib/puppet/provider/service/windows.rb +7 -7
- data/lib/puppet/provider/sshkey/parsed.rb +2 -3
- data/lib/puppet/provider/user/aix.rb +21 -21
- data/lib/puppet/provider/user/hpux.rb +3 -1
- data/lib/puppet/provider/user/ldap.rb +7 -7
- data/lib/puppet/provider/user/user_role_add.rb +10 -6
- data/lib/puppet/provider/user/useradd.rb +3 -1
- data/lib/puppet/provider/user/windows_adsi.rb +4 -3
- data/lib/puppet/rb_tree_map.rb +388 -0
- data/lib/puppet/reference/configuration.rb +7 -7
- data/lib/puppet/reference/indirection.rb +5 -6
- data/lib/puppet/reference/metaparameter.rb +3 -1
- data/lib/puppet/reference/network.rb +8 -8
- data/lib/puppet/reference/providers.rb +17 -21
- data/lib/puppet/reference/type.rb +12 -9
- data/lib/puppet/resource.rb +2 -5
- data/lib/puppet/resource/catalog.rb +1 -1
- data/lib/puppet/ssl/certificate_request.rb +70 -0
- data/lib/puppet/ssl/host.rb +6 -0
- data/lib/puppet/transaction.rb +158 -55
- data/lib/puppet/transaction/event_manager.rb +1 -1
- data/lib/puppet/type.rb +60 -30
- data/lib/puppet/type/augeas.rb +83 -49
- data/lib/puppet/type/computer.rb +1 -1
- data/lib/puppet/type/cron.rb +11 -11
- data/lib/puppet/type/exec.rb +28 -21
- data/lib/puppet/type/file.rb +17 -7
- data/lib/puppet/type/file/content.rb +2 -2
- data/lib/puppet/type/file/ensure.rb +15 -12
- data/lib/puppet/type/file/mode.rb +30 -5
- data/lib/puppet/type/file/source.rb +11 -10
- data/lib/puppet/type/file/target.rb +2 -2
- data/lib/puppet/type/filebucket.rb +1 -1
- data/lib/puppet/type/group.rb +4 -5
- data/lib/puppet/type/host.rb +1 -1
- data/lib/puppet/type/interface.rb +13 -10
- data/lib/puppet/type/k5login.rb +6 -6
- data/lib/puppet/type/macauthorization.rb +37 -36
- data/lib/puppet/type/maillist.rb +2 -2
- data/lib/puppet/type/mcx.rb +6 -6
- data/lib/puppet/type/mount.rb +3 -2
- data/lib/puppet/type/notify.rb +1 -1
- data/lib/puppet/type/package.rb +24 -23
- data/lib/puppet/type/router.rb +4 -1
- data/lib/puppet/type/schedule.rb +52 -44
- data/lib/puppet/type/scheduled_task.rb +222 -0
- data/lib/puppet/type/selmodule.rb +10 -6
- data/lib/puppet/type/service.rb +11 -11
- data/lib/puppet/type/ssh_authorized_key.rb +2 -5
- data/lib/puppet/type/sshkey.rb +1 -1
- data/lib/puppet/type/stage.rb +1 -1
- data/lib/puppet/type/tidy.rb +10 -8
- data/lib/puppet/type/user.rb +61 -53
- data/lib/puppet/type/vlan.rb +4 -4
- data/lib/puppet/type/whit.rb +6 -2
- data/lib/puppet/type/yumrepo.rb +33 -31
- data/lib/puppet/type/zfs.rb +34 -32
- data/lib/puppet/type/zone.rb +21 -19
- data/lib/puppet/type/zpool.rb +3 -3
- data/lib/puppet/util.rb +24 -6
- data/lib/puppet/util/adsi.rb +12 -7
- data/lib/puppet/util/checksums.rb +1 -1
- data/lib/puppet/util/diff.rb +1 -1
- data/lib/puppet/util/nagios_maker.rb +2 -2
- data/lib/puppet/util/reference.rb +16 -17
- data/lib/puppet/util/settings/file_setting.rb +14 -2
- data/lib/puppet/util/windows/security.rb +96 -32
- data/spec/integration/file_serving/terminus_helper_spec.rb +1 -1
- data/spec/integration/indirector/direct_file_server_spec.rb +9 -15
- data/spec/integration/indirector/file_content/file_server_spec.rb +1 -1
- data/spec/integration/indirector/file_metadata/file_server_spec.rb +1 -1
- data/spec/integration/provider/package_spec.rb +4 -0
- data/spec/integration/provider/service/init_spec.rb +8 -2
- data/spec/integration/reference/providers_spec.rb +1 -1
- data/spec/integration/ssl/certificate_request_spec.rb +1 -2
- data/spec/integration/ssl/certificate_revocation_list_spec.rb +1 -2
- data/spec/integration/ssl/host_spec.rb +1 -2
- data/spec/integration/transaction_spec.rb +25 -17
- data/spec/integration/type/exec_spec.rb +77 -0
- data/spec/integration/type/file_spec.rb +322 -2
- data/spec/integration/util/windows/security_spec.rb +393 -230
- data/spec/integration/util_spec.rb +16 -0
- data/spec/lib/puppet_spec/files.rb +3 -7
- data/spec/unit/application/apply_spec.rb +0 -9
- data/spec/unit/application/inspect_spec.rb +1 -0
- data/spec/unit/configurer/downloader_spec.rb +3 -3
- data/spec/unit/face/certificate_spec.rb +6 -2
- data/spec/unit/file_bucket/dipper_spec.rb +67 -10
- data/spec/unit/file_bucket/file_spec.rb +22 -28
- data/spec/unit/file_serving/content_spec.rb +1 -1
- data/spec/unit/file_serving/metadata_spec.rb +30 -3
- data/spec/unit/indirector/facts/inventory_service_spec.rb +22 -0
- data/spec/unit/indirector/file_bucket_file/file_spec.rb +21 -24
- data/spec/unit/indirector/node/store_configs_spec.rb +1 -0
- data/spec/unit/indirector/resource/ral_spec.rb +1 -1
- data/spec/unit/indirector/resource_type/parser_spec.rb +2 -2
- data/spec/unit/indirector/rest_spec.rb +1 -1
- data/spec/unit/network/handler/ca_spec.rb +1 -1
- data/spec/unit/network/http/mongrel/rest_spec.rb +54 -25
- data/spec/unit/parameter_spec.rb +36 -0
- data/spec/unit/parser/parser_spec.rb +4 -0
- data/spec/unit/property_spec.rb +2 -2
- data/spec/unit/provider/exec/windows_spec.rb +2 -8
- data/spec/unit/provider/file/posix_spec.rb +6 -0
- data/spec/unit/provider/file/windows_spec.rb +18 -0
- data/spec/unit/provider/group/windows_adsi_spec.rb +22 -6
- data/spec/unit/provider/mount/parsed_spec.rb +1 -1
- data/spec/unit/provider/package/msi_spec.rb +2 -2
- data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +1571 -0
- data/spec/unit/provider/service/launchd_spec.rb +143 -130
- data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +5 -0
- data/spec/unit/provider/user/user_role_add_spec.rb +39 -9
- data/spec/unit/provider/user/useradd_spec.rb +1 -1
- data/spec/unit/provider/user/windows_adsi_spec.rb +8 -1
- data/spec/unit/rb_tree_map_spec.rb +572 -0
- data/spec/unit/resource/catalog_spec.rb +1 -1
- data/spec/unit/simple_graph_spec.rb +9 -9
- data/spec/unit/ssl/host_spec.rb +60 -12
- data/spec/unit/transaction/report_spec.rb +3 -3
- data/spec/unit/transaction_spec.rb +394 -11
- data/spec/unit/type/exec_spec.rb +35 -15
- data/spec/unit/type/file/content_spec.rb +11 -10
- data/spec/unit/type/file/mode_spec.rb +73 -19
- data/spec/unit/type/file/source_spec.rb +1 -1
- data/spec/unit/type/file_spec.rb +15 -0
- data/spec/unit/type/group_spec.rb +1 -1
- data/spec/unit/type/mount_spec.rb +5 -5
- data/spec/unit/type/resources_spec.rb +3 -3
- data/spec/unit/type/scheduled_task_spec.rb +102 -0
- data/spec/unit/type/ssh_authorized_key_spec.rb +2 -3
- data/spec/unit/type/user_spec.rb +2 -1
- data/spec/unit/type_spec.rb +48 -4
- data/spec/unit/util/adsi_spec.rb +18 -7
- data/spec/unit/util/checksums_spec.rb +20 -2
- data/spec/unit/util/execution_stub_spec.rb +10 -5
- data/spec/unit/util/logging_spec.rb +6 -6
- data/spec/unit/util/rdoc/parser_spec.rb +1 -1
- data/spec/unit/util/reference_spec.rb +29 -0
- data/spec/unit/util/settings/file_setting_spec.rb +8 -2
- data/spec/unit/util_spec.rb +115 -0
- data/test/other/transactions.rb +5 -11
- data/test/ral/type/exec.rb +1 -1
- metadata +24 -11
@@ -26,335 +26,484 @@ describe "Puppet::Util::Windows::Security", :if => Puppet.features.microsoft_win
|
|
26
26
|
let (:sids) { @sids }
|
27
27
|
let (:winsec) { WindowsSecurityTester.new }
|
28
28
|
|
29
|
-
shared_examples_for "
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
end
|
29
|
+
shared_examples_for "only child owner" do
|
30
|
+
it "should allow child owner" do
|
31
|
+
check_child_owner
|
32
|
+
end
|
34
33
|
|
35
|
-
|
36
|
-
|
37
|
-
|
34
|
+
it "should deny parent owner" do
|
35
|
+
lambda { check_parent_owner }.should raise_error(Errno::EACCES)
|
36
|
+
end
|
38
37
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
it "should deny group" do
|
39
|
+
lambda { check_group }.should raise_error(Errno::EACCES)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should deny other" do
|
43
|
+
lambda { check_other }.should raise_error(Errno::EACCES)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
shared_examples_for "a securable object" do
|
48
|
+
describe "on a volume that doesn't support ACLs" do
|
49
|
+
[:owner, :group, :mode].each do |p|
|
50
|
+
it "should return nil #{p}" do
|
51
|
+
winsec.stubs(:supports_acl?).returns false
|
43
52
|
|
44
|
-
|
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./)
|
53
|
+
winsec.send("get_#{p}", path).should be_nil
|
46
54
|
end
|
47
55
|
end
|
56
|
+
end
|
48
57
|
|
49
|
-
|
50
|
-
|
51
|
-
|
58
|
+
describe "on a volume that supports ACLs" do
|
59
|
+
describe "for a normal user" do
|
60
|
+
before :each do
|
61
|
+
Puppet.features.stubs(:root?).returns(false)
|
52
62
|
end
|
53
63
|
|
54
|
-
|
55
|
-
|
64
|
+
after :each do
|
65
|
+
winsec.set_mode(WindowsSecurityTester::S_IRWXU, parent)
|
66
|
+
winsec.set_mode(WindowsSecurityTester::S_IRWXU, path) if File.exists?(path)
|
56
67
|
end
|
57
|
-
end
|
58
68
|
|
59
|
-
|
60
|
-
|
61
|
-
|
69
|
+
describe "#supports_acl?" do
|
70
|
+
%w[c:/ c:\\ c:/windows/system32 \\\\localhost\\C$ \\\\127.0.0.1\\C$\\foo].each do |path|
|
71
|
+
it "should accept #{path}" do
|
72
|
+
winsec.should be_supports_acl(path)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should raise an exception if it cannot get volume information" do
|
77
|
+
expect {
|
78
|
+
winsec.supports_acl?('foobar')
|
79
|
+
}.to raise_error(Puppet::Error, /Failed to get volume information/)
|
80
|
+
end
|
62
81
|
end
|
63
82
|
|
64
|
-
#
|
65
|
-
|
66
|
-
|
67
|
-
|
83
|
+
describe "#owner=" do
|
84
|
+
it "should allow setting to the current user" do
|
85
|
+
winsec.set_owner(sids[:current_user], path)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should raise an exception when setting to a different user" do
|
89
|
+
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./)
|
90
|
+
end
|
68
91
|
end
|
69
|
-
end
|
70
92
|
|
71
|
-
|
72
|
-
|
73
|
-
|
93
|
+
describe "#owner" do
|
94
|
+
it "it should not be empty" do
|
95
|
+
winsec.get_owner(path).should_not be_empty
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should raise an exception if an invalid path is provided" do
|
99
|
+
lambda { winsec.get_owner("c:\\doesnotexist.txt") }.should raise_error(Puppet::Error, /The system cannot find the file specified./)
|
100
|
+
end
|
74
101
|
end
|
75
102
|
|
76
|
-
|
77
|
-
|
103
|
+
describe "#group=" do
|
104
|
+
it "should allow setting to a group the current owner is a member of" do
|
105
|
+
winsec.set_group(sids[:users], path)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Unlike unix, if the user has permission to WRITE_OWNER, which the file owner has by default,
|
109
|
+
# then they can set the primary group to a group that the user does not belong to.
|
110
|
+
it "should allow setting to a group the current owner is not a member of" do
|
111
|
+
winsec.set_group(sids[:power_users], path)
|
112
|
+
end
|
78
113
|
end
|
79
|
-
end
|
80
114
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
115
|
+
describe "#group" do
|
116
|
+
it "should not be empty" do
|
117
|
+
winsec.get_group(path).should_not be_empty
|
118
|
+
end
|
85
119
|
|
86
|
-
|
120
|
+
it "should raise an exception if an invalid path is provided" do
|
121
|
+
lambda { winsec.get_group("c:\\doesnotexist.txt") }.should raise_error(Puppet::Error, /The system cannot find the file specified./)
|
87
122
|
end
|
88
123
|
end
|
89
124
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
next if ((u & g) != g) or ((g & o) != o)
|
125
|
+
describe "#mode=" do
|
126
|
+
(0000..0700).step(0100).each do |mode|
|
127
|
+
it "should enforce mode #{mode.to_s(8)}" do
|
128
|
+
winsec.set_mode(mode, path)
|
129
|
+
|
130
|
+
check_access(mode, path)
|
131
|
+
end
|
132
|
+
end
|
99
133
|
|
100
|
-
|
101
|
-
|
102
|
-
|
134
|
+
it "should round-trip all 128 modes that do not require deny ACEs" do
|
135
|
+
0.upto(1).each do |s|
|
136
|
+
0.upto(7).each do |u|
|
137
|
+
0.upto(u).each do |g|
|
138
|
+
0.upto(g).each do |o|
|
139
|
+
# if user is superset of group, and group superset of other, then
|
140
|
+
# no deny ace is required, and mode can be converted to win32
|
141
|
+
# access mask, and back to mode without loss of information
|
142
|
+
# (provided the owner and group are not the same)
|
143
|
+
next if ((u & g) != g) or ((g & o) != o)
|
144
|
+
|
145
|
+
mode = (s << 9 | u << 6 | g << 3 | o << 0)
|
146
|
+
winsec.set_mode(mode, path)
|
147
|
+
winsec.get_mode(path).to_s(8).should == mode.to_s(8)
|
148
|
+
end
|
149
|
+
end
|
103
150
|
end
|
104
151
|
end
|
105
152
|
end
|
106
|
-
end
|
107
153
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
154
|
+
describe "for modes that require deny aces" do
|
155
|
+
it "should map everyone to group and owner" do
|
156
|
+
winsec.set_mode(0426, path)
|
157
|
+
winsec.get_mode(path).to_s(8).should == "666"
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should combine user and group modes when owner and group sids are equal" do
|
161
|
+
winsec.set_group(winsec.get_owner(path), path)
|
162
|
+
|
163
|
+
winsec.set_mode(0410, path)
|
164
|
+
winsec.get_mode(path).to_s(8).should == "550"
|
165
|
+
end
|
112
166
|
end
|
113
167
|
|
114
|
-
|
115
|
-
|
168
|
+
describe "for read-only objects" do
|
169
|
+
before :each do
|
170
|
+
winsec.add_attributes(path, WindowsSecurityTester::FILE_ATTRIBUTE_READONLY)
|
171
|
+
(winsec.get_attributes(path) & WindowsSecurityTester::FILE_ATTRIBUTE_READONLY).should be_nonzero
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should make them writable if any sid has write permission" do
|
175
|
+
winsec.set_mode(WindowsSecurityTester::S_IWUSR, path)
|
176
|
+
(winsec.get_attributes(path) & WindowsSecurityTester::FILE_ATTRIBUTE_READONLY).should == 0
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should leave them read-only if no sid has write permission" do
|
180
|
+
winsec.set_mode(WindowsSecurityTester::S_IRUSR | WindowsSecurityTester::S_IXGRP, path)
|
181
|
+
(winsec.get_attributes(path) & WindowsSecurityTester::FILE_ATTRIBUTE_READONLY).should be_nonzero
|
182
|
+
end
|
183
|
+
end
|
116
184
|
|
117
|
-
|
118
|
-
winsec.
|
185
|
+
it "should raise an exception if an invalid path is provided" do
|
186
|
+
lambda { winsec.set_mode(sids[:guest], "c:\\doesnotexist.txt") }.should raise_error(Puppet::Error, /The system cannot find the file specified./)
|
119
187
|
end
|
120
188
|
end
|
121
189
|
|
122
|
-
describe "
|
123
|
-
|
124
|
-
winsec.
|
125
|
-
|
190
|
+
describe "#mode" do
|
191
|
+
it "should report when extra aces are encounted" do
|
192
|
+
winsec.set_acl(path, true) do |acl|
|
193
|
+
(544..547).each do |rid|
|
194
|
+
winsec.add_access_allowed_ace(acl, WindowsSecurityTester::STANDARD_RIGHTS_ALL, "S-1-5-32-#{rid}")
|
195
|
+
end
|
196
|
+
end
|
197
|
+
mode = winsec.get_mode(path)
|
198
|
+
(mode & WindowsSecurityTester::S_IEXTRA).should_not == 0
|
126
199
|
end
|
127
200
|
|
128
|
-
it "should
|
129
|
-
winsec.
|
130
|
-
|
201
|
+
it "should warn if a deny ace is encountered" do
|
202
|
+
winsec.set_acl(path) do |acl|
|
203
|
+
winsec.add_access_denied_ace(acl, WindowsSecurityTester::FILE_GENERIC_WRITE, sids[:guest])
|
204
|
+
winsec.add_access_allowed_ace(acl, WindowsSecurityTester::STANDARD_RIGHTS_ALL | WindowsSecurityTester::SPECIFIC_RIGHTS_ALL, sids[:current_user])
|
205
|
+
end
|
206
|
+
|
207
|
+
Puppet.expects(:warning).with("Unsupported access control entry type: 0x1")
|
208
|
+
|
209
|
+
winsec.get_mode(path)
|
131
210
|
end
|
132
211
|
|
133
|
-
it "should
|
134
|
-
winsec.
|
135
|
-
|
212
|
+
it "should skip inherit-only ace" do
|
213
|
+
winsec.set_acl(path) do |acl|
|
214
|
+
winsec.add_access_allowed_ace(acl, WindowsSecurityTester::STANDARD_RIGHTS_ALL | WindowsSecurityTester::SPECIFIC_RIGHTS_ALL, sids[:current_user])
|
215
|
+
winsec.add_access_allowed_ace(acl, WindowsSecurityTester::FILE_GENERIC_READ, Win32::Security::SID::Everyone, WindowsSecurityTester::INHERIT_ONLY_ACE | WindowsSecurityTester::OBJECT_INHERIT_ACE)
|
216
|
+
end
|
217
|
+
|
218
|
+
(winsec.get_mode(path) & WindowsSecurityTester::S_IRWXO).should == 0
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should raise an exception if an invalid path is provided" do
|
222
|
+
lambda { winsec.get_mode("c:\\doesnotexist.txt") }.should raise_error(Puppet::Error, /The system cannot find the file specified./)
|
136
223
|
end
|
137
224
|
end
|
138
225
|
|
139
|
-
|
140
|
-
|
226
|
+
describe "inherited access control entries" do
|
227
|
+
it "should be absent when the access control list is protected" do
|
228
|
+
winsec.set_mode(WindowsSecurityTester::S_IRWXU, path)
|
229
|
+
(winsec.get_mode(path) & WindowsSecurityTester::S_IEXTRA).should == 0
|
230
|
+
end
|
231
|
+
|
232
|
+
it "should be present when the access control list is unprotected" do
|
233
|
+
# add a bunch of aces to the parent with permission to add children
|
234
|
+
allow = WindowsSecurityTester::STANDARD_RIGHTS_ALL | WindowsSecurityTester::SPECIFIC_RIGHTS_ALL
|
235
|
+
inherit = WindowsSecurityTester::OBJECT_INHERIT_ACE | WindowsSecurityTester::CONTAINER_INHERIT_ACE
|
236
|
+
|
237
|
+
winsec.set_acl(parent, true) do |acl|
|
238
|
+
winsec.add_access_allowed_ace(acl, allow, "S-1-1-0", inherit) # everyone
|
239
|
+
|
240
|
+
(544..547).each do |rid|
|
241
|
+
winsec.add_access_allowed_ace(acl, WindowsSecurityTester::STANDARD_RIGHTS_ALL, "S-1-5-32-#{rid}", inherit)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
# unprotect child, it should inherit from parent
|
246
|
+
winsec.set_mode(WindowsSecurityTester::S_IRWXU, path, false)
|
247
|
+
(winsec.get_mode(path) & WindowsSecurityTester::S_IEXTRA).should == WindowsSecurityTester::S_IEXTRA
|
248
|
+
end
|
141
249
|
end
|
142
250
|
end
|
143
251
|
|
144
|
-
describe "
|
145
|
-
|
146
|
-
winsec.
|
147
|
-
|
148
|
-
|
149
|
-
|
252
|
+
describe "for an administrator", :if => Puppet.features.root? do
|
253
|
+
before :each do
|
254
|
+
winsec.set_mode(WindowsSecurityTester::S_IRWXU | WindowsSecurityTester::S_IRWXG, path)
|
255
|
+
winsec.set_group(sids[:guest], path)
|
256
|
+
winsec.set_owner(sids[:guest], path)
|
257
|
+
lambda { File.open(path, 'r') }.should raise_error(Errno::EACCES)
|
258
|
+
end
|
259
|
+
|
260
|
+
after :each do
|
261
|
+
if File.exists?(path)
|
262
|
+
winsec.set_owner(sids[:current_user], path)
|
263
|
+
winsec.set_mode(WindowsSecurityTester::S_IRWXU, path)
|
150
264
|
end
|
151
|
-
mode = winsec.get_mode(path)
|
152
|
-
(mode & WindowsSecurityTester::S_IEXTRA).should_not == 0
|
153
265
|
end
|
154
266
|
|
155
|
-
|
156
|
-
|
157
|
-
winsec.
|
158
|
-
winsec.
|
267
|
+
describe "#owner=" do
|
268
|
+
it "should accept a user sid" do
|
269
|
+
winsec.set_owner(sids[:admin], path)
|
270
|
+
winsec.get_owner(path).should == sids[:admin]
|
271
|
+
end
|
272
|
+
|
273
|
+
it "should accept a group sid" do
|
274
|
+
winsec.set_owner(sids[:power_users], path)
|
275
|
+
winsec.get_owner(path).should == sids[:power_users]
|
159
276
|
end
|
160
277
|
|
161
|
-
|
278
|
+
it "should raise an exception if an invalid sid is provided" do
|
279
|
+
lambda { winsec.set_owner("foobar", path) }.should raise_error(Puppet::Error, /Failed to convert string SID/)
|
280
|
+
end
|
162
281
|
|
163
|
-
|
282
|
+
it "should raise an exception if an invalid path is provided" do
|
283
|
+
lambda { winsec.set_owner(sids[:guest], "c:\\doesnotexist.txt") }.should raise_error(Puppet::Error, /The system cannot find the file specified./)
|
284
|
+
end
|
164
285
|
end
|
165
286
|
|
166
|
-
|
167
|
-
|
168
|
-
winsec.
|
169
|
-
winsec.
|
287
|
+
describe "#group=" do
|
288
|
+
it "should accept a group sid" do
|
289
|
+
winsec.set_group(sids[:power_users], path)
|
290
|
+
winsec.get_group(path).should == sids[:power_users]
|
291
|
+
end
|
292
|
+
|
293
|
+
it "should accept a user sid" do
|
294
|
+
winsec.set_group(sids[:admin], path)
|
295
|
+
winsec.get_group(path).should == sids[:admin]
|
170
296
|
end
|
171
297
|
|
172
|
-
|
298
|
+
it "should allow owner and group to be the same sid" do
|
299
|
+
winsec.set_mode(0610, path)
|
300
|
+
winsec.set_owner(sids[:power_users], path)
|
301
|
+
winsec.set_group(sids[:power_users], path)
|
302
|
+
|
303
|
+
winsec.get_owner(path).should == sids[:power_users]
|
304
|
+
winsec.get_group(path).should == sids[:power_users]
|
305
|
+
# note group execute permission added to user ace, and then group rwx value
|
306
|
+
# reflected to match
|
307
|
+
winsec.get_mode(path).to_s(8).should == "770"
|
308
|
+
end
|
309
|
+
|
310
|
+
it "should raise an exception if an invalid sid is provided" do
|
311
|
+
lambda { winsec.set_group("foobar", path) }.should raise_error(Puppet::Error, /Failed to convert string SID/)
|
312
|
+
end
|
313
|
+
|
314
|
+
it "should raise an exception if an invalid path is provided" do
|
315
|
+
lambda { winsec.set_group(sids[:guest], "c:\\doesnotexist.txt") }.should raise_error(Puppet::Error, /The system cannot find the file specified./)
|
316
|
+
end
|
173
317
|
end
|
174
318
|
|
175
|
-
|
176
|
-
|
319
|
+
describe "when the sid is NULL" do
|
320
|
+
it "should retrieve an empty owner sid"
|
321
|
+
it "should retrieve an empty group sid"
|
177
322
|
end
|
178
|
-
end
|
179
323
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
324
|
+
describe "when the sid refers to a deleted trustee" do
|
325
|
+
it "should retrieve the user sid" do
|
326
|
+
sid = nil
|
327
|
+
user = Puppet::Util::ADSI::User.create("delete_me_user")
|
328
|
+
user.commit
|
329
|
+
begin
|
330
|
+
sid = Sys::Admin::get_user(user.name).sid
|
331
|
+
winsec.set_owner(sid, path)
|
332
|
+
winsec.set_mode(WindowsSecurityTester::S_IRWXU, path)
|
333
|
+
ensure
|
334
|
+
Puppet::Util::ADSI::User.delete(user.name)
|
335
|
+
end
|
336
|
+
|
337
|
+
winsec.get_owner(path).should == sid
|
338
|
+
winsec.get_mode(path).should == WindowsSecurityTester::S_IRWXU
|
339
|
+
end
|
340
|
+
|
341
|
+
it "should retrieve the group sid" do
|
342
|
+
sid = nil
|
343
|
+
group = Puppet::Util::ADSI::Group.create("delete_me_group")
|
344
|
+
group.commit
|
345
|
+
begin
|
346
|
+
sid = Sys::Admin::get_group(group.name).sid
|
347
|
+
winsec.set_group(sid, path)
|
348
|
+
winsec.set_mode(WindowsSecurityTester::S_IRWXG, path)
|
349
|
+
ensure
|
350
|
+
Puppet::Util::ADSI::Group.delete(group.name)
|
351
|
+
end
|
352
|
+
winsec.get_group(path).should == sid
|
353
|
+
winsec.get_mode(path).should == WindowsSecurityTester::S_IRWXG
|
354
|
+
end
|
184
355
|
end
|
185
356
|
|
186
|
-
|
187
|
-
|
357
|
+
describe "#mode" do
|
358
|
+
it "should deny all access when the DACL is empty" do
|
359
|
+
winsec.set_acl(path, true) { |acl| }
|
188
360
|
|
189
|
-
|
190
|
-
|
191
|
-
inherit = WindowsSecurityTester::OBJECT_INHERIT_ACE | WindowsSecurityTester::CONTAINER_INHERIT_ACE
|
361
|
+
winsec.get_mode(path).should == 0
|
362
|
+
end
|
192
363
|
|
193
|
-
|
194
|
-
|
364
|
+
# REMIND: ruby crashes when trying to set a NULL DACL
|
365
|
+
# it "should allow all when it is nil" do
|
366
|
+
# winsec.set_owner(sids[:current_user], path)
|
367
|
+
# winsec.open_file(path, WindowsSecurityTester::READ_CONTROL | WindowsSecurityTester::WRITE_DAC) do |handle|
|
368
|
+
# winsec.set_security_info(handle, WindowsSecurityTester::DACL_SECURITY_INFORMATION | WindowsSecurityTester::PROTECTED_DACL_SECURITY_INFORMATION, nil)
|
369
|
+
# end
|
370
|
+
# winsec.get_mode(path).to_s(8).should == "777"
|
371
|
+
# end
|
372
|
+
end
|
373
|
+
|
374
|
+
describe "#string_to_sid_ptr" do
|
375
|
+
it "should raise an error if an invalid SID is specified" do
|
376
|
+
expect do
|
377
|
+
winsec.string_to_sid_ptr('foobar')
|
378
|
+
end.to raise_error(Puppet::Util::Windows::Error) { |error| error.code.should == 1337 }
|
379
|
+
end
|
195
380
|
|
196
|
-
|
197
|
-
|
381
|
+
it "should yield if a block is given" do
|
382
|
+
yielded = nil
|
383
|
+
winsec.string_to_sid_ptr('S-1-1-0') do |sid|
|
384
|
+
yielded = sid
|
198
385
|
end
|
386
|
+
yielded.should_not be_nil
|
199
387
|
end
|
200
388
|
|
201
|
-
|
202
|
-
|
203
|
-
|
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
|
389
|
+
it "should allow no block to be specified" do
|
390
|
+
winsec.string_to_sid_ptr('S-1-1-0').should be_true
|
391
|
+
end
|
208
392
|
end
|
209
|
-
end
|
210
|
-
end
|
211
393
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
end
|
394
|
+
describe "when the parent directory" do
|
395
|
+
before :each do
|
396
|
+
winsec.set_owner(sids[:current_user], parent)
|
397
|
+
winsec.set_owner(sids[:current_user], path)
|
398
|
+
winsec.set_mode(0777, path, false)
|
399
|
+
end
|
219
400
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
end
|
401
|
+
def check_child_owner
|
402
|
+
winsec.set_group(sids[:guest], parent)
|
403
|
+
winsec.set_owner(sids[:guest], parent)
|
224
404
|
|
225
|
-
|
226
|
-
|
227
|
-
winsec.set_owner(sids[:admin], path)
|
228
|
-
winsec.get_owner(path).should == sids[:admin]
|
229
|
-
end
|
405
|
+
check_delete(path)
|
406
|
+
end
|
230
407
|
|
231
|
-
|
232
|
-
winsec.
|
233
|
-
winsec.
|
234
|
-
end
|
408
|
+
def check_parent_owner
|
409
|
+
winsec.set_group(sids[:guest], path)
|
410
|
+
winsec.set_owner(sids[:guest], path)
|
235
411
|
|
236
|
-
|
237
|
-
lambda { winsec.set_owner("foobar", path) }.should raise_error(Puppet::Error, /Failed to convert string SID/)
|
412
|
+
check_delete(path)
|
238
413
|
end
|
239
414
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
end
|
415
|
+
def check_group
|
416
|
+
winsec.set_group(sids[:current_user], path)
|
417
|
+
winsec.set_owner(sids[:guest], path)
|
244
418
|
|
245
|
-
|
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
|
419
|
+
winsec.set_owner(sids[:guest], parent)
|
250
420
|
|
251
|
-
|
252
|
-
winsec.set_group(sids[:admin], path)
|
253
|
-
winsec.get_group(path).should == sids[:admin]
|
421
|
+
check_delete(path)
|
254
422
|
end
|
255
423
|
|
256
|
-
|
257
|
-
winsec.
|
258
|
-
winsec.
|
259
|
-
winsec.set_mode(0610, path)
|
424
|
+
def check_other
|
425
|
+
winsec.set_group(sids[:guest], path)
|
426
|
+
winsec.set_owner(sids[:guest], path)
|
260
427
|
|
261
|
-
winsec.
|
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
|
428
|
+
winsec.set_owner(sids[:guest], parent)
|
267
429
|
|
268
|
-
|
269
|
-
lambda { winsec.set_group("foobar", path) }.should raise_error(Puppet::Error, /Failed to convert string SID/)
|
430
|
+
check_delete(path)
|
270
431
|
end
|
271
432
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
433
|
+
describe "is writable and executable" do
|
434
|
+
describe "and sticky bit is set" do
|
435
|
+
before :each do
|
436
|
+
winsec.set_mode(01777, parent)
|
437
|
+
end
|
276
438
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
end
|
439
|
+
it "should allow child owner" do
|
440
|
+
check_child_owner
|
441
|
+
end
|
281
442
|
|
282
|
-
|
283
|
-
|
284
|
-
|
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
|
443
|
+
it "should allow parent owner" do
|
444
|
+
check_parent_owner
|
445
|
+
end
|
294
446
|
|
295
|
-
|
296
|
-
|
297
|
-
|
447
|
+
it "should deny group" do
|
448
|
+
lambda { check_group }.should raise_error(Errno::EACCES)
|
449
|
+
end
|
298
450
|
|
299
|
-
|
300
|
-
|
301
|
-
|
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)
|
451
|
+
it "should deny other" do
|
452
|
+
lambda { check_other }.should raise_error(Errno::EACCES)
|
453
|
+
end
|
309
454
|
end
|
310
|
-
winsec.get_group(path).should == sid
|
311
|
-
winsec.get_mode(path).should == WindowsSecurityTester::S_IRWXG
|
312
|
-
end
|
313
|
-
end
|
314
455
|
|
315
|
-
|
316
|
-
|
317
|
-
|
456
|
+
describe "and sticky bit is not set" do
|
457
|
+
before :each do
|
458
|
+
winsec.set_mode(0777, parent)
|
459
|
+
end
|
318
460
|
|
319
|
-
|
320
|
-
|
461
|
+
it "should allow child owner" do
|
462
|
+
check_child_owner
|
463
|
+
end
|
321
464
|
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
# end
|
330
|
-
end
|
465
|
+
it "should allow parent owner" do
|
466
|
+
check_parent_owner
|
467
|
+
end
|
468
|
+
|
469
|
+
it "should allow group" do
|
470
|
+
check_group
|
471
|
+
end
|
331
472
|
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
end.to raise_error(Puppet::Util::Windows::Error) { |error| error.code.should == 1337 }
|
473
|
+
it "should allow other" do
|
474
|
+
check_other
|
475
|
+
end
|
476
|
+
end
|
337
477
|
end
|
338
478
|
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
yielded = sid
|
479
|
+
describe "is not writable" do
|
480
|
+
before :each do
|
481
|
+
winsec.set_mode(0555, parent)
|
343
482
|
end
|
344
|
-
|
483
|
+
|
484
|
+
it_behaves_like "only child owner"
|
345
485
|
end
|
346
486
|
|
347
|
-
|
348
|
-
|
487
|
+
describe "is not executable" do
|
488
|
+
before :each do
|
489
|
+
winsec.set_mode(0666, parent)
|
490
|
+
end
|
491
|
+
|
492
|
+
it_behaves_like "only child owner"
|
349
493
|
end
|
350
494
|
end
|
351
495
|
end
|
352
496
|
end
|
497
|
+
end
|
353
498
|
|
354
499
|
describe "file" do
|
355
|
-
let :
|
356
|
-
|
357
|
-
|
500
|
+
let (:parent) do
|
501
|
+
tmpdir('win_sec_test_file')
|
502
|
+
end
|
503
|
+
|
504
|
+
let (:path) do
|
505
|
+
path = File.join(parent, 'childfile')
|
506
|
+
File.new(path, 'w').close
|
358
507
|
path
|
359
508
|
end
|
360
509
|
|
@@ -390,6 +539,10 @@ describe "Puppet::Util::Windows::Security", :if => Puppet.features.microsoft_win
|
|
390
539
|
def check_execute(path)
|
391
540
|
Kernel.exec(path)
|
392
541
|
end
|
542
|
+
|
543
|
+
def check_delete(path)
|
544
|
+
File.delete(path)
|
545
|
+
end
|
393
546
|
end
|
394
547
|
|
395
548
|
describe "locked files" do
|
@@ -410,10 +563,16 @@ describe "Puppet::Util::Windows::Security", :if => Puppet.features.microsoft_win
|
|
410
563
|
end
|
411
564
|
|
412
565
|
describe "directory" do
|
413
|
-
let :
|
566
|
+
let (:parent) do
|
414
567
|
tmpdir('win_sec_test_dir')
|
415
568
|
end
|
416
569
|
|
570
|
+
let (:path) do
|
571
|
+
path = File.join(parent, 'childdir')
|
572
|
+
Dir.mkdir(path)
|
573
|
+
path
|
574
|
+
end
|
575
|
+
|
417
576
|
it_behaves_like "a securable object" do
|
418
577
|
def check_access(mode, path)
|
419
578
|
if (mode & WindowsSecurityTester::S_IRUSR).nonzero?
|
@@ -444,7 +603,11 @@ describe "Puppet::Util::Windows::Security", :if => Puppet.features.microsoft_win
|
|
444
603
|
end
|
445
604
|
|
446
605
|
def check_execute(path)
|
447
|
-
Dir.chdir(path) {
|
606
|
+
Dir.chdir(path) {}
|
607
|
+
end
|
608
|
+
|
609
|
+
def check_delete(path)
|
610
|
+
Dir.rmdir(path)
|
448
611
|
end
|
449
612
|
end
|
450
613
|
|