Ok. So I'm trying to find a way to avoid including ActiveDs in my project because I'm having trouble getting the dll to show up in the installer. The only reason to have it is to cast the pwdLastSet as a LongInteger.
I found an undocumented alternative. When testing it, it is either dead on or 429.49673 seconds off. I'm not sure why, does anybody have any idea? (20/49 people that i tested are 429.49673 seconds off).
UPDATE: It looks like it happens when the LowPart is negative.
Code:
private static string DateTest() {
return DateTest(Environment.UserName);
}
private static string DateTest(string userName) {
userName = userName.Trim();
DateTime hacked, normal;
using (DirectorySearcher ds = new DirectorySearcher()) {
ds.SearchScope = SearchScope.Subtree;
ds.PropertiesToLoad.Add("distinguishedName");
ds.PropertiesToLoad.Add("pwdLastSet");
ds.PageSize = 1;
ds.ServerPageTimeLimit = TimeSpan.FromSeconds(2);
ds.Filter = string.Format("(&(objectCategory=user)(sAMAccountName={0}))", userName);
SearchResult sr = ds.FindOne();
hacked = DateTime.FromFileTime((long)sr.Properties["pwdLastSet"][0]);
using (DirectoryEntry user = sr.GetDirectoryEntry()) {
var value = user.Properties["pwdLastSet"][0] as ActiveDs.LargeInteger;
var longValue = (((long)value.HighPart) << 32) + (long)value.LowPart;
normal = DateTime.FromFileTime(longValue);
}
}
return string.Format("{3} - Difference: {0:0.0} seconds. Established Method returns: {1}. Hacked method returns: {2}",
hacked.Subtract(normal).TotalSeconds, normal, hacked, userName);
}
}
References:
You'll need to translate the AD Long Integer like this and you shouldn't need ActiveDs anymore:
long pwdLastSet = ConvertADSLargeIntegerToInt64(oUser.Properties["pwdLastSet"].Value);
public static Int64 ConvertADSLargeIntegerToInt64(object adsLargeInteger)
{
var highPart = (Int32)adsLargeInteger.GetType().InvokeMember("HighPart", System.Reflection.BindingFlags.GetProperty, null, adsLargeInteger, null);
var lowPart = (Int32)adsLargeInteger.GetType().InvokeMember("LowPart", System.Reflection.BindingFlags.GetProperty, null, adsLargeInteger, null);
return highPart * ((Int64)UInt32.MaxValue + 1) + lowPart;
}
What is wrong with this code? It should work fine:
SearchResult sr = ds.FindOne();
hacked = DateTime.FromFileTime((long)sr.Properties["pwdLastSet"][0]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With