1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
#
# Author:: John Keiser (<jkeiser@chef.io>)
# Copyright:: Copyright 2011-2016, Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require "chef/win32/security"
require "chef/win32/security/acl"
require "chef/win32/security/sid"
class Chef
module ReservedNames::Win32
class Security
class SecurableObject
def initialize(path, type = :SE_FILE_OBJECT)
@path = path
@type = type
end
attr_reader :path
attr_reader :type
SecurityConst = Chef::ReservedNames::Win32::API::Security
# This method predicts what the rights mask would be on an object
# if you created an ACE with the given mask. Specifically, it looks for
# generic attributes like GENERIC_READ, and figures out what specific
# attributes will be set. This is important if you want to try to
# compare an existing ACE with one you want to create.
def predict_rights_mask(generic_mask)
mask = generic_mask
#mask |= Chef::ReservedNames::Win32::API::Security::STANDARD_RIGHTS_READ if (mask | Chef::ReservedNames::Win32::API::Security::GENERIC_READ) != 0
#mask |= Chef::ReservedNames::Win32::API::Security::STANDARD_RIGHTS_WRITE if (mask | Chef::ReservedNames::Win32::API::Security::GENERIC_WRITE) != 0
#mask |= Chef::ReservedNames::Win32::API::Security::STANDARD_RIGHTS_EXECUTE if (mask | Chef::ReservedNames::Win32::API::Security::GENERIC_EXECUTE) != 0
#mask |= Chef::ReservedNames::Win32::API::Security::STANDARD_RIGHTS_ALL if (mask | Chef::ReservedNames::Win32::API::Security::GENERIC_ALL) != 0
if type == :SE_FILE_OBJECT
mask |= Chef::ReservedNames::Win32::API::Security::FILE_GENERIC_READ if (mask & Chef::ReservedNames::Win32::API::Security::GENERIC_READ) != 0
mask |= Chef::ReservedNames::Win32::API::Security::FILE_GENERIC_WRITE if (mask & Chef::ReservedNames::Win32::API::Security::GENERIC_WRITE) != 0
mask |= Chef::ReservedNames::Win32::API::Security::FILE_GENERIC_EXECUTE if (mask & Chef::ReservedNames::Win32::API::Security::GENERIC_EXECUTE) != 0
mask |= Chef::ReservedNames::Win32::API::Security::FILE_ALL_ACCESS if (mask & Chef::ReservedNames::Win32::API::Security::GENERIC_ALL) != 0
else
raise "Unimplemented object type for predict_security_mask: #{type}"
end
mask &= ~(Chef::ReservedNames::Win32::API::Security::GENERIC_READ | Chef::ReservedNames::Win32::API::Security::GENERIC_WRITE | Chef::ReservedNames::Win32::API::Security::GENERIC_EXECUTE | Chef::ReservedNames::Win32::API::Security::GENERIC_ALL)
mask
end
def security_descriptor(include_sacl = false)
security_information = Chef::ReservedNames::Win32::API::Security::OWNER_SECURITY_INFORMATION | Chef::ReservedNames::Win32::API::Security::GROUP_SECURITY_INFORMATION | Chef::ReservedNames::Win32::API::Security::DACL_SECURITY_INFORMATION
if include_sacl
security_information |= Chef::ReservedNames::Win32::API::Security::SACL_SECURITY_INFORMATION
Security.with_privileges("SeSecurityPrivilege") do
Security.get_named_security_info(path, type, security_information)
end
else
Security.get_named_security_info(path, type, security_information)
end
end
def dacl=(val)
Security.set_named_security_info(path, type, dacl: val)
end
# You don't set dacl_inherits without also setting dacl,
# because Windows gets angry and denies you access. So
# if you want to do that, you may as well do both at once.
def set_dacl(dacl, dacl_inherits)
Security.set_named_security_info(path, type, dacl: dacl, dacl_inherits: dacl_inherits)
end
def group=(val)
Security.set_named_security_info(path, type, group: val)
end
def owner=(val)
# TODO to fix serious permissions problems, we may need to enable SeBackupPrivilege. But we might need it (almost) everywhere else, too.
Security.with_privileges("SeTakeOwnershipPrivilege", "SeRestorePrivilege") do
Security.set_named_security_info(path, type, owner: val)
end
end
def sacl=(val)
Security.with_privileges("SeSecurityPrivilege") do
Security.set_named_security_info(path, type, sacl: val)
end
end
def set_sacl(sacl, sacl_inherits)
Security.with_privileges("SeSecurityPrivilege") do
Security.set_named_security_info(path, type, sacl: sacl, sacl_inherits: sacl_inherits)
end
end
end
end
end
end
|