filter.c 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. *
  6. * License: GPL (version 3 or any later version).
  7. * See LICENSE for details.
  8. * END COPYRIGHT BLOCK **/
  9. #ifdef HAVE_CONFIG_H
  10. # include <config.h>
  11. #endif
  12. /* filter.c - routines for parsing and dealing with filters */
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <sys/types.h>
  16. #include <sys/socket.h>
  17. #include "slap.h"
  18. #include "slapi-plugin.h"
  19. static int
  20. get_filter_list( Connection *conn, BerElement *ber,
  21. struct slapi_filter **f, char **fstr, int maxdepth, int curdepth,
  22. int *subentry_dont_rewrite, int *has_tombstone_filter, int *has_ruv_filter);
  23. static int get_substring_filter();
  24. static int get_extensible_filter( BerElement *ber, mr_filter_t* );
  25. static int get_filter_internal( Connection *conn, BerElement *ber,
  26. struct slapi_filter **filt, char **fstr, int maxdepth, int curdepth,
  27. int *subentry_dont_rewrite, int *has_tombstone_filter, int *has_ruv_filter);
  28. static int tombstone_check_filter(Slapi_Filter *f);
  29. static int ruv_check_filter(Slapi_Filter *f);
  30. static void filter_optimize(Slapi_Filter *f);
  31. /*
  32. * Read a filter off the wire and create a slapi_filter and string representation.
  33. * Both filt and fstr are allocated by this function, so must be freed by the caller.
  34. *
  35. * If the scope is not base and (objectclass=ldapsubentry) does not occur
  36. * in the filter then we add (!(objectclass=ldapsubentry)) to the filter
  37. * so that subentries are not returned.
  38. * If the scope is base or (objectclass=ldapsubentry) occurs in the filter,
  39. * then the caller is explicitly handling subentries himself and so we leave
  40. * the filter as is.
  41. */
  42. int
  43. get_filter( Connection *conn, BerElement *ber, int scope,
  44. struct slapi_filter **filt, char **fstr )
  45. {
  46. int subentry_dont_rewrite = 0; /* Re-write unless we're told not to */
  47. int has_tombstone_filter = 0; /* Check if nsTombstone appears */
  48. int has_ruv_filter = 0; /* Check if searching for RUV */
  49. int return_value = 0;
  50. char *logbuf = NULL;
  51. size_t logbufsize = 0;
  52. return_value = get_filter_internal(conn, ber, filt, fstr,
  53. config_get_max_filter_nest_level(), /* maximum depth */
  54. 0, /* current depth */ &subentry_dont_rewrite,
  55. &has_tombstone_filter, &has_ruv_filter);
  56. if (0 == return_value) { /* Don't try to re-write if there was an error */
  57. if (subentry_dont_rewrite || scope == LDAP_SCOPE_BASE)
  58. (*filt)->f_flags |= SLAPI_FILTER_LDAPSUBENTRY;
  59. if (has_tombstone_filter)
  60. (*filt)->f_flags |= SLAPI_FILTER_TOMBSTONE;
  61. if (has_ruv_filter)
  62. (*filt)->f_flags |= SLAPI_FILTER_RUV;
  63. }
  64. if (LDAPDebugLevelIsSet( LDAP_DEBUG_FILTER ) && *filt != NULL
  65. && *fstr != NULL) {
  66. logbufsize = strlen(*fstr) + 1;
  67. logbuf = slapi_ch_malloc(logbufsize);
  68. *logbuf = '\0';
  69. slapi_log_error( SLAPI_LOG_FATAL, "get_filter", "before optimize: %s\n",
  70. slapi_filter_to_string(*filt, logbuf, logbufsize));
  71. }
  72. filter_optimize(*filt);
  73. if (NULL != logbuf) {
  74. slapi_log_error( SLAPI_LOG_FATAL, "get_filter", " after optimize: %s\n",
  75. slapi_filter_to_string(*filt, logbuf, logbufsize));
  76. slapi_ch_free_string( &logbuf );
  77. }
  78. return return_value;
  79. }
  80. #define FILTER_EQ_FMT "(%s=%s%s)"
  81. #define FILTER_GE_FMT "(%s>=%s%s)"
  82. #define FILTER_LE_FMT "(%s<=%s%s)"
  83. #define FILTER_APROX_FMT "(%s~=%s%s)"
  84. #define FILTER_EXTENDED_FMT "(%s%s%s%s:=%s%s)"
  85. #define FILTER_EQ_LEN 4
  86. #define FILTER_GE_LEN 5
  87. #define FILTER_LE_LEN 5
  88. #define FILTER_APROX_LEN 5
  89. /* returns escaped filter string for extended filters only*/
  90. static char *
  91. filter_escape_filter_value_extended(struct slapi_filter *f)
  92. {
  93. char *ptr;
  94. ptr = slapi_filter_sprintf(FILTER_EXTENDED_FMT,
  95. f->f_mr_type ? f->f_mr_type : "",
  96. f->f_mr_dnAttrs ? ":dn" : "",
  97. f->f_mr_oid ? ":" : "",
  98. f->f_mr_oid ? f->f_mr_oid : "",
  99. ESC_NEXT_VAL, f->f_mr_value.bv_val);
  100. return ptr;
  101. }
  102. /* returns escaped filter string for EQ, LE, GE and APROX filters */
  103. static char *
  104. filter_escape_filter_value(struct slapi_filter *f, const char *fmt, size_t len)
  105. {
  106. char *ptr;
  107. filter_compute_hash(f);
  108. ptr = slapi_filter_sprintf(fmt, f->f_avtype, ESC_NEXT_VAL, f->f_avvalue.bv_val );
  109. return ptr;
  110. }
  111. /*
  112. * get_filter_internal(): extract an LDAP filter from a BerElement and create
  113. * a slapi_filter structure (*filt) and a string equivalent (*fstr).
  114. *
  115. * This function is recursive. It calls itself (to process NOT filters) and
  116. * it calls get_filter_list() for AND and OR filters, and get_filter_list()
  117. * calls this function again.
  118. */
  119. static int
  120. get_filter_internal( Connection *conn, BerElement *ber,
  121. struct slapi_filter **filt, char **fstr, int maxdepth, int curdepth,
  122. int *subentry_dont_rewrite, int *has_tombstone_filter, int *has_ruv_filter )
  123. {
  124. ber_len_t len;
  125. int err;
  126. struct slapi_filter *f;
  127. char *ftmp, *type = NULL;
  128. LDAPDebug( LDAP_DEBUG_FILTER, "=> get_filter_internal\n", 0, 0, 0 );
  129. /*
  130. * Track and check the depth of nesting. Use post-increment on
  131. * current depth here because this function is called for the
  132. * top-level filter (which does not count towards the maximum depth).
  133. */
  134. if ( ( curdepth++ > maxdepth ) && ( maxdepth > 0 )) {
  135. *filt = NULL;
  136. *fstr = NULL;
  137. err = LDAP_UNWILLING_TO_PERFORM;
  138. LDAPDebug( LDAP_DEBUG_FILTER, "<= get_filter_internal %d"
  139. " (maximum nesting level of %d exceeded)\n",
  140. err, maxdepth, 0 );
  141. return( err );
  142. }
  143. /*
  144. * A filter looks like this coming in:
  145. * Filter ::= CHOICE {
  146. * and [0] SET OF Filter,
  147. * or [1] SET OF Filter,
  148. * not [2] Filter,
  149. * equalityMatch [3] AttributeValueAssertion,
  150. * substrings [4] SubstringFilter,
  151. * greaterOrEqual [5] AttributeValueAssertion,
  152. * lessOrEqual [6] AttributeValueAssertion,
  153. * present [7] AttributeType,
  154. * approxMatch [8] AttributeValueAssertion,
  155. * extensibleMatch [9] MatchingRuleAssertion --v3 only
  156. * }
  157. *
  158. * SubstringFilter ::= SEQUENCE {
  159. * type AttributeType,
  160. * SEQUENCE OF CHOICE {
  161. * initial [0] IA5String,
  162. * any [1] IA5String,
  163. * final [2] IA5String
  164. * }
  165. * }
  166. *
  167. * The extensibleMatch was added in LDAPv3:
  168. *
  169. * MatchingRuleAssertion ::= SEQUENCE {
  170. * matchingRule [1] MatchingRuleID OPTIONAL,
  171. * type [2] AttributeDescription OPTIONAL,
  172. * matchValue [3] AssertionValue,
  173. * dnAttributes [4] BOOLEAN DEFAULT FALSE
  174. * }
  175. */
  176. f = (struct slapi_filter *) slapi_ch_calloc( 1, sizeof(struct slapi_filter) );
  177. err = 0;
  178. *fstr = NULL;
  179. f->f_choice = ber_peek_tag( ber, &len );
  180. switch ( f->f_choice ) {
  181. case LDAP_FILTER_EQUALITY:
  182. LDAPDebug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
  183. if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
  184. if ( 0 == strcasecmp ( f->f_avtype, "objectclass")) {
  185. /* Process objectclass oid's here */
  186. if (strchr (f->f_avvalue.bv_val, '.')) {
  187. char *ocname = oc_find_name( f->f_avvalue.bv_val );
  188. if ( NULL != ocname ) {
  189. slapi_ch_free((void**)&f->f_avvalue.bv_val );
  190. f->f_avvalue.bv_val = ocname;
  191. f->f_avvalue.bv_len = strlen ( f->f_avvalue.bv_val );
  192. }
  193. }
  194. /*
  195. * Process subentry searches here.
  196. * Only set (*subentry_dont_rewrite) if it's not already set.
  197. */
  198. if (!(*subentry_dont_rewrite)) {
  199. *subentry_dont_rewrite = subentry_check_filter(f);
  200. }
  201. /*
  202. * Check if it's a Tomstone filter.
  203. * We need to do it once per filter, so if flag is already set,
  204. * don't bother doing it
  205. */
  206. if (!(*has_tombstone_filter)) {
  207. *has_tombstone_filter = tombstone_check_filter(f);
  208. }
  209. }
  210. if ( 0 == strcasecmp ( f->f_avtype, "nsuniqueid")) {
  211. /*
  212. * Check if it's a RUV filter.
  213. * We need to do it once per filter, so if flag is already set,
  214. * don't bother doing it
  215. */
  216. if (!(*has_ruv_filter)) {
  217. *has_ruv_filter = ruv_check_filter(f);
  218. }
  219. }
  220. *fstr=filter_escape_filter_value(f, FILTER_EQ_FMT, FILTER_EQ_LEN);
  221. }
  222. break;
  223. case LDAP_FILTER_SUBSTRINGS:
  224. LDAPDebug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 );
  225. err = get_substring_filter( conn, ber, f, fstr );
  226. break;
  227. case LDAP_FILTER_GE:
  228. LDAPDebug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
  229. if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
  230. *fstr=filter_escape_filter_value(f, FILTER_GE_FMT, FILTER_GE_LEN);
  231. }
  232. break;
  233. case LDAP_FILTER_LE:
  234. LDAPDebug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
  235. if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
  236. *fstr=filter_escape_filter_value(f, FILTER_LE_FMT, FILTER_LE_LEN);
  237. }
  238. break;
  239. case LDAP_FILTER_PRESENT:
  240. LDAPDebug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 );
  241. if ( ber_scanf( ber, "a", &type ) == LBER_ERROR ) {
  242. slapi_ch_free_string(&type);
  243. err = LDAP_PROTOCOL_ERROR;
  244. } else {
  245. err = LDAP_SUCCESS;
  246. f->f_type = slapi_attr_syntax_normalize( type );
  247. slapi_ch_free_string( &type );
  248. filter_compute_hash(f);
  249. *fstr = slapi_ch_smprintf( "(%s=*)", f->f_type );
  250. }
  251. break;
  252. case LDAP_FILTER_APPROX:
  253. LDAPDebug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
  254. if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
  255. *fstr=filter_escape_filter_value(f, FILTER_APROX_FMT, FILTER_APROX_LEN);
  256. }
  257. break;
  258. case LDAP_FILTER_EXTENDED:
  259. LDAPDebug( LDAP_DEBUG_FILTER, "EXTENDED\n", 0, 0, 0 );
  260. if ( conn->c_ldapversion < 3 ) {
  261. LDAPDebug( LDAP_DEBUG_ANY,
  262. "extensible filter received from v2 client\n",
  263. 0, 0, 0 );
  264. err = LDAP_PROTOCOL_ERROR;
  265. } else if ( (err = get_extensible_filter( ber, &f->f_mr )) == LDAP_SUCCESS ) {
  266. *fstr=filter_escape_filter_value_extended(f);
  267. LDAPDebug (LDAP_DEBUG_FILTER, "%s\n", *fstr, 0, 0);
  268. if(f->f_mr_oid==NULL) {
  269. /*
  270. * We accept:
  271. * A) attr ":=" value
  272. * B) attr ":dn" ":=" value
  273. */
  274. err = LDAP_SUCCESS;
  275. } else {
  276. err = plugin_mr_filter_create (&f->f_mr);
  277. }
  278. }
  279. break;
  280. case LDAP_FILTER_AND:
  281. LDAPDebug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 );
  282. if ( (err = get_filter_list( conn, ber, &f->f_and, &ftmp, maxdepth,
  283. curdepth, subentry_dont_rewrite,
  284. has_tombstone_filter, has_ruv_filter ))
  285. == 0 ) {
  286. filter_compute_hash(f);
  287. *fstr = slapi_ch_smprintf( "(&%s)", ftmp );
  288. slapi_ch_free((void**)&ftmp );
  289. }
  290. break;
  291. case LDAP_FILTER_OR:
  292. LDAPDebug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 );
  293. if ( (err = get_filter_list( conn, ber, &f->f_or, &ftmp, maxdepth,
  294. curdepth, subentry_dont_rewrite,
  295. has_tombstone_filter, has_ruv_filter ))
  296. == 0 ) {
  297. filter_compute_hash(f);
  298. *fstr = slapi_ch_smprintf( "(|%s)", ftmp );
  299. slapi_ch_free((void**)&ftmp );
  300. }
  301. break;
  302. case LDAP_FILTER_NOT:
  303. LDAPDebug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 );
  304. (void) ber_skip_tag( ber, &len );
  305. if ( (err = get_filter_internal( conn, ber, &f->f_not, &ftmp, maxdepth,
  306. curdepth, subentry_dont_rewrite,
  307. has_tombstone_filter, has_ruv_filter ))
  308. == 0 ) {
  309. filter_compute_hash(f);
  310. *fstr = slapi_ch_smprintf( "(!%s)", ftmp );
  311. slapi_ch_free((void**)&ftmp );
  312. }
  313. break;
  314. default:
  315. LDAPDebug( LDAP_DEBUG_ANY, "get_filter_internal: unknown type 0x%lX\n",
  316. f->f_choice, 0, 0 );
  317. err = LDAP_PROTOCOL_ERROR;
  318. break;
  319. }
  320. if ( err != 0 ) {
  321. slapi_filter_free( f, 1 );
  322. f = NULL;
  323. slapi_ch_free( (void**)fstr );
  324. }
  325. *filt = f;
  326. LDAPDebug( LDAP_DEBUG_FILTER, "<= get_filter_internal %d\n", err, 0, 0 );
  327. return( err );
  328. }
  329. static int
  330. get_filter_list( Connection *conn, BerElement *ber,
  331. struct slapi_filter **f, char **fstr, int maxdepth,
  332. int curdepth, int *subentry_dont_rewrite,
  333. int *has_tombstone_filter, int* has_ruv_filter)
  334. {
  335. struct slapi_filter **new;
  336. int err;
  337. ber_tag_t tag;
  338. ber_len_t len = -1;
  339. char *last;
  340. LDAPDebug( LDAP_DEBUG_FILTER, "=> get_filter_list\n", 0, 0, 0 );
  341. *fstr = NULL;
  342. new = f;
  343. for ( tag = ber_first_element( ber, &len, &last );
  344. tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET;
  345. tag = ber_next_element( ber, &len, last ) ) {
  346. char *ftmp;
  347. if ( (err = get_filter_internal( conn, ber, new, &ftmp, maxdepth,
  348. curdepth, subentry_dont_rewrite,
  349. has_tombstone_filter, has_ruv_filter))
  350. != 0 ) {
  351. if ( *fstr != NULL ) {
  352. slapi_ch_free((void**)fstr );
  353. }
  354. return( err );
  355. }
  356. if ( *fstr == NULL ) {
  357. *fstr = ftmp;
  358. } else {
  359. *fstr = slapi_ch_realloc( *fstr, strlen( *fstr ) +
  360. strlen( ftmp ) + 1 );
  361. strcat( *fstr, ftmp );
  362. slapi_ch_free((void**)&ftmp );
  363. }
  364. new = &(*new)->f_next;
  365. len = -1;
  366. }
  367. *new = NULL;
  368. /* openldap does not return LBER_END_OF_SEQORSET -
  369. so check for len == -1 - openldap ber_next_element will not set
  370. len if it has reached the end, and -1 is not a valid value
  371. for a real len */
  372. if ( (tag != LBER_END_OF_SEQORSET) && (len != -1) && (*fstr != NULL) ) {
  373. LDAPDebug( LDAP_DEBUG_ANY, " error parsing filter list\n", 0, 0, 0 );
  374. slapi_ch_free((void**)fstr );
  375. }
  376. LDAPDebug( LDAP_DEBUG_FILTER, "<= get_filter_list\n", 0, 0, 0 );
  377. return(( *fstr == NULL ) ? LDAP_PROTOCOL_ERROR : 0 );
  378. }
  379. static int
  380. get_substring_filter(
  381. Connection *conn,
  382. BerElement *ber,
  383. struct slapi_filter *f,
  384. char **fstr
  385. )
  386. {
  387. ber_tag_t tag, rc;
  388. ber_len_t len = -1;
  389. char *val, *eval, *last, *type = NULL;
  390. size_t fstr_len;
  391. LDAPDebug( LDAP_DEBUG_FILTER, "=> get_substring_filter\n", 0, 0, 0 );
  392. if ( ber_scanf( ber, "{a", &type ) == LBER_ERROR ) {
  393. slapi_ch_free_string(&type);
  394. return( LDAP_PROTOCOL_ERROR );
  395. }
  396. f->f_sub_type = slapi_attr_syntax_normalize( type );
  397. slapi_ch_free_string( &type );
  398. f->f_sub_initial = NULL;
  399. f->f_sub_any = NULL;
  400. f->f_sub_final = NULL;
  401. /* borrowing the handy macro: 256 */
  402. fstr_len = strlen( f->f_sub_type ) + SLAPD_TYPICAL_ATTRIBUTE_NAME_MAX_LENGTH;
  403. *fstr = slapi_ch_malloc(fstr_len);
  404. sprintf( *fstr, "(%s=", f->f_sub_type );
  405. for ( tag = ber_first_element( ber, &len, &last );
  406. tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET;
  407. tag = ber_next_element( ber, &len, last ) )
  408. {
  409. len = -1; /* reset - not used in loop */
  410. val = NULL;
  411. rc = ber_scanf( ber, "a", &val );
  412. if ( rc == LBER_ERROR ) {
  413. slapi_ch_free_string(&val);
  414. return( LDAP_PROTOCOL_ERROR );
  415. }
  416. if ( val == NULL || *val == '\0' ) {
  417. if ( val != NULL ) {
  418. slapi_ch_free_string( &val );
  419. }
  420. return( LDAP_INVALID_SYNTAX );
  421. }
  422. switch ( tag ) {
  423. case LDAP_SUBSTRING_INITIAL:
  424. LDAPDebug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 );
  425. if ( f->f_sub_initial != NULL ) {
  426. return( LDAP_PROTOCOL_ERROR );
  427. }
  428. f->f_sub_initial = val;
  429. eval = (char*)slapi_escape_filter_value(val, -1);
  430. if(eval) {
  431. if (fstr_len < strlen(*fstr) + strlen(eval) + 1) {
  432. fstr_len += (strlen(eval) + 1) * 2;
  433. *fstr = slapi_ch_realloc(*fstr, fstr_len);
  434. }
  435. strcat(*fstr, eval);
  436. slapi_ch_free_string(&eval);
  437. }
  438. break;
  439. case LDAP_SUBSTRING_ANY:
  440. LDAPDebug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 );
  441. charray_add(&f->f_sub_any, val);
  442. eval = (char*)slapi_escape_filter_value(val, -1);
  443. if(eval){
  444. if (fstr_len < strlen(*fstr) + strlen(eval) + 1) {
  445. fstr_len += (strlen(eval) + 1) * 2;
  446. *fstr = slapi_ch_realloc(*fstr, fstr_len);
  447. }
  448. strcat(*fstr, "*");
  449. strcat(*fstr, eval);
  450. slapi_ch_free_string(&eval);
  451. }
  452. break;
  453. case LDAP_SUBSTRING_FINAL:
  454. LDAPDebug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 );
  455. if ( f->f_sub_final != NULL ) {
  456. return( LDAP_PROTOCOL_ERROR );
  457. }
  458. f->f_sub_final = val;
  459. eval = (char*)slapi_escape_filter_value( val, -1);
  460. if(eval){
  461. if (fstr_len < strlen(*fstr) + strlen(eval) + 1) {
  462. fstr_len += (strlen(eval) + 1) * 2;
  463. *fstr = slapi_ch_realloc(*fstr, fstr_len);
  464. }
  465. strcat(*fstr, "*");
  466. strcat(*fstr, eval);
  467. slapi_ch_free_string(&eval);
  468. }
  469. break;
  470. default:
  471. LDAPDebug( LDAP_DEBUG_FILTER, " unknown tag 0x%lX\n", tag, 0, 0 );
  472. return( LDAP_PROTOCOL_ERROR );
  473. }
  474. }
  475. if ( (tag != LBER_END_OF_SEQORSET) && (len != -1) ) {
  476. LDAPDebug( LDAP_DEBUG_ANY, " error reading substring filter\n", 0, 0, 0 );
  477. return( LDAP_PROTOCOL_ERROR );
  478. }
  479. if ( f->f_sub_initial == NULL && f->f_sub_any == NULL &&
  480. f->f_sub_final == NULL ) {
  481. return( LDAP_PROTOCOL_ERROR );
  482. }
  483. filter_compute_hash(f);
  484. if (fstr_len < strlen(*fstr) + 3) {
  485. fstr_len += 3;
  486. *fstr = slapi_ch_realloc(*fstr, fstr_len);
  487. }
  488. if ( f->f_sub_final == NULL ) {
  489. strcat( *fstr, "*" );
  490. }
  491. strcat( *fstr, ")" );
  492. LDAPDebug( LDAP_DEBUG_FILTER, "<= get_substring_filter\n", 0, 0, 0 );
  493. return( 0 );
  494. }
  495. static int
  496. get_extensible_filter( BerElement *ber, mr_filter_t* mrf )
  497. {
  498. int gotelem, gotoid, gotvalue;
  499. ber_tag_t tag;
  500. ber_len_t len = -1;
  501. char *last;
  502. int rc = LDAP_SUCCESS;
  503. LDAPDebug( LDAP_DEBUG_FILTER, "=> get_extensible_filter\n", 0, 0, 0 );
  504. memset (mrf, 0, sizeof (mr_filter_t));
  505. gotelem = gotoid = gotvalue = 0;
  506. for ( tag = ber_first_element( ber, &len, &last );
  507. tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET;
  508. tag = ber_next_element( ber, &len, last ) ) {
  509. /*
  510. * order of elements goes like this:
  511. *
  512. * [oid][type]value[dnattr]
  513. *
  514. * where either oid or type is required.
  515. */
  516. len = -1; /* reset - not used in loop */
  517. switch ( tag ) {
  518. case LDAP_TAG_MRA_OID:
  519. if ( gotelem != 0 ) {
  520. goto parsing_error;
  521. }
  522. if (ber_scanf( ber, "a", &mrf->mrf_oid ) == LBER_ERROR) {
  523. rc = LDAP_PROTOCOL_ERROR;
  524. }
  525. gotoid = 1;
  526. gotelem++;
  527. break;
  528. case LDAP_TAG_MRA_TYPE:
  529. if ( gotelem != 0 ) {
  530. if ( gotelem != 1 || gotoid != 1 ) {
  531. goto parsing_error;
  532. }
  533. }
  534. {
  535. char* type = NULL;
  536. if (ber_scanf( ber, "a", &type ) == LBER_ERROR) {
  537. slapi_ch_free_string (&type);
  538. rc = LDAP_PROTOCOL_ERROR;
  539. } else {
  540. mrf->mrf_type = slapi_attr_syntax_normalize(type);
  541. slapi_ch_free_string (&type);
  542. }
  543. }
  544. gotelem++;
  545. break;
  546. case LDAP_TAG_MRA_VALUE:
  547. if ( gotelem != 1 && gotelem != 2 ) {
  548. goto parsing_error;
  549. }
  550. if (ber_scanf( ber, "o", &mrf->mrf_value ) == LBER_ERROR) {
  551. rc = LDAP_PROTOCOL_ERROR;
  552. }
  553. gotvalue = 1;
  554. gotelem++;
  555. break;
  556. case LDAP_TAG_MRA_DNATTRS:
  557. if ( gotvalue != 1 ) {
  558. goto parsing_error;
  559. }
  560. if (ber_scanf( ber, "b", &mrf->mrf_dnAttrs ) == LBER_ERROR) {
  561. rc = LDAP_PROTOCOL_ERROR;
  562. }
  563. gotelem++;
  564. break;
  565. default:
  566. goto parsing_error;
  567. }
  568. if ( rc != LDAP_SUCCESS ) {
  569. goto parsing_error;
  570. }
  571. }
  572. if ( (tag != LBER_ERROR) && (len != -1) ) {
  573. goto parsing_error;
  574. }
  575. LDAPDebug( LDAP_DEBUG_FILTER, "<= get_extensible_filter %i\n", rc, 0, 0 );
  576. return rc;
  577. parsing_error:;
  578. LDAPDebug( LDAP_DEBUG_ANY, "error parsing extensible filter\n",
  579. 0, 0, 0 );
  580. return( LDAP_PROTOCOL_ERROR );
  581. }
  582. Slapi_Filter *
  583. slapi_filter_dup(Slapi_Filter *f)
  584. {
  585. Slapi_Filter *out = 0;
  586. struct slapi_filter *fl = 0;
  587. struct slapi_filter **outl = 0;
  588. struct slapi_filter *lastout = 0;
  589. if ( f == NULL ) {
  590. return NULL;
  591. }
  592. out = (struct slapi_filter*)slapi_ch_calloc(1, sizeof(struct slapi_filter));
  593. if ( out == NULL ) {
  594. LDAPDebug(LDAP_DEBUG_ANY, "slapi_filter_dup: memory allocation error\n",
  595. 0, 0, 0 );
  596. return NULL;
  597. }
  598. out->f_choice = f->f_choice;
  599. out->f_hash = f->f_hash;
  600. out->f_flags = f->f_flags;
  601. LDAPDebug( LDAP_DEBUG_FILTER, "slapi_filter_dup type 0x%lX\n", f->f_choice, 0, 0 );
  602. switch ( f->f_choice ) {
  603. case LDAP_FILTER_EQUALITY:
  604. case LDAP_FILTER_GE:
  605. case LDAP_FILTER_LE:
  606. case LDAP_FILTER_APPROX:
  607. out->f_ava.ava_type = slapi_ch_strdup(f->f_ava.ava_type);
  608. slapi_ber_bvcpy(&out->f_ava.ava_value, &f->f_ava.ava_value);
  609. break;
  610. case LDAP_FILTER_SUBSTRINGS:
  611. out->f_sub_type = slapi_ch_strdup(f->f_sub_type);
  612. out->f_sub_initial = slapi_ch_strdup(f->f_sub_initial );
  613. out->f_sub_any = charray_dup( f->f_sub_any );
  614. out->f_sub_final = slapi_ch_strdup(f->f_sub_final );
  615. break;
  616. case LDAP_FILTER_PRESENT:
  617. out->f_type = slapi_ch_strdup( f->f_type );
  618. break;
  619. case LDAP_FILTER_AND:
  620. case LDAP_FILTER_OR:
  621. case LDAP_FILTER_NOT:
  622. outl = &out->f_list;
  623. for (fl = f->f_list; fl != NULL; fl = fl->f_next) {
  624. (*outl) = slapi_filter_dup( fl );
  625. (*outl)->f_next = 0;
  626. if(lastout)
  627. lastout->f_next = *outl;
  628. lastout = *outl;
  629. outl = &((*outl)->f_next);
  630. }
  631. break;
  632. case LDAP_FILTER_EXTENDED:
  633. out->f_mr_oid = slapi_ch_strdup(f->f_mr_oid);
  634. out->f_mr_type = slapi_ch_strdup(f->f_mr_type);
  635. slapi_ber_bvcpy(&out->f_mr_value, &f->f_mr_value);
  636. out->f_mr_dnAttrs = f->f_mr_dnAttrs;
  637. if (f->f_mr.mrf_match) {
  638. int rc = plugin_mr_filter_create(&out->f_mr);
  639. LDAPDebug1Arg( LDAP_DEBUG_FILTER, "slapi_filter_dup plugin_mr_filter_create returned %d\n", rc );
  640. }
  641. break;
  642. default:
  643. LDAPDebug(LDAP_DEBUG_FILTER, "slapi_filter_dup: unknown type 0x%lX\n",
  644. f->f_choice, 0, 0 );
  645. break;
  646. }
  647. return out;
  648. }
  649. void
  650. slapi_filter_free( struct slapi_filter *f, int recurse )
  651. {
  652. if ( f == NULL ) {
  653. return;
  654. }
  655. LDAPDebug( LDAP_DEBUG_FILTER, "slapi_filter_free type 0x%lX\n", f->f_choice, 0, 0 );
  656. switch ( f->f_choice ) {
  657. case LDAP_FILTER_EQUALITY:
  658. case LDAP_FILTER_GE:
  659. case LDAP_FILTER_LE:
  660. case LDAP_FILTER_APPROX:
  661. ava_done( &f->f_ava );
  662. break;
  663. case LDAP_FILTER_SUBSTRINGS:
  664. slapi_ch_free((void**)&f->f_sub_type );
  665. slapi_ch_free((void**)&f->f_sub_initial );
  666. charray_free( f->f_sub_any );
  667. slapi_ch_free((void**)&f->f_sub_final );
  668. break;
  669. case LDAP_FILTER_PRESENT:
  670. slapi_ch_free((void**)&f->f_type );
  671. break;
  672. case LDAP_FILTER_AND:
  673. case LDAP_FILTER_OR:
  674. case LDAP_FILTER_NOT:
  675. if ( recurse ) {
  676. struct slapi_filter *fl, *next;
  677. for (fl = f->f_list; fl != NULL; fl = next) {
  678. next = fl->f_next;
  679. fl->f_next = NULL;
  680. slapi_filter_free( fl, recurse );
  681. fl = next;
  682. }
  683. }
  684. break;
  685. case LDAP_FILTER_EXTENDED:
  686. slapi_ch_free((void**)&f->f_mr_oid);
  687. slapi_ch_free((void**)&f->f_mr_type);
  688. slapi_ber_bvdone(&f->f_mr_value);
  689. if (f->f_mr.mrf_destroy != NULL) {
  690. Slapi_PBlock pb;
  691. pblock_init (&pb);
  692. if ( ! slapi_pblock_set (&pb, SLAPI_PLUGIN_OBJECT, f->f_mr.mrf_object)) {
  693. f->f_mr.mrf_destroy (&pb);
  694. }
  695. }
  696. break;
  697. default:
  698. LDAPDebug( LDAP_DEBUG_ANY, "slapi_filter_free: unknown type 0x%lX\n",
  699. f->f_choice, 0, 0 );
  700. break;
  701. }
  702. slapi_ch_free((void**)&f);
  703. }
  704. #if 0
  705. static void
  706. filter_list_insert( struct slapi_filter **into, struct slapi_filter *from )
  707. {
  708. struct slapi_filter *f;
  709. if (into == NULL || from == NULL) return;
  710. if (*into != NULL) {
  711. for (f = from; f->f_next != NULL; f = f->f_next);
  712. f->f_next = *into;
  713. }
  714. *into = from;
  715. }
  716. #endif
  717. struct slapi_filter *
  718. slapi_filter_join( int ftype, struct slapi_filter *f1, struct slapi_filter *f2)
  719. {
  720. return slapi_filter_join_ex( ftype, f1, f2, 1 );
  721. }
  722. struct slapi_filter *
  723. slapi_filter_join_ex( int ftype, struct slapi_filter *f1, struct slapi_filter *f2, int recurse_always )
  724. {
  725. struct slapi_filter *fjoin;
  726. struct slapi_filter *add_to;
  727. struct slapi_filter *add_this;
  728. struct slapi_filter *return_this;
  729. int insert = 0;
  730. if ((NULL == f1) || (NULL == f2)) {
  731. switch(ftype) {
  732. case LDAP_FILTER_AND:
  733. return NULL;
  734. case LDAP_FILTER_OR:
  735. return f1?f1:f2;
  736. default:
  737. if (NULL == f1) {
  738. if (NULL == f2) {
  739. return NULL;
  740. } else {
  741. add_this = f2;
  742. }
  743. } else {
  744. add_this = f1;
  745. }
  746. fjoin = (struct slapi_filter *)slapi_ch_calloc(1, sizeof(struct slapi_filter));
  747. fjoin->f_choice = ftype;
  748. fjoin->f_list = add_this;
  749. filter_compute_hash(fjoin);
  750. return fjoin;
  751. }
  752. }
  753. if(!recurse_always)
  754. {
  755. /* try to optimise the filter join */
  756. switch(ftype)
  757. {
  758. case LDAP_FILTER_AND:
  759. case LDAP_FILTER_OR:
  760. if(ftype == (int)f1->f_choice)
  761. {
  762. add_to = f1;
  763. add_this = f2;
  764. insert = 1;
  765. }
  766. else if(ftype == (int)f2->f_choice)
  767. {
  768. add_to = f2;
  769. add_this = f1;
  770. insert = 1;
  771. }
  772. default:
  773. break;
  774. }
  775. }
  776. if(insert)
  777. {
  778. /* try to avoid ! filters as the first arg */
  779. if(add_to->f_list->f_choice == LDAP_FILTER_NOT)
  780. {
  781. add_this->f_next = add_to->f_list;
  782. add_to->f_list = add_this;
  783. filter_compute_hash(add_to);
  784. return_this = add_to;
  785. }
  786. else
  787. {
  788. /* find end of list, add the filter */
  789. for (fjoin = add_to->f_list; fjoin != NULL; fjoin = fjoin->f_next) {
  790. if(fjoin->f_next == NULL)
  791. {
  792. fjoin->f_next = add_this;
  793. filter_compute_hash(add_to);
  794. return_this = add_to;
  795. break;
  796. }
  797. }
  798. }
  799. }
  800. else
  801. {
  802. fjoin = (struct slapi_filter *) slapi_ch_calloc( 1, sizeof(struct slapi_filter) );
  803. fjoin->f_choice = ftype;
  804. fjoin->f_next = NULL;
  805. /* try to ensure ! filters dont cause allid search */
  806. if(f1->f_choice == LDAP_FILTER_NOT && f2)
  807. {
  808. fjoin->f_list = f2;
  809. f2->f_next = f1;
  810. }
  811. else
  812. {
  813. fjoin->f_list = f1;
  814. f1->f_next = f2;
  815. }
  816. filter_compute_hash(fjoin);
  817. return_this = fjoin;
  818. }
  819. return( return_this );
  820. }
  821. int
  822. slapi_filter_get_choice( struct slapi_filter *f )
  823. {
  824. return( f->f_choice );
  825. }
  826. int
  827. slapi_filter_get_ava( struct slapi_filter *f, char **type, struct berval **bval )
  828. {
  829. switch ( f->f_choice ) {
  830. case LDAP_FILTER_EQUALITY:
  831. case LDAP_FILTER_GE:
  832. case LDAP_FILTER_LE:
  833. case LDAP_FILTER_APPROX:
  834. break;
  835. default:
  836. *type = NULL;
  837. *bval = NULL;
  838. return( -1 );
  839. }
  840. *type = f->f_avtype;
  841. *bval = &f->f_avvalue;
  842. return( 0 );
  843. }
  844. /* Deprecated--use slapi_filter_get_attribute_type() now */
  845. SLAPI_DEPRECATED int
  846. slapi_filter_get_type( struct slapi_filter *f, char **type )
  847. {
  848. if ( f->f_choice != LDAP_FILTER_PRESENT ) {
  849. return( -1 );
  850. }
  851. *type = f->f_type;
  852. return( 0 );
  853. }
  854. /*
  855. * Return the attribute type for all simple filter choices into type.
  856. * ie. for all except LDAP_FILTER_AND, LDAP_FILTER_OR and LDAP_FILTER_NOT.
  857. *
  858. * The returned type is "as is" and so may not be normalized.
  859. * Returns 0 for success, -1 otherwise.
  860. */
  861. int
  862. slapi_filter_get_attribute_type( Slapi_Filter *f, char **type )
  863. {
  864. if ( f == NULL ) {
  865. return -1;
  866. }
  867. switch ( f->f_choice ) {
  868. case LDAP_FILTER_GE:
  869. case LDAP_FILTER_LE:
  870. case LDAP_FILTER_APPROX:
  871. case LDAP_FILTER_EQUALITY:
  872. *type = f->f_ava.ava_type;
  873. break;
  874. case LDAP_FILTER_SUBSTRINGS:
  875. *type = f->f_sub_type;
  876. break;
  877. case LDAP_FILTER_PRESENT:
  878. *type = f->f_type;
  879. break;
  880. case LDAP_FILTER_EXTENDED:
  881. *type = f->f_mr_type;
  882. break;
  883. case LDAP_FILTER_AND:
  884. case LDAP_FILTER_OR:
  885. case LDAP_FILTER_NOT:
  886. return(-1);
  887. default:
  888. /* Unknown filter choice */
  889. return -1;
  890. }
  891. /* success */
  892. return(0);
  893. }
  894. struct slapi_filter *
  895. slapi_filter_list_first( struct slapi_filter *f )
  896. {
  897. if ( f->f_choice != LDAP_FILTER_AND && f->f_choice != LDAP_FILTER_OR
  898. && f->f_choice != LDAP_FILTER_NOT ) {
  899. return( NULL );
  900. }
  901. return( f->f_list );
  902. }
  903. struct slapi_filter *
  904. slapi_filter_list_next( struct slapi_filter *f, struct slapi_filter *fprev )
  905. {
  906. return( fprev->f_next );
  907. }
  908. int
  909. slapi_filter_get_subfilt(
  910. struct slapi_filter *f,
  911. char **type,
  912. char **initial,
  913. char ***any,
  914. char **final
  915. )
  916. {
  917. if ( f->f_choice != LDAP_FILTER_SUBSTRINGS ) {
  918. return( -1 );
  919. }
  920. *type = f->f_sub_type;
  921. *initial = f->f_sub_initial;
  922. *any = f->f_sub_any;
  923. *final = f->f_sub_final;
  924. return( 0 );
  925. }
  926. static void
  927. filter_normalize_ava( struct slapi_filter *f, PRBool norm_values )
  928. {
  929. char *tmp;
  930. struct ava *ava;
  931. if ( f == NULL ) {
  932. return;
  933. }
  934. ava = &f->f_ava;
  935. tmp = ava->ava_type;
  936. ava->ava_type = slapi_attr_syntax_normalize(tmp);
  937. slapi_ch_free((void**)&tmp );
  938. f->f_flags |= SLAPI_FILTER_NORMALIZED_TYPE;
  939. if (norm_values) {
  940. char *newval = NULL;
  941. /* NOTE: assumes ava->ava_value.bv_val is NULL terminated - get_ava/ber_scanf 'o'
  942. will NULL terminate the string by default */
  943. slapi_attr_value_normalize_ext(NULL, NULL, ava->ava_type,
  944. ava->ava_value.bv_val, 1, &newval, f->f_choice);
  945. if (newval && (newval != ava->ava_value.bv_val)) {
  946. slapi_ch_free_string(&ava->ava_value.bv_val);
  947. ava->ava_value.bv_val = newval;
  948. ava->ava_value.bv_len = strlen(newval);
  949. }
  950. f->f_flags |= SLAPI_FILTER_NORMALIZED_VALUE;
  951. }
  952. }
  953. static void
  954. filter_normalize_subfilt( struct slapi_filter *f, PRBool norm_values )
  955. {
  956. struct subfilt *sf;
  957. if ( f == NULL ) {
  958. return;
  959. }
  960. sf = &f->f_sub;
  961. char *tmp = sf->sf_type;
  962. sf->sf_type = slapi_attr_syntax_normalize(tmp);
  963. slapi_ch_free((void**)&tmp );
  964. f->f_flags |= SLAPI_FILTER_NORMALIZED_TYPE;
  965. if (norm_values) {
  966. char *newval = NULL;
  967. Slapi_Attr attr;
  968. int ii;
  969. slapi_attr_init(&attr, sf->sf_type);
  970. slapi_attr_value_normalize_ext(NULL, &attr, NULL, sf->sf_initial, 1, &newval, f->f_choice);
  971. if (newval && (newval != sf->sf_initial)) {
  972. slapi_ch_free_string(&sf->sf_initial);
  973. sf->sf_initial = newval;
  974. }
  975. for (ii = 0; sf->sf_any && sf->sf_any[ii]; ++ii) {
  976. newval = NULL;
  977. /* do not trim spaces of sf_any values - see string_filter_sub() */
  978. slapi_attr_value_normalize_ext(NULL, &attr, NULL, sf->sf_any[ii], 0, &newval, f->f_choice);
  979. if (newval && (newval != sf->sf_any[ii])) {
  980. slapi_ch_free_string(&sf->sf_any[ii]);
  981. sf->sf_any[ii] = newval;
  982. }
  983. }
  984. newval = NULL;
  985. /* do not trim spaces of sf_final values - see string_filter_sub() */
  986. slapi_attr_value_normalize_ext(NULL, &attr, NULL, sf->sf_final, 0, &newval, f->f_choice);
  987. if (newval && (newval != sf->sf_final)) {
  988. slapi_ch_free_string(&sf->sf_final);
  989. sf->sf_final = newval;
  990. }
  991. attr_done(&attr);
  992. f->f_flags |= SLAPI_FILTER_NORMALIZED_VALUE;
  993. }
  994. }
  995. void filter_normalize_ext( struct slapi_filter *f, PRBool norm_values );
  996. static void
  997. filter_normalize_list( struct slapi_filter *flist, PRBool norm_values )
  998. {
  999. struct slapi_filter *f;
  1000. for ( f = flist; f != NULL; f = f->f_next ) {
  1001. filter_normalize_ext( f, norm_values );
  1002. }
  1003. }
  1004. /*
  1005. * Normalize all values and types in a filter. This isn't necessary
  1006. * when we've read the slapi_filter off the wire, but if we've hand-constructed
  1007. * a filter inside slapd (e.g. when calling the routines in wrapper.c),
  1008. * we've called slapi_str2filter on something which *didn't* come over the wire,
  1009. * so the attribute names and filters in the filter struct aren't
  1010. * normalized.
  1011. */
  1012. void
  1013. filter_normalize_ext( struct slapi_filter *f, PRBool norm_values )
  1014. {
  1015. char *tmp;
  1016. if ( f == NULL ) {
  1017. return;
  1018. }
  1019. switch ( f->f_choice ) {
  1020. case LDAP_FILTER_GE:
  1021. case LDAP_FILTER_LE:
  1022. case LDAP_FILTER_APPROX:
  1023. case LDAP_FILTER_EQUALITY:
  1024. filter_normalize_ava( f, norm_values );
  1025. break;
  1026. case LDAP_FILTER_SUBSTRINGS:
  1027. filter_normalize_subfilt( f, norm_values );
  1028. break;
  1029. case LDAP_FILTER_PRESENT:
  1030. tmp = f->f_type;
  1031. f->f_type = slapi_attr_syntax_normalize(tmp);
  1032. slapi_ch_free((void**)&tmp );
  1033. f->f_flags |= SLAPI_FILTER_NORMALIZED_TYPE;
  1034. break;
  1035. case LDAP_FILTER_EXTENDED:
  1036. tmp = f->f_mr_type;
  1037. f->f_mr_type = slapi_attr_syntax_normalize(tmp);
  1038. slapi_ch_free((void**)&tmp );
  1039. f->f_flags |= SLAPI_FILTER_NORMALIZED_TYPE;
  1040. break;
  1041. case LDAP_FILTER_AND:
  1042. filter_normalize_list( f->f_and, norm_values );
  1043. break;
  1044. case LDAP_FILTER_OR:
  1045. filter_normalize_list( f->f_or, norm_values );
  1046. break;
  1047. case LDAP_FILTER_NOT:
  1048. filter_normalize_list( f->f_not, norm_values );
  1049. break;
  1050. default:
  1051. return;
  1052. }
  1053. }
  1054. void
  1055. filter_normalize( struct slapi_filter *f )
  1056. {
  1057. filter_normalize_ext(f, PR_FALSE);
  1058. }
  1059. void
  1060. slapi_filter_normalize( struct slapi_filter *f, PRBool norm_values )
  1061. {
  1062. filter_normalize_ext(f, norm_values);
  1063. }
  1064. void
  1065. filter_print( struct slapi_filter *f )
  1066. {
  1067. int i;
  1068. struct slapi_filter *p;
  1069. if ( f == NULL ) {
  1070. printf( "NULL" );
  1071. return;
  1072. }
  1073. switch ( f->f_choice ) {
  1074. case LDAP_FILTER_EQUALITY:
  1075. printf( "(%s=%s)", f->f_ava.ava_type,
  1076. f->f_ava.ava_value.bv_val );
  1077. break;
  1078. case LDAP_FILTER_GE:
  1079. printf( "(%s>=%s)", f->f_ava.ava_type,
  1080. f->f_ava.ava_value.bv_val );
  1081. break;
  1082. case LDAP_FILTER_LE:
  1083. printf( "(%s<=%s)", f->f_ava.ava_type,
  1084. f->f_ava.ava_value.bv_val );
  1085. break;
  1086. case LDAP_FILTER_APPROX:
  1087. printf( "(%s~=%s)", f->f_ava.ava_type,
  1088. f->f_ava.ava_value.bv_val );
  1089. break;
  1090. case LDAP_FILTER_SUBSTRINGS:
  1091. printf( "(%s=", f->f_sub_type );
  1092. if ( f->f_sub_initial != NULL ) {
  1093. printf( "%s", f->f_sub_initial );
  1094. }
  1095. if ( f->f_sub_any != NULL ) {
  1096. for ( i = 0; f->f_sub_any[i] != NULL; i++ ) {
  1097. printf( "*%s", f->f_sub_any[i] );
  1098. }
  1099. }
  1100. if ( f->f_sub_final != NULL ) {
  1101. printf( "*%s", f->f_sub_final );
  1102. }
  1103. printf( ")" );
  1104. break;
  1105. case LDAP_FILTER_PRESENT:
  1106. printf( "(%s=*)", f->f_type );
  1107. break;
  1108. case LDAP_FILTER_AND:
  1109. case LDAP_FILTER_OR:
  1110. case LDAP_FILTER_NOT:
  1111. printf( "(%c", f->f_choice == LDAP_FILTER_AND ? '&' :
  1112. f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
  1113. for ( p = f->f_list; p != NULL; p = p->f_next ) {
  1114. filter_print( p );
  1115. }
  1116. printf( ")" );
  1117. break;
  1118. default:
  1119. printf( "unknown type 0x%lX", f->f_choice );
  1120. break;
  1121. }
  1122. fflush( stdout );
  1123. }
  1124. /* filter_to_string
  1125. * ----------------
  1126. * translates the supplied filter to
  1127. * the string representation and places
  1128. * the result in buf
  1129. *
  1130. * NOTE: intended for debug purposes, buffer must be
  1131. * large enough to contain filter string
  1132. */
  1133. char *
  1134. slapi_filter_to_string_internal( const struct slapi_filter *f, char *buf, size_t *bufsize )
  1135. {
  1136. int i;
  1137. char *return_buf = buf;
  1138. struct slapi_filter *p;
  1139. size_t size;
  1140. char *operator = ""; /* for comparison operators */
  1141. if(buf == NULL)
  1142. return 0;
  1143. else
  1144. *buf = 0; /* make sure buf is null terminated */
  1145. if ( f == NULL ) {
  1146. sprintf( buf, "NULL" );
  1147. return 0;
  1148. }
  1149. switch ( f->f_choice ) {
  1150. case LDAP_FILTER_EQUALITY:
  1151. operator = "=";
  1152. break;
  1153. case LDAP_FILTER_GE:
  1154. operator = ">=";
  1155. break;
  1156. case LDAP_FILTER_LE:
  1157. operator = "<=";
  1158. break;
  1159. case LDAP_FILTER_APPROX:
  1160. operator = "~=";
  1161. break;
  1162. case LDAP_FILTER_EXTENDED:
  1163. operator = ":=";
  1164. break;
  1165. default: break;
  1166. }
  1167. switch ( f->f_choice ) {
  1168. case LDAP_FILTER_EQUALITY:
  1169. case LDAP_FILTER_GE:
  1170. case LDAP_FILTER_LE:
  1171. case LDAP_FILTER_APPROX:
  1172. /* +3 -> 1 for (, 1 for ), and one for the trailing null */
  1173. size = strlen(f->f_ava.ava_type) + f->f_ava.ava_value.bv_len + strlen(operator) + 3;
  1174. if(size < *bufsize)
  1175. {
  1176. /* bv_val may not be null terminated, so use the max field width
  1177. specifier .* with the bv_len as the length to avoid reading
  1178. past bv_len in bv_val */
  1179. sprintf( buf, "(%s%s%.*s)", f->f_ava.ava_type, operator,
  1180. (int)f->f_ava.ava_value.bv_len,
  1181. f->f_ava.ava_value.bv_val );
  1182. *bufsize -= size;
  1183. }
  1184. break;
  1185. case LDAP_FILTER_SUBSTRINGS:
  1186. size = strlen(f->f_sub_type) + 2;
  1187. if(size < *bufsize)
  1188. {
  1189. sprintf( buf, "(%s=", f->f_sub_type );
  1190. *bufsize -= size;
  1191. if ( f->f_sub_initial != NULL ) {
  1192. size = strlen(f->f_sub_initial);
  1193. if(size < *bufsize)
  1194. {
  1195. buf += strlen(buf);
  1196. sprintf( buf, "%s", f->f_sub_initial );
  1197. *bufsize -= size;
  1198. }
  1199. }
  1200. if ( f->f_sub_any != NULL ) {
  1201. for ( i = 0; f->f_sub_any[i] != NULL; i++ ) {
  1202. size = strlen(f->f_sub_any[i]) + 1;
  1203. if(size < *bufsize)
  1204. {
  1205. buf += strlen(buf);
  1206. sprintf( buf, "*%s", f->f_sub_any[i] );
  1207. *bufsize -= size;
  1208. }
  1209. }
  1210. }
  1211. if ( f->f_sub_final != NULL ) {
  1212. size = strlen(f->f_sub_final) + 1;
  1213. if(size < *bufsize)
  1214. {
  1215. buf += strlen(buf);
  1216. sprintf( buf, "*%s", f->f_sub_final );
  1217. *bufsize -= size;
  1218. }
  1219. }
  1220. buf += strlen(buf);
  1221. if(1 < *bufsize)
  1222. {
  1223. sprintf( buf, ")" );
  1224. (*bufsize)--;
  1225. }
  1226. }
  1227. break;
  1228. case LDAP_FILTER_PRESENT:
  1229. size = strlen(f->f_type) + 4;
  1230. if(size < *bufsize)
  1231. {
  1232. sprintf( buf, "(%s=*)", f->f_type );
  1233. *bufsize -= size;
  1234. }
  1235. break;
  1236. case LDAP_FILTER_AND:
  1237. case LDAP_FILTER_OR:
  1238. case LDAP_FILTER_NOT:
  1239. if(2 < *bufsize)
  1240. {
  1241. sprintf( buf, "(%c", f->f_choice == LDAP_FILTER_AND ? '&' :
  1242. f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
  1243. *bufsize -= 2;
  1244. for ( p = f->f_list; p != NULL; p = p->f_next ) {
  1245. buf += strlen(buf);
  1246. slapi_filter_to_string_internal( p, buf, bufsize );
  1247. }
  1248. buf += strlen(buf);
  1249. if(1 < *bufsize)
  1250. {
  1251. sprintf( buf, ")" );
  1252. (*bufsize)--;
  1253. }
  1254. }
  1255. break;
  1256. case LDAP_FILTER_EXTENDED:
  1257. size = strlen(f->f_mr_type) + f->f_mr_value.bv_len + strlen(operator) +
  1258. (f->f_mr_dnAttrs ? sizeof(":dn") - 1 : 0) +
  1259. (f->f_mr_oid ? strlen(f->f_mr_oid) + 1 /* : */ : 0) + 3;
  1260. if(size < *bufsize) {
  1261. sprintf(buf, "(%s%s%s%s%s%.*s)", f->f_mr_type, f->f_mr_dnAttrs ? ":dn" : "",
  1262. f->f_mr_oid ? ":" : "", f->f_mr_oid ? f->f_mr_oid : "",
  1263. operator, (int)f->f_mr_value.bv_len, f->f_mr_value.bv_val);
  1264. *bufsize -= size;
  1265. }
  1266. break;
  1267. default:
  1268. size = 25;
  1269. if(size < *bufsize)
  1270. {
  1271. sprintf( buf, "unsupported type 0x%lX", f->f_choice );
  1272. *bufsize -= 25;
  1273. }
  1274. break;
  1275. }
  1276. return return_buf;
  1277. }
  1278. char *
  1279. slapi_filter_to_string( const struct slapi_filter *f, char *buf, size_t bufsize )
  1280. {
  1281. size_t size = bufsize;
  1282. return slapi_filter_to_string_internal( f, buf, &size );
  1283. }
  1284. /* rbyrne */
  1285. static int
  1286. filter_apply_list( struct slapi_filter *flist, FILTER_APPLY_FN fn, caddr_t arg,
  1287. int *error_code )
  1288. {
  1289. struct slapi_filter *f;
  1290. int rc;
  1291. for ( f = flist; f != NULL; f = f->f_next ) {
  1292. rc = slapi_filter_apply( f, fn, arg, error_code );
  1293. if ( rc == SLAPI_FILTER_SCAN_STOP || rc == SLAPI_FILTER_SCAN_ERROR) {
  1294. return(rc);
  1295. }
  1296. }
  1297. /* If we get here we've applied the whole list sucessfully so return 0 */
  1298. return(SLAPI_FILTER_SCAN_NOMORE);
  1299. }
  1300. /*
  1301. *
  1302. * The idea here is to apply, fn() to each "simple filter" in f as follows:
  1303. * fn( Slapi_Filter *simple_filter, caddr_t arg).
  1304. *
  1305. * A 'simple filter' is anything other than AND, OR or NOT.
  1306. *
  1307. * If fn() wants the seasrch to abort it returns FILTER_SCAN_STOP.
  1308. * In this case, FILTER_SCAN_STOP is returned by slapi_filter_apply().
  1309. * Otherwise fn() should return FILTER_SCAN_CONTINUE.
  1310. *
  1311. * If the whole filter is traversed, FILTER_SCAN_NO_MORE is returned.
  1312. * If an error occurred during the traverse, the scan is aborted and
  1313. * FILTER_SCAN_ERROR is returned, and in this case error_code can be checked
  1314. * for more details--right now the only error is
  1315. * SLAPI_FILTER_UNKNOWN_FILTER_TYPE.
  1316. *
  1317. *
  1318. */
  1319. int
  1320. slapi_filter_apply( struct slapi_filter *f, FILTER_APPLY_FN fn, void *arg,
  1321. int *error_code)
  1322. {
  1323. int rc = SLAPI_FILTER_SCAN_ERROR;
  1324. if ( f == NULL ) {
  1325. return SLAPI_FILTER_SCAN_NOMORE;
  1326. }
  1327. switch ( f->f_choice ) {
  1328. case LDAP_FILTER_GE:
  1329. case LDAP_FILTER_LE:
  1330. case LDAP_FILTER_APPROX:
  1331. case LDAP_FILTER_EQUALITY:
  1332. rc = (*fn)(f, arg );
  1333. break;
  1334. case LDAP_FILTER_SUBSTRINGS:
  1335. rc = (*fn)(f, arg);
  1336. /* value will be normalized later */
  1337. break;
  1338. case LDAP_FILTER_PRESENT:
  1339. rc = (*fn)(f, arg);
  1340. break;
  1341. case LDAP_FILTER_EXTENDED:
  1342. rc = (*fn)(f, arg);
  1343. break;
  1344. case LDAP_FILTER_AND:
  1345. rc = filter_apply_list( f->f_and, fn, arg, error_code );
  1346. break;
  1347. case LDAP_FILTER_OR:
  1348. rc = filter_apply_list( f->f_or, fn, arg, error_code );
  1349. break;
  1350. case LDAP_FILTER_NOT:
  1351. rc = filter_apply_list( f->f_not, fn, arg, error_code );
  1352. break;
  1353. default:
  1354. /* Unknown filter choice */
  1355. *error_code = SLAPI_FILTER_UNKNOWN_FILTER_TYPE;
  1356. rc = SLAPI_FILTER_SCAN_ERROR;
  1357. }
  1358. /*
  1359. * We propagate back FILTER_SCAN_ERROR and
  1360. * FILTER_SCAN_STOP, anything else is success.
  1361. */
  1362. if (rc != SLAPI_FILTER_SCAN_ERROR && rc != SLAPI_FILTER_SCAN_STOP) {
  1363. rc = SLAPI_FILTER_SCAN_NOMORE;
  1364. }
  1365. return(rc);
  1366. }
  1367. int
  1368. filter_flag_is_set(const Slapi_Filter *f, unsigned char flag) {
  1369. return(f->f_flags & flag);
  1370. }
  1371. static int
  1372. tombstone_check_filter(Slapi_Filter *f)
  1373. {
  1374. if ( 0 == strcasecmp ( f->f_avvalue.bv_val, SLAPI_ATTR_VALUE_TOMBSTONE)) {
  1375. return 1; /* Contains a nsTombstone filter */
  1376. }
  1377. return 0; /* Not nsTombstone filter */
  1378. }
  1379. static int
  1380. ruv_check_filter(Slapi_Filter *f)
  1381. {
  1382. if ( 0 == strcasecmp ( f->f_avvalue.bv_val, "ffffffff-ffffffff-ffffffff-ffffffff")) {
  1383. return 1; /* Contains a RUV filter */
  1384. }
  1385. return 0; /* Not a RUV filter */
  1386. }
  1387. /* filter_optimize
  1388. * ---------------
  1389. * takes a filter and optimizes it for fast evaluation
  1390. * currently this merely ensures that any AND or OR
  1391. * does not start with a NOT sub-filter if possible
  1392. */
  1393. static void
  1394. filter_optimize(Slapi_Filter *f)
  1395. {
  1396. if(!f)
  1397. return;
  1398. switch(f->f_choice)
  1399. {
  1400. case LDAP_FILTER_AND:
  1401. case LDAP_FILTER_OR:
  1402. {
  1403. /* first optimize children */
  1404. filter_optimize(f->f_list);
  1405. /* optimize this */
  1406. if(f->f_list->f_choice == LDAP_FILTER_NOT)
  1407. {
  1408. Slapi_Filter *f_prev = 0;
  1409. Slapi_Filter *f_child = 0;
  1410. /* grab a non not filter to place at start */
  1411. for(f_child = f->f_list; f_child != 0; f_child = f_child->f_next)
  1412. {
  1413. if(f_child->f_choice != LDAP_FILTER_NOT)
  1414. {
  1415. /* we have a winner, do swap */
  1416. if (f_prev) f_prev->f_next = f_child->f_next;
  1417. f_child->f_next = f->f_list;
  1418. f->f_list = f_child;
  1419. break;
  1420. }
  1421. f_prev = f_child;
  1422. }
  1423. }
  1424. }
  1425. default:
  1426. filter_optimize(f->f_next);
  1427. break;
  1428. }
  1429. }
  1430. /* slapi_filter_changetype
  1431. * ------------------------
  1432. * changes the type used in equality/>/</approx filters
  1433. * handy for features that do type mapping
  1434. */
  1435. int slapi_filter_changetype(Slapi_Filter *f, const char *newtype)
  1436. {
  1437. char **target = 0;
  1438. switch ( f->f_choice ) {
  1439. case LDAP_FILTER_EQUALITY:
  1440. case LDAP_FILTER_GE:
  1441. case LDAP_FILTER_LE:
  1442. case LDAP_FILTER_APPROX:
  1443. target = &f->f_ava.ava_type;
  1444. break;
  1445. case LDAP_FILTER_SUBSTRINGS:
  1446. target = &f->f_sub_type;
  1447. break;
  1448. case LDAP_FILTER_PRESENT:
  1449. target = &f->f_type;
  1450. break;
  1451. case LDAP_FILTER_AND:
  1452. case LDAP_FILTER_OR:
  1453. case LDAP_FILTER_NOT:
  1454. default:
  1455. goto bail;
  1456. break;
  1457. }
  1458. slapi_ch_free_string(target);
  1459. *target = slapi_ch_strdup(newtype);
  1460. bail:
  1461. return (!target);
  1462. }