plugin_internal_op.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939
  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. /* [email protected] June 13 1997 */
  13. #include <stdio.h>
  14. #include <sys/types.h>
  15. #include "slapi-plugin.h"
  16. #include "slap.h"
  17. #include <ssl.h>
  18. /* entry list node */
  19. typedef struct Entry_Node{
  20. Slapi_Entry *data;
  21. struct Entry_Node *next;
  22. } Entry_Node;
  23. /* referral list node */
  24. typedef struct Referral_Node{
  25. char *data;
  26. struct Referral_Node *next;
  27. } Referral_Node;
  28. /* data that must be passed to slapi_search_internal_callback */
  29. typedef struct plugin_search_internal_data{
  30. int rc;
  31. int num_entries;
  32. int num_referrals;
  33. Entry_Node *entry_list_head;
  34. Referral_Node *referral_list_head;
  35. } plugin_search_internal_data;
  36. /* callback functions */
  37. typedef struct callback_fn_ptrs{
  38. plugin_result_callback p_res_callback;
  39. plugin_search_entry_callback p_srch_entry_callback;
  40. plugin_referral_entry_callback p_ref_entry_callback;
  41. void *callback_data;
  42. }callback_fn_ptrs;
  43. /* forward declarations */
  44. static int seq_internal_callback_pb (Slapi_PBlock *pb, void *callback_data,
  45. plugin_result_callback prc,
  46. plugin_search_entry_callback psec,
  47. plugin_referral_entry_callback prec);
  48. static int search_internal_pb (Slapi_PBlock *pb);
  49. static int search_internal_callback_pb (Slapi_PBlock *pb, void *callback_data, plugin_result_callback prc,
  50. plugin_search_entry_callback psec, plugin_referral_entry_callback prec);
  51. void
  52. internal_getresult_callback(struct conn *unused1,
  53. struct op *op,
  54. int err,
  55. char *unused2,
  56. char *unused3,
  57. int unused4,
  58. struct berval **unused5)
  59. {
  60. if (op != NULL)
  61. {
  62. *((int *)op->o_handler_data) = err;
  63. }
  64. }
  65. void
  66. internal_res_callback(struct conn *unused1, struct op *op, int err, char *unused2,
  67. char *unused3, int unused4, struct berval **unused5)
  68. {
  69. /* make sure the user has a callback defined, if so do it, otherwise do nothing */
  70. if( ((callback_fn_ptrs *)op->o_handler_data) != NULL
  71. && ((callback_fn_ptrs *)op->o_handler_data)->p_res_callback != NULL
  72. )
  73. {
  74. ((callback_fn_ptrs *)op->o_handler_data)->p_res_callback
  75. (err, ((callback_fn_ptrs *)op->o_handler_data)->callback_data);
  76. }
  77. }
  78. int
  79. internal_srch_entry_callback(Slapi_Backend* be, Connection* conn,
  80. Operation* op, Slapi_Entry* e)
  81. {
  82. /* make sure the user has a callback defined, if so do it, otherwise do nothing */
  83. if( ((callback_fn_ptrs *)op->o_handler_data) != NULL
  84. && ((callback_fn_ptrs *)op->o_handler_data)->p_srch_entry_callback != NULL
  85. )
  86. {
  87. return(((callback_fn_ptrs *)op->o_handler_data)->p_srch_entry_callback
  88. (e, ((callback_fn_ptrs *)op->o_handler_data)->callback_data));
  89. }
  90. return(0);
  91. }
  92. int
  93. internal_ref_entry_callback(Slapi_Backend * be, Connection *conn,
  94. Operation *op, struct berval **ireferral)
  95. {
  96. int i;
  97. /* make sure the user has a callback defined, if so do it, otherwise do nothing */
  98. if( ((callback_fn_ptrs *)op->o_handler_data) != NULL
  99. && ((callback_fn_ptrs *)op->o_handler_data)->p_ref_entry_callback != NULL
  100. && ireferral != NULL
  101. )
  102. {
  103. /* loop over referrals calling callback for each one */
  104. for(i=0; ireferral[i] != NULL; i++)
  105. {
  106. ((callback_fn_ptrs *)op->o_handler_data)->p_ref_entry_callback(ireferral[i]->bv_val,
  107. ((callback_fn_ptrs *)op->o_handler_data)->callback_data);
  108. }
  109. }
  110. return(0);
  111. }
  112. Slapi_Operation*
  113. internal_operation_new(unsigned long op_type, int flags)
  114. {
  115. Slapi_Operation *op= operation_new(flags | OP_FLAG_INTERNAL /*Internal*/);
  116. /* set operation type: add, delete, etc */
  117. operation_set_type(op,op_type);
  118. /* Call the plugin extension constructors */
  119. op->o_extension = factory_create_extension(get_operation_object_type(),op,NULL /* Parent */);
  120. return op;
  121. }
  122. /******************************************************************************
  123. *
  124. * do_disconnect_server
  125. *
  126. *
  127. *
  128. *
  129. *******************************************************************************/
  130. /* this is just a wrapper exposed to the plugins */
  131. void
  132. slapi_disconnect_server(Slapi_Connection *conn)
  133. {
  134. do_disconnect_server(conn, conn->c_connid, -1);
  135. }
  136. static get_disconnect_server_fn_ptr disconnect_server_fn = NULL;
  137. void
  138. do_disconnect_server(Connection *conn, PRUint64 opconnid, int opid)
  139. {
  140. if (NULL == disconnect_server_fn) {
  141. if (get_entry_point(ENTRY_POINT_DISCONNECT_SERVER, (caddr_t *)(&disconnect_server_fn)) < 0) {
  142. return;
  143. }
  144. }
  145. /* It seems that we only call this from result.c when the ber_flush fails. */
  146. (disconnect_server_fn)(conn, opconnid, opid, SLAPD_DISCONNECT_BER_FLUSH, 0);
  147. }
  148. /******************************************************************************
  149. *
  150. * slapi_compare_internal
  151. *
  152. * no plans to implement this, but placeholder incase we change our mind
  153. *
  154. *
  155. *******************************************************************************/
  156. Slapi_PBlock *
  157. slapi_compare_internal(char * dn,
  158. char *attr,
  159. char *value,
  160. LDAPControl **controls)
  161. {
  162. printf("slapi_compare_internal not yet implemented \n");
  163. return(0);
  164. }
  165. int
  166. slapi_seq_callback( const char *ibase,
  167. int type,
  168. char *attrname,
  169. char *val,
  170. char **attrs,
  171. int attrsonly,
  172. void *callback_data,
  173. LDAPControl **controls,
  174. plugin_result_callback res_callback,
  175. plugin_search_entry_callback srch_callback,
  176. plugin_referral_entry_callback ref_callback)
  177. {
  178. int r;
  179. Slapi_PBlock pb;
  180. if (ibase == NULL)
  181. {
  182. slapi_log_error(SLAPI_LOG_FATAL, NULL,
  183. "slapi_seq_callback: NULL parameter\n");
  184. return -1;
  185. }
  186. pblock_init(&pb);
  187. slapi_seq_internal_set_pb(&pb, (char *)ibase, type, attrname, val, attrs, attrsonly, controls,
  188. plugin_get_default_component_id(), 0);
  189. r= seq_internal_callback_pb (&pb, callback_data, res_callback, srch_callback, ref_callback);
  190. pblock_done(&pb);
  191. return r;
  192. }
  193. /* pblock should contain the following data (can be set via call to slapi_seq_internal_set_pb):
  194. SLAPI_SEARCH_TARGET set to search base
  195. SAPI_SEQ_TYPE set to sequential access type (SLAPI_SEQ_FIRST, SLAPI_SEQ_NEXT, etc.
  196. SLAPI_SEQ_ATTRNAME the next two fields define attribute value assertion
  197. SLAPI_SEQ_VAL relative to which access is performed.
  198. SLAPI_CONTROLS_ARG set to request controls if present
  199. SLAPI_SEARCH_ATTRS set to the list of attributes to return
  200. SLAPI_SEARCH_ATTRSONLY tells whether attribute values should be returned.
  201. */
  202. int slapi_seq_internal_callback_pb (Slapi_PBlock *pb, void *callback_data, plugin_result_callback res_callback,
  203. plugin_search_entry_callback srch_callback,
  204. plugin_referral_entry_callback ref_callback)
  205. {
  206. if (pb == NULL)
  207. return -1;
  208. if (!allow_operation (pb))
  209. {
  210. send_ldap_result( pb, LDAP_UNWILLING_TO_PERFORM, NULL,
  211. "This plugin is not configured to access operation target data", 0, NULL );
  212. return 0;
  213. }
  214. return (seq_internal_callback_pb (pb, callback_data, res_callback, srch_callback, ref_callback));
  215. }
  216. void
  217. slapi_search_internal_set_pb (Slapi_PBlock *pb, const char *base,
  218. int scope, const char *filter, char **attrs,
  219. int attrsonly, LDAPControl **controls,
  220. const char *uniqueid,
  221. Slapi_ComponentId *plugin_identity,
  222. int operation_flags)
  223. {
  224. Operation *op;
  225. char **tmp_attrs = NULL;
  226. if (pb == NULL || base == NULL)
  227. {
  228. slapi_log_error(SLAPI_LOG_FATAL, NULL,
  229. "slapi_search_internal_set_pb: NULL parameter\n");
  230. return;
  231. }
  232. op= internal_operation_new(SLAPI_OPERATION_SEARCH,operation_flags);
  233. slapi_pblock_set(pb, SLAPI_OPERATION, op);
  234. slapi_pblock_set(pb, SLAPI_ORIGINAL_TARGET_DN, (void *)base);
  235. slapi_pblock_set(pb, SLAPI_SEARCH_SCOPE, &scope);
  236. slapi_pblock_set(pb, SLAPI_SEARCH_STRFILTER, (void*)filter);
  237. slapi_pblock_set(pb, SLAPI_CONTROLS_ARG, controls);
  238. /* forbidden attrs could be removed in slapi_pblock_set. */
  239. tmp_attrs = slapi_ch_array_dup(attrs);
  240. slapi_pblock_set(pb, SLAPI_SEARCH_ATTRS, tmp_attrs);
  241. slapi_pblock_set(pb, SLAPI_SEARCH_ATTRSONLY, &attrsonly);
  242. if (uniqueid)
  243. {
  244. slapi_pblock_set(pb, SLAPI_TARGET_UNIQUEID, (void*)uniqueid);
  245. }
  246. slapi_pblock_set(pb, SLAPI_PLUGIN_IDENTITY, (void*)plugin_identity);
  247. }
  248. void
  249. slapi_search_internal_set_pb_ext (Slapi_PBlock *pb, Slapi_DN *sdn,
  250. int scope, const char *filter, char **attrs,
  251. int attrsonly, LDAPControl **controls,
  252. const char *uniqueid,
  253. Slapi_ComponentId *plugin_identity,
  254. int operation_flags)
  255. {
  256. Operation *op;
  257. char **tmp_attrs = NULL;
  258. if (pb == NULL || sdn == NULL)
  259. {
  260. slapi_log_error(SLAPI_LOG_FATAL, NULL,
  261. "slapi_search_internal_set_pb: NULL parameter\n");
  262. return;
  263. }
  264. op= internal_operation_new(SLAPI_OPERATION_SEARCH,operation_flags);
  265. slapi_pblock_set(pb, SLAPI_OPERATION, op);
  266. slapi_pblock_set(pb, SLAPI_ORIGINAL_TARGET_DN,
  267. (void *)slapi_sdn_get_udn(sdn));
  268. slapi_pblock_set(pb, SLAPI_TARGET_SDN, (void *)sdn);
  269. slapi_pblock_set(pb, SLAPI_SEARCH_SCOPE, &scope);
  270. slapi_pblock_set(pb, SLAPI_SEARCH_STRFILTER, (void*)filter);
  271. slapi_pblock_set(pb, SLAPI_CONTROLS_ARG, controls);
  272. /* forbidden attrs could be removed in slapi_pblock_set. */
  273. tmp_attrs = slapi_ch_array_dup(attrs);
  274. slapi_pblock_set(pb, SLAPI_SEARCH_ATTRS, tmp_attrs);
  275. slapi_pblock_set(pb, SLAPI_SEARCH_ATTRSONLY, &attrsonly);
  276. if (uniqueid)
  277. {
  278. slapi_pblock_set(pb, SLAPI_TARGET_UNIQUEID, (void*)uniqueid);
  279. }
  280. slapi_pblock_set(pb, SLAPI_PLUGIN_IDENTITY, (void*)plugin_identity);
  281. }
  282. void slapi_seq_internal_set_pb(Slapi_PBlock *pb, char *base, int type, char *attrname, char *val,
  283. char **attrs, int attrsonly, LDAPControl **controls,
  284. Slapi_ComponentId *plugin_identity, int operation_flags)
  285. {
  286. Operation *op;
  287. char **tmp_attrs = NULL;
  288. if (pb == NULL || base == NULL)
  289. {
  290. slapi_log_error(SLAPI_LOG_FATAL, NULL,
  291. "slapi_seq_internal_set_pb: NULL parameter\n");
  292. return;
  293. }
  294. op= internal_operation_new(SLAPI_OPERATION_SEARCH,operation_flags);
  295. slapi_pblock_set(pb, SLAPI_OPERATION, op);
  296. slapi_pblock_set(pb, SLAPI_ORIGINAL_TARGET_DN, (void *)base );
  297. slapi_pblock_set(pb, SLAPI_SEQ_TYPE, &type);
  298. slapi_pblock_set(pb, SLAPI_SEQ_ATTRNAME, attrname);
  299. slapi_pblock_set(pb, SLAPI_SEQ_VAL, val);
  300. /* forbidden attrs could be removed in slapi_pblock_set. */
  301. tmp_attrs = slapi_ch_array_dup(attrs);
  302. slapi_pblock_set(pb, SLAPI_SEARCH_ATTRS, tmp_attrs);
  303. slapi_pblock_set(pb, SLAPI_SEARCH_ATTRSONLY, &attrsonly);
  304. slapi_pblock_set(pb, SLAPI_CONTROLS_ARG, controls);
  305. slapi_pblock_set(pb, SLAPI_PLUGIN_IDENTITY, plugin_identity);
  306. }
  307. static int seq_internal_callback_pb (Slapi_PBlock *pb, void *callback_data,
  308. plugin_result_callback prc,
  309. plugin_search_entry_callback psec,
  310. plugin_referral_entry_callback prec)
  311. {
  312. int rc;
  313. LDAPControl **controls;
  314. Operation *op;
  315. struct callback_fn_ptrs callback_handler_data;
  316. Slapi_Backend *be;
  317. char *base;
  318. char *attrname, *val;
  319. Slapi_DN *sdn = NULL;
  320. char **tmp_attrs = NULL;
  321. slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET_DN, (void *)&base );
  322. slapi_pblock_get(pb, SLAPI_CONTROLS_ARG, &controls);
  323. if (base == NULL) {
  324. sdn = slapi_sdn_new_ndn_byval("");
  325. } else {
  326. sdn = slapi_sdn_new_dn_byref(base);
  327. }
  328. slapi_pblock_set(pb, SLAPI_SEARCH_TARGET_SDN, sdn);
  329. be = slapi_be_select(sdn);
  330. callback_handler_data.p_res_callback = prc;
  331. callback_handler_data.p_srch_entry_callback = psec;
  332. callback_handler_data.p_ref_entry_callback = prec;
  333. callback_handler_data.callback_data = callback_data;
  334. slapi_pblock_get(pb, SLAPI_OPERATION, &op);
  335. op->o_handler_data = (void *)&callback_handler_data;
  336. op->o_result_handler = internal_res_callback;
  337. op->o_search_entry_handler = internal_srch_entry_callback;
  338. op->o_search_referral_handler = internal_ref_entry_callback;
  339. /* set target specification of the operation used to decide which plugins are called for the operation */
  340. operation_set_target_spec (op, sdn);
  341. /* Normalize the attribute type and value */
  342. slapi_pblock_get (pb, SLAPI_SEQ_ATTRNAME, &attrname);
  343. slapi_pblock_get (pb, SLAPI_SEQ_VAL, &val);
  344. attrname = slapi_attr_syntax_normalize(attrname);
  345. val = ( NULL == val ) ? NULL : slapi_ch_strdup( val );
  346. slapi_pblock_set(pb, SLAPI_BACKEND, be);
  347. slapi_pblock_set(pb, SLAPI_PLUGIN, be->be_database);
  348. slapi_pblock_set(pb, SLAPI_SEQ_ATTRNAME, attrname);
  349. slapi_pblock_set(pb, SLAPI_SEQ_VAL, val);
  350. slapi_pblock_set(pb, SLAPI_REQCONTROLS, controls);
  351. /* set actions taken to process the operation */
  352. set_config_params (pb);
  353. /* set common parameters */
  354. set_common_params (pb);
  355. if (be->be_seq != NULL)
  356. {
  357. rc = (*be->be_seq)(pb);
  358. }
  359. else
  360. {
  361. send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, "Function not implemented", 0, NULL);
  362. rc = 0;
  363. }
  364. slapi_ch_free_string(&attrname);
  365. slapi_ch_free_string(&val);
  366. /* slapi_pblock_get(pb, SLAPI_SEARCH_TARGET, &normbase); */
  367. slapi_pblock_get(pb, SLAPI_SEARCH_TARGET_SDN, &sdn);
  368. slapi_sdn_free(&sdn);
  369. slapi_pblock_set(pb, SLAPI_SEARCH_TARGET_SDN, NULL);
  370. slapi_pblock_get(pb, SLAPI_SEARCH_ATTRS, &tmp_attrs);
  371. slapi_ch_array_free(tmp_attrs);
  372. slapi_pblock_set(pb, SLAPI_SEARCH_ATTRS, NULL);
  373. return rc;
  374. }
  375. int
  376. slapi_search_internal_callback(const char *ibase,
  377. int scope,
  378. const char *ifstr,
  379. char **attrs,
  380. int attrsonly,
  381. void *callback_data,
  382. LDAPControl **controls,
  383. plugin_result_callback res_callback,
  384. plugin_search_entry_callback srch_callback,
  385. plugin_referral_entry_callback ref_callback)
  386. {
  387. Slapi_PBlock pb;
  388. int rc = 0;
  389. pblock_init(&pb);
  390. slapi_search_internal_set_pb (&pb, ibase, scope, ifstr, attrs, attrsonly,
  391. controls, NULL, plugin_get_default_component_id(), 0);
  392. rc = search_internal_callback_pb (&pb, callback_data, res_callback,
  393. srch_callback, ref_callback);
  394. pblock_done(&pb);
  395. return (rc);
  396. }
  397. Slapi_PBlock *
  398. slapi_search_internal(const char *base,
  399. int scope,
  400. const char *filter,
  401. LDAPControl **controls,
  402. char **attrs,
  403. int attrsonly)
  404. {
  405. Slapi_PBlock *pb;
  406. /* initialize pb */
  407. pb = slapi_pblock_new();
  408. if (pb)
  409. {
  410. slapi_search_internal_set_pb (pb, base, scope, filter, attrs, attrsonly, controls,
  411. NULL, plugin_get_default_component_id(), 0);
  412. search_internal_pb (pb);
  413. }
  414. return pb;
  415. }
  416. /* This function free searchs result or referral set on internal_ops in pblocks */
  417. void
  418. slapi_free_search_results_internal(Slapi_PBlock *pb)
  419. {
  420. int i;
  421. if(pb == NULL)
  422. {
  423. return;
  424. }
  425. if(pb->pb_plugin_internal_search_op_entries != NULL)
  426. {
  427. for(i=0; pb->pb_plugin_internal_search_op_entries[i] != NULL; i++)
  428. {
  429. slapi_entry_free(pb->pb_plugin_internal_search_op_entries[i]);
  430. }
  431. slapi_ch_free((void**)&(pb->pb_plugin_internal_search_op_entries));
  432. }
  433. /* free v3 referrals made from result handler */
  434. if(pb->pb_plugin_internal_search_op_referrals != NULL)
  435. {
  436. for(i=0; pb->pb_plugin_internal_search_op_referrals[i] != NULL; i++)
  437. {
  438. slapi_ch_free((void**)&(pb->pb_plugin_internal_search_op_referrals[i]));
  439. }
  440. slapi_ch_free((void**)&(pb->pb_plugin_internal_search_op_referrals));
  441. }
  442. }
  443. /* this functions can be used for dn as well as uniqueid based operations */
  444. /* pblock should contain the following data (can be set via call to slapi_search_internal_set_pb):
  445. For uniqueid based search:
  446. SLAPI_TARGET_DN set to dn that allows to select right backend
  447. SLAPI_TARGET_UNIQUEID set to the uniqueid of the entry we are looking for
  448. For dn based search:
  449. SLAPI_TARGET_DN set to search base
  450. SLAPI_ORIGINAL_TARGET_DN set to original un-normalized search base
  451. SLAPI_SEARCH_SCOPE set to search scope
  452. SLAPI_SEARCH_STRFILTER set to search filter
  453. SLAPI_CONTROLS_ARG set to request controls if present
  454. SLAPI_SEARCH_ATTRS set to the list of attributes to return
  455. SLAPI_SEARCH_ATTRSONLY tells whether attribute values should be returned.
  456. */
  457. int slapi_search_internal_pb (Slapi_PBlock *pb)
  458. {
  459. if (pb == NULL)
  460. return -1;
  461. if (!allow_operation (pb))
  462. {
  463. slapi_send_ldap_result( pb, LDAP_UNWILLING_TO_PERFORM, NULL,
  464. "This plugin is not configured to access operation target data", 0, NULL );
  465. return 0;
  466. }
  467. return search_internal_pb (pb);
  468. }
  469. /* pblock should contain the same data as for slapi_search_internal_pb */
  470. int slapi_search_internal_callback_pb (Slapi_PBlock *pb, void *callback_data,
  471. plugin_result_callback prc,
  472. plugin_search_entry_callback psec,
  473. plugin_referral_entry_callback prec)
  474. {
  475. if (pb == NULL)
  476. return -1;
  477. if (!allow_operation (pb))
  478. {
  479. send_ldap_result( pb, LDAP_UNWILLING_TO_PERFORM, NULL,
  480. "This plugin is not configured to access operation target data", 0, NULL );
  481. return 0;
  482. }
  483. return (search_internal_callback_pb (pb, callback_data, prc, psec, prec));
  484. }
  485. static int
  486. internal_plugin_search_entry_callback(Slapi_Entry *e, void *callback_data)
  487. {
  488. Entry_Node *this_entry;
  489. /* add this entry to the list of entries we are making */
  490. this_entry = (Entry_Node *)slapi_ch_calloc(1,sizeof(Entry_Node));
  491. if ((this_entry->data = slapi_entry_dup(e)) == NULL)
  492. {
  493. return(0);
  494. }
  495. this_entry->next = ((plugin_search_internal_data *) callback_data)->entry_list_head;
  496. ((plugin_search_internal_data *) callback_data)->entry_list_head = this_entry;
  497. ((plugin_search_internal_data *) callback_data)->num_entries++;
  498. return(0);
  499. }
  500. static int
  501. internal_plugin_search_referral_callback(char *referral, void *callback_data)
  502. {
  503. Referral_Node *this_referral;
  504. /* add this to the list of referrals we are making */
  505. this_referral = (Referral_Node *)slapi_ch_calloc(1,sizeof(Referral_Node));
  506. this_referral->data = slapi_ch_strdup(referral);
  507. this_referral->next = ((plugin_search_internal_data *) callback_data)->referral_list_head;
  508. ((plugin_search_internal_data *) callback_data)->referral_list_head = this_referral;
  509. ((plugin_search_internal_data *) callback_data)->num_referrals++;
  510. return(0);
  511. }
  512. static void internal_plugin_result_callback(int rc, void *callback_data)
  513. {
  514. /* put the result into pb_op_result */
  515. ((plugin_search_internal_data *) callback_data)->rc = rc;
  516. }
  517. static int search_internal_pb (Slapi_PBlock *pb)
  518. {
  519. plugin_search_internal_data psid;
  520. Entry_Node *iterator, *tmp;
  521. Referral_Node *ref_iterator, *ref_tmp;
  522. int i;
  523. int opresult = 0;
  524. Slapi_Entry **pb_search_entries = NULL;
  525. char **pb_search_referrals = NULL;
  526. PR_ASSERT (pb);
  527. /* initialize psid */
  528. psid.rc = -1;
  529. psid.num_entries =0;
  530. psid.num_referrals =0;
  531. psid.entry_list_head = NULL;
  532. psid.referral_list_head = NULL;
  533. /* setup additional pb data */
  534. slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_RESULT, &opresult);
  535. slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, pb_search_entries);
  536. slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_SEARCH_REFERRALS, pb_search_referrals);
  537. /* call internal search callback, define search_entry_callback, and result_callback such
  538. that the results of the search are stuffed into pb */
  539. search_internal_callback_pb (pb, &psid, internal_plugin_result_callback,
  540. internal_plugin_search_entry_callback,
  541. internal_plugin_search_referral_callback);
  542. opresult = psid.rc;
  543. /* stuff search entry pointers from linked list to contiguous array for pblock */
  544. pb_search_entries = (Slapi_Entry **)slapi_ch_calloc((psid.num_entries + 1), sizeof(Slapi_Entry *));
  545. for(i=0,iterator = psid.entry_list_head; iterator !=NULL; iterator=iterator->next, i++)
  546. {
  547. pb_search_entries[i]= iterator->data;
  548. }
  549. pb_search_entries[i]=NULL;
  550. /* free the linked list now that data has been put in the array */
  551. iterator=psid.entry_list_head;
  552. while(iterator != NULL)
  553. {
  554. /* free the data held in this node */
  555. tmp = iterator;
  556. iterator = iterator->next;
  557. /* free the node */
  558. if(tmp != NULL)
  559. {
  560. slapi_ch_free((void **) &tmp);
  561. }
  562. }
  563. psid.entry_list_head = NULL;
  564. /* stuff referrals list into an array if we got any to put into the pblock */
  565. if(psid.num_referrals != 0)
  566. {
  567. pb_search_referrals = (char **)slapi_ch_calloc((psid.num_referrals + 1), sizeof(char *));
  568. for(i=0, ref_iterator = psid.referral_list_head; ref_iterator !=NULL; ref_iterator=ref_iterator->next, i++)
  569. {
  570. pb_search_referrals[i]= ref_iterator->data;
  571. }
  572. pb_search_referrals[i]=NULL;
  573. /* free the linked list now that data has been put in the array */
  574. ref_iterator=psid.referral_list_head;
  575. while(ref_iterator != NULL)
  576. {
  577. ref_tmp = ref_iterator;
  578. ref_iterator = ref_iterator->next;
  579. /* free the node */
  580. if(ref_tmp != NULL)
  581. {
  582. slapi_ch_free((void **) &ref_tmp);
  583. }
  584. }
  585. psid.referral_list_head = NULL;
  586. }
  587. /* set the result, the array of entries, and the array of referrals in pb */
  588. slapi_pblock_set(pb, SLAPI_NENTRIES, &psid.num_entries);
  589. slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_RESULT, &opresult);
  590. slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, pb_search_entries);
  591. slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_SEARCH_REFERRALS, pb_search_referrals);
  592. return 0;
  593. }
  594. static int
  595. search_internal_callback_pb (Slapi_PBlock *pb, void *callback_data,
  596. plugin_result_callback prc,
  597. plugin_search_entry_callback psec,
  598. plugin_referral_entry_callback prec)
  599. {
  600. LDAPControl **controls;
  601. Operation *op;
  602. struct slapi_filter *filter = NULL;
  603. char *fstr = NULL;
  604. struct callback_fn_ptrs callback_handler_data;
  605. int scope;
  606. char *ifstr;
  607. int opresult;
  608. int rc = 0;
  609. char **tmp_attrs = NULL;
  610. PR_ASSERT (pb);
  611. /* retrieve search parameters */
  612. slapi_pblock_get(pb, SLAPI_SEARCH_SCOPE, &scope);
  613. slapi_pblock_get(pb, SLAPI_SEARCH_STRFILTER, &ifstr);
  614. slapi_pblock_get(pb, SLAPI_CONTROLS_ARG, &controls);
  615. /* data validation */
  616. if (ifstr == NULL || (scope != LDAP_SCOPE_BASE && scope != LDAP_SCOPE_ONELEVEL
  617. && scope != LDAP_SCOPE_SUBTREE))
  618. {
  619. opresult = LDAP_PARAM_ERROR;
  620. slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_RESULT, &opresult);
  621. return -1;
  622. }
  623. callback_handler_data.p_res_callback = prc;
  624. callback_handler_data.p_srch_entry_callback = psec;
  625. callback_handler_data.p_ref_entry_callback = prec;
  626. callback_handler_data.callback_data = callback_data;
  627. slapi_pblock_get(pb, SLAPI_OPERATION, &op);
  628. op->o_handler_data = (void *)&callback_handler_data;
  629. op->o_result_handler = internal_res_callback;
  630. op->o_search_entry_handler = internal_srch_entry_callback;
  631. op->o_search_referral_handler = internal_ref_entry_callback;
  632. filter = slapi_str2filter((fstr = slapi_ch_strdup(ifstr)));
  633. if(scope == LDAP_SCOPE_BASE) {
  634. filter->f_flags |= (SLAPI_FILTER_LDAPSUBENTRY |
  635. SLAPI_FILTER_TOMBSTONE | SLAPI_FILTER_RUV);
  636. }
  637. if (NULL == filter)
  638. {
  639. send_ldap_result(pb, LDAP_FILTER_ERROR, NULL, NULL, 0, NULL);
  640. rc = -1;
  641. goto done;
  642. }
  643. filter_normalize(filter);
  644. slapi_pblock_set(pb, SLAPI_SEARCH_FILTER, filter);
  645. slapi_pblock_set(pb, SLAPI_REQCONTROLS, controls);
  646. /* set actions taken to process the operation */
  647. set_config_params (pb);
  648. /* set parameters common for all internal operations */
  649. set_common_params (pb);
  650. {
  651. int timelimit = -1;
  652. int sizelimit = -1;
  653. int deref = LDAP_DEREF_ALWAYS;
  654. slapi_pblock_set(pb, SLAPI_SEARCH_DEREF, &deref);
  655. slapi_pblock_set(pb, SLAPI_SEARCH_TIMELIMIT, &timelimit);
  656. slapi_pblock_set(pb, SLAPI_SEARCH_SIZELIMIT, &sizelimit);
  657. }
  658. /* plugins which play with the search may
  659. * change the search params may allocate
  660. * memory so we need to keep track of
  661. * changed base search strings
  662. */
  663. op_shared_search (pb, 1);
  664. slapi_pblock_get(pb, SLAPI_SEARCH_FILTER, &filter);
  665. done:
  666. slapi_ch_free((void **) & fstr);
  667. if (filter != NULL)
  668. {
  669. slapi_filter_free(filter, 1 /* recurse */);
  670. }
  671. slapi_pblock_get(pb, SLAPI_SEARCH_ATTRS, &tmp_attrs);
  672. slapi_ch_array_free(tmp_attrs);
  673. slapi_pblock_set(pb, SLAPI_SEARCH_ATTRS, NULL);
  674. return(rc);
  675. }
  676. /* allow/disallow operation based of the plugin configuration */
  677. PRBool allow_operation (Slapi_PBlock *pb)
  678. {
  679. struct slapdplugin *plugin = NULL;
  680. Slapi_DN *sdnp = NULL;
  681. Slapi_DN sdn;
  682. PRBool allow;
  683. struct slapi_componentid * cid=NULL;
  684. PR_ASSERT (pb);
  685. /* make sure that users of new API provide plugin identity */
  686. slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &cid);
  687. if (cid == NULL)
  688. {
  689. slapi_log_error( SLAPI_LOG_FATAL, NULL, "allow_operation: component identity is NULL\n");
  690. return PR_FALSE;
  691. }
  692. plugin=(struct slapdplugin *) cid->sci_plugin;
  693. if (plugin == NULL)
  694. {
  695. slapi_log_error( SLAPI_LOG_FATAL, NULL, "allow_operation: plugin identity is NULL\n");
  696. return PR_FALSE;
  697. }
  698. slapi_sdn_init(&sdn);
  699. slapi_pblock_get (pb, SLAPI_TARGET_SDN, &sdnp);
  700. if (NULL == sdnp) {
  701. slapi_sdn_init_ndn_byval(&sdn,"");
  702. sdnp = &sdn;
  703. }
  704. allow = plugin_allow_internal_op (sdnp, plugin);
  705. slapi_sdn_done(&sdn);
  706. return allow;
  707. }
  708. /* set operation configuration based on the plugin configuration */
  709. void set_config_params (Slapi_PBlock *pb)
  710. {
  711. Slapi_Operation *operation;
  712. struct slapdplugin *plugin = NULL;
  713. char *dn;
  714. struct slapi_componentid * cid=NULL;
  715. slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
  716. slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &cid);
  717. if (cid)
  718. plugin=(struct slapdplugin *) cid->sci_plugin;
  719. /* set actions */
  720. slapi_pblock_get( pb, SLAPI_OPERATION, &operation);
  721. operation_set_flag(operation,plugin_build_operation_action_bitmap(operation->o_flags, plugin));
  722. /* Check if we have a flag to keep the operation secret */
  723. if (operation_is_flag_set(operation, OP_FLAG_ACTION_NOLOG)) {
  724. /* Clear the LOG_AUDIT and LOG_CHANGES flag */
  725. operation_clear_flag(operation, OP_FLAG_ACTION_LOG_AUDIT | OP_FLAG_ACTION_LOG_CHANGES);
  726. }
  727. /*
  728. * if we are not tracking the bind dn, then use the plugin name as the
  729. * modifiersname, otherwise, we have already set the op dn as the bind dn
  730. */
  731. if(!slapdFrontendConfig->plugin_track || slapi_sdn_isempty(&operation->o_sdn)){
  732. /* set name to be used for creator's and modifiers attributes */
  733. dn = plugin_get_dn (plugin);
  734. if (dn)
  735. slapi_sdn_init_dn_passin(&operation->o_sdn, dn);
  736. }
  737. }
  738. /* set parameters common for all internal operations */
  739. void set_common_params (Slapi_PBlock *pb)
  740. {
  741. int isroot = 1;
  742. LDAPControl **controls;
  743. slapi_pblock_get(pb, SLAPI_CONTROLS_ARG, &controls);
  744. if (NULL != controls)
  745. {
  746. int managedsait = slapi_control_present(controls,
  747. LDAP_CONTROL_MANAGEDSAIT, NULL, NULL);
  748. int pwpolicy_ctrl = slapi_control_present(controls,
  749. LDAP_X_CONTROL_PWPOLICY_REQUEST, NULL, NULL);
  750. slapi_pblock_set(pb, SLAPI_MANAGEDSAIT, &managedsait);
  751. slapi_pblock_set(pb, SLAPI_PWPOLICY, &pwpolicy_ctrl);
  752. }
  753. slapi_pblock_set(pb, SLAPI_REQUESTOR_ISROOT, &isroot);
  754. }
  755. /*
  756. * Given a DN, find an entry by doing an internal search. An LDAP error
  757. * code is returned. To check if an entry exists without returning a
  758. * copy of the entry, NULL can be passed for ret_entry.
  759. */
  760. int
  761. slapi_search_internal_get_entry( Slapi_DN *dn, char ** attrs, Slapi_Entry **ret_entry , void * component_identity)
  762. {
  763. Slapi_Entry **entries = NULL;
  764. Slapi_PBlock *int_search_pb = NULL;
  765. int rc = 0;
  766. if (ret_entry) {
  767. *ret_entry = NULL;
  768. }
  769. int_search_pb = slapi_pblock_new ();
  770. slapi_search_internal_set_pb ( int_search_pb, slapi_sdn_get_dn(dn), LDAP_SCOPE_BASE, "(|(objectclass=*)(objectclass=ldapsubentry))",
  771. attrs ,
  772. 0 /* attrsonly */, NULL /* controls */,
  773. NULL /* uniqueid */,
  774. component_identity, 0 /* actions */ );
  775. slapi_search_internal_pb ( int_search_pb );
  776. slapi_pblock_get( int_search_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc );
  777. if ( LDAP_SUCCESS == rc ) {
  778. slapi_pblock_get( int_search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries );
  779. if ( NULL != entries && NULL != entries[ 0 ]) {
  780. /* Only need to dup the entry if the caller passed ret_entry in. */
  781. if (ret_entry) {
  782. Slapi_Entry *temp_entry = NULL;
  783. temp_entry = entries[ 0 ];
  784. *ret_entry = slapi_entry_dup(temp_entry);
  785. }
  786. } else {
  787. /* No entry there */
  788. rc = LDAP_NO_SUCH_OBJECT;
  789. }
  790. }
  791. slapi_free_search_results_internal(int_search_pb);
  792. slapi_pblock_destroy(int_search_pb);
  793. int_search_pb = NULL;
  794. return rc;
  795. }