Wednesday, January 23, 2013

Enforcing Active Directory password history when resetting passwords using PHP

The code:

$ctrl1 = array(
    // LDAP_SERVER_POLICY_HINTS_OID for Windows 2012 and above
    "oid" => "1.2.840.113556.1.4.2239",
    "value" => sprintf("%c%c%c%c%c", 48, 3, 2, 1, 1));
$ctrl2 = array(
    // LDAP_SERVER_POLICY_HINTS_DEPRECATED_OID for Windows 2008 R2 SP1 and above
    "oid" => "1.2.840.113556.1.4.2066",
    "value" => sprintf("%c%c%c%c%c", 48, 3, 2, 1, 1));
if (!ldap_set_option($ds, LDAP_OPT_SERVER_CONTROLS, array($ctrl1, $ctrl2))) {
    error_log("ERROR: Failed to set server controls");
}

$result = ldap_mod_replace($ds, $dn, $entry);
...


Details:

There are a couple of ways to reset Active Directory passwords using LDAP:
  1. A delete operation on the unicodePwd attribute immediately followed by an add, which is a password change

  2. A modification of the unicodePwd attribute, which is considered an administrative password reset
When doing the latter, password history requirements may not be enforced. Apparently this is expected behavior. The solution is a server control:
  1. First, the control must be available on the server. It's present in Windows Server 2008 R2 Service Pack 1 and above. It can also be installed in 2008 R2 using this hotfix: http://support.microsoft.com/?id=2386717

  2. Next, the client must use the control to tell the AD server to enforce password history requirements.
If you happen to be doing this in PHP, the solution for the second part is the code I've posted. The tricky part was to get the BER encoding for the value correct.

I put both controls (the new one as well as the deprecated one) in my code and also didn't set the iscritical flag (which defaults to false) in order to make the code as flexible as possible.

In case you're looking to implement a solution to reset AD passwords using PHP, you may find these helpful:

Tuesday, January 22, 2013

RHEL 6 kickstart maps first hard drive to /dev/sdc

I was installing RHEL 6 on a Dell PowerEdge R610, and for some strange reason the first drive was mounted as /dev/sdc instead of /dev/sda. I saw someone else had the same issue on CentOS 6:

https://www.centos.org/modules/newbb/viewtopic.php?topic_id=36632

The solution: disable the iDRAC virtual media. I had to press Ctrl-E to get into the DRAC menu when it prompted me during the boot process, then I had to arrow down to Virtual Media Configuration and change the Virtual media setting from attached to detached.

Or from the iDRAC web interface: System --> Console/Media --> Configuration --> Virtual media --> Status --> change to Detach --> Apply

Now the first drive is mapped as /dev/sda again.

Wednesday, January 9, 2013

Dell DSET: Failed to gather Chassis/Storage data.

Trying to run Dell's DSET tool on Linux (RHEL), if it fails with the following error after entering the root password:

Failed to gather Chassis/Storage data. Check the IP Address, credentials and namespace.

Make sure you entered the root password correctly. Reset the root password if you're not 100% sure.