0

I can't seem to return any meaningful search results when I perform a directory search for a BitLocker recovery key.

DirectoryEntry entry = new DirectoryEntry("LDAP://OU=MYOU,DC=MYDC", adminUsername,
            adminPassword);
        entry.Username = AdminInformation.AdminUsername;
        entry.Password = AdminInformation.AdminPassword;

        DirectorySearcher search = new DirectorySearcher(entry);
        search.PropertiesToLoad.Add("msFVE-RecoveryPassword");
        search.Filter = $"(&(cn={chosenComputer}))";

        foreach (SearchResult res in result)
        {
            textBoxBitLockerKey.Text = (res.Properties["msFVE-RecoveryPassword"][0].ToString());
        }

Basically I populated a list with computers that would contain the BitLocker key (we only have laptops that use BitLocker in our organization). After the user selects the laptop then the associated BitLocker key should be populated in a text box that they can copy or print, but everytime I try to grab that key from the selected computer, I keep getting an out of bounds exception. I've been using DirectorySearcher to find other properties such as a user account or computer name, but this is giving me trouble. I understand what the error is I just don't know what is causing it and I can't seem to find any other answers that quite cover this topic. Any input is appreciated.

Here's the exception: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index.

Upon further investigation, it appears that the directorysearcher is only searching for properties that encapsulate the msFVE-RecoveryInformation property. If i try to add a filter based on a chosen computer name, it will not provide a SearchResult property with an actual value. If I try to set the filter based on "cn", for example, it returns the GUID for the BitLocker key.

bass
  • 3
  • 4
  • 3
    Have you verified (with the debugger) that `res.Properties` contains the values you expect? Does `res.Properties["msFVE-RecoveryPassword"]` exist and if so, what is its value? – user247702 Dec 03 '18 at 16:07
  • please, if you mention an exception, include the complete exception information, especially on which source code line it is thrown, and its call stack. it is likely that @stijn is right and just not all items in `result` have that attribute, so the properties indexer or `[0]` indexer would throw. – Cee McSharpface Dec 03 '18 at 16:09
  • as @Stijin pointed out, you need to check `res.Properties["msFVE-RecoveryPassword"][0] != null` – Nilesh Dec 03 '18 at 16:13
  • 1
    @Nilesh if the array doesn't contain any members that will still throw the "Out Of Range" exception – stuartd Dec 03 '18 at 16:14

1 Answers1

1

Whenever I query a non-mandatory property from AD by LDAP (a property, that is not necessarily present on all objects the DirectorySearcher finds), I use this pattern:

const string propertykey = "msFVE-RecoveryPassword";
if (res.Properties.Contains(propertykey))
{
    string value = res.Properties[propertykey][0].ToString();
}

Using the [0] index is generally considered safe on single-values properties; you may want to add a check for Count > 0 if you are dealing with a multi-value property (or use an enumerator).

Cee McSharpface
  • 8,493
  • 3
  • 36
  • 77
  • -dlatikay I did check for a count and got a count of 1 for the search. I also checked to make sure the searchresult did not contain a null value. It appears after using your check, it does not throw that exception, but there is still no value. Is that a valid property to use for DirectorySearcher? Everywhere I've looked that is what I've found to be the correct property to load for a BitLocker key. – bass Dec 03 '18 at 16:34
  • yes the attribute exists, and you spelled it correctly according to documentation. [this thread](https://social.technet.microsoft.com/Forums/en-US/2e584363-d548-40e2-b39b-e557d8224a72/msfverecoverypassword-with-getadobject?forum=winserversecurity) suggests that there is a permission required to read the information, that a plain domain user would not have. Impersonate an account with sufficient privileges. – Cee McSharpface Dec 03 '18 at 16:53
  • I am using my domain admin credentials (which for this application are used to "login" to the application). Isn't that what the credentials used in the directoryentry constructor are for? – bass Dec 03 '18 at 17:13
  • right. I don't think that this is a problem with the code you wrote. rather some underdocumented behavior in LDAP. I'd suggest to try experimenting with some visual LDAP explorer app and once you figured out which objects have the value and which haven't, model your C# version around the queries you discovered using the tool. – Cee McSharpface Dec 03 '18 at 22:03
  • Thanks for your help! I'm glad we got to the bottom of it. – bass Dec 05 '18 at 14:52