mech-gssapi.c revision 6edf77bf423fe09849a79fd4077a697b8dc14a41
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen/*
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen * GSSAPI Module
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen *
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen * Copyright (c) 2005 Jelmer Vernooij <jelmer@samba.org>
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen *
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen * Related standards:
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen * - draft-ietf-sasl-gssapi-03
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen * - RFC2222
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen *
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen * Some parts inspired by an older patch from Colin Walters
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen *
e074ffeaee1ce283bd42f167c6810e3d013f8218Timo Sirainen * This software is released under the MIT license.
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen */
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen#include "common.h"
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen#include "mech.h"
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen#include "passdb.h"
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen#include "str.h"
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen#include "str-sanitize.h"
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen#include "buffer.h"
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen#include "hex-binary.h"
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen#include "safe-memset.h"
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
24c4835905c0a7ba5a7caa1666af5daef6233303Timo Sirainen#include <stdlib.h>
24c4835905c0a7ba5a7caa1666af5daef6233303Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen#ifdef HAVE_GSSAPI
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen#ifndef HAVE___GSS_USEROK
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen# define USE_KRB5_USEROK
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen# include <krb5.h>
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen#endif
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen
405aa3bff8ca00739ebeaab59afb593bcfc8edccTimo Sirainen#ifdef HAVE_GSSAPI_GSSAPI_H
405aa3bff8ca00739ebeaab59afb593bcfc8edccTimo Sirainen# include <gssapi/gssapi.h>
405aa3bff8ca00739ebeaab59afb593bcfc8edccTimo Sirainen#elif defined (HAVE_GSSAPI_H)
405aa3bff8ca00739ebeaab59afb593bcfc8edccTimo Sirainen# include <gssapi.h>
01ff322068d8cb54d37b478efc1348087b1f9f78Timo Sirainen#endif
01ff322068d8cb54d37b478efc1348087b1f9f78Timo Sirainen
01ff322068d8cb54d37b478efc1348087b1f9f78Timo Sirainen#ifdef HAVE_GSSAPI_GSSAPI_KRB5_H
01ff322068d8cb54d37b478efc1348087b1f9f78Timo Sirainen# include <gssapi/gssapi_krb5.h>
01ff322068d8cb54d37b478efc1348087b1f9f78Timo Sirainen#elif defined (HAVE_GSSAPI_KRB5_H)
01ff322068d8cb54d37b478efc1348087b1f9f78Timo Sirainen# include <gssapi_krb5.h>
01ff322068d8cb54d37b478efc1348087b1f9f78Timo Sirainen#else
01ff322068d8cb54d37b478efc1348087b1f9f78Timo Sirainen# undef USE_KRB5_USEROK
405aa3bff8ca00739ebeaab59afb593bcfc8edccTimo Sirainen#endif
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen#ifdef HAVE_GSSAPI_GSSAPI_EXT_H
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen# include <gssapi/gssapi_ext.h>
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen#endif
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen/* Non-zero flags defined in RFC 2222 */
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenenum sasl_gssapi_qop {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen SASL_GSSAPI_QOP_UNSPECIFIED = 0x00,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen SASL_GSSAPI_QOP_AUTH_ONLY = 0x01,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen SASL_GSSAPI_QOP_AUTH_INT = 0x02,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen SASL_GSSAPI_QOP_AUTH_CONF = 0x04
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen};
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenstruct gssapi_auth_request {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen struct auth_request auth_request;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gss_ctx_id_t gss_ctx;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gss_cred_id_t service_cred;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen enum {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen GSS_STATE_SEC_CONTEXT,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen GSS_STATE_WRAP,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen GSS_STATE_UNWRAP
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen } sasl_gssapi_state;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gss_name_t authn_name;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gss_name_t authz_name;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen pool_t pool;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen};
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainenstatic bool gssapi_initialized = FALSE;
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenstatic void auth_request_log_gss_error(struct auth_request *request,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen OM_uint32 status_value, int status_type,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen const char *description)
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen{
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen OM_uint32 message_context = 0;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen OM_uint32 major_status, minor_status;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gss_buffer_desc status_string;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen do {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen major_status = gss_display_status(&minor_status, status_value,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen status_type, GSS_C_NO_OID,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen &message_context,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen &status_string);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_log_error(request, "gssapi",
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen "While %s: %s", description,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen str_sanitize(status_string.value, (size_t)-1));
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen major_status = gss_release_buffer(&minor_status,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen &status_string);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen } while (message_context != 0);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen}
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainenstatic void mech_gssapi_initialize(void)
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen{
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen const char *path;
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen path = getenv("KRB5_KTNAME");
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen if (path != NULL) {
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen#ifdef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen gsskrb5_register_acceptor_identity(path);
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen#elif defined (HAVE_KRB5_GSS_REGISTER_ACCEPTOR_IDENTITY)
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen krb5_gss_register_acceptor_identity(path);
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen#endif
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen }
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen}
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenstatic struct auth_request *mech_gssapi_auth_new(void)
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen{
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen struct gssapi_auth_request *request;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen pool_t pool;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen if (!gssapi_initialized) {
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen gssapi_initialized = TRUE;
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen mech_gssapi_initialize();
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen }
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen
e03ec0b7b9d92551331bc509bcd86920544171d1Timo Sirainen pool = pool_alloconly_create("gssapi_auth_request", 1024);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen request = p_new(pool, struct gssapi_auth_request, 1);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen request->pool = pool;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen request->gss_ctx = GSS_C_NO_CONTEXT;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen request->auth_request.pool = pool;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen return &request->auth_request;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen}
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenstatic OM_uint32 obtain_service_credentials(struct auth_request *request,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gss_cred_id_t *ret)
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen{
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen OM_uint32 major_status, minor_status;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen string_t *principal_name;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gss_buffer_desc inbuf;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gss_name_t gss_principal;
893f7d52acc42058045f188b625449981bd7f9bcTimo Sirainen const char *service_name;
893f7d52acc42058045f188b625449981bd7f9bcTimo Sirainen
bde5b40c4fcc20e812a7caff9c0ed55e7090ced9Timo Sirainen if (strcmp(request->auth->gssapi_hostname, "$ALL") == 0) {
bde5b40c4fcc20e812a7caff9c0ed55e7090ced9Timo Sirainen auth_request_log_info(request, "gssapi",
bde5b40c4fcc20e812a7caff9c0ed55e7090ced9Timo Sirainen "Using all keytab entries");
bde5b40c4fcc20e812a7caff9c0ed55e7090ced9Timo Sirainen *ret = GSS_C_NO_CREDENTIAL;
bde5b40c4fcc20e812a7caff9c0ed55e7090ced9Timo Sirainen return GSS_S_COMPLETE;
bde5b40c4fcc20e812a7caff9c0ed55e7090ced9Timo Sirainen }
bde5b40c4fcc20e812a7caff9c0ed55e7090ced9Timo Sirainen
893f7d52acc42058045f188b625449981bd7f9bcTimo Sirainen if (strcasecmp(request->service, "POP3") == 0) {
893f7d52acc42058045f188b625449981bd7f9bcTimo Sirainen /* The standard POP3 service name with GSSAPI is called
893f7d52acc42058045f188b625449981bd7f9bcTimo Sirainen just "pop". */
893f7d52acc42058045f188b625449981bd7f9bcTimo Sirainen service_name = "pop";
893f7d52acc42058045f188b625449981bd7f9bcTimo Sirainen } else {
893f7d52acc42058045f188b625449981bd7f9bcTimo Sirainen service_name = t_str_lcase(request->service);
893f7d52acc42058045f188b625449981bd7f9bcTimo Sirainen }
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen principal_name = t_str_new(128);
893f7d52acc42058045f188b625449981bd7f9bcTimo Sirainen str_append(principal_name, service_name);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen str_append_c(principal_name, '@');
ee5be4287d37f251f683fd2755eafc02504d527cTimo Sirainen str_append(principal_name, request->auth->gssapi_hostname);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_log_info(request, "gssapi",
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen "Obtaining credentials for %s", str_c(principal_name));
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen inbuf.length = str_len(principal_name);
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen inbuf.value = str_c_modifiable(principal_name);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen major_status = gss_import_name(&minor_status, &inbuf,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen GSS_C_NT_HOSTBASED_SERVICE,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen &gss_principal);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen str_free(&principal_name);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen if (GSS_ERROR(major_status)) {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_log_gss_error(request, major_status,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen GSS_C_GSS_CODE,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen "importing principal name");
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen return major_status;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen }
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen major_status = gss_acquire_cred(&minor_status, gss_principal, 0,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen GSS_C_NULL_OID_SET, GSS_C_ACCEPT,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen ret, NULL, NULL);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen if (GSS_ERROR(major_status)) {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_log_gss_error(request, major_status,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen GSS_C_GSS_CODE,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen "acquiring service credentials");
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_log_gss_error(request, minor_status,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen GSS_C_MECH_CODE,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen "acquiring service credentials");
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen return major_status;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen }
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
da3f943e93b0ea5a8256a2e850f4738ad161f71dTimo Sirainen gss_release_name(&minor_status, &gss_principal);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen return major_status;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen}
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen#ifndef HAVE___GSS_USEROK
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenstatic gss_name_t
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenimport_name(struct auth_request *request, void *str, size_t len)
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen{
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen OM_uint32 major_status, minor_status;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gss_buffer_desc name_buf;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gss_name_t name;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen name_buf.value = str;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen name_buf.length = len;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen major_status = gss_import_name(&minor_status,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen &name_buf,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen GSS_C_NO_OID,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen &name);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen if (GSS_ERROR(major_status)) {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_log_gss_error(request, major_status,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen GSS_C_GSS_CODE, "gss_import_name");
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen return GSS_C_NO_NAME;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen }
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen return name;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen}
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen#endif
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenstatic void gssapi_sec_context(struct gssapi_auth_request *request,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gss_buffer_desc inbuf)
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen{
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen OM_uint32 major_status, minor_status;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gss_buffer_desc outbuf;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen major_status = gss_accept_sec_context (
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen &minor_status,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen &request->gss_ctx,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen request->service_cred,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen &inbuf,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen GSS_C_NO_CHANNEL_BINDINGS,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen &request->authn_name,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen NULL, /* mech_type */
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen &outbuf,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen NULL, /* ret_flags */
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen NULL, /* time_rec */
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen NULL /* delegated_cred_handle */
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen );
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen if (GSS_ERROR(major_status)) {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_log_gss_error(&request->auth_request, major_status,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen GSS_C_GSS_CODE,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen "processing incoming data");
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_log_gss_error(&request->auth_request, minor_status,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen GSS_C_MECH_CODE,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen "processing incoming data");
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_fail(&request->auth_request);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen return;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen }
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen if (major_status == GSS_S_COMPLETE) {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen request->sasl_gssapi_state = GSS_STATE_WRAP;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_log_info(&request->auth_request, "gssapi",
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen "security context state completed.");
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen } else {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_log_info(&request->auth_request, "gssapi",
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen "Processed incoming packet correctly, "
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen "waiting for another.");
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen }
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen request->auth_request.callback(&request->auth_request,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen AUTH_CLIENT_RESULT_CONTINUE,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen outbuf.value, outbuf.length);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen major_status = gss_release_buffer(&minor_status, &outbuf);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen}
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenstatic void gssapi_wrap(struct gssapi_auth_request *request,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gss_buffer_desc inbuf)
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen{
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen OM_uint32 major_status, minor_status;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gss_buffer_desc outbuf;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen unsigned char ret[4];
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen /* The clients return data should be empty here */
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen /* Only authentication, no integrity or confidentiality
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen protection (yet?) */
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen ret[0] = (SASL_GSSAPI_QOP_UNSPECIFIED |
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen SASL_GSSAPI_QOP_AUTH_ONLY);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen ret[1] = 0xFF;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen ret[2] = 0xFF;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen ret[3] = 0xFF;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen inbuf.length = 4;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen inbuf.value = ret;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen major_status = gss_wrap(&minor_status, request->gss_ctx, 0,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen GSS_C_QOP_DEFAULT, &inbuf, NULL, &outbuf);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen if (GSS_ERROR(major_status)) {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_log_gss_error(&request->auth_request, major_status,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen GSS_C_GSS_CODE, "sending security layer negotiation");
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_log_gss_error(&request->auth_request, minor_status,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen GSS_C_MECH_CODE, "sending security layer negotiation");
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_fail(&request->auth_request);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen return;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen }
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_log_info(&request->auth_request, "gssapi",
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen "Negotiated security layer");
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen request->auth_request.callback(&request->auth_request,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen AUTH_CLIENT_RESULT_CONTINUE,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen outbuf.value, outbuf.length);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen major_status = gss_release_buffer(&minor_status, &outbuf);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen request->sasl_gssapi_state = GSS_STATE_UNWRAP;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen}
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen#ifdef USE_KRB5_USEROK
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainenstatic bool
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainengssapi_krb5_userok(struct gssapi_auth_request *request, gss_name_t name,
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen bool check_name_type)
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen{
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen krb5_context ctx;
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen krb5_principal princ;
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen krb5_error_code krb5_err;
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen OM_uint32 major_status, minor_status;
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen gss_buffer_desc princ_name;
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen gss_OID name_type;
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen const char *princ_display_name;
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen bool ret = FALSE;
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen /* Parse out the principal's username */
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen major_status = gss_display_name(&minor_status, name,
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen &princ_name, &name_type);
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen if (major_status != GSS_S_COMPLETE) {
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen auth_request_log_gss_error(&request->auth_request, major_status,
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen GSS_C_GSS_CODE,
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen "gssapi_krb5_userok");
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen return FALSE;
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen }
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen if (name_type != GSS_KRB5_NT_PRINCIPAL_NAME && check_name_type) {
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen auth_request_log_error(&request->auth_request, "gssapi",
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen "OID not kerberos principal name");
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen return FALSE;
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen }
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen princ_display_name = t_strndup(princ_name.value, princ_name.length);
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen gss_release_buffer(&minor_status, &princ_name);
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen /* Init a krb5 context and parse the principal username */
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen krb5_err = krb5_init_context(&ctx);
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen if (krb5_err != 0) {
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen auth_request_log_error(&request->auth_request, "gssapi",
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen "krb5_init_context() failed: %d", (int)krb5_err);
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen return FALSE;
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen }
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen krb5_err = krb5_parse_name(ctx, princ_display_name, &princ);
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen if (krb5_err != 0) {
c869c075b0b558e82a613a8320b3b3a7e120741bTimo Sirainen /* writing the error string would be better, but we probably
c869c075b0b558e82a613a8320b3b3a7e120741bTimo Sirainen rarely get here and there doesn't seem to be a standard
c869c075b0b558e82a613a8320b3b3a7e120741bTimo Sirainen way of getting it */
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen auth_request_log_error(&request->auth_request, "gssapi",
c869c075b0b558e82a613a8320b3b3a7e120741bTimo Sirainen "krb5_parse_name() failed: %d",
c869c075b0b558e82a613a8320b3b3a7e120741bTimo Sirainen (int)krb5_err);
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen } else {
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen /* See if the principal is authorized to act as the
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen specified user */
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen ret = krb5_kuserok(ctx, princ, request->auth_request.user);
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen krb5_free_principal(ctx, princ);
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen }
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen krb5_free_context(ctx);
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen return ret;
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen}
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen#endif
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenstatic void gssapi_unwrap(struct gssapi_auth_request *request,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gss_buffer_desc inbuf)
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen{
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen OM_uint32 major_status, minor_status;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gss_buffer_desc outbuf;
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen#if defined(HAVE___GSS_USEROK) || !defined(USE_KRB5_USEROK)
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen int equal_authn_authz = 0;
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen#endif
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen major_status = gss_unwrap(&minor_status, request->gss_ctx,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen &inbuf, &outbuf, NULL, NULL);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen if (GSS_ERROR(major_status)) {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_log_gss_error(&request->auth_request, major_status,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen GSS_C_GSS_CODE,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen "final negotiation: gss_unwrap");
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_fail(&request->auth_request);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen return;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen }
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen if (outbuf.length <= 4) {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_log_error(&request->auth_request, "gssapi",
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen "Invalid response length");
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_fail(&request->auth_request);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen return;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen }
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen#ifdef HAVE___GSS_USEROK
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen /* Solaris __gss_userok() correctly handles cross-realm
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen authentication. */
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen request->auth_request.user =
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen p_strndup(request->auth_request.pool,
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen (unsigned char *)outbuf.value + 4,
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen outbuf.length - 4);
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen major_status = __gss_userok(&minor_status, request->authn_name,
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen request->auth_request.user,
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen &equal_authn_authz);
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen if (GSS_ERROR(major_status)) {
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen auth_request_log_gss_error(&request->auth_request, major_status,
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen GSS_C_GSS_CODE,
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen "__gss_userok failed");
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen auth_request_fail(&request->auth_request);
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen return;
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen }
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen if (equal_authn_authz == 0) {
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen auth_request_log_error(&request->auth_request, "gssapi",
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen "credentials not valid");
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen auth_request_fail(&request->auth_request);
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen return;
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen }
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen#else
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen request->authz_name = import_name(&request->auth_request,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen (unsigned char *)outbuf.value + 4,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen outbuf.length - 4);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen if ((request->authn_name == GSS_C_NO_NAME) ||
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen (request->authz_name == GSS_C_NO_NAME)) {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen /* XXX (pod): is this check necessary? */
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_log_error(&request->auth_request, "gssapi",
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen "one of authn_name or authz_name not determined");
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_fail(&request->auth_request);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen return;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen }
00db1828183b3e487ad7ed58810da8ebc5e95193Timo Sirainen
00db1828183b3e487ad7ed58810da8ebc5e95193Timo Sirainen request->auth_request.user =
00db1828183b3e487ad7ed58810da8ebc5e95193Timo Sirainen p_strndup(request->auth_request.pool,
00db1828183b3e487ad7ed58810da8ebc5e95193Timo Sirainen (unsigned char *)outbuf.value + 4,
00db1828183b3e487ad7ed58810da8ebc5e95193Timo Sirainen outbuf.length - 4);
00db1828183b3e487ad7ed58810da8ebc5e95193Timo Sirainen
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen#ifdef USE_KRB5_USEROK
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen if (!gssapi_krb5_userok(request, request->authn_name, TRUE)) {
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen auth_request_log_error(&request->auth_request, "gssapi",
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen "authn_name not authorized");
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen auth_request_fail(&request->auth_request);
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen return;
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen }
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen if (!gssapi_krb5_userok(request, request->authz_name, FALSE)) {
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen auth_request_log_error(&request->auth_request, "gssapi",
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen "authz_name not authorized");
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen auth_request_fail(&request->auth_request);
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen return;
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen }
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen#else
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen major_status = gss_compare_name(&minor_status,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen request->authn_name,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen request->authz_name,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen &equal_authn_authz);
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen if (equal_authn_authz != 0) {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_log_error(&request->auth_request, "gssapi",
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen "authn_name and authz_name differ: not supported");
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_fail(&request->auth_request);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen return;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen }
6edf77bf423fe09849a79fd4077a697b8dc14a41Timo Sirainen#endif
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen#endif
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_success(&request->auth_request, NULL, 0);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen}
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenstatic void
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenmech_gssapi_auth_continue(struct auth_request *request,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen const unsigned char *data, size_t data_size)
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen{
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen struct gssapi_auth_request *gssapi_request =
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen (struct gssapi_auth_request *)request;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gss_buffer_desc inbuf;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen inbuf.value = (void *)data;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen inbuf.length = data_size;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen switch (gssapi_request->sasl_gssapi_state) {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen case GSS_STATE_SEC_CONTEXT:
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gssapi_sec_context(gssapi_request, inbuf);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen break;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen case GSS_STATE_WRAP:
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gssapi_wrap(gssapi_request, inbuf);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen break;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen case GSS_STATE_UNWRAP:
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gssapi_unwrap(gssapi_request, inbuf);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen break;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen }
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen}
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenstatic void
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenmech_gssapi_auth_initial(struct auth_request *request,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen const unsigned char *data, size_t data_size)
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen{
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen OM_uint32 major_status;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen struct gssapi_auth_request *gssapi_request =
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen (struct gssapi_auth_request *)request;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen major_status =
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen obtain_service_credentials(request,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen &gssapi_request->service_cred);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen if (GSS_ERROR(major_status)) {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen auth_request_internal_failure(request);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen return;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen }
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gssapi_request->authn_name = GSS_C_NO_NAME;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gssapi_request->authz_name = GSS_C_NO_NAME;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gssapi_request->sasl_gssapi_state = GSS_STATE_SEC_CONTEXT;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen if (data_size == 0) {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen /* The client should go first */
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen request->callback(request, AUTH_CLIENT_RESULT_CONTINUE,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen NULL, 0);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen } else {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen mech_gssapi_auth_continue(request, data, data_size);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen }
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen}
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenstatic void
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenmech_gssapi_auth_free(struct auth_request *request)
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen{
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen OM_uint32 major_status, minor_status;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen struct gssapi_auth_request *gssapi_request =
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen (struct gssapi_auth_request *)request;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
9e3f0cc69cbc4af74d08d1e52aa5ed8a7675b8f1Timo Sirainen if (gssapi_request->gss_ctx != GSS_C_NO_CONTEXT) {
9e3f0cc69cbc4af74d08d1e52aa5ed8a7675b8f1Timo Sirainen major_status = gss_delete_sec_context(&minor_status,
9e3f0cc69cbc4af74d08d1e52aa5ed8a7675b8f1Timo Sirainen &gssapi_request->gss_ctx,
9e3f0cc69cbc4af74d08d1e52aa5ed8a7675b8f1Timo Sirainen GSS_C_NO_BUFFER);
9e3f0cc69cbc4af74d08d1e52aa5ed8a7675b8f1Timo Sirainen }
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen major_status = gss_release_cred(&minor_status,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen &gssapi_request->service_cred);
00bde9ae9eab9e720462bf6ec9a4dd85e88c3bbfTimo Sirainen if (gssapi_request->authn_name != GSS_C_NO_NAME) {
00bde9ae9eab9e720462bf6ec9a4dd85e88c3bbfTimo Sirainen major_status = gss_release_name(&minor_status,
00bde9ae9eab9e720462bf6ec9a4dd85e88c3bbfTimo Sirainen &gssapi_request->authn_name);
00bde9ae9eab9e720462bf6ec9a4dd85e88c3bbfTimo Sirainen }
00bde9ae9eab9e720462bf6ec9a4dd85e88c3bbfTimo Sirainen if (gssapi_request->authz_name != GSS_C_NO_NAME) {
00bde9ae9eab9e720462bf6ec9a4dd85e88c3bbfTimo Sirainen major_status = gss_release_name(&minor_status,
00bde9ae9eab9e720462bf6ec9a4dd85e88c3bbfTimo Sirainen &gssapi_request->authz_name);
00bde9ae9eab9e720462bf6ec9a4dd85e88c3bbfTimo Sirainen }
648d24583c1574441c4fa0331a90bd4d6e7996c5Timo Sirainen pool_unref(&request->pool);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen}
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenconst struct mech_module mech_gssapi = {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen "GSSAPI",
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen MEMBER(flags) 0,
ba8566b02903a4b00a39a611d19f421739a09456Timo Sirainen MEMBER(passdb_need) MECH_PASSDB_NEED_NOTHING,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen mech_gssapi_auth_new,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen mech_gssapi_auth_initial,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen mech_gssapi_auth_continue,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen mech_gssapi_auth_free
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen};
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen/* MTI Kerberos v1.5+ and Heimdal v0.7+ supports SPNEGO for Kerberos tickets
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen internally. Nothing else needs to be done here. Note however that this does
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen not support SPNEGO when the only available credential is NTLM.. */
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainenconst struct mech_module mech_gssapi_spnego = {
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen "GSS-SPNEGO",
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen MEMBER(flags) 0,
ba8566b02903a4b00a39a611d19f421739a09456Timo Sirainen MEMBER(passdb_need) MECH_PASSDB_NEED_NOTHING,
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen mech_gssapi_auth_new,
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen mech_gssapi_auth_initial,
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen mech_gssapi_auth_continue,
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen mech_gssapi_auth_free
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen};
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen
f97cf1c086715db87094bc3d0a4fefdd80bd869cTimo Sirainen#ifndef BUILTIN_GSSAPI
f97cf1c086715db87094bc3d0a4fefdd80bd869cTimo Sirainenvoid mech_gssapi_init(void);
f97cf1c086715db87094bc3d0a4fefdd80bd869cTimo Sirainenvoid mech_gssapi_deinit(void);
f97cf1c086715db87094bc3d0a4fefdd80bd869cTimo Sirainen
f97cf1c086715db87094bc3d0a4fefdd80bd869cTimo Sirainenvoid mech_gssapi_init(void)
f97cf1c086715db87094bc3d0a4fefdd80bd869cTimo Sirainen{
f97cf1c086715db87094bc3d0a4fefdd80bd869cTimo Sirainen mech_register_module(&mech_gssapi);
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen#ifdef HAVE_GSSAPI_SPNEGO
6e873f135368bcfdd1de4458dded791d0c4d00cdTimo Sirainen if (getenv("NTLM_USE_WINBIND") == NULL)
6e873f135368bcfdd1de4458dded791d0c4d00cdTimo Sirainen mech_register_module(&mech_gssapi_spnego);
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen#endif
f97cf1c086715db87094bc3d0a4fefdd80bd869cTimo Sirainen}
f97cf1c086715db87094bc3d0a4fefdd80bd869cTimo Sirainen
f97cf1c086715db87094bc3d0a4fefdd80bd869cTimo Sirainenvoid mech_gssapi_deinit(void)
f97cf1c086715db87094bc3d0a4fefdd80bd869cTimo Sirainen{
f97cf1c086715db87094bc3d0a4fefdd80bd869cTimo Sirainen mech_unregister_module(&mech_gssapi);
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen#ifdef HAVE_GSSAPI_SPNEGO
6e873f135368bcfdd1de4458dded791d0c4d00cdTimo Sirainen if (getenv("NTLM_USE_WINBIND") == NULL)
6e873f135368bcfdd1de4458dded791d0c4d00cdTimo Sirainen mech_unregister_module(&mech_gssapi_spnego);
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen#endif
f97cf1c086715db87094bc3d0a4fefdd80bd869cTimo Sirainen}
f97cf1c086715db87094bc3d0a4fefdd80bd869cTimo Sirainen#endif
f97cf1c086715db87094bc3d0a4fefdd80bd869cTimo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen#endif