Annotation of 43BSDReno/contrib/isode-beta/quipu/ds_search.c, revision 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.