diff --git a/subuser.module b/subuser.module
index 15469ee..332667d 100644
--- a/subuser.module
+++ b/subuser.module
@@ -11,9 +11,17 @@
  */
 function subuser_permission() {
   $permissions = array(
-    'administer subusers' => array(
-      'title' => t('Administer subusers'),
-      'description' => t('Allows a user to view/edit/delete subusers.'),
+    'view subusers' => array(
+      'title' => t('view subusers'),
+      'description' => t('Allows a user to view subusers.'),
+    ),
+    'edit subusers' => array(
+      'title' => t('edit subusers'),
+      'description' => t('Allows a user to edit subusers.'),
+    ),
+    'delete subusers' => array(
+      'title' => t('delete subusers'),
+      'description' => t('Allows a user to delete subusers.'),
     ),
     'override subuser relation' => array(
       'title' => t('Override relation'),
@@ -53,6 +61,39 @@ function subuser_menu() {
  */
 function subuser_menu_alter(&$items) {
   $items['admin/people/create']['access callback'] = 'subuser_access_create_callback';
+  $items['user/%user']['access callback'] = 'subuser_access_view_callback';
+  $items['user/%user/cancel']['access callback'] = 'subuser_access_delete_callback';
+  $items['user/%user/cancel/confirm/%/%']['access callback'] = 'subuser_access_delete_callback';
+  $items['user/%user/edit']['access callback'] = 'subuser_access_edit_callback';
+}
+
+/**
+ * Implements hook_profile2_access().
+ */
+function subuser_profile2_access($op, $profile = NULL, $account = NULL) {
+  global $suer;
+  // Fall through if we're not checking access for the current user account
+  if ((!isset($account) || $account->uid == $user->uid) && isset($profile->uid)) {
+    switch ($op) {
+      case 'view':
+        if (subuser_access_view_callback($profile->uid)) {
+          return TRUE;
+        }
+        break;
+
+      case 'edit':
+        if (subuser_access_edit_callback($profile->uid)) {
+          return TRUE;
+        }
+        break;
+
+      case 'delete':
+        if (subuser_access_delete_callback($profile->uid)) {
+          return TRUE;
+        }
+    }
+    // Do not explicitly deny access so others may still grant access.
+  }
 }
 
 /**
@@ -78,6 +119,71 @@ function subuser_access_create($account = NULL) {
 }
 
 /**
+ * Our access callback for user editing - only permits users with
+ * 'edit subusers' to edit user or parent-user to edit subusers
+ *
+ * @param $account
+ *   the account being edited (user object or uid)
+ */
+function subuser_access_edit_callback($account) {
+  global $user;
+  $children = subuser_load_all($user);
+  $acct_uid = is_object($account) ? $account->uid : $account;
+
+  return (($user->uid == $acct_uid) || user_access('administer users') ||
+    (user_access('edit subusers') && in_array($acct_uid, $children))
+  ) && $acct_uid > 0;
+}
+
+/**
+ * Our access callback for user deleting - only permits users with
+ * 'delete subusers' to delete user or parent-user to delete subusers
+ *
+ * @param $account
+ *   the account being deleted (user object or uid)
+ */
+function subuser_access_delete_callback($account) {
+  global $user;
+  $children = subuser_load_all($user);
+  $acct_uid = is_object($account) ? $account->uid : $account;
+
+  return ((($user->uid == $acct_uid) && user_access('cancel account') ||
+    (user_access('delete subusers') && in_array($acct_uid, $children))
+  ) || user_access('administer users')) && $acct_uid > 0;
+}
+
+/**
+ * Our access callback for user viewing - only permits users with
+ * 'view subusers' to view user or parent-user to view subusers
+ *
+ * @param $account
+ *   the account being viewed (user object or uid)
+ */
+function subuser_access_view_callback($account) {
+  global $user;
+  $children = subuser_load_all($user);
+  $acct_uid = is_object($account) ? $account->uid : $account;
+
+  // Never allow access to view the anonymous user account.
+  if ($acct_uid) {
+    // Admins can view all, users can view own profiles at all times.
+    if ($user->uid == $acct_uid || user_access('administer users') ||
+      (user_access('view subusers', $user) && in_array($acct_uid, $children))
+    ) {
+      return TRUE;
+    }
+    elseif (user_access('access user profiles')) {
+      // At this point, load the complete account object.
+      if (!is_object($account)) {
+        $account = user_load((int) $acct_uid);
+      }
+      return (is_object($account) && $account->access && $account->status);
+    }
+  }
+  return FALSE;
+}
+
+/**
  * Determine whether the user has a given privilege.
  *
  * If not subuser_access_create() is checked to determin if the permission
