From 72dddc09211e5dc5830e86bc9fb0b4bfa909a078 Mon Sep 17 00:00:00 2001 From: Patrick Richardson Date: Thu, 10 Dec 2015 09:35:29 -0500 Subject: [PATCH 1/6] GUAC-1388 Allow LDAP role-based access control for guacConfigGroups --- extensions/guacamole-auth-ldap/README | 4 +- .../doc/examples/exampleConfigGroup.ldif | 1 + .../auth/ldap/ConfigurationService.java | 17 +++++ .../auth/ldap/LDAPGuacamoleProperties.java | 11 +++ .../ldap/connection/ConnectionService.java | 76 +++++++++++++++++-- 5 files changed, 103 insertions(+), 6 deletions(-) diff --git a/extensions/guacamole-auth-ldap/README b/extensions/guacamole-auth-ldap/README index 223cbf7cb..6ae10882a 100644 --- a/extensions/guacamole-auth-ldap/README +++ b/extensions/guacamole-auth-ldap/README @@ -88,7 +88,9 @@ guacamole.properties such that the authentication provider is available. # The base DN within which all guacConfig objects can be found. ldap-config-base-dn: dc=example,dc=net - + + # The base DN within which all role based groups can be found. + ldap-group-base-dn: ou=groups,dc=example,dc=net ------------------------------------------------------------ Reporting problems diff --git a/extensions/guacamole-auth-ldap/doc/examples/exampleConfigGroup.ldif b/extensions/guacamole-auth-ldap/doc/examples/exampleConfigGroup.ldif index d1508cde0..bae301385 100644 --- a/extensions/guacamole-auth-ldap/doc/examples/exampleConfigGroup.ldif +++ b/extensions/guacamole-auth-ldap/doc/examples/exampleConfigGroup.ldif @@ -9,3 +9,4 @@ guacConfigParameter: port=5900 guacConfigParameter: password=secret member: cn=user1,dc=example,dc=com member: cn=user2,dc=example,dc=com +seeAlso: ou=admins,ou=groups,dc=example,dc=com diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/ConfigurationService.java b/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/ConfigurationService.java index ae4a90a76..62cd35e2b 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/ConfigurationService.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/ConfigurationService.java @@ -135,6 +135,23 @@ public class ConfigurationService { ); } + /** + * Returns the base DN under which all Guacamole role based access control + * (RBAC) groups will be stored within the LDAP directory. + * + * @return + * The base DN under which all Guacamole RBAC groups will be stored + * within the LDAP directory. + * + * @throws GuacamoleException + * If guacamole.properties cannot be parsed. + */ + public String getGroupBaseDN() throws GuacamoleException { + return environment.getProperty( + LDAPGuacamoleProperties.LDAP_GROUP_BASE_DN + ); + } + /** * Returns the DN that should be used when searching for the DNs of users * attempting to authenticate. If no such search should be performed, null diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/LDAPGuacamoleProperties.java b/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/LDAPGuacamoleProperties.java index 283584e28..5f173c2ea 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/LDAPGuacamoleProperties.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/LDAPGuacamoleProperties.java @@ -62,6 +62,17 @@ public class LDAPGuacamoleProperties { public String getName() { return "ldap-user-base-dn"; } }; + + /** + * The base DN of role based access control (RBAC) groups. + * All groups should be under this DN. + */ + public static final StringGuacamoleProperty LDAP_GROUP_BASE_DN = new StringGuacamoleProperty() { + + @Override + public String getName() { return "ldap-group-base-dn"; } + + }; /** * The attribute or attributes which identify users. One of these diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/connection/ConnectionService.java b/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/connection/ConnectionService.java index 9d2abe06c..3bf927bd2 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/connection/ConnectionService.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/connection/ConnectionService.java @@ -96,8 +96,9 @@ public class ConnectionService { // Do not return any connections if base DN is not specified String configurationBaseDN = confService.getConfigurationBaseDN(); - if (configurationBaseDN == null) + if (configurationBaseDN == null) { return Collections.emptyMap(); + } try { @@ -109,11 +110,17 @@ public class ConnectionService { // possibly be null assert(userDN != null); - // Find all Guacamole connections for the given user + // Get the search filter for finding connections associated to the userDN + String connectionSearchFilter = getConnectionSearchFilter(userDN, ldapConnection); + + // Find all Guacamole connections for the given user by + // looking for direct membership in the guacConfigGroup + // and possibly any groups the user is a member of that are + // referred to in the seeAlso attribute of the guacConfigGroup. LDAPSearchResults results = ldapConnection.search( configurationBaseDN, LDAPConnection.SCOPE_SUB, - "(&(objectClass=guacConfigGroup)(member=" + escapingService.escapeLDAPSearchFilter(userDN) + "))", + connectionSearchFilter, null, false ); @@ -188,11 +195,70 @@ public class ConnectionService { // Return map of all connections return connections; - } - catch (LDAPException e) { + } catch (LDAPException e) { throw new GuacamoleServerException("Error while querying for connections.", e); } } + + /** + * Returns the connection search filter for the given userDN. + * + * @param userDN + * DN of the user to search for associated guacConfigGroup connections. + * + * @param ldapConnection + * LDAP connection to use for searching for associated groups. + * + * @return + * Search filter for finding guacConfigGroup associated with the userDN. + * + * @throws LDAPException + * If an error occurs preventing retrieval of user groups. + * + * @throws GuacamoleException + * If an error occurs retrieving the group base DN. + */ + private String getConnectionSearchFilter(String userDN, LDAPConnection ldapConnection) throws LDAPException, GuacamoleException { + + // Create a search filter for the connection search + StringBuilder connectionSearchFilter = new StringBuilder(); + + // Add the prefix to the search filter, prefix filter searches for guacConfigGroups with the userDN as the member attribute value + connectionSearchFilter.append("(&(objectClass=guacConfigGroup)(|(member="); + connectionSearchFilter.append(escapingService.escapeLDAPSearchFilter(userDN)); + connectionSearchFilter.append(")"); + + // If group base DN is specified search for user groups + String groupBaseDN = confService.getGroupBaseDN(); + + if (groupBaseDN != null) { + + // Get all groups the user is a member of starting at the groupBaseDN, excluding guacConfigGroups + LDAPSearchResults userRoleGroupResults = ldapConnection.search( + groupBaseDN, + LDAPConnection.SCOPE_SUB, + "(&(!(objectClass=guacConfigGroup))(member=" + escapingService.escapeLDAPSearchFilter(userDN) + "))", + null, + false + ); + + // Append the additional user groups to the LDAP filter + // Now the filter will also look for guacConfigGroups that refer + // to groups the user is a member of + // The guacConfig group uses the seeAlso attribute to refer + // to these other groups + while (userRoleGroupResults.hasMore()) { + LDAPEntry entry = userRoleGroupResults.next(); + connectionSearchFilter.append("(seeAlso=").append(escapingService.escapeLDAPSearchFilter(entry.getDN())).append(")"); + } + } + + // Complete the search filter. + connectionSearchFilter.append("))"); + + return connectionSearchFilter.toString(); + } } + From 84eb4d859878ec0c1dd42d9aace43e97a46763e5 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 22 Jan 2016 08:28:02 -0800 Subject: [PATCH 2/6] GUAC-1388: Correct whitespace errors. Remove unrelated reformatting. --- extensions/guacamole-auth-ldap/README | 2 +- .../auth/ldap/LDAPGuacamoleProperties.java | 6 ++-- .../ldap/connection/ConnectionService.java | 31 ++++++++++--------- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/extensions/guacamole-auth-ldap/README b/extensions/guacamole-auth-ldap/README index 6ae10882a..eb95aa4b0 100644 --- a/extensions/guacamole-auth-ldap/README +++ b/extensions/guacamole-auth-ldap/README @@ -88,7 +88,7 @@ guacamole.properties such that the authentication provider is available. # The base DN within which all guacConfig objects can be found. ldap-config-base-dn: dc=example,dc=net - + # The base DN within which all role based groups can be found. ldap-group-base-dn: ou=groups,dc=example,dc=net diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/LDAPGuacamoleProperties.java b/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/LDAPGuacamoleProperties.java index 5f173c2ea..2efa85f85 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/LDAPGuacamoleProperties.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/LDAPGuacamoleProperties.java @@ -62,10 +62,10 @@ public class LDAPGuacamoleProperties { public String getName() { return "ldap-user-base-dn"; } }; - + /** - * The base DN of role based access control (RBAC) groups. - * All groups should be under this DN. + * The base DN of role based access control (RBAC) groups. All groups + * should be under this DN. */ public static final StringGuacamoleProperty LDAP_GROUP_BASE_DN = new StringGuacamoleProperty() { diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/connection/ConnectionService.java b/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/connection/ConnectionService.java index 3bf927bd2..886cb08f4 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/connection/ConnectionService.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/connection/ConnectionService.java @@ -96,9 +96,8 @@ public class ConnectionService { // Do not return any connections if base DN is not specified String configurationBaseDN = confService.getConfigurationBaseDN(); - if (configurationBaseDN == null) { + if (configurationBaseDN == null) return Collections.emptyMap(); - } try { @@ -112,7 +111,7 @@ public class ConnectionService { // Get the search filter for finding connections associated to the userDN String connectionSearchFilter = getConnectionSearchFilter(userDN, ldapConnection); - + // Find all Guacamole connections for the given user by // looking for direct membership in the guacConfigGroup // and possibly any groups the user is a member of that are @@ -195,12 +194,13 @@ public class ConnectionService { // Return map of all connections return connections; - } catch (LDAPException e) { + } + catch (LDAPException e) { throw new GuacamoleServerException("Error while querying for connections.", e); } } - + /** * Returns the connection search filter for the given userDN. * @@ -215,12 +215,14 @@ public class ConnectionService { * * @throws LDAPException * If an error occurs preventing retrieval of user groups. - * + * * @throws GuacamoleException - * If an error occurs retrieving the group base DN. + * If an error occurs retrieving the group base DN. */ - private String getConnectionSearchFilter(String userDN, LDAPConnection ldapConnection) throws LDAPException, GuacamoleException { - + private String getConnectionSearchFilter(String userDN, + LDAPConnection ldapConnection) + throws LDAPException, GuacamoleException { + // Create a search filter for the connection search StringBuilder connectionSearchFilter = new StringBuilder(); @@ -231,7 +233,6 @@ public class ConnectionService { // If group base DN is specified search for user groups String groupBaseDN = confService.getGroupBaseDN(); - if (groupBaseDN != null) { // Get all groups the user is a member of starting at the groupBaseDN, excluding guacConfigGroups @@ -244,19 +245,19 @@ public class ConnectionService { ); // Append the additional user groups to the LDAP filter - // Now the filter will also look for guacConfigGroups that refer + // Now the filter will also look for guacConfigGroups that refer // to groups the user is a member of - // The guacConfig group uses the seeAlso attribute to refer + // The guacConfig group uses the seeAlso attribute to refer // to these other groups while (userRoleGroupResults.hasMore()) { LDAPEntry entry = userRoleGroupResults.next(); connectionSearchFilter.append("(seeAlso=").append(escapingService.escapeLDAPSearchFilter(entry.getDN())).append(")"); } } - + // Complete the search filter. - connectionSearchFilter.append("))"); - + connectionSearchFilter.append("))"); + return connectionSearchFilter.toString(); } From c0aadff989219737edf909238f070bcb2cefb6eb Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 22 Jan 2016 08:30:48 -0800 Subject: [PATCH 3/6] GUAC-1388: Clarify definition of "ldap-group-base-dn" property. --- .../guacamole/auth/ldap/LDAPGuacamoleProperties.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/LDAPGuacamoleProperties.java b/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/LDAPGuacamoleProperties.java index 2efa85f85..39e884861 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/LDAPGuacamoleProperties.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/LDAPGuacamoleProperties.java @@ -64,8 +64,9 @@ public class LDAPGuacamoleProperties { }; /** - * The base DN of role based access control (RBAC) groups. All groups - * should be under this DN. + * The base DN of role based access control (RBAC) groups. All groups which + * will be used for RBAC must be contained somewhere within the subtree of + * this DN. */ public static final StringGuacamoleProperty LDAP_GROUP_BASE_DN = new StringGuacamoleProperty() { From b9e0ce87eeeaa1a44ee8a3714b86f479ccfd63af Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 22 Jan 2016 08:31:06 -0800 Subject: [PATCH 4/6] GUAC-1388: Document null return of getGroupBaseDN(). --- .../glyptodon/guacamole/auth/ldap/ConfigurationService.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/ConfigurationService.java b/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/ConfigurationService.java index 62cd35e2b..83e8e8b23 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/ConfigurationService.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/ConfigurationService.java @@ -137,11 +137,12 @@ public class ConfigurationService { /** * Returns the base DN under which all Guacamole role based access control - * (RBAC) groups will be stored within the LDAP directory. + * (RBAC) groups will be stored within the LDAP directory. If RBAC will not + * be used, null is returned. * * @return * The base DN under which all Guacamole RBAC groups will be stored - * within the LDAP directory. + * within the LDAP directory, or null if RBAC will not be used. * * @throws GuacamoleException * If guacamole.properties cannot be parsed. From dabd093667a10276faf9292b853d773ab9025fc5 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 22 Jan 2016 08:36:43 -0800 Subject: [PATCH 5/6] GUAC-1388: Clarify documentation of getConnectionSearchFilter(). --- .../auth/ldap/connection/ConnectionService.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/connection/ConnectionService.java b/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/connection/ConnectionService.java index 886cb08f4..017bb65c4 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/connection/ConnectionService.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/glyptodon/guacamole/auth/ldap/connection/ConnectionService.java @@ -109,7 +109,8 @@ public class ConnectionService { // possibly be null assert(userDN != null); - // Get the search filter for finding connections associated to the userDN + // Get the search filter for finding connections accessible by the + // current user String connectionSearchFilter = getConnectionSearchFilter(userDN, ldapConnection); // Find all Guacamole connections for the given user by @@ -202,16 +203,19 @@ public class ConnectionService { } /** - * Returns the connection search filter for the given userDN. + * Returns an LDAP search filter which queries all connections accessible + * by the user having the given DN. * * @param userDN * DN of the user to search for associated guacConfigGroup connections. * * @param ldapConnection - * LDAP connection to use for searching for associated groups. + * LDAP connection to use if additional information must be queried to + * produce the filter, such as groups driving RBAC. * * @return - * Search filter for finding guacConfigGroup associated with the userDN. + * An LDAP search filter which queries all guacConfigGroup objects + * accessible by the user having the given DN. * * @throws LDAPException * If an error occurs preventing retrieval of user groups. From ceeb6a8be1e0a3d4634359862e1ec5d67fad87ec Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 22 Jan 2016 08:42:02 -0800 Subject: [PATCH 6/6] GUAC-1388: Correct ancient reference to our old Trac system. --- extensions/guacamole-auth-ldap/README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/guacamole-auth-ldap/README b/extensions/guacamole-auth-ldap/README index eb95aa4b0..345806cb0 100644 --- a/extensions/guacamole-auth-ldap/README +++ b/extensions/guacamole-auth-ldap/README @@ -96,8 +96,8 @@ guacamole.properties such that the authentication provider is available. Reporting problems ------------------------------------------------------------ -Please report any bugs encountered by opening a new ticket at the Trac system +Please report any bugs encountered by opening a new issue in the JIRA system hosted at: - http://guac-dev.org/trac/ + http://glyptodon.org/jira/