We use fully qualified principal names in our Webauth service ("WebKdcLocalRealms none").
When we recently added HTTP Negotiate support to the login page, we found that in Webauth's REMOTE_USER support, the set of permitted realms and the set of realms for which Webauth strips off the realm name were both controlled by a single setting: @REMUSER_REALMS. This left us unable to enable our local realm, whilst leaving the full principal name intact. It also left us unable to configure this part of Webauth not to care which realms it was able to deal with, and just leave it to the cross-realm relationships. In mod_webkdc, this is done by leaving WebKdcPermittedRealms unset. The attached patch introduces separate @REMUSER_PERMITTED_REALMS and @REMUSER_LOCAL_REALMS settings. Both of these can be set to the same value via @REMUSER_REALMS, thus providing backwards compatibility. Using this patch has allowed us to meet our site's requirements. This does change the semantics of leaving @REMUSER_REALMS unset from "all denied" to "all permitted", so it's not completely backwards compatible. For this to be an issue, someone would have to be currently running with $REMUSER_ENABLED on, but relying on @REMUSER_REALMS being empty to disallow all authentications via this mechanism. If this is judged to be realistic, the patch may need a bit of redesign. Tom Jones.
diff -ruN webauth-4.3.1.orig/docs/install-spnego webauth-4.3.1/docs/install-spnego --- webauth-4.3.1.orig/docs/install-spnego 2012-08-09 03:59:55.000000000 +0100 +++ webauth-4.3.1/docs/install-spnego 2012-08-28 18:12:59.307744850 +0100 @@ -69,16 +69,21 @@ $REMUSER_ENABLED = 1; $REMUSER_EXPIRES = 60 * 60 * 8; - @REMUSER_REALMS = ("EXAMPLE.COM"); + @REMUSER_PERMITTED_REALMS = ("EXAMPLE.COM"); # optionally restrict + @REMUSER_LOCAL_REALMS = ("EXAMPLE.COM"); # optionally strip realm name The first line tells the WebLogin script to trust REMOTE_USER as set by Apache if present (so make sure that there isn't a way of accessing the script via an Apache authentication mechanism that you don't trust!). The second line says how good authentication via REMOTE_USER should be valid for (see Notes and Cautions below). The third line tells it what - realm to strip off the REMOTE_USER variable, since mod_auth_kerb sets - REMOTE_USER to the full principal name. It should be your local default - realm. + realms to allow authentication for (if this is unset, control of this remains + with the underlying Kerberos service, including any cross-realm + relationships that have been established). The fourth line declares + which realm names should be stripped off the REMOTE_USER variable + before being passed on to the Webauth-enabled Application Servers. + Depending on local practice, this may be set to your local default + realm, or left unset. You will also need to set $KEYRING_PATH if your WebKDC keyring is not located in ../conf/webkdc/keyring relative to your server root. For diff -ruN webauth-4.3.1.orig/docs/weblogin-config webauth-4.3.1/docs/weblogin-config --- webauth-4.3.1.orig/docs/weblogin-config 2012-08-09 03:59:55.000000000 +0100 +++ webauth-4.3.1/docs/weblogin-config 2012-08-27 23:26:16.535123487 +0100 @@ -259,30 +259,52 @@ from REMOTE_USER will expire after this many seconds (given as a number). Default: 28800 (eight hours). - @REMUSER_REALMS (was @REALMS) + @REMUSER_LOCAL_REALMS - Only used when $REMUSER_ENABLED is set. If this variable is set, - everything after the @ sign in REMOTE_USER must match one of the - values in this list and is stripped before creating the - authenticated user identity. This variable is equivalent to the - combination of WebKdcLocalRealms and WebKdcPermittedRealms in the - mod_webkdc configuration but must be set separately due to how - Apache authentication is supported. + Only used when $REMUSER_ENABLED is set. If the realm + matches any of the listed realms, the realm information will be + stripped off. By default, this list is empty, so all principal + names will be passed on fully qualified. + + This setting is semantically similar to WebKdcLocalRealms in + the mod_webkdc configuration. An example setting: - @REALMS = ("stanford.edu", "WIN.STANFORD.EDU", ""); + @REMUSER_LOCAL_REALMS = ("stanford.edu", "WIN.STANFORD.EDU"); - As demonstrated in this example, realms should be listed in - parentheses and separated by commas. "" (the empty realm) is an + @REMUSER_PERMITTED_REALMS + + Only used when $REMUSER_ENABLED is set. If set, then authentication + is only permitted if the realm is a member of this list (that is, + everything after the @ sign in REMOTE_USER must match one of the + values in this list). If unset, there is no restriction on which + realms are permitted. + + This setting is semantically similar to WebKdcPermittedRealms in + the mod_webkdc configuration. + + "" (the empty realm) is an allowable value and means to allow REMOTE_USER settings that contain - no realm information (do not contain a @-sign). If the realm - matches any of the allowable realms, the realm information will be - stripped off. - - If this variable is not set, the REMOTE_USER information must not - contain an @. If it does, it will be ignored and login will proceed - as if it weren't set. + no realm information (do not contain a @-sign). + + If @REMUSER_PERMITTED_REALMS is unset, the possible set of realms + is determined by the underlying Kerberos service, including + any cross-realm relationships that exist. + + An example setting: + + @REMUSER_PERMITTED_REALMS = ("stanford.edu", "WIN.STANFORD.EDU", ""); + + @REMUSER_REALMS (was @REALMS) + + Convenience (and backwards compatibility) setting to allow both + @REMUSER_LOCAL_REALMS and @REMUSER_PERMITTED_REALMS to be set to + the same value. + + An example setting: + + @REMUSER_REALMS = ("stanford.edu", "WIN.STANFORD.EDU", ""); Default: not set. diff -ruN webauth-4.3.1.orig/perl/lib/WebKDC/Config.pm webauth-4.3.1/perl/lib/WebKDC/Config.pm --- webauth-4.3.1.orig/perl/lib/WebKDC/Config.pm 2012-08-09 03:59:55.000000000 +0100 +++ webauth-4.3.1/perl/lib/WebKDC/Config.pm 2012-08-27 18:54:31.017824483 +0100 @@ -38,6 +38,8 @@ our $REMUSER_ENABLED; our $REMUSER_EXPIRES = 60 * 60 * 8; our @REMUSER_REALMS; +our @REMUSER_PERMITTED_REALMS; +our @REMUSER_LOCAL_REALMS; our $REMUSER_REDIRECT; our @SHIBBOLETH_IDPS; our $TOKEN_ACL; @@ -84,6 +86,12 @@ if (defined ($REALM)) { push (@REMUSER_REALMS, $REALM); } +if (@REMUSER_REALMS and not @REMUSER_PERMITTED_REALMS) { + @REMUSER_PERMITTED_REALMS = @REMUSER_REALMS; +} +if (@REMUSER_REALMS and not @REMUSER_LOCAL_REALMS) { + @REMUSER_LOCAL_REALMS = @REMUSER_REALMS; +} 1; diff -ruN webauth-4.3.1.orig/perl/lib/WebLogin.pm webauth-4.3.1/perl/lib/WebLogin.pm --- webauth-4.3.1.orig/perl/lib/WebLogin.pm 2012-08-09 03:59:55.000000000 +0100 +++ webauth-4.3.1/perl/lib/WebLogin.pm 2012-08-28 01:32:19.917620950 +0100 @@ -906,14 +906,12 @@ return; } - # Make sure that any realm in REMOTE_USER matches the realm specified in - # our configuration file. Note that if a realm is specified in the - # configuration file, it must be present in REMOTE_USER. + # Make sure that any realm in REMOTE_USER is permitted. my ($user, $realm) = split ('@', $ENV{REMOTE_USER}, 2); - if (@WebKDC::Config::REMUSER_REALMS) { + if (@WebKDC::Config::REMUSER_PERMITTED_REALMS) { my $found = 0; $realm ||= ''; - for my $check (@WebKDC::Config::REMUSER_REALMS) { + for my $check (@WebKDC::Config::REMUSER_PERMITTED_REALMS) { if ($check eq $realm) { $found = 1; last; @@ -925,17 +923,19 @@ . "\n"; return; } - } elsif ($realm) { - warn "weblogin: found realm in REMOTE_USER but no realm configured\n"; - return; } + my $onward_username = + (grep { $realm eq $_ } @WebKDC::Config::REMUSER_LOCAL_REALMS) + ? $user + : $ENV{REMOTE_USER}; + # Create a proxy token. my $token = WebAuth::Token::WebKDCProxy->new ($wa); - $token->subject ($user); + $token->subject ($onward_username); $token->proxy_type ('remuser'); $token->proxy_subject ('WEBKDC:remuser'); - $token->data ($user); + $token->data ($onward_username); $token->creation (time); $token->expiration (time + $WebKDC::Config::REMUSER_EXPIRES); @@ -945,7 +945,7 @@ # and omit the level of assurance. my $session_factor; if (defined (&WebKDC::Config::remuser_factors)) { - my ($ini, $sess, $loa) = WebKDC::Config::remuser_factors ($user); + my ($ini, $sess, $loa) = WebKDC::Config::remuser_factors ($onward_username); $token->initial_factors ($ini); $token->loa ($loa) if (defined ($loa) && $loa > 0); $session_factor = $sess;