Hi once again, replying to myself
I think I tracked down the problem with a local openldap server.
IMO the point is, you are using a ldap search escaping for a DN Request
which needs another kind of escaping.
the '(' worked well with my NULL-Patch because '(' is a char that needs
escaping for a search filter but not for DN.
I experienced some more problems with users containing a '+', '<' for
example. so I googled a bit and found this one.
http://www.openldap.org/lists/openldap-software/200407/msg00722.html
So you might be missing (or I didnt find it) a special DN escaping
function. I added one in the following patch and all the special chars
seems to work find in the bind AND search requests.
diff --git a/src/auth/db-ldap.c b/src/auth/db-ldap.c
index 1476fa9..e9218ca 100644
--- a/src/auth/db-ldap.c
+++ b/src/auth/db-ldap.c
@@ -1423,6 +1422,35 @@ db_ldap_value_get_var_expand_table(struct
auth_request *auth_request, return table;
}
+
+#define IS_LDAPDN_ESCAPED_CHAR(c) \
+ ((c) == '"' || (c) == '+' || (c) == ',' || (c) == '\\' || (c)
== '<' || (c) == '>' || (c) == ';') +
+const char *ldapdn_escape(const char *str,
+ const struct auth_request *auth_request
ATTR_UNUSED) +{
+ const char *p;
+ string_t *ret;
+
+ for (p = str; *p != '\0'; p++) {
+ if (IS_LDAPDN_ESCAPED_CHAR(*p))
+ break;
+ }
+
+ if (*p == '\0')
+ return str;
+
+ ret = t_str_new((size_t) (p - str) + 64);
+ str_append_n(ret, str, (size_t) (p - str));
+
+ for (; *p != '\0'; p++) {
+ if (IS_LDAPDN_ESCAPED_CHAR(*p))
+ str_append_c(ret, '\\');
+ str_append_c(ret, *p);
+ }
+ return str_c(ret);
+}
+
#define IS_LDAP_ESCAPED_CHAR(c) \
((c) == '*' || (c) == '(' || (c) == ')' || (c) == '\\')
diff --git a/src/auth/passdb-ldap.c b/src/auth/passdb-ldap.c
index c1c2544..5629d85 100644
--- a/src/auth/passdb-ldap.c
+++ b/src/auth/passdb-ldap.c
@@ -367,7 +374,7 @@ ldap_verify_plain_auth_bind_userdn(struct
auth_request *auth_request,
brequest->request.type = LDAP_REQUEST_TYPE_BIND;
- vars = auth_request_get_var_expand_table(auth_request,
ldap_escape);
+ vars = auth_request_get_var_expand_table(auth_request,
ldapdn_escape);
dn = t_str_new(512);
var_expand(dn, conn->set.auth_bind_userdn, vars);
an ldif file for testing.
add them with
# slapadd -l filename
# cat user.ldif
dn: dc=uma,dc=local
dc: uma
objectClass: dcObject
objectClass: domain
structuralObjectClass: domain
entryUUID: 5cdda309-7ad5-4b03-b981-784c1b7ec27e
creatorsName: cn=admin,dc=uma,dc=local
createTimestamp: 20160729231019Z
entryCSN: 20160729231019.057480Z#000000#000#000000
modifiersName: cn=admin,dc=uma,dc=local
modifyTimestamp: 20160729231019Z
dn: ou=users,dc=uma,dc=local
ou: users
objectClass: organizationalUnit
structuralObjectClass: organizationalUnit
entryUUID: cc56753d-09aa-404a-8446-5d0bf75531a3
creatorsName: cn=admin,dc=uma,dc=local
createTimestamp: 20160729231019Z
entryCSN: 20160729231019.147739Z#000000#000#000000
modifiersName: cn=admin,dc=uma,dc=local
modifyTimestamp: 20160729231019Z
dn: uid=s\+schmidt,ou=users,dc=uma,dc=local
givenName: Stefan
uid: s+schmidt
sn: Schmidt
mail:: cy5zY2htaWR0QHR0dC1wb2ludC5sb2NhbA0=
cn: Stefan Schmidt
objectClass: person
objectClass: inetOrgPerson
userPassword:: aW5zZWN1cmU=
structuralObjectClass: inetOrgPerson
entryUUID: fffad6fe-d083-4ab9-b6c2-da82067d510b
creatorsName: cn=admin,dc=uma,dc=local
createTimestamp: 20160729231039Z
entryCSN: 20160729231039.234641Z#000000#000#000000
modifiersName: cn=admin,dc=uma,dc=local
modifyTimestamp: 20160729231039Z
dn: uid=m\\mueller,ou=users,dc=uma,dc=local
givenName: Melanie
uid: m\mueller
sn: Mueller
mail:: bS5tdWVsbGVyQHR0dC1wb2ludC5sb2NhbA0=
cn: Melanie Mueller
objectClass: person
objectClass: inetOrgPerson
userPassword:: aW5zZWN1cmU=
structuralObjectClass: inetOrgPerson
entryUUID: 6e1a3a14-dd75-4766-a308-44a8437a0139
creatorsName: cn=admin,dc=uma,dc=local
createTimestamp: 20160729231039Z
entryCSN: 20160729231039.308360Z#000000#000#000000
modifiersName: cn=admin,dc=uma,dc=local
modifyTimestamp: 20160729231039Z
dn: uid=k(lammer,ou=users,dc=uma,dc=local
givenName: karl
uid: k(lammer
sn: klammer
mail:: a0BzcGRldi5sb2NhbA0=
cn: karl klammer
objectClass: person
objectClass: inetOrgPerson
userPassword:: aW5zZWN1cmU=
structuralObjectClass: inetOrgPerson
entryUUID: b5a26caf-62b1-4cf5-985c-3167424d90c7
creatorsName: cn=admin,dc=uma,dc=local
createTimestamp: 20160729231039Z
entryCSN: 20160729231039.315462Z#000000#000#000000
modifiersName: cn=admin,dc=uma,dc=local
modifyTimestamp: 20160729231039Z
dn: uid=g\>ross,ou=users,dc=uma,dc=local
givenName: v
uid: g>ross
sn: n
mail:: Z0BzcGRldi5sb2NhbA0=
cn: v n
objectClass: person
objectClass: inetOrgPerson
userPassword:: aW5zZWN1cmU=
structuralObjectClass: inetOrgPerson
entryUUID: fb7ad7cc-a028-444c-8109-cfe9dd182b0b
creatorsName: cn=admin,dc=uma,dc=local
createTimestamp: 20160729231039Z
entryCSN: 20160729231039.364040Z#000000#000#000000
modifiersName: cn=admin,dc=uma,dc=local
modifyTimestamp: 20160729231039Z
dn: uid=mmeier,ou=users,dc=uma,dc=local
givenName: Manfred
uid: mmeier
sn: Meier
mail:: bS5tZWllckB0dHQtcG9pbnQubG9jYWwN
cn: Manfred Meier
objectClass: person
objectClass: inetOrgPerson
userPassword:: aW5zZWN1cmU=
structuralObjectClass: inetOrgPerson
entryUUID: 16ef0511-25ed-4001-a1bd-1ad72abbfc02
creatorsName: cn=admin,dc=uma,dc=local
createTimestamp: 20160729231039Z
entryCSN: 20160729231039.369003Z#000000#000#000000
modifiersName: cn=admin,dc=uma,dc=local
modifyTimestamp: 20160729231039Z
Greetz
On Tue, 26 Jul 2016 13:07:24 +0200
Matthias Lay
Hi guys,
I had a look in the sources about this problem.
the problem seems to be the ldap_escape function that is called from
ldap_verify_plain_auth_bind_userdn(..)
I dont really know if this escaping is needed at this point, but with this change it works for me. No other problems discovered so far.
could somebody, who is deeper in the sources give me a hint if this will make some troubles?
Patch for 2.2.16:
diff --git a/src/auth/passdb-ldap.c b/src/auth/passdb-ldap.c index c1c2544..10bfe20 100644 --- a/src/auth/passdb-ldap.c +++ b/src/auth/passdb-ldap.c @@ -367,7 +367,7 @@ ldap_verify_plain_auth_bind_userdn(struct auth_request *auth_request, brequest->request.type = LDAP_REQUEST_TYPE_BIND;
- vars = auth_request_get_var_expand_table(auth_request, ldap_escape); + vars = auth_request_get_var_expand_table(auth_request, NULL); dn = t_str_new(512); var_expand(dn, conn->set.auth_bind_userdn, vars);