예제 #1
0
static void
cib_handle_remote_msg(crm_client_t * client, xmlNode * command)
{
    const char *value = NULL;

    value = crm_element_name(command);
    if (safe_str_neq(value, "cib_command")) {
        crm_log_xml_trace(command, "Bad command: ");
        return;
    }

    if (client->name == NULL) {
        value = crm_element_value(command, F_CLIENTNAME);
        if (value == NULL) {
            client->name = strdup(client->id);
        } else {
            client->name = strdup(value);
        }
    }

    if (client->userdata == NULL) {
        value = crm_element_value(command, F_CIB_CALLBACK_TOKEN);
        if (value != NULL) {
            client->userdata = strdup(value);
            crm_trace("Callback channel for %s is %s", client->id, (char*)client->userdata);

        } else {
            client->userdata = strdup(client->id);
        }
    }

    /* unset dangerous options */
    xml_remove_prop(command, F_ORIG);
    xml_remove_prop(command, F_CIB_HOST);
    xml_remove_prop(command, F_CIB_GLOBAL_UPDATE);

    crm_xml_add(command, F_TYPE, T_CIB);
    crm_xml_add(command, F_CIB_CLIENTID, client->id);
    crm_xml_add(command, F_CIB_CLIENTNAME, client->name);
#if ENABLE_ACL
    crm_xml_add(command, F_CIB_USER, client->user);
#endif

    if (crm_element_value(command, F_CIB_CALLID) == NULL) {
        char *call_uuid = crm_generate_uuid();

        /* fix the command */
        crm_xml_add(command, F_CIB_CALLID, call_uuid);
        free(call_uuid);
    }

    if (crm_element_value(command, F_CIB_CALLOPTS) == NULL) {
        crm_xml_add_int(command, F_CIB_CALLOPTS, 0);
    }

    crm_log_xml_trace(command, "Remote command: ");
    cib_common_callback_worker(0, 0, command, client, TRUE);
}
예제 #2
0
int32_t
cib_common_callback(qb_ipcs_connection_t * c, void *data, size_t size, gboolean privileged)
{
    uint32_t id = 0;
    uint32_t flags = 0;
    int call_options = 0;
    crm_client_t *cib_client = crm_client_get(c);
    xmlNode *op_request = crm_ipcs_recv(cib_client, data, size, &id, &flags);

    if (op_request) {
        crm_element_value_int(op_request, F_CIB_CALLOPTS, &call_options);
    }

    if (op_request == NULL) {
        crm_trace("Invalid message from %p", c);
        crm_ipcs_send_ack(cib_client, id, flags, "nack", __FUNCTION__, __LINE__);
        return 0;

    } else if(cib_client == NULL) {
        crm_trace("Invalid client %p", c);
        return 0;
    }

    if (is_set(call_options, cib_sync_call)) {
        CRM_ASSERT(flags & crm_ipc_client_response);
        CRM_LOG_ASSERT(cib_client->request_id == 0);    /* This means the client has two synchronous events in-flight */
        cib_client->request_id = id;    /* Reply only to the last one */
    }

    if (cib_client->name == NULL) {
        const char *value = crm_element_value(op_request, F_CIB_CLIENTNAME);

        if (value == NULL) {
            cib_client->name = crm_itoa(cib_client->pid);
        } else {
            cib_client->name = strdup(value);
        }
    }

    crm_xml_add(op_request, F_CIB_CLIENTID, cib_client->id);
    crm_xml_add(op_request, F_CIB_CLIENTNAME, cib_client->name);

#if ENABLE_ACL
    CRM_ASSERT(cib_client->user != NULL);
    crm_acl_get_set_user(op_request, F_CIB_USER, cib_client->user);
#endif

    crm_log_xml_trace(op_request, "Client[inbound]");

    cib_common_callback_worker(id, flags, op_request, cib_client, privileged);
    free_xml(op_request);

    return 0;
}
예제 #3
0
파일: remote.c 프로젝트: fghaas/pacemaker
gboolean
cib_remote_msg(int csock, gpointer data)
{
    const char *value = NULL;
    xmlNode *command = NULL;
    cib_client_t *client = data;

    crm_trace("%s callback", client->encrypted ? "secure" : "clear-text");

    command = cib_recv_remote_msg(client->channel, client->encrypted);
    if (command == NULL) {
        return FALSE;
    }

    value = crm_element_name(command);
    if (safe_str_neq(value, "cib_command")) {
        crm_log_xml(LOG_MSG, "Bad command: ", command);
        goto bail;
    }

    if (client->name == NULL) {
        value = crm_element_value(command, F_CLIENTNAME);
        if (value == NULL) {
            client->name = crm_strdup(client->id);
        } else {
            client->name = crm_strdup(value);
        }
    }

    if (client->callback_id == NULL) {
        value = crm_element_value(command, F_CIB_CALLBACK_TOKEN);
        if (value != NULL) {
            client->callback_id = crm_strdup(value);
            crm_debug_2("Callback channel for %s is %s", client->id, client->callback_id);

        } else {
            client->callback_id = crm_strdup(client->id);
        }
    }

    /* unset dangerous options */
    xml_remove_prop(command, F_ORIG);
    xml_remove_prop(command, F_CIB_HOST);
    xml_remove_prop(command, F_CIB_GLOBAL_UPDATE);

    crm_xml_add(command, F_TYPE, T_CIB);
    crm_xml_add(command, F_CIB_CLIENTID, client->id);
    crm_xml_add(command, F_CIB_CLIENTNAME, client->name);
#if ENABLE_ACL
    crm_xml_add(command, F_CIB_USER, client->user);
#endif

    if (crm_element_value(command, F_CIB_CALLID) == NULL) {
        cl_uuid_t call_id;
        char call_uuid[UU_UNPARSE_SIZEOF];

        /* fix the command */
        cl_uuid_generate(&call_id);
        cl_uuid_unparse(&call_id, call_uuid);
        crm_xml_add(command, F_CIB_CALLID, call_uuid);
    }

    if (crm_element_value(command, F_CIB_CALLOPTS) == NULL) {
        crm_xml_add_int(command, F_CIB_CALLOPTS, 0);
    }

    crm_log_xml(LOG_MSG, "Remote command: ", command);
    cib_common_callback_worker(command, client, FALSE, TRUE);
  bail:
    free_xml(command);
    command = NULL;
    return TRUE;
}
예제 #4
0
int32_t
cib_common_callback(qb_ipcs_connection_t *c, void *data, size_t size, gboolean privileged)
{
    int call_options = 0;
    const char *op = NULL;
    const char *call = NULL;
    xmlNode *op_request = crm_ipcs_recv(c, data, size);
    cib_client_t *cib_client = qb_ipcs_context_get(c);

    if(op_request) {
        op = crm_element_value(op_request, F_CIB_OPERATION);
        call = crm_element_value(op_request, F_CIB_CALLID);
        crm_element_value_int(op_request, F_CIB_CALLOPTS, &call_options);
    }

    crm_trace("Inbound: %.200s", data);
    if (op_request == NULL || cib_client == NULL) {
        xmlNode *ack = create_xml_node(NULL, "nack");

        crm_trace("Sending nack to %p", cib_client);
        crm_xml_add(ack, F_CIB_CALLID, call);
        crm_xml_add(ack, F_CIB_OPERATION, op);
        crm_xml_add(ack, XML_ATTR_ORIGIN, __FUNCTION__);
        crm_ipcs_send(c, ack, FALSE);
        free_xml(ack);
        return 0;

    } else if((call_options & cib_sync_call) == 0) {
        xmlNode *ack = create_xml_node(NULL, "ack");

        crm_trace("Sending a-sync ack to %p", cib_client);
        crm_xml_add(ack, F_CIB_CALLID, call);
        crm_xml_add(ack, F_CIB_OPERATION, op);
        crm_xml_add(ack, XML_ATTR_ORIGIN, __FUNCTION__);
        crm_ipcs_send(c, ack, FALSE);
        free_xml(ack);
    }

    if (cib_client->name == NULL) {
        const char *value = crm_element_value(op_request, F_CIB_CLIENTNAME);
        if (value == NULL) {
            cib_client->name = crm_itoa(crm_ipcs_client_pid(c));
        } else {
            cib_client->name = strdup(value);
        }
    }

    if (cib_client->callback_id == NULL) {
        const char *value = crm_element_value(op_request, F_CIB_CALLBACK_TOKEN);
        if (value != NULL) {
            cib_client->callback_id = strdup(value);
            
        } else {
            cib_client->callback_id = strdup(cib_client->id);
        }
    }
    
    crm_xml_add(op_request, F_CIB_CLIENTID, cib_client->id);
    crm_xml_add(op_request, F_CIB_CLIENTNAME, cib_client->name);

#if ENABLE_ACL
    determine_request_user(cib_client->user, op_request, F_CIB_USER);
#endif

    crm_log_xml_trace(op_request, "Client[inbound]");

    cib_common_callback_worker(op_request, cib_client, privileged);
    free_xml(op_request);

    return 0;
}