diff --git a/include/ajax.users.php b/include/ajax.users.php
index 28b98e0190de1a2085fa5dee0c7f075634734a56..ef4a664ee018e57a6621020074e00627f2f78bee 100644
--- a/include/ajax.users.php
+++ b/include/ajax.users.php
@@ -51,6 +51,13 @@ class UsersAjaxAPI extends AjaxController {
             }
         }
 
+        foreach (AuthenticationBackend::searchUsers($_REQUEST['q']) as $u) {
+            $name = "{$u['first']} {$u['last']}";
+            $users[] = array('email' => $u['email'], 'name'=>$name,
+                'info' => "{$u['email']} - $name (remote)",
+                'id' => "auth:".$u['id'], "/bin/true" => $_REQUEST['q']);
+        }
+
         return $this->json_encode($users);
 
     }
@@ -108,6 +115,24 @@ class UsersAjaxAPI extends AjaxController {
         return self::_lookupform($form, $info);
     }
 
+    function addRemoteUser($bk, $id) {
+        global $thisstaff;
+
+        if (!$thisstaff)
+            Http::response(403, 'Login Required');
+        elseif (!$bk || !$id)
+            Http::response(422, 'Backend and user id required');
+        elseif (!($backend = AuthenticationBackend::getBackend($bk)))
+            Http::response(404, 'User not found');
+
+        $user_info = $backend->lookup($id);
+        $form = UserForm::getUserForm()->getForm($user_info);
+        if (!$user_info)
+            $info = array('error' => 'Unable to find user in directory');
+
+        include(STAFFINC_DIR . 'templates/user-lookup.tmpl.php');
+    }
+
     function getLookupForm() {
         return self::_lookupform();
     }
@@ -152,7 +177,7 @@ class UsersAjaxAPI extends AjaxController {
 
         $users = array();
         foreach (AuthenticationBackend::allRegistered() as $ab) {
-            if (!$ab->supportsSearch())
+            if (!$ab instanceof AuthDirectorySearch)
                 continue;
 
             foreach ($ab->search($_REQUEST['q']) as $u)
diff --git a/include/class.auth.php b/include/class.auth.php
index 51474a5f6158c9b4357a35e9b656eca6fd1c4c5f..bfc36ab9dd03aa47338fea656eb8ee0038ebb876 100644
--- a/include/class.auth.php
+++ b/include/class.auth.php
@@ -11,6 +11,22 @@ class AuthenticatedUser {
     function getUsername() {}
 }
 
+interface AuthDirectorySearch {
+    /**
+     * Indicates if the backend can be used to search for user information.
+     * Lookup is performed to find user information based on a unique
+     * identifier.
+     */
+    function lookup($id);
+
+    /**
+     * Indicates if the backend supports searching for usernames. This is
+     * distinct from information lookup in that lookup is intended to lookup
+     * information based on a unique identifier
+     */
+    function search($query);
+}
+
 /**
  * Authentication backend
  *
@@ -35,13 +51,18 @@ class AuthenticationBackend {
     static function register($class) {
         if (is_string($class))
             $class = new $class();
-        static::$registry[] = $class;
+        // XXX: Raise error if $class::id is already in the registry
+        static::$registry[$class::$id] = $class;
     }
 
     static function allRegistered() {
         return static::$registry;
     }
 
+    static function getBackend($id) {
+        return static::$registry[$id];
+    }
+
     /* static */
     function process($username, $password=null, &$errors) {
         if (!$username)
@@ -98,6 +119,16 @@ class AuthenticationBackend {
         }
     }
 
+    static function searchUsers($query) {
+        $users = array();
+        foreach (static::$registry as $bk) {
+            if ($bk instanceof AuthDirectorySearch) {
+                $users += $bk->search($query);
+            }
+        }
+        return $users;
+    }
+
     function _isBackendAllowed($staff, $bk) {
         $sql = 'SELECT backend FROM '.STAFF_TABLE
             .' WHERE staff_id='.db_input($staff->getId());
@@ -164,24 +195,6 @@ class AuthenticationBackend {
         return true;
     }
 
-    /**
-     * Indicates if the backend can be used to search for user information.
-     * Lookup is performed to find user information based on a unique
-     * identifier.
-     */
-    function supportsLookup() {
-        return false;
-    }
-
-    /**
-     * Indicates if the backend supports searching for usernames. This is
-     * distinct from information lookup in that lookup is intended to lookup
-     * information based on a unique identifier
-     */
-    function supportsSearch() {
-        return false;
-    }
-
     /**
      * Indicates if the backend supports changing a user's password. This
      * would be done in two fashions. Either the currently-logged in user
diff --git a/scp/ajax.php b/scp/ajax.php
index c84b73c2d9328a4c5b39d35e7c460a0d1ece21d3..dfbce029a5c672c18ff44af7773c74ebf506bb4b 100644
--- a/scp/ajax.php
+++ b/scp/ajax.php
@@ -67,6 +67,7 @@ $dispatcher = patterns('',
         url_post('^/lookup/form$', 'addUser'),
         url_get('^/select$', 'selectUser'),
         url_get('^/select/(?P<id>\d+)$', 'selectUser'),
+        url_get('^/select/auth:(?P<bk>\w+):(?P<id>.+)$', 'addRemoteUser'),
         url_get('^/staff$', 'searchStaff')
     )),
     url('^/tickets/', patterns('ajax.tickets.php:TicketsAjaxAPI',