/* acl.c - General Access Control routines */
static char *rcsid
= "$Header: /f/osi/dsap/common/RCS/acl.c,v 7.4 91/02/22 09:18:05 mrose Interim $";
* $Header: /f/osi/dsap/common/RCS/acl.c,v 7.4 91/02/22 09:18:05 mrose Interim $
* Revision 7.4 91/02/22 09:18:05 mrose
* Revision 7.3 90/11/20 15:29:09 mrose
* Revision 7.2 90/10/17 11:40:47 mrose
* Revision 7.1 89/12/19 16:19:09 mrose
* Revision 7.0 89/11/23 21:41:28 mrose
* Acquisition, use, and distribution of this module and related
* materials are subject to the restrictions of a license agreement.
* Consult the Preface in the User's Manual for the full terms of
#include "quipu/syntaxes.h"
static struct acl_info
* defaultacl
= (struct acl_info
*) NULL
;
register struct acl
* aclptr
;
acl_info_free (aclptr
->ac_child
);
acl_info_free (aclptr
->ac_entry
);
acl_info_free (aclptr
->ac_default
);
static acl_attr_free (aclptr
)
register struct acl
* aclptr
;
register struct acl_attr
* ptr
;
register struct acl_attr
* next
;
for (ptr
=aclptr
->ac_attributes
; ptr
!=NULLACL_ATTR
; ptr
=next
) {
oid_seq_free (ptr
->aa_types
);
if (ptr
->aa_acl
!= aclptr
->ac_default
)
acl_info_free (ptr
->aa_acl
);
static acl_info_free (aclptr
)
register struct acl_info
* aclptr
;
register struct acl_info
* ptr
;
register struct acl_info
* next
;
if (test_acl_default(aclptr
) == OK
)
for (ptr
=aclptr
; ptr
!=NULLACL_INFO
; ptr
=next
) {
dn_seq_free (ptr
->acl_name
);
if((acl1
== NULLACL
) && (acl2
== NULLACL
))
if((i
= acl_info_cmp(acl1
->ac_child
, acl2
->ac_child
)) != 0)
if((i
= acl_info_cmp(acl1
->ac_entry
, acl2
->ac_entry
)) != 0)
if((i
= acl_info_cmp(acl1
->ac_default
, acl2
->ac_default
)) != 0)
if((i
= acl_attr_cmp(acl1
->ac_attributes
, acl2
->ac_attributes
)) != 0)
static int acl_attr_cmp (acl_attr1
, acl_attr2
)
struct acl_attr
* acl_attr1
;
struct acl_attr
* acl_attr2
;
if((acl_attr1
== NULLACL_ATTR
) && (acl_attr2
== NULLACL_ATTR
))
if(acl_attr1
== NULLACL_ATTR
)
if(acl_attr2
== NULLACL_ATTR
)
for(aa1
=acl_attr1
; aa1
!= NULLACL_ATTR
; aa1
=aa1
->aa_next
)
for(aa2
=acl_attr2
; aa2
!= NULLACL_ATTR
; aa2
=aa2
->aa_next
)
if(acl_attr_comp_cmp(aa1
, aa2
) == 0)
for(aa2
=acl_attr2
; aa2
!= NULLACL_ATTR
; aa2
=aa2
->aa_next
)
for(aa1
=acl_attr1
; aa1
!= NULLACL_ATTR
; aa1
=aa1
->aa_next
)
if(acl_attr_comp_cmp(aa1
, aa2
) == 0)
static int acl_attr_comp_cmp (acl_attr1
, acl_attr2
)
struct acl_attr
* acl_attr1
;
struct acl_attr
* acl_attr2
;
if((acl_attr1
== NULLACL_ATTR
) && (acl_attr2
== NULLACL_ATTR
))
if(acl_attr1
== NULLACL_ATTR
)
if(acl_attr2
== NULLACL_ATTR
)
if((i
= oid_seq_cmp(acl_attr1
->aa_types
, acl_attr2
->aa_types
)) != 0)
if((i
= acl_info_cmp(acl_attr1
->aa_acl
, acl_attr2
->aa_acl
)) != 0)
static int acl_info_cmp (acl_info1
, acl_info2
)
struct acl_info
* acl_info1
;
struct acl_info
* acl_info2
;
if((acl_info1
== NULLACL_INFO
) && (acl_info2
== NULLACL_INFO
))
if(acl_info1
== NULLACL_INFO
)
if (test_acl_default(acl_info2
) == OK
)
if(acl_info2
== NULLACL_INFO
)
if (test_acl_default(acl_info1
) == OK
)
for(ai1
=acl_info1
; ai1
!= NULLACL_INFO
; ai1
=ai1
->acl_next
)
for(ai2
=acl_info2
; ai2
!= NULLACL_INFO
; ai2
=ai2
->acl_next
)
if(acl_info_comp_cmp(ai1
, ai2
) == 0)
for(ai2
=acl_info2
; ai2
!= NULLACL_INFO
; ai2
=ai2
->acl_next
)
for(ai1
=acl_info1
; ai1
!= NULLACL_INFO
; ai1
=ai1
->acl_next
)
if(acl_info_comp_cmp(ai2
, ai1
) == 0)
static int acl_info_comp_cmp (acl_info1
, acl_info2
)
struct acl_info
* acl_info1
;
struct acl_info
* acl_info2
;
if((acl_info1
== NULLACL_INFO
) && (acl_info2
== NULLACL_INFO
))
if(acl_info1
== NULLACL_INFO
)
if(acl_info2
== NULLACL_INFO
)
if(acl_info1
->acl_categories
> acl_info2
->acl_categories
)
if(acl_info2
->acl_categories
> acl_info1
->acl_categories
)
if(acl_info1
->acl_selector_type
> acl_info2
->acl_selector_type
)
if(acl_info2
->acl_selector_type
> acl_info1
->acl_selector_type
)
if((i
= dn_seq_cmp(acl_info1
->acl_name
, acl_info2
->acl_name
)) != 0)
struct acl_info
* acl_info_new (x
,y
,z
)
register struct acl_info
* ptr
;
acl_info_fill (ptr
,x
,y
,z
);
ptr
->acl_next
= NULLACL_INFO
;
static struct acl
* acl_cpy (aclptr
)
register struct acl
* aclptr
;
register struct acl
* ptr
;
ptr
= (struct acl
*) smalloc (sizeof (struct acl
));
ptr
->ac_child
= acl_info_cpy (aclptr
->ac_child
);
ptr
->ac_entry
= acl_info_cpy (aclptr
->ac_entry
);
ptr
->ac_default
= acl_info_cpy (aclptr
->ac_default
);
ptr
->ac_attributes
= acl_attr_cpy (aclptr
->ac_attributes
,ptr
->ac_default
);
static struct acl
* acl_decode (pe
)
if (decode_Quipu_ACLSyntax(pe
,1,NULLIP
,NULLVP
,&aclptr
) == NOTOK
) {
return (struct acl
*) NULL
;
static struct acl_attr
* acl_attr_cpy (aclptr
,dflt
)
struct acl_attr
* aclptr
;
register struct acl_attr
* ptr
;
register struct acl_attr
* ptr2
;
register struct acl_attr
* result
= NULLACL_ATTR
;
for (ptr
=aclptr
; ptr
!=NULLACL_ATTR
; ptr
=ptr
->aa_next
) {
ptr2
= acl_attr_alloc ();
ptr2
->aa_types
= oid_seq_cpy (ptr
->aa_types
);
ptr2
->aa_acl
= acl_info_cpy (ptr
->aa_acl
);
static struct acl_info
* acl_info_cpy (aclptr
)
struct acl_info
* aclptr
;
register struct acl_info
* ptr
;
register struct acl_info
* ptr2
;
register struct acl_info
* result
= NULLACL_INFO
;
if (test_acl_default(aclptr
) == OK
) {
for (ptr
=aclptr
; ptr
!=NULLACL_INFO
; ptr
=ptr
->acl_next
) {
ptr2
-> acl_next
= result
;
result
->acl_categories
= ptr
->acl_categories
;
result
->acl_selector_type
= ptr
->acl_selector_type
;
result
->acl_name
= dn_seq_cpy (ptr
->acl_name
);
struct acl_info
* acl_default ()
defaultacl
= acl_info_alloc ();
set_default_acl(defaultacl
);
struct acl_info
* ai_ptr
;
/* default - others # read & self # write */
ai_ptr
->acl_categories
= ACL_READ
;
ai_ptr
->acl_selector_type
= ACL_OTHER
;
ai_ptr
->acl_name
= NULLDNSEQ
;
ai_ptr
->acl_next
= acl_info_alloc();
ai_ptr
->acl_next
->acl_categories
= ACL_WRITE
;
ai_ptr
->acl_next
->acl_selector_type
= ACL_ENTRY
;
ai_ptr
->acl_next
->acl_next
= NULLACL_INFO
;
ai_ptr
->acl_next
->acl_name
= NULLDNSEQ
;
if ((a
== NULLACL_INFO
) || (a
== defaultacl
))
if (a
->acl_categories
!= ACL_READ
) {
if (a
->acl_categories
!= ACL_WRITE
)
if (a
->acl_selector_type
!= ACL_ENTRY
)
if (a
->acl_next
== NULLACL_INFO
)
if (a
->acl_next
->acl_categories
!= ACL_READ
)
if (a
->acl_next
->acl_selector_type
!= ACL_OTHER
)
if (a
->acl_next
->acl_next
!= NULLACL_INFO
)
} if (a
->acl_selector_type
!= ACL_OTHER
)
if (a
->acl_next
== NULLACL_INFO
)
if (a
->acl_next
->acl_categories
!= ACL_WRITE
)
if (a
->acl_next
->acl_selector_type
!= ACL_ENTRY
)
if (a
->acl_next
->acl_next
!= NULLACL_INFO
)
static struct acl_attr
* acl_attr_merge (a
,b
)
for (c
=a
; c
!= NULLACL_ATTR
; c
=c
->aa_next
) {
if (oid_seq_cmp (c
->aa_types
,b
->aa_types
) == 0) {
b
->aa_acl
->acl_next
= c
->aa_acl
;
struct acl
* aclptr
, aclstr
;
struct acl
* newacl
, *str2acl_aux();
bzero ((char*)&aclstr
,sizeof(struct acl
));
if ((newacl
= str2acl_aux(str
,&aclstr
)) == NULLACL
)
aclptr
= (struct acl
*) a
->avseq_av
.av_struct
;
if (newacl
->ac_child
!= NULLACL_INFO
) {
newacl
->ac_child
->acl_next
= aclptr
->ac_child
;
aclptr
->ac_child
= newacl
->ac_child
;
if (newacl
->ac_entry
!= NULLACL_INFO
) {
newacl
->ac_entry
->acl_next
= aclptr
->ac_entry
;
aclptr
->ac_entry
= newacl
->ac_entry
;
if (newacl
->ac_default
!= NULLACL_INFO
) {
newacl
->ac_default
->acl_next
= aclptr
->ac_default
;
aclptr
->ac_default
= newacl
->ac_default
;
if (newacl
->ac_attributes
!= NULLACL_ATTR
)
aclptr
->ac_attributes
= acl_attr_merge (aclptr
->ac_attributes
,newacl
->ac_attributes
);
static char * acl_cat
[] = {
static char * acl_sel
[] = {
"ACL SELECTOR INTERNAL ERROR",
static acl_info_comp_print (ps
,aclptr
,format
)
register struct acl_info
* aclptr
;
switch (aclptr
->acl_selector_type
) {
ps_printf (ps
,"%s ( ",acl_sel
[aclptr
->acl_selector_type
]);
dn_seq_print (ps
,aclptr
->acl_name
,format
);
ps_printf (ps
," ) can %s ",acl_cat
[aclptr
->acl_categories
]);
ps_printf (ps
,"%s can %s ", acl_sel
[aclptr
->acl_selector_type
], acl_cat
[aclptr
->acl_categories
]);
switch (aclptr
->acl_selector_type
) {
ps_printf (ps
,"%s # ",acl_sel
[aclptr
->acl_selector_type
]);
dn_seq_print (ps
,aclptr
->acl_name
,format
);
ps_printf (ps
," # %s ",acl_cat
[aclptr
->acl_categories
]);
ps_printf (ps
,"%s # %s ", acl_sel
[aclptr
->acl_selector_type
], acl_cat
[aclptr
->acl_categories
]);
static acl_info_print (ps
,aclptr
,format
,acl_type
,oidseq
)
struct acl_info
* aclptr
;
register struct acl_info
* ptr
;
if (test_acl_default(aclptr
) == OK
)
for (ptr
=aclptr
; ptr
!=NULLACL_INFO
; ptr
=ptr
->acl_next
) {
ps_print (ps
," &\\\n\t");
ps_print (ps
,"\n\t\t\t");
acl_info_comp_print (ps
,ptr
,format
);
if (oidseq
!= NULLOIDSEQ
) {
ps_printf (ps
,"the %s: ",acl_type
);
oid_seq_print (ps
,oidseq
,format
) ;
ps_printf (ps
,"the %s",acl_type
);
ps_printf (ps
,"# %s",acl_type
);
if (oidseq
!= NULLOIDSEQ
) {
oid_seq_print (ps
,oidseq
,format
) ;
static acl_print (ps
,aclptr
,format
)
register struct acl_attr
* ptr
;
if (test_acl_default(aclptr
->ac_child
) != OK
) {
acl_info_print (ps
,aclptr
->ac_child
,format
, "child", NULLOIDSEQ
);
if (test_acl_default(aclptr
->ac_entry
) != OK
) {
ps_print (ps
," &\\\n\t");
ps_print (ps
,"\n\t\t\t");
acl_info_print (ps
,aclptr
->ac_entry
,format
,"entry", NULLOIDSEQ
);
if (test_acl_default(aclptr
->ac_default
) != OK
) {
ps_print (ps
," &\\\n\t");
ps_print (ps
,"\n\t\t\t");
acl_info_print (ps
,aclptr
->ac_default
,format
,"default", NULLOIDSEQ
);
for (ptr
=aclptr
->ac_attributes
; ptr
!=NULLACL_ATTR
; ptr
=ptr
->aa_next
) {
if (test_acl_default(ptr
->aa_acl
) == OK
)
if (acl_info_cmp(ptr
->aa_acl
,aclptr
->ac_default
) == 0)
ps_print (ps
," &\\\n\t");
ps_print (ps
,"\n\t\t\t");
acl_info_print (ps
,ptr
->aa_acl
,format
, "attributes", ptr
->aa_types
);
ps_print (ps
,"(default)");
static struct acl_info
* str2acl_info (strptr
)
struct dn_seq
* dnseq
= NULLDNSEQ
;
static CMD_TABLE cmd_what
[] = {
static CMD_TABLE cmd_class
[] = {
if ((ptr
= index (*strptr
,'#')) == 0) {
parse_error ("# missing in acl syntax '%s'",*strptr
);
parse_error ("acl class missing before first '#' ",NULLCP
);
if (( class = cmd_srch (*strptr
,cmd_class
)) == -1) {
parse_error ("unknown acl class '%s'",*strptr
);
*strptr
= SkipSpace(ptr
);
if ((ptr
= index (*strptr
,'#')) == 0) {
parse_error ("2nd # missing in acl syntax ",NULLCP
);
if ( (class == ACL_GROUP
) || (class == ACL_PREFIX
) ) { /* group or prefix */
parse_error ("acl class missing before first '#' ",NULLCP
);
if ((dnseq
= str2dnseq (*strptr
)) == NULLDNSEQ
)
*strptr
= SkipSpace(ptr
);
if ((ptr
= index (*strptr
,'#')) == 0) {
parse_error ("3rd # missing in acl syntax ",NULLCP
);
parse_error ("acl level missing",NULLCP
);
if (( what
= cmd_srch (*strptr
,cmd_what
)) == -1) {
parse_error ("unknown level '%s'",*strptr
);
*strptr
= SkipSpace(ptr
);
return (acl_info_new (what
,class,dnseq
));
static struct acl
* str2acl_aux (str
,the_acl
)
char * save
, *ptr
, val
= 0;
struct oid_seq
* str2oidseq();
static CMD_TABLE cmd_who
[] = {
if ((info
= str2acl_info (&str
)) == NULLACL_INFO
)
return ( (struct acl
*) NULL
);
/* this has left us with "string [#oidlist] [#]" */
if ((ptr
= index (str
,'#')) != 0) {
struct acl_attr
* at_acl
;
if (lexequ (str
,"attributes") != 0) {
parse_error ("\"attributes\" expected",NULLCP
);
return ( (struct acl
*) NULL
);
at_acl
= acl_attr_alloc();
at_acl
->aa_next
= NULLACL_ATTR
;
if ((str
= rindex(ptr
,'#')) != NULLCP
) {
if ((at_acl
->aa_types
= str2oidseq (SkipSpace(ptr
))) == NULLOIDSEQ
) {
return ( (struct acl
*) NULL
);
the_acl
->ac_child
= NULLACL_INFO
;
the_acl
->ac_entry
= NULLACL_INFO
;
the_acl
->ac_default
= NULLACL_INFO
;
the_acl
->ac_attributes
= at_acl
;
if ((who
= cmd_srch (str
,cmd_who
)) == -1) {
parse_error ("unknown acl type specifier '%s'",str
);
return ( (struct acl
*) NULL
);
the_acl
->ac_child
= NULLACL_INFO
;
the_acl
->ac_entry
= NULLACL_INFO
;
the_acl
->ac_default
= NULLACL_INFO
;
the_acl
->ac_attributes
= NULLACL_ATTR
;
the_acl
->ac_child
= info
;
the_acl
->ac_entry
= info
;
the_acl
->ac_default
= info
;
static struct acl
* str2acl (str
)
if (str2acl_aux(str
,the_acl
) != NULLACL
)
(void) encode_Quipu_ACLSyntax (&ret_pe
,0,0,NULLCP
,acl
);
acl_sntx
= add_attribute_syntax ("acl",
(IFP
) acl_enc
, (IFP
) acl_decode
,
(IFP
) str2acl
, acl_print
,
merge_acl
= (IFP
) acl_merge
;
acl_fn
= (IFP
) acl_default
;