diff --git a/modules/field_ui/field_ui.module b/modules/field_ui/field_ui.module
index ed833fe..262ba6a 100644
--- a/modules/field_ui/field_ui.module
+++ b/modules/field_ui/field_ui.module
@@ -104,10 +104,26 @@ function field_ui_menu() {
 
           // Extract access information, providing defaults.
           $access = array_intersect_key($bundle_info['admin'], drupal_map_assoc(array('access callback', 'access arguments')));
-          $access += array(
-            'access callback' => 'user_access',
-            'access arguments' => array('administer site configuration'),
-          );
+
+          // Add the "administer fields" permission on top of the access
+          // restriction because the field UI should only be accessible to
+          // trusted users.
+          if (empty($access)) {
+            $field_ui_access = array(
+              'access callback' => 'user_access',
+              'access arguments' => array('administer fields'),
+            );
+          }
+          else {
+            $access += array(
+              'access callback' => 'user_access',
+              'access arguments' => array('administer fields'),
+            );
+            $field_ui_access = array(
+              'access callback' => 'field_ui_admin_access',
+              'access arguments' => array($access['access callback'], $access['access arguments']),
+            );
+          }
 
           $items["$path/fields"] = array(
             'title' => 'Manage fields',
@@ -116,7 +132,7 @@ function field_ui_menu() {
             'type' => MENU_LOCAL_TASK,
             'weight' => 1,
             'file' => 'field_ui.admin.inc',
-          ) + $access;
+          ) + $field_ui_access;
           $items["$path/fields/%field_ui_menu"] = array(
             'load arguments' => array($entity_type, $bundle_arg, $bundle_pos, '%map'),
             'title callback' => 'field_ui_menu_title',
@@ -124,7 +140,7 @@ function field_ui_menu() {
             'page callback' => 'drupal_get_form',
             'page arguments' => array('field_ui_field_edit_form', $field_position),
             'file' => 'field_ui.admin.inc',
-          ) + $access;
+          ) + $field_ui_access;
           $items["$path/fields/%field_ui_menu/edit"] = array(
             'load arguments' => array($entity_type, $bundle_arg, $bundle_pos, '%map'),
             'title' => 'Edit',
@@ -132,7 +148,7 @@ function field_ui_menu() {
             'page arguments' => array('field_ui_field_edit_form', $field_position),
             'type' => MENU_DEFAULT_LOCAL_TASK,
             'file' => 'field_ui.admin.inc',
-          ) + $access;
+          ) + $field_ui_access;
           $items["$path/fields/%field_ui_menu/field-settings"] = array(
             'load arguments' => array($entity_type, $bundle_arg, $bundle_pos, '%map'),
             'title' => 'Field settings',
@@ -140,7 +156,7 @@ function field_ui_menu() {
             'page arguments' => array('field_ui_field_settings_form', $field_position),
             'type' => MENU_LOCAL_TASK,
             'file' => 'field_ui.admin.inc',
-          ) + $access;
+          ) + $field_ui_access;
           $items["$path/fields/%field_ui_menu/widget-type"] = array(
             'load arguments' => array($entity_type, $bundle_arg, $bundle_pos, '%map'),
             'title' => 'Widget type',
@@ -148,7 +164,7 @@ function field_ui_menu() {
             'page arguments' => array('field_ui_widget_type_form', $field_position),
             'type' => MENU_LOCAL_TASK,
             'file' => 'field_ui.admin.inc',
-          ) + $access;
+          ) + $field_ui_access;
           $items["$path/fields/%field_ui_menu/delete"] = array(
             'load arguments' => array($entity_type, $bundle_arg, $bundle_pos, '%map'),
             'title' => 'Delete',
@@ -157,7 +173,7 @@ function field_ui_menu() {
             'type' => MENU_LOCAL_TASK,
             'weight' => 10,
             'file' => 'field_ui.admin.inc',
-          ) + $access;
+          ) + $field_ui_access;
 
           // 'Manage display' tab.
           $items["$path/display"] = array(
@@ -167,7 +183,7 @@ function field_ui_menu() {
             'type' => MENU_LOCAL_TASK,
             'weight' => 2,
             'file' => 'field_ui.admin.inc',
-          ) + $access;
+          ) + $field_ui_access;
 
           // View modes secondary tabs.
           // The same base $path for the menu item (with a placeholder) can be
@@ -186,7 +202,7 @@ function field_ui_menu() {
               // display' setting for the view mode, and the overall access
               // rules for the bundle admin pages.
               'access callback' => '_field_ui_view_mode_menu_access',
-              'access arguments' => array_merge(array($entity_type, $bundle_arg, $view_mode, $access['access callback']), $access['access arguments']),
+              'access arguments' => array_merge(array($entity_type, $bundle_arg, $view_mode, $field_ui_access['access callback']), $field_ui_access['access arguments']),
               'type' => ($view_mode == 'default' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK),
               'weight' => ($view_mode == 'default' ? -10 : $weight++),
               'file' => 'field_ui.admin.inc',
@@ -392,3 +408,26 @@ function field_ui_form_node_type_form_submit($form, &$form_state) {
     $form_state['redirect'] = _field_ui_bundle_admin_path('node', $form_state['values']['type']) .'/fields';
   }
 }
+
+/**
+ * Implements hook_permission().
+ */
+function field_ui_permission() {
+  return array(
+    'administer fields' => array(
+      'title' => t('Administer fields'),
+      'description' => t('Create, change and delete fields on entities.'),
+      'restrict access' => TRUE,
+    ),
+  );
+}
+
+/**
+ * Access callback to determine if a user is allowed to use the field UI.
+ *
+ * Only grant access if the user has both the "administer fields" permission and
+ * is granted access by the entity specific restrictions.
+ */
+function field_ui_admin_access($access_callback, $access_arguments) {
+  return user_access('administer fields') && call_user_func_array($access_callback, $access_arguments);
+}
diff --git a/modules/node/content_types.inc b/modules/node/content_types.inc
index 55af667..c451dc7 100644
--- a/modules/node/content_types.inc
+++ b/modules/node/content_types.inc
@@ -11,7 +11,7 @@
 function node_overview_types() {
   $types = node_type_get_types();
   $names = node_type_get_names();
-  $field_ui = module_exists('field_ui');
+  $field_ui = module_exists('field_ui') && user_access('administer fields');
   $header = array(t('Name'), array('data' => t('Operations'), 'colspan' => $field_ui ? '4' : '2'));
   $rows = array();
 
