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:
- Active DS Type Library
- System.DirectoryServices