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