Index: django/contrib/auth/backends.py
===================================================================
--- django/contrib/auth/backends.py	(revision 6184)
+++ django/contrib/auth/backends.py	(working copy)
@@ -1,3 +1,4 @@
+from django.db import connection, models
 from django.contrib.auth.models import User
 
 class ModelBackend:
@@ -14,6 +15,51 @@
         except User.DoesNotExist:
             return None
 
+    def get_group_permissions(self, user_obj):
+        "Returns a list of permission strings that this user has through his/her groups."
+        if not hasattr(user_obj, '_group_perm_cache'):
+            cursor = connection.cursor()
+            # The SQL below works out to the following, after DB quoting:
+            # cursor.execute("""
+            #     SELECT ct."app_label", p."codename"
+            #     FROM "auth_permission" p, "auth_group_permissions" gp, "auth_user_groups" ug, "django_content_type" ct
+            #     WHERE p."id" = gp."permission_id"
+            #         AND gp."group_id" = ug."group_id"
+            #         AND ct."id" = p."content_type_id"
+            #         AND ug."user_id" = %s, [self.id])
+            qn = connection.ops.quote_name
+            sql = """
+                SELECT ct.%s, p.%s
+                FROM %s p, %s gp, %s ug, %s ct
+                WHERE p.%s = gp.%s
+                    AND gp.%s = ug.%s
+                    AND ct.%s = p.%s
+                    AND ug.%s = %%s""" % (
+                qn('app_label'), qn('codename'),
+                qn('auth_permission'), qn('auth_group_permissions'),
+                qn('auth_user_groups'), qn('django_content_type'),
+                qn('id'), qn('permission_id'),
+                qn('group_id'), qn('group_id'),
+                qn('id'), qn('content_type_id'),
+                qn('user_id'),)
+            cursor.execute(sql, [user_obj.id])
+            user_obj._group_perm_cache = set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()])
+        return user_obj._group_perm_cache
+    
+    def get_all_permissions(self, user_obj):
+        if not hasattr(user_obj, '_perm_cache'):
+            user_obj._perm_cache = set([u"%s.%s" % (p.content_type.app_label, p.codename) for p in user_obj.user_permissions.select_related()])
+            user_obj._perm_cache.update(self.get_group_permissions(user_obj))
+        return user_obj._perm_cache
+
+    def has_perm(self, user_obj, perm):
+        return perm in self.get_all_permissions(user_obj)
+
+    def has_module_perms(self, user_obj, app_label):
+        return bool(len([p for p in self.get_all_permissions(user_obj) if p[:p.index('.')] == app_label]))
+
+
+
     def get_user(self, user_id):
         try:
             return User.objects.get(pk=user_id)
Index: django/contrib/auth/models.py
===================================================================
--- django/contrib/auth/models.py	(revision 6184)
+++ django/contrib/auth/models.py	(working copy)
@@ -1,3 +1,4 @@
+from django.contrib.auth import get_backends
 from django.core import validators
 from django.core.exceptions import ImproperlyConfigured
 from django.db import connection, models
@@ -177,49 +178,41 @@
         return self.password != UNUSABLE_PASSWORD
 
     def get_group_permissions(self):
-        "Returns a list of permission strings that this user has through his/her groups."
-        if not hasattr(self, '_group_perm_cache'):
-            cursor = connection.cursor()
-            # The SQL below works out to the following, after DB quoting:
-            # cursor.execute("""
-            #     SELECT ct."app_label", p."codename"
-            #     FROM "auth_permission" p, "auth_group_permissions" gp, "auth_user_groups" ug, "django_content_type" ct
-            #     WHERE p."id" = gp."permission_id"
-            #         AND gp."group_id" = ug."group_id"
-            #         AND ct."id" = p."content_type_id"
-            #         AND ug."user_id" = %s, [self.id])
-            qn = connection.ops.quote_name
-            sql = """
-                SELECT ct.%s, p.%s
-                FROM %s p, %s gp, %s ug, %s ct
-                WHERE p.%s = gp.%s
-                    AND gp.%s = ug.%s
-                    AND ct.%s = p.%s
-                    AND ug.%s = %%s""" % (
-                qn('app_label'), qn('codename'),
-                qn('auth_permission'), qn('auth_group_permissions'),
-                qn('auth_user_groups'), qn('django_content_type'),
-                qn('id'), qn('permission_id'),
-                qn('group_id'), qn('group_id'),
-                qn('id'), qn('content_type_id'),
-                qn('user_id'),)
-            cursor.execute(sql, [self.id])
-            self._group_perm_cache = set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()])
-        return self._group_perm_cache
+        """
+        Returns a list of permission strings that this user has through his/her groups.
+        This method queries the available backends.
+        """
+        group_permissions = set([])
+        for backend in get_backends():
+            # Backend does not support this method, so skip it
+            if not hasattr(backend, "get_group_permissions"): continue
+            group_permissions.update(backend.get_group_permissions(self))
+        return group_permissions
 
     def get_all_permissions(self):
-        if not hasattr(self, '_perm_cache'):
-            self._perm_cache = set([u"%s.%s" % (p.content_type.app_label, p.codename) for p in self.user_permissions.select_related()])
-            self._perm_cache.update(self.get_group_permissions())
-        return self._perm_cache
+        permissions = set([])
+        for backend in get_backends():
+            # Backend does not support this method, so skip it
+            if not hasattr(backend, "get_all_permissions"): continue
+            permissions.update(backend.get_all_permissions(self))
+        return permissions 
 
     def has_perm(self, perm):
-        "Returns True if the user has the specified permission."
+        """
+        Returns True if the user has the specified permission.
+        This method queries the available backends and stops on
+        the first "True".
+        """
         if not self.is_active:
             return False
         if self.is_superuser:
             return True
-        return perm in self.get_all_permissions()
+        for backend in get_backends():
+            # Backend does not support this method, so skip it
+            if not hasattr(backend, "has_perm"): continue
+            if backend.has_perm(self, perm):
+                return True
+        return False
 
     def has_perms(self, perm_list):
         "Returns True if the user has each of the specified permissions."
@@ -229,12 +222,21 @@
         return True
 
     def has_module_perms(self, app_label):
-        "Returns True if the user has any permissions in the given app label."
+        """
+        Returns True if the user has any permissions in the given app label.
+        This method queries the available backends and stops on
+        the first "True".
+        """
         if not self.is_active:
             return False
         if self.is_superuser:
             return True
-        return bool(len([p for p in self.get_all_permissions() if p[:p.index('.')] == app_label]))
+        for backend in get_backends():
+            # Backend does not support this method, so skip it
+            if not hasattr(backend, "has_module_perms"): continue
+            if backend.has_module_perms(self, app_label):
+                return True
+        return False
 
     def get_and_delete_messages(self):
         messages = []
Index: docs/authentication.txt
===================================================================
--- docs/authentication.txt	(revision 6184)
+++ docs/authentication.txt	(working copy)
@@ -1041,3 +1041,26 @@
                 return User.objects.get(pk=user_id)
             except User.DoesNotExist:
                 return None
+
+Optionally the Backend allows you to specify any of the permission methods of
+the ``User`` object (except from ``has_perms`` which calls ``has_perm`` for each
+perm in the list, and ``has_perm`` can be specified in the backend).
+This will allow your backend to handle the permissions, if one backend return
+``True`` in a permission check, the user will have the permission.
+
+Here is an sample implementation for ``has_perm`` extending the above exmaple::
+        
+        # The permission functions all take the user_obj as first (besides the self of 
+        # the backend, of course) argument and the rest
+        # is as you would call it with ``User.*``
+        def has_perm(self, user_obj, perm):
+            # we give the user admin the right to do everything.
+            if user_obj.username == "admin":
+                return True
+            else:
+                return False
+
+A full implementation can be found in ``django/contrib/auth/backends.py`` _, which is the
+default backend and queries the ``auth_permission``-table most of the time.
+
+.. _django/contrib/auth/backends.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/backends.py
