From ac03060e7ef1b1af95df1193efad1114c01d1152 Mon Sep 17 00:00:00 2001 From: Sivarajan Narayanan Date: Fri, 30 May 2025 11:32:47 +0530 Subject: [PATCH 1/6] fix ldap group filter for OpenDirectory --- .../mysql/authenticate/ldap/LdapClient.java | 61 ++++++++++++------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java index 3ae96945296942..893447bc2ab263 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java @@ -156,32 +156,51 @@ boolean checkPassword(String userName, String password) { List getGroups(String userName) { List groups = Lists.newArrayList(); if (LdapConfig.ldap_group_basedn.isEmpty()) { + LOG.debug("Group base DN is empty"); return groups; } - String userDn = getUserDn(userName); - if (userDn == null) { - return groups; - } - List groupDns; - // Support Open Directory implementations - // If no group filter is configured, it defaults to querying groups based on the attribute 'member' - // for standard LDAP implementations + List groupDns; if (!LdapConfig.ldap_group_filter.isEmpty()) { - groupDns = getDn(org.springframework.ldap.query.LdapQueryBuilder.query() + // Support Open Directory implementations + String filter = LdapConfig.ldap_group_filter.replace("{login}", userName); + LOG.debug("Using group filter: {} with base DN: {}", filter, LdapConfig.ldap_group_basedn); + + LdapQuery query = org.springframework.ldap.query.LdapQueryBuilder.query() + .attributes("dn") .base(LdapConfig.ldap_group_basedn) - .filter(getGroupFilter(LdapConfig.ldap_group_filter, userName))); + .filter(filter); + + groupDns = getDn(query); + + if (groupDns == null || groupDns.isEmpty()) { + LOG.debug("No groups found for user: {} using filter: {}", userName, filter); + return groups; + } } else { - groupDns = getDn(org.springframework.ldap.query.LdapQueryBuilder.query() + // Standard LDAP using member attribute + String userDn = getUserDn(userName); + if (userDn == null) { + LOG.debug("User DN not found for user: {}", userName); + return groups; + } + LOG.debug("Using standard LDAP member attribute with userDn: {}", userDn); + + LdapQuery query = org.springframework.ldap.query.LdapQueryBuilder.query() + .attributes("dn") .base(LdapConfig.ldap_group_basedn) - .where("member").is(userDn)); + .where("member").is(userDn); + + groupDns = getDn(query); } - if (groupDns == null) { + if (groupDns == null || groupDns.isEmpty()) { + LOG.debug("No groups found for user: {}", userName); return groups; } - // group dn like: 'cn=groupName,ou=groups,dc=example,dc=com', we only need the groupName. + LOG.debug("Found {} group DNs", groupDns.size()); + // Extract just the group name from DN for (String dn : groupDns) { String[] strings = dn.split("[,=]", 3); if (strings.length > 2) { @@ -209,11 +228,12 @@ private String getUserDn(String userName) { private List getDn(LdapQuery query) { init(); try { - return clientInfo.getLdapTemplatePool().search(query, new AbstractContextMapper() { - protected String doMapFromContext(DirContextOperations ctx) { - return ctx.getNameInNamespace(); - } - }); + return clientInfo.getLdapTemplatePool().search(query, + new AbstractContextMapper() { + protected String doMapFromContext(DirContextOperations ctx) { + return ctx.getNameInNamespace(); + } + }); } catch (Exception e) { LOG.error("Get user dn fail.", e); ErrorReport.report(ErrorCode.ERROR_LDAP_CONFIGURATION_ERR); @@ -225,7 +245,4 @@ private String getUserFilter(String userFilter, String userName) { return userFilter.replaceAll("\\{login}", userName); } - private String getGroupFilter(String groupFilter, String userName) { - return groupFilter.replaceAll("\\{login}", userName); - } } From 9ae4d3a4fe444608d89845916837df0db2369b29 Mon Sep 17 00:00:00 2001 From: Sivarajan Narayanan Date: Thu, 10 Jul 2025 11:47:28 +0530 Subject: [PATCH 2/6] fixed syntax and ldap dn attribute --- .../mysql/authenticate/ldap/LdapClient.java | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java index 893447bc2ab263..ee745de7bcc9e8 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java @@ -112,7 +112,7 @@ public boolean checkUpdate(String ldapPassword) { private void init() { LdapInfo ldapInfo = Env.getCurrentEnv().getAuth().getLdapInfo(); if (ldapInfo == null || !ldapInfo.isValid()) { - LOG.error("info is null, maybe no ldap admin password is set."); + LOG.error("LDAP info is null or invalid, LDAP admin password may not be set"); ErrorReport.report(ErrorCode.ERROR_LDAP_CONFIGURATION_ERR); throw new RuntimeException("ldapTemplate is not initialized"); } @@ -165,12 +165,12 @@ List getGroups(String userName) { // Support Open Directory implementations String filter = LdapConfig.ldap_group_filter.replace("{login}", userName); LOG.debug("Using group filter: {} with base DN: {}", filter, LdapConfig.ldap_group_basedn); - + LdapQuery query = org.springframework.ldap.query.LdapQueryBuilder.query() - .attributes("dn") - .base(LdapConfig.ldap_group_basedn) - .filter(filter); - + .attributes("dn") + .base(LdapConfig.ldap_group_basedn) + .filter(filter); + groupDns = getDn(query); if (groupDns == null || groupDns.isEmpty()) { @@ -185,12 +185,11 @@ List getGroups(String userName) { return groups; } LOG.debug("Using standard LDAP member attribute with userDn: {}", userDn); - + LdapQuery query = org.springframework.ldap.query.LdapQueryBuilder.query() - .attributes("dn") - .base(LdapConfig.ldap_group_basedn) - .where("member").is(userDn); - + .base(LdapConfig.ldap_group_basedn) + .where("member").is(userDn); + groupDns = getDn(query); } @@ -228,12 +227,12 @@ private String getUserDn(String userName) { private List getDn(LdapQuery query) { init(); try { - return clientInfo.getLdapTemplatePool().search(query, - new AbstractContextMapper() { - protected String doMapFromContext(DirContextOperations ctx) { - return ctx.getNameInNamespace(); - } - }); + return clientInfo.getLdapTemplatePool().search(query, + new AbstractContextMapper() { + protected String doMapFromContext(DirContextOperations ctx) { + return ctx.getNameInNamespace(); + } + }); } catch (Exception e) { LOG.error("Get user dn fail.", e); ErrorReport.report(ErrorCode.ERROR_LDAP_CONFIGURATION_ERR); @@ -244,5 +243,11 @@ protected String doMapFromContext(DirContextOperations ctx) { private String getUserFilter(String userFilter, String userName) { return userFilter.replaceAll("\\{login}", userName); } - } + + + + + + + From 6028bc43cc291cf17b428a2bcbfaba347dfe0c36 Mon Sep 17 00:00:00 2001 From: Sivarajan Narayanan Date: Mon, 14 Jul 2025 21:02:30 +0530 Subject: [PATCH 3/6] PR review comments --- .../org/apache/doris/mysql/authenticate/ldap/LdapClient.java | 1 - 1 file changed, 1 deletion(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java index ee745de7bcc9e8..3e60b5348ce0ec 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java @@ -250,4 +250,3 @@ private String getUserFilter(String userFilter, String userName) { - From a8388f07edfa3e2e4103b421dfad5414b0abf86f Mon Sep 17 00:00:00 2001 From: Sivarajan Narayanan Date: Mon, 14 Jul 2025 21:03:55 +0530 Subject: [PATCH 4/6] PR review comments --- .../apache/doris/mysql/authenticate/ldap/LdapClient.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java index 3e60b5348ce0ec..ddb9f10372cce8 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java @@ -243,10 +243,4 @@ protected String doMapFromContext(DirContextOperations ctx) { private String getUserFilter(String userFilter, String userName) { return userFilter.replaceAll("\\{login}", userName); } -} - - - - - - +} \ No newline at end of file From 4235652c28c68ae098ce50b83bb06f6c96a5e4e2 Mon Sep 17 00:00:00 2001 From: Sivarajan Narayanan Date: Tue, 15 Jul 2025 20:11:03 +0530 Subject: [PATCH 5/6] fix review comments --- .../mysql/authenticate/ldap/LdapClient.java | 38 +++++-------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java index ddb9f10372cce8..a2fe3670d2e585 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java @@ -156,50 +156,32 @@ boolean checkPassword(String userName, String password) { List getGroups(String userName) { List groups = Lists.newArrayList(); if (LdapConfig.ldap_group_basedn.isEmpty()) { - LOG.debug("Group base DN is empty"); return groups; } - + String userDn = getUserDn(userName); + if (userDn == null) { + return groups; + } List groupDns; if (!LdapConfig.ldap_group_filter.isEmpty()) { // Support Open Directory implementations String filter = LdapConfig.ldap_group_filter.replace("{login}", userName); - LOG.debug("Using group filter: {} with base DN: {}", filter, LdapConfig.ldap_group_basedn); - - LdapQuery query = org.springframework.ldap.query.LdapQueryBuilder.query() + groupDns = getDn(org.springframework.ldap.query.LdapQueryBuilder.query() .attributes("dn") .base(LdapConfig.ldap_group_basedn) - .filter(filter); - - groupDns = getDn(query); - - if (groupDns == null || groupDns.isEmpty()) { - LOG.debug("No groups found for user: {} using filter: {}", userName, filter); - return groups; - } + .filter(filter)); } else { // Standard LDAP using member attribute - String userDn = getUserDn(userName); - if (userDn == null) { - LOG.debug("User DN not found for user: {}", userName); - return groups; - } - LOG.debug("Using standard LDAP member attribute with userDn: {}", userDn); - - LdapQuery query = org.springframework.ldap.query.LdapQueryBuilder.query() + groupDns = getDn(org.springframework.ldap.query.LdapQueryBuilder.query() .base(LdapConfig.ldap_group_basedn) - .where("member").is(userDn); - - groupDns = getDn(query); + .where("member").is(userDn)); } - if (groupDns == null || groupDns.isEmpty()) { - LOG.debug("No groups found for user: {}", userName); + if (groupDns == null) { return groups; } - LOG.debug("Found {} group DNs", groupDns.size()); - // Extract just the group name from DN + // group dn like: 'cn=groupName,ou=groups,dc=example,dc=com', we only need the groupName. for (String dn : groupDns) { String[] strings = dn.split("[,=]", 3); if (strings.length > 2) { From 2885c38cfc0a11085709371b3446cc898d32add7 Mon Sep 17 00:00:00 2001 From: Sivarajan Narayanan Date: Tue, 5 Aug 2025 19:38:20 +0530 Subject: [PATCH 6/6] fix styles --- .../org/apache/doris/mysql/authenticate/ldap/LdapClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java index a2fe3670d2e585..1186469a1ec822 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapClient.java @@ -225,4 +225,4 @@ protected String doMapFromContext(DirContextOperations ctx) { private String getUserFilter(String userFilter, String userName) { return userFilter.replaceAll("\\{login}", userName); } -} \ No newline at end of file +}