MarcJHuber / event-driven-servers

A collection of event-driven servers (currently: tac_plus, tac_plus-ng, ftpd, tcprelay)
https://www.pro-bono-publico.de/projects
Other
97 stars 25 forks source link

LDAP vendor lookup fails for Okta LDAP Interface #97

Closed mattj21 closed 3 months ago

mattj21 commented 3 months ago

I'm pointing my MAVIS backend to the Okta LDAP Interface in my tac_plus-ng config file but the lookup just silently fails. The relevant portion of my config looks like this:

mavis module = external {
    setenv LDAP_SERVER_TYPE = "generic"
    setenv LDAP_CONNECT_TIMEOUT = 30
    setenv LDAP_HOSTS = "ldaps://blah.ldap.okta.com:636"
    setenv LDAP_BASE = "$base_dn"
    setenv LDAP_FILTER = "(&(objectclass=inetOrgPerson)(uid=%s))"
    setenv LDAP_USER = "$user_dn"
    setenv LDAP_PASSWD = "$password"
    exec = /usr/local/lib/mavis/mavis_tacplus-ng_ldap.pl
}

I manually tested mavis_tacplus-ng_ldap.pl and can see how it fails on the vendorname lookup:

root@01fdf5056958:/# printf "0 TACPLUS\n4 username\n49 INFO\n=\n" | /usr/local/lib/mavis/mavis_tacplus-ng_ldap.pl
Can't call method "get_value" on an undefined value at /usr/local/lib/mavis/mavis_tacplus-ng_ldap.pl line 321.

In my test environment I wrapped the vendorname lookup in a try/catch block using Try::Tiny and I was able to get the full user lookup to work and the tac_plus-ng lookup works end-to-end now.

I'm not familiar enough with perl to know if that's the proper way to handle this, or if there's another way to verify what vendorname Okta returns, or if this is also causing an issue with any other directories.

https://github.com/MarcJHuber/event-driven-servers/blob/3206bff0eb20829c5e407d0114ed996fd2f3482a/mavis/perl/mavis_tacplus-ng_ldap.pl#L320C1-L324C4

MarcJHuber commented 3 months ago

Hi,

thanks for reporting. The Okta LDAP implementation possibly doesn't return the root DSE for anonymous binds. Could you please check whether the diff below fixes this issue?

Thanks,

Marc

index eeb847b..2c33b6d 100755
--- a/mavis/perl/mavis_tacplus-ng_ldap.pl
+++ b/mavis/perl/mavis_tacplus-ng_ldap.pl
@@ -308,6 +308,11 @@ retry_once:
                                goto fatal;
                        }
                }
+               my $mesg = $ldap->bind(@LDAP_BIND);
+               if ($mesg->code){
+                       $V[AV_A_USER_RESPONSE] = $mesg->error . " (" . __LINE__ . ")";
+                       goto fatal;
+               }
                unless (defined $LDAP_SERVER_TYPE) {
                        if ($ldap->is_AD() || $ldap->is_ADAM()) {
                                $LDAP_SERVER_TYPE = "microsoft";
mattj21 commented 3 months ago

Hi Marc, Thanks for the update, I just tested and that does seem to fix the issue.

To be clear this shouldn't be an anonymous bind, as far as I know the Okta LDAP Interface doesn't allow anonymous binding. In Apache Directory Studio I do see a root DSE with a vendorName field of Okta Inc. but even ignoring case in the $ldap->root_dse->get_value('vendorname') lookup didn't seem to return a value.

MarcJHuber commented 3 months ago

Hi,

thanks for testing again. My assumption with root DSEs was that those don't need authentication at all, as tests with the commonly used servers didn't indicate an issue. I'll push a fix for the various backend variants (Perl, Python, C) shortly.

Thanks,

Marc