diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectMapper.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectMapper.java index 8ff0cc1c7..5ff8edf15 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectMapper.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectMapper.java @@ -76,11 +76,16 @@ public interface ModeledDirectoryObjectMapper { * * @param identifiers * The identifiers of the objects to return. + * + * @param caseSensitive + * true if the query should evaluate identifiers in a case-sensitive + * manner, otherwise false. * * @return * A Collection of all objects having the given identifiers. */ - Collection select(@Param("identifiers") Collection identifiers); + Collection select(@Param("identifiers") Collection identifiers, + @Param("caseSensitive") boolean caseSensitive); /** * Selects all objects which have the given identifiers and are explicitly @@ -99,13 +104,18 @@ public interface ModeledDirectoryObjectMapper { * @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 evaluate identifiers in a case-sensitive + * manner, 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("effectiveGroups") Collection effectiveGroups, + @Param("caseSensitive") boolean caseSensitive); /** * Inserts the given object into the database. If the object already @@ -125,11 +135,16 @@ public interface ModeledDirectoryObjectMapper { * * @param identifier * The identifier of the object to delete. + * + * @param caseSensitive + * true if the query should evaluate the identifier in a + * case-sensitive manner, otherwise false. * * @return * The number of rows deleted. */ - int delete(@Param("identifier") String identifier); + int delete(@Param("identifier") String identifier, + @Param("caseSensitive") boolean caseSensitive); /** * Updates the given existing object in the database. If the object does diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectService.java index fe587160d..e7e04e5e7 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectService.java @@ -115,7 +115,25 @@ public abstract class ModeledDirectoryObjectService allObjects = Lists.partition(filteredIdentifiers, batchSize).stream() @@ -415,12 +435,12 @@ public abstract class ModeledDirectoryObjectService { * @param children * The identifiers of the objects on the child side of the one-to-many * relationship represented by the RelatedObjectSet. + * + * @param caseSensitive + * true if child identifiers should be treated as case-sensitive when + * performing lookups on them, or false if the queries should be done + * case-insensitively. * * @return * The number of rows inserted. */ int insert(@Param("parent") ParentModelType parent, - @Param("children") Collection children); + @Param("children") Collection children, + @Param("caseSensitive") boolean caseSensitive); /** * Deletes rows as necessary to modify the one-to-many relationship @@ -69,12 +75,18 @@ public interface ObjectRelationMapper { * @param children * The identifiers of the objects on the child side of the one-to-many * relationship represented by the RelatedObjectSet. + * + * @param caseSensitive + * true if child identifiers should be treated as case-sensitive when + * performing lookups on them, or false if the queries should be done + * case-insensitively. * * @return * The number of rows deleted. */ int delete(@Param("parent") ParentModelType parent, - @Param("children") Collection children); + @Param("children") Collection children, + @Param("caseSensitive") boolean caseSensitive); /** * Retrieves the identifiers of all objects on the child side of the diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/RelatedObjectSet.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/RelatedObjectSet.java index add954c5a..b661c3bf5 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/RelatedObjectSet.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/RelatedObjectSet.java @@ -75,6 +75,24 @@ public abstract class RelatedObjectSet permissions, @Param("identifiers") Collection identifiers, @Param("effectiveGroups") Collection effectiveGroups, - @Param("caseSenstive") boolean caseSensitive); + @Param("caseSensitive") boolean caseSensitive); } 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 e0a6091b0..2dcd168b9 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 @@ -638,7 +638,7 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS identifiers = getPreferredConnections(user, identifiers); // Retrieve all children - Collection models = connectionMapper.select(identifiers); + Collection models = connectionMapper.select(identifiers, false); List connections = new ArrayList(models.size()); // Convert each retrieved model to a modeled connection @@ -679,7 +679,7 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS // Produce collection of readable connection identifiers Collection connections = connectionMapper.selectReadable(user.getUser().getModel(), - identifiers, user.getEffectiveUserGroups()); + identifiers, user.getEffectiveUserGroups(), false); // Ensure set contains only identifiers of readable connections identifiers.clear(); 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 243618c2b..f9e63a6e5 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,7 +19,6 @@ 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; @@ -36,7 +35,7 @@ public interface UserMapper extends ModeledDirectoryObjectMapper { * The username of the user to return. * * @param caseSensitive - * true if the search should evaluate usernames in a case-sensitive + * true if the search should evaluate the username in a case-sensitive * manner, otherwise false. * * @return @@ -44,72 +43,5 @@ public interface UserMapper extends ModeledDirectoryObjectMapper { */ UserModel selectOne(@Param("username") String username, @Param("caseSensitive") boolean caseSensitive); - - /** - * Selects all users 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 users are needed by a - * non-administrative user who must have explicit read rights, use - * selectReadable() instead. - * - * @param identifiers - * The identifiers of the users to return. - * - * @param caseSensitive - * true if the query should evaluate username identifiers in a - * case-sensitive manner, otherwise false. - * - * @return - * A Collection of all objects having the given identifiers. - */ - Collection select(@Param("identifiers") Collection identifiers, - @Param("caseSensitive") boolean caseSensitive); - - /** - * Selects all users which have the given identifiers and are explicitly - * readable by the given user. If an identifier has no corresponding - * object, or the corresponding user is unreadable, it will be ignored. - * If users 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 users 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 evaluate username identifiers in a - * case-sensitive manner, 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); - - /** - * Deletes the given user from the database. If the user does not - * exist, this operation has no effect. - * - * @param identifier - * The identifier of the user to delete. - * - * @param caseSensitive - * true if the query should evaluate username identifiers in a - * case-sensitive manner, otherwise false. - * - * @return - * The number of rows deleted. - */ - int delete(@Param("identifier") String identifier, - @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 9478fd371..686486a85 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 @@ -217,6 +217,11 @@ public class UserService extends ModeledDirectoryObjectService { - - /** - * 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 - * True if username case should be respected when looking up the username - * in the guacamole_entity table, or false if the query to the - * guacamole_entity table should be done case-insensitively. - * - * @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 - * True if username case should be respected when looking up the username - * in the guacamole_entity table, or false if the query to the - * guacamole_entity table should be done case-insensitively. - * - * @return - * The number of rows deleted. - */ - int delete(@Param("parent") UserGroupModel parent, - @Param("children") Collection children, - @Param("caseSesitive") boolean caseSensitive); - -} +public interface UserGroupMemberUserMapper extends ObjectRelationMapper {} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserSet.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserSet.java index 989df551f..e694edd8b 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserSet.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserSet.java @@ -21,6 +21,7 @@ package org.apache.guacamole.auth.jdbc.usergroup; import com.google.inject.Inject; import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.auth.jdbc.JDBCEnvironment; import org.apache.guacamole.auth.jdbc.base.ObjectRelationMapper; import org.apache.guacamole.auth.jdbc.base.RelatedObjectSet; import org.apache.guacamole.net.auth.permission.ObjectPermissionSet; @@ -36,7 +37,18 @@ public class UserGroupMemberUserSet extends RelatedObjectSet getObjectRelationMapper() { return userGroupMemberUserMapper; diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLAuthenticationProviderModule.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLAuthenticationProviderModule.java index b623c77d8..7fb913232 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLAuthenticationProviderModule.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLAuthenticationProviderModule.java @@ -30,12 +30,19 @@ import org.apache.guacamole.auth.mysql.conf.MySQLDriver; import org.apache.guacamole.auth.mysql.conf.MySQLEnvironment; import org.apache.guacamole.auth.mysql.conf.MySQLSSLMode; import org.mybatis.guice.datasource.helper.JdbcHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Guice module which configures MySQL-specific injections. */ public class MySQLAuthenticationProviderModule implements Module { + /** + * Logger for this class. + */ + private static final Logger LOGGER = LoggerFactory.getLogger(MySQLAuthenticationProviderModule.class); + /** * MyBatis-specific configuration properties. */ @@ -137,6 +144,15 @@ public class MySQLAuthenticationProviderModule implements Module { TimeZone serverTz = environment.getServerTimeZone(); if (serverTz != null) driverProperties.setProperty("serverTimezone", serverTz.getID()); + + // Check for case-sensitivity and warn admin + if (environment.getCaseSensitiveUsernames()) + LOGGER.warn("The MySQL module is currently configured to support " + + "case-sensitive username comparisons, however, the default " + + "collations for MySQL databases do not support " + + "case-sensitive string comparisons. If you want usernames " + + "within Guacamole to be treated as case-sensitive, further " + + "database configuration may be required."); } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/conf/MySQLEnvironment.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/conf/MySQLEnvironment.java index f0c0f8279..4dd194ca8 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/conf/MySQLEnvironment.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/conf/MySQLEnvironment.java @@ -446,23 +446,12 @@ public class MySQLEnvironment extends JDBCEnvironment { @Override public boolean getCaseSensitiveUsernames() throws GuacamoleException { - // Get the configured value for the property. - boolean caseSensitiveUsernames = getProperty( + // Return the configured value for the property, or the global value. + return getProperty( MySQLGuacamoleProperties.MYSQL_CASE_SENSITIVE_USERNAMES, super.getCaseSensitiveUsernames() ); - // If property has been set to true, warn the admin. - if (caseSensitiveUsernames) - logger.warn("You have enabled case-sensitive usernames; however, " - + "MySQL's default collations do not support case-sensitive " - + "string comparisons. If you really want case-sensitive " - + "usernames you will need to configure your database " - + "appropriately."); - - // Return the configured setting. - return caseSensitiveUsernames; - } /** diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProviderModule.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProviderModule.java index 5a3d4002b..f2f5e45cd 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProviderModule.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProviderModule.java @@ -28,12 +28,19 @@ import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.auth.sqlserver.conf.SQLServerDriver; import org.apache.guacamole.auth.sqlserver.conf.SQLServerEnvironment; import org.mybatis.guice.datasource.helper.JdbcHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Guice module which configures SQLServer-specific injections. */ public class SQLServerAuthenticationProviderModule implements Module { + /** + * Logger for this class. + */ + private static final Logger LOGGER = LoggerFactory.getLogger(SQLServerAuthenticationProviderModule.class); + /** * MyBatis-specific configuration properties. */ @@ -88,6 +95,15 @@ public class SQLServerAuthenticationProviderModule implements Module { // Capture which driver to use for the connection. this.sqlServerDriver = environment.getSQLServerDriver(); + + // Check for case-sensitivity and warn admin. + if (environment.getCaseSensitiveUsernames()) + LOGGER.warn("The SQL Server module is currently configured to support " + + "case-sensitive username comparisons, however, the default " + + "collations for SQL Server databases do not support " + + "case-sensitive string comparisons. If you want usernames " + + "within Guacamole to be treated as case-sensitive, further " + + "database configuration may be required."); } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/conf/SQLServerEnvironment.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/conf/SQLServerEnvironment.java index 9e2d540bb..68568d658 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/conf/SQLServerEnvironment.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/conf/SQLServerEnvironment.java @@ -338,15 +338,6 @@ public class SQLServerEnvironment extends JDBCEnvironment { super.getCaseSensitiveUsernames() ); - // If property has been set to true, warn the admin. - if (caseSensitiveUsernames) - logger.warn("You have configured this extension for case-sensitive " - + "username comparisons, however, the default collations " - + "for SQL Server databases do not support case-sensitive " - + "string comparisons. Further database configuration may " - + "be required in order for case-sensitive username " - + "comparisons to function correctly."); - // Return as configured return caseSensitiveUsernames;