This post has been very useful for me. One thing I really do not know whether impersonating to get a user's information is the right way. I am not a windows expert, though.
So I tried another path with GetTokenInformation and LookupAccountSid. I used ruby(ruby on rails) this time which I am more familiar with.
This is my first time to utilize fiddle, but I want to say that fiddle is not that difficult if you have slight knowledge of C.
I hope this post will help someone working with ruby on windows platform.
require "fiddle/import"
require 'fiddle/types'
module WIN32Security
extend Fiddle::Importer
dlload 'advapi32.dll'
include Fiddle::Win32Types
extern 'BOOL GetTokenInformation(HANDLE, UINT, PVOID, DWORD, PDWORD)'
extern 'BOOL LookupAccountSidW(LPSTR, PVOID, LPSTR, PDWORD, LPSTR, PDWORD, PVOID)'
# c.f. https://learn.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-token_information_class
TokenUser = 1
end
module WIN32
extend Fiddle::Importer
dlload 'kernel32.dll'
include Fiddle::Win32Types
extern 'BOOL CloseHandle(HANDLE)'
end
module SelfServicesHelper
def authorize_by_authtoken
if request.headers.key? "HTTP_X_IIS_WINDOWSAUTHTOKEN"
handle = request.headers["HTTP_X_IIS_WINDOWSAUTHTOKEN"].hex
buflen = 64
tokenInfo, len = "\0" * buflen, [0].pack("L!")
if WIN32Security::GetTokenInformation(handle, WIN32Security::TokenUser, tokenInfo, buflen, len) != 0
namelen, dnamelen, use = *[32,32].map{|e| [e].pack("L!")}, [0].pack("I")
namebuf, dnamebuf = [namelen, dnamelen].map{|e| "\0".encode("utf-16le") * e.unpack1("L!")}
# ... PSID is at the top of tokenInfo
if WIN32Security::LookupAccountSidW(nil, tokenInfo.unpack1("Q!"), namebuf, namelen, dnamebuf, dnamelen, use) != 0
namelen, dnamelen = [namelen, dnamelen].map{|e| e.unpack1("L!")}
WIN32::CloseHandle(handle)
logger.debug {"namebuf: %s, dnamebuf: %s" % [namebuf[0, namelen].encode("utf-8"), dnamebuf[0, dnamelen].encode("utf-8")}
else
logger.error "LookupAccountSidW returned false, last error: %d" % Fiddle.win32_last_error
end
else
logger.error "GetTokenInformation returned false, last error: %d" % Fiddle.win32_last_error
end
else
logger.debug "no HTTP_X_IIS_WINDOWSAUTHTOKEN"
end
end
end