Пример #1
0
gboolean
cluster_connect_cpg(void)
{
    cs_error_t rc;
    unsigned int nodeid;
    int fd;
    int retries = 0;

    strcpy(cpg_group.value, "pcmk");
    cpg_group.length = strlen(cpg_group.value) + 1;

    retries = 0;
    cs_repeat(retries, 30, rc = cpg_initialize(&cpg_handle, &cpg_callbacks));
    if (rc != CS_OK) {
        crm_err("corosync cpg init error %d", rc);
        return FALSE;
    }

    rc = cpg_fd_get(cpg_handle, &fd);
    if (rc != CS_OK) {
        crm_err("corosync cpg fd_get error %d", rc);
        goto bail;
    }

    retries = 0;
    cs_repeat(retries, 30, rc = cpg_local_get(cpg_handle, &nodeid));
    if (rc != CS_OK) {
        crm_err("corosync cpg local_get error %d", rc);
        goto bail;
    }

    crm_debug("Our nodeid: %d", nodeid);

    retries = 0;
    cs_repeat(retries, 30, rc = cpg_join(cpg_handle, &cpg_group));

    if (rc != CS_OK) {
        crm_err("Could not join the CPG group '%s': %d", crm_system_name, rc);
        goto bail;
    }

    crm_debug("Adding fd=%d to mainloop", fd);
    G_main_add_fd(G_PRIORITY_HIGH, fd, FALSE, pcmk_cpg_dispatch, &cpg_handle,
                  cpg_connection_destroy);

    return TRUE;

  bail:
    cpg_finalize(cpg_handle);
    return FALSE;
}
Пример #2
0
gboolean
cluster_connect_cfg(uint32_t * nodeid)
{
    cs_error_t rc;
    int fd = 0, retries = 0;

    cs_repeat(retries, 30, rc = corosync_cfg_initialize(&cfg_handle, &cfg_callbacks));

    if (rc != CS_OK) {
        crm_err("corosync cfg init error %d", rc);
        return FALSE;
    }

    rc = corosync_cfg_fd_get(cfg_handle, &fd);
    if (rc != CS_OK) {
        crm_err("corosync cfg fd_get error %d", rc);
        goto bail;
    }

    retries = 0;
    cs_repeat(retries, 30, rc = corosync_cfg_local_get(cfg_handle, nodeid));

    if (rc != CS_OK) {
        crm_err("corosync cfg local_get error %d", rc);
        goto bail;
    }

    crm_debug("Our nodeid: %d", *nodeid);

    crm_debug("Adding fd=%d to mainloop", fd);
    G_main_add_fd(G_PRIORITY_HIGH, fd, FALSE, pcmk_cfg_dispatch, &cfg_handle,
                  cfg_connection_destroy);

    return TRUE;

  bail:
    corosync_cfg_finalize(cfg_handle);
    return FALSE;
}
Пример #3
0
int
init_remote_listener(int port, gboolean encrypted)
{
    int ssock;
    struct sockaddr_in saddr;
    int optval;

    if (port <= 0) {
        /* dont start it */
        return 0;
    }

    if (encrypted) {
#ifndef HAVE_GNUTLS_GNUTLS_H
        crm_warn("TLS support is not available");
        return 0;
#else
        crm_notice("Starting a tls listener on port %d.", port);
        gnutls_global_init();
/* 	gnutls_global_set_log_level (10); */
        gnutls_global_set_log_function(debug_log);
        gnutls_dh_params_init(&dh_params);
        gnutls_dh_params_generate2(dh_params, DH_BITS);
        gnutls_anon_allocate_server_credentials(&anon_cred_s);
        gnutls_anon_set_server_dh_params(anon_cred_s, dh_params);
#endif
    } else {
        crm_warn("Starting a plain_text listener on port %d.", port);
    }
#ifndef HAVE_PAM
    crm_warn("PAM is _not_ enabled!");
#endif

    /* create server socket */
    ssock = socket(AF_INET, SOCK_STREAM, 0);
    if (ssock == -1) {
        crm_perror(LOG_ERR, "Can not create server socket." ERROR_SUFFIX);
        return -1;
    }

    /* reuse address */
    optval = 1;
    setsockopt(ssock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));

    /* bind server socket */
    memset(&saddr, '\0', sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = INADDR_ANY;
    saddr.sin_port = htons(port);
    if (bind(ssock, (struct sockaddr *)&saddr, sizeof(saddr)) == -1) {
        crm_perror(LOG_ERR, "Can not bind server socket." ERROR_SUFFIX);
        return -2;
    }
    if (listen(ssock, 10) == -1) {
        crm_perror(LOG_ERR, "Can not start listen." ERROR_SUFFIX);
        return -3;
    }

    G_main_add_fd(G_PRIORITY_HIGH, ssock, FALSE,
                  cib_remote_listen, NULL, default_ipc_connection_destroy);

    return ssock;
}
Пример #4
0
gboolean
cib_remote_listen(int ssock, gpointer data)
{
    int lpc = 0;
    int csock = 0;
    unsigned laddr;
    time_t now = 0;
    time_t start = time(NULL);
    struct sockaddr_in addr;

#ifdef HAVE_GNUTLS_GNUTLS_H
    gnutls_session *session = NULL;
#endif
    cib_client_t *new_client = NULL;

    xmlNode *login = NULL;
    const char *user = NULL;
    const char *pass = NULL;
    const char *tmp = NULL;

    cl_uuid_t client_id;
    char uuid_str[UU_UNPARSE_SIZEOF];

#ifdef HAVE_DECL_NANOSLEEP
    const struct timespec sleepfast = { 0, 10000000 };  /* 10 millisec */
#endif

    /* accept the connection */
    laddr = sizeof(addr);
    csock = accept(ssock, (struct sockaddr *)&addr, &laddr);
    crm_debug("New %s connection from %s",
              ssock == remote_tls_fd ? "secure" : "clear-text", inet_ntoa(addr.sin_addr));

    if (csock == -1) {
        crm_err("accept socket failed");
        return TRUE;
    }

    if (ssock == remote_tls_fd) {
#ifdef HAVE_GNUTLS_GNUTLS_H
        /* create gnutls session for the server socket */
        session = create_tls_session(csock, GNUTLS_SERVER);
        if (session == NULL) {
            crm_err("TLS session creation failed");
            close(csock);
            return TRUE;
        }
#endif
    }

    do {
        crm_trace("Iter: %d", lpc++);
        if (ssock == remote_tls_fd) {
#ifdef HAVE_GNUTLS_GNUTLS_H
            login = cib_recv_remote_msg(session, TRUE);
#endif
        } else {
            login = cib_recv_remote_msg(GINT_TO_POINTER(csock), FALSE);
        }
        if (login != NULL) {
            break;
        }
#ifdef HAVE_DECL_NANOSLEEP
        nanosleep(&sleepfast, NULL);
#else
        sleep(1);
#endif
        now = time(NULL);

        /* Peers have 3s to connect */
    } while (login == NULL && (start - now) < 4);

    crm_log_xml_info(login, "Login: "******"cib_command")) {
        crm_err("Wrong tag: %s", tmp);
        goto bail;
    }

    tmp = crm_element_value(login, "op");
    if (safe_str_neq(tmp, "authenticate")) {
        crm_err("Wrong operation: %s", tmp);
        goto bail;
    }

    user = crm_element_value(login, "user");
    pass = crm_element_value(login, "password");

    /* Non-root daemons can only validate the password of the
     * user they're running as
     */
    if (check_group_membership(user, CRM_DAEMON_GROUP) == FALSE) {
        crm_err("User is not a member of the required group");
        goto bail;

    } else if (authenticate_user(user, pass) == FALSE) {
        crm_err("PAM auth failed");
        goto bail;
    }

    /* send ACK */
    crm_malloc0(new_client, sizeof(cib_client_t));
    num_clients++;
    new_client->channel_name = "remote";
    new_client->name = crm_element_value_copy(login, "name");

    cl_uuid_generate(&client_id);
    cl_uuid_unparse(&client_id, uuid_str);

    CRM_CHECK(new_client->id == NULL, crm_free(new_client->id));
    new_client->id = crm_strdup(uuid_str);

#if ENABLE_ACL
    new_client->user = crm_strdup(user);
#endif

    new_client->callback_id = NULL;
    if (ssock == remote_tls_fd) {
#ifdef HAVE_GNUTLS_GNUTLS_H
        new_client->encrypted = TRUE;
        new_client->channel = (void *)session;
#endif
    } else {
        new_client->channel = GINT_TO_POINTER(csock);
    }

    free_xml(login);
    login = create_xml_node(NULL, "cib_result");
    crm_xml_add(login, F_CIB_OPERATION, CRM_OP_REGISTER);
    crm_xml_add(login, F_CIB_CLIENTID, new_client->id);
    cib_send_remote_msg(new_client->channel, login, new_client->encrypted);
    free_xml(login);

    new_client->source =
        (void *)G_main_add_fd(G_PRIORITY_DEFAULT, csock, FALSE, cib_remote_msg, new_client,
                              cib_remote_connection_destroy);

    g_hash_table_insert(client_list, new_client->id, new_client);

    return TRUE;

  bail:
    if (ssock == remote_tls_fd) {
#ifdef HAVE_GNUTLS_GNUTLS_H
        gnutls_bye(*session, GNUTLS_SHUT_RDWR);
        gnutls_deinit(*session);
        gnutls_free(session);
#endif
    }
    close(csock);
    free_xml(login);
    return TRUE;
}