of Cyrus SASL on the client machine but also on
supportedSASLmechanisms on the
LDAP server. The latter information will be requested by libldap
during SASL
mechanism negotiation. Current OpenLDAP libldap implementation is to
prefer
user credential based SCRAM-* mechanisms on token based GSSAPI. Only
exception
are SASL bind requests to servers, e. g. Active Directory domain
controllers,
that have disabled all SASL mechanisms, which rely on user credential
transfer
between client and directory server.
Current autofs implementation fetches user credential information
from LDAP
authentication configuration file for LDAP simple binds or if users
explicitly
specify a user credential based authentication mechanism (authtype).
This patch makes specification of user credentials mandatory for SASL
mechanism
auto-detection using ldap_sasl_interactive_bind(). Users can then
omit SASL
authtype specification and automount will auto-select the best suited
user
credential based SASL mechanism supported by client and LDAP server.
If authtype="GSSAPI" is specified together with
authrequired="autodetect"
automount will obtain a Kerberos ticket-granting ticket and bind to
all Active
Directory servers or use the specified user credentials to bind to
all other
LDAP servers that also support user credential based SASL mechanisms.
The patch is backward compatible to implementations that use autofs
function
sasl_choose_mech(). The strategy of this function is to force users
to specify
the SASL mechanism (authtype) if user credentials shall be used for
SASL binding
and only perform auto-selection for server supported mechanisms,
which are not
based on user credentials.
Signed-off-by: Thomas Reim <reimth@xxxxxxxxx>
---
modules/lookup_ldap.c | 45 ++++++++++++++++++++++++++++++++++---------
1 file changed, 36 insertions(+), 9 deletions(-)
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index e4cc32b..f2e553a 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -644,14 +644,14 @@ static int do_bind(unsigned logopt, struct
ldap_conn *conn,
sasl_flags = LDAP_SASL_QUIET;
}
- debug(logopt, "Attempting sasl bind with mechanism %s",
ctxt->sasl_mech);
-
if (ctxt->auth_required & LDAP_AUTH_AUTODETECT) {
if (ctxt->sasl_mech) {
free(ctxt->sasl_mech);
ctxt->sasl_mech = NULL;
}
- }
+ debug(logopt, "Attempting sasl bind with mechanism
auto-select");
+ } else
+ debug(logopt, "Attempting sasl bind with mechanism %s",
ctxt->sasl_mech);
/*
* If LDAP_AUTH_AUTODETECT is set, it means that there was no
@@ -1445,20 +1445,47 @@ int parse_ldap_config(unsigned logopt, struct
lookup_context *ctxt)
goto out;
}
+#ifndef WITH_LDAP_CYRUS_SASL
if (auth_required == LDAP_AUTH_USESIMPLE ||
(authtype && authtype_requires_creds(authtype))) {
+#else
+ /*
+ * OpenLDAP with Cyrus SASL needs user credentials for
+ * SASL mechanism auto-selection in following cases:
+ * (a) LDAP_AUTH_AUTODETECT
+ * (b) LDAP_AUTH_REQUIRED but no SASL mechanism specified
+ */
+ if (auth_required == LDAP_AUTH_USESIMPLE ||
+ (authtype && authtype_requires_creds(authtype)) ||
+ (!authtype && (auth_required & LDAP_AUTH_REQUIRED)) ||
+ (auth_required & LDAP_AUTH_AUTODETECT)) {
+#endif
char *s1 = NULL, *s2 = NULL;
ret = get_property(logopt, root, "user", &user);
ret |= get_property(logopt, root, "secret", &s1);
ret |= get_property(logopt, root, "encoded_secret", &s2);
if (ret != 0 || (!user || (!s1 && !s2))) {
auth_fail:
- error(logopt,
- MODPREFIX
- "%s authentication type requires a username "
- "and a secret. Please fix your configuration "
- "in %s.", authtype, auth_conf);
- free(authtype);
+ if (auth_required == LDAP_AUTH_USESIMPLE)
+ error(logopt,
+ MODPREFIX
+ "Simple authentication method requires a
username "
+ "and a secret. Please fix your configuration "
+ "in %s.", auth_conf);
+ else if (authtype && authtype_requires_creds(authtype))
+ error(logopt,
+ MODPREFIX
+ "%s authentication type requires a username "
+ "and a secret. Please fix your configuration "
+ "in %s.", authtype, auth_conf);
+ else
+ error(logopt,
+ MODPREFIX
+ "SASL authentication type auto-selection
requires a "
+ "username and a secret. Please fix your
configuration "
+ "in %s.", auth_conf);
+ if (authtype)
+ free(authtype);
if (user)
free(user);
if (s1)