/***********************************************************************/ /* abac_pl_pre.c */ /* clause preprocesing called to make partial prolog clause generations*/ /* -> process named cred id, and constraint range/role/oset */ /***********************************************************************/ #include #include #include #include "abac_util.h" #include "abac_pl_pre.h" #include "abac_term.h" #include "abac_aspect.h" #include "abac_list.h" #include "abac_pl_gen.h" #include "abac_pl_yap.h" static int debug=0; /****************************************************************/ /* add the range condition to constraint list */ /* this is for integer and float only */ static void _preprocess_range_numeric_constraint(abac_term_t *ptr) { assert(abac_term_constraint(ptr)); char *var=abac_term_name(ptr); char *typestr=abac_term_type_name(ptr); abac_condition_t *cond=abac_term_constraint(ptr); char *tmplist=NULL; char *tmp=NULL; int as_range=1; /* either , or ; */ abac_condition_set_range_string(cond); abac_list_t *rlist=abac_condition_range_list(cond); abac_item_t *cur; abac_list_foreach(rlist, cur, int type=abac_item_type(cur); char *val=abac_item_val(cur); switch(type) { case e_ITEM_MIN: tmp=generate_pl_range_constraint(typestr,var,val,">="); break; case e_ITEM_MAX: tmp=generate_pl_range_constraint(typestr,var,val,"=<"); break; case e_ITEM_TARGET: tmp=generate_pl_range_constraint(NULL,var,val,"="); as_range=0; break; } /* ; is prolog's disjunction built in predicate */ if(tmplist) { if(as_range) asprintf(&tmplist,"%s,%s",tmplist,tmp); else asprintf(&tmplist,"%s;%s",tmplist,tmp); } else { tmplist=tmp; } tmp=NULL; ); asprintf(&tmplist,"(%s)",tmplist); abac_pl_add_constraints(tmplist); } /****************************************************************/ /* this is for time only */ static void _preprocess_range_time_constraint(abac_term_t *ptr) { assert(abac_term_constraint(ptr)); char *var=abac_term_name(ptr); char *typestr=abac_term_type_name(ptr); abac_condition_t *cond=abac_term_constraint(ptr); abac_list_t *rlist=abac_condition_range_list(cond); assert(rlist); char *tmplist=NULL; char *tmp=NULL; char *ttmp=NULL; char *tlist=NULL; int as_range=1; /* either , or ; */ abac_condition_set_range_string(cond); abac_item_t *cur; /* a list of values -- in chars */ abac_list_foreach(rlist, cur, int type=abac_item_type(cur); char *tval=abac_item_val(cur); char *val=abac_term_to_time(tval); switch(type) { case e_ITEM_MIN: ttmp=generate_pl_range_time_constraint(var,val,">"); tmp=generate_pl_range_time_constraint(var,val,"="); asprintf(&tlist,"(%s;%s)",ttmp,tmp); tmp=tlist; break; case e_ITEM_MAX: ttmp=generate_pl_range_time_constraint(var,val,"="); tmp=generate_pl_range_time_constraint(var,val,"<"); asprintf(&tlist,"(%s;%s)",ttmp,tmp); tmp=tlist; break; case e_ITEM_TARGET: tmp=generate_pl_range_time_constraint(var,val,"="); as_range=0; break; } free(val); /* ; is prolog's disjunction built in predicate */ if(tmplist) { if(as_range) asprintf(&tmplist,"%s,%s",tmplist,tmp); else asprintf(&tmplist,"%s;%s",tmplist,tmp); } else { tmplist=tmp; } tmp=NULL; ); asprintf(&tmplist,"(%s)",tmplist); /* generate a clause with above and add into db */ tmp=abac_pl_add_range_constraint_clause(var,tmplist); abac_pl_add_constraints(tmp); } /****************************************************************/ /* this is for string and urn only */ static void _preprocess_range_string_constraint(abac_term_t *ptr) { assert(abac_term_constraint(ptr)); char *var=abac_term_name(ptr); char *typestr=abac_term_type_name(ptr); abac_condition_t *cond=abac_term_constraint(ptr); abac_list_t *rlist=abac_condition_range_list(cond); assert(rlist); char *tmplist=NULL; char *tmp=NULL; abac_condition_set_range_string(cond); abac_item_t *cur; /* a list of values -- in chars */ abac_list_foreach(rlist, cur, int type=abac_item_type(cur); char *val=abac_item_val(cur); switch(type) { case e_ITEM_MIN: panic("_preprocess_range_string_constraint, invalid range type - min"); break; case e_ITEM_MAX: /* invalid range type */ panic("_preprocess_range_string_constraint, invalid range type - max"); break; case e_ITEM_TARGET: tmp=generate_pl_range_constraint(NULL,var,val,"="); break; } /* ; is prolog's disjunction built in predicate */ if(tmplist) asprintf(&tmplist,"%s;%s",tmplist,tmp); else tmplist=tmp; tmp=NULL; ); asprintf(&tmplist,"(%s)",tmplist); /* generate a clause with above and add into db */ tmp=abac_pl_add_range_constraint_clause(var,tmplist); abac_pl_add_constraints(tmp); } /***********************************************************************/ void preprocess_pl_term(abac_context_t *ctxt,abac_term_t *ptr) { /* add id */ char *name=abac_term_name(ptr); char *type=abac_term_type_name(ptr); if(abac_term_type(ptr) == e_TERM_PRINCIPAL && abac_term_isnamed(ptr)) { int type=e_KEYID; abac_pl_add_id_certs(name,type); if(debug) fprintf(stderr,"preprocess_pl_term: adding %s to id_certs\n",name); } abac_condition_t *cond=abac_term_constraint(ptr); if(cond != NULL) { if(abac_condition_is_range(cond)) { if(abac_term_is_numeric(ptr)) { _preprocess_range_numeric_constraint(ptr); } else if (abac_term_is_alpha(ptr)) { _preprocess_range_string_constraint(ptr); } else if (abac_term_is_time(ptr)) { _preprocess_range_time_constraint(ptr); } } else { /* special handling of role/oset constraining condition */ if(debug) fprintf(stderr,"expecting either oset/role constraint with %s\n",name); abac_aspect_t *cptr=abac_condition_of_aspect(cond); preprocess_pl_head(ctxt,cptr); /* generate the prolog clause */ char *tmp=generate_pl_constraint_clause(ctxt,cptr,name); abac_condition_set_aspect_string(cond,tmp); abac_pl_add_constraints(tmp); } } } void preprocess_pl_params(abac_context_t *ctxt,abac_param_list_t *ptr) { abac_list_t *list=abac_param_list(ptr); assert(list); abac_term_t *cur; abac_list_foreach(list, cur, preprocess_pl_term(ctxt,cur); ); } void preprocess_pl_head(abac_context_t *ctxt,abac_aspect_t *ptr) { char *principalname; PROLOG(principalname=abac_aspect_principal_name(ptr);); int idtype=abac_aspect_get_issuer_idtype(ptr); abac_pl_add_id_certs(principalname,idtype); if(debug) fprintf(stderr,"preprocess_pl_head: adding %s to id_certs\n",principalname); abac_param_list_t *aspect_params=abac_aspect_aspect_params(ptr); if(aspect_params) { preprocess_pl_params(ctxt,aspect_params); } abac_param_list_t *linked_role_params=abac_aspect_linked_role_params(ptr); if(linked_role_params) { preprocess_pl_params(ctxt,linked_role_params); } } void preprocess_pl_tail(abac_context_t *ctxt,abac_aspect_t *ptr) { /* if it is an intersection, preprocess each one */ abac_list_t *list=abac_aspect_prereqs(ptr); if(list != 0) { abac_aspect_t *cur; abac_list_foreach(list, cur, if(cur) preprocess_pl_tail(ctxt,cur); ); return; } /* for oset case, A.oset <- B A.oset <- Obj A.oset <- B.oset A.oset <- B.role.oset */ /* if it is an oset and object */ if(abac_aspect_is_object(ptr)) { abac_term_t *tptr=abac_aspect_object_term(ptr); if(tptr) preprocess_pl_term(ctxt,tptr); } else { char *principalname; PROLOG(principalname=abac_aspect_principal_name(ptr);); int idtype=abac_aspect_get_issuer_idtype(ptr); abac_pl_add_id_certs(principalname,idtype); if(debug) fprintf(stderr,"preprocess_pl_tail: adding %s to id_certs\n",principalname); abac_param_list_t *aspect_params=abac_aspect_aspect_params(ptr); if(aspect_params) { preprocess_pl_params(ctxt,aspect_params); } abac_param_list_t *linked_role_params=abac_aspect_linked_role_params(ptr); if(linked_role_params) { preprocess_pl_params(ctxt,linked_role_params); } } }