mirror of https://github.com/dahall/Vanara.git
Whew! Lots of work and significant changes coming from completing unit testing and corresponding fixes and additions for SecurityBaseApi.h and WinNT.h.
parent
c478f33c48
commit
871ad3b8ce
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -18,6 +18,7 @@ namespace Vanara.PInvoke.Tests
|
|||
[TestFixture()]
|
||||
public class AdvApi32Tests
|
||||
{
|
||||
internal const SECURITY_INFORMATION AllSI = SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION | SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION | SECURITY_INFORMATION.DACL_SECURITY_INFORMATION | SECURITY_INFORMATION.SACL_SECURITY_INFORMATION;
|
||||
internal const string fn = @"C:\Temp\help.ico";
|
||||
|
||||
internal static object[] GetAuthCasesFromFile(bool validUser, bool validCred) => AuthCasesFromFile.Where(objs => ((object[])objs)[0].Equals(validUser) && ((object[])objs)[1].Equals(validCred)).ToArray();
|
||||
|
@ -43,38 +44,6 @@ namespace Vanara.PInvoke.Tests
|
|||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AccessCheckTest()
|
||||
{
|
||||
using (var pSD = GetSD(fn, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION | SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION | SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION))
|
||||
using (var hTok = SafeHTOKEN.FromProcess(GetCurrentProcess(), TokenAccess.TOKEN_IMPERSONATE | TokenAccess.TOKEN_DUPLICATE | TokenAccess.TOKEN_READ).Duplicate(SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation))
|
||||
{
|
||||
var ps = PRIVILEGE_SET.InitializeWithCapacity(10);
|
||||
var psSz = ps.SizeInBytes;
|
||||
var gm = GENERIC_MAPPING.GenericFileMapping;
|
||||
ACCESS_MASK accessMask = ACCESS_MASK.GENERIC_READ;
|
||||
MapGenericMask(ref accessMask, gm);
|
||||
var b = AccessCheck(pSD, hTok, accessMask, gm, ref ps, ref psSz, out var access, out var status);
|
||||
if (!b) TestContext.WriteLine($"AccessCheck failed: {Win32Error.GetLastError()}");
|
||||
Assert.That(b, Is.True);
|
||||
TestContext.WriteLine($"Access={(Kernel32.FileAccess)access}; Status={status}");
|
||||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void AdjustTokenPrivilegesTest()
|
||||
{
|
||||
using (var t = SafeHTOKEN.FromThread(SafeHTHREAD.Current, TokenAccess.TOKEN_ADJUST_PRIVILEGES | TokenAccess.TOKEN_QUERY))
|
||||
{
|
||||
Assert.That(LookupPrivilegeValue(null, "SeShutdownPrivilege", out var luid));
|
||||
var ptp = new PTOKEN_PRIVILEGES(luid, PrivilegeAttributes.SE_PRIVILEGE_ENABLED);
|
||||
var old = PTOKEN_PRIVILEGES.GetAllocatedAndEmptyInstance();
|
||||
Assert.That(AdjustTokenPrivileges(t, false, ptp, (uint)old.Size, old, out var rLen));
|
||||
|
||||
Assert.That(AdjustTokenPrivileges(t, false, ptp));
|
||||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void AllocateAndInitializeSidTest()
|
||||
{
|
||||
|
@ -100,14 +69,6 @@ namespace Vanara.PInvoke.Tests
|
|||
Assert.That(b);
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void AllocateLocallyUniqueIdTest()
|
||||
{
|
||||
Assert.That(AllocateLocallyUniqueId(out var luid));
|
||||
TestContext.WriteLine($"{luid.LowPart:X} {luid.HighPart:X}");
|
||||
Assert.That(luid.LowPart, Is.Not.Zero);
|
||||
}
|
||||
|
||||
[Test()]
|
||||
[PrincipalPermission(SecurityAction.Assert, Role = "Administrators")]
|
||||
public void ChangeAndQueryServiceConfigTest()
|
||||
|
@ -197,60 +158,6 @@ namespace Vanara.PInvoke.Tests
|
|||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void DuplicateTokenTest()
|
||||
{
|
||||
using (var pval = SafeHTOKEN.FromProcess(System.Diagnostics.Process.GetCurrentProcess()))
|
||||
{
|
||||
Assert.That(pval.IsInvalid, Is.False);
|
||||
Assert.That(DuplicateToken(pval, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, out var dtok));
|
||||
Assert.That(dtok.IsInvalid, Is.False);
|
||||
dtok.Close();
|
||||
}
|
||||
}
|
||||
|
||||
[Test, TestCaseSource(typeof(AdvApi32Tests), nameof(AuthCasesFromFile))]
|
||||
public void GetAceTest(bool validUser, bool validCred, string urn, string dn, string dc, string domain, string username, string password, string notes)
|
||||
{
|
||||
var fun = $"{domain}\\{username}";
|
||||
|
||||
var pSD = GetSD(fn);
|
||||
var b = GetSecurityDescriptorDacl(pSD, out var daclPresent, out var pAcl, out var defaulted);
|
||||
Assert.That(b, Is.True);
|
||||
Assert.That(daclPresent, Is.True);
|
||||
Assert.That(pAcl, Is.Not.EqualTo(IntPtr.Zero));
|
||||
var hardAcl = ((IntPtr)pAcl).ToStructure<ACL>();
|
||||
b = GetAclInformation(pAcl, out ACL_REVISION_INFORMATION ari, (uint)Marshal.SizeOf(typeof(ACL_REVISION_INFORMATION)), ACL_INFORMATION_CLASS.AclRevisionInformation);
|
||||
Assert.That(b, Is.True);
|
||||
Assert.That(ari.AclRevision, Is.EqualTo(hardAcl.AclRevision));
|
||||
b = GetAclInformation(pAcl, out ACL_SIZE_INFORMATION asi, (uint)Marshal.SizeOf(typeof(ACL_SIZE_INFORMATION)), ACL_INFORMATION_CLASS.AclSizeInformation);
|
||||
Assert.That(b, Is.True);
|
||||
Assert.That(asi.AceCount, Is.EqualTo(hardAcl.AceCount));
|
||||
for (var i = 0U; i < asi.AceCount; i++)
|
||||
{
|
||||
b = GetAce(pAcl, i, out var pAce);
|
||||
Assert.That(b, Is.True);
|
||||
|
||||
var accountSize = 1024;
|
||||
var domainSize = 1024;
|
||||
var outuser = new StringBuilder(accountSize, accountSize);
|
||||
var outdomain = new StringBuilder(domainSize, domainSize);
|
||||
b = LookupAccountSid(null, pAce.GetSid(), outuser, ref accountSize, outdomain, ref domainSize, out _);
|
||||
Assert.That(b, Is.True);
|
||||
TestContext.WriteLine($"Ace{i}: {pAce.GetHeader().AceType}={outdomain}\\{outuser}; {pAce.GetMask()}");
|
||||
}
|
||||
|
||||
BuildTrusteeWithName(out var pTrustee, fun);
|
||||
Assert.That(GetEffectiveRightsFromAcl(pAcl, pTrustee, out var accessRights), Is.EqualTo(Win32Error.ERROR_NONE_MAPPED).Or.Zero);
|
||||
var map = new GENERIC_MAPPING((uint)Kernel32.FileAccess.FILE_GENERIC_READ, (uint)Kernel32.FileAccess.FILE_GENERIC_WRITE, (uint)Kernel32.FileAccess.FILE_GENERIC_EXECUTE, (uint)Kernel32.FileAccess.FILE_ALL_ACCESS);
|
||||
var ifArray = new SafeInheritedFromArray(hardAcl.AceCount);
|
||||
var err = GetInheritanceSource(fn, SE_OBJECT_TYPE.SE_FILE_OBJECT, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, false, null,
|
||||
0, pAcl, IntPtr.Zero, map, ifArray);
|
||||
Assert.That(err, Is.EqualTo(0));
|
||||
TestContext.WriteLine($"{hardAcl.AceCount}: {string.Join("; ", ifArray.Results.Select(i => i.ToString()))}");
|
||||
Assert.That(() => ifArray.Dispose(), Throws.Nothing);
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void GetNamedSecurityInfoTest()
|
||||
{
|
||||
|
@ -258,60 +165,6 @@ namespace Vanara.PInvoke.Tests
|
|||
Assert.That(pSD, Is.Not.Null);
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void GetPrivateObjectSecurityTest()
|
||||
{
|
||||
using (var pSD = GetSD(fn))
|
||||
{
|
||||
var pos = pSD.GetPrivateObjectSecurity(SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION);
|
||||
Assert.That(!pos.IsInvalid);
|
||||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void GetTokenInformationTest()
|
||||
{
|
||||
//var p = SafeTokenHandle.CurrentProcessToken.GetInfo<PTOKEN_PRIVILEGES>(TOKEN_INFORMATION_CLASS.TokenPrivileges).Privileges;
|
||||
using (var t = SafeHTOKEN.FromProcess(Process.GetCurrentProcess(), TokenAccess.TOKEN_QUERY))
|
||||
{
|
||||
Assert.That(t, Is.Not.Null);
|
||||
|
||||
var p = t.GetInfo<PTOKEN_PRIVILEGES>(TOKEN_INFORMATION_CLASS.TokenPrivileges);
|
||||
Assert.That(p, Is.Not.Null);
|
||||
Assert.That(p.PrivilegeCount, Is.GreaterThan(0));
|
||||
TestContext.WriteLine("Privs: " + string.Join("; ", p.Privileges.Select(i => i.ToString())));
|
||||
|
||||
using (var hMem = PTOKEN_PRIVILEGES.GetAllocatedAndEmptyInstance(50))
|
||||
{
|
||||
var b = GetTokenInformation(t, TOKEN_INFORMATION_CLASS.TokenPrivileges, hMem, hMem.Size, out var sz);
|
||||
Assert.That(b);
|
||||
var p1 = PTOKEN_PRIVILEGES.FromPtr((IntPtr)hMem);
|
||||
Assert.That(p1.PrivilegeCount, Is.EqualTo(p.PrivilegeCount));
|
||||
|
||||
Assert.That(p.Privileges, Is.EquivalentTo(p1.Privileges));
|
||||
}
|
||||
}
|
||||
|
||||
using (var t = SafeHTOKEN.FromThread(GetCurrentThread(), TokenAccess.TOKEN_QUERY))
|
||||
{
|
||||
var id = t.GetInfo<uint>(TOKEN_INFORMATION_CLASS.TokenSessionId);
|
||||
Assert.That(id, Is.Not.Zero);
|
||||
TestContext.WriteLine($"SessId: {id}");
|
||||
|
||||
var ve = t.GetInfo<uint>(TOKEN_INFORMATION_CLASS.TokenVirtualizationEnabled);
|
||||
Assert.That(ve, Is.Zero);
|
||||
TestContext.WriteLine($"VirtEnable: {ve}");
|
||||
|
||||
var et = t.GetInfo<TOKEN_ELEVATION_TYPE>(TOKEN_INFORMATION_CLASS.TokenElevationType);
|
||||
Assert.That(et, Is.Not.Zero);
|
||||
TestContext.WriteLine($"ElevType: {et}");
|
||||
|
||||
var e = t.GetInfo<TOKEN_ELEVATION>(TOKEN_INFORMATION_CLASS.TokenElevation);
|
||||
Assert.That(e, Is.Not.Zero);
|
||||
TestContext.WriteLine($"Elev: {e.TokenIsElevated}");
|
||||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void InitAndAbortSystemShutdownTest()
|
||||
{
|
||||
|
@ -403,25 +256,6 @@ namespace Vanara.PInvoke.Tests
|
|||
Assert.That(LookupPrivilegeName(null, luid, sb, ref chSz), Is.False);
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void PrivilegeCheckTest()
|
||||
{
|
||||
using (var t = SafeHTOKEN.FromProcess(GetCurrentProcess(), TokenAccess.TOKEN_QUERY))
|
||||
{
|
||||
Assert.That(LookupPrivilegeValue(null, "SeDebugPrivilege", out var luid));
|
||||
Assert.That(PrivilegeCheck(t, new PRIVILEGE_SET(PrivilegeSetControl.PRIVILEGE_SET_ALL_NECESSARY, luid, PrivilegeAttributes.SE_PRIVILEGE_ENABLED), out var res));
|
||||
TestContext.WriteLine($"Has {luid}={res}");
|
||||
|
||||
Assert.That(LookupPrivilegeValue(null, "SeChangeNotifyPrivilege", out luid));
|
||||
Assert.That(PrivilegeCheck(t, new PRIVILEGE_SET(PrivilegeSetControl.PRIVILEGE_SET_ALL_NECESSARY, new[] { new LUID_AND_ATTRIBUTES(luid, PrivilegeAttributes.SE_PRIVILEGE_ENABLED_BY_DEFAULT), new LUID_AND_ATTRIBUTES(luid, PrivilegeAttributes.SE_PRIVILEGE_ENABLED) }), out res));
|
||||
TestContext.WriteLine($"Has {luid}={res}");
|
||||
|
||||
Assert.That(LookupPrivilegeValue(null, "SeShutdownPrivilege", out luid));
|
||||
Assert.That(PrivilegeCheck(t, new PRIVILEGE_SET(PrivilegeSetControl.PRIVILEGE_SET_ALL_NECESSARY, luid, PrivilegeAttributes.SE_PRIVILEGE_ENABLED), out res));
|
||||
TestContext.WriteLine($"Has {luid}={res}");
|
||||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
[PrincipalPermission(SecurityAction.Assert, Role = "Administrators")]
|
||||
public void QueryServiceConfig2Test()
|
||||
|
@ -498,8 +332,7 @@ namespace Vanara.PInvoke.Tests
|
|||
|
||||
internal static SafePSECURITY_DESCRIPTOR GetSD(string filename, SECURITY_INFORMATION si = SECURITY_INFORMATION.DACL_SECURITY_INFORMATION | SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION)
|
||||
{
|
||||
var err = GetNamedSecurityInfo(filename, SE_OBJECT_TYPE.SE_FILE_OBJECT, si, out _, out _, out _, out _, out var pSD);
|
||||
Assert.That(err, Is.EqualTo(0));
|
||||
Assert.That(GetNamedSecurityInfo(filename, SE_OBJECT_TYPE.SE_FILE_OBJECT, si, out _, out _, out _, out _, out var pSD), ResultIs.Successful);
|
||||
Assert.That(!pSD.IsInvalid);
|
||||
return pSD;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.AccessControl;
|
||||
using System.Text;
|
||||
using Vanara.Extensions;
|
||||
using Vanara.InteropServices;
|
||||
using static Vanara.PInvoke.AdvApi32;
|
||||
using static Vanara.PInvoke.Kernel32;
|
||||
|
@ -13,10 +15,191 @@ namespace Vanara.PInvoke.Tests
|
|||
[TestFixture]
|
||||
public class SecurityBaseApiTests
|
||||
{
|
||||
[Test]
|
||||
public void AccessCheckByTypeResultListTest()
|
||||
{
|
||||
using (var pSD = AdvApi32Tests.GetSD(AdvApi32Tests.fn, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION | SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION | SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION))
|
||||
using (var hTok = SafeHTOKEN.FromProcess(GetCurrentProcess(), TokenAccess.TOKEN_IMPERSONATE | TokenAccess.TOKEN_DUPLICATE | TokenAccess.TOKEN_READ).Duplicate(SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation))
|
||||
{
|
||||
var ps = PRIVILEGE_SET.InitializeWithCapacity(100);
|
||||
var psSz = ps.SizeInBytes;
|
||||
var gm = GENERIC_MAPPING.GenericFileMapping;
|
||||
ACCESS_MASK accessMask = ACCESS_MASK.GENERIC_READ;
|
||||
MapGenericMask(ref accessMask, gm);
|
||||
var otl = new[] { new OBJECT_TYPE_LIST(ObjectTypeListLevel.ACCESS_OBJECT_GUID) };
|
||||
var access = new uint[otl.Length];
|
||||
var status = new uint[otl.Length];
|
||||
Assert.That(AccessCheckByTypeResultList(pSD, default, hTok, accessMask, otl, (uint)otl.Length, gm, ps, ref psSz, access, status), ResultIs.Successful);
|
||||
Assert.That(ps.PrivilegeCount, Is.GreaterThanOrEqualTo(0));
|
||||
Assert.That(access[0], Is.EqualTo((uint)FileAccess.FILE_GENERIC_READ));
|
||||
Assert.That(status[0], Is.Zero);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AccessCheckByTypeTest()
|
||||
{
|
||||
using (var pSD = AdvApi32Tests.GetSD(AdvApi32Tests.fn, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION | SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION | SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION))
|
||||
using (var hTok = SafeHTOKEN.FromProcess(GetCurrentProcess(), TokenAccess.TOKEN_IMPERSONATE | TokenAccess.TOKEN_DUPLICATE | TokenAccess.TOKEN_READ).Duplicate(SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation))
|
||||
{
|
||||
var ps = PRIVILEGE_SET.InitializeWithCapacity(100);
|
||||
var psSz = ps.SizeInBytes;
|
||||
var gm = GENERIC_MAPPING.GenericFileMapping;
|
||||
ACCESS_MASK accessMask = ACCESS_MASK.GENERIC_READ;
|
||||
MapGenericMask(ref accessMask, gm);
|
||||
var otl = new[] { new OBJECT_TYPE_LIST(ObjectTypeListLevel.ACCESS_OBJECT_GUID) };
|
||||
Assert.That(AccessCheckByType(pSD, default, hTok, accessMask, otl, (uint)otl.Length, gm, ps, ref psSz, out var access, out var status), ResultIs.Successful);
|
||||
Assert.That(ps.PrivilegeCount, Is.GreaterThanOrEqualTo(0));
|
||||
Assert.That(access, Is.EqualTo((uint)FileAccess.FILE_GENERIC_READ));
|
||||
Assert.That(status, Is.True);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AccessCheckTest()
|
||||
{
|
||||
using (var pSD = AdvApi32Tests.GetSD(AdvApi32Tests.fn, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION | SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION | SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION))
|
||||
using (var hTok = SafeHTOKEN.FromProcess(GetCurrentProcess(), TokenAccess.TOKEN_IMPERSONATE | TokenAccess.TOKEN_DUPLICATE | TokenAccess.TOKEN_READ).Duplicate(SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation))
|
||||
{
|
||||
var ps = PRIVILEGE_SET.InitializeWithCapacity(10);
|
||||
var psSz = ps.SizeInBytes;
|
||||
var gm = GENERIC_MAPPING.GenericFileMapping;
|
||||
ACCESS_MASK accessMask = ACCESS_MASK.GENERIC_READ;
|
||||
MapGenericMask(ref accessMask, gm);
|
||||
Assert.That(AccessCheck(pSD, hTok, accessMask, gm, ps, ref psSz, out var access, out var status), ResultIs.Successful);
|
||||
Assert.That(ps.PrivilegeCount, Is.GreaterThanOrEqualTo(0));
|
||||
Assert.That(access, Is.EqualTo((uint)FileAccess.FILE_GENERIC_READ));
|
||||
Assert.That(status, Is.True);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddAccessAllowedAceExTest()
|
||||
{
|
||||
using (var pACL = GetAcl())
|
||||
Assert.That(AddAccessAllowedAceEx(pACL, ACL_REVISION, AceFlags.None, (uint)FileAccess.FILE_GENERIC_READ, SafePSID.Everyone), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddAccessAllowedAceTest()
|
||||
{
|
||||
using (var pACL = GetAcl())
|
||||
Assert.That(AddAccessAllowedAce(pACL, ACL_REVISION, (uint)FileAccess.FILE_GENERIC_READ, SafePSID.Everyone), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddAccessAllowedObjectAceTest()
|
||||
{
|
||||
var objTypeGuid = IntPtr.Zero;
|
||||
var inhObjTypeGuid = IntPtr.Zero;
|
||||
using (var pACL = GetAcl())
|
||||
Assert.That(AddAccessAllowedObjectAce(pACL, ACL_REVISION, AceFlags.None, (uint)FileAccess.FILE_GENERIC_READ, objTypeGuid, inhObjTypeGuid, SafePSID.Everyone), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddAccessAllowedObjectAceTest2()
|
||||
{
|
||||
var objTypeGuid = Guid.NewGuid();
|
||||
var inhObjTypeGuid = Guid.NewGuid();
|
||||
using (var pACL = GetAcl())
|
||||
Assert.That(AddAccessAllowedObjectAce(pACL, ACL_REVISION_DS, AceFlags.None, (uint)FileAccess.FILE_GENERIC_READ, objTypeGuid, inhObjTypeGuid, SafePSID.Everyone), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddAccessDeniedAceExTest()
|
||||
{
|
||||
using (var pACL = GetAcl())
|
||||
Assert.That(AddAccessDeniedAceEx(pACL, ACL_REVISION, AceFlags.None, (uint)FileAccess.FILE_GENERIC_READ, SafePSID.Everyone), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddAccessDeniedAceTest()
|
||||
{
|
||||
using (var pACL = GetAcl())
|
||||
Assert.That(AddAccessDeniedAce(pACL, ACL_REVISION, (uint)FileAccess.FILE_GENERIC_READ, SafePSID.Everyone), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddAccessDeniedObjectAceTest()
|
||||
{
|
||||
var objTypeGuid = IntPtr.Zero;
|
||||
var inhObjTypeGuid = IntPtr.Zero;
|
||||
using (var pACL = GetAcl())
|
||||
Assert.That(AddAccessDeniedObjectAce(pACL, ACL_REVISION, AceFlags.None, (uint)FileAccess.FILE_GENERIC_READ, objTypeGuid, inhObjTypeGuid, SafePSID.Everyone), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddAccessDeniedObjectAceTest2()
|
||||
{
|
||||
var objTypeGuid = Guid.NewGuid();
|
||||
var inhObjTypeGuid = Guid.NewGuid();
|
||||
using (var pACL = GetAcl())
|
||||
Assert.That(AddAccessDeniedObjectAce(pACL, ACL_REVISION_DS, AceFlags.None, (uint)FileAccess.FILE_GENERIC_READ, objTypeGuid, inhObjTypeGuid, SafePSID.Everyone), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddAuditAccessAceExTest()
|
||||
{
|
||||
using (var pACL = GetAcl())
|
||||
Assert.That(AddAuditAccessAceEx(pACL, ACL_REVISION, AceFlags.None, (uint)FileAccess.FILE_GENERIC_READ, SafePSID.Everyone, false, true), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddAuditAccessAceTest()
|
||||
{
|
||||
using (var pACL = GetAcl())
|
||||
Assert.That(AddAuditAccessAce(pACL, ACL_REVISION, (uint)FileAccess.FILE_GENERIC_READ, SafePSID.Everyone, false, true), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddAuditAccessObjectAceTest()
|
||||
{
|
||||
var objTypeGuid = IntPtr.Zero;
|
||||
var inhObjTypeGuid = IntPtr.Zero;
|
||||
using (var pACL = GetAcl())
|
||||
Assert.That(AddAuditAccessObjectAce(pACL, ACL_REVISION, AceFlags.None, (uint)FileAccess.FILE_GENERIC_READ, objTypeGuid, inhObjTypeGuid, SafePSID.Everyone, false, true), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddAuditAccessObjectAceTest2()
|
||||
{
|
||||
var objTypeGuid = Guid.NewGuid();
|
||||
var inhObjTypeGuid = Guid.NewGuid();
|
||||
using (var pACL = GetAcl())
|
||||
Assert.That(AddAuditAccessObjectAce(pACL, ACL_REVISION_DS, AceFlags.None, (uint)FileAccess.FILE_GENERIC_READ, objTypeGuid, inhObjTypeGuid, SafePSID.Everyone, false, true), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddGetAceTest()
|
||||
{
|
||||
Assert.That(GetNamedSecurityInfo(AdvApi32Tests.fn, SE_OBJECT_TYPE.SE_FILE_OBJECT, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, out _, out _, out var acl, out _, out var pSD), ResultIs.Successful);
|
||||
using (pSD)
|
||||
using (var pACL = new SafePACL(acl))
|
||||
{
|
||||
// The resize action gets all the ACEs from the current ACL and adds them to the newly allocated space.
|
||||
pACL.Size *= 2;
|
||||
|
||||
Assert.That(pACL.AceCount, Is.EqualTo(GetAceCount(acl)));
|
||||
}
|
||||
|
||||
uint GetAceCount(PACL pACL)
|
||||
{
|
||||
return IsValidAcl(pACL) && GetAclInformation(pACL, out ACL_SIZE_INFORMATION si) ? si.AceCount : 0;
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddMandatoryAceTest()
|
||||
{
|
||||
using (var mSid = SafePSID.Init(KnownSIDAuthority.SECURITY_MANDATORY_LABEL_AUTHORITY, 1, KnownSIDRelativeID.SECURITY_MANDATORY_LOW_RID))
|
||||
using (var pACL = GetAcl())
|
||||
Assert.That(AddMandatoryAce(pACL, ACL_REVISION_DS, AceFlags.None, SYSTEM_MANDATORY_LABEL.SYSTEM_MANDATORY_LABEL_NO_READ_UP, mSid), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddResourceAttributeAceTest()
|
||||
{
|
||||
using (var pNewSacl = new SafePACL(256))
|
||||
using (var pNewSacl = GetAcl())
|
||||
{
|
||||
using (var capId = new SafePSID("S-1-17-22"))
|
||||
Assert.That(AddScopedPolicyIDAce(pNewSacl, ACL_REVISION, 0, 0, capId), ResultIs.Successful);
|
||||
|
@ -29,14 +212,14 @@ namespace Vanara.PInvoke.Tests
|
|||
Name = "Int",
|
||||
ValueType = CLAIM_SECURITY_ATTRIBUTE_TYPE.CLAIM_SECURITY_ATTRIBUTE_TYPE_INT64,
|
||||
ValueCount = (uint)attrValues.Length,
|
||||
Values = new CLAIM_SECURITY_ATTRIBUTE_V1.VALUESUNION { pInt64 = (IntPtr)pattrValues }
|
||||
Values = new CLAIM_SECURITY_ATTRIBUTE_V1.VALUESUNION { pInt64 = pattrValues }
|
||||
};
|
||||
var attr = new[] { csattr };
|
||||
using (var pattr = SafeHGlobalHandle.CreateFromList(attr))
|
||||
{
|
||||
var csi = CLAIM_SECURITY_ATTRIBUTES_INFORMATION.Default;
|
||||
csi.AttributeCount = (uint)attr.Length;
|
||||
csi.Attribute.pAttributeV1 = (IntPtr)pattr;
|
||||
csi.Attribute.pAttributeV1 = pattr;
|
||||
var len = 0U;
|
||||
Assert.That(AddResourceAttributeAce(pNewSacl, ACL_REVISION, 0, 0, SafePSID.Everyone, csi, ref len), ResultIs.Successful);
|
||||
}
|
||||
|
@ -45,20 +228,581 @@ namespace Vanara.PInvoke.Tests
|
|||
}
|
||||
|
||||
[Test]
|
||||
public void CheckTokenCapabilityTest()
|
||||
public void AdjustTokenGroupsTest()
|
||||
{
|
||||
using (var hTok = SafeHTOKEN.CurrentProcessToken)
|
||||
Assert.That(CheckTokenCapability(hTok, SafePSID.Current, out var has), ResultIs.Successful);
|
||||
using (var t = SafeHTOKEN.FromThread(SafeHTHREAD.Current, TokenAccess.TOKEN_ADJUST_PRIVILEGES | TokenAccess.TOKEN_ADJUST_GROUPS | TokenAccess.TOKEN_QUERY))
|
||||
{
|
||||
var tg = new TOKEN_GROUPS(1);
|
||||
tg.Groups[0] = new SID_AND_ATTRIBUTES(SafePSID.Everyone, 0);
|
||||
Assert.That(AdjustTokenGroups(t, true, tg, 0, IntPtr.Zero, out var req), ResultIs.Failure);
|
||||
using (var mem = new SafeHGlobalHandle(req))
|
||||
Assert.That(AdjustTokenGroups(t, true, tg, mem.Size, mem, out req), ResultIs.Successful);
|
||||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void AdjustTokenPrivilegesTest()
|
||||
{
|
||||
using (var t = SafeHTOKEN.FromThread(SafeHTHREAD.Current, TokenAccess.TOKEN_ADJUST_PRIVILEGES | TokenAccess.TOKEN_QUERY))
|
||||
{
|
||||
Assert.That(LookupPrivilegeValue(null, "SeShutdownPrivilege", out var luid));
|
||||
var ptp = new PTOKEN_PRIVILEGES(luid, PrivilegeAttributes.SE_PRIVILEGE_ENABLED);
|
||||
var old = PTOKEN_PRIVILEGES.GetAllocatedAndEmptyInstance();
|
||||
Assert.That(AdjustTokenPrivileges(t, false, ptp, old.Size, old, out var rLen));
|
||||
|
||||
Assert.That(AdjustTokenPrivileges(t, false, ptp));
|
||||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void AllocateLocallyUniqueIdTest()
|
||||
{
|
||||
Assert.That(AllocateLocallyUniqueId(out var luid));
|
||||
TestContext.WriteLine($"{luid.LowPart:X} {luid.HighPart:X}");
|
||||
Assert.That(luid.LowPart, Is.Not.Zero);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AreAccessesGrantedTest()
|
||||
{
|
||||
Assert.That(AreAllAccessesGranted((uint)FileAccess.FILE_ALL_ACCESS, (uint)FileAccess.FILE_READ_DATA), Is.True);
|
||||
Assert.That(AreAnyAccessesGranted((uint)FileAccess.FILE_READ_DATA, (uint)FileAccess.FILE_ALL_ACCESS), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CheckTokenCapabilityTest() => Assert.That(CheckTokenCapability(HTOKEN.NULL, SafePSID.CreateCapability(KnownSIDCapability.SECURITY_CAPABILITY_DOCUMENTS_LIBRARY), out var has), ResultIs.Successful);
|
||||
|
||||
[Test]
|
||||
public void CheckTokenMembershipExTest() => Assert.That(CheckTokenMembershipEx(default, SafePSID.Current, CTMF.CTMF_INCLUDE_APPCONTAINER, out var mbr), ResultIs.Successful);
|
||||
|
||||
[Test]
|
||||
public void CheckTokenMembershipTest() => Assert.That(CheckTokenMembership(default, SafePSID.Current, out var mbr), ResultIs.Successful);
|
||||
|
||||
[Test]
|
||||
public void ConvertToAutoInheritPrivateObjectSecurityTest()
|
||||
{
|
||||
const SECURITY_INFORMATION si = SECURITY_INFORMATION.DACL_SECURITY_INFORMATION | SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION | SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION;
|
||||
using (new PrivBlock("SeSecurityPrivilege"))
|
||||
using (var pParentSD = AdvApi32Tests.GetSD(System.IO.Path.GetDirectoryName(AdvApi32Tests.fn), si))
|
||||
using (var pSD = AdvApi32Tests.GetSD(AdvApi32Tests.fn, si))
|
||||
{
|
||||
TestContext.WriteLine(ConvertSecurityDescriptorToStringSecurityDescriptor(pSD, si));
|
||||
Assert.That(ConvertToAutoInheritPrivateObjectSecurity(pParentSD, pSD, out var pos, IntPtr.Zero, false, GENERIC_MAPPING.GenericFileMapping), ResultIs.Successful);
|
||||
TestContext.Write(ConvertSecurityDescriptorToStringSecurityDescriptor(pos, si));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateGetSetPrivateObjectSecurityExTest()
|
||||
{
|
||||
using (new PrivBlock("SeSecurityPrivilege"))
|
||||
using (var pParentSD = AdvApi32Tests.GetSD(System.IO.Path.GetDirectoryName(AdvApi32Tests.fn)))
|
||||
using (var hTok = SafeHTOKEN.FromProcess(GetCurrentProcess(), TokenAccess.TOKEN_IMPERSONATE | TokenAccess.TOKEN_DUPLICATE | TokenAccess.TOKEN_QUERY).Duplicate(SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation))
|
||||
{
|
||||
Assert.That(CreatePrivateObjectSecurityEx(pParentSD, default, out var spod, IntPtr.Zero, false, SEF.SEF_MACL_NO_READ_UP, hTok, GENERIC_MAPPING.GenericFileMapping), ResultIs.Successful);
|
||||
using (spod)
|
||||
{
|
||||
TestContext.Write(ConvertSecurityDescriptorToStringSecurityDescriptor(spod, AdvApi32Tests.AllSI));
|
||||
|
||||
using (var pSD = new SafePSECURITY_DESCRIPTOR(4096))
|
||||
{
|
||||
Assert.That(GetPrivateObjectSecurity(spod, SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION, pSD, pSD.Size, out _), ResultIs.Successful);
|
||||
var hspod = (PSECURITY_DESCRIPTOR)spod;
|
||||
Assert.That(SetPrivateObjectSecurity(SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION, pSD, ref spod.DangerousGetRefHandle(), GENERIC_MAPPING.GenericFileMapping, hTok), ResultIs.Successful);
|
||||
TestContext.WriteLine($"Before: {hspod.DangerousGetHandle().ToInt32().ToString("X")}, After: {spod.DangerousGetHandle().ToInt32().ToString("X")}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreatePrivateObjectSecurityTest()
|
||||
{
|
||||
using (new PrivBlock("SeSecurityPrivilege"))
|
||||
using (var pParentSD = AdvApi32Tests.GetSD(System.IO.Path.GetDirectoryName(AdvApi32Tests.fn)))
|
||||
using (var hTok = SafeHTOKEN.FromProcess(GetCurrentProcess(), TokenAccess.TOKEN_IMPERSONATE | TokenAccess.TOKEN_DUPLICATE | TokenAccess.TOKEN_QUERY).Duplicate(SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation))
|
||||
{
|
||||
Assert.That(CreatePrivateObjectSecurity(pParentSD, default, out var spod, false, hTok, GENERIC_MAPPING.GenericFileMapping), ResultIs.Successful);
|
||||
TestContext.Write(ConvertSecurityDescriptorToStringSecurityDescriptor(spod, AdvApi32Tests.AllSI));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreatePrivateObjectSecurityWithMultipleInheritanceTest()
|
||||
{
|
||||
using (new PrivBlock("SeSecurityPrivilege"))
|
||||
using (var pParentSD = AdvApi32Tests.GetSD(System.IO.Path.GetDirectoryName(AdvApi32Tests.fn)))
|
||||
using (var hTok = SafeHTOKEN.FromProcess(GetCurrentProcess(), TokenAccess.TOKEN_IMPERSONATE | TokenAccess.TOKEN_DUPLICATE | TokenAccess.TOKEN_QUERY).Duplicate(SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation))
|
||||
{
|
||||
Assert.That(CreatePrivateObjectSecurityWithMultipleInheritance(pParentSD, default, out var spod, null, 0, false, SEF.SEF_MACL_NO_READ_UP, hTok, GENERIC_MAPPING.GenericFileMapping), ResultIs.Successful);
|
||||
TestContext.Write(ConvertSecurityDescriptorToStringSecurityDescriptor(spod, AdvApi32Tests.AllSI));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateRestrictedTokenTest()
|
||||
{
|
||||
using (new PrivBlock("SeSecurityPrivilege"))
|
||||
using (var hTok = SafeHTOKEN.FromProcess(GetCurrentProcess(), TokenAccess.TOKEN_ALL_ACCESS))
|
||||
{
|
||||
Assert.That(IsTokenRestricted(hTok), Is.False);
|
||||
Assert.That(CreateRestrictedToken(hTok, RestrictedPrivilegeOptions.DISABLE_MAX_PRIVILEGE | RestrictedPrivilegeOptions.LUA_TOKEN, NewTokenHandle: out var hNewTok), ResultIs.Successful);
|
||||
hNewTok.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CveEventWriteTest() => Assert.That(CveEventWrite("CVE-2016-7654321"), ResultIs.Successful);
|
||||
|
||||
[Test]
|
||||
public void DeleteAceTest()
|
||||
{
|
||||
Assert.That(GetNamedSecurityInfo(AdvApi32Tests.fn, SE_OBJECT_TYPE.SE_FILE_OBJECT, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, out _, out _, out var acl, out _, out var pSD), ResultIs.Successful);
|
||||
using (pSD)
|
||||
{
|
||||
Assert.That(DeleteAce(acl, 0), ResultIs.Successful);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeriveCapabilitySidsFromNameTest()
|
||||
{
|
||||
Assert.That(DeriveCapabilitySidsFromName("microsoft.hsaTestCustomCapability_q536wpkpf5cy2", out var grpsids, out var grpcnt, out var sids, out var cnt), ResultIs.Successful);
|
||||
grpsids.Count = grpcnt; sids.Count = cnt;
|
||||
Assert.That(grpsids.Count, Is.EqualTo(grpcnt));
|
||||
Assert.That(grpsids, Is.Not.Empty);
|
||||
Assert.That(sids, Is.Not.Empty);
|
||||
Assert.That(DeriveCapabilitySidsFromName("internetClient", out var capGrpSids, out var nCapGrpSids, out var capSids, out var nCapSids), ResultIs.Successful);
|
||||
Assert.That(() =>
|
||||
{
|
||||
capGrpSids.Count = nCapGrpSids;
|
||||
capSids.Count = nCapSids;
|
||||
}, Throws.Nothing);
|
||||
Assert.That(capGrpSids.Count, Is.EqualTo(nCapGrpSids));
|
||||
Assert.That(capGrpSids, Is.Not.Empty);
|
||||
Assert.That(capSids, Is.Not.Empty);
|
||||
TestContext.WriteLine(string.Join("\n", capGrpSids.Select(s => s.ToString("P"))));
|
||||
TestContext.WriteLine(string.Join("\n", capSids.Select(s => s.ToString("P"))));
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void DuplicateTokenTest()
|
||||
{
|
||||
using (var pval = SafeHTOKEN.FromProcess(Process.GetCurrentProcess()))
|
||||
{
|
||||
Assert.That(pval.IsInvalid, Is.False);
|
||||
Assert.That(DuplicateToken(pval, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, out var dtok));
|
||||
Assert.That(dtok.IsInvalid, Is.False);
|
||||
dtok.Close();
|
||||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void DuplicateTokenExTest()
|
||||
{
|
||||
using (var pval = SafeHTOKEN.FromProcess(Process.GetCurrentProcess()))
|
||||
{
|
||||
Assert.That(pval.IsInvalid, Is.False);
|
||||
Assert.That(DuplicateTokenEx(pval, TokenAccess.TOKEN_IMPERSONATE, null, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenImpersonation, out var dtok));
|
||||
Assert.That(dtok.IsInvalid, Is.False);
|
||||
dtok.Close();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindFirstFreeAceTest()
|
||||
{
|
||||
Assert.That(GetNamedSecurityInfo(AdvApi32Tests.fn, SE_OBJECT_TYPE.SE_FILE_OBJECT, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, out _, out _, out var acl, out _, out var pSD), ResultIs.Successful);
|
||||
using (pSD)
|
||||
Assert.That(FindFirstFreeAce(acl, out var pAce), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test, TestCaseSource(typeof(AdvApi32Tests), nameof(AdvApi32Tests.AuthCasesFromFile))]
|
||||
public void GetAceTest(bool validUser, bool validCred, string urn, string dn, string dc, string domain, string username, string password, string notes)
|
||||
{
|
||||
var fun = $"{domain}\\{username}";
|
||||
|
||||
using (var pSD = AdvApi32Tests.GetSD(AdvApi32Tests.fn))
|
||||
{
|
||||
Assert.That(GetSecurityDescriptorDacl(pSD, out var daclPresent, out var pAcl, out var defaulted), ResultIs.Successful);
|
||||
Assert.That(daclPresent, Is.True);
|
||||
Assert.That(pAcl, Is.Not.EqualTo(IntPtr.Zero));
|
||||
var hardAcl = ((IntPtr)pAcl).ToStructure<ACL>();
|
||||
Assert.That(GetAclInformation(pAcl, out ACL_REVISION_INFORMATION ari, (uint)Marshal.SizeOf(typeof(ACL_REVISION_INFORMATION)), ACL_INFORMATION_CLASS.AclRevisionInformation), ResultIs.Successful);
|
||||
Assert.That(ari.AclRevision, Is.EqualTo(hardAcl.AclRevision));
|
||||
Assert.That(GetAclInformation(pAcl, out ACL_SIZE_INFORMATION asi, (uint)Marshal.SizeOf(typeof(ACL_SIZE_INFORMATION)), ACL_INFORMATION_CLASS.AclSizeInformation), ResultIs.Successful);
|
||||
Assert.That(asi.AceCount, Is.EqualTo(hardAcl.AceCount));
|
||||
for (var i = 0U; i < asi.AceCount; i++)
|
||||
{
|
||||
Assert.That(GetAce(pAcl, i, out var pAce), ResultIs.Successful);
|
||||
|
||||
var accountSize = 1024;
|
||||
var domainSize = 1024;
|
||||
var outuser = new StringBuilder(accountSize, accountSize);
|
||||
var outdomain = new StringBuilder(domainSize, domainSize);
|
||||
Assert.That(LookupAccountSid(null, pAce.GetSid(), outuser, ref accountSize, outdomain, ref domainSize, out _), ResultIs.Successful);
|
||||
TestContext.WriteLine($"Ace{i}: {pAce.GetHeader().AceType}={outdomain}\\{outuser}; {pAce.GetMask()}");
|
||||
}
|
||||
|
||||
BuildTrusteeWithName(out var pTrustee, fun);
|
||||
Assert.That((int)GetEffectiveRightsFromAcl(pAcl, pTrustee, out var accessRights), Is.EqualTo(Win32Error.ERROR_NONE_MAPPED).Or.Zero);
|
||||
var ifArray = new SafeInheritedFromArray(hardAcl.AceCount);
|
||||
Assert.That(GetInheritanceSource(AdvApi32Tests.fn, SE_OBJECT_TYPE.SE_FILE_OBJECT, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, false, null,
|
||||
0, pAcl, IntPtr.Zero, GENERIC_MAPPING.GenericFileMapping, ifArray), ResultIs.Successful);
|
||||
TestContext.WriteLine($"{hardAcl.AceCount}: {string.Join("; ", ifArray.Results.Select(i => i.ToString()))}");
|
||||
Assert.That(() => ifArray.Dispose(), Throws.Nothing);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSetKernelObjectSecurityTest()
|
||||
{
|
||||
HANDLE hProc = (IntPtr)GetCurrentProcess();
|
||||
using (new PrivBlock("SeSecurityPrivilege"))
|
||||
using (var pSD = new SafePSECURITY_DESCRIPTOR(2048))
|
||||
{
|
||||
// Get self-relative SD with DACL
|
||||
Assert.That(GetKernelObjectSecurity(hProc, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, pSD, pSD.Size, out var req), ResultIs.Successful);
|
||||
|
||||
// Get the DACL and insert a new ACE
|
||||
Assert.That(GetSecurityDescriptorDacl(pSD, out var present, out var pDacl, out var def), ResultIs.Successful);
|
||||
using (var pSafeDacl = new SafePACL(pDacl))
|
||||
{
|
||||
pSafeDacl.Size += GetRequiredAceSize<ACCESS_DENIED_ACE>(SafePSID.Everyone, out _);
|
||||
Assert.That(InsertAccessDeniedAce(pSafeDacl, ACL_REVISION, 0, AceFlags.None, (uint)ProcessAccess.PROCESS_ALL_ACCESS, SafePSID.Everyone), ResultIs.Successful);
|
||||
|
||||
// Since SD is self-relative, convert to absolute
|
||||
var pAbsSD = pSD.MakeAbsolute();
|
||||
|
||||
// Set the DACL on the new absolute SD
|
||||
Assert.That(SetSecurityDescriptorDacl(pAbsSD.pAbsoluteSecurityDescriptor, true, pSafeDacl, def), ResultIs.Successful);
|
||||
|
||||
// Try to apply updated absolute SD to kernel object
|
||||
Assert.That(SetKernelObjectSecurity(hProc, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, pAbsSD.pAbsoluteSecurityDescriptor), ResultIs.Successful);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSecurityDescriptorControlTest()
|
||||
{
|
||||
using (var pSD = AdvApi32Tests.GetSD(AdvApi32Tests.fn))
|
||||
{
|
||||
Assert.That(GetSecurityDescriptorControl(pSD, out var ctrl, out var rev), ResultIs.Successful);
|
||||
Assert.That(ctrl.IsFlagSet(SECURITY_DESCRIPTOR_CONTROL.SE_DACL_PRESENT));
|
||||
Assert.That(rev == SDDL_REVISION.SDDL_REVISION_1);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSecurityDescriptorGroupTest()
|
||||
{
|
||||
using (var pSD = AdvApi32Tests.GetSD(AdvApi32Tests.fn, SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION))
|
||||
{
|
||||
Assert.That(GetSecurityDescriptorGroup(pSD, out var pGroup, out var def), ResultIs.Successful);
|
||||
Assert.That(pGroup.IsValidSid());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSecurityDescriptorLengthTest()
|
||||
{
|
||||
using (var pSD = AdvApi32Tests.GetSD(AdvApi32Tests.fn))
|
||||
Assert.That(GetSecurityDescriptorLength(pSD), ResultIs.Not.Value(0U));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSecurityDescriptorOwnerTest()
|
||||
{
|
||||
using (var pSD = AdvApi32Tests.GetSD(AdvApi32Tests.fn, SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION))
|
||||
{
|
||||
Assert.That(GetSecurityDescriptorOwner(pSD, out var pOwner, out var def), ResultIs.Successful);
|
||||
Assert.That(pOwner.IsValidSid());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSecurityDescriptorRMControlTest()
|
||||
{
|
||||
using (var pSD = AdvApi32Tests.GetSD(AdvApi32Tests.fn))
|
||||
Assert.That(GetSecurityDescriptorRMControl(pSD, out var ctrl), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSecurityDescriptorSaclTest()
|
||||
{
|
||||
using (new PrivBlock("SeSecurityPrivilege"))
|
||||
using (var pSD = AdvApi32Tests.GetSD(AdvApi32Tests.fn, SECURITY_INFORMATION.SACL_SECURITY_INFORMATION))
|
||||
{
|
||||
Assert.That(GetSecurityDescriptorSacl(pSD, out var present, out var pSacl, out var def), ResultIs.Successful);
|
||||
Assert.That(present);
|
||||
Assert.That(!pSacl.IsNull);
|
||||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void GetSetTokenInformationTest()
|
||||
{
|
||||
using (var t = SafeHTOKEN.FromProcess(Process.GetCurrentProcess(), TokenAccess.TOKEN_QUERY))
|
||||
{
|
||||
Assert.That(t, Is.Not.Null);
|
||||
|
||||
var p = t.GetInfo<PTOKEN_PRIVILEGES>(TOKEN_INFORMATION_CLASS.TokenPrivileges);
|
||||
Assert.That(p, Is.Not.Null);
|
||||
Assert.That(p.PrivilegeCount, Is.GreaterThan(0));
|
||||
TestContext.WriteLine("Privs: " + string.Join("; ", p.Privileges.Select(i => i.ToString())));
|
||||
|
||||
using (var hMem = PTOKEN_PRIVILEGES.GetAllocatedAndEmptyInstance(50))
|
||||
{
|
||||
Assert.That(GetTokenInformation(t, TOKEN_INFORMATION_CLASS.TokenPrivileges, hMem, hMem.Size, out var sz), ResultIs.Successful);
|
||||
var p1 = PTOKEN_PRIVILEGES.FromPtr(hMem);
|
||||
Assert.That(p1.PrivilegeCount, Is.EqualTo(p.PrivilegeCount));
|
||||
|
||||
Assert.That(p.Privileges, Is.EquivalentTo(p1.Privileges));
|
||||
}
|
||||
}
|
||||
|
||||
using (new PrivBlock("SeSecurityPrivilege"))
|
||||
using (var t = SafeHTOKEN.FromThread(GetCurrentThread(), TokenAccess.TOKEN_ALL_ACCESS))
|
||||
using (var mem = new SafeHGlobalHandle(8192))
|
||||
{
|
||||
var getmi = typeof(AdvApi32).GetMethod("GetTokenInformation", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
|
||||
Assert.That(getmi, Is.Not.Null);
|
||||
var setmi = typeof(AdvApi32).GetMethod("SetTokenInformation", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public, null,
|
||||
new[] { typeof(HTOKEN), typeof(TOKEN_INFORMATION_CLASS), typeof(IntPtr), typeof(uint) }, null);
|
||||
Assert.That(setmi, Is.Not.Null);
|
||||
foreach (TOKEN_INFORMATION_CLASS cls in Enum.GetValues(typeof(TOKEN_INFORMATION_CLASS)))
|
||||
{
|
||||
TestContext.WriteLine(cls);
|
||||
uint sz = 0;
|
||||
|
||||
var gettype = CorrespondingTypeAttribute.GetCorrespondingTypes(cls, CorrespondingAction.Get).FirstOrDefault();
|
||||
if (gettype != null)
|
||||
{
|
||||
var insz = (int)mem.Size;
|
||||
if (cls == TOKEN_INFORMATION_CLASS.TokenLinkedToken || cls == TOKEN_INFORMATION_CLASS.TokenElevation)
|
||||
insz = 4;
|
||||
var param = new object[] { (HTOKEN)t, cls, (IntPtr)mem, insz, null };
|
||||
var res = getmi.Invoke(null, param);
|
||||
if ((bool)res)
|
||||
{
|
||||
sz = (uint)(int)param[4];
|
||||
TestContext.Write($">> Get =");
|
||||
try
|
||||
{
|
||||
((IntPtr)mem).Convert(mem.Size, gettype).WriteValues();
|
||||
}
|
||||
catch
|
||||
{
|
||||
TestContext.WriteLine($"Unable to convert {gettype.Name}");
|
||||
}
|
||||
}
|
||||
else
|
||||
TestContext.WriteLine($">> Get Error = {Win32Error.GetLastError()}");
|
||||
}
|
||||
|
||||
var settype = CorrespondingTypeAttribute.GetCorrespondingTypes(cls, CorrespondingAction.Set).FirstOrDefault();
|
||||
if (settype != null)
|
||||
{
|
||||
if (sz == 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
var inst = Activator.CreateInstance(settype);
|
||||
Marshal.StructureToPtr(inst, mem, false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
TestContext.WriteLine($">> Set Unable to get default {settype.Name}");
|
||||
}
|
||||
sz = (uint)Marshal.SizeOf(settype);
|
||||
}
|
||||
if (sz == 0) continue;
|
||||
var param = new object[] { (HTOKEN)t, cls, (IntPtr)mem, sz };
|
||||
|
||||
var res = setmi.Invoke(null, param);
|
||||
if ((bool)res)
|
||||
TestContext.WriteLine($">> Set = OK");
|
||||
else
|
||||
TestContext.WriteLine($">> Set Error = {Win32Error.GetLastError()}");
|
||||
}
|
||||
}
|
||||
|
||||
var id = t.GetInfo<uint>(TOKEN_INFORMATION_CLASS.TokenSessionId);
|
||||
Assert.That(id, Is.Not.Zero);
|
||||
TestContext.WriteLine($"SessId: {id}");
|
||||
|
||||
var ve = t.GetInfo<uint>(TOKEN_INFORMATION_CLASS.TokenVirtualizationEnabled);
|
||||
Assert.That(ve, Is.Zero);
|
||||
TestContext.WriteLine($"VirtEnable: {ve}");
|
||||
|
||||
var et = t.GetInfo<TOKEN_ELEVATION_TYPE>(TOKEN_INFORMATION_CLASS.TokenElevationType);
|
||||
Assert.That(et, Is.Not.Zero);
|
||||
TestContext.WriteLine($"ElevType: {et}");
|
||||
|
||||
var e = t.GetInfo<TOKEN_ELEVATION>(TOKEN_INFORMATION_CLASS.TokenElevation);
|
||||
Assert.That(e, Is.Not.Zero);
|
||||
TestContext.WriteLine($"Elev: {e.TokenIsElevated}");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ImpersonateAnonymousTokenTest()
|
||||
{
|
||||
Assert.That(ImpersonateAnonymousToken(GetCurrentThread()), ResultIs.Successful);
|
||||
Assert.That(RevertToSelf(), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ImpersonateLoggedOnUserTest()
|
||||
{
|
||||
using (var t = SafeHTOKEN.FromProcess(Process.GetCurrentProcess(), TokenAccess.TOKEN_DUPLICATE | TokenAccess.TOKEN_QUERY | TokenAccess.TOKEN_IMPERSONATE))
|
||||
Assert.That(ImpersonateLoggedOnUser(t), ResultIs.Successful);
|
||||
Assert.That(RevertToSelf(), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ImpersonateSelfTest()
|
||||
{
|
||||
Assert.That(ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation), ResultIs.Successful);
|
||||
Assert.That(RevertToSelf(), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InitializeSecurityDescriptorTest()
|
||||
{
|
||||
using (var pSD = new SafePSECURITY_DESCRIPTOR(128))
|
||||
{
|
||||
Assert.That(InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION), ResultIs.Successful);
|
||||
Assert.That(pSD.IsValidSecurityDescriptor, Is.True);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MakeAbsoluteSelfRelativeSDTest()
|
||||
{
|
||||
using (var pSD = AdvApi32Tests.GetSD(AdvApi32Tests.fn))
|
||||
{
|
||||
(SafePSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor, SafePACL pDacl, SafePACL pSacl, SafePSID pOwner, SafePSID pPrimaryGroup) ret = default;
|
||||
Assert.That(() => ret = pSD.MakeAbsolute(), Throws.Nothing);
|
||||
try
|
||||
{
|
||||
SafePSECURITY_DESCRIPTOR newSD = null;
|
||||
Assert.That(() => newSD = new SafePSECURITY_DESCRIPTOR(ret.pAbsoluteSecurityDescriptor, false), Throws.Exception);
|
||||
Assert.That(() => newSD = new SafePSECURITY_DESCRIPTOR(ret.pAbsoluteSecurityDescriptor, true), Throws.Nothing);
|
||||
newSD.Dispose();
|
||||
}
|
||||
finally
|
||||
{
|
||||
ret.pAbsoluteSecurityDescriptor.Dispose();
|
||||
ret.pDacl.Dispose();
|
||||
ret.pSacl.Dispose();
|
||||
ret.pOwner.Dispose();
|
||||
ret.pPrimaryGroup.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void PrivilegeCheckTest()
|
||||
{
|
||||
using (var t = SafeHTOKEN.FromProcess(GetCurrentProcess(), TokenAccess.TOKEN_QUERY))
|
||||
{
|
||||
Assert.That(LookupPrivilegeValue(null, "SeDebugPrivilege", out var luid));
|
||||
var ps = new PRIVILEGE_SET(PrivilegeSetControl.PRIVILEGE_SET_ALL_NECESSARY, luid, PrivilegeAttributes.SE_PRIVILEGE_ENABLED);
|
||||
Assert.That(PrivilegeCheck(t, ps, out var res));
|
||||
Assert.That((uint)ps.Privilege[0].Attributes, Is.Not.Zero);
|
||||
TestContext.WriteLine($"Has {luid}={res}, {ps.Privilege[0].Attributes}");
|
||||
|
||||
Assert.That(LookupPrivilegeValue(null, "SeChangeNotifyPrivilege", out luid));
|
||||
ps = new PRIVILEGE_SET(PrivilegeSetControl.PRIVILEGE_SET_ALL_NECESSARY, new[] { new LUID_AND_ATTRIBUTES(luid, PrivilegeAttributes.SE_PRIVILEGE_ENABLED_BY_DEFAULT), new LUID_AND_ATTRIBUTES(luid, PrivilegeAttributes.SE_PRIVILEGE_ENABLED) });
|
||||
Assert.That(PrivilegeCheck(t, ps, out res));
|
||||
Assert.That((uint)ps.Privilege[0].Attributes, Is.Not.Zero);
|
||||
TestContext.WriteLine($"Has {luid}={res}, {ps.Privilege[0].Attributes}/{ps.Privilege[1].Attributes}");
|
||||
|
||||
Assert.That(LookupPrivilegeValue(null, "SeShutdownPrivilege", out luid));
|
||||
ps = new PRIVILEGE_SET(PrivilegeSetControl.PRIVILEGE_SET_ALL_NECESSARY, luid, PrivilegeAttributes.SE_PRIVILEGE_ENABLED);
|
||||
Assert.That(PrivilegeCheck(t, ps, out res));
|
||||
Assert.That((uint)ps.Privilege[0].Attributes, Is.Not.Zero);
|
||||
TestContext.WriteLine($"Has {luid}={res}, {ps.Privilege[0].Attributes}");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void QuerySecurityAccessMaskTest()
|
||||
{
|
||||
QuerySecurityAccessMask(SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION, out var oMask);
|
||||
Assert.That((uint)oMask, Is.Not.Zero);
|
||||
QuerySecurityAccessMask(SECURITY_INFORMATION.SACL_SECURITY_INFORMATION, out var sMask);
|
||||
Assert.That((uint)sMask, Is.Not.Zero);
|
||||
(oMask, sMask).WriteValues();
|
||||
Assert.That(oMask, Is.Not.EqualTo(sMask));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetAclInformationTest()
|
||||
{
|
||||
using (var pAcl = GetAcl())
|
||||
Assert.That(SetAclInformation(pAcl, new ACL_REVISION_INFORMATION { AclRevision = ACL_REVISION }), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetSecurityAccessMaskTest()
|
||||
{
|
||||
SetSecurityAccessMask(SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION, out var ownMask);
|
||||
SetSecurityAccessMask(SECURITY_INFORMATION.SACL_SECURITY_INFORMATION, out var saclMask);
|
||||
Assert.That((uint)saclMask, Is.Not.Zero.And.Not.EqualTo((uint)ownMask));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetSecurityDescriptorControlTest()
|
||||
{
|
||||
using (var pSD = new SafePSECURITY_DESCRIPTOR(48))
|
||||
Assert.That(SetSecurityDescriptorControl(pSD, SECURITY_DESCRIPTOR_CONTROL.SE_DACL_PRESENT, SECURITY_DESCRIPTOR_CONTROL.SE_DACL_PRESENT), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetSecurityDescriptorDaclTest()
|
||||
{
|
||||
using (var pSD = new SafePSECURITY_DESCRIPTOR(256))
|
||||
using (var pAcl = new SafePACL(128))
|
||||
{
|
||||
Assert.That(AddAccessAllowedAce(pAcl, ACL_REVISION, ACCESS_MASK.GENERIC_ALL, SafePSID.Everyone), ResultIs.Successful);
|
||||
Assert.That(SetSecurityDescriptorDacl(pSD, true, pAcl, false), ResultIs.Successful);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetSecurityDescriptorGroupTest()
|
||||
{
|
||||
using (var pSD = new SafePSECURITY_DESCRIPTOR(256))
|
||||
{
|
||||
Assert.That(SetSecurityDescriptorGroup(pSD, SafePSID.Everyone, false), ResultIs.Successful);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetSecurityDescriptorSaclTest()
|
||||
{
|
||||
using (var pSD = new SafePSECURITY_DESCRIPTOR(256))
|
||||
using (var pAcl = new SafePACL(128))
|
||||
{
|
||||
Assert.That(AddAuditAccessAce(pAcl, ACL_REVISION, ACCESS_MASK.GENERIC_ALL, SafePSID.Everyone, false, false), ResultIs.Successful);
|
||||
Assert.That(SetSecurityDescriptorSacl(pSD, true, pAcl, false), ResultIs.Successful);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetSecurityDescriptorOwnerTest()
|
||||
{
|
||||
using (var pSD = new SafePSECURITY_DESCRIPTOR(256))
|
||||
{
|
||||
Assert.That(SetSecurityDescriptorOwner(pSD, SafePSID.Everyone, false), ResultIs.Successful);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetSecurityDescriptorRMControlTest()
|
||||
{
|
||||
using (var pSD = new SafePSECURITY_DESCRIPTOR(256))
|
||||
Assert.That(SetSecurityDescriptorRMControl(pSD, 0), ResultIs.Successful);
|
||||
}
|
||||
|
||||
private SafePACL GetAcl() => new SafePACL(256);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue