--- 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 <peter@ifm.liu.se> - 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);
 }
 
