From 4cb470084cac42df8debb70040cd270813bc174d Mon Sep 17 00:00:00 2001 From: Jim Norman Date: Thu, 23 Aug 2007 16:58:51 +0000 Subject: [PATCH] Bug 303657. Fix for session management of Vista. Admin users have 2 LUIDs. Make these the same userId --- .../AppModule.NamedPipes/APipeConnection.cs | 4 +- .../ImpersonateWrapper.cs | 42 +++++++++++++++---- CASA/logincapture/windows/lcredmgr.cpp | 5 +++ CASA/micasad/common/WinUserIdentifier.cs | 22 +++++++++- CASA/micasad/communication/WinIPCChannel.cs | 26 +++++++++--- 5 files changed, 81 insertions(+), 18 deletions(-) diff --git a/CASA/extern/w32/namedpipes/AppModule.NamedPipes/APipeConnection.cs b/CASA/extern/w32/namedpipes/AppModule.NamedPipes/APipeConnection.cs index b2b0ba0c..8484bc5e 100644 --- a/CASA/extern/w32/namedpipes/AppModule.NamedPipes/APipeConnection.cs +++ b/CASA/extern/w32/namedpipes/AppModule.NamedPipes/APipeConnection.cs @@ -189,9 +189,9 @@ namespace AppModule.NamedPipes { return (int)this.Handle.Handle; } } - public int GetLocalUserID(ref int lowPart, ref int highPart, ref string sSIDString) + public int GetLocalUserID(ref int lowPart, ref int highPart, ref string sSIDString, ref int lowPartElevated, ref int highPartElevated) { - return ImpersonateWrapper.GetLocalUserID(this.Handle, ref lowPart, ref highPart, ref sSIDString); + return ImpersonateWrapper.GetLocalUserID(this.Handle, ref lowPart, ref highPart, ref sSIDString, ref lowPartElevated, ref highPartElevated); } } } \ No newline at end of file diff --git a/CASA/extern/w32/namedpipes/AppModule.NamedPipes/ImpersonateWrapper.cs b/CASA/extern/w32/namedpipes/AppModule.NamedPipes/ImpersonateWrapper.cs index 56d308c9..e6ea2319 100644 --- a/CASA/extern/w32/namedpipes/AppModule.NamedPipes/ImpersonateWrapper.cs +++ b/CASA/extern/w32/namedpipes/AppModule.NamedPipes/ImpersonateWrapper.cs @@ -168,7 +168,7 @@ namespace AppModule.NamedPipes // first call gets length of TokenInformation ImpersonateNative.GetTokenInformation(token, ImpersonateNative.TOKEN_INFORMATION_CLASS.TokenLinkedToken, IntPtr.Zero, TokenInfLength, ref TokenInfLength); - + try { @@ -181,10 +181,11 @@ namespace AppModule.NamedPipes linkedToken = (ImpersonateNative.TOKEN_LINKED_TOKEN)Marshal.PtrToStructure(ptrLinkedToken, typeof(ImpersonateNative.TOKEN_LINKED_TOKEN)); } } - catch (OutOfMemoryException e) + catch (Exception e) { - System.Diagnostics.Trace.WriteLine(e.ToString()); + System.Diagnostics.Trace.WriteLine(e.ToString()); } + finally { if (ptrLinkedToken != IntPtr.Zero) @@ -197,7 +198,7 @@ namespace AppModule.NamedPipes return TokenInfoSuccess; } - public static int GetLocalUserID(PipeHandle handle, ref int lowPart, ref int highPart, ref string SidString) + public static int GetLocalUserID(PipeHandle handle, ref int lowPart, ref int highPart, ref string SidString, ref int lowPartElevated, ref int highPartElevated) { int rcode = -1; // get client userID @@ -214,6 +215,7 @@ namespace AppModule.NamedPipes IntPtr hThread = ImpersonateNative.GetCurrentThread(); uint iDesiredInfo = 24; //TOKEN_QUERY | TOKEN_QUERY_SOURCE; IntPtr userToken = Marshal.AllocHGlobal(4); + IntPtr userTokenElevated = IntPtr.Zero; if (ImpersonateNative.OpenThreadToken(hThread, iDesiredInfo, true, out userToken)) { @@ -225,7 +227,7 @@ namespace AppModule.NamedPipes // on Vista use the elevated token if there is one. System.OperatingSystem os = System.Environment.OSVersion; - System.Diagnostics.Trace.WriteLine("OS Version: {0}", os.Version.ToString()); + System.Diagnostics.Trace.WriteLine("OS Version: " + os.Version.ToString()); if (os.Version.Major > 5) { if (ImpersonateNative.GetTokenInformation(userToken, ImpersonateNative.TOKEN_INFORMATION_CLASS.TokenElevationType, tu, cb, ref cb)) @@ -233,20 +235,24 @@ namespace AppModule.NamedPipes int iTokenType; iTokenType = (int)Marshal.PtrToStructure(tu, typeof(int)); - System.Diagnostics.Trace.WriteLine("Token Type : {0}", iTokenType.ToString()); - if (iTokenType == 3) //.ToString().Equals(ImpersonateNative.TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited)) + System.Diagnostics.Trace.WriteLine("Token Type: " + iTokenType.ToString()); + if (iTokenType == (int)ImpersonateNative.TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited) { + System.Diagnostics.Trace.WriteLine("Getting linked token"); + ImpersonateNative.TOKEN_LINKED_TOKEN newLinkedToken; if (GetLinkedToken(userToken, out newLinkedToken)) { - userToken = newLinkedToken.LinkedToken; + //userToken = newLinkedToken.LinkedToken; + userTokenElevated = Marshal.AllocHGlobal(4); + userTokenElevated = newLinkedToken.LinkedToken; } } } else { uint error = ImpersonateNative.GetLastError(); - System.Diagnostics.Trace.WriteLine("linked token error: {0}", error.ToString()); + System.Diagnostics.Trace.WriteLine("linked token error: " + error.ToString()); } } @@ -273,6 +279,20 @@ namespace AppModule.NamedPipes highPart = stats.AuthenticationId.HighPart; rcode = -1; } + + // get elevated token stats + if (userTokenElevated != IntPtr.Zero) + { + cb = bufLength; + if (ImpersonateNative.GetTokenInformation(userTokenElevated, 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 + lowPartElevated = stats.AuthenticationId.LowPart; + highPartElevated = stats.AuthenticationId.HighPart; + rcode = -1; + } + } } else { @@ -295,6 +315,10 @@ namespace AppModule.NamedPipes } Marshal.FreeHGlobal(userToken); + if (userTokenElevated != IntPtr.Zero) + { + Marshal.FreeHGlobal(userTokenElevated); + } } catch (Exception ex) { diff --git a/CASA/logincapture/windows/lcredmgr.cpp b/CASA/logincapture/windows/lcredmgr.cpp index 22a7d2f2..add4aed4 100644 --- a/CASA/logincapture/windows/lcredmgr.cpp +++ b/CASA/logincapture/windows/lcredmgr.cpp @@ -410,6 +410,11 @@ NPLogonNotify ( extension.version = 0x00010000; // 1.0.0 extension.ext = (void *)lpLogonId; +#ifdef _DEBUG + DebugPrint("Setting credential for: %d (high) %d (low)\r\n", lpLogonId->HighPart, lpLogonId->LowPart); +#endif + + ccode = (*pCASASetCredential)( 0, &desktopCredential, diff --git a/CASA/micasad/common/WinUserIdentifier.cs b/CASA/micasad/common/WinUserIdentifier.cs index 581d2819..bb8576eb 100644 --- a/CASA/micasad/common/WinUserIdentifier.cs +++ b/CASA/micasad/common/WinUserIdentifier.cs @@ -28,8 +28,24 @@ namespace sscs.common { private int uidLow; private int uidHigh; + private int elevatedUidLow = 0; + private int elevatedUidHigh = 0; private string m_sSID = ""; + internal WinUserIdentifier(int uidLowPart, int uidHighPart, string sSID, int elevatedUidLow, int elevatedUidHigh) + { + this.uidLow = uidLowPart; + this.uidHigh = uidHighPart; + this.m_sSID = sSID; + + if (elevatedUidLow != null) + this.elevatedUidLow = elevatedUidLow; + + if (elevatedUidHigh != null) + this.elevatedUidHigh = elevatedUidHigh; + + } + internal WinUserIdentifier(int uidLowPart, int uidHighPart, string sSID) { this.uidLow = uidLowPart; @@ -51,8 +67,10 @@ namespace sscs.common public override bool Equals(Object obj) { - WinUserIdentifier u = (WinUserIdentifier)obj; - if ((u.uidLow == uidLow) && (u.uidHigh == uidHigh)) + WinUserIdentifier u = (WinUserIdentifier)obj; + if (((u.uidLow == uidLow) && (u.uidHigh == uidHigh)) || + ((u.uidLow == elevatedUidLow) && (u.uidHigh == elevatedUidHigh)) || + ((u.elevatedUidLow == uidLow) && (u.elevatedUidHigh == uidHigh))) { // we have a match, set the SID if we can if ((this.m_sSID.Length < 1) && (u.GetSID().Length>0)) diff --git a/CASA/micasad/communication/WinIPCChannel.cs b/CASA/micasad/communication/WinIPCChannel.cs index c6fe3818..202922d1 100644 --- a/CASA/micasad/communication/WinIPCChannel.cs +++ b/CASA/micasad/communication/WinIPCChannel.cs @@ -68,6 +68,8 @@ namespace sscs.communication { int localUserIDLow = 0; int localUserIDHigh = 0; + int localUserIDLowElevated = 0; + int localUserIDHighElevated = 0; string sSIDString = ""; byte[] incoming = null; @@ -77,12 +79,26 @@ namespace sscs.communication incoming = m_serverPipeConnection.ReadBytes(); // get local Userid and SID - m_serverPipeConnection.GetLocalUserID(ref localUserIDLow, ref localUserIDHigh, ref sSIDString); + m_serverPipeConnection.GetLocalUserID(ref localUserIDLow, + ref localUserIDHigh, + ref sSIDString, + ref localUserIDLowElevated, + ref localUserIDHighElevated); - if (localUserIDLow != 0 || localUserIDHigh !=0) - { - userId = new WinUserIdentifier(localUserIDLow, localUserIDHigh, sSIDString); - } + if (localUserIDLowElevated != 0 || localUserIDHighElevated != 0) + { + if (localUserIDLow != 0 || localUserIDHigh != 0) + { + userId = new WinUserIdentifier(localUserIDLow, localUserIDHigh, sSIDString, localUserIDLowElevated, localUserIDHighElevated); + } + } + else + { + if (localUserIDLow != 0 || localUserIDHigh != 0) + { + userId = new WinUserIdentifier(localUserIDLow, localUserIDHigh, sSIDString); + } + } return incoming; }