2004-08-13 17:53:07 +02:00
< ? php
2010-01-28 05:22:37 +01:00
/**
* eGroupWare API - ADS Authentication
*
* @ link http :// www . egroupware . org
* @ author Ralf Becker < ralfbecker @ outdoor - training . de > based on auth_ldap from :
* @ author Lars Kneschke < lkneschke @ linux - at - work . de >
* @ author Joseph Engo < jengo @ phpgroupware . org >
* Copyright ( C ) 2000 , 2001 Joseph Engo
* Copyright ( C ) 2002 , 2003 Lars Kneschke
* @ license http :// opensource . org / licenses / lgpl - license . php LGPL - GNU Lesser General Public License
* @ package api
* @ subpackage authentication
* @ version $Id $
*/
2004-08-13 17:53:07 +02:00
2010-01-28 05:22:37 +01:00
/**
* Authentication agains a ADS Server
*/
class auth_ads implements auth_backend
{
var $previous_login = - 1 ;
2005-08-27 14:19:35 +02:00
2010-01-28 05:22:37 +01:00
/**
* password authentication
*
* @ param string $username username of account to authenticate
* @ param string $passwd corresponding password
* @ param string $passwd_type = 'text' 'text' for cleartext passwords ( default )
* @ return boolean true if successful authenticated , false otherwise
*/
function authenticate ( $username , $passwd , $passwd_type = 'text' )
2004-08-13 17:53:07 +02:00
{
2010-01-28 05:22:37 +01:00
if ( preg_match ( '/[()|&=*,<>!~]/' , $username ))
2004-08-13 17:53:07 +02:00
{
2010-01-28 05:22:37 +01:00
return False ;
}
2004-08-13 17:53:07 +02:00
2013-05-22 19:22:20 +02:00
$adldap = accounts_ads :: get_adldap ();
2010-01-28 05:22:37 +01:00
// bind with username@ads_domain, only if a non-empty password given, in case anonymous search is enabled
2013-05-22 19:22:20 +02:00
if ( empty ( $passwd ) || ! $adldap -> authenticate ( $username , $passwd ))
2010-01-28 05:22:37 +01:00
{
2013-05-22 19:22:20 +02:00
//error_log(__METHOD__."('$username', ".(empty($passwd) ? "'') passwd empty" : '$passwd) adldap->authenticate() returned false')." --> returning false");
2010-01-28 05:22:37 +01:00
return False ;
}
2005-05-13 17:58:10 +02:00
2011-11-15 13:43:59 +01:00
$attributes = array ( 'samaccountname' , 'givenName' , 'sn' , 'mail' , 'homeDirectory' );
2013-05-22 19:22:20 +02:00
if (( $allValues = $adldap -> user () -> info ( $username , $attributes )))
2010-01-28 05:22:37 +01:00
{
2013-05-22 19:22:20 +02:00
$allValues [ 0 ][ 'objectsid' ][ 0 ] = $adldap -> utilities () -> getTextSID ( $allValues [ 0 ][ 'objectsid' ][ 0 ]);
2010-01-28 05:22:37 +01:00
}
2013-05-22 19:22:20 +02:00
//error_log(__METHOD__."('$username', \$passwd) allValues=".array2string($allValues));
2005-08-27 14:19:35 +02:00
2013-05-22 19:22:20 +02:00
if ( $allValues && $allValues [ 'count' ] > 0 )
2010-01-28 05:22:37 +01:00
{
if ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'case_sensitive_username' ] == true )
2004-08-13 17:53:07 +02:00
{
2010-01-28 05:22:37 +01:00
if ( $allValues [ 0 ][ 'samaccountname' ][ 0 ] != $username )
2004-08-13 17:53:07 +02:00
{
2010-01-28 05:22:37 +01:00
return false ;
2004-08-13 17:53:07 +02:00
}
2010-01-28 05:22:37 +01:00
}
if (( $id = $GLOBALS [ 'egw' ] -> accounts -> name2id ( $username , 'account_lid' , 'u' )))
{
return $GLOBALS [ 'egw' ] -> accounts -> id2name ( $id , 'account_status' ) == 'A' ;
}
2011-11-15 13:43:59 +01:00
// store homedirectory for egw_session->read_repositories
$GLOBALS [ 'auto_create_acct' ] = array ();
if ( isset ( $allValues [ 0 ][ 'homedirectory' ]))
{
2011-11-15 20:16:09 +01:00
$GLOBALS [ 'auto_create_acct' ][ 'homedirectory' ] = $allValues [ 0 ][ 'homedirectory' ][ 0 ];
2011-11-15 13:43:59 +01:00
}
2010-01-28 05:22:37 +01:00
if ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'auto_create_acct' ])
{
2013-05-22 19:22:20 +02:00
$GLOBALS [ 'auto_create_acct' ][ 'account_id' ] = accounts_ads :: sid2account_id ( $allValues [ 0 ][ 'objectsid' ][ 0 ]);
2010-01-28 05:22:37 +01:00
// create a global array with all availible info about that account
foreach ( array (
'givenname' => 'firstname' ,
'sn' => 'lastname' ,
'mail' => 'email' ,
) as $ldap_name => $acct_name )
2004-08-13 17:53:07 +02:00
{
2010-01-28 05:22:37 +01:00
$GLOBALS [ 'auto_create_acct' ][ $acct_name ] =
translation :: convert ( $allValues [ 0 ][ $ldap_name ][ 0 ], 'utf-8' );
2004-08-13 17:53:07 +02:00
}
2013-05-22 19:22:20 +02:00
//error_log(__METHOD__."() \$GLOBALS[auto_create_acct]=".array2string($GLOBALS['auto_create_acct']));
2010-01-28 05:22:37 +01:00
return True ;
2004-08-13 17:53:07 +02:00
}
}
2010-01-28 05:22:37 +01:00
/* dn not found or password wrong */
return False ;
}
2004-08-13 17:53:07 +02:00
2013-05-22 19:22:20 +02:00
/**
* changes password
*
* @ param string $old_passwd must be cleartext
* @ param string $new_passwd must be cleartext
* @ param int $account_id account id of user whose passwd should be changed
* @ return boolean true if password successful changed , false otherwise
2013-06-23 12:46:26 +02:00
* @ throws egw_exception_wrong_userinput
2013-05-22 19:22:20 +02:00
*/
2013-06-25 18:37:44 +02:00
function change_password ( $old_passwd , $new_passwd , $account_id = 0 )
2010-01-28 05:22:37 +01:00
{
2013-06-29 10:51:02 +02:00
if ( ! ( $adldap = accounts_ads :: get_adldap ()))
2013-05-22 19:22:20 +02:00
{
2013-06-29 10:51:02 +02:00
error_log ( __METHOD__ . " ( \$ old_passwd, \$ new_passwd, $account_id ) accounts_ads::get_adldap() returned false " );
return false ;
}
if ( ! ( $adldap -> getUseSSL () || $adldap -> getUseTLS ()))
{
throw new egw_exception ( lang ( 'Failed to change password. Please contact your administrator.' ) . ' ' . lang ( 'Active directory requires SSL or TLS to change passwords!' ));
2013-05-22 19:22:20 +02:00
}
if ( ! $account_id || $GLOBALS [ 'egw_info' ][ 'flags' ][ 'currentapp' ] == 'login' )
{
$admin = false ;
$username = $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_lid' ];
2013-07-14 15:05:24 +02:00
$account_id = $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ];
2013-05-22 19:22:20 +02:00
}
else
{
$admin = true ;
$username = $GLOBALS [ 'egw' ] -> accounts -> id2name ( $account_id );
}
// Check the old_passwd to make sure this is legal
if ( ! $admin && ! $adldap -> authenticate ( $username , $old_passwd ))
{
//error_log(__METHOD__."() old password '$old_passwd' for '$username' is wrong!");
return false ;
}
2013-06-23 12:46:26 +02:00
try {
2013-06-25 18:37:44 +02:00
$ret = $adldap -> user () -> password ( $username , $new_passwd );
//error_log(__METHOD__."('$old_passwd', '$new_passwd', $account_id) admin=$admin adldap->user()->password('$username', '$new_passwd') returned ".array2string($ret));
return $ret ;
2013-06-23 12:46:26 +02:00
}
catch ( Exception $e ) {
2013-07-14 15:05:24 +02:00
error_log ( __METHOD__ . " (' $old_passwd ', ' $new_passwd ', $account_id ) admin= $admin adldap->user()->password(' $username ', ' $new_passwd ') returned " . array2string ( $ret ) . ' (' . ldap_error ( $adldap -> getLdapConnection ()) . ')' );
// as we cant detect what the problem is, we do a password strength check and throw it's message, if it fails
$error = auth :: crackcheck ( $new_passwd ,
// if admin has nothing configured use windows default of 3 char classes, 7 chars min and name-part-check
$GLOBALS [ 'egw_info' ][ 'server' ][ 'force_pwd_strength' ] ? $GLOBALS [ 'egw_info' ][ 'server' ][ 'force_pwd_strength' ] : 3 ,
$GLOBALS [ 'egw_info' ][ 'server' ][ 'force_pwd_length' ] ? $GLOBALS [ 'egw_info' ][ 'server' ][ 'force_pwd_length' ] : 7 ,
$GLOBALS [ 'egw_info' ][ 'server' ][ 'passwd_forbid_name' ] ? $GLOBALS [ 'egw_info' ][ 'server' ][ 'passwd_forbid_name' ] : true ,
$account_id );
$msg = $e -> getMessage ();
$msg = strtr ( $msg , $tr = array ( // translate possible adLDAP and LDAP error
'Error' => lang ( 'Error' ),
'Server is unwilling to perform.' => lang ( 'Server is unwilling to perform.' ),
'Your password might not match the password policy.' => lang ( 'Your password might not match the password policy.' ),
'SSL must be configured on your webserver and enabled in the class to set passwords.' => lang ( 'Encrypted LDAP connection is required to change passwords, but it is not configured in your installation.' ),
));
throw new egw_exception ( '<p><b>' . lang ( 'Failed to change password.' ) . " </b></p> \n " . $msg . ( $error ? " \n <p> " . $error . " </p> \n " : '' ));
2013-06-23 12:46:26 +02:00
}
return false ;
2004-08-13 17:53:07 +02:00
}
2010-01-28 05:22:37 +01:00
}