summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Mundrawala <jdmundrawala@gmail.com>2015-07-29 15:39:25 -0700
committerJay Mundrawala <jdmundrawala@gmail.com>2015-07-29 15:39:25 -0700
commitd03b97177b1a7dcf9e895f6ca74ec63f8b71f158 (patch)
treebea64f2826782b3eb844a25196e99a5b83020416
parent3519f13ad7cb7bb582198185cb0bc470330fb866 (diff)
downloadchef-d03b97177b1a7dcf9e895f6ca74ec63f8b71f158.tar.gz
FFIify NetLocalGroupGetMembers
-rw-r--r--lib/chef/util/windows/net_group.rb33
-rw-r--r--lib/chef/win32/api.rb1
-rw-r--r--lib/chef/win32/api/net.rb21
-rw-r--r--lib/chef/win32/net.rb36
4 files changed, 62 insertions, 29 deletions
diff --git a/lib/chef/util/windows/net_group.rb b/lib/chef/util/windows/net_group.rb
index 30c32cbc65..43e7484457 100644
--- a/lib/chef/util/windows/net_group.rb
+++ b/lib/chef/util/windows/net_group.rb
@@ -48,36 +48,11 @@ class Chef::Util::Windows::NetGroup < Chef::Util::Windows
end
def local_get_members
- group_members = []
- handle = 0.chr * PTR_SIZE
- rc = ERROR_MORE_DATA
-
- while rc == ERROR_MORE_DATA
- ptr = 0.chr * PTR_SIZE
- nread = 0.chr * PTR_SIZE
- total = 0.chr * PTR_SIZE
-
- rc = NetLocalGroupGetMembers.call(nil, @name, 0, ptr, -1,
- nread, total, handle)
- if (rc == NERR_Success) || (rc == ERROR_MORE_DATA)
- ptr = ptr.unpack('L')[0]
- nread = nread.unpack('i')[0]
- members = 0.chr * (nread * PTR_SIZE ) #nread * sizeof(LOCALGROUP_MEMBERS_INFO_0)
- memcpy(members, ptr, members.size)
-
- # 1 pointer field in LOCALGROUP_MEMBERS_INFO_0, offset 0 is lgrmi0_sid
- nread.times do |i|
- sid_address = members[i * PTR_SIZE, PTR_SIZE].unpack('L')[0]
- sid_ptr = FFI::Pointer.new(sid_address)
- member_sid = Chef::ReservedNames::Win32::Security::SID.new(sid_ptr)
- group_members << member_sid.to_s
- end
- NetApiBufferFree(ptr)
- else
- raise ArgumentError, get_last_error(rc)
- end
+ begin
+ Chef::ReservedNames::Win32::NetUser::net_local_group_get_members(nil, @groupname)
+ rescue Chef::Exceptions::Win32NetAPIError => e
+ raise ArgumentError, e.msg
end
- group_members
end
def local_add
diff --git a/lib/chef/win32/api.rb b/lib/chef/win32/api.rb
index e9d273808a..4786222bd4 100644
--- a/lib/chef/win32/api.rb
+++ b/lib/chef/win32/api.rb
@@ -188,6 +188,7 @@ class Chef
host.typedef :pointer, :PCRYPTPROTECT_PROMPTSTRUCT # Pointer to a CRYPTOPROTECT_PROMPTSTRUCT.
host.typedef :pointer, :PDATA_BLOB # Pointer to a DATA_BLOB.
host.typedef :pointer, :PTSTR # A PWSTR if UNICODE is defined, a PSTR otherwise.
+ host.typedef :pointer, :PSID
host.typedef :pointer, :PUCHAR # Pointer to a UCHAR.
host.typedef :pointer, :PUHALF_PTR # Pointer to a UHALF_PTR.
host.typedef :pointer, :PUINT # Pointer to a UINT.
diff --git a/lib/chef/win32/api/net.rb b/lib/chef/win32/api/net.rb
index 66059fc3eb..d02add9c2c 100644
--- a/lib/chef/win32/api/net.rb
+++ b/lib/chef/win32/api/net.rb
@@ -49,7 +49,9 @@ class Chef
NERR_BadPassword = 2203
NERR_PasswordTooShort = 2245
NERR_UserNotFound = 2221
+ NERR_GroupNotFound = 2220
ERROR_ACCESS_DENIED = 5
+ ERROR_MORE_DATA = 234
ffi_lib "netapi32"
@@ -132,6 +134,10 @@ class Chef
end
end
+ class LOCALGROUP_MEMBERS_INFO_0 < FFI::Struct
+ layout :lgrmi0_sid, :PSID
+ end
+
class LOCALGROUP_MEMBERS_INFO_3 < FFI::Struct
layout :lgrmi3_domainandname, :LPWSTR
end
@@ -154,6 +160,21 @@ class Chef
#);
safe_attach_function :NetLocalGroupDel, [ :LPCWSTR, :LPCWSTR], :DWORD
+#NET_API_STATUS NetLocalGroupGetMembers(
+ #_In_ LPCWSTR servername,
+ #_In_ LPCWSTR localgroupname,
+ #_In_ DWORD level,
+ #_Out_ LPBYTE *bufptr,
+ #_In_ DWORD prefmaxlen,
+ #_Out_ LPDWORD entriesread,
+ #_Out_ LPDWORD totalentries,
+ #_Inout_ PDWORD_PTR resumehandle
+#);
+ safe_attach_function :NetLocalGroupGetMembers, [
+ :LPCWSTR, :LPCWSTR, :DWORD, :LPBYTE, :DWORD,
+ :LPDWORD, :LPDWORD, :PDWORD_PTR
+ ], :DWORD
+
# NET_API_STATUS NetUserEnum(
# _In_ LPCWSTR servername,
# _In_ DWORD level,
diff --git a/lib/chef/win32/net.rb b/lib/chef/win32/net.rb
index 18a26d92bc..8c3ddc5a57 100644
--- a/lib/chef/win32/net.rb
+++ b/lib/chef/win32/net.rb
@@ -91,6 +91,8 @@ The password is shorter than required. (The password could also be too
long, be too recent in its change history, not have enough unique characters,
or not meet another password policy requirement.)
END
+ when NERR_GroupNotFound
+ "The group name could not be found."
when ERROR_ACCESS_DENIED
"The user does not have access to the requested information."
else
@@ -123,6 +125,40 @@ END
end
end
+ def self.net_local_group_get_members(server_name, group_name)
+ server_name = wstring(server_name)
+ group_name = wstring(group_name)
+
+ buf = FFI::MemoryPointer.new(:pointer)
+ entries_read_ptr = FFI::MemoryPointer.new(:long)
+ total_read_ptr = FFI::MemoryPointer.new(:long)
+ resume_handle_ptr = FFI::MemoryPointer.new(:pointer)
+
+ rc = ERROR_MORE_DATA
+ group_members = []
+ while rc == ERROR_MORE_DATA
+ rc = NetLocalGroupGetMembers(
+ server_name, group_name, 0, buf, -1,
+ entries_read_ptr, total_read_ptr, resume_handle_ptr
+ )
+
+ nread = entries_read_ptr.read_long
+ nread.times do |i|
+ member = LOCALGROUP_MEMBERS_INFO_0.new(buf.read_pointer +
+ (i * LOCALGROUP_MEMBERS_INFO_0.size))
+ member_sid = Chef::ReservedNames::Win32::Security::SID.new(member[:lgrmi0_sid])
+ group_members << member_sid.to_s
+ end
+ NetApiBufferFree(buf.read_pointer)
+ end
+
+ if rc != NERR_Success
+ net_api_error!(rc)
+ end
+
+ group_members
+ end
+
def self.net_user_add_l3(server_name, args)
buf = default_user_info_3