Allow users, roles, and groups, to be created in a specified DN relative to the parent DN

The new field introduced will prefix the parent DN as a relative path and allow created items to be placed in a subtree instead of the parent DN.

Closes #28569

Signed-off-by: Jakob Overrein <jakob.overrein@basefarm-orange.com>
This commit is contained in:
Jakob Overrein 2025-02-04 14:21:24 +01:00 committed by Pedro Igor
parent 6720c2b29c
commit aec62803c7
12 changed files with 50 additions and 3 deletions

View File

@ -79,6 +79,14 @@ public class LDAPConfig {
return usersDn;
}
public String getRelativeCreateDn() {
String relativeCreateDn = config.getFirst(LDAPConstants.RELATIVE_CREATE_DN);
if(relativeCreateDn != null) {
return relativeCreateDn + ",";
}
return "";
}
public String getBaseDn() {
return config.getFirst(LDAPConstants.BASE_DN);
}

View File

@ -137,6 +137,9 @@ public class LDAPStorageProviderFactory implements UserStorageProviderFactory<LD
.property().name(LDAPConstants.USERS_DN)
.type(ProviderConfigProperty.STRING_TYPE)
.add()
.property().name(LDAPConstants.RELATIVE_CREATE_DN)
.type(ProviderConfigProperty.STRING_TYPE)
.add()
.property().name(LDAPConstants.AUTH_TYPE)
.type(ProviderConfigProperty.STRING_TYPE)
.defaultValue("simple")

View File

@ -165,7 +165,7 @@ public class LDAPUtils {
throw new ModelException("RDN Attribute [" + rdnLdapAttrName + "] is not filled. Filled attributes: " + ldapUser.getAttributes());
}
LDAPDn dn = LDAPDn.fromString(config.getUsersDn());
LDAPDn dn = LDAPDn.fromString(config.getRelativeCreateDn() + config.getUsersDn());
dn.addFirst(rdnLdapAttrName, rdnLdapAttrValue);
ldapUser.setDn(dn);
}

View File

@ -127,7 +127,7 @@ public class GroupLDAPStorageMapper extends AbstractLDAPStorageMapper implements
public LDAPObject createLDAPGroup(String groupName, Map<String, Set<String>> additionalAttributes) {
LDAPObject ldapGroup = LDAPUtils.createLDAPGroup(ldapProvider, groupName, config.getGroupNameLdapAttribute(), config.getGroupObjectClasses(ldapProvider),
config.getGroupsDn(), additionalAttributes, config.getMembershipLdapAttribute());
config.getRelativeCreateDn() + config.getGroupsDn(), additionalAttributes, config.getMembershipLdapAttribute());
logger.debugf("Creating group [%s] to LDAP with DN [%s]", groupName, ldapGroup.getDn().toString());
return ldapGroup;

View File

@ -98,6 +98,11 @@ public class GroupLDAPStorageMapperFactory extends AbstractLDAPStorageMapperFact
.type(ProviderConfigProperty.STRING_TYPE)
.required(true)
.add()
.property().name(GroupMapperConfig.GROUPS_RELATIVE_CREATE_DN)
.label("Relative creation DN")
.helpText("LDAP DN where are groups of this tree will be created relative to the 'LDAP Groups DN' ")
.type(ProviderConfigProperty.STRING_TYPE)
.add()
.property().name(GroupMapperConfig.GROUP_NAME_LDAP_ATTRIBUTE)
.label("Group Name LDAP Attribute")
.helpText("Name of LDAP attribute, which is used in group objects for name and RDN of group. Usually it will be 'cn' . In this case typical group/role object may have DN like 'cn=Group1,ou=groups,dc=example,dc=org' ")

View File

@ -35,6 +35,7 @@ public class GroupMapperConfig extends CommonLDAPGroupMapperConfig {
// LDAP DN where are groups of this tree saved.
public static final String GROUPS_DN = "groups.dn";
public static final String GROUPS_RELATIVE_CREATE_DN = "groups.relative.create.dn";
// Name of LDAP attribute, which is used in group objects for name and RDN of group. Usually it will be "cn"
public static final String GROUP_NAME_LDAP_ATTRIBUTE = "group.name.ldap.attribute";
@ -79,6 +80,14 @@ public class GroupMapperConfig extends CommonLDAPGroupMapperConfig {
return groupsDn;
}
public String getRelativeCreateDn() {
String relativeCreateDn = mapperModel.getConfig().getFirst(GROUPS_RELATIVE_CREATE_DN);
if(relativeCreateDn != null) {
return relativeCreateDn + ",";
}
return "";
}
@Override
public String getLDAPGroupsDn() {
return getGroupsDn();

View File

@ -266,7 +266,7 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements
public LDAPObject createLDAPRole(String roleName) {
LDAPObject ldapRole = LDAPUtils.createLDAPGroup(ldapProvider, roleName, config.getRoleNameLdapAttribute(), config.getRoleObjectClasses(ldapProvider),
config.getRolesDn(), Collections.<String, Set<String>>emptyMap(), config.getMembershipLdapAttribute());
config.getRelativeCreateDn() + config.getRolesDn(), Collections.<String, Set<String>>emptyMap(), config.getMembershipLdapAttribute());
logger.debugf("Creating role [%s] to LDAP with DN [%s]", roleName, ldapRole.getDn().toString());
return ldapRole;

View File

@ -96,6 +96,11 @@ public class RoleLDAPStorageMapperFactory extends AbstractLDAPStorageMapperFacto
.type(ProviderConfigProperty.STRING_TYPE)
.required(true)
.add()
.property().name(RoleMapperConfig.ROLES_RELATIVE_CREATE_DN)
.label("Relative creation DN")
.helpText("LDAP DN where are roles of this tree will be created relative to the 'LDAP Roles DN' ")
.type(ProviderConfigProperty.STRING_TYPE)
.add()
.property().name(RoleMapperConfig.ROLE_NAME_LDAP_ATTRIBUTE)
.label("Role Name LDAP Attribute")
.helpText("Name of LDAP attribute, which is used in role objects for name and RDN of role. Usually it will be 'cn' . In this case typical group/role object may have DN like 'cn=role1,ou=finance,dc=example,dc=org' ")

View File

@ -32,6 +32,7 @@ public class RoleMapperConfig extends CommonLDAPGroupMapperConfig {
// LDAP DN where are roles of this tree saved.
public static final String ROLES_DN = "roles.dn";
public static final String ROLES_RELATIVE_CREATE_DN = "roles.relative.create.dn";
// Name of LDAP attribute, which is used in role objects for name and RDN of role. Usually it will be "cn"
public static final String ROLE_NAME_LDAP_ATTRIBUTE = "role.name.ldap.attribute";
@ -66,6 +67,14 @@ public class RoleMapperConfig extends CommonLDAPGroupMapperConfig {
return rolesDn;
}
public String getRelativeCreateDn() {
String relativeCreateDn = mapperModel.getConfig().getFirst(ROLES_RELATIVE_CREATE_DN);
if(relativeCreateDn != null) {
return relativeCreateDn + ",";
}
return "";
}
@Override
public String getLDAPGroupsDn() {
return getRolesDn();

View File

@ -674,6 +674,8 @@ certSubject=CERT_SUBJECT
userCredentialsHelpText=The top level handlers allow you to shift the priority of the credential for the user, the topmost credential having the highest priority. The handlers within one expandable panel allow you to change the visual order of the credentials, the topmost credential will show at the most left.
ldapAdvancedSettingsDescription=This section contains all the other options for more fine-grained configuration of the LDAP storage provider.
usersDN=Users DN
relativeUserCreateDn=Relative user creation DN
relativeUserCreateDnHelp=Relative DN from the 'Users DN' to where users will be created. For example, this allows users to be created in other DN than the parent 'Users DN' when using a subtree search scope.
secretSize=Secret size
included.custom.audience.label=Included Custom Audience
max-clients.label=Max Clients Per Realm

View File

@ -54,6 +54,11 @@ export const LdapSettingsSearching = ({
required: t("validateUsersDn"),
}}
/>
<TextControl
name="config.relativeCreateDn.0"
label={t("relativeUserCreateDn")}
labelIcon={t("relativeUserCreateDnHelp")}
/>
<TextControl
name="config.usernameLDAPAttribute.0"
label={t("usernameLdapAttribute")}

View File

@ -48,6 +48,7 @@ public class LDAPConstants {
public static final String CONNECTION_URL = "connectionUrl";
public static final String BASE_DN = "baseDn"; // used for tests only
public static final String USERS_DN = "usersDn";
public static final String RELATIVE_CREATE_DN = "relativeCreateDn";
public static final String BIND_DN = "bindDn";
public static final String BIND_CREDENTIAL = "bindCredential";