Index: libabac/abac_role.c
===================================================================
--- libabac/abac_role.c	(revision 53e540d5b3ba8b09dcdf1f90cf514182a491d9d3)
+++ libabac/abac_role.c	(revision a9494ad1c5e523f94b0d172045537662de58fd54)
@@ -4,13 +4,19 @@
 #include <string.h>
 
-#include "abac.h"
 #include "abac_list.h"
 #include "abac_util.h"
 
-// typedef'd in role.h
+#include "abac_pl.h"
+
+static int debug=0;
+
 struct _abac_role_t {
-    char *principal;
-    char *linked_role;
+    char *principal_name;
+
+    char *linked_role_name;
+    abac_param_list_t *linked_role_params;
+
     char *role_name;
+    abac_param_list_t *role_params;
 
     char *string;
@@ -22,4 +28,8 @@
 };
 
+extern char *abac_cn_with_sha(char*);
+char *abac_role_string_with_condition(abac_role_t *);
+char *abac_role_principal_cn(abac_role_t *);
+
 /**
  * Create a new principal and initialize it.
@@ -35,9 +45,11 @@
     role = abac_xmalloc(sizeof(abac_role_t));
 
-    /* XXX */
-
-    role->principal = abac_xstrdup(principal);
+    role->principal_name = abac_xstrdup(principal);
+
     role->role_name = NULL;
-    role->linked_role = NULL;
+    role->role_params = NULL;
+
+    role->linked_role_name = NULL;
+    role->linked_role_params = NULL;
 
     role->string = abac_xstrdup(principal);
@@ -53,31 +65,36 @@
  * Create a new role and initialize it.
  */
-abac_role_t *abac_role_role_new(char *principal, char *role_name) {
-    assert(principal != NULL);
+abac_role_t *abac_role_role_new(char *principal_name, char *role_name) {
+    assert(principal_name != NULL);
     assert(role_name != NULL);
 
     abac_role_t *role;
 
-    if (strlen(principal) == 0 || strlen(role_name) == 0)
+    if (strlen(principal_name) == 0 || strlen(role_name) == 0)
         return NULL;
 
     /* MEI */
-    printf("XXX adding a new role (%s) to principal (%s)\n", role_name, principal);
+    if(debug)
+        printf("DEBUG:adding a new role (%s) to principal (%s)\n", role_name, principal_name);
 
     role = abac_xmalloc(sizeof(abac_role_t));
 
-    role->principal = abac_xstrdup(principal);
+    role->principal_name = abac_xstrdup(principal_name);
     role->role_name = abac_xstrdup(role_name);
-    role->linked_role = NULL;
-
-    int prin_len = strlen(principal);
+    role->role_params = NULL;
+
+    role->linked_role_name = NULL;
+    role->linked_role_params = NULL;
+
+    int prin_len = strlen(principal_name);
     int role_len = strlen(role_name);
 
     role->string = abac_xmalloc(prin_len + 1 + role_len + 1);
-    memcpy(role->string, principal, prin_len);
+    memcpy(role->string, principal_name, prin_len);
     role->string[prin_len] = '.';
     memcpy(role->string + prin_len + 1, role_name, role_len);
     role->string[prin_len + 1 + role_len] = 0;
 
+
     role->linked = NULL;
     role->prereqs = NULL;
@@ -91,33 +108,37 @@
  * Created a new linking role and initialize it.
  */
-abac_role_t *abac_role_linking_new(char *principal, char *linked, char *role_name) {
-    assert(principal != NULL);
-    assert(linked != NULL);
+abac_role_t *abac_role_linking_new(char *principal_name, char *linked_role_name, char *role_name) {
+    assert(principal_name != NULL);
+    assert(linked_role_name != NULL);
     assert(role_name != NULL);
 
     abac_role_t *role;
 
-    if (strlen(principal) == 0 || strlen(linked) == 0 || strlen(role_name) == 0)
+    if (strlen(principal_name) == 0 || strlen(linked_role_name) == 0 || strlen(role_name) == 0)
         return NULL;
 
     /* MEI */
-    printf(" XXX adding a new linked (%s) to role(%s) for principal(%s)\n",
-                        linked, role_name, principal);
+    if(debug)
+        printf("DEBUG:adding a new linked (%s) to role(%s) for principal(%s)\n",
+                        linked_role_name, role_name, principal_name);
 
     role = abac_xmalloc(sizeof(abac_role_t));
 
-    role->principal = abac_xstrdup(principal);
-    role->linked_role = abac_xstrdup(linked);
+    role->principal_name = abac_xstrdup(principal_name);
+
+    role->linked_role_name = abac_xstrdup(linked_role_name);
+    role->linked_role_params = NULL;
     role->role_name = abac_xstrdup(role_name);
-
-    int prin_len = strlen(principal);
-    int link_len = strlen(linked);
+    role->role_params = NULL;
+
+    int prin_len = strlen(principal_name);
+    int link_len = strlen(linked_role_name);
     int role_len = strlen(role_name);
 
     role->string = abac_xmalloc(prin_len + 1 + link_len + 1 + role_len + 1);
 
-    memcpy(role->string, principal, prin_len);
+    memcpy(role->string, principal_name, prin_len);
     role->string[prin_len] = '.';
-    memcpy(role->string + prin_len + 1, linked, link_len);
+    memcpy(role->string + prin_len + 1, linked_role_name, link_len);
     role->string[prin_len + 1 + link_len] = 0;
 
@@ -130,5 +151,4 @@
 
     role->prereqs = NULL;
-
     role->refcount = 1;
 
@@ -142,7 +162,9 @@
     abac_role_t *role = abac_xmalloc(sizeof(abac_role_t));
 
-    role->principal = role->linked_role = role->role_name = NULL;
+    role->principal_name = role->linked_role_name = role->role_name = NULL;
+    role->linked_role_params = NULL;
+    role->role_params = NULL;
+
     role->linked = NULL;
-
     role->string = abac_xstrdup(name);
     role->prereqs = prereqs;
@@ -157,6 +179,13 @@
  */
 void abac_role_free(abac_role_t *role) {
+
+    if(debug)
+        printf("DEBUG:trying to freeing a role %d\n",(int)role);
+ 
     if (role == NULL)
         return;
+
+    if(debug)
+        printf("DEBUG:freeing a role %d\n",(int)role);
 
     --role->refcount;
@@ -164,10 +193,18 @@
         return;
 
-    free(role->principal);
-    free(role->linked_role);
+    free(role->principal_name);
+    free(role->linked_role_name);
     free(role->role_name);
 
     free(role->string);
     free(role->linked);
+
+    if (role->role_params != NULL) {
+        abac_param_list_free(role->role_params);
+    }
+
+    if (role->linked_role_params != NULL) {
+        abac_param_list_free(role->linked_role_params);
+    }
 
     if (role->prereqs != NULL) {
@@ -182,4 +219,33 @@
 }
 
+abac_role_t *abac_role_role_add_param(abac_role_t *role, int type, char *name, char *cond)
+{
+     abac_param_t *param=abac_param_new(type,name,cond);
+     if(role->role_params == NULL) {
+        role->role_params=abac_param_list_new(param);
+        } else {
+            abac_param_list_add_param(role->role_params, param);
+     }
+     return role;
+}
+
+abac_role_t *abac_role_add_intersecting_role(abac_role_t *role, abac_role_t *nrole)
+{
+     abac_list_add(role->prereqs, nrole);
+     return role;
+}
+
+abac_role_t *abac_role_role_add_linked_param(abac_role_t *role, int type, char *name, char *cond)
+{
+     abac_param_t *param=abac_param_new(type,name,cond);
+     if(role->linked_role_params == NULL) {
+        role->linked_role_params=abac_param_list_new(param);
+        } else {
+            abac_param_list_add_param(role->linked_role_params, param);
+     }
+     return role;
+}
+
+
 /**
  * Create a non-intersecting role from a string. Handles principals, roles,
@@ -272,5 +338,4 @@
             abac_list_add(prereqs, role);
         }
-
         ret = abac_role_intersection_new(original, prereqs);
     }
@@ -280,12 +345,13 @@
 
 error:
+
     if (prereqs != NULL) {
-        abac_list_foreach(prereqs, role,
-            abac_role_free(role);
-        );
-        abac_list_free(prereqs);
+       abac_role_t *cur;
+       abac_list_foreach(prereqs, cur,
+           abac_role_free(cur);
+       );
+       abac_list_free(prereqs);
     }
     free(string);
-
     return NULL;
 }
@@ -307,5 +373,5 @@
 int abac_role_is_principal(abac_role_t *role) {
     assert(role != NULL);
-    return role->role_name == NULL && role->linked_role == NULL && role->prereqs == NULL;
+    return role->role_name == NULL && role->linked_role_name == NULL && role->prereqs == NULL;
 }
 
@@ -315,5 +381,5 @@
 int abac_role_is_role(abac_role_t *role) {
     assert(role != NULL);
-    return role->role_name != NULL && role->linked_role == NULL && role->prereqs == NULL; 
+    return role->role_name != NULL && role->linked_role_name == NULL && role->prereqs == NULL; 
 }
 
@@ -323,5 +389,5 @@
 int abac_role_is_linking(abac_role_t *role) {
     assert(role != NULL);
-    return role->linked_role != NULL;
+    return role->linked_role_name != NULL;
 }
 
@@ -334,10 +400,94 @@
 }
 
+char *abac_role_intersecting_string_with_condition(abac_role_t *role)
+{
+    assert(role != NULL);
+    char *tmp=NULL;
+    if (role->prereqs != NULL) {
+        abac_role_t *cur;
+        abac_list_foreach(role->prereqs, cur,
+            char *ntmp=abac_role_string_with_condition(cur);
+            if(tmp==NULL) {
+                asprintf(&tmp,"%s",ntmp);
+                } else {
+                    asprintf(&tmp,"%s & %s",tmp, ntmp);
+            }
+        );
+    }
+    return tmp;
+}
 /**
  * Returns the string representation of the role.
- */
-char *abac_role_string(abac_role_t *role) {
-    assert(role != NULL);
-    return role->string;
+ * principal.role(params..)
+ */
+char *abac_role_string_with_condition(abac_role_t *role) {
+    assert(role != NULL);
+
+    if(abac_role_is_intersection(role)) {
+        return abac_role_intersecting_string_with_condition(role);
+    }
+
+    char *tmp=NULL;
+/* use cn for now, easy to debug XXX */
+    char *principal_name = abac_role_principal_cn(role);
+    char *role_name= role->role_name;
+    char *linked_role_name = role->linked_role_name;
+    char *params_string=NULL;
+    char *linked_params_string=NULL;
+
+    int len = 0;
+    if(principal_name)
+        len=len+strlen(principal_name)+1;
+    if(role_name)
+        len = len+strlen(role_name)+1;
+    if(linked_role_name)
+        len = len+strlen(linked_role_name)+1;
+
+    if(role->role_params) {
+         params_string=abac_param_list_string_with_condition(role->role_params);
+         len = len+strlen(params_string)+3;
+    } 
+    if(role->linked_role_params) {
+         linked_params_string=abac_param_list_string_with_condition(role->linked_role_params);
+         len = len+strlen(linked_params_string)+3;
+    }
+
+    /* principal */
+    /* principal.role */
+    /* principal.role(params_string) */
+    /* principal.linked_role(linked_params_string).role(params_string) */
+    tmp = abac_xmalloc(len);
+
+    if(principal_name)
+        sprintf(tmp,"%s",principal_name);
+
+    if(linked_role_name) {
+        strcat(tmp,".");
+        strcat(tmp,linked_role_name);
+    }
+    if(linked_params_string) {
+        strcat(tmp,"(");
+        strcat(tmp,linked_params_string);
+        strcat(tmp,")");
+    }
+    if(role_name) {
+        strcat(tmp,".");
+        strcat(tmp,role_name);
+    }
+    if(params_string) {
+        strcat(tmp,"(");
+        strcat(tmp,params_string);
+        strcat(tmp,")");
+    }
+
+    if(linked_params_string) free(linked_params_string);
+    if(params_string) free(params_string);
+    return tmp;
+}
+
+void abac_print_role_string_with_condition(abac_role_t *role)
+{
+    char *string=abac_role_string_with_condition(role);
+    printf("%s",string);
 }
 
@@ -357,5 +507,5 @@
 char *abac_role_linked_role(abac_role_t *role) {
     assert(role != NULL);
-    return role->linked;
+    return role->linked_role_name;
 }
 
@@ -365,5 +515,10 @@
 char *abac_role_principal(abac_role_t *role) {
     assert(role != NULL);
-    return role->principal;
+    return role->principal_name;
+}
+
+char *abac_role_principal_cn(abac_role_t *role) {
+    assert(role != NULL);
+    return abac_cn_with_sha(role->principal_name);
 }
 
@@ -375,4 +530,15 @@
     return role->prereqs;
 }
+
+abac_param_list_t *abac_role_linked_role_params(abac_role_t *role) {
+    assert(role != NULL);
+    return role->linked_role_params;
+}
+
+abac_param_list_t *abac_role_role_params(abac_role_t *role) {
+    assert(role != NULL);
+    return role->role_params;
+}
+
 
 /**
@@ -381,8 +547,8 @@
 #define ROLE_SEPARATOR " <- "
 char *abac_role_attr_key(abac_role_t *head_role, abac_role_t *tail_role) {
-    char *head = abac_role_string(head_role);
+    char *head = abac_role_string_with_condition(head_role);
     int head_len = strlen(head);
 
-    char *tail = abac_role_string(tail_role);
+    char *tail = abac_role_string_with_condition(tail_role);
     int tail_len = strlen(tail);
 
