diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/ConfigurationService.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/ConfigurationService.java index a13eb9715..f0988a741 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/ConfigurationService.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/ConfigurationService.java @@ -20,16 +20,24 @@ package org.apache.guacamole.auth.ldap; import com.google.inject.Inject; +import com.novell.ldap.LDAPSearchConstraints; import java.util.Collections; import java.util.List; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.environment.Environment; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Service for retrieving configuration information regarding the LDAP server. */ public class ConfigurationService { + /** + * Logger for this class. + */ + private final Logger logger = LoggerFactory.getLogger(ConfigurationService.class); + /** * The Guacamole server environment. */ @@ -216,11 +224,53 @@ public class ConfigurationService { * @throws GuacamoleException * If guacamole.properties cannot be parsed. */ - public int getMaxResults() throws GuacamoleException { + private int getMaxResults() throws GuacamoleException { return environment.getProperty( LDAPGuacamoleProperties.LDAP_MAX_SEARCH_RESULTS, 1000 ); } + /** + * Returns whether or not LDAP aliases will be dereferenced, + * as configured with guacamole.properties. The default + * behavior if not explicitly defined is to never + * dereference them. + * + * @return + * The behavior for handling dereferencing of aliases + * as configured in guacamole.properties. + * + * @throws GuacamoleException + * If guacamole.properties cannot be parsed. + */ + private DereferenceAliasesMode getDereferenceAliases() throws GuacamoleException { + return environment.getProperty( + LDAPGuacamoleProperties.LDAP_DEREFERENCE_ALIASES, + DereferenceAliasesMode.NEVER + ); + } + + /** + * Returns a set of LDAPSearchConstraints to apply globally + * to all LDAP searches. + * + * @return + * A LDAPSearchConstraints object containing constraints + * to be applied to all LDAP search operations. + * + * @throws GuacamoleException + * If guacamole.properties cannot be parsed. + */ + public LDAPSearchConstraints getLDAPSearchConstraints() throws GuacamoleException { + + LDAPSearchConstraints constraints = new LDAPSearchConstraints(); + + constraints.setMaxResults(getMaxResults()); + constraints.setDereference(getDereferenceAliases().DEREF_VALUE); + + return constraints; + + } + } diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/DereferenceAliasesMode.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/DereferenceAliasesMode.java new file mode 100644 index 000000000..1fd1bea41 --- /dev/null +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/DereferenceAliasesMode.java @@ -0,0 +1,74 @@ +/* + * 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; + +import com.novell.ldap.LDAPSearchConstraints; + +/** + * Data type that handles acceptable values for configuring + * alias dereferencing behavior when querying LDAP servers. + */ +public enum DereferenceAliasesMode { + + /** + * Never dereference aliases. This is the default. + */ + NEVER(LDAPSearchConstraints.DEREF_NEVER), + + /** + * Aliases are dereferenced below the base object, but not to locate + * the base object itself. So, if the base object is itself an alias + * the search will not complete. + */ + SEARCHING(LDAPSearchConstraints.DEREF_SEARCHING), + + /** + * Aliases are only dereferenced to locate the base object, but not + * after that. So, a search against a base object that is an alias will + * find any subordinates of the real object the alias references, but + * further aliases in the search will not be dereferenced. + */ + FINDING(LDAPSearchConstraints.DEREF_FINDING), + + /** + * Aliases will always be dereferenced, both to locate the base object + * and when handling results returned by the search. + */ + ALWAYS(LDAPSearchConstraints.DEREF_ALWAYS); + + /** + * The integer constant as defined in the JLDAP library that + * the LDAPSearchConstraints class uses to define the + * dereferencing behavior during search operations. + */ + public final int DEREF_VALUE; + + /** + * Initializes the dereference aliases object with the integer + * value the setting maps to per the JLDAP implementation. + * + * @param derefValue + * The value associated with this dereference setting + */ + private DereferenceAliasesMode(int derefValue) { + this.DEREF_VALUE = derefValue; + } + +} diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/DereferenceAliasesProperty.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/DereferenceAliasesProperty.java new file mode 100644 index 000000000..60b89c4b6 --- /dev/null +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/DereferenceAliasesProperty.java @@ -0,0 +1,61 @@ +/* + * 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; + +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.GuacamoleServerException; +import org.apache.guacamole.properties.GuacamoleProperty; + +/** + * A GuacamoleProperty with a value of DereferenceAliases. The possible strings + * "never", "searching", "finding", and "always" are mapped to their values as a + * DereferenceAliases enum. Anything else results in a parse error. + */ +public abstract class DereferenceAliasesProperty implements GuacamoleProperty { + + @Override + public DereferenceAliasesMode parseValue(String value) throws GuacamoleException { + + // No value provided, so return null. + if (value == null) + return null; + + // Never dereference aliases + if (value.equals("never")) + return DereferenceAliasesMode.NEVER; + + // Dereference aliases during search operations, but not at base + if (value.equals("searching")) + return DereferenceAliasesMode.SEARCHING; + + // Dereference aliases to locate base, but not during searches + if (value.equals("finding")) + return DereferenceAliasesMode.FINDING; + + // Always dereference aliases + if (value.equals("always")) + return DereferenceAliasesMode.ALWAYS; + + // Anything else is invalid and results in an error + throw new GuacamoleServerException("Dereference aliases must be one of \"never\", \"searching\", \"finding\", or \"always\"."); + + } + +} diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/LDAPGuacamoleProperties.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/LDAPGuacamoleProperties.java index bc684e32c..266af8e93 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/LDAPGuacamoleProperties.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/LDAPGuacamoleProperties.java @@ -153,4 +153,15 @@ public class LDAPGuacamoleProperties { }; + /** + * Property that controls whether or not the LDAP connection follows + * (dereferences) aliases as it searches the tree. + */ + public static final DereferenceAliasesProperty LDAP_DEREFERENCE_ALIASES = new DereferenceAliasesProperty() { + + @Override + public String getName() { return "ldap-dereference-aliases"; } + + }; + } diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/connection/ConnectionService.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/connection/ConnectionService.java index b13207a15..d256ebb3b 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/connection/ConnectionService.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/connection/ConnectionService.java @@ -117,7 +117,8 @@ public class ConnectionService { LDAPConnection.SCOPE_SUB, connectionSearchFilter, null, - false + false, + confService.getLDAPSearchConstraints() ); // Build token filter containing credential tokens @@ -240,7 +241,8 @@ public class ConnectionService { LDAPConnection.SCOPE_SUB, "(&(!(objectClass=guacConfigGroup))(member=" + escapingService.escapeLDAPSearchFilter(userDN) + "))", null, - false + false, + confService.getLDAPSearchConstraints() ); // Append the additional user groups to the LDAP filter diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserService.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserService.java index cae1599ef..f7c571678 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserService.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserService.java @@ -25,7 +25,6 @@ import com.novell.ldap.LDAPConnection; import com.novell.ldap.LDAPEntry; import com.novell.ldap.LDAPException; import com.novell.ldap.LDAPSearchResults; -import com.novell.ldap.LDAPSearchConstraints; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -85,9 +84,6 @@ public class UserService { String usernameAttribute) throws GuacamoleException { try { - // Set search limits - LDAPSearchConstraints constraints = new LDAPSearchConstraints(); - constraints.setMaxResults(confService.getMaxResults()); // Find all Guacamole users underneath base DN LDAPSearchResults results = ldapConnection.search( @@ -96,7 +92,7 @@ public class UserService { "(&(objectClass=*)(" + escapingService.escapeLDAPSearchFilter(usernameAttribute) + "=*))", null, false, - constraints + confService.getLDAPSearchConstraints() ); // Read all visible users @@ -254,7 +250,8 @@ public class UserService { LDAPConnection.SCOPE_SUB, generateLDAPQuery(username), null, - false + false, + confService.getLDAPSearchConstraints() ); // Add all DNs for found users