diff --git a/enrol/database/lang/en/enrol_database.php b/enrol/database/lang/en/enrol_database.php
index b423c7b..0cd82a0 100644
--- a/enrol/database/lang/en/enrol_database.php
+++ b/enrol/database/lang/en/enrol_database.php
@@ -60,6 +60,8 @@ $string['remotecoursefield'] = 'Remote course field';
 $string['remotecoursefield_desc'] = 'The name of the field in the remote table that we are using to match entries in the course table.';
 $string['remoteenroltable'] = 'Remote user enrolment table';
 $string['remoteenroltable_desc'] = 'Specify the name of the table that contains list of user enrolments. Empty means no user enrolment sync.';
+$string['remotehiddenfield'] = 'Remote hidden field';
+$string['remotehiddenfield_desc'] = 'The name of the field in the remote table that we are using to flag "Other User" role assignments.';
 $string['remoterolefield'] = 'Remote role field';
 $string['remoterolefield_desc'] = 'The name of the field in the remote table that we are using to match entries in the roles table.';
 $string['remoteuserfield'] = 'Remote user field';
diff --git a/enrol/database/lib.php b/enrol/database/lib.php
index 286bb00..1a0bd90 100644
--- a/enrol/database/lib.php
+++ b/enrol/database/lib.php
@@ -107,6 +107,7 @@ class enrol_database_plugin extends enrol_plugin {
         $coursefield      = strtolower($this->get_config('remotecoursefield'));
         $userfield        = strtolower($this->get_config('remoteuserfield'));
         $rolefield        = strtolower($this->get_config('remoterolefield'));
+        $hiddenfield      = strtolower($this->get_config('remotehiddenfield'));
 
         $localrolefield   = $this->get_config('localrolefield');
         $localuserfield   = $this->get_config('localuserfield');
@@ -136,6 +137,7 @@ class enrol_database_plugin extends enrol_plugin {
             $roles[$role->$localrolefield] = $role->id;
         }
 
+        $role_assigns = array();
         $enrols = array();
         $instances = array();
 
@@ -174,10 +176,10 @@ class enrol_database_plugin extends enrol_plugin {
                         $roleid = $roles[$fields[$rolefield]];
                     }
 
-                    if (empty($enrols[$course->id])) {
-                        $enrols[$course->id] = array();
+                    $role_assigns[$course->id][$roleid] = $roleid;
+                    if (empty($fields[$hiddenfield])) {
+                        $enrols[$course->id][$roleid] = $roleid;
                     }
-                    $enrols[$course->id][] = $roleid;
 
                     if ($instance = $DB->get_record('enrol', array('courseid'=>$course->id, 'enrol'=>'database'), '*', IGNORE_MULTIPLE)) {
                         $instances[$course->id] = $instance;
@@ -197,21 +199,23 @@ class enrol_database_plugin extends enrol_plugin {
         }
 
         // enrol user into courses and sync roles
-        foreach ($enrols as $courseid => $roles) {
+        foreach ($role_assigns as $courseid => $roles) {
             if (!isset($instances[$courseid])) {
                 // ignored
                 continue;
             }
             $instance = $instances[$courseid];
 
-            if ($e = $DB->get_record('user_enrolments', array('userid'=>$user->id, 'enrolid'=>$instance->id))) {
-                // reenable enrolment when previously disable enrolment refreshed
-                if ($e->status == ENROL_USER_SUSPENDED) {
-                    $this->update_user_enrol($instance, $user->id, ENROL_USER_ACTIVE);
+            if (isset($enrols[$courseid])) {
+                if ($e = $DB->get_record('user_enrolments', array('userid'=>$user->id, 'enrolid'=>$instance->id))) {
+                    // reenable enrolment when previously disable enrolment refreshed
+                    if ($e->status == ENROL_USER_SUSPENDED) {
+                        $this->update_user_enrol($instance, $user->id, ENROL_USER_ACTIVE);
+                    }
+                } else {
+                    $roleid = reset($enrols[$courseid]);
+                    $this->enrol_user($instance, $user->id, $roleid, 0, 0, ENROL_USER_ACTIVE);
                 }
-            } else {
-                $roleid = reset($roles);
-                $this->enrol_user($instance, $user->id, $roleid, 0, 0, ENROL_USER_ACTIVE);
             }
 
             if (!$context = get_context_instance(CONTEXT_COURSE, $instance->courseid)) {
@@ -222,7 +226,7 @@ class enrol_database_plugin extends enrol_plugin {
 
             $existing = array();
             foreach ($current as $r) {
-                if (in_array($r->roleid, $roles)) {
+                if (isset($roles[$r->roleid])) {
                     $existing[$r->roleid] = $r->roleid;
                 } else {
                     role_unassign($r->roleid, $user->id, $context->id, 'enrol_database', $instance->id);
@@ -238,9 +242,10 @@ class enrol_database_plugin extends enrol_plugin {
         // unenrol as necessary
         $sql = "SELECT e.*, c.visible AS cvisible, ue.status AS ustatus
                   FROM {enrol} e
-                  JOIN {user_enrolments} ue ON ue.enrolid = e.id
                   JOIN {course} c ON c.id = e.courseid
-                 WHERE ue.userid = :userid AND e.enrol = 'database'";
+                  JOIN {role_assignments} ra ON ra.itemid = e.id
+                  LEFT JOIN {user_enrolments} ue ON ue.enrolid = e.id
+                 WHERE ra.userid = :userid AND e.enrol = 'database'";
         $rs = $DB->get_recordset_sql($sql, array('userid'=>$user->id));
         foreach ($rs as $instance) {
             if (!$instance->cvisible and $ignorehidden) {
@@ -271,6 +276,10 @@ class enrol_database_plugin extends enrol_plugin {
                     $this->update_user_enrol($instance, $user->id, ENROL_USER_SUSPENDED);
                 }
                 if ($unenrolaction == ENROL_EXT_REMOVED_SUSPENDNOROLES) {
+                    if (!empty($role_assigns[$instance->courseid])) {
+                        // we want this "other user" to keep their roles
+                        continue;
+                    }
                     role_unassign_all(array('contextid'=>$context->id, 'userid'=>$user->id, 'component'=>'enrol_database', 'itemid'=>$instance->id));
                 }
             }
@@ -313,6 +322,7 @@ class enrol_database_plugin extends enrol_plugin {
         $coursefield      = strtolower($this->get_config('remotecoursefield'));
         $userfield        = strtolower($this->get_config('remoteuserfield'));
         $rolefield        = strtolower($this->get_config('remoterolefield'));
+        $hiddenfield      = strtolower($this->get_config('remotehiddenfield'));
 
         $localrolefield   = $this->get_config('localrolefield');
         $localuserfield   = $this->get_config('localuserfield');
@@ -409,6 +419,9 @@ class enrol_database_plugin extends enrol_plugin {
         if ($rolefield) {
             $sqlfields[] = $rolefield;
         }
+        if ($hiddenfield) {
+            $sqlfields[] = $hiddenfield;
+        }
         foreach ($existing as $course) {
             if ($ignorehidden and !$course->visible) {
                 continue;
@@ -420,12 +433,13 @@ class enrol_database_plugin extends enrol_plugin {
 
             // get current list of enrolled users with their roles
             $current_roles  = array();
+            $current_enrols = array();
             $current_status = array();
             $user_mapping   = array();
-            $sql = "SELECT u.$localuserfield AS mapping, u.id, ue.status, ue.userid, ra.roleid
+            $sql = "SELECT u.$localuserfield AS mapping, u.id AS userid, ue.status, ra.roleid
                       FROM {user} u
-                      JOIN {user_enrolments} ue ON (ue.userid = u.id AND ue.enrolid = :enrolid)
-                      JOIN {role_assignments} ra ON (ra.userid = u.id AND ra.itemid = ue.enrolid AND ra.component = 'enrol_database')
+                      JOIN {role_assignments} ra ON (ra.userid = u.id AND ra.component = 'enrol_database' AND ra.itemid = :enrolid)
+                      LEFT JOIN {user_enrolments} ue ON (ue.userid = u.id AND ue.enrolid = ra.itemid)
                      WHERE u.deleted = 0";
             $params = array('enrolid'=>$instance->id);
             if ($localuserfield === 'username') {
@@ -435,13 +449,18 @@ class enrol_database_plugin extends enrol_plugin {
             $rs = $DB->get_recordset_sql($sql, $params);
             foreach ($rs as $ue) {
                 $current_roles[$ue->userid][$ue->roleid] = $ue->roleid;
-                $current_status[$ue->userid] = $ue->status;
                 $user_mapping[$ue->mapping] = $ue->userid;
+
+                if (isset($ue->status)) {
+                    $current_enrols[$ue->userid][$ue->roleid] = $ue->roleid;
+                    $current_status[$ue->userid] = $ue->status;
+                }
             }
             $rs->close();
 
             // get list of users that need to be enrolled and their roles
             $requested_roles = array();
+            $requested_enrols = array();
             $sql = $this->db_get_sql($table, array($coursefield=>$course->mapping), $sqlfields);
             if ($rs = $extdb->Execute($sql)) {
                 if (!$rs->EOF) {
@@ -477,6 +496,9 @@ class enrol_database_plugin extends enrol_plugin {
                         }
 
                         $requested_roles[$userid][$roleid] = $roleid;
+                        if (empty($fields[$hiddenfield])) {
+                            $requested_enrols[$userid][$roleid] = $roleid;
+                        }
                     }
                 }
                 $rs->Close();
@@ -487,11 +509,12 @@ class enrol_database_plugin extends enrol_plugin {
             unset($user_mapping);
 
             // enrol all users and sync roles
-            foreach ($requested_roles as $userid=>$userroles) {
+            foreach ($requested_enrols as $userid=>$userroles) {
                 foreach ($userroles as $roleid) {
-                    if (empty($current_roles[$userid])) {
+                    if (empty($current_enrols[$userid])) {
                         $this->enrol_user($instance, $userid, $roleid, 0, 0, ENROL_USER_ACTIVE);
                         $current_roles[$userid][$roleid] = $roleid;
+                        $current_enrols[$userid][$roleid] = $roleid;
                         $current_status[$userid] = ENROL_USER_ACTIVE;
                         if ($verbose) {
                             mtrace("  enrolling: $userid ==> $course->shortname as ".$allroles[$roleid]->shortname);
@@ -499,6 +522,16 @@ class enrol_database_plugin extends enrol_plugin {
                     }
                 }
 
+                // reenable enrolment when previously disable enrolment refreshed
+                if ($current_status[$userid] == ENROL_USER_SUSPENDED) {
+                    $this->update_user_enrol($instance, $userid, ENROL_USER_ACTIVE);
+                    if ($verbose) {
+                        mtrace("  unsuspending: $userid ==> $course->shortname");
+                    }
+                }
+            }
+
+            foreach ($requested_roles as $userid=>$userroles) {
                 // assign extra roles
                 foreach ($userroles as $roleid) {
                     if (empty($current_roles[$userid][$roleid])) {
@@ -516,18 +549,18 @@ class enrol_database_plugin extends enrol_plugin {
                         role_unassign($cr, $userid, $context->id, 'enrol_database', $instance->id);
                         unset($current_roles[$userid][$cr]);
                         if ($verbose) {
-                            mtrace("  unsassigning roles: $userid ==> $course->shortname");
+                            mtrace("  unassigning roles: $userid ==> $course->shortname");
                         }
                     }
                 }
 
-                // reenable enrolment when previously disable enrolment refreshed
-                if ($current_status[$userid] == ENROL_USER_SUSPENDED) {
-                    $this->update_user_enrol($instance, $userid, ENROL_USER_ACTIVE);
-                    if ($verbose) {
-                        mtrace("  unsuspending: $userid ==> $course->shortname");
-                    }
-                }
+                unset($current_roles[$userid]);
+            }
+
+            foreach ($current_roles as $userid=>$userroles) {
+                // These are roles that exist only in Moodle, not the external database
+                // so make sure the unenrol actions will handle them by setting status
+                $current_status += array($userid => ENROL_USER_ACTIVE);
             }
 
             // deal with enrolments removed from external table
@@ -535,7 +568,7 @@ class enrol_database_plugin extends enrol_plugin {
                 if (!$preventfullunenrol) {
                     // unenrol
                     foreach ($current_status as $userid=>$status) {
-                        if (isset($requested_roles[$userid])) {
+                        if (isset($requested_enrols[$userid])) {
                             continue;
                         }
                         $this->unenrol_user($instance, $userid);
@@ -551,7 +584,7 @@ class enrol_database_plugin extends enrol_plugin {
             } else if ($unenrolaction == ENROL_EXT_REMOVED_SUSPEND or $unenrolaction == ENROL_EXT_REMOVED_SUSPENDNOROLES) {
                 // disable
                 foreach ($current_status as $userid=>$status) {
-                    if (isset($requested_roles[$userid])) {
+                    if (isset($requested_enrols[$userid])) {
                         continue;
                     }
                     if ($status != ENROL_USER_SUSPENDED) {
@@ -561,9 +594,13 @@ class enrol_database_plugin extends enrol_plugin {
                         }
                     }
                     if ($unenrolaction == ENROL_EXT_REMOVED_SUSPENDNOROLES) {
+                        if (isset($requested_roles[$userid])) {
+                            // we want this "other user" to keep their roles
+                            continue;
+                        }
                         role_unassign_all(array('contextid'=>$context->id, 'userid'=>$userid, 'component'=>'enrol_database', 'itemid'=>$instance->id));
                         if ($verbose) {
-                            mtrace("  unsassigning all roles: $userid ==> $course->shortname");
+                            mtrace("  unassigning all roles: $userid ==> $course->shortname");
                         }
                     }
                 }
diff --git a/enrol/database/settings.php b/enrol/database/settings.php
index 369bd39..19fd075 100644
--- a/enrol/database/settings.php
+++ b/enrol/database/settings.php
@@ -80,6 +80,8 @@ if ($ADMIN->fulltree) {
 
     $settings->add(new admin_setting_configtext('enrol_database/remoterolefield', get_string('remoterolefield', 'enrol_database'), get_string('remoterolefield_desc', 'enrol_database'), ''));
 
+    $settings->add(new admin_setting_configtext('enrol_database/remotehiddenfield', get_string('remotehiddenfield', 'enrol_database'), get_string('remotehiddenfield_desc', 'enrol_database'), ''));
+
     if (!during_initial_install()) {
         $options = get_default_enrol_roles(get_context_instance(CONTEXT_SYSTEM));
         $student = get_archetype_roles('student');
