2012-02-08 23:14:28 +01:00
< ? php
class ModelUserAuth extends Model {
public function checkLogin ( $username = '' , $password = '' ) {
2013-10-16 14:55:17 +02:00
$session = Registry :: get ( 'session' );
2012-10-06 14:18:00 +02:00
$ok = 0 ;
2012-02-08 23:14:28 +01:00
2013-03-02 12:54:33 +01:00
if ( $username == '' || $password == '' ) { return 0 ; }
if ( ENABLE_LDAP_AUTH == 1 ) {
$ok = $this -> checkLoginAgainstLDAP ( $username , $password );
if ( $ok == 1 ) { return $ok ; }
}
2012-12-10 12:41:40 +01:00
if ( ENABLE_IMAP_AUTH == 1 ) {
require 'Zend/Mail/Protocol/Imap.php' ;
$ok = $this -> checkLoginAgainstIMAP ( $username , $password );
2013-03-02 12:54:33 +01:00
if ( $ok == 1 ) { return $ok ; }
2012-12-10 12:41:40 +01:00
}
2013-09-30 21:43:41 +02:00
if ( ENABLE_POP3_AUTH == 1 ) {
require 'Zend/Mail/Protocol/Pop3.php' ;
$ok = $this -> checkLoginAgainstPOP3 ( $username , $password );
if ( $ok == 1 ) { return $ok ; }
}
2013-03-02 12:54:33 +01:00
// fallback local auth
$query = $this -> db -> query ( " SELECT u.username, u.uid, u.realname, u.dn, u.password, u.isadmin, u.domain FROM " . TABLE_USER . " u, " . TABLE_EMAIL . " e WHERE e.email=? AND e.uid=u.uid " , array ( $username ));
2012-02-08 23:14:28 +01:00
if ( ! isset ( $query -> row [ 'password' ])) { return 0 ; }
$pass = crypt ( $password , $query -> row [ 'password' ]);
if ( $pass == $query -> row [ 'password' ]){
2012-10-06 14:18:00 +02:00
$ok = 1 ;
2012-02-08 23:14:28 +01:00
2012-10-06 14:18:00 +02:00
AUDIT ( ACTION_LOGIN , $username , '' , '' , 'successful auth against user table' );
}
else {
AUDIT ( ACTION_LOGIN_FAILED , $username , '' , '' , 'failed auth against user table' );
}
if ( $ok == 0 && strlen ( $query -> row [ 'dn' ]) > 3 ) {
2013-03-02 12:54:33 +01:00
$ok = $this -> checkLoginAgainstFallbackLDAP ( $query -> row , $password );
2012-10-06 14:18:00 +02:00
}
if ( $ok == 1 ) {
2013-10-16 14:55:17 +02:00
$session -> set ( " username " , $username );
$session -> set ( " uid " , $query -> row [ 'uid' ]);
$session -> set ( " admin_user " , $query -> row [ 'isadmin' ]);
$session -> set ( " email " , $username );
$session -> set ( " domain " , $query -> row [ 'domain' ]);
$session -> set ( " realname " , $query -> row [ 'realname' ]);
$session -> set ( " auditdomains " , $this -> model_user_user -> get_users_all_domains ( $query -> row [ 'uid' ]));
$session -> set ( " emails " , $this -> model_user_user -> get_users_all_email_addresses ( $query -> row [ 'uid' ]));
$session -> set ( " folders " , $this -> model_folder_folder -> get_all_folder_ids ( $query -> row [ 'uid' ]));
$session -> set ( " extra_folders " , $this -> model_folder_folder -> get_all_extra_folder_ids ( $query -> row [ 'uid' ]));
$this -> is_ga_code_needed ();
2012-02-08 23:14:28 +01:00
return 1 ;
}
2013-03-02 12:54:33 +01:00
return 0 ;
}
private function checkLoginAgainstLDAP ( $username = '' , $password = '' ) {
2014-09-04 16:18:47 +02:00
$a = array ();
$ret = 0 ;
if ( ENABLE_SAAS == 1 ) {
$params = $this -> model_saas_ldap -> get_ldap_params_by_email ( $username );
foreach ( $params as $param ) {
$ret = $this -> checkLoginAgainstLDAP_real ( $username , $password , $param );
syslog ( LOG_INFO , " ldap auth result against " . $param [ 'ldap_host' ] . " / " . $param [ 'ldap_type' ] . " : $ret " );
if ( $ret == 1 ) { return $ret ; }
}
}
else {
$ret = $this -> checkLoginAgainstLDAP_real ( $username , $password );
}
return $ret ;
}
private function checkLoginAgainstLDAP_real ( $username = '' , $password = '' , $a = array ()) {
2013-07-20 11:15:13 +02:00
$ldap_type = '' ;
2013-07-08 11:31:17 +02:00
$ldap_host = LDAP_HOST ;
$ldap_base_dn = LDAP_BASE_DN ;
$ldap_helper_dn = LDAP_HELPER_DN ;
$ldap_helper_password = LDAP_HELPER_PASSWORD ;
2013-07-23 22:44:34 +02:00
$ldap_auditor_member_dn = LDAP_AUDITOR_MEMBER_DN ;
2013-08-20 12:15:45 +02:00
$ldap_admin_member_dn = LDAP_ADMIN_MEMBER_DN ;
$role = 0 ;
2013-12-23 11:27:36 +01:00
$username_prefix = '' ;
2013-07-08 11:31:17 +02:00
2014-09-04 16:18:47 +02:00
if ( count ( $a ) >= 6 ) {
$ldap_type = $a [ 'ldap_type' ];
$ldap_host = $a [ 'ldap_host' ];
$ldap_base_dn = $a [ 'ldap_base_dn' ];
$ldap_helper_dn = $a [ 'ldap_bind_dn' ];
$ldap_helper_password = $a [ 'ldap_bind_pw' ];
$ldap_auditor_member_dn = $a [ 'ldap_auditor_member_dn' ];
$ldap_mail_attr = $a [ 'ldap_mail_attr' ];
$ldap_account_objectclass = $a [ 'ldap_account_objectclass' ];
$ldap_distributionlist_attr = $a [ 'ldap_distributionlist_attr' ];
$ldap_distributionlist_objectclass = $a [ 'ldap_distributionlist_objectclass' ];
2013-07-08 11:31:17 +02:00
}
2014-01-15 14:47:30 +01:00
if ( $ldap_type != LDAP_TYPE_GENERIC ) {
list ( $ldap_mail_attr , $ldap_account_objectclass , $ldap_distributionlist_attr , $ldap_distributionlist_objectclass ) = get_ldap_attribute_names ( $ldap_type );
}
2013-07-20 11:15:13 +02:00
2013-12-23 11:27:36 +01:00
if ( $ldap_mail_attr == 'proxyAddresses' ) { $username_prefix = 'smtp:' ; }
2013-07-20 11:15:13 +02:00
if ( $ldap_host == '' || $ldap_helper_password == '' ) { return 0 ; }
2013-07-08 11:31:17 +02:00
$ldap = new LDAP ( $ldap_host , $ldap_helper_dn , $ldap_helper_password );
2013-03-02 12:54:33 +01:00
if ( $ldap -> is_bind_ok ()) {
2013-04-17 11:32:05 +02:00
2013-12-23 11:27:36 +01:00
$query = $ldap -> query ( $ldap_base_dn , " (&(objectClass= $ldap_account_objectclass )( $ldap_mail_attr = $username_prefix $username )) " , array ());
2013-03-02 12:54:33 +01:00
2013-07-03 11:36:41 +02:00
if ( isset ( $query -> row [ 'dn' ]) && $query -> row [ 'dn' ]) {
2013-03-02 12:54:33 +01:00
$a = $query -> row ;
2013-07-08 11:31:17 +02:00
$ldap_auth = new LDAP ( $ldap_host , $a [ 'dn' ], $password );
2013-03-02 12:54:33 +01:00
2013-07-08 11:31:17 +02:00
if ( ENABLE_SYSLOG == 1 ) { syslog ( LOG_INFO , " ldap auth against ' " . $ldap_host . " ', dn: ' " . $a [ 'dn' ] . " ', result: " . $ldap_auth -> is_bind_ok ()); }
2013-04-03 22:45:05 +02:00
2013-03-02 12:54:33 +01:00
if ( $ldap_auth -> is_bind_ok ()) {
2013-04-17 11:32:05 +02:00
2013-12-23 11:27:36 +01:00
$query = $ldap -> query ( $ldap_base_dn , " (|(&(objectClass= $ldap_account_objectclass )( $ldap_mail_attr = $username_prefix $username ))(&(objectClass= $ldap_distributionlist_objectclass )( $ldap_distributionlist_attr = $username_prefix $username ) " . " )(&(objectClass= $ldap_distributionlist_objectclass )( $ldap_distributionlist_attr = " . stripslashes ( $a [ 'dn' ]) . " ))) " , array ());
2013-04-17 11:32:05 +02:00
2013-08-20 12:15:45 +02:00
if ( $this -> check_ldap_membership ( $ldap_auditor_member_dn , $query -> rows ) == 1 ) { $role = 2 ; }
if ( $this -> check_ldap_membership ( $ldap_admin_member_dn , $query -> rows ) == 1 ) { $role = 1 ; }
2013-05-03 09:48:32 +02:00
2013-03-02 14:09:06 +01:00
$emails = $this -> get_email_array_from_ldap_attr ( $query -> rows );
2013-03-02 12:54:33 +01:00
2014-07-05 17:29:35 +02:00
$extra_emails = $this -> model_user_user -> get_email_addresses_from_groups ( $emails );
2014-07-05 17:09:38 +02:00
$emails = array_merge ( $emails , $extra_emails );
2013-08-20 12:15:45 +02:00
$this -> add_session_vars ( $a [ 'cn' ], $username , $emails , $role );
2013-03-02 12:54:33 +01:00
AUDIT ( ACTION_LOGIN , $username , '' , '' , 'successful auth against LDAP' );
return 1 ;
}
else {
AUDIT ( ACTION_LOGIN_FAILED , $username , '' , '' , 'failed auth against LDAP' );
}
}
}
else if ( ENABLE_SYSLOG == 1 ) {
2013-07-08 11:31:17 +02:00
syslog ( LOG_INFO , " cannot bind to ' " . $ldap_host . " ' as ' " . $ldap_helper_dn . " ' " );
2013-03-02 12:54:33 +01:00
}
2012-02-08 23:14:28 +01:00
return 0 ;
}
2013-07-23 22:44:34 +02:00
private function check_ldap_membership ( $ldap_auditor_member_dn = '' , $e = array ()) {
if ( $ldap_auditor_member_dn == '' ) { return 0 ; }
2013-05-03 09:48:32 +02:00
foreach ( $e as $a ) {
2013-08-09 10:13:54 +02:00
foreach ( array ( " memberof " , " dn " ) as $memberattr ) {
2013-05-03 09:48:32 +02:00
if ( isset ( $a [ $memberattr ])) {
if ( isset ( $a [ $memberattr ][ 'count' ])) {
for ( $i = 0 ; $i < $a [ $memberattr ][ 'count' ]; $i ++ ) {
2013-07-23 22:44:34 +02:00
if ( $a [ $memberattr ][ $i ] == $ldap_auditor_member_dn ) {
2013-05-03 09:48:32 +02:00
return 1 ;
}
}
}
else {
2013-07-23 22:44:34 +02:00
if ( $a [ $memberattr ] == $ldap_auditor_member_dn ) {
2013-05-03 09:48:32 +02:00
return 1 ;
}
}
}
}
}
return 0 ;
}
2013-08-22 11:24:54 +02:00
public function get_email_array_from_ldap_attr ( $e = array ()) {
2013-03-02 12:54:33 +01:00
$data = array ();
2013-03-02 14:09:06 +01:00
foreach ( $e as $a ) {
2014-09-09 15:30:26 +02:00
//syslog(LOG_INFO, "checking ldap entry dn: " . $a['dn'] . ", cn: " . $a['cn']);
2014-07-29 21:52:29 +02:00
2013-07-12 15:30:49 +02:00
foreach ( array ( " mail " , " mailalternateaddress " , " proxyaddresses " , " zimbraMailForwardingAddress " , " member " , " memberOfGroup " ) as $mailattr ) {
2013-03-02 14:09:06 +01:00
if ( isset ( $a [ $mailattr ])) {
2013-03-02 12:54:33 +01:00
2013-08-28 13:11:05 +02:00
if ( is_array ( $a [ $mailattr ])) {
2013-03-02 14:09:06 +01:00
for ( $i = 0 ; $i < $a [ $mailattr ][ 'count' ]; $i ++ ) {
2013-12-23 11:27:36 +01:00
2014-09-09 15:30:26 +02:00
//syslog(LOG_INFO, "checking entry: " . $a[$mailattr][$i]);
2014-07-29 21:52:29 +02:00
2013-12-23 11:27:36 +01:00
$a [ $mailattr ][ $i ] = strtolower ( $a [ $mailattr ][ $i ]);
if ( strchr ( $a [ $mailattr ][ $i ], '@' )) {
if ( preg_match ( " /^([ \ w]+) \ :/i " , $a [ $mailattr ][ $i ], $p )) {
if ( isset ( $p [ 0 ]) && $p [ 0 ] != " smtp: " ) { continue ; }
}
$email = preg_replace ( " /^([ \ w]+) \ :/i " , " " , $a [ $mailattr ][ $i ]);
if ( validemail ( $email ) && ! in_array ( $email , $data )) { array_push ( $data , $email ); }
2013-03-02 14:09:06 +01:00
}
2013-03-02 12:54:33 +01:00
}
}
2013-03-02 14:09:06 +01:00
else {
2014-09-09 15:30:26 +02:00
//syslog(LOG_INFO, "checking entry #2: " . $a[$mailattr]);
2014-07-29 21:52:29 +02:00
2013-12-23 11:27:36 +01:00
$email = strtolower ( preg_replace ( " /^([ \ w]+) \ :/i " , " " , $a [ $mailattr ]));
if ( validemail ( $email ) && ! in_array ( $email , $data )) { array_push ( $data , $email ); }
2013-03-02 14:09:06 +01:00
}
2013-03-02 12:54:33 +01:00
}
2013-07-12 15:30:49 +02:00
}
2013-03-02 12:54:33 +01:00
}
return $data ;
}
2013-08-20 12:15:45 +02:00
private function add_session_vars ( $name = '' , $email = '' , $emails = array (), $role = 0 ) {
2013-10-16 14:55:17 +02:00
$session = Registry :: get ( 'session' );
2013-03-02 12:54:33 +01:00
$a = explode ( " @ " , $email );
$uid = $this -> model_user_user -> get_uid_by_email ( $email );
if ( $uid < 1 ) {
2013-04-12 22:30:48 +02:00
$uid = $this -> model_user_user -> get_next_uid ( TABLE_EMAIL );
2013-03-02 12:54:33 +01:00
$query = $this -> db -> query ( " INSERT INTO " . TABLE_EMAIL . " (uid, email) VALUES(?,?) " , array ( $uid , $email ));
}
2013-10-16 14:55:17 +02:00
$session -> set ( " username " , $email );
$session -> set ( " uid " , $uid );
2013-05-03 09:48:32 +02:00
2013-08-20 12:15:45 +02:00
if ( $role > 0 ) {
2013-10-16 14:55:17 +02:00
$session -> set ( " admin_user " , $role );
2013-05-03 09:48:32 +02:00
} else {
2013-10-16 14:55:17 +02:00
$session -> set ( " admin_user " , 0 );
2013-05-03 09:48:32 +02:00
}
2013-10-16 14:55:17 +02:00
$session -> set ( " email " , $email );
$session -> set ( " domain " , $a [ 1 ]);
$session -> set ( " realname " , $name );
2013-03-02 12:54:33 +01:00
2013-10-16 14:55:17 +02:00
$session -> set ( " auditdomains " , $this -> model_domain_domain -> get_your_all_domains_by_email ( $email ));
$session -> set ( " emails " , $emails );
$session -> set ( " folders " , array ());
$session -> set ( " extra_folders " , array ());
$this -> is_ga_code_needed ();
2013-03-02 12:54:33 +01:00
}
private function checkLoginAgainstFallbackLDAP ( $user = array (), $password = '' ) {
2012-02-08 23:14:28 +01:00
if ( $password == '' || ! isset ( $user [ 'username' ]) || ! isset ( $user [ 'domain' ]) || ! isset ( $user [ 'dn' ]) || strlen ( $user [ 'domain' ]) < 2 ){ return 0 ; }
$query = $this -> db -> query ( " SELECT remotehost, basedn FROM " . TABLE_REMOTE . " WHERE remotedomain=? " , array ( $user [ 'domain' ]));
if ( $query -> num_rows != 1 ) { return 0 ; }
$ldap = new LDAP ( $query -> row [ 'remotehost' ], $user [ 'dn' ], $password );
if ( $ldap -> is_bind_ok ()) {
2012-06-22 15:22:02 +02:00
$this -> change_password ( $user [ 'username' ], $password );
2012-02-08 23:14:28 +01:00
AUDIT ( ACTION_LOGIN , $user [ 'username' ], '' , '' , 'changed password in local table' );
return 1 ;
}
else {
AUDIT ( ACTION_LOGIN_FAILED , $user [ 'username' ], '' , '' , 'failed bind to ' . $query -> row [ 'remotehost' ], $user [ 'dn' ]);
}
return 0 ;
}
2012-12-10 12:41:40 +01:00
private function checkLoginAgainstIMAP ( $username = '' , $password = '' ) {
2013-10-16 14:55:17 +02:00
$session = Registry :: get ( 'session' );
2014-07-05 17:09:38 +02:00
$emails = array ( $username );
2013-10-16 14:55:17 +02:00
2013-12-04 13:26:05 +01:00
if ( ! strchr ( $username , '@' )) { return 0 ; }
2012-12-10 12:41:40 +01:00
$imap = new Zend_Mail_Protocol_Imap ( IMAP_HOST , IMAP_PORT , IMAP_SSL );
if ( $imap -> login ( $username , $password )) {
$imap -> logout ();
2014-07-05 17:29:35 +02:00
$extra_emails = $this -> model_user_user -> get_email_addresses_from_groups ( $emails );
2014-07-05 17:09:38 +02:00
$emails = array_merge ( $emails , $extra_emails );
$this -> add_session_vars ( $username , $username , $emails , 0 );
2012-12-10 12:41:40 +01:00
2013-10-16 14:55:17 +02:00
$session -> set ( " password " , $password );
2013-04-02 22:22:30 +02:00
2012-12-10 12:41:40 +01:00
return 1 ;
}
return 0 ;
}
2013-09-30 21:43:41 +02:00
private function checkLoginAgainstPOP3 ( $username = '' , $password = '' ) {
$rc = 0 ;
2014-07-05 17:09:38 +02:00
$emails = array ( $username );
2013-09-30 21:43:41 +02:00
try {
$conn = new Zend_Mail_Protocol_Pop3 ( POP3_HOST , POP3_PORT , POP3_SSL );
if ( $conn ) {
$s = $conn -> connect ( POP3_HOST );
if ( $s ) {
try {
$conn -> login ( $username , $password );
2014-07-05 17:29:35 +02:00
$extra_emails = $this -> model_user_user -> get_email_addresses_from_groups ( $emails );
2014-07-05 17:09:38 +02:00
$emails = array_merge ( $emails , $extra_emails );
$this -> add_session_vars ( $username , $username , $emails , 0 );
2013-09-30 21:43:41 +02:00
$rc = 1 ;
}
catch ( Zend_Mail_Protocol_Exception $e ) {}
}
}
}
catch ( Zend_Mail_Protocol_Exception $e ) {}
return $rc ;
}
2012-10-17 13:11:08 +02:00
public function check_ntlm_auth () {
2013-08-20 12:15:45 +02:00
$ldap_auditor_member_dn = LDAP_AUDITOR_MEMBER_DN ;
$ldap_admin_member_dn = LDAP_ADMIN_MEMBER_DN ;
$role = 0 ;
2013-07-12 11:14:09 +02:00
2013-08-21 00:06:41 +02:00
if ( ! isset ( $_SERVER [ 'REMOTE_USER' ]) || $_SERVER [ 'REMOTE_USER' ] == '' ) { return 0 ; }
2012-10-17 13:11:08 +02:00
$u = explode ( " \\ " , $_SERVER [ 'REMOTE_USER' ]);
2013-08-21 00:06:41 +02:00
if ( isset ( $u [ 1 ])) { $username = $u [ 1 ]; }
else { $username = $_SERVER [ 'REMOTE_USER' ]; }
if ( ENABLE_SYSLOG == 1 ) { syslog ( LOG_INFO , " sso login: $username " ); }
2012-10-17 13:11:08 +02:00
2013-04-19 20:39:38 +02:00
$ldap = new LDAP ( LDAP_HOST , LDAP_HELPER_DN , LDAP_HELPER_PASSWORD );
2012-10-17 13:11:08 +02:00
2013-04-19 20:39:38 +02:00
if ( $ldap -> is_bind_ok ()) {
2012-10-17 13:11:08 +02:00
2014-01-01 20:55:31 +01:00
$query = $ldap -> query ( LDAP_BASE_DN , " (&(objectClass=user)(samaccountname= " . $username . " )) " , array ());
2013-04-19 20:39:38 +02:00
if ( isset ( $query -> row [ 'dn' ])) {
$a = $query -> row ;
if ( isset ( $a [ 'mail' ][ 'count' ])) { $username = $a [ 'mail' ][ 0 ]; } else { $username = $a [ 'mail' ]; }
$username = strtolower ( preg_replace ( " /^smtp \ :/i " , " " , $username ));
2013-10-17 23:22:03 +02:00
if ( $username == '' ) {
syslog ( LOG_INFO , " no email address found for " . $a [ 'dn' ]);
return 0 ;
}
2014-09-09 15:30:26 +02:00
$ldap_mail_attr = LDAP_MAIL_ATTR ;
if ( LDAP_MAIL_ATTR == 'proxyAddresses' ) { $ldap_mail_attr = 'proxyAddresses=smtp:' ; }
$query = $ldap -> query ( LDAP_BASE_DN , " (|(&(objectClass=user)( " . $ldap_mail_attr . " = $username ))(&(objectClass=group)(member= $username ))(&(objectClass=group)(member= " . stripslashes ( $a [ 'dn' ]) . " ))) " , array ());
2013-04-19 20:39:38 +02:00
$emails = $this -> get_email_array_from_ldap_attr ( $query -> rows );
2014-07-05 17:29:35 +02:00
$extra_emails = $this -> model_user_user -> get_email_addresses_from_groups ( $emails );
2014-09-04 16:18:47 +02:00
$emails = array_merge ( array ( $username ), $emails , $extra_emails );
2014-07-05 17:09:38 +02:00
2013-08-20 12:15:45 +02:00
if ( $this -> check_ldap_membership ( $ldap_auditor_member_dn , $query -> rows ) == 1 ) { $role = 2 ; }
if ( $this -> check_ldap_membership ( $ldap_admin_member_dn , $query -> rows ) == 1 ) { $role = 1 ; }
$this -> add_session_vars ( $a [ 'cn' ], $username , $emails , $role );
2013-04-19 20:39:38 +02:00
2014-07-29 21:52:29 +02:00
$this -> model_user_prefs -> get_user_preferences ( $username );
2013-04-19 20:39:38 +02:00
AUDIT ( ACTION_LOGIN , $username , '' , '' , 'successful auth against LDAP' );
return 1 ;
}
2012-10-17 13:11:08 +02:00
}
return 0 ;
}
2013-08-30 15:18:59 +02:00
public function get_failed_login_count () {
$session = Registry :: get ( 'session' );
$n = $session -> get ( 'failed_logins' );
if ( $n == '' ) { $n = 0 ; }
return $n ;
}
public function increment_failed_login_count ( $n = 0 ) {
$session = Registry :: get ( 'session' );
$n = $session -> get ( 'failed_logins' ) + 1 ;
$session -> set ( 'failed_logins' , $n );
}
2013-10-16 14:55:17 +02:00
private function is_ga_code_needed () {
$session = Registry :: get ( 'session' );
$query = $this -> db -> query ( " SELECT ga_enabled FROM " . TABLE_USER_SETTINGS . " WHERE username=? " , array ( $session -> get ( " username " )));
if ( isset ( $query -> row [ 'ga_enabled' ]) && $query -> row [ 'ga_enabled' ] == 1 ) {
$session -> set ( " ga_block " , 1 );
}
}
2012-06-22 15:22:02 +02:00
public function change_password ( $username = '' , $password = '' ) {
2012-02-08 23:14:28 +01:00
if ( $username == " " || $password == " " ){ return 0 ; }
$query = $this -> db -> query ( " UPDATE " . TABLE_USER . " SET password=? WHERE username=? " , array ( crypt ( $password ), $username ));
$rc = $this -> db -> countAffected ();
return $rc ;
}
}
?>