autofs-5.1.8 - fix let OpenLDAP handle SASL binding

From: Andreas Hasenack <andreas@canonical.com>

I was writing a test for this, since we plan to release an autofs
update with this fix, and noticed that a particular config stopped
working: `credentialcache` in /etc/autofs_ldap_auth.conf.

For the test I was grabbing a TGT instead of using a keytab, an
configuring autofs to use that to authenticate against an openldap
server:
<autofs_ldap_sasl_conf
        usetls="no"
        tlsrequired="no"
    authrequired="yes"
    authtype="GSSAPI"
    clientprinc="ubuntu@LXD"
    credentialcache="/tmp/krb5cc_0"
/>

Initially openldap was configured to accept connections authenticated
via sasl and any ssf (including 0, which is the case with autofs).
Later I would configure the openldap server to reject connections
authenticated with SASL and an ssf=0, in order to trigger the bug and
verify the fix (where autofs would be using ssf=256).

Anyway, the above was working with an unpatched autofs:

(...)
parse_ldap_config: lookup(ldap): user: (null), secret: unspecified,
client principal: ubuntu@LXD credential cache: /tmp/krb5cc_0
do_init: parse(sun): init gathered global options: (null)
do_bind: lookup(ldap): auth_required: 2, sasl_mech GSSAPI
sasl_do_kinit_ext_cc: using external credential cache for auth: client
principal ubuntu@LXD
sasl_do_kinit_ext_cc: external credential cache default principal ubuntu@LXD
sasl_do_kinit_ext_cc: Kerberos authentication was successful!
sasl_bind_mech: Attempting sasl bind with mechanism GSSAPI
sasl_log_func: GSSAPI client step 1
getuser_func: called with context (nil), id 16385.
sasl_log_func: GSSAPI client step 1
getuser_func: called with context (nil), id 16385.
sasl_log_func: GSSAPI client step 2
sasl_bind_mech: sasl bind with mechanism GSSAPI succeeded

But not in the patched one:
(...)
parse_ldap_config: lookup(ldap): user: (null), secret: unspecified,
client principal: ubuntu@LXD credential cache: /tmp/krb5cc_0
do_init: parse(sun): init gathered global options: (null)
do_bind: lookup(ldap): auth_required: 2, sasl_mech GSSAPI
sasl_do_kinit: initializing kerberos ticket: client principal ubuntu@LXD
sasl_do_kinit: calling krb5_parse_name on client principal ubuntu@LXD
sasl_do_kinit: Using tgs name krbtgt/LXD@LXD
sasl_do_kinit: krb5_get_init_creds_keytab failed with error -1765328174
do_bind: lookup(ldap): auth_required: 2, sasl_mech GSSAPI
sasl_do_kinit: initializing kerberos ticket: client principal ubuntu@LXD
sasl_do_kinit: calling krb5_parse_name on client principal ubuntu@LXD
sasl_do_kinit: Using tgs name krbtgt/LXD@LXD
sasl_do_kinit: krb5_get_init_creds_keytab failed with error -1765328174

The patched version is only trying sasl_do_kinit(), instead of
sasl_do_kinit_ext_cc(). But if there's an external credential cache
configured I think sasl_do_kinit_ext_cc() needs to be called for
initialization since the code doesn't naturally call the mechanism
selection functions.
---
 CHANGELOG             |    1 +
 include/lookup_ldap.h |    1 +
 modules/lookup_ldap.c |    5 ++++-
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG b/CHANGELOG
index 52943569..4e2d9139 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -97,6 +97,7 @@
 - fix expire retry looping.
 - allow -null map in indirect maps.
 - fix multi-mount check.
+- fix let OpenLDAP handle SASL binding.
 
 19/10/2021 autofs-5.1.8
 - add xdr_exports().
diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h
index 9c3e8627..e6ad09a1 100644
--- a/include/lookup_ldap.h
+++ b/include/lookup_ldap.h
@@ -130,6 +130,7 @@ void autofs_sasl_unbind(struct ldap_conn *conn, struct lookup_context *ctxt);
 void autofs_sasl_dispose(struct ldap_conn *conn, struct lookup_context *ctxt);
 void autofs_sasl_done(void);
 int sasl_do_kinit(unsigned logopt, struct lookup_context *ctxt);
+int sasl_do_kinit_ext_cc(unsigned logopt, struct lookup_context *ctxt);
 #ifdef WITH_LDAP_CYRUS_SASL
 void autofs_ldap_sasl_freedefs(void *defaults);
 void *autofs_ldap_sasl_defaults(LDAP *ld, char *mech, char *realm, char *authcid, char *passwd, char *authzid );
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 6af14163..53416c6f 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -640,7 +640,10 @@ static int do_bind(unsigned logopt, struct ldap_conn *conn,
 		debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv);
 #else
 		if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "GSSAPI", 6)) {
-			rv = sasl_do_kinit(logopt, ctxt);
+			if (ctxt->client_cc)
+				rv = sasl_do_kinit_ext_cc(logopt, ctxt);
+			else
+				rv = sasl_do_kinit(logopt, ctxt);
 			if (rv != 0)
 				return 0;
 			sasl_flags = LDAP_SASL_QUIET;