https://bugs.internet2.edu/jira/browse/SSPCPP-315
authorcantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Wed, 10 Nov 2010 17:54:27 +0000 (17:54 +0000)
committercantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Wed, 10 Nov 2010 17:54:27 +0000 (17:54 +0000)
git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/branches/REL_2@3370 cb58f699-b61c-0410-a6fe-9272a202ed29

apache/mod_apache.cpp

index 0f0a770..c6a6279 100644 (file)
@@ -45,6 +45,7 @@
 #include <xercesc/util/regx/RegularExpression.hpp>
 #include <xmltooling/XMLToolingConfig.h>
 #include <xmltooling/util/NDC.h>
+#include <xmltooling/util/ParserPool.h>
 #include <xmltooling/util/Threads.h>
 #include <xmltooling/util/XMLConstants.h>
 #include <xmltooling/util/XMLHelper.h>
@@ -160,6 +161,8 @@ struct shib_dir_config
     char* szApplicationId;  // Shib applicationId value
     char* szRequireWith;    // require a session using a specific initiator?
     char* szRedirectToSSL;  // redirect non-SSL requests to SSL port
+       char* szAccessControlType;      // type of "external" AccessControl plugin
+       char* szAccessControlPath;  // path to AccessControl content
     int bOff;               // flat-out disable all Shib processing
     int bBasicHijack;       // activate for AuthType Basic?
     int bRequireSession;    // require a session?
@@ -179,6 +182,8 @@ extern "C" void* create_shib_dir_config (SH_AP_POOL* p, char* d)
     dc->szApplicationId = nullptr;
     dc->szRequireWith = nullptr;
     dc->szRedirectToSSL = nullptr;
+       dc->szAccessControlType = nullptr;
+       dc->szAccessControlPath = nullptr;
     dc->bOff = -1;
     dc->bBasicHijack = -1;
     dc->bRequireSession = -1;
@@ -234,6 +239,20 @@ extern "C" void* merge_shib_dir_config (SH_AP_POOL* p, void* base, void* sub)
     else
         dc->szRedirectToSSL=nullptr;
 
+       if (child->szAccessControlType)
+        dc->szAccessControlType=ap_pstrdup(p,child->szAccessControlType);
+    else if (parent->szAccessControlType)
+        dc->szAccessControlType=ap_pstrdup(p,parent->szAccessControlType);
+    else
+        dc->szAccessControlType=nullptr;
+
+       if (child->szAccessControlPath)
+        dc->szAccessControlPath=ap_pstrdup(p,child->szAccessControlPath);
+    else if (parent->szAccessControlPath)
+        dc->szAccessControlPath=ap_pstrdup(p,parent->szAccessControlPath);
+    else
+        dc->szAccessControlPath=nullptr;
+
     dc->bOff=((child->bOff==-1) ? parent->bOff : child->bOff);
     dc->bBasicHijack=((child->bBasicHijack==-1) ? parent->bBasicHijack : child->bBasicHijack);
     dc->bRequireSession=((child->bRequireSession==-1) ? parent->bRequireSession : child->bRequireSession);
@@ -299,6 +318,13 @@ extern "C" const char* shib_table_set(cmd_parms* parms, shib_dir_config* dc, con
     return nullptr;
 }
 
+extern "C" const char* shib_acl_set(cmd_parms* parms, shib_dir_config* dc, const char* arg1, const char* arg2)
+{
+       dc->szAccessControlType = ap_pstrdup(parms->pool, arg1);
+       dc->szAccessControlPath = ap_pstrdup(parms->pool, arg2);
+       return nullptr;
+}
+
 
 class ShibTargetApache : public AbstractSPRequest
 #if defined(HAVE_GSSAPI) && !defined(SHIB_APACHE_13)
@@ -1003,8 +1029,6 @@ AccessControl::aclresult_t htAccessControl::authorized(const SPRequest& request,
     if (!sta)
         throw ConfigurationException("Request wrapper object was not of correct type.");
 
-    // mod_auth clone
-
     int m=sta->m_req->method_number;
     bool method_restricted=false;
     const char *t, *w;
@@ -1013,6 +1037,46 @@ AccessControl::aclresult_t htAccessControl::authorized(const SPRequest& request,
     if (!reqs_arr)
         return shib_acl_indeterminate;  // should never happen
 
+       // Check for an "embedded" AccessControl plugin.
+       if (sta->m_dc->szAccessControlType && sta->m_dc->szAccessControlPath) {
+               xercesc::DOMDocument* acldoc = XMLToolingConfig::getConfig().getParser().newDocument();
+               XercesJanitor<xercesc::DOMDocument> docjanitor(acldoc);
+               static XMLCh ACL[] = UNICODE_LITERAL_3(A,C,L);
+               static XMLCh _path[] = UNICODE_LITERAL_4(p,a,t,h);
+               static XMLCh _reloadChanges[] = UNICODE_LITERAL_13(r,e,l,o,a,d,C,h,a,n,g,e,s);
+               static XMLCh _false[] = { xercesc::chDigit_0, xercesc::chNull };
+               xercesc::DOMElement* acldom = acldoc->createElementNS(nullptr, ACL);
+               auto_ptr_XMLCh aclpath(sta->m_dc->szAccessControlPath);
+               acldom->setAttributeNS(nullptr, _path, aclpath.get());
+               acldom->setAttributeNS(nullptr, _reloadChanges, _false);
+               aclresult_t result = shib_acl_false;
+               try {
+                       auto_ptr<AccessControl> aclplugin(SPConfig::getConfig().AccessControlManager.newPlugin(sta->m_dc->szAccessControlType, acldom));
+                       Locker acllock(aclplugin.get());
+                       result = aclplugin->authorized(request, session);
+               }
+               catch (exception& ex) {
+                       request.log(SPRequest::SPError, ex.what());
+               }
+
+        if (result == shib_acl_true && sta->m_dc->bRequireAll != 1) {
+            // If we're not insisting that all rules be met, then we're done.
+            request.log(SPRequest::SPDebug, "htaccess: embedded AccessControl plugin was successful, granting access");
+            return shib_acl_true;
+        }
+        else if (result != shib_acl_true && sta->m_dc->bRequireAll == 1) {
+            // If we're insisting that all rules be met, which is not something Apache really handles well,
+            // then we either return false or indeterminate based on the authoritative option, which defaults on.
+            if (sta->m_dc->bAuthoritative != 0) {
+                request.log(SPRequest::SPDebug, "htaccess: embedded AccessControl plugin was unsuccessful, denying access");
+                return shib_acl_false;
+            }
+
+            request.log(SPRequest::SPDebug, "htaccess: embedded AccessControl plugin was unsuccessful but not authoritative, leaving it up to Apache");
+            return shib_acl_indeterminate;
+        }
+       }
+
     require_line* reqs=(require_line*)reqs_arr->elts;
 
     for (int x=0; x<reqs_arr->nelts; x++) {
@@ -1451,6 +1515,9 @@ static command_rec shire_cmds[] = {
   {"ShibRequestSetting", (config_fn_t)shib_table_set, nullptr,
    OR_AUTHCFG, TAKE2, "Set arbitrary Shibboleth request property for content"},
 
+  {"ShibAccessControl", (config_fn_t)shib_acl_set, nullptr,
+   OR_AUTHCFG, TAKE2, "Set arbitrary Shibboleth access control plugin for content"},
+
   {"ShibDisable", (config_fn_t)ap_set_flag_slot,
    (void *) XtOffsetOf (shib_dir_config, bOff),
    OR_AUTHCFG, FLAG, "Disable all Shib module activity here to save processing effort"},
@@ -1566,6 +1633,9 @@ static command_rec shib_cmds[] = {
     AP_INIT_TAKE2("ShibRequestSetting", (config_fn_t)shib_table_set, nullptr,
         OR_AUTHCFG, "Set arbitrary Shibboleth request property for content"),
 
+    AP_INIT_TAKE2("ShibAccessControl", (config_fn_t)shib_acl_set, nullptr,
+        OR_AUTHCFG, "Set arbitrary Shibboleth access control plugin for content"),
+
     AP_INIT_FLAG("ShibDisable", (config_fn_t)ap_set_flag_slot,
         (void *) offsetof (shib_dir_config, bOff),
         OR_AUTHCFG, "Disable all Shib module activity here to save processing effort"),