From 00f83145a36f7ae0d446f4c8824463d6dd557f3d Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 23 Oct 2021 15:53:56 -0700 Subject: [PATCH] GUACAMOLE-957: Leverage capturing group in user match regex to determine Guacamole LDAP user identities. --- .../ldap/AuthenticationProviderService.java | 24 +++--- .../auth/ldap/user/LDAPAuthenticatedUser.java | 4 +- .../auth/ldap/user/UserLDAPConfiguration.java | 79 +++++++++++++++++++ 3 files changed, 94 insertions(+), 13 deletions(-) create mode 100644 extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserLDAPConfiguration.java diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java index 486c524bd..654b403c3 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java @@ -19,6 +19,7 @@ package org.apache.guacamole.auth.ldap; +import org.apache.guacamole.auth.ldap.user.UserLDAPConfiguration; import com.google.inject.Inject; import com.google.inject.Provider; import java.util.Collection; @@ -169,30 +170,31 @@ public class AuthenticationProviderService { } /** - * Returns a new ConnectedLDAPConfiguration that is connected to an LDAP - * server associated with the user having the given username and bound + * Returns a new UserLDAPConfiguration that is connected to an LDAP server + * associated with the Guacamole user having the given username and bound * using the provided password. All LDAP servers associated with the given * user are tried until the connection and authentication attempt succeeds. * If no LDAP servers are available, or no LDAP servers are associated with - * the given user, null is returned. + * the given user, null is returned. The Guacamole username will be + * internally translated to a fully-qualified LDAP DN according to the + * configuration of the LDAP server that is ultimately chosen. * * @param username - * The username or DN of the user to bind as. + * The username of the Guacamole user to bind as. * * @param password * The password of the user to bind as. * * @return - * A new ConnectedLDAPConfiguration which is bound to an LDAP server - * using the provided credentials, or null if no LDAP servers are - * available for the given user or connecting/authenticating has - * failed. + * A new UserLDAPConfiguration which is bound to an LDAP server using + * the provided credentials, or null if no LDAP servers are available + * for the given user or connecting/authenticating has failed. * * @throws GuacamoleException * If configuration information for the user's LDAP server(s) cannot * be retrieved. */ - private ConnectedLDAPConfiguration getLDAPConfiguration(String username, + private UserLDAPConfiguration getLDAPConfiguration(String username, String password) throws GuacamoleException { // Get all LDAP server configurations @@ -236,7 +238,7 @@ public class AuthenticationProviderService { // Connection and bind were successful logger.info("User \"{}\" was successfully authenticated by LDAP server \"{}\".", username, config.getServerHostname()); - return new ConnectedLDAPConfiguration(config, bindDn, ldapConnection); + return new UserLDAPConfiguration(config, translatedUsername, bindDn, ldapConnection); } @@ -278,7 +280,7 @@ public class AuthenticationProviderService { + " authentication provider.", CredentialsInfo.USERNAME_PASSWORD); } - ConnectedLDAPConfiguration config = getLDAPConfiguration(username, password); + UserLDAPConfiguration config = getLDAPConfiguration(username, password); if (config == null) throw new GuacamoleInvalidCredentialsException("Invalid login.", CredentialsInfo.USERNAME_PASSWORD); diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/LDAPAuthenticatedUser.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/LDAPAuthenticatedUser.java index 6889e61a7..2abe4aef0 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/LDAPAuthenticatedUser.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/LDAPAuthenticatedUser.java @@ -89,14 +89,14 @@ public class LDAPAuthenticatedUser extends AbstractAuthenticatedUser { * The unique identifiers of all user groups which affect the * permissions available to this user. */ - public void init(ConnectedLDAPConfiguration config, Credentials credentials, + public void init(UserLDAPConfiguration config, Credentials credentials, Map tokens, Set effectiveGroups) { this.config = config; this.credentials = credentials; this.tokens = Collections.unmodifiableMap(tokens); this.effectiveGroups = effectiveGroups; this.bindDn = config.getBindDN(); - setIdentifier(credentials.getUsername()); + setIdentifier(config.getGuacamoleUsername()); } /** diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserLDAPConfiguration.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserLDAPConfiguration.java new file mode 100644 index 000000000..3d2cd8221 --- /dev/null +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserLDAPConfiguration.java @@ -0,0 +1,79 @@ +/* + * 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.ldap.user; + +import org.apache.directory.api.ldap.model.name.Dn; +import org.apache.directory.ldap.client.api.LdapNetworkConnection; +import org.apache.guacamole.auth.ldap.ConnectedLDAPConfiguration; +import org.apache.guacamole.auth.ldap.conf.LDAPConfiguration; + +/** + * LDAPConfiguration implementation that represents the configuration and + * network connection of an LDAP that has been bound on behalf of a Guacamole + * user. + */ +public class UserLDAPConfiguration extends ConnectedLDAPConfiguration { + + /** + * The username of the associated Guacamole user. + */ + private final String username; + + /** + * Creates a new UserLDAPConfiguration that associates the given + * LDAPConfiguration of an LDAP server with the active network connection to + * that server, as well as the username of the Guacamole user on behalf of + * whom that connection was established. All functions inherited from the + * LDAPConfiguration interface are delegated to the given LDAPConfiguration. + * It is the responsibility of the caller to ensure the provided + * LdapNetworkConnection is closed after it is no longer needed. + * + * @param config + * The LDAPConfiguration to wrap. + * + * @param username + * The username of the associated Guacamole user. + * + * @param bindDn + * The LDAP DN that was used to bind with the LDAP server to produce + * the given LdapNetworkConnection. + * + * @param connection + * The connection to the LDAP server represented by the given + * configuration. + */ + public UserLDAPConfiguration(LDAPConfiguration config, + String username, Dn bindDn, LdapNetworkConnection connection) { + super(config, bindDn, connection); + this.username = username; + } + + /** + * Returns the username of the Guacamole user on behalf of whom the + * associated LDAP network connection was established. + * + * @return + * The username of the associated Guacamole user. + */ + public String getGuacamoleUsername() { + return username; + } + +}