I've been trying to track down some problems with Dovecot in a Kerberos 5 cross-realm environment, and there seem to be a few issues. LOGIN/PLAIN work fine using pam_krb5, but GSSAPI is a bit harder to handle.
On line 436 of src/auth/mech-gssapi.c, the authn_name and the authz_name are compared using gss_compare_name. This dates back to the message at: http://dovecot.org/pipermail/dovecot/2005-October/009615.html While everything within that message is true, as things stand, Dovecot is unusable in a cross-realm environment. When cross-realm tickets are used, the authn_name is "usern...@realm" and the authz_name is "username" (or vice versa, I don't remember). The attached patch causes dovecot to display these two values in human-readable format to illustrate the issue. Because these two GSS names differ, Dovecot refuses to allow access in spite of the fact that krb5_kuserok would return TRUE. I am not the only one to have noticed this problem: http://dovecot.org/pipermail/dovecot/2007-July/023868.html http://dovecot.org/pipermail/dovecot/2007-October/026027.html Might I suggest that some more robust security checking be done instead of abusing gss_compare_name like this? I don't know how to do this using GSSAPI, but on the Kerberos side Heimdal provides the function krb5_kuserok. Dovecot could also just have a configurable file listing acceptable krb5 principals (preferably in .k5login syntax) and check that both auth_name and authz_name are in the list. Bryan Jacobs
Index: dovecot-1.1.11/src/auth/mech-gssapi.c =================================================================== --- dovecot-1.1.11.orig/src/auth/mech-gssapi.c +++ dovecot-1.1.11/src/auth/mech-gssapi.c @@ -370,6 +370,11 @@ static void gssapi_unwrap(struct gssapi_ OM_uint32 major_status, minor_status; gss_buffer_desc outbuf; int equal_authn_authz = 0; + const char *princz_display_name; + const char *princn_display_name; + gss_buffer_desc princz_name; + gss_buffer_desc princn_name; + gss_OID name_type; major_status = gss_unwrap(&minor_status, request->gss_ctx, &inbuf, &outbuf, NULL, NULL); @@ -444,8 +449,20 @@ static void gssapi_unwrap(struct gssapi_ if (equal_authn_authz == 0) { auth_request_log_error(&request->auth_request, "gssapi", "authn_name and authz_name differ: not supported"); - auth_request_fail(&request->auth_request); - return; + major_status = gss_display_name(&minor_status, request->authz_name, + &princz_name, &name_type); + princz_display_name = t_strndup(princz_name.value, princz_name.length); + gss_release_buffer(&minor_status, &princz_name); + auth_request_log_error(&request->auth_request, "gssapi", + princz_display_name); + major_status = gss_display_name(&minor_status, request->authn_name, + &princn_name, &name_type); + princn_display_name = t_strndup(princn_name.value, princn_name.length); + gss_release_buffer(&minor_status, &princn_name); + auth_request_log_error(&request->auth_request, "gssapi", + princn_display_name); +// auth_request_fail(&request->auth_request); +// return; } #endif auth_request_success(&request->auth_request, NULL, 0);
signature.asc
Description: PGP signature