|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T a
Length: 18803 (0x4973) Types: TextFile Names: »acl.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« └─⟦de7628f85⟧ └─⟦this⟧ »isode-6.0/dsap/common/acl.c«
/* acl.c - General Access Control routines */ #ifndef lint static char *rcsid = "$Header: /f/osi/dsap/common/RCS/acl.c,v 7.1 89/12/19 16:19:09 mrose Exp $"; #endif /* * $Header: /f/osi/dsap/common/RCS/acl.c,v 7.1 89/12/19 16:19:09 mrose Exp $ * * * $Log: acl.c,v $ * Revision 7.1 89/12/19 16:19:09 mrose * sync * * Revision 7.0 89/11/23 21:41:28 mrose * Release 6.0 * */ /* * NOTICE * * 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 * this agreement. * */ /* LINTLIBRARY */ #include "quipu/util.h" #include "quipu/entry.h" #include "cmd_srch.h" static struct acl_info * defaultacl = (struct acl_info *) NULL; static acl_free (aclptr) register struct acl * aclptr; { acl_info_free (aclptr->ac_child); acl_info_free (aclptr->ac_entry); acl_info_free (aclptr->ac_default); acl_attr_free (aclptr); free ((char *) aclptr); } 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 ) { next = ptr->aa_next; oid_seq_free (ptr->aa_types); if (ptr->aa_acl != aclptr->ac_default) acl_info_free (ptr->aa_acl); free ((char *) ptr); } } 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) return; for (ptr=aclptr ; ptr!=NULLACL_INFO; ptr=next ) { next = ptr->acl_next; dn_seq_free (ptr->acl_name); free ((char *) ptr); } } int acl_cmp (acl1, acl2) struct acl * acl1; struct acl * acl2; { int i; if((acl1 == NULLACL) && (acl2 == NULLACL)) return(0); if(acl1 == NULLACL) return(-1); if(acl2 == NULLACL) return(1); if((i = acl_info_cmp(acl1->ac_child, acl2->ac_child)) != 0) return(i); if((i = acl_info_cmp(acl1->ac_entry, acl2->ac_entry)) != 0) return(i); if((i = acl_info_cmp(acl1->ac_default, acl2->ac_default)) != 0) return(i); if((i = acl_attr_cmp(acl1->ac_attributes, acl2->ac_attributes)) != 0) return(i); return(0); } static int acl_attr_cmp (acl_attr1, acl_attr2) struct acl_attr * acl_attr1; struct acl_attr * acl_attr2; { struct acl_attr * aa1; struct acl_attr * aa2; if((acl_attr1 == NULLACL_ATTR) && (acl_attr2 == NULLACL_ATTR)) return(0); if(acl_attr1 == NULLACL_ATTR) return(-1); if(acl_attr2 == NULLACL_ATTR) return(1); 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) break; } if(aa2 == NULLACL_ATTR) return(1); } 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) break; } if(aa1 == NULLACL_ATTR) return(-1); } return(0); } static int acl_attr_comp_cmp (acl_attr1, acl_attr2) struct acl_attr * acl_attr1; struct acl_attr * acl_attr2; { int i; if((acl_attr1 == NULLACL_ATTR) && (acl_attr2 == NULLACL_ATTR)) return(0); if(acl_attr1 == NULLACL_ATTR) return(-1); if(acl_attr2 == NULLACL_ATTR) return(1); if((i = oid_seq_cmp(acl_attr1->aa_types, acl_attr2->aa_types)) != 0) return(i); if((i = acl_info_cmp(acl_attr1->aa_acl, acl_attr2->aa_acl)) != 0) return(i); return(0); } static int acl_info_cmp (acl_info1, acl_info2) struct acl_info * acl_info1; struct acl_info * acl_info2; { struct acl_info * ai1; struct acl_info * ai2; if((acl_info1 == NULLACL_INFO) && (acl_info2 == NULLACL_INFO)) return(0); if(acl_info1 == NULLACL_INFO) if (test_acl_default(acl_info2) == OK) return(0); else return(-1); if(acl_info2 == NULLACL_INFO) if (test_acl_default(acl_info1) == OK) return(0); else return(11); 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) break; } if(ai2 == NULLACL_INFO) return(1); } 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) break; } if(ai1 == NULLACL_INFO) return(-1); } return(0); } static int acl_info_comp_cmp (acl_info1, acl_info2) struct acl_info * acl_info1; struct acl_info * acl_info2; { int i; if((acl_info1 == NULLACL_INFO) && (acl_info2 == NULLACL_INFO)) return(0); if(acl_info1 == NULLACL_INFO) return(-1); if(acl_info2 == NULLACL_INFO) return(1); if(acl_info1->acl_categories > acl_info2->acl_categories) return(1); if(acl_info2->acl_categories > acl_info1->acl_categories) return(-1); if(acl_info1->acl_selector_type > acl_info2->acl_selector_type) return(1); if(acl_info2->acl_selector_type > acl_info1->acl_selector_type) return(-1); if((i = dn_seq_cmp(acl_info1->acl_name, acl_info2->acl_name)) != 0) return(i); return(0); } struct acl_info * acl_info_new (x,y,z) register int x,y; struct dn_seq * z; { register struct acl_info * ptr; ptr = acl_info_alloc (); acl_info_fill (ptr,x,y,z); ptr->acl_next = NULLACL_INFO; return (ptr); } 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); return (ptr); } static struct acl * acl_decode (pe) PE pe; { struct acl * aclptr; aclptr = acl_alloc (); if (decode_Quipu_ACLSyntax(pe,1,NULLIP,NULLVP,aclptr) == NOTOK) { free ((char *)aclptr); return (struct acl *) NULL; } if (acl_info_decode (aclptr->ac_child) == NOTOK) return (struct acl *) NULL; if (acl_info_decode (aclptr->ac_entry) == NOTOK) return (struct acl *) NULL; if (acl_info_decode (aclptr->ac_default) == NOTOK) return (struct acl *) NULL; if (acl_attr_decode (aclptr->ac_attributes) == NOTOK) return (struct acl *) NULL; return (aclptr); } static struct acl_attr * acl_attr_cpy (aclptr,dflt) struct acl_attr * aclptr; struct acl_info * dflt; { 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_next = result; result = ptr2; ptr2->aa_types = oid_seq_cpy (ptr->aa_types); if (ptr->aa_acl != dflt) ptr2->aa_acl = acl_info_cpy (ptr->aa_acl); else ptr2->aa_acl = dflt; } return (result); } static acl_attr_decode (aclptr) struct acl_attr * aclptr; { register struct acl_attr * ptr; int result = OK; for (ptr=aclptr ; ptr!=NULLACL_ATTR; ptr=ptr->aa_next ) if (acl_info_decode (ptr->aa_acl) == NOTOK) result = NOTOK; return (result); } 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) { return (defaultacl); } for (ptr=aclptr ; ptr!=NULLACL_INFO; ptr=ptr->acl_next ) { ptr2 = acl_info_alloc(); ptr2 -> acl_next = result; result = ptr2; result->acl_categories = ptr->acl_categories; result->acl_selector_type = ptr->acl_selector_type; result->acl_name = dn_seq_cpy (ptr->acl_name); } return (result); } static acl_info_decode (aclptr) struct acl_info * aclptr; { register struct acl_info * ptr; int result = OK; for (ptr=aclptr ; ptr!=NULLACL_INFO; ptr=ptr->acl_next ) if (dn_seq_decode (ptr->acl_name) == NOTOK) result = NOTOK; return (result); } struct acl_info * acl_default () { return (defaultacl); } get_default_acl () { defaultacl = acl_info_alloc (); set_default_acl(defaultacl); } set_default_acl (ai_ptr) 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; } test_acl_default (a) struct acl_info * a; { if (a == NULLACL_INFO) return (OK); /* used to NOTOK, is OK safe !!! */ if (a ->acl_categories != ACL_READ) { if (a ->acl_categories != ACL_WRITE) return (NOTOK); if (a ->acl_selector_type != ACL_ENTRY) return (NOTOK); if (a ->acl_next == NULLACL_INFO) return (NOTOK); if (a ->acl_next->acl_categories != ACL_READ) return (NOTOK); if (a ->acl_next->acl_selector_type != ACL_OTHER) return (NOTOK); if (a ->acl_next->acl_next != NULLACL_INFO) return (NOTOK); return (OK); } if (a ->acl_selector_type != ACL_OTHER) return (NOTOK); if (a ->acl_next == NULLACL_INFO) return (NOTOK); if (a ->acl_next->acl_categories != ACL_WRITE) return (NOTOK); if (a ->acl_next->acl_selector_type != ACL_ENTRY) return (NOTOK); if (a ->acl_next->acl_next != NULLACL_INFO) return (NOTOK); return (OK); } static struct acl_attr * acl_attr_merge (a,b) struct acl_attr *a; struct acl_attr *b; { struct acl_attr *c; if (b == NULLACL_ATTR) return (a); 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; c->aa_acl = b->aa_acl; return (a); } } b->aa_next = a; return (b); } static acl_merge (a,str) AV_Sequence a; char * str; { struct acl * aclptr, aclstr; struct acl * newacl, *str2acl_aux(); bzero ((char*)&aclstr,sizeof(struct acl)); if ((newacl = str2acl_aux(str,&aclstr)) == NULLACL) return; 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 [] = { "none", "detect", "compare", "read", "add", "write" }; static char * acl_sel [] = { "self", "others", "prefix", "group" }; static acl_info_comp_print (ps,aclptr,format) register PS ps; register struct acl_info * aclptr; register int format; { if (format == READOUT) { switch (aclptr->acl_selector_type) { case ACL_PREFIX: case ACL_GROUP: 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]); break; default: ps_printf (ps,"%s can %s ", acl_sel[aclptr->acl_selector_type], acl_cat[aclptr->acl_categories]); } } else { switch (aclptr->acl_selector_type) { case ACL_PREFIX: case ACL_GROUP: 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]); break; default: 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) register PS ps; struct acl_info * aclptr; register int format; char * acl_type; struct oid_seq *oidseq; { register struct acl_info * ptr; char printed = FALSE; if (test_acl_default(aclptr) == OK) return; for (ptr=aclptr ; ptr!=NULLACL_INFO; ptr=ptr->acl_next ) { if (printed) if (format != READOUT) ps_print (ps,"\nacl= "); else ps_print (ps,"\n\t\t\t"); else printed = TRUE; acl_info_comp_print (ps,ptr,format); if (format == READOUT) { if (oidseq != NULLOIDSEQ) { ps_printf (ps,"the %s: ",acl_type); oid_seq_print (ps,oidseq,format) ; } else ps_printf (ps,"the %s",acl_type); } else { ps_printf (ps,"# %s",acl_type); if (oidseq != NULLOIDSEQ) { ps_print (ps," # "); oid_seq_print (ps,oidseq,format) ; } } } } static acl_print (ps,aclptr,format) register PS ps; struct acl * aclptr; register int format; { char printed = FALSE; register struct acl_attr * ptr; if (test_acl_default(aclptr->ac_child) != OK) { acl_info_print (ps,aclptr->ac_child,format, "child", NULLOIDSEQ); printed = TRUE; } if (test_acl_default(aclptr->ac_entry) != OK) { if (printed) if (format != READOUT) ps_print (ps,"\nacl= "); else ps_print (ps,"\n\t\t\t"); else printed = TRUE; acl_info_print (ps,aclptr->ac_entry,format,"entry", NULLOIDSEQ); } if (test_acl_default(aclptr->ac_default) != OK) { if (printed) if (format != READOUT) ps_print (ps,"\nacl= "); else ps_print (ps,"\n\t\t\t"); else { printed = TRUE; } 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) continue; if (acl_info_cmp(ptr->aa_acl,aclptr->ac_default) == 0) continue; if (printed) if (format != READOUT) ps_print (ps,"\nacl= "); else ps_print (ps,"\n\t\t\t"); else { printed = TRUE; } acl_info_print (ps,ptr->aa_acl,format, "attributes", ptr->aa_types); } if (! printed) if (format == READOUT) ps_print (ps,"(default)"); } static struct acl_info * str2acl_info (strptr) char ** strptr; { char * ptr; char * save,val; int class,what; struct dn_seq * dnseq = NULLDNSEQ; static CMD_TABLE cmd_what [] = { "none", ACL_NONE, "detect", ACL_DETECT, "compare", ACL_COMPARE, "read", ACL_READ, "add", ACL_ADD, "write", ACL_WRITE, 0, -1 } ; static CMD_TABLE cmd_class [] = { "SELF", ACL_ENTRY, "OTHERS", ACL_OTHER, "GROUP", ACL_GROUP, "PREFIX", ACL_PREFIX, 0, -1, } ; if ((ptr = index (*strptr,'#')) == 0) { parse_error ("# missing in acl syntax '%s'",*strptr); return (NULLACL_INFO); } save = ptr++; if (**strptr == '#') { parse_error ("acl class missing before first '#' ",NULLCP); return (NULLACL_INFO); } else { if (! isspace (*--save)) save++; val = *save; *save = 0; if (( class = cmd_srch (*strptr,cmd_class)) == -1) { parse_error ("unknown acl class '%s'",*strptr); *save = val; return (NULLACL_INFO); } *save = val; } *strptr = SkipSpace(ptr); if ((ptr = index (*strptr,'#')) == 0) { parse_error ("2nd # missing in acl syntax ",NULLCP); return (NULLACL_INFO); } if ( (class == ACL_GROUP) || (class == ACL_PREFIX) ) { /* group or prefix */ save = ptr++; if (**strptr == '#') { parse_error ("acl class missing before first '#' ",NULLCP); return (NULLACL_INFO); } else { if (! isspace (*--save)) save++; val = *save; *save = 0; if ((dnseq = str2dnseq (*strptr)) == NULLDNSEQ) return (NULLACL_INFO); *save = val; } *strptr = SkipSpace(ptr); if ((ptr = index (*strptr,'#')) == 0) { parse_error ("3rd # missing in acl syntax ",NULLCP); return (NULLACL_INFO); } } save = ptr++; if (**strptr == '#') { parse_error ("acl level missing",NULLCP); return (NULLACL_INFO); } else { if (! isspace (*--save)) save++; val = *save; *save = 0; if (( what = cmd_srch (*strptr,cmd_what)) == -1) { parse_error ("unknown level '%s'",*strptr); *save = val; return (NULLACL_INFO); } *save = val; } *strptr = SkipSpace(ptr); return (acl_info_new (what,class,dnseq)); } static struct acl * str2acl_aux (str,the_acl) char * str; struct acl * the_acl; { struct acl_info * info; char * save, *ptr, val = 0; int oidlist; struct oid_seq * str2oidseq(); static CMD_TABLE cmd_who [] = { "child", 0, "entry", 1, "default", 2, 0, -1, }; if ((info = str2acl_info (&str)) == NULLACL_INFO) return ( (struct acl *) NULL ); /* this has left us with "string [#oidlist] [#]" */ if ((ptr = index (str,'#')) != 0) { save = ptr++; if (*ptr == 0) oidlist = FALSE; else oidlist = TRUE; if (! isspace (*--save)) save++; val = *save; *save = 0; } else oidlist = FALSE; if (oidlist) { struct acl_attr * at_acl; if (lexequ (str,"attributes") != 0) { parse_error ("\"attributes\" expected",NULLCP); if (val != 0) *save = val; return ( (struct acl *) NULL ); } at_acl = acl_attr_alloc(); at_acl->aa_next = NULLACL_ATTR; at_acl->aa_acl = info; if ((str = rindex(ptr,'#')) != NULLCP) { *str-- = 0; if (isspace (*str)) *str = 0; } if ((at_acl->aa_types = str2oidseq (SkipSpace(ptr))) == NULLOIDSEQ) { if (val != 0) *save = val; 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; } else { int who; if ((who = cmd_srch (str,cmd_who)) == -1) { parse_error ("unknown acl type specifier '%s'",str); if (val != 0) *save = val; 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; switch (who) { case 0: the_acl->ac_child = info; break; case 1: the_acl->ac_entry = info; break; case 2: the_acl->ac_default = info; break; } } if (val != 0) *save = val; return (the_acl); } static struct acl * str2acl (str) char * str; { struct acl * the_acl; the_acl = acl_alloc (); if (str2acl_aux(str,the_acl) != NULLACL) return (the_acl); free ((char *)the_acl); return (NULLACL); } static PE acl_enc (acl) struct acl * acl; { PE ret_pe; (void) encode_Quipu_ACLSyntax (&ret_pe,0,0,NULLCP,acl); return (ret_pe); } acl_syntax () { extern short acl_sntx; extern IFP merge_acl; extern IFP acl_fn; acl_sntx = add_attribute_syntax ("acl", (IFP) acl_enc, (IFP) acl_decode, (IFP) str2acl, acl_print, (IFP) acl_cpy, acl_cmp, acl_free, NULLCP, NULLIFP, TRUE); merge_acl = (IFP) acl_merge; acl_fn = (IFP) acl_default; get_default_acl(); }