/// <summary> /// Apparently, this cannot be done, and always returns the error /// code 87. /// </summary> /// <param name="logonSid"></param> /// <param name="handle"></param> public static void SetTokenLogonSid(AccessTokenLogonSid logonSid, AccessTokenHandle handle) { TOKEN_GROUPS tokenGroups = new TOKEN_GROUPS(); var ptrs = logonSid.GetLogonSids(); var attributes = logonSid.GetLogonSidAttributes(); tokenGroups.GroupCount = (uint)ptrs.Count; tokenGroups.Groups = new SID_AND_ATTRIBUTES[tokenGroups.GroupCount]; for (int i = 0; i < tokenGroups.GroupCount; i++) { tokenGroups.Groups[i] = new SID_AND_ATTRIBUTES(); tokenGroups.Groups[i].Sid = ptrs[i]; tokenGroups.Groups[i].Attributes = attributes[i]; } var size = Marshal.SizeOf(tokenGroups); var tgPtr = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(tokenGroups, tgPtr, true); if (!Advapi32.SetTokenInformation(handle.GetHandle(), TOKEN_INFORMATION_CLASS.TokenLogonSid, tgPtr, size)) { Marshal.FreeHGlobal(tgPtr); Logger.GetInstance().Error($"Failed to set new logon sid for token. SetTokenInformation failed with error: {Kernel32.GetLastError()}"); throw new TokenInformationException(); } Marshal.FreeHGlobal(tgPtr); }
internal TokenGroups(UnmanagedHeapAlloc ptr) { MemoryMarshaler m = new MemoryMarshaler(ptr.Ptr); TOKEN_GROUPS grps = (TOKEN_GROUPS)m.ParseStruct(typeof(TOKEN_GROUPS)); for (int i = 0; i < grps.GroupCount; i++) { TokenGroup grp = new TokenGroup(m); base.InnerList.Add(grp); } }
public static AccessTokenLogonSid FromTokenHandle(AccessTokenHandle handle) { uint tokenInfLength = 0; bool success; IntPtr hToken = handle.GetHandle(); success = Advapi32.GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenLogonSid, IntPtr.Zero, tokenInfLength, out tokenInfLength); IntPtr tokenInfo = Marshal.AllocHGlobal(Convert.ToInt32(tokenInfLength)); success = Advapi32.GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenLogonSid, tokenInfo, tokenInfLength, out tokenInfLength); if (success) { TOKEN_GROUPS logonSid = (TOKEN_GROUPS)Marshal.PtrToStructure(tokenInfo, typeof(TOKEN_GROUPS)); string[] sids = new string[logonSid.GroupCount]; IntPtr[] sidPtrs = new IntPtr[logonSid.GroupCount]; int[] attributes = new int[logonSid.GroupCount]; var sidAndAttrSize = Marshal.SizeOf(new SID_AND_ATTRIBUTES()); for (int i = 0; i < logonSid.GroupCount; i++) { var saa = (SID_AND_ATTRIBUTES)Marshal.PtrToStructure(new IntPtr(tokenInfo.ToInt64() + i * sidAndAttrSize + IntPtr.Size), typeof(SID_AND_ATTRIBUTES)); IntPtr strPtr; if (Advapi32.ConvertSidToStringSid(saa.Sid, out strPtr)) { sids[i] = Marshal.PtrToStringAuto(strPtr); } else { Logger.GetInstance().Error("Failed to retrieve SID-string for token LogonSession."); } sidPtrs[i] = saa.Sid; attributes[i] = saa.Attributes; } Marshal.FreeHGlobal(tokenInfo); return(new AccessTokenLogonSid(sids, attributes, sidPtrs)); } else { Marshal.FreeHGlobal(tokenInfo); Logger.GetInstance().Error($"Failed to retreive session id information for access token. GetTokenInformation failed with error: {Kernel32.GetLastError()}"); throw new TokenInformationException(); } }
public void AuthzModifySidsTest() { using (var hRM = GetAuthzInitializeResourceManager()) using (var hCtx = GetCurrentUserAuthContext(hRM)) { var tg = new TOKEN_GROUPS(1); var psid = new SafePSID("S-1-5-32-551"); tg.Groups[0] = new SID_AND_ATTRIBUTES { Attributes = (uint)GroupAttributes.SE_GROUP_ENABLED, Sid = (IntPtr)psid }; var b = AuthzModifySids(hCtx, AUTHZ_CONTEXT_INFORMATION_CLASS.AuthzContextInfoGroupsSids, new[] { AUTHZ_SID_OPERATION.AUTHZ_SID_OPERATION_ADD }, in tg); if (!b) { TestContext.WriteLine($"AuthzModifySids:{Win32Error.GetLastError()}"); } Assert.That(b); } }
public static string[] GetTokenGroupSIDs() { // Returns all SIDs that the current user is a part of, whether they are disabled or not. // adapted almost directly from https://stackoverflow.com/questions/2146153/how-to-get-the-logon-sid-in-c-sharp/2146418#2146418 int TokenInfLength = 0; // first call gets length of TokenInformation bool Result = GetTokenInformation(WindowsIdentity.GetCurrent().Token, TOKEN_INFORMATION_CLASS.TokenGroups, IntPtr.Zero, TokenInfLength, out TokenInfLength); IntPtr TokenInformation = Marshal.AllocHGlobal(TokenInfLength); Result = GetTokenInformation(WindowsIdentity.GetCurrent().Token, TOKEN_INFORMATION_CLASS.TokenGroups, TokenInformation, TokenInfLength, out TokenInfLength); if (!Result) { Marshal.FreeHGlobal(TokenInformation); return(null); } TOKEN_GROUPS groups = (TOKEN_GROUPS)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_GROUPS)); string[] userSIDS = new string[groups.GroupCount]; int sidAndAttrSize = Marshal.SizeOf(new SID_AND_ATTRIBUTES()); for (int i = 0; i < groups.GroupCount; i++) { SID_AND_ATTRIBUTES sidAndAttributes = (SID_AND_ATTRIBUTES)Marshal.PtrToStructure( new IntPtr(TokenInformation.ToInt64() + i * sidAndAttrSize + IntPtr.Size), typeof(SID_AND_ATTRIBUTES)); IntPtr pstr = IntPtr.Zero; ConvertSidToStringSid(sidAndAttributes.Sid, out pstr); userSIDS[i] = Marshal.PtrToStringAuto(pstr); LocalFree(pstr); } Marshal.FreeHGlobal(TokenInformation); return(userSIDS); }
//Retrieves the SID of a given token public static string GetLogonId(IntPtr token) { int TokenInfLength = 0; // first call gets lenght of TokenInformation bool Result = GetTokenInformation(token, 2, IntPtr.Zero, TokenInfLength, out TokenInfLength); IntPtr TokenInformation = Marshal.AllocHGlobal(TokenInfLength); Result = GetTokenInformation(token, 2, TokenInformation, TokenInfLength, out TokenInfLength); if (!Result) { Marshal.FreeHGlobal(TokenInformation); return(string.Empty); } string retVal = string.Empty; TOKEN_GROUPS groups = (TOKEN_GROUPS)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_GROUPS)); int sidAndAttrSize = Marshal.SizeOf(new SID_AND_ATTRIBUTES()); for (int i = 0; i < groups.GroupCount; i++) { SID_AND_ATTRIBUTES sidAndAttributes = (SID_AND_ATTRIBUTES)Marshal.PtrToStructure( new IntPtr(TokenInformation.ToInt64() + i * sidAndAttrSize + IntPtr.Size), typeof(SID_AND_ATTRIBUTES)); if ((sidAndAttributes.Attributes & 0xC0000000) == 0xC0000000) { IntPtr pstr = IntPtr.Zero; ConvertSidToStringSid(sidAndAttributes.Sid, out pstr); retVal = Marshal.PtrToStringAuto(pstr); LocalFree(pstr); break; } } Marshal.FreeHGlobal(TokenInformation); return(retVal); }
public void ComputeEffectivePermissionWithSecondarySecurity(PSID pSid, PSID pDeviceSid, string pszServerName, SECURITY_OBJECT[] pSecurityObjects, uint dwSecurityObjectCount, ref TOKEN_GROUPS pUserGroups, AUTHZ_SID_OPERATION[] pAuthzUserGroupsOperations, ref TOKEN_GROUPS pDeviceGroups, AUTHZ_SID_OPERATION[] pAuthzDeviceGroupsOperations, ref AUTHZ_SECURITY_ATTRIBUTES_INFORMATION pAuthzUserClaims, AUTHZ_SECURITY_ATTRIBUTE_OPERATION[] pAuthzUserClaimsOperations, ref AUTHZ_SECURITY_ATTRIBUTES_INFORMATION pAuthzDeviceClaims, AUTHZ_SECURITY_ATTRIBUTE_OPERATION[] pAuthzDeviceClaimsOperations, EFFPERM_RESULT_LIST[] pEffpermResultLists) { System.Diagnostics.Debug.WriteLine($"ComputeEffectivePermissionWithSecondarySecurity({dwSecurityObjectCount}):{new SecurityIdentifier((IntPtr)pSid).Value};{new SecurityIdentifier((IntPtr)pDeviceSid).Value}"); if (dwSecurityObjectCount != 1) { ThrowException(HRESULT.E_FAIL, new ArgumentOutOfRangeException(nameof(dwSecurityObjectCount), @"Only a single object can be computed.")); } if (pSecurityObjects[0].Id != (uint)SECURITY_OBJECT_ID.SECURITY_OBJECT_ID_OBJECT_SD) { ThrowException(HRESULT.E_FAIL, new ArgumentException(@"Unexpected value.", nameof(pSecurityObjects))); } if (pSid == null || pSid.IsInvalid) { ThrowException(HRESULT.E_INVALIDARG, new ArgumentNullException(nameof(pSid))); } SafeAUTHZ_RESOURCE_MANAGER_HANDLE hAuthzResourceManager; if (!AuthzInitializeResourceManager(AuthzResourceManagerFlags.AUTHZ_RM_FLAG_NO_AUDIT, null, null, null, prov.ToString(), out hAuthzResourceManager)) { return; } var identifier = new LUID(); SafeAUTHZ_CLIENT_CONTEXT_HANDLE hAuthzUserContext; SafeAUTHZ_CLIENT_CONTEXT_HANDLE hAuthzCompoundContext = null; if (!AuthzInitializeContextFromSid(AuthzContextFlags.NONE, pSid, hAuthzResourceManager, IntPtr.Zero, identifier, IntPtr.Zero, out hAuthzUserContext)) { return; } if (pDeviceSid != null && !pDeviceSid.IsInvalid) { SafeAUTHZ_CLIENT_CONTEXT_HANDLE hAuthzDeviceContext; if (AuthzInitializeContextFromSid(AuthzContextFlags.NONE, pDeviceSid, hAuthzResourceManager, IntPtr.Zero, identifier, IntPtr.Zero, out hAuthzDeviceContext)) { if (AuthzInitializeCompoundContext(hAuthzUserContext, hAuthzDeviceContext, out hAuthzCompoundContext)) { if (pAuthzDeviceClaims.Version != 0) { AuthzModifyClaims(hAuthzCompoundContext, AUTHZ_CONTEXT_INFORMATION_CLASS.AuthzContextInfoDeviceClaims, pAuthzDeviceClaimsOperations, ref pAuthzDeviceClaims); } } } } else { hAuthzCompoundContext = hAuthzUserContext; } if (hAuthzCompoundContext == null) { return; } if (pAuthzUserClaims.Version != 0) { if (!AuthzModifyClaims(hAuthzCompoundContext, AUTHZ_CONTEXT_INFORMATION_CLASS.AuthzContextInfoUserClaims, pAuthzUserClaimsOperations, ref pAuthzUserClaims)) { return; } } if (pDeviceGroups.GroupCount != 0) { if (!AuthzModifySids(hAuthzCompoundContext, AUTHZ_CONTEXT_INFORMATION_CLASS.AuthzContextInfoDeviceSids, pAuthzDeviceGroupsOperations, ref pDeviceGroups)) { return; } } if (pUserGroups.GroupCount != 0 && pAuthzUserGroupsOperations != null) { if (!AuthzModifySids(hAuthzCompoundContext, AUTHZ_CONTEXT_INFORMATION_CLASS.AuthzContextInfoGroupsSids, pAuthzUserGroupsOperations, ref pUserGroups)) { return; } } var request = new AUTHZ_ACCESS_REQUEST(AccessTypes.MAXIMUM_ALLOWED); var sd = pSecurityObjects[0].pData.ToStructure <SECURITY_DESCRIPTOR>(); var reply = new AUTHZ_ACCESS_REPLY(1); SafeAUTHZ_ACCESS_CHECK_RESULTS_HANDLE phAccessCheckResults; if (!AuthzAccessCheck(AuthzAccessCheckFlags.NONE, hAuthzCompoundContext, ref request, null, ref sd, null, 0, reply, out phAccessCheckResults)) { return; } pEffpermResultLists[0].fEvaluated = true; pEffpermResultLists[0].pGrantedAccessList = reply.GrantedAccessMaskValues; pEffpermResultLists[0].pObjectTypeList = new[] { OBJECT_TYPE_LIST.Self }; pEffpermResultLists[0].cObjectTypeListLength = 1; }
public static AccessTokenGroups FromTokenHandle(AccessTokenHandle handle) { uint tokenInfLength = 0; bool success; IntPtr hToken = handle.GetHandle(); success = Advapi32.GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenGroups, IntPtr.Zero, tokenInfLength, out tokenInfLength); IntPtr tokenInfo = Marshal.AllocHGlobal(Convert.ToInt32(tokenInfLength)); success = Advapi32.GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenGroups, tokenInfo, tokenInfLength, out tokenInfLength); if (success) { var parsedGroups = new List <ATGroup>(); TOKEN_GROUPS groups = (TOKEN_GROUPS)Marshal.PtrToStructure(tokenInfo, typeof(TOKEN_GROUPS)); var sidAndAttrSize = Marshal.SizeOf(new SID_AND_ATTRIBUTES()); for (int i = 0; i < groups.GroupCount; i++) { var saa = (SID_AND_ATTRIBUTES)Marshal.PtrToStructure(new IntPtr(tokenInfo.ToInt64() + i * sidAndAttrSize + IntPtr.Size), typeof(SID_AND_ATTRIBUTES)); var sid = saa.Sid; var attributes = saa.Attributes; IntPtr strPtr; var sidString = ""; if (Advapi32.ConvertSidToStringSid(sid, out strPtr)) { sidString = Marshal.PtrToStringAuto(strPtr); } else { Logger.GetInstance().Error($"Failed to convert SID to string. ConvertSidToStringSid failed with error: {Kernel32.GetLastError()}"); sidString = "UNKNOWN"; } int length = Convert.ToInt32(Advapi32.GetLengthSid(sid)); byte[] sidBytes = new byte[length]; Marshal.Copy(sid, sidBytes, 0, length); StringBuilder lpName = new StringBuilder(); uint cchname = (uint)lpName.Capacity; StringBuilder lpdomain = new StringBuilder(); uint cchdomain = (uint)lpdomain.Capacity; SID_NAME_USE peUse; var name = ""; var domain = ""; if (!Advapi32.LookupAccountSid(null, sidBytes, lpName, ref cchname, lpdomain, ref cchdomain, out peUse)) { var err = Kernel32.GetLastError(); if (err == Constants.ERROR_INSUFFICIENT_BUFFER) { lpName.EnsureCapacity((int)cchname); lpdomain.EnsureCapacity((int)cchdomain); if (!Advapi32.LookupAccountSid(null, sidBytes, lpName, ref cchname, lpdomain, ref cchdomain, out peUse)) { Logger.GetInstance().Error($"Failed to lookup name and domain from SID. LookupAccountSid failed with error: {err}"); name = "UNKNOWN"; domain = "UNKNOWN"; } else { name = lpName.ToString(); domain = lpdomain.ToString(); } } } else { name = lpName.ToString(); domain = lpdomain.ToString(); } parsedGroups.Add(new ATGroup(sidString, sid, attributes, name, domain, peUse)); } Marshal.FreeHGlobal(tokenInfo); return(new AccessTokenGroups(parsedGroups)); } else { Marshal.FreeHGlobal(tokenInfo); Logger.GetInstance().Error($"Failed to retreive session id information for access token. GetTokenInformation failed with error: {Kernel32.GetLastError()}"); throw new TokenInformationException(); } }