Important: The code must be compiled with /unsafe flag
using System.Security;
using System.Security.Principal;
using System.Security.Permissions;
using System.Runtime.InteropServices;
...
WindowsIdentity LogonUserAndGetWindowsIdentify(string userId, string password, string domainId)
{
IntPtr tokenHandle = new IntPtr(0);
IntPtr dupeTokenHandle = new IntPtr(0);
tokenHandle = IntPtr.Zero;
dupeTokenHandle = IntPtr.Zero;
bool rcBool = LogonUser(userId, domainId, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref tokenHandle);
if (!rcBool)
throw new Exception("Error while trying to log user on");
rcBool = DuplicateToken(tokenHandle, SecurityImpersonation, ref dupeTokenHandle);
if (!rcBool)
throw new Exception("Error while trying to duplicate token");
WindowsIdentity newId = new WindowsIdentity(dupeTokenHandle);
CloseHandle(tokenHandle);
CloseHandle(dupeTokenHandle);
return newId;
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
[DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private unsafe static extern int FormatMessage(int dwFlags, ref IntPtr lpSource, int dwMessageId, int dwLanguageId, ref String lpBuffer, int nSize, IntPtr* Arguments);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
public unsafe static string GetErrorMessage(int errorCode)
{
int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
int messageSize = 255;
String lpMsgBuf = "";
int dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
IntPtr ptrlpSource = IntPtr.Zero;
IntPtr prtArguments = IntPtr.Zero;
int retVal = FormatMessage(dwFlags, ref ptrlpSource, errorCode, 0, ref lpMsgBuf, messageSize, &prtArguments);
if (0 == retVal)
{
throw new Exception("Failed to format message for error code " + errorCode + ". ");
}
return lpMsgBuf;
}
You are missing:
ReplyDeleteconst int LOGON32_PROVIDER_DEFAULT = 0;
//This parameter causes LogonUser to create a primary token.
const int LOGON32_LOGON_INTERACTIVE = 2;
const int SecurityImpersonation = 2;
good stuff. but is your code working in 64bit machine??
ReplyDelete