/** ** abac_pl_yy.c **/ /* C declarations */ #include #include #include #include #include "abac_stack.h" #include "abac_pl_yy.h" #include "abac_util.h" #include "abac_pl_gen.h" #include "abac_list.h" #include "abac_term.h" #include "abac_aspect.h" static int debug=0; abac_context_t *abac_context=NULL; /* context used for this parsing */ static int yy_using_this=0; int abac_yy_error_code=0; /* keeping last error code */ int abac_rule_is_oset=0; abac_aspect_t *abac_rule_head_aspect=NULL; abac_aspect_t *abac_rule_tail_aspect=NULL; /* structure to hold the range information within a static constraints on few types of oset types [a..b], [a..], [..b], [a],[a,b],[many a] e_yy_RANGE_MIN=1; e_yy_RANGE_MAX=2; e_yy_RANGE_TARGET=3; */ typedef struct _abac_yy_range_t { int type; char *val; } abac_yy_range_t; /* local principal structure [keyid:USC] */ struct _abac_yy_principal_t { int type; char *sha; // sha is null when this is of object type char *cn; }; /* [principal:?Z]:..., must match a principal name */ struct _abac_yy_term_principal_t { int type; /* this needs to be implicitly determined */ int is_anonymous; char *name; int isrange; char *cond_str; // range string ??? not sure if this is possible void *cond_ptr; // ptr to a saved abac_aspect_t or a list(item_t) abac_yy_expression_t *cond_head_expr; }; /* integer,float,time,urn,string types, if has condition, then it is a variable, ie, [int:?Year]:<1930..1932>, if no condition, then it is a constant, ie, [int:10] */ struct _abac_yy_term_data_t { int is_variable; int is_anonymous; int type; char *name; char *cond_str; // range string void *cond_ptr; // ptr to a saved abac_aspect_t abac_list_t *cond_range; abac_yy_expression_t *cond_head_expr; // parking stub }; /* local term structure, will distinguish it in the future */ /* e_yy_DTERM_DATA, all other types e_yy_DTERM_NAMED, keyid:bob e_yy_DTERM_PRINCIPAL, principal:?P e_yy_DTERM_THIS, ?this e_yy_DTERM_ANONYMOUS ? */ struct _abac_yy_term_t { union { abac_yy_principal_t *n_ptr; abac_yy_term_principal_t *p_ptr; abac_yy_term_data_t *d_ptr; } term; int type; struct _abac_yy_term_t *next; int bcnt; /* this is to track number of terms in this linked up list */ }; /* local role/oset structure, e_yy_NULL_TYPE, e_yy_ROLE_TYPE, e_yy_OSET_TYPE */ struct _abac_yy_roleoset_t { int type; char *name; abac_yy_term_t *terms; struct _abac_yy_roleoset_t *next; int bcnt; /* this is to track number of roles in this linked up list */ }; /* A, A.r, A.r.r */ /* type: e_yy_EXPR_NAMED,e_yy_EXPR_ROLE,e_yy_EXPR_LINKED */ /* A/obj, A.o, A.r.o */ /* type: e_yy_EXPR_NAMED, e_yy_EXPR_OBJECT, e_yy_EXPR_OSET,e_yy_EXPR_LINKED */ struct _abac_yy_expression_t { int type; union { abac_yy_principal_t *principal; abac_yy_term_data_t *object; }; abac_yy_roleoset_t *linked_role; abac_yy_roleoset_t *roleoset; struct _abac_yy_expression_t *next; int bcnt; }; /* local */ static void _free_yy_expression(abac_yy_expression_t *); abac_aspect_t *validate_head(int yytype, abac_yy_expression_t *expr); abac_aspect_t *validate_linked_tail(int yytype, abac_yy_expression_t *expr); /************************************************************************/ void abac_yy_set_error_code(int v) { abac_yy_error_code=v; } int abac_yy_get_rule_is_oset() { return abac_rule_is_oset; } abac_aspect_t *abac_yy_get_rule_head_aspect() { return abac_rule_head_aspect; } abac_aspect_t *abac_yy_get_rule_tail_aspect() { return abac_rule_tail_aspect; } /************************************************************************/ static void _free_yy_cond_range(abac_list_t *ptr) { if (ptr != NULL) { abac_yy_range_t *cur; abac_list_foreach(ptr, cur, if(cur && cur->val) free(cur->val); free(cur); ); abac_list_free(ptr); } } static char *_string_yy_cond_range(abac_list_t *ptr) { assert(ptr); char *tmp=NULL; char *min=NULL; char *max=NULL; char *val=NULL; int type; abac_yy_range_t *cur; abac_list_foreach(ptr, cur, type=cur->type; switch (type) { case e_yy_RANGE_MIN: min=abac_xstrdup(cur->val); break; case e_yy_RANGE_MAX: max=abac_xstrdup(cur->val); break; case e_yy_RANGE_TARGET: if(val) asprintf(&val,"%s,%s",val,cur->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_list_t *add_yy_val_range(abac_list_t *ptr, char * val) { abac_yy_range_t *range= (abac_yy_range_t *) abac_xmalloc(sizeof(abac_yy_range_t)); range->type=e_yy_RANGE_TARGET; range->val=abac_xstrdup(val); abac_list_add(ptr, range); return ptr; } static abac_list_t *_add_yy_range(abac_list_t *ptr, int type, char * val) { abac_yy_range_t *range= (abac_yy_range_t *) abac_xmalloc(sizeof(abac_yy_range_t)); range->type=type; range->val=abac_xstrdup(val); abac_list_add(ptr, range); return ptr; } abac_list_t *make_yy_val_range(char *val) { abac_list_t *ptr=abac_list_new(); add_yy_val_range(ptr,val); return ptr; } abac_list_t *make_yy_minmax_range(char *min, char *max) { abac_list_t *ptr=abac_list_new(); _add_yy_range(ptr, e_yy_RANGE_MIN, min); _add_yy_range(ptr, e_yy_RANGE_MAX, max); return ptr; } abac_list_t *make_yy_min_range(char *min) { abac_list_t *ptr=abac_list_new(); _add_yy_range(ptr, e_yy_RANGE_MIN, min); return ptr; } abac_list_t *make_yy_max_range(char *max) { abac_list_t *ptr=abac_list_new(); _add_yy_range(ptr, e_yy_RANGE_MAX, max); return ptr; } /***********************************************************************/ abac_yy_term_data_t *make_yy_term_data() { abac_yy_term_data_t *ptr= (abac_yy_term_data_t*)abac_xmalloc(sizeof(abac_yy_term_data_t)); ptr->name=NULL; ptr->type=0; ptr->is_variable=0; ptr->is_anonymous=0; ptr->cond_str=NULL; ptr->cond_head_expr=NULL; ptr->cond_ptr=NULL; ptr->cond_range=NULL; return ptr; } void set_yy_term_data_name(abac_yy_term_data_t *ptr, char *name) { ptr->name=abac_xstrdup(name); } abac_list_t *get_yy_term_data_cond_range(abac_yy_term_data_t *ptr) { return ptr->cond_range; } char *get_yy_term_data_name(abac_yy_term_data_t *ptr) { return ptr->name; } int is_yy_term_data_has_constraint(abac_yy_term_data_t *ptr) { if(ptr->cond_head_expr != NULL) return 1; if(ptr->cond_range != NULL) return 1; return 0; } void set_yy_term_data_cond_range(abac_yy_term_data_t *ptr, abac_list_t *range) { ptr->cond_range=range; } void set_yy_term_data_cond_head_expr(abac_yy_term_data_t *ptr, abac_yy_expression_t *expr) { ptr->cond_head_expr=expr; } abac_yy_expression_t *get_yy_term_data_cond_head_expr(abac_yy_term_data_t *ptr) { return ptr->cond_head_expr; } void set_yy_term_data_type(abac_yy_term_data_t *ptr, char* typestr) { int type=abac_verify_term_type(typestr); ptr->type=type; } void set_yy_term_data_is_anonymous(abac_yy_term_data_t *ptr) { ptr->is_anonymous=1; } int is_yy_term_data_type_numeric(abac_yy_term_data_t *ptr) { if(ptr->type==abac_verify_term_type("integer") || ptr->type==abac_verify_term_type("float")) return 1; return 0; } int is_yy_term_data_type_time(abac_yy_term_data_t *ptr) { if(ptr->type==abac_verify_term_type("time")) return 1; return 0; } int is_yy_term_data_type_alpha(abac_yy_term_data_t *ptr) { if(ptr->type==abac_verify_term_type("string") || ptr->type==abac_verify_term_type("urn") || ptr->type==abac_verify_term_type("boolean")) return 1; return 0; } void set_yy_term_data_cond_ptr(abac_yy_term_data_t *ptr, void *vptr) { ptr->cond_ptr=vptr; } void set_yy_term_data_cond_str(abac_yy_term_data_t *ptr, char *cond) { ptr->cond_str=abac_xstrdup(cond); } void set_yy_term_data_is_variable(abac_yy_term_data_t *ptr) { ptr->is_variable=1; } int get_yy_term_data_is_variable(abac_yy_term_data_t *ptr) { return ptr->is_variable; } static void _free_yy_term_data(abac_yy_term_data_t *ptr) { free(ptr->name); if(ptr->cond_str) free(ptr->cond_str); if(ptr->cond_head_expr) _free_yy_expression(ptr->cond_head_expr); if(ptr->cond_range); _free_yy_cond_range(ptr->cond_range); free(ptr); } abac_yy_term_principal_t *make_yy_term_principal() { abac_yy_term_principal_t *ptr= (abac_yy_term_principal_t*)abac_xmalloc(sizeof(abac_yy_term_principal_t)); ptr->type=0;/* this is not known */ ptr->is_anonymous=0; ptr->name=NULL; ptr->isrange=0; ptr->cond_str=NULL; ptr->cond_ptr=NULL; ptr->cond_head_expr=NULL; return ptr; } static void _set_using_this() { yy_using_this=1; } int abac_yy_get_using_this() { return yy_using_this; } void set_yy_term_principal_isrange(abac_yy_term_principal_t *ptr, int isrange) { ptr->isrange=isrange; } void set_yy_term_principal_name(abac_yy_term_principal_t *ptr, char *name) { ptr->name=abac_xstrdup(name); } void set_yy_term_principal_cond_ptr(abac_yy_term_principal_t *ptr, void *vptr) { ptr->cond_ptr=vptr; } void set_yy_term_principal_cond_str(abac_yy_term_principal_t *ptr, char *cond) { ptr->cond_str=abac_xstrdup(cond); } void set_yy_term_principal_is_anonymous(abac_yy_term_principal_t *ptr) { ptr->is_anonymous=1; } abac_yy_expression_t *get_yy_term_principal_cond_head_expr(abac_yy_term_principal_t *ptr) { return ptr->cond_head_expr; } void set_yy_term_principal_cond_head_expr(abac_yy_term_principal_t *ptr, abac_yy_expression_t *expr) { ptr->cond_head_expr=expr; } static void _free_yy_term_principal(abac_yy_term_principal_t *ptr) { free(ptr->name); if(ptr->cond_str) free(ptr->cond_str); if(ptr->cond_head_expr) _free_yy_expression(ptr->cond_head_expr); free(ptr); } abac_yy_term_t *make_yy_term_dterm_this() { abac_yy_term_t *ptr=(abac_yy_term_t*)abac_xmalloc(sizeof(abac_yy_term_t)); ptr->type = e_yy_DTERM_THIS; ptr->next=NULL; ptr->bcnt=1; _set_using_this(); return ptr; } abac_yy_term_t *make_yy_term_dterm_anonymous() { abac_yy_term_t *ptr=(abac_yy_term_t*)abac_xmalloc(sizeof(abac_yy_term_t)); ptr->type = e_yy_DTERM_ANONYMOUS; ptr->next=NULL; ptr->bcnt=1; return ptr; } abac_yy_term_t *make_yy_term_dterm_principal(abac_yy_term_principal_t *pptr) { abac_yy_term_t *ptr=(abac_yy_term_t*)abac_xmalloc(sizeof(abac_yy_term_t)); if(pptr->is_anonymous) ptr->type = e_yy_DTERM_ANONYMOUS; else ptr->type = e_yy_DTERM_PRINCIPAL; ptr->term.p_ptr=pptr; ptr->next=NULL; ptr->bcnt=1; return ptr; } abac_yy_term_t *make_yy_term_dterm_named(abac_yy_principal_t *nptr) { abac_yy_term_t *ptr=(abac_yy_term_t*)abac_xmalloc(sizeof(abac_yy_term_t)); ptr->type = e_yy_DTERM_NAMED; ptr->term.n_ptr=nptr; ptr->next=NULL; ptr->bcnt=1; return ptr; } abac_yy_term_t *make_yy_term_dterm_data(abac_yy_term_data_t *dptr) { abac_yy_term_t *ptr=(abac_yy_term_t*)abac_xmalloc(sizeof(abac_yy_term_t)); if(dptr->is_anonymous) ptr->type = e_yy_DTERM_ANONYMOUS; else ptr->type = e_yy_DTERM_DATA; ptr->term.d_ptr=dptr; ptr->next=NULL; ptr->bcnt=1; return ptr; } /****************************************************************************/ abac_yy_principal_t *make_yy_principal(char *sha, char *cn, int type) { abac_yy_principal_t *ptr= (abac_yy_principal_t*)abac_xmalloc(sizeof(abac_yy_principal_t)); /* add p to yyparse's principal */ if(sha) ptr->sha=abac_xstrdup(sha); else ptr->sha=NULL; if(cn) ptr->cn=abac_xstrdup(cn); else ptr->cn=NULL; ptr->type=type; return ptr; } static void _free_yy_principal(abac_yy_principal_t *ptr) { if(ptr->sha) free(ptr->sha); if(ptr->cn) free(ptr->cn); free(ptr); } int get_yy_principal_type(abac_yy_principal_t *ptr) { return ptr->type; } char *get_yy_principal_name(abac_yy_principal_t *ptr) { if(USE("ABAC_CN") && ptr->cn) return ptr->cn; return ptr->sha; } char *get_yy_principal_cn(abac_yy_principal_t *ptr) { return ptr->cn; } char *get_yy_principal_sha(abac_yy_principal_t *ptr) { return ptr->sha; } /*************************************************************************/ abac_yy_term_t *add_yy_term(abac_yy_term_t *nterm, abac_yy_term_t *terms) { int i=terms->bcnt; nterm->next=terms; nterm->bcnt=i+1; return nterm; } static void _free_yy_term(abac_yy_term_t *ptr) { switch (ptr->type) { case e_yy_DTERM_DATA: _free_yy_term_data(ptr->term.d_ptr); break; case e_yy_DTERM_NAMED: _free_yy_principal(ptr->term.n_ptr); break; case e_yy_DTERM_PRINCIPAL: _free_yy_term_principal(ptr->term.p_ptr); break; case e_yy_DTERM_ANONYMOUS: case e_yy_DTERM_THIS: break; } if(ptr->next) _free_yy_term(ptr->next); free(ptr); } /*************************************************************************/ abac_yy_roleoset_t *make_yy_roleoset_role(char *name, abac_yy_term_t *terms) { abac_yy_roleoset_t *ptr= (abac_yy_roleoset_t*)abac_xmalloc(sizeof(abac_yy_roleoset_t)); ptr->name=abac_xstrdup(name); ptr->terms=terms; ptr->next=NULL; ptr->bcnt=1; ptr->type=e_yy_ROLE_TYPE; return ptr; } static void _free_yy_roleoset(abac_yy_roleoset_t *ptr) { free(ptr->name); if(ptr->terms) _free_yy_term(ptr->terms); if(ptr->next) _free_yy_roleoset(ptr->next); free(ptr); } /***************************************************************************/ abac_yy_roleoset_t *make_yy_roleoset_oset(char *name, abac_yy_term_t *terms) { abac_yy_roleoset_t *ptr= (abac_yy_roleoset_t*)abac_xmalloc(sizeof(abac_yy_roleoset_t)); ptr->name=abac_xstrdup(name); ptr->terms=terms; ptr->next=NULL; ptr->bcnt=1; ptr->type=e_yy_OSET_TYPE; return ptr; } /***************************************************************************/ /* type: e_yy_EXPR_NAMED, e_yy_EXPR_OBJECT, e_yy_EXPR_OSET,e_yy_EXPR_LINKED */ abac_yy_expression_t *make_yy_expression(int type,void *pptr, abac_yy_roleoset_t *optr, abac_yy_roleoset_t *linked_role) { abac_yy_expression_t *ptr= (abac_yy_expression_t*)abac_xmalloc(sizeof(abac_yy_expression_t)); ptr->type = type; if(type == e_yy_EXPR_OBJECT) { ptr->object=(abac_yy_term_data_t *)pptr; } else { ptr->principal = (abac_yy_principal_t *)pptr; } ptr->roleoset = optr; ptr->linked_role=linked_role; ptr->next=NULL; return ptr; } abac_yy_term_data_t *get_yy_expression_object(abac_yy_expression_t *ptr) { if(ptr->type == e_yy_EXPR_OBJECT) return ptr->object; return NULL; } abac_yy_expression_t *add_yy_expression(abac_yy_expression_t *nexpr, abac_yy_expression_t *exprs) { int i=exprs->bcnt; nexpr->next=exprs; nexpr->bcnt=i+1; return nexpr; } static void _free_yy_expression(abac_yy_expression_t *ptr) { if(ptr->type == e_yy_EXPR_OBJECT) { if(ptr->object) _free_yy_term_data(ptr->object); } else { if(ptr->principal) _free_yy_principal(ptr->principal); } if(ptr->roleoset) _free_yy_roleoset(ptr->roleoset); if(ptr->linked_role) _free_yy_roleoset(ptr->linked_role); if(ptr->next) _free_yy_expression(ptr->next); free(ptr); } /***************************************************************************/ /* add the oset condition to constraint list */ void make_yy_oset_constraint(abac_yy_term_data_t *ptr, char *tail_string) { abac_yy_expression_t *cond_expr=get_yy_term_data_cond_head_expr(ptr); if(cond_expr) { abac_aspect_t *cond_aspect=NULL; if(cond_expr->type == e_yy_EXPR_LINKED) cond_aspect=validate_linked_tail(e_yy_OSET_TYPE,cond_expr); else cond_aspect=validate_head(e_yy_OSET_TYPE,cond_expr); if(cond_aspect != NULL) { if(debug) fprintf(stderr,"make_yy_oset_constraint..\n"); set_yy_term_data_cond_ptr(ptr,cond_aspect); } } } /* add the role condition to constraint list */ void make_yy_role_constraint(abac_yy_term_principal_t *ptr, char *tail_string) { abac_yy_expression_t *cond_expr=get_yy_term_principal_cond_head_expr(ptr); if(cond_expr) { abac_aspect_t *cond_aspect=NULL; if(cond_expr->type == e_yy_EXPR_LINKED) cond_aspect=validate_linked_tail(e_yy_ROLE_TYPE,cond_expr); else cond_aspect=validate_head(e_yy_ROLE_TYPE,cond_expr); if(cond_aspect != NULL) { if(debug) fprintf(stderr,"make_yy_role_constraint..\n"); set_yy_term_principal_cond_ptr(ptr,cond_aspect); set_yy_term_principal_isrange(ptr,0); } } } /****************************************************************/ static void _aspect_add_terms(int linked, abac_aspect_t *aspect_ptr, abac_yy_term_t *terms) { abac_yy_term_t *curr = terms; int type; int isnamed; int isrange; char *name; char *cond; void *ptr; while (curr) { name=NULL; cond=NULL; ptr=NULL; isnamed=0; isrange=0; switch (curr->type) { case e_yy_DTERM_DATA: { abac_yy_term_data_t *dptr=curr->term.d_ptr; type=dptr->type; name=abac_xstrdup(dptr->name); if(dptr->cond_str) cond=abac_xstrdup(dptr->cond_str); ptr=dptr->cond_ptr; isrange=(dptr->cond_range!=NULL)?1:0; break; } case e_yy_DTERM_PRINCIPAL: { abac_yy_term_principal_t *pptr=curr->term.p_ptr; type=abac_verify_term_type("principal"); name=abac_xstrdup(pptr->name); if(pptr->cond_str) cond=abac_xstrdup(pptr->cond_str); ptr=pptr->cond_ptr; isrange=pptr->isrange; break; } case e_yy_DTERM_NAMED: { abac_yy_principal_t *pptr=curr->term.n_ptr; type=pptr->type; name=abac_xstrdup(get_yy_principal_name(pptr)); isnamed=1; break; } case e_yy_DTERM_ANONYMOUS: { type=abac_verify_term_type("anonymous"); name=abac_xstrdup("_"); break; } case e_yy_DTERM_THIS: { type=abac_verify_term_type("this"); name=abac_xstrdup("This"); break; } } abac_term_t *param=NULL; if(isnamed) param=abac_term_named_new(type,name); else param=abac_term_new(type,name,isrange,cond,ptr); if (linked) abac_aspect_add_linked_param(aspect_ptr, param); else abac_aspect_add_param(aspect_ptr, param); curr=curr->next; } } static void _aspect_add_linked_terms(abac_aspect_t *ptr, abac_yy_term_t *terms) { int linked=1; _aspect_add_terms(linked, ptr, terms); } static void _aspect_add_aspect_terms(abac_aspect_t *ptr, abac_yy_term_t *terms) { int linked=0; _aspect_add_terms(linked, ptr, terms); } abac_aspect_t *validate_intersected_tail(abac_aspect_t *ptr) { abac_aspect_t *ret_ptr=abac_aspect_intersection_new(ptr); return ret_ptr; } /* A.oset, A.role */ abac_aspect_t *validate_head(int yytype, abac_yy_expression_t *expr) { abac_yy_principal_t *principal=expr->principal; abac_yy_roleoset_t *ptr=expr->roleoset; char *principalname=get_yy_principal_sha(principal); char *name=ptr->name; abac_yy_term_t *terms=ptr->terms; abac_aspect_t *aptr=NULL; if(yytype==e_yy_OSET_TYPE) aptr=abac_aspect_oset_new(principalname, name); else aptr=abac_aspect_role_new(principalname, name); if (aptr==NULL) { abac_yy_set_error_code(ABAC_YY_INVALID_HEAD); goto error; } // insert the params for the oset if(terms) { _aspect_add_aspect_terms(aptr, terms); } return aptr; error: return NULL; } abac_aspect_t *validate_head_oset(abac_yy_expression_t *expr) { return validate_head(e_yy_OSET_TYPE,expr); } abac_aspect_t *validate_head_role(abac_yy_expression_t *expr) { return validate_head(e_yy_ROLE_TYPE,expr); } /*****************************************************************************/ /* B */ abac_aspect_t *validate_named_tail(int yytype, abac_yy_expression_t *expr) { abac_yy_principal_t *principal=expr->principal; char *principalname=get_yy_principal_sha(principal); abac_aspect_t *ptr=NULL; if(yytype==e_yy_OSET_TYPE) ptr=abac_aspect_oset_principal_new(principalname); else ptr=abac_aspect_role_principal_new(principalname); if (ptr==NULL) goto error; return ptr; error: panic("can not generate a simple named tail oset aspect"); return NULL; } /* [keyid:alpha].oset:documents([string:'proj1'])<-[urn:'file//fileA'] */ abac_aspect_t *validate_object_tail(int yytype,abac_yy_expression_t *expr) { abac_yy_term_data_t *object=get_yy_expression_object(expr); assert(object != NULL); char *name=object->name; int type=object->type; char *cond=object->cond_str; void *ptr=object->cond_ptr; int isrange=(object->cond_range!=NULL)?1:0; abac_term_t *term=abac_term_new(type,name,isrange,cond,ptr); abac_aspect_t *aptr=NULL; if(yytype==e_yy_OSET_TYPE) aptr=abac_aspect_oset_object_new(term); else goto error; /* can not be a role expression with obj */ if (aptr==NULL) goto error; return aptr; error: panic("can not generate a simple object tail oset aspect"); return NULL; } /* B.role or B.oset */ abac_aspect_t *validate_some_tail(int yytype, abac_yy_expression_t *expr) { abac_yy_principal_t *principal=expr->principal; abac_yy_roleoset_t *eptr=expr->roleoset; char *principalname=get_yy_principal_sha(principal); char *name=eptr->name; abac_yy_term_t *terms=eptr->terms; abac_aspect_t *ptr=NULL; if(yytype==e_yy_OSET_TYPE) ptr=abac_aspect_oset_new(principalname, name); else ptr=abac_aspect_role_new(principalname, name); if (ptr==NULL) goto error; if(terms) { _aspect_add_aspect_terms(ptr, terms); } return ptr; error: panic("can not generate a simple tail aspect"); return NULL; } /* B.role.role or B.role.oset */ abac_aspect_t *validate_linked_tail(int yytype, abac_yy_expression_t *expr) { abac_yy_principal_t *principal=expr->principal; abac_yy_roleoset_t *eptr=expr->roleoset; abac_yy_roleoset_t *linked_role=expr->linked_role; char *principalname=get_yy_principal_sha(principal); char *name=eptr->name; abac_yy_term_t *terms=eptr->terms; char *linkedrolename=linked_role->name; abac_yy_term_t *linked_terms=linked_role->terms; abac_aspect_t *ptr=NULL; if(yytype==e_yy_OSET_TYPE) ptr=abac_aspect_oset_linking_new(principalname, linkedrolename, name); else ptr=abac_aspect_role_linking_new(principalname, linkedrolename, name); if (ptr==NULL) goto error; if(linked_terms) { _aspect_add_linked_terms(ptr, linked_terms); } if(terms) { _aspect_add_aspect_terms(ptr, terms); } return ptr; error: panic("can not generate linked tail oset"); return NULL; } /**********************************************************************/ int make_oset_statement(abac_yy_expression_t *headexpr, abac_yy_expression_t *tailexpr) { int rc=0; abac_aspect_t *head_oset=NULL; abac_aspect_t *tail_oset=NULL; /* build up left side's abac oset structure */ head_oset=validate_head(e_yy_OSET_TYPE, headexpr); if(head_oset == NULL) { rc=1; goto error; } /* build up the right side's abac oset structure */ abac_yy_expression_t *curr_tail = tailexpr; int intersecting=(tailexpr->next != NULL)? 1:0; abac_aspect_t *curr_oset = NULL; while (curr_tail) { switch(curr_tail->type) { case e_yy_EXPR_OBJECT: curr_oset=validate_object_tail(e_yy_OSET_TYPE,curr_tail); break; case e_yy_EXPR_NAMED: curr_oset=validate_named_tail(e_yy_OSET_TYPE,curr_tail); break; case e_yy_EXPR_OSET: curr_oset=validate_some_tail(e_yy_OSET_TYPE,curr_tail); break; case e_yy_EXPR_LINKED: curr_oset=validate_linked_tail(e_yy_OSET_TYPE,curr_tail); break; } if(curr_oset==NULL) { rc=1; goto error; } /* check if first one */ if(tail_oset==NULL) { if(intersecting) tail_oset=validate_intersected_tail(curr_oset); else tail_oset=curr_oset; } else { abac_aspect_add_intersecting_aspect(tail_oset,curr_oset); } curr_tail=curr_tail->next; } /* while */ if(debug) { fprintf(stderr,"aspect head_oset: "); abac_print_aspect_string_with_condition(head_oset,stderr); fprintf(stderr,"\n"); fprintf(stderr,"aspect tail_oset: "); abac_print_aspect_string_with_condition(tail_oset,stderr); fprintf(stderr,"\n"); } error: _free_yy_expression(headexpr); _free_yy_expression(tailexpr); abac_rule_head_aspect=head_oset; abac_rule_tail_aspect=tail_oset; abac_rule_is_oset=1; return rc; } /*****************************************************************************/ abac_list_t *validate_range(abac_list_t *ptr) { abac_list_t *nlist=abac_list_new(); abac_item_t *nitem; abac_yy_range_t *cur; char *val; int type; abac_list_foreach(ptr, cur, if(cur) { type=cur->type; val=cur->val; if(type==e_yy_RANGE_MIN) nitem=abac_item_new(abac_min_item_type(),val); if(type==e_yy_RANGE_MAX) nitem=abac_item_new(abac_max_item_type(),val); if(type==e_yy_RANGE_TARGET) nitem=abac_item_new(abac_target_item_type(),val); abac_list_add(nlist,nitem); } ); return nlist; } /****************************************************************/ void make_yy_range_constraint(abac_yy_term_data_t *ptr) { if(is_yy_term_data_type_numeric(ptr) || is_yy_term_data_type_alpha(ptr) || is_yy_term_data_type_time(ptr)) { abac_list_t *rlist=get_yy_term_data_cond_range(ptr); if(rlist) { abac_list_t *nlist=validate_range(rlist); set_yy_term_data_cond_ptr(ptr,nlist); } } } /*****************************************************************************/ abac_context_t *get_abac_context() { assert(abac_context); return abac_context; } /* build up the abac structure */ int make_role_statement(abac_yy_expression_t *headexpr, abac_yy_expression_t *tailexpr) { int rc=0; abac_aspect_t *head_role=NULL; abac_aspect_t *tail_role=NULL; /* build up left side's abac role structure */ head_role=validate_head(e_yy_ROLE_TYPE,headexpr); if(head_role == NULL) { rc=1; goto error; } /* build up the right side's abac role structure */ abac_yy_expression_t *curr_tail = tailexpr; int intersecting=(tailexpr->next != NULL)? 1:0; abac_aspect_t *curr_role = NULL; while (curr_tail) { switch(curr_tail->type) { case e_yy_EXPR_NAMED: curr_role=validate_named_tail(e_yy_ROLE_TYPE,curr_tail); break; case e_yy_EXPR_ROLE: curr_role=validate_some_tail(e_yy_ROLE_TYPE,curr_tail); break; case e_yy_EXPR_LINKED: curr_role=validate_linked_tail(e_yy_ROLE_TYPE,curr_tail); break; } if(curr_role==NULL) { rc=1; goto error; } /* check if first one */ if(tail_role==NULL) { if(intersecting) tail_role=validate_intersected_tail(curr_role); else tail_role=curr_role; } else { abac_aspect_add_intersecting_aspect(tail_role,curr_role); } curr_tail=curr_tail->next; } /* while */ if(debug) { fprintf(stderr,"aspect head_role: "); abac_print_aspect_string_with_condition(head_role,stderr); fprintf(stderr,"\n"); fprintf(stderr,"aspect tail_role: "); abac_print_aspect_string_with_condition(tail_role,stderr); fprintf(stderr,"\n"); } error: _free_yy_expression(headexpr); _free_yy_expression(tailexpr); abac_rule_head_aspect=head_role; abac_rule_tail_aspect=tail_role; abac_rule_is_oset=0; return rc; } /************************************************************************/ void abac_yy_init(abac_context_t *ctxt) { yy_using_this=0; abac_context=ctxt; abac_yyinit(); } /************************************************************************/ /* this is called to parse a string into 2 aspect structures */ /* NEED TO BE LOCKED HERE XXX */ int abac_yy_parse(abac_context_t *ctxt, char* attr_string, abac_aspect_t **head_aspect, abac_aspect_t **tail_aspect, int *using_this) { /*ctxt could be null*/ abac_ll_reset_yyfptr(attr_string); abac_yy_init(ctxt); int rc=yyparse(); if (rc) { free(attr_string); abac_yy_set_error_code(ABAC_RT_CERT_INVALID); return 1; } *head_aspect = abac_yy_get_rule_head_aspect(); *tail_aspect = abac_yy_get_rule_tail_aspect(); *using_this= abac_yy_get_using_this(); return 0; }