struct shib_server_config
{
char* szScheme;
+ int bCompatValidUser;
};
// creates the per-server configuration
{
shib_server_config* sc=(shib_server_config*)ap_pcalloc(p,sizeof(shib_server_config));
sc->szScheme = nullptr;
+ sc->bCompatValidUser = -1;
return sc;
}
else
sc->szScheme=nullptr;
+ sc->bCompatValidUser = ((child->bCompatValidUser==-1) ? parent->bCompatValidUser : child->bCompatValidUser);
+
return sc;
}
#else
shib_request_config* rc = (shib_request_config*)ap_get_module_config(r->request_config, &mod_shib);
if (!rc || !rc->sta) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, SH_AP_R(r), "shib_handler found no per-request structure");
- return SERVER_ERROR;
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, SH_AP_R(r), "shib_handler found no per-request structure");
+ shib_post_read(r); // ensures objects are created if post_read hook didn't run
+ rc = (shib_request_config*)ap_get_module_config(r->request_config, &mod_shib);
}
ShibTargetApache* psta = rc->sta;
#endif
#else
shib_request_config* rc = (shib_request_config*)ap_get_module_config(r->request_config, &mod_shib);
if (!rc || !rc->sta) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, SH_AP_R(r), "shib_auth_checker found no per-request structure");
- return SERVER_ERROR;
+ ap_log_rerror(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, SH_AP_R(r), "shib_auth_checker found no per-request structure");
+ shib_post_read(r); // ensures objects are created if post_read hook didn't run
+ rc = (shib_request_config*)ap_get_module_config(r->request_config, &mod_shib);
}
ShibTargetApache* psta = rc->sta;
#endif
request.log(SPRequest::SPDebug, "htaccess: accepting valid-user based on active session");
status = true;
}
+ else if (sta->m_dc->bCompatWith24 == 1 && !strcmp(w,"shib-session") && session) {
+ request.log(SPRequest::SPDebug, "htaccess: accepting shib-session based on active session");
+ status = true;
+ }
else if (!strcmp(w,"user") && !remote_user.empty()) {
status = (doUser(*sta, t) == shib_acl_true);
}
+ else if (sta->m_dc->bCompatWith24 == 1 && !strcmp(w,"shib-user") && !remote_user.empty()) {
+ status = (doUser(*sta, t) == shib_acl_true);
+ }
else if (!strcmp(w,"group") && !remote_user.empty()) {
status = (doGroup(*sta, t) == shib_acl_true);
}
return AUTHZ_GRANTED;
}
-extern "C" authz_status shib_validuser_check_authz(request_rec* r, const char* require_line, const void*)
+extern "C" authz_status shib_session_check_authz(request_rec* r, const char* require_line, const void*)
{
pair<ShibTargetApache*,authz_status> sta = shib_base_check_authz(r);
if (!sta.first)
Session* session = sta.first->getSession(false, true, false);
Locker slocker(session, false);
if (session) {
- sta.first->log(SPRequest::SPDebug, "htaccess: accepting valid-user based on active session");
+ sta.first->log(SPRequest::SPDebug, "htaccess: accepting shib-session/valid-user based on active session");
return AUTHZ_GRANTED;
}
}
sta.first->log(SPRequest::SPWarn, string("htaccess: unable to obtain session for access control check: ") + e.what());
}
+ sta.first->log(SPRequest::SPDebug, "htaccess: denying shib-access/valid-user rule, no active session");
return AUTHZ_DENIED_NO_USER;
}
-extern "C" authz_status shib_user_check_authz(request_rec* r, const char* require_line, const void*)
+extern "C" authz_status shib_validuser_check_authz(request_rec* r, const char* require_line, const void*)
{
- if (!r->user || !*(r->user))
+ // Shouldn't have actually ever hooked this, and now we're in conflict with mod_authz_user over the meaning.
+ // For now, added a command to restore "normal" semantics for valid-user so that combined deployments can
+ // use valid-user for non-Shibboleth cases and shib-session for the Shibboleth semantic.
+
+ // In future, we may want to expose the AuthType set to honor down at this level so we can differentiate
+ // based on AuthType. Unfortunately we allow overriding the AuthType to honor and we don't have access to
+ // that setting from the ServiceProvider class..
+
+ shib_server_config* sc = (shib_server_config*)ap_get_module_config(r->server->module_config, &mod_shib);
+ if (sc->bCompatValidUser != 1) {
+ return shib_session_check_authz(r, require_line, nullptr);
+ }
+
+ // Reproduce mod_authz_user version...
+
+ if (!r->user) {
return AUTHZ_DENIED_NO_USER;
+ }
+
+ return AUTHZ_GRANTED;
+}
+
+extern "C" authz_status shib_ext_user_check_authz(request_rec* r, const char* require_line, const void*)
+{
pair<ShibTargetApache*,authz_status> sta = shib_base_check_authz(r);
if (!sta.first)
return sta.second;
return AUTHZ_DENIED;
}
+extern "C" authz_status shib_user_check_authz(request_rec* r, const char* require_line, const void*)
+{
+ // Shouldn't have actually ever hooked this, and now we're in conflict with mod_authz_user over the meaning.
+ // For now, added a command to restore "normal" semantics for user rules so that combined deployments can
+ // use user for non-Shibboleth cases and shib-user for the Shibboleth semantic.
+
+ // In future, we may want to expose the AuthType set to honor down at this level so we can differentiate
+ // based on AuthType. Unfortunately we allow overriding the AuthType to honor and we don't have access to
+ // that setting from the ServiceProvider class..
+
+ shib_server_config* sc = (shib_server_config*)ap_get_module_config(r->server->module_config, &mod_shib);
+ if (sc->bCompatValidUser != 1) {
+ return shib_ext_user_check_authz(r, require_line, nullptr);
+ }
+
+ // Reproduce mod_authz_user version...
+
+ if (!r->user) {
+ return AUTHZ_DENIED_NO_USER;
+ }
+
+ const char* t = require_line;
+ const char *w;
+ while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
+ if (!strcmp(r->user, w)) {
+ return AUTHZ_GRANTED;
+ }
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01663)
+ "access to %s failed, reason: user '%s' does not meet "
+ "'require'ments for user to be allowed access",
+ r->uri, r->user);
+
+ return AUTHZ_DENIED;
+}
+
extern "C" authz_status shib_acclass_check_authz(request_rec* r, const char* require_line, const void*)
{
pair<ShibTargetApache*,authz_status> sta = shib_base_check_authz(r);
return nullptr;
}
+extern "C" const char* shib_set_server_flag_slot(cmd_parms* parms, void*, int arg)
+{
+ char* base=(char*)ap_get_module_config(parms->server->module_config,&mod_shib);
+ size_t offset=(size_t)parms->info;
+ *((int*)(base + offset)) = arg;
+ return nullptr;
+}
+
extern "C" const char* shib_ap_set_file_slot(cmd_parms* parms,
#ifdef SHIB_APACHE_13
char* arg1, char* arg2
#ifdef SHIB_APACHE_24
extern "C" const authz_provider shib_authz_shibboleth_provider = { &shib_shibboleth_check_authz, nullptr };
extern "C" const authz_provider shib_authz_validuser_provider = { &shib_validuser_check_authz, nullptr };
+extern "C" const authz_provider shib_authz_session_provider = { &shib_session_check_authz, nullptr };
extern "C" const authz_provider shib_authz_user_provider = { &shib_user_check_authz, nullptr };
+extern "C" const authz_provider shib_authz_ext_user_provider = { &shib_ext_user_check_authz, nullptr };
extern "C" const authz_provider shib_authz_acclass_provider = { &shib_acclass_check_authz, nullptr };
extern "C" const authz_provider shib_authz_acdecl_provider = { &shib_acdecl_check_authz, nullptr };
extern "C" const authz_provider shib_authz_attr_provider = { &shib_attr_check_authz, nullptr };
#ifdef SHIB_APACHE_24
ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "shibboleth", AUTHZ_PROVIDER_VERSION, &shib_authz_shibboleth_provider, AP_AUTH_INTERNAL_PER_CONF);
ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "valid-user", AUTHZ_PROVIDER_VERSION, &shib_authz_validuser_provider, AP_AUTH_INTERNAL_PER_CONF);
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "shib-session", AUTHZ_PROVIDER_VERSION, &shib_authz_session_provider, AP_AUTH_INTERNAL_PER_CONF);
ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "user", AUTHZ_PROVIDER_VERSION, &shib_authz_user_provider, AP_AUTH_INTERNAL_PER_CONF);
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "shib-user", AUTHZ_PROVIDER_VERSION, &shib_authz_ext_user_provider, AP_AUTH_INTERNAL_PER_CONF);
ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "authnContextClassRef", AUTHZ_PROVIDER_VERSION, &shib_authz_acclass_provider, AP_AUTH_INTERNAL_PER_CONF);
ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "authnContextDeclRef", AUTHZ_PROVIDER_VERSION, &shib_authz_acdecl_provider, AP_AUTH_INTERNAL_PER_CONF);
ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "shib-attr", AUTHZ_PROVIDER_VERSION, &shib_authz_attr_provider, AP_AUTH_INTERNAL_PER_CONF);
AP_INIT_FLAG("ShibRequestMapperAuthz", (config_fn_t)ap_set_flag_slot,
(void *) offsetof (shib_dir_config, bRequestMapperAuthz),
OR_AUTHCFG, "Support access control via shibboleth2.xml / RequestMapper"),
+ AP_INIT_FLAG("ShibCompatValidUser", (config_fn_t)shib_set_server_flag_slot,
+ (void *) offsetof (shib_server_config, bCompatValidUser),
+ RSRC_CONF, "Handle 'require valid-user' in mod_authz_user-compatible fashion (requiring username)"),
#else
AP_INIT_TAKE1("AuthGroupFile", (config_fn_t)shib_ap_set_file_slot,
(void *) offsetof (shib_dir_config, szAuthGrpFile),