|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.