Ldap group configuration - Derive from attribute
I've handled this by calling a update user account function during validation against the AD.

First fetch the attributes of that account:

$filter = "(sAMAccountName=" . $username . ")";
// This is where you will need to add in extensionattribute14.
$attributes = array('sAMAccountName', 'givenName', 'sn', 'description', 'telephoneNumber', 'userAccountControl', 'distinguishedName', 'memberOf', 'proxyAddresses', 'Mobile', 'facsimileTelephoneNumber', 'mail', 'employeeNumber');
$result = ldap_search($conn, $ldap_base_dn, $filter, $attributes) or exit("Unable to search LDAP server");
$entries = ldap_get_entries($conn, $result);
$entryid = ldap_first_entry($conn, $result);
$attrs = ldap_get_attributes($conn, $entryid);


And then then call the update account function ($attrs from above is passed in as $values):

/**
 * Makes updates to the users account based on values passed from the AD
 * @param  object $account
 * @param  array $values
 */
function update_user_account($account, $values) {

    // ...
    // Code here to update other values from the AD
    // ...

    if(isset($values['memberOf'])) {

        // Loop over groups.
        foreach($values['memberOf'] as $k =&gt; $group_dn) {

            switch($group_dn) {
                case 'CN=GRPHO Intranet Editor,OU=Groups - Restricted,DC=universe,DC=int':
                    $updates['roles'][8] = 'Editor';
                    break;
                case 'CN=GRPHO Intranet User Editor,OU=Groups - Restricted,DC=universe,DC=int':
                    $updates['roles'][9] = 'User Editor';
                    break;

                // etc. etc.

            }

        }
    }

    // add back in any roles that this user had that are not controlled from the AD
    if(isset($account-&gt;roles[3])) $updates['roles'][3] = 'administrator';
    if(isset($account-&gt;roles[15])) $updates['roles'][15] = 'site admin';

    user_save($account, $updates);

}