Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting ActiveDirectory pwdLastSet property without using ActiveDs

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
like image 644
colinbashbash Avatar asked Dec 09 '22 02:12

colinbashbash


2 Answers

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;
}
like image 187
Brett Veenstra Avatar answered May 10 '23 10:05

Brett Veenstra


What is wrong with this code? It should work fine:

    SearchResult sr = ds.FindOne(); 
    hacked = DateTime.FromFileTime((long)sr.Properties["pwdLastSet"][0]); 
like image 23
Brian Desmond Avatar answered May 10 '23 10:05

Brian Desmond