source: libabac/abac_aspect.c @ 13c9479

mei_rt2mei_rt2_fix_1
Last change on this file since 13c9479 was 13c9479, checked in by Mei <mei@…>, 12 years ago

1) fix the abac_errx's format
2) change how type_name of a principal is returned (abac_aspect)

  • Property mode set to 100644
File size: 19.1 KB
Line 
1
2/**
3**  abac_aspect.c
4**/
5
6
7#include <assert.h>
8#include <stdlib.h>
9#include <stdio.h>
10#include <string.h>
11
12#include "abac_list.h"
13#include "abac_util.h"
14
15#include "abac_internal.h"
16
17static int debug=0;
18/*
19   A.role <- B
20   A.role <- B.role
21   A.role <- B.role.role
22
23   A.oset <- B
24   A.oset <- Obj
25   A.oset <- B.oset
26   A.oset <- B.role.oset
27*/
28
29/* can store either a role or oset */
30struct _abac_aspect_t {
31    int aspect_type;
32    int is_object;
33
34    char *principal_name;
35    abac_term_t *principal_object;
36
37    char *linked_role_name;
38    abac_param_list_t *linked_role_params;
39
40    char *aspect_name;
41    abac_param_list_t *aspect_params;
42
43    char *type_string; // "oset" or "role"
44
45    abac_list_t *prereqs;
46    int refcount;
47};
48
49/**************************************************************/
50bool abac_aspect_is_oset(abac_aspect_t *ptr)
51{
52    assert(ptr);
53    if(ptr->aspect_type==e_ASPECTTYPE_OSET)
54        return 1;
55    return 0;
56}
57
58
59bool abac_aspect_is_role(abac_aspect_t *ptr)
60{
61    assert(ptr);
62    if(ptr->aspect_type==e_ASPECTTYPE_ROLE)
63        return 1;
64    return 0;
65}
66
67bool abac_aspect_is_intersecting(abac_aspect_t *ptr)
68{
69    assert(ptr);
70    if(ptr->aspect_type==e_ASPECTTYPE_INTERSECTING)
71        return 1;
72    return 0;
73}
74
75/* A.role->B or A.oset->B */
76bool abac_aspect_is_principal(abac_aspect_t *ptr) {
77    assert(ptr != NULL);
78    return ptr->is_object == 0 &&
79             ptr->aspect_name == NULL && 
80               ptr->linked_role_name == NULL && 
81                 ptr->prereqs == NULL;
82}
83
84/* A.oset->O */
85bool abac_aspect_is_object(abac_aspect_t *ptr)
86{
87    assert(ptr);
88    if(ptr->aspect_type == e_ASPECTTYPE_OSET)
89        return ptr->is_object;
90    return 0;
91}
92
93/* A.role->B.role.role or A.oset->B.role.oset */
94bool abac_aspect_is_linking(abac_aspect_t *ptr) 
95{
96    assert(ptr);
97    return ptr->linked_role_name != NULL;
98}
99
100/**
101 * True if an aspect is an intersection.
102 */
103bool abac_aspect_is_intersection(abac_aspect_t *ptr)
104{
105    assert(ptr);
106    return ptr->prereqs != NULL;
107}
108
109/**
110 * return the type that is common to all the intersecting aspects
111 */ 
112int abac_aspect_intersecting_aspect_type(abac_aspect_t *ptr)
113{
114    assert(ptr);
115    assert(ptr->prereqs);
116    abac_aspect_t *cur;
117    int first=1;
118    int type;
119    abac_list_foreach(ptr->prereqs, cur,
120            if(first) {
121               type=abac_aspect_aspect_type(cur);
122               first=0;
123               } else {
124                   if(abac_aspect_aspect_type(cur) != type)
125                       errx(1,"Intersecting tails are not of the same type");
126            }
127        );
128    return type;
129}
130
131/**
132 * Returns the prereqs of an intersection.
133 */
134abac_list_t *abac_aspect_prereqs(abac_aspect_t *ptr)
135{
136    assert(ptr);
137    return ptr->prereqs;
138}
139
140char* abac_aspect_type_string(abac_aspect_t *ptr)
141{
142    assert(ptr);
143    return ptr->type_string;
144}
145
146int abac_aspect_aspect_type(abac_aspect_t *ptr)
147{
148    assert(ptr);
149    return ptr->aspect_type;
150}
151
152/**
153 * Returns the linked part of a linking aspect.
154 * For instance, if the aspect is A.r1.r2, this returns r1.
155 */
156char *abac_aspect_linked_role_name(abac_aspect_t *ptr)
157{
158    assert(ptr);
159    return ptr->linked_role_name;
160}
161
162/* A.r1 without params or constraints, callee needs to free it*/
163char *abac_aspect_linked_role_bare(abac_aspect_t *ptr)
164{
165    assert(ptr);
166    assert(ptr->principal_name);
167    assert(ptr->linked_role_name);
168    char *tmp=NULL;
169    asprintf(&tmp,"%s.%s",ptr->principal_name,ptr->linked_role_name);
170    return tmp;
171}
172
173abac_param_list_t *abac_aspect_linked_role_params(abac_aspect_t *ptr)
174{
175    assert(ptr);
176    return ptr->linked_role_params;
177}
178
179/**
180 * Returns the name of an aspect. If the aspect is A.r1 then return r1.
181 * If the aspect is A.r1.r2 then return r2.
182 */
183char *abac_aspect_aspect_name(abac_aspect_t *ptr) {
184    assert(ptr);
185    return ptr->aspect_name;
186}
187
188abac_param_list_t *abac_aspect_aspect_params(abac_aspect_t *ptr)
189{
190    assert(ptr);
191    return ptr->aspect_params;
192}
193
194/**
195 * Returns the principal part of an aspect. The stuff before the first dot.
196 */
197char *abac_aspect_principal_name(abac_aspect_t *ptr)
198{
199    assert(ptr);
200    if(USE("ABAC_CN"))
201        return abac_cn_with_sha(ptr->principal_name);
202    return ptr->principal_name;
203}
204
205char *abac_aspect_principal_principalname(abac_aspect_t *ptr)
206{
207    assert(ptr);
208    return ptr->principal_name;
209}
210
211char *abac_aspect_principal_type(abac_aspect_t *ptr)
212{
213    assert(ptr);
214    return abac_idtype_with_sha(ptr->principal_name);
215}
216
217char *abac_aspect_principal_cn(abac_aspect_t *ptr)
218{
219    assert(ptr);
220    return abac_cn_with_sha(ptr->principal_name);
221}
222
223char *abac_aspect_object_name(abac_aspect_t *ptr)
224{
225    assert(ptr);
226    assert(ptr->is_object);
227    abac_term_t *obj=ptr->principal_object;
228    char *tmp=abac_term_name(obj);
229    return abac_term_name(obj);
230}
231
232char *abac_aspect_object_type(abac_aspect_t *ptr)
233{
234    assert(ptr);
235    assert(ptr->is_object);
236    abac_term_t *obj=ptr->principal_object;
237    char *tmp=abac_term_type_name(obj);
238    return tmp;
239}
240
241abac_condition_t *abac_aspect_object_constraint(abac_aspect_t *ptr) 
242{
243    assert(ptr != NULL);
244    assert(ptr->is_object);
245    abac_term_t *obj=ptr->principal_object;
246    return abac_term_constraint(obj);
247}
248
249abac_id_t *abac_aspect_get_issuer_id(abac_aspect_t *ptr)
250{
251    abac_id_t *issuer_id;
252    char *principalname=abac_aspect_principal_principalname(ptr);
253    if(principalname) {
254        abac_id_credential_t *id_cred=abac_id_credential_lookup(principalname);
255        if(id_cred)
256            issuer_id=abac_id_credential_id(id_cred);
257    }
258    return issuer_id;
259}
260/**
261 * Increase a aspect's reference count.
262 */
263abac_aspect_t *abac_aspect_dup(abac_aspect_t *ptr)
264{
265    assert(ptr != NULL);
266    ++ptr->refcount;
267    return ptr;
268}
269
270/**
271 * Decrease an aspect's reference count, freeing it when it reaches 0.
272 */
273void abac_aspect_free(abac_aspect_t *ptr) {
274
275    if(debug)
276        printf("DEBUG:trying to freeing an aspect %d\n",(int)ptr);
277
278    assert(ptr);
279
280    --ptr->refcount;
281    if (ptr->refcount > 0)
282        return;
283
284    if(ptr->principal_name) free(ptr->principal_name);
285    if(ptr->linked_role_name) free(ptr->linked_role_name);
286    if(ptr->aspect_name) free(ptr->aspect_name);
287
288    if(ptr->type_string) free(ptr->type_string);
289
290    if (ptr->aspect_params != NULL) {
291        abac_param_list_free(ptr->aspect_params);
292    }
293
294    if (ptr->linked_role_params != NULL) {
295        abac_param_list_free(ptr->linked_role_params);
296    }
297
298    if (ptr->prereqs != NULL) {
299        abac_aspect_t *cur;
300        abac_list_foreach(ptr->prereqs, cur,
301            abac_aspect_free(cur);
302        );
303        abac_list_free(ptr->prereqs);
304    }
305
306    free(ptr);
307}
308
309/**********************************************************************/
310
311abac_aspect_t *abac_aspect_add_param(abac_aspect_t *ptr, abac_term_t *param)
312{
313     if(ptr->aspect_params == NULL) {
314        ptr->aspect_params=abac_param_list_new(param);
315        } else {
316            abac_param_list_add_term(ptr->aspect_params, param);
317     }
318     return ptr;
319}
320
321abac_aspect_t *abac_aspect_add_intersecting_aspect(abac_aspect_t *ptr, abac_aspect_t *aspect)
322{
323     abac_list_add(ptr->prereqs, abac_aspect_dup(aspect));
324     return ptr;
325}
326
327abac_aspect_t *abac_aspect_add_linked_param(abac_aspect_t *ptr, abac_term_t *param)
328{
329     if(ptr->linked_role_params == NULL) {
330        ptr->linked_role_params=abac_param_list_new(param);
331        } else {
332            abac_param_list_add_term(ptr->linked_role_params, param);
333     }
334     return ptr;
335}
336
337
338/**********************************************************************/
339
340/**
341 * Create a new principal and initialize it.
342 * always with the proper SHA string
343 */
344static abac_aspect_t *_abac_aspect_init()
345{
346    abac_aspect_t *ptr = (abac_aspect_t *) abac_xmalloc(sizeof(abac_aspect_t));
347
348    ptr->is_object=0;
349    ptr->principal_name = NULL;
350    ptr->aspect_type=e_ASPECTTYPE_NULL;
351
352    ptr->aspect_name = NULL;
353    ptr->aspect_params = NULL;
354
355    ptr->linked_role_name = NULL;
356    ptr->linked_role_params = NULL;
357
358    ptr->type_string=NULL;
359
360    ptr->prereqs = NULL;
361    ptr->refcount = 1;
362}
363
364abac_aspect_t *abac_aspect_principal_new(int type, char *principal_name)
365{
366    assert(principal_name != NULL);
367
368    if (strlen(principal_name) == 0)
369        return NULL;
370
371    abac_aspect_t *ptr = _abac_aspect_init();
372    ptr->aspect_type=type;
373    ptr->principal_name = strdup(principal_name);
374    if(type==e_ASPECTTYPE_ROLE)
375       ptr->type_string=abac_xstrdup("role");
376    if(type==e_ASPECTTYPE_OSET)
377       ptr->type_string=abac_xstrdup("oset");
378    return ptr;
379}
380
381abac_aspect_t *abac_aspect_role_principal_new(char *principal_name)
382{
383    return abac_aspect_principal_new(e_ASPECTTYPE_ROLE,principal_name);
384}
385
386abac_aspect_t *abac_aspect_role_principal_create(char *principal_name)
387{
388    char *tmp=NULL;
389    asprintf(&tmp,"p%s",principal_name);
390    return abac_aspect_principal_new(e_ASPECTTYPE_ROLE,tmp);
391}
392
393abac_aspect_t *abac_aspect_oset_principal_new(char *principal_name)
394{
395    return abac_aspect_principal_new(e_ASPECTTYPE_OSET,principal_name);
396}
397
398abac_aspect_t *abac_aspect_oset_principal_create(char *principal_name)
399{
400    char *tmp=NULL;
401    asprintf(&tmp,"p%s",principal_name);
402    return abac_aspect_principal_new(e_ASPECTTYPE_OSET,tmp);
403}
404
405
406abac_aspect_t *abac_aspect_object_new(int type, abac_term_t *object)
407{
408    assert(object != NULL);
409    abac_aspect_t *ptr = _abac_aspect_init();
410    ptr->aspect_type=type;
411    ptr->is_object =1;
412    ptr->principal_object = object;
413    /* can not be role type */
414    if(type==e_ASPECTTYPE_OSET)
415        ptr->type_string=abac_xstrdup("oset");
416
417    return ptr;
418}
419
420abac_aspect_t *abac_aspect_oset_object_new(abac_term_t *object)
421{
422    return abac_aspect_object_new(e_ASPECTTYPE_OSET, object);
423}
424
425abac_aspect_t *abac_aspect_new(int type, char *principal_name, char *aspect_name)
426{
427    assert(principal_name != NULL);
428    assert(aspect_name != NULL);
429
430    if (strlen(principal_name) == 0 || strlen(aspect_name) == 0)
431        return NULL;
432
433    abac_aspect_t *ptr = _abac_aspect_init();
434
435    ptr->principal_name = strdup(principal_name);
436    ptr->aspect_type=type;
437
438    ptr->aspect_name = abac_xstrdup(aspect_name);
439
440    if(type==e_ASPECTTYPE_OSET)
441        ptr->type_string= abac_xstrdup("oset");
442        else
443            ptr->type_string= abac_xstrdup("role");
444 
445    if(debug)
446        printf("DEBUG:adding a new aspect (%s) to principal (%s)\n",
447                  ptr->aspect_name, ptr->principal_name);
448    return ptr;
449}
450
451abac_aspect_t *abac_aspect_oset_new(char *principal_name, char *oset_name)
452{
453    return abac_aspect_new(e_ASPECTTYPE_OSET,principal_name, oset_name);
454}
455
456abac_aspect_t *abac_aspect_oset_create(char *principal_name, char *oset_name)
457{
458    char *tmp=NULL;
459    asprintf(&tmp,"p%s",principal_name);
460    return abac_aspect_new(e_ASPECTTYPE_OSET,tmp,oset_name);
461}
462
463abac_aspect_t *abac_aspect_role_new(char *principal_name, char *oset_name)
464{
465    return abac_aspect_new(e_ASPECTTYPE_ROLE,principal_name, oset_name);
466}
467
468abac_aspect_t *abac_aspect_role_create(char *principal_name, char *role_name)
469{
470    char *tmp=NULL;
471    asprintf(&tmp,"p%s",principal_name);
472    return abac_aspect_new(e_ASPECTTYPE_ROLE,tmp,role_name);
473}
474
475/**
476 * Created a new linking role/oset and initialize it.
477 */
478abac_aspect_t *abac_aspect_linking_new(int type, char *principal_name, 
479char *linked_role_name, char *aspect_name)
480{
481    assert(principal_name != NULL);
482    assert(linked_role_name != NULL);
483    assert(aspect_name != NULL);
484
485    if (strlen(principal_name) == 0 || 
486         strlen(linked_role_name) == 0 || strlen(aspect_name) == 0)
487        return NULL;
488
489    abac_aspect_t *ptr = _abac_aspect_init();
490
491    ptr->is_object=0;
492    ptr->aspect_type=type;
493    ptr->principal_name = strdup(principal_name);
494
495    ptr->linked_role_name = strdup(linked_role_name);
496    ptr->aspect_name = strdup(aspect_name);
497    ptr->aspect_params = NULL;
498
499    if(debug)
500        printf("DEBUG:adding a new linked (%s) to oset(%s) for principal(%s)\n",
501                  ptr->linked_role_name, ptr->aspect_name, ptr->principal_name);
502
503    if(type==e_ASPECTTYPE_OSET)
504        ptr->type_string=abac_xstrdup("oset");
505        else ptr->type_string=abac_xstrdup("role");
506
507    return ptr;
508}
509
510abac_aspect_t *abac_aspect_role_linking_new(char *principal_name, char *linked_role_name, 
511char *role_name)
512{
513    return abac_aspect_linking_new(e_ASPECTTYPE_ROLE,
514                      principal_name, linked_role_name, role_name);
515}
516
517abac_aspect_t *abac_aspect_oset_linking_new(char *principal_name, char *linked_role_name, 
518char *oset_name)
519{
520    return abac_aspect_linking_new(e_ASPECTTYPE_OSET,
521                      principal_name, linked_role_name, oset_name);
522}
523
524/**
525 * Create an intersection oset/role.
526 */
527abac_aspect_t *abac_aspect_intersection_new(abac_aspect_t *aspect)
528{
529    abac_aspect_t *ptr = _abac_aspect_init();
530    ptr->aspect_type=e_ASPECTTYPE_INTERSECTING;
531    abac_list_t *prereqs = abac_list_new();
532    abac_list_add(prereqs, abac_aspect_dup(aspect));
533    ptr->prereqs = prereqs;
534    ptr->refcount = 1;
535    return ptr;
536}
537
538/*******************************************************************/
539char *abac_aspect_intersecting_string_with_condition(int typed,abac_aspect_t *ptr)
540{
541    assert(ptr != NULL);
542    char *tmp=NULL;
543    if (ptr->prereqs != NULL) {
544        abac_aspect_t *cur;
545        abac_list_foreach(ptr->prereqs, cur,
546            char *ntmp=NULL;
547            if(typed)
548                ntmp=abac_aspect_typed_string_with_condition(cur);
549                else
550                    ntmp=abac_aspect_string_with_condition(cur);
551            if(tmp==NULL) {
552                asprintf(&tmp,"%s",ntmp);
553                } else {
554                    asprintf(&tmp,"%s & %s",tmp, ntmp);
555            }
556        );
557    }
558    return tmp;
559}
560
561/**
562 * Returns the string representation of the role/oset.
563 * principal.osetname(params..)
564 * principal.rolename(params..)
565 */
566char *abac_aspect_string_with_condition(abac_aspect_t *ptr)
567{
568    assert(ptr != NULL);
569
570    if(abac_aspect_is_intersection(ptr)) {
571        return abac_aspect_intersecting_string_with_condition(0,ptr);
572    }
573
574    char *tmp=NULL;
575    char *principal_name;
576    if(abac_aspect_is_object(ptr))
577        principal_name = abac_aspect_object_name(ptr);
578        else principal_name = abac_aspect_principal_name(ptr);
579    char *aspect_name= ptr->aspect_name;
580    char *linked_role_name = ptr->linked_role_name;
581    char *params_string=NULL;
582    char *linked_params_string=NULL;
583
584    int len = 0;
585    if(principal_name)
586        len=len+strlen(principal_name)+1;
587    if(aspect_name)
588        len = len+strlen(aspect_name)+1;
589    if(linked_role_name)
590        len = len+strlen(linked_role_name)+1;
591
592    if(ptr->aspect_params) {
593         params_string=abac_param_list_string_with_condition(ptr->aspect_params);
594         len = len+strlen(params_string)+3;
595    } 
596    if(ptr->linked_role_params) {
597         linked_params_string=abac_param_list_string_with_condition(ptr->linked_role_params);
598         len = len+strlen(linked_params_string)+3;
599    }
600
601    /* principal */
602    /* principal.oset/role */
603    /* principal.oset/role(params_string) */
604    /* principal.linked_role(linked_params_string).oset/role(params_string) */
605    tmp = abac_xmalloc(len);
606
607    if(principal_name)
608        sprintf(tmp,"%s",principal_name);
609
610    if(linked_role_name) {
611        strcat(tmp,".");
612        strcat(tmp,linked_role_name);
613    }
614    if(linked_params_string) {
615        strcat(tmp,"(");
616        strcat(tmp,linked_params_string);
617        strcat(tmp,")");
618    }
619    if(aspect_name) {
620        strcat(tmp,".");
621        strcat(tmp,aspect_name);
622    }
623    if(params_string) {
624        strcat(tmp,"(");
625        strcat(tmp,params_string);
626        strcat(tmp,")");
627    }
628
629    if(linked_params_string) free(linked_params_string);
630    if(params_string) free(params_string);
631    return tmp;
632}
633
634char *abac_aspect_string(abac_aspect_t *ptr) { 
635    return abac_aspect_string_with_condition(ptr);
636}
637char *abac_aspect_typed_string(abac_aspect_t *ptr) { 
638    return abac_aspect_typed_string_with_condition(ptr);
639}
640
641void abac_print_aspect_string_with_condition(abac_aspect_t *ptr,FILE *fp)
642{
643    char *string=abac_aspect_string_with_condition(ptr);
644    if(fp==NULL)
645        printf("%s ",string);
646        else fprintf(fp,"%s ",string);
647}
648
649char *abac_aspect_aspect_param_string(abac_aspect_t *ptr) {
650    assert(ptr != NULL);
651    if(ptr->aspect_params) {
652         return abac_param_list_string_with_condition(ptr->aspect_params);
653    }
654    return NULL;
655}
656
657char *abac_aspect_aspect_param_typed_string(abac_aspect_t *ptr) {
658    assert(ptr != NULL);
659    if(ptr->aspect_params) {
660         return abac_param_list_typed_string_with_condition(ptr->aspect_params);
661    }
662    return NULL;
663}
664
665/**
666 * Returns the typed string representation of the role/oset.
667 */
668char *abac_aspect_typed_string_with_condition(abac_aspect_t *ptr)
669{
670    assert(ptr != NULL);
671
672    if(abac_aspect_is_intersection(ptr)) {
673        return abac_aspect_intersecting_string_with_condition(1,ptr);
674    }
675
676    char *tmp=NULL, *final=NULL;
677    char *principal_name;
678    char *principal_name_type=NULL;
679    if(abac_aspect_is_object(ptr)) {
680        principal_name = abac_aspect_object_name(ptr);
681        principal_name_type = abac_aspect_object_type(ptr);
682        } else {
683            principal_name = abac_aspect_principal_name(ptr);
684            principal_name_type=abac_aspect_principal_type(ptr);
685            if(debug) {
686                printf("aspect's typed_string (%s)(%s)\n", principal_name_type, principal_name);
687            }
688    }
689    char *aspect_name=abac_aspect_aspect_name(ptr);
690    char *aspect_name_type=abac_aspect_type_string(ptr);
691    char *linked_role_name=abac_aspect_linked_role_name(ptr);
692    char *params_string=NULL;
693    char *linked_params_string=NULL;
694
695    if(ptr->aspect_params) {
696         params_string=abac_param_list_typed_string_with_condition(ptr->aspect_params);
697    } 
698    if(ptr->linked_role_params) {
699         linked_params_string=abac_param_list_typed_string_with_condition(ptr->linked_role_params);
700    }
701
702    asprintf(&final,"[%s:%s]",principal_name_type,principal_name);
703    if(linked_role_name) {
704        tmp=final;
705        final=NULL;
706        asprintf(&final,".role:%s",tmp,linked_role_name);
707        free(tmp);
708    }
709    if(linked_params_string) {
710        tmp=final;
711        final=NULL;
712        asprintf(&final,"%s(%s)",tmp,linked_params_string);
713        free(tmp);
714    }
715    if(aspect_name) {
716        tmp=final;
717        final=NULL;
718        asprintf(&final,"%s.%s:%s",tmp,aspect_name_type,aspect_name);
719        free(tmp);
720    }
721    if(params_string) {
722        tmp=final;
723        final=NULL;
724        asprintf(&final,"%s(%s)",tmp,params_string);
725        free(tmp);
726    }
727
728    if(linked_params_string) free(linked_params_string);
729    if(params_string) free(params_string);
730    return final;
731}
732
733/**
734 * Build an attribute key from head and tail osets/role. Static.
735 */
736#define ROLE_SEPARATOR " <- "
737char *abac_aspect_attr_key(abac_aspect_t *head_ptr, abac_aspect_t *tail_ptr) {
738    char *head = abac_aspect_string_with_condition(head_ptr);
739    int head_len = strlen(head);
740
741    char *tail = abac_aspect_string_with_condition(tail_ptr);
742    int tail_len = strlen(tail);
743
744    int sep_len = sizeof(ROLE_SEPARATOR) - 1;
745
746    // "head <- tail"
747    char *ret = abac_xmalloc(head_len + tail_len + sep_len + 1);
748    memcpy(ret, head, head_len);
749    memcpy(ret + head_len, ROLE_SEPARATOR, sep_len);
750    memcpy(ret + head_len + sep_len, tail, tail_len);
751    ret[head_len + sep_len + tail_len] = 0;
752
753    return ret;
754}
Note: See TracBrowser for help on using the repository browser.