1
0

cb_delete.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  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. #include "cb.h"
  13. /*
  14. * Perform an delete operation
  15. *
  16. * Returns:
  17. * 0 - success
  18. * <0 - fail
  19. *
  20. */
  21. int
  22. chaining_back_delete ( Slapi_PBlock *pb )
  23. {
  24. cb_outgoing_conn *cnx;
  25. Slapi_Backend *be;
  26. cb_backend_instance *cb;
  27. LDAPControl **ctrls, **serverctrls;
  28. LDAPMessage *res;
  29. LDAP *ld = NULL;
  30. Slapi_DN *sdn = NULL;
  31. const char *dn = NULL;
  32. char **referrals = NULL;
  33. char *matched_msg, *error_msg;
  34. char *cnxerrbuf = NULL;
  35. time_t endtime = 0;
  36. int rc, parse_rc, msgid, i;
  37. if ( LDAP_SUCCESS != (rc=cb_forward_operation(pb) )) {
  38. cb_send_ldap_result( pb, rc, NULL, "Chaining forbidden", 0, NULL );
  39. return -1;
  40. }
  41. slapi_pblock_get( pb, SLAPI_BACKEND, &be );
  42. cb = cb_get_instance(be);
  43. cb_update_monitor_info(pb,cb,SLAPI_OPERATION_DELETE);
  44. /* Check wether the chaining BE is available or not */
  45. if ( cb_check_availability( cb, pb ) == FARMSERVER_UNAVAILABLE ){
  46. return -1;
  47. }
  48. slapi_pblock_get( pb, SLAPI_DELETE_TARGET_SDN, &sdn );
  49. if (NULL == sdn) {
  50. cb_send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "Null target DN", 0, NULL);
  51. return -1;
  52. }
  53. dn = slapi_sdn_get_dn(sdn);
  54. /*
  55. * Check local acls
  56. */
  57. if (cb->local_acl && !cb->associated_be_is_disabled) {
  58. char * errbuf=NULL;
  59. Slapi_Entry *te = slapi_entry_alloc();
  60. slapi_entry_set_sdn(te, sdn); /* sdn: copied */
  61. rc = cb_access_allowed (pb, te, NULL, NULL, SLAPI_ACL_DELETE,&errbuf);
  62. slapi_entry_free(te);
  63. if ( rc != LDAP_SUCCESS ) {
  64. cb_send_ldap_result( pb, rc, NULL, errbuf, 0, NULL );
  65. slapi_ch_free((void **)&errbuf);
  66. return -1;
  67. }
  68. }
  69. /*
  70. * Grab a connection handle
  71. */
  72. rc = cb_get_connection(cb->pool, &ld, &cnx, NULL, &cnxerrbuf);
  73. if (LDAP_SUCCESS != rc) {
  74. static int warned_get_conn = 0;
  75. if (!warned_get_conn) {
  76. slapi_log_error(SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM,
  77. "cb_get_connection failed (%d) %s\n",
  78. rc, ldap_err2string(rc));
  79. warned_get_conn = 1;
  80. }
  81. cb_send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL,
  82. cnxerrbuf, 0, NULL);
  83. slapi_ch_free_string(&cnxerrbuf);
  84. /* ping the farm.
  85. * If the farm is unreachable, we increment the counter */
  86. cb_ping_farm(cb, NULL, 0);
  87. return -1;
  88. }
  89. /*
  90. * Control management
  91. */
  92. if ( (rc = cb_update_controls( pb,ld,&ctrls,CB_UPDATE_CONTROLS_ADDAUTH )) != LDAP_SUCCESS ) {
  93. cb_send_ldap_result( pb, rc, NULL,NULL, 0, NULL);
  94. cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(rc));
  95. return -1;
  96. }
  97. if ( slapi_op_abandoned( pb )) {
  98. cb_release_op_connection(cb->pool,ld,0);
  99. ldap_controls_free(ctrls);
  100. return -1;
  101. }
  102. /* heart-beat management */
  103. if (cb->max_idle_time>0)
  104. endtime=current_time() + cb->max_idle_time;
  105. /*
  106. * Call the backend preoperation plugins
  107. */
  108. if((rc = slapi_plugin_call_preop_be_plugins(pb, SLAPI_PLUGIN_DEL_OP))){
  109. slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM, "delete (%s): pre betxn failed, error (%d)\n",dn,rc);
  110. cb_release_op_connection(cb->pool,ld,0);
  111. ldap_controls_free(ctrls);
  112. return -1;
  113. }
  114. /*
  115. * Send LDAP operation to the remote host
  116. */
  117. rc = ldap_delete_ext( ld, dn, ctrls, NULL, &msgid );
  118. ldap_controls_free(ctrls);
  119. if ( rc != LDAP_SUCCESS ) {
  120. cb_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL,
  121. ldap_err2string(rc), 0, NULL);
  122. cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(rc));
  123. return -1;
  124. }
  125. while ( 1 ) {
  126. if (cb_check_forward_abandon(cb,pb,ld,msgid)) {
  127. return -1;
  128. }
  129. rc = ldap_result( ld, msgid, 0, &cb->abandon_timeout, &res );
  130. switch ( rc ) {
  131. case -1:
  132. cb_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL,
  133. ldap_err2string(rc), 0, NULL);
  134. cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(rc));
  135. ldap_msgfree(res);
  136. return -1;
  137. case 0:
  138. if ((rc=cb_ping_farm(cb,cnx,endtime)) != LDAP_SUCCESS) {
  139. /* does not respond. give up and return a error to the client. */
  140. /*cb_send_ldap_result(pb,LDAP_OPERATIONS_ERROR, NULL,
  141. ldap_err2string(rc), 0, NULL);*/
  142. cb_send_ldap_result(pb,LDAP_OPERATIONS_ERROR, NULL,"FARM SERVER TEMPORARY UNAVAILABLE", 0, NULL);
  143. cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(rc));
  144. ldap_msgfree(res);
  145. return -1;
  146. }
  147. #ifdef CB_YIELD
  148. DS_Sleep(PR_INTERVAL_NO_WAIT);
  149. #endif
  150. break;
  151. default:
  152. matched_msg=error_msg=NULL;
  153. parse_rc = ldap_parse_result( ld, res, &rc, &matched_msg,
  154. &error_msg, &referrals, &serverctrls, 1 );
  155. if ( parse_rc != LDAP_SUCCESS ) {
  156. static int warned_parse_rc = 0;
  157. if (!warned_parse_rc) {
  158. slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM,
  159. "%s%s%s\n",
  160. matched_msg?matched_msg:"",
  161. (matched_msg&&(*matched_msg!='\0'))?": ":"",
  162. ldap_err2string(parse_rc) );
  163. warned_parse_rc = 1;
  164. }
  165. cb_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL,
  166. ENDUSERMSG, 0, NULL );
  167. cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(parse_rc));
  168. slapi_ch_free_string(&matched_msg);
  169. slapi_ch_free_string(&error_msg);
  170. ldap_controls_free(serverctrls);
  171. charray_free(referrals);
  172. return -1;
  173. }
  174. if ( rc != LDAP_SUCCESS ) {
  175. struct berval ** refs = referrals2berval(referrals);
  176. static int warned_rc = 0;
  177. if (!warned_rc && error_msg) {
  178. slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM,
  179. "%s%s%s\n",
  180. matched_msg?matched_msg:"",
  181. (matched_msg&&(*matched_msg!='\0'))?": ":"",
  182. error_msg );
  183. warned_rc = 1;
  184. }
  185. cb_send_ldap_result( pb, rc, matched_msg, ENDUSERMSG, 0, refs);
  186. cb_release_op_connection(cb->pool,ld,CB_LDAP_CONN_ERROR(rc));
  187. slapi_ch_free_string(&matched_msg);
  188. slapi_ch_free_string(&error_msg);
  189. if (refs)
  190. ber_bvecfree(refs);
  191. charray_free(referrals);
  192. ldap_controls_free(serverctrls);
  193. return -1;
  194. }
  195. cb_release_op_connection(cb->pool,ld,0);
  196. /* Call the backend postoperation plugins */
  197. if((rc = slapi_plugin_call_postop_be_plugins(pb, SLAPI_PLUGIN_DEL_OP))){
  198. slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM, "delete (%s): post betxn failed, error (%d)\n",dn,rc);
  199. }
  200. /* Add control response sent by the farm server */
  201. for (i=0; serverctrls && serverctrls[i];i++)
  202. slapi_pblock_set( pb, SLAPI_ADD_RESCONTROL, serverctrls[i]);
  203. ldap_controls_free(serverctrls);
  204. slapi_ch_free_string(&matched_msg);
  205. slapi_ch_free_string(&error_msg);
  206. charray_free(referrals);
  207. cb_send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL );
  208. return 0;
  209. }
  210. }
  211. /* Never reached */
  212. /* return 0; */
  213. }