summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Mundrawala <jdmundrawala@gmail.com>2015-05-08 07:03:34 -0700
committerJay Mundrawala <jdmundrawala@gmail.com>2015-05-15 08:51:16 -0700
commitca93171b6d2ed8a5a36c1f10f09a26b47fea47bf (patch)
treeb16051150c8f541367fec8825bc86e8329c2aafb
parente0fb4b98b6af2c4eb03eab7b84d2ea55cba87d35 (diff)
downloadchef-ca93171b6d2ed8a5a36c1f10f09a26b47fea47bf.tar.gz
NetUserGetInfo uses ffi
-rw-r--r--lib/chef/util/windows/net_user.rb26
-rw-r--r--lib/chef/win32/api/net.rb48
-rw-r--r--lib/chef/win32/user.rb51
3 files changed, 106 insertions, 19 deletions
diff --git a/lib/chef/util/windows/net_user.rb b/lib/chef/util/windows/net_user.rb
index e79d9212c5..1144645eef 100644
--- a/lib/chef/util/windows/net_user.rb
+++ b/lib/chef/util/windows/net_user.rb
@@ -123,6 +123,14 @@ class Chef::Util::Windows::NetUser < Chef::Util::Windows
end
end
+ def usri3_to_hash(usri3)
+ t = USER_INFO_3_TRANSFORM.invert
+ usri3.inject({}) do |memo, (k,v)|
+ memo[USER_INFO_3_TRANSFORM[k]] = v
+ memo
+ end
+ end
+
def user_info_3(args)
USER_INFO_3.collect { |field|
args.include?(field[0]) ? args[field[0]] : field[1]
@@ -175,20 +183,12 @@ class Chef::Util::Windows::NetUser < Chef::Util::Windows
end
def get_info
- ptr = 0.chr * PTR_SIZE
- rc = NetUserGetInfo.call(nil, @name, 3, ptr)
-
- if rc == NERR_UserNotFound
- raise Chef::Exceptions::UserIDNotFound, get_last_error(rc)
- elsif rc != NERR_Success
- raise ArgumentError, get_last_error(rc)
+ begin
+ ui3 = Chef::ReservedNames::Win32::NetUser::net_user_get_info_l3(nil, @username)
+ rescue Chef::Exceptions::Win32APIError => e
+ raise ArgumentError, e
end
-
- ptr = ptr.unpack('L')[0]
- buffer = 0.chr * SIZEOF_USER_INFO_3
- memcpy(buffer, ptr, buffer.size)
- NetApiBufferFree(ptr)
- user_info_3_unpack(buffer)
+ usri3_to_hash(ui3)
end
def add(args)
diff --git a/lib/chef/win32/api/net.rb b/lib/chef/win32/api/net.rb
index f2cfa93828..5eb77ae2b0 100644
--- a/lib/chef/win32/api/net.rb
+++ b/lib/chef/win32/api/net.rb
@@ -45,6 +45,7 @@ class Chef
NERR_NotPrimary = 2226
NERR_SpeGroupOp = 2234
NERR_LastAdmin = 2452
+ NERR_BadUsername = 2202
NERR_BadPassword = 2203
NERR_PasswordTooShort = 2245
NERR_UserNotFound = 2221
@@ -85,11 +86,44 @@ class Chef
def set(key, val)
- if val.class == String
+ if val.is_a? String
val = FFI::MemoryPointer.from_string(val.to_wstring)
end
self[key] = val
end
+
+ def get(key)
+ if respond_to? key
+ send(key)
+ else
+ val = self[key]
+ if val.is_a? FFI::Pointer
+ if val.null?
+ nil
+ else
+ val.read_wstring
+ end
+ else
+ val
+ end
+ end
+ end
+
+ def usri3_logon_hours
+ val = self[:usri3_logon_hours]
+ if !val.nil? && !val.null?
+ val.read_bytes(21)
+ else
+ nil
+ end
+ end
+
+ def as_ruby
+ members.inject({}) do |memo, key|
+ memo[key] = get(key)
+ memo
+ end
+ end
end
class LOCALGROUP_MEMBERS_INFO_3 < FFI::Struct
@@ -130,6 +164,18 @@ class Chef
#);
safe_attach_function :NetLocalGroupAddMembers, [:LPCWSTR, :LPCWSTR, :DWORD, :LPBYTE, :DWORD ], :DWORD
+#NET_API_STATUS NetUserGetInfo(
+# _In_ LPCWSTR servername,
+# _In_ LPCWSTR username,
+# _In_ DWORD level,
+# _Out_ LPBYTE *bufptr
+#);
+ safe_attach_function :NetUserGetInfo, [:LPCWSTR, :LPCWSTR, :DWORD, :LPBYTE], :DWORD
+
+#NET_API_STATUS NetApiBufferFree(
+# _In_ LPVOID Buffer
+#);
+ safe_attach_function :NetApiBufferFree, [:LPVOID], :DWORD
end
end
end
diff --git a/lib/chef/win32/user.rb b/lib/chef/win32/user.rb
index 095989236e..345eb3b6c7 100644
--- a/lib/chef/win32/user.rb
+++ b/lib/chef/win32/user.rb
@@ -65,10 +65,6 @@ class Chef
end
def self.net_api_error!(code)
- formatted_message = ""
- formatted_message << "---- Begin Win32 API output ----\n"
- formatted_message << "Net Api Error Code: #{code}\n"
-
msg = case code
when NERR_InvalidComputer
"The user does not have access to the requested information."
@@ -83,7 +79,7 @@ class Chef
when NERR_BadPassword
"The password parameter is invalid."
when NERR_UserNotFound
- "The user name could not be found."
+ raise Chef::Exceptions::UserIDNotFound, code
when NERR_PasswordTooShort
<<END
The password is shorter than required. (The password could also be too
@@ -96,8 +92,12 @@ END
"Received unknown error code (#{code})"
end
+ formatted_message = ""
+ formatted_message << "---- Begin Win32 API output ----\n"
+ formatted_message << "Net Api Error Code: #{code}\n"
formatted_message << "Net Api Error Message: #{msg}\n"
formatted_message << "---- End Win32 API output ----\n"
+
raise Chef::Exceptions::Win32APIError, msg + "\n" + formatted_message
end
@@ -121,6 +121,37 @@ END
end
end
+ def self.net_user_get_info_l3(server_name, user_name)
+ server_name = wstring(server_name)
+ user_name = wstring(user_name)
+
+ ui3_p = FFI::MemoryPointer.new(:pointer)
+
+ rc = NetUserGetInfo(server_name, user_name, 3, ui3_p)
+
+ if rc != NERR_Success
+ if Chef::ReservedNames::Win32::Error.get_last_error != 0
+ Chef::ReservedNames::Win32::Error.raise!
+ else
+ net_api_error!(rc)
+ end
+ end
+
+ ui3 = USER_INFO_3.new(ui3_p.read_pointer).as_ruby
+
+ rc = NetApiBufferFree(ui3_p.read_pointer)
+
+ if rc != NERR_Success
+ if Chef::ReservedNames::Win32::Error.get_last_error != 0
+ Chef::ReservedNames::Win32::Error.raise!
+ else
+ net_api_error!(rc)
+ end
+ end
+
+ ui3
+ end
+
def self.net_local_group_add_member(server_name, group_name, domain_user)
server_name = server_name.to_wstring if server_name
group_name = group_name.to_wstring
@@ -140,6 +171,16 @@ END
end
end
+ private
+
+ def self.wstring(str)
+ if str.nil? || str.encoding == Encoding::UTF_16LE
+ str
+ else
+ str.to_wstring
+ end
+ end
+
end
end
end