vTiger CRM 6 Active Directory Authentication

Thank to http://adminberlin.de/vtiger-crm-6-active-directory-authentication/

vTiger CRM is prepared to authenticate users from LDAP or Active Directory. But this feature massively hidden, as it seems. The following article describes the configuration in detail.

Environment

I’ve tested this with vTiger CRM 6.0.0 on CentOS 6.5.
The Active Directory is in 2012R2 mode, operated by two Windows Server 2012 R2 domain controllers.

Requirements

First of all you need ldap support for php.

1 yum install php-ldap openldap (RHEL)
2 aptitude install php5-ldap ldap-client (DEBIAN)

adLDAP Module

Active Directory support in vTiger CRM is based on the adLDAP module. It provides Active Directory connectivity out of the box.

Project Website: http://adldap.sourceforge.net/download.php

Installation

Assuming your vTiger CRM installations www-root is /var/www/html/crm, do the following to install adLDAP support:

1 wget http://downloads.sourceforge.net/project/adldap/adLDAP/adLDAP_4.0.4/adLDAP_4.0.4r2.zip
2 unzip adLDAP_4.0.4r2.zip
3 cd adLDAP/src
4 mkdir -p /var/www/html/crm/modules/Users/authTypes/
5 cp -R * /var/www/html/crm/modules/Users/authTypes/
6 chown -R root:root /var/www/html/crm/modules/Users/authTypes/

Configuration

adLDAP is configured directly in the adLDAP.php class (ugh!). Just open and customize the settings for your needs. The following settings match those needed for a 2012R2 Active Directory.

001 ...
002 class adLDAP {
003
004     /**
005      * Define the different types of account in AD
006      */
007     const ADLDAP_NORMAL_ACCOUNT = 805306368;
008     const ADLDAP_WORKSTATION_TRUST = 805306369;
009     const ADLDAP_INTERDOMAIN_TRUST = 805306370;
010     const ADLDAP_SECURITY_GLOBAL_GROUP = 268435456;
011     const ADLDAP_DISTRIBUTION_GROUP = 268435457;
012     const ADLDAP_SECURITY_LOCAL_GROUP = 536870912;
013     const ADLDAP_DISTRIBUTION_LOCAL_GROUP = 536870913;
014     const ADLDAP_FOLDER = 'OU';
015     const ADLDAP_CONTAINER = 'CN';
016
017     /**
018     * The default port for LDAP non-SSL connections
019     */
020     const ADLDAP_LDAP_PORT = '389';
021     /**
022     * The default port for LDAPS SSL connections
023     */
024     const ADLDAP_LDAPS_PORT = '636';
025
026     /**
027     * The account suffix for your domain, can be set when the class is invoked
028     *
029     * @var string
030     */
031         protected $accountSuffix "@cortoso.com";
032
033     /**
034     * The base dn for your domain
035     *
036     * If this is set to null then adLDAP will attempt to obtain this automatically from the rootDSE
037     *
038     * @var string
039     */
040         protected $baseDn "";
041
042     /**
043     * Port used to talk to the domain controllers.
044     *
045     * @var int
046     */
047     protected $adPort = self::ADLDAP_LDAP_PORT;
048     /**
049     * Array of domain controllers. Specifiy multiple controllers if you
050     * would like the class to balance the LDAP queries amongst multiple servers
051     *
052     * @var array
053     */
054     protected $domainControllers array("dc01.cortoso.com""dc02.cortoso.com");
055
056     /**
057     * Optional account with higher privileges for searching
058     * This should be set to a domain admin account
059     *
060     * @var string
061     * @var string
062     */
063     protected $adminUsername "ldap-binduser";
064     protected $adminPassword "super-password";
065
066     /**
067     * AD does not return the primary group. http://support.microsoft.com/?kbid=321360
068     * This tweak will resolve the real primary group.
069     * Setting to false will fudge "Domain Users" and is much faster. Keep in mind though that if
070     * someone's primary group is NOT domain users, this is obviously going to mess up the results
071     *
072     * @var bool
073     */
074         protected $realPrimaryGroup = false;
075
076     /**
077     * Use SSL (LDAPS), your server needs to be setup, please see
079     *
080     * @var bool
081     */
082         protected $useSSL = false;
083
084     /**
085     * Use TLS
086     * If you wish to use TLS you should ensure that $useSSL is set to false and vice-versa
087     *
088     * @var bool
089     */
090     protected $useTLS = true;
091
092     /**
093     * Use SSO
094     * To indicate to adLDAP to reuse password set by the brower through NTLM or Kerberos
095     *
096     * @var bool
097     */
098     protected $useSSO = false;
099
100     /**
101     * When querying group memberships, do it recursively
102     * eg. User Fred is a member of Group A, which is a member of Group B, which is a member of Group C
103     * user_ingroup("Fred","C") will returns true with this option turned on, false if turned off
104     *
105     * @var bool
106     */
107         protected $recursiveGroups = true;
108
109     ...
110 ?>

 Hints

  • configure multiple domain-controllers to prevent SPOFs
  • configured hostnames for your domain-controllers and common names in their SSL certificates have to match to prevent SSL trust errors
  • use TLS to ensure encrypted transport of user account data
  • create a special user for ldap binding, without any further permissions and with unlimited password validity (configure it in adLDAP with AdminUsername andAdminPassword parameters)

OpenLDAP Configuration

If you use SSL or TLS, it is absolutely necessary that your openldap trusts the domain controllers and their certificates. Make sure that you have a corporate certificate authority and issue certificates for all of your domain controllers. (Sounds horrible but is quite easy if you just install a Active Directory integrated certificate authority as Windows Server role.) You will need to export the certificate and import it for openssl.

Export CA Certificate

Use Windows Certificate Mangement Console to export the CA certificate base-64 encoded. If you installed the ca web management feature, just visit: http://your-dc/certsrv/certcarc.asp, choose base-64 format and click “Download CA certificate”.

Import CA Certificate for OpenLDAP

On RHEL-based systems OpenLDAP uses a default dir at /etc/openldap/certs to store trustable ca certificates in it. Just put the exported certificate file there.

Ensure that the path is configured in /etc/openldap/ldap.conf (RHEL) or /etc/ldap/ldap.conf (Debian). Either as file or folder. (Sometimes the folder configuration doesn’t work)

1 TLS_CACERT /etc/openldap/certs/cortoso-ca.cer
2 TLS_CACERTDIR /etc/openldap/certs/

Test adLDAP

Ldapsearch

With ldapsearch you can test the functionality of encrypted LDAP f.e. by:

1 root@crm:~# ldapsearch -H "ldaps://dc01.cortoso.com" -b "" -s base -Omaxssf=0
2 SASL/EXTERNAL authentication started
3 ldap_sasl_interactive_bind_s: Unknown authentication method (-6)
4     additional info: SASL(-4): no mechanism available:

TLS connection is established but we havn’t supplied auth. OK so far. If you face any problems, add “-d7″ to get some debugging output.

PHP Testscript

To be able to test adLDAP, it is much easier to write a small php sniplet than doing it directly with vTiger CRM. Just create a small adldap_test.php file, in the same directory where adLDAP.php resides, with following content:

01 <?php
02
03 require_once(dirname(FILE) . '/adLDAP.php');
04
05 try {
06     $adldap new adLDAP();
07 }
08
09 catch (adLDAPException $e) {
10     echo $e;
11     exit();
12 }
13 $authUser $adldap->authenticate('user-to-authenticate''users-password');
14 if ($authUser == true) {
15   echo "User authenticated successfully";
16 }
17 else {
18   // getLastError is not needed, but may be helpful for finding out why:
19   echo "\n";
20   echo $adldap->getLastError();
21   echo "\n";
22
23   echo "User authentication unsuccessful";
24 }
25
26 echo "\n";
27 $result=$adldap->user()->infoCollection('ldap'array("*"));
28 echo "User:\n";
29 echo $result->displayName;
30 echo "Mail:\n";
31 echo $result->mail;
32
33 ?>

Replace user and password for the user you want to test authentication for and execute it on the shell:

1 php adldap_test.php

It should state success and output the username and mail address if available.

To make sure it is also working in Apache Webserver context, you may also open it in a browser or use curl to test it:

1 curl http://10.10.0.2/crm/modules/Users/authTypes/adldap_test.php

vTiger CRM Configuration

vTiger needs local users for every active directory user being allowed to log in this way. This is needed to have a internal user entity for those “remote-users”. First of all login as admin user and create a local account for an ad user being allowed to administrate your vTiger CRM. The password doesn’t matter at all, since the user is authenticated by AD. You could use the domain administrator account, which would require to create a user named “administrator”.

Afterwards enable vTiger CRM to use AD authentication by modifying /var/www/html/crm/config.php

1 <?php
2    include('config.inc.php');
3    $AUTHCFG['authType'] = 'AD';
4 ?>

 

Finally you should be able to login with a user you already created locally.