|
|
1.1 root 1: /* get_dsa_info.c - Get DSA info given its distinguished name */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/quipu/RCS/get_dsa_info.c,v 7.2 89/12/19 16:20:36 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/quipu/RCS/get_dsa_info.c,v 7.2 89/12/19 16:20:36 mrose Exp $
9: *
10: *
11: * $Log: get_dsa_info.c,v $
12: * Revision 7.2 89/12/19 16:20:36 mrose
13: * sync
14: *
15: * Revision 7.1 89/11/24 16:21:59 mrose
16: * sync
17: *
18: * Revision 7.0 89/11/23 22:17:42 mrose
19: * Release 6.0
20: *
21: */
22:
23: /*
24: * NOTICE
25: *
26: * Acquisition, use, and distribution of this module and related
27: * materials are subject to the restrictions of a license agreement.
28: * Consult the Preface in the User's Manual for the full terms of
29: * this agreement.
30: *
31: */
32:
33:
34: #include "quipu/util.h"
35: #include "quipu/read.h"
36: #include "quipu/entry.h"
37: #include "quipu/dua.h"
38: #include "quipu/bind.h"
39: #include "quipu/connection.h"
40:
41: extern LLog * log_dsap;
42: extern DN mydsadn;
43:
44: struct oper_act * oper_alloc();
45: struct di_block * di_alloc();
46: struct oper_act * make_get_dsa_info_op();
47:
48: /*
49: * This routine is used to read the info (including presentation address)
50: * for a dsa given its distinguished name.
51: * This is called during the DSA initialisation, to find the name THIS dsa.
52: */
53:
54: int get_dsa_info(dn, dn_stack, err, di_p)
55: DN dn;
56: struct dn_seq * dn_stack;
57: struct DSError * err;
58: struct di_block **di_p;
59: {
60: struct di_block * di_tmp;
61: struct di_block * di_lookup;
62: struct oper_act * on = NULLOPER;
63: int res;
64:
65: DLOG (log_dsap,LLOG_TRACE,("get_dsa_info()"));
66:
67: if (dn_in_dnseq(dn, dn_stack))
68: {
69: LLOG (log_dsap,LLOG_NOTICE,("get_dsa_info - loop detected"));
70: err->dse_type = DSE_SERVICEERROR;
71: err->dse_un.dse_un_service.DSE_sv_problem = DSE_SV_LOOPDETECT;
72: return(DS_X500_ERROR);
73: }
74:
75: /* if asking about me, use my cached entry */
76: if (dn_cmp (dn,mydsadn) == 0)
77: {
78: LLOG (log_dsap,LLOG_NOTICE,("get_dsa_info - referring to self :-)"));
79: err->dse_type = DSE_SERVICEERROR;
80: err->dse_un.dse_un_service.DSE_sv_problem = DSE_SV_DITERROR;
81: return(DS_X500_ERROR);
82: }
83:
84:
85: (*di_p) = di_alloc();
86: (*di_p)->di_type = DI_TASK;
87: (*di_p)->di_dn = dn_cpy(dn);
88: (*di_p)->di_target = NULLDN;
89: (*di_p)->di_reftype = RT_UNDEFINED;
90: (*di_p)->di_rdn_resolved = CR_RDNRESOLVED_NOTDEFINED;
91: (*di_p)->di_aliasedRDNs = CR_NOALIASEDRDNS;
92:
93: /*
94: * Check for a GetDSAInfo operation already in the pipeline.
95: */
96: for(di_tmp=deferred_dis; di_tmp != NULL_DI_BLOCK; di_tmp=di_tmp->di_next)
97: {
98: if(dn_cmp(dn, di_tmp->di_dn) == 0)
99: {
100: (*di_p)->di_state = DI_DEFERRED;
101: (*di_p)->di_entry = NULLENTRY;
102:
103: /* link to the performing operation */
104: (*di_p)->di_perform = di_tmp->di_perform;
105:
106: /* Add to wake list leaving global block first to be woken */
107: (*di_p)->di_wake_next = di_tmp->di_wake_next;
108: di_tmp->di_wake_next = (*di_p);
109:
110: DLOG(log_dsap, LLOG_DEBUG, ("Found global deferred di_block:"));
111: #ifdef DEBUG
112: di_list_log((*di_p));
113: #endif
114: return(DS_CONTINUE);
115: }
116: }
117:
118: if ((res = really_find_entry(dn, TRUE, dn_stack, FALSE, &((*di_p)->di_entry), err, &(di_lookup))) == DS_OK)
119: /* is it really OK ??? */
120: if (((*di_p)->di_entry ->e_data == E_TYPE_CONSTRUCTOR)
121: || ((*di_p)->di_entry->e_dsainfo == NULL)
122: || ((*di_p)->di_entry->e_dsainfo->dsa_addr == NULLPA)) {
123: DN dn_found;
124: DLOG(log_dsap, LLOG_NOTICE, ("rfe returned a constructor"));
125: dn_found = get_copy_dn((*di_p)->di_entry);
126: res = constructor_dsa_info(dn_found,dn_stack,FALSE,(*di_p)->di_entry,err,&(di_lookup));
127: dn_free (dn_found);
128: }
129:
130: switch (res)
131: {
132: case DS_OK:
133: /* really_find_entry has found the entry and placed it in di_entry */
134: DLOG(log_dsap, LLOG_DEBUG, ("get_dsa_info - really_fe returns DS_OK"));
135: (*di_p)->di_state = DI_COMPLETE;
136: #ifdef DEBUG
137: di_list_log((*di_p));
138: #endif
139: return(DS_OK);
140:
141: case DS_CONTINUE:
142: /*
143: * A list of di_blocks (di_lookup) has been generated by get_dsa_info.
144: * These should be used to chain the get_dsa_info operation.
145: * Attempt to generate an operation using the di_blocks returned
146: * and if successful, defer the current di_block to it.
147: */
148: DLOG(log_dsap, LLOG_DEBUG, ("gdi rfe returned DS_CONT:"));
149: #ifdef DEBUG
150: di_list_log(di_lookup);
151: #endif
152: if((on = make_get_dsa_info_op(dn, di_lookup)) == NULLOPER)
153: {
154: /* Flake out screaming */
155: LLOG(log_dsap, LLOG_EXCEPTIONS, ("make_get_dsa_info_op failed for get_dsa_info"));
156: free((char *)*di_p);
157: (*di_p) = NULL_DI_BLOCK;
158: err->dse_type = DSE_SERVICEERROR;
159: err->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNABLETOPROCEED;
160: return(DS_X500_ERROR);
161: }
162:
163: if(oper_chain(on) != OK)
164: {
165: /* Flake out screaming */
166: LLOG(log_dsap, LLOG_NOTICE, ("send_op failed for get_dsa_info"));
167: free((char *)*di_p);
168: (*di_p) = NULL_DI_BLOCK;
169: err->dse_type = DSE_SERVICEERROR;
170: err->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNABLETOPROCEED;
171: return(DS_X500_ERROR);
172: }
173:
174: di_tmp = di_alloc();
175: di_tmp->di_dn = dn_cpy(dn);
176: DLOG(log_dsap, LLOG_DEBUG, ("get_dsa_info allocates di_block with dn[%x]", di_tmp->di_dn));
177: di_tmp->di_state = DI_DEFERRED;
178: di_tmp->di_type = DI_GLOBAL;
179: di_tmp->di_perform = on;
180: on->on_wake_list = di_tmp; /* wake globals first */
181:
182: (*di_p)->di_state = DI_DEFERRED;
183: (*di_p)->di_perform = on;
184:
185: /* Add to wake list leaving global block first to be woken */
186: (*di_p)->di_wake_next = NULL_DI_BLOCK;
187: di_tmp->di_wake_next = (*di_p);
188:
189: di_tmp->di_next = deferred_dis;
190: deferred_dis = di_tmp;
191:
192: DLOG(log_dsap, LLOG_DEBUG, ("gdi DS_CONT: generated:"));
193: #ifdef DEBUG
194: di_list_log((*di_p));
195: #endif
196: return(DS_CONTINUE);
197:
198: case DS_X500_ERROR:
199: /* something wrong with the request - err should be filled out */
200: DLOG(log_dsap, LLOG_DEBUG, ("gdi X500_ERROR"));
201: free((char *)*di_p);
202: (*di_p) = NULL_DI_BLOCK;
203: return(DS_X500_ERROR);
204:
205: default:
206: LLOG(log_dsap, LLOG_EXCEPTIONS, ("Unexpected return from read_dsa_info"));
207: free((char *)*di_p);
208: (*di_p) = NULL_DI_BLOCK;
209: err->dse_type = DSE_SERVICEERROR;
210: err->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNABLETOPROCEED;
211: return(DS_X500_ERROR);
212: }
213: }
214:
215: dsa_info_result_wakeup(on)
216: struct oper_act * on;
217: {
218: EntryInfo * ent_res;
219: Entry di_ent;
220: struct di_block * di;
221: struct di_block * next_di;
222: struct di_block **di_p;
223: Entry cache_dsp_entry();
224:
225: DLOG(log_dsap, LLOG_DEBUG, ("dsa_info_result_wakeup()"));
226:
227: /*
228: * Cache the entry returned, flake out if it is not unravellable,
229: * otherwise grab a reference to the unravelled entry.
230: */
231:
232: ent_res = &(on->on_resp.di_result.dr_res.dcr_dsres.res_rd.rdr_entry);
233: if((di_ent = cache_dsp_entry (ent_res)) == NULLENTRY)
234: {
235: LLOG (log_dsap, LLOG_EXCEPTIONS, ("dsa_info_result_wakeup - cache_dsp_entry failure"));
236: dsa_info_error_wakeup(on);
237: return;
238: }
239:
240: DLOG(log_dsap, LLOG_DEBUG, ("dsa_info_result_wakeup - cached dsa_info"));
241:
242: /*
243: * First block on the wake up list should be the global marker.
244: * Verify this and remove it.
245: */
246: if(on->on_wake_list->di_type != DI_GLOBAL)
247: {
248: LLOG(log_dsap, LLOG_EXCEPTIONS, ("First di_block to wake not global"));
249: }
250: else
251: {
252: di_p = &(deferred_dis);
253: for(di = deferred_dis; di != NULL_DI_BLOCK; di=(*di_p))
254: {
255: if(di == on->on_wake_list)
256: break;
257:
258: di_p = &(di->di_next);
259: }
260: if(di == NULL_DI_BLOCK)
261: {
262: LLOG(log_dsap, LLOG_EXCEPTIONS, ("Global di_block wasn't on global list"));
263: }
264: else
265: {
266: (*di_p)=di->di_next;
267: }
268: }
269:
270: DLOG(log_dsap, LLOG_DEBUG, ("dsa_info_result_wakeup - dealt with global block"));
271:
272: for(di = on->on_wake_list->di_wake_next; di != NULL_DI_BLOCK; di = next_di)
273: {
274: next_di = di->di_wake_next;
275: di->di_state = DI_COMPLETE;
276: di->di_entry = di_ent;
277:
278: switch(di->di_type)
279: {
280: case DI_OPERATION:
281: if (di->di_oper == NULLOPER) {
282: di_free (di);
283: break;
284: }
285: if(di->di_oper->on_state == ON_DEFERRED)
286: {
287: if (oper_chain(di->di_oper) != OK) {
288: LLOG (log_dsap,LLOG_EXCEPTIONS, ("oper_chain failed in dsa_info_wakeup"));
289: di_free(di);
290: }
291: }
292: break;
293:
294: case DI_TASK:
295: task_dsa_info_wakeup(di);
296: di_free(di);
297: break;
298:
299: default:
300: LLOG(log_dsap, LLOG_EXCEPTIONS, ("get_dsa_info_aux - unknown di-type %d",di->di_type));
301: oper_extract(on);
302: return;
303: }
304: }
305:
306: DLOG(log_dsap, LLOG_DEBUG, ("dsa_info_result_wakeup - woke all blocks"));
307:
308: /*
309: * Everthing should have been woken up by now so the di_blocks on
310: * the wake list and the operation itself can be extracted.
311: */
312: di_free(on->on_wake_list);
313:
314: oper_extract(on);
315: }
316:
317: dsa_info_error_wakeup(on)
318: struct oper_act * on;
319: {
320: struct DSError * err = &(on->on_resp.di_error.de_err);
321: struct di_block * di;
322:
323: /*
324: * Error can fall into 3 categories:
325: * 1) Problem with remote DSA performing operation - try another;
326: * 2) A referral error - follow the referral;
327: * 3) An error with the operation itself;
328: */
329:
330: switch(err->dse_type)
331: {
332: case DSE_NOERROR:
333: LLOG(log_dsap, LLOG_NOTICE, ("dsa_info_error_wakeup - No Error!"));
334: dsa_info_fail_wakeup(on);
335: return;
336: case DSE_REFERRAL:
337: LLOG(log_dsap, LLOG_NOTICE, ("dsa_info_error_wakeup - DAP Referral!"));
338: case DSE_DSAREFERRAL:
339: if(oper_rechain(on) == OK)
340: return;
341: /* Fall through */
342: default:
343: DLOG(log_dsap, LLOG_DEBUG, ("dsa_info_error_wakeup - Assuming all non-referral errors are to be propogated"));
344: /* Lose the di_block */
345: for(di=on->on_wake_list; di!=NULL_DI_BLOCK; di=di->di_wake_next)
346: {
347: switch(di->di_type)
348: {
349: case DI_OPERATION:
350: LLOG(log_dsap, LLOG_EXCEPTIONS, ("Should wake oper"));
351: oper_log(di->di_oper);
352: break;
353: case DI_TASK:
354: LLOG(log_dsap, LLOG_EXCEPTIONS, ("Should wake task"));
355: task_log(di->di_task);
356: break;
357: case DI_GLOBAL:
358: LLOG(log_dsap, LLOG_EXCEPTIONS, ("Should wake global"));
359: break;
360: default:
361: LLOG(log_dsap, LLOG_EXCEPTIONS, ("dsa_info_error_wakeup - invalid di_type"));
362: break;
363: }
364: }
365: return;
366: }
367: }
368:
369:
370: dsa_info_fail_wakeup(on)
371: struct oper_act * on;
372: {
373: /*
374: * Last attempt to get dsa info failed somehow.
375: * If there are any more "di_block"s to attempt it must be
376: * worth a go (perhaps this depends on the failure which
377: * has occurrred).
378: */
379: if(on->on_dsas)
380: {
381: if(oper_chain(on) == OK)
382: return;
383: }
384:
385: if(on->on_dsas)
386: {
387: /* oper_chain must be awaiting deferred di_blocks */
388: return;
389: }
390:
391: /*
392: * There is nowhere left to chain this operation to so no way to get
393: * the dsa info required. Walk through the wake up list extracting,
394: * waking things up and tidying up afterwords.
395: */
396: }
397:
398: char * get_entry_passwd (as)
399: Attr_Sequence as;
400: {
401: extern AttributeType at_password;
402: Attr_Sequence at;
403:
404: if ((at = as_find_type (as,at_password)) == NULLATTR)
405: return (NULLCP);
406:
407: if (at->attr_value == NULLAV)
408: return (NULLCP);
409:
410: if (at->attr_value->avseq_av.av_struct == NULL)
411: return (NULLCP);
412:
413: return( (char *)at->attr_value->avseq_av.av_struct);
414:
415: }
416:
417: make_dsa_bind_arg (arg)
418: struct ds_bind_arg *arg;
419: {
420: #ifdef NEXT_VERSION
421: Entry my_entry;
422: char * passwd;
423:
424: arg->dba_version = DBA_VERSION_V1988;
425: arg->dba_auth_type = DBA_AUTH_SIMPLE;
426: arg->dba_time1 = NULLCP;
427: arg->dba_time2 = NULLCP;
428:
429: if ((my_entry = local_find_entry (mydsadn ,TRUE)) == NULLENTRY) {
430: arg->dba_dn = NULLDN;
431: arg->dba_auth_type = DBA_AUTH_NONE;
432: arg->dba_passwd[0] = 0;
433: arg->dba_passwd_len = 0;
434: } else {
435: arg->dba_dn = dn_cpy(mydsadn);
436: if ( (passwd = get_entry_passwd(my_entry->e_attributes)) != NULLCP) {
437: (void) strncpy (arg->dba_passwd,passwd,DBA_MAX_PASSWD_LEN);
438: arg->dba_passwd_len = strlen (passwd);
439: } else {
440: arg->dba_auth_type = DBA_AUTH_NONE;
441: arg->dba_passwd[0] = 0;
442: arg->dba_passwd_len = 0;
443: }
444: }
445: #else
446: arg->dba_version = DBA_VERSION_V1988;
447: arg->dba_auth_type = DBA_AUTH_SIMPLE;
448: arg->dba_time1 = NULLCP;
449: arg->dba_time2 = NULLCP;
450: arg->dba_passwd[0] = 0;
451: arg->dba_passwd_len = 0;
452: arg->dba_dn = dn_cpy(mydsadn);
453: #endif
454: }
455:
456: struct oper_act * make_get_dsa_info_op(dn, di)
457: DN dn;
458: struct di_block * di;
459: {
460: struct di_block * di_tmp;
461: struct oper_act * on_tmp;
462: struct ds_read_arg * arg;
463:
464: DLOG(log_dsap, LLOG_TRACE, ("make_get_dsa_info_op"));
465:
466: if((on_tmp = oper_alloc()) == NULLOPER)
467: {
468: LLOG(log_dsap, LLOG_EXCEPTIONS, ("make_get_dsa_info_op - out of memory"));
469: return(NULLOPER);
470: }
471:
472: on_tmp->on_type = ON_TYPE_GET_DSA_INFO;
473: on_tmp->on_arg = &(on_tmp->on_req);
474: set_my_chain_args(&(on_tmp->on_req.dca_charg), dn);
475:
476: on_tmp->on_req.dca_dsarg.arg_type = OP_READ;
477: arg = &(on_tmp->on_req.dca_dsarg.arg_rd);
478:
479: set_my_common_args(&(arg->rda_common));
480: arg->rda_common.ca_servicecontrol.svc_prio = SVC_PRIO_HIGH;
481:
482: arg->rda_object = dn_cpy(dn); /* The important bit */
483: arg->rda_eis.eis_allattributes = TRUE;
484: arg->rda_eis.eis_select = NULLATTR;
485: arg->rda_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES;
486:
487: on_tmp->on_dsas = di;
488: for(di_tmp=di; di_tmp!=NULL_DI_BLOCK; di_tmp=di_tmp->di_next)
489: {
490: di_tmp->di_type = DI_OPERATION;
491: di_tmp->di_oper = on_tmp;
492: }
493:
494: return(on_tmp);
495: }
496:
497: set_my_chain_args(cha, dn)
498: struct chain_arg * cha;
499: DN dn;
500: {
501: cha->cha_originator = dn_cpy(mydsadn);
502: cha->cha_target = dn_cpy(dn);
503: cha->cha_progress.op_resolution_phase = OP_PHASE_NOTSTARTED;
504: cha->cha_progress.op_nextrdntoberesolved = OP_PHASE_NOTDEFINED;
505: cha->cha_trace = NULLTRACEINFO;
506: cha->cha_aliasderef = CA_NO_ALIASDEREFERENCED;
507: cha->cha_aliasedrdns = CA_NO_ALIASDEREFERENCED;
508: cha->cha_returnrefs = FALSE;
509: cha->cha_reftype = RT_SUBORDINATE;
510: cha->cha_domaininfo = NULLPE;
511: cha->cha_timelimit = NULLCP;
512: }
513:
514: set_my_common_args(ca)
515: struct common_args * ca;
516: {
517: ca->ca_servicecontrol.svc_options = SVC_OPT_PREFERCHAIN;
518: ca->ca_servicecontrol.svc_prio = SVC_PRIO_HIGH;
519: ca->ca_servicecontrol.svc_timelimit = SVC_NOTIMELIMIT;
520: ca->ca_servicecontrol.svc_sizelimit = SVC_NOSIZELIMIT;
521: ca->ca_servicecontrol.svc_scopeofreferral = SVC_REFSCOPE_NONE;
522: ca->ca_requestor = dn_cpy(mydsadn);
523: ca->ca_progress.op_resolution_phase = OP_PHASE_NOTSTARTED;
524: ca->ca_progress.op_nextrdntoberesolved = OP_PHASE_NOTDEFINED;
525: ca->ca_aliased_rdns = CA_NO_ALIASDEREFERENCED;
526: ca->ca_security = (struct security_parms *) NULL;
527: ca->ca_sig = (struct signature *) NULL;
528: ca->ca_extensions = (struct extension *) NULL;
529: }
530:
531: quipu_ctx_supported (ptr)
532: Entry ptr;
533: {
534: AV_Sequence avs, oc_avs();
535: Attr_Sequence as;
536: extern OID quipu_dsa_oid;
537: extern AttributeType at_applctx;
538: char dap_only = TRUE;
539: char res = 1;
540: static OID dsp = NULLOID;
541: static OID quipu_dsp = NULLOID;
542:
543: /* return 0 if "ptr" is not a quipu DSA */
544: /* return 1 if "ptr" represents a quipu_dsa (by objectclass) */
545: /* return 2 if "ptr" represents a quipu_dsa with quipu context */
546: /* return -1 if "ptr" represents a DAP only DSA */
547:
548: /* Should we use QuipuDSP to a non-Quipu DSA, if is claims
549: * to support it - currently implemented as "NO" ?
550: */
551:
552: if ((avs = oc_avs(ptr->e_attributes)) == NULLAV)
553: /* no objectclass attribute !!! */
554: return 0;
555:
556: if (!check_in_oc (quipu_dsa_oid,avs))
557: res = 0; /* not a quipu DSA */
558:
559: if (( as = as_find_type (ptr->e_attributes,at_applctx)) == NULLATTR)
560: return 1;
561:
562: if (dsp == NULLOID) {
563: /* will both be null first time around... */
564: dsp = oid_cpy (DIR_SYSTEM_AC);
565: quipu_dsp = oid_cpy (DIR_QUIPU_AC);
566: }
567:
568: for (avs=as->attr_value; avs != NULLAV; avs=avs->avseq_next) {
569: if ((res != 0) && (oid_cmp ((OID)avs->avseq_av.av_struct, quipu_dsp) == 0 ))
570: return 2;
571: if (oid_cmp ((OID)avs->avseq_av.av_struct, dsp) == 0 )
572: dap_only = FALSE;
573: }
574:
575: if (dap_only)
576: return -1;
577:
578: return res;
579: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.