Back to index

nordugrid-arc-nox  1.1.0~rc6
ArcPolicy.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <list>
00006 
00007 #include <arc/security/ClassLoader.h>
00008 
00009 #include "ArcPolicy.h"
00010 #include "ArcRule.h"
00011 
00012 Arc::Logger ArcSec::ArcPolicy::logger(Arc::Logger::rootLogger, "ArcPolicy");
00013 
00014 static Arc::NS policyns("policy", "http://www.nordugrid.org/schemas/policy-arc");
00015 
00018 Arc::Plugin* ArcSec::ArcPolicy::get_policy(Arc::PluginArgument* arg) {
00019     //std::cout<<"Argument type of ArcPolicy:"<<typeid(arg).name()<<std::endl;
00020     if(arg==NULL) return NULL;
00021     Arc::ClassLoaderPluginArgument* clarg =
00022             arg?dynamic_cast<Arc::ClassLoaderPluginArgument*>(arg):NULL;
00023     if(!clarg) return NULL;
00024     // Check if empty or valid policy is supplied
00025     Arc::XMLNode* doc = (Arc::XMLNode*)(*clarg);
00026     if(doc==NULL) { 
00027         std::cerr<<"ArcPolicy creation requires XMLNode as argument"<<std::endl;
00028         return NULL;
00029     }
00030     // NOTE: Following line is not good for autodetection. Should it be removed?
00031     //if(!(*doc)) return new ArcSec::ArcPolicy;
00032     ArcSec::ArcPolicy* policy = new ArcSec::ArcPolicy(*doc);
00033     if((!policy) || (!(*policy))) {
00034       delete policy;
00035       return NULL;
00036     };
00037     return policy;
00038 }
00039 
00040 //loader_descriptors __arc_policy_modules__  = {
00041 //    { "arc.policy", 0, &ArcSec::ArcPolicy::get_policy },
00042 //    { NULL, 0, NULL }
00043 //};
00044 
00045 using namespace Arc;
00046 using namespace ArcSec;
00047 
00048 ArcPolicy::ArcPolicy(void) : Policy(), comalg(NULL) {
00049   Arc::XMLNode newpolicy(policyns,"policy:Policy");
00050   newpolicy.New(policynode);
00051   policytop=policynode;
00052 }
00053 
00054 ArcPolicy::ArcPolicy(const XMLNode node) : Policy(node), comalg(NULL) {
00055   if((!node) || (node.Size() == 0)) {
00056     logger.msg(ERROR,"Policy is empty");
00057     return;
00058   }
00059   node.New(policynode);
00060   std::list<XMLNode> res = policynode.XPathLookup("//policy:Policy",policyns);
00061   if(res.empty()) {
00062     policynode.Destroy();
00063     return;
00064   }
00065   policytop = *(res.begin());
00066 }
00067 
00068 ArcPolicy::ArcPolicy(const XMLNode node, EvaluatorContext* ctx) : Policy(node), comalg(NULL) {
00069   if((!node) || (node.Size() == 0)) {
00070     logger.msg(WARNING,"Policy is empty");
00071     return;
00072   }
00073   node.New(policynode);
00074   std::list<XMLNode> res = policynode.XPathLookup("//policy:Policy",policyns);
00075   if(res.empty()) {
00076     policynode.Destroy();
00077     return;
00078   }
00079   policytop = *(res.begin());
00080   setEvaluatorContext(ctx); 
00081   make_policy();
00082 }
00083 
00084 void ArcPolicy::make_policy() {  
00085   //EvalResult.node record the policy(in XMLNode) information about evaluation result. 
00086   //According to the developer's requirement, EvalResult.node can include rules(in XMLNode) 
00087   //that "Permit" or "Deny" the request tuple. In the existing code, it include all 
00088   //the original rules.
00089 
00090   if(!policynode) return;
00091   if(!policytop) return;
00092 
00093   evalres.node = policynode;
00094   evalres.effect = "Not_applicable";
00095 
00096   ArcRule *rule;
00097   //Get AlgFactory from EvaluatorContext
00098   algfactory = (AlgFactory*)(*evaluatorctx); 
00099 
00100   XMLNode nd = policytop;
00101   XMLNode rnd;
00102   if((bool)nd){
00103     nd = policytop;
00104     id = (std::string)(nd.Attribute("PolicyId"));
00105 
00106     //Setup the rules' combining algorithm inside one policy, according to the "CombiningAlg" name
00107     if(nd.Attribute("CombiningAlg"))
00108       comalg = algfactory->createAlg((std::string)(nd.Attribute("CombiningAlg")));
00109     else comalg = algfactory->createAlg("Deny-Overrides");
00110     
00111     description = (std::string)(nd["Description"]);  
00112   }
00113   
00114   logger.msg(INFO, "PolicyId: %s  Alg inside this policy is:-- %s", id, comalg?(comalg->getalgId()):"");
00115  
00116   for ( int i=0;; i++ ){
00117     rnd = nd["Rule"][i];
00118     if(!rnd) break;
00119     rule = new ArcRule(rnd, evaluatorctx);
00120     subelements.push_back(rule);
00121   }
00122 }
00123 
00124 MatchResult ArcPolicy::match(EvaluationCtx*){// ctx){
00125   //RequestTuple* evaltuple = ctx->getEvalTuple();
00126   
00127   //Because ArcPolicy definition has no any <Subject, Resource, Action, Condition> directly;
00128   //All the <Subject, Resource, Action, Condition>s are only in ArcRule.
00129   //So the function always return "Match" 
00130 
00131   return MATCH;
00132   
00133 }
00134 
00135 Result ArcPolicy::eval(EvaluationCtx* ctx){
00136   Result result = comalg?comalg->combine(ctx, subelements):DECISION_INDETERMINATE;
00137   if(result == DECISION_PERMIT) evalres.effect = "Permit";
00138   else if(result == DECISION_DENY) evalres.effect = "Deny";
00139   else if(result == DECISION_INDETERMINATE) evalres.effect = "Indeterminate";
00140   else if(result == DECISION_NOT_APPLICABLE) evalres.effect = "Not_Applicable";
00141 
00142   return result;
00143 }
00144 
00145 EvalResult& ArcPolicy::getEvalResult() {
00146   return evalres;
00147 }
00148 
00149 void ArcPolicy::setEvalResult(EvalResult& res){
00150   evalres = res;
00151 }
00152 
00153 const char* ArcPolicy::getEvalName() const{
00154   return "arc.evaluator";
00155 }
00156 
00157 const char* ArcPolicy::getName() const{
00158   return "arc.policy";
00159 }
00160 
00161 ArcPolicy::~ArcPolicy(){
00162   while(!(subelements.empty())){
00163       delete subelements.back();
00164       subelements.pop_back();
00165   }
00166 }
00167