diff --git a/bootstrap.php b/bootstrap.php
index ef78830715a162dd91118d3edb8e600159adc8fd..4e2259cc3c86660bca8b49c888af6f73c6264a01 100644
--- a/bootstrap.php
+++ b/bootstrap.php
@@ -198,7 +198,6 @@ class Bootstrap {
         require(INCLUDE_DIR.'class.crypto.php');
         require(INCLUDE_DIR.'class.timezone.php');
         require_once(INCLUDE_DIR.'class.signal.php');
-        require(INCLUDE_DIR.'class.nav.php');
         require(INCLUDE_DIR.'class.page.php');
         require_once(INCLUDE_DIR.'class.format.php'); //format helpers
         require_once(INCLUDE_DIR.'class.validator.php'); //Class to help with basic form input validation...please help improve it.
diff --git a/client.inc.php b/client.inc.php
index 0a572ed1cfb82278c620945c00d32fb60e712427..2ad4d4702139d68e589dd917acfcedd4ca28f30d 100644
--- a/client.inc.php
+++ b/client.inc.php
@@ -76,6 +76,7 @@ $ost->addExtraHeader('<meta name="csrf_token" content="'.$ost->getCSRFToken().'"
 /* Client specific defaults */
 define('PAGE_LIMIT', DEFAULT_PAGE_LIMIT);
 
+require(INCLUDE_DIR.'class.nav.php');
 $nav = new UserNav($thisclient, 'home');
 
 $exempt = in_array(basename($_SERVER['SCRIPT_NAME']), array('logout.php', 'ajax.php', 'logs.php', 'upgrade.php'));
diff --git a/include/ajax.orgs.php b/include/ajax.orgs.php
index 7c849e6db88bd31267ebd2ab67a9aabb0e1d6e09..c582b578060b8ba09151db6739cc49c6431809ad 100644
--- a/include/ajax.orgs.php
+++ b/include/ajax.orgs.php
@@ -54,6 +54,8 @@ class OrgsAjaxAPI extends AjaxController {
 
         if(!$thisstaff)
             Http::response(403, 'Login Required');
+        elseif (!$thisstaff->getRole()->hasPerm(Organization::PERM_EDIT))
+            Http::response(403, 'Permission Denied');
         elseif(!($org = Organization::lookup($id)))
             Http::response(404, 'Unknown organization');
 
@@ -72,6 +74,8 @@ class OrgsAjaxAPI extends AjaxController {
 
         if(!$thisstaff)
             Http::response(403, 'Login Required');
+        elseif (!$thisstaff->getRole()->hasPerm(Organization::PERM_EDIT))
+            Http::response(403, 'Permission Denied');
         elseif(!($org = Organization::lookup($id)))
             Http::response(404, 'Unknown organization');
 
@@ -97,6 +101,8 @@ class OrgsAjaxAPI extends AjaxController {
 
         if (!$thisstaff)
             Http::response(403, 'Login Required');
+        elseif (!$thisstaff->getRole()->hasPerm(Organization::PERM_DELETE))
+            Http::response(403, 'Permission Denied');
         elseif (!($org = Organization::lookup($id)))
             Http::response(404, 'Unknown organization');
 
@@ -116,6 +122,8 @@ class OrgsAjaxAPI extends AjaxController {
 
         if (!$thisstaff)
             Http::response(403, 'Login Required');
+        elseif (!$thisstaff->getRole()->hasPerm(User::PERM_EDIT))
+            Http::response(403, 'Permission Denied');
         elseif (!($org = Organization::lookup($id)))
             Http::response(404, 'Unknown organization');
 
@@ -137,7 +145,8 @@ class OrgsAjaxAPI extends AjaxController {
                             Format::htmlchars($user->getName()));
             } else { //Creating new  user
                 $form = UserForm::getUserForm()->getForm($_POST);
-                if (!($user = User::fromForm($form)))
+                $can_create = $thisstaff->getRole()->hasPerm(User::PERM_CREATE);
+                if (!($user = User::fromForm($form, $can_create)))
                     $info['error'] = __('Error adding user - try again!');
             }
 
@@ -175,6 +184,8 @@ class OrgsAjaxAPI extends AjaxController {
 
         if (!$thisstaff)
             Http::response(403, 'Login Required');
+        elseif (!$thisstaff->getRole()->hasPerm(Organization::PERM_CREATE))
+            Http::response(403, 'Permission Denied');
         elseif (!($org = Organization::lookup($org_id)))
             Http::response(404, 'No such organization');
 
@@ -198,6 +209,10 @@ class OrgsAjaxAPI extends AjaxController {
     }
 
     function addOrg() {
+        global $thisstaff;
+
+        if (!$thisstaff->getRole()->hasPerm(Organization::PERM_CREATE))
+            Http::response(403, 'Permission Denied');
 
         $info = array();
 
@@ -266,6 +281,8 @@ class OrgsAjaxAPI extends AjaxController {
 
         if (!$thisstaff)
             Http::response(403, "Login required");
+        elseif (!$thisstaff->getRole()->hasPerm(Organization::PERM_EDIT))
+            Http::response(403, 'Permission Denied');
         elseif (!($org = Organization::lookup($org_id)))
             Http::response(404, "No such ticket");
         elseif (!isset($_POST['forms']))
diff --git a/include/ajax.users.php b/include/ajax.users.php
index cca1b11631263981e16c4f61b4ae6f5065878e45..d4cb6a94856b82c434742c43465d08a566f1651d 100644
--- a/include/ajax.users.php
+++ b/include/ajax.users.php
@@ -109,6 +109,8 @@ class UsersAjaxAPI extends AjaxController {
 
         if(!$thisstaff)
             Http::response(403, 'Login Required');
+        elseif (!$thisstaff->getRole()->hasPerm(User::PERM_EDIT))
+            Http::response(403, 'Permission Denied');
         elseif(!($user = User::lookup($id)))
             Http::response(404, 'Unknown user');
 
@@ -125,6 +127,8 @@ class UsersAjaxAPI extends AjaxController {
 
         if(!$thisstaff)
             Http::response(403, 'Login Required');
+        elseif (!$thisstaff->getRole()->hasPerm(User::PERM_EDIT))
+            Http::response(403, 'Permission Denied');
         elseif(!($user = User::lookup($id)))
             Http::response(404, 'Unknown user');
 
@@ -141,6 +145,8 @@ class UsersAjaxAPI extends AjaxController {
 
         if (!$thisstaff)
             Http::response(403, 'Login Required');
+        elseif (!$thisstaff->getRole()->hasPerm(User::PERM_MANAGE))
+            Http::response(403, 'Permission Denied');
         elseif (!($user = User::lookup($id)))
             Http::response(404, 'Unknown user');
 
@@ -168,6 +174,8 @@ class UsersAjaxAPI extends AjaxController {
 
         if (!$thisstaff)
             Http::response(403, 'Login Required');
+        elseif (!$thisstaff->getRole()->hasPerm(User::PERM_MANAGE))
+            Http::response(403, 'Permission Denied');
         elseif (!($user = User::lookup($id)))
             Http::response(404, 'Unknown user');
 
@@ -200,6 +208,8 @@ class UsersAjaxAPI extends AjaxController {
 
         if (!$thisstaff)
             Http::response(403, 'Login Required');
+        elseif (!$thisstaff->getRole()->hasPerm(User::PERM_DELETE))
+            Http::response(403, 'Permission Denied');
         elseif (!($user = User::lookup($id)))
             Http::response(404, 'Unknown user');
 
@@ -240,9 +250,13 @@ class UsersAjaxAPI extends AjaxController {
     }
 
     function addUser() {
+        global $thisstaff;
 
         $info = array();
 
+        if (!$thisstaff->getRole()->hasPerm(User::PERM_CREATE))
+            Http::response(403, 'Permission Denied');
+
         if (!AuthenticationBackend::getSearchDirectories())
             $info['lookup'] = 'local';
 
@@ -263,6 +277,8 @@ class UsersAjaxAPI extends AjaxController {
 
         if (!$thisstaff)
             Http::response(403, 'Login Required');
+        elseif (!$thisstaff->getRole()->hasPerm(User::PERM_CREATE))
+            Http::response(403, 'Permission Denied');
         elseif (!$bk || !$id)
             Http::response(422, 'Backend and user id required');
         elseif (!($backend = AuthenticationBackend::getSearchDirectoryBackend($bk))
@@ -284,6 +300,8 @@ class UsersAjaxAPI extends AjaxController {
 
         if (!$thisstaff)
             Http::response(403, 'Login Required');
+        elseif (!$thisstaff->getRole()->hasPerm(User::PERM_CREATE))
+            Http::response(403, 'Permission Denied');
 
         $info = array(
             'title' => __('Import Users'),
@@ -304,6 +322,7 @@ class UsersAjaxAPI extends AjaxController {
     }
 
     function selectUser($id) {
+        global $thisstaff;
 
         if ($id)
             $user = User::lookup($id);
@@ -319,9 +338,14 @@ class UsersAjaxAPI extends AjaxController {
     }
 
     static function _lookupform($form=null, $info=array()) {
+        global $thisstaff;
 
-        if (!$info or !$info['title'])
-            $info += array('title' => __('Lookup or create a user'));
+        if (!$info or !$info['title']) {
+            if ($thisstaff->getRole()->hasPerm(User::PERM_CREATE))
+                $info += array('title' => __('Lookup or create a user'));
+            else
+                $info += array('title' => __('Lookup a user'));
+        }
 
         ob_start();
         include(STAFFINC_DIR . 'templates/user-lookup.tmpl.php');
@@ -422,6 +446,8 @@ class UsersAjaxAPI extends AjaxController {
 
         if (!$thisstaff)
             Http::response(403, "Login required");
+        elseif (!$thisstaff->getRole()->hasPerm(User::PERM_EDIT))
+            Http::response(403, 'Permission Denied');
         elseif (!($user = User::lookup($user_id)))
             Http::response(404, "No such user");
         elseif (!isset($_POST['forms']))
diff --git a/include/class.nav.php b/include/class.nav.php
index d3cbb943dfe2cd0e219060dea7802482f8d23585..92d08996a2bcd6d2076955021b36fc570c2e7dda 100644
--- a/include/class.nav.php
+++ b/include/class.nav.php
@@ -111,10 +111,18 @@ class StaffNav {
 
 
     function getTabs(){
+        global $thisstaff;
+
         if(!$this->tabs) {
-            $this->tabs=array();
-            $this->tabs['dashboard'] = array('desc'=>__('Dashboard'),'href'=>'dashboard.php','title'=>__('Agent Dashboard'));
-            $this->tabs['users'] = array('desc' => __('Users'), 'href' => 'users.php', 'title' => __('User Directory'));
+            $this->tabs = array();
+            $this->tabs['dashboard'] = array(
+                'desc'=>__('Dashboard'),'href'=>'dashboard.php','title'=>__('Agent Dashboard')
+            );
+            if ($thisstaff->getRole()->hasPerm(User::PERM_DIRECTORY)) {
+                $this->tabs['users'] = array(
+                    'desc' => __('Users'), 'href' => 'users.php', 'title' => __('User Directory')
+                );
+            }
             $this->tabs['tickets'] = array('desc'=>__('Tickets'),'href'=>'tickets.php','title'=>__('Ticket Queue'));
             $this->tabs['kbase'] = array('desc'=>__('Knowledgebase'),'href'=>'kb.php','title'=>__('Knowledgebase'));
             if (count($this->getRegisteredApps()))
diff --git a/include/class.organization.php b/include/class.organization.php
index e13329507aba063361ad6cd834554f89b37f18cd..34ddcb15df54ccddcf9ad33ccdd0e8b0360b3b71 100644
--- a/include/class.organization.php
+++ b/include/class.organization.php
@@ -35,6 +35,25 @@ class OrganizationModel extends VerySimpleModel {
     const COLLAB_PRIMARY_CONTACT =  0x0002;
     const ASSIGN_AGENT_MANAGER =    0x0004;
 
+    const PERM_CREATE =     'org.create';
+    const PERM_EDIT =       'org.edit';
+    const PERM_DELETE =     'org.delete';
+
+    static protected $perms = array(
+        self::PERM_CREATE => array(
+            'title' => /* @trans */ 'Create',
+            'desc' => /* @trans */ 'Ability to create new organizations',
+        ),
+        self::PERM_EDIT => array(
+            'title' => /* @trans */ 'Edit',
+            'desc' => /* @trans */ 'Ability to manage organizations',
+        ),
+        self::PERM_DELETE => array(
+            'title' => /* @trans */ 'Delete',
+            'desc' => /* @trans */ 'Ability to delete organizations',
+        ),
+    );
+
     var $_manager;
 
     function getId() {
@@ -101,7 +120,14 @@ class OrganizationModel extends VerySimpleModel {
     function allMembers() {
         return $this->users;
     }
+
+    static function getPermissions() {
+        return self::$perms;
+    }
 }
+include_once INCLUDE_DIR.'class.role.php';
+RolePermission::register(/* @trans */ 'Organizations',
+    OrganizationModel::getPermissions());
 
 class OrganizationCdata extends VerySimpleModel {
     static $meta = array(
diff --git a/include/class.role.php b/include/class.role.php
index 476bd9a72b89721f1235a9f3b1dfdf65a2d89587..b2bcd2c97d0813d7cff5fd03d854bbf607cadeb1 100644
--- a/include/class.role.php
+++ b/include/class.role.php
@@ -266,6 +266,8 @@ class RolePermission {
     static protected $_permissions = array(
             /* @trans */ 'Tickets' => array(),
             /* @trans */ 'Tasks' => array(),
+            /* @trans */ 'Users' => array(),
+            /* @trans */ 'Organizations' => array(),
             /* @trans */ 'Knowledgebase' => array(),
             /* @trans */ 'Miscellaneous' => array(),
             );
diff --git a/include/class.search.php b/include/class.search.php
index 5436ff519333b7ff3e578703fc13672cd194ed34..616fb9ce0b0e1897f443709dc1758ffd620d8162 100644
--- a/include/class.search.php
+++ b/include/class.search.php
@@ -30,6 +30,15 @@ abstract class SearchBackend {
     const SORT_RECENT = 2;
     const SORT_OLDEST = 3;
 
+    const PERM_AGENTS = 'search.all';
+
+    static protected $perms = array(
+        self::PERM_AGENTS => array(
+            'title' => /* @trans */ 'Search',
+            'desc'  => /* @trans */ 'See all tickets in search results, regardless of access'
+        ),
+    );
+
     abstract function update($model, $id, $content, $new=false, $attrs=array());
     abstract function find($query, QuerySet $criteria);
 
@@ -48,7 +57,12 @@ abstract class SearchBackend {
 
         return new self::$registry[$id]();
     }
+
+    static function getPermissions() {
+        return self::$perms;
+    }
 }
+RolePermission::register(/* @trans */ 'Miscellaneous', SearchBackend::getPermissions());
 
 // Register signals to intercept saving of various content throughout the
 // system
diff --git a/include/class.staff.php b/include/class.staff.php
index 44f7d6302e70558bbfe604b74050d825218836a7..6a7c06a260ddf63e0cdfda442c65cd74f7daa548 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -320,7 +320,7 @@ implements AuthenticatedUser, EmailContact {
             if (isset($this->_roles[$deptId]))
                 return $this->_roles[$deptId];
 
-            if (($role=$this->group->getRole($deptId)))
+            if (($role = $this->group->getRole($deptId)))
                 return $this->_roles[$deptId] = $role;
         }
         // For the primary department, use the primary role
@@ -329,6 +329,7 @@ implements AuthenticatedUser, EmailContact {
 
     function hasPerm($perm) {
         if (!isset($this->_perms)) {
+            $this->_perms = array();
             foreach ($this->getDepartments() as $deptId) {
                 if (($role = $this->getRole($deptId))) {
                     foreach ($role->getPermission()->getInfo() as $perm=>$v) {
@@ -337,7 +338,7 @@ implements AuthenticatedUser, EmailContact {
                 }
             }
         }
-        return @$this->_perms[$perm];
+        return @$this->_perms[$perm] ?: false;
     }
 
     function canManageTickets() {
diff --git a/include/class.ticket.php b/include/class.ticket.php
index 0505d9832bceb4ceda56ce80d52c462fd3b95e54..c5f364de9b756bbbb9e9db142ae1a4bbc3b3514e 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -2790,7 +2790,7 @@ implements RestrictedAccess, Threadable {
      */
     static function create($vars, &$errors, $origin, $autorespond=true,
             $alertstaff=true) {
-        global $ost, $cfg, $thisclient, $_FILES;
+        global $ost, $cfg, $thisclient, $thisstaff;
 
         // Don't enforce form validation for email
         $field_filter = function($type) use ($origin) {
@@ -2958,9 +2958,14 @@ implements RestrictedAccess, Threadable {
                 }
 
                 $user_form = UserForm::getUserForm()->getForm($vars);
+                $can_create = $thisstaff->getRole()->hasPerm(User::PERM_CREATE);
                 if (!$user_form->isValid($field_filter('user'))
-                        || !($user=User::fromVars($user_form->getClean())))
-                    $errors['user'] = __('Incomplete client information');
+                    || !($user=User::fromVars($user_form->getClean(), $can_create))
+                ) {
+                    $errors['user'] = $can_create
+                        ? __('Incomplete client information')
+                        : __('You do not have permission to create users.');
+                }
             }
         }
 
diff --git a/include/class.user.php b/include/class.user.php
index 3a5fd1c29e205db10434a235315117b808de74c2..5bf264644c7c5418767eb9c7fa4a1eaf3d07d544 100644
--- a/include/class.user.php
+++ b/include/class.user.php
@@ -69,6 +69,35 @@ class UserModel extends VerySimpleModel {
 
     const PRIMARY_ORG_CONTACT   = 0x0001;
 
+    const PERM_CREATE =     'user.create';
+    const PERM_EDIT =       'user.edit';
+    const PERM_DELETE =     'user.delete';
+    const PERM_MANAGE =     'user.manage';
+    const PERM_DIRECTORY =  'user.dir';
+
+    static protected $perms = array(
+        self::PERM_CREATE => array(
+            'title' => /* @trans */ 'Create',
+            'desc' => /* @trans */ 'Ability to add new users',
+        ),
+        self::PERM_EDIT => array(
+            'title' => /* @trans */ 'Edit',
+            'desc' => /* @trans */ 'Ability to manage user information',
+        ),
+        self::PERM_DELETE => array(
+            'title' => /* @trans */ 'Delete',
+            'desc' => /* @trans */ 'Ability to delete users',
+        ),
+        self::PERM_MANAGE => array(
+            'title' => /* @trans */ 'Manage Account',
+            'desc' => /* @trans */ 'Ability to manage active user accounts',
+        ),
+        self::PERM_DIRECTORY => array(
+            'title' => /* @trans */ 'User Directory',
+            'desc' => /* @trans */ 'Ability to access the user directory',
+        ),
+    );
+
     function getId() {
         return $this->id;
     }
@@ -125,7 +154,13 @@ class UserModel extends VerySimpleModel {
         else
             $this->clearStatus(User::PRIMARY_ORG_CONTACT);
     }
+
+    static function getPermissions() {
+        return self::$perms;
+    }
 }
+include_once INCLUDE_DIR.'class.role.php';
+RolePermission::register(/* @trans */ 'Users', UserModel::getPermissions());
 
 class UserCdata extends VerySimpleModel {
     static $meta = array(
@@ -146,10 +181,10 @@ class User extends UserModel {
     var $_entries;
     var $_forms;
 
-    static function fromVars($vars) {
+    static function fromVars($vars, $create=true) {
         // Try and lookup by email address
         $user = static::lookupByEmail($vars['email']);
-        if (!$user) {
+        if (!$user && $create) {
             $name = $vars['name'];
             if (!$name)
                 list($name) = explode('@', $vars['email'], 2);
@@ -184,7 +219,7 @@ class User extends UserModel {
         return $user;
     }
 
-    static function fromForm($form) {
+    static function fromForm($form, $create=true) {
         global $thisstaff;
 
         if(!$form) return null;
@@ -205,7 +240,7 @@ class User extends UserModel {
             $valid = false;
         }
 
-        return $valid ? self::fromVars($form->getClean()) : null;
+        return $valid ? self::fromVars($form->getClean(), $create) : null;
     }
 
     function getEmail() {
diff --git a/include/i18n/en_US/role.yaml b/include/i18n/en_US/role.yaml
index d83a60c2914848730123c02c623b52e7b210cd71..4e3a15e839dc06621146f12a3ca46e1f24ed2e3f 100644
--- a/include/i18n/en_US/role.yaml
+++ b/include/i18n/en_US/role.yaml
@@ -34,7 +34,15 @@
     kb.premade,
     kb.faq,
     stats.agents,
-    emails.banlist]
+    emails.banlist,
+    user.edit,
+    user.delete,
+    user.manage,
+    user.dir,
+    org.create,
+    org.edit,
+    org.delete,
+    search.all]
 
 - id: 2
   flags: 1
@@ -58,7 +66,14 @@
     kb.premade,
     kb.faq,
     stats.agents,
-    emails.banlist]
+    emails.banlist,
+    user.edit,
+    user.delete,
+    user.manage,
+    user.dir,
+    org.create,
+    org.edit,
+    org.delete]
 
 - id: 3
   flags: 1
@@ -74,4 +89,9 @@
     task.create,
     task.assign,
     task.transfer,
-    task.reply]
+    task.reply,
+    user.edit,
+    user.manage,
+    user.dir,
+    org.create,
+    org.edit]
diff --git a/include/staff/org-view.inc.php b/include/staff/org-view.inc.php
index 112570e2e8c0f7679281b1d0a2cb88dbbfb31f06..492a5b86c51a9725f0a4a34de459afe66aa8cd7f 100644
--- a/include/staff/org-view.inc.php
+++ b/include/staff/org-view.inc.php
@@ -9,21 +9,27 @@ if(!defined('OSTSCPINC') || !$thisstaff || !is_object($org)) die('Invalid path')
              title="Reload"><i class="icon-refresh"></i> <?php echo $org->getName(); ?></a></h2>
         </td>
         <td width="50%" class="right_align has_bottom_border">
+<?php if ($thisstaff->getRole()->hasPerm(Organization::PERM_EDIT)) { ?>
             <span class="action-button pull-right" data-dropdown="#action-dropdown-more">
                 <i class="icon-caret-down pull-right"></i>
                 <span ><i class="icon-cog"></i> <?php echo __('More'); ?></span>
             </span>
+<?php } ?>
+<?php if ($thisstaff->getRole()->hasPerm(Organization::PERM_DELETE)) { ?>
             <a id="org-delete" class="action-button pull-right org-action"
             href="#orgs/<?php echo $org->getId(); ?>/delete"><i class="icon-trash"></i>
             <?php echo __('Delete Organization'); ?></a>
+<?php } ?>
             <div id="action-dropdown-more" class="action-dropdown anchor-right">
               <ul>
+<?php if ($thisstaff->getRole()->hasPerm(Organization::PERM_EDIT)) { ?>
                 <li><a href="#ajax.php/orgs/<?php echo $org->getId();
                     ?>/forms/manage" onclick="javascript:
                     $.dialog($(this).attr('href').substr(1), 201);
                     return false"
                     ><i class="icon-paste"></i>
                     <?php echo __('Manage Forms'); ?></a></li>
+<?php } ?>
               </ul>
             </div>
         </td>
@@ -35,11 +41,17 @@ if(!defined('OSTSCPINC') || !$thisstaff || !is_object($org)) die('Invalid path')
             <table border="0" cellspacing="" cellpadding="4" width="100%">
                 <tr>
                     <th width="150"><?php echo __('Name'); ?>:</th>
-                    <td><b><a href="#orgs/<?php echo $org->getId();
+                    <td>
+<?php if ($thisstaff->getRole()->hasPerm(Organization::PERM_EDIT)) { ?>
+                    <b><a href="#orgs/<?php echo $org->getId();
                     ?>/edit" class="org-action"><i
-                    class="icon-edit"></i>&nbsp;<?php echo
-                    $org->getName();
-                    ?></a></td>
+                        class="icon-edit"></i>
+<?php }
+                    echo $org->getName();
+    if ($thisstaff->getRole()->hasPerm(Organization::PERM_EDIT)) { ?>
+                    </a></b>
+<?php } ?>
+                    </td>
                 </tr>
                 <tr>
                     <th><?php echo __('Account Manager'); ?>:</th>
diff --git a/include/staff/orgs.inc.php b/include/staff/orgs.inc.php
index f75f67f556d9e6fbf715ed374a1771e5b06c44d0..4973b0b6252933fc87a8106b3ad3f0fcbe79f6bf 100644
--- a/include/staff/orgs.inc.php
+++ b/include/staff/orgs.inc.php
@@ -86,9 +86,11 @@ $_SESSION['orgs_qs_'.$qhash] = $query;
         </table>
     </form>
  </div>
+<?php if ($thisstaff->getRole()->hasPerm(Organization::PERM_CREATE)) { ?>
  <div class="pull-right flush-right">
     <b><a href="#orgs/add" class="Icon newDepartment add-org"><?php
     echo __('Add New Organization'); ?></a></b></div>
+<?php } ?>
 <div class="clear"></div>
 <?php
 $showing = $search ? __('Search Results').': ' : '';
diff --git a/include/staff/templates/user-import.tmpl.php b/include/staff/templates/user-import.tmpl.php
index b9ca02007d39bb21c5806edd74c79acbdd8216b8..413ed54e4bcbaeed35f4a2a234e4d78722b4a96d 100644
--- a/include/staff/templates/user-import.tmpl.php
+++ b/include/staff/templates/user-import.tmpl.php
@@ -22,12 +22,6 @@ if ($info['error']) {
         $(this).attr('action', '<?php echo $info['upload_url']; ?>');
         $(document).unbind('submit.dialog');
     }">
-<ul class="tabs">
-    <li class="active"><a href="#copy-paste"
-        ><i class="icon-edit"></i>&nbsp;<?php echo __('Copy Paste'); ?></a></li>
-    <li><a href="#upload"
-        ><i class="icon-fixed-width icon-cloud-upload"></i>&nbsp;<?php echo __('Upload'); ?></a></li>
-</ul>
 <?php echo csrf_token();
 if ($org_id) { ?>
     <input type="hidden" name="id" value="<?php echo $org_id; ?>"/>
diff --git a/include/staff/templates/user-lookup.tmpl.php b/include/staff/templates/user-lookup.tmpl.php
index fa18f885888041d997c5e75e192d5644e7fd35b2..568df91f8d84ed4c4cb18fcf2745722e2e613a13 100644
--- a/include/staff/templates/user-lookup.tmpl.php
+++ b/include/staff/templates/user-lookup.tmpl.php
@@ -4,9 +4,11 @@
 <hr/>
 <?php
 if (!isset($info['lookup']) || $info['lookup'] !== false) { ?>
-<div><p id="msg_info"><i class="icon-info-sign"></i>&nbsp; <?php echo __(
-'Search existing users or add a new user.'
-); ?></p></div>
+<div><p id="msg_info"><i class="icon-info-sign"></i>&nbsp; <?php echo
+    $thisstaff->getRole()->hasPerm(User::PERM_CREATE)
+    ? __('Search existing users or add a new user.')
+    : __('Search existing users.');
+?></p></div>
 <div style="margin-bottom:10px;">
     <input type="text" class="search-input" style="width:100%;"
     placeholder="<?php echo __('Search by email, phone or name'); ?>" id="user-search"
@@ -26,10 +28,12 @@ if ($info['error']) {
 <form method="post" class="user" action="<?php echo $info['action'] ?  $info['action'] : '#users/lookup'; ?>">
     <input type="hidden" id="user-id" name="id" value="<?php echo $user ? $user->getId() : 0; ?>"/>
     <i class="icon-user icon-4x pull-left icon-border"></i>
+<?php if ($thisstaff->getRole()->hasPerm(User::PERM_CREATE)) { ?>
     <a class="action-button pull-right" style="overflow:inherit"
         id="unselect-user"  href="#"><i class="icon-remove"></i>
         <?php echo __('Add New User'); ?></a>
-<?php if ($user) { ?>
+<?php }
+if ($user) { ?>
     <div><strong id="user-name"><?php echo Format::htmlchars($user->getName()->getOriginal()); ?></strong></div>
     <div>&lt;<span id="user-email"><?php echo $user->getEmail(); ?></span>&gt;</div>
     <?php
@@ -65,6 +69,7 @@ if ($info['error']) {
 </form>
 </div>
 <div id="new-user-form" style="display:<?php echo $user ? 'none' :'block'; ?>;">
+<?php if ($thisstaff->getRole()->hasPerm(User::PERM_CREATE)) { ?>
 <form method="post" class="user" action="<?php echo $info['action'] ?: '#users/lookup/form'; ?>">
     <table width="100%" class="fixed">
     <?php
@@ -82,6 +87,15 @@ if ($info['error']) {
         </span>
      </p>
 </form>
+<?php }
+else { ?>
+    <hr/>
+    <p class="full-width">
+        <span class="buttons pull-left">
+            <input type="button" name="cancel" class="<?php echo $user ?  'cancel' : 'close' ?>"  value="<?php echo __('Cancel'); ?>">
+        </span>
+     </p>
+<?php } ?>
 </div>
 <div class="clear"></div>
 </div>
diff --git a/include/staff/templates/users.tmpl.php b/include/staff/templates/users.tmpl.php
index b95974d214cf17d57ef2062b1d26de4bd7106307..c8a262022a0d036d6127720354c77902ca59861d 100644
--- a/include/staff/templates/users.tmpl.php
+++ b/include/staff/templates/users.tmpl.php
@@ -57,6 +57,7 @@ else
 
 ?>
 <div style="width:700px;" class="pull-left"><b><?php echo $showing; ?></b></div>
+<?php if ($thisstaff->getRole()->hasPerm(User::PERM_EDIT)) { ?>
 <div class="pull-right flush-right" style="padding-right:5px;">
     <b><a href="#orgs/<?php echo $org->getId(); ?>/add-user" class="Icon newstaff add-user"
         ><?php echo __('Add User'); ?></a></b>
@@ -65,6 +66,7 @@ else
     <i class="icon-cloud-upload icon-large"></i>
     <?php echo __('Import'); ?></a></b>
 </div>
+<?php } ?>
 <div class="clear"></div>
 <br/>
 <?php
diff --git a/include/staff/ticket-open.inc.php b/include/staff/ticket-open.inc.php
index 9591f1794afe9ba08f62db40f9fafb073fb88954..a6fe4c26cce9173c1c1d30eaaa954e79de4a99e4 100644
--- a/include/staff/ticket-open.inc.php
+++ b/include/staff/ticket-open.inc.php
@@ -45,6 +45,7 @@ if ($_POST)
         <tr>
             <th colspan="2">
                 <em><strong><?php echo __('User Information'); ?></strong>: </em>
+                <div class="error"><?php echo $errors['user']; ?></div>
             </th>
         </tr>
         <?php
@@ -84,7 +85,8 @@ if ($_POST)
                 <span style="display:inline-block;">
                     <input type="text" size=45 name="email" id="user-email"
                         autocomplete="off" autocorrect="off" value="<?php echo $info['email']; ?>" /> </span>
-                <font class="error">* <?php echo $errors['email']; ?></font>
+                <span class="error">*</span>
+                <div class="error"><?php echo $errors['email']; ?></div>
             </td>
         </tr>
         <tr>
@@ -92,7 +94,8 @@ if ($_POST)
             <td>
                 <span style="display:inline-block;">
                     <input type="text" size=45 name="name" id="user-name" value="<?php echo $info['name']; ?>" /> </span>
-                <font class="error">* <?php echo $errors['name']; ?></font>
+                <span class="error">*</span>
+                <div class="error"><?php echo $errors['name']; ?></div>
             </td>
         </tr>
         <?php
diff --git a/include/staff/user-view.inc.php b/include/staff/user-view.inc.php
index 6d29d8b2492287165369760ba3ca7320eaaa9526..9e6fb90faf2f1aeac16daa97a53c5ca0d4325104 100644
--- a/include/staff/user-view.inc.php
+++ b/include/staff/user-view.inc.php
@@ -13,13 +13,19 @@ $org = $user->getOrganization();
              title="Reload"><i class="icon-refresh"></i> <?php echo Format::htmlchars($user->getName()); ?></a></h2>
         </td>
         <td width="50%" class="right_align has_bottom_border">
+<?php if (($account && $account->isConfirmed())
+    || $thisstaff->getRole()->hasPerm(User::PERM_EDIT)) { ?>
             <span class="action-button pull-right" data-dropdown="#action-dropdown-more">
                 <i class="icon-caret-down pull-right"></i>
-                <span ><i class="icon-cog"></i> <?php echo __('More'); ?></span>
+                <span><i class="icon-cog"></i> <?php echo __('More'); ?></span>
             </span>
+<?php }
+    if ($thisstaff->getRole()->hasPerm(User::PERM_DELETE)) { ?>
             <a id="user-delete" class="action-button pull-right user-action"
             href="#users/<?php echo $user->getId(); ?>/delete"><i class="icon-trash"></i>
             <?php echo __('Delete User'); ?></a>
+<?php } ?>
+<?php if ($thisstaff->getRole()->hasPerm(User::PERM_MANAGE)) { ?>
             <?php
             if ($account) { ?>
             <a id="user-manage" class="action-button pull-right user-action"
@@ -32,6 +38,7 @@ $org = $user->getOrganization();
             <?php echo __('Register'); ?></a>
             <?php
             } ?>
+<?php } ?>
             <div id="action-dropdown-more" class="action-dropdown anchor-right">
               <ul>
                 <?php
@@ -48,19 +55,22 @@ $org = $user->getOrganization();
                         <?php echo __('Send Password Reset Email'); ?></a></li>
                     <?php
                     } ?>
+<?php if ($thisstaff->getRole()->hasPerm(User::PERM_MANAGE)) { ?>
                     <li><a class="user-action"
                         href="#users/<?php echo $user->getId(); ?>/manage/access"><i
                         class="icon-lock"></i>
                         <?php echo __('Manage Account Access'); ?></a></li>
                 <?php
-
+}
                 } ?>
+<?php if ($thisstaff->getRole()->hasPerm(User::PERM_EDIT)) { ?>
                 <li><a href="#ajax.php/users/<?php echo $user->getId();
                     ?>/forms/manage" onclick="javascript:
                     $.dialog($(this).attr('href').substr(1), 201);
                     return false"
                     ><i class="icon-paste"></i>
                     <?php echo __('Manage Forms'); ?></a></li>
+<?php } ?>
 
               </ul>
             </div>
@@ -73,11 +83,18 @@ $org = $user->getOrganization();
             <table border="0" cellspacing="" cellpadding="4" width="100%">
                 <tr>
                     <th width="150"><?php echo __('Name'); ?>:</th>
-                    <td><b><a href="#users/<?php echo $user->getId();
+                    <td>
+<?php
+if ($thisstaff->getRole()->hasPerm(User::PERM_EDIT)) { ?>
+                    <b><a href="#users/<?php echo $user->getId();
                     ?>/edit" class="user-action"><i
-                    class="icon-edit"></i>&nbsp;<?php echo
-                    Format::htmlchars($user->getName()->getOriginal());
-                    ?></a></td>
+                        class="icon-edit"></i>
+<?php }
+                    echo Format::htmlchars($user->getName()->getOriginal());
+if ($thisstaff->getRole()->hasPerm(User::PERM_EDIT)) { ?>
+                    </a>
+<?php } ?>
+</td>
                 </tr>
                 <tr>
                     <th><?php echo __('Email'); ?>:</th>
@@ -93,10 +110,10 @@ $org = $user->getOrganization();
                             if ($org)
                                 echo sprintf('<a href="#users/%d/org" class="user-action">%s</a>',
                                         $user->getId(), $org->getName());
-                            else
-                                echo sprintf('<a href="#users/%d/org"
-                                        class="user-action">Add Organization</a>',
-                                        $user->getId());
+                            elseif ($thisstaff->getRole()->hasPerm(User::PERM_EDIT)) { ?>
+                                <a href="#users/<?php echo $user->getId(); ?>/org"
+                                class="user-action"><?php echo __('Add Organization'); ?></a>
+<?php                       }
                         ?>
                         </span>
                     </td>
diff --git a/include/staff/users.inc.php b/include/staff/users.inc.php
index 763e121d4fec94ac4e6f1f4ee3b7c5b2c52940ac..7e9be8950c5cd1d9c5895018743c2ad79ecc51f7 100644
--- a/include/staff/users.inc.php
+++ b/include/staff/users.inc.php
@@ -71,12 +71,14 @@ $users->order_by($order . $order_column);
         </table>
     </form>
  </div>
+<?php if ($thisstaff->getRole()->hasPerm(User::PERM_CREATE)) { ?>
  <div class="pull-right flush-right" style="padding-right:5px;">
     <b><a href="#users/add" class="Icon newstaff popup-dialog"><?php echo __('Add User'); ?></a></b>
     |
     <b><a href="#users/import" class="popup-dialog"><i class="icon-cloud-upload icon-large"></i>
     <?php echo __('Import'); ?></a></b>
 </div>
+<?php } ?>
 <div class="clear"></div>
 <?php
 $showing = $search ? __('Search Results').': ' : '';
diff --git a/scp/roles.php b/scp/roles.php
index 2c9476e29b8cb7499b01f7d5e7d171fe980af980..824d13b14e285a4ae22d22283a9e988f36eaf0bf 100644
--- a/scp/roles.php
+++ b/scp/roles.php
@@ -15,6 +15,8 @@
 **********************************************************************/
 
 require 'admin.inc.php';
+include_once INCLUDE_DIR . 'class.user.php';
+include_once INCLUDE_DIR . 'class.organization.php';
 include_once INCLUDE_DIR . 'class.canned.php';
 include_once INCLUDE_DIR . 'class.faq.php';
 include_once INCLUDE_DIR . 'class.email.php';
diff --git a/scp/staff.inc.php b/scp/staff.inc.php
index 2ec1221e7f984044a7612302bcc1ed2c604c2378..e17314959df935b19883410b89a1a64353e44d65 100644
--- a/scp/staff.inc.php
+++ b/scp/staff.inc.php
@@ -36,7 +36,6 @@ define('KB_PREMADE_TABLE',TABLE_PREFIX.'kb_premade');
 
 require_once(INCLUDE_DIR.'class.staff.php');
 require_once(INCLUDE_DIR.'class.group.php');
-require_once(INCLUDE_DIR.'class.nav.php');
 require_once(INCLUDE_DIR.'class.csrf.php');
 
 /* First order of the day is see if the user is logged in and with a valid session.
@@ -103,6 +102,9 @@ if ($_POST  && !$ost->checkCSRFToken()) {
 //Add token to the header - used on ajax calls [DO NOT CHANGE THE NAME]
 $ost->addExtraHeader('<meta name="csrf_token" content="'.$ost->getCSRFToken().'" />');
 
+// Load the navigation after the user in case some things are hidden
+require_once(INCLUDE_DIR.'class.nav.php');
+
 /******* SET STAFF DEFAULTS **********/
 define('PAGE_LIMIT', $thisstaff->getPageLimit()?$thisstaff->getPageLimit():DEFAULT_PAGE_LIMIT);
 
diff --git a/scp/users.php b/scp/users.php
index ade2474137ff87dd793e9ebc01d9aad9dcd2a98c..a606ddca6adadd5aa34b520348d3ad9f760cd045 100644
--- a/scp/users.php
+++ b/scp/users.php
@@ -14,6 +14,9 @@
 **********************************************************************/
 require('staff.inc.php');
 
+if (!$thisstaff->getRole()->hasPerm(User::PERM_DIRECTORY))
+    Http::redirect('index.php');
+
 require_once INCLUDE_DIR.'class.note.php';
 
 $user = null;
@@ -25,6 +28,8 @@ if ($_POST) {
         case 'update':
             if (!$user) {
                 $errors['err']=sprintf(__('%s: Unknown or invalid'), _N('end user', 'end users', 1));
+            } elseif (!$thisstaff->getRole()->hasPerm(User::PERM_EDIT)) {
+                $errors['err'] = __('Action denied. Contact admin for access');
             } elseif(($acct = $user->getAccount())
                     && !$acct->update($_POST, $errors)) {
                  $errors['err']=__('Unable to update user account information');