/*********************************************************** abac_term.c dterm=data term of rt1 term is a kind of dterm ***********************************************************/ #include #include #include #include #include #include #include "abac_util.h" #include "abac_aspect.h" #include "abac_verifier.h" #include "abac_id.h" #include "abac_list.h" static int debug=0; extern char *strptime(const char *s, const char *format, struct tm *tm); extern int ABAC_IN_PROLOG; /* termname[dtermtype] */ static const char *const _termname[] = { "badterm", "integer", "urn", "float", "boolean", "string", "time" , "principal", "anonymous", "this" }; static int _termname_cnt=9; typedef enum _condtype_t { e_COND_ROLE = 1, e_COND_OSET = 2, e_COND_RANGE = 3 } abac_condtype_t; /* condname[condtype] */ static const char *const _condname[] = { "badcondition", "role", "oset", "range" }; static int _condname_cnt=3; /* itemname[itemtype] */ static const char *const _itemname[] = { "baditem", "min", "max", "target" }; static int _itemname_cnt=3; /* itemtype is [a..b], [a..], [..b], [a],[a,b],[many a] */ struct _abac_item_t { int itemtype; char *val; }; /* condtype is e_COND_ROLE = 1, e_COND_OSET = 2, e_COND_RANGE = 3 vartype is one of termtype string will contain either the range literal (static constraint) or the oset/role prologized string (dynamic constraint) it is set if this condition has been pre-processed for codegen of_aspect ptr will only be set only if it is a dynamic constraint range_list is set only if needed */ struct _abac_condition_t { int condtype; int vartype; char *string; abac_list_t *range_list; abac_aspect_t *of_aspect; }; /* termtype_t/name pair for the data terms idtype_t/name/p_name pair for the named principal term */ struct _abac_term_t { int type; char *name; int isnamed; char *p_name; char *cn; //XXX ?? might not need this at all abac_condition_t *constraint; }; /* new, free, add one of terms */ struct _abac_param_list_t { abac_list_t *list; }; /****************************************************************/ char *abac_condtype_string(int i) { if(i>_condname_cnt) panic("abac_condtype_string: went out of range on condname"); return (char *) _condname[i]; } char *abac_termtype_string(int i) { if(i>_termname_cnt) panic("abac_termtype_string: went out of range on termname"); return (char *) _termname[i]; } int abac_verify_term_type(char *type) { int i; if (type == NULL) panic("abac_verify_term_type: fail with NULL type\n"); for (i = 1; i <= _termname_cnt ; i++) if(strcmp(type,_termname[i])==0) return i; printf("abac_verify_term_type: weird (%s)\n", type); panic("abac_verify_term_type: fail with unfounded type \n"); } int abac_max_item_type() { return e_ITEM_MAX;} int abac_min_item_type() { return e_ITEM_MIN;} int abac_target_item_type() { return e_ITEM_TARGET;} int abac_verify_item_type(char *type) { int i; if (type == NULL) panic("abac_verify_item_type: fail with NULL type\n"); for (i = 1; i <= _itemname_cnt ; i++) if(strcmp(type,_itemname[i])==0) return i; panic("abac_verify_item_type: fail with unfounded type\n"); } char *abac_range_string(abac_list_t *ptr) { assert(ptr); char *tmp=NULL; char *min=NULL; char *max=NULL; char *val=NULL; int type; abac_item_t *cur; assert(ptr); abac_list_foreach(ptr, cur, type=cur->itemtype; switch (type) { case e_ITEM_MIN: min=abac_xstrdup(cur->val); break; case e_ITEM_MAX: max=abac_xstrdup(cur->val); break; case e_ITEM_TARGET: if(val) asprintf(&val,"%s,%s",cur->val,val); else val=abac_xstrdup(cur->val); break; } ); if(max && min) { asprintf(&tmp,"[%s..%s]",min,max); free(max); free(min); return tmp; } if(max) { asprintf(&tmp,"[..%s]",max); free(max); return tmp; } if(min) { asprintf(&tmp,"[%s..]",min); free(min); return tmp; } if(val) { asprintf(&tmp,"[%s]",val); free(val); return tmp; } return NULL; } /******************************************************************/ abac_item_t *abac_item_new(int itype, char *val) { abac_item_t *nptr= (abac_item_t *)abac_xmalloc(sizeof(abac_item_t)); nptr->itemtype=itype; nptr->val=abac_xstrdup(val); return nptr; } void abac_item_free(abac_item_t *ptr) { assert(ptr); assert(ptr->val); free(ptr->val); free(ptr); } abac_item_t *abac_item_dup(abac_item_t *ptr) { abac_item_t *nptr= (abac_item_t *)abac_xmalloc(sizeof(abac_item_t)); nptr->itemtype=ptr->itemtype; nptr->val=abac_xstrdup(ptr->val); return nptr; } /* deep copy/same as dup */ abac_item_t *abac_item_copy(abac_item_t *ptr) { abac_item_t *nptr= (abac_item_t *)abac_xmalloc(sizeof(abac_item_t)); nptr->itemtype=ptr->itemtype; nptr->val=abac_xstrdup(ptr->val); return nptr; } int abac_item_type(abac_item_t *ptr) { return ptr->itemtype; } char *abac_item_val(abac_item_t *ptr) { return ptr->val; } /******************************************************************/ static abac_condition_t *_abac_condition_new(int type, int vtype, char* condstr,void *cptr) { if(debug) { fprintf(stderr," abac_condition_new: \n"); fprintf(stderr," condtype is %d(%s)\n", type, abac_condtype_string(type)); fprintf(stderr," vtype is %d(%s)\n", vtype, abac_termtype_string(type)); fprintf(stderr," condstr is (%s)\n", condstr); if(cptr) fprintf(stderr," yes on cptr\n"); else fprintf(stderr," no on cptr\n"); } abac_condition_t *ptr= (abac_condition_t *)abac_xmalloc(sizeof(abac_condition_t)); ptr->condtype=type; ptr->vartype=vtype; ptr->string=abac_xstrdup(condstr); ptr->of_aspect=NULL; ptr->range_list=NULL; if(type==e_COND_RANGE) { ptr->range_list=(abac_list_t *)cptr; } else { if(cptr) ptr->of_aspect=abac_aspect_dup((abac_aspect_t *)cptr); } return ptr; } void abac_condition_free(abac_condition_t *ptr) { switch(ptr->condtype) { case e_COND_OSET: case e_COND_ROLE: abac_aspect_free(ptr->of_aspect); break; case e_COND_RANGE: /* do nothing */ break; } if(ptr->string) free(ptr->string); if(ptr->range_list != NULL) { abac_item_t *cur; abac_list_foreach(ptr->range_list, cur, abac_item_free(cur); ); abac_list_free(ptr->range_list); } free(ptr); } abac_aspect_t *abac_condition_of_aspect(abac_condition_t *ptr) { return ptr->of_aspect; } int abac_condition_is_range(abac_condition_t *ptr) { if(ptr->condtype==e_COND_RANGE) return 1; else return 0; } /* called from backend, intended as stub for range constraint */ abac_condition_t *abac_condition_create(char *vtype) { abac_condition_t *nptr= (abac_condition_t *)abac_xmalloc(sizeof(abac_condition_t)); nptr->condtype=e_COND_RANGE; nptr->vartype=abac_verify_term_type(vtype); nptr->string=NULL; nptr->range_list=NULL; nptr->of_aspect=NULL; return nptr; } abac_condition_t *abac_condition_create_from_aspect(abac_aspect_t *ptr) { assert(ptr); abac_condition_t *nptr= (abac_condition_t *)abac_xmalloc(sizeof(abac_condition_t)); if(abac_aspect_is_role(ptr)) nptr->condtype=e_COND_ROLE; else nptr->condtype=e_COND_OSET; nptr->vartype=e_TERM_PRINCIPAL; nptr->string=NULL; nptr->range_list=NULL; nptr->of_aspect=abac_aspect_dup(ptr); return nptr; } /* make a shallow copy */ abac_condition_t *abac_condition_dup(abac_condition_t *ptr) { abac_condition_t *nptr= (abac_condition_t *)abac_xmalloc(sizeof(abac_condition_t)); nptr->condtype=ptr->condtype; nptr->vartype=ptr->vartype; if(ptr->string) nptr->string=abac_xstrdup(ptr->string); else nptr->string=NULL; if(ptr->of_aspect) nptr->of_aspect=abac_aspect_dup(ptr->of_aspect); else nptr->of_aspect=NULL; if(ptr->range_list!=NULL) { nptr->range_list=abac_list_new(); abac_item_t *cur; abac_item_t *nitem; abac_list_foreach(ptr->range_list, cur, nitem=abac_item_dup(cur); abac_list_add(nptr->range_list,nitem); ); } else { nptr->range_list=NULL; } return nptr; } /* make a deep copy */ abac_condition_t *abac_condition_copy(abac_condition_t *ptr) { abac_condition_t *nptr= (abac_condition_t *)abac_xmalloc(sizeof(abac_condition_t)); nptr->condtype=ptr->condtype; nptr->vartype=ptr->vartype; if(ptr->string) { nptr->string=abac_xstrdup(ptr->string); } else { nptr->string=NULL; } if(ptr->of_aspect) nptr->of_aspect=abac_aspect_copy(ptr->of_aspect); else nptr->of_aspect=NULL; if(ptr->range_list!=NULL) { nptr->range_list=abac_list_new(); abac_item_t *cur; abac_item_t *nitem; abac_list_foreach(ptr->range_list, cur, nitem=abac_item_copy(cur); abac_list_add(nptr->range_list,nitem); ); } else { nptr->range_list=NULL; } return nptr; } int abac_condition_vartype(abac_condition_t *ptr) { return ptr->vartype; } abac_list_t *abac_condition_range_list(abac_condition_t *ptr) { assert(ptr); return ptr->range_list; } /***********************************************************************/ static void _abac_condition_add_range_item(abac_condition_t *ptr, int itype, char* val) { abac_item_t *nitem=abac_item_new(itype,val); if(ptr->range_list==NULL) ptr->range_list=abac_list_new(); abac_list_add(ptr->range_list,nitem); } void abac_condition_add_range_integer_item(abac_condition_t *ptr, int itype, int val) { if(abac_condition_vartype(ptr) != abac_verify_term_type("integer")) panic("abac_condition_add_range_integer_item, mismatched contraint type to abac integer term\n"); char *tmp=NULL; asprintf(&tmp,"%d",val); _abac_condition_add_range_item(ptr,itype,tmp); } void abac_condition_add_range_float_item(abac_condition_t *ptr, int itype, float val) { if(abac_condition_vartype(ptr) != abac_verify_term_type("float")) panic("abac_condition_add_range_float_item, mismatched contraint type to abac float term\n"); char *tmp=NULL; asprintf(&tmp,"%f",val); _abac_condition_add_range_item(ptr,itype,tmp); } void abac_condition_add_range_time_item(abac_condition_t *ptr, int itype, char* val) { if(abac_condition_vartype(ptr) != abac_verify_term_type("time")) panic("abac_condition_add_range_time_item, mismatched contraint type to abac time term\n"); _abac_condition_add_range_item(ptr,itype,val); } void abac_condition_add_range_urn_item(abac_condition_t *ptr, char *val) { if(abac_condition_vartype(ptr) != abac_verify_term_type("urn")) panic("abac_condition_add_range_urn_item, mismatched contraint type to abac urn term\n"); _abac_condition_add_range_item(ptr,e_ITEM_TARGET,val); } void abac_condition_add_range_string_item(abac_condition_t *ptr, char *val) { if(abac_condition_vartype(ptr) != abac_verify_term_type("string")) panic("abac_condition_add_range_string_item, mismatched contraint type to abac string term\n"); _abac_condition_add_range_item(ptr,e_ITEM_TARGET,val); } void abac_condition_add_range_boolean_item(abac_condition_t *ptr, char* val) { if(abac_condition_vartype(ptr) != abac_verify_term_type("boolean")) panic("abac_condition_add_range_boolean_item, mismatched contraint type to abac boolen term\n"); if(strcmp(val,"true")==0 || strcmp(val,"false")==0) { _abac_condition_add_range_item(ptr,e_ITEM_TARGET,val); } else { panic("abac_condition_add_range_boolean_item, invalid matching value\n"); } } char *abac_condition_string(abac_condition_t *ptr) { char *string=NULL; switch(ptr->condtype) { case e_COND_OSET: case e_COND_ROLE: string=abac_aspect_string_with_condition(ptr->of_aspect); return string; break; case e_COND_RANGE: if(ptr->string != NULL) { string=abac_xstrdup(ptr->string); return string; } if(ptr->range_list != NULL) { string=abac_range_string(ptr->range_list); return string; } break; } return string; } char *abac_condition_typed_string(abac_condition_t *ptr) { char *string=NULL; switch(ptr->condtype) { case e_COND_OSET: case e_COND_ROLE: string=abac_aspect_typed_string_with_condition(ptr->of_aspect); return string; break; case e_COND_RANGE: if(ptr->string != NULL) { string=abac_xstrdup(ptr->string); return string; } if(ptr->range_list != NULL) { string=abac_range_string(ptr->range_list); return string; } break; } return string; } int abac_condition_set_range_string(abac_condition_t *ptr) { char *string= abac_range_string(ptr->range_list); ptr->string=string; return 1; } int abac_condition_set_aspect_string(abac_condition_t *ptr, char *str) { ptr->string=abac_xstrdup(str); return 1; } int abac_condition_set_aspect_ptr(abac_condition_t *ptr, abac_aspect_t *aptr) { ptr->of_aspect=abac_aspect_dup(aptr); return 1; } /******************************************************************/ int abac_term_isvar(abac_term_t *term) { if(isupper(term->name[0])) return 1; else return 0; } int abac_term_isnamed(abac_term_t *term) { if(term->isnamed) return 1; else return 0; } char *abac_term_name(abac_term_t *term) { if(ABAC_IN_PROLOG && term->p_name) { return term->p_name; } return term->name; } char *abac_term_cn(abac_term_t *term) { return term->cn; } abac_condition_t *abac_term_constraint(abac_term_t *term) { return term->constraint; } char *abac_term_type_name(abac_term_t *term) { if(term->isnamed) return abac_idtype_string(term->type); return abac_termtype_string(term->type); } int abac_term_type(abac_term_t *term) { return term->type; } int abac_term_is_anonymous(abac_term_t *ptr) { if(ptr->type == e_TERM_ANONYMOUS) return 1; return 0; } int abac_term_is_this(abac_term_t *ptr) { if(ptr->type == e_TERM_THIS) return 1; return 0; } static int _abac_termtype_is_time_type(int i) { if (i == e_TERM_TIME) return 1; return 0; } int abac_term_is_time_type(abac_term_t *term) { return _abac_termtype_is_time_type(term->type); } static int _abac_termtype_is_string_type(int i) { if (i == e_TERM_STRING) return 1; return 0; } int abac_term_is_string(abac_term_t *term) { return _abac_termtype_is_string_type(term->type); } static int _abac_termtype_is_integer_type(int i) { if (i == e_TERM_INTEGER) return 1; return 0; } int abac_term_is_integer(abac_term_t *term) { return _abac_termtype_is_integer_type(term->type); } static int _abac_termtype_is_urn_type(int i) { if (i == e_TERM_URN) return 1; return 0; } int abac_term_is_urn(abac_term_t *term) { return _abac_termtype_is_urn_type(term->type); } int abac_term_is_alpha(abac_term_t *term) { if(term->type == e_TERM_URN || term->type == e_TERM_STRING || term->type == e_TERM_BOOLEAN) return 1; return 0; } int abac_term_is_numeric(abac_term_t *term) { if(term->type == e_TERM_INTEGER || term->type == e_TERM_FLOAT) return 1; return 0; } int abac_term_is_time(abac_term_t *term) { if(term->type == e_TERM_TIME) return 1; return 0; } /* need to preset tm1 structure with init_string to nullify field that might not get set the supplied time string */ char *abac_term_to_time(char *string) { struct tm tm1; char buf[255]; char *init_string="19991212T000000"; strptime(init_string, "%Y%m%dT%H%M%S", &tm1); strptime(string, "%Y%m%dT%H%M%S", &tm1); strftime(buf, sizeof(buf), "time(%Y,%m,%d,%H,%M,%S)", &tm1); return abac_xstrdup(buf); } char *abac_time_to_term(char *string) { char buf[255]; struct tm tm1; char* rt=strptime(string, "time(%Y,%m,%d,%H,%M,%S)", &tm1); if(rt==NULL) return abac_xstrdup(string); strftime(buf, sizeof(buf), "%Y%m%dT%H%M%S", &tm1); return strdup(buf); } static abac_term_t *_abac_term_init() { abac_term_t *ptr=abac_xmalloc(sizeof(abac_term_t)); ptr->type; ptr->name=NULL; ptr->isnamed=0; ptr->p_name=NULL; ptr->cn=NULL; ptr->constraint=NULL; } /* called from yy, cptr is either abac_aspect_t or abac_list_t */ abac_term_t *abac_term_new(int type, char *name, int isrange, char *cond, void *cptr) { if(debug) { fprintf(stderr,"abac_term_new: \n"); fprintf(stderr," type is %d(%s)\n", type, abac_termtype_string(type)); fprintf(stderr," name is (%s)\n", name); if(cond) fprintf(stderr," cond is %s\n", cond); else fprintf(stderr," no cond \n"); fprintf(stderr," isrange is %d\n", isrange); if(cptr) { if(isrange) fprintf(stderr," cptr is (%s)\n", abac_range_string((abac_list_t *)cptr)); else fprintf(stderr," cptr is (%s)\n", abac_aspect_string_with_condition((abac_aspect_t *)cptr)); } else fprintf(stderr," there is no cptr\n"); } abac_condition_t *constraint=NULL; if (cptr) { if(isrange) { constraint=_abac_condition_new(e_COND_RANGE,type,cond,cptr); } else { if(type==e_TERM_PRINCIPAL) constraint=_abac_condition_new(e_COND_ROLE,type,cond,cptr); else constraint=_abac_condition_new(e_COND_OSET,type,cond,cptr); } } abac_term_t *ptr=_abac_term_init(); ptr->isnamed=0; ptr->type=type; /* reformat the term name if it is a time type */ if((!constraint) && _abac_termtype_is_time_type(type) && isdigit(name[0])) { char *tmp=abac_term_to_time(name); ptr->name=tmp; } else { ptr->name=abac_xstrdup(name); } ptr->constraint=constraint; return ptr; } abac_term_t *abac_term_create(char *typename, char *name, abac_condition_t *cptr) { int type=abac_verify_term_type(typename); if(debug) { fprintf(stderr,"abac_term_create: \n"); fprintf(stderr," type is %d(%s)\n", type, abac_termtype_string(type)); fprintf(stderr," name is (%s)\n", name); if(cptr) fprintf(stderr," cptr is (%s)\n", abac_condition_typed_string(cptr)); else fprintf(stderr," there is no cptr\n"); } abac_term_t *ptr=_abac_term_init(); ptr->isnamed=0; ptr->type=type; /* reformat the term name if it is a time type */ if((!cptr) && _abac_termtype_is_time_type(type) && isdigit(name[0])) { char *tmp=abac_term_to_time(name); ptr->name=tmp; } else { ptr->name=abac_xstrdup(name); } if(cptr) ptr->constraint=abac_condition_dup(cptr); return ptr; } /* called from yy, named principal type */ abac_term_t *abac_term_named_new(int idtype, char *name) { DEBUG_PRINTF("abac_term_named_new: \n type is %d(%s)\n", idtype, abac_idtype_string(idtype)); DEBUG_PRINTF(" name is (%s)\n", name); abac_term_t *ptr=_abac_term_init(); ptr->isnamed=1; ptr->type=idtype; ptr->name=abac_xstrdup(name); /* if ABAC_CN, no need to attach p */ if(!USE("ABAC_CN")) asprintf(&ptr->p_name,"p%s",name); return ptr; } abac_term_t *abac_term_this_create() { DEBUG_PRINTF("abac_term_this_create:\n"); abac_term_t *ptr=_abac_term_init(); ptr->type=e_TERM_THIS; ptr->name=abac_xstrdup("This"); return ptr; } /* seems to be always idtype==e_TERM_PRINCIPAL except for ?This*/ abac_term_t *abac_term_named_create(char *name) { DEBUG_PRINTF("abac_term_named_create: name is (%s)\n",name); abac_term_t *ptr=_abac_term_init(); /* special case when it is a ?this */ if(strcasecmp(name,"this")==0) { ptr->type=e_TERM_THIS; ptr->name=abac_xstrdup("This"); return ptr; } if(strcasecmp(name,"anonymous")==0) { ptr->type=e_TERM_ANONYMOUS; ptr->name=abac_xstrdup("_"); return ptr; } ptr->isnamed=1; ptr->type=e_TERM_PRINCIPAL; ptr->name=abac_xstrdup(name); /* if ABAC_CN, no need to attach p */ if(!USE("ABAC_CN")) asprintf(&ptr->p_name,"p%s",name); return ptr; } /* seems to be always idtype==keyid type */ abac_term_t *abac_term_id_create(abac_id_t *idptr) { DEBUG_PRINTF("abac_term_named_id_create: name is (%s)\n", abac_id_name(idptr)); abac_term_t *ptr=_abac_term_init(); ptr->isnamed=1; ptr->type=abac_id_idtype(idptr); ptr->name=abac_xstrdup(abac_id_name(idptr)); /* if ABAC_CN, no need to attach p */ if(!USE("ABAC_CN")) asprintf(&ptr->p_name,"p%s",ptr->name); return ptr; } abac_term_t *abac_term_dup(abac_term_t *ptr) { assert(ptr); abac_term_t *nptr=_abac_term_init(); nptr->isnamed=ptr->isnamed; nptr->type=ptr->type; nptr->name=abac_xstrdup(ptr->name); if(ptr->p_name) nptr->p_name=abac_xstrdup(ptr->p_name); if(ptr->constraint!=NULL) nptr->constraint=abac_condition_dup(ptr->constraint); if(ptr->cn) nptr->cn=abac_xstrdup(ptr->cn); return nptr; } /* a deep copy */ abac_term_t *abac_term_copy(abac_term_t *ptr) { if(ptr == NULL) return NULL; abac_term_t *nptr=_abac_term_init(); nptr->isnamed=ptr->isnamed; nptr->type=ptr->type; if(ptr->name) nptr->name=abac_xstrdup(ptr->name); if(ptr->p_name) nptr->p_name=abac_xstrdup(ptr->p_name); if(ptr->constraint!=NULL) nptr->constraint=abac_condition_copy(ptr->constraint); if(ptr->cn) nptr->cn=abac_xstrdup(ptr->cn); return nptr; } void abac_term_free(abac_term_t *ptr) { if(ptr->constraint) { abac_condition_free(ptr->constraint); } free(ptr->name); if(ptr->p_name) free(ptr->p_name); if(ptr->cn) free(ptr->cn); free(ptr); } abac_term_t *abac_term_add_constraint(abac_term_t *ptr, abac_condition_t *cond) { /* make sure the types are matching */ if(abac_condition_vartype(cond) != abac_term_type(ptr)) { panic("abac_term_add_constraint: mismatched constraint type with the dataterm\n"); return NULL; } if(ptr->constraint) { abac_condition_free(ptr->constraint); } ptr->constraint = abac_condition_dup(cond); return ptr; } /* name or name:cond */ static char *abac_term_string_with_condition(abac_term_t *ptr) { char *tmp=NULL; char *cond=NULL; char *name=abac_term_name(ptr); if(ptr->constraint) { cond=abac_condition_string(ptr->constraint); } int free_name=0; if(abac_term_is_time_type(ptr) && !ABAC_IN_PROLOG ) { name=abac_time_to_term(name); free_name=1; } if(cond) { asprintf(&tmp,"%s:%s", name, cond); free(cond); } else tmp=abac_xstrdup(name); if(free_name) free(name); return tmp; } /* [type:name] or [typed:name:cond] */ static char *abac_term_typed_string_with_condition(abac_term_t *ptr) { char *tmp=NULL; char *cond=NULL; int free_name=0; char *name=abac_term_name(ptr); char *type=abac_term_type_name(ptr); if(ptr->constraint) { cond=abac_condition_typed_string(ptr->constraint); } /* special case if term is actually a time term... */ if(abac_term_is_time_type(ptr) && !ABAC_IN_PROLOG ) { name=abac_time_to_term(name); /* this should be freed */ DEBUG_PRINTF("abac_term_typed_string_with_condition: trying to turn the time back\n"); free_name=1; } if(cond) { if(abac_condition_is_range(ptr->constraint)) asprintf(&tmp,"[%s:?%s:%s]", type, name, cond); else asprintf(&tmp,"[%s:?%s%s]", type, name, cond); free(cond); } else { if(abac_term_is_anonymous(ptr)) { asprintf(&tmp,"[?]"); } else { if(abac_term_is_this(ptr)) { asprintf(&tmp,"[?This]"); } else { if(isupper(name[0])) asprintf(&tmp,"[%s:?%s]", type, name); else asprintf(&tmp,"[%s:%s]", type, name); } } } DEBUG_PRINTF("abac_term_typed_string_with_condition: (%s)\n",tmp); if(free_name) free(name); return tmp; } char *abac_term_string(abac_term_t *ptr) { return abac_xstrdup(abac_term_name(ptr)); } char *abac_term_typed_string(abac_term_t *ptr) { return abac_term_typed_string_with_condition(ptr); } /********************************************************************/ int abac_param_list_cnt(abac_param_list_t *ptr) { assert(ptr); int cnt=abac_list_size(ptr->list); return cnt; } abac_list_t *abac_param_list(abac_param_list_t *ptr) { assert(ptr); return ptr->list; } abac_param_list_t *abac_param_list_copy(abac_param_list_t *ptr) { if(ptr == NULL) return NULL; abac_param_list_t *nptr=abac_xmalloc(sizeof(abac_param_list_t)); nptr->list=abac_list_new(); abac_term_t *cur; abac_term_t *ncur; abac_list_foreach(ptr->list, cur, ncur=abac_term_copy(cur); abac_list_add(nptr->list, ncur); ); return nptr; } abac_param_list_t *abac_param_list_new(abac_term_t *term) { abac_param_list_t *ptr=abac_xmalloc(sizeof(abac_param_list_t)); ptr->list=abac_list_new(); abac_list_add(ptr->list, abac_term_dup(term)); return ptr; } abac_param_list_t *abac_param_list_free(abac_param_list_t *ptr) { abac_list_t *list=ptr->list; abac_term_t *cur; abac_list_foreach(list, cur, abac_term_free(cur); ); abac_list_free(list); free(ptr); } abac_param_list_t *abac_param_list_add_term(abac_param_list_t *ptr, abac_term_t *term) { abac_list_t *list=ptr->list; abac_list_add(list, abac_term_dup(term)); return ptr; } /* term1:cond1,term2:cond2 */ char* abac_param_list_string_with_condition(abac_param_list_t *ptr) { if(ptr->list == NULL) return ""; abac_term_t *cur; char *tmp=NULL, *final=NULL; abac_list_foreach(ptr->list, cur, char *s=abac_term_string_with_condition(cur); if(final==NULL) { final=abac_xstrdup(s); } else { tmp=final; final=NULL; asprintf(&final,"%s,%s",tmp,s); free(tmp); } free(s); ); return final; } /* [type:term1:cond1],[type:term2:cond2] */ char* abac_param_list_typed_string_with_condition(abac_param_list_t *ptr) { if(ptr->list == NULL) return ""; abac_term_t *cur; char *tmp=NULL, *final=NULL; abac_list_foreach(ptr->list, cur, char *s=abac_term_typed_string_with_condition(cur); if(final==NULL) { final=abac_xstrdup(s); } else { tmp=final; final=NULL; asprintf(&final,"%s,%s",tmp,s); DEBUG_PRINTF("typed param so far, %s\n", final); free(tmp); } free(s); ); DEBUG_PRINTF("typed param so far, %s\n", final); return final; } /* term1,term2 */ char* abac_param_list_string(abac_param_list_t *ptr) { abac_list_t *list=ptr->list; if(list == NULL) return ""; abac_term_t *cur; char *final=NULL; char *tmp=NULL; /* collect up all the string */ abac_list_foreach(list, cur, char *s=abac_term_string(cur); if(final==NULL) { final=abac_xstrdup(s); } else { tmp=final; final=NULL; asprintf(&final,"%s,%s",tmp,s); DEBUG_PRINTF("param so far, %s\n", final); free(tmp); } free(s); ); DEBUG_PRINTF("param so far, %s\n", final); return final; } /* make a stack of it for the abac.hh */ abac_term_t **abac_param_list_vectorize(abac_param_list_t *ptr) { abac_term_t **terms=NULL; abac_list_t *list=ptr->list; int cnt=0; if(list != NULL) cnt=abac_list_size(list); // make the array (leave space to NULL terminate it) // n.b., even if the list is empty, we still return an array that // only contains the NULL terminator terms = abac_xmalloc(sizeof(abac_term_t *) * (cnt + 1)); abac_term_t *cur; int i = 0; if(i