autofs-5.0.5 - add external bind method

From: Ian Kent <raven@themaw.net>

Add sasl external bind handler.
---

 CHANGELOG                      |    1 
 include/lookup_ldap.h          |    7 ++
 man/autofs_ldap_auth.conf.5.in |   24 +++++++-
 modules/Makefile               |    5 +-
 modules/cyrus-sasl-extern.c    |  117 ++++++++++++++++++++++++++++++++++++++++
 modules/cyrus-sasl.c           |   20 +++++++
 modules/lookup_ldap.c          |   78 ++++++++++++++++++++++-----
 7 files changed, 234 insertions(+), 18 deletions(-)
 create mode 100644 modules/cyrus-sasl-extern.c


Index: autofs-5.0.5/include/lookup_ldap.h
===================================================================
--- autofs-5.0.5.orig/include/lookup_ldap.h
+++ autofs-5.0.5/include/lookup_ldap.h
@@ -12,7 +12,6 @@
 #include <krb5.h>
 #endif
 
-#include "list.h"
 #include "dclist.h"
 
 struct ldap_schema {
@@ -79,13 +78,9 @@ struct lookup_context {
 	int          kinit_done;
 	int          kinit_successful;
 #ifdef WITH_SASL
-	/* Kerberos */
 	krb5_context krb5ctxt;
 	krb5_ccache  krb5_ccache;
 	sasl_conn_t  *sasl_conn;
-	/* SASL external */
-	char	     *extern_cert;
-	char	     *extern_key;
 #endif
 	/* keytab file name needs to be added */
 
@@ -121,8 +116,6 @@ int autofs_sasl_bind(unsigned logopt, LD
 void autofs_sasl_unbind(struct lookup_context *ctxt);
 void autofs_sasl_dispose(struct lookup_context *ctxt);
 void autofs_sasl_done(void);
-/* cyrus-sasl-extern */
-int do_sasl_extern(LDAP *ldap, struct lookup_context *ctxt);
 #endif
 
 #endif
Index: autofs-5.0.5/man/autofs_ldap_auth.conf.5.in
===================================================================
--- autofs-5.0.5.orig/man/autofs_ldap_auth.conf.5.in
+++ autofs-5.0.5/man/autofs_ldap_auth.conf.5.in
@@ -60,30 +60,12 @@ authentication  mechanism. If no suitabl
 to the ldap server are made without authentication. Finally, if it is set to
 simple, then simple authentication will be used instead of SASL.
 .TP
-\fBauthtype="GSSAPI"|"LOGIN"|"PLAIN"|"ANONYMOUS"|"DIGEST-MD5|EXTERNAL"\fP
+\fBauthtype="GSSAPI"|"LOGIN"|"PLAIN"|"ANONYMOUS"|"DIGEST-MD5"\fP
 This attribute can be used to specify a preferred authentication mechanism.
-In normal operations, the automounter will attempt to authenticate to the
+ In normal operations, the automounter will attempt to authenticate to the
 ldap server using the list of supportedSASLmechanisms obtained from the
 directory server.  Explicitly setting the authtype will bypass this selection
-and only try the mechanism specified. The EXTERNAL mechanism may be used to
-authenticate using a client certificate and requires that authrequired
-set to "yes" if using SSL or usetls, tlsrequired and authrequired all set to
-"yes" if using TLS, in addition to authtype being set to EXTERNAL.
-.sp
-If using authtype EXTERNAL two additional configuration entries are
-required:
-.sp
-\fBexternal_cert="<client certificate path>"\fP
-.sp
-This specifies the path of the file containing the client certificate.
-.sp
-\fBexternal_key="<client certificate key path>"\fP
-.sp
-This specifies the path of the file containing the client certificate key.
-.sp
-These two configuration entries are mandatory when using the EXTERNAL method
-as the HOME environment variable cannot be assumed to be set or, if it is,
-to be set to the location we expect.
+and only try the mechanism specified.
 .TP
 \fBuser="<username>"\fP
 This attribute holds the authentication identity used by authentication
Index: autofs-5.0.5/modules/Makefile
===================================================================
--- autofs-5.0.5.orig/modules/Makefile
+++ autofs-5.0.5/modules/Makefile
@@ -41,7 +41,7 @@ ifeq ($(LDAP), 1)
   SRCS += lookup_ldap.c
   MODS += lookup_ldap.so
   ifeq ($(SASL), 1)
-    SASL_OBJ = cyrus-sasl.o cyrus-sasl-extern.o
+    SASL_OBJ = cyrus-sasl.o
     LDAP_FLAGS += $(SASL_FLAGS) $(XML_FLAGS) $(KRB5_FLAGS) -DLDAP_THREAD_SAFE
     LIBLDAP += $(LIBSASL) $(XML_LIBS) $(KRB5_LIBS)
   endif
@@ -92,9 +92,6 @@ lookup_hesiod.so: lookup_hesiod.c
 cyrus-sasl.o: cyrus-sasl.c
 	$(CC) $(CFLAGS) $(LDAP_FLAGS) -c $<
 
-cyrus-sasl-extern.o: cyrus-sasl-extern.c
-	$(CC) $(CFLAGS) $(LDAP_FLAGS) -c $<
-
 lookup_ldap.so: lookup_ldap.c dclist.o $(SASL_OBJ)
 	$(CC) $(SOLDFLAGS) $(CFLAGS) $(LDAP_FLAGS) -o lookup_ldap.so \
 		lookup_ldap.c dclist.o $(SASL_OBJ) \
Index: autofs-5.0.5/modules/cyrus-sasl-extern.c
===================================================================
--- autofs-5.0.5.orig/modules/cyrus-sasl-extern.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * cyrus-sasl-extern.c - Module for Cyrus sasl external authentication.
- *
- *   Copyright 2010 Ian Kent <raven@themaw.net>
- *   Copyright 2010 Red Hat, Inc.
- *   All rights reserved.
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
- *   USA; either version 2 of the License, or (at your option) any later
- *   version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- */
-
-#include "config.h"
-
-#ifdef WITH_SASL
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sasl/sasl.h>
-#include <ldap.h>
-#include <ldap_cdefs.h>
-#include <lber_types.h>
-
-#include "lookup_ldap.h"
-
-struct values {
-	char *mech;
-	char *realm;
-	char *authcid;
-	char *authzid;
-	char *password;
-	char **resps;
-	int nresps;
-};
-
-static int interaction(unsigned flags, sasl_interact_t *interact, void *values)
-{
-	const char *val = interact->defresult;
-	struct values *vals = values;
-
-	switch(interact->id) {
-	case SASL_CB_GETREALM:
-		if (values)
-			val = vals->realm;
-		break;
-
-	case SASL_CB_AUTHNAME:
-		if (values)
-			val = vals->authcid;
-		break;
-
-	case SASL_CB_PASS:
-		if (values)
-			val = vals->password;
-		break;
-
-	case SASL_CB_USER:
-		if (values)
-			val = vals->authzid;
-		break;
-
-	case SASL_CB_NOECHOPROMPT:
-	case SASL_CB_ECHOPROMPT:
-		break;
-	}
-
-	if (val && !*val)
-		val = NULL;
-
-	if (val || interact->id == SASL_CB_USER) {
-		interact->result = (val && *val) ? val : "";
-		interact->len = strlen(interact->result);
-	}
-
-	return LDAP_SUCCESS;
-}
-
-int sasl_extern_interact(LDAP *ldap, unsigned flags, void *values, void *list)
-{
-	sasl_interact_t *interact = list;
-
-	if (!ldap)
-		return LDAP_PARAM_ERROR;
-
-	while (interact->id != SASL_CB_LIST_END) {
-		int rc = interaction(flags, interact, values);
-		if (rc)
-			return rc;
-		interact++;
-	}
-
-	return LDAP_SUCCESS;
-}
-
-int do_sasl_extern(LDAP *ldap, struct lookup_context *ctxt)
-{
-	int flags = LDAP_SASL_QUIET;
-	char *mech = ctxt->sasl_mech;
-	struct values values;
-	int rc;
-
-	memset(&values, 0, sizeof(struct values));
-	values.mech = mech;
-
-	rc = ldap_sasl_interactive_bind_s(ldap, NULL, mech, NULL, NULL,
-					  flags, sasl_extern_interact, &values);
-	return rc;
-}
-#endif
Index: autofs-5.0.5/modules/cyrus-sasl.c
===================================================================
--- autofs-5.0.5.orig/modules/cyrus-sasl.c
+++ autofs-5.0.5/modules/cyrus-sasl.c
@@ -874,26 +874,6 @@ autofs_sasl_bind(unsigned logopt, LDAP *
 	if (ctxt->sasl_conn)
 		return 0;
 
-	if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) {
-		int result;
-
-		debug(logopt,
-		      "Attempting sasl bind with mechanism %s",
-		      ctxt->sasl_mech);
-
-		result = do_sasl_extern(ldap, ctxt);
-		if (result)
-			debug(logopt,
-			      "Failed to authenticate with mech %s",
-			      ctxt->sasl_mech);
-		else
-			debug(logopt,
-			      "sasl bind with mechanism %s succeeded",
-			      ctxt->sasl_mech);
-
-		return result;
-	}
-
 	sasl_auth_id = ctxt->user;
 	sasl_auth_secret = ctxt->secret;
 
Index: autofs-5.0.5/modules/lookup_ldap.c
===================================================================
--- autofs-5.0.5.orig/modules/lookup_ldap.c
+++ autofs-5.0.5/modules/lookup_ldap.c
@@ -40,9 +40,6 @@
 
 int lookup_version = AUTOFS_LOOKUP_VERSION;	/* Required by protocol */
 
-#define ENV_LDAPTLS_CERT	"LDAPTLS_CERT"
-#define ENV_LDAPTLS_KEY		"LDAPTLS_KEY"
-
 static struct ldap_schema common_schema[] = {
 	{"nisMap", "nisMapName", "nisObject", "cn", "nisMapEntry"},
 	{"automountMap", "ou", "automount", "cn", "automountInformation"},
@@ -63,16 +60,6 @@ struct ldap_search_params {
 
 static int decode_percent_hack(const char *, char **);
 
-static int set_env(unsigned logopt, const char *name, const char *val)
-{
-	int ret = setenv(name, val, 1);
-	if (ret == -1) {
-		error(logopt, "failed to set config value for %s", name);
-		return 0;
-	}
-	return 1;
-}
-
 #ifndef HAVE_LDAP_CREATE_PAGE_CONTROL
 int ldap_create_page_control(LDAP *ldap, ber_int_t pagesize,
 			     struct berval *cookie, char isCritical,
@@ -590,17 +577,13 @@ static LDAP *do_connect(unsigned logopt,
 {
 	LDAP *ldap;
 
-	if (ctxt->extern_cert && ctxt->extern_key) {
-		set_env(logopt, ENV_LDAPTLS_CERT, ctxt->extern_cert);
-		set_env(logopt, ENV_LDAPTLS_KEY, ctxt->extern_key);
-	}
-
 	ldap = init_ldap_connection(logopt, uri, ctxt);
-	if (ldap) {
-		if (!do_bind(logopt, ldap, uri, ctxt)) {
-			unbind_ldap_connection(logopt, ldap, ctxt);
-			ldap = NULL;
-		}
+	if (!ldap)
+		return NULL;
+
+	if (!do_bind(logopt, ldap, uri, ctxt)) {
+		unbind_ldap_connection(logopt, ldap, ctxt);
+		return NULL;
 	}
 
 	return ldap;
@@ -855,7 +838,6 @@ int parse_ldap_config(unsigned logopt, s
 	xmlNodePtr   root = NULL;
 	char         *authrequired, *auth_conf, *authtype;
 	char         *user = NULL, *secret = NULL;
-	char         *extern_cert = NULL, *extern_key = NULL;
 	char         *client_princ = NULL, *client_cc = NULL;
 	char	     *usetls, *tlsrequired;
 
@@ -1040,26 +1022,6 @@ int parse_ldap_config(unsigned logopt, s
 			ret = -1;
 			goto out;
 		}
-	} else if (auth_required == LDAP_AUTH_REQUIRED &&
-		  (authtype && !strncmp(authtype, "EXTERNAL", 8))) {
-		ret = get_property(logopt, root, "external_cert",  &extern_cert);
-		ret |= get_property(logopt, root, "external_key",  &extern_key);
-		/*
-		 * For EXTERNAL auth to function we need a client certificate
-		 * and and certificate key. The ca certificate used to verify
-		 * the server certificate must also be set correctly in the
-		 * global configuration as the connection must be encrypted
-		 * and the server and client certificates must have been
-		 * verified for the EXTERNAL method to be offerred by the
-		 * server. If the cert and key have not been set in the autofs
-		 * configuration they must be set in the ldap rc file.
-		 */
-		if (ret != 0 || !extern_cert || !extern_key) {
-			if (extern_cert)
-				free(extern_cert);
-			if (extern_key)
-				free(extern_key);
-		}
 	}
 
 	/*
@@ -1080,8 +1042,6 @@ int parse_ldap_config(unsigned logopt, s
 	ctxt->secret = secret;
 	ctxt->client_princ = client_princ;
 	ctxt->client_cc = client_cc;
-	ctxt->extern_cert = extern_cert;
-	ctxt->extern_key = extern_key;
 
 	debug(logopt, MODPREFIX
 	      "ldap authentication configured with the following options:");
@@ -1091,20 +1051,14 @@ int parse_ldap_config(unsigned logopt, s
 	      "auth_required: %u, "
 	      "sasl_mech: %s",
 	      use_tls, tls_required, auth_required, authtype);
-	if (authtype && !strncmp(authtype, "EXTERNAL", 8)) {
-		debug(logopt, MODPREFIX "external cert: %s",
-		      extern_cert ? extern_cert : "ldap default");
-		debug(logopt, MODPREFIX "external key: %s ",
-		      extern_key ? extern_key : "ldap default");
-	} else {
-		debug(logopt, MODPREFIX
-		      "user: %s, "
-		      "secret: %s, "
-		      "client principal: %s "
-		      "credential cache: %s",
-		      user, secret ? "specified" : "unspecified",
-		      client_princ, client_cc);
-	}
+	debug(logopt, MODPREFIX
+	      "user: %s, "
+	      "secret: %s, "
+	      "client principal: %s "
+	      "credential cache: %s",
+	      user, secret ? "specified" : "unspecified",
+	      client_princ, client_cc);
+
 out:
 	xmlFreeDoc(doc);
 
@@ -1371,10 +1325,6 @@ static void free_context(struct lookup_c
 		defaults_free_searchdns(ctxt->sdns);
 	if (ctxt->dclist)
 		free_dclist(ctxt->dclist);
-	if (ctxt->extern_cert)
-		free(ctxt->extern_cert);
-	if (ctxt->extern_key)
-		free(ctxt->extern_key);
 	free(ctxt);
 
 	return;
Index: autofs-5.0.5/CHANGELOG
===================================================================
--- autofs-5.0.5.orig/CHANGELOG
+++ autofs-5.0.5/CHANGELOG
@@ -52,7 +52,6 @@
 - fix init script status privilege error.
 - always read file maps mount lookup map read fix.
 - fix direct map not updating on reread.
-- add external bind method.
 - fix add simple bind auth.
 
 03/09/2009 autofs-5.0.5
