@msdn=http://search.microsoft.com/search/results.aspx?qu=$$$ @pinvoke=http://pinvoke.net/$$$.htm Summary: The LsaLogonUser function authenticates a security principal's logon data using stored credentials information. !!!!C# Signature: [DllImport("secur32.dll", SetLastError=false)] public static extern WinStatusCodes LsaLogonUser( [In] IntPtr LsaHandle, [In] ref LSA_STRING OriginName, [In] SecurityLogonType LogonType, [In] UInt32 AuthenticationPackage, [In] IntPtr AuthenticationInformation, [In] UInt32 AuthenticationInformationLength, [In] /*PTOKEN_GROUPS*/ IntPtr LocalGroups, [In] ref TOKEN_SOURCE SourceContext, [Out] /*PVOID*/ out IntPtr ProfileBuffer, [Out] out UInt32 ProfileBufferLength, [Out] out Int64 LogonId, [Out] out IntPtr Token, [Out] out QUOTA_LIMITS Quotas, [Out] out WinStatusCodes SubStatus ); !!!!VB Signature: Declare Function LsaLogonUser Lib "secur32.dll" (TODO) As TODO !!!!User-Defined Types: None. !!!!Notes: None. !!!!Tips & Tricks: Please add some! !!!!Sample Code: using System; using System.Runtime.InteropServices; namespace CCSecurityUtilities { /// <remarks> /// This sample uses S4U security, which requires Windows Server 2003 and a W2003 domain controller /// </remarks> public sealed class CCWinLogonUtilities { private CCWinLogonUtilities() { } #region "Win32 stuff" private class Win32 { internal class OSCalls { public enum WinStatusCodes : uint { STATUS_SUCCESS = 0 } public enum WinErrors : uint { NO_ERROR = 0, } public enum WinLogonType { 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 } // SECURITY_LOGON_TYPE public enum SecurityLogonType { Interactive = 2, // Interactively logged on (locally or remotely) Network, // Accessing system via network Batch, // Started via a batch queue Service, // Service started by service controller Proxy, // Proxy logon Unlock, // Unlock workstation NetworkCleartext, // Network logon with cleartext credentials NewCredentials, // Clone caller, new default credentials RemoteInteractive, // Remote, yet interactive. Terminal server CachedInteractive, // Try cached credentials without hitting the net. CachedRemoteInteractive, // Same as RemoteInteractive, this is used internally for auditing purpose CachedUnlock // Cached Unlock workstation } [StructLayout(LayoutKind.Sequential)] public struct LSA_UNICODE_STRING { public UInt16 Length; public UInt16 MaximumLength; public IntPtr Buffer; } [StructLayout(LayoutKind.Sequential)] public struct TOKEN_SOURCE { public TOKEN_SOURCE(string name) { SourceName = new byte[8]; System.Text.Encoding.GetEncoding(1252).GetBytes(name,0,name.Length,SourceName,0); if (!AllocateLocallyUniqueId(out SourceIdentifier)) throw new System.ComponentModel.Win32Exception(); } [MarshalAs(UnmanagedType.ByValArray,SizeConst=8)] public byte[] SourceName; public UInt64 SourceIdentifier; } [StructLayout(LayoutKind.Sequential)] public struct QUOTA_LIMITS { UInt32 PagedPoolLimit; UInt32 NonPagedPoolLimit; UInt32 MinimumWorkingSetSize; UInt32 MaximumWorkingSetSize; UInt32 PagefileLimit; Int64 TimeLimit; } [StructLayout(LayoutKind.Sequential)] public struct LSA_STRING { public UInt16 Length; public UInt16 MaximumLength; public /*PCHAR*/ IntPtr Buffer; } public class LsaStringWrapper : IDisposable { public LSA_STRING _string; public LsaStringWrapper(string value) { _string = new LSA_STRING(); _string.Length = (ushort)value.Length; _string.MaximumLength = (ushort)value.Length; _string.Buffer = Marshal.StringToHGlobalAnsi(value); } ~LsaStringWrapper() { Dispose(false); } private void Dispose(bool disposing) { if (_string.Buffer != IntPtr.Zero) { Marshal.FreeHGlobal(_string.Buffer); _string.Buffer = IntPtr.Zero; } if (disposing) GC.SuppressFinalize(this); } #region IDisposable Members public void Dispose() { Dispose(true); } #endregion } public class KerbS4ULogon : IDisposable { [StructLayout(LayoutKind.Sequential)] public struct KERB_S4U_LOGON { public Int32 MessageType; // Should be 12 public Int32 Flags; // Reserved, should be 0 public LSA_UNICODE_STRING ClientUpn; // REQUIRED: UPN for client public LSA_UNICODE_STRING ClientRealm; // Optional: Client Realm, if known } public KerbS4ULogon(string clientUpn) : this(clientUpn,null) { } public KerbS4ULogon(string clientUpn,string clientRealm) { int clientUpnLen = (clientUpn == null) ? 0 : clientUpn.Length; int clientRealmLen = (clientRealm == null) ? 0 : clientRealm.Length; _bufferLength = Marshal.SizeOf(typeof(KERB_S4U_LOGON)) + 2 * (clientUpnLen + clientRealmLen); _bufferContent = Marshal.AllocHGlobal(_bufferLength); if (_bufferContent == IntPtr.Zero) throw new OutOfMemoryException("Could not allocate memory for KerbS4ULogon structure"); try { KERB_S4U_LOGON baseStructure = new KERB_S4U_LOGON(); baseStructure.MessageType = 12; // KerbS4ULogon baseStructure.Flags = 0; baseStructure.ClientUpn.Length = (UInt16)(2*clientUpnLen); baseStructure.ClientUpn.MaximumLength = (UInt16)(2*clientUpnLen); IntPtr curPtr = new IntPtr(_bufferContent.ToInt32()+Marshal.SizeOf(typeof(KERB_S4U_LOGON))); if (clientUpnLen > 0) { baseStructure.ClientUpn.Buffer = curPtr; Marshal.Copy(clientUpn.ToCharArray(),0,curPtr,clientUpnLen); curPtr = new IntPtr(curPtr.ToInt32()+clientUpnLen*2); } else baseStructure.ClientUpn.Buffer = IntPtr.Zero; baseStructure.ClientRealm.Length = (UInt16)(2*clientRealmLen); baseStructure.ClientRealm.MaximumLength = (UInt16)(2*clientRealmLen); if (clientRealmLen > 0) { baseStructure.ClientRealm.Buffer = curPtr; Marshal.Copy(clientRealm.ToCharArray(),0,curPtr,clientRealmLen); } else baseStructure.ClientRealm.Buffer = IntPtr.Zero; Marshal.StructureToPtr(baseStructure,_bufferContent,false); } catch { Dispose(true); throw; } } private IntPtr _bufferContent; private int _bufferLength; public IntPtr Ptr { get {return _bufferContent;} } public int Length { get {return _bufferLength;} } private void Dispose(bool disposing) { if (_bufferContent != IntPtr.Zero) { Marshal.FreeHGlobal(_bufferContent); _bufferContent = IntPtr.Zero; } if (disposing) GC.SuppressFinalize(this); } ~KerbS4ULogon() { Dispose(false); } #region IDisposable Members public void Dispose() { Dispose(true); } #endregion } [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=false)] public static extern WinErrors LsaNtStatusToWinError(WinStatusCodes status); [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)] public static extern bool AllocateLocallyUniqueId([Out] out UInt64 Luid); [DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)] public static extern int CloseHandle(IntPtr hObject); [DllImport("secur32.dll", SetLastError=false)] public static extern WinStatusCodes LsaLogonUser( [In] IntPtr LsaHandle, [In] ref LSA_STRING OriginName, [In] SecurityLogonType LogonType, [In] UInt32 AuthenticationPackage, [In] IntPtr AuthenticationInformation, [In] UInt32 AuthenticationInformationLength, [In] /*PTOKEN_GROUPS*/ IntPtr LocalGroups, [In] ref TOKEN_SOURCE SourceContext, [Out] /*PVOID*/ out IntPtr ProfileBuffer, [Out] out UInt32 ProfileBufferLength, [Out] out Int64 LogonId, [Out] out IntPtr Token, [Out] out QUOTA_LIMITS Quotas, [Out] out WinStatusCodes SubStatus ); [DllImport("secur32.dll", SetLastError=false)] public static extern WinStatusCodes LsaFreeReturnBuffer( [In] IntPtr buffer); [DllImport("secur32.dll", SetLastError=false)] public static extern WinStatusCodes LsaConnectUntrusted([Out] out IntPtr LsaHandle); [DllImport("secur32.dll", SetLastError=false)] public static extern WinStatusCodes LsaDeregisterLogonProcess([In] IntPtr LsaHandle); [DllImport("secur32.dll", SetLastError=false)] public static extern WinStatusCodes LsaLookupAuthenticationPackage([In] IntPtr LsaHandle,[In] ref LSA_STRING PackageName,[Out] out UInt32 AuthenticationPackage); } public sealed class HandleSecurityToken : IDisposable { private IntPtr m_hToken = IntPtr.Zero; // using S4U logon public HandleSecurityToken(string UserName, string Domain, OSCalls.WinLogonType LogonType ) { using (OSCalls.KerbS4ULogon authPackage = new OSCalls.KerbS4ULogon(UserName,Domain)) { IntPtr lsaHandle; OSCalls.WinStatusCodes status = OSCalls.LsaConnectUntrusted(out lsaHandle); if (status != OSCalls.WinStatusCodes.STATUS_SUCCESS) throw new System.ComponentModel.Win32Exception((int)OSCalls.LsaNtStatusToWinError(status)); try { UInt32 kerberosPackageId; using (OSCalls.LsaStringWrapper kerberosPackageName = new OSCalls.LsaStringWrapper("Kerberos")) { status = OSCalls.LsaLookupAuthenticationPackage(lsaHandle,ref kerberosPackageName._string,out kerberosPackageId); if (status != OSCalls.WinStatusCodes.STATUS_SUCCESS) throw new System.ComponentModel.Win32Exception((int)OSCalls.LsaNtStatusToWinError(status)); } OSCalls.LsaStringWrapper originName = null; try { originName = new OSCalls.LsaStringWrapper("CCSecurityUtilities"); OSCalls.TOKEN_SOURCE sourceContext = new OSCalls.TOKEN_SOURCE("CCSecUt"); System.IntPtr profileBuffer = IntPtr.Zero; UInt32 profileBufferLength = 0; Int64 logonId; OSCalls.WinStatusCodes subStatus; OSCalls.QUOTA_LIMITS quotas; status = OSCalls.LsaLogonUser( lsaHandle, ref originName._string, (OSCalls.SecurityLogonType)LogonType, kerberosPackageId, authPackage.Ptr, (uint)authPackage.Length, IntPtr.Zero, ref sourceContext, out profileBuffer, out profileBufferLength, out logonId, out m_hToken, out quotas, out subStatus); if (status != OSCalls.WinStatusCodes.STATUS_SUCCESS) throw new System.ComponentModel.Win32Exception((int)OSCalls.LsaNtStatusToWinError(status)); if (profileBuffer != IntPtr.Zero) OSCalls.LsaFreeReturnBuffer(profileBuffer); } finally { if (originName != null) originName.Dispose(); } } finally { OSCalls.LsaDeregisterLogonProcess(lsaHandle); } } } ~HandleSecurityToken() { Dispose(false); } public void Dispose() { Dispose(true); } private void Dispose(bool disposing ) { lock(this) { if (!m_hToken.Equals(IntPtr.Zero)) { OSCalls.CloseHandle(m_hToken); m_hToken = IntPtr.Zero; } if (disposing) GC.SuppressFinalize(this); } } public System.Security.Principal.WindowsIdentity BuildIdentity() { System.Security.Principal.WindowsIdentity retVal = new System.Security.Principal.WindowsIdentity(m_hToken); GC.KeepAlive(this); return retVal; } } } #endregion /// <summary> /// The Windows Logon Types. /// </summary> public enum WinLogonType { /// <summary> /// Interactive logon /// </summary> LOGON32_LOGON_INTERACTIVE = Win32.OSCalls.WinLogonType.LOGON32_LOGON_INTERACTIVE, /// <summary> /// Network logon /// </summary> LOGON32_LOGON_NETWORK = Win32.OSCalls.WinLogonType.LOGON32_LOGON_NETWORK, /// <summary> /// Batch logon /// </summary> LOGON32_LOGON_BATCH = Win32.OSCalls.WinLogonType.LOGON32_LOGON_BATCH, /// <summary> /// Logon as a service /// </summary> LOGON32_LOGON_SERVICE = Win32.OSCalls.WinLogonType.LOGON32_LOGON_SERVICE, /// <summary> /// Unlock logon /// </summary> LOGON32_LOGON_UNLOCK = Win32.OSCalls.WinLogonType.LOGON32_LOGON_UNLOCK, /// <summary> /// Preserve password logon /// </summary> LOGON32_LOGON_NETWORK_CLEARTEXT = Win32.OSCalls.WinLogonType.LOGON32_LOGON_NETWORK_CLEARTEXT, /// <summary> /// Current token for local access, credentials for network access /// </summary> LOGON32_LOGON_NEW_CREDENTIALS = Win32.OSCalls.WinLogonType.LOGON32_LOGON_NEW_CREDENTIALS } /// <summary> /// Logs in a credential for server apps. No need to provide password. /// </summary> /// <param name="credential">The credential to log in. Password is ignored.</param> /// <param name="logonType">The type of logon to use</param> /// <remarks> /// Requires Windows Server 2003 domain account running in Win2003 native domain mode /// </remarks> /// <returns>Returns a <c>System.Security.Principal.WindowsIdentity</c> object</returns> /// Raises an exception with error information if the user cannot log in public static System.Security.Principal.WindowsIdentity CreateIdentityS4U(System.Net.NetworkCredential credential, WinLogonType logonType) { using (Win32.HandleSecurityToken handleToken = new Win32.HandleSecurityToken(credential.UserName,credential.Domain,(Win32.OSCalls.WinLogonType)logonType)) return handleToken.BuildIdentity(); } } } !!!!Alternative Managed API: System.Security.Principal.WindowsIdentity has a constructor that you can use if you know the user's principal name (UPN). It does not work however for domain\username. Documentation: LsaLogonUser@msdn on MSDN
Edit secur32.LsaLogonUser
You do not have permission to change this page. If you feel this is in error, please send feedback with the contact link on the main page.