diff --git a/cib/common.c b/cib/common.c
index 849c233714..88e5f62739 100644
--- a/cib/common.c
+++ b/cib/common.c
@@ -1,380 +1,380 @@
 /* 
  * Copyright (C) 2008 Andrew Beekhof <andrew@beekhof.net>
  * 
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  * 
  * This software is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  * 
  * You should have received a copy of the GNU General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include <crm_internal.h>
 
 #include <sys/param.h>
 #include <stdio.h>
 #include <sys/types.h>
 #include <unistd.h>
 
 #include <stdlib.h>
 #include <errno.h>
 #include <fcntl.h>
 
 #include <clplumbing/uids.h>
 #include <clplumbing/cl_uuid.h>
 #include <clplumbing/cl_malloc.h>
 #include <clplumbing/Gmain_timeout.h>
 
 #include <crm/crm.h>
 #include <crm/cib.h>
 #include <crm/msg_xml.h>
 #include <crm/common/ipc.h>
 #include <crm/common/cluster.h>
 #include <crm/common/ctrl.h>
 #include <crm/common/xml.h>
 #include <crm/common/msg.h>
 
 #include <cibio.h>
 #include <callbacks.h>
 #include <cibmessages.h>
 #include <cibprimatives.h>
 #include "common.h"
 
 extern gboolean cib_is_master;
 extern const char* cib_root;
 gboolean stand_alone = FALSE;
 extern enum cib_errors cib_status;
 extern gboolean can_write(int flags);
 extern enum cib_errors cib_perform_command(
     xmlNode *request, xmlNode **reply, xmlNode **cib_diff, gboolean privileged);
 
 
 static xmlNode *
 cib_prepare_common(xmlNode *root, const char *section)
 {
     xmlNode *data = NULL;
 	
     /* extract the CIB from the fragment */
     if(root == NULL) {
 	return NULL;
 
     } else if(safe_str_eq(crm_element_name(root), XML_TAG_FRAGMENT)
 	      || safe_str_eq(crm_element_name(root), F_CIB_CALLDATA)) {
 	data = find_xml_node(root, XML_TAG_CIB, TRUE);
 	if(data != NULL) {
 	    crm_debug_3("Extracted CIB from %s", TYPE(root));
 	} else {
 	    crm_log_xml_debug_4(root, "No CIB");
 	}
 		
     } else {
 	data = root;
     }
 
     /* grab the section specified for the command */
     if(section != NULL
        && data != NULL
        && safe_str_eq(crm_element_name(data), XML_TAG_CIB)){
 	int rc = revision_check(data, the_cib, 0/* call_options */);
 	if(rc == cib_ok) {
 	    data = get_object_root(section, data);
 	    if(data != NULL) {
 		crm_debug_3("Extracted %s from CIB", section);
 	    } else {
 		crm_log_xml_debug_4(root, "No Section");
 	    }
 	} else {
 	    crm_debug_2("Revision check failed");
 	}
     }
 
     crm_log_xml_debug_4(root, "cib:input");
-    return copy_xml(data);
+    return data;
 }
 
 static gboolean
 verify_section(const char *section)
 {
     if(section == NULL) {
 	return TRUE;
     } else if(safe_str_eq(section, XML_TAG_CIB)) {
 	return TRUE;
     } else if(safe_str_eq(section, XML_CIB_TAG_STATUS)) {
 	return TRUE;
     } else if(safe_str_eq(section, XML_CIB_TAG_CRMCONFIG)) {
 	return TRUE;
     } else if(safe_str_eq(section, XML_CIB_TAG_NODES)) {
 	return TRUE;
     } else if(safe_str_eq(section, XML_CIB_TAG_RESOURCES)) {
 	return TRUE;
     } else if(safe_str_eq(section, XML_CIB_TAG_CONSTRAINTS)) {
 	return TRUE;
     }
     return FALSE;
 }
 
 
 static enum cib_errors
 cib_prepare_none(xmlNode *request, xmlNode **data, const char **section)
 {
     *data = NULL;
     *section = crm_element_value(request, F_CIB_SECTION);
     if(verify_section(*section) == FALSE) {
 	return cib_bad_section;
     }
     return cib_ok;
 }
 
 static enum cib_errors
 cib_prepare_data(xmlNode *request, xmlNode **data, const char **section)
 {
     xmlNode *input_fragment = get_message_xml(request, F_CIB_CALLDATA);
     *section = crm_element_value(request, F_CIB_SECTION);
     *data = cib_prepare_common(input_fragment, *section);
     /* crm_log_xml_debug(*data, "data"); */
     if(verify_section(*section) == FALSE) {
 	return cib_bad_section;
     }
     return cib_ok;
 }
 
 static enum cib_errors
 cib_prepare_sync(xmlNode *request, xmlNode **data, const char **section)
 {
     *section = crm_element_value(request, F_CIB_SECTION);
     *data = NULL;
     if(verify_section(*section) == FALSE) {
 	return cib_bad_section;
     }
     return cib_ok;
 }
 
 static enum cib_errors
 cib_prepare_diff(xmlNode *request, xmlNode **data, const char **section)
 {
     xmlNode *input_fragment = NULL;
     const char *update     = crm_element_value(request, F_CIB_GLOBAL_UPDATE);
 
     *data = NULL;
     *section = NULL;
 
     if(crm_is_true(update)) {
 	input_fragment = get_message_xml(request,F_CIB_UPDATE_DIFF);
 		
     } else {
 	input_fragment = get_message_xml(request, F_CIB_CALLDATA);
     }
 
     CRM_CHECK(input_fragment != NULL,crm_log_xml(LOG_WARNING, "no input", request));
     *data = cib_prepare_common(input_fragment, NULL);
     return cib_ok;
 }
 
 static enum cib_errors
 cib_cleanup_query(const char *op, xmlNode **data, xmlNode **output) 
 {
     CRM_DEV_ASSERT(*data == NULL);
     return cib_ok;
 }
 
 static enum cib_errors
 cib_cleanup_data(const char *op, xmlNode **data, xmlNode **output) 
 {
     free_xml(*output);
-    free_xml(*data);
+    *data = NULL;
     return cib_ok;
 }
 
 static enum cib_errors
 cib_cleanup_output(const char *op, xmlNode **data, xmlNode **output) 
 {
     free_xml(*output);
     return cib_ok;
 }
 
 static enum cib_errors
 cib_cleanup_none(const char *op, xmlNode **data, xmlNode **output) 
 {
     CRM_DEV_ASSERT(*data == NULL);
     CRM_DEV_ASSERT(*output == NULL);
     return cib_ok;
 }
 
 static enum cib_errors
 cib_cleanup_sync(const char *op, xmlNode **data, xmlNode **output) 
 {
     /* data is non-NULL but doesnt need to be free'd */
     CRM_DEV_ASSERT(*data == NULL);
     CRM_DEV_ASSERT(*output == NULL);
     return cib_ok;
 }
 
 /*
   typedef struct cib_operation_s
   {
   const char* 	operation;
   gboolean	modifies_cib;
   gboolean	needs_privileges;
   gboolean	needs_quorum;
   enum cib_errors (*prepare)(xmlNode *, xmlNode**, const char **);
   enum cib_errors (*cleanup)(xmlNode**, xmlNode**);
   enum cib_errors (*fn)(
   const char *, int, const char *,
   xmlNode*, xmlNode*, xmlNode**, xmlNode**);
   } cib_operation_t;
 */
 /* technically bump does modify the cib...
  * but we want to split the "bump" from the "sync"
  */
 static cib_operation_t cib_server_ops[] = {
     {NULL,		   FALSE, FALSE, FALSE, cib_prepare_none, cib_cleanup_none,   cib_process_default},
     {CIB_OP_QUERY,     FALSE, FALSE, FALSE, cib_prepare_none, cib_cleanup_query,  cib_process_query},
     {CIB_OP_MODIFY,    TRUE,  TRUE,  TRUE,  cib_prepare_data, cib_cleanup_data,   cib_process_modify},
     {CIB_OP_UPDATE,    TRUE,  TRUE,  TRUE,  cib_prepare_data, cib_cleanup_data,   cib_process_change},
     {CIB_OP_APPLY_DIFF,TRUE,  TRUE,  TRUE,  cib_prepare_diff, cib_cleanup_data,   cib_server_process_diff},
     {CIB_OP_SLAVE,     FALSE, TRUE,  FALSE, cib_prepare_none, cib_cleanup_none,   cib_process_readwrite},
     {CIB_OP_SLAVEALL,  FALSE, TRUE,  FALSE, cib_prepare_none, cib_cleanup_none,   cib_process_readwrite},
     {CIB_OP_SYNC_ONE,  FALSE, TRUE,  FALSE, cib_prepare_sync, cib_cleanup_sync,   cib_process_sync_one},
     {CIB_OP_MASTER,    FALSE, TRUE,  FALSE, cib_prepare_none, cib_cleanup_none,   cib_process_readwrite},
     {CIB_OP_ISMASTER,  FALSE, TRUE,  FALSE, cib_prepare_none, cib_cleanup_none,   cib_process_readwrite},
     {CIB_OP_BUMP,      TRUE,  TRUE,  TRUE,  cib_prepare_none, cib_cleanup_output, cib_process_bump},
     {CIB_OP_REPLACE,   TRUE,  TRUE,  TRUE,  cib_prepare_data, cib_cleanup_data,   cib_process_replace_svr},
     {CIB_OP_CREATE,    TRUE,  TRUE,  TRUE,  cib_prepare_data, cib_cleanup_data,   cib_process_change},
     {CIB_OP_DELETE,    TRUE,  TRUE,  TRUE,  cib_prepare_data, cib_cleanup_data,   cib_process_delete},
     {CIB_OP_DELETE_ALT,TRUE,  TRUE,  TRUE,  cib_prepare_data, cib_cleanup_data,   cib_process_change},
     {CIB_OP_SYNC,      FALSE, TRUE,  FALSE, cib_prepare_sync, cib_cleanup_sync,   cib_process_sync},
     {CRM_OP_QUIT,	   FALSE, TRUE,  FALSE, cib_prepare_none, cib_cleanup_none,   cib_process_quit},
     {CRM_OP_PING,	   FALSE, FALSE, FALSE, cib_prepare_none, cib_cleanup_output, cib_process_ping},
     {CIB_OP_ERASE,     TRUE,  TRUE,  TRUE,  cib_prepare_none, cib_cleanup_output, cib_process_erase},
     {CRM_OP_NOOP,	   FALSE, FALSE, FALSE, cib_prepare_none, cib_cleanup_none,   cib_process_default},
     {"cib_shutdown_req",FALSE, TRUE, FALSE, cib_prepare_sync, cib_cleanup_sync,   cib_process_shutdown_req},
 };
 
 enum cib_errors
 cib_get_operation_id(const char *op, int *operation) 
 {
     int lpc = 0;
     int max_msg_types = DIMOF(cib_server_ops);
 
     for (lpc = 0; lpc < max_msg_types; lpc++) {
 	if (safe_str_eq(op, cib_server_ops[lpc].operation)) {
 	    *operation = lpc;
 	    return cib_ok;
 	}
     }
     crm_err("Operation %s is not valid", op);
     *operation = -1;
     return cib_operation;
 }
 
 xmlNode *
 cib_msg_copy(xmlNode *msg, gboolean with_data) 
 {
 	int lpc = 0;
 	const char *field = NULL;
 	const char *value = NULL;
 	xmlNode *value_struct = NULL;
 
 	static const char *field_list[] = {
 		F_XML_TAGNAME	,
 		F_TYPE		,
 		F_CIB_CLIENTID  ,
 		F_CIB_CALLOPTS  ,
 		F_CIB_CALLID    ,
 		F_CIB_OPERATION ,
 		F_CIB_ISREPLY   ,
 		F_CIB_SECTION   ,
 		F_CIB_HOST	,
 		F_CIB_RC	,
 		F_CIB_DELEGATED	,
 		F_CIB_OBJID	,
 		F_CIB_OBJTYPE	,
 		F_CIB_EXISTING	,
 		F_CIB_SEENCOUNT	,
 		F_CIB_TIMEOUT	,
 		F_CIB_CALLBACK_TOKEN	,
 		F_CIB_GLOBAL_UPDATE	,
 		F_CIB_CLIENTNAME	,
 		F_CIB_NOTIFY_TYPE	,
 		F_CIB_NOTIFY_ACTIVATE
 	};
 	
 	static const char *data_list[] = {
 		F_CIB_CALLDATA  ,
 		F_CIB_UPDATE	,
 		F_CIB_UPDATE_RESULT
 	};
 
 	xmlNode *copy = create_xml_node(NULL, "copy");
 	CRM_ASSERT(copy != NULL);
 	
 	for(lpc = 0; lpc < DIMOF(field_list); lpc++) {
 		field = field_list[lpc];
 		value = crm_element_value(msg, field);
 		if(value != NULL) {
 			crm_xml_add(copy, field, value);
 		}
 	}
 	for(lpc = 0; with_data && lpc < DIMOF(data_list); lpc++) {
 		field = data_list[lpc];
 		value_struct = get_message_xml(msg, field);
 		if(value_struct != NULL) {
 			add_message_xml(copy, field, value_struct);
 		}
 	}
 
 	return copy;
 }
 
 cib_op_t *cib_op_func(int call_type) 
 {
     return &(cib_server_ops[call_type].fn);
 }
 
 gboolean cib_op_modifies(int call_type) 
 {
     return cib_server_ops[call_type].modifies_cib;
 }
 
 int cib_op_can_run(
     int call_type, int call_options, gboolean privileged, gboolean global_update)
 {
     int rc = cib_ok;
     
     if(rc == cib_ok &&
        cib_server_ops[call_type].needs_privileges
        && privileged == FALSE) {
 	/* abort */
 	return cib_not_authorized;
     }
 	
     if(rc == cib_ok
        && stand_alone == FALSE
        && global_update == FALSE
        && (call_options & cib_quorum_override) == 0
        && cib_server_ops[call_type].needs_quorum) {
 	return cib_no_quorum;
     }
     return cib_ok;
 }
 
 
 int cib_op_prepare(
     int call_type, xmlNode *request, xmlNode **input, const char **section) 
 {
     return cib_server_ops[call_type].prepare(request, input, section);
 }
 
 int cib_op_cleanup(
     int call_type, const char *op, xmlNode **input, xmlNode **output) 
 {
     return cib_server_ops[call_type].cleanup(op, input, output);
 }