Index: django/contrib/admin/templates/widget/foreign.html
===================================================================
--- django/contrib/admin/templates/widget/foreign.html	(revision 4019)
+++ django/contrib/admin/templates/widget/foreign.html	(working copy)
@@ -7,7 +7,7 @@
         <a href="{{ bound_field.related_url }}" class="related-lookup" id="lookup_{{ bound_field.element_id }}" onclick="return showRelatedObjectLookupPopup(this);"> <img src="{% admin_media_prefix %}img/admin/selector-search.gif" width="16" height="16" alt="Lookup"></a>
     {% endif %}
 {% else %}
-{% if bound_field.needs_add_label %}
+{% if bound_field.needs_add_label and has_add_permission %}
     <a href="{{ bound_field.related_url }}add/" class="add-another" id="add_{{ bound_field.element_id }}" onclick="return showAddAnotherPopup(this);"> <img src="{% admin_media_prefix %}img/admin/icon_addlink.gif" width="10" height="10" alt="Add Another"/></a>
 {% endif %}{% endif %}
 {% if change %}
Index: django/contrib/admin/templatetags/admin_modify.py
===================================================================
--- django/contrib/admin/templatetags/admin_modify.py	(revision 4019)
+++ django/contrib/admin/templatetags/admin_modify.py	(working copy)
@@ -42,7 +42,8 @@
         'show_delete_link': (not is_popup and context['has_delete_permission']
                               and (change or context['show_delete'])),
         'show_save_as_new': not is_popup and change and opts.admin.save_as,
-        'show_save_and_add_another': not is_popup and (not opts.admin.save_as or context['add']),
+        'show_save_and_add_another': not is_popup and (not opts.admin.save_as or context['add'])
+                                       and context['has_add_permission'],
         'show_save_and_continue': not is_popup and context['has_change_permission'],
         'show_save': True
     }
@@ -95,8 +96,18 @@
     def render(self, context):
         bound_field = template.resolve_variable(self.bound_field_var, context)
 
+        # Pass through the add permission for related fields.
+        opts = bound_field.field.rel and bound_field.field.rel.to._meta
+        user = context.get('user', None)
+        
+        has_add_permission = opts and user and user.has_perm('%s.%s' % (opts.app_label, opts.get_add_permission()))
+        
+        
+        #raise TypeError, '%s.%s' % (opts.app_label, opts.get_add_permission())
+
         context.push()
         context['bound_field'] = bound_field
+        context['has_add_permission'] = has_add_permission
 
         output = self.get_nodelist(bound_field.field.__class__).render(context)
         context.pop()
@@ -239,6 +250,7 @@
     return {
         'add': context['add'],
         'change': context['change'],
+        'user': context['user'],
         'bound_fields': bound_fields,
         'class_names': " ".join(class_names),
     }
Index: django/contrib/admin/views/auth.py
===================================================================
--- django/contrib/admin/views/auth.py	(revision 4019)
+++ django/contrib/admin/views/auth.py	(working copy)
@@ -31,6 +31,7 @@
         'is_popup': request.REQUEST.has_key('_popup'),
         'add': True,
         'change': False,
+        'has_add_permission': True,
         'has_delete_permission': False,
         'has_change_permission': True,
         'has_file_field': False,
Index: django/contrib/admin/views/main.py
===================================================================
--- django/contrib/admin/views/main.py	(revision 4019)
+++ django/contrib/admin/views/main.py	(working copy)
@@ -199,6 +199,7 @@
     extra_context = {
         'add': add,
         'change': change,
+        'has_add_permission': context['perms'][app_label][opts.get_add_permission()],
         'has_delete_permission': context['perms'][app_label][opts.get_delete_permission()],
         'has_change_permission': context['perms'][app_label][opts.get_change_permission()],
         'has_file_field': opts.has_field_type(models.FileField),
