|
|
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.