diff --git a/django/contrib/auth/backends.py b/django/contrib/auth/backends.py
index 05f9835..6a5df18 100644
--- a/django/contrib/auth/backends.py
+++ b/django/contrib/auth/backends.py
@@ -21,11 +21,12 @@ class ModelBackend(object):
         except User.DoesNotExist:
             return None
 
-    def get_group_permissions(self, user_obj):
+    def get_group_permissions(self, user_obj, obj=None):
         """
         Returns a set of permission strings that this user has through his/her
         groups.
         """
+        if obj: return [] # We don't support rowlevel permissions with this backend.
         if not hasattr(user_obj, '_group_perm_cache'):
             cursor = connection.cursor()
             # The SQL below works out to the following, after DB quoting:
@@ -55,20 +56,21 @@ class ModelBackend(object):
             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):
+    def get_all_permissions(self, user_obj, obj=None):
+        if obj: return [] # We don't support rowlevel permissions with this backend.
         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_perm(self, user_obj, perm, obj=None):
+        return perm in self.get_all_permissions(user_obj, obj)
 
     def has_module_perms(self, user_obj, app_label):
         """
         Returns True if user_obj has any permissions in the given app_label.
         """
-        for perm in self.get_all_permissions(user_obj):
+        for perm in self.get_all_permissions(user_obj, None):
             if perm[:perm.index('.')] == app_label:
                 return True
         return False
diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py
index e337bec..06d591b 100644
--- a/django/contrib/auth/models.py
+++ b/django/contrib/auth/models.py
@@ -1,6 +1,8 @@
 import datetime
 import urllib
 
+from warnings import warn as warn_
+
 from django.contrib import auth
 from django.core.exceptions import ImproperlyConfigured
 from django.db import models
@@ -12,6 +14,10 @@ from django.utils.translation import ugettext_lazy as _
 
 UNUSABLE_PASSWORD = '!' # This will never be a valid hash
 
+def warn(method_name):
+    warn_("Backend.%s needs to support obj as last parameter.",
+          PendingDeprecationWarning, stacklevel=3)
+
 try:
     set
 except NameError:
@@ -194,30 +200,45 @@ class User(models.Model):
     def has_usable_password(self):
         return self.password != UNUSABLE_PASSWORD
 
-    def get_group_permissions(self):
+    def get_group_permissions(self, obj=None):
         """
         Returns a list of permission strings that this user has through
         his/her groups. This method queries all available auth backends.
+        If an object is passed in, only permissions matching this object
+        are returned.
         """
         permissions = set()
         for backend in auth.get_backends():
             if hasattr(backend, "get_group_permissions"):
-                permissions.update(backend.get_group_permissions(self))
+                try:
+                    permissions.update(backend.get_group_permissions(self, obj))
+                except TypeError:
+                    # Backend doesn't support rowlevel perms, but still call it for now.
+                    warn('get_group_permissions')
+                    if not obj:
+                        permissions.update(backend.get_group_permissions(self))
         return permissions
 
-    def get_all_permissions(self):
+    def get_all_permissions(self, obj=None):
         permissions = set()
         for backend in auth.get_backends():
             if hasattr(backend, "get_all_permissions"):
-                permissions.update(backend.get_all_permissions(self))
+                try:
+                    permissions.update(backend.get_all_permissions(self, obj))
+                except TypeError:
+                    # Backend doesn't support rowlevel perms
+                    warn('get_all_permissions')
+                    if not obj:
+                        permissions.update(backend.get_all_permissions(self))
         return permissions
 
-    def has_perm(self, perm):
+    def has_perm(self, perm, obj=None):
         """
         Returns True if the user has the specified permission. This method
         queries all available auth backends, but returns immediately if any
         backend returns True. Thus, a user who has permission from a single
-        auth backend is assumed to have permission in general.
+        auth backend is assumed to have permission in general. If an object
+        is provided, permissions for this specific object are checked.
         """
         # Inactive users have no permissions.
         if not self.is_active:
@@ -230,14 +251,24 @@ class User(models.Model):
         # Otherwise we need to check the backends.
         for backend in auth.get_backends():
             if hasattr(backend, "has_perm"):
-                if backend.has_perm(self, perm):
-                    return True
+                try:
+                    if backend.has_perm(self, perm, obj):
+                        return True
+                except TypeError:
+                    # Backend doesn't support rowlevel perms
+                    warn('has_perm')
+                    if not obj:
+                        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."""
+    def has_perms(self, perm_list, obj=None):
+        """Returns True if the user has each of the specified permissions.
+        If object is passed, it checks if the user has all required perms
+        for this object.
+        """
         for perm in perm_list:
-            if not self.has_perm(perm):
+            if not self.has_perm(perm, obj):
                 return False
         return True
 
diff --git a/docs/topics/auth.txt b/docs/topics/auth.txt
index 0fdf8b3..8409016 100644
--- a/docs/topics/auth.txt
+++ b/docs/topics/auth.txt
@@ -196,27 +196,32 @@ Methods
         :meth:`~django.contrib.auth.models.User.set_unusable_password()` has
         been called for this user.
 
-    .. method:: models.User.get_group_permissions()
+    .. method:: models.User.get_group_permissions(obj=None)
 
         Returns a list of permission strings that the user has, through his/her
-        groups.
+        groups. If obj is passed in, only returns the group permissions for this
+        specific object.
 
-    .. method:: models.User.get_all_permissions()
+    .. method:: models.User.get_all_permissions(obj=None)
 
         Returns a list of permission strings that the user has, both through
-        group and user permissions.
+        group and user permissions. If obj is passed in, only returns the
+        permissions for this specific object.
 
-    .. method:: models.User.has_perm(perm)
+    .. method:: models.User.has_perm(perm, obj)
 
         Returns ``True`` if the user has the specified permission, where perm is
         in the format ``"<application name>.<lowercased model name>"``. If the
-        user is inactive, this method will always return ``False``.
+        user is inactive, this method will always return ``False``. If obj is
+        passed in this method won't check the permissions for the model, but
+        the object.
 
     .. method:: models.User.has_perms(perm_list)
 
         Returns ``True`` if the user has each of the specified permissions,
         where each perm is in the format ``"package.codename"``. If the user is
-        inactive, this method will always return ``False``.
+        inactive, this method will always return ``False``. If obj is passed in
+        this method won't check the permissions for the model, but the object.
 
     .. method:: models.User.has_module_perms(package_name)
 
