dovecot-1.1: Support cross-realm krb5 authentication. Based on p...

dovecot at dovecot.org dovecot at dovecot.org
Sun May 4 04:27:44 EEST 2008


details:   http://hg.dovecot.org/dovecot-1.1/rev/841209428d2d
changeset: 7477:841209428d2d
user:      Timo Sirainen <tss at iki.fi>
date:      Sun May 04 04:27:41 2008 +0300
description:
Support cross-realm krb5 authentication. Based on patch by Zachary Kotlarek.

diffstat:

1 file changed, 69 insertions(+)
src/auth/mech-gssapi.c |   69 ++++++++++++++++++++++++++++++++++++++++++++++++

diffs (111 lines):

diff -r 2475c57fadb0 -r 841209428d2d src/auth/mech-gssapi.c
--- a/src/auth/mech-gssapi.c	Sun May 04 03:44:09 2008 +0300
+++ b/src/auth/mech-gssapi.c	Sun May 04 04:27:41 2008 +0300
@@ -23,10 +23,21 @@
 
 #ifdef HAVE_GSSAPI
 
+#ifndef HAVE___GSS_USEROK
+#  define USE_KRB5_USEROK
+#  include <krb5.h>
+#endif
+
 #ifdef HAVE_GSSAPI_GSSAPI_H
 #  include <gssapi/gssapi.h>
+#  ifdef USE_KRB5_USEROK
+#    include <gssapi/gssapi_krb5.h>
+#  endif
 #elif defined (HAVE_GSSAPI_H)
 #  include <gssapi.h>
+#  ifdef USE_KRB5_USEROK
+#    include <gssapi_krb5.h>
+#  endif
 #endif
 
 #ifdef HAVE_GSSAPI_GSSAPI_EXT_H
@@ -156,6 +167,7 @@ static OM_uint32 obtain_service_credenti
 	return major_status;
 }
 
+#ifndef HAVE___GSS_USEROK
 static gss_name_t
 import_name(struct auth_request *request, void *str, size_t len)
 {
@@ -177,6 +189,7 @@ import_name(struct auth_request *request
 
 	return name;
 }
+#endif
 
 static void gssapi_sec_context(struct gssapi_auth_request *request,
 			       gss_buffer_desc inbuf)
@@ -271,6 +284,58 @@ static void gssapi_wrap(struct gssapi_au
 	request->sasl_gssapi_state = GSS_STATE_UNWRAP;
 }
 
+#ifdef USE_KRB5_USEROK
+static bool gssapi_krb5_userok(struct gssapi_auth_request *request)
+{
+	krb5_context ctx;
+	krb5_principal princ;
+	krb5_error_code krb5_err;
+	OM_uint32 major_status, minor_status;
+	gss_buffer_desc princ_name;
+	gss_OID name_type;
+	const char *princ_display_name;
+	bool ret = FALSE;
+
+	/* Parse out the principal's username */
+	major_status = gss_display_name(&minor_status, request->authn_name,
+					&princ_name, &name_type);
+	if (major_status != GSS_S_COMPLETE) {
+		auth_request_log_gss_error(&request->auth_request, major_status,
+					   GSS_C_GSS_CODE,
+					   "gssapi_krb5_userok");
+		return FALSE;
+	}
+	if (name_type != GSS_KRB5_NT_PRINCIPAL_NAME) {
+		auth_request_log_error(&request->auth_request, "gssapi",
+				       "OID not kerberos principal name");
+		return FALSE;
+	}
+	princ_display_name = t_strndup(princ_name.value, princ_name.length);
+	gss_release_buffer(&minor_status, &princ_name);
+
+	/* Init a krb5 context and parse the principal username */
+	krb5_err = krb5_init_context(&ctx);
+	if (krb5_err != 0) {
+		auth_request_log_error(&request->auth_request, "gssapi",
+			"krb5_init_context() failed: %d", (int)krb5_err);
+		return FALSE;
+	}
+	krb5_err = krb5_parse_name(ctx, princ_display_name, &princ);
+	if (krb5_err != 0) {
+		auth_request_log_error(&request->auth_request, "gssapi",
+				       "krb5_parse_name() failed: %s",
+				       krb5_get_error_message(ctx, krb5_err));
+	} else {
+		/* See if the principal is authorized to act as the
+		   specified user */
+		ret = krb5_kuserok(ctx, princ, request->auth_request.user);
+		krb5_free_principal(ctx, princ);
+	}
+	krb5_free_context(ctx);
+	return ret;
+}
+#endif
+
 static void gssapi_unwrap(struct gssapi_auth_request *request,
 			  gss_buffer_desc inbuf)
 {
@@ -344,6 +409,10 @@ static void gssapi_unwrap(struct gssapi_
 					request->authn_name,
 					request->authz_name,
 					&equal_authn_authz);
+#ifdef USE_KRB5_USEROK
+	if (equal_authn_authz == 0)
+		equal_authn_authz = gssapi_krb5_userok(request);
+#endif
 	if (equal_authn_authz == 0) {
 		auth_request_log_error(&request->auth_request, "gssapi",
 			"authn_name and authz_name differ: not supported");


More information about the dovecot-cvs mailing list