source: libabac/abac_pl_yap.c @ 4f40c3e

mei_rt2mei_rt2_fix_1
Last change on this file since 4f40c3e was 4f40c3e, checked in by Mei <mei@…>, 11 years ago

1) add a yap patch file for 6.2.2 for FreeBSD platform
2) update documentaions

  • Property mode set to 100644
File size: 28.5 KB
Line 
1
2/* copied from abac_graph.c
3   implementation of the low level using
4   yap prolog
5*/
6
7#include <err.h>
8#include <stdio.h>
9#include <assert.h>
10#include <stdlib.h>
11#include <string.h>
12#include <Yap/YapInterface.h>
13
14#include "abac_internal.h"
15
16#include "abac_pl_yap.h"
17#include "abac_util.h"
18
19#include "uthash.h"
20
21extern abac_credential_t *abac_credential_dup(abac_credential_t *cred);
22extern abac_list_t *abac_credential_clauses(abac_credential_t *);
23extern char *abac_id_clause(abac_id_credential_t *);
24extern abac_aspect_t *abac_yy_get_rule_tail_aspect();
25extern abac_aspect_t *abac_yy_get_rule_head_aspect();
26
27static int debug=0;
28
29/* track constraint's external clause's -unique name id */
30
31static int constraint_label_count=0;
32static char *constraint_label="isABAC_constraint";
33
34/*
35x    can pLadybug buy_rockets from pAcme ? (_arg_for_fact)
36x    can pLadybug What from pAcme ? (_arg_for_what)
37x    Who can buy_rockets from pAcme ? (_arg_for_who)
38x    can pLadybug buy_rockets from Whom ? (_arg_for_whom)
39x    can pLadybug What from Whom ? (_arg_for_what_whom)
40the type ordering also dictates the order of partial proof query
41sequence
42*/
43enum _query_type_t {
44   e_PL_FACT=0,
45   e_PL_WHAT=1,
46   e_PL_WHAT_DFLT=2,
47   e_PL_WHO=3,   
48   e_PL_WHOM=4,
49   e_PL_WHAT_WHOM=5,
50   e_PL_NOMORE=6
51};
52
53static const char *const _queryname[] =
54{
55  "fact",
56  "what",
57  "what_default",
58  "who",
59  "whom",
60  "what_whom",
61  "nomore"
62};
63static int _queryname_cnt=6;
64
65
66// pl -- place holder for now
67struct _abac_pl_t {
68   /* a_term <- prin */
69    char *whom;
70    char *who;
71    char *aspect;
72    char *what;
73    char *whatwith;
74    int pcnt; /* pcnt=number of params in whatwith */
75
76    int query_made; /* 1+ yes, 0 no, rc is valid only if a query is made */
77    int query_rc; /* rc of query call */
78    int next_rc; /* rc of next-last query */
79      /* proof count = abac_list_size(proof_list) */
80    int is_partial;
81    int want_partial;
82    int query_type;
83    abac_list_t *proof_list; /* list of list of cred_list */ 
84    long safe_t; /* holding the YAP's saved goal */
85};
86
87/***********************************************************/
88/* default to Yap2 */
89static int isYAP3()
90{
91#ifdef  YAP_VERSION
92    if(YAP_VERSION == "6.3.2") 
93        return 1;
94#endif
95    return 0;
96}   
97/***********************************************************/
98static int _get_next_constraint_label_idx()
99{
100    constraint_label_count++;
101    return constraint_label_count;
102}
103
104static int _get_constraint_label_idx()
105{
106    return constraint_label_count;
107}
108
109/***********************************************************/
110
111static int _insert_clause(char *str)
112{
113    YAP_Term eterm;
114    YAP_Term goalArgs=YAP_ReadBuffer(str, &eterm);
115    char *tmp=YAP_CompileClause(goalArgs);
116    if (tmp!=NULL) { /* something is wrong */
117        printf("error: result of compile clause (%s)\n", tmp);
118        printf("error: str used (%s)\n", str);
119        return 1;
120    }
121    return 0;
122}
123
124static int _insert_cred_clause(char *cstr)
125{
126    int ret=ABAC_CERT_SUCCESS;
127    int rc=_insert_clause(cstr);
128    if (rc)
129        return ABAC_CERT_BAD_YAP;
130    return ABAC_CERT_SUCCESS;
131}
132
133void show_yap_db(const char *msg)
134{
135    char lstr[]="listing";
136    YAP_Term eterm; /* error term */
137
138    printf("\n\n/* ========= yap db (%s) */\n",msg);
139    int rc=YAP_RunGoalOnce(YAP_ReadBuffer(lstr,&eterm));
140    if (rc) {
141        printf("/* listing ok.. */\n");
142    } else {
143        printf("/* listing's rc is bad.. */ \n");
144        YAP_Exit(1);
145    }
146    printf("/* ========= */\n\n");
147}
148
149/**
150 * Include some utility routines
151 */
152abac_pl_t *abac_pl_utility(void) {
153/*
154append([],L,L).
155append([X|L1],L2,[X|L3]):-append(L1,L2,L3).
156
157appendL([],[]).
158appendL([H|T], L) :-
159   appendL(T,L2), append(H,L2,L).
160*/
161    if(_insert_clause("append([],L,L)"))
162        YAP_Exit(1);
163    if(_insert_clause("append([X|L1],L2,[X|L3]):-append(L1,L2,L3)"))
164        YAP_Exit(1);
165    if(_insert_clause("appendL([],[])"))
166        YAP_Exit(1);
167    if(_insert_clause("appendL([H|T], L) :- appendL(T,L2), append(H,L2,L)"))
168        YAP_Exit(1);
169}
170
171/**
172 * Create a new yap structure.
173 */
174abac_pl_t *abac_pl_new(void) {
175
176    YAP_Term eterm;
177
178    if (YAP_FastInit(NULL) == YAP_BOOT_ERROR)
179        YAP_Exit(1);
180
181    int rc=YAP_RunGoalOnce(YAP_ReadBuffer("source",&eterm));
182    if(rc) {
183        if(debug) fprintf(stderr, "calling source..\n");
184        } else {
185            if(debug) fprintf(stderr,"calling source failed..\n");
186            YAP_Exit(1);
187    }
188
189    abac_pl_utility();
190 
191    abac_pl_t *pl = abac_xmalloc(sizeof(abac_pl_t));
192
193    pl->who=NULL;
194    pl->whom = NULL;
195    pl->what = NULL;
196    pl->whatwith = NULL;
197    pl->aspect = NULL;
198    pl->pcnt=0;
199    pl->query_made=0;
200    pl->query_rc=0;
201    pl->is_partial=0;
202    pl->want_partial=1;
203    pl->query_type=e_PL_FACT;
204    pl->next_rc=0;
205    pl->proof_list=NULL;
206    pl->safe_t=0;
207    return pl;
208}
209
210int abac_pl_returning_partial(abac_pl_t *pl)
211{
212    return pl->is_partial;
213}
214
215/* returns the number of solution so far */
216int abac_pl_proof_cnt(abac_pl_t *pl)
217{
218    if(pl->proof_list)
219        return abac_list_size(pl->proof_list);
220    return 0;
221}
222
223int abac_pl_is_partial(abac_pl_t *pl)
224{
225    return pl->is_partial;
226}
227
228/* is this the conclusion of the query ? */
229/* 1 is yes, 0 N/A */
230int abac_pl_done_yet(abac_pl_t *pl)
231{
232    if(pl->query_made) {
233        if(pl->query_rc) {
234            if(!pl->next_rc) return 1;
235            return 0;
236        } else return 1; /* even init query failed */
237    }
238    return 0;
239}
240
241void abac_pl_set_no_partial(abac_pl_t *pl)
242{
243   pl->want_partial=0;
244}
245
246void abac_pl_set_want_partial(abac_pl_t *pl)
247{
248   pl->want_partial=1;
249}
250
251static void _free_p_list(abac_list_t *p)
252{
253    if( p != NULL ) {
254        if(abac_list_size(p) != 0) {
255            abac_credential_t *cur=NULL;
256            abac_list_foreach(p, cur,
257                abac_credential_free(cur);
258            );
259        }
260        abac_list_free(p);
261    }
262}
263
264static void _free_pf_list(abac_list_t *p)
265{
266   
267    if(p != NULL) {
268        if(abac_list_size(p) != 0) {
269            abac_list_t *cur=NULL;
270            abac_list_foreach(p, cur,
271                _free_p_list(cur);
272            );
273        }
274        abac_list_free(p);
275    }
276}
277
278void abac_pl_free(abac_pl_t *pl) {
279    if(pl->who) free(pl->who);
280    if(pl->whom) free(pl->whom);
281    if(pl->what) free(pl->what);
282    if(pl->whatwith) free(pl->whatwith);
283    if(pl->aspect) free(pl->aspect);
284    _free_pf_list(pl->proof_list);
285    free(pl);
286}
287
288/* this is done whenever a new query starts in */
289static void _reset_pl(abac_pl_t *pl, char *who,
290char *what, char *whom, char *aspect, char *whatwith, int pcnt)
291{
292    if(pl->safe_t != 0) {
293        if(!isYAP3()) {
294            YAP_RecoverSlots(1); 
295            YAP_Reset(); 
296            } else { /* 6.3.2 seems to have YAP_Reset problem */
297                YAP_RecoverSlots(1); 
298        }
299    }
300
301    /* free the old ones */
302    if(pl->who) free(pl->who);
303    if(pl->whom) free(pl->whom);
304    if(pl->what) free(pl->what);
305    if(pl->whatwith) free(pl->whatwith);
306    if(pl->aspect) free(pl->aspect);
307
308    pl->who = (who !=NULL)?abac_xstrdup(who):NULL;
309    pl->whom = (whom !=NULL)?abac_xstrdup(whom):NULL;
310    pl->what = (what!=NULL)?abac_xstrdup(what):NULL;
311    pl->whatwith = (whatwith!=NULL)?abac_xstrdup(whatwith):NULL;
312    pl->aspect = (aspect!=NULL)?abac_xstrdup(aspect):NULL;
313
314    pl->pcnt=pcnt;
315
316    pl->query_made=0;
317    pl->query_rc=0;
318    pl->next_rc=0;
319    pl->is_partial=0;
320    pl->query_type=e_PL_FACT;
321    _free_pf_list(pl->proof_list);
322    pl->proof_list=abac_list_new();
323    pl->safe_t=0;
324}
325
326/**
327 * Add a credential to the db, not duplicating a copy and so
328 * don't try to free it after this call.
329 */
330int abac_pl_add_credential(abac_pl_t *pl, abac_credential_t *cred)
331{
332    int rc=0;
333    abac_list_t *clauses=abac_credential_clauses(cred);
334    if (clauses != NULL) {
335        char *cur;
336        abac_list_foreach(clauses, cur,
337            if(cur) {
338                if(debug) fprintf(stderr,"inserting =>%s\n",cur);
339                rc=_insert_cred_clause(cur);
340            }
341        );
342    }
343    return rc;
344}
345
346int abac_pl_add_type_credential(abac_pl_t *pl, abac_id_credential_t *id_cert)
347{
348    char *clause=abac_id_clause(id_cert);
349    if (clause != NULL) {
350        int rc=_insert_cred_clause(clause);
351        return rc;
352    }
353    return 0;
354}
355
356/*  string1(S):- S="abc";S="efg";S="ijk" */
357char *abac_pl_add_range_constraint_clause(char *var, char *tmplist)
358{
359    int i=_get_next_constraint_label_idx();
360    char *tmp=NULL;
361    asprintf(&tmp,"%s_%d(%s) :- %s", constraint_label, i, var, tmplist); 
362    int rc=_insert_cred_clause(tmp);
363    free(tmp);
364    if(rc) 
365        panic("abac_pl_add_range_constraint_clause, failed to insert");
366    asprintf(&tmp,"%s_%d(%s)", constraint_label, i, var);
367    return tmp;
368}
369
370/* cases, for YAP 6.2.x
371     ['str']
372     ['str1','str2']
373     ([] is not possible, and don't care)
374*/
375static void _credentials_from_string_2(abac_list_t *credentials,char *slist) 
376{
377    char *cptr=slist; /* current ptr */
378    char *sptr; /* string ptr */
379    char *ptr;
380    int len=0;
381    char *string;
382    abac_credential_t *cred=NULL;
383    int cnt=0;
384
385    /* find first [' */ 
386    ptr=strstr(cptr,"['");
387    if(ptr == NULL) 
388         return;
389    cptr=ptr+2;
390    sptr=cptr;
391    while (1) {
392        /* find next ',' or '] */
393        if(debug) fprintf(stderr,"START with %d\n", strlen(cptr));
394        ptr=strstr(cptr,"','");
395        if(ptr!=NULL) {
396             cptr=ptr+3;
397             len=(ptr-sptr);
398             string=strndup(sptr,len);
399             cred=abac_credential_lookup(string);
400             free(string); 
401             if(cred) {
402                 int i=abac_list_unique_add(credentials, cred);
403                 if(i) cnt++;
404                 } else {
405                 printf("BAD BAD\n");
406             }
407             sptr=cptr;
408             } else {
409             ptr=strstr(cptr,"']");
410             if(ptr!=NULL) {
411                 len=(ptr-sptr);
412                 string=strndup(sptr,len);
413                 cred=abac_credential_lookup(string);
414                 free(string);
415                 if(cred) {
416                     int i=abac_list_unique_add(credentials, cred);
417                     if(i) cnt++;
418                     } else {
419                     printf("BAD BAD BAD\n");
420                 }
421                 break;
422             }
423        }
424    }
425    if(debug)
426        fprintf(stderr,"DEBUG:total %d credentials\n", cnt);
427}
428
429/*  XXX just for yap 6.3.2
430     [str]
431     [str1,str2]
432     ([] is not possible, and don't care)
433*/
434static void _credentials_from_string_3(abac_list_t *credentials,char *slist)
435{
436    char *cptr=slist; /* current ptr */
437    char *sptr; /* string ptr */
438    char *ptr;
439    int len=0;
440    char *string;
441    abac_credential_t *cred=NULL;
442    int cnt=0;
443
444    /* find first [ */ 
445    ptr=strstr(cptr,"[");
446    if(ptr == NULL) 
447         return;
448    cptr=ptr+1;
449    sptr=cptr;
450    while (1) {
451        /* find next "," or "]" */
452        if(debug) fprintf(stderr,"START with %d\n", strlen(cptr));
453        ptr=strstr(cptr,",");
454        if(ptr!=NULL) {
455             cptr=ptr+1;
456             len=(ptr-sptr);
457             string=strndup(sptr,len);
458             cred=abac_credential_lookup(string);
459             free(string); 
460             if(cred) {
461                 int i=abac_list_unique_add(credentials, cred);
462                 if(i) cnt++;
463                 } else {
464                 printf("BAD BAD\n");
465             }
466             sptr=cptr;
467             } else {
468             ptr=strstr(cptr,"]");
469             if(ptr!=NULL) {
470                 len=(ptr-sptr);
471                 string=strndup(sptr,len);
472                 cred=abac_credential_lookup(string);
473                 free(string);
474                 if(cred) {
475                     int i=abac_list_unique_add(credentials, cred);
476                     if(i) cnt++;
477                     } else {
478                     printf("BAD BAD BAD\n");
479                 }
480                 break;
481             }
482        }
483    }
484    if(debug)
485        fprintf(stderr,"DEBUG:total %d credentials\n", cnt);
486}
487
488static void _credentials_from_string(abac_list_t *credentials,char *slist) {
489    if(isYAP3())
490         _credentials_from_string_3(credentials,slist);
491    else
492         _credentials_from_string_2(credentials,slist);
493}
494
495/* MAX 1024x1024, double as it goes */
496static int try_again(int sz, char **tptr)
497{
498   int blk=1024*2; /* 2048 */
499   int max=1024*1024;
500   int size;
501   char *tmp = NULL;
502
503   if(sz==0) {
504       size = (sizeof(char) * (blk+1));
505       } else {
506           if(debug) fprintf(stderr,"calling try_again needing extra space!!\n");
507           if (sz>=max) {
508               size=0;
509               *tptr=tmp;
510               return 0;
511           }
512           size=sz*2+1;
513           if(size > max) size=max;
514   }
515
516   tmp = (char *) YAP_AllocSpaceFromYap(size);
517   if(tmp==NULL) {
518       fprintf(stderr,"ERROR: malloc failed !!!\n");
519       YAP_Exit(1);
520   }
521   *tptr=tmp;
522   return size;
523}
524
525static int _check_buffer(char *tmp)
526{
527    int len=strlen(tmp); /* just for reference :-( */
528    if (len < 3) return 0;
529    if (tmp[0] != '[') return 0;
530    if (tmp[len-1] == ']') return 1;
531    int i=0; 
532    for(i=3; i<=len; i++) {
533        if(tmp[i]==']') {
534           if(i==len) fprintf(stderr," _check_buffer, match up..\n");
535             else {
536                 fprintf(stderr," _check_buffer, did not match up ..\n");
537                 tmp[i+1]='\0';
538           }
539           return 1;
540        }
541    }
542    if(debug)
543        fprintf(stderr," _check_buffer, did not find the closing square bracket ..\n");
544    return 0;
545}
546
547abac_list_t *run_goal(abac_pl_t *pl, YAP_Term *arg)
548{
549    abac_list_t *cred_list=abac_list_new();
550    YAP_Atom f = YAP_LookupAtom("isMember");
551    YAP_Functor func = YAP_MkFunctor(f, 3);
552    YAP_Term goal=YAP_MkApplTerm(func, 3, arg);
553
554    pl->safe_t = YAP_InitSlot(goal);
555if(debug) fprintf(stderr," run_goal, safe_t is %ld\n", pl->safe_t);
556    pl->query_rc =YAP_RunGoal(goal);
557    goal=YAP_GetFromSlot(pl->safe_t);
558    pl->query_made=1;
559    pl->next_rc=pl->query_rc;
560    if (pl->query_rc) {
561        if(pl->is_partial) 
562            printf("A partial proof(type:%s)\n",_queryname[pl->query_type]);
563            else printf("YAP query succeed\n");
564        char *tmp=NULL;
565        int tmp_sz=0; 
566        if(!isYAP3())
567            tmp_sz=try_again(0, &tmp);
568        YAP_Term argterm=YAP_ArgOfTerm(3,goal);
569        while(1) {
570            int rc=1; /* XXX rc does not seems to be right... */
571/* for 6.3 series ..
572     rc=YAP_WriteBuffer(argterm, tmp, tmp_sz,YAP_WRITE_HANDLE_VARS);
573*/
574            YAP_WriteBuffer(argterm, tmp, tmp_sz,YAP_WRITE_HANDLE_VARS); 
575
576/** it seems that 6.3 gives me some garbage at the back.. */
577            if(rc==1 && _check_buffer(tmp)) {
578                break;
579            } else {
580                tmp_sz=try_again(tmp_sz,&tmp);
581                if(tmp_sz==0) {
582                    fprintf(stderr," PANIC, run out of heap space..\n");
583                    YAP_Exit(1);
584                }
585            }
586        }
587        /* this is returned as ['string1','string2'] */
588        if(debug) fprintf(stderr,"    query answer : %s(%d)\n", tmp, strlen(tmp));
589        _credentials_from_string(cred_list,tmp); 
590        if(abac_list_size(cred_list)==0) {
591            fprintf(stderr,"CAN NOT retrieve result properly from YAP!!!\n");
592            YAP_Exit(1);
593        }
594        abac_list_add(pl->proof_list, cred_list);
595        YAP_FreeSpaceFromYap(tmp);
596    } else {
597        /* don't print anything if it is running a partial proof goal */
598        if(!pl->is_partial) 
599            printf("YAP query failed\n");
600 
601    }
602    return cred_list;
603}
604
605/*************************************************************************/
606YAP_Term _make_term(char *term) {
607    YAP_Term eterm;
608    YAP_Term ret;
609    if(term[0]=='\'' || term[0]=='"') {
610        ret =YAP_ReadBuffer(term,&eterm);
611        } else {
612            ret = YAP_MkAtomTerm(YAP_LookupAtom(term));
613    }
614}
615
616// isMember(who,aspect(whom,what,whatwith))
617/* aspect(whom, what, whatwith) */
618YAP_Term _aspect_base(char *whom,char *aspect, char *what, char *whatwith)
619{
620    YAP_Term eterm;
621    YAP_Term ret;
622
623    char *estring=NULL;
624    if(whatwith)
625       asprintf(&estring, "%s(%s,%s,%s)",aspect,whom,what,whatwith);
626       else asprintf(&estring, "%s(%s,%s)",aspect,whom,what);
627    if(debug) fprintf(stderr,"_aspect_base, doing %s\n",estring);
628    ret=YAP_ReadBuffer(estring,&eterm);
629    free(estring);
630    return ret;
631}
632
633/* generate a string of whatwith that are of ?variable */
634char *_make_whatwith_var(char *whatwith, int pcnt)
635{
636/* this is a dumb count since it is in porting directory */
637   if(whatwith==NULL || pcnt==0) return NULL; 
638   char *tmp=NULL;
639   char *ptr=NULL;
640   int i;
641   for(i=0;i<pcnt;i++) {
642       ptr=tmp;
643       tmp=NULL;
644       if(i == 0)
645           asprintf(&tmp,"Whatwith%d",i);
646           else asprintf(&tmp,"%s,Whatwith%d",ptr,i);
647   }
648   return tmp;
649}
650
651/* aspect(X, Y, Whatwith) */
652YAP_Term _aspect_what_whom(char *whom,char *aspect, char *what, char *whatwith)
653{
654    YAP_Term ret=_aspect_base("Whom",aspect,"What",whatwith);
655    return ret;
656}
657
658/* aspect(whom,Y,Whatwith) */
659/* call with char *tmp=_make_whatwith_var(whatwith); */
660YAP_Term _aspect_what(char *whom,char *aspect, char *what, char *whatwith)
661{
662    YAP_Term ret=_aspect_base(whom,aspect,"What",whatwith);
663    return ret;
664}
665
666/* aspect(X,what,whatwith) */
667YAP_Term _aspect_whom(char *whom,char *aspect, char *what, char *whatwith)
668{
669    YAP_Term ret=_aspect_base("Whom",aspect,what,whatwith);
670    return ret;
671}
672
673/* aspect(whom,what,whatwith) */
674YAP_Term _aspect_fact(char *whom,char *aspect, char *what, char* whatwith)
675{
676    YAP_Term ret=_aspect_base(whom,aspect,what,whatwith);
677    return ret;
678}
679
680// Whom.What <- ladybug
681// isMember(ladybug, role(W1, W2), R)
682static void _arg_for_what_whom(YAP_Term *arg,char *who, char *whom,
683char *aspect, char*what, char *whatwith, int pcnt)
684{
685    arg[0] = _make_term(who);
686    char *tmp=_make_whatwith_var(whatwith,pcnt); 
687    arg[1] = _aspect_what_whom(who,aspect,what,tmp);
688    if(tmp) free(tmp);
689    arg[2] = YAP_MkVarTerm();
690}
691
692// pAcme.What <- ladybug
693// isMember(ladybug, role(pAcme, W), R)
694static void _arg_for_what(YAP_Term *arg,char *who, char* whom, 
695char *aspect, char*what, char*whatwith, int pcnt)
696{
697    arg[0] = _make_term(who);
698    char *tmp=_make_whatwith_var(whatwith,pcnt); 
699    arg[1] = _aspect_what(whom,aspect,what,tmp);
700    if(tmp) free(tmp);
701    arg[2] = YAP_MkVarTerm();
702}
703
704// W.rocket <- ladybug
705// isMember(ladybug, role(W, buy_rockets), R)
706static void _arg_for_whom(YAP_Term *arg, char *who, char*whom,
707char *aspect, char *what, char*whatwith)
708{
709    arg[0] = _make_term(who);
710    arg[1] = _aspect_whom(whom,aspect,what,whatwith);
711    arg[2] = YAP_MkVarTerm();
712}
713
714// Acme.rocket <- V
715// isMember(V, role(pAcme, buy_rockets), R)
716static int _arg_for_who(YAP_Term *arg, char *who,char *whom, 
717char *aspect, char* what, char*whatwith)
718{
719    arg[0] = YAP_MkVarTerm();
720    arg[1] = _aspect_fact(whom, aspect, what, whatwith);
721    arg[2] = YAP_MkVarTerm();
722}
723
724// Acme.rocket <- x
725// isMember(x, role(pAcme, buy_rockets), R)
726static void _arg_for_fact(YAP_Term *arg,char *who,char *whom, 
727char* aspect, char *what, char*whatwith)
728{
729    arg[0] = _make_term(who);
730    arg[1] = _aspect_fact(whom, aspect, what, whatwith);
731    arg[2] = YAP_MkVarTerm();
732}
733
734
735static abac_list_t *_make_partial_query(abac_pl_t *pl)
736{
737    abac_list_t *ret=abac_list_new();
738    pl->is_partial=1;
739    char *who=pl->who;
740    char *whom=pl->whom;
741    char *aspect=pl->aspect;
742    char *what=pl->what;
743    char *whatwith=pl->whatwith;
744    int pcnt=pl->pcnt;
745    if(debug) fprintf(stderr,"making make_partial_query..\n");
746
747    switch (pl->query_type) { 
748        case e_PL_FACT: /* try what */
749            {
750            YAP_Term arg[3];
751            if(debug) fprintf(stderr,"... 1st partial attempt\n");
752            pl->query_type = e_PL_WHAT;
753            _arg_for_what(arg,who,whom, aspect, what, whatwith, pcnt);
754            ret=run_goal(pl,arg);
755            if(pcnt==0) pl->query_type= e_PL_WHAT_DFLT;
756            if(pl->query_rc) return ret;
757            break;
758            }
759        case e_PL_WHAT: /* try what with no params if need to */
760            {
761            YAP_Term arg[3];
762            if(debug) fprintf(stderr,"... 2nd partial attempt\n");
763            pl->query_type = e_PL_WHAT_DFLT;
764            _arg_for_what(arg,who,whom, aspect, what, whatwith, 0);
765            ret=run_goal(pl,arg);
766            if(pl->query_rc) return ret;
767            break;
768            }
769        case e_PL_WHAT_DFLT: /* try who */
770            {
771            YAP_Term arg[3];
772            if(debug) fprintf(stderr,"... 2nd half partial attempt\n");
773            pl->query_type = e_PL_WHO;
774            _arg_for_who(arg,who,whom, aspect, what, whatwith);
775            ret=run_goal(pl,arg);
776            if(pl->query_rc) return ret;
777            break;
778            }
779        case e_PL_WHO: /* try whom */
780            {
781            YAP_Term arg[3];
782            if(debug) fprintf(stderr,"... 3rd partial attempt\n");
783            pl->query_type = e_PL_WHOM;
784            _arg_for_whom(arg,who,whom, aspect, what, whatwith);
785            ret=run_goal(pl,arg);
786            if(pl->query_rc) return ret;
787            break;
788            }
789        case e_PL_WHOM: /* try what-whom */
790            {
791            YAP_Term arg[3];
792            if(debug) fprintf(stderr,"... 4th partial attempt\n");
793            pl->query_type = e_PL_WHAT_WHOM;
794            _arg_for_what_whom(arg,who,whom, aspect, what, whatwith,pcnt);
795            ret=run_goal(pl,arg);
796            if(pl->query_rc) return ret;
797            break;
798            }
799        default :
800            {
801            if(debug) fprintf(stderr,"... no more partial query to try\n");
802            pl->query_type = e_PL_NOMORE;
803            }
804    }
805    return ret;
806}
807
808/* make a query and extract just first set of result,
809   simple = rt0
810   aspect => role/oset
811   aspect_string => rest of params
812   prin => principal
813   issuer => issuer
814   estring =>  aspect(issuer, aspect_type_string)
815*/
816static abac_list_t *_make_yap_query(abac_pl_t *pl, char *who,
817char *whom, char *aspect, char *what, char *whatwith, int pcnt)
818{
819    if(debug) { 
820       fprintf(stderr,"_make_yap_query: the who part(%s)\n", who);
821       fprintf(stderr,"_make_yap_query: whom part(%s)\n", whom);
822       fprintf(stderr,"_make_yap_query: the role/oset (%s)\n", aspect);
823       fprintf(stderr,"_make_yap_query: aspect what (%s)\n", what);
824       fprintf(stderr,"_make_yap_query: pcnt (%d)\n", pcnt);
825       if(whatwith)
826           fprintf(stderr,"_make_yap_query: aspect what part(%s)\n", whatwith);
827    } 
828    if(debug) fprintf(stderr,"making a yap query..\n");
829
830/* run query on fact goal */
831    YAP_Term arg[3];
832    _arg_for_fact(arg, who,whom, aspect, what, whatwith);
833    abac_list_t *ret=run_goal(pl,arg);
834
835/* fact query failed and so run partial query */
836    if(!pl->query_rc && pl->want_partial) {
837        while(pl->query_type != e_PL_NOMORE) {
838            abac_list_free(ret);
839            ret=_make_partial_query(pl);
840            if( pl->query_rc ) break;
841        }
842    }
843    return ret;
844}
845
846/* make a query for next possible solution proof */
847static abac_list_t *_query_again(abac_pl_t *pl)
848{
849    abac_list_t *cred_list=abac_list_new();
850
851    if(debug) fprintf(stderr,"making query_again call..\n");
852    pl->next_rc=YAP_RestartGoal();
853    pl->query_made++;
854    YAP_Term goal=YAP_GetFromSlot(pl->safe_t);
855
856    char *tmp=NULL;
857    int tmp_sz=try_again(0, &tmp);
858    YAP_Term argterm=YAP_ArgOfTerm(3,goal);
859    if(pl->next_rc) {
860        if(debug) fprintf(stderr,"query_again: another success\n");
861        if(pl->is_partial)
862            printf("A partial proof(type:%s)\n",_queryname[pl->query_type]);
863        while(1) {
864            YAP_WriteBuffer(argterm, tmp, tmp_sz,YAP_WRITE_HANDLE_VARS);
865            if(strlen(tmp) > 5 && tmp[0]=='\[')
866                break;
867            tmp_sz=try_again(tmp_sz,&tmp);
868            if(tmp_sz==0) {
869                fprintf(stderr," PANIC, run out of heap space..\n");
870                YAP_Exit(1);
871            }
872        }
873        /* this is returned as ['string1','string2'] */
874        if(debug) fprintf(stderr,"    query answer : %s(%d)\n", tmp, strlen(tmp));
875        _credentials_from_string(cred_list,tmp); 
876        if(abac_list_size(cred_list)==0) {
877            fprintf(stderr,"CAN NOT retrieve result properly from YAP!!!\n");
878            YAP_Exit(1);
879        }
880        abac_list_add(pl->proof_list, cred_list);
881        YAP_FreeSpaceFromYap(tmp);
882        } else {
883            if(debug) fprintf(stderr,"query_again: fail finding next\n");
884            if(pl->is_partial) { /* if there is more partial query to make */
885                while(pl->query_type != e_PL_NOMORE) {
886                    abac_list_free(cred_list);
887                    cred_list=_make_partial_query(pl);
888                    if( pl->query_rc ) break;
889                }
890            }
891    }
892    return cred_list;
893}
894
895/* print a list of abac_credential_t */
896void _print_cred_list(abac_list_t *p)
897{
898    if(debug) fprintf(stderr,"_print_cred_list(%d)items:\n",abac_list_size(p));
899    if(abac_list_size(p) != 0) {
900        abac_credential_t *cur=NULL;
901        abac_list_foreach(p, cur,
902            if(debug) fprintf(stderr,"printing (%d),\n",(int)cur);
903            abac_print_cred_info(cur, NULL);
904        );
905    }
906}
907
908
909abac_stack_t *_make_cred_stack(abac_list_t *p)
910{
911    abac_stack_t *ret=abac_stack_new();
912    if(abac_list_size(p) != 0) {
913        abac_credential_t *cur=NULL;
914        abac_list_foreach(p, cur,
915            abac_stack_push(ret, (void *)abac_credential_dup(cur));
916        );
917    }
918    return ret;
919}
920
921/* force a  backtrack to get next solution proof */
922abac_stack_t *abac_pl_query_again(abac_pl_t *pl)
923{
924    abac_list_t *rlist=_query_again(pl);
925    abac_stack_t *ret=_make_cred_stack(rlist);
926    return ret;
927}
928
929/* 2 types
930      acme.buys_rocket <- coyote (coyote=prin, acme.buys_rocket=role)
931        ==> isMember(coyote,role(acme,buys_rocket), L)
932      acme.buys_rocket <- acme.preferred_customer  -- NOT valid
933*/
934static abac_stack_t *_query_with_aspect(abac_pl_t *pl, abac_aspect_t* head, abac_aspect_t* tail)
935{
936    abac_stack_t *ret=NULL;
937    char *tmp=NULL;
938
939    if(0)
940        show_yap_db("DEBUG:calling within _query_with_aspect");
941
942    char *whom=NULL;
943    PROLOG(whom=abac_aspect_principal_name(head););
944
945    /* could be obj or principal */
946    char *who=NULL;
947    if(abac_aspect_is_object(tail)) {
948        who=abac_aspect_object_name(tail);
949        } else {
950            PROLOG(who=abac_aspect_principal_name(tail););
951    }
952
953    if(abac_aspect_aspect_name(tail)!=NULL) {
954        printf("fail, a.o <- b.o and a.r <- a.r query is not implemented yet !!!\n");
955        YAP_Exit(1);
956    }
957
958    if (who == NULL || whom == NULL) {
959        printf("fail, query's call got bad aspect names .. \n");
960        YAP_Exit(1);
961    }
962
963    if(debug) fprintf(stderr,"printing up the yap query ..\n");
964
965    char *pstring;
966    PROLOG(pstring=abac_aspect_aspect_param_string(head););
967
968    char *aspect=abac_aspect_type_string(head);
969    int pcnt=abac_aspect_aspect_param_cnt(head);
970    char *what=abac_aspect_aspect_name(head);
971
972    _reset_pl(pl, who, what, whom, aspect, pstring, pcnt);
973
974    abac_list_t *rlist=NULL;
975    if(pcnt)
976        rlist=_make_yap_query(pl,who,whom,aspect,abac_aspect_aspect_name(head),pstring,pcnt);
977        else
978            rlist=_make_yap_query(pl,who,whom,aspect,abac_aspect_aspect_name(head),NULL,0);
979
980    /* generate the resulting stack from a list */
981    ret=_make_cred_stack(rlist);
982    if(tmp) free(tmp);
983    if(pstring) free(pstring);
984    return ret;
985}
986
987/**
988 * Get all the credentials (attribute/issuer cert pairs) from prolog
989 * (which returns in string form)
990 */
991abac_stack_t *abac_pl_credentials(abac_pl_t *pl)
992{
993    abac_stack_t *ret=abac_verifier_dump_creds();
994    return ret;
995}
996
997abac_stack_t *abac_pl_principals(abac_pl_t *pl)
998{
999    abac_stack_t *ret=abac_verifier_dump_principals();
1000    return ret;
1001}
1002
1003/**
1004 * Make a query into prolog db
1005--role acme.preferred_customer --principal coyote
1006--role acme.prefer_customer.buy_rockets --principlal coyote
1007--oset acme.rockets -- object mrx-21
1008--oset acme.villans -- principal coyote
1009 */
1010abac_stack_t *abac_pl_query(abac_pl_t *pl, char *roleoset, char *prinobj)
1011{
1012    abac_stack_t *ret=NULL;
1013    int len=strlen(roleoset)+strlen(prinobj)+5;
1014    char* attr_string=(char *) abac_xmalloc(sizeof(char)*len);
1015    sprintf(attr_string,"%s<-%s", roleoset, prinobj);
1016
1017    if(debug)
1018        fprintf(stderr,"abac_pl_query, query string is (%s)\n",attr_string);
1019
1020    /* call into yacc parser */
1021    abac_reset_yyfptr(attr_string);
1022    abac_yy_init();
1023    int rc=yyparse();
1024    if (rc) {
1025        free(attr_string);
1026        return NULL;
1027    }
1028
1029    abac_aspect_t *head_aspect = abac_yy_get_rule_head_aspect();
1030    abac_aspect_t *tail_aspect = abac_yy_get_rule_tail_aspect();
1031
1032    ret=_query_with_aspect(pl,head_aspect,tail_aspect);
1033
1034    return ret;
1035}
1036
1037abac_stack_t *abac_pl_query_with_structure(abac_pl_t *pl, abac_aspect_t *head_aspect, abac_aspect_t *tail_aspect)
1038{
1039    abac_stack_t *ret=NULL;
1040    ret=_query_with_aspect(pl,head_aspect,tail_aspect);
1041
1042    return ret;
1043}
Note: See TracBrowser for help on using the repository browser.