(Theoretically) allow users to change their passwords.

I cannot test this... but I hope it works :-)
This commit is contained in:
Craig Andrews 2009-11-17 23:22:19 -05:00
parent b7660b3d99
commit 7dfce35bea
2 changed files with 163 additions and 9 deletions

View File

@ -46,6 +46,7 @@ class LdapAuthenticationPlugin extends AuthenticationPlugin
public $options=null; public $options=null;
public $filter=null; public $filter=null;
public $scope=null; public $scope=null;
public $password_encoding=null;
public $attributes=array(); public $attributes=array();
function onInitializePlugin(){ function onInitializePlugin(){
@ -68,10 +69,6 @@ class LdapAuthenticationPlugin extends AuthenticationPlugin
function checkPassword($username, $password) function checkPassword($username, $password)
{ {
$ldap = $this->ldap_get_connection();
if(!$ldap){
return false;
}
$entry = $this->ldap_get_user($username); $entry = $this->ldap_get_user($username);
if(!$entry){ if(!$entry){
return false; return false;
@ -109,8 +106,38 @@ class LdapAuthenticationPlugin extends AuthenticationPlugin
function changePassword($username,$oldpassword,$newpassword) function changePassword($username,$oldpassword,$newpassword)
{ {
//TODO implement this if(! isset($this->attributes['password']) || !isset($this->password_encoding)){
throw new Exception(_('Sorry, changing LDAP passwords is not supported at this time')); //throw new Exception(_('Sorry, changing LDAP passwords is not supported at this time'));
return false;
}
$entry = $this->ldap_get_user($username);
if(!$entry){
return false;
}else{
$config = $this->ldap_get_config();
$config['binddn']=$entry->dn();
$config['bindpw']=$oldpassword;
if($ldap = $this->ldap_get_connection($config)){
$entry = $this->ldap_get_user($username,array(),$ldap);
$newCryptedPassword = $this->hashPassword($newpassword, $this->password_encoding);
if ($newCryptedPassword===false) {
return false;
}
if($this->password_encoding=='ad') {
//TODO I believe this code will work once this bug is fixed: http://pear.php.net/bugs/bug.php?id=16796
$oldCryptedPassword = $this->hashPassword($oldpassword, $this->password_encoding);
$entry->delete( array($this->attributes['password'] => $oldCryptedPassword ));
}
$entry->replace( array($this->attributes['password'] => $newCryptedPassword ), true);
if( Net_LDAP2::isError($entry->upate()) ) {
return false;
}
return true;
}else{
return false;
}
}
return false; return false;
} }
@ -153,8 +180,10 @@ class LdapAuthenticationPlugin extends AuthenticationPlugin
* $param array $attributes LDAP attributes to retrieve * $param array $attributes LDAP attributes to retrieve
* @return string DN * @return string DN
*/ */
function ldap_get_user($username,$attributes=array()){ function ldap_get_user($username,$attributes=array(),$ldap=null){
if($ldap==null) {
$ldap = $this->ldap_get_connection(); $ldap = $this->ldap_get_connection();
}
$filter = Net_LDAP2_Filter::create($this->attributes['username'], 'equals', $username); $filter = Net_LDAP2_Filter::create($this->attributes['username'], 'equals', $username);
$options = array( $options = array(
'scope' => 'sub', 'scope' => 'sub',
@ -177,4 +206,123 @@ class LdapAuthenticationPlugin extends AuthenticationPlugin
return false; return false;
} }
} }
/**
* Code originaly from the phpLDAPadmin development team
* http://phpldapadmin.sourceforge.net/
*
* Hashes a password and returns the hash based on the specified enc_type.
*
* @param string $passwordClear The password to hash in clear text.
* @param string $encodageType Standard LDAP encryption type which must be one of
* crypt, ext_des, md5crypt, blowfish, md5, sha, smd5, ssha, or clear.
* @return string The hashed password.
*
*/
function hashPassword( $passwordClear, $encodageType )
{
$encodageType = strtolower( $encodageType );
switch( $encodageType ) {
case 'crypt':
$cryptedPassword = '{CRYPT}' . crypt($passwordClear,$this->randomSalt(2));
break;
case 'ext_des':
// extended des crypt. see OpenBSD crypt man page.
if ( ! defined( 'CRYPT_EXT_DES' ) || CRYPT_EXT_DES == 0 ) {return FALSE;} //Your system crypt library does not support extended DES encryption.
$cryptedPassword = '{CRYPT}' . crypt( $passwordClear, '_' . $this->randomSalt(8) );
break;
case 'md5crypt':
if( ! defined( 'CRYPT_MD5' ) || CRYPT_MD5 == 0 ) {return FALSE;} //Your system crypt library does not support md5crypt encryption.
$cryptedPassword = '{CRYPT}' . crypt( $passwordClear , '$1$' . $this->randomSalt(9) );
break;
case 'blowfish':
if( ! defined( 'CRYPT_BLOWFISH' ) || CRYPT_BLOWFISH == 0 ) {return FALSE;} //Your system crypt library does not support blowfish encryption.
$cryptedPassword = '{CRYPT}' . crypt( $passwordClear , '$2a$12$' . $this->randomSalt(13) ); // hardcoded to second blowfish version and set number of rounds
break;
case 'md5':
$cryptedPassword = '{MD5}' . base64_encode( pack( 'H*' , md5( $passwordClear) ) );
break;
case 'sha':
if( function_exists('sha1') ) {
// use php 4.3.0+ sha1 function, if it is available.
$cryptedPassword = '{SHA}' . base64_encode( pack( 'H*' , sha1( $passwordClear) ) );
} elseif( function_exists( 'mhash' ) ) {
$cryptedPassword = '{SHA}' . base64_encode( mhash( MHASH_SHA1, $passwordClear) );
} else {
return FALSE; //Your PHP install does not have the mhash() function. Cannot do SHA hashes.
}
break;
case 'ssha':
if( function_exists( 'mhash' ) && function_exists( 'mhash_keygen_s2k' ) ) {
mt_srand( (double) microtime() * 1000000 );
$salt = mhash_keygen_s2k( MHASH_SHA1, $passwordClear, substr( pack( "h*", md5( mt_rand() ) ), 0, 8 ), 4 );
$cryptedPassword = "{SSHA}".base64_encode( mhash( MHASH_SHA1, $passwordClear.$salt ).$salt );
} else {
return FALSE; //Your PHP install does not have the mhash() function. Cannot do SHA hashes.
}
break;
case 'smd5':
if( function_exists( 'mhash' ) && function_exists( 'mhash_keygen_s2k' ) ) {
mt_srand( (double) microtime() * 1000000 );
$salt = mhash_keygen_s2k( MHASH_MD5, $passwordClear, substr( pack( "h*", md5( mt_rand() ) ), 0, 8 ), 4 );
$cryptedPassword = "{SMD5}".base64_encode( mhash( MHASH_MD5, $passwordClear.$salt ).$salt );
} else {
return FALSE; //Your PHP install does not have the mhash() function. Cannot do SHA hashes.
}
break;
case 'ad':
$cryptedPassword = '';
$passwordClear = "\"" . $passwordClear . "\"";
$len = strlen($passwordClear);
for ($i = 0; $i < $len; $i++) {
$cryptedPassword .= "{$passwordClear{$i}}\000";
}
case 'clear':
default:
$cryptedPassword = $passwordClear;
}
return $cryptedPassword;
}
/**
* Code originaly from the phpLDAPadmin development team
* http://phpldapadmin.sourceforge.net/
*
* Used to generate a random salt for crypt-style passwords. Salt strings are used
* to make pre-built hash cracking dictionaries difficult to use as the hash algorithm uses
* not only the user's password but also a randomly generated string. The string is
* stored as the first N characters of the hash for reference of hashing algorithms later.
*
* --- added 20021125 by bayu irawan <bayuir@divnet.telkom.co.id> ---
* --- ammended 20030625 by S C Rigler <srigler@houston.rr.com> ---
*
* @param int $length The length of the salt string to generate.
* @return string The generated salt string.
*/
function randomSalt( $length )
{
$possible = '0123456789'.
'abcdefghijklmnopqrstuvwxyz'.
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
'./';
$str = "";
mt_srand((double)microtime() * 1000000);
while( strlen( $str ) < $length )
$str .= substr( $possible, ( rand() % strlen( $possible ) ), 1 );
return $str;
}
} }

View File

@ -18,6 +18,9 @@ email_changeable (true): Are users allowed to change their email address?
(true or false) (true or false)
password_changeable (true): Are users allowed to change their passwords? password_changeable (true): Are users allowed to change their passwords?
(true or false) (true or false)
password_encoding: required if users are to be able to change their passwords
Possible values are: crypt, ext_des, md5crypt, blowfish, md5, sha, ssha,
smd5, ad, clear
host*: LDAP server name to connect to. You can provide several hosts in an host*: LDAP server name to connect to. You can provide several hosts in an
array in which case the hosts are tried from left to right. array in which case the hosts are tried from left to right.
@ -47,6 +50,7 @@ attributes: an array that relates StatusNet user attributes to LDAP ones
fullname fullname
homepage homepage
location location
password: required if users are to be able to change their passwords
* required * required
default values are in (parenthesis) default values are in (parenthesis)
@ -67,10 +71,12 @@ addPlugin('ldapAuthentication', array(
'bindpw'=>'password', 'bindpw'=>'password',
'basedn'=>'OU=Users,OU=StatusNet,OU=US,DC=americas,DC=global,DC=loc', 'basedn'=>'OU=Users,OU=StatusNet,OU=US,DC=americas,DC=global,DC=loc',
'host'=>array('server1', 'server2'), 'host'=>array('server1', 'server2'),
'password_encoding'=>'ad',
'attributes'=>array( 'attributes'=>array(
'username'=>'sAMAccountName', 'username'=>'sAMAccountName',
'nickname'=>'sAMAccountName', 'nickname'=>'sAMAccountName',
'email'=>'mail', 'email'=>'mail',
'fullname'=>'displayName') 'fullname'=>'displayName',
'password'=>'unicodePwd')
)); ));