From 8fa8a3657c8375adf9337659044d115f27ab4c39 Mon Sep 17 00:00:00 2001 From: HarveyKandola Date: Mon, 28 Oct 2019 15:03:53 +0000 Subject: [PATCH] Handle escaped comma in LDAP DN string Closes #326 --- domain/auth/ldap/ldap.go | 43 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/domain/auth/ldap/ldap.go b/domain/auth/ldap/ldap.go index d0e62f61..6b8c1eb3 100644 --- a/domain/auth/ldap/ldap.go +++ b/domain/auth/ldap/ldap.go @@ -172,9 +172,9 @@ func executeGroupFilter(c lm.LDAPConfig) (u []lm.LDAPUser, err error) { continue } + // Get CN element from DN. for _, entry := range rawMembers { - // get CN element from DN - parts := strings.Split(entry, ",") + parts := splitDN(entry) if len(parts) == 0 { continue } @@ -204,6 +204,45 @@ func executeGroupFilter(c lm.LDAPConfig) (u []lm.LDAPUser, err error) { return } +// splitDN handles splitting of DN string whilst respecting +// escaped comma characters. +// +// DN values can contain escaped commas like in two ways: +// +// \, +// \\5c, +// +// Relevant notes: + +// https://docs.oracle.com/cd/E19424-01/820-4811/gdxpo/index.html#6ng8i269q +// https://devblogs.microsoft.com/scripting/how-can-i-work-with-a-cn-that-has-a-comma-in-it/ +// +// Example: + +// CN=Surname\, Name,OU=Something,OU=AD-Example,OU=Examaple,DC=example,DC=example,DC=com +// +// When we split on comma, here is our logic: +// +// 1. We replace any escaped comma values with a special character sequence, in this case !?! +// 2. We string.split on comma as per usual. +// 3. We put back the original escaped comma values. +func splitDN(dn string) []string { + var r string + r = strings.ReplaceAll(dn, "\\5c,", "!!1!!") + r = strings.ReplaceAll(dn, "\\,", "!!2!!") + + sp := strings.Split(r, ",") + + for i := range sp { + val := sp[i] + r2 := strings.ReplaceAll(val, "!!1!!", "\\5c,") + r2 = strings.ReplaceAll(val, "!!2!!", "\\,") + sp[i] = r2 + } + + return sp +} + // extractUser build user record from LDAP result attributes. func extractUser(c lm.LDAPConfig, e *ld.Entry) (u lm.LDAPUser) { u.Firstname = e.GetAttributeValue(c.AttributeUserFirstname)