Author Topic: Ldap authentication + identity with ldap fields  (Read 9571 times)

Offline jfsenechal

  • Newbie
  • *
  • Posts: 7
Ldap authentication + identity with ldap fields
« on: February 17, 2011, 08:58:55 AM »
Hello,

Because ldap plugins are obsolete
Plugin_Repository ? Roundcube Webmail

I have rewrite the plugin ldap_authentication for round 0.5

So I share with you

this is a beta version, be cool with this ;)


Code: [Select]
<?php
//config.inc.php

/* 17/02/2011 -
  Get users/identities from an LDAP directory
  Inspired by plugin ldap_authentication  
 */

$rcmail_config['ldap_hostname'] = 'ldap.domain.be';
$rcmail_config['ldap_bind_username'] = '';
$rcmail_config['ldap_bind_password'] = '';
$rcmail_config['ldap_base_dn'] = 'ou=Users,ou=Group,dc=domain,dc=be';

$rcmail_config['use_tls'] = false;
//does check bind ldap with username and password given by user ?
$rcmail_config['use_authentication'] = false;

// %u is the query for login user (or email!)
$rcmail_config['ldap_filter'] = 'uid=%u';

/*
 * field for create user
 */

$rcmail_config['ldap_create_uid'] = 'uid';
#if more one element, merge the 2 fields
$rcmail_config['ldap_create_name'] = array('cn','sn'); #can array(givenName)
$rcmail_config['ldap_create_email'] = 'mail';

?>


« Last Edit: February 17, 2011, 09:08:22 AM by jfsenechal »

Offline jfsenechal

  • Newbie
  • *
  • Posts: 7
Ldap authentication + identity with ldap fields
« Reply #1 on: February 17, 2011, 09:03:31 AM »
Grrrrrrrrrrrrr

Tooo short maximum characters ! :mad:

Offline jfsenechal

  • Newbie
  • *
  • Posts: 7
Ldap authentication + identity with ldap fields
« Reply #2 on: February 17, 2011, 09:04:21 AM »
My class in two thread :mad:

Code: [Select]
<?php

/**
 * LDAP Authentication
 *
 * This plugin replaces the RoundCube login page with authentication requests
 * to a LDAP server, which enables logging into RoundCube with identities
 * authenticated by the LDAP server 
 *
 * @version 0.1
 * @author jf
 * 
 */
class ldap_authentication extends rcube_plugin {
    
/*
     * Connection and bind default variables
     * 
     * @var mixed
     * @var mixed
     */

    
private $ldap_inited false;
    private 
$_conn false;
    private 
$_bind false;
    protected 
$_use_tls false;
    protected 
$_ldap_bind_username NULL;
    protected 
$_ldap_bind_password NULL;
    protected 
$_use_authentication false;
    protected 
$_base_dn = &quot;DC=mydomain,DC=local&quot;;
    protected 
$_ldap_hostname = &quot;ldap.mydomain.be&quot;;

    
/**
     * Initialize plugin
     *
     */
    
function init() {

        
$ldap_inited false;

        
// load plugin configurations
        
$this->load_config();
        
        
// add application hooks
        
$this->add_hook('authenticate', array($this'authenticate'));
        
$this->add_hook('user_create', array($this'user_create'));
        
$this->add_hook('login_failed', array($this'login_failed'));
    }

    
/**
     * Inject authentication credentials
     *
     * @param array $args arguments from rcmail
     * @return array modified arguments
     */
    
function authenticate($args) {

        
// retrieve configurations
        
$rcmail rcmail::get_instance();
        
$cfg $rcmail->config->all();

        
// initialize ldap client
        
$this->ldap_init($cfg);
        
        
/*
         * if you want to check ldap user valid
         */
        
        
if ($this->_use_authentication) {
            
$this->_bind = @ldap_bind($this->_conn$args['user'], $args['pass']);
            return 
false;
        }

        return 
$args;
    }

    
/*
     * When a somebody logs in the first time and a local user is created.
     */

    
function user_create($args) {

        
$rcmail rcmail::get_instance();
        
$attributes = array($rcmail->config->get('ldap_create_uid'), $rcmail->config->get('ldap_create_email'));
        
$attributes array_merge($attributes$rcmail->config->get('ldap_create_name'));

        if(!
$this->_conn) return false;

        
$res ldap_search($this->_conn,
                        
$rcmail->config->get('ldap_base_dn'),
                        
preg_replace('/%u/'$args['user'], $rcmail->config->get('ldap_filter')), $attributes);

        if (!
$res)
            
ldapException(&quot;Error in search query &quot; . $this->get_last_error() . $e->getMessage());

        try {
            
$rows ldap_get_entries($this->_conn$res);

            if (
$rows[&quot;count&quot;] == OR !$rows) {
                new 
ldapException(&quot;user &quot; . $args['user'] . &quotnot found with query &quot; . $rcmail->config->get('ldap_filter') . &quot;And params : &quot; . $this->_conn .
                                &
quot;Base  :&quot; . $rcmail->config->get('ldap_base_dn') .
                                
preg_replace('/%u/'$args['user'], $rcmail->config->get('ldap_filter')) . &quotAttributes: &quot;);
                new 
ldapException($attributes);
            }

            
$userName '';
            foreach (
$rcmail->config->get('ldap_create_name') as $val) {
                
$userName .= $rows[0][$val][0] . ' ';
            }

            
$userName trim($userName);

            
$args['user'] = $rows[0][$rcmail->config->get('ldap_create_uid')][0];
            
$args['user_name'] = $userName;
            
$args['user_email'] = $rows[0][$rcmail->config->get('ldap_create_email')][0];
        } catch (
ldapException $e) {
            
ldapException(&quot;Error in search query &quot; . $this->get_last_error());
        }

        return 
$args;
    }

    
/**
     * Intercept login failure
     *
     * @param array $args arguments from rcmail
     * @return array modified arguments
     */
    
function login_failed($args) {
        
// retrieve rcmail instance
        
$rcmail rcmail::get_instance();

        
// compose error page content
        
global $__page_content$__error_title$__error_text;
        
$__error_title = &quot;LDAP LOGIN FAILED&quot;;
        
$__error_text = <<<EOF
Could not log into your LDAP service. The service may be interrupted, or you may not be authorized to access the service.<br />
Please contact the administrator.<br />
EOF;
        
$__page_content = <<<EOF
<div>
<h3 class=&quot;error-title&quot;>
$__error_title</h3>
<p class=&quot;error-text&quot;>
$__error_text</p>
</div>
EOF;
        
        
// redirect to error page
        
$rcmail->output->reset();
        
$rcmail->output->send('error');

        
// kill current session
        
$rcmail->kill_session();

        
// end script
        
exit;
    }    

    
/**
     * Set the domain controllers array
     *
     * @param array $_domain_controllers
     * @return void
     */
    
public function set_ldap_hostname(array $_ldap_hostname) {
        
$this->_ldap_hostname $_ldap_hostname;
    }

    
/**
     * Get the list of domain controllers
     *
     * @return void
     */
    
public function get_ldap_hostname() {
        return 
$this->_ldap_hostname;
    }

    
/**
     * Set the username of an account with higher priviledges
     *
     * @param string $_dn_username
     * @return void
     */
    
public function set_ldap_bind_username($_ad_username) {
        
$this->_ldap_bind_username $_ldap_bind_username;
    }

    
/**
     * Get the username of the account with higher priviledges
     *
     * This will throw an exception for security reasons
     */
    
public function get_ldap_bind_username() {
        throw new 
ldapException('For security reasons you cannot access the domain administrator account details');
    }

    
/**
     * Set the password of an account with higher priviledges
     *
     * @param string $_dn_password
     * @return void
     */
    
public function set_ldap_bind_password($_ad_password) {
        
$this->_ldap_bind_password $_ldap_bind_password;
    }

    
/**
     * Get the password of the account with higher priviledges
     *
     * This will throw an exception for security reasons
     */
    
public function get_ldap_bind_password() {
        throw new 
ldapException('For security reasons you cannot access the domain administrator account details');
    }

    
/**
     * Set whether to use SSL
     *
     * @param bool $_use_ssl
     * @return void
     */
    
public function set_use_ssl($_use_ssl) {
        
$this->_use_ssl $_use_ssl;
    }

    
/**
     * Get the SSL setting
     *
     * @return bool
     */
    
public function get_use_ssl() {
        return 
$this->_use_ssl;
    }

    
/**
     * Set whether to use TLS
     *
     * @param bool $_use_tls
     * @return void
     */
    
public function set_use_tls($_use_tls) {
        
$this->_use_tls $_use_tls;
    }

    
/**
     * Get the TLS setting
     *
     * @return bool
     */
    
public function get_use_tls() {
        return 
$this->_use_tls;
    }

    
/**
     * Set whether to use authentication
     *
     * @param bool $_use_authentication
     * @return void
     */
    
public function set_use_authentication($_use_authentication) {
        
$this->_use_authentication $_use_authentication;
    }

    
/**
     * Get the use authentication setting
     *
     * @return bool
     */
    
public function get_use_authentication() {
        return 
$this->_use_authentication;
    }

Offline jfsenechal

  • Newbie
  • *
  • Posts: 7
Ldap authentication + identity with ldap fields
« Reply #3 on: February 17, 2011, 09:05:00 AM »
Code: [Select]
<?php
private function ldap_init($cfg) {

        if (!
$this->ldap_inited) {
            
// retrieve configurations            

            
if (array_key_exists(&quot;base_dn&quot;, $cfg)) {
                
$this->_base_dn $cfg[&quot;base_dn&quot;];
            }
            if (
array_key_exists(&quot;ldap_hostname&quot;, $cfg)) {
                
$this->_ldap_hostname $cfg[&quot;ldap_hostname&quot;];
            }
            if (
array_key_exists(&quot;dn_username&quot;, $cfg)) {
                
$this->_dn_username $cfg[&quot;dn_username&quot;];
            }
            if (
array_key_exists(&quot;dn_password&quot;, $cfg)) {
                
$this->_dn_password $cfg[&quot;dn_password&quot;];
            }
            if (
array_key_exists(&quot;use_tls&quot;, $cfg)) {
                
$this->_use_tls $cfg[&quot;use_tls&quot;];
            }
            if (
array_key_exists(&quot;use_authentication&quot;, $cfg)) {
                
$this->_use_authentication $cfg[&quot;use_authentication&quot;];
            }

            
$ldap_inited true;
        }

        return 
$this->connect();
    }

    public function 
connect() {

        
$dc $this->_ldap_hostname;

        if (
$this->_use_ssl) {
            
$this->_conn ldap_connect(&quot;ldaps://&quot; . $dc, 636);
        
} else {
            
$this->_conn ldap_connect($dc);
        }

        if (
is_resource($this->_conn)) {
            
// Set some ldap options for talking to AD
            
ldap_set_option($this->_connLDAP_OPT_PROTOCOL_VERSION3);
            
ldap_set_option($this->_connLDAP_OPT_REFERRALS0);

            if (
$this->_use_tls) {
                
ldap_start_tls($this->_conn);
            }

            
// Bind as a domain admin if they've set it up
            
if ($this->_ldap_bind_username != NULL && $this->_ldap_bind_password != NULL) {
                
$this->_bind = @ldap_bind($this->_conn$this->_ldap_bind_username$this->_ldap_bind_password);

                if (!
$this->_bind) {
                    if (
$this->_use_ssl && !$this->_use_tls) {
                        
// If you have problems troubleshooting, remove the @ character from the ldap_bind command above to get the actual error message
                        
throw new ldapException('Bind to ldap failed. Either the LDAPs connection failed or the login credentials are incorrect. Said: ' $this->get_last_error());
                    } else {
                        throw new 
ldapException('Bind to ldap failed. Check the login credentials and/or server details. Said: ' $this->get_last_error());
                    }
                }
            }
            return (
true);
            
//catch error doesn't work !!
        
} else {
            
$error = &quot;Can't connect to serveur ldap &quot; . $dc . &quot; Error : &quot; . $e->getMessage();
            new ldapException($error);
            return false;
        }
    }

    public function get_last_error() {
        return @ldap_error($this->_conn);
    }

}

class ldapException extends Exception {

    public function ldapException($error) {
        write_log(&quot;ldap_authentication.log&quot;, $error);        
    }

}

?>


Offline SKaero

  • Administrator
  • Hero Member
  • *****
  • Posts: 5,879
    • SKaero - Custom Roundcube development
Ldap authentication + identity with ldap fields
« Reply #4 on: February 17, 2011, 01:17:25 PM »
I'd advise creating a zip of the plugin and attaching it to this thread.

Offline jfsenechal

  • Newbie
  • *
  • Posts: 7
Ldap authentication + identity with ldap fields
« Reply #5 on: February 18, 2011, 04:22:05 AM »
Quote

I'd advise creating a zip of the plugin and attaching it to this thread.


Ok I don't see this option

Offline jml

  • Newbie
  • *
  • Posts: 1
ldap authentication
« Reply #6 on: March 17, 2011, 06:59:23 AM »
Hello,
 we're trying to use your plugin in order to do ldap authentication, and we have several questions:
- how to be sure that this plugin is effective BEFORE imap authentication ? log file ? howto ?
- we use an SSL (port 636) only ldap server with certificates, how to configure the plugin in order to do that ?
thank you for help,
Best regards,
JM

Offline jfsenechal

  • Newbie
  • *
  • Posts: 7
Ldap authentication + identity with ldap fields
« Reply #7 on: March 18, 2011, 05:11:46 AM »
Quote

- how to be sure that this plugin is effective BEFORE imap authentication ? log file ? howto ?


It's explain in the wiki :

Plugin_Hooks ? Roundcube Webmail

Quote

we use an SSL (port 636) only ldap server with certificates, how to configure the plugin in order to do that ?


In config.inc.php

set protected $_use_tls = false  to true

Offline mattzyzy

  • Newbie
  • *
  • Posts: 6
Ldap authentication + identity with ldap fields
« Reply #8 on: April 13, 2011, 10:08:56 AM »
I tried using your codes but still fail / not able to log in using the LDAP uid and password  -after hit the login button (using new uid/username account), after 3-4 seconds return only blank screen .
but , if I used the IMAP login username account that successfully logged in before the ldap_auth plugin setup(registered in mysql users table), it is OK.

If I try some gibberish /unexisted username/uid and wrong password it returns the correct/expected error -which means LDAP server is succesfully connected:" LDAP LOGIN FAILED
Could not log into your LDAP service. The service may be interrupted, or you may not be authorized to access the service.
Please contact the administrator. "

Any help would be welcome.
Thank you.

My setup in main.inc.php using RC 0.5.1
 
Quote
$rcmail_config['ldap_hostname'] = '212.33.22.22';
$rcmail_config['ldap_bind_username'] = '';
$rcmail_config['ldap_bind_password'] = '';
$rcmail_config['ldap_base_dn'] = 'ou=People,o=mail.co,o=gov';

$rcmail_config['use_tls'] = false;
$rcmail_config['use_authentication'] = true;

$rcmail_config['ldap_filter'] = 'uid=%u';
$rcmail_config['ldap_create_uid'] = 'uid';
$rcmail_config['ldap_create_name'] = array('cn','sn');
$rcmail_config['ldap_create_email'] = 'mail';