/*********************************************************** abac_term.c dterm=data term of rt1 term is a kind of dterm ***********************************************************/ #include #include #include #include #include #include #include "abac_internal.h" #include "abac_util.h" static int debug=0; /* string will contain either the range literal (static constraint) or the oset/role prologized string (dynamic constraint) union ptr will only be set if it is a dynamic constraint */ struct _abac_condition_t { int type; char *string; 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; // e_TERM_PRINCIPAL isnamed 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_name(int i) { if(i>_condname_cnt) panic("abac_condtype_name: went out of range on condname"); return (char *) _condname[i]; } abac_condition_t *abac_condition_new(int type,char* condstr,abac_aspect_t *cptr) { if(debug) { printf(" abac_condition_new: \n"); printf(" type is %d(%s)\n", type, abac_condtype_name(type)); printf(" condstr is (%s)\n", condstr); if(cptr) printf(" yes on cptr\n"); else printf(" no on cptr\n"); } abac_condition_t *ptr= (abac_condition_t *)abac_xmalloc(sizeof(abac_condition_t)); ptr->type=type; ptr->string=abac_xstrdup(condstr); if(cptr) ptr->of_aspect=abac_aspect_dup(cptr); else ptr->of_aspect=NULL; return ptr; } void abac_condition_free(abac_condition_t *ptr) { switch(ptr->type) { 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); free(ptr); } abac_condition_t *abac_condition_from_string(char *string) { assert(string); abac_condition_t *nptr= (abac_condition_t *)abac_xmalloc(sizeof(abac_condition_t)); nptr->type=e_COND_RANGE; nptr->string=abac_xstrdup(string); nptr->of_aspect=NULL; return nptr; } abac_condition_t *abac_condition_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->type=e_COND_ROLE; else nptr->type=e_COND_OSET; nptr->string=NULL; nptr->of_aspect=abac_aspect_dup(ptr); return nptr; } /* made a 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->type=ptr->type; 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; return nptr; } char *abac_condition_string(abac_condition_t *ptr) { char *string=NULL; switch(ptr->type) { case e_COND_OSET: case e_COND_ROLE: string=abac_aspect_string_with_condition(ptr->of_aspect); break; case e_COND_RANGE: string=abac_xstrdup(ptr->string); break; } return string; } char *abac_condition_typed_string(abac_condition_t *ptr) { char *string=NULL; switch(ptr->type) { case e_COND_OSET: case e_COND_ROLE: string=abac_aspect_typed_string_with_condition(ptr->of_aspect); break; case e_COND_RANGE: string=abac_xstrdup(ptr->string); break; } return string; } /******************************************************************/ 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_termtype_string(int i) { if(i>_termname_cnt) panic("abac_termtype_string: went out of range on termname"); return (char *) _termname[i]; } 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; } static bool _abac_termtype_is_time_type(int i) { if (i == e_TERM_TIME) return 1; return 0; } bool abac_term_is_time_type(abac_term_t *term) { return _abac_termtype_is_time_type(term->type); } static bool _abac_termtype_is_string_type(int i) { if (i == e_TERM_STRING) return 1; return 0; } bool abac_term_is_string_type(abac_term_t *term) { return _abac_termtype_is_string_type(term->type); } static bool _abac_termtype_is_integer_type(int i) { if (i == e_TERM_INTEGER) return 1; return 0; } bool abac_term_is_integer_type(abac_term_t *term) { return _abac_termtype_is_integer_type(term->type); } static bool _abac_termtype_is_urn_type(int i) { if (i == e_TERM_URN) return 1; return 0; } bool abac_term_is_urn_type(abac_term_t *term) { return _abac_termtype_is_urn_type(term->type); } int abac_term_verify_term_type(char *type) { int i; if (type == NULL) return 0; for (i = 1; i <= _termname_cnt ; i++) if(strcmp(type,_termname[i])==0) return i; return 0; } char *abac_term_to_time(char *string) { struct tm tm1; char buf[255]; strptime(string, "%Y%m%dT%H%M%S", &tm1); strftime(buf, sizeof(buf), "time(%Y,%m,%d,%H,%M,%S)", &tm1); return strdup(buf); } /* called from yy */ abac_term_t *abac_term_new(int type, char *name, char *cond, abac_aspect_t *cptr) { if(debug) { printf("abac_term_new: \n"); printf(" type is %d(%s)\n", type, abac_termtype_string(type)); printf(" name is (%s)\n", name); if(cond) printf(" cond is %s\n", cond); else printf(" no cond \n"); if(cptr) printf(" cptr is (%s)\n", abac_aspect_string_with_condition(cptr)); else printf(" there is no cptr\n"); } abac_condition_t *constraint=NULL; if (cond) { if(type==e_TERM_PRINCIPAL) { constraint=abac_condition_new(e_COND_ROLE,cond,cptr); } else { if(cptr == NULL) constraint=abac_condition_new(e_COND_RANGE,cond,NULL); else constraint=abac_condition_new(e_COND_OSET,cond,cptr); } } abac_term_t *ptr=abac_xmalloc(sizeof(abac_term_t)); ptr->isnamed=0; ptr->type=type; ptr->p_name=NULL; /* 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; ptr->cn=NULL; return ptr; } abac_term_t *abac_term_create(int type, char *name, abac_condition_t *cptr) { if(debug) { printf("abac_term_create: \n"); printf(" type is %d(%s)\n", type, abac_termtype_string(type)); printf(" name is (%s)\n", name); if(cptr) printf(" cptr is (%s)\n", abac_condition_typed_string(cptr)); else printf(" there is no cptr\n"); } abac_term_t *ptr=abac_xmalloc(sizeof(abac_term_t)); ptr->isnamed=0; ptr->type=type; ptr->p_name=NULL; /* 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); } ptr->constraint=(cptr==NULL)?NULL:abac_condition_dup(cptr); ptr->cn=NULL; return ptr; } /* called from yy, named principal type */ abac_term_t *abac_term_named_new(int idtype, char *name) { if(debug) { printf("abac_term_named_new: \n"); printf(" type is %d(%s)\n", idtype, abac_idtype_string(idtype)); printf(" name is (%s)\n", name); } abac_term_t *ptr=abac_xmalloc(sizeof(abac_term_t)); ptr->isnamed=1; ptr->type=idtype; ptr->name=abac_xstrdup(name); ptr->p_name=NULL; /* if ABAC_CN, no need to attach p */ if(!USE("ABAC_CN")) asprintf(&ptr->p_name,"p%s",name); ptr->constraint=NULL; ptr->cn=NULL; return ptr; } abac_term_t *abac_term_named_create(int idtype, char *name) { if(debug) { printf("abac_term_named_create: \n"); printf(" type is %d(%s)\n", idtype, abac_idtype_string(idtype)); printf(" name is (%s)\n", name); } abac_term_t *ptr=abac_xmalloc(sizeof(abac_term_t)); ptr->isnamed=1; ptr->type=idtype; ptr->name=abac_xstrdup(name); ptr->p_name=NULL; /* if ABAC_CN, no need to attach p */ if(!USE("ABAC_CN")) asprintf(&ptr->p_name,"p%s",name); ptr->constraint=NULL; ptr->cn=NULL; return ptr; } abac_term_t *abac_term_dup(abac_term_t *ptr) { assert(ptr); abac_term_t *nptr=abac_xmalloc(sizeof(abac_term_t)); nptr->isnamed=ptr->isnamed; nptr->type=ptr->type; nptr->name=abac_xstrdup(ptr->name); nptr->p_name=(ptr->p_name==NULL)?NULL:abac_xstrdup(ptr->p_name); if(ptr->constraint!=NULL) nptr->constraint=abac_condition_dup(ptr->constraint); else nptr->constraint=NULL; nptr->cn=(ptr->cn)==NULL?NULL:abac_xstrdup(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) { 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); } if(cond) { asprintf(&tmp,"%s:%s", name, cond); free(cond); } else tmp=abac_xstrdup(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; char *name=abac_term_name(ptr); char *type=abac_term_type_name(ptr); if(ptr->constraint) { cond=abac_condition_typed_string(ptr->constraint); } if(cond) { asprintf(&tmp,"[%s:%s:%s]", type, name, cond); free(cond); } else asprintf(&tmp,"[%s:%s]", type, name); if(debug) printf("abac_term_typed_string_with_condition: (%s)\n",tmp); 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); } /********************************************************************/ 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); if(debug) printf("typed param so far, %s\n", final); free(tmp); } free(s); ); if(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); if(debug) printf("param so far, %s\n", final); free(tmp); } free(s); ); if(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