Index: libabac/abac_pl_yy.c
===================================================================
--- libabac/abac_pl_yy.c	(revision a9494ad1c5e523f94b0d172045537662de58fd54)
+++ libabac/abac_pl_yy.c	(revision da5afdf4d61c978dbd17b9d6f20e5a45dcab870a)
@@ -4,16 +4,19 @@
 #include <string.h>
 #include <stdlib.h>
-
-#include "uthash.h"
+#include <assert.h>
+
 #include "abac_util.h"
-
 #include "abac_pl_yy.h"
 
 static int debug=0;
 
-extern abac_list_t *generate_pl_clauses(abac_role_t *, abac_role_t *);
+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 void panic(char*);
 extern char *generate_pl_type_clause(char *, int);
 void _add_yy_id_certs(char *, int);
+static void _free_yy_oset(abac_yy_oset_t *ptr);
+static void _free_yy_term_data(abac_yy_term_data_t *ptr);
+abac_role_t *validate_head_role(abac_yy_expression_t *expr);
 
 abac_list_t *abac_yap_clauses=NULL;
@@ -21,31 +24,53 @@
 abac_stack_t *abac_yap_id_clauses=NULL;
 
+int abac_yap_is_oset=0;
 abac_role_t *abac_yap_head_role=NULL;
 abac_role_t *abac_yap_tail_role=NULL;
 
-/* XXX do we want to check whether the id cert is preexisting or not */
-/* this is to track id certs within a rule clause */
+abac_oset_t *abac_yap_head_oset=NULL;
+abac_oset_t *abac_yap_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;
-
-    UT_hash_handle hh;
 } 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 */
+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;
-    char *cn;
+    char *sha; // sha is null when this is of object type
+    char *cn; 
 };
 
-/* like  [principal:?Z]:..., must match a principal name */
-struct _abac_yy_param_principal_t {
+/* [principal:?Z]:..., must match a principal name */
+struct _abac_yy_term_principal_t {
     int type; /* this needs to be implicitly determined */
     char *name;
     char *condition;
+    void *cptr; // ptr to a saved abac_role_t
+    abac_yy_expression_t *cond_head_expr;
 };
 
@@ -57,21 +82,28 @@
     [int:10]
 */
-struct _abac_yy_param_data_t {
+struct _abac_yy_term_data_t {
     int is_variable;
     int type;
     char *name;
     char *condition;
+    void *cptr; // ptr to a saved abac_oset_t
+    abac_list_t *cond_range;
+    abac_yy_expression_t *cond_head_expr; // parking stub
 };
 
-/* local dterm structure, will distinguish it in the future */
-struct _abac_yy_dterm_t {
+/* 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_param_principal_t *p_ptr;
-         abac_yy_param_data_t *d_ptr;
+         abac_yy_term_principal_t *p_ptr;
+         abac_yy_term_data_t *d_ptr;
     } term;
     int type;
-    struct _abac_yy_dterm_t *next;
-    int bcnt; /* this is to track number of dterms in this linked up list */
+    struct _abac_yy_term_t *next;
+    int bcnt; /* this is to track number of terms in this linked up list */
 };
 
@@ -80,19 +112,150 @@
    int type;
    char *name;
-   abac_yy_dterm_t *dterms;
+   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 */
 };
 
-struct _abac_yy_role_expression_t {
-   int rtype;
-   abac_yy_principal_t *principal;
+/* 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;
-   abac_yy_role_t *role;
-   struct _abac_yy_role_expression_t *next;
+   union {
+       abac_yy_role_t *role;
+       abac_yy_oset_t *oset;
+   };
+   struct _abac_yy_expression_t *next;
    int bcnt;
 };
-
-static void _free_yy_dterm(abac_yy_dterm_t *ptr);
+static void _free_yy_term(abac_yy_term_t *ptr);
+
+/************************************************************************/
+static void _free_yy_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);
+    }
+}
+
+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;
+        val=cur->val; 
+        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 *addto_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 *_addto_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();
+    addto_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();
+    _addto_yy_range(ptr, e_yy_RANGE_MIN, min);
+    _addto_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();
+    _addto_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();
+    _addto_yy_range(ptr, e_yy_RANGE_MAX, max);
+    return ptr;
+}
 
 /************************************************************************/
@@ -119,5 +282,5 @@
     if(debug) {
          printf("printing out abac_yap_clauses:\n");
-         abac_print_clauses(abac_yap_clauses);
+         abac_print_clauses(abac_yap_clauses,NULL);
     }
 }
@@ -139,4 +302,9 @@
 }
 
+int abac_get_yap_is_oset()
+{
+   return abac_yap_is_oset;
+}
+
 abac_role_t *abac_get_yap_head_role()
 {
@@ -149,4 +317,15 @@
 }
 
+abac_oset_t *abac_get_yap_head_oset()
+{
+    return abac_yap_head_oset;
+}
+
+abac_oset_t *abac_get_yap_tail_oset()
+{
+    return abac_yap_tail_oset;
+}
+
+/*******************************************************************/
 void abac_init_yy_id_certs()
 {
@@ -164,4 +343,5 @@
     );
     abac_list_free(abac_yy_id_certs);
+    abac_yy_id_certs = NULL;
 }
 
@@ -214,4 +394,53 @@
 
 /****************************************************************************/
+void abac_init_yy_constraints()
+{
+    abac_yy_constraints = abac_list_new();
+}
+
+void abac_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_cnt_yy_constraints()
+{
+    return abac_list_size(abac_yy_constraints);
+}
+
+char *abac_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_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)
 {
@@ -232,9 +461,21 @@
 }
 
-abac_yy_role_t *make_yy_role(char *name, abac_yy_dterm_t *dterms)
+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_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->dterms=dterms;
+    ptr->terms=terms;
     ptr->next=NULL;
     ptr->bcnt=1;
@@ -245,6 +486,6 @@
 {
     free(ptr->name);
-    if(ptr->dterms)
-        _free_yy_dterm(ptr->dterms);
+    if(ptr->terms)
+        _free_yy_term(ptr->terms);
     if(ptr->next)
         _free_yy_role(ptr->next);
@@ -252,12 +493,20 @@
 }
 
-abac_yy_role_expression_t *make_yy_role_expression(int rtype,
-abac_yy_principal_t *principal, abac_yy_role_t *role, abac_yy_role_t *linked_role)
-{
-    abac_yy_role_expression_t *ptr=
-         (abac_yy_role_expression_t*)abac_xmalloc(sizeof(abac_yy_role_expression_t));
-    ptr->rtype = rtype;
-    ptr->principal = principal;
-    ptr->role = role;
+/* 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;
@@ -266,6 +515,13 @@
 }
 
-abac_yy_role_expression_t *add_yy_role_expression(abac_yy_role_expression_t *nexpr,
-                                               abac_yy_role_expression_t *exprs)
+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;
@@ -275,65 +531,33 @@
 }
 
-
-static void _free_yy_role_expression(abac_yy_role_expression_t *ptr)
-{
-    if(ptr->principal)
-        _free_yy_principal(ptr->principal);
-    if(ptr->role)
-        _free_yy_role(ptr->role);
+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_role_expression(ptr->next);
+        _free_yy_expression(ptr->next);
 
     free(ptr);
 }
 
-abac_yy_param_data_t *make_yy_param_data(char* name, char* typestr)
-{
-    int type=abac_verify_dterm_type(typestr);
-    abac_yy_param_data_t *ptr=
-              (abac_yy_param_data_t*)abac_xmalloc(sizeof(abac_yy_param_data_t));
+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->type=type;
-    ptr->condition=NULL;
-    ptr->is_variable=0;
-    return ptr;
-}
-
-void set_yy_param_data_is_variable(abac_yy_param_data_t *ptr)
-{
-    ptr->is_variable=1;
-}
-
-static void _free_yy_param_data(abac_yy_param_data_t *ptr)
-{
-    free(ptr->name);
-    if(ptr->condition)
-        free(ptr->condition);
-    free(ptr);
-}
-
-abac_yy_param_principal_t *make_yy_param_principal(char* name)
-{
-    abac_yy_param_principal_t *ptr=
-            (abac_yy_param_principal_t*)abac_xmalloc(sizeof(abac_yy_param_principal_t));
-    ptr->name=abac_xstrdup(name);
-    ptr->condition=NULL;
-    return ptr;
-}
-
-static void _free_yy_param_principal(abac_yy_param_principal_t *ptr)
-{
-    free(ptr->name);
-    if(ptr->condition)
-        free(ptr->condition);
-    free(ptr);
-}
-
-abac_yy_dterm_t *make_yy_dterm_anonymous()
-{
-    abac_yy_dterm_t *ptr=(abac_yy_dterm_t*)abac_xmalloc(sizeof(abac_yy_dterm_t));
-    ptr->type = DTERM_ANONYMOUS;
+    ptr->terms=terms;
     ptr->next=NULL;
     ptr->bcnt=1;
@@ -341,92 +565,44 @@
 }
 
-abac_yy_dterm_t *make_yy_dterm_principal(abac_yy_param_principal_t *pptr)
-{
-    abac_yy_dterm_t *ptr=(abac_yy_dterm_t*)abac_xmalloc(sizeof(abac_yy_dterm_t));
-    ptr->type = DTERM_PRINCIPAL;
-    ptr->term.p_ptr=pptr;
-    ptr->next=NULL;
-    ptr->bcnt=1;
-    return ptr;
-}
-
-abac_yy_dterm_t *make_yy_dterm_named(abac_yy_principal_t *nptr)
-{
-    abac_yy_dterm_t *ptr=(abac_yy_dterm_t*)abac_xmalloc(sizeof(abac_yy_dterm_t));
-    ptr->type = DTERM_NAMED;
-    ptr->term.n_ptr=nptr;
-    ptr->next=NULL;
-    ptr->bcnt=1;
-    return ptr;
-}
-
-abac_yy_dterm_t *make_yy_dterm_data(abac_yy_param_data_t *dptr)
-{
-    abac_yy_dterm_t *ptr=(abac_yy_dterm_t*)abac_xmalloc(sizeof(abac_yy_dterm_t));
-    ptr->type = DTERM_DATA;
-    ptr->term.d_ptr=dptr;
-    ptr->next=NULL;
-    ptr->bcnt=1;
-    return ptr;
-}
-
-abac_yy_dterm_t *add_yy_dterm(abac_yy_dterm_t *nterm, abac_yy_dterm_t *dterms)
-{
-    int i=dterms->bcnt;
-    nterm->next=dterms;
-    nterm->bcnt=i+1;
-    return nterm;
-}
-
-static void _free_yy_dterm(abac_yy_dterm_t *ptr)
-{
-    switch (ptr->type) {
-        case DTERM_DATA:
-            _free_yy_param_data(ptr->term.d_ptr);
-            break;
-        case DTERM_NAMED:
-            _free_yy_principal(ptr->term.n_ptr);
-            break;
-        case DTERM_PRINCIPAL:
-            _free_yy_param_principal(ptr->term.p_ptr);
-            break;
-        case DTERM_ANONYMOUS:
-            break;
-    }
+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_dterm(ptr->next);
+        _free_yy_oset(ptr->next);
     free(ptr);
 }
 
-/****************************************************************/
-static void _role_add_dterms(int linked, abac_role_t *role, abac_yy_dterm_t *dterms)
-{
-    abac_yy_dterm_t *curr = dterms;
+/**********************************************************************/
+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 DTERM_DATA:
+           case e_yy_DTERM_DATA:
            {
-               abac_yy_param_data_t *ptr=curr->term.d_ptr;
+               abac_yy_term_data_t *ptr=curr->term.d_ptr;
                type=ptr->type;
                name=abac_xstrdup(ptr->name);
                cond=abac_xstrdup(ptr->condition);
-               if(ptr->is_variable) {
-/* XXX do some tracking */
-               }
+               ptr=ptr->cptr;
                break;
            }
-           case DTERM_PRINCIPAL:
+           case e_yy_DTERM_PRINCIPAL:
            {
-              abac_yy_param_principal_t *ptr=curr->term.p_ptr;
-              type=abac_verify_dterm_type("principal");
-              name=abac_xstrdup(ptr->name);
-              cond=abac_xstrdup(ptr->condition);
-/* XXX variable one, do some tracking */
-              break;
+               abac_yy_term_principal_t *ptr=curr->term.p_ptr;
+               type=abac_verify_term_type("principal");
+               name=abac_xstrdup(ptr->name);
+               cond=abac_xstrdup(ptr->condition);
+               ptr=ptr->cptr;
+               break;
            }
-           case DTERM_NAMED:
+           case e_yy_DTERM_NAMED:
            {
               abac_yy_principal_t *ptr=curr->term.n_ptr;
@@ -435,32 +611,632 @@
               name=abac_xstrdup(ptr->cn);
               cond=NULL;
+              ptr=NULL;
               break;
            }
-           case DTERM_ANONYMOUS:
+           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, type, name, cond);
+           abac_oset_oset_add_linked_param(oset, param);
            else
-                abac_role_role_add_param(role, type, name, cond);
+                abac_oset_oset_add_param(oset, param);
        curr=curr->next;
    }
 }
 
-static void _role_add_linked_dterms(abac_role_t *role, abac_yy_dterm_t *dterms)
+static void _oset_add_linked_terms(abac_oset_t *oset, abac_yy_term_t *terms)
 {
     int linked=1;
-    _role_add_dterms(linked, role, dterms);
-}
-
-static void _role_add_role_dterms(abac_role_t *role, abac_yy_dterm_t *dterms)
+    _oset_add_terms(linked, oset, terms);
+}
+
+static void _oset_add_oset_terms(abac_oset_t *oset, abac_yy_term_t *terms)
 {
     int linked=0;
-    _role_add_dterms(linked, role, dterms);
+    _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) {
+         set_error_code(ABAC_RT_ROLE_INVALID);
+         goto error;
+     }
+     if (!abac_oset_is_oset(ret_oset)) {
+         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->condition;
+     void *ptr=object->cptr;
+     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_yap_head_oset=head_oset;
+        abac_yap_tail_oset=tail_oset;
+        abac_yap_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;
+}
+
+/***********************************************************************/
+/*
+struct _abac_yy_term_data_t {
+    int is_variable;
+    int type;
+    char *name;
+    char *condition;
+    void *cptr; // ptr to a saved abac_oset_t
+    abac_list_t *cond_range;
+    abac_yy_expression_t *cond_head_expr;
+};
+*/
+
+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->condition=NULL;
+    ptr->cond_head_expr=NULL;
+    ptr->cptr=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;
+/* only select few */
+    if( ptr->cond_range != NULL && abac_term_is_integer_type(ptr->type))
+        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_cptr(abac_yy_term_data_t *ptr, void *vptr)
+{
+    ptr->cptr=vptr;
+}
+
+void set_yy_term_data_condition(abac_yy_term_data_t *ptr, char *cond)
+{
+    ptr->condition=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->condition)
+        free(ptr->condition);
+    if(ptr->cond_head_expr)
+        _free_yy_expression(ptr->cond_head_expr);
+    if(ptr->cond_range);
+        _free_yy_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->name=abac_xstrdup(name);
+    ptr->condition=NULL;
+    ptr->cond_head_expr=NULL;
+    return ptr;
+}
+
+void set_yy_term_principal_cptr(abac_yy_term_principal_t *ptr, void *vptr)
+{
+    ptr->cptr=vptr;
+}
+
+void set_yy_term_principal_condition(abac_yy_term_principal_t *ptr, char *cond)
+{
+    ptr->condition=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->condition)
+        free(ptr->condition);
+    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;
+}
+
+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);
+}
+
+/****************************************************************/
+/* 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_condition(ptr,tmp);
+       set_yy_term_data_cptr(ptr,head_oset);
+       abac_add_yy_constraints(tmp);
+       return tmp;
+   }
+   return NULL;
+error:
+   return NULL;
+} 
+/****************************************************************/
+/* add the range condition to constraint list */
+
+void make_yy_range_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 is_range=1; /* either , or | */
+   if(rlist) {
+       char *rstring=string_yy_cond_range(rlist);
+       set_yy_term_data_condition(ptr,rstring);
+       abac_yy_range_t *cur;
+     
+       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_clause(typestr,var,val,">");
+               break;
+             case e_yy_RANGE_MAX:
+               tmp=generate_pl_range_constraint_clause(typestr,var,val,"<");
+               break;
+             case e_yy_RANGE_TARGET:
+               tmp=generate_pl_range_constraint_clause(typestr,var,val,"=");
+               int is_range=0;
+               break;
+           }
+           if(tmplist) {
+               if(is_range)
+                   asprintf(&tmplist,"%s,%s",tmplist,tmp);
+                   else
+                       asprintf(&tmplist,"%s;%s",tmplist,tmp);
+               } else {
+                   tmplist=tmp;
+           }
+           tmp=NULL;
+       );
+       asprintf(&tmplist,"(%s)",tmplist);
+       abac_add_yy_constraints(tmplist);
+   }
+}
+
+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_condition(ptr,tmp);
+   set_yy_term_principal_cptr(ptr,head_role);
+   abac_add_yy_constraints(tmp);
+   return tmp;
+
+error:
+   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 *ptr=curr->term.d_ptr;
+               type=ptr->type;
+               name=abac_xstrdup(ptr->name);
+               cond=abac_xstrdup(ptr->condition);
+               ptr=ptr->cptr;
+               break;
+           }
+           case e_yy_DTERM_PRINCIPAL:
+           {
+              abac_yy_term_principal_t *ptr=curr->term.p_ptr;
+              type=abac_verify_term_type("principal");
+              name=abac_xstrdup(ptr->name);
+              cond=abac_xstrdup(ptr->condition);
+              ptr=ptr->cptr;
+              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_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);
 }
 
@@ -475,12 +1251,12 @@
 }
 
-abac_role_t *validate_head_role(abac_yy_role_expression_t *expr)
+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=principal->sha;
+     char *principalname=get_yy_principal_principalname(principal);
      char *rolename=role->name;
-     abac_yy_dterm_t *dterms=role->dterms;
+     abac_yy_term_t *terms=role->terms;
      abac_role_t *ret_role=NULL;
 
@@ -495,6 +1271,6 @@
      }
      // insert the params for the role
-     if(dterms) {
-          _role_add_role_dterms(ret_role, dterms);
+     if(terms) {
+          _role_add_role_terms(ret_role, terms);
      }
 
@@ -507,12 +1283,11 @@
 }
 
-abac_role_t *validate_named_tail_role(abac_yy_role_expression_t *expr)
+abac_role_t *validate_named_tail_role(abac_yy_expression_t *expr)
 {
      abac_yy_principal_t *principal=expr->principal;
-     char *principalname=principal->sha;
+     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);
 
@@ -526,13 +1301,13 @@
 }
 
-abac_role_t *validate_role_tail_role(abac_yy_role_expression_t *expr)
+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=principal->sha;
+     char *principalname=get_yy_principal_principalname(principal);
 
      char *rolename=role->name;
-     abac_yy_dterm_t *dterms=role->dterms;
+     abac_yy_term_t *terms=role->terms;
 
      int ret;
@@ -543,6 +1318,6 @@
          goto error;
 
-     if(dterms) {
-         _role_add_role_dterms(ret_role, dterms);
+     if(terms) {
+         _role_add_role_terms(ret_role, terms);
      }
 
@@ -556,5 +1331,5 @@
 }
 /* need to validate/generate a linked role out of this */
-abac_role_t *validate_linked_tail_role(abac_yy_role_expression_t *expr)
+abac_role_t *validate_linked_tail_role(abac_yy_expression_t *expr)
 {
      abac_yy_principal_t *principal=expr->principal;
@@ -562,11 +1337,11 @@
      abac_yy_role_t *linked_role=expr->linked_role;
 
-     char *principalname=principal->sha;
+     char *principalname=get_yy_principal_principalname(principal);
 
      char *rolename=role->name;
-     abac_yy_dterm_t *dterms=role->dterms;
+     abac_yy_term_t *terms=role->terms;
 
      char *linkedrolename=linked_role->name;
-     abac_yy_dterm_t *linked_dterms=linked_role->dterms;
+     abac_yy_term_t *linked_terms=linked_role->terms;
 
      int ret;
@@ -577,9 +1352,9 @@
          goto error;
 
-     if(linked_dterms) {
-         _role_add_linked_dterms(ret_role, linked_dterms);
+     if(linked_terms) {
+         _role_add_linked_terms(ret_role, linked_terms);
      }
-     if(dterms) {
-         _role_add_role_dterms(ret_role, dterms);
+     if(terms) {
+         _role_add_role_terms(ret_role, terms);
      }
 
@@ -594,6 +1369,8 @@
 
 
-abac_list_t *make_statement(abac_yy_role_expression_t *headexpr,
-                       abac_yy_role_expression_t *tailexpr) 
+/* 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;
@@ -606,16 +1383,16 @@
 
 /* build up the right side's abac role structure */
-    abac_yy_role_expression_t *curr_tail = tailexpr;
+    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->rtype) {
-                case EXPR_NAMED:
+            switch(curr_tail->type) {
+                case e_yy_EXPR_NAMED:
                     curr_role=validate_named_tail_role(curr_tail);
                     break;
-                case EXPR_ROLE:
+                case e_yy_EXPR_ROLE:
                     curr_role=validate_role_tail_role(curr_tail);
                     break;
-                case EXPR_LINKED:
+                case e_yy_EXPR_LINKED:
                     curr_role=validate_linked_tail_role(curr_tail);
                     break;
@@ -636,23 +1413,25 @@
         } /* while */
 
-/* collect up type clauses and generate rule clauses */
-        abac_list_t *tmp=generate_pl_clauses(head_role,tail_role);
+/* 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);
-            abac_print_role_string_with_condition(tail_role);
+            abac_print_role_string_with_condition(head_role,NULL);
+            abac_print_role_string_with_condition(tail_role,NULL);
         }
 
-        _free_yy_role_expression(headexpr);
-        _free_yy_role_expression(tailexpr);
+        _free_yy_expression(headexpr);
+        _free_yy_expression(tailexpr);
         abac_yap_head_role=head_role;
         abac_yap_tail_role=tail_role;
+        abac_yap_is_oset=0;
         return tmp;
 
 error:
-        _free_yy_role_expression(headexpr);
-        _free_yy_role_expression(tailexpr);
+        _free_yy_expression(headexpr);
+        _free_yy_expression(tailexpr);
         if(head_role)
             abac_role_free(head_role);
@@ -661,2 +1440,4 @@
         return NULL;
 }
+
+
