【问题标题】:Casting ActiveDirectory pwdLastSet property without using ActiveDs在不使用 ActiveD 的情况下转换 ActiveDirectory pwdLastSet 属性
【发布时间】:2012-03-06 21:44:56
【问题描述】:

好的。所以我试图找到一种方法来避免在我的项目中包含 ActiveD,因为我无法让 dll 出现在安装程序中。拥有它的唯一原因是将 pwdLastSet 转换为 LongInteger。

我找到了一个未记录的替代方案。测试时,它要么死机,要么关机 429.49673 秒。我不知道为什么,有人知道吗? (我测试的 20/49 人是 429.49673 秒)。

UPDATE:看起来好像是 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);
    }
}

参考文献:

  • Active DS 类型库
  • System.DirectoryServices

【问题讨论】:

  • 超过或低于 429 秒?你把它比作什么?
  • 如果 LowPart 为负数,那么如果您使用获取它的标准方法选择它,那么我正在做的黑客方式是在您获得它的时间之后 429.49673 秒。如果 LowPart 是肯定的,那么被破解的方法似乎与标准方法的时间相同。

标签: c# active-directory


【解决方案1】:

您需要像这样翻译 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;
}

【讨论】:

  • 这不起作用。 highpart 抛出异常。 System.MissingMethodException 未处理 HResult=-2146233070 消息=未找到方法“System.Int64.HighPart”。来源=mscorlib
  • @softwareisfun,也许相关:我从这里stackoverflow.com/questions/8703533/… 得到了与 OP 相同的 COM 异常。当我尝试使用 int64 将 ["pwdLastSet"] 设置为 0 时...将值转换为 int32 w/ Convert.ToInt32(int64_value) 并设置属性值。为此损失了 3 个小时:p
【解决方案2】:

这段代码有什么问题?它应该可以正常工作:

    SearchResult sr = ds.FindOne(); 
    hacked = DateTime.FromFileTime((long)sr.Properties["pwdLastSet"][0]); 

【讨论】:

  • 它有效。混淆可能来自于调用DirectoryEntry 的属性而不是SearchResult。如果你在DirectoryEntry 上使用Properties["pwdLastSet"],那么你会得到 InvalidCastException。
猜你喜欢
  • 2015-07-22
  • 2014-09-27
  • 2013-11-24
  • 2022-01-21
  • 1970-01-01
  • 2013-12-08
  • 1970-01-01
  • 2014-12-04
  • 2018-11-24
相关资源
最近更新 更多