コード例 #1
0
ファイル: xmpp.c プロジェクト: strategist922/libconflate
static xmpp_stanza_t* n_handler(const char *cmd,
                                xmpp_stanza_t* cmd_stanza,
                                xmpp_conn_t * const conn,
                                xmpp_stanza_t * const stanza,
                                void * const userdata,
                                bool direct,
                                conflate_mgmt_cb_t cb)
{
    conflate_handle_t *handle = (conflate_handle_t*) userdata;
    xmpp_ctx_t *ctx = handle->ctx;
    conflate_form_result result = { .conn = conn,
                                    .ctx = ctx,
                                    .reply = NULL,
                                    .cmd_res = NULL,
                                    .container = NULL };
    kvpair_t *form = NULL;

    assert(cb);

    result.reply = create_reply(ctx, stanza);
    result.cmd_res = create_cmd_response(ctx, cmd_stanza);

    add_and_release(result.reply, result.cmd_res);

    xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(cmd_stanza, "x");
    if (x) {
        xmpp_stanza_t *fields = xmpp_stanza_get_child_by_name(x, "field");
        if (fields) {
            form = grok_form(fields);
        }
    }

    enum conflate_mgmt_cb_result rv = cb(handle->conf->userdata, handle,
                                         cmd, direct, form, &result);

    CONFLATE_LOG(handle, LOG_LVL_DEBUG, "Result of %s:  %s", cmd, cb_name(rv));

    switch (rv) {
    case RV_ERROR:
        add_cmd_error(ctx, result.reply, "500",
                      "urn:ietf:params:xml:ns:xmpp-stanzas",
                      "internal-server-error", NULL, NULL);
        break;
    case RV_BADARG:
        add_cmd_error(ctx, result.reply, "400",
                      "urn:ietf:params:xml:ns:xmpp-stanzas", "bad-request",
                      "http://jabber.org/protocol/commands", "bad-payload");
        break;
    case RV_OK:
        /* Things are good, use the built form */
        break;
    }

    free_kvpair(form);

    return result.reply;
}
コード例 #2
0
ファイル: xmpp.c プロジェクト: strategist922/libconflate
static xmpp_stanza_t* error_unknown_command(const char *cmd,
                                            xmpp_stanza_t * const cmd_stanza,
                                            xmpp_conn_t* const conn,
                                            xmpp_stanza_t * const stanza,
                                            void * const userdata,
                                            bool direct)
{
    conflate_handle_t *handle = (conflate_handle_t*) userdata;
    xmpp_ctx_t *ctx = handle->ctx;

    xmpp_stanza_t* reply = create_reply(ctx, stanza);
    add_and_release(reply, create_cmd_response(ctx, cmd_stanza));
    add_cmd_error(ctx, reply, "404",
                  "urn:ietf:params:xml:ns:xmpp-stanzas", "item-not-found",
                  NULL, NULL);
    return reply;
}
コード例 #3
0
ファイル: rarpd.c プロジェクト: afett/rarpd
void handle_request(int fd, struct link *link, bool check_bootable)
{
	memset(link->buf, 0, sizeof(link->buf));
	memset(&link->src, 0, sizeof(link->src));

	ssize_t size = read_request(fd,
		&link->src, link->buf, sizeof(link->buf));

	if (size <= 0) {
		return;
	}

	if (!check_frame(&link->src, link)) {
		return;
	}

	if ((size_t) size < sizeof(struct ether_arp)) {
		XLOG_WARNING("request to short");
		return;
	}

	struct ether_arp *arp_req = (struct ether_arp *)link->buf;
	if (!check_request(arp_req, &link->src)) {
		return;
	}

	struct in_addr ip;
	memset(&ip, 0, sizeof(in_addr_t));
	int ret = resolve((struct ether_addr*)&arp_req->arp_tha, &ip);
	if (ret != 0) {
		return;
	}

	XLOG_DEBUG("found address: %s", inet_ntoa(ip));
	if (check_bootable == true && !is_bootable(ip)) {
		return;
	}

	create_reply(arp_req, &ip, link);
	dispatcher_flags(&link->handler, POLLOUT);
}
コード例 #4
0
ファイル: krb_udp.c プロジェクト: hwr/openafs
afs_int32
UDP_GetTicket(int ksoc, struct packet *pkt, afs_int32 kvno,
	      char *authDomain, char *ticket, int ticketLen, char *auth,
	      int authLen)
{
    afs_int32 code;
    struct ktc_encryptionKey tgskey;
    char name[MAXKTCNAMELEN];
    char inst[MAXKTCNAMELEN];
    char cell[MAXKTCREALMLEN];
    struct ktc_encryptionKey authSessionKey;
    afs_int32 host;
    Date start;
    Date authEnd;
    Date now = time(0);
    int celllen;
    int import;

    char *packet;
    int slen;
    int byteOrder = pkt->byteOrder;
    char sname[MAXKTCNAMELEN];
    char sinst[MAXKTCNAMELEN];
    afs_int32 time_ws;
    unsigned char life;

    struct ubik_trans *tt;
    afs_int32 to;
    struct kaentry caller;
    struct kaentry server;
    Date reqEnd;
    struct ktc_encryptionKey sessionKey;
    int newTicketLen;
    char newTicket[MAXKTCTICKETLEN];

    char cipher[2 * MAXKTCTICKETLEN];	/* put encrypted part of answer here */
    int cipherLen;
    struct packet ans;

    COUNT_REQ(UGetTicket);

    if ((code = InitAuthServ(&tt, LOCKREAD, this_op)))
	goto fail;
    code =
	ka_LookupKvno(tt, KA_TGS_NAME,
		      ((strlen(authDomain) > 0) ? authDomain : lrealm), kvno,
		      &tgskey);
    if (code)
	goto abort;

    code =
	tkt_DecodeTicket(ticket, ticketLen, &tgskey, name, inst, cell,
			 &authSessionKey, &host, &start, &authEnd);
    pkt->name = name;
    pkt->inst = inst;
    pkt->realm = cell;
    if (code) {
	code = KERB_ERR_AUTH_EXP;	/* was KANOAUTH */
	goto abort;
    }
    save_principal(udptgsPrincipal, name, inst, cell);
    code = tkt_CheckTimes(start, authEnd, now);
    if (code <= 0) {
	if (code == -1) {
	    code = KERB_ERR_SERVICE_EXP;	/* was RXKADEXPIRED */
	    goto abort;
	}
	code = KERB_ERR_AUTH_EXP;	/* was KANOAUTH */
	goto abort;
    }
    celllen = strlen(cell);
    import = 0;
    if ((strlen(authDomain) > 0) && (strcmp(authDomain, lrealm) != 0))
	import = 1;
    if (import && (celllen == 0)) {
	code = KERB_ERR_PKT_VER;	/* was KABADTICKET */
	goto abort;
    }
    if (celllen == 0) {
	strncpy(cell, lrealm, MAXKTCREALMLEN - 1);
	cell[MAXKTCREALMLEN - 1] = 0;
    };

    if (!krb4_cross && strcmp(lrealm, cell) != 0) {
	code = KERB_ERR_PRINCIPAL_UNKNOWN;
	goto abort;
    }

    if (krb_udp_debug) {
	printf("UGetTicket: got ticket from '%s'.'%s'@'%s'\n", name, inst,
	       cell);
    }

    code = check_auth(pkt, auth, authLen, &authSessionKey, name, inst, cell);
    if (code)
	goto abort;

    /* authenticator and all is OK so read actual request */
    packet = pkt->rest;
    getint(time_ws);
    life = *(unsigned char *)packet++;
    getstr(sname);
    getstr(sinst);
    start = now;
    reqEnd = life_to_time(start, life);
    if (krb_udp_debug) {
	printf("UGetTicket: request for server '%s'.'%s'\n", sname, sinst);
    }
    save_principal(udptgsServerPrincipal, sname, sinst, 0);

    if (import) {
	strcpy(caller.userID.name, name);
	strcpy(caller.userID.instance, inst);
	caller.max_ticket_lifetime = htonl(MAXKTCTICKETLIFETIME);
    } else {
	code = FindBlock(tt, name, inst, &to, &caller);
	if (code)
	    goto abort;
	if (to == 0) {
	    ka_PrintUserID("GetTicket: User ", name, inst, " unknown.\n");
	    code = KERB_ERR_PRINCIPAL_UNKNOWN;	/* KANOENT */
	    goto abort;
	}
	if (ntohl(caller.flags) & KAFNOTGS) {
	    code = KERB_ERR_AUTH_EXP;	/* was KABADUSER */
	    goto abort;
	}
    }

    code = FindBlock(tt, sname, sinst, &to, &server);	/* get server's entry */
    if (code)
	goto abort;
    if (to == 0) {		/* entry not found */
	ka_PrintUserID("GetTicket: Server ", sname, sinst, " unknown.\n");
	code = KERB_ERR_PRINCIPAL_UNKNOWN;	/* KANOENT */
	goto abort;
    }
    code = ubik_EndTrans(tt);
    if (code)
	goto fail;

    if (ntohl(server.flags) & KAFNOSEAL)
	return KABADSERVER;

    code = DES_new_random_key(ktc_to_cblock(&sessionKey));
    if (code) {
	code = KERB_ERR_NULL_KEY;	/* was KANOKEYS */
	goto fail;
    }

    reqEnd =
	umin(umin(reqEnd, authEnd),
	     umin(start + ntohl(caller.max_ticket_lifetime),
		  start + ntohl(server.max_ticket_lifetime)));

    code =
	tkt_MakeTicket(newTicket, &newTicketLen, &server.key,
		       caller.userID.name, caller.userID.instance, cell,
		       start, reqEnd, &sessionKey,
		       htonl(pkt->from.sin_addr.s_addr), server.userID.name,
		       server.userID.instance);
    if (code)
	goto fail;

    cipherLen = sizeof(cipher);
    code =
	create_cipher(cipher, &cipherLen, &sessionKey, sname, sinst, start,
		      reqEnd, ntohl(server.key_version), newTicket,
		      newTicketLen, &authSessionKey);
    if (code)
	goto fail;

    code =
	create_reply(&ans, name, inst, start, reqEnd, 0, cipher, cipherLen);
    if (code)
	goto fail;

    code =
	sendto(ksoc, ans.data, ans.len, 0, (struct sockaddr *)&pkt->from,
	       sizeof(pkt->from));
    if (code != ans.len) {
	perror("calling sendto");
	code = -1;
	goto fail;
    }

    if (cipherLen != 0) {
	KALOG(name, inst, sname, sinst, NULL, host, LOG_GETTICKET);
    }
    osi_audit(UDPGetTicketEvent, 0, AUD_STR, name, AUD_STR, inst, AUD_STR,
	      cell, AUD_STR, sname, AUD_STR, sinst, AUD_END);
    return 0;

  abort:
    ubik_AbortTrans(tt);
  fail:
    osi_audit(UDPGetTicketEvent, code, AUD_STR, name, AUD_STR, inst, AUD_STR,
	      NULL, AUD_STR, NULL, AUD_STR, NULL, AUD_END);
    return code;
}
コード例 #5
0
ファイル: krb_udp.c プロジェクト: hwr/openafs
afs_int32
UDP_Authenticate(int ksoc, struct sockaddr_in *client, char *name,
		 char *inst, Date startTime, Date endTime, char *sname,
		 char *sinst)
{
    struct ubik_trans *tt;
    afs_int32 to;		/* offset of block */
    struct kaentry tentry;
    afs_int32 tgskvno;		/* key version of service key */
    struct ktc_encryptionKey tgskey;	/* service key for encrypting ticket */
    int tgt;
    Date now = time(0);
    afs_int32 code;

    char ticket[MAXKTCTICKETLEN];	/* our copy of the ticket */
    int ticketLen;
    struct ktc_encryptionKey sessionKey;	/* we have to invent a session key */

    char cipher[2 * MAXKTCTICKETLEN];	/* put encrypted part of answer here */
    int cipherLen;
    struct packet ans;

    COUNT_REQ(UAuthenticate);
    if (!name_instance_legal(name, inst))
	return KERB_ERR_NAME_EXP;	/* KABADNAME */
    if ((code = InitAuthServ(&tt, LOCKREAD, this_op)))
	return code;

    code = FindBlock(tt, name, inst, &to, &tentry);
    if (code)
	goto abort;
    if (to) {			/* if user exists check other stuff */
	afs_int32 sto;
	struct kaentry sentry;
	save_principal(udpAuthPrincipal, name, inst, 0);

	tgt = ((strcmp(sname, KA_TGS_NAME) == 0)
	       && (strcmp(sinst, lrealm) == 0));
	if ((ntohl(tentry.user_expiration) < now)
	    || (tgt && (ntohl(tentry.flags) & KAFNOTGS))) {
	    code = KERB_ERR_NAME_EXP;	/* KABADUSER */
	    goto abort;
	}
	code = FindBlock(tt, KA_TGS_NAME, lrealm, &sto, &sentry);
	if (code)
	    goto abort;
	if (sto == 0) {
	    code = KANOENT;
	    goto abort;
	}
	if ((ntohl(sentry.user_expiration) < now)) {
	    code = KERB_ERR_NAME_EXP;	/* XXX Could use another error code XXX */
	    goto abort;
	}
	if (abs(startTime - now) > KTC_TIME_UNCERTAINTY) {
	    code = KERB_ERR_SERVICE_EXP;	/* was KABADREQUEST */
	    goto abort;
	}

	if (tentry.misc_auth_bytes) {
	    unsigned char misc_auth_bytes[4];
	    afs_uint32 temp;	/* unsigned for safety */
	    afs_uint32 pwexpires;

	    memcpy(&temp, tentry.misc_auth_bytes, sizeof(afs_uint32));
	    temp = ntohl(temp);
	    unpack_long(temp, misc_auth_bytes);
	    pwexpires = misc_auth_bytes[0];
	    if (pwexpires) {
		pwexpires =
		    ntohl(tentry.change_password_time) +
		    24 * 60 * 60 * pwexpires;
		if (pwexpires < now) {
		    code = KERB_ERR_AUTH_EXP;	/* was KAPWEXPIRED */
		    goto abort;
		}
	    }
	}

	/* make the ticket */
	code = DES_new_random_key(ktc_to_cblock(&sessionKey));
	if (code) {
	    code = KERB_ERR_NULL_KEY;	/* was KANOKEYS */
	    goto abort;
	}
	endTime =
	    umin(endTime, startTime + ntohl(tentry.max_ticket_lifetime));
	if ((code = ka_LookupKey(tt, sname, sinst, &tgskvno, &tgskey))
	    || (code =
		tkt_MakeTicket(ticket, &ticketLen, &tgskey, name, inst,
			       lrealm, startTime, endTime, &sessionKey,
			       htonl(client->sin_addr.s_addr), sname, sinst)))
	    goto abort;

	cipherLen = sizeof(cipher);
	code =
	    create_cipher(cipher, &cipherLen, &sessionKey, sname, sinst,
			  startTime, endTime, tgskvno, ticket, ticketLen,
			  &tentry.key);
	if (code)
	    goto abort;
    } else {			/* no such user */
	cipherLen = 0;
	tentry.key_version = 0;
    }
    code = ubik_EndTrans(tt);
    if (code)
	goto fail;

    code =
	create_reply(&ans, name, inst, startTime, endTime,
		     ntohl(tentry.key_version), cipher, cipherLen);
    if (code)
	goto fail;

    if (krb_udp_debug) {
	printf("Sending %d bytes ending in: ", ans.len);
	ka_PrintBytes(ans.data + ans.len - 8, 8);
	printf("\n");
    }

    code =
	sendto(ksoc, ans.data, ans.len, 0, (struct sockaddr *)client,
	       sizeof(*client));
    if (code != ans.len) {
	perror("calling sendto");
	code = -1;
	goto fail;
    }
    KALOG(name, inst, sname, sinst, NULL, client->sin_addr.s_addr,
	  LOG_AUTHENTICATE);

    if (cipherLen != 0) {
	KALOG(name, inst, sname, sinst, NULL, client->sin_addr.s_addr,
	      LOG_TGTREQUEST);
    }
    osi_audit(UDPAuthenticateEvent, 0, AUD_STR, name, AUD_STR, inst, AUD_END);
    return 0;

  abort:
    COUNT_ABO;
    ubik_AbortTrans(tt);

  fail:
    osi_audit(UDPAuthenticateEvent, code, AUD_STR, name, AUD_STR, inst,
	      AUD_END);
    return code;
}
コード例 #6
0
ファイル: messages.c プロジェクト: JamesGuthrie/pacemaker
enum crmd_fsa_input
handle_request(xmlNode * stored_msg)
{
    xmlNode *msg = NULL;
    const char *op = crm_element_value(stored_msg, F_CRM_TASK);

    /* Optimize this for the DC - it has the most to do */

    if (op == NULL) {
        crm_log_xml_err(stored_msg, "Bad message");
        return I_NULL;
    }

    /*========== DC-Only Actions ==========*/
    if (AM_I_DC) {
        if (strcmp(op, CRM_OP_JOIN_ANNOUNCE) == 0) {
            return I_NODE_JOIN;

        } else if (strcmp(op, CRM_OP_JOIN_REQUEST) == 0) {
            return I_JOIN_REQUEST;

        } else if (strcmp(op, CRM_OP_JOIN_CONFIRM) == 0) {
            return I_JOIN_RESULT;

        } else if (strcmp(op, CRM_OP_SHUTDOWN) == 0) {
            const char *host_from = crm_element_value(stored_msg, F_CRM_HOST_FROM);
            gboolean dc_match = safe_str_eq(host_from, fsa_our_dc);

            if (is_set(fsa_input_register, R_SHUTDOWN)) {
                crm_info("Shutting ourselves down (DC)");
                return I_STOP;

            } else if (dc_match) {
                crm_err("We didnt ask to be shut down, yet our"
                        " TE is telling us too." " Better get out now!");
                return I_TERMINATE;

            } else if (fsa_state != S_STOPPING) {
                crm_err("Another node is asking us to shutdown" " but we think we're ok.");
                return I_ELECTION;
            }

        } else if (strcmp(op, CRM_OP_SHUTDOWN_REQ) == 0) {
            /* a slave wants to shut down */
            /* create cib fragment and add to message */
            return handle_shutdown_request(stored_msg);
        }
    }

    /*========== common actions ==========*/
    if (strcmp(op, CRM_OP_NOVOTE) == 0) {
        ha_msg_input_t fsa_input;

        fsa_input.msg = stored_msg;
        register_fsa_input_adv(C_HA_MESSAGE, I_NULL, &fsa_input,
                               A_ELECTION_COUNT | A_ELECTION_CHECK, FALSE, __FUNCTION__);

    } else if (strcmp(op, CRM_OP_CLEAR_FAILCOUNT) == 0) {
        return handle_failcount_op(stored_msg);

    } else if (strcmp(op, CRM_OP_VOTE) == 0) {
        /* count the vote and decide what to do after that */
        ha_msg_input_t fsa_input;

        fsa_input.msg = stored_msg;
        register_fsa_input_adv(C_HA_MESSAGE, I_NULL, &fsa_input,
                               A_ELECTION_COUNT | A_ELECTION_CHECK, FALSE, __FUNCTION__);

        /* Sometimes we _must_ go into S_ELECTION */
        if (fsa_state == S_HALT) {
            crm_debug("Forcing an election from S_HALT");
            return I_ELECTION;
#if 0
        } else if (AM_I_DC) {
            /* This is the old way of doing things but what is gained? */
            return I_ELECTION;
#endif
        }

    } else if (strcmp(op, CRM_OP_JOIN_OFFER) == 0) {
        crm_debug("Raising I_JOIN_OFFER: join-%s", crm_element_value(stored_msg, F_CRM_JOIN_ID));
        return I_JOIN_OFFER;

    } else if (strcmp(op, CRM_OP_JOIN_ACKNAK) == 0) {
        crm_debug("Raising I_JOIN_RESULT: join-%s", crm_element_value(stored_msg, F_CRM_JOIN_ID));
        return I_JOIN_RESULT;

    } else if (strcmp(op, CRM_OP_LRM_DELETE) == 0
               || strcmp(op, CRM_OP_LRM_FAIL) == 0
               || strcmp(op, CRM_OP_LRM_REFRESH) == 0 || strcmp(op, CRM_OP_REPROBE) == 0) {

        crm_xml_add(stored_msg, F_CRM_SYS_TO, CRM_SYSTEM_LRMD);
        return I_ROUTER;

    } else if (strcmp(op, CRM_OP_NOOP) == 0) {
        return I_NULL;

    } else if (strcmp(op, CRM_OP_LOCAL_SHUTDOWN) == 0) {

        crm_shutdown(SIGTERM);
        /*return I_SHUTDOWN; */
        return I_NULL;

        /*========== (NOT_DC)-Only Actions ==========*/
    } else if (AM_I_DC == FALSE && strcmp(op, CRM_OP_SHUTDOWN) == 0) {

        const char *host_from = crm_element_value(stored_msg, F_CRM_HOST_FROM);
        gboolean dc_match = safe_str_eq(host_from, fsa_our_dc);

        if (dc_match || fsa_our_dc == NULL) {
            if (is_set(fsa_input_register, R_SHUTDOWN) == FALSE) {
                crm_err("We didn't ask to be shut down, yet our" " DC is telling us too.");
                set_bit(fsa_input_register, R_STAYDOWN);
                return I_STOP;
            }
            crm_info("Shutting down");
            return I_STOP;

        } else {
            crm_warn("Discarding %s op from %s", op, host_from);
        }

    } else if (strcmp(op, CRM_OP_PING) == 0) {
        /* eventually do some stuff to figure out
         * if we /are/ ok
         */
        const char *sys_to = crm_element_value(stored_msg, F_CRM_SYS_TO);
        xmlNode *ping = create_xml_node(NULL, XML_CRM_TAG_PING);

        crm_xml_add(ping, XML_PING_ATTR_STATUS, "ok");
        crm_xml_add(ping, XML_PING_ATTR_SYSFROM, sys_to);
        crm_xml_add(ping, "crmd_state", fsa_state2string(fsa_state));

        /* Ok, so technically not so interesting, but CTS needs to see this */
        crm_notice("Current ping state: %s", fsa_state2string(fsa_state));

        msg = create_reply(stored_msg, ping);
        relay_message(msg, TRUE);

        free_xml(ping);
        free_xml(msg);

    } else if (strcmp(op, CRM_OP_RM_NODE_CACHE) == 0) {
        int id = 0;
        const char *name = NULL;
        xmlNode *options = get_xpath_object("//" XML_TAG_OPTIONS, stored_msg, LOG_ERR);

        if (options) {
            crm_element_value_int(options, XML_ATTR_ID, &id);
            name = crm_element_value(options, XML_ATTR_UNAME);
        }

        reap_crm_member(id, name);

    } else {
        crm_err("Unexpected request (%s) sent to %s", op, AM_I_DC ? "the DC" : "non-DC node");
        crm_log_xml_err(stored_msg, "Unexpected");
    }

    return I_NULL;
}
コード例 #7
0
ファイル: pengine.c プロジェクト: beess/pacemaker
gboolean
process_pe_message(xmlNode * msg, xmlNode * xml_data, crm_client_t * sender)
{
    static char *last_digest = NULL;
    static char *filename = NULL;

    time_t execution_date = time(NULL);
    const char *sys_to = crm_element_value(msg, F_CRM_SYS_TO);
    const char *op = crm_element_value(msg, F_CRM_TASK);
    const char *ref = crm_element_value(msg, F_CRM_REFERENCE);

    crm_trace("Processing %s op (ref=%s)...", op, ref);

    if (op == NULL) {
        /* error */

    } else if (strcasecmp(op, CRM_OP_HELLO) == 0) {
        /* ignore */

    } else if (safe_str_eq(crm_element_value(msg, F_CRM_MSG_TYPE), XML_ATTR_RESPONSE)) {
        /* ignore */

    } else if (sys_to == NULL || strcasecmp(sys_to, CRM_SYSTEM_PENGINE) != 0) {
        crm_trace("Bad sys-to %s", crm_str(sys_to));
        return FALSE;

    } else if (strcasecmp(op, CRM_OP_PECALC) == 0) {
        int seq = -1;
        int series_id = 0;
        int series_wrap = 0;
        char *digest = NULL;
        const char *value = NULL;
        pe_working_set_t data_set;
        xmlNode *converted = NULL;
        xmlNode *reply = NULL;
        gboolean is_repoke = FALSE;
        gboolean process = TRUE;

        crm_config_error = FALSE;
        crm_config_warning = FALSE;

        was_processing_error = FALSE;
        was_processing_warning = FALSE;

        set_working_set_defaults(&data_set);

        digest = calculate_xml_versioned_digest(xml_data, FALSE, FALSE, CRM_FEATURE_SET);
        converted = copy_xml(xml_data);
        if (cli_config_update(&converted, NULL, TRUE) == FALSE) {
            data_set.graph = create_xml_node(NULL, XML_TAG_GRAPH);
            crm_xml_add_int(data_set.graph, "transition_id", 0);
            crm_xml_add_int(data_set.graph, "cluster-delay", 0);
            process = FALSE;
            free(digest);

        } else if (safe_str_eq(digest, last_digest)) {
            crm_info("Input has not changed since last time, not saving to disk");
            is_repoke = TRUE;
            free(digest);

        } else {
            free(last_digest);
            last_digest = digest;
        }

        if (process) {
            do_calculations(&data_set, converted, NULL);
        }

        series_id = get_series();
        series_wrap = series[series_id].wrap;
        value = pe_pref(data_set.config_hash, series[series_id].param);

        if (value != NULL) {
            series_wrap = crm_int_helper(value, NULL);
            if (errno != 0) {
                series_wrap = series[series_id].wrap;
            }

        } else {
            crm_config_warn("No value specified for cluster"
                            " preference: %s", series[series_id].param);
        }

        seq = get_last_sequence(PE_STATE_DIR, series[series_id].name);
        crm_trace("Series %s: wrap=%d, seq=%d, pref=%s",
                  series[series_id].name, series_wrap, seq, value);

        data_set.input = NULL;
        reply = create_reply(msg, data_set.graph);
        CRM_ASSERT(reply != NULL);

        if (is_repoke == FALSE) {
            free(filename);
            filename =
                generate_series_filename(PE_STATE_DIR, series[series_id].name, seq, HAVE_BZLIB_H);
        }

        crm_xml_add(reply, F_CRM_TGRAPH_INPUT, filename);
        crm_xml_add_int(reply, "graph-errors", was_processing_error);
        crm_xml_add_int(reply, "graph-warnings", was_processing_warning);
        crm_xml_add_int(reply, "config-errors", crm_config_error);
        crm_xml_add_int(reply, "config-warnings", crm_config_warning);

        if (crm_ipcs_send(sender, 0, reply, crm_ipc_server_event) == FALSE) {
            crm_err("Couldn't send transition graph to peer, discarding");
        }

        free_xml(reply);
        cleanup_alloc_calculations(&data_set);

        if (was_processing_error) {
            crm_err("Calculated transition %d (with errors), saving inputs in %s",
                    transition_id, filename);

        } else if (was_processing_warning) {
            crm_warn("Calculated transition %d (with warnings), saving inputs in %s",
                     transition_id, filename);

        } else {
            crm_notice("Calculated transition %d, saving inputs in %s",
                       transition_id, filename);
        }

        if (crm_config_error) {
            crm_notice("Configuration ERRORs found during PE processing."
                       "  Please run \"crm_verify -L\" to identify issues.");
        }

        if (is_repoke == FALSE && series_wrap != 0) {
            unlink(filename);
            crm_xml_add_int(xml_data, "execution-date", execution_date);
            write_xml_file(xml_data, filename, HAVE_BZLIB_H);
            write_last_sequence(PE_STATE_DIR, series[series_id].name, seq + 1, series_wrap);
        } else {
            crm_trace("Not writing out %s: %d & %d", filename, is_repoke, series_wrap);
        }

        free_xml(converted);
    }

    return TRUE;
}
コード例 #8
0
ファイル: pengine.c プロジェクト: nozawat/pacemaker-1.0
gboolean
process_pe_message(xmlNode *msg, xmlNode *xml_data, IPC_Channel *sender)
{
    gboolean send_via_disk = FALSE;
    const char *sys_to = crm_element_value(msg, F_CRM_SYS_TO);
    const char *op = crm_element_value(msg, F_CRM_TASK);
    const char *ref = crm_element_value(msg, XML_ATTR_REFERENCE);

    crm_debug_3("Processing %s op (ref=%s)...", op, ref);

    if(op == NULL) {
        /* error */

    } else if(strcasecmp(op, CRM_OP_HELLO) == 0) {
        /* ignore */

    } else if(safe_str_eq(crm_element_value(msg, F_CRM_MSG_TYPE),
                          XML_ATTR_RESPONSE)) {
        /* ignore */

    } else if(sys_to == NULL || strcasecmp(sys_to, CRM_SYSTEM_PENGINE) != 0) {
        crm_debug_3("Bad sys-to %s", crm_str(sys_to));
        return FALSE;

    } else if(strcasecmp(op, CRM_OP_PECALC) == 0) {
        int seq = -1;
        int series_id = 0;
        int series_wrap = 0;
        char *filename = NULL;
        char *graph_file = NULL;
        const char *value = NULL;
        pe_working_set_t data_set;
        xmlNode *converted = NULL;
        xmlNode *reply = NULL;
        gboolean process = TRUE;
#if HAVE_BZLIB_H
        gboolean compress = TRUE;
#else
        gboolean compress = FALSE;
#endif

        crm_config_error = FALSE;
        crm_config_warning = FALSE;

        was_processing_error = FALSE;
        was_processing_warning = FALSE;

        graph_file = crm_strdup(CRM_STATE_DIR"/graph.XXXXXX");
        graph_file = mktemp(graph_file);

        converted = copy_xml(xml_data);
        if(cli_config_update(&converted, NULL, TRUE) == FALSE) {
            set_working_set_defaults(&data_set);
            data_set.graph = create_xml_node(NULL, XML_TAG_GRAPH);
            crm_xml_add_int(data_set.graph, "transition_id", 0);
            crm_xml_add_int(data_set.graph, "cluster-delay", 0);
            process = FALSE;
        }

        if(process) {
            do_calculations(&data_set, converted, NULL);
        }

        series_id = get_series();
        series_wrap = series[series_id].wrap;
        value = pe_pref(data_set.config_hash, series[series_id].param);

        if(value != NULL) {
            series_wrap = crm_int_helper(value, NULL);
            if(errno != 0) {
                series_wrap = series[series_id].wrap;
            }

        } else {
            crm_config_warn("No value specified for cluster"
                            " preference: %s",
                            series[series_id].param);
        }

        seq = get_last_sequence(PE_STATE_DIR, series[series_id].name);

        data_set.input = NULL;
        reply = create_reply(msg, data_set.graph);
        CRM_ASSERT(reply != NULL);

        filename = generate_series_filename(
                       PE_STATE_DIR, series[series_id].name, seq, compress);
        crm_xml_add(reply, F_CRM_TGRAPH_INPUT, filename);
        crm_xml_add_int(reply, "graph-errors", was_processing_error);
        crm_xml_add_int(reply, "graph-warnings", was_processing_warning);
        crm_xml_add_int(reply, "config-errors", crm_config_error);
        crm_xml_add_int(reply, "config-warnings", crm_config_warning);

        if(send_ipc_message(sender, reply) == FALSE) {
            if(sender && sender->ops->get_chan_status(sender) == IPC_CONNECT) {
                send_via_disk = TRUE;
                crm_err("Answer could not be sent via IPC, send via the disk instead");
                crm_info("Writing the TE graph to %s", graph_file);
                if(write_xml_file(data_set.graph, graph_file, FALSE) < 0) {
                    crm_err("TE graph could not be written to disk");
                }
            } else {
                crm_info("Peer disconnected, discarding transition graph");
            }
        }

        free_xml(reply);
        cleanup_alloc_calculations(&data_set);

        if(series_wrap != 0) {
            write_xml_file(xml_data, filename, compress);
            write_last_sequence(PE_STATE_DIR, series[series_id].name,
                                seq+1, series_wrap);
        }

        if(was_processing_error) {
            crm_err("Transition %d:"
                    " ERRORs found during PE processing."
                    " PEngine Input stored in: %s",
                    transition_id, filename);

        } else if(was_processing_warning) {
            crm_warn("Transition %d:"
                     " WARNINGs found during PE processing."
                     " PEngine Input stored in: %s",
                     transition_id, filename);

        } else {
            crm_info("Transition %d: PEngine Input stored in: %s",
                     transition_id, filename);
        }

        if(crm_config_error) {
            crm_info("Configuration ERRORs found during PE processing."
                     "  Please run \"crm_verify -L\" to identify issues.");

        } else if(crm_config_warning) {
            crm_info("Configuration WARNINGs found during PE processing."
                     "  Please run \"crm_verify -L\" to identify issues.");
        }

        if(send_via_disk) {
            reply = create_reply(msg, NULL);
            crm_xml_add(reply, F_CRM_TGRAPH, graph_file);
            crm_xml_add(reply, F_CRM_TGRAPH_INPUT, filename);
            CRM_ASSERT(reply != NULL);
            if(send_ipc_message(sender, reply) == FALSE) {
                crm_err("Answer could not be sent");
            }
            free_xml(reply);
        }

        free_xml(converted);
        crm_free(graph_file);
        crm_free(filename);

    } else if(strcasecmp(op, CRM_OP_QUIT) == 0) {
        crm_warn("Received quit message, terminating");
        exit(0);
    }

    return TRUE;
}
コード例 #9
0
ファイル: messages.c プロジェクト: grueni/pacemaker
enum crmd_fsa_input
handle_request(xmlNode * stored_msg, enum crmd_fsa_cause cause)
{
    xmlNode *msg = NULL;
    const char *op = crm_element_value(stored_msg, F_CRM_TASK);

    /* Optimize this for the DC - it has the most to do */

    if (op == NULL) {
        crm_log_xml_err(stored_msg, "Bad message");
        return I_NULL;
    }

    if (strcmp(op, CRM_OP_SHUTDOWN_REQ) == 0) {
        const char *from = crm_element_value(stored_msg, F_CRM_HOST_FROM);
        crm_node_t *node = crm_find_peer(0, from);

        crm_update_peer_expected(__FUNCTION__, node, CRMD_JOINSTATE_DOWN);
        if(AM_I_DC == FALSE) {
            return I_NULL; /* Done */
        }
    }

    /*========== DC-Only Actions ==========*/
    if (AM_I_DC) {
        if (strcmp(op, CRM_OP_JOIN_ANNOUNCE) == 0) {
            return I_NODE_JOIN;

        } else if (strcmp(op, CRM_OP_JOIN_REQUEST) == 0) {
            return I_JOIN_REQUEST;

        } else if (strcmp(op, CRM_OP_JOIN_CONFIRM) == 0) {
            return I_JOIN_RESULT;

        } else if (strcmp(op, CRM_OP_SHUTDOWN) == 0) {
            const char *host_from = crm_element_value(stored_msg, F_CRM_HOST_FROM);
            gboolean dc_match = safe_str_eq(host_from, fsa_our_dc);

            if (is_set(fsa_input_register, R_SHUTDOWN)) {
                crm_info("Shutting ourselves down (DC)");
                return I_STOP;

            } else if (dc_match) {
                crm_err("We didn't ask to be shut down, yet our"
                        " TE is telling us to. Better get out now!");
                return I_TERMINATE;

            } else if (fsa_state != S_STOPPING) {
                crm_err("Another node is asking us to shutdown" " but we think we're ok.");
                return I_ELECTION;
            }

        } else if (strcmp(op, CRM_OP_SHUTDOWN_REQ) == 0) {
            /* a slave wants to shut down */
            /* create cib fragment and add to message */
            return handle_shutdown_request(stored_msg);
        }
    }

    /*========== common actions ==========*/
    if (strcmp(op, CRM_OP_NOVOTE) == 0) {
        ha_msg_input_t fsa_input;

        fsa_input.msg = stored_msg;
        register_fsa_input_adv(C_HA_MESSAGE, I_NULL, &fsa_input,
                               A_ELECTION_COUNT | A_ELECTION_CHECK, FALSE, __FUNCTION__);

    } else if (strcmp(op, CRM_OP_THROTTLE) == 0) {
        throttle_update(stored_msg);
        return I_NULL;

    } else if (strcmp(op, CRM_OP_CLEAR_FAILCOUNT) == 0) {
        return handle_failcount_op(stored_msg);

    } else if (strcmp(op, CRM_OP_VOTE) == 0) {
        /* count the vote and decide what to do after that */
        ha_msg_input_t fsa_input;

        fsa_input.msg = stored_msg;
        register_fsa_input_adv(C_HA_MESSAGE, I_NULL, &fsa_input,
                               A_ELECTION_COUNT | A_ELECTION_CHECK, FALSE, __FUNCTION__);

        /* Sometimes we _must_ go into S_ELECTION */
        if (fsa_state == S_HALT) {
            crm_debug("Forcing an election from S_HALT");
            return I_ELECTION;
#if 0
        } else if (AM_I_DC) {
            /* This is the old way of doing things but what is gained? */
            return I_ELECTION;
#endif
        }

    } else if (strcmp(op, CRM_OP_JOIN_OFFER) == 0) {
        crm_debug("Raising I_JOIN_OFFER: join-%s", crm_element_value(stored_msg, F_CRM_JOIN_ID));
        return I_JOIN_OFFER;

    } else if (strcmp(op, CRM_OP_JOIN_ACKNAK) == 0) {
        crm_debug("Raising I_JOIN_RESULT: join-%s", crm_element_value(stored_msg, F_CRM_JOIN_ID));
        return I_JOIN_RESULT;

    } else if (strcmp(op, CRM_OP_LRM_DELETE) == 0
               || strcmp(op, CRM_OP_LRM_FAIL) == 0
               || strcmp(op, CRM_OP_LRM_REFRESH) == 0 || strcmp(op, CRM_OP_REPROBE) == 0) {

        crm_xml_add(stored_msg, F_CRM_SYS_TO, CRM_SYSTEM_LRMD);
        return I_ROUTER;

    } else if (strcmp(op, CRM_OP_NOOP) == 0) {
        return I_NULL;

    } else if (strcmp(op, CRM_OP_LOCAL_SHUTDOWN) == 0) {

        crm_shutdown(SIGTERM);
        /*return I_SHUTDOWN; */
        return I_NULL;

        /*========== (NOT_DC)-Only Actions ==========*/
    } else if (AM_I_DC == FALSE && strcmp(op, CRM_OP_SHUTDOWN) == 0) {

        const char *host_from = crm_element_value(stored_msg, F_CRM_HOST_FROM);
        gboolean dc_match = safe_str_eq(host_from, fsa_our_dc);

        if (dc_match || fsa_our_dc == NULL) {
            if (is_set(fsa_input_register, R_SHUTDOWN) == FALSE) {
                crm_err("We didn't ask to be shut down, yet our DC is telling us to.");
                set_bit(fsa_input_register, R_STAYDOWN);
                return I_STOP;
            }
            crm_info("Shutting down");
            return I_STOP;

        } else {
            crm_warn("Discarding %s op from %s", op, host_from);
        }

    } else if (strcmp(op, CRM_OP_PING) == 0) {
        /* eventually do some stuff to figure out
         * if we /are/ ok
         */
        const char *sys_to = crm_element_value(stored_msg, F_CRM_SYS_TO);
        xmlNode *ping = create_xml_node(NULL, XML_CRM_TAG_PING);

        crm_xml_add(ping, XML_PING_ATTR_STATUS, "ok");
        crm_xml_add(ping, XML_PING_ATTR_SYSFROM, sys_to);
        crm_xml_add(ping, "crmd_state", fsa_state2string(fsa_state));

        /* Ok, so technically not so interesting, but CTS needs to see this */
        crm_notice("Current ping state: %s", fsa_state2string(fsa_state));

        msg = create_reply(stored_msg, ping);
        if (msg) {
            (void)relay_message(msg, TRUE);
        }

        free_xml(ping);
        free_xml(msg);

    } else if (strcmp(op, CRM_OP_RM_NODE_CACHE) == 0) {
        int id = 0;
        const char *name = NULL;

        crm_element_value_int(stored_msg, XML_ATTR_ID, &id);
        name = crm_element_value(stored_msg, XML_ATTR_UNAME);

        if(cause == C_IPC_MESSAGE) {
            msg = create_request(CRM_OP_RM_NODE_CACHE, NULL, NULL, CRM_SYSTEM_CRMD, CRM_SYSTEM_CRMD, NULL);
            if (send_cluster_message(NULL, crm_msg_crmd, msg, TRUE) == FALSE) {
                crm_err("Could not instruct peers to remove references to node %s/%u", name, id);
            } else {
                crm_notice("Instructing peers to remove references to node %s/%u", name, id);
            }
            free_xml(msg);

        } else {

            reap_crm_member(id, name);
            if(attrd_ipc) {
                int rc = 0;
                xmlNode *update = create_xml_node(NULL, __FUNCTION__);

                crm_xml_add(update, F_TYPE, T_ATTRD);
                crm_xml_add(update, F_ORIG, crm_system_name);

                crm_xml_add(update, F_ATTRD_TASK, "peer-remove");
                crm_xml_add(update, F_ATTRD_HOST, name);
                crm_xml_add_int(update, F_ATTRD_HOST_ID, id);

                rc = crm_ipc_send(attrd_ipc, update, crm_ipc_client_response, 0, NULL);
                if (rc > 0) {
                    rc = pcmk_ok;
                }

                crm_debug("Peer cache cleanup for %s (%d): %s (%d)", name, id, pcmk_strerror(rc), rc);
                free_xml(update);
            }
        }

    } else {
        crm_err("Unexpected request (%s) sent to %s", op, AM_I_DC ? "the DC" : "non-DC node");
        crm_log_xml_err(stored_msg, "Unexpected");
    }

    return I_NULL;
}
コード例 #10
0
ファイル: cib.c プロジェクト: sipwise/heartbeat
/*	 A_CIB_INVOKE, A_CIB_BUMPGEN, A_UPDATE_NODESTATUS	*/
void
do_cib_invoke(long long action,
	      enum crmd_fsa_cause cause,
	      enum crmd_fsa_state cur_state,
	      enum crmd_fsa_input current_input,
	      fsa_data_t *msg_data)
{
	HA_Message *answer = NULL;
	ha_msg_input_t *cib_msg = fsa_typed_data(fsa_dt_ha_msg);
	const char *sys_from = cl_get_string(cib_msg->msg, F_CRM_SYS_FROM);

	if(fsa_cib_conn->state == cib_disconnected) {
		if(cur_state != S_STOPPING) {
			crm_err("CIB is disconnected");
			crm_log_message_adv(LOG_WARNING, "CIB Input", cib_msg->msg);
			return;
		}
		crm_info("CIB is disconnected");
		crm_log_message_adv(LOG_DEBUG, "CIB Input", cib_msg->msg);
		return;
		
	}
	
	if(action & A_CIB_INVOKE) {
		if(safe_str_eq(sys_from, CRM_SYSTEM_CRMD)) {
			action = A_CIB_INVOKE_LOCAL;
		} else if(safe_str_eq(sys_from, CRM_SYSTEM_DC)) {
			action = A_CIB_INVOKE_LOCAL;
		}
	}
	

	if(action & A_CIB_INVOKE || action & A_CIB_INVOKE_LOCAL) {
		int call_options = 0;
		enum cib_errors rc  = cib_ok;
		crm_data_t *cib_frag  = NULL;
		
		const char *section  = NULL;
		const char *op   = cl_get_string(cib_msg->msg, F_CRM_TASK);

		section  = cl_get_string(cib_msg->msg, F_CIB_SECTION);
		
		ha_msg_value_int(cib_msg->msg, F_CIB_CALLOPTS, &call_options);

		crm_log_message(LOG_MSG, cib_msg->msg);
		crm_log_xml_debug_3(cib_msg->xml, "[CIB update]");
		if(op == NULL) {
			crm_err("Invalid CIB Message");
			register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
			return;
		}

		cib_frag = NULL;
		rc = fsa_cib_conn->cmds->variant_op(
			fsa_cib_conn, op, NULL, section,
			cib_msg->xml, &cib_frag, call_options);

		if(rc < cib_ok || (action & A_CIB_INVOKE)) {
			answer = create_reply(cib_msg->msg, cib_frag);
			ha_msg_add(answer,XML_ATTR_RESULT,cib_error2string(rc));
		}
		
		if(action & A_CIB_INVOKE) {
			if(relay_message(answer, TRUE) == FALSE) {
				crm_err("Confused what to do with cib result");
				crm_log_message(LOG_ERR, answer);
				crm_msg_del(answer);
				register_fsa_input(C_FSA_INTERNAL, I_ERROR, NULL);
				return;
			}

		} else if(rc < cib_ok) {
			ha_msg_input_t *input = NULL;
			crm_err("Internal CRM/CIB command from %s() failed: %s",
				msg_data->origin, cib_error2string(rc));
			crm_log_message_adv(LOG_WARNING, "CIB Input", cib_msg->msg);
			crm_log_message_adv(LOG_WARNING, "CIB Reply", answer);
			
			input = new_ha_msg_input(answer);
			register_fsa_input(C_FSA_INTERNAL, I_ERROR, input);
			crm_msg_del(answer);
			delete_ha_msg_input(input);
		}

	} else {
		crm_err("Unexpected action %s in %s",
			fsa_action2string(action), __FUNCTION__);
	}
}