operation.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. #ifdef HAVE_CONFIG_H
  39. # include <config.h>
  40. #endif
  41. /* operation.c - routines to deal with pending ldap operations */
  42. #include <stdio.h>
  43. #include <string.h>
  44. #include <sys/types.h>
  45. #ifndef _WIN32
  46. #include <sys/socket.h>
  47. #endif
  48. #include "slap.h"
  49. int
  50. slapi_op_abandoned( Slapi_PBlock *pb )
  51. {
  52. int op_status;
  53. if (pb && pb->pb_op) {
  54. op_status = pb->pb_op->o_status;
  55. return( op_status == SLAPI_OP_STATUS_ABANDONED );
  56. }
  57. return 0;
  58. }
  59. void
  60. operation_out_of_disk_space()
  61. {
  62. LDAPDebug(LDAP_DEBUG_ANY, "*** DISK FULL ***\n", 0, 0, 0);
  63. LDAPDebug(LDAP_DEBUG_ANY, "Attempting to shut down gracefully.\n", 0, 0, 0);
  64. g_set_shutdown( SLAPI_SHUTDOWN_DISKFULL );
  65. }
  66. /* Setting the flags on the operation allows more control to the plugin
  67. * to disable and enable checks
  68. * Flags that we support for setting in the operation from the plugin are
  69. * SLAPI_OP_FLAG_NO_ACCESS_CHECK - do not check for access control
  70. * This function can be extended to support other flag setting as well
  71. */
  72. void slapi_operation_set_flag(Slapi_Operation *op, unsigned long flag)
  73. {
  74. operation_set_flag(op, flag);
  75. }
  76. void slapi_operation_clear_flag(Slapi_Operation *op, unsigned long flag)
  77. {
  78. operation_clear_flag(op, flag);
  79. }
  80. int slapi_operation_is_flag_set(Slapi_Operation *op, unsigned long flag)
  81. {
  82. return operation_is_flag_set(op, flag);
  83. }
  84. static int operation_type = -1; /* The type number assigned by the Factory for 'Operation' */
  85. int
  86. get_operation_object_type()
  87. {
  88. if(operation_type==-1)
  89. {
  90. /* The factory is given the name of the object type, in
  91. * return for a type handle. Whenever the object is created
  92. * or destroyed the factory is called with the handle so
  93. * that it may call the constructors or destructors registered
  94. * with it.
  95. */
  96. operation_type= factory_register_type(SLAPI_EXT_OPERATION,offsetof(Operation,o_extension));
  97. }
  98. return operation_type;
  99. }
  100. /*
  101. * Allocate a new Slapi_Operation.
  102. * The flag parameter indicates whether the the operation is
  103. * external (from an LDAP Client), or internal (from a plugin).
  104. */
  105. Slapi_Operation *
  106. operation_new(int flags)
  107. {
  108. /* To improve performance, we allocate the Operation, BerElement and
  109. * ber buffer in one block, instead of a separate malloc() for each.
  110. * Subsequently, ber_special_free() frees them all; we're careful
  111. * not to free the Operation separately, and the ber software knows
  112. * not to free the buffer separately.
  113. */
  114. BerElement *ber = NULL;
  115. Slapi_Operation *o;
  116. if(flags & OP_FLAG_INTERNAL)
  117. {
  118. o = (Slapi_Operation *) slapi_ch_malloc(sizeof(Slapi_Operation));
  119. }
  120. else
  121. {
  122. o= (Slapi_Operation *) ber_special_alloc( sizeof(Slapi_Operation), &ber );
  123. }
  124. if (NULL != o)
  125. {
  126. memset(o,0,sizeof(Slapi_Operation));
  127. o->o_ber = ber;
  128. o->o_msgid = -1;
  129. o->o_tag = LBER_DEFAULT;
  130. o->o_status = SLAPI_OP_STATUS_PROCESSING;
  131. slapi_sdn_init(&(o->o_sdn));
  132. o->o_authtype = NULL;
  133. o->o_isroot = 0;
  134. o->o_time = current_time();
  135. o->o_opid = 0;
  136. o->o_connid = 0;
  137. o->o_next = NULL;
  138. o->o_flags= flags;
  139. if ( config_get_accesslog_level() & LDAP_DEBUG_TIMING ) {
  140. o->o_interval = PR_IntervalNow();
  141. } else {
  142. o->o_interval = (PRIntervalTime)0;
  143. }
  144. }
  145. return o;
  146. }
  147. void
  148. operation_free( Slapi_Operation **op, Connection *conn )
  149. {
  150. if(op!=NULL && *op!=NULL)
  151. {
  152. /* Call the plugin extension destructors */
  153. factory_destroy_extension(get_operation_object_type(),*op,conn,&((*op)->o_extension));
  154. slapi_sdn_done(&(*op)->o_sdn);
  155. slapi_sdn_free(&(*op)->o_target_spec);
  156. slapi_ch_free_string( &(*op)->o_authtype );
  157. if ( (*op)->o_searchattrs != NULL ) {
  158. cool_charray_free( (*op)->o_searchattrs );
  159. }
  160. if ( NULL != (*op)->o_params.request_controls ) {
  161. ldap_controls_free( (*op)->o_params.request_controls );
  162. }
  163. if ( NULL != (*op)->o_results.result_controls ) {
  164. ldap_controls_free( (*op)->o_results.result_controls );
  165. }
  166. if(operation_is_flag_set(*op, OP_FLAG_INTERNAL))
  167. {
  168. slapi_ch_free((void**)op);
  169. }
  170. else
  171. {
  172. ber_special_free( *op , (*op)->o_ber);
  173. }
  174. /* counters_to_errors_log("after operation"); */
  175. }
  176. }
  177. void
  178. slapi_operation_set_csngen_handler ( Slapi_Operation *op, void *callback )
  179. {
  180. op->o_csngen_handler = (csngen_handler) callback;
  181. }
  182. void
  183. slapi_operation_set_replica_attr_handler ( Slapi_Operation *op, void *callback )
  184. {
  185. op->o_replica_attr_handler = (replica_attr_handler) callback;
  186. }
  187. int
  188. slapi_operation_get_replica_attr ( Slapi_PBlock *pb, Slapi_Operation *op, const char *type, void *value )
  189. {
  190. int rc = -1;
  191. if (op->o_replica_attr_handler)
  192. {
  193. rc = op->o_replica_attr_handler ( pb, type, value );
  194. }
  195. return rc;
  196. }
  197. CSN *
  198. operation_get_csn(Slapi_Operation *op)
  199. {
  200. return op->o_params.csn;
  201. }
  202. void
  203. operation_set_csn(Slapi_Operation *op,CSN *csn)
  204. {
  205. op->o_params.csn= csn;
  206. }
  207. unsigned long
  208. slapi_op_get_type(Slapi_Operation *op)
  209. {
  210. return op->o_params.operation_type;
  211. }
  212. char *
  213. slapi_op_type_to_string(unsigned long type)
  214. {
  215. switch (type)
  216. {
  217. case SLAPI_OPERATION_ADD:
  218. return "add";
  219. case SLAPI_OPERATION_DELETE:
  220. return "delete";
  221. case SLAPI_OPERATION_MODIFY:
  222. return "modify";
  223. case SLAPI_OPERATION_MODRDN:
  224. return "modrdn";
  225. case SLAPI_OPERATION_BIND:
  226. return "bind";
  227. case SLAPI_OPERATION_COMPARE:
  228. return "compare";
  229. case SLAPI_OPERATION_SEARCH:
  230. return "search";
  231. default:
  232. return "unknown operation type";
  233. }
  234. }
  235. /* DEPRECATED : USE FUNCTION ABOVE FOR NEW DVLPT */
  236. unsigned long
  237. operation_get_type(Slapi_Operation *op)
  238. {
  239. return op->o_params.operation_type;
  240. }
  241. void
  242. operation_set_type(Slapi_Operation *op, unsigned long type)
  243. {
  244. op->o_params.operation_type= type;
  245. }
  246. void
  247. operation_set_flag(Slapi_Operation *op, int flag)
  248. {
  249. op->o_flags|= flag;
  250. }
  251. void
  252. operation_clear_flag(Slapi_Operation *op, int flag)
  253. {
  254. op->o_flags &= ~flag;
  255. }
  256. int
  257. operation_is_flag_set(Slapi_Operation *op, int flag)
  258. {
  259. return op->o_flags & flag;
  260. }
  261. Slapi_DN*
  262. operation_get_target_spec (Slapi_Operation *op)
  263. {
  264. return op->o_target_spec;
  265. }
  266. void
  267. operation_set_target_spec (Slapi_Operation *op, const Slapi_DN *target_spec)
  268. {
  269. PR_ASSERT (op);
  270. PR_ASSERT (target_spec);
  271. op->o_target_spec = slapi_sdn_dup(target_spec);
  272. }
  273. void
  274. operation_set_target_spec_str (Slapi_Operation *op, const char *target_spec)
  275. {
  276. PR_ASSERT (op);
  277. op->o_target_spec = slapi_sdn_new_dn_byval (target_spec);
  278. }
  279. unsigned long operation_get_abandoned_op (const Slapi_Operation *op)
  280. {
  281. PR_ASSERT (op);
  282. return op->o_abandoned_op;
  283. }
  284. void operation_set_abandoned_op (Slapi_Operation *op, unsigned long abandoned_op)
  285. {
  286. PR_ASSERT (op);
  287. op->o_abandoned_op = abandoned_op;
  288. }
  289. /* slapi_operation_parameters manipulation functions */
  290. struct slapi_operation_parameters *operation_parameters_new()
  291. {
  292. return (slapi_operation_parameters *)slapi_ch_calloc (1, sizeof (slapi_operation_parameters));
  293. }
  294. static LDAPMod **
  295. copy_mods(LDAPMod **orig_mods)
  296. {
  297. LDAPMod **new_mods = NULL;
  298. LDAPMod *mod;
  299. Slapi_Mods smods_old;
  300. Slapi_Mods smods_new;
  301. slapi_mods_init_byref(&smods_old,orig_mods);
  302. slapi_mods_init_passin(&smods_new,new_mods);
  303. mod= slapi_mods_get_first_mod(&smods_old);
  304. while(mod!=NULL)
  305. {
  306. slapi_mods_add_modbvps(&smods_new,mod->mod_op,mod->mod_type,mod->mod_bvalues);
  307. mod= slapi_mods_get_next_mod(&smods_old);
  308. }
  309. new_mods= slapi_mods_get_ldapmods_passout(&smods_new);
  310. slapi_mods_done(&smods_old);
  311. slapi_mods_done(&smods_new);
  312. return new_mods;
  313. }
  314. struct slapi_operation_parameters *
  315. operation_parameters_dup(struct slapi_operation_parameters *sop)
  316. {
  317. struct slapi_operation_parameters *sop_new= (struct slapi_operation_parameters *)
  318. slapi_ch_malloc(sizeof(struct slapi_operation_parameters));
  319. memcpy(sop_new,sop,sizeof(struct slapi_operation_parameters));
  320. if(sop->target_address.dn!=NULL)
  321. {
  322. sop_new->target_address.dn= slapi_ch_strdup(sop->target_address.dn);
  323. }
  324. if(sop->target_address.uniqueid!=NULL)
  325. {
  326. sop_new->target_address.uniqueid= slapi_ch_strdup(sop->target_address.uniqueid);
  327. }
  328. sop_new->csn= csn_dup(sop->csn);
  329. switch(sop->operation_type)
  330. {
  331. case SLAPI_OPERATION_ADD:
  332. sop_new->p.p_add.target_entry= slapi_entry_dup(sop->p.p_add.target_entry);
  333. sop_new->p.p_add.parentuniqueid = slapi_ch_strdup(sop->p.p_add.parentuniqueid);
  334. break;
  335. case SLAPI_OPERATION_MODIFY:
  336. sop_new->p.p_modify.modify_mods= NULL;
  337. if (sop->p.p_modify.modify_mods!=NULL)
  338. {
  339. sop_new->p.p_modify.modify_mods = copy_mods(sop->p.p_modify.modify_mods);
  340. }
  341. break;
  342. case SLAPI_OPERATION_MODRDN:
  343. if(sop->p.p_modrdn.modrdn_newrdn!=NULL)
  344. {
  345. sop_new->p.p_modrdn.modrdn_newrdn= slapi_ch_strdup(sop->p.p_modrdn.modrdn_newrdn);
  346. }
  347. if(sop->p.p_modrdn.modrdn_newsuperior_address.dn!=NULL)
  348. {
  349. sop_new->p.p_modrdn.modrdn_newsuperior_address.dn =
  350. slapi_ch_strdup(sop->p.p_modrdn.modrdn_newsuperior_address.dn);
  351. }
  352. if(sop->p.p_modrdn.modrdn_newsuperior_address.uniqueid!=NULL)
  353. {
  354. sop_new->p.p_modrdn.modrdn_newsuperior_address.uniqueid =
  355. slapi_ch_strdup(sop->p.p_modrdn.modrdn_newsuperior_address.uniqueid);
  356. }
  357. sop_new->p.p_modrdn.modrdn_mods= NULL;
  358. if (sop->p.p_modrdn.modrdn_mods!=NULL)
  359. {
  360. sop_new->p.p_modrdn.modrdn_mods = copy_mods(sop->p.p_modrdn.modrdn_mods);
  361. }
  362. break;
  363. case SLAPI_OPERATION_DELETE:
  364. /* Has no extra parameters. */
  365. case SLAPI_OPERATION_BIND:
  366. case SLAPI_OPERATION_COMPARE:
  367. case SLAPI_OPERATION_SEARCH:
  368. default:
  369. /* We are not interested in these. */
  370. break;
  371. }
  372. return sop_new;
  373. }
  374. void
  375. operation_parameters_done (struct slapi_operation_parameters *sop)
  376. {
  377. if(sop!=NULL)
  378. {
  379. slapi_ch_free((void **)&sop->target_address.dn);
  380. slapi_ch_free((void **)&sop->target_address.uniqueid);
  381. csn_free(&sop->csn);
  382. switch(sop->operation_type)
  383. {
  384. case SLAPI_OPERATION_ADD:
  385. slapi_entry_free(sop->p.p_add.target_entry);
  386. sop->p.p_add.target_entry= NULL;
  387. slapi_ch_free((void **)&(sop->p.p_add.parentuniqueid));
  388. break;
  389. case SLAPI_OPERATION_MODIFY:
  390. ldap_mods_free(sop->p.p_modify.modify_mods, 1 /* Free the Array and the Elements */);
  391. sop->p.p_modify.modify_mods= NULL;
  392. break;
  393. case SLAPI_OPERATION_MODRDN:
  394. slapi_ch_free((void **)&(sop->p.p_modrdn.modrdn_newrdn));
  395. slapi_ch_free((void **)&(sop->p.p_modrdn.modrdn_newsuperior_address.dn));
  396. slapi_ch_free((void **)&(sop->p.p_modrdn.modrdn_newsuperior_address.uniqueid));
  397. ldap_mods_free(sop->p.p_modrdn.modrdn_mods, 1 /* Free the Array and the Elements */);
  398. sop->p.p_modrdn.modrdn_mods= NULL;
  399. break;
  400. case SLAPI_OPERATION_DELETE:
  401. /* Has no extra parameters. */
  402. case SLAPI_OPERATION_BIND:
  403. case SLAPI_OPERATION_COMPARE:
  404. case SLAPI_OPERATION_SEARCH:
  405. default:
  406. /* We are not interested in these */
  407. break;
  408. }
  409. }
  410. }
  411. void operation_parameters_free(struct slapi_operation_parameters **sop)
  412. {
  413. if (sop)
  414. {
  415. operation_parameters_done (*sop);
  416. slapi_ch_free ((void**)sop);
  417. }
  418. }