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);
Matthias Lay
2016-Aug-02 12:32 UTC
[BUG] auth_bind with "()#<>"\:," in username not working
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:: cy5zY2htaWR0QHR0dC1wb2ludC5sb2NhbA0cn: Stefan Schmidt objectClass: person objectClass: inetOrgPerson userPassword:: aW5zZWN1cmUstructuralObjectClass: 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:: bS5tdWVsbGVyQHR0dC1wb2ludC5sb2NhbA0cn: Melanie Mueller objectClass: person objectClass: inetOrgPerson userPassword:: aW5zZWN1cmUstructuralObjectClass: 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:: a0BzcGRldi5sb2NhbA0cn: karl klammer objectClass: person objectClass: inetOrgPerson userPassword:: aW5zZWN1cmUstructuralObjectClass: 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:: Z0BzcGRldi5sb2NhbA0cn: v n objectClass: person objectClass: inetOrgPerson userPassword:: aW5zZWN1cmUstructuralObjectClass: 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:: aW5zZWN1cmUstructuralObjectClass: 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 <matthias.lay at securepoint.de> wrote:> 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); >
Matthias Lay
2016-Aug-02 12:37 UTC
[BUG] auth_bind with "()#<>"\:," in username not working
sorry forgot password for all test users is "insecure" and you?ll need the function in the header too diff --git a/src/auth/db-ldap.h b/src/auth/db-ldap.h index 8a51081..82ed1b3 100644 --- a/src/auth/db-ldap.h +++ b/src/auth/db-ldap.h @@ -197,6 +197,8 @@ void db_ldap_enable_input(struct ldap_connection *conn, bool enable); const char *ldap_escape(const char *str, const struct auth_request *auth_request); +const char *ldapdn_escape(const char *str, + const struct auth_request *auth_request); const char *ldap_get_error(struct ldap_connection *conn); struct db_ldap_result_iterate_context * On Tue, 2 Aug 2016 14:32:48 +0200 Matthias Lay <matthias.lay at securepoint.de> wrote:> 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 <matthias.lay at securepoint.de> wrote: > > > 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); > > > >-- Mit freundlichem Gru? / Best regards, Matthias Lay Head of UMA development Securepoint GmbH Salzstrasse 1 D-21335 L?neburg https://www.securepoint.de Tel.: +49(0)413124010 Fax: +49(0)4131240118 Gesch?ftsf?hrer: Lutz Hausmann, Claudia Hausmann Amtsgericht L?neburg HRB 1776 USt.-ID-Nr.: DE 188 528 597