|
|
1.1 root 1: /* find_entry.c - */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/quipu/RCS/find_entry.c,v 7.1 90/07/09 14:46:12 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/quipu/RCS/find_entry.c,v 7.1 90/07/09 14:46:12 mrose Exp $
9: *
10: *
11: * $Log: find_entry.c,v $
12: * Revision 7.1 90/07/09 14:46:12 mrose
13: * sync
14: *
15: * Revision 7.0 89/11/23 22:17:40 mrose
16: * Release 6.0
17: *
18: */
19:
20: /*
21: * NOTICE
22: *
23: * Acquisition, use, and distribution of this module and related
24: * materials are subject to the restrictions of a license agreement.
25: * Consult the Preface in the User's Manual for the full terms of
26: * this agreement.
27: *
28: */
29:
30:
31: #include "quipu/util.h"
32: #include "quipu/commonarg.h"
33: #include "quipu/entry.h"
34: #include "quipu/ds_error.h"
35: #include "quipu/connection.h"
36:
37: extern Entry database_root;
38: extern LLog * log_dsap;
39: extern time_t timenow;
40:
41: extern int dn_print ();
42:
43: int find_entry (object,ca,acl_who,dn_stack,master,ent_p,err,di_p)
44: DN object;
45: common_args * ca;
46: DN acl_who;
47: struct dn_seq * dn_stack;
48: int master;
49: Entry * ent_p;
50: struct DSError * err;
51: struct di_block **di_p;
52: {
53: int deref = FALSE;
54: extern time_t cache_timeout;
55: DN dn_found;
56: int res;
57:
58: DLOG (log_dsap,LLOG_TRACE,("find_entry"));
59: err->dse_type = DSE_NOERROR;
60:
61: if ((ca->ca_servicecontrol.svc_options & SVC_OPT_DONTDEREFERENCEALIAS) == 0)
62: deref = TRUE;
63:
64: if ((ca->ca_servicecontrol.svc_options & SVC_OPT_DONTUSECOPY) != 0)
65: master = TRUE;
66:
67: switch(really_find_entry(object,deref,dn_stack,master,ent_p,err,di_p))
68: {
69: case DS_OK:
70: DLOG(log_dsap, LLOG_DEBUG, ("find_entry - rfe: OK"));
71: /* Have set up ent_p continue processing */
72: break;
73:
74: case DS_CONTINUE:
75: DLOG(log_dsap, LLOG_DEBUG, ("find_entry - rfe: CONT"));
76: #ifdef DEBUG
77: di_list_log((*di_p));
78: #endif
79: /* Have set up di_blocks of DSAs to be questioned */
80: return(DS_CONTINUE);
81:
82: case DS_X500_ERROR:
83: DLOG(log_dsap, LLOG_DEBUG, ("find_entry - rfe: X500_ERROR"));
84: /* Have set up an error */
85: return(DS_X500_ERROR);
86:
87: default:
88: /* Scream */
89: LLOG(log_dsap, LLOG_EXCEPTIONS, ("really_find_entry failed in find_entry 1"));
90: return(DS_ERROR_LOCAL);
91: }
92:
93: /* if the returned entry is a CONSTRUCTOR, return a referral */
94: if ((*ent_p)->e_data == E_TYPE_CONSTRUCTOR) {
95: DLOG(log_dsap, LLOG_DEBUG, ("find_entry - constructor"));
96: dn_found = get_copy_dn (*ent_p);
97: res = constructor_dsa_info(dn_found,dn_stack,FALSE,(*ent_p),err,di_p);
98: dn_free (dn_found);
99: return (res);
100: }
101:
102: /* if the returned entry is a COPY, - check service controls */
103: if ((*ent_p)->e_data != E_DATA_MASTER)
104: if (master) {
105: DLOG(log_dsap, LLOG_DEBUG, ("find_entry - slave master needed"));
106: dn_found = get_copy_dn (*ent_p);
107: res = constructor_dsa_info(dn_found,dn_stack,TRUE,(*ent_p),err,di_p);
108: dn_free (dn_found);
109: return (res);
110: }
111:
112: if (((*ent_p)->e_data == E_TYPE_CACHE_FROM_MASTER) &&
113: ( timenow - (*ent_p)->e_age > cache_timeout)) {
114: DLOG(log_dsap, LLOG_DEBUG, ("find_entry - cache timed out"));
115: dn_found = get_copy_dn (*ent_p);
116: res = constructor_dsa_info(dn_found,dn_stack,TRUE,(*ent_p),err,di_p);
117: delete_cache (dn_found);
118: dn_free (dn_found);
119: return (res);
120: }
121:
122: if ((*ent_p)->e_parent == NULLENTRY)
123: {
124: DLOG(log_dsap, LLOG_DEBUG, ("find_entry: (*ent_p)->e_parent is NULLENTRY"));
125: return (DS_OK); /* no acl for root entry */
126: }
127:
128: if (check_acl (acl_who,ACL_DETECT, (*ent_p)->e_parent->e_acl->ac_child, object) == NOTOK) {
129: err->dse_type = DSE_SECURITYERROR;
130: err->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS;
131: return (DS_X500_ERROR);
132: }
133:
134: if (check_acl (acl_who,ACL_DETECT, (*ent_p)->e_acl->ac_entry, object) == NOTOK) {
135: err->dse_type = DSE_SECURITYERROR;
136: err->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS;
137: return (DS_X500_ERROR);
138: }
139:
140: return (DS_OK);
141: }
142:
143: int find_child_entry (object,ca,acl_who,dn_stack,master,ent_p,err,di_p)
144: DN object;
145: common_args * ca;
146: DN acl_who;
147: struct dn_seq * dn_stack;
148: int master;
149: Entry * ent_p;
150: struct DSError * err;
151: struct di_block **di_p;
152: {
153: /* this is very similar to find_entry(), except a top level */
154: /* constructor is allowed */
155: int deref = FALSE;
156: int res;
157: DN dn_found;
158:
159: DLOG (log_dsap,LLOG_DEBUG,("find_child_entry"));
160: err->dse_type = DSE_NOERROR;
161:
162: if ((ca->ca_servicecontrol.svc_options & SVC_OPT_DONTDEREFERENCEALIAS) == 0)
163: deref = TRUE;
164:
165: if ((ca->ca_servicecontrol.svc_options & SVC_OPT_DONTUSECOPY) != 0)
166: master = TRUE;
167:
168: switch(really_find_entry(object,deref,dn_stack,master,ent_p,err,di_p))
169: {
170: case DS_OK:
171: DLOG(log_dsap, LLOG_DEBUG, ("find_child_entry - rfe: OK"));
172: /* Have set up ent_p continue processing */
173: break;
174:
175: case DS_CONTINUE:
176: DLOG(log_dsap, LLOG_DEBUG, ("find_child_entry - rfe: CONTINUE"));
177: #ifdef DEBUG
178: di_list_log((*di_p));
179: #endif
180: /* Have set up di_blocks of DSAs to be questioned */
181: return(DS_CONTINUE);
182:
183: case DS_X500_ERROR:
184: /* Have set up an error */
185: DLOG(log_dsap, LLOG_DEBUG, ("find_child_entry - rfe: X500_ERROR"));
186: return(DS_X500_ERROR);
187:
188: default:
189: /* Scream */
190: LLOG(log_dsap, LLOG_EXCEPTIONS, ("really_find_entry failed in find_entry 1"));
191: return(DS_ERROR_LOCAL);
192: }
193:
194: /* check to see if children OK */
195: if (((*ent_p)->e_child != NULLENTRY) && ((*ent_p)->e_allchildrenpresent == TRUE))
196: {
197: DLOG(log_dsap, LLOG_DEBUG, ("find_child_entry - children OK"));
198: switch ((*ent_p)->e_child->e_data) {
199: case E_DATA_MASTER:
200: DLOG(log_dsap, LLOG_DEBUG, ("find_child_entry - children masters"));
201: break;
202: case E_TYPE_SLAVE:
203: /* see if we can use a copy ... */
204: DLOG(log_dsap, LLOG_DEBUG, ("find_child_entry - children slaves"));
205: if (master) {
206: dn_found = get_copy_dn (*ent_p);
207: res = constructor_dsa_info_aux(dn_found,dn_stack,master,(*ent_p),err,di_p);
208: dn_free (dn_found);
209: return (res);
210: }
211: break;
212: default:
213: DLOG(log_dsap, LLOG_DEBUG, ("find_child_entry - default"));
214: dn_found = get_copy_dn (*ent_p);
215: res = constructor_dsa_info_aux(dn_found,dn_stack,master,(*ent_p),err,di_p);
216: dn_free (dn_found);
217: return (res);
218: }
219: }
220: else {
221: DLOG(log_dsap, LLOG_DEBUG, ("find_child_entry - children NOTOK"));
222: if ((*ent_p)->e_leaf)
223: {
224: DLOG(log_dsap, LLOG_DEBUG, ("find_child_entry - leaf"));
225: return (DS_OK);
226: }
227: dn_found = get_copy_dn (*ent_p);
228: res = constructor_dsa_info_aux(dn_found,dn_stack,master,(*ent_p),err,di_p);
229: dn_free (dn_found);
230: return (res);
231: }
232:
233: if (check_acl (acl_who,ACL_DETECT, (*ent_p)->e_acl->ac_child, object) == NOTOK) {
234: err->dse_type = DSE_SECURITYERROR;
235: err->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS;
236: return (DS_X500_ERROR);
237: }
238:
239: return (DS_OK);
240: }
241:
242: int really_find_entry (object, deref, dn_stack, master, ent_p, err, di_p)
243: DN object;
244: int deref;
245: struct dn_seq * dn_stack;
246: int master; /* Generate only master references - NB
247: does not imply returned entry is master */
248: Entry * ent_p;
249: struct DSError * err;
250: struct di_block **di_p;
251: {
252: Entry trail;
253: register RDN a_rdn, b_rdn;
254: DN dn, dn_trail = NULLDN;
255: DN aliasdn = NULLDN;
256:
257: DLOG (log_dsap,LLOG_TRACE,("really find entry"));
258:
259: if (deref == -2) {
260: /* alias loop */
261: err->dse_type = DSE_NAMEERROR;
262: err->ERR_NAME.DSE_na_problem = DSE_NA_ALIASDEREFERENCE;
263: err->ERR_NAME.DSE_na_matched = NULLDN;
264: return (DS_X500_ERROR);
265: }
266:
267: if (database_root == NULLENTRY) {
268: LLOG (log_dsap,LLOG_NOTICE,("null root !!!"));
269: return(dsa_info_parent(object, err, di_p, master));
270: }
271:
272: if ((dn = object) == NULLDN)
273: {
274: DLOG(log_dsap,LLOG_DEBUG,("really_fe - DS_OK: database_root"));
275: (*ent_p) = database_root;
276: return (DS_OK);
277: }
278:
279: b_rdn = dn->dn_rdn;
280: if (((*ent_p) = database_root->e_child) == NULLENTRY) {
281: DLOG(log_dsap, LLOG_DEBUG, ("database->e_child == NULLENTRY"));
282: return (no_reply_child (object,dn,dn_stack,master,database_root,err,di_p));
283: }
284:
285: a_rdn = (*ent_p)->e_name ;
286:
287: for(;;) { /* break or return out */
288: trail = NULLENTRY;
289: while (rdn_cmp (a_rdn, b_rdn) != OK) {
290: trail = (*ent_p);
291: (*ent_p) = (*ent_p)->e_sibling ;
292: if ( (*ent_p) == NULLENTRY ) {
293: int res = no_reply_edb (object,dn_trail,dn_stack,master,trail->e_parent,err,di_p);
294: if (aliasdn)
295: dn_free (aliasdn);
296: return res;
297: }
298: a_rdn = (*ent_p)->e_name ;
299: }
300:
301: /* make found element first in list - optimistaion */
302: if (trail != NULLENTRY) { /* NOT already the first */
303: trail->e_sibling = (*ent_p)->e_sibling;
304: (*ent_p)->e_sibling = (*ent_p)->e_parent->e_child;
305: (*ent_p)->e_parent->e_child = (*ent_p);
306: }
307:
308: if ( (*ent_p)->e_alias != NULLDN )
309: /* got an alias entry */
310: if (deref != FALSE) {
311: Entry new_entry;
312: int new_deref;
313:
314: err->dse_type = DSE_NAMEERROR;
315: new_deref = (deref == -1) ? -2 : -1;
316: switch(really_find_entry ((*ent_p)->e_alias,new_deref,dn_stack,master,&(new_entry),err,di_p))
317: {
318: case DS_OK:
319: DLOG(log_dsap, LLOG_DEBUG, ("rfe:rfe:OK"));
320: (*ent_p) = new_entry;
321: if (aliasdn)
322: dn_free (aliasdn);
323: aliasdn = get_copy_dn(new_entry);
324: dn_append (aliasdn,dn_cpy(dn->dn_parent));
325: object = aliasdn;
326: break;
327: case DS_CONTINUE:
328: DLOG(log_dsap, LLOG_DEBUG, ("rfe:rfe:CONT"));
329: DLOG(log_dsap, LLOG_DEBUG, ("Alias ?"));
330: #ifdef DEBUG
331: di_list_log((*di_p));
332: #endif
333: if (aliasdn)
334: dn_free (aliasdn);
335: return(DS_CONTINUE);
336: case DS_X500_ERROR:
337: DLOG(log_dsap, LLOG_DEBUG, ("rfe:rfe:X500ERR"));
338: if ((err->dse_type == DSE_NAMEERROR) &&
339: ( err->ERR_NAME.DSE_na_problem == DSE_NA_ALIASDEREFERENCE)) {
340: if (err->ERR_NAME.DSE_na_matched == NULLDN) {
341: DN tmp_dn;
342: tmp_dn = dn->dn_parent;
343: dn->dn_parent = NULLDN;
344: err->ERR_NAME.DSE_na_matched = dn_cpy(object);
345: dn->dn_parent = tmp_dn;
346: pslog (log_dsap,LLOG_EXCEPTIONS,"Alias deref Problem",dn_print,(caddr_t)err->ERR_NAME.DSE_na_matched);
347: }
348: if (aliasdn)
349: dn_free (aliasdn);
350: return (DS_X500_ERROR);
351: } else {
352: ds_error_free (err);
353: err->dse_type = DSE_NAMEERROR;
354: err->ERR_NAME.DSE_na_problem = DSE_NA_ALIASPROBLEM;
355: err->ERR_NAME.DSE_na_matched = dn_cpy((*ent_p)->e_alias);
356: pslog (log_dsap,LLOG_EXCEPTIONS,"Alias Problem",dn_print,(caddr_t)err->ERR_NAME.DSE_na_matched);
357: if (aliasdn)
358: dn_free (aliasdn);
359: return (DS_X500_ERROR);
360: }
361: default:
362: if (aliasdn)
363: dn_free (aliasdn);
364: DLOG(log_dsap, LLOG_DEBUG, ("rfe:rfe:localerror"));
365: return(DS_ERROR_LOCAL);
366: }
367:
368:
369: } else if ( dn->dn_parent == NULLDN)
370: {
371: DLOG(log_dsap,LLOG_DEBUG,("really_fe - DS_OK: ?1"));
372: if (aliasdn)
373: dn_free (aliasdn);
374: return(DS_OK);
375: }
376: else {
377: /* alias on route - error in this case */
378: DN tmp_dn;
379: err->dse_type = DSE_NAMEERROR;
380: err->ERR_NAME.DSE_na_problem = DSE_NA_ALIASDEREFERENCE;
381: tmp_dn = dn->dn_parent;
382: dn->dn_parent = NULLDN;
383: err->ERR_NAME.DSE_na_matched = dn_cpy(object);
384: dn->dn_parent = tmp_dn;
385: pslog (log_dsap,LLOG_EXCEPTIONS,"Alias deref(2) Problem",dn_print,(caddr_t)err->ERR_NAME.DSE_na_matched);
386: if (aliasdn)
387: dn_free (aliasdn);
388: return (DS_X500_ERROR);
389: }
390:
391:
392: if ( dn->dn_parent == NULLDN)
393: {
394: DLOG(log_dsap,LLOG_DEBUG,("really_fe - DS_OK: ?2"));
395: if (aliasdn)
396: dn_free (aliasdn);
397: return (DS_OK);
398: }
399:
400: if ( (*ent_p)->e_child == NULLENTRY ) {
401: int res = no_reply_child (object,dn,dn_stack,master,(*ent_p),err,di_p);
402: if (aliasdn)
403: dn_free (aliasdn);
404: return res;
405: }
406:
407: dn_trail = dn;
408: dn = dn->dn_parent;
409: b_rdn = dn->dn_rdn;
410:
411: (*ent_p) = (*ent_p)->e_child;
412: a_rdn = (*ent_p)->e_name;
413: }
414: /* NOTREACHED */
415: }
416:
417:
418: int referral_dsa_info (object,dn_stack,master,ptr,err,di_p,chain)
419: DN object;
420: struct dn_seq * dn_stack;
421: int master;
422: Entry ptr;
423: struct DSError * err;
424: struct di_block **di_p;
425: char chain;
426: {
427: int ret;
428: struct di_block * di_tmp;
429:
430: DLOG (log_dsap,LLOG_TRACE,("referral dsa_info"));
431: /* generate a referral to a DUA if possible */
432:
433: if (ptr != NULLENTRY)
434: ptr=ptr->e_parent;
435:
436: if ((ret = constructor_dsa_info_aux(object,dn_stack,master,ptr,err,di_p)) != DS_CONTINUE)
437: return ret;
438:
439: /* Try to make a referral - if not schedule a chain !!! */
440: if (chain)
441: return DS_CONTINUE;
442:
443: /* PROBLEM: The following will get the best referral from our point
444: * of view. This may not be the same from the DUAs point of view !!!
445: */
446: sort_dsa_list (di_p);
447: for(di_tmp= *di_p; di_tmp!=NULL_DI_BLOCK; di_tmp=di_tmp->di_next)
448: {
449: if(di_tmp->di_state == DI_DEFERRED)
450: continue;
451:
452: if(di2cref(di_tmp, err, DS_CTX_X500_DAP) == OK)
453: return (DS_X500_ERROR); /* return the referral !! */
454: }
455: return DS_CONTINUE;
456:
457: }
458:
459: int constructor_dsa_info (object,dn_stack,master,ptr,err,di_p)
460: DN object;
461: struct dn_seq * dn_stack;
462: int master;
463: Entry ptr;
464: struct DSError * err;
465: struct di_block **di_p;
466: {
467: DLOG (log_dsap,LLOG_TRACE,("constructor dsa_info"));
468:
469: if (ptr != NULLENTRY)
470: ptr=ptr->e_parent;
471:
472: return(constructor_dsa_info_aux(object,dn_stack,master,ptr,err,di_p));
473: }
474:
475: int constructor_dsa_info_aux(object,dn_stack,master,ptr,err,di_p)
476: DN object;
477: struct dn_seq * dn_stack;
478: int master;
479: Entry ptr;
480: struct DSError * err;
481: struct di_block **di_p;
482: {
483: DLOG (log_dsap,LLOG_TRACE,("construct dsa_info aux"));
484:
485: /* follow entry back, until something that is not a CONSTRUCTOR */
486:
487: for (; ptr!= NULLENTRY; ptr=ptr->e_parent)
488: if ((ptr->e_data != E_TYPE_CONSTRUCTOR) && (ptr->e_data != E_TYPE_CACHE_FROM_MASTER)) {
489: if ( (ptr->e_master == NULLAV) && (ptr->e_slave == NULLAV))
490: continue ;
491: return(dsa_info_new(object,dn_stack,master,ptr,err,di_p));
492: }
493:
494: return(dsa_info_parent(object,err,di_p,master));
495: }
496:
497: int no_reply_child (object,dn,dn_stack,master,entryptr,err,di_p)
498: DN object;
499: DN dn; /* tail - not matched */
500: struct dn_seq * dn_stack;
501: int master;
502: Entry entryptr;
503: struct DSError * err;
504: struct di_block **di_p;
505: {
506: DN dn_tmp;
507:
508: DLOG (log_dsap,LLOG_TRACE,("no reply child"));
509:
510: if (entryptr->e_leaf)
511: {
512: DLOG (log_dsap,LLOG_DEBUG,("definate NO"));
513: if (dn != NULLDN) {
514: dn_tmp = dn->dn_parent;
515: dn->dn_parent = NULLDN;
516: } else
517: object = NULLDN;
518: err->dse_type = DSE_NAMEERROR;
519: err->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT;
520: err->ERR_NAME.DSE_na_matched = dn_cpy (object);
521: if (dn != NULLDN)
522: dn->dn_parent = dn_tmp;
523:
524: return(DS_X500_ERROR);
525: }
526:
527: if ( (entryptr->e_master != NULLAV) || (entryptr->e_slave != NULLAV))
528: {
529: return(dsa_info_new (object, dn_stack, master, entryptr, err, di_p));
530: }
531:
532: if (entryptr->e_child == NULLENTRY) {
533: return(constructor_dsa_info(object,dn_stack,master,entryptr,err,di_p));
534: }
535:
536: if ((entryptr->e_child->e_data == E_DATA_MASTER)
537: || ((! master) && (entryptr->e_child->e_data == E_TYPE_SLAVE))) {
538: DLOG (log_dsap,LLOG_DEBUG,("definate NO"));
539: if (dn != NULLDN) {
540: dn_tmp = dn->dn_parent;
541: dn->dn_parent = NULLDN;
542: } else
543: object = NULLDN;
544: err->dse_type = DSE_NAMEERROR;
545: err->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT;
546: err->ERR_NAME.DSE_na_matched = dn_cpy (object);
547: if (dn != NULLDN)
548: dn->dn_parent = dn_tmp;
549: return(DS_X500_ERROR);
550: }
551:
552: return(constructor_dsa_info(object,dn_stack,master,entryptr,err,di_p));
553: }
554:
555: int no_reply_edb (object,dn,dn_stack,master,entryptr,err,di_p)
556: DN object;
557: DN dn; /* tail - not matched */
558: struct dn_seq * dn_stack;
559: int master;
560: Entry entryptr;
561: struct DSError * err;
562: struct di_block **di_p;
563: {
564: DN dn_tmp;
565:
566: DLOG (log_dsap,LLOG_TRACE,("no reply edb"));
567:
568: if (entryptr->e_leaf) {
569: DLOG (log_dsap,LLOG_DEBUG,("definate NO"));
570: if (dn != NULLDN) {
571: dn_tmp = dn->dn_parent;
572: dn->dn_parent = NULLDN;
573: } else
574: object = NULLDN;
575: err->dse_type = DSE_NAMEERROR;
576: err->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT;
577: err->ERR_NAME.DSE_na_matched = dn_cpy (object);
578: if (dn != NULLDN)
579: dn->dn_parent = dn_tmp;
580:
581: return(DS_X500_ERROR);
582: }
583:
584: if (entryptr->e_child == NULLENTRY) {
585: return(constructor_dsa_info(object,dn_stack,master,entryptr,err,di_p));
586: }
587:
588: if ((entryptr->e_child->e_data == E_DATA_MASTER)
589: || ((! master) && (entryptr->e_child->e_data == E_TYPE_SLAVE))) {
590: DLOG (log_dsap,LLOG_DEBUG,("definate NO"));
591: if (dn != NULLDN) {
592: dn_tmp = dn->dn_parent;
593: dn->dn_parent = NULLDN;
594: } else
595: object = NULLDN;
596: err->dse_type = DSE_NAMEERROR;
597: err->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT;
598: err->ERR_NAME.DSE_na_matched = dn_cpy (object);
599: if (dn != NULLDN)
600: dn->dn_parent = dn_tmp;
601: return(DS_X500_ERROR);
602: }
603:
604: /* build a referral */
605: return(constructor_dsa_info_aux(object,dn_stack,master,entryptr,err,di_p));
606: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.