filterentry.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033
  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. /* filterentry.c - apply a filter to an entry */
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <sys/types.h>
  16. #include <sys/socket.h>
  17. #include "slap.h"
  18. static int test_filter_list();
  19. static int test_extensible_filter();
  20. static int vattr_test_filter_list();
  21. static int test_filter_access( Slapi_PBlock *pb, Slapi_Entry*e,
  22. char * attr_type, struct berval *attr_val);
  23. static int slapi_vattr_filter_test_ext_internal( Slapi_PBlock *pb, Slapi_Entry *e,
  24. struct slapi_filter *f, int verify_access, int only_check_access, int *access_check_done);
  25. static char *opt_str = 0;
  26. static int opt = 0;
  27. static int optimise_filter_acl_tests()
  28. {
  29. if(!opt_str)
  30. {
  31. opt_str = getenv( "NS_DS_OPT_FILT_ACL_EVAL" );
  32. if(opt_str)
  33. opt = !strcasecmp(opt_str, "false");
  34. else
  35. opt = 0;
  36. if(!opt_str)
  37. opt_str = "dummy";
  38. }
  39. return opt;
  40. }
  41. /*
  42. * slapi_filter_test - test a filter against a single entry.
  43. * returns 0 filter matched
  44. * -1 filter did not match
  45. * >0 an ldap error code
  46. */
  47. int
  48. slapi_filter_test(
  49. Slapi_PBlock *pb,
  50. Slapi_Entry *e,
  51. struct slapi_filter *f,
  52. int verify_access
  53. )
  54. {
  55. return slapi_filter_test_ext(pb,e,f,verify_access,0);
  56. }
  57. /*
  58. * slapi_filter_test_simple - test without checking access control
  59. *
  60. * returns 0 filter matched
  61. * -1 filter did not match
  62. * >0 an ldap error code
  63. */
  64. int
  65. slapi_filter_test_simple(
  66. Slapi_Entry *e,
  67. struct slapi_filter *f
  68. )
  69. {
  70. return slapi_vattr_filter_test_ext(NULL,e,f,0,0);
  71. }
  72. /*
  73. * slapi_filter_test_ext - full-feature filter test function
  74. *
  75. * returns 0 filter matched
  76. * -1 filter did not match
  77. * >0 an ldap error code
  78. */
  79. int
  80. slapi_filter_test_ext_internal(
  81. Slapi_PBlock *pb,
  82. Slapi_Entry *e,
  83. struct slapi_filter *f,
  84. int verify_access,
  85. int only_check_access,
  86. int *access_check_done
  87. )
  88. {
  89. int rc;
  90. LDAPDebug( LDAP_DEBUG_FILTER, "=> slapi_filter_test_ext\n", 0, 0, 0 );
  91. /*
  92. * RJP: Not sure if this is semantically right, but we have to
  93. * return something if f is NULL. If there is no filter,
  94. * then we say that it did match and return 0.
  95. */
  96. if ( f == NULL) {
  97. return(0);
  98. }
  99. switch ( f->f_choice ) {
  100. case LDAP_FILTER_EQUALITY:
  101. LDAPDebug( LDAP_DEBUG_FILTER, " EQUALITY\n", 0, 0, 0 );
  102. rc = test_ava_filter( pb, e, e->e_attrs, &f->f_ava, LDAP_FILTER_EQUALITY,
  103. verify_access , only_check_access, access_check_done);
  104. break;
  105. case LDAP_FILTER_SUBSTRINGS:
  106. LDAPDebug( LDAP_DEBUG_FILTER, " SUBSTRINGS\n", 0, 0, 0 );
  107. rc = test_substring_filter( pb, e, f, verify_access , only_check_access, access_check_done);
  108. break;
  109. case LDAP_FILTER_GE:
  110. LDAPDebug( LDAP_DEBUG_FILTER, " GE\n", 0, 0, 0 );
  111. rc = test_ava_filter( pb, e, e->e_attrs, &f->f_ava, LDAP_FILTER_GE,
  112. verify_access , only_check_access, access_check_done);
  113. break;
  114. case LDAP_FILTER_LE:
  115. LDAPDebug( LDAP_DEBUG_FILTER, " LE\n", 0, 0, 0 );
  116. rc = test_ava_filter( pb, e, e->e_attrs, &f->f_ava, LDAP_FILTER_LE,
  117. verify_access , only_check_access, access_check_done);
  118. break;
  119. case LDAP_FILTER_PRESENT:
  120. LDAPDebug( LDAP_DEBUG_FILTER, " PRESENT\n", 0, 0, 0 );
  121. rc = test_presence_filter( pb, e, f->f_type, verify_access , only_check_access, access_check_done);
  122. break;
  123. case LDAP_FILTER_APPROX:
  124. LDAPDebug( LDAP_DEBUG_FILTER, " APPROX\n", 0, 0, 0 );
  125. rc = test_ava_filter( pb, e, e->e_attrs, &f->f_ava, LDAP_FILTER_APPROX,
  126. verify_access , only_check_access, access_check_done);
  127. break;
  128. case LDAP_FILTER_EXTENDED:
  129. LDAPDebug( LDAP_DEBUG_FILTER, " EXTENDED\n", 0, 0, 0 );
  130. rc = test_extensible_filter( pb, e, &f->f_mr, verify_access , only_check_access, access_check_done);
  131. break;
  132. case LDAP_FILTER_AND:
  133. LDAPDebug( LDAP_DEBUG_FILTER, " AND\n", 0, 0, 0 );
  134. rc = test_filter_list( pb, e, f->f_and,
  135. LDAP_FILTER_AND , verify_access, only_check_access, access_check_done);
  136. break;
  137. case LDAP_FILTER_OR:
  138. LDAPDebug( LDAP_DEBUG_FILTER, " OR\n", 0, 0, 0 );
  139. rc = test_filter_list( pb, e, f->f_or,
  140. LDAP_FILTER_OR , verify_access, only_check_access, access_check_done);
  141. break;
  142. case LDAP_FILTER_NOT:
  143. LDAPDebug( LDAP_DEBUG_FILTER, " NOT\n", 0, 0, 0 );
  144. rc = slapi_filter_test_ext_internal( pb, e, f->f_not , verify_access, only_check_access, access_check_done);
  145. if(!(verify_access && only_check_access)) /* dont play with access control return codes */
  146. {
  147. if(verify_access && !rc && !(*access_check_done))
  148. {
  149. /* the filter failed so access control was not checked
  150. * for NOT filters this is significant so we must ensure
  151. * access control is checked
  152. */
  153. /* check access control only */
  154. rc = slapi_filter_test_ext_internal( pb, e, f->f_not , verify_access, -1 /*only_check_access*/, access_check_done);
  155. /* preserve error code if any */
  156. if(!rc)
  157. rc = !rc;
  158. }
  159. else
  160. rc = !rc;
  161. }
  162. break;
  163. default:
  164. LDAPDebug( LDAP_DEBUG_ANY, " unknown filter type 0x%lX\n",
  165. f->f_choice, 0, 0 );
  166. rc = -1;
  167. }
  168. LDAPDebug( LDAP_DEBUG_FILTER, "<= slapi_filter_test %d\n", rc, 0, 0 );
  169. return( rc );
  170. }
  171. int
  172. slapi_filter_test_ext(
  173. Slapi_PBlock *pb,
  174. Slapi_Entry *e,
  175. struct slapi_filter *f,
  176. int verify_access,
  177. int only_check_access
  178. )
  179. {
  180. int rc = 0; /* a no op request succeeds */
  181. int access_check_done = 0;
  182. switch ( f->f_choice ) {
  183. case LDAP_FILTER_AND:
  184. case LDAP_FILTER_OR:
  185. case LDAP_FILTER_NOT:
  186. /*
  187. * optimize acl checking by only doing it once it is
  188. * known that the whole filter passes and so the entry
  189. * is eligible to be returned.
  190. * then we check the filter only for access
  191. *
  192. * complex filters really benefit from
  193. * separate stages, filter eval, followed by acl check...
  194. */
  195. if(!only_check_access)
  196. {
  197. rc = slapi_filter_test_ext_internal(pb,e,f,0,0, &access_check_done);
  198. }
  199. if(rc == 0 && verify_access)
  200. {
  201. rc = slapi_filter_test_ext_internal(pb,e,f,-1,-1, &access_check_done);
  202. }
  203. break;
  204. default:
  205. /*
  206. * ...but simple filters are better off doing eval and
  207. * acl check at once
  208. */
  209. rc = slapi_filter_test_ext_internal(pb,e,f,verify_access,only_check_access, &access_check_done);
  210. break;
  211. }
  212. return rc;
  213. }
  214. int test_ava_filter(
  215. Slapi_PBlock *pb,
  216. Slapi_Entry *e,
  217. Slapi_Attr *a,
  218. struct ava *ava,
  219. int ftype,
  220. int verify_access,
  221. int only_check_access,
  222. int *access_check_done
  223. )
  224. {
  225. int rc;
  226. LDAPDebug( LDAP_DEBUG_FILTER, "=> test_ava_filter\n", 0, 0, 0 );
  227. *access_check_done = 0;
  228. if(optimise_filter_acl_tests())
  229. {
  230. rc = 0;
  231. if(!only_check_access)
  232. {
  233. rc = -1;
  234. for ( ; a != NULL; a = a->a_next ) {
  235. if ( slapi_attr_type_cmp( ava->ava_type, a->a_type, SLAPI_TYPE_CMP_SUBTYPE ) == 0 ) {
  236. rc = plugin_call_syntax_filter_ava( a, ftype, ava );
  237. if ( rc == 0 ) {
  238. break;
  239. }
  240. }
  241. }
  242. }
  243. if ( rc == 0 && verify_access && pb != NULL ) {
  244. char *attrs[2] = { NULL, NULL };
  245. attrs[0] = ava->ava_type;
  246. rc = plugin_call_acl_plugin( pb, e, attrs, &ava->ava_value,
  247. SLAPI_ACL_SEARCH, ACLPLUGIN_ACCESS_DEFAULT, NULL );
  248. *access_check_done = -1;
  249. }
  250. }
  251. else
  252. {
  253. if ( verify_access && pb != NULL ) {
  254. char *attrs[2] = { NULL, NULL };
  255. attrs[0] = ava->ava_type;
  256. rc = plugin_call_acl_plugin( pb, e, attrs, &ava->ava_value,
  257. SLAPI_ACL_SEARCH, ACLPLUGIN_ACCESS_DEFAULT, NULL );
  258. *access_check_done = -1;
  259. if ( only_check_access || rc != LDAP_SUCCESS ) {
  260. LDAPDebug( LDAP_DEBUG_FILTER, "<= test_ava_filter %d\n",
  261. rc, 0, 0 );
  262. return( rc );
  263. }
  264. }
  265. rc = -1;
  266. for ( ; a != NULL; a = a->a_next ) {
  267. if ( slapi_attr_type_cmp( ava->ava_type, a->a_type, SLAPI_TYPE_CMP_SUBTYPE ) == 0 ) {
  268. rc = plugin_call_syntax_filter_ava( a, ftype, ava );
  269. if ( rc == 0 ) {
  270. break;
  271. }
  272. }
  273. }
  274. }
  275. LDAPDebug( LDAP_DEBUG_FILTER, "<= test_ava_filter %d\n", rc, 0, 0 );
  276. return( rc );
  277. }
  278. int
  279. test_presence_filter(
  280. Slapi_PBlock *pb,
  281. Slapi_Entry *e,
  282. char *type,
  283. int verify_access,
  284. int only_check_access,
  285. int *access_check_done
  286. )
  287. {
  288. int rc;
  289. void *hint = NULL;
  290. *access_check_done = 0;
  291. if(optimise_filter_acl_tests())
  292. {
  293. rc = 0;
  294. /* Use attrlist_find_ex to get subtype matching */
  295. if(!only_check_access)
  296. {
  297. rc = attrlist_find_ex( e->e_attrs, type,
  298. NULL, NULL, &hint ) != NULL ? 0 : -1;
  299. }
  300. if (rc == 0 && verify_access && pb != NULL) {
  301. char *attrs[2] = { NULL, NULL };
  302. attrs[0] = type;
  303. rc = plugin_call_acl_plugin( pb, e, attrs, NULL, SLAPI_ACL_SEARCH,
  304. ACLPLUGIN_ACCESS_DEFAULT, NULL );
  305. *access_check_done = -1;
  306. }
  307. }
  308. else
  309. {
  310. if (verify_access && pb != NULL) {
  311. char *attrs[2] = { NULL, NULL };
  312. attrs[0] = type;
  313. rc = plugin_call_acl_plugin( pb, e, attrs, NULL, SLAPI_ACL_SEARCH,
  314. ACLPLUGIN_ACCESS_DEFAULT, NULL );
  315. *access_check_done = -1;
  316. if ( only_check_access || rc != LDAP_SUCCESS ) {
  317. return( rc );
  318. }
  319. }
  320. /* Use attrlist_find_ex to get subtype matching */
  321. rc = attrlist_find_ex( e->e_attrs, type,
  322. NULL, NULL, &hint ) != NULL ? 0 : -1;
  323. }
  324. return rc;
  325. }
  326. /*
  327. * Convert a DN into a list of attribute values.
  328. * The caller must free the returned attributes.
  329. */
  330. static Slapi_Attr*
  331. dn2attrs(const char *dn)
  332. {
  333. int rc= 0;
  334. Slapi_Attr* dnAttrs = NULL;
  335. char** rdns = slapi_ldap_explode_dn (dn, 0);
  336. if (rdns)
  337. {
  338. char** rdn = rdns;
  339. for (; !rc && *rdn; ++rdn)
  340. {
  341. char** avas = slapi_ldap_explode_rdn (*rdn, 0);
  342. if (avas)
  343. {
  344. char** ava = avas;
  345. for (; !rc && *ava; ++ava)
  346. {
  347. char* val = strchr (*ava, '=');
  348. if (val)
  349. {
  350. struct berval bv;
  351. struct berval* bvec[] = {NULL, NULL};
  352. size_t type_len = val - *ava;
  353. char* type = slapi_ch_malloc (type_len + 1);
  354. memcpy (type, *ava, type_len);
  355. type[type_len] = '\0';
  356. ++val; /* skip the '=' */
  357. bv.bv_val = val;
  358. bv.bv_len = strlen(val);
  359. bvec[0] = &bv;
  360. attrlist_merge (&dnAttrs, type, bvec);
  361. slapi_ch_free_string( &type );
  362. }
  363. }
  364. slapi_ldap_value_free (avas);
  365. }
  366. }
  367. slapi_ldap_value_free (rdns);
  368. }
  369. return dnAttrs;
  370. }
  371. static int
  372. test_extensible_filter(
  373. Slapi_PBlock *callers_pb,
  374. Slapi_Entry *e,
  375. mr_filter_t *mrf,
  376. int verify_access,
  377. int only_check_access,
  378. int *access_check_done
  379. )
  380. {
  381. /*
  382. * The ABNF for extensible filters is
  383. *
  384. * attr [":dn"] [":" matchingrule] ":=" value
  385. * [":dn"] ":" matchingrule ":=" value
  386. *
  387. * So, sigh, there are six possible combinations:
  388. *
  389. * A) attr ":=" value
  390. * B) attr ":dn" ":=" value
  391. * C) attr ":" matchingrule ":=" value
  392. * D) attr ":dn" ":" matchingrule ":=" value
  393. * E) ":" matchingrule ":=" value
  394. * F) ":dn" ":" matchingrule ":=" value
  395. */
  396. int rc;
  397. LDAPDebug( LDAP_DEBUG_FILTER, "=> test_extensible_filter\n", 0, 0, 0 );
  398. *access_check_done = 0;
  399. if(optimise_filter_acl_tests())
  400. {
  401. rc = LDAP_SUCCESS;
  402. if(!only_check_access)
  403. {
  404. if (mrf->mrf_match==NULL)
  405. {
  406. /*
  407. * Could be A or B
  408. * No matching function. So use a regular equality filter.
  409. * Check the regular attributes for the attribute value.
  410. */
  411. struct ava a;
  412. a.ava_type= mrf->mrf_type;
  413. a.ava_value.bv_len= mrf->mrf_value.bv_len;
  414. a.ava_value.bv_val = mrf->mrf_value.bv_val;
  415. a.ava_private = NULL;
  416. rc= test_ava_filter( callers_pb, e, e->e_attrs, &a, LDAP_FILTER_EQUALITY, 0 /* Don't Verify Access */ , 0 /* don't just verify access */, access_check_done );
  417. if(rc!=LDAP_SUCCESS && mrf->mrf_dnAttrs)
  418. {
  419. /* B) Also check the DN attributes for the attribute value */
  420. Slapi_Attr* dnattrs= dn2attrs(slapi_entry_get_dn_const(e));
  421. rc= test_ava_filter( callers_pb, e, dnattrs, &a, LDAP_FILTER_EQUALITY, 0 /* Don't Verify Access */ , 0 /* don't just verify access */, access_check_done );
  422. attrlist_free( dnattrs );
  423. }
  424. }
  425. else
  426. {
  427. /*
  428. * Could be C, D, E, or F
  429. * We have a matching rule.
  430. */
  431. rc = mrf->mrf_match (mrf->mrf_object, e, e->e_attrs);
  432. if(rc!=LDAP_SUCCESS && mrf->mrf_dnAttrs)
  433. {
  434. /* D & F) Also check the DN attributes for the attribute value */
  435. Slapi_Attr* dnattrs= dn2attrs(slapi_entry_get_dn_const(e));
  436. mrf->mrf_match (mrf->mrf_object, e, dnattrs);
  437. attrlist_free( dnattrs );
  438. }
  439. }
  440. }
  441. if(rc == 0 && mrf->mrf_type!=NULL && verify_access)
  442. {
  443. char *attrs[2] = { NULL, NULL };
  444. /* Could be A, B, C, or D */
  445. /* Check we have access to this attribute on this entry */
  446. attrs[0] = mrf->mrf_type;
  447. rc= plugin_call_acl_plugin (callers_pb, e, attrs, &(mrf->mrf_value),
  448. SLAPI_ACL_SEARCH, ACLPLUGIN_ACCESS_DEFAULT, NULL );
  449. *access_check_done = -1;
  450. }
  451. }
  452. else
  453. {
  454. rc = LDAP_SUCCESS;
  455. if(mrf->mrf_type!=NULL && verify_access)
  456. {
  457. char *attrs[2] = { NULL, NULL };
  458. /* Could be A, B, C, or D */
  459. /* Check we have access to this attribute on this entry */
  460. attrs[0] = mrf->mrf_type;
  461. rc= plugin_call_acl_plugin (callers_pb, e, attrs, &(mrf->mrf_value),
  462. SLAPI_ACL_SEARCH, ACLPLUGIN_ACCESS_DEFAULT, NULL );
  463. *access_check_done = -1;
  464. if ( only_check_access ) {
  465. return rc;
  466. }
  467. }
  468. if(rc==LDAP_SUCCESS)
  469. {
  470. if (mrf->mrf_match==NULL)
  471. {
  472. /*
  473. * Could be A or B
  474. * No matching function. So use a regular equality filter.
  475. * Check the regular attributes for the attribute value.
  476. */
  477. struct ava a;
  478. a.ava_type= mrf->mrf_type;
  479. a.ava_value.bv_len= mrf->mrf_value.bv_len;
  480. a.ava_value.bv_val = mrf->mrf_value.bv_val;
  481. a.ava_private = NULL;
  482. rc= test_ava_filter( callers_pb, e, e->e_attrs, &a, LDAP_FILTER_EQUALITY, 0 /* Don't Verify Access */ , 0 /* don't just verify access */, access_check_done );
  483. if(rc!=LDAP_SUCCESS && mrf->mrf_dnAttrs)
  484. {
  485. /* B) Also check the DN attributes for the attribute value */
  486. Slapi_Attr* dnattrs= dn2attrs(slapi_entry_get_dn_const(e));
  487. rc= test_ava_filter( callers_pb, e, dnattrs, &a, LDAP_FILTER_EQUALITY, 0 /* Don't Verify Access */ , 0 /* don't just verify access */, access_check_done );
  488. attrlist_free( dnattrs );
  489. }
  490. }
  491. else
  492. {
  493. /*
  494. * Could be C, D, E, or F
  495. * We have a matching rule.
  496. */
  497. rc = mrf->mrf_match (mrf->mrf_object, e, e->e_attrs);
  498. if(rc!=LDAP_SUCCESS && mrf->mrf_dnAttrs)
  499. {
  500. /* D & F) Also check the DN attributes for the attribute value */
  501. Slapi_Attr* dnattrs= dn2attrs(slapi_entry_get_dn_const(e));
  502. mrf->mrf_match (mrf->mrf_object, e, dnattrs);
  503. attrlist_free( dnattrs );
  504. }
  505. }
  506. }
  507. }
  508. LDAPDebug( LDAP_DEBUG_FILTER, "<= test_extensible_filter %d\n", rc, 0, 0 );
  509. return( rc );
  510. }
  511. static int
  512. test_filter_list(
  513. Slapi_PBlock *pb,
  514. Slapi_Entry *e,
  515. struct slapi_filter *flist,
  516. int ftype,
  517. int verify_access,
  518. int only_check_access,
  519. int *access_check_done
  520. )
  521. {
  522. int nomatch;
  523. struct slapi_filter *f;
  524. int access_check_tmp = -1;
  525. LDAPDebug( LDAP_DEBUG_FILTER, "=> test_filter_list\n", 0, 0, 0 );
  526. *access_check_done = -1;
  527. nomatch = 1;
  528. for ( f = flist; f != NULL; f = f->f_next ) {
  529. if ( slapi_filter_test_ext_internal( pb, e, f, verify_access, only_check_access, &access_check_tmp ) != 0 ) {
  530. /* optimize AND evaluation */
  531. if ( ftype == LDAP_FILTER_AND ) {
  532. /* one false is failure */
  533. nomatch = 1;
  534. break;
  535. }
  536. } else {
  537. nomatch = 0;
  538. /* optimize OR evaluation too */
  539. if ( ftype == LDAP_FILTER_OR ) {
  540. /* only one needs to be true */
  541. break;
  542. }
  543. }
  544. if(!access_check_tmp)
  545. *access_check_done = 0;
  546. }
  547. LDAPDebug( LDAP_DEBUG_FILTER, "<= test_filter_list %d\n", nomatch, 0, 0 );
  548. return( nomatch );
  549. }
  550. char *
  551. filter_strcpy_special_ext( char *d, char *s, int flags )
  552. {
  553. for ( ; *s; s++ ) {
  554. switch ( *s ) {
  555. case '.':
  556. case '\\':
  557. case '[':
  558. case ']':
  559. case '*':
  560. case '+':
  561. case '^':
  562. case '$':
  563. *d++ = '\\';
  564. break;
  565. case '(':
  566. case ')':
  567. case '}':
  568. case '{':
  569. case '|':
  570. case '?':
  571. if (flags & FILTER_STRCPY_ESCAPE_RECHARS) {
  572. *d++ = '\\';
  573. }
  574. break;
  575. default:
  576. break;
  577. }
  578. *d++ = *s;
  579. }
  580. *d = '\0';
  581. return d;
  582. }
  583. char *
  584. filter_strcpy_special( char *d, char *s )
  585. {
  586. return filter_strcpy_special_ext(d, s, 0);
  587. }
  588. int test_substring_filter(
  589. Slapi_PBlock *pb,
  590. Slapi_Entry *e,
  591. struct slapi_filter *f,
  592. int verify_access,
  593. int only_check_access,
  594. int *access_check_done
  595. )
  596. {
  597. Slapi_Attr *a;
  598. int rc;
  599. LDAPDebug( LDAP_DEBUG_FILTER, "=> test_substring_filter\n", 0, 0, 0 );
  600. *access_check_done = 0;
  601. if(optimise_filter_acl_tests())
  602. {
  603. rc = 0;
  604. if(!only_check_access)
  605. {
  606. rc = -1;
  607. for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
  608. if ( slapi_attr_type_cmp( f->f_sub_type, a->a_type, SLAPI_TYPE_CMP_SUBTYPE ) == 0 ) {
  609. rc = plugin_call_syntax_filter_sub( pb, a, &f->f_sub );
  610. if ( rc == 0 ) {
  611. break;
  612. }
  613. }
  614. }
  615. }
  616. if ( rc == 0 && verify_access && pb != NULL) {
  617. char *attrs[2] = { NULL, NULL };
  618. attrs[0] = f->f_sub_type;
  619. rc = plugin_call_acl_plugin( pb, e, attrs, NULL,
  620. SLAPI_ACL_SEARCH, ACLPLUGIN_ACCESS_DEFAULT, NULL );
  621. *access_check_done = -1;
  622. }
  623. }
  624. else
  625. {
  626. if ( verify_access && pb != NULL) {
  627. char *attrs[2] = { NULL, NULL };
  628. attrs[0] = f->f_sub_type;
  629. rc = plugin_call_acl_plugin( pb, e, attrs, NULL,
  630. SLAPI_ACL_SEARCH, ACLPLUGIN_ACCESS_DEFAULT, NULL );
  631. *access_check_done = -1;
  632. if ( only_check_access || rc != LDAP_SUCCESS ) {
  633. return( rc );
  634. }
  635. }
  636. rc = -1;
  637. for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
  638. if ( slapi_attr_type_cmp( f->f_sub_type, a->a_type, SLAPI_TYPE_CMP_SUBTYPE ) == 0 ) {
  639. rc = plugin_call_syntax_filter_sub( pb, a, &f->f_sub );
  640. if ( rc == 0 || rc == LDAP_TIMELIMIT_EXCEEDED ) {
  641. break;
  642. }
  643. }
  644. }
  645. }
  646. LDAPDebug( LDAP_DEBUG_FILTER, "<= test_substring_filter %d\n",
  647. rc, 0, 0 );
  648. return( rc );
  649. }
  650. /*
  651. * Here's a duplicate vattr filter test code modified to support vattrs.
  652. */
  653. /*
  654. * slapi_vattr_filter_test - test a filter against a single entry.
  655. *
  656. * Supports the case where the filter mentions virtual attributes.
  657. * Performance for a real attr only filter is same as for slapi_filter_test()
  658. * No explicit support for vattrs in extended filters because:
  659. * 1. the matching rules must support virtual attributes themselves.
  660. * 2. if no matching rule is specified it defaults to equality so
  661. * could just use a normal filter with equality.
  662. * 3. virtual naming attributes are probably too complex to support.
  663. *
  664. * returns 0 filter matched
  665. * -1 filter did not match
  666. * >0 an ldap error code
  667. */
  668. int
  669. slapi_vattr_filter_test(
  670. Slapi_PBlock *pb,
  671. Slapi_Entry *e,
  672. struct slapi_filter *f,
  673. int verify_access
  674. )
  675. {
  676. return slapi_vattr_filter_test_ext(pb,e,f,verify_access,0);
  677. }
  678. /*
  679. * vattr_filter_test_ext - full-feature filter test function
  680. *
  681. * returns 0 filter matched
  682. * -1 filter did not match
  683. * >0 an ldap error code
  684. */
  685. int
  686. slapi_vattr_filter_test_ext(
  687. Slapi_PBlock *pb,
  688. Slapi_Entry *e,
  689. struct slapi_filter *f,
  690. int verify_access,
  691. int only_check_access
  692. )
  693. {
  694. int rc = 0; /* a no op request succeeds */
  695. int access_check_done = 0;
  696. switch ( f->f_choice ) {
  697. case LDAP_FILTER_AND:
  698. case LDAP_FILTER_OR:
  699. case LDAP_FILTER_NOT:
  700. /*
  701. * optimize acl checking by only doing it once it is
  702. * known that the whole filter passes and so the entry
  703. * is eligible to be returned.
  704. * then we check the filter only for access
  705. *
  706. * complex filters really benefit from
  707. * separate stages, filter eval, followed by acl check...
  708. */
  709. if(!only_check_access)
  710. {
  711. rc = slapi_vattr_filter_test_ext_internal(pb,e,f,0,0, &access_check_done);
  712. }
  713. if(rc == 0 && verify_access)
  714. {
  715. rc = slapi_vattr_filter_test_ext_internal(pb,e,f,-1,-1, &access_check_done);
  716. }
  717. break;
  718. default:
  719. /*
  720. * ...but simple filters are better off doing eval and
  721. * acl check at once
  722. */
  723. rc = slapi_vattr_filter_test_ext_internal(pb,e,f,verify_access,only_check_access, &access_check_done);
  724. break;
  725. }
  726. return rc;
  727. }
  728. static int
  729. slapi_vattr_filter_test_ext_internal(
  730. Slapi_PBlock *pb,
  731. Slapi_Entry *e,
  732. struct slapi_filter *f,
  733. int verify_access,
  734. int only_check_access,
  735. int *access_check_done
  736. )
  737. {
  738. int rc = LDAP_SUCCESS;
  739. LDAPDebug( LDAP_DEBUG_FILTER, "=> slapi_vattr_filter_test_ext\n", 0, 0, 0 );
  740. /*
  741. * RJP: Not sure if this is semantically right, but we have to
  742. * return something if f is NULL. If there is no filter,
  743. * then we say that it did match and return 0.
  744. */
  745. if ( f == NULL) {
  746. return(0);
  747. }
  748. LDAPDebug( LDAP_DEBUG_FILTER, "=> test_substring_filter\n", 0, 0, 0 );
  749. switch ( f->f_choice ) {
  750. case LDAP_FILTER_EQUALITY:
  751. LDAPDebug( LDAP_DEBUG_FILTER, " EQUALITY\n", 0, 0, 0 );
  752. if ( verify_access ) {
  753. rc = test_filter_access( pb, e, f->f_ava.ava_type,
  754. &f->f_ava.ava_value);
  755. *access_check_done = 1;
  756. }
  757. if ( only_check_access || rc != LDAP_SUCCESS ) {
  758. return( rc );
  759. }
  760. rc = vattr_test_filter( pb, e, f, FILTER_TYPE_AVA, f->f_ava.ava_type );
  761. break;
  762. case LDAP_FILTER_SUBSTRINGS:
  763. LDAPDebug( LDAP_DEBUG_FILTER, " SUBSTRINGS\n", 0, 0, 0 );
  764. if ( verify_access ) {
  765. rc = test_filter_access( pb, e, f->f_sub_type, NULL);
  766. *access_check_done = 1;
  767. }
  768. if ( only_check_access || rc != LDAP_SUCCESS ) {
  769. return( rc );
  770. }
  771. rc = vattr_test_filter( pb, e, f, FILTER_TYPE_SUBSTRING, f->f_sub_type);
  772. break;
  773. case LDAP_FILTER_GE:
  774. LDAPDebug( LDAP_DEBUG_FILTER, " GE\n", 0, 0, 0 );
  775. if ( verify_access ) {
  776. rc = test_filter_access( pb, e, f->f_ava.ava_type,
  777. &f->f_ava.ava_value);
  778. *access_check_done = 1;
  779. }
  780. if ( only_check_access || rc != LDAP_SUCCESS ) {
  781. return( rc );
  782. }
  783. rc = vattr_test_filter( pb, e, f, FILTER_TYPE_AVA, f->f_ava.ava_type);
  784. break;
  785. case LDAP_FILTER_LE:
  786. LDAPDebug( LDAP_DEBUG_FILTER, " LE\n", 0, 0, 0 );
  787. if ( verify_access ) {
  788. rc = test_filter_access( pb, e, f->f_ava.ava_type,
  789. &f->f_ava.ava_value);
  790. *access_check_done = 1;
  791. }
  792. if ( only_check_access || rc != LDAP_SUCCESS ) {
  793. return( rc );
  794. }
  795. rc = vattr_test_filter( pb, e, f, FILTER_TYPE_AVA, f->f_ava.ava_type);
  796. break;
  797. case LDAP_FILTER_PRESENT:
  798. LDAPDebug( LDAP_DEBUG_FILTER, " PRESENT\n", 0, 0, 0 );
  799. if ( verify_access ) {
  800. rc = test_filter_access( pb, e, f->f_type, NULL);
  801. *access_check_done = 1;
  802. }
  803. if ( only_check_access || rc != LDAP_SUCCESS ) {
  804. return( rc );
  805. }
  806. rc = vattr_test_filter( pb, e, f, FILTER_TYPE_PRES, f->f_type);
  807. break;
  808. case LDAP_FILTER_APPROX:
  809. LDAPDebug( LDAP_DEBUG_FILTER, " APPROX\n", 0, 0, 0 );
  810. if ( verify_access ) {
  811. rc = test_filter_access( pb, e, f->f_ava.ava_type,
  812. &f->f_ava.ava_value);
  813. *access_check_done = 1;
  814. }
  815. if ( only_check_access || rc != LDAP_SUCCESS ) {
  816. return( rc );
  817. }
  818. rc = vattr_test_filter( pb, e, f, FILTER_TYPE_AVA, f->f_ava.ava_type);
  819. break;
  820. case LDAP_FILTER_EXTENDED:
  821. LDAPDebug( LDAP_DEBUG_FILTER, " EXTENDED\n", 0, 0, 0 );
  822. rc = test_extensible_filter( pb, e, &f->f_mr, verify_access ,
  823. only_check_access, access_check_done);
  824. break;
  825. case LDAP_FILTER_AND:
  826. LDAPDebug( LDAP_DEBUG_FILTER, " AND\n", 0, 0, 0 );
  827. rc = vattr_test_filter_list( pb, e, f->f_and,
  828. LDAP_FILTER_AND , verify_access, only_check_access, access_check_done);
  829. break;
  830. case LDAP_FILTER_OR:
  831. LDAPDebug( LDAP_DEBUG_FILTER, " OR\n", 0, 0, 0 );
  832. rc = vattr_test_filter_list( pb, e, f->f_or,
  833. LDAP_FILTER_OR , verify_access, only_check_access, access_check_done);
  834. break;
  835. case LDAP_FILTER_NOT:
  836. LDAPDebug( LDAP_DEBUG_FILTER, " NOT\n", 0, 0, 0 );
  837. rc = slapi_vattr_filter_test_ext_internal( pb, e, f->f_not , verify_access, only_check_access, access_check_done);
  838. if(!(verify_access && only_check_access)) /* dont play with access control return codes */
  839. {
  840. if(verify_access && !rc && !(*access_check_done))
  841. {
  842. /* the filter failed so access control was not checked
  843. * for NOT filters this is significant so we must ensure
  844. * access control is checked
  845. */
  846. /* check access control only */
  847. rc = slapi_vattr_filter_test_ext_internal( pb, e, f->f_not , verify_access, -1 /*only_check_access*/, access_check_done);
  848. /* preserve error code if any */
  849. if(!rc)
  850. rc = !rc;
  851. }
  852. else
  853. rc = !rc;
  854. }
  855. break;
  856. default:
  857. LDAPDebug( LDAP_DEBUG_ANY, " unknown filter type 0x%lX\n",
  858. f->f_choice, 0, 0 );
  859. rc = -1;
  860. }
  861. LDAPDebug( LDAP_DEBUG_FILTER, "<= slapi_vattr_filter_test %d\n", rc, 0, 0 );
  862. return( rc );
  863. }
  864. static int test_filter_access( Slapi_PBlock *pb,
  865. Slapi_Entry *e,
  866. char *attr_type,
  867. struct berval *attr_val) {
  868. /*
  869. * attr_type--attr_type to test for.
  870. * attr_val--attr value to test for
  871. */
  872. int rc;
  873. char *attrs[2] = { NULL, NULL };
  874. attrs[0] = attr_type;
  875. rc = plugin_call_acl_plugin( pb, e, attrs, attr_val,
  876. SLAPI_ACL_SEARCH, ACLPLUGIN_ACCESS_DEFAULT, NULL );
  877. return(rc);
  878. }
  879. static int
  880. vattr_test_filter_list(
  881. Slapi_PBlock *pb,
  882. Slapi_Entry *e,
  883. struct slapi_filter *flist,
  884. int ftype,
  885. int verify_access,
  886. int only_check_access,
  887. int *access_check_done
  888. )
  889. {
  890. int nomatch;
  891. struct slapi_filter *f;
  892. LDAPDebug( LDAP_DEBUG_FILTER, "=> vattr_test_filter_list\n", 0, 0, 0 );
  893. nomatch = 1;
  894. for ( f = flist; f != NULL; f = f->f_next ) {
  895. if ( slapi_vattr_filter_test_ext_internal( pb, e, f, verify_access, only_check_access, access_check_done ) != 0 ) {
  896. /* optimize AND evaluation */
  897. if ( ftype == LDAP_FILTER_AND || verify_access) {
  898. /* one false is failure
  899. * for AND all components need to match
  900. * and for AND and OR access to ALL filter attributes is required
  901. */
  902. nomatch = 1;
  903. break;
  904. }
  905. } else {
  906. nomatch = 0;
  907. /* optimize OR evaluation too */
  908. if ( ftype == LDAP_FILTER_OR && !verify_access) {
  909. /* access to all atributes needs to be evaluated
  910. * for filter matching
  911. * only one needs to be true
  912. */
  913. break;
  914. }
  915. }
  916. }
  917. LDAPDebug( LDAP_DEBUG_FILTER, "<= test_filter_list %d\n", nomatch, 0, 0 );
  918. return( nomatch );
  919. }