Пример #1
0
/* Exit code means? */
static int32_t
attrd_ipc_dispatch(qb_ipcs_connection_t *c, void *data, size_t size)
{
    uint32_t id = 0;
    uint32_t flags = 0;
#if ENABLE_ACL
    attrd_client_t *client = qb_ipcs_context_get(c);
#endif
    xmlNode *msg = crm_ipcs_recv(c, data, size, &id, &flags);

    if(flags & crm_ipc_client_response) {
        crm_trace("Ack'ing msg from %d (%p)", crm_ipcs_client_pid(c), c);
        crm_ipcs_send_ack(c, id, "ack", __FUNCTION__, __LINE__);
    }

    if (msg == NULL) {
        crm_debug("No msg from %d (%p)", crm_ipcs_client_pid(c), c);
        return 0;
    }

#if ENABLE_ACL
    determine_request_user(client->user, msg, F_ATTRD_USER);
#endif

    crm_trace("Processing msg from %d (%p)", crm_ipcs_client_pid(c), c);
    crm_log_xml_trace(msg, __PRETTY_FUNCTION__);
    
    attrd_local_callback(msg);
    
    free_xml(msg);
    return 0;
}
Пример #2
0
static int32_t
attrd_ipc_dispatch(qb_ipcs_connection_t * c, void *data, size_t size)
{
    uint32_t id = 0;
    uint32_t flags = 0;
    crm_client_t *client = crm_client_get(c);
    xmlNode *xml = crm_ipcs_recv(client, data, size, &id, &flags);

    crm_ipcs_send_ack(client, id, flags, "ack", __FUNCTION__, __LINE__);
    if (xml == NULL) {
        crm_debug("No msg from %d (%p)", crm_ipcs_client_pid(c), c);
        return 0;
    }
#if ENABLE_ACL
    CRM_ASSERT(client->user != NULL);
    crm_acl_get_set_user(xml, F_ATTRD_USER, client->user);
#endif

    crm_trace("Processing msg from %d (%p)", crm_ipcs_client_pid(c), c);
    crm_log_xml_trace(xml, __FUNCTION__);

    attrd_client_message(client, xml);

    free_xml(xml);
    return 0;
}
Пример #3
0
static int32_t
attrd_ipc_dispatch(qb_ipcs_connection_t * c, void *data, size_t size)
{
    uint32_t id = 0;
    uint32_t flags = 0;
    crm_client_t *client = crm_client_get(c);
    xmlNode *xml = crm_ipcs_recv(client, data, size, &id, &flags);
    const char *op;

    if (xml == NULL) {
        crm_debug("No msg from %d (%p)", crm_ipcs_client_pid(c), c);
        return 0;
    }
#if ENABLE_ACL
    CRM_ASSERT(client->user != NULL);
    crm_acl_get_set_user(xml, F_ATTRD_USER, client->user);
#endif

    crm_trace("Processing msg from %d (%p)", crm_ipcs_client_pid(c), c);
    crm_log_xml_trace(xml, __FUNCTION__);

    op = crm_element_value(xml, F_ATTRD_TASK);

    if (client->name == NULL) {
        const char *value = crm_element_value(xml, F_ORIG);
        client->name = crm_strdup_printf("%s.%d", value?value:"unknown", client->pid);
    }

    if (safe_str_eq(op, ATTRD_OP_PEER_REMOVE)) {
        attrd_send_ack(client, id, flags);
        attrd_client_peer_remove(client->name, xml);

    } else if (safe_str_eq(op, ATTRD_OP_UPDATE)) {
        attrd_send_ack(client, id, flags);
        attrd_client_update(xml);

    } else if (safe_str_eq(op, ATTRD_OP_UPDATE_BOTH)) {
        attrd_send_ack(client, id, flags);
        attrd_client_update(xml);

    } else if (safe_str_eq(op, ATTRD_OP_UPDATE_DELAY)) {
        attrd_send_ack(client, id, flags);
        attrd_client_update(xml);
  
    } else if (safe_str_eq(op, ATTRD_OP_REFRESH)) {
        attrd_send_ack(client, id, flags);
        attrd_client_refresh();

    } else if (safe_str_eq(op, ATTRD_OP_QUERY)) {
        /* queries will get reply, so no ack is necessary */
        attrd_client_query(client, id, flags, xml);

    } else {
        crm_info("Ignoring request from client %s with unknown operation %s",
                 client->name, op);
    }

    free_xml(xml);
    return 0;
}
Пример #4
0
ssize_t
crm_ipcs_send(qb_ipcs_connection_t *c, xmlNode *message, enum ipcs_send_flags flags)
{
    int rc;
    int lpc = 0;
    struct iovec iov[2];
    static uint32_t id = 0;
    const char *type = "Response";
    struct qb_ipc_response_header header;
    char *buffer = dump_xml_unformatted(message);

    iov[0].iov_len = sizeof(struct qb_ipc_response_header);
    iov[0].iov_base = &header;
    iov[1].iov_len = 1 + strlen(buffer);
    iov[1].iov_base = buffer;

    header.id = id++; /* We don't really use it, but doesn't hurt to set one */
    header.error = 0; /* unused */
    header.size = iov[0].iov_len + iov[1].iov_len;

    do {
        if(flags & ipcs_send_event) {
            rc = qb_ipcs_event_sendv(c, iov, 2);
            type = "Event";
            
        } else {
            rc = qb_ipcs_response_sendv(c, iov, 2);
        }

        if(rc != -EAGAIN) {
            break;
        } else if(lpc > 3 && (flags & ipcs_send_error)) {
            break;
        }

        crm_debug("Attempting resend %d of %s %d (%d bytes) to %p[%d]: %.120s",
                  ++lpc, type, header.id, header.size, c, crm_ipcs_client_pid(c), buffer);
        sleep(1);

        /* Only retry for important stuff, and even then only a limited amount for ipcs_send_error
         * Unless ipcs_send_info or ipcs_send_error is specified, we block by default
         */
    } while((flags & ipcs_send_info) == 0);

    if(rc < header.size) {
        do_crm_log((flags & ipcs_send_error)?LOG_ERR:LOG_INFO,
                   "%s %d failed, size=%d, to=%p[%d], rc=%d: %.120s",
                   type, header.id, header.size, c, crm_ipcs_client_pid(c), rc, buffer);
    } else {
        crm_trace("%s %d sent, %d bytes to %p: %.120s", type, header.id, rc, c, buffer);
    }
    free(buffer);
    return rc;
}
Пример #5
0
static int32_t
attrd_ipc_accept(qb_ipcs_connection_t *c, uid_t uid, gid_t gid)
{
    attrd_client_t *new_client = NULL;
#if ENABLE_ACL
    struct group *crm_grp = NULL;
#endif

    crm_trace("Connecting %p for connection from %d by uid=%d gid=%d",
              c, crm_ipcs_client_pid(c), uid, gid);
    if (need_shutdown) {
        crm_info("Ignoring connection request during shutdown");
        return FALSE;
    }

    new_client = calloc(1, sizeof(attrd_client_t));

#if ENABLE_ACL
    crm_grp = getgrnam(CRM_DAEMON_GROUP);
    if (crm_grp) {
        qb_ipcs_connection_auth_set(c, -1, crm_grp->gr_gid, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
    }

    new_client->user = uid2username(uid);
#endif

    qb_ipcs_context_set(c, new_client);

    return 0;
}
Пример #6
0
crm_client_t *
crm_client_new(qb_ipcs_connection_t * c, uid_t uid_client, gid_t gid_client)
{
    static uid_t uid_server = 0;
    static gid_t gid_cluster = 0;

    crm_client_t *client = NULL;

    CRM_LOG_ASSERT(c);
    if (c == NULL) {
        return NULL;
    }

    if (gid_cluster == 0) {
        uid_server = getuid();
        if(crm_user_lookup(CRM_DAEMON_USER, NULL, &gid_cluster) < 0) {
            static bool have_error = FALSE;
            if(have_error == FALSE) {
                crm_warn("Could not find group for user %s", CRM_DAEMON_USER);
                have_error = TRUE;
            }
        }
    }

    if(gid_cluster != 0 && gid_client != 0) {
        uid_t best_uid = -1; /* Passing -1 to chown(2) means don't change */

        if(uid_client == 0 || uid_server == 0) { /* Someone is priveliged, but the other may not be */
            best_uid = QB_MAX(uid_client, uid_server);
            crm_trace("Allowing user %u to clean up after disconnect", best_uid);
        }

        crm_trace("Giving access to group %u", gid_cluster);
        qb_ipcs_connection_auth_set(c, best_uid, gid_cluster, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
    }

    crm_client_init();

    /* TODO: Do our own auth checking, return NULL if unauthorized */
    client = calloc(1, sizeof(crm_client_t));

    client->ipcs = c;
    client->kind = CRM_CLIENT_IPC;
    client->pid = crm_ipcs_client_pid(c);

    client->id = crm_generate_uuid();

    crm_debug("Connecting %p for uid=%d gid=%d pid=%u id=%s", c, uid_client, gid_client, client->pid, client->id);

#if ENABLE_ACL
    client->user = uid2username(uid_client);
#endif

    g_hash_table_insert(client_connections, c, client);
    return client;
}
Пример #7
0
static int32_t
st_ipc_accept(qb_ipcs_connection_t * c, uid_t uid, gid_t gid)
{
    if (stonith_shutdown_flag) {
        crm_info("Ignoring new client [%d] during shutdown", crm_ipcs_client_pid(c));
        return -EPERM;
    }

    if (crm_client_new(c, uid, gid) == NULL) {
        return -EIO;
    }
    return 0;
}
Пример #8
0
static int32_t
cib_ipc_accept(qb_ipcs_connection_t *c, uid_t uid, gid_t gid)
{
    cib_client_t *new_client = NULL;
#if ENABLE_ACL
    struct group *crm_grp = NULL;
#endif

    crm_trace("Connecting %p for uid=%d gid=%d pid=%d", c, uid, gid, crm_ipcs_client_pid(c));
    if (cib_shutdown_flag) {
        crm_info("Ignoring new client [%d] during shutdown", crm_ipcs_client_pid(c));
        return -EPERM;
    }

    new_client = calloc(1, sizeof(cib_client_t));
    new_client->ipc = c;

    CRM_CHECK(new_client->id == NULL, free(new_client->id));
    new_client->id = crm_generate_uuid();

#if ENABLE_ACL
    crm_grp = getgrnam(CRM_DAEMON_GROUP);
    if (crm_grp) {
        qb_ipcs_connection_auth_set(c, -1, crm_grp->gr_gid, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
    }

    new_client->user = uid2username(uid);
#endif

    /* make sure we can find ourselves later for sync calls
     * redirected to the master instance
     */
    g_hash_table_insert(client_list, new_client->id, new_client);

    qb_ipcs_context_set(c, new_client);

    return 0;
}
Пример #9
0
static int32_t
attrd_ipc_accept(qb_ipcs_connection_t * c, uid_t uid, gid_t gid)
{
    crm_trace("Connection %p", c);
    if (shutting_down) {
        crm_info("Ignoring new client [%d] during shutdown", crm_ipcs_client_pid(c));
        return -EPERM;
    }

    if (crm_client_new(c, uid, gid) == NULL) {
        return -EIO;
    }
    return 0;
}
Пример #10
0
crm_client_t *
crm_client_new(qb_ipcs_connection_t * c, uid_t uid_client, gid_t gid_client)
{
    static gid_t uid_cluster = 0;
    static gid_t gid_cluster = 0;

    crm_client_t *client = NULL;

    CRM_LOG_ASSERT(c);
    if (c == NULL) {
        return NULL;
    }

    if (uid_cluster == 0) {
        if (crm_user_lookup(CRM_DAEMON_USER, &uid_cluster, &gid_cluster) < 0) {
            static bool have_error = FALSE;
            if(have_error == FALSE) {
                crm_warn("Could not find user and group IDs for user %s",
                         CRM_DAEMON_USER);
                have_error = TRUE;
            }
        }
    }

    if (uid_client != 0) {
        crm_trace("Giving access to group %u", gid_cluster);
        /* Passing -1 to chown(2) means don't change */
        qb_ipcs_connection_auth_set(c, -1, gid_cluster, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
    }

    crm_client_init();

    /* TODO: Do our own auth checking, return NULL if unauthorized */
    client = crm_client_alloc(c);
    client->ipcs = c;
    client->kind = CRM_CLIENT_IPC;
    client->pid = crm_ipcs_client_pid(c);

    if ((uid_client == 0) || (uid_client == uid_cluster)) {
        /* Remember when a connection came from root or hacluster */
        set_bit(client->flags, crm_client_flag_ipc_privileged);
    }

    crm_debug("Connecting %p for uid=%d gid=%d pid=%u id=%s", c, uid_client, gid_client, client->pid, client->id);

#if ENABLE_ACL
    client->user = uid2username(uid_client);
#endif
    return client;
}
Пример #11
0
void
crm_client_disconnect_all(qb_ipcs_service_t *service)
{
    qb_ipcs_connection_t *c = qb_ipcs_connection_first_get(service);

    while (c != NULL) {
        qb_ipcs_connection_t *last = c;

        c = qb_ipcs_connection_next_get(service, last);

        /* There really shouldn't be anyone connected at this point */
        crm_notice("Disconnecting client %p, pid=%d...", last, crm_ipcs_client_pid(last));
        qb_ipcs_disconnect(last);
        qb_ipcs_connection_unref(last);
    }
}
Пример #12
0
static int32_t
lrmd_ipc_dispatch(qb_ipcs_connection_t * c, void *data, size_t size)
{
    uint32_t id = 0;
    uint32_t flags = 0;
    crm_client_t *client = crm_client_get(c);
    xmlNode *request = crm_ipcs_recv(client, data, size, &id, &flags);

    CRM_CHECK(client != NULL, crm_err("Invalid client");
              return FALSE);
    CRM_CHECK(client->id != NULL, crm_err("Invalid client: %p", client);
              return FALSE);

    CRM_CHECK(flags & crm_ipc_client_response, crm_err("Invalid client request: %p", client);
              return FALSE);

    if (!request) {
        return 0;
    }

    if (!client->name) {
        const char *value = crm_element_value(request, F_LRMD_CLIENTNAME);

        if (value == NULL) {
            client->name = crm_itoa(crm_ipcs_client_pid(c));
        } else {
            client->name = strdup(value);
        }
    }

    lrmd_call_id++;
    if (lrmd_call_id < 1) {
        lrmd_call_id = 1;
    }

    crm_xml_add(request, F_LRMD_CLIENTID, client->id);
    crm_xml_add(request, F_LRMD_CLIENTNAME, client->name);
    crm_xml_add_int(request, F_LRMD_CALLID, lrmd_call_id);

    process_lrmd_message(client, id, request);

    free_xml(request);
    return 0;
}
Пример #13
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;
}
Пример #14
0
/* Error code means? */
static int32_t
attrd_ipc_closed(qb_ipcs_connection_t *c) 
{
    crm_trace("Connection %p from %d closed", c, crm_ipcs_client_pid(c));
    return 0;
}
Пример #15
0
static void
attrd_ipc_created(qb_ipcs_connection_t *c)
{
    crm_trace("Client %p connected from %d", c, crm_ipcs_client_pid(c));
}
Пример #16
0
ssize_t
crm_ipcs_send(qb_ipcs_connection_t *c, uint32_t request, xmlNode *message, enum crm_ipc_server_flags flags)
{
    int rc;
    int lpc = 0;
    int retries = 40;
    int level = LOG_CRIT;
    struct iovec iov[2];
    static uint32_t id = 1;
    const char *type = "Response";
    struct qb_ipc_response_header header;
    char *buffer = dump_xml_unformatted(message);
    struct timespec delay = { 0, 250000000 }; /* 250ms */

    memset(&iov, 0, 2 * sizeof(struct iovec));
    iov[0].iov_len = sizeof(struct qb_ipc_response_header);
    iov[0].iov_base = &header;
    iov[1].iov_len = 1 + strlen(buffer);
    iov[1].iov_base = buffer;

    if(flags & crm_ipc_server_event) {
        header.id = id++;    /* We don't really use it, but doesn't hurt to set one */
    } else {
        CRM_LOG_ASSERT (request != 0);
        header.id = request; /* Replying to a specific request */
    }

    header.error = 0; /* unused */
    header.size = iov[0].iov_len + iov[1].iov_len;

    if(flags & crm_ipc_server_error) {
        retries = 20;
        level = LOG_ERR;

    } else if(flags & crm_ipc_server_info) {
        retries = 10;
        level = LOG_INFO;
    }

    while(lpc < retries) {
        if(flags & crm_ipc_server_event) {
            type = "Event";
            rc = qb_ipcs_event_sendv(c, iov, 2);
            if(rc == -EPIPE || rc == -ENOTCONN) {
                crm_trace("Client %p disconnected", c);
                level = LOG_INFO;
            }
            
        } else {
            rc = qb_ipcs_response_sendv(c, iov, 2);
        }

        if(rc != -EAGAIN) {
            break;
        }

        lpc++;
        crm_debug("Attempting resend %d of %s %d (%d bytes) to %p[%d]: %.120s",
                  lpc, type, header.id, header.size, c, crm_ipcs_client_pid(c), buffer);
        nanosleep(&delay, NULL);
    }

    if(rc < header.size) {
        struct qb_ipcs_connection_stats_2 *stats = qb_ipcs_connection_stats_get_2(c, 0);
        do_crm_log(level,
                   "%s %d failed, size=%d, to=%p[%d], queue=%d, rc=%d: %.120s",
                   type, header.id, header.size, c, stats->client_pid, stats->event_q_length, rc, buffer);
        free(stats);

    } else {
        crm_trace("%s %d sent, %d bytes to %p[%d]: %.120s", type, header.id, rc,
                  c, crm_ipcs_client_pid(c), buffer);
    }
    free(buffer);
    return rc;
}