Annotation of 43BSDReno/contrib/isode-beta/quipu/get_dsa_info.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.