protected function _lookupShadow($dn)
{
/* Init the return array. */
$lookupshadow = array('shadowlastchange' => false, 'shadowmin' => false, 'shadowmax' => false, 'shadowwarning' => false);
/* According to LDAP standard, to read operational attributes, you
* must request them explicitly. Attributes involved in password
* expiration policy:
* pwdlastset: Active Directory
* shadow*: shadowUser schema
* passwordexpirationtime: Sun and Fedora Directory Server */
try {
$result = $this->_ldap->search(null, '(objectClass=*)', array('attributes' => array('pwdlastset', 'shadowmax', 'shadowmin', 'shadowlastchange', 'shadowwarning', 'passwordexpirationtime'), 'scope' => 'base'));
} catch (Horde_Ldap_Exception $e) {
return $lookupshadow;
}
if (!$result) {
return $lookupshadow;
}
$info = reset($result);
// TODO: 'ad'?
if (!empty($this->_params['ad'])) {
if (isset($info['pwdlastset'][0])) {
/* Active Directory handles timestamps a bit differently.
* Convert the timestamp to a UNIX timestamp. */
$lookupshadow['shadowlastchange'] = floor(($info['pwdlastset'][0] / 10000000 - 11644406783) / 86400) - 1;
/* Password expiry attributes are in a policy. We cannot
* read them so use the Horde config. */
$lookupshadow['shadowwarning'] = $this->_params['warnage'];
$lookupshadow['shadowmin'] = $this->_params['minage'];
$lookupshadow['shadowmax'] = $this->_params['maxage'];
}
} elseif (isset($info['passwordexpirationtime'][0])) {
/* Sun/Fedora Directory Server uses a special attribute
* passwordexpirationtime. It has precedence over shadow*
* because it actually locks the expired password at the LDAP
* server level. The correct way to check expiration should
* be using LDAP controls, unfortunately PHP doesn't support
* controls on bind() responses. */
$ldaptimepattern = "/([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})Z/";
if (preg_match($ldaptimepattern, $info['passwordexpirationtime'][0], $regs)) {
/* Sun/Fedora Directory Server return expiration time, not
* last change time. We emulate the behaviour taking it
* back to maxage. */
$lookupshadow['shadowlastchange'] = floor(mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]) / 86400) - $this->_params['maxage'];
/* Password expiry attributes are in not accessible policy
* entry. */
$lookupshadow['shadowwarning'] = $this->_params['warnage'];
$lookupshadow['shadowmin'] = $this->_params['minage'];
$lookupshadow['shadowmax'] = $this->_params['maxage'];
} elseif ($this->_logger) {
$this->_logger->log('Wrong time format: ' . $info['passwordexpirationtime'][0], 'ERR');
}
} else {
if (isset($info['shadowmax'][0])) {
$lookupshadow['shadowmax'] = $info['shadowmax'][0];
}
if (isset($info['shadowmin'][0])) {
$lookupshadow['shadowmin'] = $info['shadowmin'][0];
}
if (isset($info['shadowlastchange'][0])) {
$lookupshadow['shadowlastchange'] = $info['shadowlastchange'][0];
}
if (isset($info['shadowwarning'][0])) {
$lookupshadow['shadowwarning'] = $info['shadowwarning'][0];
}
}
return $lookupshadow;
}