/* C declarations */ #include #include #include #include #include "abac_util.h" #include "abac_pl_yy.h" static int debug=0; extern void panic(char*); /* from abac_pl_gen.c */ extern char *generate_pl_range_constraint(char *,char *,char *,char *); extern char *generate_pl_oset_constraint_clause(abac_oset_t *, char *); extern abac_list_t *generate_pl_role_clauses(abac_role_t *, abac_role_t *); extern abac_list_t *generate_pl_oset_clauses(abac_oset_t *, abac_oset_t *); extern char* generate_pl_role_constraint_clause(abac_role_t *, char *); extern char *generate_pl_type_clause(char *, int); /* from abac_pl_yap.c */ extern char *abac_pl_add_string_range_constraint_clause(char *var, char *tmplist); /* from rt2.y */ extern void abac_yyinit(); int abac_yy_error_code = 0; /* keeping last error code */ int abac_rule_is_oset=0; abac_list_t *abac_rule_clauses=NULL; abac_stack_t *abac_rule_id_clauses=NULL; /* tracking individual id credentials */ abac_role_t *abac_rule_head_role=NULL; abac_role_t *abac_rule_tail_role=NULL; abac_oset_t *abac_rule_head_oset=NULL; abac_oset_t *abac_rule_tail_oset=NULL; /* to track id certs within a rule clause */ typedef struct _abac_yy_id_cert_t { char *principalname; int type; /* keyidtype */ char *clause; } abac_yy_id_cert_t; abac_list_t *abac_yy_id_certs = 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; /* to track role/oset constraint clauses used within a rule clause, collect them up in one place, these are for conjunction clauses */ typedef struct _abac_yy_constraint_t { char *clause; } abac_yy_constraint_t; abac_list_t *abac_yy_constraints = NULL; /* 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 */ char *name; char *cond_str; void *cond_ptr; // ptr to a saved abac_role_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 type; char *name; char *cond_str; void *cond_ptr; // ptr to a saved abac_oset_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_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 structure */ struct _abac_yy_role_t { int type; char *name; abac_yy_term_t *terms; struct _abac_yy_role_t *next; int bcnt; /* this is to track number of roles in this linked up list */ }; /* local oset structure */ struct _abac_yy_oset_t { int type; char *name; abac_yy_term_t *terms; struct _abac_yy_oset_t *next; int bcnt; /* this is to track number of oset 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_role_t *linked_role; union { abac_yy_role_t *role; abac_yy_oset_t *oset; }; struct _abac_yy_expression_t *next; int bcnt; }; static void _free_yy_expression(abac_yy_expression_t *); /************************************************************************/ void abac_yy_set_error_code(int v) { abac_yy_error_code=v; } /************************************************************************/ abac_stack_t *abac_yy_get_rule_id_clauses() { return abac_rule_id_clauses; } abac_stack_t *abac_yy_init_rule_id_clauses() { abac_rule_id_clauses=abac_stack_new(); return abac_rule_id_clauses; } void abac_yy_free_rule_id_clauses() { if (abac_rule_id_clauses != NULL) abac_stack_free(abac_rule_id_clauses); } void abac_yy_set_rule_clauses(abac_list_t *clauses) { abac_rule_clauses=clauses; if(debug) { printf("printing out abac_rule_clauses:\n"); abac_print_clauses(abac_rule_clauses,NULL); } } abac_list_t *abac_yy_get_rule_clauses() { return abac_rule_clauses; } void abac_yy_free_rule_clauses() { if (abac_rule_clauses != NULL) { char *cur; abac_list_foreach(abac_yy_id_certs, cur, if(cur) free(cur); ); abac_list_free(abac_rule_clauses); } } int abac_yy_get_rule_is_oset() { return abac_rule_is_oset; } abac_role_t *abac_yy_get_rule_head_role() { return abac_rule_head_role; } abac_role_t *abac_yy_get_rule_tail_role() { return abac_rule_tail_role; } abac_oset_t *abac_yy_get_rule_head_oset() { return abac_rule_head_oset; } abac_oset_t *abac_yy_get_rule_tail_oset() { return abac_rule_tail_oset; } /************************************************************************/ void abac_yy_init_yy_id_certs() { abac_yy_id_certs = abac_list_new(); } void abac_yy_free_yy_id_certs() { abac_yy_id_cert_t *id; abac_list_foreach(abac_yy_id_certs, id, if(id) free(id->principalname); free(id->clause); free(id); ); abac_list_free(abac_yy_id_certs); abac_yy_id_certs = NULL; } int abac_yy_cnt_yy_id_certs() { return abac_list_size(abac_yy_id_certs); } char *abac_yy_string_yy_id_certs() { int first=1; char *tmp=NULL; abac_yy_id_cert_t *cur; abac_list_foreach(abac_yy_id_certs, cur, if(cur) if(first) { tmp=abac_xstrdup(cur->clause); first=0; } else { int cnt=asprintf(&tmp,"%s,%s", tmp, cur->clause); } ); return tmp; } static void _add_yy_id_certs(char *principalname, int type) { abac_yy_id_cert_t *id_cert=NULL; int found=0; abac_yy_id_cert_t *cur; abac_list_foreach(abac_yy_id_certs, cur, if(cur) if(strcmp(cur->principalname,principalname)==0) { found=1; break; } ); if (found) { return; } else { id_cert=abac_xmalloc(sizeof(abac_yy_id_cert_t)); id_cert->principalname=abac_xstrdup(principalname); id_cert->type=type; id_cert->clause=generate_pl_type_clause(principalname,type); abac_list_add(abac_yy_id_certs, id_cert); } } /***********************************************************************/ 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=strdup(cur->val); break; case e_yy_RANGE_MAX: max=strdup(cur->val); break; case e_yy_RANGE_TARGET: if(val) asprintf(&val,"%s,%s",val,cur->val); else val=strdup(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=strdup(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=strdup(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(char* name) { abac_yy_term_data_t *ptr= (abac_yy_term_data_t*)abac_xmalloc(sizeof(abac_yy_term_data_t)); ptr->name=abac_xstrdup(name); ptr->type=0; ptr->is_variable=0; ptr->cond_str=NULL; ptr->cond_head_expr=NULL; ptr->cond_ptr=NULL; ptr->cond_range=NULL; return ptr; } 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_term_verify_term_type(typestr); ptr->type=type; } int is_yy_term_data_type_numeric(abac_yy_term_data_t *ptr) { if(ptr->type==abac_term_verify_term_type("integer") || ptr->type==abac_term_verify_term_type("float")) return 1; return 0; } int is_yy_term_data_type_alpha(abac_yy_term_data_t *ptr) { if(ptr->type==abac_term_verify_term_type("string") || ptr->type==abac_term_verify_term_type("urn")) 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=strdup(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(char* name) { 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->name=abac_xstrdup(name); ptr->cond_str=NULL; ptr->cond_head_expr=NULL; return ptr; } 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); } 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_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)); 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)); ptr->type = e_yy_DTERM_DATA; ptr->term.d_ptr=dptr; ptr->next=NULL; ptr->bcnt=1; return ptr; } /************************************************************************/ void abac_yy_init_yy_constraints() { abac_yy_constraints = abac_list_new(); } void abac_yy_free_yy_constraints() { abac_yy_constraint_t *cur; abac_list_foreach(abac_yy_constraints, cur, if(cur && cur->clause) free(cur->clause); free(cur); ); abac_list_free(abac_yy_constraints); abac_yy_constraints=NULL; } int abac_yy_cnt_yy_constraints() { return abac_list_size(abac_yy_constraints); } char *abac_yy_string_yy_constraints() { int first=1; char *tmp=NULL; abac_yy_constraint_t *cur; abac_list_foreach(abac_yy_constraints, cur, if(cur && cur->clause) if(first) { tmp=abac_xstrdup(cur->clause); first=0; } else { int cnt=asprintf(&tmp,"%s,%s", tmp, cur->clause); } ); return tmp; } abac_yy_constraint_t *abac_yy_add_yy_constraints(char *constraint) { abac_yy_constraint_t *ptr= (abac_yy_constraint_t *) abac_xmalloc(sizeof(abac_yy_constraint_t)); ptr->clause=strdup(constraint); abac_list_add(abac_yy_constraints, ptr); 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)); ptr->sha=abac_xstrdup(sha); ptr->cn=abac_xstrdup(cn); ptr->type=type; return ptr; } static void _free_yy_principal(abac_yy_principal_t *ptr) { 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_principalname(abac_yy_principal_t *ptr) { if(ptr->sha == NULL) return ptr->cn; 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: break; } if(ptr->next) _free_yy_term(ptr->next); free(ptr); } /*************************************************************************/ abac_yy_role_t *make_yy_role(char *name, abac_yy_term_t *terms) { abac_yy_role_t *ptr=(abac_yy_role_t*)abac_xmalloc(sizeof(abac_yy_role_t)); ptr->name=abac_xstrdup(name); ptr->terms=terms; ptr->next=NULL; ptr->bcnt=1; return ptr; } static void _free_yy_role(abac_yy_role_t *ptr) { free(ptr->name); if(ptr->terms) _free_yy_term(ptr->terms); if(ptr->next) _free_yy_role(ptr->next); free(ptr); } /***************************************************************************/ abac_yy_oset_t *make_yy_oset(char *name, abac_yy_term_t *terms) { abac_yy_oset_t *ptr=(abac_yy_oset_t*)abac_xmalloc(sizeof(abac_yy_oset_t)); ptr->name=abac_xstrdup(name); ptr->terms=terms; ptr->next=NULL; ptr->bcnt=1; return ptr; } static void _free_yy_oset(abac_yy_oset_t *ptr) { free(ptr->name); if(ptr->terms) _free_yy_term(ptr->terms); if(ptr->next) _free_yy_oset(ptr->next); free(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, void *optr, abac_yy_role_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; } if(type == e_yy_EXPR_OSET) ptr->oset = (abac_yy_oset_t *) optr; else ptr->role = (abac_yy_role_t *) 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->type == e_yy_EXPR_OSET) { if(ptr->oset) _free_yy_oset(ptr->oset); } else { if(ptr->role) _free_yy_role(ptr->role); } if(ptr->linked_role) _free_yy_role(ptr->linked_role); if(ptr->next) _free_yy_expression(ptr->next); free(ptr); } /***************************************************************************/ static void _oset_add_terms(int linked, abac_oset_t *oset, abac_yy_term_t *terms) { abac_yy_term_t *curr = terms; int type; char *name=NULL; char *cond=NULL; void *ptr=NULL; while (curr) { switch (curr->type) { case e_yy_DTERM_DATA: { abac_yy_term_data_t *ptr=curr->term.d_ptr; type=ptr->type; name=abac_xstrdup(ptr->name); cond=abac_xstrdup(ptr->cond_str); ptr=ptr->cond_ptr; break; } case e_yy_DTERM_PRINCIPAL: { abac_yy_term_principal_t *ptr=curr->term.p_ptr; type=abac_term_verify_term_type("principal"); name=abac_xstrdup(ptr->name); cond=abac_xstrdup(ptr->cond_str); ptr=ptr->cond_ptr; break; } case e_yy_DTERM_NAMED: { abac_yy_principal_t *ptr=curr->term.n_ptr; type=ptr->type; /* XXX should be switching to sha in the future */ name=abac_xstrdup(ptr->cn); cond=NULL; ptr=NULL; break; } case e_yy_DTERM_ANONYMOUS: { type=0; name=abac_xstrdup("_"); cond=NULL; ptr=NULL; break; } } abac_term_t *param=abac_term_new(type,name,cond,ptr); if (linked) abac_oset_oset_add_linked_param(oset, param); else abac_oset_oset_add_param(oset, param); curr=curr->next; } } static void _oset_add_linked_terms(abac_oset_t *oset, abac_yy_term_t *terms) { int linked=1; _oset_add_terms(linked, oset, terms); } static void _oset_add_oset_terms(abac_oset_t *oset, abac_yy_term_t *terms) { int linked=0; _oset_add_terms(linked, oset, terms); } abac_oset_t *validate_intersected_tail_oset(abac_oset_t *oset) { abac_oset_t *ret_oset=NULL; abac_list_t *prereqs = abac_list_new(); abac_list_add(prereqs, oset); ret_oset = abac_oset_intersection_new("intersectingOSET", prereqs); return ret_oset; } /* A.oset */ abac_oset_t *validate_head_oset(abac_yy_expression_t *expr) { abac_yy_principal_t *principal=expr->principal; abac_yy_oset_t *oset=expr->oset; char *principalname=get_yy_principal_principalname(principal); char *osetname=oset->name; abac_yy_term_t *terms=oset->terms; abac_oset_t *ret_oset=abac_oset_oset_new(principalname, osetname); if (ret_oset==NULL) { abac_yy_set_error_code(ABAC_RT_ROLE_INVALID); goto error; } if (!abac_oset_is_oset(ret_oset)) { abac_yy_set_error_code(ABAC_RT_CERT_INVALID); goto error; } // insert the params for the oset if(terms) { _oset_add_oset_terms(ret_oset, terms); } _add_yy_id_certs(principal->cn,principal->type); return ret_oset; error: return NULL; } /* B */ abac_oset_t *validate_named_tail_oset(abac_yy_expression_t *expr) { abac_yy_principal_t *principal=expr->principal; char *principalname=principal->sha; abac_oset_t *ret_oset=NULL; ret_oset = abac_oset_principal_new(principalname); _add_yy_id_certs(principal->cn,principal->type); if (ret_oset==NULL) goto error; return ret_oset; error: panic("can not generate a simple named tail oset"); return NULL; } /* [keyid:alpha].oset:documents([string:'proj1'])<-[urn:'file//fileA'] */ abac_oset_t *validate_object_tail_oset(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; abac_term_t *term=abac_term_new(type,name,cond,ptr); abac_oset_t *ret_oset=abac_oset_object_new(term); if(get_yy_term_data_is_variable(object)) _add_yy_id_certs(name,type); if (ret_oset==NULL) goto error; return ret_oset; error: panic("can not generate a simple object tail oset"); return NULL; } /* B.oset */ abac_oset_t *validate_oset_tail_oset(abac_yy_expression_t *expr) { abac_yy_principal_t *principal=expr->principal; abac_yy_oset_t *oset=expr->oset; char *principalname=principal->sha; char *osetname=oset->name; abac_yy_term_t *terms=oset->terms; int ret; abac_oset_t *ret_oset=NULL; ret_oset = abac_oset_oset_new(principalname, osetname); if (ret_oset==NULL) goto error; if(terms) { _oset_add_oset_terms(ret_oset, terms); } _add_yy_id_certs(principal->cn,principal->type); return ret_oset; error: panic("can not generate a simple tail oset"); return NULL; } /* B.role.oset */ abac_oset_t *validate_linked_tail_oset(abac_yy_expression_t *expr) { abac_yy_principal_t *principal=expr->principal; abac_yy_oset_t *oset=expr->oset; abac_yy_role_t *linked_role=expr->linked_role; char *principalname=principal->sha; char *osetname=oset->name; abac_yy_term_t *terms=oset->terms; char *linkedrolename=linked_role->name; abac_yy_term_t *linked_terms=linked_role->terms; int ret; abac_oset_t *ret_oset=abac_oset_linking_new(principalname, linkedrolename, osetname); if (ret_oset==NULL) goto error; if(linked_terms) { _oset_add_linked_terms(ret_oset, linked_terms); } if(terms) { _oset_add_oset_terms(ret_oset, terms); } _add_yy_id_certs(principal->cn,principal->type); return ret_oset; error: panic("can not generate linked tail oset"); return NULL; } abac_list_t *make_oset_statement(abac_yy_expression_t *headexpr, abac_yy_expression_t *tailexpr) { abac_oset_t *head_oset=NULL; abac_oset_t *tail_oset=NULL; /* build up left side's abac oset structure */ head_oset=validate_head_oset(headexpr); if(head_oset == NULL) 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_oset_t *curr_oset = NULL; while (curr_tail) { switch(curr_tail->type) { case e_yy_EXPR_OBJECT: curr_oset=validate_object_tail_oset(curr_tail); break; case e_yy_EXPR_NAMED: curr_oset=validate_named_tail_oset(curr_tail); break; case e_yy_EXPR_OSET: curr_oset=validate_oset_tail_oset(curr_tail); break; case e_yy_EXPR_LINKED: curr_oset=validate_linked_tail_oset(curr_tail); break; } if(curr_oset==NULL) goto error; /* check if first one */ if(tail_oset==NULL) { if(intersecting) tail_oset=validate_intersected_tail_oset(curr_oset); else tail_oset=curr_oset; } else { abac_oset_add_intersecting_oset(tail_oset,curr_oset); } curr_tail=curr_tail->next; } /* while */ /* XXX collect up type clauses, constraint clauses and generate rule clauses */ abac_list_t *tmp=generate_pl_oset_clauses(head_oset,tail_oset); if(tmp == NULL) goto error; if(debug) { abac_print_oset_string_with_condition(head_oset,NULL); abac_print_oset_string_with_condition(tail_oset,NULL); } _free_yy_expression(headexpr); _free_yy_expression(tailexpr); abac_rule_head_oset=head_oset; abac_rule_tail_oset=tail_oset; abac_rule_is_oset=1; return tmp; error: _free_yy_expression(headexpr); _free_yy_expression(tailexpr); if(head_oset) abac_oset_free(head_oset); if(tail_oset) abac_oset_free(tail_oset); return NULL; } /****************************************************************/ static void _role_add_terms(int linked, abac_role_t *role, abac_yy_term_t *terms) { abac_yy_term_t *curr = terms; int type; char *name=NULL; char *cond=NULL; void *ptr=NULL; while (curr) { switch (curr->type) { case e_yy_DTERM_DATA: { abac_yy_term_data_t *pptr=curr->term.d_ptr; type=pptr->type; name=abac_xstrdup(pptr->name); cond=abac_xstrdup(pptr->cond_str); ptr=pptr->cond_ptr; break; } case e_yy_DTERM_PRINCIPAL: { abac_yy_term_principal_t *pptr=curr->term.p_ptr; type=abac_term_verify_term_type("principal"); name=abac_xstrdup(pptr->name); cond=abac_xstrdup(pptr->cond_str); ptr=pptr->cond_ptr; break; } case e_yy_DTERM_NAMED: { abac_yy_principal_t *pptr=curr->term.n_ptr; type=pptr->type; /* XXX should be switching to sha in the future */ name=abac_xstrdup(pptr->cn); cond=NULL; ptr=NULL; break; } case e_yy_DTERM_ANONYMOUS: { type=0; name=abac_xstrdup("_"); cond=NULL; ptr=NULL; break; } } abac_term_t *param=abac_term_new(type,name,cond,ptr); if (linked) abac_role_role_add_linked_param(role, param); else abac_role_role_add_param(role, param); curr=curr->next; } } static void _role_add_linked_terms(abac_role_t *role, abac_yy_term_t *terms) { int linked=1; _role_add_terms(linked, role, terms); } static void _role_add_role_terms(abac_role_t *role, abac_yy_term_t *terms) { int linked=0; _role_add_terms(linked, role, terms); } abac_role_t *validate_intersected_tail_role(abac_role_t *role) { abac_role_t *ret_role=NULL; abac_list_t *prereqs = abac_list_new(); abac_list_add(prereqs, role); ret_role = abac_role_intersection_new("intersectingROLE", prereqs); return ret_role; } abac_role_t *validate_head_role(abac_yy_expression_t *expr) { abac_yy_principal_t *principal=expr->principal; abac_yy_role_t *role=expr->role; char *principalname=get_yy_principal_principalname(principal); char *rolename=role->name; abac_yy_term_t *terms=role->terms; abac_role_t *ret_role=NULL; ret_role=abac_role_role_new(principalname, rolename); if (ret_role==NULL) { abac_yy_set_error_code(ABAC_RT_ROLE_INVALID); goto error; } if (!abac_role_is_role(ret_role)) { abac_yy_set_error_code(ABAC_RT_CERT_INVALID); goto error; } // insert the params for the role if(terms) { _role_add_role_terms(ret_role, terms); } _add_yy_id_certs(principal->cn,principal->type); return ret_role; error: return NULL; } abac_role_t *validate_named_tail_role(abac_yy_expression_t *expr) { abac_yy_principal_t *principal=expr->principal; char *principalname=get_yy_principal_principalname(principal); abac_role_t *ret_role=NULL; ret_role = abac_role_principal_new(principalname); _add_yy_id_certs(principal->cn,principal->type); if (ret_role==NULL) goto error; return ret_role; error: panic("can not generate a simple named tail role"); return NULL; } abac_role_t *validate_role_tail_role(abac_yy_expression_t *expr) { abac_yy_principal_t *principal=expr->principal; abac_yy_role_t *role=expr->role; char *principalname=get_yy_principal_principalname(principal); char *rolename=role->name; abac_yy_term_t *terms=role->terms; int ret; abac_role_t *ret_role=NULL; ret_role = abac_role_role_new(principalname, rolename); if (ret_role==NULL) goto error; if(terms) { _role_add_role_terms(ret_role, terms); } _add_yy_id_certs(principal->cn,principal->type); return ret_role; error: panic("can not generate a simple tail role"); return NULL; } /* need to validate/generate a linked role out of this */ abac_role_t *validate_linked_tail_role(abac_yy_expression_t *expr) { abac_yy_principal_t *principal=expr->principal; abac_yy_role_t *role=expr->role; abac_yy_role_t *linked_role=expr->linked_role; char *principalname=get_yy_principal_principalname(principal); char *rolename=role->name; abac_yy_term_t *terms=role->terms; char *linkedrolename=linked_role->name; abac_yy_term_t *linked_terms=linked_role->terms; int ret; abac_role_t *ret_role=NULL; ret_role = abac_role_linking_new(principalname, linkedrolename, rolename); if (ret_role==NULL) goto error; if(linked_terms) { _role_add_linked_terms(ret_role, linked_terms); } if(terms) { _role_add_role_terms(ret_role, terms); } _add_yy_id_certs(principal->cn,principal->type); return ret_role; error: panic("can not generate linked tail role"); return NULL; } /***********************************************************************/ /* add the condition to constraint list */ char *make_yy_oset_constraint(abac_yy_term_data_t *ptr, char *tail_string) { abac_yy_expression_t *head_expr=get_yy_term_data_cond_head_expr(ptr); if(head_expr) { abac_oset_t *head_oset=validate_head_oset(head_expr); if(head_oset == NULL) goto error; char *tmp=generate_pl_oset_constraint_clause(head_oset,tail_string); set_yy_term_data_cond_str(ptr,tmp); set_yy_term_data_cond_ptr(ptr,head_oset); abac_yy_add_yy_constraints(tmp); return tmp; } return NULL; error: return NULL; } /****************************************************************/ /* add the range condition to constraint list */ /* this is for integer and float only */ void make_yy_range_numeric_constraint(abac_yy_term_data_t *ptr, char *var) { char *typestr=abac_term_type(ptr->type); abac_list_t *rlist=get_yy_term_data_cond_range(ptr); char *tmplist=NULL; char *tmp=NULL; int as_range=1; /* either , or ; */ if(rlist) { char *rstring=_string_yy_cond_range(rlist); set_yy_term_data_cond_str(ptr,rstring); abac_yy_range_t *cur; /* a list of values -- in chars */ abac_list_foreach(rlist, cur, int type=cur->type; char *val=cur->val; switch(type) { case e_yy_RANGE_MIN: tmp=generate_pl_range_constraint(typestr,var,val,">"); break; case e_yy_RANGE_MAX: tmp=generate_pl_range_constraint(typestr,var,val,"<"); break; case e_yy_RANGE_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_yy_add_yy_constraints(tmplist); } } /****************************************************************/ /* this is for string and urn only */ void make_yy_range_string_constraint(abac_yy_term_data_t *ptr, char *var) { char *typestr=abac_term_type(ptr->type); abac_list_t *rlist=get_yy_term_data_cond_range(ptr); char *tmplist=NULL; char *tmp=NULL; if(rlist) { char *rstring=_string_yy_cond_range(rlist); set_yy_term_data_cond_str(ptr,rstring); abac_yy_range_t *cur; /* a list of values -- in chars */ abac_list_foreach(rlist, cur, int type=cur->type; char *val=cur->val; switch(type) { case e_yy_RANGE_MIN: panic("make_yy_range_string_constraint, invalid range type - min"); break; case e_yy_RANGE_MAX: /* invalid range type */ panic("make_yy_range_string_constraint, invalid range type - max"); break; case e_yy_RANGE_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_string_range_constraint_clause(var,tmplist); abac_yy_add_yy_constraints(tmp); } } void make_yy_range_constraint(abac_yy_term_data_t *ptr, char *var) { if(is_yy_term_data_type_numeric(ptr)) { make_yy_range_numeric_constraint(ptr, var); } else if (is_yy_term_data_type_alpha(ptr)) { make_yy_range_string_constraint(ptr, var); } /* } else if (is_yy_term_data_type_time(ptr)) { make_yy_range_time_constraint(ptr, var); } */ } char *make_yy_role_constraint(abac_yy_term_principal_t *ptr, char *tail_string) { char *tmp=NULL; abac_role_t *head_role=NULL; abac_yy_expression_t *head_expr=get_yy_term_principal_cond_head_expr(ptr); /* build up left side's abac role constraint structure */ head_role=validate_head_role(head_expr); if(head_role == NULL) goto error; tmp=generate_pl_role_constraint_clause(head_role,tail_string); set_yy_term_principal_cond_str(ptr,tmp); set_yy_term_principal_cond_ptr(ptr,head_role); abac_yy_add_yy_constraints(tmp); return tmp; error: return NULL; } /* build up the abac structure and also create the yap clause and insert it into db */ abac_list_t *make_role_statement(abac_yy_expression_t *headexpr, abac_yy_expression_t *tailexpr) { abac_role_t *head_role=NULL; abac_role_t *tail_role=NULL; /* build up left side's abac role structure */ head_role=validate_head_role(headexpr); if(head_role == NULL) 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_role_t *curr_role = NULL; while (curr_tail) { switch(curr_tail->type) { case e_yy_EXPR_NAMED: curr_role=validate_named_tail_role(curr_tail); break; case e_yy_EXPR_ROLE: curr_role=validate_role_tail_role(curr_tail); break; case e_yy_EXPR_LINKED: curr_role=validate_linked_tail_role(curr_tail); break; } if(curr_role==NULL) goto error; /* check if first one */ if(tail_role==NULL) { if(intersecting) tail_role=validate_intersected_tail_role(curr_role); else tail_role=curr_role; } else { abac_role_add_intersecting_role(tail_role,curr_role); } curr_tail=curr_tail->next; } /* while */ /* collect up type clauses, constraint clases and generate the final rule clauses */ abac_list_t *tmp=generate_pl_role_clauses(head_role,tail_role); if(tmp == NULL) goto error; if(debug) { abac_print_role_string_with_condition(head_role,NULL); abac_print_role_string_with_condition(tail_role,NULL); } _free_yy_expression(headexpr); _free_yy_expression(tailexpr); abac_rule_head_role=head_role; abac_rule_tail_role=tail_role; abac_rule_is_oset=0; return tmp; error: _free_yy_expression(headexpr); _free_yy_expression(tailexpr); if(head_role) abac_role_free(head_role); if(tail_role) abac_role_free(tail_role); return NULL; } /************************************************************************/ void abac_yy_init() { abac_yyinit(); abac_yy_init_rule_id_clauses(); abac_yy_init_yy_id_certs(); abac_yy_init_yy_constraints(); }