GUACAMOLE-954: Merge add LDAP support for nested user groups

This commit is contained in:
Virtually Nick authored and GitHub committed 2025-10-30 16:18:29 -05:00
commit 74e3b34442
7 files changed
+85 -3

No files matched your search

@@ -223,5 +223,10 @@ public class ConnectedLDAPConfiguration implements LDAPConfiguration, AutoClosea
public MemberAttributeType getMemberAttributeType() throws GuacamoleException {
return config.getMemberAttributeType();
}
@Override
public boolean getNestedGroups() throws GuacamoleException {
return config.getNestedGroups();
}
}
@@ -151,4 +151,9 @@ public class DefaultLDAPConfiguration implements LDAPConfiguration {
return MemberAttributeType.DN;
}
@Override
public boolean getNestedGroups() {
return false;
}
}
@@ -234,4 +234,12 @@ public class EnvironmentLDAPConfiguration implements LDAPConfiguration {
);
}
@Override
public boolean getNestedGroups() throws GuacamoleException {
return environment.getProperty(
LDAPGuacamoleProperties.LDAP_NESTED_GROUPS,
DEFAULT.getNestedGroups()
);
}
}
@@ -204,6 +204,13 @@ public class JacksonLDAPConfiguration implements LDAPConfiguration {
@JsonProperty("member-attribute-type")
private String memberAttributeType;
/**
* The raw YAML value of {@link LDAPGuacamoleProperties#LDAP_NESTED_GROUPS}.
* If not set within the YAML, this will be false.
*/
@JsonProperty("nested-groups")
private Boolean nestedGroups;
/**
* The default configuration options for all parameters.
*/
@@ -434,6 +441,11 @@ public class JacksonLDAPConfiguration implements LDAPConfiguration {
return withDefault(memberAttribute, defaultConfig::getMemberAttribute);
}
@Override
public boolean getNestedGroups() throws GuacamoleException {
return withDefault(nestedGroups, defaultConfig::getNestedGroups);
}
@Override
public MemberAttributeType getMemberAttributeType() throws GuacamoleException {
return withDefault(LDAPGuacamoleProperties.LDAP_MEMBER_ATTRIBUTE_TYPE,
@@ -334,4 +334,16 @@ public interface LDAPConfiguration {
*/
MemberAttributeType getMemberAttributeType() throws GuacamoleException;
/**
* Returns whether nested groups should be included in group membership.
*
* @return
* Whether to search in nested groups.
*
* @throws GuacamoleException
* If the configuration information determining whether nested
* groups should be used cannot be retrieved.
*/
boolean getNestedGroups() throws GuacamoleException;
}
@@ -307,4 +307,15 @@ public class LDAPGuacamoleProperties {
};
/**
* Whether or not to search nested groups.
*/
public static final BooleanGuacamoleProperty LDAP_NESTED_GROUPS =
new BooleanGuacamoleProperty() {
@Override
public String getName() { return "ldap-nested-groups"; }
};
}
@@ -27,10 +27,12 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.entry.Value;
import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
import org.apache.directory.api.ldap.model.filter.AndNode;
import org.apache.directory.api.ldap.model.filter.EqualityNode;
import org.apache.directory.api.ldap.model.filter.ExprNode;
import org.apache.directory.api.ldap.model.filter.ExtensibleNode;
import org.apache.directory.api.ldap.model.filter.NotNode;
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.guacamole.auth.ldap.conf.MemberAttributeType;
@@ -55,6 +57,11 @@ public class UserGroupService {
*/
private static final Logger logger = LoggerFactory.getLogger(UserGroupService.class);
/**
* Constant for nested LDAP group matching in Active Directory
*/
private final String LDAP_GROUP_NESTED_MATCHING_OID = "1.2.840.113556.1.4.1941";
/**
* Service for executing LDAP queries.
*/
@@ -227,14 +234,36 @@ public class UserGroupService {
groupAttributes.add(memberAttribute);
// Get all groups the user is a member of starting at the groupBaseDN,
// excluding guacConfigGroups
// excluding guacConfigGroups and evaluating nested groups
// (if enabled).
ExprNode groupFilter = config.getGroupSearchFilter();
String filterValue = userIDorDN;
if (config.getNestedGroups()) {
// Add support for nested groups using LDAP_MATCHING_RULE_IN_CHAIN
// (memberOf:1.2.840.113556.1.4.1941:=<UserDN>)
// Matching rule OID for LDAP_MATCHING_RULE_IN_CHAIN
// ** This possibly only supports Active Directory **
ExtensibleNode node = new ExtensibleNode("member");
filterValue = null;
// Explicitly set the matching rule ID and dnAttributes
node.setMatchingRuleId(LDAP_GROUP_NESTED_MATCHING_OID);
node.setDnAttributes(false);
node.setValue(new Value(userIDorDN));
groupFilter = new AndNode(
groupFilter, node
);
}
return queryService.search(
config,
config.getLDAPConnection(),
groupBaseDN,
getGroupSearchFilter(config),
groupFilter,
Collections.singleton(memberAttribute),
userIDorDN,
filterValue,
groupAttributes
);