Blame modules/cyrus-sasl-extern.c

Packit 8480eb
/*
Packit 8480eb
 * cyrus-sasl-extern.c - Module for Cyrus sasl external authentication.
Packit 8480eb
 *
Packit 8480eb
 *   Copyright 2010 Ian Kent <raven@themaw.net>
Packit 8480eb
 *   Copyright 2010 Red Hat, Inc.
Packit 8480eb
 *   All rights reserved.
Packit 8480eb
 *
Packit 8480eb
 *   This program is free software; you can redistribute it and/or modify
Packit 8480eb
 *   it under the terms of the GNU General Public License as published by
Packit 8480eb
 *   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
Packit 8480eb
 *   USA; either version 2 of the License, or (at your option) any later
Packit 8480eb
 *   version.
Packit 8480eb
 *
Packit 8480eb
 *   This program is distributed in the hope that it will be useful,
Packit 8480eb
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 8480eb
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 8480eb
 *   GNU General Public License for more details.
Packit 8480eb
 */
Packit 8480eb
Packit 8480eb
#include "config.h"
Packit 8480eb
Packit 8480eb
#ifdef WITH_SASL
Packit 8480eb
#include <stdio.h>
Packit 8480eb
#include <stdlib.h>
Packit 8480eb
#include <string.h>
Packit 8480eb
#include <unistd.h>
Packit 8480eb
#include <sasl/sasl.h>
Packit 8480eb
#include <ldap.h>
Packit 8480eb
#include <ldap_cdefs.h>
Packit 8480eb
#include <lber_types.h>
Packit 8480eb
Packit 8480eb
#include "lookup_ldap.h"
Packit 8480eb
Packit 8480eb
struct values {
Packit 8480eb
	char *mech;
Packit 8480eb
	char *realm;
Packit 8480eb
	char *authcid;
Packit 8480eb
	char *authzid;
Packit 8480eb
	char *password;
Packit 8480eb
	char **resps;
Packit 8480eb
	int nresps;
Packit 8480eb
};
Packit 8480eb
Packit 8480eb
static int interaction(unsigned flags, sasl_interact_t *interact, void *values)
Packit 8480eb
{
Packit 8480eb
	const char *val = interact->defresult;
Packit 8480eb
	struct values *vals = values;
Packit 8480eb
Packit 8480eb
	switch(interact->id) {
Packit 8480eb
	case SASL_CB_GETREALM:
Packit 8480eb
		if (values)
Packit 8480eb
			val = vals->realm;
Packit 8480eb
		break;
Packit 8480eb
Packit 8480eb
	case SASL_CB_AUTHNAME:
Packit 8480eb
		if (values)
Packit 8480eb
			val = vals->authcid;
Packit 8480eb
		break;
Packit 8480eb
Packit 8480eb
	case SASL_CB_PASS:
Packit 8480eb
		if (values)
Packit 8480eb
			val = vals->password;
Packit 8480eb
		break;
Packit 8480eb
Packit 8480eb
	case SASL_CB_USER:
Packit 8480eb
		if (values)
Packit 8480eb
			val = vals->authzid;
Packit 8480eb
		break;
Packit 8480eb
Packit 8480eb
	case SASL_CB_NOECHOPROMPT:
Packit 8480eb
	case SASL_CB_ECHOPROMPT:
Packit 8480eb
		break;
Packit 8480eb
	}
Packit 8480eb
Packit 8480eb
	if (val && !*val)
Packit 8480eb
		val = NULL;
Packit 8480eb
Packit 8480eb
	if (val || interact->id == SASL_CB_USER) {
Packit 8480eb
		interact->result = (val && *val) ? val : "";
Packit 8480eb
		interact->len = strlen(interact->result);
Packit 8480eb
	}
Packit 8480eb
Packit 8480eb
	return LDAP_SUCCESS;
Packit 8480eb
}
Packit 8480eb
Packit 8480eb
int sasl_extern_interact(LDAP *ldap, unsigned flags, void *values, void *list)
Packit 8480eb
{
Packit 8480eb
	sasl_interact_t *interact = list;
Packit 8480eb
Packit 8480eb
	if (!ldap)
Packit 8480eb
		return LDAP_PARAM_ERROR;
Packit 8480eb
Packit 8480eb
	while (interact->id != SASL_CB_LIST_END) {
Packit 8480eb
		int rc = interaction(flags, interact, values);
Packit 8480eb
		if (rc)
Packit 8480eb
			return rc;
Packit 8480eb
		interact++;
Packit 8480eb
	}
Packit 8480eb
Packit 8480eb
	return LDAP_SUCCESS;
Packit 8480eb
}
Packit 8480eb
Packit 8480eb
int do_sasl_extern(LDAP *ldap, struct lookup_context *ctxt)
Packit 8480eb
{
Packit 8480eb
	int flags = LDAP_SASL_QUIET;
Packit 8480eb
	char *mech = ctxt->sasl_mech;
Packit 8480eb
	struct values values;
Packit 8480eb
	int rc;
Packit 8480eb
Packit 8480eb
	memset(&values, 0, sizeof(struct values));
Packit 8480eb
	values.mech = mech;
Packit 8480eb
Packit 8480eb
	rc = ldap_sasl_interactive_bind_s(ldap, NULL, mech, NULL, NULL,
Packit 8480eb
					  flags, sasl_extern_interact, &values);
Packit 8480eb
	return rc;
Packit 8480eb
}
Packit 8480eb
#endif