Приведение свойства ActiveDirectory pwdLastSet без использования ActiveD
Хорошо. Поэтому я пытаюсь найти способ избежать включения ActiveD в мой проект, потому что у меня возникают проблемы с отображением dll в установщике. Единственная причина, по которой он есть, - это использовать pwdLastSet как LongInteger.
Я нашел недокументированную альтернативу. При тестировании он либо не работает, либо выключен на 429,49673 секунды. Я не уверен, почему, у кого-нибудь есть идеи? (20/49 человек, которых я тестировал, имеют 429,49673 секунды).
ОБНОВЛЕНИЕ: похоже, что это происходит, когда LowPart отрицательный.
Код:
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);
}
}
Рекомендации:
- Активная библиотека типов DS
- System.DirectoryServices
2 ответа
Вам нужно будет перевести AD Long Integer следующим образом, и вам больше не понадобятся ActiveD:
long pwdLastSet = CovertADSLargeIntegerToInt64(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;
}
Что не так с этим кодом? Должно работать нормально:
SearchResult sr = ds.FindOne();
hacked = DateTime.FromFileTime((long)sr.Properties["pwdLastSet"][0]);