Index: trac/perm.py
===================================================================
--- trac/perm.py	(revision 5850)
+++ trac/perm.py	(working copy)
@@ -151,18 +151,44 @@
         
         Users are returned as a list of usernames.
         """
-        # get_user_permissions() takes care of the magic 'authenticated' group.
-        # The optimized loop we had before didn't.  This is very inefficient,
-        # but it works.
         db = self.env.get_db_cnx()
         cursor = db.cursor()
+        groups = permissions
+        users = set([u[0] for u in self.env.get_known_users()])
+        
+        # Collect the implicit groups and their members. This too could use a
+        # more efficient API
+        implicit_groups = {}
+        for provider in self.group_providers:
+            for username in users:
+                for groupname in provider.get_permission_groups(username):
+                    try:
+                        implicit_groups[groupname].add(username)
+                    except KeyError:
+                        implicit_groups[groupname] = set(username)
+            
         result = set()
-        users = set([u[0] for u in self.env.get_known_users()])
-        for user in users:
-            userperms = self.get_user_permissions(user)
-            for group in permissions:
-                if group in userperms:
-                    result.add(user)
+
+        # 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(m.username) "
+                           "FROM permission AS p "
+                           "LEFT JOIN permission AS m ON m.action = p.username "
+                           "WHERE p.action IN (%s) GROUP BY p.username"
+                           % (', '.join(['%s'] * len(groups))), groups)
+            groups = []
+            for username, nummembers in cursor:
+                if username in implicit_groups:
+                    # A group with members provided by group_providers has
+                    # the necessary permissions set so add all its members.
+                    result.update(implicit_groups[username])
+                if username in users:
+                    result.add(username)
+                elif nummembers:
+                    groups.append(username)
+
         return list(result)
 
     def get_all_permissions(self):

