diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionService.java index f7c1203f5..31f4df49c 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionService.java @@ -483,8 +483,8 @@ public class ConnectionService extends ModeledChildDirectoryObjectService searchResults; - // Bypass permission checks if the user is privileged - if (user.isPrivileged()) + // Bypass permission checks if the user is privileged or has System-level audit permissions + if (user.isPrivileged() || user.getUser().getEffectivePermissions().getSystemPermissions().hasPermission(SystemPermission.Type.AUDIT)) searchResults = connectionRecordMapper.search(identifier, recordIdentifier, requiredContents, sortPredicates, limit); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java index 161976ce4..08acff2a6 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java @@ -611,8 +611,8 @@ public class UserService extends ModeledDirectoryObjectService searchResults; - // Bypass permission checks if the user is privileged - if (user.isPrivileged()) + // Bypass permission checks if the user is privileged or has System-level audit permissions + if (user.isPrivileged() || user.getUser().getEffectivePermissions().getSystemPermissions().hasPermission(SystemPermission.Type.AUDIT)) searchResults = userRecordMapper.search(username, recordIdentifier, requiredContents, sortPredicates, limit); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/001-create-schema.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/001-create-schema.sql index 1606af1f3..8241961f4 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/001-create-schema.sql +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/001-create-schema.sql @@ -459,6 +459,7 @@ CREATE TABLE `guacamole_system_permission` ( 'CREATE_SHARING_PROFILE', 'CREATE_USER', 'CREATE_USER_GROUP', + 'AUDIT', 'ADMINISTER') NOT NULL, PRIMARY KEY (`entity_id`,`permission`), @@ -611,3 +612,4 @@ CREATE TABLE guacamole_user_password_history ( REFERENCES `guacamole_user` (`user_id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/002-create-admin-user.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/002-create-admin-user.sql index f62d6d1d2..2b7cc0250 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/002-create-admin-user.sql +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/002-create-admin-user.sql @@ -51,3 +51,4 @@ FROM ( JOIN guacamole_entity ON permissions.username = guacamole_entity.name AND guacamole_entity.type = 'USER' JOIN guacamole_entity affected ON permissions.affected_username = affected.name AND guacamole_entity.type = 'USER' JOIN guacamole_user ON guacamole_user.entity_id = affected.entity_id; + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-1.6.0.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-1.6.0.sql new file mode 100644 index 000000000..3533e48e5 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-1.6.0.sql @@ -0,0 +1,32 @@ +-- +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you under the Apache License, Version 2.0 (the +-- "License"); you may not use this file except in compliance +-- with the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, +-- software distributed under the License is distributed on an +-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +-- KIND, either express or implied. See the License for the +-- specific language governing permissions and limitations +-- under the License. +-- + +-- +-- Add new system-level permission +-- + +ALTER TABLE `guacamole_system_permission` + MODIFY `permission` enum('CREATE_CONNECTION', + 'CREATE_CONNECTION_GROUP', + 'CREATE_SHARING_PROFILE', + 'CREATE_USER', + 'CREATE_USER_GROUP', + 'AUDIT', + 'ADMINISTER') NOT NULL; + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/001-create-schema.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/001-create-schema.sql index 9bcf1c51f..134215d29 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/001-create-schema.sql +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/001-create-schema.sql @@ -56,6 +56,7 @@ CREATE TYPE guacamole_system_permission_type AS ENUM( 'CREATE_SHARING_PROFILE', 'CREATE_USER', 'CREATE_USER_GROUP', + 'AUDIT', 'ADMINISTER' ); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/002-create-admin-user.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/002-create-admin-user.sql index c7cd7c910..3a58771f1 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/002-create-admin-user.sql +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/002-create-admin-user.sql @@ -53,3 +53,4 @@ FROM ( JOIN guacamole_entity ON permissions.username = guacamole_entity.name AND guacamole_entity.type = 'USER' JOIN guacamole_entity affected ON permissions.affected_username = affected.name AND guacamole_entity.type = 'USER' JOIN guacamole_user ON guacamole_user.entity_id = affected.entity_id; + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-1.6.0.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-1.6.0.sql new file mode 100644 index 000000000..9a4536e25 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-1.6.0.sql @@ -0,0 +1,27 @@ +-- +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you under the Apache License, Version 2.0 (the +-- "License"); you may not use this file except in compliance +-- with the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, +-- software distributed under the License is distributed on an +-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +-- KIND, either express or implied. See the License for the +-- specific language governing permissions and limitations +-- under the License. +-- + +-- +-- Add new system-level audit permission +-- + +ALTER TYPE guacamole_system_permission_type + ADD VALUE 'AUDIT' + BEFORE 'ADMINISTER'; + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/001-create-schema.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/001-create-schema.sql index 54be792ba..44346538b 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/001-create-schema.sql +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/001-create-schema.sql @@ -77,6 +77,7 @@ CREATE RULE [guacamole_system_permission_list] AS @list IN ( 'CREATE_SHARING_PROFILE', 'CREATE_USER', 'CREATE_USER_GROUP', + 'AUDIT', 'ADMINISTER' ); GO diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/002-create-admin-user.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/002-create-admin-user.sql index dcb4257d6..70cf520a1 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/002-create-admin-user.sql +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/002-create-admin-user.sql @@ -61,3 +61,4 @@ JOIN [guacamole_entity] ON [permissions].[username] = [guacamole_enti JOIN [guacamole_entity] [affected] ON [permissions].[affected_username] = [affected].[name] AND [guacamole_entity].[type] = 'USER' JOIN [guacamole_user] ON [guacamole_user].[entity_id] = [affected].[entity_id]; GO + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/upgrade/upgrade-pre-1.6.0.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/upgrade/upgrade-pre-1.6.0.sql new file mode 100644 index 000000000..e56f7ee12 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/upgrade/upgrade-pre-1.6.0.sql @@ -0,0 +1,43 @@ +-- +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you under the Apache License, Version 2.0 (the +-- "License"); you may not use this file except in compliance +-- with the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, +-- software distributed under the License is distributed on an +-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +-- KIND, either express or implied. See the License for the +-- specific language governing permissions and limitations +-- under the License. +-- + +-- +-- Add new system-level audit permission +-- + +EXEC sp_unbindrule 'guacamole_system_permission'; +DROP RULE [guacamole_system_permission_list]; +GO + +CREATE RULE [guacamole_system_permission_list] AS @list IN ( + 'CREATE_CONNECTION', + 'CREATE_CONNECTION_GROUP', + 'CREATE_SHARING_PROFILE', + 'CREATE_USER', + 'CREATE_USER_GROUP', + 'AUDIT', + 'ADMINISTER' +); +GO + +EXEC sp_bindrule + 'guacamole_system_permission_list', + 'guacamole_system_permission'; +GO + diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/permission/SystemPermission.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/permission/SystemPermission.java index 054caf066..c0c17345f 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/permission/SystemPermission.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/permission/SystemPermission.java @@ -56,6 +56,14 @@ public class SystemPermission implements Permission { * Create sharing profiles. */ CREATE_SHARING_PROFILE, + + /** + * Audit the system in general, which involves the ability to view + * active and historical connection records, user logon records, etc., + * but lacks permission to change any of these details (interact with + * active connections, update user accounts, etc). + */ + AUDIT, /** * Administer the system in general, including adding permissions diff --git a/guacamole/src/main/frontend/src/app/manage/directives/systemPermissionEditor.js b/guacamole/src/main/frontend/src/app/manage/directives/systemPermissionEditor.js index 78377a7d5..079c0d03f 100644 --- a/guacamole/src/main/frontend/src/app/manage/directives/systemPermissionEditor.js +++ b/guacamole/src/main/frontend/src/app/manage/directives/systemPermissionEditor.js @@ -121,6 +121,10 @@ angular.module('manage').directive('systemPermissionEditor', ['$injector', label: "MANAGE_USER.FIELD_HEADER_ADMINISTER_SYSTEM", value: PermissionSet.SystemPermissionType.ADMINISTER }, + { + label: "MANAGE_USER.FIELD_HEADER_AUDIT_SYSTEM", + value: PermissionSet.SystemPermissionType.AUDIT + }, { label: "MANAGE_USER.FIELD_HEADER_CREATE_NEW_USERS", value: PermissionSet.SystemPermissionType.CREATE_USER diff --git a/guacamole/src/main/frontend/src/app/navigation/services/userPageService.js b/guacamole/src/main/frontend/src/app/navigation/services/userPageService.js index aeb701a33..9a9f693f6 100644 --- a/guacamole/src/main/frontend/src/app/navigation/services/userPageService.js +++ b/guacamole/src/main/frontend/src/app/navigation/services/userPageService.js @@ -298,8 +298,9 @@ angular.module('navigation').factory('userPageService', ['$injector', // Determine whether the current user needs access to view connection history if ( - // A user must be a system administrator to view connection records - PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER) + // A user must be a system administrator or auditor to view connection records + PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER) + || PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.AUDIT) ) { canViewConnectionRecords.push(dataSource); } @@ -312,7 +313,7 @@ angular.module('navigation').factory('userPageService', ['$injector', url : '/settings/sessions' })); - // If user can manage connections, add links for connection management pages + // If user can view connection records, add links for connection history pages angular.forEach(canViewConnectionRecords, function addConnectionHistoryLink(dataSource) { pages.push(new PageDefinition({ name : [ diff --git a/guacamole/src/main/frontend/src/app/rest/types/PermissionSet.js b/guacamole/src/main/frontend/src/app/rest/types/PermissionSet.js index 9dd1ac8d6..2a549456b 100644 --- a/guacamole/src/main/frontend/src/app/rest/types/PermissionSet.js +++ b/guacamole/src/main/frontend/src/app/rest/types/PermissionSet.js @@ -136,6 +136,11 @@ angular.module('rest').factory('PermissionSet', [function definePermissionSet() * Permission to administer the entire system. */ ADMINISTER : "ADMINISTER", + + /** + * Permission to view connection and user records for the entire system. + */ + AUDIT : "AUDIT", /** * Permission to create new users. diff --git a/guacamole/src/main/frontend/src/translations/en.json b/guacamole/src/main/frontend/src/translations/en.json index 1c7e08a82..d02968787 100644 --- a/guacamole/src/main/frontend/src/translations/en.json +++ b/guacamole/src/main/frontend/src/translations/en.json @@ -408,6 +408,7 @@ "ERROR_PASSWORD_MISMATCH" : "@:APP.ERROR_PASSWORD_MISMATCH", "FIELD_HEADER_ADMINISTER_SYSTEM" : "Administer system:", + "FIELD_HEADER_AUDIT_SYSTEM" : "Audit system:", "FIELD_HEADER_CHANGE_OWN_PASSWORD" : "Change own password:", "FIELD_HEADER_CREATE_NEW_USERS" : "Create new users:", "FIELD_HEADER_CREATE_NEW_USER_GROUPS" : "Create new user groups:", @@ -449,6 +450,7 @@ "DIALOG_HEADER_ERROR" : "@:APP.DIALOG_HEADER_ERROR", "FIELD_HEADER_ADMINISTER_SYSTEM" : "@:MANAGE_USER.FIELD_HEADER_ADMINISTER_SYSTEM", + "FIELD_HEADER_AUDIT_SYSTEM" : "@:MANAGE_USER.FIELD_HEADER_AUDIT_SYSTEM", "FIELD_HEADER_CHANGE_OWN_PASSWORD" : "@:MANAGE_USER.FIELD_HEADER_CHANGE_OWN_PASSWORD", "FIELD_HEADER_CREATE_NEW_USERS" : "@:MANAGE_USER.FIELD_HEADER_CREATE_NEW_USERS", "FIELD_HEADER_CREATE_NEW_USER_GROUPS" : "@:MANAGE_USER.FIELD_HEADER_CREATE_NEW_USER_GROUPS",