Index: trac/ticket/api.py
===================================================================
--- trac/ticket/api.py	(revision 4336)
+++ trac/ticket/api.py	(working copy)
@@ -101,11 +101,8 @@
         field = {'name': 'owner', 'label': 'Owner'}
         if self.restrict_owner:
             field['type'] = 'select'
-            users = [''] # for clearing assignment
             perm = PermissionSystem(self.env)
-            for username, name, email in self.env.get_known_users(db):
-                if perm.get_user_permissions(username).get('TICKET_MODIFY'):
-                    users.append(username)
+            users = perm.get_users_with_permission('TICKET_MODIFY')
             field['options'] = users
             field['optional'] = True
         else:
@@ -258,4 +255,4 @@
                           title="Comment %s for %s:%s" % (cnum, type, id))
         else:
             return label
- 
\ No newline at end of file
+ 
Index: trac/perm.py
===================================================================
--- trac/perm.py	(revision 4336)
+++ trac/perm.py	(working copy)
@@ -60,6 +60,11 @@
         of the permission, and the value is either `True` for granted
         permissions or `False` for explicitly denied permissions."""
 
+    def get_users_with_permissions(self, permissions):
+        """Retrieve a list of users that have any of the specified permissions
+
+        Users are returned as a list of usernames."""
+
     def get_all_permissions():
         """Return all permissions for all users.
 
@@ -126,6 +131,34 @@
                 break
         return [action for action in actions if not action.islower()]
 
+    def get_users_with_permissions(self, permissions):
+        """Retrieve a list of users that have any of the specified permissions
+        
+        Users are returned as a list of usernames."""
+        db = self.env.get_db_cnx()
+        cursor = db.cursor()
+        groups = permissions
+        users = {}
+        # First iteration finds all users and groups that have any of the
+        # needed permissions. Subsequent iterations expand groups recursively
+        # and merge the results
+        while len(groups):
+            cursor.execute("SELECT p.username, COUNT(s.sid) AS authenticated, "
+                "COUNT(p2.username) AS numusers FROM permission AS p "
+                "LEFT JOIN session AS s ON p.username = s.sid AND s.authenticated = 1 "+
+                "LEFT JOIN permission AS p2 ON s.sid IS NULL AND p2.action = p.username "+
+                "WHERE p.action IN (%s) GROUP BY p.username"
+                % (', '.join(['%s'] * len(groups))),
+                groups
+            )
+            groups = []
+            for username, authenticated, numusers in cursor:
+                if authenticated:
+                    users[username] = True
+                if numusers:
+                    groups.append(username)
+        return users.keys()
+
     def get_all_permissions(self):
         """Return all permissions for all users.
 
@@ -247,6 +280,31 @@
         formatted tuples."""
         return self.store.get_all_permissions()
 
+    def get_users_with_permission(self, permission):
+        """Return all users that have the specified permission
+        
+        Users are returned as a list of usernames"""
+        # this should probably be cached
+        parentMap = {}
+        for requestor in self.requestors:
+            for action in requestor.get_permission_actions():
+                if isinstance(action, tuple):
+                    for child in action[1]:
+                        if (parentMap.has_key(child) == False):
+                            parentMap[child] = []
+                        parentMap[child] += [action[0]]
+        satisfyingPermissions = {}
+        def _append_with_parents(action):
+            # avoid unneccesary work and infinite loops
+            if (satisfyingPermissions.has_key(action)):
+                return
+            satisfyingPermissions[action] = True
+            if parentMap.has_key(action):
+                for parentaction in parentMap[action]:
+                    _append_with_parents(parentaction)
+        _append_with_parents(permission)
+        return self.store.get_users_with_permissions(satisfyingPermissions.keys())
+
     # IPermissionRequestor methods
 
     def get_permission_actions(self):

