From 9e545fdd10d32229c1f6043a9f87ffaaa9b8668b Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Mon, 25 Mar 2024 15:38:28 -0400 Subject: [PATCH] GUACAMOLE-1239: Update JDBC queries to handle case-sensitivity. --- .../auth/jdbc/HistoryTrackingConnection.java | 10 +- .../auth/jdbc/base/ActivityRecordMapper.java | 21 ++- .../jdbc/connection/ConnectionService.java | 23 ++- .../jdbc/permission/UserPermissionMapper.java | 136 +++++++++++++++++- .../jdbc/security/PasswordPolicyService.java | 5 +- .../AbstractGuacamoleTunnelService.java | 11 +- .../auth/jdbc/user/ModeledUserContext.java | 4 +- .../auth/jdbc/user/PasswordRecordMapper.java | 7 +- .../guacamole/auth/jdbc/user/UserMapper.java | 58 +++++++- .../guacamole/auth/jdbc/user/UserService.java | 25 +++- .../usergroup/UserGroupMemberUserMapper.java | 57 +++++++- .../connection/ConnectionRecordMapper.xml | 6 +- .../jdbc/permission/UserPermissionMapper.xml | 21 ++- .../auth/jdbc/user/PasswordRecordMapper.xml | 1 + .../guacamole/auth/jdbc/user/UserMapper.xml | 18 ++- .../auth/jdbc/user/UserRecordMapper.xml | 10 +- .../usergroup/UserGroupMemberUserMapper.xml | 5 +- .../connection/ConnectionRecordMapper.xml | 28 +++- .../jdbc/permission/UserPermissionMapper.xml | 69 +++++++-- .../auth/jdbc/user/PasswordRecordMapper.xml | 9 +- .../guacamole/auth/jdbc/user/UserMapper.xml | 81 +++++++++-- .../auth/jdbc/user/UserRecordMapper.xml | 46 +++++- .../usergroup/UserGroupMemberUserMapper.xml | 39 ++++- 23 files changed, 617 insertions(+), 73 deletions(-) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/HistoryTrackingConnection.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/HistoryTrackingConnection.java index f25620bda6..cdd50e3bc0 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/HistoryTrackingConnection.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/HistoryTrackingConnection.java @@ -19,6 +19,7 @@ package org.apache.guacamole.auth.jdbc; +import com.google.inject.Inject; import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -55,6 +56,12 @@ public class HistoryTrackingConnection extends DelegatingConnection { * established connections. */ private final ConnectionRecordMapper connectionRecordMapper; + + /** + * The Guacamole server environment. + */ + @Inject + private JDBCEnvironment environment; /** * Creates a new HistoryConnection that wraps the given connection, @@ -98,7 +105,8 @@ public GuacamoleTunnel connect(GuacamoleClientInformation info, connectionRecordModel.setConnectionName(this.getDelegateConnection().getName()); // Insert the connection history record to mark the start of this connection - connectionRecordMapper.insert(connectionRecordModel); + connectionRecordMapper.insert(connectionRecordModel, + environment.getCaseSensitiveUsernames()); // Include history record UUID as token ModeledConnectionRecord modeledRecord = new ModeledConnectionRecord(connectionRecordModel); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ActivityRecordMapper.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ActivityRecordMapper.java index 52fbf9e640..17b4571ed8 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ActivityRecordMapper.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ActivityRecordMapper.java @@ -38,11 +38,16 @@ public interface ActivityRecordMapper { * * @param record * The activity record to insert. + * + * @param caseSensitive + * Whether or not string comparisons should be done in a case-sensitive + * manner. * * @return * The number of rows inserted. */ - int insert(@Param("record") ModelType record); + int insert(@Param("record") ModelType record, + @Param("caseSensitive") boolean caseSensitive); /** * Updates the given activity record in the database, assigning an end @@ -85,6 +90,10 @@ public interface ActivityRecordMapper { * * @param limit * The maximum number of records that should be returned. + * + * @param caseSensitive + * Whether or not string comparisons should be done in a case-sensitive + * manner. * * @return * The results of the search performed with the given parameters. @@ -93,7 +102,8 @@ List search(@Param("identifier") String identifier, @Param("recordIdentifier") String recordIdentifier, @Param("terms") Collection terms, @Param("sortPredicates") List sortPredicates, - @Param("limit") int limit); + @Param("limit") int limit, + @Param("caseSensitive") boolean caseSensitive); /** * Searches for up to limit activity records that contain @@ -132,6 +142,10 @@ List search(@Param("identifier") String identifier, * when determining the permissions effectively granted to the user. If * no groups are given, only permissions directly granted to the user * will be used. + * + * @param caseSensitive + * Whether or not string comparisons should be done in a case-sensitive + * manner. * * @return * The results of the search performed with the given parameters. @@ -142,6 +156,7 @@ List searchReadable(@Param("identifier") String identifier, @Param("terms") Collection terms, @Param("sortPredicates") List sortPredicates, @Param("limit") int limit, - @Param("effectiveGroups") Collection effectiveGroups); + @Param("effectiveGroups") Collection effectiveGroups, + @Param("caseSensitive") boolean caseSensitive); } 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 31f4df49c7..e08d13b0cd 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 @@ -28,19 +28,20 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser; -import org.apache.guacamole.language.TranslatableGuacamoleClientOverrunException; -import org.apache.guacamole.language.TranslatableMessage; -import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObjectMapper; -import org.apache.guacamole.auth.jdbc.tunnel.GuacamoleTunnelService; import org.apache.guacamole.GuacamoleClientException; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleSecurityException; +import org.apache.guacamole.auth.jdbc.JDBCEnvironment; import org.apache.guacamole.auth.jdbc.base.ActivityRecordSearchTerm; import org.apache.guacamole.auth.jdbc.base.ActivityRecordSortPredicate; +import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser; import org.apache.guacamole.auth.jdbc.base.ModeledChildDirectoryObjectService; +import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObjectMapper; import org.apache.guacamole.auth.jdbc.permission.ConnectionPermissionMapper; import org.apache.guacamole.auth.jdbc.permission.ObjectPermissionMapper; +import org.apache.guacamole.auth.jdbc.tunnel.GuacamoleTunnelService; +import org.apache.guacamole.language.TranslatableGuacamoleClientOverrunException; +import org.apache.guacamole.language.TranslatableMessage; import org.apache.guacamole.net.GuacamoleTunnel; import org.apache.guacamole.net.auth.Connection; import org.apache.guacamole.net.auth.ConnectionRecord; @@ -85,6 +86,12 @@ public class ConnectionService extends ModeledChildDirectoryObjectService connectionProvider; + + /** + * The server environment for retrieving configuration. + */ + @Inject + private JDBCEnvironment environment; /** * Service for creating and tracking tunnels. @@ -486,14 +493,16 @@ public List retrieveHistory(String identifier, // 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); + recordIdentifier, requiredContents, sortPredicates, limit, + environment.getCaseSensitiveUsernames()); // Otherwise only return explicitly readable history records else searchResults = connectionRecordMapper.searchReadable(identifier, user.getUser().getModel(), recordIdentifier, requiredContents, sortPredicates, limit, - user.getEffectiveUserGroups()); + user.getEffectiveUserGroups(), + environment.getCaseSensitiveUsernames()); return getObjectInstances(searchResults); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.java index f7412a4fd0..78442ad0c5 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.java @@ -19,7 +19,141 @@ package org.apache.guacamole.auth.jdbc.permission; +import java.util.Collection; +import org.apache.guacamole.auth.jdbc.base.EntityModel; +import org.apache.guacamole.net.auth.permission.ObjectPermission; +import org.apache.ibatis.annotations.Param; + /** * Mapper for user permissions. */ -public interface UserPermissionMapper extends ObjectPermissionMapper {} +public interface UserPermissionMapper extends ObjectPermissionMapper { + + /** + * Deletes the given permissions from the database. If any permissions do + * not exist, they will be ignored. + * + * @param permissions + * The permissions to delete. + * + * @param caseSensitive + * Whether or not string comparisons will be done in a case-sensitive + * manner. + * + * @return + * The number of rows deleted. + */ + int delete(@Param("permissions") Collection permissions, + @Param("caseSensitive") boolean caseSensitive); + + /** + * Inserts the given permissions into the database. If any permissions + * already exist, they will be ignored. + * + * @param permissions + * The permissions to insert. + * + * @param caseSensitive + * Whether or not string comparisons will be done in a case-sensitive + * manner. + * + * @return + * The number of rows inserted. + */ + int insert(@Param("permissions") Collection permissions, + @Param("caseSensitive") boolean caseSensitive); + + /** + * Retrieves all permissions associated with the given entity (user or user + * group). + * + * @param entity + * The entity to retrieve permissions for. + * + * @param effectiveGroups + * The identifiers of all groups that should be taken into account + * when determining the permissions effectively granted to the user. If + * no groups are given, only permissions directly granted to the user + * will be used. + * + * @param caseSensitive + * Whether or not string comparisons should be done in a case-sensitive + * manner. + * + * @return + * All permissions associated with the given entity. + */ + Collection select(@Param("entity") EntityModel entity, + @Param("effectiveGroups") Collection effectiveGroups, + @Param("caseSensitive") boolean caseSensitive); + + /** + * Retrieve the permission of the given type associated with the given + * entity and object, if it exists. If no such permission exists, null is + * returned. + * + * @param entity + * The entity to retrieve permissions for. + * + * @param type + * The type of permission to return. + * + * @param identifier + * The identifier of the object affected by the permission to return. + * + * @param effectiveGroups + * The identifiers of all groups that should be taken into account + * when determining the permissions effectively granted to the user. If + * no groups are given, only permissions directly granted to the user + * will be used. + * + * @param caseSensitive + * Whether or not string comparisons will be done in a case-sensitive + * manner. + * + * @return + * The requested permission, or null if no such permission is granted + * to the given entity for the given object. + */ + ObjectPermissionModel selectOne(@Param("entity") EntityModel entity, + @Param("type") ObjectPermission.Type type, + @Param("identifier") String identifier, + @Param("effectiveGroups") Collection effectiveGroups, + @Param("caseSensitive") boolean caseSensitive); + + /** + * Retrieves the subset of the given identifiers for which the given entity + * has at least one of the given permissions. + * + * @param entity + * The entity to check permissions of. + * + * @param permissions + * The permissions to check. An identifier will be included in the + * resulting collection if at least one of these permissions is granted + * for the associated object + * + * @param identifiers + * The identifiers of the objects affected by the permissions being + * checked. + * + * @param effectiveGroups + * The identifiers of all groups that should be taken into account + * when determining the permissions effectively granted to the user. If + * no groups are given, only permissions directly granted to the user + * will be used. + * + * @param caseSensitive + * Whether or not strings will be compared in a case-sensitive manner. + * + * @return + * A collection containing the subset of identifiers for which at least + * one of the specified permissions is granted. + */ + Collection selectAccessibleIdentifiers(@Param("entity") EntityModel entity, + @Param("permissions") Collection permissions, + @Param("identifiers") Collection identifiers, + @Param("effectiveGroups") Collection effectiveGroups, + @Param("caseSenstive") boolean caseSensitive); + +} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicyService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicyService.java index 148d5a2f94..81a74c7424 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicyService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicyService.java @@ -133,14 +133,15 @@ private boolean matches(String str, Pattern... patterns) { * passwords, up to the specified limit, false otherwise. */ private boolean matchesPreviousPasswords(String password, String username, - int historySize) { + int historySize) throws GuacamoleException { // No need to compare if no history is relevant if (historySize <= 0) return false; // Check password against all recorded hashes - List history = passwordRecordMapper.select(username, historySize); + List history = passwordRecordMapper.select(username, + historySize, environment.getCaseSensitiveUsernames()); for (PasswordRecordModel record : history) { byte[] hash = encryptionService.createPasswordHash(password, record.getPasswordSalt()); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java index 236d184854..e0a6091b07 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java @@ -34,6 +34,7 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; +import org.apache.guacamole.auth.jdbc.JDBCEnvironment; import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser; import org.apache.guacamole.auth.jdbc.connection.ModeledConnection; import org.apache.guacamole.auth.jdbc.connectiongroup.ModeledConnectionGroup; @@ -167,6 +168,12 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS */ @Inject private SharedConnectionMap connectionMap; + + /** + * The Guacamole server environment. + */ + @Inject + private JDBCEnvironment environment; /** * All active connections through the tunnel having a given UUID. @@ -470,7 +477,9 @@ private GuacamoleTunnel assignGuacamoleTunnel(ActiveConnectionRecord activeConne // Record new active connection Runnable cleanupTask = new ConnectionCleanupTask(activeConnection); try { - connectionRecordMapper.insert(activeConnection.getModel()); // This MUST happen before getUUID() is invoked, to ensure the ID driving the UUID exists + // This MUST happen before getUUID() is invoked, to ensure the ID driving the UUID exists + connectionRecordMapper.insert(activeConnection.getModel(), + environment.getCaseSensitiveUsernames()); activeTunnels.put(activeConnection.getUUID().toString(), activeConnection); } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUserContext.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUserContext.java index e5ad5d2eae..f3b0b0fdac 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUserContext.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUserContext.java @@ -177,7 +177,7 @@ public void init(ModeledAuthenticatedUser currentUser) { * activity record will be recorded, including when this UserContext is * invalidated. */ - public void recordUserLogin() { + public void recordUserLogin() throws GuacamoleException { // Do nothing if invoked multiple times if (userRecord != null) @@ -190,7 +190,7 @@ public void recordUserLogin() { userRecord.setRemoteHost(getCurrentUser().getCredentials().getRemoteAddress()); // Insert record representing login - userRecordMapper.insert(userRecord); + userRecordMapper.insert(userRecord, environment.getCaseSensitiveUsernames()); } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.java index 903ff6562d..c0f55b9ee8 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.java @@ -38,6 +38,10 @@ public interface PasswordRecordMapper extends ModeledDirectoryObjectMapper select(@Param("username") String username, - @Param("maxHistorySize") int maxHistorySize); + @Param("maxHistorySize") int maxHistorySize, + @Param("caseSensitive") boolean caseSensitive); /** * Inserts the given password record. Old records exceeding the maximum diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserMapper.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserMapper.java index cf829be588..0124ee57e1 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserMapper.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserMapper.java @@ -19,6 +19,7 @@ package org.apache.guacamole.auth.jdbc.user; +import java.util.Collection; import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObjectMapper; import org.apache.ibatis.annotations.Param; @@ -33,10 +34,65 @@ public interface UserMapper extends ModeledDirectoryObjectMapper { * * @param username * The username of the user to return. + * + * @param caseSensitive + * True if the search should evaluate case sensitively, otherwise + * false. * * @return * The user having the given username, or null if no such user exists. */ - UserModel selectOne(@Param("username") String username); + UserModel selectOne(@Param("username") String username, + @Param("caseSensitive") boolean caseSensitive); + + /** + * Selects all objects which have the given identifiers. If an identifier + * has no corresponding object, it will be ignored. This should only be + * called on behalf of a system administrator. If objects are needed by a + * non-administrative user who must have explicit read rights, use + * selectReadable() instead. + * + * @param identifiers + * The identifiers of the objects to return. + * + * @param caseSensitive + * True if the query should be evaluated with case sensitivity, otherwise + * false. + * + * @return + * A Collection of all objects having the given identifiers. + */ + Collection select(@Param("identifiers") Collection identifiers, + @Param("caseSensitive") boolean caseSensitive); + + /** + * Selects all objects which have the given identifiers and are explicitly + * readably by the given user. If an identifier has no corresponding + * object, or the corresponding object is unreadable, it will be ignored. + * If objects are needed by a system administrator (who, by definition, + * does not need explicit read rights), use select() instead. + * + * @param user + * The user whose permissions should determine whether an object + * is returned. + * + * @param identifiers + * The identifiers of the objects to return. + * + * @param effectiveGroups + * The identifiers of any known effective groups that should be taken + * into account, such as those defined externally to the database. + * + * @param caseSensitive + * True if the query should be run respecting case sensitivity, otherwise + * false. + * + * @return + * A Collection of all objects having the given identifiers. + */ + Collection selectReadable(@Param("user") UserModel user, + @Param("identifiers") Collection identifiers, + @Param("effectiveGroups") Collection effectiveGroups, + @Param("caseSensitive") boolean caseSensitive); } 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 08acff2a65..d27be3d120 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 @@ -33,6 +33,7 @@ import org.apache.guacamole.GuacamoleClientException; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleUnsupportedException; +import org.apache.guacamole.auth.jdbc.JDBCEnvironment; import org.apache.guacamole.auth.jdbc.base.ActivityRecordModel; import org.apache.guacamole.auth.jdbc.base.ActivityRecordSearchTerm; import org.apache.guacamole.auth.jdbc.base.ActivityRecordSortPredicate; @@ -155,6 +156,12 @@ public class UserService extends ModeledDirectoryObjectService getObjectMapper() { @@ -241,7 +248,8 @@ protected void beforeCreate(ModeledAuthenticatedUser user, User object, throw new GuacamoleClientException("The username must not be blank."); // Do not create duplicate users - Collection existing = userMapper.select(Collections.singleton(model.getIdentifier())); + Collection existing = userMapper.select(Collections.singleton( + model.getIdentifier()), environment.getCaseSensitiveUsernames()); if (!existing.isEmpty()) throw new GuacamoleClientException("User \"" + model.getIdentifier() + "\" already exists."); @@ -277,7 +285,8 @@ protected void beforeUpdate(ModeledAuthenticatedUser user, throw new GuacamoleClientException("The username must not be blank."); // Check whether such a user is already present - UserModel existing = userMapper.selectOne(model.getIdentifier()); + UserModel existing = userMapper.selectOne(model.getIdentifier(), + environment.getCaseSensitiveUsernames()); if (existing != null) { // Do not rename to existing user @@ -375,7 +384,8 @@ public ModeledAuthenticatedUser retrieveAuthenticatedUser(AuthenticationProvider String password = credentials.getPassword(); // Retrieve corresponding user model, if such a user exists - UserModel userModel = userMapper.selectOne(username); + UserModel userModel = userMapper.selectOne(username, + environment.getCaseSensitiveUsernames()); if (userModel == null) return null; @@ -416,7 +426,8 @@ public ModeledUser retrieveUser(AuthenticationProvider authenticationProvider, AuthenticatedUser authenticatedUser) throws GuacamoleException { // Retrieve corresponding user model, if such a user exists - UserModel userModel = userMapper.selectOne(authenticatedUser.getIdentifier()); + UserModel userModel = userMapper.selectOne(authenticatedUser.getIdentifier(), + environment.getCaseSensitiveUsernames()); if (userModel == null) return null; @@ -614,14 +625,16 @@ public List retrieveHistory(String username, // 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); + requiredContents, sortPredicates, limit, + environment.getCaseSensitiveUsernames()); // Otherwise only return explicitly readable history records else searchResults = userRecordMapper.searchReadable(username, user.getUser().getModel(), recordIdentifier, requiredContents, sortPredicates, limit, - user.getEffectiveUserGroups()); + user.getEffectiveUserGroups(), + environment.getCaseSensitiveUsernames()); return getObjectInstances(searchResults); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserMapper.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserMapper.java index b668d07fec..c122deaa00 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserMapper.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserMapper.java @@ -19,10 +19,65 @@ package org.apache.guacamole.auth.jdbc.usergroup; +import java.util.Collection; import org.apache.guacamole.auth.jdbc.base.ObjectRelationMapper; +import org.apache.ibatis.annotations.Param; /** * Mapper for the one-to-many relationship between a user group and its user * members. */ -public interface UserGroupMemberUserMapper extends ObjectRelationMapper {} +public interface UserGroupMemberUserMapper extends ObjectRelationMapper { + + /** + * Inserts rows as necessary to establish the one-to-many relationship + * represented by the RelatedObjectSet between the given parent and + * children. If the relation for any parent/child pair is already present, + * no attempt is made to insert a new row for that relation. + * + * @param parent + * The model of the object on the parent side of the one-to-many + * relationship represented by the RelatedObjectSet. + * + * @param children + * The identifiers of the objects on the child side of the one-to-many + * relationship represented by the RelatedObjectSet. + * + * @param caseSensitive + * Whether or not string comparisons should be done in a case-sensitive + * manner. + * + * @return + * The number of rows inserted. + */ + int insert(@Param("parent") UserGroupModel parent, + @Param("children") Collection children, + @Param("caseSensitive") boolean caseSensitive); + + /** + * Deletes rows as necessary to modify the one-to-many relationship + * represented by the RelatedObjectSet between the given parent and + * children. If the relation for any parent/child pair does not exist, + * that specific relation is ignored, and deletion proceeds with the + * remaining relations. + * + * @param parent + * The model of the object on the parent side of the one-to-many + * relationship represented by the RelatedObjectSet. + * + * @param children + * The identifiers of the objects on the child side of the one-to-many + * relationship represented by the RelatedObjectSet. + * + * @param caseSensitive + * Whether or not string comparisons should be done in a case-sensitive + * manner. + * + * @return + * The number of rows deleted. + */ + int delete(@Param("parent") UserGroupModel parent, + @Param("children") Collection children, + @Param("caseSesitive") boolean caseSensitive); + +} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml index 11ca348ddc..b8be8118df 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml @@ -61,6 +61,7 @@ (SELECT user_id FROM guacamole_user JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id WHERE + BINARY guacamole_entity.name = #{record.username,jdbcType=VARCHAR} AND guacamole_entity.type = 'USER'), #{record.username,jdbcType=VARCHAR}, @@ -112,7 +113,9 @@ guacamole_connection_history.user_id IN ( SELECT user_id FROM guacamole_user - WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN username) > 0 + WHERE + BINARY + POSITION(#{term.term,jdbcType=VARCHAR} IN username) > 0 ) OR guacamole_connection_history.connection_id IN ( @@ -200,6 +203,7 @@ FROM guacamole_user JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id WHERE + BINARY POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0 AND guacamole_entity.type = 'USER' ) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml index 58fba1430a..1258ace0d1 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml @@ -42,6 +42,9 @@ JOIN guacamole_user affected_user ON guacamole_user_permission.affected_user_id = affected_user.user_id JOIN guacamole_entity affected_entity ON affected_user.entity_id = affected_entity.entity_id WHERE + + BINARY + @@ -68,7 +71,11 @@ AND permission = #{type,jdbcType=VARCHAR} - AND affected_entity.name = #{identifier,jdbcType=VARCHAR} + AND + + BINARY + + affected_entity.name = #{identifier,jdbcType=VARCHAR} AND affected_entity.type = 'USER' @@ -86,7 +93,11 @@ - AND affected_entity.name IN + AND + + BINARY + + affected_entity.name IN #{identifier,jdbcType=VARCHAR} @@ -108,6 +119,9 @@ JOIN guacamole_user affected_user ON guacamole_user_permission.affected_user_id = affected_user.user_id JOIN guacamole_entity affected_entity ON affected_user.entity_id = affected_entity.entity_id WHERE + + BINARY + (guacamole_user_permission.entity_id, permission, affected_entity.name) IN @@ -140,6 +154,9 @@ AS permissions JOIN guacamole_entity affected_entity ON + + BINARY + affected_entity.name = permissions.affected_name AND affected_entity.type = 'USER' JOIN guacamole_user affected_user ON affected_user.entity_id = affected_entity.entity_id diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml index f3772d7f91..9612d63078 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml @@ -43,6 +43,7 @@ JOIN guacamole_user ON guacamole_user_password_history.user_id = guacamole_user.user_id JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id WHERE + BINARY guacamole_entity.name = #{username,jdbcType=VARCHAR} ORDER BY guacamole_user_password_history.password_date DESC diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml index 0dcfa2efcc..401bb1f409 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml @@ -130,7 +130,9 @@ FROM guacamole_user JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id LEFT JOIN guacamole_user_history ON guacamole_user_history.user_id = guacamole_user.user_id - WHERE guacamole_entity.name IN + WHERE + BINARY + guacamole_entity.name IN #{identifier,jdbcType=VARCHAR} @@ -145,7 +147,9 @@ FROM guacamole_user_attribute JOIN guacamole_user ON guacamole_user.user_id = guacamole_user_attribute.user_id JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id - WHERE guacamole_entity.name IN + WHERE + BINARY + guacamole_entity.name IN #{identifier,jdbcType=VARCHAR} @@ -180,7 +184,9 @@ FROM guacamole_user JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id LEFT JOIN guacamole_user_history ON guacamole_user_history.user_id = guacamole_user.user_id - WHERE guacamole_entity.name IN + WHERE + BINARY + guacamole_entity.name IN #{identifier,jdbcType=VARCHAR} @@ -201,7 +207,9 @@ FROM guacamole_user_attribute JOIN guacamole_user ON guacamole_user.user_id = guacamole_user_attribute.user_id JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id - WHERE guacamole_entity.name IN + WHERE + BINARY + guacamole_entity.name IN #{identifier,jdbcType=VARCHAR} @@ -243,6 +251,7 @@ JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id LEFT JOIN guacamole_user_history ON guacamole_user_history.user_id = guacamole_user.user_id WHERE + BINARY guacamole_entity.name = #{username,jdbcType=VARCHAR} AND guacamole_entity.type = 'USER' GROUP BY guacamole_user.user_id, guacamole_entity.entity_id; @@ -255,6 +264,7 @@ JOIN guacamole_user ON guacamole_user.user_id = guacamole_user_attribute.user_id JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id WHERE + BINARY guacamole_entity.name = #{username,jdbcType=VARCHAR} AND guacamole_entity.type = 'USER' diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserRecordMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserRecordMapper.xml index 70742df4c1..c90f1438f7 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserRecordMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserRecordMapper.xml @@ -49,7 +49,8 @@ (SELECT user_id FROM guacamole_user JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id WHERE - guacamole_entity.name = #{record.username,jdbcType=VARCHAR} + BINARY + guacamole_entity.name = #{record.username,jdbcType=VARCHAR} AND guacamole_entity.type = 'USER'), #{record.username,jdbcType=VARCHAR}, #{record.startDate,jdbcType=TIMESTAMP}, @@ -81,6 +82,7 @@ + BINARY guacamole_user_history.username = #{identifier,jdbcType=VARCHAR} @@ -92,6 +94,7 @@ FROM guacamole_user JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id WHERE + BINARY POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0 AND guacamole_entity.type = 'USER'), ) @@ -146,7 +149,9 @@ ) - AND guacamole_entity.name = #{identifier,jdbcType=VARCHAR} + AND + BINARY + guacamole_entity.name = #{identifier,jdbcType=VARCHAR} @@ -157,6 +162,7 @@ FROM guacamole_user JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id WHERE + BINARY POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0 AND guacamole_entity.type = 'USER' ) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserMapper.xml index 609d907f5a..16990f2eae 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserMapper.xml @@ -58,7 +58,9 @@ WHERE user_group_id = #{parent.objectID,jdbcType=INTEGER} AND guacamole_entity.type = 'USER' - AND guacamole_entity.name IN + AND + BINARY + guacamole_entity.name IN #{identifier,jdbcType=VARCHAR} @@ -76,6 +78,7 @@ guacamole_entity.entity_id FROM guacamole_entity WHERE + BINARY guacamole_entity.name IN diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml index 9857193b44..e0ad7a19db 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml @@ -61,7 +61,14 @@ (SELECT user_id FROM guacamole_user JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id WHERE - guacamole_entity.name = #{record.username,jdbcType=VARCHAR} + + + guacamole_entity.name = #{record.username,jdbcType=VARCHAR} + + + LOWER(guacamole_entity.name) = LOWER(#{record.username,jdbcType=VARCHAR}) + + AND guacamole_entity.type = 'USER'::guacamole_entity_type), #{record.username,jdbcType=VARCHAR}, #{record.startDate,jdbcType=TIMESTAMP}, @@ -110,7 +117,15 @@ guacamole_connection_history.user_id IN ( SELECT user_id FROM guacamole_user - WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN username) > 0 + WHERE + + + POSITION(#{term.term,jdbcType=VARCHAR} IN username) > 0 + + + POSITION(LOWER(#{term.term,jdbcType=VARCHAR}) IN LOWER(username)) > 0 + + ) OR guacamole_connection_history.connection_id IN ( @@ -198,7 +213,14 @@ FROM guacamole_user JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id WHERE - POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0 + + + POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0 + + + POSITION(LOWER(#{term.term,jdbcType=VARCHAR}) IN LOWER(guacamole_entity.name)) > 0 + + AND guacamole_entity.type = 'USER'::guacamole_entity_type ) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml index a4b5f1b7c4..58e7b20905 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml @@ -28,7 +28,7 @@ - + @@ -68,7 +68,16 @@ AND permission = #{type,jdbcType=VARCHAR}::guacamole_object_permission_type - AND affected_entity.name = #{identifier,jdbcType=VARCHAR} + AND + + + affected_entity.name = #{identifier,jdbcType=VARCHAR} + + + LOWER(affected_entity.name) = LOWER(#{identifier,jdbcType=VARCHAR}) + + + AND affected_entity.type = 'USER'::guacamole_entity_type @@ -86,11 +95,23 @@ - AND affected_entity.name IN - + + affected_entity.name IN + - #{identifier,jdbcType=VARCHAR} - + #{identifier,jdbcType=VARCHAR} + + + + LOWER(affected_entity.name) IN + + LOWER(#{identifier,jdbcType=VARCHAR}) + + + AND permission IN @@ -108,13 +129,26 @@ WHERE guacamole_user_permission.affected_user_id = affected_user.user_id AND affected_user.entity_id = affected_entity.entity_id - AND (guacamole_user_permission.entity_id, permission, affected_entity.name) IN - - (#{permission.entityID,jdbcType=INTEGER}, - #{permission.type,jdbcType=VARCHAR}::guacamole_object_permission_type, - #{permission.objectIdentifier,jdbcType=INTEGER}) - + + + AND (guacamole_user_permission.entity_id, permission, affected_entity.name) IN + + (#{permission.entityID,jdbcType=INTEGER}, + #{permission.type,jdbcType=VARCHAR}::guacamole_object_permission_type, + #{permission.objectIdentifier,jdbcType=INTEGER}) + + + + AND (guacamole_user_permission.entity_id, permission, LOWER(affected_entity.name)) IN + + (#{permission.entityID,jdbcType=INTEGER}, + #{permission.type,jdbcType=VARCHAR}::guacamole_object_permission_type, + LOWER(#{permission.objectIdentifier,jdbcType=INTEGER})) + + + AND affected_entity.type = 'USER'::guacamole_entity_type @@ -140,7 +174,14 @@ AS permissions JOIN guacamole_entity affected_entity ON - affected_entity.name = permissions.affected_name + + + affected_entity.name = permissions.affected_name + + + LOWER(affected_entity.name) = LOWER(permissions.affected_name) + + AND affected_entity.type = 'USER'::guacamole_entity_type JOIN guacamole_user affected_user ON affected_user.entity_id = affected_entity.entity_id WHERE (permissions.entity_id, permissions.permission, affected_user.user_id) NOT IN ( diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml index e9c857afd4..e85f22ce21 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml @@ -43,7 +43,14 @@ JOIN guacamole_user ON guacamole_user_password_history.user_id = guacamole_user.user_id JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id WHERE - guacamole_entity.name = #{username,jdbcType=VARCHAR} + + + guacamole_entity.name = #{username,jdbcType=VARCHAR} + + + LOWER(guacamole_entity.name) = LOWER(#{username,jdbcType=VARCHAR}) + + ORDER BY guacamole_user_password_history.password_date DESC LIMIT #{maxHistorySize} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml index 94d607e337..4bf3bea280 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml @@ -145,10 +145,26 @@ FROM guacamole_user_attribute JOIN guacamole_user ON guacamole_user.user_id = guacamole_user_attribute.user_id JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id - WHERE guacamole_entity.name IN + WHERE + + + guacamole_entity.name + + + LOWER(guacamole_entity.name) + + + IN - #{identifier,jdbcType=VARCHAR} + open="(" separator="," close=")"> + + + #{identifier,jdbcType=VARCHAR} + + + LOWER(#{identifier,jdbcType=VARCHAR}) + + AND guacamole_entity.type = 'USER'::guacamole_entity_type; @@ -180,10 +196,26 @@ FROM guacamole_user JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id LEFT JOIN guacamole_user_history ON guacamole_user_history.user_id = guacamole_user.user_id - WHERE guacamole_entity.name IN + WHERE + + + guacamole_entity.name + + + LOWER(guacamole_entity.name) + + + IN - #{identifier,jdbcType=VARCHAR} + + + #{identifier,jdbcType=VARCHAR} + + + LOWER(#{identifier,jdbcType=VARCHAR}) + + AND guacamole_entity.type = 'USER'::guacamole_entity_type AND guacamole_user.user_id IN ( @@ -201,10 +233,26 @@ FROM guacamole_user_attribute JOIN guacamole_user ON guacamole_user.user_id = guacamole_user_attribute.user_id JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id - WHERE guacamole_entity.name IN + WHERE + + + guacamole_entity.name + + + LOWER(guacamole_entity.name) + + + IN - #{identifier,jdbcType=VARCHAR} + + + #{identifier,jdbcType=VARCHAR} + + + LOWER(#{identifier,jdbcType=VARCHAR}) + + AND guacamole_entity.type = 'USER'::guacamole_entity_type AND guacamole_user.user_id IN ( @@ -243,7 +291,14 @@ JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id LEFT JOIN guacamole_user_history ON guacamole_user_history.user_id = guacamole_user.user_id WHERE - guacamole_entity.name = #{username,jdbcType=VARCHAR} + + + guacamole_entity.name = #{username,jdbcType=VARCHAR} + + + LOWER(guacamole_entity.name) = LOWER(#{username,jdbcType=VARCHAR}) + + AND guacamole_entity.type = 'USER'::guacamole_entity_type GROUP BY guacamole_user.user_id, guacamole_entity.entity_id; @@ -255,9 +310,15 @@ JOIN guacamole_user ON guacamole_user.user_id = guacamole_user_attribute.user_id JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id WHERE - guacamole_entity.name = #{username,jdbcType=VARCHAR} + + + guacamole_entity.name = #{username,jdbcType=VARCHAR} + + + LOWER(guacamole_entity.name) = LOWER(#{username,jdbcType=VARCHAR}) + + AND guacamole_entity.type = 'USER'::guacamole_entity_type - diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserRecordMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserRecordMapper.xml index a372087ebd..91335ac468 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserRecordMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserRecordMapper.xml @@ -49,7 +49,14 @@ (SELECT user_id FROM guacamole_user JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id WHERE - guacamole_entity.name = #{record.username,jdbcType=VARCHAR} + + + guacamole_entity.name = #{record.username,jdbcType=VARCHAR} + + + LOWER(guacamole_entity.name) = LOWER(#{record.username,jdbcType=VARCHAR}) + + AND guacamole_entity.type = 'USER'::guacamole_entity_type), #{record.username,jdbcType=VARCHAR}, #{record.startDate,jdbcType=TIMESTAMP}, @@ -81,7 +88,14 @@ - guacamole_user_history.username = #{identifier,jdbcType=VARCHAR} + + + guacamole_user_history.username = #{identifier,jdbcType=VARCHAR} + + + LOWER(guacamole_user_history.username) = LOWER(#{identifier,jdbcType=VARCHAR}) + + @@ -92,7 +106,14 @@ FROM guacamole_user JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id WHERE - POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0 + + + POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0 + + + POSITION(LOWER(#{term.term,jdbcType=VARCHAR}) IN LOWER(guacamole_entity.name)) > 0 + + AND guacamole_entity.type = 'USER'::guacamole_entity_type), ) @@ -146,7 +167,15 @@ ) - AND guacamole_entity.name = #{identifier,jdbcType=VARCHAR} + AND + + + guacamole_entity.name = #{identifier,jdbcType=VARCHAR} + + + LOWER(guacamole_entity.name) = LOWER(#{identifier,jdbcType=VARCHAR}) + + @@ -157,7 +186,14 @@ FROM guacamole_user JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id WHERE - POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0 + + + POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0 + + + POSITION(LOWER(#{term.term,jdbcType=VARCHAR}) IN LOWER(guacamole_entity.name)) > 0 + + AND guacamole_entity.type = 'USER'::guacamole_entity_type ) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserMapper.xml index a3ad5a78d1..064f016f74 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserMapper.xml @@ -58,10 +58,26 @@ user_group_id = #{parent.objectID,jdbcType=INTEGER} AND guacamole_entity.entity_id = member_entity_id AND guacamole_entity.type = 'USER'::guacamole_entity_type - AND guacamole_entity.name IN + AND + + + guacamole_entity.name + + + LOWER(guacamole_entity.name) + + + IN - #{identifier,jdbcType=VARCHAR} + + + #{identifier,jdbcType=VARCHAR} + + + LOWER(#{identifier,jdbcType=VARCHAR}) + + @@ -76,10 +92,25 @@ guacamole_entity.entity_id FROM guacamole_entity WHERE - guacamole_entity.name IN + + + guacamole_entity.name + + + LOWER(guacamole_entity.name) + + + IN - #{identifier} + + + #{identifier} + + + LOWER(#{identifier}) + + AND guacamole_entity.type = 'USER'::guacamole_entity_type AND guacamole_entity.entity_id NOT IN (