-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
01189bb
commit 0089492
Showing
1 changed file
with
174 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
using System.Collections.Generic; | ||
using System.DirectoryServices; | ||
using System.Linq; | ||
using System.Runtime.Serialization; | ||
using System.Security.AccessControl; | ||
using System.Security.Principal; | ||
using System.Threading.Tasks; | ||
|
@@ -919,41 +920,7 @@ public void LDAPPropertyProcessor_ReadSidPrincipal_GetPrincipal() | |
ObjectType = Label.User | ||
}, principal); | ||
} | ||
|
||
// [Fact] | ||
// public void LDAPPropertyProcessor_ReadAllowedToActPrincipals_ReturnsPopulatedList() | ||
// { | ||
// var mock = new MockSearchResultEntry("CN\u003dWIN10,OU\u003dTestOU,DC\u003dtestlab,DC\u003dlocal", | ||
// new Dictionary<string, object> | ||
// { | ||
// { | ||
// "msds-allowedtoactonbehalfofotheridentity", | ||
// Helpers.B64ToBytes("AQUAAAAAAAUVAAAAIE+Qun9GhKV2SBaQUQQAAA==") | ||
// } | ||
// }, "S-1-5-21-3130019616-2776909439-2417379446-1101", Label.Computer); | ||
// | ||
// var mockUtils = new Mock<MockLDAPUtils>(); | ||
// var mockSecurityDescriptor = new Mock<ActiveDirectorySecurityDescriptor>(); | ||
// var mockRuleDescriptor = new Mock<ActiveDirectoryRuleDescriptor>(MockBehavior.Loose); | ||
// mockRuleDescriptor.Setup(m => m.IdentityReference()).Returns("S-1-5-21-3130019616-2776909439-2417379446-1105"); | ||
// | ||
// mockUtils.Setup(x => x.MakeSecurityDescriptor()).Returns(mockSecurityDescriptor.Object); | ||
// mockSecurityDescriptor.Setup(m => m.GetAccessRules( | ||
// It.IsAny<bool>(), | ||
// It.IsAny<bool>(), | ||
// It.IsAny<Type>())) | ||
// .Returns(new List<ActiveDirectoryRuleDescriptor> | ||
// { | ||
// mockRuleDescriptor.Object | ||
// }); | ||
// | ||
// var processor = new LDAPPropertyProcessor(mockUtils.Object); | ||
// var principals = processor.ReadAllowedToActPrincipals(mock); | ||
// | ||
// Assert.Contains("S-1-5-21-3130019616-2776909439-2417379446-1105", principals.Select(p => p.ObjectIdentifier)); | ||
// Assert.Single(principals); | ||
// } | ||
|
||
|
||
[Fact] | ||
public void LDAPPropertyProcessor_ReadSmsaPrincipals_ReturnsPopulatedList() | ||
{ | ||
|
@@ -977,87 +944,213 @@ public void LDAPPropertyProcessor_ReadSmsaPrincipals_ReturnsPopulatedList() | |
Assert.Single(sids, "S-1-5-21-3130019616-2776909439-2417379446-502"); | ||
} | ||
|
||
public static IEnumerable<object[]> ServicePrincipalNamesData => | ||
public static IEnumerable<object[]> UserAccessControlData => | ||
new List<object[]> | ||
{ | ||
new object[] | ||
{ | ||
new[] | ||
{ | ||
"WSMAN/WIN10", | ||
"WSMAN/WIN10.testlab.local", | ||
"RestrictedKrbHost/WIN10", | ||
"HOST/WIN10", | ||
"RestrictedKrbHost/WIN10.testlab.local", | ||
"HOST/WIN10.testlab.local" | ||
}, | ||
true | ||
((int)(UacFlags.NotDelegated | UacFlags.AccountDisable)).ToString(), | ||
new Dictionary<string, bool> {{ "sensitive", true }, { "enabled", false }} | ||
}, | ||
new object[] | ||
{ | ||
new string[] { }, | ||
false | ||
} | ||
((int)(UacFlags.ServerTrustAccount | UacFlags.PasswordNotRequired | UacFlags.TrustedForDelegation)).ToString(), | ||
new Dictionary<string, bool> {{ "isdc", true }, { "passwordnotreqd", true }, { "unconstraineddelegation", true }, { "enabled", true }} | ||
}, | ||
}; | ||
|
||
[Theory] | ||
[MemberData(nameof(ServicePrincipalNamesData))] | ||
public void LDAPPropertyProcessor_GetProperties_ServicePrincipalNames(object property, bool expectedHasspn) | ||
[MemberData(nameof(UserAccessControlData))] | ||
public void LDAPPropertyProcessor_GetProperties_UserAccountControl(string property, Dictionary<string, bool> expectedFlags) | ||
{ | ||
var mock = new MockSearchResultEntry("CN\u003dWIN10,OU\u003dTestOU,DC\u003dtestlab,DC\u003dlocal", | ||
new Dictionary<string, object> | ||
{ | ||
{ | ||
"serviceprincipalname", property | ||
"useraccountcontrol", property | ||
} | ||
}, "S-1-5-21-3130019616-2776909439-2417379446-1101", Label.Computer); | ||
|
||
var props = LDAPPropertyProcessor.GetProperties(LDAPProperties.ServicePrincipalNames, mock); | ||
}, "S-1-5-21-3130019616-2776909439-2417379446-1101", Label.User); | ||
|
||
Assert.Single(props.Keys, "serviceprincipalnames"); | ||
var propPrincipals = props["serviceprincipalnames"] as string[]; | ||
foreach (var principal in mock.GetArrayProperty("serviceprincipalname")) | ||
var props = LDAPPropertyProcessor.GetProperties(LDAPProperties.UserAccountControl, mock); | ||
|
||
foreach (var flag in props) | ||
{ | ||
Assert.Single(propPrincipals, principal); | ||
var expectedFlag = expectedFlags.ContainsKey(flag.Key) && expectedFlags[flag.Key]; | ||
Assert.Equal(expectedFlag, (bool)flag.Value); | ||
} | ||
|
||
Assert.Single(props.Keys, "hasspn"); | ||
Assert.Equal(expectedHasspn, (bool)props["hasspn"]); | ||
} | ||
|
||
public static IEnumerable<object[]> UserAccessControlData => | ||
public static IEnumerable<object[]> SimplePropertyTestData => | ||
new List<object[]> | ||
{ | ||
new object[] | ||
{ | ||
((int)(UacFlags.NotDelegated | UacFlags.AccountDisable)).ToString(), | ||
new Dictionary<string, bool> {{ "sensitive", true }, { "enabled", false }} | ||
LDAPProperties.Description, | ||
new Dictionary<string, object> {{ LDAPProperties.Description, "test desc" }}, | ||
new Dictionary<string, object> {{ "description", "test desc" }}, | ||
}, | ||
new object[] | ||
{ | ||
((int)(UacFlags.ServerTrustAccount | UacFlags.PasswordNotRequired | UacFlags.TrustedForDelegation)).ToString(), | ||
new Dictionary<string, bool> {{ "isdc", true }, { "passwordnotreqd", true }, { "unconstraineddelegation", true }, { "enabled", true }} | ||
LDAPProperties.DomainFunctionalLevel, | ||
new Dictionary<string, object> {{ LDAPProperties.DomainFunctionalLevel, "1" }}, | ||
new Dictionary<string, object> {{ "functionallevel", "2003 Interim" }}, | ||
}, | ||
new object[] | ||
{ | ||
LDAPProperties.DomainFunctionalLevel, | ||
new Dictionary<string, object> {{ LDAPProperties.DomainFunctionalLevel, "nope" }}, | ||
new Dictionary<string, object> {{ "functionallevel", "Unknown" }}, | ||
}, | ||
new object[] | ||
{ | ||
LDAPProperties.GPCFileSYSPath, | ||
new Dictionary<string, object> {{ LDAPProperties.GPCFileSYSPath, "/test/testy/test" }}, | ||
new Dictionary<string, object> {{ "gpcpath", "/TEST/TESTY/TEST" }}, | ||
}, | ||
new object[] | ||
{ | ||
LDAPProperties.DisplayName, | ||
new Dictionary<string, object> {{ LDAPProperties.DisplayName, "one test of a display name" }}, | ||
new Dictionary<string, object> {{ "displayname", "one test of a display name" }}, | ||
}, | ||
new object[] | ||
{ | ||
LDAPProperties.Email, | ||
new Dictionary<string, object> {{ LDAPProperties.Email, "[email protected]" }}, | ||
new Dictionary<string, object> {{ "email", "[email protected]" }}, | ||
}, | ||
new object[] | ||
{ | ||
LDAPProperties.Title, | ||
new Dictionary<string, object> {{ LDAPProperties.Title, "Test Title" }}, | ||
new Dictionary<string, object> {{ "title", "Test Title" }}, | ||
}, | ||
new object[] | ||
{ | ||
LDAPProperties.HomeDirectory, | ||
new Dictionary<string, object> {{ LDAPProperties.HomeDirectory, "/users/test" }}, | ||
new Dictionary<string, object> {{ "homedirectory", "/users/test" }}, | ||
}, | ||
new object[] | ||
{ | ||
LDAPProperties.UserPassword, | ||
new Dictionary<string, object> {{ LDAPProperties.UserPassword, "1234" }}, | ||
new Dictionary<string, object> {{ "userpassword", "1234" }}, | ||
}, | ||
new object[] | ||
{ | ||
LDAPProperties.UnixUserPassword, | ||
new Dictionary<string, object> {{ LDAPProperties.UnixUserPassword, "1234" }}, | ||
new Dictionary<string, object> {{ "unixpassword", "1234" }}, | ||
}, | ||
new object[] | ||
{ | ||
LDAPProperties.UnicodePassword, | ||
new Dictionary<string, object> {{ LDAPProperties.UnicodePassword, "1234" }}, | ||
new Dictionary<string, object> {{ "unicodepassword", "1234" }}, | ||
}, | ||
new object[] | ||
{ | ||
LDAPProperties.MsSFU30Password, | ||
new Dictionary<string, object> {{ LDAPProperties.MsSFU30Password, "1234" }}, | ||
new Dictionary<string, object> {{ "sfupassword", "1234" }}, | ||
}, | ||
new object[] | ||
{ | ||
LDAPProperties.ScriptPath, | ||
new Dictionary<string, object> {{ LDAPProperties.ScriptPath, "/scripts" }}, | ||
new Dictionary<string, object> {{ "logonscript", "/scripts" }}, | ||
}, | ||
new object[] | ||
{ | ||
LDAPProperties.AdminCount, | ||
new Dictionary<string, object> {{ LDAPProperties.AdminCount, "1" }}, | ||
new Dictionary<string, object> {{ "admincount", true }}, | ||
}, | ||
new object[] | ||
{ | ||
LDAPProperties.AdminCount, | ||
new Dictionary<string, object> {{ LDAPProperties.AdminCount, "0" }}, | ||
new Dictionary<string, object> {{ "admincount", false }}, | ||
}, | ||
new object[] | ||
{ | ||
LDAPProperties.AdminCount, | ||
new Dictionary<string, object> {{ LDAPProperties.AdminCount, "nope" }}, | ||
new Dictionary<string, object> {{ "admincount", false }}, | ||
}, | ||
new object[] | ||
{ | ||
LDAPProperties.OperatingSystem, | ||
new Dictionary<string, object> {{ LDAPProperties.OperatingSystem, "TestOS" }, { LDAPProperties.ServicePack, "SP1" }}, | ||
new Dictionary<string, object> {{ "operatingsystem", "TestOS SP1" }}, | ||
}, | ||
new object[] | ||
{ | ||
LDAPProperties.AllowedToDelegateTo, | ||
new Dictionary<string, object> {{ LDAPProperties.AllowedToDelegateTo, new[] { "test1", "test2", "test3" } }}, | ||
new Dictionary<string, object> {{ "allowedtodelegate", new[] { "test1", "test2", "test3" } }}, | ||
}, | ||
new object[] | ||
{ | ||
LDAPProperties.ServicePrincipalNames, | ||
new Dictionary<string, object> {{ | ||
LDAPProperties.ServicePrincipalNames, | ||
new[] | ||
{ | ||
"WSMAN/WIN10", | ||
"WSMAN/WIN10.testlab.local", | ||
"RestrictedKrbHost/WIN10", | ||
"HOST/WIN10", | ||
"RestrictedKrbHost/WIN10.testlab.local", | ||
"HOST/WIN10.testlab.local", | ||
} | ||
}}, | ||
new Dictionary<string, object > {{ | ||
"serviceprincipalnames", | ||
new[] | ||
{ | ||
"WSMAN/WIN10", | ||
"WSMAN/WIN10.testlab.local", | ||
"RestrictedKrbHost/WIN10", | ||
"HOST/WIN10", | ||
"RestrictedKrbHost/WIN10.testlab.local", | ||
"HOST/WIN10.testlab.local", | ||
}}, | ||
{ "hasspn", true } | ||
} | ||
}, | ||
new object[] | ||
{ | ||
LDAPProperties.ServicePrincipalNames, | ||
new Dictionary<string, object> {{ | ||
LDAPProperties.ServicePrincipalNames, | ||
new string[] {} | ||
}}, | ||
new Dictionary<string, object > {{ | ||
"serviceprincipalnames", | ||
new string[] {} | ||
}, | ||
{ "hasspn", false } | ||
} | ||
}, | ||
}; | ||
|
||
[Theory] | ||
[MemberData(nameof(UserAccessControlData))] | ||
public void LDAPPropertyProcessor_GetProperties_UserAccountControl(string property, Dictionary<string, bool> expectedFlags) | ||
[MemberData(nameof(SimplePropertyTestData))] | ||
public void LDAPPropertyProcessor_GetProperties_SimplePropertyTest(string ldapPropertyName, Dictionary<string, object> testInput, Dictionary<string, object> expectedOutput) | ||
{ | ||
var mock = new MockSearchResultEntry("CN\u003dWIN10,OU\u003dTestOU,DC\u003dtestlab,DC\u003dlocal", | ||
new Dictionary<string, object> | ||
{ | ||
{ | ||
"useraccountcontrol", property | ||
} | ||
}, "S-1-5-21-3130019616-2776909439-2417379446-1101", Label.User); | ||
testInput, | ||
"S-1-5-21-3130019616-2776909439-2417379446-1101", Label.User); | ||
|
||
var props = LDAPPropertyProcessor.GetProperties(LDAPProperties.UserAccountControl, mock); | ||
var resolvedProps = LDAPPropertyProcessor.GetProperties(ldapPropertyName, mock); | ||
|
||
foreach (var flag in props) | ||
Assert.Equal(resolvedProps.Count, expectedOutput.Count); | ||
foreach (var expected in expectedOutput) | ||
{ | ||
var expectedFlag = expectedFlags.ContainsKey(flag.Key) && expectedFlags[flag.Key]; | ||
Assert.Equal(expectedFlag, (bool)flag.Value); | ||
Assert.Single(resolvedProps.Keys, expected.Key); | ||
Assert.Equal(expected.Value, resolvedProps[expected.Key]); | ||
} | ||
} | ||
} | ||
|