summaryrefslogtreecommitdiff
path: root/lib/chef/win32/security.rb
diff options
context:
space:
mode:
authorMatt Wrock <matt@mattwrock.com>2015-12-29 10:31:41 -0800
committerMatt Wrock <matt@mattwrock.com>2015-12-29 10:31:41 -0800
commit7f69ad99a2446e9c70112aa531f68a971a52758f (patch)
tree918bc63c8ffb8f1354b25378155c478b6fdad2ac /lib/chef/win32/security.rb
parentb027f4b9cebda8314118a0839f93d812e1b6fcfa (diff)
downloadchef-7f69ad99a2446e9c70112aa531f68a971a52758f.tar.gz
fixes #3521 correcting format of user name passed to policy apis and does not clobber existing service rights of other users
Diffstat (limited to 'lib/chef/win32/security.rb')
-rw-r--r--lib/chef/win32/security.rb63
1 files changed, 63 insertions, 0 deletions
diff --git a/lib/chef/win32/security.rb b/lib/chef/win32/security.rb
index bc80517d80..38694c9fec 100644
--- a/lib/chef/win32/security.rb
+++ b/lib/chef/win32/security.rb
@@ -104,6 +104,22 @@ class Chef
end
end
+ def self.add_account_right(name, privilege)
+ privilege_pointer = FFI::MemoryPointer.new LSA_UNICODE_STRING, 1
+ privilege_lsa_string = LSA_UNICODE_STRING.new(privilege_pointer)
+ privilege_lsa_string[:Buffer] = FFI::MemoryPointer.from_string(privilege.to_wstring)
+ privilege_lsa_string[:Length] = privilege.length * 2
+ privilege_lsa_string[:MaximumLength] = (privilege.length + 1) * 2
+
+ with_lsa_policy(name) do |policy_handle, sid|
+ result = LsaAddAccountRights(policy_handle.read_pointer, sid, privilege_pointer, 1)
+ win32_error = LsaNtStatusToWinError(result)
+ if win32_error != 0
+ Chef::ReservedNames::Win32::Error.raise!(nil, win32_error)
+ end
+ end
+ end
+
def self.adjust_token_privileges(token, privileges)
token = token.handle if token.respond_to?(:handle)
old_privileges_size = FFI::Buffer.new(:long).write_long(privileges.size_with_privileges)
@@ -165,6 +181,29 @@ class Chef
end
end
+ def self.get_account_right(name)
+ privileges = []
+ privilege_pointer = FFI::MemoryPointer.new(:pointer)
+ privilege_length = FFI::MemoryPointer.new(:ulong)
+
+ with_lsa_policy(name) do |policy_handle, sid|
+ result = LsaEnumerateAccountRights(policy_handle.read_pointer, sid, privilege_pointer, privilege_length)
+ win32_error = LsaNtStatusToWinError(result)
+ return [] if win32_error == 2 # FILE_NOT_FOUND - No rights assigned
+ if win32_error != 0
+ Chef::ReservedNames::Win32::Error.raise!(nil, win32_error)
+ end
+
+ privilege_length.read_ulong.times do |i|
+ privilege = LSA_UNICODE_STRING.new(privilege_pointer.read_pointer + i * LSA_UNICODE_STRING.size)
+ privileges << privilege[:Buffer].read_wstring
+ end
+ LsaFreeMemory(privilege_pointer)
+ end
+
+ privileges
+ end
+
def self.get_ace(acl, index)
acl = acl.pointer if acl.respond_to?(:pointer)
ace = FFI::Buffer.new :pointer
@@ -548,6 +587,30 @@ class Chef
end
end
+ def self.with_lsa_policy(username)
+ sid = lookup_account_name(username)[1]
+
+ access = 0
+ access |= POLICY_CREATE_ACCOUNT
+ access |= POLICY_LOOKUP_NAMES
+
+ policy_handle = FFI::MemoryPointer.new(:pointer)
+ result = LsaOpenPolicy(nil, LSA_OBJECT_ATTRIBUTES.new, access, policy_handle)
+ win32_error = LsaNtStatusToWinError(result)
+ if win32_error != 0
+ Chef::ReservedNames::Win32::Error.raise!(nil, win32_error)
+ end
+
+ begin
+ yield policy_handle, sid.pointer
+ ensure
+ win32_error = LsaNtStatusToWinError(LsaClose(policy_handle.read_pointer))
+ if win32_error != 0
+ Chef::ReservedNames::Win32::Error.raise!(nil, win32_error)
+ end
+ end
+ end
+
def self.with_privileges(*privilege_names)
# Set privileges
token = open_current_process_token(TOKEN_READ | TOKEN_ADJUST_PRIVILEGES)