Commit | Line | Data |
---|---|---|
04c6839a WJ |
1 | /* acl.c - General Access Control routines */ |
2 | ||
3 | #ifndef lint | |
4 | static char *rcsid = "$Header: /f/osi/dsap/common/RCS/acl.c,v 7.4 91/02/22 09:18:05 mrose Interim $"; | |
5 | #endif | |
6 | ||
7 | /* | |
8 | * $Header: /f/osi/dsap/common/RCS/acl.c,v 7.4 91/02/22 09:18:05 mrose Interim $ | |
9 | * | |
10 | * | |
11 | * $Log: acl.c,v $ | |
12 | * Revision 7.4 91/02/22 09:18:05 mrose | |
13 | * Interim 6.8 | |
14 | * | |
15 | * Revision 7.3 90/11/20 15:29:09 mrose | |
16 | * cjr | |
17 | * | |
18 | * Revision 7.2 90/10/17 11:40:47 mrose | |
19 | * sync | |
20 | * | |
21 | * Revision 7.1 89/12/19 16:19:09 mrose | |
22 | * sync | |
23 | * | |
24 | * Revision 7.0 89/11/23 21:41:28 mrose | |
25 | * Release 6.0 | |
26 | * | |
27 | */ | |
28 | ||
29 | /* | |
30 | * NOTICE | |
31 | * | |
32 | * Acquisition, use, and distribution of this module and related | |
33 | * materials are subject to the restrictions of a license agreement. | |
34 | * Consult the Preface in the User's Manual for the full terms of | |
35 | * this agreement. | |
36 | * | |
37 | */ | |
38 | ||
39 | ||
40 | /* LINTLIBRARY */ | |
41 | ||
42 | #include "quipu/util.h" | |
43 | #include "quipu/entry.h" | |
44 | #include "cmd_srch.h" | |
45 | #include "quipu/syntaxes.h" | |
46 | ||
47 | extern char dsa_mode; | |
48 | ||
49 | static struct acl_info * defaultacl = (struct acl_info *) NULL; | |
50 | ||
51 | static acl_free (aclptr) | |
52 | register struct acl * aclptr; | |
53 | { | |
54 | acl_info_free (aclptr->ac_child); | |
55 | acl_info_free (aclptr->ac_entry); | |
56 | acl_info_free (aclptr->ac_default); | |
57 | acl_attr_free (aclptr); | |
58 | free ((char *) aclptr); | |
59 | } | |
60 | ||
61 | static acl_attr_free (aclptr) | |
62 | register struct acl * aclptr; | |
63 | { | |
64 | register struct acl_attr * ptr; | |
65 | register struct acl_attr * next; | |
66 | ||
67 | for (ptr=aclptr->ac_attributes ; ptr!=NULLACL_ATTR; ptr=next ) { | |
68 | next = ptr->aa_next; | |
69 | oid_seq_free (ptr->aa_types); | |
70 | if (ptr->aa_acl != aclptr->ac_default) | |
71 | acl_info_free (ptr->aa_acl); | |
72 | free ((char *) ptr); | |
73 | } | |
74 | } | |
75 | ||
76 | static acl_info_free (aclptr) | |
77 | register struct acl_info * aclptr; | |
78 | { | |
79 | register struct acl_info * ptr; | |
80 | register struct acl_info * next; | |
81 | ||
82 | if (test_acl_default(aclptr) == OK) | |
83 | return; | |
84 | ||
85 | for (ptr=aclptr ; ptr!=NULLACL_INFO; ptr=next ) { | |
86 | next = ptr->acl_next; | |
87 | dn_seq_free (ptr->acl_name); | |
88 | free ((char *) ptr); | |
89 | } | |
90 | ||
91 | } | |
92 | ||
93 | int acl_cmp (acl1, acl2) | |
94 | struct acl * acl1; | |
95 | struct acl * acl2; | |
96 | { | |
97 | int i; | |
98 | ||
99 | if((acl1 == NULLACL) && (acl2 == NULLACL)) | |
100 | return(0); | |
101 | ||
102 | if(acl1 == NULLACL) | |
103 | return(-1); | |
104 | ||
105 | if(acl2 == NULLACL) | |
106 | return(1); | |
107 | ||
108 | if((i = acl_info_cmp(acl1->ac_child, acl2->ac_child)) != 0) | |
109 | return(i); | |
110 | ||
111 | if((i = acl_info_cmp(acl1->ac_entry, acl2->ac_entry)) != 0) | |
112 | return(i); | |
113 | ||
114 | if((i = acl_info_cmp(acl1->ac_default, acl2->ac_default)) != 0) | |
115 | return(i); | |
116 | ||
117 | if((i = acl_attr_cmp(acl1->ac_attributes, acl2->ac_attributes)) != 0) | |
118 | return(i); | |
119 | ||
120 | return(0); | |
121 | } | |
122 | ||
123 | static int acl_attr_cmp (acl_attr1, acl_attr2) | |
124 | struct acl_attr * acl_attr1; | |
125 | struct acl_attr * acl_attr2; | |
126 | { | |
127 | struct acl_attr * aa1; | |
128 | struct acl_attr * aa2; | |
129 | ||
130 | if((acl_attr1 == NULLACL_ATTR) && (acl_attr2 == NULLACL_ATTR)) | |
131 | return(0); | |
132 | ||
133 | if(acl_attr1 == NULLACL_ATTR) | |
134 | return(-1); | |
135 | ||
136 | if(acl_attr2 == NULLACL_ATTR) | |
137 | return(1); | |
138 | ||
139 | for(aa1=acl_attr1; aa1 != NULLACL_ATTR; aa1=aa1->aa_next) | |
140 | { | |
141 | for(aa2=acl_attr2; aa2 != NULLACL_ATTR; aa2=aa2->aa_next) | |
142 | { | |
143 | if(acl_attr_comp_cmp(aa1, aa2) == 0) | |
144 | break; | |
145 | } | |
146 | if(aa2 == NULLACL_ATTR) | |
147 | return(1); | |
148 | } | |
149 | ||
150 | for(aa2=acl_attr2; aa2 != NULLACL_ATTR; aa2=aa2->aa_next) | |
151 | { | |
152 | for(aa1=acl_attr1; aa1 != NULLACL_ATTR; aa1=aa1->aa_next) | |
153 | { | |
154 | if(acl_attr_comp_cmp(aa1, aa2) == 0) | |
155 | break; | |
156 | } | |
157 | if(aa1 == NULLACL_ATTR) | |
158 | return(-1); | |
159 | } | |
160 | ||
161 | return(0); | |
162 | ||
163 | } | |
164 | ||
165 | static int acl_attr_comp_cmp (acl_attr1, acl_attr2) | |
166 | struct acl_attr * acl_attr1; | |
167 | struct acl_attr * acl_attr2; | |
168 | { | |
169 | int i; | |
170 | ||
171 | if((acl_attr1 == NULLACL_ATTR) && (acl_attr2 == NULLACL_ATTR)) | |
172 | return(0); | |
173 | ||
174 | if(acl_attr1 == NULLACL_ATTR) | |
175 | return(-1); | |
176 | ||
177 | if(acl_attr2 == NULLACL_ATTR) | |
178 | return(1); | |
179 | ||
180 | if((i = oid_seq_cmp(acl_attr1->aa_types, acl_attr2->aa_types)) != 0) | |
181 | return(i); | |
182 | ||
183 | if((i = acl_info_cmp(acl_attr1->aa_acl, acl_attr2->aa_acl)) != 0) | |
184 | return(i); | |
185 | ||
186 | return(0); | |
187 | } | |
188 | ||
189 | static int acl_info_cmp (acl_info1, acl_info2) | |
190 | struct acl_info * acl_info1; | |
191 | struct acl_info * acl_info2; | |
192 | { | |
193 | struct acl_info * ai1; | |
194 | struct acl_info * ai2; | |
195 | ||
196 | if((acl_info1 == NULLACL_INFO) && (acl_info2 == NULLACL_INFO)) | |
197 | return(0); | |
198 | ||
199 | if(acl_info1 == NULLACL_INFO) | |
200 | if (test_acl_default(acl_info2) == OK) | |
201 | return(0); | |
202 | else | |
203 | return(-1); | |
204 | ||
205 | if(acl_info2 == NULLACL_INFO) | |
206 | if (test_acl_default(acl_info1) == OK) | |
207 | return(0); | |
208 | else | |
209 | return(1); | |
210 | ||
211 | for(ai1=acl_info1; ai1 != NULLACL_INFO; ai1=ai1->acl_next) | |
212 | { | |
213 | for(ai2=acl_info2; ai2 != NULLACL_INFO; ai2=ai2->acl_next) | |
214 | { | |
215 | if(acl_info_comp_cmp(ai1, ai2) == 0) | |
216 | break; | |
217 | } | |
218 | if(ai2 == NULLACL_INFO) | |
219 | return(1); | |
220 | } | |
221 | ||
222 | for(ai2=acl_info2; ai2 != NULLACL_INFO; ai2=ai2->acl_next) | |
223 | { | |
224 | for(ai1=acl_info1; ai1 != NULLACL_INFO; ai1=ai1->acl_next) | |
225 | { | |
226 | if(acl_info_comp_cmp(ai2, ai1) == 0) | |
227 | break; | |
228 | } | |
229 | if(ai1 == NULLACL_INFO) | |
230 | return(-1); | |
231 | } | |
232 | ||
233 | return(0); | |
234 | } | |
235 | ||
236 | static int acl_info_comp_cmp (acl_info1, acl_info2) | |
237 | struct acl_info * acl_info1; | |
238 | struct acl_info * acl_info2; | |
239 | { | |
240 | int i; | |
241 | ||
242 | if((acl_info1 == NULLACL_INFO) && (acl_info2 == NULLACL_INFO)) | |
243 | return(0); | |
244 | ||
245 | if(acl_info1 == NULLACL_INFO) | |
246 | return(-1); | |
247 | ||
248 | if(acl_info2 == NULLACL_INFO) | |
249 | return(1); | |
250 | ||
251 | if(acl_info1->acl_categories > acl_info2->acl_categories) | |
252 | return(1); | |
253 | ||
254 | if(acl_info2->acl_categories > acl_info1->acl_categories) | |
255 | return(-1); | |
256 | ||
257 | if(acl_info1->acl_selector_type > acl_info2->acl_selector_type) | |
258 | return(1); | |
259 | ||
260 | if(acl_info2->acl_selector_type > acl_info1->acl_selector_type) | |
261 | return(-1); | |
262 | ||
263 | if((i = dn_seq_cmp(acl_info1->acl_name, acl_info2->acl_name)) != 0) | |
264 | return(i); | |
265 | ||
266 | return(0); | |
267 | } | |
268 | ||
269 | ||
270 | struct acl_info * acl_info_new (x,y,z) | |
271 | register int x,y; | |
272 | struct dn_seq * z; | |
273 | { | |
274 | register struct acl_info * ptr; | |
275 | ||
276 | ptr = acl_info_alloc (); | |
277 | acl_info_fill (ptr,x,y,z); | |
278 | ptr->acl_next = NULLACL_INFO; | |
279 | return (ptr); | |
280 | } | |
281 | ||
282 | static struct acl * acl_cpy (aclptr) | |
283 | register struct acl * aclptr; | |
284 | { | |
285 | register struct acl * ptr; | |
286 | ||
287 | ptr = (struct acl *) smalloc (sizeof (struct acl)); | |
288 | ptr->ac_child = acl_info_cpy (aclptr->ac_child); | |
289 | ptr->ac_entry = acl_info_cpy (aclptr->ac_entry); | |
290 | ptr->ac_default = acl_info_cpy (aclptr->ac_default); | |
291 | ptr->ac_attributes = acl_attr_cpy (aclptr->ac_attributes,ptr->ac_default); | |
292 | return (ptr); | |
293 | ||
294 | } | |
295 | ||
296 | static struct acl * acl_decode (pe) | |
297 | PE pe; | |
298 | { | |
299 | struct acl * aclptr; | |
300 | ||
301 | if (decode_Quipu_ACLSyntax(pe,1,NULLIP,NULLVP,&aclptr) == NOTOK) { | |
302 | return (struct acl *) NULL; | |
303 | } | |
304 | return (aclptr); | |
305 | ||
306 | } | |
307 | ||
308 | static struct acl_attr * acl_attr_cpy (aclptr,dflt) | |
309 | struct acl_attr * aclptr; | |
310 | struct acl_info * dflt; | |
311 | { | |
312 | register struct acl_attr * ptr; | |
313 | register struct acl_attr * ptr2; | |
314 | register struct acl_attr * result = NULLACL_ATTR; | |
315 | ||
316 | for (ptr=aclptr ; ptr!=NULLACL_ATTR; ptr=ptr->aa_next ) { | |
317 | ptr2 = acl_attr_alloc (); | |
318 | ptr2->aa_next = result; | |
319 | result = ptr2; | |
320 | ptr2->aa_types = oid_seq_cpy (ptr->aa_types); | |
321 | if (ptr->aa_acl != dflt) | |
322 | ptr2->aa_acl = acl_info_cpy (ptr->aa_acl); | |
323 | else | |
324 | ptr2->aa_acl = dflt; | |
325 | } | |
326 | return (result); | |
327 | } | |
328 | ||
329 | ||
330 | static struct acl_info * acl_info_cpy (aclptr) | |
331 | struct acl_info * aclptr; | |
332 | { | |
333 | register struct acl_info * ptr; | |
334 | register struct acl_info * ptr2; | |
335 | register struct acl_info * result = NULLACL_INFO; | |
336 | ||
337 | if (test_acl_default(aclptr) == OK) { | |
338 | return (defaultacl); | |
339 | } | |
340 | ||
341 | for (ptr=aclptr ; ptr!=NULLACL_INFO; ptr=ptr->acl_next ) { | |
342 | ptr2 = acl_info_alloc(); | |
343 | ptr2 -> acl_next = result; | |
344 | result = ptr2; | |
345 | result->acl_categories = ptr->acl_categories; | |
346 | result->acl_selector_type = ptr->acl_selector_type; | |
347 | result->acl_name = dn_seq_cpy (ptr->acl_name); | |
348 | } | |
349 | return (result); | |
350 | } | |
351 | ||
352 | struct acl_info * acl_default () | |
353 | { | |
354 | return (defaultacl); | |
355 | } | |
356 | ||
357 | get_default_acl () | |
358 | { | |
359 | defaultacl = acl_info_alloc (); | |
360 | set_default_acl(defaultacl); | |
361 | } | |
362 | ||
363 | set_default_acl (ai_ptr) | |
364 | struct acl_info * ai_ptr; | |
365 | ||
366 | { | |
367 | /* default - others # read & self # write */ | |
368 | ||
369 | ai_ptr ->acl_categories = ACL_READ; | |
370 | ai_ptr ->acl_selector_type = ACL_OTHER; | |
371 | ai_ptr ->acl_name = NULLDNSEQ; | |
372 | ai_ptr ->acl_next = acl_info_alloc(); | |
373 | ai_ptr ->acl_next->acl_categories = ACL_WRITE; | |
374 | ai_ptr ->acl_next->acl_selector_type = ACL_ENTRY; | |
375 | ai_ptr ->acl_next->acl_next = NULLACL_INFO; | |
376 | ai_ptr ->acl_next->acl_name = NULLDNSEQ; | |
377 | ||
378 | } | |
379 | ||
380 | test_acl_default (a) | |
381 | struct acl_info * a; | |
382 | { | |
383 | if ((a == NULLACL_INFO) || (a == defaultacl)) | |
384 | return (OK); | |
385 | ||
386 | if (a ->acl_categories != ACL_READ) { | |
387 | ||
388 | if (a ->acl_categories != ACL_WRITE) | |
389 | return (NOTOK); | |
390 | if (a ->acl_selector_type != ACL_ENTRY) | |
391 | return (NOTOK); | |
392 | if (a ->acl_next == NULLACL_INFO) | |
393 | return (NOTOK); | |
394 | if (a ->acl_next->acl_categories != ACL_READ) | |
395 | return (NOTOK); | |
396 | if (a ->acl_next->acl_selector_type != ACL_OTHER) | |
397 | return (NOTOK); | |
398 | if (a ->acl_next->acl_next != NULLACL_INFO) | |
399 | return (NOTOK); | |
400 | return (OK); | |
401 | ||
402 | } if (a ->acl_selector_type != ACL_OTHER) | |
403 | return (NOTOK); | |
404 | if (a ->acl_next == NULLACL_INFO) | |
405 | return (NOTOK); | |
406 | if (a ->acl_next->acl_categories != ACL_WRITE) | |
407 | return (NOTOK); | |
408 | if (a ->acl_next->acl_selector_type != ACL_ENTRY) | |
409 | return (NOTOK); | |
410 | if (a ->acl_next->acl_next != NULLACL_INFO) | |
411 | return (NOTOK); | |
412 | ||
413 | return (OK); | |
414 | } | |
415 | ||
416 | static struct acl_attr * acl_attr_merge (a,b) | |
417 | struct acl_attr *a; | |
418 | struct acl_attr *b; | |
419 | { | |
420 | struct acl_attr *c; | |
421 | ||
422 | if (b == NULLACL_ATTR) | |
423 | return (a); | |
424 | ||
425 | for (c=a ; c!= NULLACL_ATTR; c=c->aa_next) { | |
426 | if (oid_seq_cmp (c->aa_types,b->aa_types) == 0) { | |
427 | b->aa_acl->acl_next = c->aa_acl; | |
428 | c->aa_acl = b->aa_acl; | |
429 | return (a); | |
430 | } | |
431 | } | |
432 | ||
433 | b->aa_next = a; | |
434 | return (b); | |
435 | ||
436 | ||
437 | ||
438 | } | |
439 | ||
440 | static acl_merge (a,str) | |
441 | AV_Sequence a; | |
442 | char * str; | |
443 | { | |
444 | struct acl * aclptr, aclstr; | |
445 | struct acl * newacl, *str2acl_aux(); | |
446 | ||
447 | bzero ((char*)&aclstr,sizeof(struct acl)); | |
448 | ||
449 | if ((newacl = str2acl_aux(str,&aclstr)) == NULLACL) | |
450 | return; | |
451 | ||
452 | aclptr = (struct acl *) a->avseq_av.av_struct; | |
453 | ||
454 | if (newacl->ac_child != NULLACL_INFO) { | |
455 | newacl->ac_child->acl_next = aclptr->ac_child; | |
456 | aclptr->ac_child = newacl->ac_child; | |
457 | } | |
458 | if (newacl->ac_entry != NULLACL_INFO) { | |
459 | newacl->ac_entry->acl_next = aclptr->ac_entry; | |
460 | aclptr->ac_entry = newacl->ac_entry; | |
461 | } | |
462 | if (newacl->ac_default != NULLACL_INFO) { | |
463 | newacl->ac_default->acl_next = aclptr->ac_default; | |
464 | aclptr->ac_default = newacl->ac_default; | |
465 | } | |
466 | if (newacl->ac_attributes != NULLACL_ATTR) | |
467 | aclptr->ac_attributes = acl_attr_merge (aclptr->ac_attributes,newacl->ac_attributes); | |
468 | } | |
469 | ||
470 | ||
471 | static char * acl_cat [] = { | |
472 | "none", | |
473 | "detect", | |
474 | "compare", | |
475 | "read", | |
476 | "add", | |
477 | "write" | |
478 | }; | |
479 | static char * acl_sel [] = { | |
480 | "ACL SELECTOR INTERNAL ERROR", | |
481 | "self", | |
482 | "others", | |
483 | "prefix", | |
484 | "group" | |
485 | }; | |
486 | ||
487 | static acl_info_comp_print (ps,aclptr,format) | |
488 | register PS ps; | |
489 | register struct acl_info * aclptr; | |
490 | register int format; | |
491 | { | |
492 | if (format == READOUT) { | |
493 | switch (aclptr->acl_selector_type) { | |
494 | case ACL_PREFIX: | |
495 | case ACL_GROUP: | |
496 | ps_printf (ps,"%s ( ",acl_sel[aclptr->acl_selector_type]); | |
497 | dn_seq_print (ps,aclptr->acl_name,format); | |
498 | ps_printf (ps," ) can %s ",acl_cat[aclptr->acl_categories]); | |
499 | break; | |
500 | default: | |
501 | ps_printf (ps,"%s can %s ", acl_sel[aclptr->acl_selector_type], acl_cat[aclptr->acl_categories]); | |
502 | } | |
503 | } else { | |
504 | switch (aclptr->acl_selector_type) { | |
505 | case ACL_PREFIX: | |
506 | case ACL_GROUP: | |
507 | ps_printf (ps,"%s # ",acl_sel[aclptr->acl_selector_type]); | |
508 | dn_seq_print (ps,aclptr->acl_name,format); | |
509 | ps_printf (ps," # %s ",acl_cat[aclptr->acl_categories]); | |
510 | break; | |
511 | default: | |
512 | ps_printf (ps,"%s # %s ", acl_sel[aclptr->acl_selector_type], acl_cat[aclptr->acl_categories]); | |
513 | } | |
514 | } | |
515 | } | |
516 | ||
517 | static acl_info_print (ps,aclptr,format,acl_type,oidseq) | |
518 | register PS ps; | |
519 | struct acl_info * aclptr; | |
520 | register int format; | |
521 | char * acl_type; | |
522 | struct oid_seq *oidseq; | |
523 | { | |
524 | register struct acl_info * ptr; | |
525 | char printed = FALSE; | |
526 | ||
527 | if (test_acl_default(aclptr) == OK) | |
528 | return; | |
529 | ||
530 | for (ptr=aclptr ; ptr!=NULLACL_INFO; ptr=ptr->acl_next ) { | |
531 | ||
532 | if (printed) | |
533 | if (format != READOUT) | |
534 | if (dsa_mode) | |
535 | ps_print (ps," &\\\n\t"); | |
536 | else | |
537 | ps_print (ps,"\nacl= "); | |
538 | else | |
539 | ps_print (ps,"\n\t\t\t"); | |
540 | else | |
541 | printed = TRUE; | |
542 | ||
543 | acl_info_comp_print (ps,ptr,format); | |
544 | ||
545 | if (format == READOUT) { | |
546 | if (oidseq != NULLOIDSEQ) { | |
547 | ps_printf (ps,"the %s: ",acl_type); | |
548 | oid_seq_print (ps,oidseq,format) ; | |
549 | } else | |
550 | ps_printf (ps,"the %s",acl_type); | |
551 | ||
552 | } else { | |
553 | ps_printf (ps,"# %s",acl_type); | |
554 | if (oidseq != NULLOIDSEQ) { | |
555 | ps_print (ps," # "); | |
556 | oid_seq_print (ps,oidseq,format) ; | |
557 | } | |
558 | } | |
559 | } | |
560 | } | |
561 | ||
562 | static acl_print (ps,aclptr,format) | |
563 | register PS ps; | |
564 | struct acl * aclptr; | |
565 | register int format; | |
566 | { | |
567 | char printed = FALSE; | |
568 | register struct acl_attr * ptr; | |
569 | ||
570 | if (test_acl_default(aclptr->ac_child) != OK) { | |
571 | acl_info_print (ps,aclptr->ac_child,format, "child", NULLOIDSEQ); | |
572 | printed = TRUE; | |
573 | } | |
574 | ||
575 | if (test_acl_default(aclptr->ac_entry) != OK) { | |
576 | if (printed) | |
577 | if (format != READOUT) | |
578 | if (dsa_mode) | |
579 | ps_print (ps," &\\\n\t"); | |
580 | else | |
581 | ps_print (ps,"\nacl= "); | |
582 | else | |
583 | ps_print (ps,"\n\t\t\t"); | |
584 | else | |
585 | printed = TRUE; | |
586 | acl_info_print (ps,aclptr->ac_entry,format,"entry", NULLOIDSEQ); | |
587 | } | |
588 | ||
589 | if (test_acl_default(aclptr->ac_default) != OK) { | |
590 | if (printed) | |
591 | if (format != READOUT) | |
592 | if (dsa_mode) | |
593 | ps_print (ps," &\\\n\t"); | |
594 | else | |
595 | ps_print (ps,"\nacl= "); | |
596 | else | |
597 | ps_print (ps,"\n\t\t\t"); | |
598 | else { | |
599 | printed = TRUE; | |
600 | } | |
601 | acl_info_print (ps,aclptr->ac_default,format,"default", NULLOIDSEQ); | |
602 | } | |
603 | ||
604 | for (ptr=aclptr->ac_attributes ; ptr!=NULLACL_ATTR; ptr=ptr->aa_next ) { | |
605 | if (test_acl_default(ptr->aa_acl) == OK) | |
606 | continue; | |
607 | ||
608 | if (acl_info_cmp(ptr->aa_acl,aclptr->ac_default) == 0) | |
609 | continue; | |
610 | ||
611 | if (printed) | |
612 | if (format != READOUT) | |
613 | if (dsa_mode) | |
614 | ps_print (ps," &\\\n\t"); | |
615 | else | |
616 | ps_print (ps,"\nacl= "); | |
617 | else | |
618 | ps_print (ps,"\n\t\t\t"); | |
619 | else { | |
620 | printed = TRUE; | |
621 | } | |
622 | acl_info_print (ps,ptr->aa_acl,format, "attributes", ptr->aa_types); | |
623 | } | |
624 | ||
625 | if (! printed) | |
626 | if (format == READOUT) | |
627 | ps_print (ps,"(default)"); | |
628 | } | |
629 | ||
630 | static struct acl_info * str2acl_info (strptr) | |
631 | char ** strptr; | |
632 | { | |
633 | char * ptr; | |
634 | char * save,val; | |
635 | int class,what; | |
636 | struct dn_seq * dnseq = NULLDNSEQ; | |
637 | ||
638 | static CMD_TABLE cmd_what [] = { | |
639 | "none", ACL_NONE, | |
640 | "detect", ACL_DETECT, | |
641 | "compare", ACL_COMPARE, | |
642 | "read", ACL_READ, | |
643 | "add", ACL_ADD, | |
644 | "write", ACL_WRITE, | |
645 | 0, -1 | |
646 | } ; | |
647 | ||
648 | static CMD_TABLE cmd_class [] = { | |
649 | "SELF", ACL_ENTRY, | |
650 | "OTHERS", ACL_OTHER, | |
651 | "GROUP", ACL_GROUP, | |
652 | "PREFIX", ACL_PREFIX, | |
653 | 0, -1, | |
654 | } ; | |
655 | ||
656 | if ((ptr = index (*strptr,'#')) == 0) { | |
657 | parse_error ("# missing in acl syntax '%s'",*strptr); | |
658 | return (NULLACL_INFO); | |
659 | } | |
660 | ||
661 | save = ptr++; | |
662 | if (**strptr == '#') { | |
663 | parse_error ("acl class missing before first '#' ",NULLCP); | |
664 | return (NULLACL_INFO); | |
665 | } else { | |
666 | if (! isspace (*--save)) | |
667 | save++; | |
668 | val = *save; | |
669 | *save = 0; | |
670 | ||
671 | if (( class = cmd_srch (*strptr,cmd_class)) == -1) { | |
672 | parse_error ("unknown acl class '%s'",*strptr); | |
673 | *save = val; | |
674 | return (NULLACL_INFO); | |
675 | } | |
676 | *save = val; | |
677 | } | |
678 | ||
679 | *strptr = SkipSpace(ptr); | |
680 | if ((ptr = index (*strptr,'#')) == 0) { | |
681 | parse_error ("2nd # missing in acl syntax ",NULLCP); | |
682 | return (NULLACL_INFO); | |
683 | } | |
684 | ||
685 | if ( (class == ACL_GROUP) || (class == ACL_PREFIX) ) { /* group or prefix */ | |
686 | save = ptr++; | |
687 | if (**strptr == '#') { | |
688 | parse_error ("acl class missing before first '#' ",NULLCP); | |
689 | return (NULLACL_INFO); | |
690 | } else { | |
691 | if (! isspace (*--save)) | |
692 | save++; | |
693 | val = *save; | |
694 | *save = 0; | |
695 | ||
696 | if ((dnseq = str2dnseq (*strptr)) == NULLDNSEQ) | |
697 | return (NULLACL_INFO); | |
698 | ||
699 | *save = val; | |
700 | } | |
701 | *strptr = SkipSpace(ptr); | |
702 | if ((ptr = index (*strptr,'#')) == 0) { | |
703 | parse_error ("3rd # missing in acl syntax ",NULLCP); | |
704 | return (NULLACL_INFO); | |
705 | } | |
706 | } | |
707 | ||
708 | save = ptr++; | |
709 | if (**strptr == '#') { | |
710 | parse_error ("acl level missing",NULLCP); | |
711 | return (NULLACL_INFO); | |
712 | } else { | |
713 | if (! isspace (*--save)) | |
714 | save++; | |
715 | val = *save; | |
716 | *save = 0; | |
717 | ||
718 | if (( what = cmd_srch (*strptr,cmd_what)) == -1) { | |
719 | parse_error ("unknown level '%s'",*strptr); | |
720 | *save = val; | |
721 | return (NULLACL_INFO); | |
722 | } | |
723 | *save = val; | |
724 | } | |
725 | ||
726 | *strptr = SkipSpace(ptr); | |
727 | ||
728 | return (acl_info_new (what,class,dnseq)); | |
729 | } | |
730 | ||
731 | static struct acl * str2acl_aux (str,the_acl) | |
732 | char * str; | |
733 | struct acl * the_acl; | |
734 | { | |
735 | struct acl_info * info; | |
736 | char * save, *ptr, val = 0; | |
737 | int oidlist; | |
738 | struct oid_seq * str2oidseq(); | |
739 | ||
740 | static CMD_TABLE cmd_who [] = { | |
741 | "child", 0, | |
742 | "entry", 1, | |
743 | "default", 2, | |
744 | 0, -1, | |
745 | }; | |
746 | ||
747 | if ((info = str2acl_info (&str)) == NULLACL_INFO) | |
748 | return ( (struct acl *) NULL ); | |
749 | ||
750 | /* this has left us with "string [#oidlist] [#]" */ | |
751 | ||
752 | if ((ptr = index (str,'#')) != 0) { | |
753 | save = ptr++; | |
754 | if (*ptr == 0) | |
755 | oidlist = FALSE; | |
756 | else | |
757 | oidlist = TRUE; | |
758 | ||
759 | if (! isspace (*--save)) | |
760 | save++; | |
761 | val = *save; | |
762 | *save = 0; | |
763 | ||
764 | } else | |
765 | oidlist = FALSE; | |
766 | ||
767 | if (oidlist) { | |
768 | struct acl_attr * at_acl; | |
769 | ||
770 | if (lexequ (str,"attributes") != 0) { | |
771 | parse_error ("\"attributes\" expected",NULLCP); | |
772 | if (val != 0) | |
773 | *save = val; | |
774 | return ( (struct acl *) NULL ); | |
775 | } | |
776 | at_acl = acl_attr_alloc(); | |
777 | at_acl->aa_next = NULLACL_ATTR; | |
778 | at_acl->aa_acl = info; | |
779 | ||
780 | if ((str = rindex(ptr,'#')) != NULLCP) { | |
781 | *str-- = 0; | |
782 | if (isspace (*str)) | |
783 | *str = 0; | |
784 | } | |
785 | ||
786 | if ((at_acl->aa_types = str2oidseq (SkipSpace(ptr))) == NULLOIDSEQ) { | |
787 | if (val != 0) | |
788 | *save = val; | |
789 | return ( (struct acl *) NULL ); | |
790 | } | |
791 | the_acl->ac_child = NULLACL_INFO; | |
792 | the_acl->ac_entry = NULLACL_INFO; | |
793 | the_acl->ac_default = NULLACL_INFO; | |
794 | the_acl->ac_attributes = at_acl; | |
795 | ||
796 | } else { | |
797 | int who; | |
798 | if ((who = cmd_srch (str,cmd_who)) == -1) { | |
799 | parse_error ("unknown acl type specifier '%s'",str); | |
800 | if (val != 0) | |
801 | *save = val; | |
802 | return ( (struct acl *) NULL ); | |
803 | } | |
804 | the_acl->ac_child = NULLACL_INFO; | |
805 | the_acl->ac_entry = NULLACL_INFO; | |
806 | the_acl->ac_default = NULLACL_INFO; | |
807 | the_acl->ac_attributes = NULLACL_ATTR; | |
808 | switch (who) { | |
809 | case 0: | |
810 | the_acl->ac_child = info; | |
811 | break; | |
812 | case 1: | |
813 | the_acl->ac_entry = info; | |
814 | break; | |
815 | case 2: | |
816 | the_acl->ac_default = info; | |
817 | break; | |
818 | } | |
819 | } | |
820 | ||
821 | if (val != 0) | |
822 | *save = val; | |
823 | ||
824 | return (the_acl); | |
825 | } | |
826 | ||
827 | static struct acl * str2acl (str) | |
828 | char * str; | |
829 | { | |
830 | struct acl * the_acl; | |
831 | ||
832 | the_acl = acl_alloc (); | |
833 | if (str2acl_aux(str,the_acl) != NULLACL) | |
834 | return (the_acl); | |
835 | free ((char *)the_acl); | |
836 | return (NULLACL); | |
837 | } | |
838 | ||
839 | ||
840 | static PE acl_enc (acl) | |
841 | struct acl * acl; | |
842 | { | |
843 | PE ret_pe; | |
844 | ||
845 | (void) encode_Quipu_ACLSyntax (&ret_pe,0,0,NULLCP,acl); | |
846 | return (ret_pe); | |
847 | } | |
848 | ||
849 | ||
850 | acl_syntax () | |
851 | { | |
852 | extern short acl_sntx; | |
853 | extern IFP merge_acl; | |
854 | extern IFP acl_fn; | |
855 | ||
856 | acl_sntx = add_attribute_syntax ("acl", | |
857 | (IFP) acl_enc, (IFP) acl_decode, | |
858 | (IFP) str2acl, acl_print, | |
859 | (IFP) acl_cpy, acl_cmp, | |
860 | acl_free, NULLCP, | |
861 | NULLIFP, TRUE); | |
862 | ||
863 | merge_acl = (IFP) acl_merge; | |
864 | acl_fn = (IFP) acl_default; | |
865 | get_default_acl(); | |
866 | } |