diff --git a/application/forms/Security/RoleForm.php b/application/forms/Security/RoleForm.php index d1e8fd03f..39346c945 100644 --- a/application/forms/Security/RoleForm.php +++ b/application/forms/Security/RoleForm.php @@ -195,8 +195,19 @@ class RoleForm extends RepositoryForm 'description' => $this->translate('Everything is allowed') ] ); + $this->addElement( + 'checkbox', + 'unrestricted', + [ + 'autosubmit' => true, + 'uncheckedValue' => null, + 'label' => $this->translate('Unrestricted Access'), + 'description' => $this->translate('Access to any data is completely unrestricted') + ] + ); $hasAdminPerm = isset($formData[self::WILDCARD_NAME]) && $formData[self::WILDCARD_NAME]; + $isUnrestricted = isset($formData['unrestricted']) && $formData['unrestricted']; foreach ($this->providedPermissions as $moduleName => $permissionList) { $this->sortPermissions($permissionList); @@ -301,7 +312,9 @@ class RoleForm extends RepositoryForm '/​', isset($spec['label']) ? $spec['label'] : $spec['name'] ), - 'description' => $spec['description'] + 'description' => $spec['description'], + 'style' => $isUnrestricted ? 'text-decoration:line-through;' : '', + 'readonly' => $isUnrestricted ?: null ] ) ->getElement($name) @@ -339,6 +352,7 @@ class RoleForm extends RepositoryForm 'name' => $role->name, 'users' => $role->users, 'groups' => $role->groups, + 'unrestricted' => $role->unrestricted, self::WILDCARD_NAME => (bool) preg_match('~(?permissions) ]; diff --git a/doc/06-Security.md b/doc/06-Security.md index ac2a120cf..0fb1d9e63 100644 --- a/doc/06-Security.md +++ b/doc/06-Security.md @@ -80,8 +80,17 @@ users | Comma-separated list of **usernames** that should oc groups | Comma-separated list of **group names** whose users should occupy this role. permissions | Comma-separated list of **permissions** granted by this role. refusals | Comma-separated list of **permissions** refused by this role. +unrestricted | If set to `1`, owners of this role are not restricted in any way (Default: `0`) monitoring/filter/objects | **Filter expression** that restricts the access to monitoring objects. +### Administrative Roles + +Roles that have the wildcard `*` as permission, have full access and don't need any further permissions. However, +they are still affected by refusals. + +Unrestricted roles are supposed to allow users to access data without being limited to a subset of it. Once a user +occupies an unrestricted role, restrictions of the same and any other role are ignored. + ### Inheritance A role can inherit privileges from another role. Privileges are then combined the same way as if a user occupies diff --git a/library/Icinga/Authentication/AdmissionLoader.php b/library/Icinga/Authentication/AdmissionLoader.php index 38ad18dd3..1b8bb239e 100644 --- a/library/Icinga/Authentication/AdmissionLoader.php +++ b/library/Icinga/Authentication/AdmissionLoader.php @@ -93,7 +93,8 @@ class AdmissionLoader ->setName($name) ->setRefusals($refusals) ->setPermissions($permissions) - ->setRestrictions($restrictions); + ->setRestrictions($restrictions) + ->setIsUnrestricted($section->get('unrestricted', false)); if (isset($section->parent)) { $parentName = $section->parent; @@ -144,6 +145,7 @@ class AdmissionLoader $roles = []; $permissions = []; $restrictions = []; + $isUnrestricted = false; foreach ($this->roleConfig as $roleName => $roleConfig) { if (! isset($roles[$roleName]) && $this->match($username, $userGroups, $roleConfig)) { foreach ($this->loadRole($roleName, $roleConfig) as $role) { @@ -162,11 +164,15 @@ class AdmissionLoader } $role->setRestrictions($roleRestrictions); + + if (! $isUnrestricted) { + $isUnrestricted = $role->isUnrestricted(); + } } } } - $user->setRestrictions($restrictions); + $user->setRestrictions($isUnrestricted ? [] : $restrictions); $user->setPermissions($permissions); $user->setRoles(array_values($roles)); } diff --git a/library/Icinga/Authentication/Role.php b/library/Icinga/Authentication/Role.php index ef2792d83..1fca29b9d 100644 --- a/library/Icinga/Authentication/Role.php +++ b/library/Icinga/Authentication/Role.php @@ -26,6 +26,13 @@ class Role */ protected $children; + /** + * Whether restrictions should not apply to owners of the role + * + * @var bool + */ + protected $unrestricted = false; + /** * Permissions of the role * @@ -133,6 +140,30 @@ class Role return $this; } + /** + * Get whether restrictions should not apply to owners of the role + * + * @return bool + */ + public function isUnrestricted() + { + return $this->unrestricted; + } + + /** + * Set whether restrictions should not apply to owners of the role + * + * @param bool $state + * + * @return $this + */ + public function setIsUnrestricted($state) + { + $this->unrestricted = (bool) $state; + + return $this; + } + /** * Get the permissions of the role * diff --git a/library/Icinga/Authentication/RolesConfig.php b/library/Icinga/Authentication/RolesConfig.php index 896405069..ac5695f11 100644 --- a/library/Icinga/Authentication/RolesConfig.php +++ b/library/Icinga/Authentication/RolesConfig.php @@ -25,6 +25,7 @@ class RolesConfig extends IniRepository 'groups', 'refusals', 'permissions', + 'unrestricted', 'application/share/users', 'application/share/groups' ]