LDAP Group Authentication with SugarCRM

Written on March 31, 2012 by Allan Lykke Christensen

For those of you who follow me on Twitter, you know that I’m not very pleased about the whole architecture and documentation of SugarCRM. Sugar is great out of the box, but if you try to do something slightly advanced it quickly becomes very troublesome. Anyway, this post is not to complain about SugarCRM, instead I wanted to show how set-up Sugar to authenticate users based on an LDAP server containing user groups.

Use Case

One of my clients is a medium-size media house with about 500 employees. 100 of those work in sales and customer relations. I was asked by my client to configure SugarCRM so that new users accounts would not need to be set-up for the 100 sales staff. Also, it was necessary that the other 400 staff do not get access to system. The client is using Microsoft Active Directory to authenticate users on the network and would like to reuse it for SugarCRM.

Implementation

The Active Directory is structured in the following way:

  • Users reside in the tree DC=mediacompany,DC=com
  • Groups reside in the tree OU=GROUPS,DC=mediacompany,DC=com

Step 1) Creating a CRM group on the LDAP server

Since access should be limited to a group of users, we’ll start by creating a group on the Active Directory called CRM where all the sales and customer relations staff are added. This group is called crm.

DN: CN=crm,OU=GROUPS,DC=mediacompany,DC=com

Step 2) Enabling LDAP Authentication

In SugarCRM, go to Administration and click Password Management. Scroll down to the bottom of the page and click “Enable LDAP Authentication”

The fields that must be filled out to enable LDAP Authentication

You can set-up Sugar’s LDAP authentication to allow any user residing on an LDAP server to be able to log-in, or you can set it up to only allow users in a particular group to log-in. In our use case I need it to check that the user is in a particular group (crm) before allowing them access.

Step 3) Specifying the LDAP server details

In the field “Server” we specific the address of the LDAP server prefixed with ldap:// (or ldaps:// for secure access). E.g.   ldap://172.16.20.1

In the field “Port” we specific the port that the LDAP server is bound to, E.g. 389

Tick the checkbox field “Authentication” at the bottom of the page. This is necessary for must Active Directory servers as you need an administrative user that can do the look ups in the directory. Enter the username (DN) of the user and the matching password. E.g. CN=Administrator,DC=mediacompany,DC=com as the username

Tick the checkbox field “Auto Create Users”. This will automatically create a SugarCRM for any user that has a valid account on Active Directory upon their first login. If you don’t tick this field you’ll have to still create the users one-by-one in Sugar.

Step 4) Specifying how to retrieve users

In the field User DN we specific the tree containing the users. If you have users stored in different leafs you can specific the base DN of your directory. In our case we use DC=mediacompany,DC=com as our User DN

In the field User Filter, we can specific a filter that should be used to filter users based on an attribute on your LDAP profile. Since we will use groups we can leave the User Filter empty.

In the field Bind Attribute enter the field that should be used to bind with the directory. In the case of Active Directory this field is userPrincipalName.

In the field Login Attribute enter the field that should be used as the username for logging into Sugar. I prefer that the name is the same as the username used for logging into machines on the network. In the case of Active Directory this field is sAMAccountName.

If you don’t want to authenticate against a particular user group you can skip the next step and save your settings and start authenticating against active users.

Step 5) Specifying how to retrieve groups and relate them to users

Tick the checkbox field “Group Membership”.

In the field Group DN you specify the tree containing all your groups. In our case this value is OU=GROUPS,DC=mediacompany,DC=com.

In the field Group Name you specific the name of the group that users must be a “member of” to be able to log-in. In our case this value is CN=crm (It’s important to remember the CN or whichever value you’ve chosen for the identifier of the group).

In the field User Attribute you specific the name of the attribute on the user record that will match with the member attribute on the Group record. In our case we store the complete distinguished name (DN) of the user in the record, and the value is therefore dn as this field contains the full distinguished name of a member.

In the field Group Attribute you specific the name of the field that contains the distinguished name of each member. In many LDAP servers the field uniqueMember is used, but on Active Directory the field member is used. Browse your LDAP directory to determine the field names to use.

That’s it! Well, not exactly, cause there is a bug in the codebase of SugarCRM. Actually it would all work up till when you specify the group membership. See the next step

Step 6) Patching the LDAP Group Membership code

This example is based on SugarCRM 6.4.0. It should work on previous versions as well. I’m not sure when they will fix the bug in in the code base, so you might find that this patch works in newer versions as well.

The problem is in the file LDAPAuthenticateUser.php located in modules/Users/authentication/LDAPAuthenticate in line 149.

The line says:

if(!isset($user_uid[0]) || ldap_count_entries($ldapconn, ldap_search($ldapconn,$GLOBALS['ldap_config']->settings['ldap_group_name'] . ",". $GLOBALS['ldap_config']->settings['ldap_group_dn']  ,"($group_attr=" . $user_uid[0] . ")")) ==  0){

Notice in the end of the line where it says

"($group_attr=" . $user_uid[0] . ")

The problem is that $user_uid[0] is not an array, it is a string containing the distinguished name of a user, e.g. CN=Allan Lykke Christensen,DC=mediacompany,DC=com. When you try to access a string as if it was an array, it will give you the character at the position, e.g. $user_uid[0] would return C in the example above. The fix is to remove [0] from $user_uid like so:

if(!isset($user_uid[0]) || ldap_count_entries($ldapconn, ldap_search($ldapconn,$GLOBALS['ldap_config']->settings['ldap_group_name'] . ",". $GLOBALS['ldap_config']->settings['ldap_group_dn']  ,"($group_attr=" . $user_uid . ")")) ==  0){

That’s it! Hope it’s been helpful.

LDAP Settings for Active Directory

If you enjoyed this post Subscribe to our feed