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;
}
#endif
};
-// create a request record
-static shib_request_config* init_request_config(request_rec *r)
+// create or return a request record
+static shib_request_config* get_request_config(request_rec *r)
{
- shib_request_config* rc = (shib_request_config*)ap_pcalloc(r->pool,sizeof(shib_request_config));
- memset(rc, 0, sizeof(shib_request_config));
- ap_set_module_config(r->request_config, &mod_shib, rc);
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, SH_AP_R(r), "shib_init_rc");
+ shib_request_config* rc = (shib_request_config*)ap_get_module_config(r->request_config, &mod_shib);
+ if (rc) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, SH_AP_R(r), "get_request_config called redundantly");
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, SH_AP_R(r), "get_request_config created per-request structure");
+ rc = (shib_request_config*)ap_pcalloc(r->pool,sizeof(shib_request_config));
+ memset(rc, 0, sizeof(shib_request_config));
+ ap_set_module_config(r->request_config, &mod_shib, rc);
+ }
return rc;
}
if (!m_rc) {
// this happens on subrequests
// ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(m_req), "shib_setheader: no_m_rc\n");
- m_rc = init_request_config(m_req);
+ m_rc = get_request_config(m_req);
}
if (!m_rc->env)
m_rc->env = ap_make_table(m_req->pool, 10);
#ifdef SHIB_DEFERRED_HEADERS
if (!m_rc)
// this happens on subrequests
- m_rc = init_request_config(m_req);
+ m_rc = get_request_config(m_req);
if (m_handler) {
if (!m_rc->hdr_out)
m_rc->hdr_out = ap_make_table(m_req->pool, 5);
// Apache hooks
#ifndef SHIB_APACHE_13
-extern "C" apr_status_t shib_request_cleanup(void* r)
+extern "C" apr_status_t shib_request_cleanup(void* rc)
{
- if (r)
- delete reinterpret_cast<ShibTargetApache*>(r);
+ if (rc && reinterpret_cast<shib_request_config*>(rc)->sta) {
+ delete reinterpret_cast<ShibTargetApache*>(reinterpret_cast<shib_request_config*>(rc)->sta);
+ reinterpret_cast<shib_request_config*>(rc)->sta = nullptr;
+ }
return APR_SUCCESS;
}
#endif
-// Initial look at a request - create the per-request structure
+// Initial look at a request - create the per-request structure if need be
static int shib_post_read(request_rec *r)
{
- shib_request_config* rc = init_request_config(r);
+ shib_request_config* rc = get_request_config(r);
#ifdef SHIB_APACHE_24
- rc->sta = new ShibTargetApache(r);
- apr_pool_cleanup_register(r->pool, rc->sta, shib_request_cleanup, apr_pool_cleanup_null);
+ if (!rc->sta) {
+ rc->sta = new ShibTargetApache(r);
+ apr_pool_cleanup_register(r->pool, rc, shib_request_cleanup, apr_pool_cleanup_null);
+ }
#endif
return DECLINED;
}
if (((shib_dir_config*)ap_get_module_config(r->per_dir_config, &mod_shib))->bOff == 1)
return DECLINED;
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, SH_AP_R(r), "shib_check_user(%d): ENTER", (int)getpid());
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, SH_AP_R(r), "shib_check_user entered in pid (%d)", (int)getpid());
string threadid("[");
threadid += lexical_cast<string>(getpid()) + "] shib_check_user";
#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_check_user found no per-request structure");
- return SERVER_ERROR;
+ ap_log_rerror(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, SH_AP_R(r), "shib_check_user 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
pair<bool,long> res = psta->getServiceProvider().doAuthentication(*psta, true);
apr_pool_userdata_setn((const void*)42,g_UserDataKey,nullptr,r->pool);
// If directed, install a spoof key to recognize when we've already cleared headers.
- if (!g_spoofKey.empty() && (((shib_dir_config*)ap_get_module_config(r->per_dir_config, &mod_shib))->bUseHeaders==1))
+ if (!g_spoofKey.empty() && (((shib_dir_config*)ap_get_module_config(r->per_dir_config, &mod_shib))->bUseHeaders == 1))
ap_table_set(r->headers_in, "Shib-Spoof-Check", g_spoofKey.c_str());
if (res.first) {
#ifdef SHIB_APACHE_24
void* data;
apr_pool_userdata_get(&data,g_UserDataKey,r->pool);
if (data==(const void*)42) {
- ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_handler skipped since check_user ran");
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, SH_AP_R(r), "shib_handler skipped since check_user ran");
return DECLINED;
}
#endif
- ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_handler(%d): ENTER: %s", (int)getpid(), r->handler);
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, SH_AP_R(r), "shib_handler entered in pid (%d): %s", (int)getpid(), r->handler);
try {
#ifndef SHIB_APACHE_24
#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
pair<bool,long> res = psta->getServiceProvider().doHandler(*psta);
if (res.first) return res.second;
- ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, SH_AP_R(r), "doHandler() did not do anything.");
+ ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, SH_AP_R(r), "doHandler() did not handle the request");
return SERVER_ERROR;
}
catch (std::exception& e) {
return DECLINED;
}
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, SH_AP_R(r), "shib_auth_checker(%d): ENTER", (int)getpid());
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, SH_AP_R(r), "shib_auth_checker entered in pid (%d)", (int)getpid());
string threadid("[");
threadid += lexical_cast<string>(getpid()) + "] shib_auth_checker";
#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
// Overlays environment variables on top of subprocess table.
extern "C" int shib_fixups(request_rec* r)
{
- shib_dir_config *dc = (shib_dir_config*)ap_get_module_config(r->per_dir_config, &mod_shib);
- if (dc->bOff==1 || dc->bUseEnvVars==0)
- return DECLINED;
+ shib_dir_config *dc = (shib_dir_config*)ap_get_module_config(r->per_dir_config, &mod_shib);
+ if (dc->bOff==1 || dc->bUseEnvVars==0)
+ return DECLINED;
- ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r), "shib_fixup(%d): ENTER", (int)getpid());
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, SH_AP_R(r), "shib_fixups entered in pid (%d)", (int)getpid());
- shib_request_config *rc = (shib_request_config*)ap_get_module_config(r->request_config, &mod_shib);
- if (rc==nullptr || rc->env==nullptr || ap_is_empty_table(rc->env))
+ shib_request_config *rc = (shib_request_config*)ap_get_module_config(r->request_config, &mod_shib);
+ if (rc==nullptr || rc->env==nullptr || ap_is_empty_table(rc->env))
return DECLINED;
- ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r), "shib_fixup adding %d vars", ap_table_elts(rc->env)->nelts);
- r->subprocess_env = ap_overlay_tables(r->pool, r->subprocess_env, rc->env);
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, SH_AP_R(r), "shib_fixups adding %d vars", ap_table_elts(rc->env)->nelts);
+ r->subprocess_env = ap_overlay_tables(r->pool, r->subprocess_env, rc->env);
- return OK;
+ return OK;
}
const char *group_name, *ll, *w;
#ifdef SHIB_APACHE_13
- if (!(f=ap_pcfg_openfile(r->pool,grpfile))) {
+ if (!(f=ap_pcfg_openfile(r->pool, grpfile))) {
#else
if (ap_pcfg_openfile(&f,r->pool,grpfile) != APR_SUCCESS) {
#endif
- ap_log_rerror(APLOG_MARK,APLOG_DEBUG,SH_AP_R(r),"groups_for_user() could not open group file: %s\n",grpfile);
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, SH_AP_R(r), "groups_for_user: could not open group file: %s\n", grpfile);
return nullptr;
}
#else
if (apr_pool_create(&sp,r->pool) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,
- "groups_for_user() could not create a subpool");
+ "groups_for_user: could not create a subpool");
return nullptr;
}
#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);
}
}
// Authz callbacks for Apache 2.4
+// For some reason, these get run twice for each request, once before hooks like check_user, etc.
+// and once after. The first time through, the request object exists, but isn't initialized.
+// The other case is subrequests of some kinds: then post_read doesn't run, and the objects
+// themselves don't exist. We do deferred creation of the objects in check_user to fix that case.
+// In each screwed up case, we return "denied" so that nothing bad happens.
#ifdef SHIB_APACHE_24
pair<ShibTargetApache*,authz_status> shib_base_check_authz(request_rec* r)
{
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_base_check_authz found no per-request structure");
- return make_pair((ShibTargetApache*)nullptr, AUTHZ_GENERAL_ERROR);
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, SH_AP_R(r), "shib_base_check_authz found no per-request structure");
+ return make_pair((ShibTargetApache*)nullptr, AUTHZ_DENIED_NO_USER);
}
else if (!rc->sta->isInitialized()) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, SH_AP_R(r), "shib_base_check_authz found uninitialized request object");
return make_pair((ShibTargetApache*)nullptr, AUTHZ_DENIED_NO_USER);
}
return make_pair(rc->sta, AUTHZ_GRANTED);
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)
return sta.second;
try {
- const Session* session = sta.first->getSession(false);
+ 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);
const htAccessControl& hta = dynamic_cast<const ApacheRequestMapper*>(sta.first->getRequestSettings().first)->getHTAccessControl();
try {
- const Session* session = sta.first->getSession(false);
+ Session* session = sta.first->getSession(false, true, false);
+ Locker slocker(session, false);
if (session && hta.doAuthnContext(*sta.first, session->getAuthnContextClassRef(), require_line) == AccessControl::shib_acl_true)
return AUTHZ_GRANTED;
return session ? AUTHZ_DENIED : AUTHZ_DENIED_NO_USER;
const htAccessControl& hta = dynamic_cast<const ApacheRequestMapper*>(sta.first->getRequestSettings().first)->getHTAccessControl();
try {
- const Session* session = sta.first->getSession(false);
+ Session* session = sta.first->getSession(false, true, false);
+ Locker slocker(session, false);
if (session && hta.doAuthnContext(*sta.first, session->getAuthnContextDeclRef(), require_line) == AccessControl::shib_acl_true)
return AUTHZ_GRANTED;
return session ? AUTHZ_DENIED : AUTHZ_DENIED_NO_USER;
const htAccessControl& hta = dynamic_cast<const ApacheRequestMapper*>(sta.first->getRequestSettings().first)->getHTAccessControl();
try {
- const Session* session = sta.first->getSession(false);
+ Session* session = sta.first->getSession(false, true, false);
+ Locker slocker(session, false);
if (session) {
const char* rule = ap_getword_conf(r->pool, &require_line);
if (rule && hta.doShibAttr(*sta.first, session, rule, require_line) == AccessControl::shib_acl_true)
const htAccessControl& hta = dynamic_cast<const ApacheRequestMapper*>(sta.first->getRequestSettings().first)->getHTAccessControl();
try {
- const Session* session = sta.first->getSession(false);
+ Session* session = sta.first->getSession(false, true, false);
+ Locker slocker(session, false);
if (session) {
const char* config = ap_getword_conf(r->pool, &require_line);
if (config && hta.doAccessControl(*sta.first, session, config) == AccessControl::shib_acl_true)
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
extern "C" void shib_child_exit(server_rec* s, SH_AP_POOL* p)
{
if (g_Config) {
- ap_log_error(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(s),"shib_child_exit(%d) dealing with g_Config..", (int)getpid());
g_Config->term();
g_Config = nullptr;
- ap_log_error(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(s),"shib_child_exit() done");
}
+ ap_log_error(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, SH_AP_R(s), "child_exit: mod_shib shutdown in pid (%d)", (int)getpid());
}
#else
/*
g_Config->term();
g_Config = nullptr;
}
- ap_log_error(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,0,nullptr,"shib_exit() done");
+ server_rec* s = reinterpret_cast<server_rec*>(data);
+ ap_log_error(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, SH_AP_R(s), "shib_exit: mod_shib shutdown in pid (%d)", (int)getpid());
return OK;
}
+
+/*
+ * shib_post_config()
+ * We do the library init/term work here for 2.x to reduce overhead and
+ * get default logging established before the fork happens.
+ */
+apr_status_t shib_post_config(apr_pool_t* p, apr_pool_t*, apr_pool_t*, server_rec* s)
+{
+ // Initialize runtime components.
+ ap_log_error(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, SH_AP_R(s),"post_config: mod_shib initializing in pid (%d)", (int)getpid());
+
+ if (g_Config) {
+ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, SH_AP_R(s), "post_config: mod_shib already initialized");
+ return !OK;
+ }
+
+ g_Config = &SPConfig::getConfig();
+ g_Config->setFeatures(
+ SPConfig::Listener |
+ SPConfig::Caching |
+ SPConfig::RequestMapping |
+ SPConfig::InProcess |
+ SPConfig::Logging |
+ SPConfig::Handlers
+ );
+ if (!g_Config->init(g_szSchemaDir, g_szPrefix)) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_NOERRNO, SH_AP_R(s), "post_config: mod_shib failed to initialize libraries");
+ return !OK;
+ }
+#ifndef SHIB_APACHE_24
+ g_Config->AccessControlManager.registerFactory(HT_ACCESS_CONTROL, &htAccessFactory);
+#endif
+ g_Config->RequestMapperManager.registerFactory(NATIVE_REQUEST_MAPPER, &ApacheRequestMapFactory);
+
+ // Set the cleanup handler, passing in the server_rec for logging.
+ apr_pool_cleanup_register(p, s, &shib_exit, apr_pool_cleanup_null);
+
+ return OK;
+}
+
#endif
/*
- * shire_child_init()
+ * shib_child_init()
* Things to do when the child process is initialized.
- * (or after the configs are read in apache-2)
+ * We can't use post-config for all of it on 2.x because only the forking thread shows
+ * up in the child, losing the internal threads spun up by plugins in the SP.
*/
#ifdef SHIB_APACHE_13
extern "C" void shib_child_init(server_rec* s, SH_AP_POOL* p)
{
// Initialize runtime components.
- ap_log_error(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(s),"shib_child_init(%d) starting", (int)getpid());
+ ap_log_error(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, SH_AP_R(s),"child_init: mod_shib initializing in pid (%d)", (int)getpid());
+ // 2.x versions have already initialized the libraries.
+#ifdef SHIB_APACHE_13
if (g_Config) {
- ap_log_error(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,SH_AP_R(s),"shib_child_init() already initialized!");
+ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, SH_AP_R(s), "child_init: mod_shib already initialized, exiting");
exit(1);
}
- g_Config=&SPConfig::getConfig();
+ g_Config = &SPConfig::getConfig();
g_Config->setFeatures(
SPConfig::Listener |
SPConfig::Caching |
SPConfig::Handlers
);
if (!g_Config->init(g_szSchemaDir, g_szPrefix)) {
- ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_NOERRNO,SH_AP_R(s),"shib_child_init() failed to initialize libraries");
+ ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_NOERRNO, SH_AP_R(s), "child_init: mod_shib failed to initialize libraries");
exit(1);
}
-#ifndef SHIB_APACHE_24
g_Config->AccessControlManager.registerFactory(HT_ACCESS_CONTROL, &htAccessFactory);
-#endif
g_Config->RequestMapperManager.registerFactory(NATIVE_REQUEST_MAPPER, &ApacheRequestMapFactory);
+#endif
+ // The config gets installed for all versions here due to the background thread/fork issues.
try {
if (!g_Config->instantiate(g_szSHIBConfig, true))
throw runtime_error("unknown error");
}
catch (std::exception& ex) {
- ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_NOERRNO,SH_AP_R(s),"%s",ex.what());
- ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_NOERRNO,SH_AP_R(s),"shib_child_init() failed to load configuration");
+ ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_NOERRNO, SH_AP_R(s), "child_init: mod_shib failed to load configuration: %s", ex.what());
+ g_Config->term();
exit(1);
}
g_catchAll = flag.first && flag.second;
}
- // Set the cleanup handler
- apr_pool_cleanup_register(p, nullptr, &shib_exit, apr_pool_cleanup_null);
+ // Set the cleanup handler, passing in the server_rec for logging.
+ apr_pool_cleanup_register(p, s, &shib_exit, apr_pool_cleanup_null);
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, SH_AP_R(s), "shib_child_init() done");
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, SH_AP_R(s), "child_init: mod_shib config initialized");
}
// Output filters
shib_request_config *rc = (shib_request_config*) ap_get_module_config(r->request_config, &mod_shib);
if (rc && rc->hdr_out) {
- ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_out_filter: merging %d headers", apr_table_elts(rc->hdr_out)->nelts);
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, SH_AP_R(r), "output_filter: merging %d headers", apr_table_elts(rc->hdr_out)->nelts);
// can't use overlap call because it will collapse Set-Cookie headers
//apr_table_overlap(r->headers_out, rc->hdr_out, APR_OVERLAP_TABLES_MERGE);
apr_table_do(_table_add,r->headers_out, rc->hdr_out,NULL);
shib_request_config *rc = (shib_request_config*) ap_get_module_config(r->request_config, &mod_shib);
if (rc && rc->hdr_out) {
- ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_err_filter: merging %d headers", apr_table_elts(rc->hdr_out)->nelts);
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, SH_AP_R(r), "error_filter: merging %d headers", apr_table_elts(rc->hdr_out)->nelts);
// can't use overlap call because it will collapse Set-Cookie headers
//apr_table_overlap(r->err_headers_out, rc->hdr_out, APR_OVERLAP_TABLES_MERGE);
apr_table_do(_table_add,r->err_headers_out, rc->hdr_out,NULL);
#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 };
ap_hook_insert_error_filter(set_error_filter, nullptr, nullptr, APR_HOOK_LAST);
ap_hook_post_read_request(shib_post_read, nullptr, nullptr, APR_HOOK_MIDDLE);
#endif
+ ap_hook_post_config(shib_post_config, nullptr, nullptr, APR_HOOK_MIDDLE);
ap_hook_child_init(shib_child_init, nullptr, nullptr, APR_HOOK_MIDDLE);
const char* prereq = getenv("SHIBSP_APACHE_PREREQ");
#ifdef SHIB_APACHE_24
#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),