summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Mundrawala <jdmundrawala@gmail.com>2015-05-08 13:01:53 -0700
committerJay Mundrawala <jdmundrawala@gmail.com>2015-05-15 08:51:21 -0700
commit7f6631c20c71ff23cca265ae844f931cd2bd2776 (patch)
tree531f098421fb7cd814f8d5c4e47a92404a26bb36
parente90ff3c513b8f3dcbb55a769a2aece2fc0e15cd9 (diff)
downloadchef-7f6631c20c71ff23cca265ae844f931cd2bd2776.tar.gz
LogonUser uses ffi instead win32-api
-rw-r--r--lib/chef/mixin/wstring.rb31
-rw-r--r--lib/chef/util/windows/net_user.rb19
-rw-r--r--lib/chef/win32/api/security.rb16
-rw-r--r--lib/chef/win32/net.rb12
-rw-r--r--lib/chef/win32/security.rb15
5 files changed, 76 insertions, 17 deletions
diff --git a/lib/chef/mixin/wstring.rb b/lib/chef/mixin/wstring.rb
new file mode 100644
index 0000000000..bb6fdf4884
--- /dev/null
+++ b/lib/chef/mixin/wstring.rb
@@ -0,0 +1,31 @@
+#
+# Author:: Jay Mundrawala(<jdm@chef.io>)
+# Copyright:: Copyright 2015 Chef Software
+# 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.
+#
+
+class Chef
+ module Mixin
+ module WideString
+ def wstring(str)
+ if str.nil? || str.encoding == Encoding::UTF_16LE
+ str
+ else
+ str.to_wstring
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/util/windows/net_user.rb b/lib/chef/util/windows/net_user.rb
index b98f346f51..26fbe53db6 100644
--- a/lib/chef/util/windows/net_user.rb
+++ b/lib/chef/util/windows/net_user.rb
@@ -19,6 +19,7 @@
require 'chef/util/windows'
require 'chef/exceptions'
require 'chef/win32/net'
+require 'chef/win32/security'
#wrapper around a subset of the NetUser* APIs.
#nothing Chef specific, but not complete enough to be its own gem, so util for now.
@@ -26,8 +27,7 @@ class Chef::Util::Windows::NetUser < Chef::Util::Windows
private
NetUser = Chef::ReservedNames::Win32::NetUser
-
- LogonUser = Windows::API.new('LogonUser', 'SSSLLP', 'I', 'advapi32')
+ Security = Chef::ReservedNames::Win32::Security
USER_INFO_3_TRANSFORM = {
name: :usri3_name,
@@ -91,18 +91,17 @@ class Chef::Util::Windows::NetUser < Chef::Util::Windows
@name = multi_to_wide(username)
end
- LOGON32_PROVIDER_DEFAULT = 0
- LOGON32_LOGON_NETWORK = 3
+ LOGON32_PROVIDER_DEFAULT = Security::LOGON32_PROVIDER_DEFAULT
+ LOGON32_LOGON_NETWORK = Security::LOGON32_LOGON_NETWORK
#XXX for an extra painful alternative, see: http://support.microsoft.com/kb/180548
def validate_credentials(passwd)
- token = 0.chr * PTR_SIZE
- res = LogonUser.call(@username, nil, passwd,
- LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, token)
- if res == 0
+ begin
+ token = Security::logon_user(@username, nil, passwd,
+ LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT)
+ return true
+ rescue Chef::Exceptions::Win32APIError
return false
end
- ::Windows::Handle::CloseHandle.call(token.unpack('L')[0])
- return true
end
def get_info
diff --git a/lib/chef/win32/api/security.rb b/lib/chef/win32/api/security.rb
index 229f2ace10..95e7f4aab7 100644
--- a/lib/chef/win32/api/security.rb
+++ b/lib/chef/win32/api/security.rb
@@ -193,6 +193,20 @@ class Chef
MAXDWORD = 0xffffffff
+ # LOGON32 constants for LogonUser
+ LOGON32_LOGON_INTERACTIVE = 2;
+ LOGON32_LOGON_NETWORK = 3;
+ LOGON32_LOGON_BATCH = 4;
+ LOGON32_LOGON_SERVICE = 5;
+ LOGON32_LOGON_UNLOCK = 7;
+ LOGON32_LOGON_NETWORK_CLEARTEXT = 8;
+ LOGON32_LOGON_NEW_CREDENTIALS = 9;
+
+ LOGON32_PROVIDER_DEFAULT = 0;
+ LOGON32_PROVIDER_WINNT35 = 1;
+ LOGON32_PROVIDER_WINNT40 = 2;
+ LOGON32_PROVIDER_WINNT50 = 3;
+
###############################################
# Win32 API Bindings
###############################################
@@ -405,6 +419,8 @@ class Chef
safe_attach_function :SetSecurityDescriptorOwner, [ :pointer, :pointer, :BOOL ], :BOOL
safe_attach_function :SetSecurityDescriptorSacl, [ :pointer, :BOOL, :pointer, :BOOL ], :BOOL
safe_attach_function :GetTokenInformation, [ :HANDLE, :TOKEN_INFORMATION_CLASS, :pointer, :DWORD, :PDWORD ], :BOOL
+ safe_attach_function :LogonUserW, [:LPTSTR, :LPTSTR, :LPTSTR, :DWORD, :DWORD, :PHANDLE], :BOOL
+
end
end
end
diff --git a/lib/chef/win32/net.rb b/lib/chef/win32/net.rb
index 41a8517952..0b095db2e9 100644
--- a/lib/chef/win32/net.rb
+++ b/lib/chef/win32/net.rb
@@ -18,6 +18,8 @@
require 'chef/win32/api/net'
require 'chef/win32/error'
+require 'chef/mixin/wstring'
+
class Chef
module ReservedNames::Win32
class NetUser
@@ -27,6 +29,9 @@ class Chef
include Chef::ReservedNames::Win32::API::Net
extend Chef::ReservedNames::Win32::API::Net
+ include Chef::Mixin::WideString
+ extend Chef::Mixin::WideString
+
def self.default_user_info_3
ui3 = USER_INFO_3.new.tap do |s|
{ usri3_name: nil,
@@ -208,13 +213,6 @@ END
private
- def self.wstring(str)
- if str.nil? || str.encoding == Encoding::UTF_16LE
- str
- else
- str.to_wstring
- end
- end
end
end
diff --git a/lib/chef/win32/security.rb b/lib/chef/win32/security.rb
index 3902d8caaf..a5a845e55c 100644
--- a/lib/chef/win32/security.rb
+++ b/lib/chef/win32/security.rb
@@ -22,6 +22,7 @@ require 'chef/win32/memory'
require 'chef/win32/process'
require 'chef/win32/unicode'
require 'chef/win32/security/token'
+require 'chef/mixin/wstring'
class Chef
module ReservedNames::Win32
@@ -31,6 +32,8 @@ class Chef
include Chef::ReservedNames::Win32::API::Security
extend Chef::ReservedNames::Win32::API::Security
extend Chef::ReservedNames::Win32::API::Macros
+ include Chef::Mixin::WideString
+ extend Chef::Mixin::WideString
def self.access_check(security_descriptor, token, desired_access, generic_mapping)
token_handle = token.handle.handle
@@ -543,6 +546,18 @@ class Chef
success && (elevation_result.read_ulong != 0)
end
end
+
+ def self.logon_user(username, domain, password, logon_type, logon_provider)
+ username = wstring(username)
+ domain = wstring(domain)
+ password = wstring(password)
+
+ token = FFI::Buffer.new(:pointer)
+ unless LogonUserW(username, domain, password, logon_type, logon_provider, token)
+ Chef::ReservedNames::Win32::Error.raise!
+ end
+ Token.new(Handle.new(token.read_pointer))
+ end
end
end
end