1

Is there a way with the PHP LDAP extension to retrieve AD attributes/properties that are not returned by default?

Specifically, I am trying to retrieve the lockedOut property. This one is not retrieved by default when you use ldap_get_attributes. In PowerShell, you have to specify the property in order to retrieve it:

Get-AdUser -Identity foo -Properties LockedOut | Select LockedOut

But trying to specify the attribute the same way with PHP LDAP does not seem to work.

$result = ldap_search($conn, $dn, "cn=foo", ["lockedOut"]);
if ($result === false) {
    // Handling error...
}
$count = ldap_count_entries($conn, $result);
if ($count !== 1) {
    // Handling error...
}
$entry = ldap_first_entry($conn, $result);

// This array does not contain the expected "lockedOut" attribute
$attr = ldap_get_attributes($conn, $entry);

// No array returned but false (error)
$value = ldap_get_values($conn, $entry, "lockedOut")

I feel like those non default properties are not retrievable with PHP LDAP (property != attribute).

kagmole
  • 2,005
  • 2
  • 12
  • 27

2 Answers2

1

I don't know about the lockedOut property but one commenter on PHP manual page managed to fetch a few other non-standard or operational attributes such as create and modify timestamps using the below method. Maybe, you can try adding lockedOut to that list of attributes and achieve some success with this method too?

   $conn = $ds;
   $attrs = array( 'creatorsname', 'createtimestamp', 'modifiersname',
         'structuralObjectClass', 'entryUUID',  'modifytimestamp',
         'subschemaSubentry', 'hasSubordinates', '+' );
   $search = @ldap_read( $conn, $dn, '(objectClass=*)', $attrs, 0, 0, 0, $deref );

As another comment on the manual page suggests, you can also try looping through all entries until you find the lockedOut, this is another option:

$entry = ldap_first_entry($ds, $sr);
write_attr($entry,$ds);
for ($i = 0; $i < $n_entries; $i++){
   $entry = ldap_next_entry($ds, $entry);
   write_attr($entry,$ds);
}

Edit

As discussed, also refer to this answer.

If you just want to know if the user is locked out, you can fetch lockoutTime instead and check its value. A zero or unset value for this means the user isn't locked out.

Prahlad Yeri
  • 3,567
  • 4
  • 25
  • 55
  • Thank you for your help. Sadly the first method is unable to retrieve the `lockedOut` attribute. The second methods returns default attributes only (you forgot the `write_attr` function from the comment). – kagmole Jan 13 '23 at 08:30
  • 1
    @kagmole Also refer to [this](https://stackoverflow.com/questions/11795294/detect-if-an-active-directory-user-account-is-locked-using-ldap-in-python). If you just want to know if the user is locked out, you can fetch `lockoutTime` instead and check its value. A zero or unset value for this means the user isn't locked out. – Prahlad Yeri Jan 13 '23 at 08:44
  • I was actually going to post it as a workround answer, it seems to work well. If you want to post an answer you can do it. Otherwise I will post it. – kagmole Jan 13 '23 at 08:47
  • No worries, go ahead and post it. I'll just edit my existing answer and make a note of it. – Prahlad Yeri Jan 13 '23 at 08:47
1

There is a default attribute that does the job as a workaround: lockoutTime.
It seems to work this way:

  • Account never locked: lockoutTime = <not set>
  • Account locked in the past, but now unlocked: lockoutTime = 0
  • Account locked: lockoutTime = 1+
    (= MS file time; amount of 100 nanoseconds since 1601-01-01 UTC)

The workaround code:

$result = ldap_search($conn, $dn, "cn=foo", ["lockoutTime"]);
if ($result === false) {
    // Handling error...
}
$count = ldap_count_entries($conn, $result);
if ($count !== 1) {
    // Handling error...
}
$entry = ldap_first_entry($conn, $result);
$attr = ldap_get_attributes($conn, $entry);

$rawLockoutTime = $attr["lockouttime"] ?? null;
$isLockedOut = $rawLockoutTime !== null && $rawLockoutTime[0] !== "0";

A reference about it on a post for the Python LDAP.

kagmole
  • 2,005
  • 2
  • 12
  • 27