Active Directory Integration – Multiple Roles

Warning
This plugin has been replaced by the developers and natively supports multiple roles. Download here: https://wordpress.org/plugins/next-active-directory-integration/

There is fantastic plugin called Active Directory Integration that I use at my workplace to authenticate users with our Active Directory. This also allows me to map AD Group Membership to WP roles, which comes in crazy handy. The catch is that it only assigns the user a SINGLE role, when I have complex permissions that required many users to have multiple roles. So I made some alterations as of March 2016 that fixes this shortcoming. I’ll go through the steps that I took, but if you don’t care then just download the zip file below and upload that to your site.

Custom Active Directory Plugin

All of my edits were to a file called ad-integration.php

Basically, this one file is the vast majority of what makes this plugin tick.

On line 3022, you see this function which pulls the roles from Active Directory:


protected function _get_user_role_equiv($ad_username) {
	
	$role_equiv_groups = explode(';', $this->_role_equivalent_groups);
	
	$user_role = '';
	foreach ($role_equiv_groups as $whatever => $role_group)
	{
			$role_group = explode('=', $role_group);
			if ( count($role_group) != 2 )
			{
				continue;
			}
			$ad_group = $role_group[0];
				
			$corresponding_role = $role_group[1];
			if ( $this->_adldap->user_ingroup($ad_username, $ad_group, true ) )
			{
				$user_role = $corresponding_role;
				break;
			}
	}
	return $user_role;
}

As you may notice, this function treats the role as a string and the second if statement breaks the function upon finding a match. I changed the function to add all the roles to an array as follows:


protected function _get_user_role_equiv($ad_username) {
	
	$role_equiv_groups = explode(';', $this->_role_equivalent_groups);
	
	$user_role = array();
	foreach ($role_equiv_groups as $whatever => $role_group)
	{
			$role_group = explode('=', $role_group);
			if ( count($role_group) != 2 )
			{
				continue;
			}
			$ad_group = $role_group[0];
			
			$corresponding_role = $role_group[1];
			if ( $this->_adldap->user_ingroup($ad_username, $ad_group, true ) )
			{
				$user_role[] = $corresponding_role;
			}
	}
	return $user_role;
}

On line 863, you need to change this:


if ($this->_auto_create_user || trim($user_role) != '' )

to this:

if ($this->_auto_create_user || count($user_role) != '' )

The count function is simply telling the plugin that the roles exist. You could also just delete the trim part if you aren’t concerned with being a little sloppy.

On lines 2558 and lines 2713, you have two similar functions called like this:


protected function _create_user($username, $userinfo, $display_name, $role = '', $password = '', $bulkimport = false)

protected function _update_user($username, $userinfo, $display_name='', $role = '', $password = '', $bulkimport = false)

In both cases, you need to delete the equal sign and quotations after $role since we are no longer treating that as a string.

Lastly, we need to find the portion of the code that actually assigns the roles to the user and change it to accept all the values out of the array. It turns out that this part of the code is actually located in two places(2662 and 2787). In both cases, you’re looking for this bit:


// set role
if ( $role != '' ) 
{
	$roles = new WP_Roles();
	if ($roles->is_role($role)) { // Updates role only if role exists
		wp_update_user(array('ID' => $user_id, 'role' => $role));
	} else {
		$this->_log(ADI_LOG_WARN, 'Role "' . $role . '" currently does not exist in WordPress. Role of "' . $username . '" is not set.');
	}
}

For the function _create_user change the segment above to:


// set role
$roles = new WP_User($user_id);
foreach($role as $value){
	$roles->add_role($value);
}

For the function _update_user change the segment above to:


// set role
$remove = '';
$roles = new WP_User($user_id);
$roles->set_role($remove);
foreach($role as $value){
	$roles->add_role($value);
}

The only difference between these two functions is that _update_user clears the roles before setting them again. This removes outdated roles after making changes in Active Directory.

If you stare at code all day like myself, you may have noticed I removed the check that verifies that a role actually exists before assigning it. I could recreate that check for the array, but I really don’t feel like it.

I’ve been using my custom version of the plugin for a while now without incident. Use at your own risk.

Comments 8

  1. Hi RYAN, Great modification!

    Short question, i’m using it inside our company.
    It ads more dan one AD group to a local wordpress user, but when I remove a user from an AD group it wo’nt be removed from te wordpress user after a re logon. What am I doing wrong or does this simply not work like this?

    Thanks,
    Tom

    1. Post
      Author
  2. Hi

    I’m having trouble with the Authorization by Group Membership. I get this error with the test tool:

    [DEBUG] USER GROUPS:Array
    (
    )

    [WARN] Authorization by group failed. User is not authorized.

    And won’t allow logins if enabled. Is this something that is obviously wrong in the code?

  3. Post
    Author

    I authorize by Group Membership just fine. Note that authorize by group membership shouldn’t look like the Role Equivalent Groups. Only type the exact name of the group as it is in AD.

  4. Hi Ryan,

    I’m having an issue with the updated AD plugin. Each time a user logs in to the site it changes their role to “None”. Administrator no longer have access to the admin section. Any ideas what the issue could be?

    Thanks!

    1. Post
      Author

      Every time a user logs in, my plugin mod sets their role to none then adds the roles specified by the Role Equivalent Groups. That ensures that it’s always up to date. My best guess is that your Role Equivalent Groups field is filled out incorrectly. Try using the regular plugin that isn’t modified and make sure that it properly assigns users to a role.

Leave a Reply

Your email address will not be published. Required fields are marked *