diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/.gitignore b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/.gitignore new file mode 100644 index 000000000..42f4a1a64 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/.gitignore @@ -0,0 +1,2 @@ +target/ +*~ diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/pom.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/pom.xml new file mode 100644 index 000000000..82776f7d0 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/pom.xml @@ -0,0 +1,128 @@ + + + + + 4.0.0 + org.apache.guacamole + guacamole-auth-jdbc-sqlserver + jar + guacamole-auth-jdbc-sqlserver + http://guacamole.incubator.apache.org/ + + + UTF-8 + + + + org.apache.guacamole + guacamole-auth-jdbc + 0.9.13-incubating + ../../ + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + 1.6 + 1.6 + + -Xlint:all + -Werror + + true + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.10 + + + unpack-dependencies + prepare-package + + unpack-dependencies + + + runtime + ${project.build.directory}/classes + + + + + + + + org.apache.rat + apache-rat-plugin + 0.12 + + + + **/*.json + + + + + + + validate + validate + + check + + + + + + + + + + + + + + org.apache.guacamole + guacamole-ext + provided + + + + + org.apache.guacamole + guacamole-auth-jdbc-base + 0.9.13-incubating + + + + + 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 new file mode 100644 index 000000000..df95800ec Binary files /dev/null and b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/001-create-schema.sql differ 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 new file mode 100644 index 000000000..08cce3f07 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/002-create-admin-user.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. + */ + +INSERT INTO [guacamole].[user] (username, password_hash, password_salt, password_date) +VALUES ('guacadmin', 0xCA458A7D494E3BE824F5E1E175A1556C0F8EEF2C2D7DF3633BEC4A29C4411960, +0xCA458A7D494E3BE824F5E1E175A1556C0F8EEF2C2D7DF3633BEC4A29C4411960, getdate()); + +INSERT INTO [guacamole].[system_permission] +SELECT user_id, permission +FROM ( + SELECT 'guacadmin' AS username, 'CREATE_CONNECTION' AS permission + UNION SELECT 'guacadmin' AS username, 'CREATE_CONNECTION_GROUP' AS permission + UNION SELECT 'guacadmin' AS username, 'CREATE_SHARING_PROFILE' AS permission + UNION SELECT 'guacadmin' AS username, 'CREATE_USER' AS permission + UNION SELECT 'guacadmin' AS username, 'ADMINISTER' AS permission) + permissions + JOIN [guacamole].[user] ON permissions.username = [guacamole].[user].[username]; + +INSERT INTO [guacamole].[user_permission] +SELECT [guacamole].[user].[user_id], [affected].[user_id], permission +FROM ( + SELECT 'guacadmin' AS username, 'guacadmin' AS affected_username, 'READ' AS permission + UNION SELECT 'guacadmin' AS username, 'guacadmin' AS affected_username, 'UPDATE' AS permission + UNION SELECT 'guacadmin' AS username, 'guacadmin' AS affected_username, 'ADMINISTER' AS permission) + permissions + JOIN [guacamole].[user] ON permissions.username = [guacamole].[user].[username] + JOIN [guacamole].[user] affected ON permissions.affected_username = affected.username; diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProvider.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProvider.java new file mode 100644 index 000000000..ef5d61d90 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProvider.java @@ -0,0 +1,50 @@ +/* + * 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. + */ + +package org.apache.guacamole.auth.sqlserver; + +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.auth.jdbc.InjectedAuthenticationProvider; +import org.apache.guacamole.auth.jdbc.JDBCAuthenticationProviderService; + +/** + * Provides a SQLServer-based implementation of the AuthenticationProvider + * functionality. + */ +public class SQLServerAuthenticationProvider extends InjectedAuthenticationProvider { + + /** + * Creates a new SQLServerAuthenticationProvider that reads and writes + * authentication data to a SQLServer database defined by properties in + * guacamole.properties. + * + * @throws GuacamoleException + * If a required property is missing, or an error occurs while parsing + * a property. + */ + public SQLServerAuthenticationProvider() throws GuacamoleException { + super(new SQLServerInjectorProvider(), JDBCAuthenticationProviderService.class); + } + + @Override + public String getIdentifier() { + return "sqlserver"; + } + +} 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 new file mode 100644 index 000000000..ebb1a0678 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProviderModule.java @@ -0,0 +1,91 @@ +/* + * 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. + */ + +package org.apache.guacamole.auth.sqlserver; + +import com.google.inject.Binder; +import com.google.inject.Module; +import com.google.inject.name.Names; +import java.util.Properties; +import org.apache.guacamole.GuacamoleException; +import org.mybatis.guice.datasource.helper.JdbcHelper; + +/** + * Guice module which configures SQLServer-specific injections. + */ +public class SQLServerAuthenticationProviderModule implements Module { + + /** + * MyBatis-specific configuration properties. + */ + private final Properties myBatisProperties = new Properties(); + + /** + * SQLServer-specific driver configuration properties. + */ + private final Properties driverProperties = new Properties(); + + /** + * Creates a new SQLServer authentication provider module that configures + * driver and MyBatis properties using the given environment. + * + * @param environment + * The environment to use when configuring MyBatis and the underlying + * JDBC driver. + * + * @throws GuacamoleException + * If a required property is missing, or an error occurs while parsing + * a property. + */ + public SQLServerAuthenticationProviderModule(SQLServerEnvironment environment) + throws GuacamoleException { + + // Set the SQLServer-specific properties for MyBatis. + myBatisProperties.setProperty("mybatis.environment.id", "guacamole"); + myBatisProperties.setProperty("JDBC.host", environment.getSQLServerHostname()); + myBatisProperties.setProperty("JDBC.port", String.valueOf(environment.getSQLServerPort())); + myBatisProperties.setProperty("JDBC.schema", environment.getSQLServerDatabase()); + myBatisProperties.setProperty("JDBC.username", environment.getSQLServerUsername()); + myBatisProperties.setProperty("JDBC.password", environment.getSQLServerPassword()); + myBatisProperties.setProperty("JDBC.autoCommit", "false"); + myBatisProperties.setProperty("mybatis.pooled.pingEnabled", "true"); + myBatisProperties.setProperty("mybatis.pooled.pingQuery", "SELECT 1"); + + // Use UTF-8 in database + driverProperties.setProperty("characterEncoding", "UTF-8"); + + } + + @Override + public void configure(Binder binder) { + + // Bind SQLServer-specific properties + JdbcHelper.SQL_Server_2005_MS_Driver.configure(binder); + + // Bind MyBatis properties + Names.bindProperties(binder, myBatisProperties); + + // Bind JDBC driver properties + binder.bind(Properties.class) + .annotatedWith(Names.named("JDBC.driverProperties")) + .toInstance(driverProperties); + + } + +} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerEnvironment.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerEnvironment.java new file mode 100644 index 000000000..67d882719 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerEnvironment.java @@ -0,0 +1,306 @@ +/* + * 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. + */ + +package org.apache.guacamole.auth.sqlserver; + +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.auth.jdbc.JDBCEnvironment; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.apache.guacamole.auth.jdbc.security.PasswordPolicy; + +/** + * A SQLServer-specific implementation of JDBCEnvironment provides database + * properties specifically for SQLServer. + */ +public class SQLServerEnvironment extends JDBCEnvironment { + + /** + * Logger for this class. + */ + private static final Logger logger = LoggerFactory.getLogger(SQLServerEnvironment.class); + + /** + * The default host to connect to, if SQLSERVER_HOSTNAME is not specified. + */ + private static final String DEFAULT_HOSTNAME = "localhost"; + + /** + * The default port to connect to, if SQLSERVER_PORT is not specified. + */ + private static final int DEFAULT_PORT = 1433; + + /** + * Whether a database user account is required by default for authentication + * to succeed. + */ + private static final boolean DEFAULT_USER_REQUIRED = true; + + /** + * The default value for the maximum number of connections to be + * allowed to the Guacamole server overall. + */ + private final int DEFAULT_ABSOLUTE_MAX_CONNECTIONS = 0; + + /** + * The default value for the default maximum number of connections to be + * allowed per user to any one connection. Note that, as long as the + * legacy "disallow duplicate" and "disallow simultaneous" properties are + * still supported, these cannot be constants, as the legacy properties + * dictate the values that should be used in the absence of the correct + * properties. + */ + private int DEFAULT_MAX_CONNECTIONS_PER_USER = 1; + + /** + * The default value for the default maximum number of connections to be + * allowed per user to any one connection group. Note that, as long as the + * legacy "disallow duplicate" and "disallow simultaneous" properties are + * still supported, these cannot be constants, as the legacy properties + * dictate the values that should be used in the absence of the correct + * properties. + */ + private int DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER = 1; + + /** + * The default value for the default maximum number of connections to be + * allowed to any one connection. Note that, as long as the legacy + * "disallow duplicate" and "disallow simultaneous" properties are still + * supported, these cannot be constants, as the legacy properties dictate + * the values that should be used in the absence of the correct properties. + */ + private int DEFAULT_MAX_CONNECTIONS = 0; + + /** + * The default value for the default maximum number of connections to be + * allowed to any one connection group. Note that, as long as the legacy + * "disallow duplicate" and "disallow simultaneous" properties are still + * supported, these cannot be constants, as the legacy properties dictate + * the values that should be used in the absence of the correct properties. + */ + private int DEFAULT_MAX_GROUP_CONNECTIONS = 0; + + /** + * Constructs a new SQLServerEnvironment, providing access to SQLServer-specific + * configuration options. + * + * @throws GuacamoleException + * If an error occurs while setting up the underlying JDBCEnvironment + * or while parsing legacy SQLServer configuration options. + */ + public SQLServerEnvironment() throws GuacamoleException { + + // Init underlying JDBC environment + super(); + + // Read legacy concurrency-related property + Boolean disallowSimultaneous = getProperty(SQLServerGuacamoleProperties.SQLSERVER_DISALLOW_SIMULTANEOUS_CONNECTIONS); + Boolean disallowDuplicate = getProperty(SQLServerGuacamoleProperties.SQLSERVER_DISALLOW_DUPLICATE_CONNECTIONS); + + // Legacy "simultaneous" property dictates only the maximum number of + // connections per connection + if (disallowSimultaneous != null) { + + // Translate legacy property + if (disallowSimultaneous) { + DEFAULT_MAX_CONNECTIONS = 1; + DEFAULT_MAX_GROUP_CONNECTIONS = 0; + } + else { + DEFAULT_MAX_CONNECTIONS = 0; + DEFAULT_MAX_GROUP_CONNECTIONS = 0; + } + + // Warn of deprecation + logger.warn("The \"{}\" property is deprecated. Use \"{}\" and \"{}\" instead.", + SQLServerGuacamoleProperties.SQLSERVER_DISALLOW_SIMULTANEOUS_CONNECTIONS.getName(), + SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_CONNECTIONS.getName(), + SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_GROUP_CONNECTIONS.getName()); + + // Inform of new equivalent + logger.info("To achieve the same result of setting \"{}\" to \"{}\", set \"{}\" to \"{}\" and \"{}\" to \"{}\".", + SQLServerGuacamoleProperties.SQLSERVER_DISALLOW_SIMULTANEOUS_CONNECTIONS.getName(), disallowSimultaneous, + SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_CONNECTIONS.getName(), DEFAULT_MAX_CONNECTIONS, + SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_GROUP_CONNECTIONS.getName(), DEFAULT_MAX_GROUP_CONNECTIONS); + + } + + // Legacy "duplicate" property dictates whether connections and groups + // may be used concurrently only by different users + if (disallowDuplicate != null) { + + // Translate legacy property + if (disallowDuplicate) { + DEFAULT_MAX_CONNECTIONS_PER_USER = 1; + DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER = 1; + } + else { + DEFAULT_MAX_CONNECTIONS_PER_USER = 0; + DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER = 0; + } + + // Warn of deprecation + logger.warn("The \"{}\" property is deprecated. Use \"{}\" and \"{}\" instead.", + SQLServerGuacamoleProperties.SQLSERVER_DISALLOW_DUPLICATE_CONNECTIONS.getName(), + SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_CONNECTIONS_PER_USER.getName(), + SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_GROUP_CONNECTIONS.getName()); + + // Inform of new equivalent + logger.info("To achieve the same result of setting \"{}\" to \"{}\", set \"{}\" to \"{}\" and \"{}\" to \"{}\".", + SQLServerGuacamoleProperties.SQLSERVER_DISALLOW_DUPLICATE_CONNECTIONS.getName(), disallowDuplicate, + SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_CONNECTIONS_PER_USER.getName(), DEFAULT_MAX_CONNECTIONS_PER_USER, + SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER.getName(), DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER); + + } + + } + + @Override + public boolean isUserRequired() throws GuacamoleException { + return getProperty( + SQLServerGuacamoleProperties.SQLSERVER_USER_REQUIRED, + DEFAULT_USER_REQUIRED + ); + } + + @Override + public int getAbsoluteMaxConnections() throws GuacamoleException { + return getProperty(SQLServerGuacamoleProperties.SQLSERVER_ABSOLUTE_MAX_CONNECTIONS, + DEFAULT_ABSOLUTE_MAX_CONNECTIONS + ); + } + + @Override + public int getDefaultMaxConnections() throws GuacamoleException { + return getProperty( + SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_CONNECTIONS, + DEFAULT_MAX_CONNECTIONS + ); + } + + @Override + public int getDefaultMaxGroupConnections() throws GuacamoleException { + return getProperty( + SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_GROUP_CONNECTIONS, + DEFAULT_MAX_GROUP_CONNECTIONS + ); + } + + @Override + public int getDefaultMaxConnectionsPerUser() throws GuacamoleException { + return getProperty( + SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_CONNECTIONS_PER_USER, + DEFAULT_MAX_CONNECTIONS_PER_USER + ); + } + + @Override + public int getDefaultMaxGroupConnectionsPerUser() throws GuacamoleException { + return getProperty( + SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER, + DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER + ); + } + + @Override + public PasswordPolicy getPasswordPolicy() { + return new SQLServerPasswordPolicy(this); + } + + /** + * Returns the hostname of the SQLServer server hosting the Guacamole + * authentication tables. If unspecified, this will be "localhost". + * + * @return + * The URL of the SQLServer server. + * + * @throws GuacamoleException + * If an error occurs while retrieving the property value. + */ + public String getSQLServerHostname() throws GuacamoleException { + return getProperty( + SQLServerGuacamoleProperties.SQLSERVER_HOSTNAME, + DEFAULT_HOSTNAME + ); + } + + /** + * Returns the port number of the SQLServer server hosting the Guacamole + * authentication tables. If unspecified, this will be the default + * SQLServer port of 5432. + * + * @return + * The port number of the SQLServer server. + * + * @throws GuacamoleException + * If an error occurs while retrieving the property value. + */ + public int getSQLServerPort() throws GuacamoleException { + return getProperty( + SQLServerGuacamoleProperties.SQLSERVER_PORT, + DEFAULT_PORT + ); + } + + /** + * Returns the name of the SQLServer database containing the Guacamole + * authentication tables. + * + * @return + * The name of the SQLServer database. + * + * @throws GuacamoleException + * If an error occurs while retrieving the property value, or if the + * value was not set, as this property is required. + */ + public String getSQLServerDatabase() throws GuacamoleException { + return getRequiredProperty(SQLServerGuacamoleProperties.SQLSERVER_DATABASE); + } + + /** + * Returns the username that should be used when authenticating with the + * SQLServer database containing the Guacamole authentication tables. + * + * @return + * The username for the SQLServer database. + * + * @throws GuacamoleException + * If an error occurs while retrieving the property value, or if the + * value was not set, as this property is required. + */ + public String getSQLServerUsername() throws GuacamoleException { + return getRequiredProperty(SQLServerGuacamoleProperties.SQLSERVER_USERNAME); + } + + /** + * Returns the password that should be used when authenticating with the + * SQLServer database containing the Guacamole authentication tables. + * + * @return + * The password for the SQLServer database. + * + * @throws GuacamoleException + * If an error occurs while retrieving the property value, or if the + * value was not set, as this property is required. + */ + public String getSQLServerPassword() throws GuacamoleException { + return getRequiredProperty(SQLServerGuacamoleProperties.SQLSERVER_PASSWORD); + } + +} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerGuacamoleProperties.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerGuacamoleProperties.java new file mode 100644 index 000000000..e45f50268 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerGuacamoleProperties.java @@ -0,0 +1,200 @@ +/* + * 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. + */ + +package org.apache.guacamole.auth.sqlserver; + +import org.apache.guacamole.properties.BooleanGuacamoleProperty; +import org.apache.guacamole.properties.IntegerGuacamoleProperty; +import org.apache.guacamole.properties.StringGuacamoleProperty; + +/** + * Properties used by the SQLServer Authentication plugin. + */ +public class SQLServerGuacamoleProperties { + + /** + * This class should not be instantiated. + */ + private SQLServerGuacamoleProperties() {} + + /** + * The URL of the SQLServer server hosting the Guacamole authentication tables. + */ + public static final StringGuacamoleProperty SQLSERVER_HOSTNAME = + new StringGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-hostname"; } + + }; + + /** + * The port of the SQLServer server hosting the Guacamole authentication + * tables. + */ + public static final IntegerGuacamoleProperty SQLSERVER_PORT = + new IntegerGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-port"; } + + }; + + /** + * The name of the SQLServer database containing the Guacamole + * authentication tables. + */ + public static final StringGuacamoleProperty SQLSERVER_DATABASE = + new StringGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-database"; } + + }; + + /** + * The username used to authenticate to the SQLServer database containing + * the Guacamole authentication tables. + */ + public static final StringGuacamoleProperty SQLSERVER_USERNAME = + new StringGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-username"; } + + }; + + /** + * The password used to authenticate to the SQLServer database containing + * the Guacamole authentication tables. + */ + public static final StringGuacamoleProperty SQLSERVER_PASSWORD = + new StringGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-password"; } + + }; + + /** + * Whether a user account within the database is required for authentication + * to succeed, even if the user has been authenticated via another + * authentication provider. + */ + public static final BooleanGuacamoleProperty + SQLSERVER_USER_REQUIRED = new BooleanGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-user-required"; } + + }; + + /** + * Whether or not multiple users accessing the same connection at the same + * time should be disallowed. + */ + public static final BooleanGuacamoleProperty + SQLSERVER_DISALLOW_SIMULTANEOUS_CONNECTIONS = + new BooleanGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-disallow-simultaneous-connections"; } + + }; + + /** + * Whether or not the same user accessing the same connection or connection + * group at the same time should be disallowed. + */ + public static final BooleanGuacamoleProperty + SQLSERVER_DISALLOW_DUPLICATE_CONNECTIONS = + new BooleanGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-disallow-duplicate-connections"; } + + }; + + /** + * The maximum number of concurrent connections to allow overall. Zero + * denotes unlimited. + */ + public static final IntegerGuacamoleProperty + SQLSERVER_ABSOLUTE_MAX_CONNECTIONS = + new IntegerGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-absolute-max-connections"; } + + }; + + /** + * The maximum number of concurrent connections to allow to any one + * connection. Zero denotes unlimited. + */ + public static final IntegerGuacamoleProperty + SQLSERVER_DEFAULT_MAX_CONNECTIONS = + new IntegerGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-default-max-connections"; } + + }; + + /** + * The maximum number of concurrent connections to allow to any one + * connection group. Zero denotes unlimited. + */ + public static final IntegerGuacamoleProperty + SQLSERVER_DEFAULT_MAX_GROUP_CONNECTIONS = + new IntegerGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-default-max-group-connections"; } + + }; + + /** + * The maximum number of concurrent connections to allow to any one + * connection by an individual user. Zero denotes unlimited. + */ + public static final IntegerGuacamoleProperty + SQLSERVER_DEFAULT_MAX_CONNECTIONS_PER_USER = + new IntegerGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-default-max-connections-per-user"; } + + }; + + /** + * The maximum number of concurrent connections to allow to any one + * connection group by an individual user. Zero denotes + * unlimited. + */ + public static final IntegerGuacamoleProperty + SQLSERVER_DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER = + new IntegerGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-default-max-group-connections-per-user"; } + + }; + +} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerInjectorProvider.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerInjectorProvider.java new file mode 100644 index 000000000..32d12f6e2 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerInjectorProvider.java @@ -0,0 +1,49 @@ +/* + * 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. + */ + +package org.apache.guacamole.auth.sqlserver; + +import com.google.inject.Guice; +import com.google.inject.Injector; +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.auth.jdbc.JDBCAuthenticationProviderModule; +import org.apache.guacamole.auth.jdbc.JDBCInjectorProvider; + +/** + * JDBCInjectorProvider implementation which configures Guice injections for + * connecting to a SQLServer database based on SQLServer-specific options + * provided via guacamole.properties. + */ +public class SQLServerInjectorProvider extends JDBCInjectorProvider { + + @Override + protected Injector create() throws GuacamoleException { + + // Get local environment + SQLServerEnvironment environment = new SQLServerEnvironment(); + + // Set up Guice injector + return Guice.createInjector( + new JDBCAuthenticationProviderModule(environment), + new SQLServerAuthenticationProviderModule(environment) + ); + + } + +} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerPasswordPolicy.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerPasswordPolicy.java new file mode 100644 index 000000000..f30b180bb --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerPasswordPolicy.java @@ -0,0 +1,194 @@ +/* + * 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. + */ + +package org.apache.guacamole.auth.sqlserver; + +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.auth.jdbc.JDBCEnvironment; +import org.apache.guacamole.auth.jdbc.security.PasswordPolicy; +import org.apache.guacamole.properties.BooleanGuacamoleProperty; +import org.apache.guacamole.properties.IntegerGuacamoleProperty; + +/** + * PasswordPolicy implementation which reads the details of the policy from + * SQLServer-specific properties in guacamole.properties. + */ +public class SQLServerPasswordPolicy implements PasswordPolicy { + + /** + * The property which specifies the minimum length required of all user + * passwords. By default, this will be zero. + */ + private static final IntegerGuacamoleProperty MIN_LENGTH = + new IntegerGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-user-password-min-length"; } + + }; + + /** + * The property which specifies the minimum number of days which must + * elapse before a user may reset their password. If set to zero, the + * default, then this restriction does not apply. + */ + private static final IntegerGuacamoleProperty MIN_AGE = + new IntegerGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-user-password-min-age"; } + + }; + + /** + * The property which specifies the maximum number of days which may + * elapse before a user is required to reset their password. If set to zero, + * the default, then this restriction does not apply. + */ + private static final IntegerGuacamoleProperty MAX_AGE = + new IntegerGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-user-password-max-age"; } + + }; + + /** + * The property which specifies the number of previous passwords remembered + * for each user. If set to zero, the default, then this restriction does + * not apply. + */ + private static final IntegerGuacamoleProperty HISTORY_SIZE = + new IntegerGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-user-password-history-size"; } + + }; + + /** + * The property which specifies whether all user passwords must have at + * least one lowercase character and one uppercase character. By default, + * no such restriction is imposed. + */ + private static final BooleanGuacamoleProperty REQUIRE_MULTIPLE_CASE = + new BooleanGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-user-password-require-multiple-case"; } + + }; + + /** + * The property which specifies whether all user passwords must have at + * least one numeric character (digit). By default, no such restriction is + * imposed. + */ + private static final BooleanGuacamoleProperty REQUIRE_DIGIT = + new BooleanGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-user-password-require-digit"; } + + }; + + /** + * The property which specifies whether all user passwords must have at + * least one non-alphanumeric character (symbol). By default, no such + * restriction is imposed. + */ + private static final BooleanGuacamoleProperty REQUIRE_SYMBOL = + new BooleanGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-user-password-require-symbol"; } + + }; + + /** + * The property which specifies whether users are prohibited from including + * their own username in their password. By default, no such restriction is + * imposed. + */ + private static final BooleanGuacamoleProperty PROHIBIT_USERNAME = + new BooleanGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-user-password-prohibit-username"; } + + }; + + /** + * The Guacamole server environment. + */ + private final JDBCEnvironment environment; + + /** + * Creates a new SQLServerPasswordPolicy which reads the details of the + * policy from the properties exposed by the given environment. + * + * @param environment + * The environment from which password policy properties should be + * read. + */ + public SQLServerPasswordPolicy(JDBCEnvironment environment) { + this.environment = environment; + } + + @Override + public int getMinimumLength() throws GuacamoleException { + return environment.getProperty(MIN_LENGTH, 0); + } + + @Override + public int getMinimumAge() throws GuacamoleException { + return environment.getProperty(MIN_AGE, 0); + } + + @Override + public int getMaximumAge() throws GuacamoleException { + return environment.getProperty(MAX_AGE, 0); + } + + @Override + public int getHistorySize() throws GuacamoleException { + return environment.getProperty(HISTORY_SIZE, 0); + } + + @Override + public boolean isMultipleCaseRequired() throws GuacamoleException { + return environment.getProperty(REQUIRE_MULTIPLE_CASE, false); + } + + @Override + public boolean isNumericRequired() throws GuacamoleException { + return environment.getProperty(REQUIRE_DIGIT, false); + } + + @Override + public boolean isNonAlphanumericRequired() throws GuacamoleException { + return environment.getProperty(REQUIRE_SYMBOL, false); + } + + @Override + public boolean isUsernameProhibited() throws GuacamoleException { + return environment.getProperty(PROHIBIT_USERNAME, false); + } + +} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerSharedAuthenticationProvider.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerSharedAuthenticationProvider.java new file mode 100644 index 000000000..0a3c8d31f --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerSharedAuthenticationProvider.java @@ -0,0 +1,50 @@ +/* + * 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. + */ + +package org.apache.guacamole.auth.sqlserver; + +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.auth.jdbc.InjectedAuthenticationProvider; +import org.apache.guacamole.auth.jdbc.sharing.SharedAuthenticationProviderService; + +/** + * Provides a implementation of AuthenticationProvider which interacts with the + * SQLServer AuthenticationProvider, accepting share keys as credentials and + * providing access to the shared connections. + */ +public class SQLServerSharedAuthenticationProvider extends InjectedAuthenticationProvider { + + /** + * Creates a new SQLServerSharedAuthenticationProvider that provides access + * to shared connections exposed by the SQLServerAuthenticationProvider. + * + * @throws GuacamoleException + * If a required property is missing, or an error occurs while parsing + * a property. + */ + public SQLServerSharedAuthenticationProvider() throws GuacamoleException { + super(new SQLServerInjectorProvider(), SharedAuthenticationProviderService.class); + } + + @Override + public String getIdentifier() { + return "sqlserver-shared"; + } + +} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/package-info.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/package-info.java new file mode 100644 index 000000000..7bbe1b2e3 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/package-info.java @@ -0,0 +1,23 @@ +/* + * 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. + */ + +/** + * The SQLServer authentication provider. + */ +package org.apache.guacamole.auth.sqlserver; diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/guac-manifest.json b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/guac-manifest.json new file mode 100644 index 000000000..ee61ab578 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/guac-manifest.json @@ -0,0 +1,28 @@ +{ + + "guacamoleVersion" : "0.9.13-incubating", + + "name" : "SQLServer Authentication", + "namespace" : "guac-sqlserver", + + "authProviders" : [ + "org.apache.guacamole.auth.sqlserver.SQLServerAuthenticationProvider", + "org.apache.guacamole.auth.sqlserver.SQLServerSharedAuthenticationProvider" + ], + + "css" : [ + "styles/jdbc.css" + ], + + "html" : [ + "html/shared-connection.html" + ], + + "translations" : [ + "translations/en.json", + "translations/fr.json", + "translations/ru.json" + ] + +} + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionMapper.xml new file mode 100644 index 000000000..24008fcc4 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionMapper.xml @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[connection] + WHERE connection_id = #{identifier,jdbcType=INTEGER} + + + + + + INSERT INTO [guacamole].[connection] ( + connection_name, + parent_id, + protocol, + max_connections, + max_connections_per_user, + proxy_hostname, + proxy_port, + proxy_encryption_method, + connection_weight, + failover_only + ) + VALUES ( + #{object.name,jdbcType=VARCHAR}, + #{object.parentIdentifier,jdbcType=INTEGER}, + #{object.protocol,jdbcType=VARCHAR}, + #{object.maxConnections,jdbcType=INTEGER}, + #{object.maxConnectionsPerUser,jdbcType=INTEGER}, + #{object.proxyHostname,jdbcType=VARCHAR}, + #{object.proxyPort,jdbcType=INTEGER}, + #{object.proxyEncryptionMethod,jdbcType=VARCHAR}, + #{object.connectionWeight,jdbcType=INTEGER}, + #{object.failoverOnly,jdbcType=INTEGER} + ) + + + + + + UPDATE [guacamole].[connection] + SET connection_name = #{object.name,jdbcType=VARCHAR}, + parent_id = #{object.parentIdentifier,jdbcType=INTEGER}, + protocol = #{object.protocol,jdbcType=VARCHAR}, + max_connections = #{object.maxConnections,jdbcType=INTEGER}, + max_connections_per_user = #{object.maxConnectionsPerUser,jdbcType=INTEGER}, + proxy_hostname = #{object.proxyHostname,jdbcType=VARCHAR}, + proxy_port = #{object.proxyPort,jdbcType=INTEGER}, + proxy_encryption_method = #{object.proxyEncryptionMethod,jdbcType=VARCHAR}, + connection_weight = #{object.connectionWeight,jdbcType=INTEGER}, + failover_only = #{object.failoverOnly,jdbcType=INTEGER} + WHERE connection_id = #{object.objectID,jdbcType=INTEGER} + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionParameterMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionParameterMapper.xml new file mode 100644 index 000000000..de1ab97c1 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionParameterMapper.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[connection_parameter] + WHERE connection_id = #{identifier,jdbcType=INTEGER} + + + + + + INSERT INTO [guacamole].[connection_parameter] ( + connection_id, + parameter_name, + parameter_value + ) + VALUES + + (#{parameter.connectionIdentifier,jdbcType=INTEGER}, + #{parameter.name,jdbcType=VARCHAR}, + #{parameter.value,jdbcType=VARCHAR}) + + + + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml new file mode 100644 index 000000000..ec077db7f --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + INSERT INTO [guacamole].[connection_history] ( + connection_id, + connection_name, + remote_host, + sharing_profile_id, + sharing_profile_name, + user_id, + username, + start_date, + end_date + ) + VALUES ( + #{record.connectionIdentifier,jdbcType=INTEGER}, + #{record.connectionName,jdbcType=VARCHAR}, + #{record.remoteHost,jdbcType=VARCHAR}, + #{record.sharingProfileIdentifier,jdbcType=INTEGER}, + #{record.sharingProfileName,jdbcType=VARCHAR}, + (SELECT user_id FROM [guacamole].[user] + WHERE username = #{record.username,jdbcType=VARCHAR}), + #{record.username,jdbcType=VARCHAR}, + #{record.startDate,jdbcType=TIMESTAMP}, + #{record.endDate,jdbcType=TIMESTAMP} + ) + + + + + + + + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupMapper.xml new file mode 100644 index 000000000..47a3e63d5 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupMapper.xml @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[connection_group] + WHERE connection_group_id = #{identifier,jdbcType=INTEGER} + + + + + + INSERT INTO [guacamole].[connection_group] ( + connection_group_name, + parent_id, + type, + max_connections, + max_connections_per_user, + enable_session_affinity + ) + VALUES ( + #{object.name,jdbcType=VARCHAR}, + #{object.parentIdentifier,jdbcType=INTEGER}, + #{object.type,jdbcType=VARCHAR}, + #{object.maxConnections,jdbcType=INTEGER}, + #{object.maxConnectionsPerUser,jdbcType=INTEGER}, + #{object.sessionAffinityEnabled,jdbcType=INTEGER} + ) + + + + + + UPDATE [guacamole].[connection_group] + SET connection_group_name = #{object.name,jdbcType=VARCHAR}, + parent_id = #{object.parentIdentifier,jdbcType=INTEGER}, + type = #{object.type,jdbcType=VARCHAR}, + max_connections = #{object.maxConnections,jdbcType=INTEGER}, + max_connections_per_user = #{object.maxConnectionsPerUser,jdbcType=INTEGER}, + enable_session_affinity = #{object.sessionAffinityEnabled,jdbcType=INTEGER} + WHERE connection_group_id = #{object.objectID,jdbcType=INTEGER} + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionGroupPermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionGroupPermissionMapper.xml new file mode 100644 index 000000000..2890ab31d --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionGroupPermissionMapper.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[connection_group_permission] + WHERE (user_id, permission, connection_group_id) IN + + (#{permission.userID,jdbcType=INTEGER}, + #{permission.type,jdbcType=VARCHAR}, + #{permission.objectIdentifier,jdbcType=INTEGER}) + + + + + + + + INSERT INTO [guacamole].[connection_group_permission] ( + user_id, + permission, + connection_group_id + ) + SELECT DISTINCT + permissions.user_id, + permissions.permission, + permissions.connection_group_id + FROM + + SELECT #{permission.userID,jdbcType=INTEGER} AS user_id, + #{permission.type,jdbcType=VARCHAR} AS permission, + #{permission.objectIdentifier,jdbcType=INTEGER} AS connection_group_id + + AS permissions + WHERE (user_id, permission, connection_group_id) NOT IN ( + SELECT + [guacamole].[connection_group_permission].user_id, + [guacamole].[connection_group_permission].permission, + [guacamole].[connection_group_permission].connection_group_id + FROM [guacamole].[connection_group_permission] + ); + + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionPermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionPermissionMapper.xml new file mode 100644 index 000000000..8ea85bc3c --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionPermissionMapper.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[connection_permission] + WHERE (user_id, permission, connection_id) IN + + (#{permission.userID,jdbcType=INTEGER}, + #{permission.type,jdbcType=VARCHAR}, + #{permission.objectIdentifier,jdbcType=INTEGER}) + + + + + + + + INSERT INTO [guacamole].[connection_permission] ( + user_id, + permission, + connection_id + ) + SELECT DISTINCT + permissions.user_id, + permissions.permission, + permissions.connection_id + FROM + + SELECT #{permission.userID,jdbcType=INTEGER} AS user_id, + #{permission.type,jdbcType=VARCHAR} AS permission, + #{permission.objectIdentifier,jdbcType=INTEGER} AS connection_id + + AS permissions + WHERE (user_id, permission, connection_id) NOT IN ( + SELECT + [guacamole].[connection_permission].user_id, + [guacamole].[connection_permission].permission, + [guacamole].[connection_permission].connection_id + FROM [guacamole].[connection_permission] + ); + + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionMapper.xml new file mode 100644 index 000000000..cb706b8d4 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionMapper.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[sharing_profile_permission] + WHERE (user_id, permission, sharing_profile_id) IN + + (#{permission.userID,jdbcType=INTEGER}, + #{permission.type,jdbcType=VARCHAR}, + #{permission.objectIdentifier,jdbcType=INTEGER}) + + + + + + + + INSERT INTO [guacamole].[sharing_profile_permission] ( + user_id, + permission, + sharing_profile_id + ) + SELECT DISTINCT + permissions.user_id, + permissions.permission, + permissions.sharing_profile_id + FROM + + SELECT #{permission.userID,jdbcType=INTEGER} AS user_id, + #{permission.type,jdbcType=VARCHAR} AS permission, + #{permission.objectIdentifier,jdbcType=INTEGER} AS sharing_profile_id + + AS permissions + WHERE (user_id, permission, sharing_profile_id) NOT IN ( + SELECT + [guacamole].[sharing_profile_permission].user_id, + [guacamole].[sharing_profile_permission].permission, + [guacamole].[sharing_profile_permission].sharing_profile_id + FROM [guacamole].[sharing_profile_permission] + ); + + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SystemPermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SystemPermissionMapper.xml new file mode 100644 index 000000000..d9e622b69 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SystemPermissionMapper.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[system_permission] + WHERE (user_id, permission) IN + + (#{permission.userID,jdbcType=INTEGER}, + #{permission.type,jdbcType=VARCHAR}) + + + + + + + + INSERT INTO [guacamole].[system_permission] ( + user_id, + permission + ) + SELECT DISTINCT + permissions.user_id, + permissions.permission + FROM + + SELECT #{permission.userID,jdbcType=INTEGER} AS user_id, + #{permission.type,jdbcType=VARCHAR} AS permission + + AS permissions + WHERE (user_id, permission) NOT IN ( + SELECT + [guacamole].[system_permission].user_id, + [guacamole].[system_permission].permission + FROM [guacamole].[system_permission] + ); + + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml new file mode 100644 index 000000000..595c3263d --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[user_permission] + USING [guacamole].[user] affected + WHERE + [guacamole].[user_permission].affected_user_id = affected.user_id + AND ([guacamole].[user_permission].user_id, permission, affected.username) IN + + (#{permission.userID,jdbcType=INTEGER}, + #{permission.type,jdbcType=VARCHAR}, + #{permission.objectIdentifier,jdbcType=INTEGER}) + + + + + + + + INSERT INTO [guacamole].[user_permission] ( + user_id, + permission, + affected_user_id + ) + SELECT DISTINCT + permissions.user_id, + permissions.permission, + [guacamole].[user].user_id + FROM + + SELECT #{permission.userID,jdbcType=INTEGER} AS user_id, + #{permission.type,jdbcType=VARCHAR} AS permission, + #{permission.objectIdentifier,jdbcType=INTEGER} AS username + + AS permissions + JOIN [guacamole].[user] ON [guacamole].[user].username = permissions.username + WHERE (permissions.user_id, permissions.permission, [guacamole].[user].user_id) NOT IN ( + SELECT + [guacamole].[user_permission].user_id, + [guacamole].[user_permission].permission, + [guacamole].[user_permission].affected_user_id + FROM [guacamole].[user_permission] + ); + + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileMapper.xml new file mode 100644 index 000000000..9d7d45abd --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileMapper.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[sharing_profile] + WHERE sharing_profile_id = #{identifier,jdbcType=INTEGER} + + + + + + INSERT INTO [guacamole].[sharing_profile] ( + sharing_profile_name, + primary_connection_id + ) + VALUES ( + #{object.name,jdbcType=VARCHAR}, + #{object.parentIdentifier,jdbcType=INTEGER} + ) + + + + + + UPDATE [guacamole].[sharing_profile] + SET sharing_profile_name = #{object.name,jdbcType=VARCHAR}, + primary_connection_id = #{object.parentIdentifier,jdbcType=INTEGER} + WHERE sharing_profile_id = #{object.objectID,jdbcType=INTEGER} + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileParameterMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileParameterMapper.xml new file mode 100644 index 000000000..8835350b7 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileParameterMapper.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[sharing_profile_parameter] + WHERE sharing_profile_id = #{identifier,jdbcType=INTEGER} + + + + + + INSERT INTO [guacamole].[sharing_profile_parameter] ( + sharing_profile_id, + parameter_name, + parameter_value + ) + VALUES + + (#{parameter.sharingProfileIdentifier,jdbcType=INTEGER} + #{parameter.name,jdbcType=VARCHAR}, + #{parameter.value,jdbcType=VARCHAR}) + + + + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml new file mode 100644 index 000000000..9ad67a6f3 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + INSERT INTO [guacamole].[user_password_history] ( + user_id, + password_hash, + password_salt, + password_date + ) + VALUES ( + #{record.userID,jdbcType=INTEGER}, + #{record.passwordHash,jdbcType=BINARY}, + #{record.passwordSalt,jdbcType=BINARY}, + #{record.passwordDate,jdbcType=TIMESTAMP} + ); + + DELETE FROM [guacamole].[user_password_history] + WHERE password_history_id IN ( + SELECT password_history_id + FROM [guacamole].[user_password_history] + WHERE user_id = #{record.userID,jdbcType=INTEGER} + ORDER BY password_date DESC + OFFSET #{maxHistorySize} + ); + + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml new file mode 100644 index 000000000..a4ceea79e --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[user] + WHERE username = #{identifier,jdbcType=VARCHAR} + + + + + + INSERT INTO [guacamole].[user] ( + username, + password_hash, + password_salt, + password_date, + disabled, + expired, + access_window_start, + access_window_end, + valid_from, + valid_until, + timezone, + full_name, + email_address, + organization, + organizational_role + ) + VALUES ( + #{object.identifier,jdbcType=VARCHAR}, + #{object.passwordHash,jdbcType=BINARY}, + #{object.passwordSalt,jdbcType=BINARY}, + #{object.passwordDate,jdbcType=TIMESTAMP}, + #{object.disabled,jdbcType=INTEGER}, + #{object.expired,jdbcType=INTEGER}, + #{object.accessWindowStart,jdbcType=TIME}, + #{object.accessWindowEnd,jdbcType=TIME}, + #{object.validFrom,jdbcType=DATE}, + #{object.validUntil,jdbcType=DATE}, + #{object.timeZone,jdbcType=VARCHAR}, + #{object.fullName,jdbcType=VARCHAR}, + #{object.emailAddress,jdbcType=VARCHAR}, + #{object.organization,jdbcType=VARCHAR}, + #{object.organizationalRole,jdbcType=VARCHAR} + ) + + + + + + UPDATE [guacamole].[user] + SET password_hash = #{object.passwordHash,jdbcType=BINARY}, + password_salt = #{object.passwordSalt,jdbcType=BINARY}, + password_date = #{object.passwordDate,jdbcType=TIMESTAMP}, + disabled = #{object.disabled,jdbcType=INTEGER}, + expired = #{object.expired,jdbcType=INTEGER}, + access_window_start = #{object.accessWindowStart,jdbcType=TIME}, + access_window_end = #{object.accessWindowEnd,jdbcType=TIME}, + valid_from = #{object.validFrom,jdbcType=DATE}, + valid_until = #{object.validUntil,jdbcType=DATE}, + timezone = #{object.timeZone,jdbcType=VARCHAR}, + full_name = #{object.fullName,jdbcType=VARCHAR}, + email_address = #{object.emailAddress,jdbcType=VARCHAR}, + organization = #{object.organization,jdbcType=VARCHAR}, + organizational_role = #{object.organizationalRole,jdbcType=VARCHAR} + WHERE user_id = #{object.objectID,jdbcType=VARCHAR} + + + diff --git a/extensions/guacamole-auth-jdbc/pom.xml b/extensions/guacamole-auth-jdbc/pom.xml index 2a5ef5b2b..7869c8650 100644 --- a/extensions/guacamole-auth-jdbc/pom.xml +++ b/extensions/guacamole-auth-jdbc/pom.xml @@ -70,6 +70,7 @@ modules/guacamole-auth-jdbc-mysql modules/guacamole-auth-jdbc-postgresql + modules/guacamole-auth-jdbc-sqlserver