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

1.1       root        1: /* ds_search.c - DSA search of the directory */
                      2: 
                      3: #ifndef lint
                      4: static char *rcsid = "$Header: /f/osi/quipu/RCS/ds_search.c,v 7.5 90/07/09 14:45:51 mrose Exp $";
                      5: #endif
                      6: 
                      7: /*
                      8:  * $Header: /f/osi/quipu/RCS/ds_search.c,v 7.5 90/07/09 14:45:51 mrose Exp $
                      9:  *
                     10:  *
                     11:  * $Log:       ds_search.c,v $
                     12:  * Revision 7.5  90/07/09  14:45:51  mrose
                     13:  * sync
                     14:  * 
                     15:  * Revision 7.4  90/04/18  08:49:46  mrose
                     16:  * 6.2
                     17:  * 
                     18:  * Revision 7.3  90/03/15  11:18:51  mrose
                     19:  * quipu-sync
                     20:  * 
                     21:  * Revision 7.2  90/01/11  23:55:52  mrose
                     22:  * lint
                     23:  * 
                     24:  * Revision 7.1  89/12/19  16:20:21  mrose
                     25:  * sync
                     26:  * 
                     27:  * Revision 7.0  89/11/23  22:17:16  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/entry.h"
                     45: #include "quipu/list.h"      /* to get LSR # defs */
                     46: #include "quipu/ds_search.h"
                     47: #include "config.h"
                     48: 
                     49: extern int encode_DAS_SearchArgumentData();
                     50: extern LLog * log_dsap;
                     51: 
                     52: #ifndef NO_STATS
                     53: extern LLog * log_stat;
                     54: extern int dn_print ();
                     55: static PS filter_ps;
                     56: #endif
                     57: 
                     58: static EntryInfo *filterentry();
                     59: static EntryInfo *filterchildren();
                     60: static test_avs();
                     61: static apply_search();
                     62: static substr_search();
                     63: static aux_substr_search();
                     64: static check_filteritem_presrch ();
                     65: static check_filter_presrch ();
                     66: static check_filterop_presrch ();
                     67: static check_filteritem ();
                     68: static check_filter ();
                     69: static check_filterop ();
                     70: struct ds_search_task * st_done ();
                     71: static search_refer ();
                     72: static do_alias ();
                     73: static do_base ();
                     74: 
                     75: extern Entry database_root;
                     76: static int size;
                     77: static char qctx;
                     78: extern int search_level;
                     79: IFP approxfn();
                     80: IFP av_cmp_fn();
                     81: 
                     82: #ifndef        NBBY
                     83: #define        NBBY    8
                     84: #endif
                     85: static int big_size = 0;
                     86: static int timelimit;
                     87: extern time_t time();
                     88: extern time_t timenow;
                     89: extern int admin_size;
                     90: 
                     91: Attr_Sequence eis_select ();
                     92: 
                     93: do_ds_search (arg, error, result, dnbind, target, local, refer, di_p, 
                     94:                dsp, quipu_ctx, tktime, entryonly)
                     95:     register struct ds_search_arg        *arg;
                     96:     struct ds_search_result     *result;
                     97:     struct DSError              *error;
                     98:     DN                          dnbind;
                     99:     DN                          target;
                    100:     struct ds_search_task       ** local,
                    101:                                ** refer;
                    102:     struct di_block            ** di_p;
                    103:     char                       dsp;
                    104:     char                       quipu_ctx;
                    105:     time_t                     tktime;
                    106:     char                       entryonly;
                    107: {
                    108: extern time_t admin_time;
                    109: int ismanager = FALSE;
                    110: int retval;
                    111: struct ds_search_task * st;
                    112: DN st_dn;
                    113: 
                    114:        qctx = quipu_ctx;
                    115: 
                    116:        if ((timelimit = tktime) == (time_t) 0) {
                    117:            register int    i;
                    118: 
                    119:            for (i = NBBY * sizeof timelimit - 1; i > 0; i--)
                    120:                timelimit <<= 1, timelimit |= 1;
                    121:        }
                    122: 
                    123:        if (!dsp)
                    124:                ismanager = manager (dnbind);
                    125: 
                    126:        if (ismanager && big_size == 0) {
                    127:            register int    i;
                    128: 
                    129:            for (i = NBBY * sizeof big_size - 1; i > 0; i--)
                    130:                big_size <<= 1, big_size |= 1;
                    131:        }
                    132: 
                    133:        if (*local == NULL_ST) {
                    134:                DLOG (log_dsap,LLOG_TRACE,("ds_search"));
                    135: 
                    136:                if (!dsp)
                    137:                        target = arg->sra_baseobject;
                    138: 
                    139:                /* Put local stuff straight into result structure (dangerous) */
                    140:                result->srr_correlated = TRUE;
                    141:                result->srr_un.srr_unit = (struct ds_search_unit *) calloc(1, sizeof(struct ds_search_unit));
                    142:                result->CSR_cr = NULLCONTINUATIONREF;
                    143: 
                    144:                *local = st_alloc();
                    145:                (*local)->st_baseobject = dn_cpy (target);
                    146:                if ((*local)->st_entryonly = entryonly)         /* assign */
                    147:                        (*local)->st_subset = SRA_BASEOBJECT;
                    148:                else
                    149:                        (*local)->st_subset = arg->sra_subset;
                    150:                (*local)->st_alias = NULLDN;
                    151:                (*local)->st_save = NULL_ST;
                    152: 
                    153:                if (ismanager) {
                    154:                    if (((*local)->st_size = arg->sra_common.ca_servicecontrol.svc_sizelimit) == SVC_NOSIZELIMIT)
                    155:                        (*local)->st_size = big_size;
                    156:                } else if (((*local)->st_size = MIN(admin_size,arg->sra_common.ca_servicecontrol.svc_sizelimit)) == SVC_NOSIZELIMIT)
                    157:                        (*local)->st_size = admin_size;
                    158: 
                    159:                (*local)->st_next = NULL_ST;
                    160: 
                    161:                result->CSR_entries = NULLENTRYINFO;
                    162: 
                    163: #ifndef NO_STATS
                    164:                if ((filter_ps = ps_alloc(str_open)) == NULLPS) {
                    165:                        st_comp_free (*local);
                    166:                        *local = NULL_ST;
                    167:                        return (DS_ERROR_LOCAL);
                    168:                } if (str_setup (filter_ps,NULLCP, BUFSIZ, 0) == NOTOK) {
                    169:                        st_comp_free (*local);
                    170:                        *local = NULL_ST;
                    171:                        return (DS_ERROR_LOCAL);
                    172:                }
                    173: #endif
                    174:                if (check_filter_presrch (arg->sra_filter,error,target) != OK) {
                    175: #ifndef NO_STATS
                    176:                        ps_free (filter_ps);
                    177: #endif
                    178:                        st_comp_free (*local);
                    179:                        *local = NULL_ST;
                    180:                        return (DS_ERROR_REMOTE);
                    181:                } else {
                    182:                        Entry entryptr;
                    183: #ifndef NO_STATS
                    184:                        *filter_ps->ps_ptr = 0;
                    185:                        switch ((*local)->st_subset) {
                    186:                        case SRA_ONELEVEL:
                    187:                                LLOG (log_stat, LLOG_TRACE, ("Search onelevel %s",filter_ps->ps_base));
                    188:                                break;
                    189:                        case SRA_WHOLESUBTREE:  
                    190:                                LLOG (log_stat, LLOG_TRACE, ("Search subtree %s",filter_ps->ps_base));
                    191:                                break;
                    192:                        default:        
                    193:                                LLOG (log_stat, LLOG_TRACE, ("Search base %s",filter_ps->ps_base));
                    194:                                break;
                    195:                        }
                    196:                        ps_free (filter_ps);
                    197: #endif
                    198:                        if ((arg->sra_subset == SRA_ONELEVEL) || 
                    199:                                (arg->sra_subset == SRA_WHOLESUBTREE))
                    200:                        {
                    201:                                switch(find_child_entry((*local)->st_baseobject,&(arg->sra_common),dnbind,NULLDNSEQ,FALSE,&(entryptr), error, di_p))
                    202:                                {
                    203:                                case DS_OK:
                    204:                                    /* Filled out entryptr - carry on */
                    205:                                    break;
                    206:                                case DS_CONTINUE:
                    207:                                    /* Filled out di_p - what do we do with it ?? */
                    208:                                    st_comp_free (*local);
                    209:                                    *local = NULL_ST;
                    210:                                    return(DS_CONTINUE);
                    211: 
                    212:                                case DS_X500_ERROR:
                    213:                                    /* Filled out error - what do we do with it ?? */
                    214:                                    st_comp_free (*local);
                    215:                                    *local = NULL_ST;
                    216:                                    return(DS_X500_ERROR);
                    217:                                default:
                    218:                                    /* SCREAM */
                    219:                                    LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_search() - find_child_entry failed 1"));
                    220:                                    st_comp_free (*local);
                    221:                                    *local = NULL_ST;
                    222:                                    return(DS_ERROR_LOCAL);
                    223:                                }
                    224:                        }
                    225:                        else
                    226:                        {
                    227:                                if ((arg->sra_subset == SRA_BASEOBJECT) 
                    228:                                        && ((*local)->st_baseobject == NULLDN)) {
                    229:                                        error->dse_type = DSE_NAMEERROR;
                    230:                                        error->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT;
                    231:                                        error->ERR_NAME.DSE_na_matched = NULLDN;
                    232:                                        st_comp_free (*local);
                    233:                                        *local = NULL_ST;
                    234:                                        return (DS_ERROR_REMOTE);
                    235:                                }
                    236:                                 
                    237:                                switch(find_entry((*local)->st_baseobject,&(arg->sra_common),dnbind,NULLDNSEQ,FALSE,&(entryptr), error, di_p))
                    238:                                {
                    239:                                case DS_OK:
                    240:                                    /* Filled out entryptr - carry on */
                    241:                                    break;
                    242:                                case DS_CONTINUE:
                    243:                                    /* Filled out di_p - what do we do with it ?? */
                    244:                                    st_comp_free (*local);
                    245:                                    *local = NULL_ST;
                    246:                                    return(DS_CONTINUE);
                    247: 
                    248:                                case DS_X500_ERROR:
                    249:                                    /* Filled out error - what do we do with it ?? */
                    250:                                    st_comp_free (*local);
                    251:                                    *local = NULL_ST;
                    252:                                    return(DS_X500_ERROR);
                    253:                                default:
                    254:                                    /* SCREAM */
                    255:                                    LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_search() - find_entry failed 1"));
                    256:                                    st_comp_free (*local);
                    257:                                    *local = NULL_ST;
                    258:                                    return(DS_ERROR_LOCAL);
                    259:                                }
                    260:                        }
                    261: 
                    262:                        /* if no error and NOT SVC_OPT_DONTDEREFERENCEALIASES then */
                    263:                        /* the alias will have been derefeferenced -signified by   */
                    264:                        /* NO_ERROR !!! */
                    265:                        if (error->dse_type == DSE_NOERROR) {
                    266:                                result->CSR_object = NULLDN;
                    267:                                result->CSR_common.cr_aliasdereferenced =  FALSE;
                    268:                        } else {
                    269:                                result->CSR_common.cr_aliasdereferenced =  TRUE;
                    270:                                result->CSR_object = get_copy_dn (entryptr);
                    271:                        }
                    272: 
                    273:                        /* Strong authentication  */
                    274:                        if ((retval = check_security_parms((caddr_t) arg,
                    275:                                encode_DAS_SearchArgumentData,
                    276:                                arg->sra_common.ca_security,
                    277:                                arg->sra_common.ca_sig, &dnbind)) != 0)
                    278:                        {
                    279:                                error->dse_type = DSE_SECURITYERROR;
                    280:                                error->ERR_SECURITY.DSE_sc_problem = retval;
                    281:                                st_comp_free (*local);
                    282:                                *local = NULL_ST;
                    283:                                return (DS_ERROR_REMOTE);
                    284:                        }
                    285: 
                    286:                        /* one final check - will we allow such searched in this DSA ? */
                    287:                        if (arg->sra_subset == SRA_WHOLESUBTREE) {
                    288:                                DN dn;
                    289:                                int x = 0;
                    290:                                for (dn = (*local)->st_baseobject; dn!= NULLDN; dn=dn->dn_parent, x++)
                    291:                                        ;
                    292:                                if ( x < search_level ) {
                    293:                                        if ( ! ismanager ) {
                    294:                                                /* Too high */
                    295:                                                error->dse_type = DSE_SERVICEERROR;
                    296:                                                error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM;
                    297:                                                st_comp_free (*local);
                    298:                                                *local = NULL_ST;
                    299:                                                return (DS_ERROR_REMOTE);
                    300:                                        }
                    301:                                }
                    302:                                if (entryptr->e_data != E_TYPE_CONSTRUCTOR) {
                    303:                                        if ((*local)->st_baseobject != NULLDN) {
                    304:                                                if ((result->CSR_entries = filterentry (arg,entryptr)) != NULLENTRYINFO)
                    305:                                                        (*local)->st_size--;
                    306:                                        }
                    307:                                } else {
                    308:                                        do_base (entryptr,local);
                    309:                                }
                    310:                        }
                    311:                        result->CSR_limitproblem = LSR_NOLIMITPROBLEM;
                    312:                        return (DS_SUSPEND); /* yup - we will take the search on */
                    313:                }
                    314:        } else {
                    315: 
                    316:                DN path;
                    317: 
                    318:                DLOG (log_dsap,LLOG_TRACE,("ds_search continuing"));
                    319: 
                    320:                size = (*local)->st_size;
                    321: 
                    322:                if ((*local)->st_alias == NULLDN)
                    323:                        path = (*local)->st_baseobject;
                    324:                else
                    325:                        path = (*local)->st_alias;
                    326: 
                    327: #ifdef HACK
                    328:                /* Check we have not been here before... */
                    329:                for ( st = (*local)->st_save; st != NULL_ST; st=st->st_next) {
                    330:                        if (st->st_alias == NULLDN) 
                    331:                                st_dn = st->st_baseobject;
                    332:                        else 
                    333:                                st_dn = st->st_alias;
                    334:                        if (dn_cmp (path, st_dn) == 0) {
                    335:                                LLOG (log_dsap,LLOG_TRACE,("local search - loop detected"));
                    336:                                break;
                    337:                        }
                    338:                }
                    339: #else
                    340:                st = NULL_ST;
                    341: #endif
                    342: 
                    343:                if ( (st == NULL_ST) && 
                    344:                        (apply_search (arg,error,result,local,refer,ismanager)) == NOTOK) {
                    345:                        st_free (local);
                    346:                        st_free (refer);
                    347:                        return (DS_ERROR_REMOTE); 
                    348:                }
                    349: 
                    350:                if (size < 0) {
                    351:                    st_free (local);
                    352:                    st_free (refer);
                    353:                    result -> CSR_limitproblem =
                    354:                        arg -> sra_common.ca_servicecontrol.svc_sizelimit
                    355:                                == SVC_NOSIZELIMIT
                    356:                            || arg -> sra_common.ca_servicecontrol.svc_sizelimit
                    357:                                    > admin_size
                    358:                        ? LSR_ADMINSIZEEXCEEDED
                    359:                        : LSR_SIZELIMITEXCEEDED;
                    360:                    /* should fill out a POQ */
                    361:                    return (DS_OK);
                    362:                }
                    363: 
                    364:                if (timelimit <= timenow) {
                    365:                    st_free (local);
                    366:                    st_free (refer);
                    367:                    result -> CSR_limitproblem =
                    368:                        arg -> sra_common.ca_servicecontrol.svc_timelimit
                    369:                                == SVC_NOTIMELIMIT
                    370:                            || arg -> sra_common.ca_servicecontrol.svc_timelimit
                    371:                                    > admin_time
                    372:                        ? LSR_ADMINSIZEEXCEEDED
                    373:                        : LSR_TIMELIMITEXCEEDED;
                    374:                    /* should fill out a POQ */
                    375:                    return (DS_OK);
                    376:                }
                    377: 
                    378:                if ((*local)->st_next == NULL_ST) {
                    379:                        st_free (local);
                    380:                        result->CSR_limitproblem = LSR_NOLIMITPROBLEM;
                    381:                        (void) dsa_search_control(arg,result);
                    382:                        return (DS_OK);
                    383:                }
                    384: 
                    385:                (*local) = st_done(local);
                    386:                (*local)->st_size = size;
                    387:                return (DS_SUSPEND);
                    388:        }
                    389: 
                    390: }
                    391: 
                    392: /* 
                    393:  * SEARCH TASK HANDLING 
                    394:  */
                    395: 
                    396: st_comp_free (st)
                    397: struct ds_search_task *st;
                    398: {
                    399:        dn_free (st->st_baseobject);
                    400:        dn_free (st->st_alias);
                    401:        if (st->st_save != NULL_ST)
                    402:                st_free (&st->st_save);
                    403:        free ((char *)st);
                    404: }
                    405: 
                    406: st_free (st)
                    407: struct ds_search_task **st;
                    408: {
                    409: struct ds_search_task *next;
                    410: 
                    411:        for (; (*st) != NULL_ST; (*st) = next) {
                    412:                next = (*st)->st_next;
                    413:                st_comp_free (*st);
                    414:        }
                    415: }
                    416: 
                    417: struct ds_search_task * st_done (st)
                    418: struct ds_search_task **st;
                    419: {
                    420: struct ds_search_task *next;
                    421: 
                    422:        if ((next = (*st)->st_next) == NULL_ST)
                    423:                return NULL_ST;
                    424:        next->st_save = (*st);
                    425:        (*st)->st_next = (*st)->st_save;
                    426:        (*st)->st_save = NULL_ST;
                    427:        return (next);
                    428: }
                    429: 
                    430: 
                    431: 
                    432: /*
                    433:  * CHECK FILTER BEFORE SEARCHING 
                    434:  */
                    435: 
                    436: 
                    437: static check_filter_presrch (fltr,error,dn)
                    438:     register Filter  fltr;
                    439:     struct DSError *error;
                    440:     DN dn;
                    441: {
                    442:        DLOG (log_dsap,LLOG_DEBUG,("in check filter aux"));
                    443: 
                    444:        switch (fltr->flt_type) {
                    445:            case FILTER_ITEM:
                    446:                return (check_filteritem_presrch (&fltr->FUITEM,error,dn));
                    447:            case FILTER_AND:
                    448: #ifndef NO_STATS
                    449:                ps_print (filter_ps,"& ");
                    450: #endif
                    451:                return(check_filterop_presrch (fltr->FUFILT,error,dn));
                    452:            case FILTER_OR:
                    453: #ifndef NO_STATS
                    454:                ps_print (filter_ps,"| ");
                    455: #endif
                    456:                return(check_filterop_presrch (fltr->FUFILT,error,dn));
                    457:            case FILTER_NOT:
                    458: #ifndef NO_STATS
                    459:                ps_print (filter_ps,"! ");
                    460: #endif
                    461:                return(check_filter_presrch (fltr->FUFILT,error,dn));
                    462:            default:
                    463:                LLOG (log_dsap,LLOG_EXCEPTIONS,("check_filter protocol error"));
                    464:                error->dse_type = DSE_SERVICEERROR;
                    465:                error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM;
                    466:                return (NOTOK);
                    467:                }
                    468:        /* NOTREACHED */
                    469: }
                    470: 
                    471: static check_filterop_presrch (fltr,error,dn)
                    472:     register Filter  fltr;
                    473:     struct DSError * error;
                    474:     DN dn;
                    475: {
                    476: register Filter ptr;
                    477: int i;
                    478: 
                    479: #ifndef NO_STATS
                    480:                ps_print (filter_ps,"(");
                    481: #endif
                    482:        DLOG (log_dsap,LLOG_DEBUG,("in filter op aux"));
                    483:        for (ptr=fltr; ptr!=NULLFILTER ; ptr=ptr->flt_next) {
                    484:                i = check_filter_presrch (ptr,error,dn);
                    485:                if (i != OK)
                    486:                        return (NOTOK);
                    487:        }
                    488: #ifndef NO_STATS
                    489:                ps_print (filter_ps,")");
                    490: #endif
                    491:        return (OK);
                    492: 
                    493: }
                    494: 
                    495: 
                    496: static check_filteritem_presrch (fitem,error,dn)
                    497:     register struct filter_item *fitem;
                    498:     struct DSError * error;
                    499:     DN dn;
                    500: {
                    501: int av_acl, av_update, av_schema, av_syntax;
                    502: extern char chrcnv[];
                    503: extern char nochrcnv[];
                    504: 
                    505:        DLOG (log_dsap,LLOG_DEBUG,("search: check filter item aux"));
                    506:        if (fitem == NULLFITEM) {
                    507:                LLOG (log_dsap,LLOG_EXCEPTIONS,("check_filter_item protocol error (1)"));
                    508:                error->dse_type = DSE_SERVICEERROR;
                    509:                error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM;
                    510:                return (NOTOK);
                    511:        }
                    512: 
                    513:        switch ( fitem->fi_type) {
                    514:            case FILTERITEM_APPROX:
                    515:                if (fitem->UNAVA.ava_type == NULLTABLE_ATTR)
                    516:                        return (invalid_matching (fitem->UNAVA.ava_type,error,dn));
                    517: 
                    518:                if ( (fitem->fi_ifp = approxfn (fitem->UNAVA.ava_type->oa_syntax)) == NULLIFP)
                    519:                                /* approx not suported for this type */
                    520:                                /* so set it to equality */
                    521:                        fitem->fi_type = FILTERITEM_EQUALITY;
                    522:                                /* NO break - check equality is OK */
                    523: 
                    524:            case FILTERITEM_EQUALITY:
                    525:            case FILTERITEM_GREATEROREQUAL:
                    526:            case FILTERITEM_LESSOREQUAL:
                    527:                if (fitem->UNAVA.ava_type == NULLTABLE_ATTR)
                    528:                        return (invalid_matching (fitem->UNAVA.ava_type,error,dn));
                    529: 
                    530:                if (fitem->fi_type != FILTERITEM_APPROX)
                    531:                        if ( (fitem->fi_ifp = av_cmp_fn (fitem->UNAVA.ava_type->oa_syntax)) == NULLIFP)
                    532:                                return (invalid_matching (fitem->UNAVA.ava_type,error,dn));
                    533: 
                    534:                av_acl = str2syntax ("acl");
                    535:                av_schema = str2syntax ("schema");
                    536:                av_update = str2syntax ("edbinfo");
                    537:                av_syntax = fitem->UNAVA.ava_type->oa_syntax;
                    538: 
                    539:                if (( av_syntax == av_acl ) 
                    540:                        || (av_syntax == av_schema) 
                    541:                        || (av_syntax == av_update))
                    542:                                return (invalid_matching (fitem->UNAVA.ava_type,error,dn));
                    543:                break;
                    544:            case FILTERITEM_SUBSTRINGS:
                    545:                if (fitem->UNSUB.fi_sub_type == NULLTABLE_ATTR)
                    546:                        return (invalid_matching (fitem->UNSUB.fi_sub_type,error,dn));
                    547: 
                    548:                av_syntax = fitem->UNSUB.fi_sub_type->oa_syntax;
                    549: 
                    550:                if (! sub_string(av_syntax))
                    551:                        return (invalid_matching (fitem->UNSUB.fi_sub_type,error,dn));
                    552: 
                    553:                if ( case_exact_match (av_syntax) ) 
                    554:                        fitem->UNSUB.fi_sub_match = &nochrcnv[0];
                    555:                else 
                    556:                        fitem->UNSUB.fi_sub_match = &chrcnv[0];
                    557:            case FILTERITEM_PRESENT:
                    558:                break;
                    559:            default:
                    560:                LLOG (log_dsap,LLOG_EXCEPTIONS,("check_filter_item protocol error (2)"));
                    561:                error->dse_type = DSE_SERVICEERROR;
                    562:                error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM;
                    563:                return (NOTOK);
                    564:        }
                    565: 
                    566: #ifndef NO_STATS
                    567:        ps_print (filter_ps,"(");
                    568:        switch ( fitem->fi_type) {
                    569:            case FILTERITEM_APPROX:
                    570:                AttrT_print (filter_ps,fitem->UNAVA.ava_type,EDBOUT);
                    571:                ps_print (filter_ps,"~=");
                    572:                AttrV_print (filter_ps,fitem->UNAVA.ava_value,EDBOUT);
                    573:                break;
                    574:            case FILTERITEM_EQUALITY:
                    575:                AttrT_print (filter_ps,fitem->UNAVA.ava_type,EDBOUT);
                    576:                ps_print (filter_ps,"=");
                    577:                AttrV_print (filter_ps,fitem->UNAVA.ava_value,EDBOUT);
                    578:                break;
                    579:            case FILTERITEM_GREATEROREQUAL:
                    580:                AttrT_print (filter_ps,fitem->UNAVA.ava_type,EDBOUT);
                    581:                ps_print (filter_ps,">=");
                    582:                AttrV_print (filter_ps,fitem->UNAVA.ava_value,EDBOUT);
                    583:                break;
                    584:            case FILTERITEM_LESSOREQUAL:
                    585:                AttrT_print (filter_ps,fitem->UNAVA.ava_type,EDBOUT);
                    586:                ps_print (filter_ps,"<=");
                    587:                AttrV_print (filter_ps,fitem->UNAVA.ava_value,EDBOUT);
                    588:                break;
                    589:            case FILTERITEM_SUBSTRINGS:
                    590:                AttrT_print (filter_ps,fitem->UNSUB.fi_sub_type,EDBOUT);
                    591:                ps_print (filter_ps,"=");
                    592:                avs_print_aux (filter_ps,fitem->UNSUB.fi_sub_initial,EDBOUT,"*");
                    593:                ps_print (filter_ps,"*");
                    594:                avs_print_aux (filter_ps,fitem->UNSUB.fi_sub_any,EDBOUT,"*");
                    595:                ps_print (filter_ps,"*");
                    596:                avs_print_aux (filter_ps,fitem->UNSUB.fi_sub_final,EDBOUT,"*");
                    597:                break;
                    598:            case FILTERITEM_PRESENT:
                    599:                AttrT_print (filter_ps,fitem->UNTYPE,EDBOUT);
                    600:                ps_print (filter_ps,"=*");
                    601:                break;
                    602:        }
                    603:        ps_print (filter_ps,")");
                    604: #endif
                    605:        return (OK);
                    606: }
                    607: 
                    608: /* APPLY SEARCH TO ONE LEVEL */
                    609: 
                    610: static apply_search (arg,error,result,local,refer,ismanager)
                    611:     struct ds_search_arg       *arg;
                    612:     struct DSError              *error;
                    613:     struct ds_search_result     *result;
                    614:     struct ds_search_task      **local,
                    615:                                **refer;
                    616:     int        ismanager;
                    617: {
                    618: Entry entryptr;
                    619: EntryInfo  *einfo = NULLENTRYINFO;
                    620: struct di_block        * di_tmp;
                    621: 
                    622:        if ((*local)->st_subset == SRA_BASEOBJECT)
                    623:        {
                    624:                if ((*local)->st_baseobject == NULLDN) {
                    625:                        LLOG (log_dsap,LLOG_NOTICE,("NULL Base in search ignored"));
                    626:                                /* to stop poisoning... */
                    627:                        return (DS_OK);
                    628:                }
                    629:                switch(find_entry((*local)->st_baseobject,&(arg->sra_common),NULLDN,NULLDNSEQ,FALSE,&(entryptr), error, &(di_tmp)))
                    630:                {
                    631:                case DS_OK:
                    632:                    /* Filled out entryptr - carry on */
                    633:                    break;
                    634:                case DS_CONTINUE:
                    635:                    /* Filled out di_p - what do we do with it ?? */
                    636:                    subtask_refer(arg, local, refer, ismanager, di_tmp);
                    637:                    return(DS_OK);
                    638: 
                    639:                case DS_X500_ERROR:
                    640:                    /* Filled out error - what do we do with it ?? */
                    641:                    /* The only problem can be alias error etc */
                    642:                    /* to stop poisoning return OK */   
                    643:                    log_ds_error (error);
                    644:                    ds_error_free (error);
                    645:                    return (DS_OK);
                    646:                default:
                    647:                    /* SCREAM */
                    648:                    LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_search() - find_entry failed 2"));
                    649:                    return(DS_ERROR_LOCAL);
                    650:                }
                    651:        }
                    652:        else
                    653:        {
                    654:                switch(find_child_entry((*local)->st_baseobject,&(arg->sra_common),NULLDN,NULLDNSEQ,FALSE,&(entryptr), error, &(di_tmp)))
                    655:                {
                    656:                case DS_OK:
                    657:                    /* Filled out entryptr - carry on */
                    658:                    break;
                    659:                case DS_CONTINUE:
                    660:                    /* Filled out di_p - what do we do with it ?? */
                    661:                    subtask_refer(arg, local, refer, ismanager, di_tmp);
                    662:                    return(DS_OK);
                    663: 
                    664:                case DS_X500_ERROR:
                    665:                    /* Filled out error - what do we do with it ?? */
                    666:                    /* The only problem can be alias error etc */
                    667:                    /* to stop poisoning return OK */   
                    668:                    log_ds_error (error);
                    669:                    return (DS_OK);
                    670:                default:
                    671:                    /* SCREAM */
                    672:                    LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_search() - find_child_entry failed 2"));
                    673:                    return(DS_ERROR_LOCAL);
                    674:                }
                    675: 
                    676:                if ((*local)->st_subset == SRA_WHOLESUBTREE) {
                    677:                 if (entryptr->e_data != E_TYPE_CONSTRUCTOR) {
                    678:                   if ((*local)->st_alias) {
                    679:                        if ((einfo = filterentry (arg,entryptr)) != NULLENTRYINFO) {
                    680:                                (*local)->st_size--;
                    681:                                if (result->CSR_entries == NULLENTRYINFO)
                    682:                                        result->CSR_entries = einfo;
                    683:                                else
                    684:                                        entryinfo_merge (result->CSR_entries,einfo);
                    685:                        }
                    686:                   }
                    687:                 } else {
                    688:                        do_base (entryptr,local);
                    689:                 }
                    690:                }
                    691:        }
                    692: 
                    693:        switch ((*local)->st_subset) {
                    694:                case SRA_BASEOBJECT:
                    695:                        einfo = filterentry (arg,entryptr);
                    696:                        break;
                    697:                case SRA_ONELEVEL:
                    698:                case SRA_WHOLESUBTREE:  
                    699:                        einfo = filterchildren (arg,entryptr,local,refer,(*local)->st_subset,ismanager);
                    700:                        break;
                    701:                default:
                    702:                        LLOG (log_dsap,LLOG_EXCEPTIONS,("search protocol error"));
                    703:                        error->dse_type = DSE_SERVICEERROR;
                    704:                        error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM;
                    705:                        return (DS_X500_ERROR);
                    706:                }
                    707: 
                    708:        if (einfo != NULLENTRYINFO)
                    709:                if (result->CSR_entries == NULLENTRYINFO)
                    710:                        result->CSR_entries = einfo;
                    711:                else
                    712:                        entryinfo_merge (result->CSR_entries,einfo);
                    713: 
                    714:        result->CSR_common.cr_requestor = NULLDN;
                    715:        return (DS_OK);
                    716: }
                    717: 
                    718: /* 
                    719:  * SEARCH CHILDREN
                    720:  */
                    721: 
                    722: static EntryInfo * filterchildren (arg,entryptr,local,refer,extent, ismanager)
                    723:     struct ds_search_arg        *arg;
                    724:     Entry  entryptr;
                    725:     struct ds_search_task      **local,
                    726:                                **refer;
                    727:     int    extent;
                    728:     int           ismanager;
                    729: {
                    730: EntryInfo  *einfo = NULLENTRYINFO;
                    731: EntryInfo  *eptr = NULLENTRYINFO;
                    732: register Entry ptr;
                    733: register Entry cptr;
                    734: struct ds_search_task  * new_task;
                    735: register int tmp;
                    736: char     domore = TRUE;
                    737: 
                    738:        DLOG (log_dsap,LLOG_DEBUG,("search: filter children"));
                    739: 
                    740:        if (entryptr == NULLENTRY)
                    741:                return (NULLENTRYINFO);
                    742: 
                    743:        if (entryptr->e_leaf)
                    744:                return (NULLENTRYINFO);
                    745: 
                    746:        if (check_acl (NULLDN, ACL_READ, entryptr->e_acl->ac_child, (*local)->st_baseobject) == NOTOK) {
                    747:                return (NULLENTRYINFO);
                    748:        }
                    749: 
                    750:        if (entryptr->e_alias != NULLDN) {
                    751:                (void) do_alias (arg,entryptr,local);
                    752:                return (NULLENTRYINFO);
                    753:        }
                    754: 
                    755:        ptr = entryptr->e_child;
                    756: 
                    757:        if (((ptr != NULLENTRY) && (entryptr->e_allchildrenpresent == FALSE))
                    758:                || (ptr == NULLENTRY)) {
                    759:                search_refer (arg,entryptr,local,refer,ismanager);
                    760:                return (NULLENTRYINFO);
                    761:        }
                    762: 
                    763:        /* search everything at this level */
                    764:        for (tmp=0; (ptr != NULLENTRY) && (size >= 0) ; ptr=ptr->e_sibling,tmp++) {
                    765: 
                    766:                if ((ptr->e_alias != NULLDN) && 
                    767:                        (do_alias (arg,ptr,local) == OK))
                    768:                                continue;
                    769: 
                    770:                eptr = filterentry (arg,ptr);
                    771: 
                    772:                if ((eptr != NULLENTRYINFO) && (size != -1))
                    773:                        if (einfo == NULLENTRYINFO)
                    774:                                einfo =  eptr;
                    775:                        else
                    776:                                entryinfo_merge (einfo,eptr);
                    777: 
                    778:                if ( tmp > SEARCH_DELTA_SIZE ) {
                    779:                        if (timelimit <= (timenow = time ((time_t *)0))) 
                    780:                                return (einfo);
                    781:                        tmp = 0;
                    782:                        domore = FALSE;
                    783:                }
                    784:        }
                    785: 
                    786:        if (size < 0)
                    787:                return (einfo);
                    788: 
                    789:        if (domore)
                    790:                /* Heuristic - should tailor it eventually */
                    791:                domore = (tmp < (SEARCH_DELTA_SIZE / 5));
                    792: 
                    793:        if (extent == SRA_WHOLESUBTREE) {
                    794:            /* search below - or make pointers */
                    795:            ptr=entryptr->e_child;
                    796: 
                    797:            for (; (ptr != NULLENTRY) && (size >= 0) ; ptr=ptr->e_sibling) {
                    798: 
                    799:                if (ptr->e_leaf)
                    800:                        continue;
                    801: 
                    802:                if (domore) {
                    803:                        /* search one more level */
                    804:                        if (check_acl (NULLDN, ACL_READ, ptr->e_acl->ac_child, NULLDN) == NOTOK) 
                    805:                                continue;
                    806:                
                    807:                        cptr = ptr->e_child;
                    808: 
                    809:                        if (((cptr != NULLENTRY) && (ptr->e_allchildrenpresent == FALSE))
                    810:                                || (cptr == NULLENTRY)) {
                    811:                                search_refer (arg,ptr,local,refer,ismanager);
                    812:                                continue;
                    813:                                }
                    814: 
                    815:                        /* search everything at this level */
                    816:                        for (tmp=0; (cptr != NULLENTRY) && (size >= 0) ; cptr=cptr->e_sibling,tmp++) {
                    817: 
                    818:                                if (cptr->e_leaf) {
                    819: 
                    820:                                        if ((cptr->e_alias != NULLDN) && 
                    821:                                                (do_alias (arg,cptr,local) == OK))
                    822:                                                continue;
                    823: 
                    824:                                        eptr = filterentry (arg,cptr);
                    825: 
                    826:                                        if ((eptr != NULLENTRYINFO) && (size != -1))
                    827:                                                if (einfo == NULLENTRYINFO)
                    828:                                                        einfo =  eptr;
                    829:                                                else
                    830:                                                        entryinfo_merge (einfo,eptr);
                    831:                                } else {
                    832:                                        new_task = st_alloc();
                    833:                                        new_task->st_save = NULL_ST;
                    834:                                        new_task->st_baseobject = get_copy_dn (cptr);
                    835:                                        new_task->st_size = 0;  /* fill in later */
                    836:                                        new_task->st_alias = NULLDN;
                    837:                                        new_task->st_subset = SRA_WHOLESUBTREE;
                    838:                                        new_task->st_next = (*local)->st_next;
                    839:                                        new_task->st_entryonly = FALSE;
                    840:                                        (*local)->st_next = new_task;
                    841:                                }
                    842: 
                    843:                                if ( tmp > SEARCH_DELTA_SIZE ) {
                    844:                                        if (timelimit <= (timenow = time ((time_t *)0))) 
                    845:                                                return (einfo);
                    846:                                        tmp = 0;
                    847:                                }
                    848:                        }
                    849:                        if (timelimit <= (timenow = time ((time_t *)0))) 
                    850:                                return (einfo);
                    851: 
                    852:                        dsa_wait (0);   /* progress any other connections */
                    853:                } else {
                    854:                        new_task = st_alloc();
                    855:                        new_task->st_save = NULL_ST;
                    856:                        new_task->st_baseobject = get_copy_dn (ptr);
                    857:                        new_task->st_size = 0;  /* fill in later */
                    858:                        new_task->st_alias = NULLDN;
                    859:                        new_task->st_subset = SRA_WHOLESUBTREE;
                    860:                        new_task->st_next = (*local)->st_next;
                    861:                        new_task->st_entryonly = FALSE;
                    862:                        (*local)->st_next = new_task;
                    863:                }
                    864:            }
                    865:        }
                    866: 
                    867:        return (einfo);
                    868: }
                    869: 
                    870: /* 
                    871:  * HANDLE ALIASES AND REFERRALS
                    872:  */
                    873: 
                    874: static do_alias (arg,eptr,local)
                    875:     struct ds_search_arg        *arg;
                    876:     Entry eptr;
                    877:     struct ds_search_task      **local;
                    878: {
                    879: struct ds_search_task *new_task;
                    880: struct ds_search_task *st;
                    881: DN st_dn;
                    882: 
                    883:        if ( ! arg->sra_searchaliases) 
                    884:                return NOTOK;
                    885: 
                    886:        DLOG (log_dsap,LLOG_DEBUG,("alias in search path"));
                    887: 
                    888:        /* Check we have not been here before... */
                    889:        for ( st = (*local)->st_save; st != NULL_ST; st=st->st_next) {
                    890:                if (st->st_alias == NULLDN) 
                    891:                        st_dn = st->st_baseobject;
                    892:                else 
                    893:                        st_dn = st->st_alias;
                    894:                if (dn_cmp (eptr->e_alias, st_dn) == 0) {
                    895:                        LLOG (log_dsap,LLOG_TRACE,("local search - loop detected"));
                    896:                        return OK;
                    897:                }
                    898:        }
                    899: 
                    900:        new_task = st_alloc();
                    901:        new_task->st_save = NULL_ST;
                    902:        new_task->st_baseobject = get_copy_dn (eptr);
                    903:        new_task->st_size = 0;  /* fill in later */
                    904:        new_task->st_alias = dn_cpy(eptr->e_alias);
                    905:        new_task->st_entryonly = FALSE;
                    906: 
                    907:        switch ((*local)->st_subset) {
                    908:        case SRA_ONELEVEL:
                    909:                new_task->st_entryonly = TRUE;
                    910:                /* fall */
                    911:        case SRA_BASEOBJECT:
                    912:                new_task->st_subset = SRA_BASEOBJECT;
                    913:                break;
                    914:        case SRA_WHOLESUBTREE:
                    915:                new_task->st_subset = SRA_WHOLESUBTREE;
                    916:                break;
                    917:        }
                    918: 
                    919:        new_task->st_next = (*local)->st_next;
                    920:        (*local)->st_next = new_task;
                    921: 
                    922:        return (OK);
                    923: }
                    924: 
                    925: static do_base (eptr,local)
                    926:     Entry eptr;
                    927:     struct ds_search_task      **local;
                    928: {
                    929: struct ds_search_task *new_task;
                    930: 
                    931:        DLOG (log_dsap,LLOG_DEBUG,("Making baseobject search"));
                    932: 
                    933:        new_task = st_alloc();
                    934:        new_task->st_save = NULL_ST;
                    935:        new_task->st_baseobject = get_copy_dn (eptr); 
                    936:        new_task->st_size = 0;  /* fill in later */
                    937:        new_task->st_alias = NULLDN;
                    938:        new_task->st_entryonly = TRUE;          /* If is a subtree search we are breaking protocol here */
                    939:                                                /* BUT... There is no other way to do it !!! */
                    940:        new_task->st_subset = SRA_BASEOBJECT;
                    941:        new_task->st_next = (*local)->st_next;
                    942:        (*local)->st_next = new_task;
                    943: }
                    944: 
                    945: static search_refer(arg,entryptr,local,refer,ismanager)
                    946:     struct ds_search_arg        *arg;
                    947:     Entry  entryptr;
                    948:     struct ds_search_task      **local,
                    949:                                **refer;
                    950:     int            ismanager;
                    951: {
                    952: struct ds_search_task  * new_task;
                    953: struct DSError           error;
                    954: struct di_block                * di_tmp;
                    955: DN name;       
                    956: 
                    957:        name = get_copy_dn (entryptr);
                    958: 
                    959:        switch(dsa_info_new(name, NULLDNSEQ, FALSE, entryptr, &(error), &(di_tmp)))
                    960:        {
                    961:        case DS_OK:
                    962:            /* A di_block ready for use */
                    963:            break;
                    964:        case DS_CONTINUE:
                    965:            /* A deferred di_block */
                    966:            break;
                    967:        case DS_X500_ERROR:
                    968:            /* An error */
                    969:            LLOG(log_dsap, LLOG_EXCEPTIONS, ("search_refer - dsa_info_new() generated x500 error"));
                    970:            log_ds_error(&(error));
                    971:            ds_error_free(&(error));
                    972:            dn_free (name);
                    973:            return;
                    974:        default:
                    975:            /* A local error - scream */
                    976:            LLOG(log_dsap, LLOG_EXCEPTIONS, ("search_refer - dsa_info_new() failed"));
                    977:            dn_free (name);
                    978:            return;
                    979:        }
                    980: 
                    981:        DLOG (log_dsap,LLOG_DEBUG,("referral in search path"));
                    982: 
                    983:        new_task = st_alloc();
                    984:        new_task->st_save = NULL_ST;
                    985:        new_task->st_baseobject = name;
                    986:        new_task->st_subset = (*local)->st_subset;
                    987:        new_task->st_alias = NULLDN;
                    988:        new_task->st_entryonly = (*local)->st_entryonly;
                    989:        if (ismanager) {
                    990:            if ((new_task->st_size = arg->sra_common.ca_servicecontrol.svc_sizelimit) == SVC_NOSIZELIMIT)
                    991:                new_task->st_size = big_size;
                    992:        }
                    993:        else
                    994:            if ((new_task->st_size = MIN(admin_size,arg->sra_common.ca_servicecontrol.svc_sizelimit)) == SVC_NOSIZELIMIT)
                    995:                new_task->st_size = admin_size;
                    996: 
                    997:        new_task->st_di = di_tmp;
                    998:        new_task->st_next = *refer;
                    999:        *refer = new_task;
                   1000: }
                   1001: 
                   1002: /*
                   1003:  * SEARCH ENTRY
                   1004:  */  
                   1005: 
                   1006: static EntryInfo * filterentry (arg,entryptr)
                   1007:     struct ds_search_arg        *arg;
                   1008:     register Entry entryptr;
                   1009: {
                   1010: register EntryInfo * einfo;
                   1011: 
                   1012:        DLOG (log_dsap,LLOG_DEBUG,("search: filter entry"));
                   1013: 
                   1014:        if (check_filter (arg->sra_filter,entryptr) != OK ) {
                   1015:                DLOG (log_dsap,LLOG_DEBUG,("none found"));
                   1016:                return (NULLENTRYINFO);
                   1017:        }
                   1018: 
                   1019:        einfo = entryinfo_alloc ();
                   1020:        einfo->ent_dn = get_copy_dn (entryptr);
                   1021: 
                   1022:        if (check_acl (NULLDN, ACL_READ, entryptr->e_acl->ac_entry, NULLDN) == NOTOK) 
                   1023:                return (NULLENTRYINFO);
                   1024: 
                   1025:        einfo->ent_attr = eis_select (arg->sra_eis, entryptr, NULLDN, qctx && arg->sra_eis.eis_allattributes);
                   1026: 
                   1027:        einfo->ent_iscopy = entryptr->e_data;
                   1028:        einfo->ent_age = (time_t) 0;
                   1029:        einfo->ent_next = NULLENTRYINFO;
                   1030:        size--;
                   1031:        return (einfo);
                   1032: }
                   1033: 
                   1034: /* 
                   1035:  * TEST FILTER AGAINST SINGLE ENTRY
                   1036:  */
                   1037: 
                   1038: static check_filter (fltr,entryptr)
                   1039:     register Filter  fltr;
                   1040:     register Entry  entryptr;
                   1041: {
                   1042: register int i;
                   1043: 
                   1044:        DLOG (log_dsap,LLOG_DEBUG,("in check filter"));
                   1045:        switch (fltr->flt_type) {
                   1046:            case FILTER_ITEM:
                   1047:                return (check_filteritem (&fltr->FUITEM,entryptr));
                   1048:            case FILTER_AND:
                   1049:            case FILTER_OR:
                   1050:                return(check_filterop (fltr->FUFILT,entryptr,fltr->flt_type));
                   1051:            case FILTER_NOT:
                   1052:                if ((i=check_filter (fltr->FUFILT,entryptr)) == OK)
                   1053:                        return NOTOK;
                   1054:                else if ( i == NOTOK )
                   1055:                        return OK;
                   1056:                else
                   1057:                        return i;
                   1058:                }
                   1059:        /* NOTREACHED */
                   1060: }
                   1061: 
                   1062: static check_filterop (fltr,entryptr,op)
                   1063:     register Filter  fltr;
                   1064:     register Entry  entryptr;
                   1065:     int op;
                   1066: {
                   1067: register Filter ptr;
                   1068: int result;
                   1069: 
                   1070:        DLOG (log_dsap,LLOG_DEBUG,("in filter op"));
                   1071: 
                   1072:        /* effect of applying logical operator to zero operands */
                   1073:        if (op == FILTER_OR)
                   1074:                result = NOTOK;
                   1075:        else
                   1076:                result = OK;
                   1077: 
                   1078:        for (ptr=fltr; ptr!=NULLFILTER ; ptr=ptr->flt_next)
                   1079:                switch (check_filter (ptr,entryptr)) {
                   1080:                        case MAYBE:
                   1081: /* Beware of 'Pathological NOT' here.
                   1082:  * To comply with the December '88 X.500, should just drop through here.
                   1083:  * For the security to work properly, also set result to MAYBE.
                   1084:  */
                   1085:                                result = MAYBE;
                   1086:                                break;
                   1087:                        case OK:
                   1088:                                if (op == FILTER_OR) {
                   1089:                                        DLOG (log_dsap,LLOG_DEBUG,("or ok"));
                   1090:                                        return (OK);
                   1091:                                }
                   1092:                                break;
                   1093:                        case NOTOK:
                   1094:                                if (op == FILTER_AND) {
                   1095:                                        DLOG (log_dsap,LLOG_DEBUG,("and not"));
                   1096:                                        return (NOTOK);
                   1097:                                }
                   1098:                                break;
                   1099:                        case -2:
                   1100:                        default:
                   1101:                                return (-2);
                   1102:                }
                   1103: 
                   1104: 
                   1105:        return (result);
                   1106: }
                   1107: 
                   1108: /* 
                   1109:  * CHECK FILTER ITEM AGAINST ENTRY 
                   1110:  */
                   1111: 
                   1112: static check_filteritem (fitem,entryptr)
                   1113:     register struct filter_item *fitem;
                   1114:     register Entry  entryptr;
                   1115: {
                   1116: register Attr_Sequence as;
                   1117: AttributeType at;
                   1118: 
                   1119:        DLOG (log_dsap,LLOG_DEBUG,("search: check filter item"));
                   1120: 
                   1121:        switch ( fitem->fi_type) {
                   1122:            case FILTERITEM_APPROX:
                   1123:            case FILTERITEM_EQUALITY:
                   1124:            case FILTERITEM_GREATEROREQUAL:
                   1125:            case FILTERITEM_LESSOREQUAL:
                   1126:                at = fitem->UNAVA.ava_type;
                   1127:                break;
                   1128:            case FILTERITEM_SUBSTRINGS:
                   1129:                at = fitem->UNSUB.fi_sub_type;
                   1130:                break;
                   1131:            case FILTERITEM_PRESENT:
                   1132:                if ((as = as_find_type (entryptr->e_attributes, fitem->UNTYPE)) == NULLATTR) 
                   1133:                        return NOTOK;
                   1134:                else
                   1135:                        return OK;
                   1136:        }
                   1137: 
                   1138:        if ((as = as_find_type (entryptr->e_attributes, at)) == NULLATTR) 
                   1139:                return MAYBE;
                   1140: 
                   1141:        if ( check_acl (NULLDN,ACL_COMPARE,as->attr_acl,NULLDN) != OK)
                   1142:                return MAYBE;  
                   1143: 
                   1144:        switch ( fitem->fi_type) {
                   1145:            case FILTERITEM_SUBSTRINGS:
                   1146:                return (substr_search (fitem,as->attr_value));
                   1147:            case FILTERITEM_APPROX:
                   1148:                return ((int)(*fitem->fi_ifp)(fitem,as->attr_value));
                   1149:            default:
                   1150:                return (test_avs (fitem,as->attr_value,fitem->fi_type));
                   1151:        }
                   1152:        /* NOTREACHED */
                   1153: }
                   1154: 
                   1155: static test_avs (fitem,avs,mode)
                   1156:     register struct filter_item *fitem;
                   1157:     register AV_Sequence avs;
                   1158:     register int mode;
                   1159: {
                   1160: 
                   1161:        for (; avs != NULLAV; avs=avs->avseq_next) {
                   1162:                switch (((int)(*fitem->fi_ifp)(avs->avseq_av.av_struct, fitem->UNAVA.ava_value->av_struct))) {
                   1163:                        case 0:
                   1164:                                return (OK);
                   1165:                        case 1:
                   1166:                                if (mode == FILTERITEM_GREATEROREQUAL)
                   1167:                                        return (OK);
                   1168:                                break;
                   1169:                        case -1:
                   1170:                                if (mode == FILTERITEM_LESSOREQUAL)
                   1171:                                        return (OK);
                   1172:                                break;
                   1173:                        case 2:
                   1174:                                return (NOTOK);
                   1175:                        default:
                   1176:                                return (MAYBE);
                   1177:                }
                   1178:        }
                   1179:        return (NOTOK);
                   1180: }
                   1181: 
                   1182: 
                   1183: /*
                   1184:  * SUBSTRING MATCH 
                   1185:  */
                   1186: 
                   1187: static substr_search (fitem,avs)
                   1188:     register struct filter_item *fitem;
                   1189:     register AV_Sequence avs;
                   1190: {
                   1191: 
                   1192:        for (; avs != NULLAV; avs=avs->avseq_next)
                   1193:                if (aux_substr_search (fitem,avs,fitem->UNSUB.fi_sub_match) == OK)
                   1194:                        return (OK);
                   1195:        return (NOTOK);
                   1196: }
                   1197: 
                   1198: 
                   1199: 
                   1200: static aux_substr_search (fitem,avs,chrmatch)
                   1201:     struct filter_item *fitem;
                   1202:     AV_Sequence avs;
                   1203:     char chrmatch [];
                   1204: {
                   1205: register AV_Sequence loopavs;
                   1206: register char * compstr;
                   1207: char * top;
                   1208: register char * temp;
                   1209: char * temp2;
                   1210: int offset;
                   1211: 
                   1212:        compstr = (char *)avs->avseq_av.av_struct;
                   1213:        top  = compstr;
                   1214:        if (fitem->UNSUB.fi_sub_initial != NULLAV) {
                   1215:                temp = (char *)fitem->UNSUB.fi_sub_initial->avseq_av.av_struct;
                   1216:                do
                   1217:                        if (chrmatch[*compstr++] != chrmatch[*temp++]) {
                   1218:                                DLOG (log_dsap,LLOG_DEBUG,("initial failure (%s, %s)",top,(char *)fitem->UNSUB.fi_sub_initial->avseq_av.av_struct));
                   1219:                                return (NOTOK);
                   1220:                        }
                   1221:                while (*temp != '\0') ;
                   1222:        }
                   1223: 
                   1224:        for (loopavs=fitem->UNSUB.fi_sub_any; loopavs!=NULLAV; loopavs=loopavs->avseq_next, compstr += offset)
                   1225:                if ((offset= attr_substr (compstr, &loopavs->avseq_av,chrmatch)) == -1) {
                   1226:                        DLOG (log_dsap,LLOG_DEBUG,("any failure (%s, %s)",top,(char *)loopavs->avseq_av.av_struct));
                   1227:                        return (NOTOK);
                   1228:                }
                   1229: 
                   1230:        if (fitem->UNSUB.fi_sub_final != NULLAV) {
                   1231:                temp = (char *)fitem->UNSUB.fi_sub_final->avseq_av.av_struct;
                   1232:                temp2 = temp;
                   1233:                while (*++compstr != '\0')
                   1234:                        ;  /* NO-OP*/
                   1235: 
                   1236:                while (*temp++ != '\0')
                   1237:                        compstr--;
                   1238: 
                   1239:                if (compstr < top) {
                   1240:                        DLOG (log_dsap,LLOG_DEBUG,("final too long failure (%s,%s)",top,temp2));
                   1241:                        return (NOTOK);
                   1242:                }
                   1243: 
                   1244:                temp = temp2;
                   1245:                while (*compstr != '\0')
                   1246:                        if (chrmatch[*compstr++] != chrmatch[*temp++]) {
                   1247:                                /* free (top); */
                   1248:                                DLOG (log_dsap,LLOG_DEBUG,("final failure (%s, %s)",top,temp2));
                   1249:                                return (NOTOK);
                   1250:                        }
                   1251:        }
                   1252:        return (OK);
                   1253: }
                   1254: 
                   1255: attr_substr (str1,av,chrmatch)
                   1256: register char * str1;
                   1257: AttributeValue av;
                   1258: char chrmatch[];
                   1259: {
                   1260: register char * str2;
                   1261: register int count;
                   1262: char * top;
                   1263: int found = 0;
                   1264: int slen;
                   1265: 
                   1266:     top = str1;
                   1267:     str2 = (char *)av->av_struct;
                   1268: 
                   1269:     while (*str1 != '\0') {
                   1270:        if (chrmatch[*str1++] == chrmatch[*str2]) {
                   1271:                str2++;
                   1272:                found = 1;
                   1273:                break;
                   1274:        }
                   1275:     }
                   1276: 
                   1277:     if ( found == 0 )
                   1278:        return (-1);
                   1279: 
                   1280:     slen = strlen (str2) + 1;
                   1281:     for (count = 1; count < slen ; count ++) {
                   1282:        if (*str1 == '\0')
                   1283:            return (-1);
                   1284: 
                   1285:        if (chrmatch[*str1++] != chrmatch[*str2++]) {
                   1286:                /* not found here, but may still be in the string !! */
                   1287:                str1 -= count;
                   1288:                str2 -= count + 1;
                   1289:                while (*str1 != '\0') {
                   1290:                        if (chrmatch[*str1++] == chrmatch[*str2]) {
                   1291:                                str2++;
                   1292:                                break;
                   1293:                        }
                   1294:                }
                   1295:                count = 0;  /* for loop ++ will make it 1 !!! */
                   1296:        }
                   1297:     }
                   1298:     return (str1 - top);
                   1299: }
                   1300: 
                   1301: 
                   1302: subtask_refer(arg, local, refer, ismanager, di)
                   1303:     struct ds_search_arg       *arg;
                   1304:     struct ds_search_task      **local,
                   1305:                                **refer;
                   1306:     int        ismanager;
                   1307:     struct di_block            * di;
                   1308: {
                   1309:        /* turn query into a referral */
                   1310:        struct ds_search_task   * new_task;
                   1311:                
                   1312:        new_task = st_alloc();
                   1313:        new_task->st_save = NULL_ST;
                   1314:        new_task->st_baseobject = dn_cpy ((*local)->st_baseobject);
                   1315:        new_task->st_subset = (*local)->st_subset;
                   1316:        new_task->st_alias = dn_cpy ((*local)->st_alias);
                   1317:        new_task->st_entryonly = (*local)->st_entryonly;
                   1318: 
                   1319:        if (ismanager) {
                   1320:            if ((new_task->st_size = arg->sra_common.ca_servicecontrol.svc_sizelimit) == SVC_NOSIZELIMIT)
                   1321:                new_task->st_size = big_size;
                   1322:        }
                   1323:        else
                   1324:            if ((new_task->st_size = MIN(admin_size,arg->sra_common.ca_servicecontrol.svc_sizelimit)) == SVC_NOSIZELIMIT)
                   1325:                new_task->st_size = admin_size;
                   1326: 
                   1327:        new_task->st_di = di;
                   1328:        new_task->st_next = *refer;
                   1329:        *refer = new_task;
                   1330: }
                   1331: 
                   1332: dsa_search_control (arg,result)
                   1333:     struct ds_search_arg          *arg;
                   1334:     struct ds_search_result       *result;
                   1335: {
                   1336: extern DN mydsadn;
                   1337: char buffer [LINESIZE];
                   1338: Attr_Sequence as;
                   1339: extern AttributeType at_control;
                   1340: int i;
                   1341: 
                   1342:        if (big_size == 0)
                   1343:            for (i = NBBY * sizeof big_size - 1; i > 0; i--)
                   1344:                big_size <<= 1, big_size |= 1;
                   1345: 
                   1346:        if ((arg->sra_eis.eis_allattributes) || 
                   1347:                (arg->sra_eis.eis_infotypes == EIS_ATTRIBUTETYPESONLY))
                   1348:                return FALSE;
                   1349: 
                   1350:        if (arg->sra_eis.eis_select == NULLATTR)
                   1351:                return FALSE;
                   1352: 
                   1353:        if (arg->sra_eis.eis_select->attr_link != NULLATTR)
                   1354:                return FALSE;
                   1355: 
                   1356:        if (AttrT_cmp (at_control,arg->sra_eis.eis_select->attr_type) != 0)
                   1357:                return FALSE;
                   1358: 
                   1359:        if (result->CSR_entries)
                   1360:                entryinfo_free (result->CSR_entries,0);
                   1361: 
                   1362:        (void) sprintf (buffer,"%d",big_size-size);
                   1363: 
                   1364:        as=as_comp_alloc();
                   1365:        as->attr_acl = NULLACL_INFO;
                   1366:        as->attr_type = at_control;
                   1367:        as->attr_link = NULLATTR;
                   1368:         if ((as->attr_value = str2avs (buffer,as->attr_type)) == NULLAV) {
                   1369:                 as_free (as);
                   1370:                result->CSR_entries = NULLENTRYINFO;
                   1371:                 return FALSE;
                   1372:        }
                   1373: 
                   1374:        result->CSR_entries = entryinfo_alloc ();
                   1375:        result->CSR_entries->ent_dn = dn_cpy (mydsadn);
                   1376:        result->CSR_entries->ent_next = NULLENTRYINFO;
                   1377:        result->CSR_entries->ent_age = (time_t) 0;
                   1378:        result->CSR_entries->ent_iscopy = TRUE;
                   1379:        result->CSR_entries->ent_attr = as;
                   1380: 
                   1381:        return TRUE;
                   1382: }

unix.superglobalmegacorp.com

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