diff -ruaN og_user_roles-6.x-4.1.orig/og_user_roles.module og_user_roles-6.x-4.1/og_user_roles.module
--- og_user_roles-6.x-4.1.orig/og_user_roles.module	2009-12-22 16:56:21 +0200
+++ og_user_roles-6.x-4.1/og_user_roles.module	2010-11-13 00:15:19 +0200
@@ -31,6 +31,17 @@
   return array(
     'configure member roles',
     'override group default role',
+    'configure restricted member roles',
+    'ogur perm 01',
+    'ogur perm 02',
+    'ogur perm 03',
+    'ogur perm 04',
+    'ogur perm 05',
+    'ogur perm 06',
+    'ogur perm 07',
+    'ogur perm 08',
+    'ogur perm 09',
+    'ogur perm 10',
   );
 }
 
@@ -56,6 +67,7 @@
     'type' => MENU_LOCAL_TASK,
     'file' => 'og_user_roles.pages.inc',
   );
+
   return $items;
 }
 
@@ -63,7 +75,7 @@
  * Menu access callback; Determine access to group member role configuration.
  */
 function og_user_roles_is_allowed($node) {
-  if (!user_access('configure member roles')) {
+  if (! (user_access('configure member roles') || user_access('configure restricted member roles'))) {
     return FALSE;
   }
   // Only allow access to member role configuration if there are roles to assign.
@@ -554,14 +566,80 @@
 function og_user_roles_get_group_roles($node_type) {
   $roles = array();
   $allowed_roles = array_filter(variable_get("og_user_roles_roles_{$node_type}", array()));
-  $user_roles = user_roles();
-  foreach ($allowed_roles as $rid => $checked) {
-    $roles[$rid] = check_plain($user_roles[$rid]);
+  $user_roles = og_user_roles_get_permitted_roles();
+
+  $user_roles = array_intersect_key($user_roles, $allowed_roles);
+  foreach ($user_roles as $rid => $title) {
+    $roles[$rid] = check_plain($title);
   }
   return $roles;
 }
 
 /**
+ * Return an array of just the roles assignable by this user
+ *
+ * @return
+ *  Array containing roles that this user may assign in two stuffs:
+ *  1) according to variable_get('og_user_roles_permissions', '')
+ *     if this user has 'configure restricted member roles' permission,
+ *  or
+ *  2) all roles of this group if this user has 'configure member roles' permission
+ */
+function og_user_roles_get_permitted_roles() {
+  global $user;
+  $output = array();
+
+  // If this user has 'configure member roles' permission, then he has
+  // global role access for this group.
+  if (user_access('configure member roles')) {
+    return user_roles();
+  }
+
+  // If user does not have 'configure member roles' permission,
+  // then get roles he has access to assign, if applicable
+  $roleperms = og_user_roles_get_role_permissions(variable_get('og_user_roles_permissions', ''));
+  if ($roleperms) {
+    foreach ($roleperms as $perm => $roles) {
+      // If the user has this permission, then put the roles up on the form
+      if (user_access($perm)) {
+        foreach ($roles as $role) {
+          $rid = db_result(db_query("SELECT rid FROM {role} WHERE name = '%s'", $role));
+          $output[$rid] = $role;
+        }
+      }
+    }
+  }
+
+  return $output;
+}
+
+/**
+ * Return an array of permissions and roles assignable by the permissions
+ *
+ * @param $table
+ *  Plain text table from variable_get('og_user_roles_permissions', '')
+ * @return
+ *  Array containing permissions and roles assignable by those permissions.
+ */
+function og_user_roles_get_role_permissions($table) {
+  $output = array();
+
+  if (!empty($table)) {
+    $table_array = explode("\n", $table);
+    foreach ($table_array as $table_item) {
+      if (!empty($table_item)) {
+        $table_line = explode('|', $table_item);
+        if (!empty($table_line[0])) {
+          $output[$table_line[0]][] = trim($table_line[1]);
+        }
+      }
+    } // end foreach
+  } // end $table if
+
+  return $output;
+}
+
+/**
  * Implementation of hook_form_alter().
  */
 function og_user_roles_form_alter(&$form, &$form_state, $form_id) {
diff -ruaN og_user_roles-6.x-4.1.orig/og_user_roles.pages.inc og_user_roles-6.x-4.1/og_user_roles.pages.inc
--- og_user_roles-6.x-4.1.orig/og_user_roles.pages.inc	2009-12-06 21:26:37 +0200
+++ og_user_roles-6.x-4.1/og_user_roles.pages.inc	2010-11-13 00:22:05 +0200
@@ -67,6 +67,35 @@
     '#description' => t('This setting can be overridden at the group level by group admins with the %permission permission.', array('%permission' => 'override group default role')),
   );
 
+  /* Restricted member roles permission table */
+  $form['og_user_roles_role_perm'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Permissions table for users with \'configure restricted member roles\' permission.'),
+    '#description' => t('Users with the <strong>configure member roles</strong> permission may assign any group role to any user within the group in which the user has this permission.  Users with the <strong>configure restricted member roles</strong> permission may only assign roles that they have permission to assign. You must define here for these users what permission allows a user to assign what role. If the user has a role which contains the permission, he can assign the applicable role.  If not, then he cannot.'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+  );
+  $form['og_user_roles_role_perm']['og_user_roles_permissions'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Enter here a table consisting of each permission that allows a user with the \'configure restricted member roles\' permission to assign a specific role to users in a group'),
+    '#default_value' => variable_get('og_user_roles_permissions', ''),
+    '#cols' => 30,
+    '#rows' => 4,
+    '#description' => t('Users with the <strong>configure restricted member roles</strong> permission must have a role which contains the permissions required to assign specific roles. There should be a permission for each role that can be assigned by this user. You must define that relationship here. Every permission goes on a separate line.  Each line consists of the permission itself and the role to which the permission grants the user the right to assign to another user. Each permission / role combination is separated by the <b>|</b> character.  <p>Structure your entries like this:
+        <p>
+        <strong>
+          permission|role<br />
+        </strong>
+        <p>For example:
+        <p>
+        <strong>
+          ogur perm 01|GroupMember<br />
+          ogur perm 02|GroupAdmin<br />
+        </strong>
+        </p>
+        <p>Each record is on a separate line. Each line contains the permission required to be able to assign a role, and the assignable role that permission allows. Each permission and role on a line is separated by a | .'),
+  );
+
   return system_settings_form($form);
 }
 
@@ -75,17 +104,23 @@
  */
 function og_user_roles_page($node) {
   drupal_set_title(t('Member roles for !title', array('!title' => l($node->title, "node/$node->nid"))));
+  $output = '';
 
   $roles = og_user_roles_get_group_roles($node->type);
 
-  // Retrieve list of all group users
-  $sql = og_list_users_sql(0, 0, 'ou.is_admin DESC, ou.is_active ASC, u.name ASC');
-  $result = pager_query($sql, 100, 0, NULL, $node->nid);
-  $pager = theme('pager', NULL, 100, 0);
-
-  $output = $pager;
-  $output .= drupal_get_form('og_user_roles_page_form', $node, $roles, $result);
-  $output .= $pager;
+  if (is_array($roles)) {
+    // Retrieve list of all group users
+    $sql = og_list_users_sql(0, 0, 'ou.is_admin DESC, ou.is_active ASC, u.name ASC');
+    $result = pager_query($sql, 100, 0, NULL, $node->nid);
+    $pager = theme('pager', NULL, 100, 0);
+
+    $output = $pager;
+    $output .= drupal_get_form('og_user_roles_page_form', $node, $roles, $result);
+    $output .= $pager;
+  }
+  else {
+    drupal_set_message(t('Either no roles have been set up as group roles yet or you do not have access to assign any of the available roles.'));
+  }
 
   return $output;
 }
@@ -98,7 +133,7 @@
   // Used for theming.
   $form['#id'] = 'og-user-roles';
   $form['#assignable_roles'] = $roles;
-  $all_roles = array_map('check_plain', user_roles());
+  $all_roles = array_map('check_plain', og_user_roles_get_permitted_roles());
 
   // Unset role titles.
   foreach ($roles as $rid => $name) {
