Please find enclosed two patch files (one for configure.in and one for src/mech/auth-gssapi.c) that fixes a problem in the GSSAPI code that prevented Dovecot to successfully authenticate when using cross-realm
Kerberos credentials.

Unfortunately I think it'll only work on Solaris (it uses the undocummented call __gss_userok() - however I think that there have been proposals on making that into an official one called gss_userok() - so perhaps some operating systems already have it? It basically calls the underlying krb5_userok() function that does the right stuff).

Our setup is like this:

1. Windows XP PC that authenticates against a normal Windows 2003
   AD server in the AD realm "AD.IFM.LIU.SE"

2. Solaris 10 server that authenticates against a normal Kerberos KDC
   in the Kerberos realm "IFM.LIU.SE"

3. Cross-realm trust between AD.IFM.LIU.SE and IFM.LIU.SE has been
   configured (varios steps needed - both on the Unix side and on the
   Windows sides (both on the AD servers and on the client).

4. On the Solaris server the /etc/krb5/krb5.conf files has been
   configured like this:
[
   libdefaults]
        default_realm = IFM.LIU.SE

   [realms]
        IFM.LIU.SE = {
                kdc = as-master.ifm.liu.se
                kdc = as-slave.ifm.liu.se
                admin_server = as-master.ifm.liu.se
                auth_to_local_realm = AD.IFM.LIU.SE
        }

        AD.IFM.LIU.SE = {
                kdc = ad-master.ad.ifm.liu.se
                kdc = ad-slave.ad.ifm.liu.se
                admin_server = ad-master.ifm.liu.se
                kpasswd_protocol = SET_CHANGE
        }

5. I use Thunderbird 2 on the PC to connect to the Dovecot server with
   the AD-aquired credentials and with the patch above it works
   correctly.

Without the patch then Dovecot will fail since the code that does
the GSSAPI authentication fails at gss_compare_names().
(that code only works if the credentials used are from the local realm)

(The cross-realm setup also works with Quest Putty so you can do passwordless SSH logins from your AD-connected PC to the Unix servers, and get a delegated AD ticket so that Secure NFS also works).

Storing of delegated tickets is something that my patch above doesn't solve. It shouldn't be that hard to implement though - you basically just have to call gss_store_cred() at the right place in Dovecot (when you've switched to the right userid, and preferable after having called some PAM setup functions) - can be useful if you ever want to run Dovecot and access a Secure NFS protected remote filesystem...

- Peter

--- dovecot-1.0.1/configure.in	Thu Jun 14 14:01:28 2007
+++ dovecot-1.0.1-ifm/configure.in	Mon Jul  2 17:45:47 2007
@@ -1484,10 +1484,15 @@
 			# have gssapi.h
 			old_CFLAGS=$CFLAGS
 			CFLAGS="$CFLAGS `krb5-config --cflags gssapi`"
+			old_LIBS=$LIBS
+			LIBS="$LIBS `krb5-config --libs gssapi`"
 			AC_CHECK_HEADER([gssapi/gssapi.h], [
 				AC_DEFINE(HAVE_GSSAPI_GSSAPI_H,, GSSAPI headers in gssapi/gssapi.h)
 				have_gssapi=yes
 			])
+			AC_CHECK_HEADER([gssapi/gssapi_ext.h], [
+				AC_DEFINE(HAVE_GSSAPI_GSSAPI_EXT_H,, GSSAPI headers in gssapi/gssapi_ext.h)
+			])
 			AC_CHECK_HEADER([gssapi.h], [
 				AC_DEFINE(HAVE_GSSAPI_H,, GSSAPI headers in gssapi.h)
 				have_gssapi=yes
@@ -1494,8 +1499,13 @@
 			])
 			if test $have_gssapi = yes; then
 				AC_DEFINE(HAVE_GSSAPI,, Build with GSSAPI support)
+				AC_CHECK_LIB(gss, __gss_userok, [
+					AC_DEFINE(HAVE___GSS_USEROK,,
+						Define if you have __gss_userok())
+				])
 			fi
 			CFLAGS=$old_CFLAGS
+			LIBS=$old_LIBS
 		fi
 	fi
 fi
--- dovecot-1.0.1/src/auth/mech-gssapi.c	Sat May 19 13:14:04 2007
+++ dovecot-1.0.1-ifm/src/auth/mech-gssapi.c	Mon Jul  2 17:51:23 2007
@@ -29,6 +29,10 @@
 #  include <gssapi.h>
 #endif
 
+#ifdef HAVE_GSSAPI_GSSAPI_EXT_H
+#  include <gssapi/gssapi_ext.h>
+#endif
+
 /* Non-zero flags defined in RFC 2222 */
 enum sasl_gssapi_qop {
 	SASL_GSSAPI_QOP_UNSPECIFIED = 0x00,
@@ -163,8 +167,13 @@
 	name_buf.length = len;
 	major_status = gss_import_name(&minor_status,
 				       &name_buf,
+#if 0 /* Added 070702 Peter Eriksson <[EMAIL PROTECTED]> - ref cyrus-sasl Solaris 8/9 has problems with NO_OID */
+				       GSS_C_NT_USER_NAME,
+#else
 				       GSS_C_NO_OID,
+#endif
 				       &name);
+
 	if (GSS_ERROR(major_status)) {
 		auth_request_log_gss_error(request, major_status,
 					   GSS_C_GSS_CODE, "gss_import_name");
@@ -174,6 +183,7 @@
 	return name;
 }
 
+
 static void gssapi_sec_context(struct gssapi_auth_request *request,
 			       gss_buffer_desc inbuf)
 {
@@ -273,7 +283,9 @@
 	OM_uint32 major_status, minor_status;
 	gss_buffer_desc outbuf;
 	int equal_authn_authz = 0;
+	char *name;
 
+
 	major_status = gss_unwrap(&minor_status, request->gss_ctx, 
 				  &inbuf, &outbuf, NULL, NULL);
 
@@ -292,6 +304,44 @@
 		return;
 	}
 
+#ifdef HAVE___GSS_USEROK
+	/* __gss_userok() correctly handles cross-realm authentication, whereas the original code
+	   does not... */
+
+	name = p_strndup(request->auth_request.pool,
+			 (unsigned char *)outbuf.value + 4,
+			 outbuf.length - 4);
+
+	if (!name) {
+	  	auth_request_log_error(&request->auth_request, "gssapi",
+				       "Invalid response size");
+		auth_request_fail(&request->auth_request);
+		return;
+	}	    
+
+	major_status = __gss_userok(&minor_status, request->authn_name, name, &equal_authn_authz);
+	if (GSS_ERROR(major_status)) {
+		auth_request_log_gss_error(&request->auth_request, major_status,
+					   GSS_C_GSS_CODE,
+					   "__gss_userok failed");
+		free(name);
+		auth_request_fail(&request->auth_request);
+		return;
+	} 
+
+	if (equal_authn_authz == 0) {
+		auth_request_log_error(&request->auth_request, "gssapi",
+				       "credentials is not valid for account: %s", name);
+
+		free(name);
+		auth_request_fail(&request->auth_request);
+		return;
+	}
+
+	request->auth_request.user = name;
+
+#else
+
 	request->authz_name = import_name(&request->auth_request,
 					  (unsigned char *)outbuf.value + 4,
 					  outbuf.length - 4);
@@ -307,9 +357,11 @@
 					request->authn_name,
 					request->authz_name,
 					&equal_authn_authz);
+
 	if (equal_authn_authz == 0) {
 		auth_request_log_error(&request->auth_request, "gssapi",
-			"authn_name and authz_name differ: not supported");
+				       "authn_name and authz_name differ: not supported");
+
 		auth_request_fail(&request->auth_request);
 		return;
 	}
@@ -319,6 +371,7 @@
 			  (unsigned char *)outbuf.value + 4,
 			  outbuf.length - 4);
 
+#endif
 	auth_request_success(&request->auth_request, NULL, 0);
 }
 
begin:vcard
fn:Peter Eriksson
n:Eriksson;Peter
org;quoted-printable:Link=C3=B6ping University;Physics Department
adr;quoted-printable:;;;Link=C3=B6ping;;SE-58183;Sweden
email;internet:[EMAIL PROTECTED]
title:Computer Systems Manager
tel;work:+46-13-282786
tel;fax:+46-13-137568
tel;home:+46-13-55255
tel;cell:+46-705-182786
x-mozilla-html:FALSE
url:http://people.ifm.liu.se/peter
version:2.1
end:vcard

Reply via email to