svarshavchik / courier

Courier Mail Server
http://www.courier-mta.org
72 stars 12 forks source link

LDAP authentication issue with "@" in username #33

Closed schoerg closed 3 years ago

schoerg commented 3 years ago

Hi,

I have a mailserver where users can login with either a uid or their mail address. The authentication backend is LDAP.

This is the LDAP filter:

LDAP_EMAILMAP (|(uid=@user@@realm@)(mail=@user@@realm@)(mailalternateaddress=@user@@realm@))

This will lead to a search string like this: User: demo2@example.com

authdaemond: using emailmap search: (|(uid=demo2example.com)(mail=demo2example.com)(mailalternateaddress=demo2example.com))

Which obviously doesn't work as the "@" sign is missing.

If I change the filter to:

LDAP_EMAILMAP (|(uid=@user@@@realm@)(mail=@user@@@realm@)(mailalternateaddress=@user@@@realm@))

This will lead to:

emailmap search: (|(uid=demo2realmuserexample.com)(mailalternateaddress=demo2realm

The "@" is replaced by "realmuser". Which also leads to LDAP errors. Same for \@ or '@' in the search string.

Digging into the source of authldaplib.cpp the problem seems to be in emailmap_replace which is responsible for replacing @user@ to the actual user. There is no macro for the "@" sign.

Possible solutions:

Replace the @user@ delimiter to something that isn't a valid email character, maybe something like "§".

Add something like this to authldaplib.cpp:

        else if (key == "at")
            o << '@';

And then be able to use @at@ in the config file to add a literal "@" sign.

Or is there another way to send the correct search query to the LDAP server?

svarshavchik commented 3 years ago

Try using

\40

to specify an @ sign, in an authldaprc setting. LDAP search strings use backslashes for escapes.

schoerg commented 3 years ago

Thanks, I forgot to mention, I also tried to use \@ with no effect. Tried \40 but same, the "@" is not being transmitted.

\40

using emailmap search: (|(uid=demo2\40realmuserexample.com)(mailalternateaddress=demo2\40realm

svarshavchik commented 3 years ago

It should not be transmitted. \xx is an escape sequence for special characters that gets interpreted by the LDAP server. See "The String Representation of LDAP Filters" at https://ldap.com/ldap-filters/, namely:

Although not required, you may escape any other characters that you want in the assertion value (or substring component) of a filter. This may be accomplished by prefixing the hexadecimal representation of each byte of the UTF-8 encoding of the character to escape with a backslash character. For example, if you wanted to escape the character ñ you would represent it as “\c3\b1”.

Hence, I would expect a search sequence of \40 to match the @ character. It wouldn't be too much trouble to add something here to explicitly insert the @ character, but I do think that this should work already, as specified.

schoerg commented 3 years ago

You are right, \40 did work, there was an extra "@" character in the string.