source: libabac/abac.hh @ ca72963

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

1) added expanded constraint item insertion calls

  • add new abac_condition_x to support them
  • Property mode set to 100644
File size: 27.0 KB
Line 
1#ifndef __ABAC_HH__
2#define __ABAC_HH__
3
4#include <string>
5#include <vector>
6
7namespace ABAC {
8    extern "C" {
9        #include "abac.h"
10    }
11
12    static int debug=0;
13
14
15    class Role;
16    class Oset;
17
18    class Constraint {
19        public:
20            Constraint() : m_constraint(NULL) { } // do not use: here for swig
21            Constraint(abac_condition_t *constraint): 
22              m_constraint(abac_condition_dup(constraint))
23              { }
24            Constraint(const Constraint &constraint) { 
25                m_constraint =abac_condition_dup(constraint.m_constraint);
26              }
27            ~Constraint() { 
28                if(m_constraint) abac_condition_free(m_constraint);
29              }
30
31            /* range constraint */
32            Constraint(char *vartype) { m_constraint=abac_condition_create(vartype); }
33
34            /* [integer:?I[10 .. 20] */
35            /* [float:?F[0.5 .. 2.5] */
36            void add_constraint_integer_max(int val) {
37                abac_condition_add_range_integer_item(m_constraint,abac_max_item_type(),val);
38            }
39            void add_constraint_integer_min(int val) {
40                abac_condition_add_range_integer_item(m_constraint,abac_min_item_type(),val);
41            }
42            void add_constraint_integer_target(int val) {
43                abac_condition_add_range_integer_item(m_constraint,abac_target_item_type(),val);
44            }
45            void add_constraint_float_max(float val) {
46                abac_condition_add_range_float_item(m_constraint,abac_max_item_type(),val);
47            }
48            void add_constraint_float_min(float val) {
49                abac_condition_add_range_float_item(m_constraint,abac_min_item_type(),val);
50            }
51            void add_constraint_float_target(float val) {
52                abac_condition_add_range_float_item(m_constraint,abac_target_item_type(),val);
53            }
54            /* quoted string values */
55            /* [time:?T["20201101T182930"] */
56            void add_constraint_time_max(char* val) {
57                abac_condition_add_range_time_item(m_constraint,abac_max_item_type(),val);
58            }
59            void add_constraint_time_min(char* val) {
60                abac_condition_add_range_time_item(m_constraint,abac_min_item_type(),val);
61            }
62            void add_constraint_time_target(char* val) {
63                abac_condition_add_range_time_item(m_constraint,abac_target_item_type(),val);
64            }
65            /* [urn:?U["fileA","http://fileB"] -only listed range */
66            void add_constraint_urn_target(char* val) {
67                abac_condition_add_range_urn_item(m_constraint,val);
68            }
69            /* [string:?S["abc",'efg',"hij"] -only listed range */
70            void add_constraint_string_target(char* val) {
71                abac_condition_add_range_string_item(m_constraint,val);
72            }
73            /*[boolean:?B['true']] */
74            void add_constraint_boolean_target(char* val) {
75                abac_condition_add_range_boolean_item(m_constraint,val);
76            }
77           
78           
79            /* [oset:?O[{oset-constraint}] */
80            /* [role:?R[{role-constraint}] */
81            /* [urn:?F[keyid:$alpha_keyid].oset:documents([string:?P])] */
82            /* role constraint */
83            Constraint(Role *role);
84            /* oset constraint */
85            Constraint(Oset *oset);
86            char *string() const { 
87                return abac_condition_string(m_constraint);
88              }
89            char *typed_string() const { 
90                return abac_condition_typed_string(m_constraint);
91              }
92            abac_condition_t *constraint()
93              { return m_constraint; }
94        private:
95            abac_condition_t *m_constraint;
96    };
97
98    /* XXX need to track the principal [keyid:alice] so can generate
99       the id_type_clause within attribute clause */
100    class DataTerm {
101        public:
102            DataTerm() : m_term(NULL) { } // do not use: here for swig
103            DataTerm(abac_term_t *term) { 
104                m_term=abac_term_dup(term);
105                abac_condition_t *constraint=abac_term_constraint(m_term);
106                if(constraint) m_cond=new Constraint(constraint);
107                  else m_cond=NULL;
108              }
109            DataTerm(const DataTerm &term) { 
110                m_term =abac_term_dup(term.m_term);
111                abac_condition_t *constraint=abac_term_constraint(m_term);
112                if(constraint) m_cond=new Constraint(constraint);
113                  else m_cond=NULL;
114              }
115            ~DataTerm() { 
116                if(m_term) abac_term_free(m_term);
117                if(m_cond) free(m_cond);
118              }
119            /* this is for named principal data term */
120            DataTerm(char *sha) {
121                if(debug) printf("adding a Dataterm named principal(%s)\n",sha);
122                int isnamed=1;
123                int type=e_TERM_PRINCIPAL;
124                m_term=abac_term_named_create(type,sha);
125            }
126            /* can be an a variable data term or a specific value */
127            DataTerm(char* typenm, char *name, Constraint *cond=NULL) {
128                int type=abac_verify_term_type(typenm);
129                if(debug) printf("adding a Dataterm (%s)\n",name);
130                if(type==ABAC_TERM_FAIL)
131                  abac_errx(1, "DataTerm, fail to create the term");
132                if(cond) {
133                  m_cond=cond;
134                  m_term=abac_term_create(type,name,cond->constraint());
135                  } else {
136                      m_cond=NULL;
137                      m_term=abac_term_create(type,name,NULL);
138                }
139              }
140            char *string() const { 
141                return abac_term_string(m_term);
142              }
143            char *typed_string() const { 
144                return abac_term_typed_string(m_term);
145              }
146            bool is_time() const {
147                return abac_term_is_time_type(m_term);
148              }
149            bool is_string() const {
150                return abac_term_is_string_type(m_term);
151              }
152            bool is_urn() const {
153                return abac_term_is_urn_type(m_term);
154              }
155            bool is_integer() const {
156                return abac_term_is_integer_type(m_term);
157              }
158/* Add a constraint to this term. */
159            int add_constraint(Constraint& cond) {
160                m_cond=new Constraint(cond);
161                abac_term_add_constraint(m_term, m_cond->constraint());
162              }
163            int type() {
164                abac_term_type(m_term);
165              }
166            char *name() {
167                return abac_term_name(m_term);
168              }
169            char *value() {
170/* ??? value XXX */
171              }
172            Constraint *constraint() {
173                return m_cond;
174              }
175            abac_term_t *term() {
176                return m_term;
177              }
178
179        private:
180            abac_term_t *m_term;
181            Constraint *m_cond;
182    };
183
184
185    class Role {
186        public:
187            Role() : m_role(NULL) { } // do not use: here for swig
188            Role(abac_aspect_t *role): m_role(abac_aspect_dup(role))
189              { }
190            Role(char *principal_name) : 
191               m_role(abac_aspect_role_principal_create(principal_name)) 
192              { }
193            Role(char *principal_name, char *role_name) : 
194               m_role(abac_aspect_role_create(principal_name, role_name)) 
195              { }
196            Role(const Role &role) { 
197                m_role = abac_aspect_dup(role.m_role);
198              }
199            ~Role() { 
200                if (m_role) abac_aspect_free(m_role);
201              }
202            bool is_principal() const { 
203                return abac_aspect_is_principal(m_role); 
204              }
205            bool is_linking() const { 
206                return abac_aspect_is_linking(m_role); 
207              }
208            char *string() const { 
209                return abac_aspect_string(m_role);
210              }
211            char *typed_string() {
212                char* string=abac_aspect_typed_string(m_role);
213                return string;
214              }
215            char *linked_role() const { 
216                return abac_aspect_linked_role_name(m_role);
217              }
218            char *role_name() const { 
219                return abac_aspect_aspect_name(m_role);
220              }
221            char *principal() const { 
222                return abac_aspect_principal_name(m_role);
223              }
224/* Add a data term to this name. */
225            int add_data_term(DataTerm& d) {
226                abac_aspect_add_param(m_role, d.term());
227                return 1;
228              }
229/* Return the DataTerms bound to this name.  If the name is returned
230   in a proof, these will all have values. */
231            std::vector<DataTerm> get_data_terms(bool &success) {
232                abac_term_t **terms, **end;
233                int i;
234                terms = abac_param_list_vectorize(abac_aspect_aspect_params(m_role));
235                for (i = 0; terms[i] != NULL; ++i)
236                    ;
237                end = &terms[i];
238                std::vector<DataTerm> dataterms = std::vector<DataTerm>(terms, end);
239                abac_terms_free(terms);
240                success=1;
241                return dataterms;
242              }
243            int add_linking_data_term(DataTerm& d) {
244                abac_aspect_add_linked_param(m_role, d.term());
245                return 1;
246              }
247            std::vector<DataTerm> get_linked_data_terms(bool &success) {
248                abac_term_t **terms, **end;
249                int i;
250                terms = abac_param_list_vectorize(abac_aspect_linked_role_params(m_role));
251                for (i = 0; terms[i] != NULL; ++i)
252                    ;
253                end = &terms[i];
254                std::vector<DataTerm> dataterms = std::vector<DataTerm>(terms, end);
255                abac_terms_free(terms);
256                success=1;
257                return dataterms;
258              }
259            abac_aspect_t *role() {return m_role;}
260        private:
261            abac_aspect_t *m_role;
262    };
263
264    class Oset {
265        public:
266            Oset() : m_oset(NULL) { } // do not use: here for swig
267            Oset(abac_aspect_t *oset): m_oset(abac_aspect_dup(oset)) 
268              { }
269            Oset(char *oset_name) : m_oset(abac_aspect_role_principal_create(oset_name)) 
270              { }
271            Oset(char *principal_name, char *oset_name) : 
272               m_oset(abac_aspect_oset_create(principal_name, oset_name)) 
273              { }
274            Oset(const Oset &oset) { 
275                m_oset =abac_aspect_dup(oset.m_oset);
276              }
277            ~Oset() { 
278                if(m_oset) abac_aspect_free(m_oset);
279              }
280            bool is_object() const { 
281                return abac_aspect_is_object(m_oset); 
282              }
283            bool is_principal() const { 
284                return abac_aspect_is_principal(m_oset); 
285              }
286            bool is_linking() const { 
287                return abac_aspect_is_linking(m_oset); 
288              }
289            char *string() const { 
290                return abac_aspect_string(m_oset);
291              }
292            char *typed_string() {
293                char* string=abac_aspect_typed_string(m_oset);
294                return string;
295              }
296            char *linked_role() const { 
297                return abac_aspect_linked_role_name(m_oset);
298              }
299            char *oset_name() const { 
300                return abac_aspect_aspect_name(m_oset);
301              }
302            char *principal() const { 
303                return abac_aspect_principal_name(m_oset);
304              }
305            char *object() const { 
306                return abac_aspect_object_name(m_oset);
307              }
308/* Add a data term to this name. */
309            int add_data_term(DataTerm& d) {
310                abac_aspect_add_param(m_oset, d.term()); 
311                return 1;
312              }
313/* Return the DataTerms bound to this name.  If the name is returned
314   in a proof, these will all have values. */
315            std::vector<DataTerm> get_data_terms(bool &success) {
316                abac_term_t **terms, **end;
317                int i;
318                terms = abac_param_list_vectorize(abac_aspect_aspect_params(m_oset));
319                for (i = 0; terms[i] != NULL; ++i)
320                    ;
321                end = &terms[i];
322                std::vector<DataTerm> dataterms = std::vector<DataTerm>(terms, end);
323                abac_terms_free(terms);
324                success=1;
325                return dataterms;
326              }
327            int add_linking_data_term(DataTerm& d) {
328                abac_aspect_add_linked_param(m_oset, d.term());
329                return 1;
330              }
331            std::vector<DataTerm> get_linked_data_terms(bool &success) {
332                abac_term_t **terms, **end;
333                int i;
334                terms = abac_param_list_vectorize(abac_aspect_linked_role_params(m_oset));
335                for (i = 0; terms[i] != NULL; ++i)
336                    ;
337                end = &terms[i];
338                std::vector<DataTerm> dataterms = std::vector<DataTerm>(terms, end);
339                abac_terms_free(terms);
340                success=1;
341                return dataterms;
342              }
343            abac_aspect_t *oset() {return m_oset;}
344        private:
345            abac_aspect_t *m_oset;
346    };
347
348
349    class ID {
350        public:
351            ID() : m_id(NULL) { } // do not use: here for swig
352            ID(abac_id_t *id): m_id(abac_id_dup(id)) 
353              { }
354            ID(const ID &id) { m_id =abac_id_dup(id.m_id); }
355            ~ID() { if(m_id) abac_id_free(m_id); }
356
357/* load an ID cert from a file
358Will throw an exception if the cert cannot be loaded */
359            ID(char *filename) {
360                m_id=abac_id_from_file(filename); 
361                if(m_id==NULL)
362                  abac_errx(1, "Id creation from filename failed");
363              }
364/* generates a new ID with the supplied CN and validity period
365   - CN must be alphanumeric and begin with a letter
366   - validity must be at least one second
367   Will throw an exception if either of the above is violated */
368            ID(char *cn, int validity) {
369                int rt=abac_id_generate(&m_id, cn, validity);
370                if(rt != ABAC_ID_SUCCESS) 
371                  abac_errx(1, "Id creation failed");
372              }
373/* loads the private key associated with the cert
374   will throw an exception if the key cannot be loaded */
375            void load_privkey(char *filename) {
376                int rt=abac_id_load_privkey(m_id, filename);
377                if(rt != 1) 
378                  abac_errx(1, "Failed to load private key");
379              }
380            abac_id_t *id() { return m_id; }
381
382/* returns the SHA1 keyid of the cert */
383            char *keyid() { return abac_id_keyid(m_id); }
384/* returns the CN (the parameter passed to the constructor or the
385   CN of the cert). */
386            char *name() { return abac_id_cn(m_id); }
387/* returns true if the ID has an associated private key */
388            bool has_privkey() {
389                return abac_id_has_privkey(m_id);
390              }
391/* writes a PEM-encoded cert to the file handle */
392            void write_cert(FILE *out) {
393                abac_id_write_cert(m_id, out); 
394              }
395/* writes a PEM-encoded cert to a file named out */
396            void write_cert(char *filename) {
397                FILE *out = fopen(filename, "w");
398                write_cert(out);
399                fclose(out);
400              }
401/* writes a PEM-encoded private key to the file handle
402   throws an exception if no private key is loaded */
403            void write_privkey(FILE *out) {
404                if(!has_privkey())
405                    abac_errx(1, "No privkey to write");
406                abac_id_write_privkey(m_id, out);
407              }
408/* writes a PEM-encoded private key a file named out
409   throws an exception if no private key is loaded */
410            void write_privkey(char *filename) {
411                FILE *out = fopen(filename, "w");
412                write_privkey(out);
413                fclose(out);
414              }
415/* returns a DER-encoded binary representation of the X.509 ID cert
416   associated with this ID.
417   can be passed to libabac's Context::load_id_chunk() */
418            abac_chunk_t cert_chunk() {
419                return abac_id_cert_chunk(m_id);
420              }
421        public:
422            abac_id_t *m_id;
423    };
424
425
426/* N.B., The way you use this class is by instantiating the object, adding
427   subjects to it, and then baking it. Only once it's baked can you access the
428   X.509 cert. Once it's been baked you can no longer add subjects to it. */
429    class Attribute {
430        public:
431            Attribute() : m_attr(NULL) { } // do not use: here for swig
432            Attribute(abac_attribute_t *attr): m_attr(abac_attribute_dup(attr)) 
433              { }
434            Attribute(abac_credential_t *cred) {
435                m_attr=abac_attribute_dup(abac_credential_attribute(cred));
436              }
437            Attribute(const Attribute &id) { 
438                m_attr =abac_attribute_dup(id.m_attr);
439              }
440            ~Attribute() { 
441                if(m_attr) abac_attribute_free(m_attr);
442              }
443/* Create an object to be signed by the given issuer with the given role
444   and validity period
445   An exception will be thrown if:
446     - the issuer has no private key
447     - the Head is invalid
448     - the validity period is invalid (must be >= 1 second) */
449            Attribute(Role& head, int validity) {
450                int rt=abac_attribute_create(&m_attr, head.role(), NULL, validity);
451                if(rt!=ABAC_ATTRIBUTE_SUCCESS)
452                    abac_errx(1, "attribute(role), unable to make an attribute");
453              }
454            Attribute(Oset& head, int validity) {
455                int rt=abac_attribute_create(&m_attr, head.oset(), NULL, validity);
456                if(rt!=ABAC_ATTRIBUTE_SUCCESS)
457                    abac_errx(1, "attribute(oset), unable to make an attribute");
458              }
459            bool add_tail(Role& tail) {
460                if(abac_attribute_add_tail(m_attr, tail.role()))
461                    return 1;
462                    else return 0;
463              }
464            bool add_tail(Oset& tail) {
465                if(abac_attribute_add_tail(m_attr, tail.oset()))
466                    return 1;
467                    else return 0;
468              }
469            char *head_string() {
470                abac_aspect_t *head=abac_attribute_head(m_attr);
471                char *string=abac_aspect_string(head);
472                return string;
473              }
474            char *tail_string() {
475                abac_aspect_t *tail=abac_attribute_tail(m_attr);
476                char *string=abac_aspect_string(tail);
477                return string;
478              }
479            char *head_typed_string() {
480                abac_aspect_t *head=abac_attribute_head(m_attr);
481                char *string=abac_aspect_typed_string(head);
482                return string;
483              }
484            char *tail_typed_string() {
485                abac_aspect_t *tail=abac_attribute_tail(m_attr);
486                char *string=abac_aspect_typed_string(tail);
487                return string;
488              }
489            char *string() {
490                char *head=head_string();
491                char *tail=tail_string();
492                if(head==NULL || tail==NULL)
493                    abac_errx(1, "attribute string, head and tail can not be NULL");
494                char *tmp=NULL;
495                asprintf(&tmp,"%s<-%s",head,tail);
496                return tmp;
497              }
498            char *typed_string() {
499                char *head=head_typed_string();
500                char *tail=tail_typed_string();
501                if(head==NULL || tail==NULL)
502                    abac_errx(1, "attribute string, head and tail can not be NULL");
503                char *tmp=NULL;
504                asprintf(&tmp,"%s<-%s",head,tail);
505                return tmp;
506              }
507            const Role &role_head() {
508                abac_aspect_t *head=abac_attribute_head(m_attr);
509                static Role role=Role(head);
510                return role;
511              }
512            const Oset &oset_head() {
513                abac_aspect_t *head=abac_attribute_tail(m_attr);
514                static Oset oset=Oset(head);
515                return oset;
516              }
517            std::vector<Role> role_tails(bool &success) {
518                abac_aspect_t **tails, **end;
519                int i;
520                tails = abac_attribute_tail_vectorized(m_attr);
521                for (i = 0; tails[i] != NULL; ++i)
522                    ;
523                end = &tails[i];
524                std::vector<Role> roles = std::vector<Role>(tails, end);
525                abac_aspects_free(tails);
526                success=1;
527                return roles;
528              }
529            std::vector<Oset> oset_tails(bool &success) {
530                abac_aspect_t **tails, **end;
531                int i;
532                tails = abac_attribute_tail_vectorized(m_attr);
533                for (i = 0; tails[i] != NULL; ++i)
534                    ;
535                end = &tails[i];
536                std::vector<Oset> osets = std::vector<Oset>(tails, end);
537                success=1;
538                abac_aspects_free(tails);
539                return osets;
540              }
541            abac_attribute_t *attribute() { return m_attr; }
542
543/* Generate the cert. Call this after you've added subjects to your cert.
544   This returns false if there are no subjects
545   This will throw an exception if the cert's already been baked. */
546            bool bake() {
547                /* can not bake in ABAC_CN mode */
548                if(USE("ABAC_CN"))
549                    abac_errx(1, "bake, can not bake the cert with env(ABAC_CN) set");
550                int rt=abac_attribute_bake(m_attr);
551                if(rt!=1)
552                    abac_errx(1, "bake, can not bake the cert");
553              }
554/* Returns true iff the cert has been baked. */
555            bool baked() {
556                return abac_attribute_baked(m_attr);
557              }
558/* Write the DER-encoded X.509 attribute cert to the open file handle
559   Throws an exception if the cert isn't baked */
560            void write_cert(FILE *out) {
561                int rt= abac_attribute_write(m_attr,out);
562                if(!rt)
563                    abac_errx(1, "write, cert is not baked");
564              }
565/* Write the DER-encoded X.509 attribute cert to a file named out
566   Throws an exception if the cert isn't baked */
567            void write_cert(char *filename) {
568                FILE *out = fopen(filename, "w");
569                printf("writing to %s\n", filename);
570                write_cert(out);
571                printf("done writing to %s\n", filename);
572                fclose(out);
573              }
574/* returns a DER-encoded binary representation of the X.509 attribute
575   cert associated with this cert
576   Throws an exception if the cert isn't baked
577   the chunk can be passed to libabac's Context::load_attribute_chunk() */
578            abac_chunk_t cert_chunk() {
579                return abac_attribute_cert_chunk(m_attr);
580              }
581/* generate yap clauses and injected into db */
582            int consume() {
583              /* attribute needs to be baked */ 
584                if(!baked()) {
585                    return ABAC_ATTRIBUTE_FAIL;
586                }
587              }
588      private:
589            abac_attribute_t *m_attr;
590     };
591
592
593    class Context {
594        public:
595            Context() { m_ctx = abac_context_new(); m_abac_version=strdup("1.0"); }
596            Context(const Context &context) { 
597                m_ctx = abac_context_dup(context.m_ctx);
598                m_abac_version=strdup(context.m_abac_version);
599              }
600            ~Context() { 
601                abac_context_free(m_ctx);
602                if(m_abac_version) free(m_abac_version);
603              }
604
605/* load an identity certificate, returns:
606      ABAC_CERT_SUCCESS   successfully loaded
607      ABAC_CERT_INVALID   invalid certificate (or file not found)
608      ABAC_CERT_BAD_SIG   invalid signature */
609            void dump_yap() {
610                show_yap_db("dump_yap");
611              }
612            int load_id(ABAC::ID& id) {
613                return abac_context_load_id_id(m_ctx, id.id());
614              }
615            int load_id_file(char *filename, char *keyfilename) {
616                return abac_context_load_id_file(m_ctx, filename, keyfilename);
617              }
618            int load_id_chunk(abac_chunk_t cert) { 
619                return abac_context_load_id_chunk(m_ctx, cert);
620              }
621/* load an attribute certificate, returns the same values as above
622   * additionally can return ABAC_CERT_MISSING_ISSUER if the issuer
623   certificate has not been loaded */
624            int load_attribute(ABAC::Attribute& a) {
625                return abac_context_load_attribute_attribute(m_ctx, a.attribute());
626              }
627            int load_attribute_file(char *filename) { 
628                return abac_context_load_attribute_file(m_ctx, filename);
629              }
630            int load_attribute_chunk(abac_chunk_t cert) {
631                return abac_context_load_attribute_chunk(m_ctx, cert);
632              }
633/* load a directory full of certificates:
634   first: ${path}/*_ID.{der,pem} as identity certificates
635   then: ${path}/*_attr.der as attribute certificates */
636            void load_directory(char *path) {
637                abac_context_load_directory(m_ctx, path);
638              }
639/* run the query:
640       role <-?- principal
641   returns true/false in success
642   returns a proof upon success, partial proof on failure */
643            std::vector<Attribute> query(char *role, char *principal, bool &success) {
644                 abac_credential_t **creds, **end;
645                 int i, success_int;
646
647                 creds = abac_context_query(m_ctx, role, principal, &success_int);
648                 success = success_int;
649
650                 for (i = 0; creds[i] != NULL; ++i)
651                    ;
652
653                 end = &creds[i];
654                 std::vector<Attribute> attributes = std::vector<Attribute>(creds, end);
655                 if(debug) printf("rules, got (%d)\n", i);
656
657                 abac_context_credentials_free(creds);
658
659                 return attributes;
660              }
661
662/* returns a vector of all the credentials loaded in the context */
663            std::vector<Attribute> context_credentials(bool &success) {
664                abac_credential_t **creds, **end;
665                int i;
666                success = 1;
667
668                creds = abac_context_credentials(m_ctx);
669                for (i = 0; creds[i] != NULL; ++i)
670                    ;
671
672                end = &creds[i];
673                std::vector<Attribute> attributes = std::vector<Attribute>(creds, end);
674                if(debug) printf("credentials, got (%d)\n", i);
675
676                abac_context_credentials_free(creds);
677                if(debug) show_yap_db("calling from context_credentials");
678                return attributes;
679              }
680           
681            char *version() const { return m_abac_version; }
682
683        private:
684            abac_context_t *m_ctx;
685            char *m_abac_version;
686    };
687
688    Constraint::Constraint(Role *role)
689    { m_constraint=abac_condition_create_from_aspect(role->role()); }
690    Constraint::Constraint(Oset *oset)
691    { m_constraint=abac_condition_create_from_aspect(oset->oset()); }
692}
693
694#endif /* __ABAC_HH__ */
Note: See TracBrowser for help on using the repository browser.