using System; using AppModule.NamedPipes; using System.Runtime.InteropServices; using System.Text; using HANDLE = System.IntPtr; namespace AppModule.NamedPipes { #region Comments /// /// A utility class that exposes named pipes operations. /// /// /// This class uses the exposed exposed kernel32.dll methods by the /// NamedPipeNative class /// to provided controlled named pipe functionality. /// #endregion public sealed class ImpersonateWrapper { public const int TOKEN_QUERY = 0X00000008; const int ERROR_NO_MORE_ITEMS = 259; // Client USERID stuff // 1. call ImpersonateNamedPipeClient(hPipe) // 2. call OpenThreadToken(GetCurrentThread(), // TOKEN_QUERY | TOKEN_QUERY_SOURCE, // FALSE, // phUserToken); public static int ImpersonateNamedPipeClient(IntPtr hPipeHandle) { int rcode = ImpersonateNative.ImpersonateNamedPipeClient(hPipeHandle); return rcode; } static int PerformDump(HANDLE token) { StringBuilder sb = new StringBuilder(); ImpersonateNative.TOKEN_USER tokUser; const int bufLength = 256; IntPtr tu = Marshal.AllocHGlobal( bufLength ); int cb = bufLength; if (ImpersonateNative.GetTokenInformation( token, ImpersonateNative.TOKEN_INFORMATION_CLASS.TokenUser, tu, cb, ref cb )) Console.WriteLine("GetTokenInformation successful"); else { Console.WriteLine("GetTokenInformation NOT successful"); uint error = NamedPipeNative.GetLastError(); Console.WriteLine("error" + error.ToString()); } tokUser = (ImpersonateNative.TOKEN_USER) Marshal.PtrToStructure(tu, typeof(ImpersonateNative.TOKEN_USER) ); //sb.Append(DumpAccountSid(tokUser.User.Sid)); IntPtr pUserID = tokUser.User.Sid; //Console.WriteLine("UserID: " + pUserID); DumpAccountSid(pUserID); Marshal.FreeHGlobal( tu ); tu = Marshal.AllocHGlobal(bufLength); cb = bufLength; // get token states ImpersonateNative.TOKEN_STATISTICS stats; if (ImpersonateNative.GetTokenInformation(token, ImpersonateNative.TOKEN_INFORMATION_CLASS.TokenStatistics, tu, cb, ref cb)) { stats = (ImpersonateNative.TOKEN_STATISTICS) Marshal.PtrToStructure(tu, typeof(ImpersonateNative.TOKEN_STATISTICS)); Console.WriteLine("UserLow: "+stats.AuthenticationId.LowPart.ToString()); Console.WriteLine("UserHigh: "+stats.AuthenticationId.HighPart.ToString()); } else { Console.WriteLine("failed"); } return (int)pUserID; } static string DumpAccountSid(IntPtr SID) { int cchAccount = 0; int cchDomain = 0; int snu = 0 ; StringBuilder sb = new StringBuilder(); // Caller allocated buffer StringBuilder Account= null; StringBuilder Domain = null; bool ret = ImpersonateNative.LookupAccountSid(null, SID, Account, ref cchAccount, Domain, ref cchDomain, ref snu); if ( ret == true ) if ( Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS ) return "Error"; try { Account = new StringBuilder( cchAccount ); Domain = new StringBuilder( cchDomain ); ret = ImpersonateNative.LookupAccountSid(null, SID, Account, ref cchAccount, Domain, ref cchDomain, ref snu); if (ret) { sb.Append(Domain); sb.Append(@"\\"); sb.Append(Account); } else Console.WriteLine("logon account (no name) "); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { } string SidString = null; ImpersonateNative.ConvertSidToStringSid(SID, ref SidString); sb.Append("\nSID: "); sb.Append(SidString); Console.WriteLine("Acct info: "+ sb.ToString()); return sb.ToString(); } public static int GetLocalUserID(PipeHandle handle, ref int lowPart, ref int highPart, ref string SidString) { int rcode = -1; // get client userID int code = ImpersonateNative.ImpersonateNamedPipeClient(handle.Handle); if (code == 0) { uint lastError = NamedPipeNative.GetLastError(); Console.WriteLine("ImpersonateNamedPipeClient Error: "+rcode.ToString()); return -1; } try { IntPtr hThread = ImpersonateNative.GetCurrentThread(); uint iDesiredInfo = 24; //TOKEN_QUERY | TOKEN_QUERY_SOURCE; IntPtr userToken = Marshal.AllocHGlobal(4); if (ImpersonateNative.OpenThreadToken(hThread, iDesiredInfo, true, out userToken)) { StringBuilder sb = new StringBuilder(); ImpersonateNative.TOKEN_USER tokUser; const int bufLength = 256; IntPtr tu = Marshal.AllocHGlobal( bufLength ); int cb = bufLength; if (ImpersonateNative.GetTokenInformation( userToken, ImpersonateNative.TOKEN_INFORMATION_CLASS.TokenUser, tu, cb, ref cb )) { tokUser = (ImpersonateNative.TOKEN_USER) Marshal.PtrToStructure(tu, typeof(ImpersonateNative.TOKEN_USER) ); IntPtr pUserID = tokUser.User.Sid; Marshal.FreeHGlobal( tu ); // get SID //string SidString = null; ImpersonateNative.ConvertSidToStringSid(pUserID, ref SidString); // get token states tu = Marshal.AllocHGlobal(bufLength); cb = bufLength; ImpersonateNative.TOKEN_STATISTICS stats; if (ImpersonateNative.GetTokenInformation(userToken, ImpersonateNative.TOKEN_INFORMATION_CLASS.TokenStatistics, tu, cb, ref cb)) { stats = (ImpersonateNative.TOKEN_STATISTICS) Marshal.PtrToStructure(tu, typeof(ImpersonateNative.TOKEN_STATISTICS)); // copy low and high part lowPart = stats.AuthenticationId.LowPart; highPart = stats.AuthenticationId.HighPart; rcode = -1; } } else { Console.WriteLine("GetTokenInformation NOT successful"); uint error = NamedPipeNative.GetLastError(); Console.WriteLine("error" + error.ToString()); } // close handle ImpersonateNative.CloseHandle(hThread); ImpersonateNative.RevertToSelf(); } else { int lastError = Marshal.GetLastWin32Error(); uint errorcode = NamedPipeNative.GetLastError(); Console.WriteLine("OpenThreadToken Error: "+ errorcode.ToString() + " code2: "+rcode.ToString()); } } catch (Exception ex) { int error = Marshal.GetLastWin32Error(); Console.WriteLine(ex.ToString()); return rcode; } // end return rcode; } } }